4

Configuring the Network Stack



4.1    Introduction

This chapter tells you how to include and configure VxWorks components on a VxWorks target. It also tells you how to set any parameter values associated with those components. Configuring VxWorks involves activities such as:

  • including VxWorks components in the VxWorks image at build time
  • setting the parameter values associated with those components
  • configuring the network interfaces
  • manually adjusting the contents of the forwarding table (optional)


*      
NOTE: By default, IP forwarding is turned on. This is typical for a router. If you want a host only product, you could turn off IP forwarding. To do this, remove the IP_DO_FORWARDING flag from the IP_FLAGS_DFLT configuration parameter.



4.2    Summary of Configuration Settings

The following summary lists all compile-time components and parameters, boot-line parameters, and run-time function calls associated with configuring the VxWorks stack. The more familiar you are with these components, parameters, functions, and the functionality associated with each, the easier it will be to configure your VxWorks stack.

Compile-time Configuration Components and Parameters

ARP_MAX_ENTRIES -- limit size of ARP table

INCLUDE_TCP -- include the TCP protocol

INCLUDE_UDP -- include the UDP protocol

INCLUDE_ICMP -- include the ICMP protocol

INCLUDE_IGMP -- include the IGMP protocol (host side)

INCLUDE_IGMP_ROUTER -- include the IGMP protocol (router side)

INCLUDE_PING -- include PING client

INCLUDE_SM_NET -- include shared memory network support

INCLUDE_PROXY_SERVER -- include the proxy ARP server

INCLUDE_PROXY_CLIENT -- include the proxy ARP client

INCLUDE_SM_SEQ_ADDR -- assign sequential addresses to hosts on the shared memory back plane

INCLUDE_PROXY_DEFAULT_ADDR -- use default IP address (ead plus 1) for interface to shared memory backplane

SM_OFF_BOARD -- identifies whether shared memory is off or on local board

TCP_FLAGS_DFLT -- TCP Default Flags

TCP_SND_SIZE_DFLT -- TCP Send Buffer Size

TCP_RCV_SIZE_DFLT -- TCP Receive Buffer Size

TCP_CON_TIMEO_DFLT -- TCP Connection Time out

TCP_REXMT_THLD_DFLT -- TCP Retransmission Threshold

TCP_MSS_DFLT -- Default TCP Maximum Segment Size

TCP_RND_TRIP_DFLT -- Default Round Trip Interval

TCP_IDLE_TIMEO_DFLT -- TCP Idle Time-out Value

TCP_MAX_PROBE_DFLT -- TCP Probe Limit

UDP_FLAGS_DFLT -- UDP Configuration Flags

UDP_SND_SIZE_DFLT -- UDP Send Buffer Size

UDP_RCV_SIZE_DFLT -- UDP Receive Buffer Size

ICMP_FLAGS_DFLT -- ICMP Configuration Flags

IP_FLAGS_DFLT -- IP Configuration Flags

IP_MAX_UNITS -- maximum number of interfaces attached to IP layer

IP_TTL_DFLT -- IP Time-to-live Value

IP_QLEN_DFLT -- IP Packet Queue Size

IP_FRAG_TTL_DFLT -- IP Time-to-live Value for packet fragments

NUM_64 -- Number of 64 byte clusters for network data memory pool

NUM_128 -- Number of 128 byte clusters for network data memory pool

NUM_256 -- Number of 256 byte clusters for network data memory pool

NUM_512 -- Number of 512 byte clusters for network data memory pool

NUM_1024 -- Number of 1024 byte clusters for network data memory pool

NUM_2048 -- Number of 2048 byte clusters for network data memory pool

NUM_CL_BLKS -- Number of clBlks for network data memory pool

NUM_NET_MBLKS -- Number of mBlks for network data memory pool

NUM_SYS_64 -- Number of 64 byte clusters for network system memory pool

NUM_SYS_128 -- Number of 128 byte clusters for network system memory pool

NUM_SYS_256 -- Number of 256 byte clusters for network system memory pool

NUM_SYS_512 -- Number of 512 byte clusters for network system memory pool

NUM_SYS_CL_BLKS -- Number of clBlks for network system memory pool

NUM_SYS_MBLKS -- Number of mBlks for network system memory pool

Boot Line Configuration Values

ead -- boot line parameter specifying IP address and mask for boot interface

bootDev -- boot line parameter specifying name of boot network interface

unitNum -- boot line parameter specifying number of boot network interface

gad -- address and mask of the intermediate gateway to host supplying boot image

bad -- address and mask assigned to interface representing the shared memory back plane. If you are using sequential addressing and proxy default addressing, the target generates a bad value from the ead parameter and the CPU number.

Configuration Functions Callable at Run-Time

igmpRouterLibInit( ) -- initialize IGMPv2 router

igmpRouterLibQuit( ) -- shut down IGMPv2 router

igmpInterfaceEnable( ) -- enable IGMPv2 on specified interface

igmpInterfaceDisable( ) -- disable IGMPv2 on specified interface

igmpLibInit( ) -- initialize the IGMPv2 host

ipAttach( ) -- attach IP to the MUX

ipDetach( ) -- detach IP from the MUX

ifMaskSet( ) -- set network mask for an interface

ifAddrSet( ) -- set IP address for an interface and associated broadcast address

ifBroadcastSet( ) -- set custom broadcast IP address

mRouteAdd( ) -- add a static route to the routing table

mRouteDelete( ) -- delete a static route from the routing table

mRouteEntryAdd( ) -- add a protocol-owned route to the routing table

mRouteEntryDelete( ) -- delete a protocol-owned route from the routing table

proxyPortFwdOn( ) -- allow forwarding of broadcasts for specified port

proxyPortFwdOff( ) -- block forwarding of broadcasts for specified port

smNetShow( ) -- find the shared memory anchor

sysBusToLocalAddr( ) -- get the correct bus address for the shared memory anchor



4.3    Configuring the Network Stack at Build Time

At compile time, you select the protocols and facilities that are included in the networking stack. You may also specify resources allocated to the networking stack as well as set behavior configuration values for IP, TCP, UDP, and ICMP.

4.3.1   Network Protocol Scalability

The default VxWorks stack includes the code implementing the TCP, UDP, ICMP, and IGMP protocols. If you want to exclude one of these protocols, reconfigure VxWorks using the configuration parameters listed below:

INCLUDE_TCP

Include the TCP protocol.

INCLUDE_UDP

Include the UDP protocol.

INCLUDE_ICMP

Include the ICMP protocol.

INCLUDE_IGMP

Include the IGMP protocol (host side).

INCLUDE_IGMP_ROUTER

Include the IGMP protocol (router side).

About UDP -- User Datagram Protocol

UDP provides a simple datagram-based end-to-end communication mechanism. UDP extends the message address to include a port address in addition to the host Internet address. The port address identifies one of several distinct destinations within a single host. Thus, UDP accepts messages addressed to a particular port on a particular host, and tries to deliver them, using IP to transport the messages between the hosts. Like IP, UDP makes no guarantees that messages are delivered correctly or even delivered at all.

However, this relatively low-overhead delivery mechanism makes UDP useful to many other protocols and utilities, such as BOOTP, DHCP, DNS, RIP, SNMP, and NFS.

About TCP -- Transmission Control Protocol

TCP provides reliable, flow-controlled, two-way, process-to-process transmission of data. TCP is a connection-based communication mechanism. This means that before data can be exchanged over TCP, the two communicating processes must first establish a connection through a distinct connection phase. Data is then sent and received as a byte stream at both ends.

Like UDP, TCP extends the connection address to include a port address in addition to the host Internet address. That is, a connection is established between a particular port in one host and a particular port in another host. TCP guarantees that the delivery of data is correct, in the proper order, and without duplication.

About ICMP -- Internet Control Message Protocol

ICMP provides information on the success of data transfer. This protocol defines a set of messages that the TCP/IP stack uses to detect a variety of transmission failure types as well as time information. How the TCP/IP stack processes these messages and how these messages change TCP/IP stack configuration often depends upon higher level protocols, such as TCP and interested users of UDP. Still, ICMP is fundamental to monitoring transmission success.

About IGMP -- Internet Group Management Protocol

The TCP/IP stack uses IGMP to support multicasting. The standard VxWorks stack supports both the host-side and the router-side of the IGMP v2 protocol.

IGMP v2 is specified in RFC 2236. According to the RFC, IGMP routers listen on enabled interfaces for membership reports from attached hosts. Using this information, the IGMP routers maintain lists of the multicast addresses to which the IGMP hosts are listening. The IGMP router keeps separate lists for each interface. To discover when it needs to prune entries from a list, the IGMP router periodically transmits queries to the multicast groups on a given interface. If no reply arrives within a specifiable time or if a leave message is processed, the IGMP router removes that group from the list for that interface.

To configure the host-side VxWorks IGMP implementation, you need only include it in your image. It starts up automatically at boot time and requires no system management attention. Configuring the router-side implementation can be as simple, although you have more options. For more information, see 4.6 IGMP under VxWorks, p.71.

4.3.2   Configuring the ARP, IP, TCP, UDP, IGMP, and ICMP Protocols

This section describes the configuration for the network layer protocols. Table 4-1 describes all configuration options. For some options, the default value is specified using symbolic constants. These configuration components are defined in netLib.h. To override any default values assigned to these constants, reconfigure VxWorks with the appropriate values set.

Table 4-1 :   Network Configuration Options   


Configuration Component
Default Value and Description

ARP Cache Size
ARP_MAX_ENTRIES
Default Value: 20
Limits the number of entries in the ARP cache. Each entry requires two 64-byte clusters and one 256-byte cluster.
TCP Default Flags
TCP_FLAGS_DFLT
Default Value: TCP_DO_RFC1323
Includes RFC 1323 support. RFC 1323 is a specification to support networks that have high bandwidth and longer round trip times. This option is enabled by default. If the peer cannot negotiate this option, it should drop the option. If the host does not understand this option, it closes the connection. For such hosts, you must turn off this option.
You can also use this option in conjunction with IP_FLAGS_DFLT to turn off software checksum computation. See IP_FLAGS_DFLT, p.48.
TCP Send Buffer Size
TCP_SND_SIZE_DFLT
Default Value: 8192
Sets the default send buffer size of a TCP connection.
TCP Receive Buffer Size
TCP_RCV_SIZE_DFLT
Default Value: 8192
Sets the default receive buffer size of a TCP connection.
TCP Connection Timeout
TCP_CON_TIMEO_DFLT
Default Value: 150 (75 seconds)
Sets the timeout on establishing a TCP connection.
TCP Retransmission Threshold
TCP_REXMT_THLD_DFLT
Default Value: 3
Sets the number of duplicate ACKs needed to trigger the fast retransmit algorithm. Typically, TCP receives a duplicate ACK only if a segment is lost.
Default TCP Maximum Segment Size
(TCP_MSS_DFLT)
Default Value: 512
Sets the default maximum segment size to use if TCP cannot establish the maximum segment size of a connection.
Default Round Trip Interval
TCP_RND_TRIP_DFLT
Default Value: 3 (seconds)
Sets the round-trip time to use if TCP cannot get an estimate within 3 seconds. The round trip time of a connection is calculated dynamically.
TCP Idle Timeout Value
TCP_IDLE_TIMEO_DFLT
Default Value: 14400 (4 hours, in seconds)
Sets the idle time for a connection. Idle times greater than this value trigger a keep-alive probe. After the first keep-alive probe, a probe is sent every 75 seconds for a number of times restricted by the TCP Probe Limit.
TCP Probe Limit
TCP_MAX_PROBE_DFLT
Default Value: 8
Sets the maximum number of keep-alive probes sent out on an idle TCP connection. If TPC sends out the maximum number of keep-alive probes but receives no response, TCP drops the connection.
UDP Configuration Flags
UDP_FLAGS_DFLT
Default Value: UDP_DO_CKSUM_SND | UDP_DO_CKSUM_RCV
Specifies a calculation of data checksum for both send and receive UDP datagrams.
UDP Send Buffer Size
UDP_SND_SIZE_DFLT
Default Value: 9216
Sets the default send buffer size of a UDP socket.
UDP Receive Buffer Size
UDP_RCV_SIZE_DFLT
Default Value: 41600
Sets the default receive buffer size of a UDP socket.
ICMP Configuration Flags
ICMP_FLAGS_DFLT
Default Value: ICMP_NO_MASK_REPLY
The default value specifies no ICMP mask replies. If this option is enabled on a VxWorks host, and the host receives an ICMP mask query, the VxWorks host replies with its network interface mask.
IP Configuration Flags
IP_FLAGS_DFLT
Default Value: IP_DO_FORWARDING | IP_DO_REDIRECT | IP_DO_CHECKSUM_SND | IP_DO_CHECKSUM_RCV
The IP_DO_FORWARDING flag enables packet forwarding on systems with multiple external interfaces. This is a typical router configuration. If you want a product that does not forward packets, you must remove this flag from the default value.
The IP_DO_REDIRECT flag enables ICMP redirects, which are messages sent by a receiving host that was not the optimal recipient of a packet. The redirect message provides the address of a better host.
IP_DO_CHECKSUM_SND and IP_DO_CHECKSUM_RCV enable software checksums for packets sent and received. Both checksums are required for RFC compliance, but, if the network chip handles IP checksum computation and insertion, you do not need it in software. To prevent all software checksums, clear both IP_DO_CHECKSUM_SND and IP_DO_CHECKSUM_RCV. You must also set UDP_FLAGS_DFLT to zero.
IP Time-to-live Value
IP_TTL_DFLT
Default Value: 64
Sets the IP default time to live, an upper limit on the number of routers through which a datagram can pass. This value limits the lifetime of a datagram. It is decremented by one by every router that handles the datagram. If a host or router gets a packet whose time to live is zero (this value is stored in a field in the IP header), the datagram is thrown out and the sender is notified with an ICMP message. This behavior prevents packets from wandering in the networks forever.
IP Packet Queue Size
IP_QLEN_DFLT
Default Value: 50
Sets the default length of the IP queue and the network interface queue. IP packets are added to the IP queue when packets are received. Packets are added to the network interface queue when transmitting.
IP Time-to-live Value for packet fragments
IP_FRAG_TTL_DFLT
Default Value: 60 (30 seconds for received fragments)
Sets the default time to live value for an IP fragment. To transmit a packet bigger than the MTU size, the IP layer breaks the packet into fragments. On the receiving side, IP re-assembles these fragments to form the original packet. Upon receiving a fragment, IP adds it to the IP fragment queue. Each fragment waiting to be re-assembled is removed after the time-to-live expires. If the network is extremely busy, the IP fragment queue can accumulate many fragments. This accumulation of fragments can use up a large amount of system memory. To alleviate this problem, reduce the value of this configuration parameter.

TCP Window Sizes

For TCP sockets, the socket buffer sizes also limit the maximum send and receive window sizes for a connection. While TCP window sizes under BSD 4.4 can theoretically exceed a billion bytes, the maximum socket receive or send buffer size of 258,111 bytes determines the actual upper limit.

The window size for a connection must be set with setsockopt( ) before the listen( ) call (on the server) or the connect( ) call (on the client), because the maximum window sizes are among the parameters negotiated when the connection is established. If you change the buffer size after the connection has been established, this change will not have any effect.

Periodically TCP sends window updates informing the peer how much space is available in the receive buffer. The advertised window size cannot exceed the maximum set when the connection was established, but will decrease to zero if the receive buffer becomes full.

4.3.3   Network Memory Pool Configuration

VxWorks allocates and initializes memory for the network stack during network initialization. This memory is allocated to two pools, a system pool and a data pool. To get status information on these pools, use netStackSysPoolShow( ) and netStackDataPoolShow( ).


*      
WARNING: Failure to configure these two pools correctly is one of the single biggest causes of "frozen" network applications. The default settings for these pools are just enough to get the stack up, running, and able to respond to simple tests, such as ping. Deployed applications require more resources. Therefore, study carefully the information in Determining Memory Pool Usage, p.55.

The memory in these pools is organized and managed using mBlk structures, clBlk structures, cluster buffers (simple character arrays), and routines supplied by netBufLib. The mBlk and clBlk structures provide information necessary to support buffer sharing and buffer chaining for the data that is stored in clusters. The clusters come in sizes that are determined by the CL_DESC table that describes the memory pool. The netBufLib functions provide an interface that you can use to get or return buffers associated with a memory pool.

The CL_DESC tables for the network system memory pool and the network data memory pool are defined in target/config/comps/src/net/usrNetLib.c as sysClDescTbl[ ] and clDescTbl[ ] respectively.

Clusters

Valid cluster sizes are powers of two to up to 64KB (65536). Whether a particular cluster size is valid within a particular memory pool depends on the contents of the CL_DESC table that describes the pool. The two pools integral to the network stack use the CL_DESC tables, clDescTbl[ ] and sysClDescTbl[ ].

  • Data pool cluster sizes

Data pool cluster sizes are defined in usrNetLib.c by clDescTbl[ ] as follows:

CL_DESC clDescTbl [] =  /* network cluster pool configuration table */ 
{
/*
clusterSize num memArea memSize
----------- ---- ------- -------
*/
{64, NUM_64, NULL, 0},
{128, NUM_128, NULL, 0},
{256, NUM_256, NULL, 0},
{512, NUM_512, NULL, 0},
{1024, NUM_1024, NULL, 0},
{2048, NUM_2048, NULL, 0}
};
  • System pool cluster sizes

System pool cluster sizes are defined in usrNetLib.c by sysClDescTbl[ ] as follows:

CL_DESC sysClDescTbl [] = 
{
/*
clusterSize num memArea memSize
----------- ---- ------- -------
*/
{64, NUM_SYS_64, NULL, 0},
{128, NUM_SYS_128, NULL, 0},
{256, NUM_SYS_256, NULL, 0},
{512, NUM_SYS_512, NULL, 0},
};

A value in the first column specifies a valid cluster size in bytes. A value in the second column, the "num" column, specifies how many clusters of the specified size are allocated for the table. In the tables shown above, all values in the second column are specified using symbolic constants. You can assign the values of these constants using the standard Tornado configuration utility. In particular, look for these values in the configuration component for network buffer initialization.

If you do not modify the network stack internals, you should not need to edit (add or delete rows) either of these tables directly. However, you will need to adjust the values assigned to the NUM_* constants. See Setting the Number of Clusters on p. 53.

mBlks and clBlks

The clBlk provides the first level of abstraction above the data in a cluster. For each cluster in a memory pool, there needs to be a corresponding clBlk structure. Contained in the clBlk is information such as a pointer to the cluster data, the cluster size, and an external reference count.

Above the clBlk, is the mBlk structure. This structure stores a link to a clBlk and can store a link to another mBlk. By chaining mBlks, you can reference an arbitrarily large amount of data, such as a packet chain (see Figure 4-1).

Figure 4-1 :   Presentation of Two Packets in One mBlk Chain

Because the mBlk references the cluster data through a clBlk, duplicating an mBlk does not copy the cluster data. For example, by duplicating mBlk 1 in Figure 4-2, you can produce mBlk A. However, this duplication did not create a new copy of the underlying cluster. When you use the netBufLib routines to duplicate an mBlk (or mBlk chain), the library automatically increments the external reference counter in the underlying clBlks. This is important when it comes time to free data back to the memory pools.

Figure 4-2 :   Different mBlks Can Share the Same Cluster

If you use netBufLib routines to free an mBlk, the mBlk returns to the pool and the reference count in the underlying clBlk is decremented. If this reference count drops to zero (indicating that no mBlks reference the clBlk), netBufLib frees the clBlk and its associated cluster back to the memory pool.

The number of mBlks allocated for the network stack system and data memory pools are determined by the configuration constants NUM_NET_MBLK and NUM_SYS_MBLK. See Table 4-2 and Table 4-3.

Setting the Number of Clusters

Table 4-2 describes the NUM_* constants used to configure the network data memory pool. Table 4-3 describes the NUM_* constants used to configure the network system memory pool.


*      
WARNING: Failure to configure these two pools correctly is one of the single biggest causes of "frozen" network applications. The default settings for these pools are just enough to get the stack up, running, and able to respond to simple tests, such as ping. Deployed applications require more resources. Therefore, study carefully the information provided in Determining Memory Pool Usage, p.55.

Table 4-2 :   Configuration Parameters for Network Data Memory Pool   


Parameter
Description

NUM_NET_MBLK
Default: 400
Specifies the number of mBlk structures to allocate for the network data memory pool. At a minimum, there should be at least as many mBlks as there are clusters.
NUM_64
Default: 100
Specifies the number of 64-byte clusters to allocate for the network data memory pool.
NUM_128
Default: 100
Specifies the number of 128-byte clusters to allocate for the network data memory pool.
NUM_256
Default: 40
Specifies the number of 256-byte clusters to allocate for the network data memory pool.
NUM_512
Default: 40
Specifies the number of 512-byte clusters to allocate for the network data memory pool.
NUM_1024
Default: 25
Specifies the number of 1024-byte clusters to allocate for the network data memory pool.
NUM_2048
Default: 25
Specifies the number of 2048-byte clusters to allocate for the network data memory pool.
NUM_CL_BLKS
Default: the sum of NUM_64 through NUM_2048
This value specifies the number of clBlk structures to allocate. You need exactly one clBlk structure per cluster. If you add another cluster pool to clDescTbl[ ], be sure you increment this value appropriately.

Table 4-3 :   Configuration Parameters for Network System Memory Pool   


Parameter
Description

NUM_SYS_MBLK
Default value: 2 times NUM_SYS_CL_BLKS
Specifies the number of mBlk structures to allocate for the network system memory pool. At a minimum, there should be at least as many mBlks as there are clusters.
NUM_SYS_64
Default value: 40
Specifies the number of 64-byte clusters to allocate for the network system memory pool.
NUM_SYS_128
Default value: 40
Specifies the number of 128-byte clusters to allocate for the network system memory pool.
NUM_SYS_256
Default value: 40
Specifies the number of 256-byte clusters to allocate for the network system memory pool.
NUM_SYS_512
Default value: 20
Specifies the number of 512-byte clusters to allocate for the network system memory pool.
NUM_SYS_CL_BLKS
Default: the sum of NUM_SYS_64 through NUM_SYS_512
This value specifies the number of clBlk structures to allocate. You need exactly one clBlk structure per cluster.

The defaults assigned to these parameters are tuned to let you run Tornado out of the box. However, if you add an application that makes significant use of the network, you will need to adjust these values.

Determining Memory Pool Usage

Estimating the demands on the network stack memory pools requires a detailed understanding of the applications making the demands. Based on that understanding, you should be able to estimate the number of simultaneous open socket connections, the number of routing table and ARP entries needed, and the number of network interfaces needed. Each of these elements creates a predictable demand on the memory pool. For example:

128 byte cluster, a 256 byte cluster, and a 512 byte cluster; these are used for the generic protocol control block, the TCP protocol control block, and the socket structure respectively. 1

one 128-byte cluster and one 512-byte cluster; these are used for the generic protocol control block and socket structures.

four 64-byte clusters and two 256-byte clusters

two 64-byte clusters and one 256-byte cluster per cache entry. To limit the size of the ARP cache, use ARP_MAX_ENTRIES.

two 64-byte clusters, two 128-byte clusters, and one 256-byte cluster

However, if you are unsure of how your application uses the above resources, you can run the application under the debugger, pause it at critical points, and then compare network stack pool usage at each point. To determine memory pool usage, use the following functions:

netStackSysPoolShow( )

netStackDataPoolShow( )

memShow( )

By scaling such single-event values according to your knowledge of how your application uses sockets, the routing table, and so on, you should be able to make some initial estimates on how to set the NUM_* parameters (Table 4-2 and Table 4-3). However, it is critical that you test these values before deploying the system. Failure to adequately reserve memory resources for the network stack is one of the biggest reasons for "frozen" network applications. In addition, you must avoid creating a network stack that reserves nearly all available memory to itself and thus locks out all other applications.

4.3.4   Testing Network Connections

You can use the ping( ) utility from a target to test whether a particular system is accessible over the network. Like the UNIX command of the same name, ping( ) sends one or more packets to another system and waits for a response. You can identify the other system either by name or by its numeric Internet address. This feature is useful for testing routing tables and host tables, or determining whether another machine is receiving and sending data.

The following example shows ping( ) output for an unreachable address:

-> ping "150.12.0.1",1 
no answer from 150.12.0.1
value = -1 = 0xffffffff = _end + 0xfff91c4f

If the first argument uses a host name, ping( ) uses the host table to look it up, as in the following example:

-> ping "caspian",1 
caspian is alive
value = 0 = 0x0

The second argument specifies how many packets to expect back (typically, when an address is reachable, that is also how many packets are sent). If you specify more than one packet, ping( ) displays more elaborate output, including summary statistics. For example, the following test sends packets to a remote network address until it receives ten acknowledgments. Then the test reports on the time it takes to get replies:

-> ping "198.41.0.5",10 
PING 198.41.0.5: 56 data bytes
64 bytes from 198.41.0.5: icmp_seq=0. time=176. ms
64 bytes from 198.41.0.5: icmp_seq=1. time=64. ms
64 bytes from 198.41.0.5: icmp_seq=2. time=64. ms
64 bytes from 198.41.0.5: icmp_seq=3. time=64. ms
64 bytes from 198.41.0.5: icmp_seq=4. time=80. ms
64 bytes from 198.41.0.5: icmp_seq=5. time=64. ms
64 bytes from 198.41.0.5: icmp_seq=6. time=64. ms
64 bytes from 198.41.0.5: icmp_seq=7. time=64. ms
64 bytes from 198.41.0.5: icmp_seq=8. time=64. ms
64 bytes from 198.41.0.5: icmp_seq=9. time=64. ms

----198.41.0.5 PING Statistics----
10 packets transmitted, 10 packets received, 0% packet loss
round-trip (ms) min/avg/max = 64/76/176
value = 0 = 0x0

The report format matches the format used by the UNIX ping utility. Timings are based on the system clock; its resolution could be too coarse to show any elapsed time when communicating with targets on a local network.

Applications can use ping( ) periodically to test whether another network node is available. To support this use, the ping( ) routine returns a STATUS value and accepts a PING_OPT_SILENT flag as a bit in its third argument to suppress printed output, as in the following code fragment:

/* Check whether other system still there */ 

if (ping (partnerName, 1, PING_OPT_SILENT) == ERROR)
{
myShutdown(); /* clean up and exit */
}
...

You can set one other flag in the third ping( ) argument: PING_OPT_DONTROUTE restricts ping( ) to hosts that are directly connected, without going through a gateway.

4.3.5   Supporting Multiple Network Interface Drivers

The VxWorks stack lets you use multiple network interface cards simultaneously. You can use multiple cards of the same variety, or different types of cards, with any combination of END and NPT drivers.2

Configuring VxWorks for Multiple Drivers

If you want to set up VxWorks to function as a router, you must configure it to support multiple network interfaces. As a first step, make sure that you have compiled all the necessary network drivers into your image. You may also need to increase the value of the configuration parameter IP_MAX_UNITS.

If the image includes all the necessary drivers, you are ready to configure the target to load, start, and configure the driver. For deployed systems, you will probably want to set up the image so that it does this automatically at boot time. For information on how to do this, see:

However, as shown in Manually Starting Additional Network Interfaces at Run-Time, p.66, is also possible to load, start, and configure a driver manually.



4.4    Overview of TCP/IP

IP is the heart of TCP/IP. The goal of the IP protocol is to accept packets addressed to a particular host and then transmit the packets to that host. To accomplish this task, IP works within a stack of cooperating protocols. Using a four-layer model, the layers of the VxWorks stack are:

  • Application--Telnet, FTP, and others
  • Transport--TCP and UDP
  • Network--IP
  • Link--the MUX (a feature specific to VxWorks), its subordinate drivers, and various supporting protocols, such as ARP
Data Plane Functionality

The four-layer model mentioned above describes the data plane functionality of a TCP/IP stack. The data plane describes how the TCP/IP stack organizes the flow of data from an application, down through the stack, out onto the network, and then back. As packets flow down the stack, each layer adds a header to the packet and pushes the packet down to the next level. As packets flow up the stack, each layer strips its header, uses the header to determine the recipient of the packet, and pushes the packet up to the appropriate recipient in the next higher layer.

To deliver a packet, IP hands the packet to the link layer after a routing table lookup determines that the packet is deliverable. If the routing table cannot match the destination address, IP considers the packet undeliverable and discards it. A matching routing table entry gives IP all the information needed to transmit the packet to a destination on the local network.

If the packet is destined for a remote host, the routing table match provides access information for a local gateway. Gateways (also known as routers) have multiple network interfaces (at least two) that let the gateway transfer data between different networks. When a gateway accepts a packet, its IP layer checks the destination of the packet. If the packet is not destined for the gateway itself, IP does a routing table search on the destination address of the packet.

This lookup duplicates the process that took place on the machine originating the packet. Depending on the results of the routing table search, the packet is dropped, delivered, or forwarded. If the packet is forwarded, the process continues until the packet is delivered, dropped, or expired. A packet expires if it cannot reach its destination within a configurable number of hops (gateway forwardings).

If the packet expires, or IP drops the packet, IP generates an ICMP error message. IP uses its data plane functionality to transmit this message, but the message itself is processed by the TCP/IP control plane functionality.

Control Plane Functionality

The control plane functionality of the TCP/IP stack allows the protocols to detect transmission failures and the like.

Maintaining Routing Information

How you set up and manage a routing table for your VxWorks stack depends on your application. For example, you could use RIP to initialize, populate, and manage the routing table. RIP uses IP functionality (through UDP) to announce its presence on the network and discover peers with which to exchange information on network topology.

In addition to a routing protocol, VxWorks includes functionality that you can use to set up and manage a routing table manually. Although you might not use this manual functionality in your deployed application, it is often very useful when you are first developing and debugging your network communications for your application.



4.5    Configuring the IP-to-Link Layer Interface

Configuring the IP-to-Link Layer interface involves the following:

  1. Bind IP to the MUX.
  1. Set the network mask for an interface.
  1. Assign an IP address to each interface.
  1. Assign broadcast addresses.

Binding IP to the MUX happens by default for the boot interface. If your target includes only one network interface, you can set the interface network mask and address from the boot line (additional interfaces will require explicit configuration after booting). Assigning the netmask also sets a default broadcast address--the IP address with all the host bits set. However, VxWorks includes functionality that you can use to override this default.

4.5.1   Binding IP to the MUX (Link Layer)

The MUX interface provides data link layer access to registered network protocols. The MUX decouples IP and the data link layer and makes it possible to run different network protocols over the same network hardware. To bind the TCP/IP stack to a particular interface in the MUX, you must call ipAttach( ). If you need to remove this binding, call ipDetach( ).

For the boot device, the built-in TCP/IP stack initialization code automatically calls ipAttach( ). To bind the VxWorks stack to additional interfaces, you must make an explicit ipAttach( ) call for each additional interface.

For more information on the MUX interface, see 10. Integrating a New Network Interface Driver.

4.5.2   Assigning an IP Address and Network Mask to an Interface

A network interface represents a physical connection to a network through a specific device. To use a specific network device with IP, you must assign a 32-bit Internet (inet) address and a 32-bit network mask to the interface. The network mask distinguishes the network address portion of the IP address from the host address portion. IP uses this information to determine whether a particular IP address is local (directly reachable). This information is also used to create local entries in the routing table.

When setting the IP address and network mask value for a network interface, you must specify the mask first and then the IP address. To assign a network mask to an interface, call ifMaskSet( ). To assign an IP address to an interface, call ifAddrSet( ). Because you must assign the mask first, you should call ifMaskSet( ) before calling ifAddrSet( ). This is because ifAddrSet( ) uses the net mask when assigning the broadcast address. Calling ifMaskSet( ) does not update these structures.

If your target boot line already includes an ead value (an IPaddress:mask value) for a network interface, you do not need to call ifMaskSet( ) and ifAddrSet( ) for that network interface. That is done for you automatically. For any additional interfaces attached to the target, you will need to call ifMaskSet( ) and ifAddrSet( ) explicitly.

For detailed information on these functions, see the ifLib reference entries.

Interfaces Configured from the Boot Line

If the boot line for the target specifies an ead value, your target uses this value as the IP address of the network interface identified in the boot line by the bootDev and unitNum values.

To specify the network mask for the interface, append a colon and network mask value to the IP address in the ead value. For example, to assign an IP address of 147.38.1.2 and a network mask of 0xFFFFFFC0 in the boot line, you would specify an ead value of:

147.38.1.2:FFFFFFC0

The base-16 network mask after the colon does not take a 0x prefix.

Consider the boot line:

ln(0, 0) bear:/usr/wpwr/target/config/mz7122/vxworks e=90.10.50.2:FFFFFFC0 b=90.10.50.2 h=100.0.0.4 g=90.10.50.3 u=papa pw=ornery f=0x80 tn=goldilox  
s=bear:/usr/papa/startupScript o=

This line assigns an IP address of 90.10.50.2 with a network mask of 0xFFFFFFC0 to the ln0 interface.

Assigning the Net Mask to a Network Interface

IP routing table entries use the network number of an interface to determine which IP addresses are reachable through that interface. If the network number of an IP address matches the network number of a local network interface, IP can reach the destination through that network interface.

Class-Based IP Addresses and Network Mask Values

Before Classless Inter-domain Routing (CIDR), the Internet address space was divided into address classes (see Figure 4-3), each with its own default network mask (see Table 4-4). IP could determine the class of an address by reading the high-order bits of an Internet address as shown in Figure 4-3.

Figure 4-3 :   Pre-CIDR Internet Address Classes

Table 4-4 :   Pre-CIDR Internet Address Ranges and Masks   


Class
High Order Bits
Default Address Mask
Address Range

A
0
0xff000000 
0.0.0.0 - 126.255.255.255
Reserved
127.0.0.0 - 127.255.255.255
B
10
0xffff0000 
128.0.0.0 - 191.255.255.255
C
110
0xffffff00 
192.0.0.0 - 223.255.255.255
D
1110
None
224.0.0.0 - 239.255.255.255

The default class-oriented address masks fell on byte boundaries. Masks with this degree of granularity carved up the Internet address space into rather large chunks. A network with a class A network number could manage 16,777,216 IP addresses, a class B address network number allowed a network of 61,696 IP addresses, and a class C network number could manage 256 IP addresses.


*      
NOTE: The number of hosts on an IP network is not quite as large as its IP address space. This is because IP requires each network to reserve at least one address as the broadcast address. If the network is divided into subnets, each subnet must similarly reserve a local IP address for broadcasting to the local subnet. By default, VxWorks reserves at least two addresses for broadcasting. One reserved address follows the current convention for broadcast addresses--all host address bit are set. The other reserved address follows the obsolete "all host address bits are cleared" convention. In addition, the ifBroadcastSet( ) routine lets you designate still another address as the local broadcast address.

CIDR IP Addresses and Network Masks

Under CIDR, IP routing no longer assumes a network mask based on the Internet address class. Although, if you fail to set a network mask value for a network interface before calling ifAddrSet( ), the VxWorks routing table software assumes a default value based on the class system.

In the current CIDR environment, your network is still described by a network number and a mask. However, the mask no longer falls on byte boundaries. Masks can now be assigned by the bit. When choosing a network number, you can select a network mask that has enough bits to include as many IP addresses as you expect to need for your network.

For example, if you need a network of 1000 IP addresses, you would need a netmask of at least 10 bits. Such a mask would give you an address space of 210 addresses (1024 possible IP addresses).

Determining the Network Mask for an Interface

When adding a host or router to an existing network, use the same network mask as all the other interfaces attached to that network. If you did not set up that network, you can get the network mask by asking the network administrator. The network administrator can also assign you an available IP address for the host you are adding.

For a simple example of how you would use masks to divide an address space into subnets, consider a network with the network number 147.38.1.0 and a mask of 24 bits, which you can represent as 255.255.255.0 or 0xFFFFFF00. This gives you an address space of 256 IP addresses (147.38.1.00 through 147.38.1.255).

If you want to divide this space into four equal subnets, you typically need five interfaces, one connecting to the outside world and four connecting to the internal subnets.

To subdivide your address space, you extend the assigned network mask. Each added bit of mask subdivides your address space by powers of two. Thus, if you extend the mask by one bit, you divide your address space into two subnets, two bits subdivides your address space into four subnets, three bits into eight subnets, four bits into 16 subnets, and so on.

If you extend the assigned mask by two bits, the last field of the mask contains a value of:

11 00 00 00 = 27 + 26 + 0  + 0  + 0  + 0  + 0  + 0  = 192 = 0xC0

Joining this to the network mask assigned to your overall network gives you the mask to use on each of the four subnets:

255.255.255.192 = 0xFFFFFFC0

The network number of each subnet is the assigned network number plus all the values expressible within the mask extension:

00 00 00 00 = 0  + 0  + 0  + 0  + 0  + 0  + 0  + 0  =   0 =  0x0 
01 00 00 00 = 0  + 26 + 0  + 0  + 0  + 0  + 0  + 0  =  64 = 0x10
10 00 00 00 = 27 + 0  + 0  + 0  + 0  + 0  + 0  + 0  = 128 = 0x80
11 00 00 00 = 27 + 26 + 0  + 0  + 0  + 0  + 0  + 0  = 192 = 0xC0

This gives the four network numbers shown in Table 4-5.

Table 4-5 :   Example Two-Bit Subnets under 147.38.1.00/0xFFFFFF00   


Network Address/Network Mask
IP Address Range (inclusive)

147.38.1.0/0xFFFFFFC0
147.38.1.0
to
147.38.63
147.38.1.64/0xFFFFFFC0
147.38.1.64
to
147.38.127
147.38.1.128/0xFFFFFFC0
147.38.1.128
to
147.38.191
147.38.1.192/0xFFFFFFC0
147.38.1.192
to
147.38.255


*      
NOTE: Although the example divides the network into subnets of equal size, it is possible to create subnets of different sizes. For example, the address/mask values 147.38.1.128/0xFFFFFF00, 147.38.1.0/0xFFFFFFC0, and 147.38.1.64/0xFFFFFFC0 create three subnets. The subnets with the longer 0xFFFFFFC0 masks create subnets for the address ranges 147.38.1.0 to 147.38.63 and 147.38.1.64 to 147.38.127. With these subnets already carved out of the 147.38.1.0 to 147.38.1.255 address space, the 147.38.1.128/0xFFFFFF00 subnet contains the 147.38.128 to 147.38.255 space.

Assigning the Internet Address for a Network Interface

On a UNIX system, you assign an IP address to network interface using the ifconfig command. For example, to assign the Internet address 147.38.1.64. to the ln0 network interface, you would enter:

% ifconfig ln0 147.38.1.64

This is usually handled in the UNIX start-up file /etc/rc.boot. For more information, see the UNIX reference entry for ifconfig.

Under VxWorks, use ifAddrSet( ) to assign an IP address to a local interface.


*      
NOTE: Before calling ifAddrSet( ), call ifMaskSet( ) to set the network mask. Otherwise, the network interface assumes the default netmask from the now obsolete class-based system. Such a mask will likely be too large. This is not necessarily a disaster, but the routing table may incorrectly indicate that it has local access to addresses that actually reside on a remote network. For that reason, you will see a lot of ARP errors and transmission failures.

For example, to assign the Internet address 147.38.1.64 to the ln0 interface, enter:

ifAddrSet ("ln0", "147.38.1.64");

The ifAddrSet( ) routine does not let you specify a mask value. Prior to calling ifAddrSet( ), you must set the subnet mask for the interface by calling ifMaskSet( ).

Fixing Misconfigured Interfaces

A call to ifAddrSet( ) automatically creates a local entry in the routing table. Local entries in the routing table identify network interfaces on the local host. If you did not assign the correct address to the interface or if you forgot to call ifMaskSet( ) before calling ifAddrSet( ), you need to delete the local host table entry and then reconfigure the interface. The sequence should be:

mRouteDelete ( "old IP address for network interface", "old mask value for network" ) 
ifMaskSet ( "new IP address for network interface", "new mask value for network" )
ifAddrSet ( "new IP address for network interface", "new mask value for network" )

The IP address for a network interface can be any available IP address within the IP address space of the network to which the interface connects.

Conventions for Assigning Interface Addresses

A free address is any address not already used by another interface or a service, such as broadcasting. By convention, the broadcast address is the local address with all its host bits set. Thus, within 147.38.1.64/0xFFFFFFC0, the conventional broadcast address is 147.38.1.127:

         Mask: 01 00 00 00 = 0  + 26 + 0  + 0  + 0  + 0  + 0  + 0  =  64 = 0x10 
    Broadcast: 01 11 11 11 = 0  + 26 + 25 + 24 + 23 + 22 + 21 + 20 = 127 = 0x7F

An old-style broadcast address would be 147.38.1.64. When VxWorks on a subnet sees a packet addressed to either address style, it treats it as a broadcast packet for the local network. Beyond avoiding the broadcast address, there are no general conventions for assigning IP addresses. However, many organizations have their own conventions. For example, some organizations reserve the network address plus one as the address of the gateway machine.

Manually Starting Additional Network Interfaces at Run-Time

Although you can configure VxWorks at build time to automatically load, start, and configure multiple network interfaces, it is also possible to do it manually at run-time.3


*      
NOTE: You may need to increase the value of the configuration parameter IP_MAX_UNITS.

To start additional network interfaces manually at run-time:

  1. Use ifShow( ) to display information on each currently loaded interface. When adding a new interface, you do not want to conflict with any interface already loaded.
  1. Use muxDevLoad( ) to load the driver for the network interface.
  1. Use muxAddrResFuncAdd( ) to install an address resolution function if necessary. If you loaded an Ethernet driver, you can probably skip this step. Drivers that register as Ethernet drivers automatically use arpresolve( ) to handle address resolution, so you need not call muxAddrResFuncAdd( ).
  1. Use muxDevStart( ) to initialize the network interface.
  1. Call the network layer's fooAttach( ) routine to attach the driver to the service. For example, to attach to the standard VxWorks stack, call ipAttach( ).
  1. Configure the interface. If working with the standard VxWorks stack, this means assigning an IP address and a netmask. Use:
  • ifMaskSet( ) -- assign a netmask to the interface
  • ifAddrSet( ) -- assign an IP address to the interface
  1. Use hostAdd( ) -- to add the interface to the host table.
  1. Check that the interface was loaded and configured correctly:
  • ifShow( ) -- list configuration information for network devices
  • routeShow( ) -- check that the routing table has an entry for the device
  • hostShow( ) -- check that the device was added to the host table


*      
NOTE: For information on the exact inputs expected by the routines named above, see the relevant reference entries.

Consider Figure 4-4. The device acts as a router for tama. When tama pings abuna, the packet goes out 136.12.38.11 to 136.12.38.125, from where it is routed out 136.12.117.10 to 136.12.117.12, the network interface to abuna.

Figure 4-4 :   Using a VxWorks Target as a Router

The routing table on tama, a Solaris box, contains the following entries:

Routing Table: 
  Destination           Gateway           Flags  Ref   Use   Interface
-------------------- -------------------- ----- ----- ------ ---------
136.12.38.0          136.12.38.11          U        3     78  le0
default              136.12.38.125         UG       0     32

To manually add the fei0 interface shown in Figure 4-4, you would access a command shell on the target and enter the following muxDevLoad( ), muxDevStart( ), ipAttach( ), ifAddrSet( ), and hostAdd( ) commands:

[vxKernel] -> fei2=muxDevLoad(0,fei82557EndLoad,"-1:0x00:0x20:0x20:0x00",1,0) 
fei2 = 0x2e2650: value = 0 = 0x0 (PD NAME: vxKernel)
[vxKernel] -> muxDevStart(fei2) 
value = 62 = 0x3e = '>'
[vxKernel] -> ipAttach(0,"fei") 
value = 0 = 0x0
[vxKernel] -> ifMaskSet("fei0",0xffffff00) 
value = 0 = 0x0
[vxKernel] -> ifAddrSet("fei0","136.12.117.10") 
value = 0 = 0x0
[vxKernel] -> hostAdd("woof-route-10","136.12.117.10") 
value = 0 = 0x0
[vxKernel] -> muxShow 
Device: elPci Unit: 0
Description: 3COM 3c90X Fast Etherlink Endhanced Network Driver.
Protocol: Wind Debug Agent      Type: 257       Recv 0x1b87d0   Shutdown 0x0
Protocol: IP 4.4 ARP    Type: 2054      Recv 0x14e480   Shutdown 0x14e780
Protocol: IP 4.4 TCP/IP Type: 2048      Recv 0x14e480   Shutdown 0x14e6a0
Device: fei Unit: 0
Description: Intel 82557 Ethernet Enhanced Network Driver
Protocol: IP 4.4 ARP    Type: 2054      Recv 0x14e480   Shutdown 0x14e780
Protocol: IP 4.4 TCP/IP Type: 2048      Recv 0x14e480   Shutdown 0x14e6a0
value = 0 = 0x0
[vxKernel] -> hostShow 
hostname         inet address       aliases
--------         ------------       -------
localhost        127.0.0.1
t38-125          136.12.38.125
tama             136.12.38.11
woof-route-10    136.12.117.10
value = 0 = 0x0
[vxKernel] -> ifShow 
elPci (unit number 0):
     Flags: (0x8863) UP BROADCAST MULTICAST ARP RUNNING
     Type: ETHERNET_CSMACD
     Internet address: 136.12.38.125
     Broadcast address: 136.12.38.255
     Netmask 0xffff0000 Subnetmask 0xffffff00
     Ethernet address is 00:60:97:d1:5e:ce
     Metric is 0
     Maximum Transfer Unit size is 1500
     0 octets received
     0 octets sent
     1899 packets received
     0 packets sent
     1899 unicast packets received
     0 unicast packets sent
     0 non-unicast packets received
     0 non-unicast packets sent
     0 input discards
     617 input unknown protocols
     0 input errors
     0 output errors
     0 collisions; 0 dropped
lo (unit number 0):
     Flags: (0x8069) UP LOOPBACK MULTICAST ARP RUNNING
     Type: SOFTWARE_LOOPBACK
     Internet address: 127.0.0.1
     Netmask 0xff000000 Subnetmask 0xff000000
     Metric is 0
     Maximum Transfer Unit size is 32768
     0 packets received; 0 packets sent
     0 multicast packets received
     0 multicast packets sent
     0 input errors; 0 output errors
     0 collisions; 0 dropped
fei (unit number 0):
     Flags: (0x8063) UP BROADCAST MULTICAST ARP RUNNING
     Type: ETHERNET_CSMACD
     Internet address: 136.12.117.10
     Broadcast address: 136.12.117.255
     Netmask 0xffff0000 Subnetmask 0xffffff00
     Ethernet address is 00:02:b3:1d:29:a8
     Metric is 0
     Maximum Transfer Unit size is 1500
     0 octets received
     0 octets sent
     0 packets received
     1 packets sent
     0 unicast packets received
     1 unicast packets sent
     0 non-unicast packets received
     0 non-unicast packets sent
     0 input discards
     0 input unknown protocols
     0 input errors
     0 output errors
     0 collisions; 0 dropped
value = 1 = 0x1
[vxKernel] -> mRouteShow 
Destination   Mask      TOS  Gateway        Flags RefCnt Use Interface  Proto
127.0.0.1     0         0    127.0.0.1      5     0      0    lo0       0
136.12.38.0   ffffff00  0    136.12.38.125  101   0      0    elPci0    0
136.12.117.0  ffffff00  0    136.12.117.10  101   0      0    fei0      0
value = 0 = 0x0

4.5.3   Configuring IP Broadcast Addresses

Many physical networks support the notion of broadcasting a packet to all hosts on the network. A special Internet broadcast address is interpreted by the network subsystem to mean "all systems" when specified as the destination address of a datagram message (UDP).

Unfortunately, there is ambiguity concerning which address is the broadcast address. The Internet specification now states that the broadcast address is an Internet address with a host part of all ones (1). However, some older systems use an Internet address with a host part of all zeros as the broadcast address.

Most new network stacks, including VxWorks, accept either address on incoming packets as being a broadcast packet. However, when an application sends a broadcast packet, it must use the correct broadcast address for its system.

VxWorks normally uses a host part of all ones as the broadcast address. Thus a datagram sent to Internet address 150.255.255.255 (0x96FFFFFF) is broadcast to all systems on network 150. However, to allow compatibility with other systems, VxWorks allows the broadcast address to be reassigned for each network interface by calling the routine ifBroadcastSet( ). For more information, see the reference entry for ifBroadcastSet( ).

In addition, VxWorks supports multicasting -- transmission to a subset of hosts on the network. For more information on multicasting, see Using a Datagram (UDP) Socket to Access IP Multicasting, p.129.



4.6    IGMP under VxWorks

According to RFC 2236, an IGMPv2 router listens on IGMP-enabled interfaces for membership reports from networked hosts. Using the membership reports, an IGMP router constructs and maintains per-interface lists of the multicast addresses to which IGMP hosts are listening. To discover when it needs to prune entries from a list, an IGMP router periodically transmits queries to the multicast groups accessible through a given interface. If no replies arrive after a specific time, or if a leave message is processed, the IGMP router removes the group from the list for that interface.

To support its IGMPv2 router implementation, VxWorks relies on tIGMPtask, an IGMP-dedicated task that waits on igmpMsgQ. This message queue collects IGMP timer expiration messages as well as IGMP packet-arrival messages from tNetTask.

In response to a timer expiration message, tIGMPtask either removes a multicast destination from the interface on which it has expired, or the task sends a query. In response to a packet arrival message, tIGMPtask processes the packet. This processing can involve adding an address to an interface (when a new membership report arrives) or deleting an address (when a leave report arrives).

To support the IGMPv2 host implementation, VxWorks does not spawn an independent task. Processing for the IGMPv2 host implementation takes place within the context of tNetTask.

4.6.1   Including IGMPv2

The IGMPv2 host is included by default, but IGMPv2 routing is not. To include the IGMPv2 routing:

  1. Access the project facility and select the VxWorks tab.
  1. Select the IGMPv2 Routing component.
  1. Select the Project -> Add/Include -> Component(s) menu option.

Because IGMPv2 routing depends on kernel multicast routing, the project facility will prompt to add INCLUDE_MCAST_ROUTING (if it is not already included).

  1. Select OK.

The configuration parameters associated with the IGMPv2 host and router are INCLUDE_IGMP and INCLUDE_IGMP_ROUTER.

4.6.2   IGMPv2 APIs

The IGMPv2 router side API consists of the following functions:

  • igmpRouterLibInit( )--initialize the IGMPv2 router
  • igmpRouterLibQuit( )--shut down the IGMPv2 router
  • igmpInterfaceEnable( )--enable IGMPv2 on the specified interface
  • igmpInterfaceDisable( )--disable IGMPv2 on the specified interface
  • igmpNameToPort( )--return a port number (VIF) for the specified interface

For detailed information on the above functions, see the igmpRouterLib reference entries.

The IGMPv2 host side API consists of the function:

  • igmpLibInit( )--initialize the IGMPv2 host

IGMPv2 Host Initialization

If you include the IGMPv2 host in your application, the network initialization code calls igmpLibInit( ). You should have no need to call igmpLibInit( ) explicitly. Because the IGMPv2 host does not launch an independent task or reserve significant system resources, there is no IGMPv2 host termination function.

IGMPv2 Router Initialization and Termination

If you used the project tool to enable IGMPv2 routing, the VxWorks start-up code automatically calls igmpRouterLibInit( ). You should have no need to call igmpRouterLibInit( ) explicitly. If you need to shut down IGMPv2 routing before shutting down the target, you can call igmpRouterLibQuit( ).


*      
NOTE: An IGMP router necessarily requires that the host device support at least two network interfaces on which IGMP routing is enabled. Simply including IGMP is not enough. Neither is enabling it on only one interface.

igmpRouterLibInit( )--initialize the IGMP router

Calling igmpRouterLibInit( ) spawns the IGMP router task and does almost everything necessary to initialize (but not start) the router side of the IGMPv2 implementation. A call to igmpRouterLibInit( ) returns OK if successful, or ERROR otherwise, such as when IGMP has already been started. To actually start IGMP routing, you must enable it on at least two host-local interfaces.

igmpRouterLibQuit( )--shut down the IGMP router

Calling igmpRouterLibQuit( ) ends IGMP routing by closing the IGMP socket, deleting the router task, and generally cleaning up. An igmpRouterLibQuit( ) call returns OK if successful, ERROR otherwise, such as when IGMP has not been started.

IGMPv2 Router Control

Nothing in VxWorks automatically calls igmpInterfaceEnable( ). You must call igmpInterfaceEnable( ) explicitly for each network interface on which you want to enable IGMPv2 routing. Similarly, nothing in VxWorks automatically calls igmpInterfaceDisable( ). If an IGMPv2 routing enabled interface goes down, you must explicitly call igmpInterfaceDisable( ) for that interface.

igmpInterfaceEnable( )--enable IGMP on the specified interface

Calling igmpInterfaceEnable( ) enables IGMP on an interface. A call to igmpInterfaceEnable( ) applies on the router side only. The host side of IGMP does not have a notion of enabled or disabled interfaces. You can call this function for any interface that is capable of receiving multicast packets.

If you use igmpInterfaceEnable( ) to enable more than one interface on a target, IGMP routing occurs. If there are fewer than two enabled interfaces on a target, there is no possibility of multicast routing. This routine is also responsible for populating the appropriate elements of the IGMP control structure.

An igmpInterfaceEnable( ) call returns OK if successful, ERROR otherwise, such as when an interface is not multicast capable.

igmpInterfaceDisable( )--disable IGMP on the specified interface

igmpInterfaceDisable( ) disables IGMP on an interface. If the target supports fewer than two IGMP-enabled interfaces, IGMP on that target stops acting as a router. igmpInterfaceDisable( ) returns OK if successful, ERROR otherwise, such as when the interface was not enabled.

Working with VIFs (Ports) and ifnet Structure Pointers

Virtual Interfaces (VIFs), also known as ports, are implemented as indexes into a system-internal array of ifnet structures. When working with the VxWorks IGMPv2 implementation, it is often more convenient to work with ports than with pointers to ifnet structures.

  • igmpNameToPort( )--return a port number (VIF) for the specified interface


4.7    Manually Editing the Routing Table

When IP needs to transmit a packet, it searches the routing table for an entry that provides the address information it needs to supply when it hands the packet to the link layer for transmission. The information in that table is often entered automatically by a protocol such as RIP, but you can also manually add and delete routing table entries using routeLib functions.

A review of the routeLib API in Table 4-6 shows a redundancy of add and delete functions. This redundancy supports backward compatibility with earlier routeLib and routing table implementations.

Table 4-6 :   routeLib Routines   


Routine
Definition

routeAdd( )
Add a static route (class based).1
routeNetAdd( )
Add a route to a destination that is a network.*
routeDelete( )
Delete a static route (class based).*
mRouteAdd( )
Add mask-distinguished static routes to a destination. (CIDR)
mRouteEntryAdd( )
Add a protocol-specific route. (CIDR)
mRouteEntryDelete( )
Delete a protocol-specific route. (CIDR)
mRouteDelete( )
Delete a static route from the routing table. (CIDR)

1:  These routines have been deprecated. Use the mRoute*( ) equivalents.

Deprecated Functions

The routeAdd( ), routeDelete( ), and routeNetAdd( ) functions date from the class-based VxWorks routing table implementation. Thus, when they add routes, they use the netmasks assumed by the class-based system. As a result, the routes they add are often disastrously inappropriate. These functions still work as documented, but you should consider them obsolete. Do not use them in any new code. You should also upgrade existing code to use mRouteAdd( ) and mRouteDelete( ) to manage the static routes in your table.

4.7.1   Adding Gateways (Routers) to a Network

A gateway or router is a machine that is able to forward packets from one network to another. Thus, a gateway has a physical connection to two or more networks. If the destination of a packet is local to a network attached to the gateway, it can deliver the packet directly. Otherwise, the gateway passes the packet to still another gateway (if one is available). This process, called routing, continues until the packet is delivered or is dropped.

To support routing, VxWorks depends on the routing table to distinguish addresses on the local network from addresses that are accessible through a gateway only. Using a routing protocol, such as RIP, VxWorks is able to discover gateways and add or delete them from its routing table dynamically. In addition to these dynamic routes, routeLib supplies functions you can use to create static gateway routes. You can use these static routes to provide initial routing table information.

Finally, the VxWorks routing table supports the idea of a default gateway. The gateway you assign to 0.0.0.0 serves as the gateway of last resort. If the routing table does not contain any other entry for a destination IP address, it returns the gateway you assign to 0.0.0.0.

Adding a Gateway on Windows

The procedures vary according to your version of Windows and your networking software package. For the details, see the documentation for your system.

Adding a Gateway on UNIX

A UNIX system can be told explicitly about a gateway in one of two ways: by editing /etc/gateways or by using the route command. When the UNIX route daemon routed is started (usually at boot time), it reads a static routing configuration from /etc/gateways. Each line in /etc/gateways specifies a network gateway in the following format:

net destinationAddr gateway gatewayAddr metric n passive

where n is the hop count from the host system to the destination network (the number of gateways between the host and the destination network) and "passive" indicates the entry is to remain in the routing tables.

For example, consider a system on network 150. The following line in /etc/gateways describes a gateway between networks 150 and 161, with an Internet address 150.12.0.1 on network 150. A hop count (metric) of 1 specifies that the gateway is a direct connection between the two networks:

net 161.27.0.0 gateway 150.12.0.1 metric 1 passive

After editing /etc/gateways, you must kill the route daemon and restart it, because it only reads /etc/gateways when it starts. After the route daemon is running, it is not aware of subsequent changes to the file.

Alternatively, you can use the route command to add routing information explicitly:

# route add destination-network gatewayAddr [metric]

For example, the following command configures the gateway in the same way as the previous example, which used the /etc/gateways file:

# route add net 161.27.0.0 150.12.0.1 1

Note, however, that routes added with this manual method are lost the next time the system boots.

You can confirm that a route is in the routing table by using the UNIX command netstat -r.

Adding a Gateway on VxWorks

The routeLib API provides a number of functions that you can use to add routes to the routing table. Some of these functions are now obsolete and included for backward compatibility only. All new development should use the following routines:

mRouteAdd( )

Add mask-distinguished static routes.

mRouteEntryAdd( )

Add a protocol-specific dynamic route.

As input to these functions, you can specify IP addresses using either dotted decimal notation or host names.

Using an IP address, you can specify a single interface on the Internet. Using an IP address and a mask, you can specify a group of IP addresses -- a network.

When creating a host entry in your routing table, you specify the destination as a combination of the following values:

  • an IP address
  • the RTF_HOST flag

When creating a network entry in your routing table, you specify the destination as a combination of the following values:

  • an IP address
  • a network mask

In the current implementation, a VxWorks routing table entry also stores:

  • type of service
  • protocol ID
  • weight (router stack implementation only)

In the router stack, it is possible for the routing table to store multiple distinct entries to the same destination. Only one of these route entries is externally visible to protocols such as IP. This representative route is chosen based on its assigned weight. The entry with the lowest weight value is used as the representative route.

If you add a route using a function that does not let you specify a weight, type of service, or protocol ID, VxWorks assigns appropriate default values for these route characteristics.

Before you edit the table, it is generally a good idea to look at what is already there. To inspect the contents of the routing table, use routeShow( ). If a VxWorks host boots through an Ethernet network interface, a typical routeShow( ) call would display the following:4

-> routeShow() 

ROUTE NET TABLE
destination      gateway           flags  Refcnt  Use       Interface 
----------------------------------------------------------------------
136.12.44.0      136.12.44.165     101    0       0             ei0 
----------------------------------------------------------------------
ROUTE HOST TABLE 
destination      gateway           flags  Refcnt  Use       Interface 
----------------------------------------------------------------------
127.0.0.1        127.0.0.1         5      1       0             lo0 
----------------------------------------------------------------------
value = 77 = 0x4d = 'M'

In the output shown above, the route entry for 136.12.44.0 shows that the flags RTF_CLONING (0x100) and RTF_UP (0x001, signifying that the route is available for use) are set. This route entry is set when the Ethernet network device "ei0" is initialized. This is a network route and the network mask associated with this route is 0xFFFFFF00.

To use mRouteAdd( ) to add a gateway to your routing table, you need to specify a destination, a gateway, a net mask, and a type of service value for the route. The general format of an mRouteAdd( ) call is as follows:

mRouteAdd ( "destination", "gateway", netmask, type-of-service, flags)

To use mRouteAdd( ) to add a default entry to the routing table:

mRouteAdd ("0.0.0.0", "gatewayAddrs", 0, 0, 0);

If the routing table contains a route to 0.0.0.0, the gateway assigned to 0.0.0.0 serves as the default for any destination for which there is no better match. Note also that the netmask is all zeros.


*      
NOTE: Although the boot line gad value (if any) automatically adds an entry to your routing table, the gad is not used as a default gateway (the gateway associated with 0.0.0.0). Instead, the gad gateway has a destination value equal to that of the network (IP address and mask) of the remote network connected to the boot host.

For an example of using mRouteAdd( ) to add a gateway to the routing table, consider the vx2 and vx3 VxWorks targets shown in Figure 4-5. Both have network interfaces that link them to network 161.27.0.0:FFFFFF00. Because vx3 also has an interface on network 150.12.0.0:FFFFFF00, it can serve as a gateway linking networks 150.12.0.0:FFFFFF00 and 161.27.0.0:FFFFFF00.

Figure 4-5 :   Configuring vx3 as a Gateway

On vx2, you can use the following calls to establish vx3 as a gateway to 150:

-> mRouteAdd ("150.12.0.0", "vx3", 0xFFFFFF00, 0, 0 );

or:

-> mRouteAdd ("150.12.0.0", "161.27.0.3", 0xFFFFFF00, 0, 0 );

To confirm that a route is in the routing table, call routeShow( ).5

Unique routing table entries are defined by a destination address, a network mask (or RTF_HOST flag for host routes), and a type of service value -- not simply a destination IP address. For example, consider the network routing table entries created by the calls:

mRouteAdd( "90.0.0.0", "91.0.0.3",   0xFFFFFF00, 0, 0 ); 
mRouteAdd( "90.0.0.0", "91.0.0.254", 0xFFFF0000, 0, 0 );

Both calls specify a destination IP address of 90.0.0.0 but differ in their network mask values. When the routing software searches the routing table, it tries to match a destination IP address with a routing entry based on the stored network address and network mask.

The first mRouteAdd( ) call creates a routing table entry that matches with destination IP addresses 90.0.0.0 through 90.0.0.255. The second mRouteAdd( ) call uses a shorter mask and so matches more entries, 90.0.0.0 through 90.0.255.255. This overlaps the range of the first mRouteAdd( ) call. However, because routing software prefers matches with longer masks, searches for IP addresses within the 90.0.0.0 to 90.0.0.255 range match the 91.0.0.3 interface first.

Thus, these two entries divide the 90.0.0.0:0xFFFFFF00 traffic between 91.0.0.3 and 91.0.0.254. Packets destined to addresses in the 90.0.0.0 through 90.0.0.255 range go to 91.0.0.3. Packets destined to addresses in the 90.0.1.0 through 90.0.255.255 range go to 91.0.0.254.

If you were to delete the 91.0.0.3 route, all its traffic would go out through 91.0.0.254. However, deleting the 91.0.0.254 route would not result in all its traffic going to 91.0.0.3. Only addresses matching 90.0.0.0 within the 0xFFFFFF00 mask can map to the 91.0.0.3 entry. Thus, addresses in the 90.0.1.0 through 90.0.255.255 range are directed to the default gateway (if any) or are discarded as unreachable.

To delete a static routing table entry, use mRouteDelete( ). For example, to delete an entry with a destination of 161.27.0.51 with a mask of 0xFFFFFF00, a type of service value of 0, and a flags value of RTF_HOST, you would call mRouteDelete( ) as follows:

mRouteDelete( "161.27.0.51", 0xFFFFFF00, 0, RTF_HOST );

The destination IP address as well as the values for network mask, type of service, and flags that you specify in the parameters must match the values for the table entry. Otherwise, the mRouteDelete( ) call fails.

Adding and Managing Dynamic Routes Manually

Although dynamic routes are normally added and deleted by a protocol, it is possible to use mRouteEntryAdd( ) to impersonate a protocol when adding a route.



4.8    Proxy ARP for Transparent Subnets

The IP routing discussed previously relies on the assignment of a separate network number to each physical network. This restriction prevents communication between hosts on different physical networks unless each host's routing table contains an entry for the appropriate network number.

Proxy ARP provides a method for assigning the same logical network number to different physical networks without altering the routing table entries for existing hosts. This feature is particularly valuable when creating a shared-memory network on the back plane (see 3.3 The Shared-Memory Backplane Network Driver, p.21).

RFCs Relevant to Proxy ARP

Proxy ARP is described in Request For Comments (RFC) 925 "Multi LAN Address Resolution," and an implementation is discussed in RFC 1027 "Using ARP to Implement Transparent Subnet Gateways." The ARP protocol is described in RFC 826 "Ethernet Address Resolution Protocol: Or converting network protocol addresses to 48-bit Ethernet address for transmission on Ethernet hardware." The implementation of Proxy ARP for VxWorks is based on RFC 925. However, it is a limited subset of that proposal.

4.8.1   Proxy ARP Protocol Overview

Proxy ARP uses the address resolution protocol (ARP) to provide transparent data transfer across physical network boundaries. The IP transmission process uses ARP to find the required link-level address information for a specific destination address. Ordinarily, ARP messages are restricted to a single physical network. Running a proxy ARP server on a multi-homed host lets ARP requests from hosts on physically separate networks to succeed. From the perspective of individual hosts, the result completely disguises the physical separation of the networks.

A Single Proxy ARP Instance Cannot Serve Both as a Server and a Client

A single proxy ARP instance can act as a server or as a client but not both. Thus, configurations such as that in Figure 4-6 are not supported.

Figure 4-6 :   Multi-Tier Configurations CANNOT Be Used with Proxy ARP

This restriction provides built-in protection against the accidental creation of network circles, broadcast storms, and eternally forwarded ARP requests. In addition, the restriction helps avoid routing table scalability issues that could arise because the proxy ARP server edits the local routing table to add one host-specific route per host on the proxy network.

This is not to say that a VxWorks target running VxWorks cannot be the node linking multiple proxy networks. For example, the configuration shown in Figure 4-7 is possible.

Two Instances of Proxy ARP on a Single Target Allow Chaining

In Figure 4-6, the vx3 target is labeled as a Proxy Server. As a simple proxy server, it cannot fulfill all its functions. The vx3 target must function both as a proxy server for vx5 and vx6 and as a proxy client to vx1. To do this, vx3 must run two instances of proxy ARP; you can configure one instance to function as a server for vx5. The other instance should be configured as a proxy client to vx1. Still, use such configurations with extreme caution. Used casually, you risk accidentally creating network circles, broadcast storms, and eternally forwarded ARP requests.

4.8.2   Routing and the Proxy ARP Server

Although a response to an ARP request is necessary for a host to begin an IP data transfer, it is not enough to actually accomplish the data transfer. The data can reach the final destination only if the proxy ARP server added appropriate entries to the local routing table. Setting up a network interface ordinarily creates a single route entry that serves for all hosts on the network attached to the network interface. By default, the proxy ARP server automatically creates host-specific routing table entries for proxy clients.

4.8.3   Proxy ARP and Broadcast Datagrams

When you broadcast an IP packet on a network, all nodes on that network are expected to receive the packet. To make the proxy network truly appear part of the main network, the proxy ARP server can forward broadcasts to and from the proxy network. Thus, if a broadcast datagram originates on a proxy network (and the port is enabled), the server forwards the broadcast to the main network, and to all other proxy networks that have the same main network.

For example, in Figure 4-7, if a broadcast originates on sm1, proxy ARP may forward the broadcast to ln0 and sm0.

Figure 4-7 :   Broadcast Datagram Forwarding

If the broadcast originates on the main network (and the port is enabled), the server forwards the broadcast to all appropriate proxy networks. For example, in Figure 4-7, a broadcast from ln0 is forwarded to both sm0 and sm1. To prevent forwarding loops, broadcasts forwarded onto proxy networks are given a time-to-live value of 1.

However, most broadcasts are not of interest to any host outside the true physical network. To give you selective control over which broadcasts are forwarded and which are not, you can configure the proxy ARP server to forward the broadcasts of specific destination UDP ports only. To enable proxy ARP broadcast forwarding on a UDP port, call proxyPortFwdOn( ). To disable forwarding for a port, call proxyPortFwdOff( ). By default, forwarding is disabled on all ports.

4.8.4   Proxy ARP Configuration

To include proxy ARP in VxWorks, reconfigure the image and rebuild it to include the proxy server. The relevant configuration parameter is INCLUDE_PROXY_SERVER.

On the target with processor zero (the shared-memory network master), the proxy ARP server assumes the main network is on the other side of the default local network interface. This interface uses the IP address:mask value specified in the ead boot parameter, inet on ethernet (e).

For a shared memory configuration, the address of the interface between the proxy ARP server and the backplane depends on whether you have set the INCLUDE_PROXY_DEFAULT_ADDR configuration parameter. If this configuration parameter is not set, the interface to the back plane gets its address from the bad boot parameter, inet on backplane (b). If INCLUDE_PROXY_DEFAULT_ADDR is set, the target hosting the proxy ARP server generates the address for the back plane interface by adding one to the ead boot parameter.

For a shared memory configuration, how you assign an address to each host on the proxy network depends on whether you have configured VxWorks with the configuration parameter INCLUDE_SM_SEQ_ADDR set.

If INCLUDE_SM_SEQ_ADDR is not set, each slave target uses its ead value as the IP address for its interface to shared memory back plane.

If INCLUDE_SM_SEQ_ADDR is set, the slave targets generate their IP address by adding their CPU number (1, 2, 3, and so on) to the IP address of the interface between the proxy ARP master and the shared memory back plane. For example, if the proxy ARP server has a backplane address of 150.12.0.4, the first slave is 150.12.0.5, the second slave 150.12.0.6, and so on.


*      
NOTE: When using proxy ARP, it is no longer necessary to specify the gateway. Each target on the shared-memory network (except the proxy server) can register itself as a proxy client by specifying the proxy ARP flag, 0x100, in the boot flags instead of specifying the gateway.

Proxy ARP not Limited To a Shared Memory Network

Although this document describes the use of Proxy ARP over a shared memory network, the current Proxy ARP implementation is no longer limited to the shared memory network.

Proxy ARP with Shared Memory and IP Routing

Even if you are using the same board for the master and the slaves, the master and slaves need separate BSP directories because they have different configurations. For more information on configuration, see the Tornado User's Guide: Customizing VxWorks AE.

Proxy ARP and Shared Memory Configuration Parameters:
  1. PING client (configuration parameter: INCLUDE_PING)
  1. Shared memory network initialization (INCLUDE_SM_NET)
  1. Proxy ARP server (INCLUDE_PROXY_SERVER)
  1. Auto address setup (INCLUDE_SM_SEQ_ADDR)--required for default addressing of proxy clients, but required in both client and server
  1. Default address for back plane--required only for default addressing
Parameters for proxy ARP sever:
INCLUDE_PROXY_SERVER
SM_OFF_BOARD=FALSE

Parameters for proxy client:
INCLUDE_PROXY_CLIENT
SM_OFF_BOARD=TRUE

Setting Up Boot Parameters and Booting

See 3.3 The Shared-Memory Backplane Network Driver, p.21 for information on booting shared memory networks. After booting vx1 (the master, Figure 4-8), use smNetShow( ) to find the shared memory anchor, which will be used with the slave boot device (for vx2, vx3, and vx4). You will need to run sysLocalToBusAddr( ) on the master and sysBusToLocalAddr( ) on each type of target to get the correct bus address for the anchor.

Figure 4-8 :   Multi-Tier Example Using Proxy ARP and IP Routing

Creating Network Connections

From vx1 (the master):

Use mRouteAdd( ) to tell the master (the proxy server) about the IP routing network:

-> mRouteAdd ("161.27.0.0", "150.12.0.6", 0xffff0000, 0, 0) 

value = 0 = 0x0
From vx3:

Since vx3 boots from the shared memory network, it needs to have its connection to the IP routing network brought up explicitly. The following example shows how to do this for vx3 in Figure 4-8:

-> usrNetIfAttach ("ln", "161.27.0.1") 
Attaching network interface ln0...done.
value = 0 = 0x0
-> usrNetIfConfig ("ln", "161.27.0.1", "t0-1", 0xffff0000)
value = 0 = 0x


*      
NOTE: Substitute the appropriate network boot device for "ln". The correct boot device is given in the output from a boot prompt ? command.

Diagnosing Shared Memory Booting Problems

See Troubleshooting, p.38 for information on debugging the shared memory network.

Diagnosing Routing Problems

The following routines can be useful in locating the source of routing problems:

ping( )

smNetShow( )

arpResolve( )

arpShow( )

arptabShow( )

routeShow( )

ifShow( )

proxyNetShow( )

proxyPortShow( )

Routing Configuration for Multi-Homed Proxy Clients

If a proxy client also has an interface to the main network, some additional configuration is required for optimal communications. The proxy client's routing tables must have network-specific routes with netmask 0xFFFFFFFF for nodes on the proxy network, and a network-specific route for the main network. Otherwise, traffic travels an extra unnecessary hop through the proxy server.

In the example shown in Figure 4-9, vx1 is the proxy server and vx2 is a proxy client with an interface on the main network. You must configure vx2 to store network-specific routes to each of the other proxy clients (vx4 and vx5) and the main network. In addition, these routes must use a mask of 0xFFFFFFFF. Otherwise, any traffic from vx2 to vx4 (or vx5) unnecessarily travels over the main network through the proxy server (vx1).

Figure 4-9 :   Routing Example

The following is an example of vx2's routing table. The routing table is manipulated using mRouteAdd( ) and mRouteDelete( ). For more information, see the reference entry for routeLib.

Destination                                                 Gateway 
150.12.0.4 (network with netmask   0xffffffff)            150.12.0.6
150.12.0.5 (network with netmask   0xffffffff)            150.12.0.6
150.12.0.0 (network)                                      150.12.0.7

Broadcasts Configuration for Multi-Homed Proxy Clients

A proxy client that also has an interface connected to the main network must disable broadcast packets from the proxy interface. Otherwise, it receives duplicate copies of broadcast datagrams (one from Ethernet and one from the shared-memory network).



4.9    Using Unnumbered Interfaces

Typically, each IP host or router needs its own IP address. However, when an interface is the local end of a point-to-point link, it is possible for that interface to borrow the IP address of a local interface that joins the router to a larger network. This scheme, called unnumbered interfaces, is described in section 2.2.7 of RFC 1812. VxWorks provides support for unnumbered interfaces using ifUnnumberedSet( ), an ifLib routine.

As input, ifUnnumberedSet( ) expects the name of the local unnumbered interface and the router IDs that identify the ends of the point-to-point link. Both router IDs are "borrowed" IP addresses. For example, Figure 4-10 shows 147.38.11.150 serving as the IP address of both fei0 and fei1 on Vx A. Similarly, 138.12.12.12 serves as the IP address for both fei0 and fei1 on Vx B.

Figure 4-10 :   Unnumbered Interface Setup

To use unnumbered interfaces to connect two VxWorks hosts:

  1. Call ipAttach( ) to assign a name to the local unnumbered interface on a point-to-point link.
  1. Call ifUnnumberedSet( ) to assign a borrowed IP address to source interface and associate that interface with a destination interface. For example, on Vx A in Figure 4-10, the system manager calls:
ifUnnumberedSet( "fei1", "138.12.12.12", "136.12.38.150" );

This reuses 136.12.38.150 for the local interface and tells Vx A that 138.12.12.12 is the interface on the other side of the point-to-point link.

Similarly on Vx B, the system manager calls:

ifUnnumberedSet( "fei1", "138.12.12.12", "136.12.38.150" );
  1. Use mRouteAdd( ) to create appropriate network routes on all machines participating in the system. For example, on Vx A in Figure 4-10, the system manager calls:
mRouteAdd( "138.12.0.0", "138.12.12.12", 0, 0, 0 );

This tells Vx A that it can reach network 138.12.0.0 by forwarding to the router at 138.12.12.12. The previous ifUnnumberedSet( ) call told it that it could reach 138.12.12.12 by broadcasting on fei1.



4.10    Network Byte Order

A single network can contain CPUs using different internal architectures. The numeric representation schemes of these architectures can differ: some use big-endian numbers, and some use little-endian numbers. To permit exchanging numeric data over a network, some overall convention is necessary. Network byte order is the convention that governs exchange of numeric data related to the network itself, such as socket addresses or shared-semaphore IDs. Numbers in network byte order are big-endian.

The routines in Table 4-7 convert longs and shorts between host and network byte order. To minimize overhead, macro implementations (which have no effect on architectures where no conversion is needed) are also available, in h/netinet/in.h.

Table 4-7 :   Network Address Conversion Macros   


Macro
Description

htonl
Convert a long from host to network byte ordering.
htons
Convert a short from host to network byte ordering.
ntohl
Convert a long from network to host byte ordering.
ntohs
Convert a short from network to host byte ordering.

To avoid macro-expansion side effects, do not apply these macros directly to an expression. The following increments pBuf four times (on little-endian architectures):

pBufHostLong = ntohl (*pBuf++);     /* UNSAFE */

It is safer to increment separately from the macro call. The following increments pBuf only once, whether the architecture is big- or little-endian:

pBufHostLong = ntohl (*pBuf); 
pBuf++;


4.11    Assigning Host Names to IP Addresses

On a VxWorks host, you can use the functions of the ifLib library to associate Internet addresses with network interfaces and addresses. For a listing of these configuration functions, see the reference entry for ifLib. To add host names, use the functions supplied in hostLib. For a listing of these configuration functions, see the reference entry for hostLib.

Associating Internet Addresses with Host Names

The underlying Internet protocol uses the 32-bit Internet addresses of systems on the network. People, however, prefer to use system names that are more meaningful to them. Thus VxWorks and most host development systems maintain their own maps between system names and Internet addresses.

On UNIX systems, /etc/hosts contains the mapping between system names and Internet addresses. Each line consists of an Internet address and the assigned name(s) for that address:

150.12.0.1 vx1

There must be an entry in this file for each UNIX system and for each VxWorks host on the network. For more information on /etc/hosts, see your UNIX system reference entry hosts(5).

On a VxWorks host, call hostAdd( ) to associate system names with Internet addresses. Make one call to hostAdd( ) for each system with which the VxWorks host communicates. For example:

hostAdd ("vx1", "150.12.0.1");


*      
NOTE: In addition to hostAdd( ), VxWorks also includes DNS. You can use DNS to create and automatically maintain host-name/address associations for a VxWorks host. See 9. DNS and SNTP.

To associate more than one name with an Internet address, hostAdd( ) can be called several times with different host names and the same Internet address. The routine hostShow( ) displays the current system name and Internet address associations. In the following example, 150.12.0.1 is accessible using the names host, myHost, and widget:

-> hostShow  
value = 0 = 0x0

The standard output device displays the following output:

hostname         inet address     aliases 
--------          -----------     -------
localhost        127.0.0.1
host             150.12.0.1

-> hostAdd "myHost", "150.12.0.1"
value = 0 = 0x0
-> hostAdd "widget", "150.12.0.1"
value = 0 = 0x0
-> hostShow
value = 0 = 0x0

Now standard output displays the following:6

hostname         inet address     aliases 
--------          -----------     -------
localhost        127.0.0.1
vx1             150.12.0.1       myHost widget
value = 0 = 0x0

The VxWorks startup routine, usrNetInit( ) in usrNetwork.c, automatically adds the name of the host from which the target booted, using the host name specified in the boot parameters.


1:  If your applications open more than 50 sockets, increase the default NUM_FILES value (in the I/O system component), which currently defaults to fifty.

2:  Some BSPs and drivers may impose their own limitations on the number of interfaces and units they support.

3:  For information on configuring VxWorks to automatically start multiple network interfaces, see Adding an END to VxWorks, p.191, and Adding an NPT Driver to VxWorks, p.206.

4:  This assumes that VxWorks is configured to include network show routines. The relevant configuration parameter is INCLUDE_NET_SHOW.

5:  This function is not built into the Tornado shell. The relevant configuration parameter is INCLUDE_NET_SHOW.

6:  Internally, hostShow( ) uses the resolver library to access DNS to get the information it needs to respond to a query.