Professional Documents
Culture Documents
WR Net Stack Vxworks 6 Programmers Guide 3.1 PDF
WR Net Stack Vxworks 6 Programmers Guide 3.1 PDF
Wind River ®
Network Stack
for VxWorks 6 ®
P R O G R A M M E R ’S G U I D E
3.1
Copyright © 2006 Wind River Systems, Inc.
All rights reserved. No part of this publication may be reproduced or transmitted in any
form or by any means without the prior written permission of Wind River Systems, Inc.
Wind River, the Wind River logo, Tornado, and VxWorks are registered trademarks of
Wind River Systems, Inc. Any third-party trademarks referenced are the property of their
respective owners. For further information regarding Wind River trademarks, please see:
http://www.windriver.com/company/terms/trademark.html
This product may include software licensed to Wind River by third parties. Relevant
notices (if any) are provided in your product installation at the following location:
installDir/product_name/3rd_party_licensor_notice.pdf.
Corporate Headquarters
Wind River Systems, Inc.
500 Wind River Way
Alameda, CA 94501-1153
U.S.A.
For additional contact information, please visit the Wind River URL:
http://www.windriver.com
For information on how to contact Customer Support, please visit the following URL:
http://www.windriver.com/support
28 Apr 06
Part #: DOC-15751-ZD-00
Contents
1 Overview ............................................................................................... 1
iii
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
iv
Contents
v
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
vi
Contents
7.5 Using SNMP with Virtual TCP/IP Stack Instances ......................................... 122
vii
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
viii
Contents
ix
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
9.11 Changing the Default Login for FTP, FTPv6, and Telnet ................................ 173
9.11.1 Changing the Default Login Before You Build VxWorks ................... 174
Obtaining an Encrypted Password ........................................................ 174
Changing the user name and password in configAll.h ...................... 174
Changing the user name and password in Workbench ...................... 175
9.11.2 Changing the Default Login After You Build VxWorks ..................... 175
x
Contents
xi
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
xii
Contents
xiii
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
xiv
Contents
xv
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
17.4 Writing the Initialization Routine for a Fast Path Application ..................... 357
17.4.1 Allocating Resources for the fastPathLib Interface ............................. 357
17.4.2 Registering a Fast Path Application with fastPathLib ........................ 359
xvi
Contents
18.4 Adding and Deleting Virtual Interfaces for Multicast Routing .................... 383
18.7 Configuring and Using MLD Hosts and Routers ........................................... 394
18.7.1 Compiling the Network Stack for MLD ............................................... 394
18.7.2 Configuring VxWorks for MLD ............................................................. 395
MLD ........................................................................................................... 395
IPv6 MLDv2 Proxy Router ...................................................................... 396
18.7.3 Build-Time Configuration Considerations ........................................... 397
18.7.4 Run-time Configuration Considerations .............................................. 397
xvii
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
19.6 Rules and Rule Groups for Assigning Packets to Queues ............................. 419
19.8 Sample Code for Pentium Processor Machine-Clock Routines .................... 428
xviii
Contents
xix
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
xx
Contents
xxi
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
xxii
Contents
xxiii
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
xxiv
Contents
xxv
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
xxvi
1
Overview
1.1 Introduction 1
1.2 Component Overview 4
1.3 About this Manual 6
1.1 Introduction
The Wind River Network Stack is a dual IPv4/IPv6 network stack based on a port
of the KAME/FreeBSD TCP/IP release and some applications ported from
previous versions of the Wind River Network Stack. It contains support for the
UDP and TCP transport layer protocols, DHCPv4 and DHCPv6 host configuration
protocols, standard network application protocols such as Telnet and FTP, and fast
IP forwarding.
While the Wind River General Purpose Platform supports the standard TCP/IP
and application protocols, some features are available only with the Wind River
Platforms builds of the network stack. This includes Platform for Industrial
Devices, Platform for Network Equipment, Platform for Consumer Devices, and
Platform for Automotive Devices. These additional features, listed below and
noted in the documentation, are not available with the Wind River General
Purpose Platform, VxWorks Edition:
1
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
■
Stream Control Transmission Protocol (SCTP)
■
Multi-Instance Virtual TCP/IP Stacks
■
Internet Group Management Protocol (IGMP)
■
IGMPv2 Router
■
IGMPv3 Host
■
ALTQ (ALTernate Queueing) Quality of Service (QoS)
■
Multicast Listener Discovery (MLD) and MLDv2
■ Support for 802-Style VLAN (802.1Q VLAN Tag)
If you have purchased one of the Wind River Platforms that supports these
features, Wind River Platforms Getting Started includes instructions on how to build
the network stack code to activate these features. Note that full routing is now
supported in all stacks.
NOTE: RIP is supported even in host stacks. Therefore, if you build the code as a
host stack, the stack includes RIP implementation and is capable of forwarding
packets. RIP and RIPng are included to support a machine that uses an internal
IP-based network to communicate among multiple internal devices.
1.1.1 Installation
Underlying all variants of the Wind River Network Stack is one fully integrated
code base. Depending on how you build the code (and configure licensing), you
can activate or deactivate different features. Some components shipped with your
Platform are provided as source code, which you must compile before you can use
the component in a VxWorks image project. In some cases, changing configuration
options requires that you recompile the component source. If you have purchased
a Wind River Platform, you need to recompile the network stack code to activate
the Platform-specific features. For detailed component source compile instructions
and other information on how to build the network stack, see the Wind River
Platforms Getting Started.
The build process referred to here is not the VxWorks image build. That build
depends upon a set of pre-compiled network stack object modules. The build
2
1 Overview
1.1 Introduction
referred to here is the building of the network stack code in order to create that set
1
of object modules. Depending on how you build the network stack code, you can
expand the module set to include additional non-default functionality. You can
also build the network stack code to change the behavior of certain modules
already in the default set. For example, it is possible to rebuild the modules to
exclude Wind River System Viewer instrumentation.
The latest information on this release can be found in the release notes for your
Platform. Release notes are shipped with your Platform product and are also
available from the Wind River Online Support site:
http://www.windriver.com/support/
In addition, this site includes links to topics such as known problems, fixed
problems, documentation, and patches.
NOTE: Wind River strongly recommends that you visit the Online Support
website before installing or using this product. The Online Support website may
include important software patches or other critical information regarding this
release.
For information on accessing the Wind River Online Support site, see the Customer
Services section of your Platform getting started guide.
The focus of this manual is the configuration of the Wind River Network Stack.
Although this manual includes some networking background information, it is
beyond the scope of this manual to provide a thorough description of socket usage,
routing, protocol implementation, writing a network interface driver, and
interpreting statistics returned by routines. For information of that sort, consider
the following sources:
■
The Design and Implementation of the 4.4 BSD Operating System, by Marshall Kirk
McKusick, Keith Bostic, Michael J. Kraals, John S. Quarterman
■
TCP/IP Illustrated, Vol. 1, by Richard Stevens
■
TCP/IP Illustrated, Vol. 2, by Gary Wright and Richard Stevens
3
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
■
Internetworking with TCP/IP Volume III, by Douglas Comer and David Stevens.
■
UNIX Network Programming, by Richard Stevens
(for information on socket programming)
■
Implementing IPv6, by Mark A. Miller, P.E.
In addition, you will want to visit The IPv6 Forum Web site:
http://www.ipv6forum.com
4
1 Overview
1.2 Component Overview
transmit this message, but the message itself is processed by the TCP/IP control
1
plane functionality. The control plane functionality of the TCP/IP stack allows the
protocols to detect transmission failures and monitor connectivity. Control plane
functionality is provided by the ICMP protocol.
SNMP
To support the Simple Network Management Protocol (SNMP), the Wind River
Network Stack includes standard MIBs for IPv4, UDP, TCP, ICMP, and the
network interfaces. The source code was instrumented for early versions of the
IPv6 MIBs that are now obsolete. This instrumentation is unsupported.
Also included is m2IfLib and m2IfMgtLib. These libraries provide MIB 2 services
for the interface group. Thus, they provide routines to initialize the group, access
the group scalar variables, read the table interfaces and change the state of the
interfaces. The externally callable routines associated with this configuration
component are described in the m2IfLib reference entries.
For more information, see 7.5 Using SNMP with Virtual TCP/IP Stack Instances,
p.122.
This stack includes libraries that provide the instrumentation code needed to
support the MIBs associated with RFC 2452 (TCP), RFC 2454 (UDP), RFC 2465
(IPv6), and RFC 2466 (ICMPv6). The IETF is revising these RFCs. These revisions
will make the current instrumentation code obsolete. For this reason, the
m2Ipv6NameLib libraries are not supported for this stack. Similarly, the MIB for
MLD is unsupported.
5
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
For more information, see 7. Enabling Virtual TCP/IP Stacks and 21. Integrating a
New Network Interface Driver.
1. Overview
This chapter provides an overview of the Wind River Network Stack, including a
list of the features that are unique to the Wind River Platforms builds of the
network stack. It also summarizes the topic of each chapter of the programming
guide (this manual).
This chapter describes how to include the minimum number of network stack
components needed to create a ping-responsive network stack.
6
1 Overview
1.3 About this Manual
This chapter lists the network stack configuration variables whose values can be
changed at run-time. Default values for these variables are set at build time, and
not all of these variables can be meaningfully reset at run-time. For example,
configuration parameters that determine the size of a memory pool cannot be
meaningfully reset at run-time. Parameters that control behaviors, such as
enabling IP redirects, can be reset at run-time.
6. Using SCTP
This chapter describes how to configure and use the Wind River implementation
of SCTP, a transport layer protocol that provides services not available from either
TCP or UDP. This chapter assumes that you are familiar with the SCTP protocol as
described in RFC 2960 and its companion documents.
NOTE: SCTP is only available in the Wind River Platforms builds of the network
stack.
This chapter describes how to configure and use virtual TCP/IP stacks with IPv6.
Virtual stacks let you run two TCP/IP stack instances on a single VxWorks target.
Each stack instance is data-independent and is designed to guarantee privacy at
the network layer.
NOTE: The virtual TCP/IP stacks feature is only available in the Wind River
Platforms builds of the network stack.
7
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
This chapter covers the Network File Service (NFS), used access to file systems on
remote networked hosts. The Wind River implementation currently supports
Versions 2 and 3.
The Wind River Network Stack implements standard and remote network
application protocols that handle domain name lookup (DNS), file transfer (FTP,
TFTP), remote login (RLOGIN), remote execution (RSH), remote procedure call
(RPC), telnet, and so on. This chapter describes how to include these protocols in
a VxWorks image and configure them for use with the network stack.
This chapter focuses on network applications and services that have been ported
to RTPs. Also included are some recommendations on how to port your network
application to operate within an RTP.
This chapter describes how to use the standard BSD socket interface in the Internet
domain. The Wind River Network Stack supports a standard BSD socket interface
to TCP and UDP. Using these sockets, you can:
■ Communicate with other processes.
■ Access the IP multicasting functionality.
Also described in this chapter are local domain sockets (AF_LOCAL sockets) based
on the COMP protocol, which provides message-oriented reliable communication
among processes on the same node.
This chapter focuses on how to write applications using UDP (datagram) and TCP
(stream) sockets.
8
1 Overview
1.3 About this Manual
This chapter describes how to use a routing socket to make and monitor changes
in the content of the route table.
This chapter tells you how to select a route table storage mechanism. It also
describes some of the protocols used to maintain the contents of the route table.
This chapter includes discussions of RIP, RIPng, ARP, NDP, and ICMPv4.
This chapter describes how to use a fast IP-forwarding mechanism, also known as
a fast path application, which intercepts packets before they are passed up to IP.
This chapter documents IGMP and MLD, which are used to support multicasting
in IPv4 and IPv6 domains, respectively. The Wind River General Purpose
Platform, VxWorks Edition, supports the IGMPv2 host and the MLDv1 host.
NOTE: The IGMPv2 router, IGMPv3 host, and the MLDv2 host and router are
available only in the Wind River Platforms builds of the network stack. See Features
Unique to Wind River Platforms, p.1.
19. ALTQ
In addition to drivers supplied for the physical network interfaces, the Wind River
Network Stack also includes drivers for the creation of stf, gif, and BPF devices.
This chapter provides instruction and some background information on how to
9
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
create and configure device instances associated with the network stack. This
includes:
■
network interface instances for communication with the local network
■
gif pseudo devices for general purpose tunneling through the IPv4 Internet
■
stf pseudo devices for “6 to 4” tunneling through the IPv4 Internet
■
BSD (Berkeley) Packet Filter (BPF) devices for filtering incoming packets
The Wind River Network Stack supports all network interface drivers currently
compatible with VxWorks 5.5. Although the Wind River Network Stack is based
on the KAME/FreeBSD TCP/IP release, the stack does not support drivers based
on the BSD 4.3 or 4.4 models. If you must use such a driver, you must port the
driver to the MUX interface model, as described in this chapter.
This chapter describes the implementation of 802.1Q VLAN tagging for VxWorks
and tells you how to configure VxWorks to include this feature.
NOTE: The 802.1Q VLAN tagging feature is only available in the Wind River
Platforms builds of the network stack.
When working with the examples in this manual, you may find it convenient to cut
and paste example text into source code or to a command line. To avoid disrupting
the use of IPv4 or IPv6 addresses that are or might be put into service, the examples
in this manual restrict themselves to the following address spaces:
■
10/24 - one part of the private address space
■
127.0/8 - loopback addresses
■
169.254/16 - link local addresses
■
172.16/12 - another part of the private address space
10
1 Overview
1.3 About this Manual
■
192.0.2/24 - test and documentation addresses
1
■
192.168/16 - another part of the private address space
■
2001:DB8::/32 - test and documentation addresses (RFC 2849)
■
FE80::/10 - link local addresses
11
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
12
2
Configuring VxWorks
for the Network Stack
2.1 Introduction 13
2.2 Adding Network Stack Configuration Components 14
2.3 Configuring the Network Daemon Task 21
2.4 Testing Connectivity from the Target 23
2.1 Introduction
You can configure components for VxWorks in either of two ways. You can use the
Wind River Workbench to include components into your VxWorks image or you
can use the vxprj command-line tool to configure your project. Both facilities
handle dependencies for you.
To add a component from Workbench, you can use the Find tool to navigate to the
component in the configuration editor. For instructions on using Workbench to
include configuration components, see the Wind River Workbench User's Guide. For
instructions on adding configuration components using the vxprj command-line
tool, see the VxWorks Command-Line Tools User's Guide.
13
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
To build a minimal network stack, include the components in this list. Both
Workbench and vxprj will automatically include the component dependencies. All
components listed below and their required components are needed to build a
minimal network stack. If a component contains configuration parameters, you
may need or want to modify them.
14
2 Configuring VxWorks for the Network Stack
2.2 Adding Network Stack Configuration Components
This section includes components required to build both the IPv4 or an IPv6
network stack. To build only an IPv4 stack, you can optionally omit the IPv6
components. 2
INCLUDE_BSD_SOCKET
This component is needed to support standard BSD Internet Domain sockets and
is documented in BSD Socket Support, p.236 with its associated configuration
parameters. This component requires the following components:
■ INCLUDE_SOCKLIB, documented in Socket API, p.235.
■ INCLUDE_NET_POOL, documented in Network Stack Memory Pool
Configuration, p.28 with its associated configuration parameters.
The INCLUDE_NET_POOL component is automatically included with the
INCLUDE_BSD_SOCKET component. INCLUDE_NET_POOL itself requires and
pulls in the following essential configuration components:
■ INCLUDE_NETBUFLIB
■ INCLUDE_NETBUFPOOL
These components are also fully documented in Network Stack Memory Pool
Configuration, p.28.
INCLUDE_ETHERNET
INCLUDE_GTF_TIMER_START
This component automatically starts the General Timer Facility. This component
requires the following component:
■
INCLUDE_GTF, which pulls in modules that support the General Timer
Facility. INCLUDE_GTF has no configuration parameters.
15
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
INCLUDE_INETLIB
This component pulls in inetLib and other modules that implement routines for
manipulating Internet addresses, including the UNIX BSD inet_ routines. It
includes routines for converting between character addresses in Internet standard
dotted decimal notation and integer addresses, routines for extracting the network
and host portions out of an Internet address, and routines for constructing Internet
addresses given the network and host address parts.
There are no component dependencies or configuration parameters associated
with this component. For information on the externally callable functions
associated with this component, see the inetLib reference entry.
INCLUDE_ICMPV4
This component pulls in icmpLib and other modules that implement ICMP for
IPv4 and is documented in ICMP v4, p.83. This component requires the following
component:
■ INCLUDE_IPV4, documented in IP v4, p.78.
INCLUDE_ICMPV6
This component pulls in icmpv6Lib and other modules that implement ICMPv6.
This component is documented in ICMP v6, p.89. The INCLUDE_ICMPV6
component requires the following component:
■ INCLUDE_IPV6, documented in IP v6, p.86.
The INCLUDE_ICMPV6 component is only required for an IPv6 stack.
INCLUDE_IPATTACH
This component configures the IPv4 stack to automatically attach to the network
interface specified in the boot line parameters. This component is documented in
Attach END to IPv4, p.85. The INCLUDE_IPATTACH component requires the
following component:
■
INCLUDE_IPV4, documented in IP v4, p.78.
INCLUDE_IP6ATTACH
This component configures the IPv6 stack to automatically attach to the network
interface specified in the boot line parameters. This component and its associated
16
2 Configuring VxWorks for the Network Stack
2.2 Adding Network Stack Configuration Components
These components are essential to a minimal network stack build, however, you
do not need to explicitly include them; they are automatically pulled in as
dependencies of several essential network stack components. These components
also require the following essential configuration components that are also
automatically included:
■ INCLUDE_LOOPBACK
■
INCLUDE_ND (IPv6 only)
■
INCLUDE_ROUTE
■
INCLUDE_ROUTE_STORAGE, documented in 16.3 Configuring VxWorks for
Route Storage, p.324.
The INCLUDE_IPV6 and the INCLUDE_ND components are only required for an
IPv6 stack.
INCLUDE_MIB2_IF
This component pulls in modules and MIB files that SNMP needs to provide access
to the network interface layer. This component and its associated configuration
parameters are documented in Configuring VxWorks for Counter Instrumentation,
p.466. There are no component dependencies for this component.
INCLUDE_MLD
This component adds support for the MLD host. This component and its
associated configuration parameters are documented in MLD, p.395. The
INCLUDE_MLD component requires the following component:
■
INCLUDE_IPV6, documented in IP v6, p.86.
The INCLUDE_MLD component is only required for an IPv6 stack.
17
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
INCLUDE_NBIO_LOG
INCLUDE_NET_BOOT_CONFIG
INCLUDE_NET_DAEMON
This component pulls in the software modules needed for tNetTask and is
documented in 2.3 Configuring the Network Daemon Task, p.21.
INCLUDE_NET_REM_IO
This component pulls in modules that initialize systems in support of file access on
the boot host. This component supports the activities of components such as
INCLUDE_NET_DRV and requires the following configuration components:
■ INCLUDE_NET_DRV
■
INCLUDE_BOOT_LINE_INIT
■
INCLUDE_NET_BOOT
■
INCLUDE_NET_HOST_SETUP
For more information on how to use netDrv, see the netDrv reference entry and
9.12 Creating a netDrv Device for RSH or FTP, p.176.
18
2 Configuring VxWorks for the Network Stack
2.2 Adding Network Stack Configuration Components
INCLUDE_PING
This component pulls in support for the ping utility with IPv4 and is documented
2
in PING ICMP Client, p.147.
INCLUDE_PING6
This component pulls in support for the ping utility with IPv6 and is documented
in PING6 ICMP Client, p.147. This component is only required for an IPv6 stack.
INCLUDE_RAWV4
This component pulls in modules to support raw IPv4 sockets. This component is
documented in RAW v4, p.83 and requires the INCLUDE_IPV4 component,
documented in IP v4, p.78.
INCLUDE_RAWV6
This component pulls in modules in support of raw IPv6 sockets. There are no
user-callable functions or configuration parameters associated with this
component. This component is documented in RAW v6, p.89 and requires the
INCLUDE_IPV6 component, documented in IP v6, p.86.
The INCLUDE_RAWV6 component is only required for an IPv6 stack.
INCLUDE_NET_SYSCTL
This component pulls in the sysctlLib module and adds network system control
support. This component requires INCLUDE_SYSCTL and has no configuration
parameters.
INCLUDE_TCPV4
This component pulls in tcpLib and the other modules that provide IPv4 support
for TCP. This component is documented in TCP v4, p.73 and requires the
INCLUDE_IPV4 component, documented in IP v4, p.78.
INCLUDE_TCPV6
This component provides IPv6 support for TCP. This component is documented in
TCP v6, p.86 and requires the INCLUDE_IPV6 component, documented in IP v6,
p.86.
The INCLUDE_TCPV6 component is only required for an IPv6 stack.
19
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
INCLUDE_UDPV4
This component pulls in udpLib and other modules that implement UDP over
IPv4. This component requires the INCLUDE_IPV4 component. This component
and its associated configuration parameters are documented in UDP v4, p.77.
INCLUDE_UDPV6
This component implements UDP over IPv6 . This component requires the
INCLUDE_IPV6 component. This component and its associated configuration
parameters are documented in UDP v6, p.86.
The INCLUDE_UDPV6 component is only required for an IPv6 stack.
INCLUDE_XDR
This component pulls in modules that implement generic XDR (External Data
Representation) routines. It is automatically included as a requirement for RPC.
This component is required only if you also include WDB_COMM_SERIAL. For
more information, see XDR, p.166.
The minimal run-time stack described above assumes that you run no application
other than ping or ping6. If you want to run an application, you will probably
want the default stack components (at the very least), which includes all of the
above plus the following:
INCLUDE_DHCPC_LEASE_CLEAN
INCLUDE_APPL_LOG_UTIL
INCLUDE_NET_GETOPT
INCLUDE_STRICMP
To make the stack usable, it must include at least one network driver and
INCLUDE_MIILIB (the Media Independent Interface (MII) library). This module
implements a Media Independent Interface (MII) library. MII provides an
easy-to-implement connection between the Carrier Sense Multiple Access with
Collision Detection (CSMA/CD) media access controllers and the Physical Layer
Entities (PHYs). The purpose of this library is to provide Ethernet drivers in
VxWorks with a standardized and MII-compliant interface to various PHYs.
20
2 Configuring VxWorks for the Network Stack
2.3 Configuring the Network Daemon Task
Using the services of this library, network drivers can scan the existing PHYs, run
diagnostics, electrically isolate a subset of them, and negotiate their technology
abilities with other link-partners on the network. In short, this library lets you 2
initialize and configure a specific PHY in a proper MII-compliant fashion.
You can include an interface driver by editing the BSP’s config.h or configAll.h
file to define items such as INCLUDE_FEI82557END or INCLUDE_EL3C90XEND.
In addition, for IPv6, you may want to set up a tunnel to a remote IPv6 destination
if no IPv6 router is available locally. For information on how to do this at run-time,
see 20. Working with Device Instances.
A minimal stack to which you have added the components listed in this chapter
will support a ping or ping6 made from the stack using the host shell. However,
you cannot use the kernel shell because that feature is not part of the minimal
default stack, although you can add it in if you want.
21
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
NET_JOB_NUM_CFG
NET_TASK_PRIORITY
For the most part, you should not need to adjust any of these parameters. If you
think you need to adjust the task priority consider the following. By default,
tNetTask runs at a priority of 50. If you launch a task that depends on network
services, make sure your new task runs at a lower priority than that of tNetTask.1
When assigning a priority to a task dependent upon network services, keep in
mind the following:
■
An ISR interrupts even a priority 0 task.
■
When tNetTask is the highest priority task ready to run, it runs.
■
If a user task with a priority greater than tNetTask is ready, it runs instead of
tNetTask.2
■
While tNetTask does not run, packets are not processed, although ISRs
continue to receive the packets.
You must also consider the hazards of priority inversion. After a task takes a
semaphore with priority inversion protection, its task priority is elevated if
another higher priority task tries to take the semaphore. The new task priority is
equal to that of the highest priority task waiting for the semaphore. This priority
elevation is temporary. The priority of the elevated task drops back down to its
normal level after it releases the semaphore with priority inversion protection.
If a task dependent on tNetTask takes a semaphore with priority inversion
protection, and if a higher priority task subsequently tries to take the same
1. Changes to the TFTP client make it necessary that the application run at a priority less than
that of tNetTask. Otherwise, calls such as tftpXfer( ) will fail. This change is consistent
with the general advice that network applications should run at a priority less than that of
tNetTask. Previously, the TFTP client would work even if it was running at a higher
priority.
2. Only user tasks with priority greater than tNetTask, numerically less than 50, can
pre-empt tNetTask.
22
2 Configuring VxWorks for the Network Stack
2.4 Testing Connectivity from the Target
semaphore, the tNetTask-dependent task inherits the higher task priority. Thus, it
is possible for a network-dependent task to elevate in priority beyond that of
tNetTask. This locks tNetTask out until after the tNetTask-dependent task gives 2
back the problematic semaphore or semaphores.
NOTE: For more information on priority inversion protection and semaphores, see
the reference entry for semMLib.
NET_TASK_STACKSIZE
For more information on valid stack size values, see the taskSpawn( ) reference
entry.
NET_TASK_OPTIONS
For more information on valid task options, see the taskSpawn( ) reference entry.
23
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
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 received packets it needs before
terminating. A value of one tells ping( ) to terminate and report success as soon as
the first response packet arrives. A value of zero tells ping( ) to (send and) receive
packets forever or until forcibly terminated). If you specify more than one packet,
ping( ) includes 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 that it takes to get replies:
-> ping "192.0.2.2",10
PING 192.0.2.2: 56 data bytes
64 bytes from 192.0.2.2: icmp_seq=0. time=176. ms
64 bytes from 192.0.2.2: icmp_seq=1. time=64. ms
64 bytes from 192.0.2.2: icmp_seq=2. time=64. ms
64 bytes from 192.0.2.2: icmp_seq=3. time=64. ms
64 bytes from 192.0.2.2: icmp_seq=4. time=80. ms
64 bytes from 192.0.2.2: icmp_seq=5. time=64. ms
64 bytes from 192.0.2.2: icmp_seq=6. time=64. ms
64 bytes from 192.0.2.2: icmp_seq=7. time=64. ms
64 bytes from 192.0.2.2: icmp_seq=8. time=64. ms
64 bytes from 192.0.2.2: icmp_seq=9. time=64. ms
The report format matches that used by the UNIX ping utility. Timings are based
on the system clock, resolution of which 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 */
24
2 Configuring VxWorks for the Network Stack
2.4 Testing Connectivity from the Target
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. 2
The ping6( ) API does not differ much from the ping( ) interface (see the ping6( )
reference entry for the details). Using ping6( ) to test connectivity with a remote
site requires tunneling if the local link does not contain a native IPV6 router. For
information on how to set up a tunnel that links you to a remote IPv6 router, see
20.5 Working with IPv4 and IPv6 Tunneling, p.444.
25
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
26
3
Configuring and Managing
Memory
3.1 Introduction 27
3.2 Configuring VxWorks for Network Memory Pools 28
3.3 Configuring Network Stack Pool Resources 30
3.4 Managing Memory Buffers 39
3.1 Introduction
The Wind River Network Stack uses netBufLib to manage its internal system and
data memory pools. These pools are created automatically if you include the
INCLUDE_NET_POOL component, which also supplies parameters that let you
control the resources allocated to these system and data pools.
This chapter begins by listing the memory management configuration components
discussed in the chapter. Then, it describes how to configure memory pool usage
using the INCLUDE_NET_POOL component and its parameters.
The second part of this chapter covers the buffer management components:
INCLUDE_LINKBUFPOOL, INCLUDE_NETBUFPOOL., INCLUDE_NETBUFLIB, and
the APIs associated with the buffer management libraries, netBufLib and
netBufAdvLib.
27
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The INCLUDE_NET_POOL component supplies the parameters that you can use to
configure the two memory pools dedicated to the network stack, the system
memory pool and the data memory pool. The system pool provides the network
stack with the memory it needs for its internal structures and data types. The data
pool provides the stack with the memory it needs for packet-oriented data
received from or transmitted over the Internet.
Including INCLUDE_NET_POOL sets up an automatic call to usrNetPoolConfig( ),
which is defined in the configlette net/coreip/usrNetPool.c. The stack initialization
code calls netPoolInit( ) twice, once for the system memory pool, and once for the
data memory pool. The parameters supplied by INCLUDE_NET_POOL provide the
input values to two netPoolInit( ) calls.
The INCLUDE_NET_POOL component requires INCLUDE_NETBUFLIB and
(because the memory pools use the original memory pool back end)
INCLUDE_NETBUFPOOL.
This component contains configuration parameters documented in 3.3.3 Network
Stack Memory Pool Configuration Parameters, p.35.
! WARNING: Failure to correctly configure the system and data memory pools is the
single biggest cause of frozen network applications. The default settings for these
pools are enough to get the stack up, running, and able to respond to simple tests,
such as ping. Deployed applications typically require more resources.
28
3 Configuring and Managing Memory
3.2 Configuring VxWorks for Network Memory Pools
linkBufPool
netBufPool
netBufLib
29
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
netBufAdvLib
To choose values for these parameters, you need to know how much memory your
deployed application will require. Regrettably, there is no simple formula that you
can use to anticipate memory usage. Your only real option is to determine memory
usage empirically. This means running your application under the debugger,
pausing the application at critical points in its execution, and monitoring the state
of the memory pool. You will need to perform these tests under both stressed and
unstressed conditions.
30
3 Configuring and Managing Memory
3.3 Configuring Network Stack Pool Resources
Routines to Use
While reliably estimating network pool resource needs requires observing your
network applications in action, there are some general facts of which to be aware.
■ For the most part, the stack allocates bare clusters from the cluster pools of the
stack system pool. Therefore, the system pool does not require large numbers
of mBlks or clBlks.
■ In most cases, received packets are delivered to the stack in tuples loaned from
network driver receive pools. If these packets are forwarded, the loaned tuples
are passed to the outgoing interface and are freed when transmission
completes. Thus, no network stack data pool resources are usually needed in
the forwarding path, or for pure receive traffic; however, the number of
available tuples in these separate driver receive pools may need to be adjusted.
■ Tuples are allocated from the stack data pool by the socket layer when local
applications send data. If zero-copy socket sends are used, the data clusters
themselves are provided by the application, but mBlks and clBlks for these
sends frequently come from the stack data pool. This, when zero-copy socket
sends (for example, zbuf sends) are performed, the stack data pool needs extra
mBlks and clBlks.
■ TCP (and other reliable protocols) keep a copy of sent data in the send socket
buffer until it is acknowledged by the peer. In the socket buffer, application
send data is described as a chain of tuples. TCP constructs mBlk chains
referencing shared clusters and clBlks in these tuples, and passes the
duplicated chain of mBlks to the network interface driver for transmission. To
construct these duplicate mBlk chains, there should be more mBlks in the
network stack data pool than the total number of clusters (which is usually the
same as the total number of clBlks).
31
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
■
If you are working with SCTP, keep in mind that it uses a 20-byte cluster for
each streaming connection. If you know that your application will use a large
number of such connections, you need to increase the number of 20-byte
clusters allocated in the system memory table.
Table 3-1 Mapping of M_CL_CONFIG Fields to System and Data Pool Configuration Parameters
32
3 Configuring and Managing Memory
3.3 Configuring Network Stack Pool Resources
NOTE: For most purposes, every cluster buffer in a memory pool requires exactly
one clBlk structure. The exception to this occurs when code uses unchained
unshared cluster buffers directly, as is often the case for the stack system pool.
Every clBlk structure requires at least one mBlk structure, but buffer sharing 3
(copying by reference) increases your mBlk needs. If you do not already
understand the relationship between the mBlk, the clBlk, and the cluster, see
3.4 Managing Memory Buffers, p.39.
The PMA_ and PMS_ parameters let you handle the allocation of the memory that
contains the memory pool management structures and data. If you do not need to
control the exact memory location of these structures and data, you can leave the
PMA_ and PMS_ parameters at their default value of zero. This tells the network
stack initialization code to handle the allocation.
The pClDescTbl parameter in netPoolInit( ) points to the start of a table of CL_DESC
structures. A CL_DESC structure is defined as:
typedef struct clDesc
{
int clSize; /* cluster size */
int clNum; /* number of clusters */
char * memArea; /* start of pre-allocated memory area */
int memSize; /* size of pre-allocated memory area */
} CL_DESC;
For the system pool, each of the fields in this structure gives rise to a configuration
parameter. Thus, each CL_DESC gives rise to four configuration parameters for
each buffer size supported in the system pool. The system buffer pool supports 8
different buffer sizes, which gives rise to the configuration parameters listed in
Table 3-2.
Of the parameters listed in Table 3-2, the only ones you are likely to change are the
NUM_ parameters. These parameters specify the number of clusters in the pool.
You will need to increase the parameter values to values appropriate to your
deployed application. The PMA_ and PMS_ parameters let you handle the memory
allocation for the data clusters. If you leave these parameters at their default value
of zero, the network stack initialization code handles the memory allocation for
you.
! WARNING: Do not change the SIZ_ parameter values casually. Change them only
if a careful study of the output of netStackSysPoolShow( ),
netStackDataPoolShow( ), and memShow( ) indicates that you need to increase
these values to handle the demands placed on the stack by the application you
intend to deploy.
33
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The network stack requires 8 buffer sizes to allocate memory for the data
structures that it uses internally. These buffer sizes (in bytes) are presently 20, 44,
96, 172, 292, 664, 1144, and 2048 bytes and correspond to the SIZ_SYS_16,
SIZ_SYS_32, SIZ_SYS_64 parameters and so on. These default sizes are based on a
compromise between the various data structure sizes needed internally and the
distribution of sizes that netBufLib can support within a single memory pool. As
such, the exact sizes may change in the future as the sizes of stack data structures
are modified.
Each supported buffer size within a netBufLib pool must be unique within a size
range that is bounded by powers of two. The bottom power of two is included in
the range. The upper power of two is in the next range. Thus, SIZ_SYS_16 indicates
the range of sizes from 16 to 31 bytes. A buffer size of 20 bytes is valid within this
range. Likewise, 44 (SIZ_SYS_32) is within the 32 to 63 size range, 96 (SIZ_SYS_64)
is within the 64 to 127 size range, and so on. When the stack needs memory for any
structure or data type of 20 bytes or less, the stack takes a SIZ_SYS_16 buffer. When
it needs a buffer of more than 20 bytes but less than 45 bytes, it takes a SIZ_SYS_32
buffer, and so on for other buffer sizes up to 2048.
For the data pool, the stack uses buffer sizes that were chosen based on the packet
data exchanged on the Internet. Currently, these sizes are hard-coded to 64, 128,
256, 512, 1024, and 2048. This requires six CL_DESC structures. Because the cluster
size is hard coded, each CL_DESC structure gives rise to only three (not four)
configuration parameters, which are listed in Table 3-3.
34
3 Configuring and Managing Memory
3.3 Configuring Network Stack Pool Resources
Of the parameters listed in Table 3-3, the only ones you are likely to change are the
NUM_ parameters. These parameters specify the number of clusters in the pool.
You will need to increase to values appropriate to your deployed application. The
PMA_ and PMS_ parameters let you handle the memory allocation for the data
clusters. If you leave these parameters at their default value of zero, the network
stack initialization code handles the memory allocation for you.
Following are tables listing the configuration parameters associated with the
INCLUDE_NET_POOL component.
NUM_SYS_MBLKS
Synopsis: The number of mBlk structures needed for the system pool.
Default: 20
35
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
NUM_SYS_CLBLKS
Synopsis: The number of clBlk structures needed for the system pool.
Default: 20
PMA_SYSPOOL
PMS_SYSPOOL
SIZ_SYS_16
Synopsis: The buffer size selected from within this size band, 16 to 31 bytes.
Default: 20
! WARNING: Do not change the SIZ_ parameter values casually. Change them only
if a careful study of the output of memShow( ), netStackSysPoolShow( ), and
netStackDataPoolShow( ) indicates that you need to increase these values to
handle the demands placed on the stack by the application you intend to deploy.
The netBufLib implementation for memory pools that support multiple buffer
sizes requires that each supported buffer size be unique within a size range
that is bounded by powers of two. The bottom power of two is included in the
range. The upper power of two is in the next range.
SIZ_SYS_32 indicates the band of sizes from 32 to 63 bytes.
SIZ_SYS_64 indicates the band of sizes from 64 to 127 bytes.
SIZ_SYS_128 indicates the band of sizes from 128 to 255 bytes.
SIZ_SYS_256 indicates the band of sizes from 256 to 511 bytes.
SIZ_SYS_512 indicates the band of sizes from 512 to 1023 bytes.
SIZ_SYS_1024 indicates the band of sizes from 1024 to 2047 bytes.
SIZ_SYS_2048 indicates the band of sizes from 2048 to 4095 bytes.
36
3 Configuring and Managing Memory
3.3 Configuring Network Stack Pool Resources
The selected buffer sizes for the size bands SIZ_SYS_32 through SIZ_SYS_2048
are as follows:
SIZ_SYS_32 44
SIZ_SYS_64 96 3
SIZ_SYS_128 172
SIZ_SYS_256 292
SIZ_SYS_512 664
SIZ_SYS_1024 1144
SIZ_SYS_2048 2048
NUM_SYS_16
PMA_SYS_16
PMS_SYS_16
37
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
PMS_SYS_2048 are optional parameters. If you leave them at the default value
of zero, the stack initialization code allocates the memory.
NUM_DAT_MBLKS
Synopsis: The number of mBlk structures needed for the data pool.
Default: NUM_DAT_CLBLKS
NUM_DAT_CLBLKS
Synopsis: The number of clBlk structures needed for the data pool.
Default: NUM_DAT_64 + NUM_DAT_128 + NUM_DAT_256 + NUM_DAT_512 +
NUM_DAT_1024 + NUM_DAT_2048 + NUM_DAT_4096 +
NUM_DAT_8192 + NUM_DAT_16384 + NUM_DAT_32768 +
NUM_DAT_65536
NUM_DAT_64
PMA_DAT_64
Synopsis: Start of preallocated space for the 64-byte data pool buffers.
Default: 0
PMA_DAT_128 through PMA_DAT_65536 parallel the description shown above
but deal with 128-byte buffers, 256-byte buffers, 512-byte buffers, 1024-byte
buffers, and 2048-byte buffers respectively. PMS_DAT_64 through
PMS_DAT_65536 are optional parameters. If you leave them at the default
value of zero, the stack initialization code allocates the necessary memory.
38
3 Configuring and Managing Memory
3.4 Managing Memory Buffers
PMS_DAT_64
Synopsis: Size of preallocated space for the 64-byte data pool buffers.
Default: 0
3
This is an optional parameter. If you leave it at the default value of zero, the
stack initialization code allocates the necessary memory. PMS_DAT_128
through PMS_DAT_65536 parallel the description shown above but deal with
128-byte buffers, 256-byte buffers, 512-byte buffers, 1024-byte buffers, and
2048-byte buffers respectively.
39
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Clusters
Valid cluster sizes range up to 64KB (65536 bytes). The netBufPool back end
supports multiple clusters sizes, but requires that only one cluster size is allowed
between consecutive powers of two. The linkBufPool back end allows, at most, a
single cluster size within each net pool.
To support buffer (cluster) loaning, netBufLib tracks clusters using mBlk and
clBlk structures.
For each cluster in a memory pool, there needs to be a corresponding clBlk
structure.
The clBlk structure tracks how many mBlks share its underlying cluster. 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 3-1).
The mBlk structure is the primary object you use to access the data that resides in
a memory pool. Because an mBlk is only a reference to the data available through
a clBlk, network layers can exchange data without copying between internal
buffers. Each mBlk structure stores separate links for the data within a packet and
for the data that starts a new packet.
40
3 Configuring and Managing Memory
3.4 Managing Memory Buffers
clBlk clBlk
Packet 2
Cluster Cluster
64 bytes 2048
bytes
Because the mBlk references the cluster data through a clBlk, duplicating an mBlk
need not copy the cluster data. For example, mBlk A in Figure 3-2 is a duplicate of
mBlk 1. Creating this duplicate did not require the copying of the underlying
cluster. The duplication did require incrementing the external reference count
stored in the clBlk that manages the underlying cluster. This is critical when it
comes time to free an mBlk.
If you use netBufLib to free the mBlk, the mBlk is freed back to the pool and the
reference count in the underlying clBlk is decremented. If this reference count
drops to zero (indicating that no mBlks are referencing the cluster), the clBlk and
cluster are also freed back to the memory pool.
41
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
mBlk A mBlkBb
mBlk null
clBlk clBlk
Cluster Cluster
64 bytes 2048
bytes
When using the older netPoolInit( ) API, you preallocate distinct memory areas
for the mBlk structures, the clBlk structures, and for each cluster size supported
in the memory pool. Using the newer netPoolCreate( ) API, this preallocation is
not necessary. The netPoolCreate( ) call allocates memory internally for the
management and data structures required in the pool.
NOTE: The _pLinkBufPool back end creates pools limited to a single buffer size.
42
3 Configuring and Managing Memory
3.4 Managing Memory Buffers
These structures are defined in netBufLib.h. Using these structures, you can
specify the pool name, its attributes (see Table 3-4), whether it is allocated out of
the kernel memory space or an RTP, the number of mBlks and clBlks (ctrlNumber
of each), and the numbers and sizes of the clusters available from the pool. The
allocation of the required space is handled for you internally by netPoolCreate( ).
For more information, see the netPoolCreate( ) reference entry.
43
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Attaching to a memory pool allows a task to use the buffers in the pool. This
routine lets multiple agents share a preexisting pool.
For example, all of the network interfaces managed by a driver (or even by
multiple drivers) could share a single pool. The netPoolAttach( ) checks that the
pool is intended to be sharable and guards against pool release at least until one
calls netPoolDetach( ). For more information on attaching and detaching from a
memory pool, see the netPoolAttach( ) and netPoolDetach( ) reference entries.
Using the pFuncTbl parameter, you can specify an alternative set of back end buffer
management routines for the network pool. The INCLUDE_NETBUFPOOL back
end supplies the _pNetPoolFuncTbl table. The INCLUDE_LINKBUFPOOL back
end provides the _pLinkPoolFuncTbl table.
44
3 Configuring and Managing Memory
3.4 Managing Memory Buffers
The original netBufLib API for creating a memory pool is netPoolInit( ). Pools
created through netPoolInit( ) do not support:
3
■
borrowing buffers from a parent pool
■
delaying pool deletion until all buffers are returned
M_CL_CONFIG
An M_CL_CONFIG structure specifies the pool’s clBlk count, its mBlk count, and
a previously allocated memory area identified by a starting address and a size. The
count values are analogous to the NUM_SYS_MBLKS and NET_SYS_CLBLKS
values you specified for the network system memory table.
Unless the pool is primarily used to allocate bare clusters, the clBlk count you
specify is usually equal to the number of clusters in the memory pool. The mBlk
count would usually be at least as large, but could be larger or smaller depending
on how you use the memory pool. The allocated memory referenced in the
supplied pointer should be large enough to contain all the clBlk and mBlk
structures specified by the supplied counts.
CL_DESC
Each row of a table of CL_DESC structures associates a cluster size with a cluster
count and a memory area identified by a starting address and a size. If you are
setting up a table of CL_DESC structures for a network driver pool, your table will
likely need only one row. This row specifies a cluster size close to the MTU of the
underlying device. For example, the Lance Ethernet driver uses a cluster size of
1520 bytes, which is the Ethernet MTU plus some slack. The CL_DESC table for a
network protocol will likely contain several rows. This is because protocols
typically require buffers of several different sizes.
45
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
When deciding on cluster sizes, keep in mind that a table of CL_DESC structures
requires each size to be unique within a size range that is bounded by powers of
two. The bottom power of two is within the range, and the upper power of two is
in the next range.
Figure 3-3 shows two examples of sets of cluster sizes. The first, {48, 92, 244}, is
valid because there is at least one power of two between the different sizes. The
second, {48, 88, 128, 192}, is invalid because the cluster sizes of 128 and 192 both fall
within the range bounded by 128 and 256.
In addition, although the {48, 92, 244} set of cluster sizes does not skip a size band,
netBufLib does allow this. Thus, {48, 244} would be a valid set of cluster sizes for
a single memory pool. When setting up a table of CL_DESC structures, make sure
that you specify the smaller buffer sizes first. Ordering the sizes from smaller to
larger is a requirement.
When your driver or protocol needs a buffer for a packet, allocate an mBlk tuple
from the pool using netTupleGet( ). If your protocol needs to allocate a control
structure not containing packet data, it can allocate a bare cluster using
netClusterGet( ) or the clusterGet( ) macro, rather than allocating a tuple. When
doing so, it can determine the appropriate cluster pool to use by calling
netClPoolIdGet( ) or the clPoolIdGet( ) macro. Sometimes this can be done ahead
of time.
46
3 Configuring and Managing Memory
3.4 Managing Memory Buffers
NOTE: The various net*Get( ) routines reserve memory from a pre-allocated pool.
Internally, they are non-blocking, and are safe to call from interrupt level,
provided the M_DONTWAIT option is used rather than M_WAIT. This avoids
calling the protocol garbage collection routines if the allocation is not immediately 3
successful.
Generally the net*Free( ) routines (specifically those which involve freeing cluster
blocks) should not be called from interrupt level, because a user-specified cluster
free routine might be present and unsafe to call from an ISR. In particular, END
drivers should avoid freeing transmit M_BLK chains at interrupt level.
Protocols prepending headers to application data may use the mBlk chaining
feature to do so, although if space is reserved for headers at the start of the data
cluster, this can be more efficient. Various routines are provided in netBufLib for
copying or sharing data in mBlk chains. For example, to read the data out of an
mBlk chain and into a buffer, call netMblkToBufCopy( ). Use
netMblkChainDup( ) to form a new mBlk chain sharing data with part of an
existing chain.
This macro prepends plen bytes at the beginning of buffer m. You can set how to
M_WAIT or M_DONTWAIT. This corresponds to the canWait parameter in the
netMblkGet( ) call. It specifies the desired behavior if there is not enough space in
m for plen bytes and a new buffer must be allocated and added to the buffer chain
to contain these prepended bytes.
For information on pre-allocating space at the beginning of a buffer, which
increases the speed of the M_PREPEND( ) operation, see 21.4.3 Early Link-Level
Header Allocation in an NPT Driver, p.465.
47
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
M_ALIGN( m, len )
This macro adjusts the data pointer of newly allocated tuple’s M_BLK, m, to point
to an address len bytes before the end of the tuple’s cluster, rounded down to a
four-byte boundary. It is only valid to call this macro when the data pointer of m
points to the start of the tuple cluster, for instance right after tuple allocation. Note
that M_ALIGN( ) does not append space to what is already reserved in the M_BLK.
M_LEADINGSPACE( m )
This macro reports the size of the leading space that comes before the data held in
the cluster belonging to buffer m. M_LEADINGSPACE returns zero if the tuple's
cluster is shared (that is, if the cluster reference count is not 1).
M_TRAILINGSPACE( m )
For the cluster belonging to mbuf m, this macro computes the amount of remaining
space past the segment of the cluster presently described by m.
M_TRAILINGSPACE returns zero if the tuple's cluster is shared (that is, if the
cluster reference count is not 1).
48
4
Modifying Parameters
at Run-time
4.1 Introduction 50
4.2 kern.ipc Variables 50
4.3 net.inet.icmp Variables 51
4.4 net.inet.ip Variables 52
4.5 net.inet.ip.portrange Variables 54
4.6 net.inet.raw Variables 55
4.7 net.inet.sctp Variables 55
4.8 net.inet.tcp Variables 58
4.9 net.inet.tcp.syncache Variables 62
4.10 net.inet.udp Variables 62
4.11 net.inet6.icmp6 Variables 63
4.12 net.inet6.ip6 Variables 65
4.13 net.link.ether.inet Variables 68
49
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
4.1 Introduction
This chapter describes the network stack configuration variables that you can set
or inspect at run-time by calling Sysctl( ) or sysctl( ). Many of these variables
receive their default value from parameters of build-time configuration
components. For information on Sysctl( ) or sysctl( ), see their reference entries.
Sets a stack parameter whose default value is the sum of the MAX_LINKHDR_CFG
(maximum size of a link header) and MAX_PROTOHDR_CFG (maximum size of a
protocol header) configuration parameters.
kern.ipc.max_linkhdr
Specifies the maximum size of a link header. Use this variable to reset the current
value of the MAX_LINKHDR_CFG configuration parameter.
kern.ipc.max_protohdr
Specifies the maximum size of a protocol header. Use this variable to reset the
current value of the MAX_PROTOHDR_CFG configuration parameter.
kern.ipc.maxsockbuf
Sepcifies the maximum socket buffer size. Use this variable to reset the current
value of the MAXSOCKBUF_CFG configuration parameter.
kern.ipc.sockbuf_waste_factor
Specifies the sb_efficiency value for sbreserve( ) calls. The stack reserves the
specified number of buffers for each new socket. Use this variable to reset the
current value of the SOCKBUF_WASTE_FACTOR_CFG configuration parameter.
kern.ipc.somaxconn
Specifies the maximum pending socket connections queue size. Use this variable
to reset the current value of the SOMAXCONN_CFG configuration parameter.
50
4 Modifying Parameters at Run-time
4.3 net.inet.icmp Variables
If TRUE, enables ICMP broadcast echo. Use this variable to reset the current value
of the ICMPBMCASTECHO_CFG configuration parameter. 4
net.inet.icmp.drop_redirect
If TRUE, tells stack to drop incoming ICMP redirect packets. Use this variable to
reset the current value of the ICMP_DROP_REDIRECT_CFG configuration
parameter.
net.inet.icmp.icmpErrorLen
Tells the system the expected size of the payload in an ICMP error message. Use
this variable to reset the current value of the ICMPERRORLEN_CFG configuration
parameter.
The ICMP error message payload consists of an ICMP message header followed by
a sample from the start of the bad packet that triggered the ICMP error. The ICMP
error message header requires 8 bytes. At one time, a sample of 8 bytes from the
bad packet was considered sufficient. With the advent of IP tunneling and other
technologies, this message sample was found to be insufficient.
A sample of 56 bytes has proven to be adequate for most tunneled messages. Thus,
the default is 64 bytes, which allows 8 bytes for the ICMP header plus 56 for the
sample of the bad packet. If you find that you need a larger sample of the bad
packet, increase icmpErrorLen to any value not greater than 488 bytes. This upper
limit is imposed by the maximum size of an ICMP datagram.
51
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
net.inet.icmp.icmplim
Sets the ICMP error-response bandwidth limit. Use this variable to reset the
current value of the ICMPLIM_CFG configuration parameter.
net.inet.icmp.icmplim_output
If TRUE, the default, this parameter tells the stack to print a message informing you
that the bandwidth, (icmplim) is exceeded.
net.inet.icmp.log_redirect
If TRUE, tells the stack to log ICMP redirects of incoming packets. Use this variable
to reset the current value of the ICMP_LOG_REDIRECT_CFG configuration
parameter.
net.inet.icmp.maskrepl
Accept incoming ICMP mask reply packets. Use this variable to reset the current
value of the ICMPMASKREPL_CFG configuration parameter.
net.inet.icmp.stats
net.inet.ip.check_interface
52
4 Modifying Parameters at Run-time
4.4 net.inet.ip Variables
net.inet.ip.fastforwarding
If TRUE, enables flow-based IP forwarding. Use this variable to reset the current
value of the FASTFORWARDING_CFG configuration parameter.
net.inet.ip.forwarding
4
If TRUE, this variable enables IP forwarding between interfaces. Use this variable
to reset the current value of the IPFORWARDING_CFG configuration parameter.
net.inet.ip.maxfragpackets
net.inet.ip.maxfragsperpacket
net.inet.ip.redirect
If TRUE, sending IP redirects is enabled. Use this variable to reset the current value
of the IPSENDREDIRECTS_CFG configuration parameter.
net.inet.ip.rtexpire
Sets the expiration time on dynamically learned routes. Use this variable to reset
the current value of the RTEXPIRE_CFG configuration parameter.
net.inet.ip.rtmaxcache
Sets the upper limit on dynamically learned routes. Use this variable to reset the
current value of the RTMAXCACHE_CFG configuration parameter.
net.inet.ip.rtminexpire
Sets the minimum time to try to hold onto dynamically learned routes. Use this
variable to reset the current value of the RTMINEXPIRE_CFG configuration
parameter.
net.inet.ip.sourceroute
If TRUE, enables forwarding source-routed IP packets. Use this variable to reset the
current value of the IP_DOSOURCEROUTE_CFG configuration parameter.
53
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
net.inet.ip.subnets_are_local
If TRUE, tells the stack to test that the in_localaddr for a packet includes other
subnets of the local net. Use this variable to reset the current value of the
SUBNETS_ARE_LOCAL_CFG configuration parameter.
net.inet.ip.ttl
Sets the maximum TTL on IP packets. Use this variable to reset the current value
of the IP_DEFTTL_CFG configuration parameter.
net.inet.ip.stats
Lists IP statistics.
Sets the value of ipport_firstauto, the IP privileged port range. Use this variable to
reset the current value of the IPPORT_RESERVED_CFG configuration parameter.
net.inet.ip.portrange.hifirst
Sets the value of ipport_hifirstauto, the first local port. Use this variable to reset
the current value of the IPPORT_HIFIRSTAUTO_CFG configuration parameter.
net.inet.ip.portrange.hilast
Sets the value of ipport_hilastauto, the last local port. Use this variable to reset the
current value of the IPPORT_HILASTAUTO_CFG configuration parameter.
net.inet.ip.portrange.last
Sets the value of ipport_lastauto, the IP system reserved first port. Use this
variable to reset the current value of the IPPORT_USERRESERVED_CFG
configuration parameter.
54
4 Modifying Parameters at Run-time
4.6 net.inet.raw Variables
net.inet.ip.portrange.lowfirst
net.inet.ip.portrange.lowlast
4
Sets the value of ipport_lowlastauto, the IP privileged first port. Use this variable
to reset the current value of the IPPORT_RESERVEDSTART_CFG configuration
parameter.
Sets the maximum outgoing raw IP datagram size. Use this variable to reset the
current value of the RAW_MAXDGRAM_CFG configuration parameter.
net.inet.raw.pcblist
net.inet.raw.recvspace
Sets the maximum incoming raw IP datagram size. Use this variable to reset the
current value of the RAW_RECVSPACE_CFG configuration parameter.
net.inet.sctp.recvspace
55
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
net.inet.sctp.auto_asconf
Enable auto-ASCONF.
net.inet.sctp.ecn_enable
net.inet.sctp.ecn_nonce
net.inet.sctp.strict_sacks
net.inet.sctp.loopback_nocsum
net.inet.sctp.strict_init
net.inet.sctp.peer_chkoh
net.inet.sctp.maxburst
net.inet.sctp.maxchunks
net.inet.sctp.delayed_sack_time
net.inet.sctp.heartbeat_interval
net.inet.sctp.pmtu_raise_time
56
4 Modifying Parameters at Run-time
4.7 net.inet.sctp Variables
net.inet.sctp.shutdown_guard_time
net.inet.sctp.secret_lifetime
net.inet.sctp.rto_max
net.inet.sctp.rto_min
net.inet.sctp.rto_initial
net.inet.sctp.init_rto_max
net.inet.sctp.valid_cookie_life
net.inet.sctp.init_rtx_max
net.inet.sctp.assoc_rtx_max
net.inet.sctp.path_rtx_max
net.inet.sctp.nr_outgoing_streams
57
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
If TRUE, assume SO_KEEPALIVE on all TCP connections. Use this variable to reset
the current value of the TCP_ALWAYS_KEEPALIVE_CFG configuration parameter.
net.inet.tcp.blackhole
If TRUE, tells the stack not to send RST when dropping refused connections. Use
this variable to reset the current value of the TCP_BLACKHOLE_CFG configuration
parameter.
net.inet.tcp.delacktime
Sets the time before a delayed ACK is sent. Use this variable to reset the current
value of the TCP_DELACKTIME_CFG configuration parameter.
net.inet.tcp.delayed_ack
net.inet.tcp.do_tcpdrain
Enable tcp_drain routine for extra help when low on mbufs. Use this variable to
reset the current value of the DO_TCPDRAIN_CFG configuration parameter.
net.inet.tcp.drop_synfin
If TRUE, drop TCP packets with SYN+FIN set. Use this variable to reset the current
value of the TCP_DROP_SYNFIN configuration parameter.
net.inet.tcp.icmp_may_rst
If TRUE, ICMP unreachable messages can abort SYN_SENT connections. Use this
variable to reset the current value of the ICMP_MAY_RST_CFG configuration
parameter.
net.inet.tcp.inflight_debug
If TRUE, display the results of TCP inflight calculations. Use this variable to reset
the current value of the TCP_INFLIGHT_DEBUG configuration parameter.
58
4 Modifying Parameters at Run-time
4.8 net.inet.tcp Variables
net.inet.tcp.inflight_enable
If TRUE, enable automatic TCP inflight data limiting. Use this variable to reset the
current value of the TCP_INFLIGHT_ENABLE configuration parameter.
net.inet.tcp.inflight_max
4
Sets the upper bound for the TCP inflight window. Use this variable to reset the
current value of the TCP_INFLIGHT_MAX configuration parameter.
net.inet.tcp.inflight_min
Sets the lower bound for the TCP inflight window. Use this variable to reset the
current value of the TCP_INFLIGHT_MIN configuration parameter.
net.inet.tcp.isn_reseed_interval
Sets the number of seconds between the reseeding of a random ISN secret. This is
normally set to zero because reseeding should not be necessary. Use this variable
to reset the current value of the TCP_SEQ_ISNSEED_INTERVAL configuration
parameter.
net.inet.tcp.keepidle
Sets the TCP keepalive: idle time before first probe. Use this variable to override
the TCP_KEEPIDLE_CFG configuration parameter.
net.inet.tcp.keepinit
Sets the TCP keepinit. Use this variable to reset the current value of the
TCP_KEEPINIT_CFG configuration parameter.
net.inet.tcp.keepintvl
Sets the TCP keepalive: interval between probes when no response is received.
Use this variable to reset the current value of the TCP_KEEPINTVL_CFG
configuration parameter.
net.inet.tcp.local_slowstart_flightsize
Slow start flight size for local networks. Use this variable to reset the current value
of the TCP_LOCAL_SLOWSTART_FLIGHTSIZE_CFG configuration parameter.
59
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
net.inet.tcp.log_in_vain
If TRUE, the stack logs all incoming TCP connections. Use this variable to reset the
current value of the TCP_LOG_IN_VAIN_CFG configuration parameter.
net.inet.tcp.msl
Sets the TCP maximum segment lifetime. Use this variable to reset the current
value of the TCP_MSL_CFG configuration parameter.
net.inet.tcp.mssdflt
Set the default TCP maximum segment size. Use this variable to reset the current
value of the TCP_MSSDFLT_CFG configuration parameter.
net.inet.tcp.newreno
If TRUE, enables NewReno Algorithms. Use this variable to reset the current value
of the TCP_DO_NEWRENO_CFG configuration parameter.
net.inet.tcp.path_mtu_discovery
If TRUE, enable Path MTU discovery. Use this variable to reset the current value of
the TCP_PATH_MTU_DISCOVERY_CFG configuration parameter.
net.inet.tcp.pcbcount
net.inet.tcp.pcblist
net.inet.tcp.recvspace
Sets the maximum incoming TCP datagram size. Use this variable to reset the
current value of the TCP_RECVSPACE_CFG configuration parameter.
net.inet.tcp.rexmit_min
net.inet.tcp.rexmit_slop
60
4 Modifying Parameters at Run-time
4.8 net.inet.tcp Variables
net.inet.tcp.rfc1323
If TRUE, enable RFC 1323 (high performance TCP) extensions. Use this variable to
reset the current value of the TCP_DO_RFC1323_CFG configuration parameter.
net.inet.tcp.rfc1644
4
If TRUE, enable RFC 1644 (TTCP) extensions. Use this variable to reset the current
value of the TCP_DO_RFC1644_CFG configuration parameter.
net.inet.tcp.rttdflt
net.inet.tcp.sendspace
Sets the maximum outgoing TCP datagram size. Use this variable to reset the
current value of the TCP_SENDSPACE_CFG configuration parameter.
net.inet.tcp.slowstart_flightsize
Slow start flight size. Use this variable to reset the current value of the
TCP_SLOWSTART_FLIGHTSIZE_CFG configuration parameter.
net.inet.tcp.syncookies
net.inet.tcp.tcbhashsize
Target size of TCP PCB hash tables. Must be a power of two. The default is 512.
net.inet.tcp.stats
net.inet.tcp.v6mssdflt
Sets the default TCP maximum segment size for IPv6. Use this variable to reset the
current value of the TCP_V6MSSDFLT_CFG configuration parameter.
61
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
net.inet.tcp.syncache.cachelimit
net.inet.tcp.syncache.count
net.inet.tcp.syncache.hashsize
net.inet.tcp.syncache.rexmtlimit
If TRUE, tells the stack not to send port unreachable messages for refused
connections. Use this variable to reset the current value of the
UDP_BLACKHOLE_CFG configuration parameter.
net.inet.udp.checksum
If TRUE, enables UDP checksum. Use this variable to reset the current value of the
UDPCKSUM_CFG configuration parameter.
net.inet.udp.log_in_vain
If TRUE, turns on logging of all incoming UDP packets. Use this variable to reset
the current value of the UDP_LOG_IN_VAIN_CFG configuration parameter.
62
4 Modifying Parameters at Run-time
4.11 net.inet6.icmp6 Variables
net.inet.udp.maxdgram
Sets the maximum outgoing UDP datagram size. Use this variable to reset the
current value of the UDP_MAXDGRAM_CFG configuration parameter.
net.inet.udp.pcblist
4
Reports the list of active UDP sockets.
net.inet.udp.recvspace
net.inet.udp.stats
Specifies the per-second limit on ICMPv6 error packets. Use this variable to reset
the current value of the ICMPV6CTL_ERRPPSLIMIT_CFG configuration parameter.
net.inet6.icmp6.nd6_debug
Enables the ND6 debug option. Use this variable to reset the current value of the
ND6_DEBUG_CFG configuration parameter.
net.inet6.icmp6.nd6_delay
Specifies the ND6 delay first probe time (seconds). Use this variable to reset the
current value of the ND6_DELAY_CFG configuration parameter.
net.inet6.icmp6.nd6_drlist
63
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
net.inet6.icmp6.nd6_maxnudhint
Specifies the ND6 maximum number of subsequent upper layer hints. Use this
variable to reset the current value of the ND6_MAXNUDHINT_CFG configuration
parameter.
net.inet6.icmp6.nd6_mmaxtries
Specifies the ND6 maximum multicast query tries. Use this variable to reset the
current value of the ND6_MMAXTRIES_CFG configuration parameter.
net.inet6.icmp6.nd6_prlist
net.inet6.icmp6.nd6_prune
Specifies the interval (in seconds) between walks of the ND6 list. Use this variable
to reset the current value of the ND6_PRUNE_CFG configuration parameter.
net.inet6.icmp6.nd6_maxqueuelen
net.inet6.icmp6.nd6_umaxtries
Specifies the maximum unicast query tries for ND6. Use this variable to reset the
current value of the ND6_UMAXTRIES_CFG configuration parameter.
net.inet6.icmp6.nd6_useloopback
Specifies that ND6 use the loopback interface for local traffic. Use this variable to
reset the current value of the ND6_USELOOPBACK_CFG configuration parameter.
net.inet6.icmp6.nodeinfo
net.inet6.icmp6.rediraccept
Specifies that the stack accept and process ICMPv6 redirects. Use this variable to
reset the current value of the ICMPV6CTL_REDIRACCEPT_CFG configuration
parameter.
64
4 Modifying Parameters at Run-time
4.12 net.inet6.ip6 Variables
net.inet6.icmp6.redirtimeout
Specifies the ICMPv6 redirect cache time out (in seconds). Use this variable to reset
the current value of the ICMPV6CTL_REDIRTIMEOUT_CFG configuration
parameter.
4
net.inet6.icmp6.stats
Allows the acceptance of IPv6 routing advertisements. Use this variable to reset
the current value of the IPV6CTL_ACCEPT_RTADV_CFG configuration parameter.
net.inet6.ip6.auto_flowlabel
Enables IPv6 auto flow label. Use this variable to reset the current value of the
IPV6CTL_AUTO_FLOWLABEL_CFG configuration parameter.
net.inet6.ip6.auto_linklocal
Assigns the IPv6 automatic link-local address. Use this variable to reset the current
value of the IPV6CTL_AUTO_LINKLOCAL_CFG configuration parameter.
net.inet6.ip6.dad_count
net.inet6.ip6.defmcasthlim
Specifies the default hop limit for IPv6 multicasting. Use this variable to reset the
current value of the IPV6CTL_DEFMCASTHLIM_CFG configuration parameter.
65
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
net.inet6.ip6.forwarding
Allow IPv6 forwarding (act as an IPv6 router). Use this variable to reset the current
value of the IPV6CTL_FORWARDING_CFG configuration parameter.
net.inet6.ip6.gifhlim
Specifies the default hop limit for the gif encapsulated packets. Use this variable to
reset the current value of the IPV6CTL_GIF_HLIM_CFG configuration parameter.
net.inet6.ip6.hdrnestlimit
Specifies the maximum number of extension headers allowed per packet. Use this
variable to reset the current value of the IPV6CTL_HDRNESTLIMIT_CFG
configuration parameter.
net.inet6.ip6.hlim
Specifies the IPv6 hop limit. Use this variable to reset the current value of the
IPV6CTL_DEFHLIM_CFG configuration parameter.
net.inet6.ip6.ip6_mcast_pmtu
net.inet6.ip6.keepfaith
Enables IPv6 keepfaith. Use this variable to reset the current value of the
IPV6CTL_KEEPFAITH_CFG configuration parameter.
net.inet6.ip6.log_interval
Specifies the minimum amount of time elapsed, in seconds, before next IPv6 debug
log message generation is allowed. Use this variable to reset the current value of
the IPV6CTL_LOG_INTERVAL_CFG configuration parameter.
net.inet6.ip6.maxfragpackets
Specifies the maximum number of IPv6 packets in the reassembly queue. Use this
variable to reset the current value of the IPV6CTL_MAXFRAGPACKETS_CFG
configuration parameter.
66
4 Modifying Parameters at Run-time
4.12 net.inet6.ip6 Variables
net.inet6.ip6.redirect
Allow redirects when IPv6 forwarding. Use this variable to reset the current value
of the IPV6CTL_SENDREDIRECTS_CFG configuration parameter which is set in
INCLUDE_IPV6.
4
net.inet6.ip6.rip6stats
net.inet6.ip6.rr_prune
Specifies the IPv6 walk timer value (in seconds) for router renumbering. Use this
variable to reset the current value of the IPV6CTL_RR_PRUNE_CFG configuration
parameter.
net.inet6.ip6.rtexpire
Specifies the IPv6 cloned route expiration time (seconds). Use this variable to reset
the current value of the IPV6CTL_RTEXPIRE_CFG configuration parameter.
net.inet6.ip6.rtmaxcache
Specifies the maximum number of cached IPv6 routes. This values serves as the
trigger-level for dynamic expire. Use this variable to reset the current value of the
IPV6CTL_RTMAXCACHE_CFG configuration parameter.
net.inet6.ip6.rtminexpire
Specifies the IPv6 minimum expiration time value (seconds). Use this variable to
reset the current value of the IPV6CTL_RTMINEXPIRE_CFG configuration
parameter.
net.inet6.ip6.rttimeout
Specifies the timeout (seconds) for cached routes. Use this variable to reset the
current value of the IPV6CTL_RTTIMEOUT_CFG configuration parameter.
net.inet6.ip6.stats
net.inet6.ip6.use_deprecated
Allows the deprecated IPv6 address (RFC 2462 5.5.4). Use this variable to reset the
current value of the IPV6CTL_USE_DEPRECATED_CFG configuration parameter.
67
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
net.inet6.ip6.use_tempaddr
Allows the use of IPv6 temporary addresses (RFC 3041). Use this variable to reset
the current value of the IPV6CTL_USETEMPADDR_CFG configuration parameter.
net.inet6.ip6.temppltime
Specifies the maximum duration, in seconds, for preferred addresses. This is how
long to use the address in preference to other addresses. For example, to choose
this address when starting a connection.
net.inet6.ip6.tempvltime
Specifies the maximum duration, in seconds, for valid addresses. For example, a
system could continue using a connection that has a valid address even after it
should stop using that address to create new connections. When the valid address
expires, it should no longer be used. Contrast this parameter with temppltime.
net.inet6.ip6.v6only
Configures the stack to restrict AF_INET6 sockets to IPv6 traffic (by default they
can exchange IPv4 traffic too). Use this variable to reset the current value of the
IPV6CTL_V6ONLY_CFG configuration parameter.
net.link.ether.inet.gratuitous_arp
net.link.ether.inet.host_down_time
net.link.ether.inet.log_arp_wrong_iface
When TRUE, the stack logs the ARP packets that arrive on the wrong interface.
68
4 Modifying Parameters at Run-time
4.13 net.link.ether.inet Variables
net.link.ether.inet.max_age
The number of seconds for which an ARP entry remains valid after it is resolved.
net.link.ether.inet.maxtries
net.link.ether.inet.proxyall
net.link.ether.inet.prune_intvl
net.link.ether.inet.useloopback
Use this variable to configure the stack to use the loopback interface.
69
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
70
5
Configuring Transport and
Network Protocols
TCP, UDP, IP, ICMP
5.1 Introduction 71
5.2 Configuring IPv4 Components 73
5.3 Configuring IPv6 Components 85
5.4 Configuring VxWorks for Network Show Routines 91
5.1 Introduction
This chapter covers the transport and network layer protocols implemented for the
Wind River Network Stack. It describes the components and configuration
parameters that provides support for these protocols.
71
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
This port address is an extension to the Internet address (whether IPv4 or IPv6) of
the host that contains the communication endpoint. Thus, changes to the
underlying IP protocol have not necessitated any great changes to either UDP or
TCP. The ability of IPv6 to carry a jumbogram, a packet containing a payload
longer than 65,535 octets, has provided a new opportunity that has required some
changes to UDP and TCP. These changes, described in RFC 2675, have been
included in this stack’s implementations of TCP, UDP, and supporting software.
Although SCTP was originally developed to transport PSTN signaling messages
over IP networks, it is capable of broader applications. Like TCP, SCTP is a reliable
transport layer protocol. However, SCTP also provides services not available from
TCP. For more information on these additional services, see 6. Using SCTP.
The core RFC for IPv6 is RFC 2460. This RFC describes the new packet header
format for IPv6. The RFC also mentions support for flow labeling, improved
authentication/privacy capabilities, improved support for future options, and
expanded addressing capabilities. If you access IPv6 from a high level and do not
expect to construct an IPv6 packet directly, the expanded 128-bit address is the
most relevant of the new IPv6 features.
The details of the IPv6 addressing architecture are not included in RFC 2460. That
information is provided in RFC 3513, which defines the addressing conventions
that divide the IPv6 address space into special uses, such as multicast addresses,
as well as addresses reserved for future use.
ICMP
IP hosts use the Internet Control Message Protocol (ICMP) to note and report any
errors encountered when processing a packet. Hosts also use ICMP for
Internet-layer diagnostics (echo requests and echo replies associated with ping).
The IPv4 side of the Wind River Network Stack implements ICMP as defined by
RFC 792. The IPv6 side of the stack implements ICMP as defined by RFC 2463. In
addition, the IPv6 side of the Wind River Network Stack implements RFC 2461,
the RFC for the Neighbor Discovery Protocol (NDP), which defines five new ICMP
packet types.
For information on ICMPv4 routing, see 16.7 Using the ICMPv4 Router Discovery
Server, p.347.
72
5 Configuring Transport and Network Protocols
5.2 Configuring IPv4 Components
TCP v4
The INCLUDE_TCPV4 component pulls in tcpLib and the other modules that
provide IPv4 support for TCP. This component requires the INCLUDE_IPV4
component.
This component supports the following configuration parameters:
DO_TCPDRAIN_CFG
TCP_MSSDFLT_CFG
TCP_DO_RFC1323_CFG
73
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
TCP_DO_RFC1644_CFG
TCP_SEQ_ISNSEED_INTERVAL
TCP_INFLIGHT_ENABLE
TCP_INFLIGHT_DEBUG
TCP_INFLIGHT_MIN
TCP_INFLIGHT_MAX
TCP_KEEPINIT_CFG
TCP_KEEPIDLE_CFG
74
5 Configuring Transport and Network Protocols
5.2 Configuring IPv4 Components
TCP_KEEPINTVL_CFG
TCP_KEEPCNT_CFG
TCP_DELACKTIME_CFG
TCP_MSL_CFG
TCP_ALWAYS_KEEPALIVE_CFG
TCP_SENDSPACE_CFG
TCP_RECVSPACE_CFG
TCP_LOG_IN_VAIN_CFG
The value you specify here is effective only if you have recompiled the stack
with the preprocessor macro TCP_LOG_IN_VAIN defined as a non-zero
numeric value.
75
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
TCP_BLACKHOLE_CFG
TCP_DELACK_ENABLED_CFG
TCP_DROP_SYNFIN_CFG
TCP_PATH_MTU_DISCOVERY_CFG
TCP_REASS_GLOBAL_MAX_CFG
TCP_REASS_ENDPT_MAX_CFG
TCP_SLOWSTART_FLIGHTSIZE_CFG
TCP_LOCAL_SLOWSTART_FLIGHTSIZE_CFG
76
5 Configuring Transport and Network Protocols
5.2 Configuring IPv4 Components
TCP_DO_NEWRENO_CFG
TCP Debugging
5
The INCLUDE_TCP_DEBUG component pulls in the tcp_debug library and other
modules that implement the TCP debugging functionality. This component
requires the INCLUDE_TCPV4 configuration component. There are no
user-callable functions or configuration parameters associated with these
modules.
To access the debug functionality pulled in by this component, set the SO_DEBUG
option on the socket endpoint you are debugging. If you set tcpDebugCons, a
global variable, to 1, then TCP debugging output is sent to standard output for the
running task. However, this can severely interfere with performance, and it might
lead to deadlock if writing to the standard output file descriptor requires another
task to enter network code (that is, to take the splnet( ) semaphore). As an
alternative, leave tcpDebugCons set to zero. Then, to output the buffered TCP
debug information after the fact, call tcpDebugShow( ), a routine provided by the
INCLUDE_TCP_SHOW component.
UDP v4
UDPCKSUM_CFG
UDP_LOG_IN_VAIN_CFG
77
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The value you assign to this parameter is ignored if you have not rebuilt the
stack with UDP_LOG_IN_VAIN defined as a preprocessor macro with a
nonzero numeric value.
UDP_BLACKHOLE_CFG
UDP_MAXDGRAM_CFG
For an individual socket connection, you can use the SO_SNDBUF socket
option to override the limit set here.
UDP_RECVSPACE_CFG
Use this parameter to set the default maximum buffer usage per socket for
queuing received UDP datagrams. For an individual socket connection, you
can use the SO_RECVBUF socket option to override the limit set here.
IP v4
The INCLUDE_IPV4 component provides your network stack with the modules
that implement the data-plane functionality associated with IPv4. Almost none of
this functionality is directly accessible to user applications, although they can use
sysctl( ) to make run-time changes to the configuration values here.
This component requires the following components:
■
SELECT_NET_INIT
■ INCLUDE_NET_POOL
■
INCLUDE_ROUTE_STORAGE
■
INCLUDE_ROUTE
■ INCLUDE_DOMAIN_INIT
This component supports the following configuration parameters:
78
5 Configuring Transport and Network Protocols
5.2 Configuring IPv4 Components
IPPORT_RESERVED_CFG
IPPORT_RESERVEDSTART_CFG
IPPORT_USERRESERVED_CFG
IPPORT_HIFIRSTAUTO_CFG
IPPORT_HILASTAUTO_CFG
IPFORWARDING_CFG
IPSENDREDIRECTS_CFG
IP_DEFTTL_CFG
79
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
IP_DOSOURCEROUTE_CFG
IP_ACCEPTSOURCEROUTE_CFG
IP_CHECKINTERFACE_CFG
IPSTEALTH_CFG
Setting this parameter to TRUE has no effect in you have not recompiled the
stack with IPSTEALTH defined. In a default build, IPSTEALTH is undefined.
RTEXPIRE_CFG
RTMINEXPIRE_CFG
RTMAXCACHE_CFG
SUBNETS_ARE_LOCAL_CFG
Use this parameter to set the flag that controls whether in_localaddr needs to
include other subnets of the local net when it tests an address.
80
5 Configuring Transport and Network Protocols
5.2 Configuring IPv4 Components
ARP_MAX_ENTRIES_CFG
The default value of zero configures for an unlimited table. To reset this value
at run-time, call Sysctl( ) on arpMaxEntries.
5
ARP_PRUNE_INTVL_CFG
ARP_MAX_AGE_CFG
ARP_HOST_DOWN_TIME_CFG
Use this parameter to set the number of seconds to refrain from sending ARPs
after the destination host is considered to be down. To reset this value at
run-time, call Sysctl( ) on host_down_time.
ARP_MAXTRIES_CFG
ARP_USELOOPBACK_CFG
ARP_PROXYALL_CFG
81
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
ARP_GRATUITOUS_CFG
LOG_ARP_WRONG_IFACE_CFG
IPV4_RT_DISP_TBL
Synopsis: Assigns IPv4 route table storage method (default is Patricia tree).
Default: ptRibDispatchTable
FASTFORWARDING_CFG
82
5 Configuring Transport and Network Protocols
5.2 Configuring IPv4 Components
RAW v4
For an individual socket connection, you can use the SO_SNDBUF socket
option to override the limit set here.
RAW_RECVSPACE_CFG
For an individual socket connection, you can use the SO_RECVBUF socket
option to override the limit set here.
ICMP v4
ICMPMASKREPL_CFG
ICMP_DROP_REDIRECT_CFG
83
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
ICMP_LOG_REDIRECT_CFG
ICMPLIM_CFG
ICMPBMCASTECHO_CFG
ICMP_MAY_RST_CFG
ICMPERRORLEN_CFG
84
5 Configuring Transport and Network Protocols
5.3 Configuring IPv6 Components
85
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
TCP v6
The INCLUDE_TCPV6 component provides IPv6 support for TCP. There are no
user-callable functions associated with this component.
The INCLUDE_TCPV6 component requires the INCLUDE_IPV6 component and
supports the following configuration parameters:
TCP_V6MSSDFLT_CFG
Synopsis: Default TCP Maximum Segment Size for IPv6.
Default: 1024
UDP v6
The INCLUDE_UDPV6 component pulls in the udp6 library and other modules that
implement IPv6 support for UDP. This component requires the INCLUDE_IPV6
component. There are no user-callable functions or configuration parameters
associated with this component.
IP v6
The INCLUDE_IPV6 component provides your network stack with the modules
that implement the data-plane functionality associated with IPv6. None of this
functionality is directly accessible to user applications. Thus, there are no library
reference entries directly associated with this configuration component.
This component requires the following components:
■
SELECT_NET_INIT
■
INCLUDE_NET_POOL
■ INCLUDE_LOOPBACK
■
INCLUDE_ROUTE_STORAGE
■
INCLUDE_ROUTE
■ INCLUDE_DOMAIN_INIT
86
5 Configuring Transport and Network Protocols
5.3 Configuring IPv6 Components
■
INCLUDE_ICMPV6
■
INCLUDE_ND
■
INCLUDE_TCPV6
■
INCLUDE_UDPV6
This component supplies the following configuration parameters:
IPV6CTL_FORWARDING_CFG 5
Synopsis: Allow IPv6 forwarding (act as an IPv6 router).
Default: FALSE, in a host stack. TRUE, in a router stack.
In some platforms, you can build the network stack code to support host stack
functionality or router stack functionality. The default value of this parameter
changes accordingly.
IPV6CTL_SENDREDIRECTS_CFG
IPV6CTL_DEFHLIM_CFG
IPV6CTL_MAXFRAGPACKETS_CFG
IPV6CTL_ACCEPT_RTADV_CFG
IPV6CTL_KEEPFAITH_CFG
IPV6CTL_LOG_INTERVAL_CFG
Synopsis: Time (seconds) until next IPv6 debug log message is allowed.
Default: 5
87
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
IPV6CTL_LOG_INTERVAL_CFG
IPV6CTL_DAD_COUNT_CFG
At the end of this count, the stack transitions an IPv6 address into operational
mode.
IPV6CTL_AUTO_FLOWLABEL_CFG
IPV6CTL_DEFMCASTHLIM_CFG
IPV6CTL_GIF_HLIM_CFG
IPV6CTL_USE_DEPRECATED_CFG
Synopsis: Allow the deprecated IPv6 address (RFC 2462, section 5.5.4).
Default: TRUE
IPV6CTL_RR_PRUNE_CFG
IPV6CTL_V6ONLY_CFG
88
5 Configuring Transport and Network Protocols
5.3 Configuring IPv6 Components
IPV6CTL_AUTO_LINKLOCAL_CFG
IPV6CTL_RTEXPIRE_CFG
IPV6CTL_RTMINEXPIRE_CFG
IPV6CTL_RTMAXCACHE_CFG
RAW v6
ICMP v6
ICMPV6CTL_REDIRACCEPT_CFG
ICMPV6CTL_REDIRTIMEOUT_CFG
89
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
ICMPV6CTL_NODEINFO_CFG
ICMPV6CTL_ERRPPSLIMIT_CFG
IFF_INET6_UP_CFG
Synopsis: Enables RFC 2462 auto configuration for the boot interface.
Default: 1
RFC 2462 auto configuration lets a node create a link-local IPv6 address and verify
its uniqueness on a link using the Duplicate Address Detection procedure. If
necessary, the target can then use DHCP to negotiate for an assigned IPv6 address
of broader scope. This broader scope address is needed to make the node
addressable by IPv6 nodes outside the scope of its generated link-local address.
90
5 Configuring Transport and Network Protocols
5.4 Configuring VxWorks for Network Show Routines
91
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
NOTE: If you want inetstatShow( ) to display TCP socket status, then you must
include INCLUDE_TCP_SHOW.
92
6
Using SCTP
6.1 Introduction 93
6.2 Building and Configuring for SCTP 95
6.3 Understanding the SCTP Transport Layer 99
6.4 Working with SCTP 102
6.1 Introduction
This chapter describes how to use the Wind River implementation of SCTP, a
transport layer protocol that provides services not available from either TCP or
UDP. This chapter assumes that you are familiar with the SCTP protocol as
described in RFC 2960 and its companion documents.
The Wind River SCTP implementation is well contained. Thus, if you do not
require SCTP services, you can exclude it from your network stack.
NOTE: SCTP is available only in the Wind River Platforms builds of the network
stack. The Wind River General Purpose Platform, VxWorks Edition, does not
support SCTP.
93
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Supported Features
Unsupported Features
1. Sockets API Extensions for Stream Control Transmission Protocol, February 2005, R. Stewart, et
al., Internet Engineering Task Force - Transport Area Working Group. Work In Progress.
http://www.ietf.org/internet-drafts/draft-ietf-tsvwg-sctpsocket-10.txt
94
6 Using SCTP
6.2 Building and Configuring for SCTP
■
SCTP MIB from RFC 3873
■
multi-stack support (the SCTP module is not virtualized, thus, it cannot run on
a host running more than a single stack instance)
■
RTP support. Some support is inherent in using sockets, however this is not
tested and additional APIs have not been enhanced to work across the trap
boundary
The SIGTRAN working group defined SCTP as the key transport mechanism to
transfer SS7 signaling messages over IP networks. Thus, there exist several user
adaptation layers that use SCTP services for transferring signaling information. It
is beyond the scope of this chapter to discuss the designs for user adaptation layers
(UAL) such as M3UA, M2UA, and M2PA.
Recommended Reading
The book listed below discusses sockets network programming in general, and it
has been updated for SCTP.
Unix Network Programming, Vol. 1: The Sockets Networking API, Third Edition, W.
Richard Stevens, Bill Fenner, and Andre M. Rudoff.
SCTP is available only in the Wind River Platforms builds of the network stack. To
make the SCTP modules available for inclusion in a VxWorks image, you must
have previously built the network stack code with SCTP defined (-DSCTP). For
information on building the network stack, see Wind River Platforms Getting Started.
95
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The Wind River Network Stack supports the following NFS client configuration
components, which you can use to include the modules needed to create an NFS
client:
■
SCTP
This component is listed under the
Network Components > Network Protocol Components folder in Workbench.
SCTP
SCTP_SENDSPACE_CFG
SCTP_RECVSPACE_CFG
SCTP_AUTO_ASCONF_CFG
96
6 Using SCTP
6.2 Building and Configuring for SCTP
SCTP_ECN_CFG
SCTP_ECN_NONCE_CFG
SCTP_STRICT_SACKS_CFG
SCTP_NO_CKSUM_ON_LOOPBACK_CFG
SCTP_STRICT_INIT_CFG
SCTP_PEER_CHUNK_OH_CFG
SCTP_MAX_BURST_DEF_CFG
SCTP_MAX_CHUNKS_ON_QUEUE_CFG
97
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
SCTP_DELAYED_SACK_TIME_DEF_CFG
SCTP_HEARTBEAT_INTERVAL_DEF_CFG
SCTP_DEF_PMTU_RAISE_SEC_CFG
Synopsis: Time (in seconds) to wait before trying to increase PMTU again.
Default: 600
SCTP_DEF_MAX_SHUTDOWN_SEC_CFG
SCTP_DEF_SECRET_LIFE_SEC_CFG
SCTP_RTO_UPPER_BOUND_CFG
SCTP_RTO_LOWER_BOUND_CFG
SCTP_RTO_INITIAL_CFG
98
6 Using SCTP
6.3 Understanding the SCTP Transport Layer
SCTP_DEFAULT_COOKIE_LIFE_CFG
SCTP_DEF_MAX_INIT_CFG
SCTP_DEF_MAX_SEND_CFG
SCTP_OSTREAM_INITIAL_CFG
SCTP_DEBUG_CFG
NOTE: For each stream, SCTP uses a number of the smaller-sized buffers (such as
the 20-byte buffers) in the network stack system pool. If you expect to run a large
number of stream connections, you will need to adjust the number of smaller-sized
buffers. For information on adjusting the count of a particular buffer size in the
network stack system pool, see 3. Configuring and Managing Memory.
99
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
RFC Information
RFC 2960 describes the protocol for SCTP and a checksum algorithm. After
RFC 2960 was first published, weaknesses were discovered in the original
Adler-32 checksum algorithm. These weaknesses have been addressed in the
CRC-32 checksum algorithm, as described in RFC 3309.
TCP Shortcomings
SCTP Advantages
Message Boundaries
100
6 Using SCTP
6.3 Understanding the SCTP Transport Layer
are carried in a single SCTP chunk. Larger messages are carried in a series of
associated chunks that allow the receiving SCTP engine to recreate the proper
message boundaries.
Multiple Streams
TCP provides a single stream that can be blocked by a single delayed packet. SCTP
provides for multiple partially independent streams. The streams all share a
common congestion mechanism but are independent from a sequencing point of
view. A delayed data chunk affects only a single stream. Applications using other
streams will not see a disruption in their data.
In order to use multiple streams, an application needs to use the sendmsg( ) and
recvmsg( ) routines or some of the routines from the extended sctp_name( ) API.
The send( ), recv( ), sendto( ) and recvfrom( ) routines do not provide a
mechanism for passing the stream identifier between the application and the SCTP
engine.
Multi-Home
TCP is limited to a single address for each of its endpoints. SCTP allows each
endpoint to include multiple addresses and the SCTP engine will attempt to use a
different pair of addresses if traffic isn't flowing on the current pair.
In order to use the multi-home capabilities an application needs to use one of the
new APIs associated with SCTP, such as sctp_bindx( ) or sctp_connectx( ). These
allow an application to pass or retrieve a list of addresses from the SCTP engine.
101
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
TCP is not well protected against DoS attacks. During the initialization of an
association, SCTP uses a four-message handshake. This lets a server avoid saving
state for a requested association until after it has received a reply from the client.
Although the standard socket API is sufficient to access some SCTP functionality,
it does not support a parameter set that can encompass all of the functionality
provided by SCTP, in particular, the multi-home ability. To access this additional
SCTP functionality, you need to use a socket API that has been extended for SCTP.
Currently, the Wind River SCTP implementation supports the one-to-one interface
style but not the one-to-many style. A one-to-one style SCTP socket can control
only one SCTP association, and it is semantically similar to the standard socket
interface for connection-oriented protocols, such as TCP.
To access the extended socket API for SCTP, you must create a socket with a
protocol type of IPPROTO_SCTP. For example:
mySCTPsd = socket ( AF_INET, SOCK_STREAM, IPPROTO_SCTP );
Using the socket descriptor from such a socket( ) call, you can make either
standard socket calls or socket calls from the extended API. This extended API
includes support for SCTP’s multi-home functionality, which allows one to
associate multiple addresses with a socket endpoint.
102
6 Using SCTP
6.4 Working with SCTP
Table 6-1 provides a side-by-side listing of the standard socket interface and the
socket interface extended for use with SCTP. Keep in mind that, for SCTP sockets,
both the standard and the extended interface are supported.
Table 6-1 Standard versus the Extended (Multi-Home) Socket API for SCTP
STATUS listen
(
int sd,
int backlog
)
int accept
(
int sd,
struct sockaddr *addr,
int addrlen
)
STATUS shutdown
(
int sd,
int how
)
103
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Table 6-1 Standard versus the Extended (Multi-Home) Socket API for SCTP (cont’d)
void sctp_freepaddrs
(
struct sockaddr *addrs
)
104
6 Using SCTP
6.4 Working with SCTP
Table 6-1 Standard versus the Extended (Multi-Home) Socket API for SCTP (cont’d)
int recv
(
FAST int sd,
FAST char *buf,
FAST int bufLen,
FAST int flags
)
ssize_t recvfrom
(
FAST int sd,
FAST char *buf,
FAST int bufLen,
FAST int flags,
FAST struct sockaddr *pFrom,
FAST int *pFromlen
)
105
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Table 6-1 Standard versus the Extended (Multi-Home) Socket API for SCTP (cont’d)
STATUS setsockopt
(
int sd,
int level,
int optname,
char *optval,
int optlen
)
Because the SCTP socket calls are designed to fit into the standard socket system,
they use the same APIs whenever possible. In some cases, an argument is defined
as a void* to allow greater flexibility.
106
6 Using SCTP
6.4 Working with SCTP
When running protocols such as TCP or UDP over SCTP, you can use the -a
netstat( ) option to retrieve socket/association information and statistics. For
example:
-> netstat "-a"
Active Internet connections (including servers)
Proto Recv-Q Send-Q Local Address Foreign Address (state)
tcp4 0 0 pcPentium.12865 pcPentium.1027 ESTABLISHED
tcp4 0 0 pcPentium.1027 pcPentium.12865 ESTABLISHED
tcp4 0 0 *.12865 *.* LISTEN
tcp4 0 0 *.ftp *.* LISTEN
tcp4 0 0 *.telnet *.* LISTEN
Active Stream Control Transmission Protocol associations (including servers)
Proto Recv-Q Send-Q Local Address Foreign Address (state)
sctp 20000 0 localhost.58279 localhost.30464 ESTABLISHED
pcPentium.58279 pcPentium.30464
sctp 0 0 localhost.58279 *.* LISTEN
pcPentium.58279 *.*
sctp 0 0 localhost.30464 pcPentium.58279 ESTABLISHED
pcPentium.30464 localhost.58279
value = 0 = 0x0
To retrieve SCTP information alone, you can use the -a -p sctp netstat( ) options.
The listing above shows an SCTP server listening on a socket and another client
connected to it over loopback. For the statistics, you can use netstat( ) as follows:
-> netstat "-s -p sctp"
sctp:
1142209 :PEG_SACKS_SEEN
1142209 :PEG_SACKS_SENT
3582594 :PEG_TSNS_SENT
3582594 :PEG_TSNS_RCVD
3426892 :DATAGRAMS_SENT
3426892 :DATAGRAMS_RCVD
0 :RETRANTSN_SENT
0 :DUPTSN_RECVD
156 :HB_RECV
156 :HB_ACK_RECV
156 :HB_SENT
0 :WINDOW_PROBES
107
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
2284343 :DATA_DG_RECV
0 :TMIT_TIMER
5 :RECV_TIMER
0 :HB_TIMER
0 :FAST_RETRAN
165 :TIMERS_EXP
0 :FR_INAWINDOW
0 :RWND_BLOCKED
13 :CWND_BLOCKED
0 :RWND_DROPS
0 :BAD_STRMNO
0 :BAD_SSN_WRAP
0 :DROP_NOMEMORY
0 :DROP_FRAG
0 :BAD_VTAGS
0 :BAD_CSUM
3426892 :INPKTS
0 :IN_MCAST
0 :HDR_DROPS
0 :NOPORTS
13 :CWND_NOFILL
3973248 :CALLS_TO_CO
2230213 :CO_NODATASNT
1142159 :CWND_NOUSE_SS
171497 :MAX_BURST_APL
2101884 :EXPRESS_ROUTE
0 :NO_COPY_IN
4725131 :CACHED_SRC
0 :CWND_NOCUM
17 :CWND_SS
0 :CWND_CA
0 :CWND_SKIP
0 :CWND_NOUSE_CA
29152 :MAX_CWND
0 :CWND_DIFF_CA
26560 :CWND_DIFF_SA
0 :OQS_AT_SS
0 :SQQ_AT_SS
0 :OQS_AT_CA
0 :SQQ_AT_CA
29152 :MOVED_MTU
13 :MOVED_QMAX
0 :SQC_AT_SS
0 :SQC_AT_CA
546199 :MOVED_MAX
27163 :MOVED_NLEF
2024480 :NAGLE_NOQ
546173 :NAGLE_OFF
546173 :OUTPUT_FRM_SND
0 :SOS_NOSNT
2230213 :NOS_NOSNT
0 :SOSE_NOSNT
2230213 :NOSE_NOSNT
0 :DATA_OUT_ERR
0 :DUP_SSN_RCVD
0 :DUP_FR
108
6 Using SCTP
6.4 Working with SCTP
3426880 :VTAG_EXPR
4 :VTAG_BOGUS
0 :T3_SAFEGRD
0 :PDRP_FMBOX
0 :PDRP_FEHOS
0 :PDRP_MB_DA
0 :PDRP_MB_CT
0 :PDRP_BWRPT
0 :PDRP_CRUPT
0 :PDRP_NEDAT
0 :PDRP_PDBRK
value = 0 = 0x0 6
109
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
110
7
Enabling Virtual TCP/IP Stacks
7.1 Introduction
If compiled with virtual stack support enabled, the Wind River Network Stack
IPv6 lets you run two TCP/IP stack instances on a single VxWorks target. Each
stack instance is data-independent of the other. This means that each stack has its
own routing table, network buffer memory pools, localized global variables, and
so on. In addition, each stack instance is designed to guarantee privacy at the
network layer.
NOTE: The TCP/IP virtual stacks feature is available only in Wind River Platforms
builds of the network stack. The Wind River General Purpose Platform, VxWorks
Edition, does not support virtual TCP/IP virtual stacks.
111
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Because each stack instance can guarantee network layer privacy, ISPs can use a
secondary stack instance within a single router in order to create virtual private
routed networks (VPRNs). These VPRNs let an ISP give each of its customers a
functionally private IP address space even though the same IP addresses might be
reused in the different stack instances.
NOTE: Virtual stacks are not supported in user space. In addition, if the stack has
been built with the VIRTUAL_STACK option, no networking feature can be used
from an RTP.
Using the rlogin application in the secondary virtual stack is possible only if you
have not already started the INCLUDE_NET_REM_IO utility in the first stack.
Among other scenarios, this requirement prevents the use of rlogin in the
secondary virtual stack when the VxWorks image downloads the symbol table. A
standalone image or an image that does not include symbols will allow rlogin to
run in either the primary or the secondary virtual stack instance.
NOTE: Virtual stack support is limited to two stack instances per target.
112
7 Enabling Virtual TCP/IP Stacks
7.2 Configuring VxWorks for Virtual Stacks
NOTE: These components are available to you only if the stack code was built
using -DROUTER_STACK and -DVIRTUAL_STACK. For information on building
the network stack, see your Wind River Platforms Getting Started.
VIRTUAL_STACK
Virtual stack support flag. This flag affects the compilation of numerous
modules throughout the network stack. After changing the value of this
parameter, you must rebuild all of the network stack code.
VS_DELTIMEO_CFG
VS_SOCKTIMEO_CFG
VS_APPLTIMEO_CFG
113
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
114
7 Enabling Virtual TCP/IP Stacks
7.3 Understanding Dual-Instance Network Stacks
All global variables are collected into appropriate classes in order to assure that
virtualized instances of a particular component (for example, IP, TCP, and Routing
Tables) can coexist within the same flat memory space.
Consistent with the virtualization of global variables described above, the spl( )
routines for global blocking in a network stack have been modified to work with
stack-specific spl locks. Thus, when one stack instance takes its spl lock, it has no
impact on any other stack instance.
115
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
From time to time, each network stack instance needs to run code within the
context of tNetTask. While a stack executes in tNetTask, that stack instance may
slightly delay all other stack instances. If a stack blocks in tNetTask, that stack will
eventually block all other stack instances.
Configuring VS0
When the startup code initializes VS0, it initializes all core stack protocols and
applications included in the VxWorks image. Not all network stack components
included in a VxWorks image are necessarily core components. To determine
whether it should initialize a non-core component, the startup code relies on the
parameters to the INCLUDE_APPL_IN_VIRTUAL_STACK component. Each
parameter in INCLUDE_APPL_IN_VIRTUAL_STACK accepts a boolean value. If the
parameter value is TRUE, the associated application is initialized in VS0.
Otherwise, the application is not initialized for VS0.
For a secondary stack, there is no automatic startup code. Instead, you need to
write your own code that calls the necessary stack configuration and startup
routines. By default, a secondary stack instance starts all the protocols and
applications enabled for VS0. You can use vsComponentStatusSet( ) to selectively
enable or disable the protocols and applications included in the stack. For more
information, see 7.4 Starting a Secondary Stack Instance, p.120.
116
7 Enabling Virtual TCP/IP Stacks
7.3 Understanding Dual-Instance Network Stacks
In the preferred vsLib API for managing a virtual stack instance, you use a virtual
stack number to identify a stack instance. Internally, this number is interpreted as
an index into a table of pointers. Each pointer in this table references the head of a
system of structures that store the management data specific to a stack instance. In
the original vsLib API, some routines required you to supply not the index but the
pointer at that index location. That pointer is known as a Virtual Stack ID (VSID).
NOTE: Never directly access any data through its reference in a VSID. The internals
of the VSID are not part of the published API and could change in subsequent
releases. Your code should remain agnostic of the internals of the VSID.
To manage two virtual stack instances on a single target device, use the interface
defined in vsLib.
If you compile the network stack to include virtual stack support, you can initialize
virtual stack support by calling vsLibInit( ). If your image includes the
INCLUDE_VIRTUAL_STACK component, this call is made for you in the image
startup code.
117
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
At this point, you are ready to register the startup and shutdown routines for the
applications you want included in this network stack instance. For the Wind River
supplied network protocols and applications included in an image, registration is
handled for you automatically.
If you have written your own network stack protocol or application, you can call
vsComponentRegister( ) or vsApplicationRegister( ) to register your code’s
constructor and destructor routines. This is an optional step. It lets the stack
automatically start your application at initialization time.
When registering a protocol or application, you must specify whether it should be
enabled in the next stack instance to be created. If necessary, you can later use
vsComponentStatusSet( ) to reset this value. To check on the status of a registered
component or application, call vsComponentStatusGet( ).
All core network components supplied by Wind River are registered as enabled.
Non-core Wind River supplied applications register according to the parameters
supplied by the INCLUDE_APPL_IN_VIRTUAL_STACK configuration component.
These parameters report the values set at build time. It is possible that a run-time
call to vsComponentStatusSet( ) has since changed the registration to a different
state. This change would not be reflected in the values of the parameters to
INCLUDE_APPL_IN_VIRTUAL_STACK.
At this point, you are ready to call vsCreate( ), the routine that creates the virtual
stack instance. This routine does not initialize any network components or
applications for the stack it creates. To do that, you need to make at least two calls
to vsStart( ).
In the first vsStart( ) call, you should initialize the core components, those
registered by vsComponentRegister( ). After the first vsStart( ), use vsStatusSet( )
to set the stack’s state to VS_RUNNING. In the second vsStart( ) call, you should
initialize the code registered by vsApplicationRegister( ).
Finally, after you have a stack instance up and running, you must bind it to at least
one network interface. Call either ipAttach( ) or ip6Attach( ). In the case of VS0, the
stack binds automatically to the boot interface. For a secondary network stack, you
must explicitly bind the stack instance to an available interface. Keep in mind that
you may bind no more than one stack instance to a single network interface. Stack
instances cannot share a network interface. Thus, if VS0 is bound to the boot
interface, you cannot bind a secondary stack instance to the boot interface.
118
7 Enabling Virtual TCP/IP Stacks
7.3 Understanding Dual-Instance Network Stacks
To specify the virtual stack within which a task runs subsequent network service
requests, use vsIdContextSet( ).
! WARNING: If you use vsIdContextSet( ) to select the wrong stack instance, the next
network service call executes in an inappropriate context. The results are
unpredictable and almost certainly not what you intended.
By default, a newly initialized task assumes the management stack as its network
7
stack context. If you change the current stack context, the new stack context
remains until you explicitly change it. The only exception to this is when a shell
executes a routine that throws an exception. When the shell recovers from the
exception, it resets its stack context to the management stack.
When writing a task routine, the routine specified in a taskSpawn( ) call, you
should include a parameter that lets the caller specify the stack number. Within
your task routine, your first act should be to call vsIdContextSet( ) to set the stack
context to whatever the caller passed in. Otherwise, your task routine runs in the
context of the management stack.
When running a command from a Wind shell, the normal context-setting routines
mentioned above are ineffective. The assumed stack context is always stack 0, the
management stack. To run a command in a different stack context, you must call
vsexec( ). As input, this routine accepts a stack number, followed by the
command/routine name you want to run, followed by up to ten arguments to that
routine. For more information, see the vsexec( ) reference entry.
Use vsShow( ) to show information for a TCP/IP stack instance that you specify
by stack number. If you do not specify a stack number, vsShow( ) prints a brief
description of each stack.
119
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
When you create a socket in a virtual stack, you are, by default, limited to using
that socket within that original stack context only. Attempting to use the socket in
any other stack context generates an error. This is the default behavior.
There are situations in which it can be convenient for a single socket to be
accessible from other virtual stack contexts. To allow this, set SO_VSLOCK, a
setsockopt( ) option, to zero. This socket option lets you configure individual
sockets so that they are accessible from any stack context. For the duration of the
call against the socket, the stack context switches to that of the socket’s origin. After
the operation completes, the stack context reverts to whatever it was before you
made the call against the socket.
If you are working with a socket and need to test whether it auto-switches, you can
use getsockopt( ) to discover the value of the socket’s SO_VSLOCK option.
NOTE: Do not use the vsDeb API in deployed applications. The functionality
supplied in vsDeb will be supported in the next release, but the details of the API
are almost certain to change. Thus, for deployed applications, applications for
which you want forward compatibility, use the vsLib API. Consider the vsDeb
API to be a deprecated API.
120
7 Enabling Virtual TCP/IP Stacks
7.4 Starting a Secondary Stack Instance
If this complete set of components includes more than you want to run in VS0,
you can use the INCLUDE_APPL_IN_VIRTUAL_STACK component parameters
to identify which non-core applications you want to exclude from VS0.
For the Wind River supplied network protocols and applications, including a
component automatically registers it with the virtual stack manager. If you
have written a network protocol or application, you can use either
vsComponentRegister( ) or vsApplicationRegister( ) to register your code’s
startup and shutdown routines with the virtual stack manager. This is not
required, but it is convenient when you must shutdown the stack and all its
applications in an orderly manner. 7
5. Activate the stack instance. Call vsStatusSet( ) and set the stack’s state to
VS_RUNNING.
6. Call vsStart( ) to initialize the network applications for the secondary stack.
vsStart( 1, VS_APPL )
121
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
■
vshelp( ) - list available debugging commands
■
vscreate( ) - create a new (complete) virtual stack instance
■
vslist( ) - list status information for a virtual stack instance
■
vsset( ) - set virtual stack context of a running task/shell
■
vsscena( ) - enable a stack component for a specified virtual stack instance
■
vsscdis( ) - disable a stack component for a specified virtual stack instance
■
vsscshow( ) - show the status of virtual stack component(s)
■ vsscshowdis( ) - show disabled virtual stack component(s) per stack instance
■ vsscerr( ) - show the error status of virtual stack component(s)
■ vssta( ) - show the status of a virtual stack
■ vssglin( ) - call a single instance initialization routine
■ vssglde( ) - call a single destructor routine
■ vsstrt( ) - start an application in different stack contexts
In addition to those listed by vshelp, there are three additional routines:
■ vsdevl( ) - load and attach devices
■ vsdeva( ) - attach devices
■ vsdevrestart( ) - restart an interface on a new stack
These routines access functionality provided by the vsLib and vsShow libraries. In
a deployed application, access the vsLib and vsShow functionality directly.
122
7 Enabling Virtual TCP/IP Stacks
7.5 Using SNMP with Virtual TCP/IP Stack Instances
When working with SNMPv1 or SNMPv2c, use the community string to specify a
context. This is a standard overloading of this string. When working with
SNMPv3, use a context name to specify the proper context.
To access the different contexts, you need to program your SNMP manager to use
the proper community string or context name for the information you want to
examine. The default community string is comprised of a prefix of "VS" prepended
to the stack number as the string or name. Thus, you would use a community
string of "VS1" to access the information for virtual stack 1.
The community strings used as defaults in previous releases are unchanged and
7
will continue to access information relating to virtual stack 0, which is by default
the management stack.
Configuration
In support of virtual stacks, the configuration file (.cfg) for Wind River SNMP
supports two new options:
■ SNMP_VXWORKS_VIRTUAL_STACK
■
SNMP_VXWORKS_VS_ENTITY
The SNMP_VXWORKS_VIRTUAL_STACK option enables support for the new
handling of virtual stacks within Wind River SNMP. The
SNMP_VXWORKS_VS_ENTITY option adds information about the names used to
reach the virtual stacks into the logical entity table (entLogicalTable) from the
Entity MIB. For this option to be useful, you must also install the entity MIB. This
MIB is already a feature of Wind River SNMP and is installed under the option
ENVOY_ENTITY_MIB.
If you use the Makefile facility, configuration is largely automatic. If you include
VIRTUAL_STACK as an option on the command line, the facility turns on the
installation options that affect virtual stack support within Wind River SNMP and
support for two virtual stack instances (VS0 and VS1) is entered into the
appropriate tables.
In addition to options that enable virtual stack support in Wind River SNMP, there
are also several configuration options within the code. To access these options, edit
the standard Wind River SNMP porting file, envoy.h. These options and their
defaults are listed in Table 7-1.
123
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Table 7-1 Wind River SNMP Porting File Virtual Stack Options
Option Default
SNMP_VIRTUAL_STACK_NUM 2
SNMP_SET_VIRTUAL_STACK virtualStackNumTaskIdSet, which is now a
deprecated API. The default will change soon
to a supported routine.
NAMING_SCOPE_PREFIX "VS"
ENT_LOGICAL_DESCR "Virtual Stack #"
ENT_LOGICAL_TADDRESS "192.168.0.52"
Within envoy.h, there are additional options dealing with user exits for the virtual
stack functions. You should treat these as internal implementation artifacts and
leave their values unchanged.
Caveats
There are several items to keep in mind when using these SNMP features:
■ By default, the information for all virtual stacks is added to the tables at
initialization. This provides a simple mechanism for populating the tables. It
should be acceptable for most purposes if you plan to create all your virtual
stack instances at initialization. If you choose to create a virtual stack later, you
must consider the following:
– A manager querying the not yet created stack receives a timeout in
response to its request.
– A management request for a stack that has been created but not yet
initialized causes problems for the SNMP daemon.
■
By default, the VS_ENTITY option is installed. This causes the community
strings to be placed into the logical entity table (entLogicalTable) from which
they may be examined. You might want to keep this information more hidden.
The current version of the new solution does not interact well with deferred
processing routines (asynchronous method routines).
124
7 Enabling Virtual TCP/IP Stacks
7.6 Using sysctl with Virtual Stacks
The non-networking related oids are still installed as previously, using the
SYSCTL_* macros.
125
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
126
8
Adding NFS Support
8.1 Introduction
Wind River Network Stack implements the Network File System (NFS)
application protocol. The first part of this chapter describes how to configure and
use an NFS client, which enables a VxWorks target to mount remote file systems
and access the contents of those file systems as if they were local. The second part
of this chapter describes how to configure and use an NFS server, which enables a
VxWorks target to export local systems to remote network systems.
NOTE: VxWorks does not normally provide authentication services for NFS
requests, and the DOS file system does not provide file permissions. If you need
the NFS server to authenticate incoming requests, see the nfsdInit( ) and
mountdInit( ) reference entries for information on authorization hooks.
127
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
NFS_USER_ID
NFS_GROUP_ID
NFS_MAXPATH
128
8 Adding NFS Support
8.2 Configuring VxWorks for an NFS Client
NFS v2 Client
8
The INCLUDE_NFS2_CLIENT component pulls in nfs2Lib and nfs2Drv, which
provide support of an NFS version two client. Using this client, you can mount
exported NFS (version two) directories to your VxWorks target.
This component requires the INCLUDE_CORE_NFS_CLIENT component.
Initialization
This component also configures the VxWorks image to initialize the NFS v2 client,
which includes a call to nfsAuthUnixSet( ):
nfsAuthUnixSet ( sysBootParams.hostName, NFS_USER_ID, NFS_GROUP_ID, 0,
(int *) 0);
Values for the NFS_USER_ID and NFS_GROUP_ID parameters are taken from the
required INCLUDE_CORE_NFS_CLIENT component.
Parameters
NFS2_CLIENT_CACHE_DEFAULT_NUM_LINES
129
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
NFS2_CLIENT_CACHE_DEFAULT_LINE_SIZE
Changing the size of the cache will not affect any existing cache. It will only
impact future caches.
NFS2_CLIENT_CACHE_DEFAULT_OPTIONS
This parameter configures the default options for the NFS v2 client cache. The
two valid settings for this parameter are:
0
The default value of zero (0) means that the cache will collect the written
data and only send it to the server when the cache line is full, or it needs
to be flushed (no options), which is the default value
1, NFS_CACHE_WRITE_THROUGH
A value of one means that the cache will be write-through.
You can modify the cache options, either at build time or at run-time. To
configure the cache at run time, call the routine usrNfs2CacheInit( ):
usrNfs2CacheInit (UINT32 numLines, UINT32 lineSize, UINT32 options);
NFS v3 Client
130
8 Adding NFS Support
8.2 Configuring VxWorks for an NFS Client
Initialization
This component also configures the VxWorks image to initialize the NFS v3 client,
which includes a call to nfsAuthUnixSet( ):
nfsAuthUnixSet ( sysBootParams.hostName, NFS_USER_ID, NFS_GROUP_ID, 0,
(int *) 0);
Values for the NFS_USER_ID and NFS_GROUP_ID parameters to this routine are
taken from the required INCLUDE_CORE_NFS_CLIENT component.
Parameters 8
NFS3_CLIENT_CACHE_DEFAULT_NUM_LINES
NFS3_CLIENT_CACHE_DEFAULT_LINE_SIZE
131
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Changing the size of the cache will not affect any existing cache. It will only
impact future caches.
NFS3_CLIENT_CACHE_DEFAULT_OPTIONS
This parameter configures the default options for the NFS v3 client cache. The
two valid settings for this parameter are:
0
The default value of zero (0) means that the cache will collect the written
data and only send it to the server when the cache line is full, or it needs
to be flushed (no options), which is the default value
1, NFS_CACHE_WRITE_THROUGH
A value of one means that the cache will be write-through.
You can modify the cache options, either at build time or at run-time. To
configure the cache at run time, call the routine usrNfs3CacheInit( ):
usrNfs3CacheInit (UINT32 numLines, UINT32 lineSize, UINT32 options);
The NFS v3 client has one additional configurable parameter that is not available
on NFS v2. According to the RFC, the NFS v3 client can dictate to an NFS v3 server
how it should perform the write operations. At runtime, the NFS v3 client can be
set to inform the server that it should perform writes one of the following styles:
■ UNSTABLE
■ FILE_SYNC
■ DATA_SYNC
The default setting is UNSTABLE.
You can use two routines to configure these options at run-time:
■
nfs3StableWriteSet(stable_how mode) lets you set the mode
■
nfs3StableWriteGet( ) routine gets the current mode
132
8 Adding NFS Support
8.3 Creating an NFS Client
GROUP_EXPORTS
An NFS server can specify that an exported file system is intended for particular
group of clients. Before mounting an exported file system, a client typically checks
that it is a group member. If the client is not a group member, it does not mount
the file system. To configure the client to skip this check, set this parameter to
TRUE. The default of FALSE ensures that the check occurs.
133
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
VxWorks calls hostAdd( ) for the host system automatically at boot time. If
you want to mount file systems from other remote systems, you need to make
and explicit hostAdd( ) call for those systems.
4. Call nfsMount( ) or nfsMountAll( ) to actually mount a remote file system.
The nfsMountAll( ) routine queries the specified remote system for a list of
exported file names and then creates NFS client device instances for each
exported file system. To unmount a file system, use nfsUnmount( ). Use
nfsDevShow( ) to display a list of the mounted NFS devices.
As a convenience, the INCLUDE_NFS_MOUNT_ALL component configures an
image to make a boot time call to nfsMountAll( ) to mount all file systems
exported by the boot host.
The following sections supplement and expand on the procedure outlined above.
For a UNIX NFS server, the /etc/exports file specifies which of the server’s file
systems are exported for mounting by remote NFS clients. If a file system on a
UNIX NFS server is not listed in /etc/exports, the file system is not exported, which
means other machines cannot use NFS to mount it. For example, consider an
/etc/exports file that contains the line:
/usr
The server exports /usr without restriction. If you want to limit access to this
directory, you can include additional parameters on the line. For example:
1. On the UNIX box, login as root (super user).
2. Edit: /etc/exports
3. Specify the path and permission for the file system that you would export.
For example: /usr * (rw)
For more information on these parameters, consult your UNIX system
documentation.
4. Export the file system, run: exportfs -ra
5. On the UNIX target, run the NFS daemon: rpc.nfsd
6. Run: rpc.rquotad
7. To run mount the daemon, run: rpc.mountd
To check whether NFS is running, use: rpcinfo -p.
134
8 Adding NFS Support
8.3 Creating an NFS Client
Internally, NFS depends upon RPC to handle the remote execution of the
commands (open, read, write, and others) that access the data in the remote file
system. Associated with the RPC protocol is an authentication system known as 8
AUTH_UNIX. This authentication system requires RPC peers to provide a user
name, a user ID, and a group name. The recipient of an RPC message uses this
information to decide whether to honor or ignore the RPC request.
On a VxWorks host, you can set the NFS user name, user ID, and group name
using the NFS_GROUP_ID and NFS_USER_ID parameters included in the
INCLUDE_CORE_NFS_CLIENT component. You can also set these values by calling
nfsAuthUnixSet( ) or nfsAuthUnixPrompt( ). For example, to use
nfsAuthUnixSet( ) to set the NFS user ID to 1000 and the NFS group ID to 200 for
the machine mars, you would call nfsAuthUnixSet( ) as follows:
-> nfsAuthUnixSet "mars", 1000, 200, 0
After setting your NFS client name, user ID, and group ID, you are ready to call
nfsMount( ) to mount any file system exported by a known host. To add a system
to the list of hosts known to a VxWorks system, call hostAdd( ):
hostAdd ("host", "IPaddress" )
This routine associates a host name with an IP address. Thus, if you wanted to
mount a file system exported by a system called "mars", you would need to have
135
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
already called hostAdd( ) for "mars". For example, if "mars" were at 192.168.10.1
you would need to call hostAdd( ) as follows:
hostAdd ("mars", "192.168.10.1" )
If "mars" exports a file system called /usr, you can now use a call to nfsMount( ) to
create a local mount of that remotely exported file system. The syntax of an
nfsMount( ) call is as follows:
nfsMount ("hostName", "hostFileSys", "localName")
hostName
The host name of the NFS server that exports the file system you want to
mount.
hostFileSys
The name of the host file system or subdirectory as it is known on the
exporting NFS server system.
localName
The local name to assign to the file system.
For example, if you wanted to mount a remote file system, /d0/, on your target,
wrs, as a device called /myDevice0/, you would make the following call to
nfsMount( ):
nfsMount ("wrs", "/d0/", "/myDevice0/");
The VxWorks target now has access to the contents of /d0/, although using the
device name, /myDevice0/. For example, if the remote device stores the file,
/d0/bigdog, you can access this file from the wrs target using the pathname,
/myDevice0/bigdog. If you want the local device to use the same device name
as is used on the exporting system, use a NULL as the third parameter of the
nfsMount( ) call. For example:
nfsMount ("wrs", "/d0/", NULL);
On the VxWorks target, the nfsMount( ) call creates the local device, /d0/.
Thus, on the target, the pathname to bigdog is the same as on the exporting
system; that is: /d0/bigdog.
If you do not need to mount the remote file system under a new name, you should
consider using nfsMountAll( ) instead of nfsMount( ). A call to nfsMountAll( )
mounts all file systems that are exported from the remote system and that are
accessible to the specified client.
136
8 Adding NFS Support
8.3 Creating an NFS Client
hostName
The name of the host from which you want to mount all exported file
systems.
clientName
The name of a client specified in an access list, if any. A NULL clientName
mounts only those file systems that are accessible to any client.
quietFlag
A boolean value that tells nfsMountAll( ) whether to execute in verbose 8
or silent mode. FALSE indicates verbose mode, and TRUE indicates quiet
mode.
After opening a file in a mounted directory, you can work with the file using the
IOCTL values listed in Table 8-1.
Table 8-1 Supported IOCTL Values for Files Accessed through NFS
IOCTL Description
FIOGETNAME Gets the file name of fd and copies it to the buffer referenced
by nameBuf:
status = ioctl (fd, FIOGETNAME, &nameBuf);
FIOSEEK Sets the current byte offset in the file to the position specified
by newOffset. If the seek goes beyond the end-of-file, the file
grows. The end-of-file pointer gets moved to the new
position, and the new space is filled with zeros:
status = ioctl (fd, FIOSEEK, newOffset);
137
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Table 8-1 Supported IOCTL Values for Files Accessed through NFS (cont’d)
IOCTL Description
FIOWHERE Returns the current byte position in the file. This is the byte
offset of the next byte to be read or written. It takes no
additional argument:
position = ioctl (fd, FIOWHERE, 0);
FIOREADDIR Reads the next directory entry. Use the third argument in the
ioctl( ) call to supply a pointer to a directory descriptor of
type DIR.
DIR dirStruct;
fd = open ("directory", O_RDONLY);
status = ioctl (fd, FIOREADDIR, &dirStruct);
138
8 Adding NFS Support
8.4 Configuring VxWorks for an NFS Server
NFS Server
139
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
NFS_MAXPATH
NFS_USER_ID
NFS_MAXFILENAME
Synopsis: Maximum file name length. Valid values range from 1 to 99.
Default: 40
NFS server V2
140
8 Adding NFS Support
8.4 Configuring VxWorks for an NFS Server
NOTE: VxWorks does not normally provide authentication services for NFS
requests, and the DOS file system does not provide file permissions. If you need to
authenticate incoming requests, see the documentation for nfsdInit( ) and
mountdInit( ) for information about authorization hooks.
8
NFS server V3
NOTE: VxWorks does not normally provide authentication services for NFS
requests, and the DOS file system does not provide file permissions. If you need to
authenticate incoming requests, see the documentation for nfsdInit( ) and
mountdInit( ) for information about authorization hooks.
The following requests are accepted from clients. For details of their use, see RFC
1813: NFS: Network File System Protocol Specification.
141
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
NFSPROC_NULL 0
NFSPROC_GETATTR 1
NFSPROC_SETATTR 2
NFSPROC_LOOKUP 3
NFSPROC_ACCESS 4
NFSPROC_READLINK 5 – not supported, limitation in DOSFS
NFSPROC_READ 6
NFSPROC_WRITE 7
NFSPROC_CREATE 8
NFSPROC_MKDIR 9
NFSPROC_SYMLINK 10 – not supported
NFSPROC_MKNOD 11 – not supported
NFSPROC_REMOVE 12
NFSPROC_RMDIR 13
NFSPROC_RENAME 14
NFSPROC_LINK 15 – not supported
NFSPROC_READDIR 16
NFSPROC_READDIRPLUS 17
NFSPROC_FSSTAT 18
NFSPROC_FSINFO 19
NFSPROC_PATHCONF 20
NFSPROC_COMMIT 21
142
8 Adding NFS Support
8.5 Creating an NFS Server
8
Initializing an NFS File System for Export
myBlockSize = 512;
myTotalSize = 16777216; /* 16Mb */
! CAUTION: For NFS-exportable file systems, the device name absolutely must not
end in a slash.
After you have an exportable file system, call nfsExport( ) to make it available to
NFS clients on your network. Then mount the file system from the remote NFS
client using the facilities of that system. The following example shows how to
export the new file system from a VxWorks target called vxTarget, and how to
mount it from a typical UNIX system.
1. After the file system (/export in this example) is initialized, the following
routine call specifies it as a file system to be exported with NFS:
nfsExport ("/export", 0, FALSE, 0);
The first three arguments specify the name of the file system to export; the
VxWorks NFS export ID (0 means to assign one automatically); and whether
143
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
to export the file system as read-only. The last argument is a placeholder for
future extensions.
2. To mount the file system from another machine, see the system documentation
for that machine. Specify the name of the VxWorks system that exports the file
system, and the name of the desired file system. You can also specify a
different name for the file system as seen on the NFS client.
! CAUTION: On UNIX systems, you normally need root access to mount file systems.
144
9
Adding Support for
Network Applications
145
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
9.1 Introduction
This chapter describes the network application protocols implemented by the
Wind River Network Stack, and the configuration components and parameters
associated with each.
In support of remote login, the Wind River Network Stack includes the RSH
protocol as well as implementations of rlogin and telnet. Both rlogin and telnet
have been modified to support the identification of the remote site using either an
IPv4 or an IPv6 address.
The Wind River Network Stack implements the remote file access protocols RSH,
FTP, and TFTP for use with either IPv4 and IPv6 addresses. Using these protocols,
a VxWorks target can access the files on a remote networked machine as easily as
if the files were local to the VxWorks system. Going the other way, the Wind River
Network Stack implementations of these protocols (except RSH) let remote
networked machines access files on a VxWorks target just as transparently.
Programs running on the host need not know that the files they use are maintained
on the VxWorks system.
If your application requires direct access to the RSH, FTP, and TFTP protocol
implementations, it can do so. To simplify remote file access using the RSH or FTP
protocols, the Wind River Network Stack includes netDrv. Using this driver, you
can open, read, write, and close files located on remote systems without needing
to manage the details of the underlying protocol used to effect the transfer of
information. For more information on how to do this, see 9.12 Creating a netDrv
Device for RSH or FTP, p.176. For additional information, see the reference entries
for the following libraries: remLib, ftp6Lib, ftpd6Lib, tftpLib, and tftpdLib.
9.2 Ping
Packet InterNet Grouper (PING) is used to test of whether a particular host is
reachable and operating properly on the network. Ping works by sending ICMP
“echo request” packets to the target host and listening for replies (ICMP “echo
response” packets). The Wind River Network Stack implements the ping
application protocols for IPv4 and IPv6.
146
9 Adding Support for Network Applications
9.2 Ping
The Wind River Network Stack supports the following ping client configuration
components:
■
PING ICMP Client
■
PING6 ICMP Client
These components are all listed under the
Network Components > Network Applications folder in Workbench.
9
The INCLUDE_PING component pulls in pingLib, the library that implements the
IPv4 ping( ) utility. By calling ping( ), you can check the network connection to a
remote host. The remote host must be running TCP/IP networking code that
responds to ICMP echo request packets. The ping( ) routine is re-entrant and thus
can be called concurrently from many tasks.
NOTE: When using ping( ) programmatically, you may want to use the
PING_OPT_SILENT option to suppress output. See the ping( ) reference entry for
more information on this and other ping( ) options.
147
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
9.3 DNS
Domain Name Server (DNS) is a distributed database that most TCP/IP
applications can use to translate host names to IP addresses and back. DNS uses a
client/server architecture. The client side is known as the resolver. The server side
is called the name server. For detailed information on DNS, see RFC 1034 and RFC
1035. For a description for IPv6 records, see RFC 3596. The Wind River
Network Stack includes both a resolver and a server.
The Wind River Network Stack implementation of the resolver closely follows the
4.4 BSD resolver implementation, differing in the way it handles the hostent
structure.
The 4.4 BSD resolver is a library that links with each process and uses static
structures to exchange data with the process. This is not possible under VxWorks,
which uses a single copy of the library that it shares among all the tasks in the
system. All applications using the resolver library must provide their own buffers.
Thus, the routines resolvGetHostByName( ) and resolvGetHostByAnyAddr( )
require two extra parameters For more information, see the reference entries for
resolvGetHostByName( ) and resolvGetHostByAnyAddr( ).
The Wind River Network Stack resolver library uses UDP to send requests to the
configured name servers. The resolver also expects the server to handle any
recursion necessary to perform the name resolution. You can configure the
resolver at initialization or at run-time.1
In addition, you can configure how the resolver library responds to a failed name
server query. Either the resolver looks in the static host configuration table
immediately after the failed query, or the resolver ignores the static table.2 The
default behavior of the resolver is to query only the name server and ignore the
static table.
148
9 Adding Support for Network Applications
9.3 DNS
The resolver has been fully integrated into the Wind River Network Stack.
Existing applications can benefit from the resolver without needing to make any
code changes. This is because the code internal to hostGetByName( ) and
hostGetByAddr( ) has been updated to use the resolver.3
Thus, all you need do to take advantage of the resolver is to include it in your stack
and configure it (configuring the resolver involves specifying the server address
and domain).
NOTE: The current Wind River DNS resolver supports the feature set found in the
BIND 8.x DNS resolver only. Thus, it does not yet support features such as
DNAMEs and Bitstring.
9
Configuring VxWorks for DNS
The Wind River Network Stack supports the following DNS resolver
configuration component:
■
Domain Name Service Client
■
Domain Name Service Client Debug Output
This component is listed under the
Network Components > Network Applications folder in Workbench.
NOTE: If you include the DNS resolver, INCLUDE_DNS_RESOLVER, you will need
to specify functioning values for its domain and domain server configuration
parameters.
149
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
RESOLVER_DOMAIN
RESOLVER_DOMAIN_SERVER
Synopsis: The IPv4 or IPv6 address of the DNS server to contact with queries.
Default: "192.168.0.6"
RES_TIMEOUT_CFG
150
9 Adding Support for Network Applications
9.3 DNS
RETRY_CFG
RES_OPTIONS_CFG
NSCOUNT_CFG
Increase this parameter value if you will query more than one DNS server.
This behavior can be helpful if the primary DNS server is unable to send a
reply.
151
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
DNS_DEBUG
9.4 SNTP
The Simple Network Time Protocol (SNTP) is a less complex form of the Network
Time Protocol (NTP) that does not require storing information about previous
communication. NTP is a protocol for synchronizing the clocks of computer
systems over packet-switched, variable-latency data networks. NTP uses UDP
port 123 as its transport layer.
The Wind River Network Stack supports the following SNTP client and server
configuration components:
■
SNTP Client
■
SNTP Server
These components are listed under the
Network Components > Network Applications folder in Workbench.
152
9 Adding Support for Network Applications
9.4 SNTP
SNTP Client
SNTPC_PORT
SNTP Server
Using SNTP
Depending on the value of the SNTP Server Mode Selection (set by the
configuration parameter SNTPS_MODE), the server executes either in
SNTP_PASSIVE or SNTP_ACTIVE mode. In SNTP_PASSIVE mode, the server waits
for requests from clients and sends replies containing an NTP timestamp. In
SNTP_ACTIVE mode, the server periodically transmits NTP timestamp
information at fixed intervals.
When executing in active mode, the SNTP server determines the target IP address
and broadcast interval using the configuration parameters:
■
SNTPS_DSTADDR – SNTP Server Destination Address
■
SNTPS_INTERVAL – SNTP Server Update Interval
153
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
By default, the server transmits the timestamp information to the local subnet
broadcast address every 64 seconds. To change these settings after system startup,
call the sntpsConfigSet( ) routine. The SNTP server operating in active mode can
also respond to client requests as they arrive.
The SNTP Client/Server Port (configuration parameter SNTP_PORT) assigns the
source and destination UDP port. The default port setting is 123 as specified by the
RFC 1769.
Finally, the SNTP server requires access to a reliable external time source. To do
this, you must provide a routine of the form:
STATUS sntpsClockHook (int request, void *pBuffer);
Until this routine is hooked into SNTP, the server cannot provide timestamp
information. There are two ways to hook this routine into the SNTP server. The
first is to configure VxWorks with the SNTPS Time Hook (configuration parameter
SNTPS_TIME_HOOK) set to the appropriate routine name. You can also call
sntpsClockSet( ). For more information, see the sntpsClockSet( ) reference entry.
If you include INCLUDE_SNTPS, you can configure the SNTP Server at build time
using the following parameters:
SNPTS_MODE
SNTPS_PORT
154
9 Adding Support for Network Applications
9.5 FTP
SNTPS_DSTADDR
SNTPS_INTERVAL
SNTPS_TIME_HOOK
9.5 FTP
File Transfer Protocol (FTP) is the standard protocol for exchanging files over any
TCP/IP network. The FTP server is the computer that listens on the network for
connection requests from another computer. This computer is the FTP client, which
requests and connects to the FTP server, using FTP client software. The FTP client
can then manipulate files on the server, including uploading, downloading,
renaming, and deleting them.
155
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The Wind River Network Stack supports the following FTP client and server
configuration components usable for an FTP a client, a server, and anonymous
login:
■
FTP Client
■
FTPv6 Server Security
■ Anonymous FTP
■ FTP6 Client
■ FTP6 Server
These components are listed under the
Network Components > Network Applications folder in Workbench.
FTP Client
The INCLUDE_FTP component pulls in the ftpLib library and other modules that
implement the File Transfer Protocol (FTP) Client for IPv4. For information on the
functionality supplied by this configuration component, see the ftpLib reference
entry.
This component supplies the following configuration parameters:
FTP_DEBUG_OPTIONS
FTP_TRANSIENT_MAX_RETRY_COUNT
156
9 Adding Support for Network Applications
9.5 FTP
FTP_TRANSIENT_RETRY_INTERVAL
FTP_TRANSIENT_FATAL
157
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
FTP_TIMEOUT
After sending a command to a server, an FTP client applies this timeout while
waiting for a reply. A value of zero defaults to FTP_REPLYTIMEOUTDEFAULT
(10 seconds).
Anonymous FTP
FTPD6_GUEST_1
FTPD6_GUEST_2
158
9 Adding Support for Network Applications
9.5 FTP
FTPD6_GUEST_3
FTPD6_GUEST_ROOT_DIR
FTPD6_GUEST_UPLOAD_DIR
FTPD6_GUEST_DIR_VALIDATE
FTP6 Client
The INCLUDE_FTP6 component pulls in the modules that implement the File
Transfer Protocol (FTP) Client for IPv6. Including this component pulls in the
ftp6Lib library. For information on the functionality supplied by this
configuration component, see the ftp6Lib reference entry.
The configuration parameter for this component is used as a parameter to the
ftpd6LibInit( ) call made from the network stack initialization code.
ftpd6LibInit (FTP6_REPLYTIMEOUT);
FTP6_REPLYTIMEOUT
159
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
FTP6 Server
For information on the ftpd6Init( ) parameters, see the ftpd6Init( ) reference entry.
This component contains the following configuration parameters.
FTPD6_OPTIONS_STRING
FTPD6_LOGINRTN
FTPD6_SSIZE
Synopsis: Specifies the stack size for the primary server task.
Default: 0
9.6 TFTP
Trivial File Transfer Protocol (TFTP) is a simple file transfer protocol used to read
and write files to a remote server. TFTP has the functionality of a very basic form
of FTP; it uses a minimal amount of memory, cannot list directory contents, and
has no authentication or encryption mechanisms. Unlike FTP, which uses the TCP
transport layer protocol (port 21), TFTP uses the UDP (port 69) as its transport
protocol.
160
9 Adding Support for Network Applications
9.6 TFTP
The Wind River Network Stack supports the following TFTP client and server
configuration components:
■
TFTP Client
■
TFTP Server
These components are listed under the
Network Components > Network Applications folder in Workbench.
TFTP Client
9
The INCLUDE_TFTP_CLIENT component pulls tftpLib and other modules that
implement the client side of the Trivial File Transfer Protocol (TFTP) for IPv4 and
IPv6. TFTP is implemented on top of the Internet User Datagram Protocol (UDP)
and conforms to the RFC 1350 recommendations for packet format.
Unlike FTP and RSH, TFTP requires no authentication; that is, the remote system
does not require an account or password. The TFTP client is able to access only
those files that the remote system considers publicly readable.
The TFTP client is useful at boot time, when you can use it to download a VxWorks
image from the boot host. For more information on the functionality associated
with this component, see the reference entry for tftpLib.
The INCLUDE_TFTP_CLIENT component has no configuration parameters and
requires the INCLUDE_BSD_SOCKET component.
NOTE: Changes to the TFTP client make it necessary that the application run at a
priority less than that of tNetTask. Otherwise, calls such as tftpXfer( ) will fail.
This change is consistent with the general advice that network applications should
run at a priority less than that of tNetTask. Previously, the TFTP client would
work even if it was running at a higher priority.
To help you transfer files from a remote TFTP host, this module supplies two
high-level interfaces: tftpXfer( ) and tftpCopy( ). For detailed information on these
routines, see the reference entry for tftpLib.
161
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
On a host running UNIX or some UNIX variant, the host-resident Internet daemon
starts the TFTP server. For added security, some hosts (for example, Sun hosts)
default to starting the TFTP server with the secure (-s) option enabled. If -s is
specified, the server restricts host access by rooting all TFTP requests into the
directory specified (for example, /tftpboot).
For example, if the secure option was set with -s /tftpboot, a TFTP request for the
file /vxBoot/vxWorks is satisfied by the file /tftpboot/vxBoot/vxWorks rather than
the expected file /vxBoot/vxWorks.
To disable the secure option on the TFTP server, edit /etc/inetd.conf and remove
the -s option from the tftpd entry.
TFTP Server
For information on how to use the parameters to this routine, see the
usrTftpdStart( ) reference entry. This component contains the following
configuration parameters.
TFTP_SERVER_STACKSIZE
The default of zero tells the system to use the internal default stack size, 12000.
162
9 Adding Support for Network Applications
9.7 RSH
TFTP_SERVER_DIRECTORYNAMES
TFTP_SERVER_NOCONTROL
TFTP_SERVER_MAXCONNECTIONS
9.7 RSH
Rsh (remote shell) is a command-line program that executes shell commands as a
different user on a remote computer across a network. The remote system on
which the rsh executes needs to be running the rshd daemon.
The Wind River Network Stack rsh implementation does not include an
equivalent to the rshd daemon. Thus, remote systems cannot use rsh to run
commands remotely on a Wind River Network Stack host.
The Wind River Network Stack supports the following rsh configuration
components:
■
Remote Command
This component is listed under the
Network Components > Network Applications folder in Workbench.
163
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Remote Command
RSH_STDERR_SETUP_TIMEOUT
Synopsis: The timeout (if any) on the wait for a remote response.
Default: -1
Use this parameter to specify how long an rcmd( ) call should wait for a return
from its internal call to select. The default value for this parameter is -1, which
is no timeout or WAIT_FOREVER.
For more information on how to use RSH under the Wind River Network Stack,
see the remLib reference entries.
Included in an RSH request is the name of the requesting user. The receiving host
can then honor or ignore the request based on the user name and the site from
which the request originates. How you set up a receiving system to allow access to
particular users and sites depends on the specifics of the receiving system’s OS and
networking software.
For Windows hosts, support for RSH is determined by your version of Windows
and the networking software you are using. See that documentation for details.
For UNIX hosts running the BSD rshd, an RSH request is honored only if it
originated on a known system by a user with local login privileges (although you
can use the -l (dash el) option to configure the BSD rshd to omit this verification).
The list of known systems is specified in either of two locations. The first location,
the /etc/hosts.equiv file (UNIX) or the /etc/hosts.allow file (LINUX), maintains a
list of all systems from which remote access is allowed for all users that have local
164
9 Adding Support for Network Applications
9.8 RPC
9.8 RPC
9
The Remote Procedure Call (RPC) protocol, as specified by RFC 1831, is a protocol
that allows a process on one machine to call a procedure that is executed by
another process on another machine. It implements a client-server model of task
interaction. In this model, client tasks request services of server tasks and then wait
for replies. RPC formalizes this model and provides a standard protocol for
passing requests and returning replies.
165
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The Wind River Network Stack supports the following RPC configuration
components:
■
RPC
■
XDR
■
XDR Boolean Support
These components are listed under the
Network Components > Network Applications > RPC Components folder in
Workbench.
RPC
The INCLUDE_RPC component pulls in rpcLib and other modules that implement
the Remote Procedure Call (RPC) protocol. For information on the externally
callable functions associated with the modules in this component, see the rpcLib
reference entry.
XDR
166
9 Adding Support for Network Applications
9.9 RLOGIN
9.9 RLOGIN
RLOGIN allows remote access to and from a target. The Wind River
implementation of RLOGIN supports both IPv4 and IPv6.
The Wind River Network Stack supports the following RPC configuration
components:
■
RLOGIN
This component is listed under the 9
Network Components > Network Applications folder in Workbench.
RLOGIN
When connecting with a Windows host system, the ability of VxWorks to remotely
login depends on your version of Windows and the networking software you are
using. See that documentation for details.
When connecting with a UNIX host system, access permission must be granted to
the VxWorks system by entering its system name either in the .rhosts file (in your
home directory) or in the /etc/hosts.equiv file. For more information, see Enabling
Access to an RSH User, p.164.
167
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Because this application must interact with a user, it requires the active shell to be
locked to access standard IO. The shellLock( ) API is not supported for use in an
RTP. Thus, instead of using rtpSp( ), you launch the client through a shell
command interpreter. To do this, make sure that the image includes:
■
INCLUDE_SHELL_INTERP_CMD
■ INCLUDE_SHELL_INTERP_C
In a target shell for such an image, you can type:
-> cmd
# rlogin.vxe "10.34.10.21"
9.10 Telnet
Telnet is an application protocol that provides command-line login sessions
between hosts on a network. The Wind River implementation of telnet supports
both IPv4 or IPv6.
The Wind River Network Stack supports the following telnet configuration
components:
■ Telnet Server
■ Telnet Client
■
TELNET/FTP password protection
These components are listed under the
Network Components > Network Applications folder in Workbench.
168
9 Adding Support for Network Applications
9.10 Telnet
Telnet Server
TELNETD_MAX_CLIENTS
TELNETD_TASKFLAG
TELNETD_PORT
169
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
TELNETD_PARSER_HOOK
170
9 Adding Support for Network Applications
9.10 Telnet
Telnet Client
NOTE: By default, the client sends an ECHO at start up. It works in default mode
only when it receives DO and DONOT from a remote telnet server.
LOGIN_PASSWORD
LOGIN_USERNAME
Because this application must interact with a user, it requires the active shell to be
locked to access standard IO. The shellLock( ) API is not supported for use in an
RTP. Thus, instead of using rtpSp( ), you should launch the client through a shell
command interpreter. To do this, make sure that the image you build includes the
components:
■
INCLUDE_SHELL_INTERP_CMD
■
INCLUDE_SHELL_INTERP_C
171
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The VxWorks telnet client can decode commands (ICA) sent from a remote host,
but, for the most part, it does not process them. Table 9-1 lists the unsupported
commands.
Data Mark 242 The data stream portion of a Synch. This should
always be accompanied by a TCP Urgent notification.
DO option code 253 Indicates the request that the other party perform, or
confirmation that you are expecting the other party to
perform, the indicated option.
172
9 Adding Support for Network Applications
9.11 Changing the Default Login for FTP, FTPv6, and Telnet
DON'T option code 254 Indicates the demand that the other party stop
performing, or confirmation that you are no longer
expecting the other party to perform, the indicated
option.
The VxWorks implementation of the send command supports only the ECHO and
TERMINALTYPE options. Not supported are the following send options:
9.11 Changing the Default Login for FTP, FTPv6, and Telnet
VxWorks provides a default user name and password for logging in to FTP,
FTPv6, and Telnet. If you enable security for these applications, you should reset
the user name and password to prevent unauthorized access from a source that is
familiar with the default values. In building these applications, security is enabled
when you include either of the following build components:
■
For FTP and Telnet: TELNET/FTP password protection (INCLUDE_SECURITY)
■
For FTPv6: FTPv6 server security (INCLUDE_FTPD6_SECURITY)
FTPv6 server security (INCLUDE_FTPD6_SECURITY)
173
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Before you build, you can change the login user name and password in the
configAll.h file or from within Workbench. In both cases, you first need to obtain
an encrypted version of the password you want to use.
After you build, you can change the user name and password from the VxWorks
development shell. In this case, you need to first obtain an encrypted version of the
password.
174
9 Adding Support for Network Applications
9.11 Changing the Default Login for FTP, FTPv6, and Telnet
3. To change the default login user name, locate the following line and replace
target with the user name of your choice:
#define LOGIN_USER_NAME "target"
4. To change the default login password, locate the following line and replace
RcQbRbzRyc with the encrypted password you obtained at Step 1:
#define LOGIN_PASSWORD "RcQbRbzRyc" /* "password" */
Figure 9-1 TELNET/FTP password protection parameters (user name and password)
To change the default login user name and password after building VxWorks:
1. Obtain an encrypted password, as described in Obtaining an Encrypted
Password, p.174.
175
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
2. From the VxWorks development shell command line, delete the default login
values, target and password, as follows:
loginUserDelete "target", "password"
3. Enter new login values, as follows:
loginUserAdd "username", "password"
where password is the encrypted password you obtained at Step 1.
176
9 Adding Support for Network Applications
9.12 Creating a netDrv Device for RSH or FTP
Setting the User ID for Remote File Access with RSH or FTP
All FTP and RSH requests to a remote system include the user name. All FTP
requests include a password as well as a user name. From VxWorks, you can
specify the user name and password for remote requests by calling iam( ):
iam ("username", "password");
The first argument to iam( ) is the user name that identifies you when you access
remote systems. The second argument is the FTP password. This is ignored if RSH
is being used, and can be specified as NULL or 0 (zero).
For example, the following command tells VxWorks that all accesses to remote
systems with RSH or FTP are through user darger, and if FTP is used, the password
is unreal: 9
-> iam "darger", "unreal"
For a VxWorks system to have access to a particular file on a host, you must set up
permissions on the host system appropriately. The user name seen from the host
must have permission to read that file (and write it, if necessary). That user name
must also have permission to access all directories in the path. The easiest way to
check this is to log in to the host with the user name VxWorks uses, and try to read
or write the file in question. If you cannot do this, neither can the VxWorks system.
Although you can use netDrv at boot time to download a run-time image, netDrv
is not limited to boot time or run-time images. It is a generic I/O device that you
can use to access files on a remote networked system. To include netDrv, use the
INCLUDE_NET_DRV configuration component.
177
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
To use netDrv, you must create a netDrv instance for each system on which you
want to access files. You can then use this device in standard VxWorks I/O device
calls such as open( ), read( ), write( ), and close( ). To create a netDrv device, call
netDevCreate( ):
netDevCreate ("devName", "host", protocol);
After a network device is created, files on that host are accessible by appending the
host pathname to the device name. For example, the filename
mars:/usr/darger/myfile refers to the file /usr/darger/myfile on the mars system.
You can read or write to this file as if it were a local file. For example, the following
shell command opens that file for I/O access:
-> fd = open ("mars:/usr/darger/myfile", 2)
178
9 Adding Support for Network Applications
9.12 Creating a netDrv Device for RSH or FTP
password. When the FTP password is present, netDrv uses FTP. Otherwise,
netDrv uses RSH.4
Consider the system shown in Figure 9-2. Using a network connection, CPU 1 can
use FTP to download its run-time image from the storage device accessible
through CPU 0. Note that the client must include a non-empty ftp password field
in its boot parameter.
Including an FTP password tells netDrv to use FTP. Whether the FTP server on
CPU 0 checks the validity of the password depends on whether the FTP server on
CPU 0 has been configured with security turned off (the default) or on. The
relevant configuration component is INCLUDE_FTPD6_SECURITY.
The FTP server daemon is initialized on the VxWorks server based on the
configuration. The relevant configuration parameter is INCLUDE_FTP6_SERVER. 9
See also the reference entry for ftpd6Lib.
vxServer vxClient
Disk
10.27.0.1 10.27.0.2
4. When creating a boot program that must download an image using an RSH or an FTP client,
you must make sure that you include those components in the program.
179
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
180
10
Working with DHCPv4
and DHCPv6
10.1 Introduction
The purpose of the BOOTP, DHCP, and DHCPv6 protocols is to provide a
mechanism by which a host can retrieve configuration parameters (in particular,
an IP address) from a remote server. The Wind River Network Stack includes a
DHCP client, server, and relay agent. Both the client and server implementations
support all options described in RFC 2132.
The DHCP (RFC 2131) protocol is the successor to BOOTP, and an extension of it,
designed to supply clients with all of the Internet configuration parameters
defined in the Host Requirements documents (RFC 1122 and RFC 1123) without
manual intervention. As such, DHCP can provide all that BOOTP provides and
181
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
more. In fact, the RFCs for DHCP require that the server handle requests (see RFC
2132) from BOOTP clients. For this reason, although the Wind River
Network Stack includes a BOOTP implementation, ongoing developments will be
addressed in DHCP and not BOOTP.
This chapter provides per-component descriptions of all the components
associated with the Wind River DHCPv4 and DHCPv6 implementations.
Currently, the standard VxWorks boot program supports IPv4 but not IPv6,
although it can download a run-time image that does support IPv6.
The Wind River Network Stack supports the following DHCPv4 configuration
components:
■
DHCPv4 Run-time Client
■
DHCPv4 Boot-Time Client
■
DHCPv4 Client Timestamp Storage
■
DHCPv4 Client Lease Verification/Assignment
■
DHCPv4 Client Common Library
■
DHCP Client Show Routines
■
DHCP Server
■
DHCP Relay Agent
■
DHCP Shared Files for Server and Relay Agent
■
DHCP Core files
These components are all listed under the
Network Components > Network Applications > DHCP Components folder in
Workbench.
182
10 Working with DHCPv4 and DHCPv6
10.2 Configuring VxWorks for DHCPv4
NOTE: The asynchronous use of DHCP requires that you provide an event hook
routine to handle lease events. For more information, see the
dhcpcEventHookAdd( ) reference entry.
NOTE: This component pulls in the standard DHCP client for use in the image
loaded by a boot program. It is not the reduced DHCP client implementation
designed for use in a boot program. That reduced client is associated with the
INCLUDE_DHCPC_BOOT component. See DHCPv4 Boot-Time Client, p.185.
DHCPC_CPORT
DHCPC_DEFAULT_LEASE
183
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
DHCPC_MAX_LEASES
DHCPC_MAX_MSGSIZE
Synopsis: Specifies the maximum size (in bytes) for a DHCP message.
Default: 590
DHCPC_MIN_LEASE
Keep in mind that the DHCP client rejects all offers whose duration is less than
the minimum lease. Therefore, setting the DHCP Client Minimum Lease value
too high could prevent the retrieval of any configuration parameters.
DHCPC_OFFER_TIMEOUT
DHCPC_SPORT
DHCPC_DISCOVER_RETRIES
Synopsis: DHCP client discover retry limit, specifies the maximum number
of DHCPDISCOVER attempts before timeout.
Default: 67
184
10 Working with DHCPv4 and DHCPv6
10.2 Configuring VxWorks for DHCPv4
DHCPC_CPORT 10
DHCPC_DEFAULT_LEASE
DHCPC_MAX_MSGSIZE
DHCPC_MIN_LEASE
DHCPC_OFFER_TIMEOUT
DHCPC_SPORT
185
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
186
10 Working with DHCPv4 and DHCPv6
10.2 Configuring VxWorks for DHCPv4
DHCPS_MAX_MSGSIZE
Synopsis: Maximum message size for the DHCP server or relay agent.
Default: 590
The default value allows for a minimum DHCP message in an Ethernet frame.
187
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
DHCPS_CPORT
DHCPS_SPORT
Synopsis: The host port monitored by DHCP servers and relay agents.
Default: 67
DHCP_MAX_HOPS
This value limits the number of subnets that a DHCP message can cross
(prevents network flooding). The maximum valid value is 16.
DHCP Server
188
10 Working with DHCPv4 and DHCPv6
10.2 Configuring VxWorks for DHCPv4
DHCPS_ADDRESS_HOOK
This parameter lets you specify the name of an optional storage routine. For
more information, see Storing and Retrieving Active Network Configurations,
p.198.
DHCPS_DEFAULT_LEASE
This constant specifies the default lease length in seconds. This value applies
if no explicit value is set in the address pool.
10
DHCPS_LEASE_HOOK
This constant specifies the name of the routine that handles non-volatile
storage of the active leases. For more information, see Storing and Retrieving
Active Network Configurations, p.198
189
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
is usually temporary. To continue using the assigned parameters, the client must
periodically contact the issuing server to renew the lease.
! WARNING: The Wind River development tools do not currently have any way to
discover or respond to a change in the target’s IP address. Such a change breaks the
network connection. In response, you must manually reconnect the tools to the
target’s new IP address. During development, this is rarely a serious problem, and
you can avoid it by having the DHCP server issue an infinite lease on the target’s
IP address.
In the code above, the dhcpcInit( ) call used a value of TRUE for the autoconfig
parameter. This automatically includes a request for a subnet mask and broadcast
address in the cookie (pLeaseCookie). To request additional options for this lease
the code makes a call to dhcpcOptionAdd( ). Because the DHCPv4 protocol
190
10 Working with DHCPv4 and DHCPv6
10.3 Working with the DHCPv4 Client
case DHCPC_LEASE_INVALID : 10
/* this case gets called when the client gives up... */
printf(" DHCPC_LEASE_INVALID \n ");
break;
default:
printf(" leaseEvent = %d \n ", leaseEvent );
break;
}
}
To query the local DHCPv4 client for a parameter value from the lease information
it has retrieved, call dhcpcOptionGet( ). This routine checks whether the lease
associated with a particular lease cookie is valid and whether the server provided
the requested parameter. If so, dhcpcOptionGet( ) copies the parameter value into
a buffer. Otherwise, it returns ERROR. A call to dhcpcOptionGet( ) generates no
network traffic; it queries the local DHCPv4 client for the information it needs.
The following sample demonstrates the use of this routine:
struct in_addr webServer;
STATUS result;
int length = sizeof (struct in_addr);
char ipAddress[INET_ADDR_LEN];
...
result = dhcpcOptionGet (pLeaseCookie, _DHCP_DFLT_WWW_SERVER_TAG,
&length, (char *) &webServer);
if (result == OK)
{
inet_ntoa_b (webServer, ipAddress);
printf("Primary web server: %s\n", ipAddress);
}...
191
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
NOTE: To check on parameters associated with a lease established at boot time, use
the pDhcpcBootCookie global variable as the lease cookie for dhcpcOptionGet( ).
NOTE: If you already have an IP address and do not want another but want to
query the server for any other information it has for you, call dhcpcInformGet( ).
NOTE: In the sections that follow, the examples talk of editing tables defined in
usrNetDhcprCfg.c, usrNetDhcpcCfg.c, and usrNetDhcpsCfg.c. If you are doing
a BSP build, the table definitions are in:
installDir/vxworks-6.n/target/src/config/usrNetwork.c
In addition to setting values for the parameters associated with the DHCP relay
agent, you also need tell the relay agent how to find other DHCP relay agents or
servers with whom to relay DHCP requests. To do this, you must edit the
dhcprTargetTbl[ ] table defined in usrNetDhcprCfg.c. This table is of the form:
DHCP_TARGET_DESC dhcprTargetTbl [] =
{
/*
IP address of DHCP target servers
---------------------------------
*/
/* {"192.0.2.1"}, */
};
192
10 Working with DHCPv4 and DHCPv6
10.4 Working with the DHCPv4 Relay Agent
Each entry in the table must specify a valid IP address for a DHCP server on a
different subnet than the relay agent. The relay agent transmits a copy of all DHCP
messages sent by clients to each of the specified addresses. The agent does not set
the IP routing tables so that the specified target addresses are reachable.
The relay agent forwards DHCP client messages through only a limited number of
targets: the DHCP Server/Relay Agent Network Radius. When the configured
value is exceeded, the message is silently discarded. This value is increased only
when a DHCP agent forwards the message. It is completely independent of the
similar value used by IP routers. RFC 1542 specifies the maximum value of 16 for
this constant. The default hops value is four.
Beyond providing the list of target addresses, and optionally changing the
maximum number of hops permitted, no further action is necessary. The DHCP
relay agent executes automatically whenever it is included in the image.
10
Use a dhcprIfTbl to identify which interfaces the relay agent should monitor and
use. For example:
/*
* This table contains a list of interfaces that the relay agent
* will listen to. The boot device is used when the table's
* first entry is the null string.
*/
DHCPR_IF_DESC dhcprIfTbl [] =
{
{""} /* Use primary interface */
/* Sample interface entries. */
/* {"fei1"}, */
/* {"ln0"} */
};
By default, the table is empty and the relay agent notices only the boot interface.
However, to function correctly, the relay agent needs at least two interfaces. Thus,
you must populate this table with the names of the other interfaces that the relay
agent should monitor and use.
The agent does not start or configure the interfaces listed in dhcprIfTbl. The
primary interface (usually the boot device) is automatically configured by the
general network initialization code. Use the INCLUDE_ADDIF component to
configure an additional interface.
193
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The target configured as a relay agent must have IP forwarding enabled: set the
IPFORWARDING_CFG parameter to TRUE. By default, this parameter is set to
FALSE.
The Wind River DHCP server accepts relayed messages only from those DHCP
relay agents (identified by IP address and subnet number) that are listed in
dhcpsRelayTbl[ ] defined in usrNetDhcpsCfg.c.
DHCPS_RELAY_DESC dhcpsRelayTbl [] =
{
/*
IP address of agent Subnet Number
-------------------- -------------
*/
/* {"192.0.2.254", "192.0.2.0"}, */
};
This table acts as an authorization list. If messages arrive from relay agents not
listed in the table, the messages are ignored. Consider the example in Figure 10-1.
194
10 Working with DHCPv4 and DHCPv6
10.5 Working with the DHCPv4 Server
195
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
and name that routine in the DHCPS_LEASE_HOOK parameter associated with this
configuration component. For information on how to write this routine, see Storing
and Retrieving Active Network Configurations, p.198.
Finally, if your DHCP server needs to support DHCP relay agents, you will need
to identify those agents in dhcpsRelayTbl[ ]. For more information, see
Configuring the Relay Agent Table in the Wind River DHCP Server, p.198.
This table supplies the list of interfaces to which the server will listen. To configure
the server to use the boot device, set up the table’s first entry to be a null string.
DHCPS_IF_DESC dhcpsIfTbl [] =
{
{""} /* Use primary interface */
/* Sample interface entries. */
/* {"fei1"}, */
/* {"ln0"} */
};
To determine its initial configuration data, the Wind River DHCP server uses the
dhcpsLeaseTbl[ ] defined in usrNetDhcpsCfg.c. This table describes the server’s
pool of network configuration parameter sets. It has the following format:
DHCPS_LEASE_DESC dhcpsLeaseTbl [] =
{
/* {"Name", "Start IP", "End IP", "parameters"} */
};
196
10 Working with DHCPv4 and DHCPv6
10.5 Working with the DHCPv4 Server
Each entry in this lease table must include a unique entry name of up to eight
characters and an IP address range for assignment to requesting clients. The
parameters field contains a colon-separated list of optional parameters for
inclusion in the DHCP server’s response. If subnetting is in effect, a critical entry
in the parameters field is the subnet mask (snmk). The server does not issue
addresses to clients that would change their current subnet. The address pool must
specify a correct subnet mask if the default class-based mask is not valid.
You can find complete description of the parameters field in the reference entries
for the DHCP server. Any parameters not specified take default values according
to the Host Requirements Documents (RFC 1122 and RFC 1123). The server can
also read additional entries from an optional storage hook (Storing and Retrieving
Active Network Configurations, p.198). The most commonly used lease table
parameters are:
clid 10
Indicates that this is a manual lease. Such a lease is issued only to the client
with the matching type:id pair. The address range for these entries must
specify a single IP address. The sample shown for “ent1” uses the
hardware address that the Wind River DHCP client uses for an identifier.
maxl
Indicates that this lease is dynamic. This parameter specifies the maximum
lease duration granted to any requesting client. The automatic lease
illustrated in the third sample entry is implied by the assignment of an
infinite value for maxl.
albp
Indicates a special type of automatic lease. Setting the albp parameter to
true in the fourth entry marks this lease as suitable for BOOTP clients that
contact this DHCP server.
siad
Specifies the (boot) server Internet address, the IP address of the boot host.
Of the parameters shown above, the first three, clid, max1, and albp, indicate lease
types. The server uses the lease type to select one of the three supported
mechanisms for IP address allocation. With manual allocation, DHCP simply
conveys the related manual lease to the client. If dynamic allocation is used, the
protocol assigns one of the dynamic leases to the client for a finite period.
Automatic allocation assigns a permanent IP address from the corresponding
automatic leases.
Dynamic allocation is the only method that allows reuse of addresses. The
allocation type defines the priority for assigning an IP address to a DHCP client.
197
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Manual allocations have the highest priority, and automatic allocations the lowest.
Among automatic leases, the preferred configurations are those available only to
DHCP clients.
Configuring the Relay Agent Table in the Wind River DHCP Server
If the DHCP server expects messages from relay agents, you must list those agents
(identified by IP address and subnet number) in the dhcpsRelayTbl[ ]. This table
acts as an authorization list. If messages arrive from relay agents not listed in the
table, the messages are ignored.
DHCPS_RELAY_DESC dhcpsRelayTbl [] =
{
/*
IP address of agent Subnet Number
-------------------- -------------
*/
/* {"192.0.2.254", "192.0.2.0"}, */
};
Your lease storage routine must store and retrieve active network configurations.
To install the routine you created, set DHCPS_LEASE_HOOK (a configuration
parameter) to a string containing the routine name. The address storage routine
uses the following prototype:
198
10 Working with DHCPv4 and DHCPv6
10.5 Working with the DHCPv4 Server
STATUS dhcpsAddressStorageHook
(
int op, /* requested storage operation */
char * pName, /* name of address pool entry */
char * pStartIp, /* first IP address in range */
char * pEndIp, /* last IP address in range */
char * pParams /* lease parameters for each address */
)
199
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
DHCPS_STORAGE_READ
Tells your storage routine to retrieve network configurations. Each read must
copy the data (stored by earlier writes) into the buffers provided. The returned
information must be of the same format provided to the write operation.
If a read completes successfully, your routine must return OK. If earlier reads
have retrieved all available data, or no data is available, your routine must
return ERROR. The server calls your routine with read requests until ERROR
is returned.
DHCPS_STORAGE_CLEAR
Used only in calls to your lease storage routine. This value tells your routine
that any data currently stored is no longer needed. Following this operation,
reads should return error until after the next write.
NOTE: If you are configuring address storage and lease storage hooks, remove the
comments from the hook declarations in the server configlette:
installDir/vxworks-6.n/target/config/comps/src/net/coreip/apps/
usrNetDhcpsCfg.c
/* Include these declarations if hooks are defined. */
/* IMPORT STATUS DHCPS_LEASE_HOOK (int, char *, int); */
/* IMPORT STATUS DHCPS_ADDRESS_HOOK (int, char *, int); */
200
10 Working with DHCPv4 and DHCPv6
10.6 Using DHCPv6
NOTE: The Wind River DHCPv6 implementation supports prefix delegation, but
it does not implement the full standard.
10
10.6.2 Configuring VxWorks for DHCPv6
201
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
DHCP6C_UPORT
DHCP6C_DPORT
DHCP6C_OPTION
DHCP6C_VERBOSE
DHCP6C_UPLINK_IF
DHCP6C_DOWNLINK_IF
DHCP6C_PRIORITY
DHCP6C_SIZE
DHCP6C_KEY_REALM_STRING
202
10 Working with DHCPv4 and DHCPv6
10.6 Using DHCPv6
DHCP6C_KEY_SECRET_STRING
DHCP6C_KEY_EXPIRE_STRING
DHCPv6 Server
■ INCLUDE_IPV6
■ INCLUDE_DISK_UTIL
■ INCLUDE_DOSFS_MAIN
■ INCLUDE_DOSFS_FMT
■ INCLUDE_XBD_RAMDRV
The INCLUDE_DHCP6S component contains the following configuration
parameters:
DHCP6S_UPORT
DHCP6S_DPORT
DHCP6S_CONF_FILE_NAME
203
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
DHCP6S_RAMDISK_SIZE
Synopsis: DHCPv6 Server Ram Disk Size, in bytes. Must be an even multiple
of 512.
Default: 512*32
DHCP6S_VERBOSE
DHCP6S_DOWNLINK_IF
DHCP6S_PRIORITY
DHCP6S_SIZE
DHCP6R_HOP_LIMIT
204
10 Working with DHCPv4 and DHCPv6
10.6 Using DHCPv6
DHCP6R_UPORT
DHCP6R_DPORT
DHCP6R_SRC_ADDR
DHCP6R_SERVER_ADDR 10
DHCP6R_VERBOSE
DHCP6R_UPLINK_IF
DHCP6R_DOWNLINK_IF
DHCP6R_PRIORITY
DHCP6R_SIZE
205
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
206
11
Creating Network Applications
as RTPs
11.1 Introduction
The core network stack functionality runs in the kernel only. This core network
stack functionality consists of implementations of fundamental networking
protocols such as IP, TCP, UDP as well as the network interface drivers and the
MUX functionality. Most network applications can run either in the kernel or as an
RTP, provided all services upon which they rely are also supported in RTPs.
NOTE: In the process of porting network applications to RTPs, Wind River has
exposed both the standard socket APIs and the routing socket APIs at the RTP
level. If you have an application that limits (or can limit) its interaction with the
network stack to standard or routing socket API calls, that application is a good
candidate for porting to run in an RTP.
For a listing of which applications have been ported to run as an RTP, see
Table 11-1. In this table, if the IP version is relevant to the application but the listing
does not specify either IPv4 or IPv6, assume it is the original IPv4-only application.
207
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Applications that are independent of the underlying IP version (those are DNS and
TFTP) are supported over both IPv4 and IPv6, although no special mention of this
is made in the table.
NFS ping
RIPng ping6
For an application that you have written to use network services, no changes are
required to run that application in the kernel. To run that application as an RTP,
you will need to make a few changes. This chapter provides information on how
to modify an existing network application to run as an RTP. Also included is
information on how RTPs can use sockets.
208
11 Creating Network Applications as RTPs
11.2 Network Applications Supported in RTPs
NOTE: The clients provided are intended as sample .vxe files. They are not
intended to be feature-complete production applications. However, the servers
(FTP, TFTP and RIP) are production applications as are ping and ping6. All others
are samples to use as starting points for your own implementations.
Using the DNS resolver within an RTP requires no special changes. Within your
application, call resolvInit( ) when you initialize the RTP, then proceed to use the
resolvLib library.
NOTE: To run the FTP server in an RTP, the kernel must include support for POSIX
timers. Use the INCLUDE_POSIX_TIMERS component to include POSIX timer
support in an image.
Running either the IPv4 or IPv6 FTP client as an RTP requires no special changes.
Within your application, call ftpLibInit( ) or ftp6LibInit( ) when you initialize the
RTP, then proceed to use the library.
209
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Internally, ping.vxe initializes the ping library, handles the ping request for the
requested number of packets, and then exits. Exiting shuts down the RTP. If you
specify a continuous ping, a ping with a number_of_packets value of 0, the ping
runs forever, or until you shut it down explicitly. The ping6.vxe RTP works much
the same way, but runs a different library.
Using the remLib functionality within an RTP requires no special changes. Within
your RTP, call remLibInit( ) when you initialize the RTP, then proceed to use the
resolvLib library routines such as rcmd( ) and rresvport( ).
To load the RIP RTP, call rtpSp( ). From a kernel shell, cd to the directory
containing the rip.vxe and run the command according to the following syntax:
-> rtpSp "path/rip.vxe parameter1 parameter2 parameter3 ... parameter9"
210
11 Creating Network Applications as RTPs
11.2 Network Applications Supported in RTPs
! WARNING: Do not set RIP_GATEWAY to 1 unless this really is the general gateway.
Setting this to 1 configures the RIP server to send out a default route (0.0.0.0) with
every routing update. This tells all the other listening servers that this server is the
11
default route for its subnet. This causes all packets to go to this router if they do not
have a route that matches an existing entry in their routing table.
211
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
parameter6—supply interval
The value of this parameter supplies the length of the interval, in seconds,
between successive route updates. The default value is 30.
parameter7—expire interval
The value of this parameter supplies the length of the interval, in seconds, after
which a stale route (a route that has not been refreshed by a neighbor's update)
is marked unreachable and deleted from the system routing table. Expired
routes are retained in RIP's routing table until the garbage timeout, parameter8,
so that their expiration can be announced in subsequent route updates. The
default value is 180 seconds.
parameter8—garbage interval
The value of this parameter supplies the length of the interval, in seconds, after
which a stale route is removed from RIP's routing table and not advertised
anymore.
parameter9—authentication type
The value of this parameter specifies the default authentication type. The valid
values for this parameter are as follows:
1 to specify M2_rip2IfConfAuthType_noAuthentication
2 to specify M2_rip2IfConfAuthType_simplePassword
3 to specify M2_rip2IfConfAuthType_md5
The rip.vxe application exits with a value of 1 on error and with value of 0 (zero)
on user termination. Sample usages:
> rtpSp "rip.vxe 1 0 0 1 1 30 180 300 1"
> rtpSp "rip.vxe 1 0 0 2"
> rtpSp "rip.vxe"
To shut down the RIP RTP in a controlled manner, use rtpKill( ) as follows:
-> rtpKill rtpId, 15
In the command above, substitute rtpId with the RTP ID of the RIP application.
This command ensures a proper shutdown of the application, which is preferred
to the abort that would be effected by a rtpDelete( ) call or an rtpKill(rtpId, 9) call.
212
11 Creating Network Applications as RTPs
11.2 Network Applications Supported in RTPs
For an application running in the kernel, you can manage that application by
invoking its management routines from the kernel shell or from another program
running in the kernel. An application in an RTP runs in its own private virtual
memory space. Consequently, the management routines for that application are
inaccessible from outside the RTP. For applications that allow run-time
configuration changes, applications such as RIP, this can be very limiting.
To overcome this limit, the RIP implementation ported to run in a VxWorks RTP
now supports a set of management routines that are callable from outside the RTP.
Internally, these management routines use a simple RPC-like mechanism to
communicate with the application running in the RTP.
To access the RIP management functions from outside the RTP, compile and link in
the ripCmdFuncs.c file supplied in:
installDir/vxworks-6.n/target/usr/apps/coreip/ripv4/ripCmdFuncs.c 11
This file depends upon ripAppDefs.h. Thus, when you copy ripCmdFuncs.c into
your project, you also need to copy in:
installDir/vxworks-6.n/target/usr/apps/coreip/ripv4/ripAppDefs.h
If working with a BSP build, make sure that you update you BSP’s Makefile to
build ripCmdFuncs.c.
The API supplied by ripCmdFuncs requires SNS support, as well as the SAL client
and the SAL server. To include these components in a build, make sure that you
include:
■ INCLUDE_SNS
■ INCLUDE_SAL_CLIENT
■
INCLUDE_SAL_SERVER
■ INCLUDE_UN_COMP
■ INCLUDE_UN
For details, see 11.4.1 Configuring VxWorks for the SAL Library, p.225.
To include these components in a BSP build, your BSP’s config.h must define the
following:
#define INCLUDE_SNS
#define INCLUDE_SAL_CLIENT
#define INCLUDE_SAL_SERVER
#define INCLUDE_UN_COMP
#define INCLUDE_UN
213
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
In this call, 0x12345 is the RTP ID for the RTP running the RIP application. This
RTP ID is returned as the value of the call that launched the RTP. Similarly, to call
ripIfAddrReset( ) for the RIP application running in an RTP with an ID of 0x12345,
you would call:
_ripIfAddrReset (0x12345, char * pIfName, char * pIfAddr, u_long mask1)
214
11 Creating Network Applications as RTPs
11.2 Network Applications Supported in RTPs
Using the rlogin client functionality within an RTP requires no special changes.
Within your RTP, call rlogInit( ) when you initialize the RTP, then proceed to use
the rlogLib library routines such as rlogin( ). The rlogin client is compatible with
both IPv4 and IPv6.
Using the Telnet client functionality within an RTP requires no special changes.
Within your RTP, call telnetcInit( ) when you initialize the RTP, then proceed to use
the telnetcLib library routines such as telnet( ).
Using the TFTP client functionality within an RTP requires no special changes.
Within your RTP, call tftpInit( ) when you initialize the RTP, then proceed to use
the tftpLib library routines within the RTP.
The RTP implementation of the TFTP Server (the Trivial File Transfer Protocol
daemon), tftpd.vxe, is supplied in:
instalDir/vxworks-6.n/target/usr/apps/coreip/tftpd/tftpdMain.c
This directory also contains a makefile that you can use to build the tftpd.vxe ELF
file. To load this RTP, call rtpSp( ). From a kernel shell, cd to the directory
containing the tftpd.vxe and try the following:
-> rtpSp "tftpd.vxe"
Because this server is implemented as a daemon, this server does not shut itself
down. You must shut it down explicitly.
As mentioned in the introduction, core network stack protocols such as IP, TCP,
UDP, and the like run in the kernel only, although they are accessible to RTPs
through socket connections and sysctl( ) calls.
215
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Likewise, the MUX functionality and network interface drivers run in the kernel
space only. Thus, if you want to launch and configure a network interface, you do
so within the kernel space. RTPs cannot create and configure network interfaces.
In addition, most network show and configuration utilities are available in the
kernel space only. The exception is the sysctl( ) routine, which is supported as
system call for RTPs.
In addition, because of the isolation of an RTP memory space, RTPs cannot supply
call back routines to kernel-resident network protocols and services. A pointer to
a routine in an RTP memory space would be meaningless at best in the kernel
memory space.
216
11 Creating Network Applications as RTPs
11.3 Working with Application RTPs
This section describes how to write and build the venerable “Hello World”
application to run as an RTP. Although “Hello World” is not particularly
representative of a network application, porting “Hello World” to an RTP
demonstrates the most basic mechanics of creating an RTP. To present a more
network-oriented example, this section also presents the RTP port of the FTP
server.
int main
( 11
int argc, /* number of arguments */
char * argv[], /* array of arguments */
)
{
printf("hello world\n");
return 0;
}
To create an RTP that uses this main( ), you need to change it slightly to accept all
the inputs provided when an RTP executes its main( ).
#include
int main
(
int argc, /* number of arguments */
char * argv[], /* array of arguments */
char * envp[], /* array of environment strings */
void * auxp /* implementation specific auxiliary vector */
)
{
printf("hello world\n");
return 0;
}
The argc and argv parameters serve their traditional function of passing in a count
of caller arguments as well as an array containing the arguments themselves. You
can use envp and auxp parameters to pass in whatever additional information your
RTP needs at run-time to configure its environment or any auxiliary
implementation-specific need.
217
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
To build this as an RTP ELF object file, you need a makefile with the following basic
format:
# Makefile - makefile for hello world example RTP
#
# DESCRIPTION
# This file contains the makefile rules for building an example RTP
EXE = helloworld.vxe
OBJS = mainHello.o
include $(WIND_USR)/make/rules.rtp
This makefile assumes that the “Hello World” main( ) is defined in a file called
helloworld.c. To build the helloworld.vxe, you could run the following make:
$ make CPU=cpuType TOOL=toolType
Where:
cpuType is a valid CPU type, such as PPC32.
toolType is a value such as diab or gnu
What if “Hello World” did not print the message but used a customized service to
transmit the message over the Internet? Such services typically require some
initialization that needs to be completed before an application can use the service.
For some libraries, it is possible to mark the initialization routine with the
_WRS_CONSTRUCTOR attribute. For more information, see 11.3.3 Identifying the
RTP Initialization Routine in a Library, p.222.
For some utilities and services, the initialization routines require the run-time
input of information, such as the IP address of a server. These initialization
routines are not suitable for use with the _WRS_CONSTRUCTOR. For libraries and
utilities that depend on this sort of initialization routine, your RTP main( ) needs
to call the initialization routine directly.
218
11 Creating Network Applications as RTPs
11.3 Working with Application RTPs
/* forward declarations */
extern int sysClkRateGet (void);
int main
(
int argc, /* number of arguments */
char * argv[], /* array of arguments */
char * envp[], /* array of environment strings */ 11
void * auxp /* implementation specific auxiliary vector */
)
{
STATUS rc = OK;
char * pOptStr;
if (argc == 1)
pOptStr = "";
else
pOptStr = argv[1];
219
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The core of this code is the call to ftpd6Init( ). This call launches a task that serves
as the foundation of the FTP server daemon. Note the taskExit( ) call that comes
before the end brace of the main( ) routine. If execution had reached the end brace,
the RTP and all its tasks, including the FTP server daemon, would have shut down
entirely. More information on why a taskExit( ) is called here is provided in
11.3.4 Shutting down an RTP Application, p.223.
To build this as an RTP ELF object file, VxWorks supplies a makefile with the
following content:
# Makefile - makefile for FTP server application
#
# DESCRIPTION
# This file contains the makefile rules to build FTP server
# application executable
EXE = ftpd.vxe
OBJS = ftp6dMain.o
include $(WIND_USR)/make/rules.rtp
This makefile assumes that the main( ) is defined in a file called ftp6dMain.c. To
build the ftpd.vxe, you could run the following make:
$ make CPU=cpuType TOOL=toolType
Where:
cpuType is one of the following:
PPC32
toolType is one of the following:
diab, gnu
220
11 Creating Network Applications as RTPs
11.3 Working with Application RTPs
There are several ways to launch an RTP. From a kernel shell, you can use rtpSp( ):
-> rtpSp "ELF_object_file [arg1 [...arg20 ]"
For example:
-> rtpSp "path/ping.vxe remote_system number_of_packets options"
NOTE: The rtpSp( ) utility is supported in the kernel shell only, not the host shell.
If you are using the new command interpreter, you can omit the explicit call to
rtpSp( ). For example:
# path/ping.vxe remote_system number_of_packets options
221
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
When an RTP first launches, and after validation, it runs the initialization routines
for the libraries referenced either directly or indirectly in its main( ). This list of
initialization routines was generated automatically when the RTP was built. When
the build processes the referenced libraries, it notes routines marked with the
_WRS_CONSTRUCTOR attribute. These routines are automatically added to the
RTP’s initialization routine list. When you launch the RTP, the system
automatically calls each of these initialization routines in an order determined by
the priority assigned in the _WRS_CONSTRUCTOR attribute.
After the successful completion of the initialization routines, the RTP executes the
RTP’s main( ).
If you have written a library whose initialization routine you want to mark using
the _WRS_CONSTRUCTOR attribute, the syntax is as follows:
_WRS_CONSTRUCTOR ( functionName, priority )
functionName
This parameter expects the name of the initialization routine.
priority
This parameter expects a value that is used to determine the execution
order of the initialization routines for an RTP. The lower the priority value,
the sooner the routine executes. For example, an initialization routine with
a priority of 10 executes before an initialization routine with a priority of
20. If two initialization routines have the same priority, the execution order
of those same-priority routines is not determinable. Thus, if one routine
must execute before the other, you must adjust the priority values
appropriately.
For an example of how one would use _WRS_CONSTRUCTOR, consider the
hypothetical routine, myLibInit( ):
STATUS myLibInit (void)
{
...
}
222
11 Creating Network Applications as RTPs
11.4 Using Socket Connections with RTPs
This mechanism is supported by both the Wind River Compiler and the GNU
compiler.
An RTP shuts down entirely when any task in the RTP calls exit( ). Thus, to avoid
accidentally shutting down an RTP, you need to be very careful about when you
call exit( ). You also need to avoid implicit calls to exit( ). These occur if the
execution reaches the end brace of the main( ) routine.
11
One way to avoid an implicit exit( ) call is to call taskExit( ) before execution
reaches the routine end brace. As an alternative to taskExit( ), you could use a
forever loop or you could call:
taskSuspend(0);
223
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
protocols and services that support Internet sockets resides in the kernel. If your
application runs in the kernel, it can access these socket support services directly.
To make these services available to applications running as RTPs, the kernel
exports a selected set of routines as system calls. This set of socket-related system
calls supports all the well-known routines in the standard BSD socket API plus the
VxWorks-specific connectWithTimeout( ). See Table 11-2.
For more information on using sockets under VxWorks, see 12. Working with
Internet and Local Domain Sockets.
224
11 Creating Network Applications as RTPs
11.4 Using Socket Connections with RTPs
For more information on AF_LOCAL sockets, see 12. Working with Internet and
Local Domain Sockets.
11
The following components support the Socket Application Library and the Socket
Name Service:
■ Socket Application Library Client
■ Socket Application Library Server
■
Socket Name Service Server in Kernel
■
Socket Name Service Server in RTP
■
Socket Name Service Show Routine
These components are all listed under the
Network Components > Distributed Systems Infrastructure >
Socket Applications Library Components folder and under the
Socket Name Service Server subfolder in Workbench.
NOTE: The SAL client and server are not network stack applications. Using them
does not require that you include a network stack in your image.
225
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
226
11 Creating Network Applications as RTPs
11.4 Using Socket Connections with RTPs
SNS_PRIORITY
SNS_STACK_SIZE
11
Synopsis: Socket Name Service task stack size.
Default: 20000
SNS_LISTEN_BACKLOG
227
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
SNS_PATHNAME
SNS_PRIORITY
SNS_STACK_SIZE
SNS_LISTEN_BACKLOG
228
11 Creating Network Applications as RTPs
11.4 Using Socket Connections with RTPs
The VxWorks SAL implementation supports the AF_LOCAL address family and
the SOCK_SEQPACKET socket type. For additional information on SAL, see the
salClient and salServer reference entries.
VxWorks supports a SAL client and a SAL server in both the kernel space and the
user space.
NOTE: Any client or server application that uses SAL’s service naming capabilities
requires the presence of a Socket Name Service (SNS) server.
SAL client capabilities are available in both kernel space and user space.
To use the SAL client in kernel space:
1. Include the file dsi/salClient.h in source code that uses the SAL client API.
11
2. Include the INCLUDE_SAL_CLIENT component when building the kernel.
To use the SAL client in user space:
1. Include the file dsi/salClient.h in source code that uses the SAL client API.
2. Link in the user-space version of libdsi.a when building the RTP.
SAL server capabilities are available in both kernel space and user space.
To use the SAL server in kernel space:
1. Include dsi/salServer.h in source code that uses the SAL server API.
2. Include the INCLUDE_SAL_SERVER component when building the kernel.
To use the SAL server in user space:
1. Include the file dsi/salServer.h in source code that uses the SAL server API.
2. Link in the user-space version of libdsi.a when building the RTP.
229
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
VxWorks supports an SNS client and an SNS server in both the kernel space and
the user space. The SNS show capability is supported in kernel space only.
You can set up an SNS server to run in either the kernel space or in user space. You
should not set up more than one SNS server on a single VxWorks target. To set up
an SNS server task that runs in kernel space, include the INCLUDE_SNS
component when building the kernel. To set up an SNS server RTP that runs in
user space:
1. Include the INCLUDE_SNS_RTP component when building the kernel.
2. Include the snsServer.vxe executable in the ROM file system when building a
bootable application image. To create this executable, build the directory:
installDir/vxworks-6.n/target/usr/apps/dsi/snsd
To check that SAL-based services have correctly registered with the SNS server,
you can use the SNS show functionality. Keep in mind that this functionality is
supported in the kernel space only. To configure a VxWorks image to include
support for the SNS show capability:
1. Include the INCLUDE_SNS_SHOW component when building the kernel.
2. Run snsShow command from the shell. This command displays information
on all server applications that have registered with SNS. If no server
applications are registered, a message reports the fact.
230
12
Working with Internet and
Local Domain Sockets
12.1 Introduction
This chapter describes how to use the standard BSD socket interface for Internet
domain sockets on a target running the Wind River Network Stack.
Some mention is made of routing sockets and local domain sockets. For detailed
information on the following related topics, refer to the appropriate chapters:
■
Using the Socket Application Library (SAL), see 11.4 Using Socket Connections
with RTPs, p.223.
■
Writing applications using sockets, see 13. Writing Sample Applications
Using Sockets.
■
Using zbuf sockets, see 14. Using Fast UDP and Zbuf Sockets.
231
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
■
Using routing sockets, see 15. Working with Routing Sockets.
■
Adding socket-support code to a new network service or protocol, see
22.4 Adding a Socket Interface to Your Service, p.520.
Although the Wind River Network Stack is fully compatible with the BSD socket
interface, the particulars of the VxWorks environment do affect how you use
sockets. Specifically, the globally accessible file descriptors available in the
task-independent address space of the VxWorks kernel or a VxWorks RTP require
that you take extra precautions when closing a file descriptor.
You must make sure that one task does not close the socket descriptor on which
another task is pending during an accept( ). Although the accept( ) on the closed
descriptor sometimes returns with an error, the accept( ) can also fail to return at
all. Thus, if you need to asynchronously close the descriptor for a socket
connection, you will probably need to set up a semaphore-based locking
mechanism that prevents the close while an accept( ) is pending on the descriptor.
The focus of this chapter is the introduction of the particulars of the Wind River
Network Stack sockets implementation. Teaching you how to work with sockets
in general is beyond the scope of this chapter. Fortunately, the necessary
information is publicly available in RFCs and a variety of online documents that
you can discover using a Web search.
For IPv6 sockets in particular, read RFC 3493: Basic Socket Interface Extensions for
IPv6 and RFC 3542: Advanced Sockets API for IPv6. The Wind River Network Stack
Socket implementation supports these RFCs. It does not now support any of
proposals published only in the Internet drafts.
NOTE: The update to RFC 3542 has changed some of the definitions in a
non-backward compatible way. The IPv6 APIs have changed as per the updated
RFC. For more information, see the release notes and RFC 3542.
232
12 Working with Internet and Local Domain Sockets
12.2 Types of Sockets
This chapter makes reference to the include files, socket.h, in.h, in6.h, and tcp.h.
The full pathnames of these files are as follows:
■
installDir/vxworks-6.n/target/h/wrn/coreip/sys/socket.h
■
installDir/vxworks-6.n/target/h/wrn/coreip/netinet/in.h
■
installDir/vxworks-6.n/target/h/wrn/coreip/netinet6/in6.h
■ installDir/vxworks-6.n/target/h/wrn/coreip/netinet/tcp.h
233
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Routing Sockets
234
12 Working with Internet and Local Domain Sockets
12.3 Configuring VxWorks for Sockets
NOTE: Although the COMP protocol is mentioned in this manual, you should
know that COMP is independent of the network stack. Thus, if you need to use
COMP, you do not need to include a network stack in your VxWorks image.
Socket API
235
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
For information on how to register additional socket back ends, see 22. Integrating
a New Network Service, and the sockLib reference entry.
MAXSOCKBUF_CFG
SOCKBUF_WASTE_FACTOR_CFG
Before using a new socket, the stack reserves the specified number of buffers
for the socket.
SOMAXCONN_CFG
236
12 Working with Internet and Local Domain Sockets
12.3 Configuring VxWorks for Sockets
SO_LINGER_INFINITE_CFG
Use this parameter to restore the behavior previously associated with the
SO_LINGER option.
In earlier releases, the l_linger member of the struct linger argument to the
SO_LINGER option was significant only insofar as it was zero or nonzero. If
SO_LINGER was enabled and the l_linger was zero, a close( ) on the socket
descriptor resulted in dropping the connection (for TCP, a RST segment was
sent to the peer). If SO_LINGER was enabled and the l_linger value was
nonzero, then the call to close( ) would block until either all outstanding data
(and TCP FIN) had been acknowledged by the peer, or until the protocol timed
out and dropped the connection itself.
More typically, the close( ) call should return if l_linger seconds elapsed
before either all outstanding data and FIN were acknowledged or the
connection was dropped by the protocol. VxWorks previously did not support 12
such time-outs. Now it does, by default. The previous VxWorks behavior can
be restored by setting the SO_LINGER_INFINITE_CFG parameter to TRUE.
In the current release, when the timeout expires on a close( ) against a socket:
■
If SO_LINGER_INFINITE_CFG is FALSE.
■
If SO_LINGER is enabled with a non-zero timeout.
■
If the timeout expired without the connection successfully disconnecting.
What happens next depends upon SO_LINGERRESET, a VxWorks-specific
socket option. By default, SO_LINGERRESET is not enabled, and the protocol
(TCP) continues with the graceful shutdown attempt. If SO_LINGERRESET is
enabled, then the connection is aborted (sending a TCP RST segment to the
peer). In either case, the close( ) call returns ERROR, and errno is set (usually
to ETIMEDOUT, unless the protocol itself dropped the connection, in which
case errno might indicate a “soft” error). The socket has been closed, and you
can no longer use the socket descriptor. For more information, see the
setsockopt( ) reference entry.
237
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
BSD UNIX supports a long list of communications domains for its sockets. Of
these, only the following are supported under VxWorks:
■
the IPv4 Internet communications domain (AF_INET)
■
the IPv6 Internet communications domain (AF_INET6)
■
the routing communications domain (AF_ROUTE)
■
local domain sockets for interprocess communication (AF_LOCAL)
■
the Transparent Inter-Process Communication domain (AF_TIPC)
■
the Mobile IPv6 domain (AF_MOBILITY)
NOTE: Neither the AF_TIPC domain sockets nor the AF_MOBILITY domain sockets
are described in this manual. For information on AF_TIPC sockets, see the Wind
River TIPC for VxWorks 6 Programmer's Guide. For information on AF_MOBILITY
sockets, see the Wind River Mobile IPv6 for VxWorks 6 Programmer's Guide.
238
12 Working with Internet and Local Domain Sockets
12.4 Using BSD Sockets under VxWorks
host. Under VxWorks, there are more efficient mechanisms, such a AF_LOCAL
sockets, TIPC, and message queues, for communications among local tasks.
Sockets in the routing communications domain, AF_ROUTE, communicate with
the local route table. You can use a routing socket to make or monitor changes to
the contents of the local route table.
Under VxWorks, sockets in the local communications domain, AF_LOCAL, bind to
names modeled after the names of files in file system. No actual file system is
required to use AF_LOCAL sockets. Under VxWorks, local domain socket names
are handled by the proprietary Connection-Oriented Message Passing (COMP)
protocol.
239
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
BSD sockets support an additional socket communication type known as the raw
socket. The raw socket is a socket with an unspecified communication style. Its
communication characteristics (reliable or not, sequenced or not, and so on) are
determined by the services provided by the domain and protocol that you specify
when you create the socket. Under VxWorks, the primary use of the raw socket is
within the AF_ROUTE domain, where sockets provide a mechanism by which
host-local tasks can monitor and make changes in the contents of the route table.
240
12 Working with Internet and Local Domain Sockets
12.5 Working with Local Domain Sockets
To create a VxWorks image that includes support for local domain sockets, you
must include the INCLUDE_UN_COMP component. This component pulls in the
COMP implementation. Note that this component is not a network stack
component and that COMP is independent of the network stack. You can include
COMP in a VxWorks image and use even if you do not include a network stack.
Under VxWorks, COMP manages the name space for an AF_LOCAL domain
socket. Thus, when creating names for AF_LOCAL sockets, you must conform to
the expectations of the COMP system, which is a name in the format: 12
/comp/socket/0xNumber
In this name, treat the /comp/socket/ part as an invariable prefix. Treat the
0xNumber part as a string representation of a 16-bit number in hexadecimal format.
No other format is supported. This name is used when you bind( ) a name to a
socket and when you connect( ) to a listening socket. This name is supplied using
a sockaddr_un structure:
struct sockaddr_un /* LOCAL (UNIX) family address */
{ /* --------------------------- */
uint8_t sun_len; /* 0x00: structure size */
uint8_t sun_family; /* 0x01: address family */
char sun_path [104]; /* 0x02: actual address */
}; /* 0x6A: TOTAL SIZE */
This structure is defined in un.h. You will need to include un.h as well as
sockLib.h, the include file for the standard socket API:
sockLib.h /* standard socket API */
sys/un.h /* struct sockaddr_un definition */
241
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
To send and receive data over a socket, you need a socket descriptor. To create a
socket descriptor, call socket( ). As input, a VxWorks socket( ) call expects you to
specify three things:
■
a communications domain for the socket
■
a socket type
■
a protocol type
For the communications domain, specify either AF_INET or AF_INET6, depending
on whether you want a socket in the IPv4 or IPv6 domain. For the socket type, use
SOCK_STREAM to indicate a stream type socket. To indicate a datagram type
socket, use SOCK_DGRAM.
For a stream socket in an Internet domain, you could specify a protocol type of
IPPROTO_TCP or IPPROTO_SCTP. These protocols provide the necessary support
services for a streams type socket in the Internet domains. For datagram sockets,
you could specify a protocol type of IPPROTO_UDP. UDP is the IP protocol that
provides the necessary support services for a datagram type socket in the Internet
domain. You do not typically specify either IPPROTO_TCP or IPPROTO_UDP
explicitly. Instead, you should specify 0 (zero), which tells socket( ) to choose
whatever supporting transport layer protocol is best suited to the requested socket
type and communications domain.
242
12 Working with Internet and Local Domain Sockets
12.6 Working with Internet Domain Sockets
For raw sockets in the Internet domains, a protocol of zero indicates the IP
protocol, IPPROTO_IP. Such a socket gives you direct access to IP. If you want an
Internet domain raw socket into a different protocol, use an appropriate
IPPROTO_name value as defined in in.h. For example, to verify that an IP address
is not already in use, a DHCP server implementation might create a raw socket in
the IPv4 Internet domain and specify a protocol of IPPROTO_ICMP. In the IPv6
Internet domain, it would specify a protocol of IPPROTO_ICMPV6. The server
could then send out an ICMP echo request on the socket to test the address.
After creating a socket descriptor, you want to specify the socket options that
configure the socket for your particular needs. Most options you can handle with
a call to setsockopt( ), although there is one “option” you set with an ioctl( ) call.
243
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
This routine sets the options associated with a socket and any underlying protocols
that support the services accessible through the socket. You should make your
setsockopt( ) call before binding a name to a socket. This is because some socket
options affect the outcome of the bind. For example, some socket options let you
restrict the bind to a particular range of port numbers.
The level parameter of a setsockopt( ) call lets you specify whether the option
applies to the socket itself or an underlying protocol. The socket-level options (level
is SOL_SOCKET) are the most generic options and make sense in the context of
many sockets. Names (optname values) for these socket options are defined in
socket.h. In addition to these socket-level options, setsockopt( ) also lets you pass
options through to the underlying protocol or protocols that support and
implement the services accessed through the socket.
For example, there are a large number of options associated with IPv4. To set these
options for IPv4, you would specify a level of IPPROTO_IP. These options control
and configure access to IPv4-supplied functionality such as IPv4-based
multicasting. Names (optname values) for these socket options are defined in in.h.
The setsockopt( ) reference entry describes the most commonly used of the IP
socket options listed above. Paralleling the socket options for IPv4, Wind River
Network Stack also includes support for IPv6 socket options. For IPv6, you would
assign level a value of IPPROTO_IPV6 and use the optname values for these socket
options as defined in in6.h.
Other commonly socket-accessed protocols and options include the IPPROTO_TCP
protocol and the TCP_NODELAY option, which is described in the setsockopt( )
reference entry. Other socket option names for this protocol are defined in tcp.h.
Whether a protocol supports socket access depends on the protocol. For more
information, see the RFCs for the protocol that interests you.
To bind a name to a socket descriptor, call bind( ). As input, a VxWorks bind( ) call
expects you to specify three things:
■
the socket to which you would bind a name
■
the name, passed in using a sockaddr structure
■
the length of the name
As input, bind( ) expects the socket name to be supplied using a pointer to a
sockaddr structure. The layout of the sockaddr structure is not convenient for
setting up all the information needed to specify a socket name in the Internet
communications domain. Instead, you should use either a sockaddr_in structure
244
12 Working with Internet and Local Domain Sockets
12.6 Working with Internet Domain Sockets
or a sockaddr_in6 structure that you cast as a sockaddr structure when you make
the actual bind( ) call. Use the sockaddr_in structure for sockets in the IPv4
Internet communications domain, and the sockaddr_in6 structure for sockets in
the IPv6 Internet communications domain.
NOTE: Sockets in the routing domain, never require an explicit bind( ) call.
If you omit the explicit bind( ) call for the socket descriptor that you create, the
internals of your first send through the socket automatically handle the bind( ) for
you. In this case, the port number bound to your socket is chosen for you from
among the unused private port numbers (also known as dynamic or ephemeral
port numbers), which are port 49152 through port 65535. This approach is
acceptable if, as is often the case, your code does not need to know the number of
the port to which its socket is bound.
245
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
publish to the entire Internet. For a service offered within a network throughout
which you can control how port numbers are used, you can choose a private port
number within the range 49152 through 65535.
NOTE: sin_len must be assigned a value. If this is not done prior to calling
sendmsg( ), for example, the call will fail with an EINVAL (0x22) error.
The following code fragment shows one way to set up a sockaddr_in structure for
a server identified by a user-entered text string. This string can contain either a
dot-notation IPv4 address or its user-friendly equivalent name.
struct sockaddr_in serverAddr;
The inet_addr( ) call converts a dot-notation IPv4 address to a long integer. If that
call fails, the code assumes that the user specified the server by name. To convert
the name to an IPv4 address, the code calls hostGetByName( ). This routine looks
up the name in the host table and returns its IPv4 address. If you configured the
stack to include DNS, hostGetByName( ) uses DNS to get the name if the host
table search fails.
246
12 Working with Internet and Local Domain Sockets
12.6 Working with Internet Domain Sockets
The code above assumes serverName contains either the name of the server or a
string representation of its IPv6 address. This guarantees success for either the
gethostbyname( ) or gethostbyaddr( ) calls if the code received a valid host name
or address and if it has access to a well informed host table or a functioning DNS
implementation.
The code fragment then initializes the address fields. Some of them, sin6_len and
sin6_family are set to well known values for all IPv6 addresses. Others, sin_port
and sin6_scope_id, are set to known values for this application. The scope id is a
247
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
32-bit integer that identifies a set of interfaces as appropriate for the scope of the
address carried in the sin6_addr field.
The code fragment then copies the address information the returned hostent
structure and then calls hostentFree( ) to free the hostent structure. This structure
was allocated internally by either the gethostbyname( ) or gethostbyaddr( ) call.
Freeing this structure is the responsibility of any code that calls gethostbyname( )
or gethostbyaddr( ).
Sending and receiving data through a socket is more or less the same whether the
socket is a stream or datagram socket. Before you can exchange data over a stream
socket, you must establish a connection. The routines used to create this
connection assume a client server relationship.
A client wishing to establish a connection with a server calls connect( ) on a socket
it has created to communicate with its server. Whether the connect( ) call blocks if
a connection is not immediately available depends on how you have configured
the socket (see Setting Socket Options, p.243).
If the socket is non-blocking, control returns from connect( ) immediately. If a
connection was established, the returned routine value was OK. Otherwise, the
routine returns a ERROR and sets errno to EINPROGRESS or EALREADY. You can
repeat the connect( ) call until you establish a connection. Upon establishing the
connection, the returned routine value will still be ERROR, but the errno value will
be EISCONN.
On the server side, the server needs to have called listen( ) on the socket it has
created to communicate with clients. The server can then call accept( ) on the
socket to indicate that it accepts the socket connection. This sends a message to the
client that indicates that the connection is established.
248
12 Working with Internet and Local Domain Sockets
12.6 Working with Internet Domain Sockets
When the call returns from the accept( ), the routine value is a new socket
descriptor. Using this new descriptor, the server can exchange messages with the
client that requested the connection. The new socket descriptor makes it possible
to queue the accepted connection onto another task for processing. This allows the
server to loop back to accept the next connection request (if any) queued on the
original socket.
Servers typically call accept( ) from within a forever loop. If there is no connection
request pending, the accept( ) blocks until a connection request arrives on the
socket. If this is unacceptable, configure the socket to be non-blocking (see Setting
Socket Options, p.243). If there is no connection request on the socket, and the socket
is non-blocking, the accept( ) call returns ERROR.
Calling connect( ) for a datagram socket does not create a monitored connection to
the specified destination. It does configure the socket to assume the specified
destination for all messages read from and written to the socket. This makes it
possible to call send( ) and recv( ) on the datagram socket instead of sendto( ) and 12
recvfrom( ).
The mechanics of sending and receiving data on a socket are quite simple. Forming
or interpreting the message can be a bit more complicated, and it varies according
to the protocol assumed by the sender and recipient. For the most part, the
mechanics of forming protocol-appropriate messages is beyond the scope of this
document. The only exception is the discussion of routing socket messages
provided in 15. Working with Routing Sockets.
If you have called connect( ) on a socket descriptor, or have received the socket
descriptor from an accept( ) call, the socket is already configured with the address
of the communication partner on the other side of the socket. This is also true for
all client sockets in the routing domain. For such a socket descriptor, you can
exchange messages over the socket using send( ) and recv( ) or the generic write( )
or read( ) routines. All four of these routines are typically used with stream
sockets. If you called connect( ) on a datagram socket, you can use these routines
to communicate over a datagram socket.
249
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
For a datagram socket for which you have not called connect( ), you need to
explicitly identify communications partner on the other side of the socket. In this
situation, you can use sendto( ) and recvfrom( ) to exchange messages over the
socket.
In addition to the send and receive routines mentioned above, sockLib also
supports the routines, sendmsg( ) and recvmsg( ). These routines let you work
with the entirety of the socket message – both its message header and its data
payload. The message header is accessible using a msghdr structure, which is
defined in socket.h as:
/*
* Message header for recvmsg and sendmsg calls.
* Used value-result for recvmsg, value only for sendmsg.
*/
struct msghdr {
void *msg_name; /* optional address */
socklen_t msg_namelen; /* size of address */
struct iovec *msg_iov; /* scatter/gather array */
int msg_iovlen; /* # elements in msg_iov */
void *msg_control; /* ancillary data, see below */
socklen_t msg_controllen; /* ancillary data buffer len */
int msg_flags; /* flags on received message */
};
When using the sendmsg( ) and recvmsg( ) routines with a datagram socket for
which you have not called connect( ), use the msg_name field to specify the
address of the communication partner on the other side of the socket.
The advantage of using sendmsg( ) and recvmsg( ) is that it makes it easier to
access the control (ancillary) information associated with the message and not
merely the message payload data. The msg_control field points to a buffer
containing the ancillary data. The data objects in this control buffer are accessible
using cmsghdr structures, which socket.h defines as:
/*
* Header for ancillary data objects in msg_control buffer.
* Used for additional information with/about a datagram
* not expressible by flags. The format is a sequence
* of message elements headed by cmsghdr structures.
*/
struct cmsghdr {
socklen_t cmsg_len; /* data byte count, including hdr */
int cmsg_level; /* originating protocol */
int cmsg_type; /* protocol-specific type */
/* followed by u_char cmsg_data[]; */
};
250
12 Working with Internet and Local Domain Sockets
12.6 Working with Internet Domain Sockets
To make it easier to work with these message headers, socket.h defines the macros
CMSG_FIRSTHDR( ), CMSG_DATA( ), and CMSG_NXTHDR( ) as follows:
/* given pointer to struct cmsghdr, return pointer to data */
#define CMSG_DATA(cmsg) ((u_char *)(cmsg) + \
_ALIGN(sizeof(struct cmsghdr)))
When a client or server has decided that it is time to end its conversation with the
communication partner, it can break the connection by calling shutdown( ) or its
generic near equivalent, close( ). Of the two routines, shutdown( ) provides the
greater flexibility. Using shutdown( ), you can break the send side of the socket
connection, the receive side of the socket connection, or both.
If you shutdown both the send and receive sides of the socket connection, and the
socket is configured with the SO_REUSEADDR option set, you can reuse the socket
to support a connection with a different client or server.
There can be a degree of latency associated with closing a socket connection if you
enabled the SO_LINGER socket option and set the l_linger member of the
struct linger argument.
251
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
In earlier releases, the l_linger member of the struct linger argument to the
SO_LINGER option was significant only insofar as it was zero or nonzero. If
SO_LINGER was enabled and the l_linger was zero, closing a socket resulted in
dropping the connection (for TCP, a RST segment was sent to the peer). If
SO_LINGER was enabled and the l_linger value was nonzero, then the call that
closed the socket connection would block until either all outstanding data (and
TCP FIN) had been acknowledged by the peer, or until the protocol timed out and
dropped the connection itself.
More typically, a socket close( ) call should return if l_linger seconds elapsed
before either all outstanding data and FIN were acknowledged or the connection
was dropped by the protocol. VxWorks previously did not support such time-outs.
Now it does, by default. You can restore the previous VxWorks behavior by setting
the SO_LINGER_INFINITE_CFG parameter to TRUE.
In the current release, the timeout expires on a close( ) against a socket:
■ If SO_LINGER_INFINITE_CFG is FALSE.
■ If SO_LINGER is enabled with a non-zero timeout.
■ If the timeout expired without the connection successfully disconnecting.
What happens next depends upon SO_LINGERRESET, a VxWorks-specific socket
option. By default, SO_LINGERRESET is not enabled, and the protocol (TCP)
continues with the graceful shutdown attempt. If SO_LINGERRESET is enabled,
then the connection is aborted (sending a TCP RST segment to the peer). In either
case, the close( ) call returns ERROR, and errno is set (usually to ETIMEDOUT,
unless the protocol itself dropped the connection, in which case errno might
indicate a “soft” error). The socket has been closed, and you can no longer use the
socket descriptor. For more information, see the setsockopt( ) reference entry.
While the socket is in its period of graceful shutdown, it is referred to as being in a
TIME_WAIT state. To bypass the TIME_WAIT state, turn off the SO_LINGER
option. This lets you bind socket to the same port and reconnect to the same
destination even if the TIME_WAIT has not yet expired. To turn off the SO_LINGER
option, use code similar to the following:
struct linger linger;
linger.l_onoff = 1;
linger.l_linger = 0;
if ( setsockopt (
newConnection, SOL_SOCKET, SO_LINGER, (char *)&linger, sizeof(linger)
)
== ERROR ) {
perror ("setsockopt SO_LINGER failed");
return (ERROR);
}
252
12 Working with Internet and Local Domain Sockets
12.6 Working with Internet Domain Sockets
If you are writing a socket-based application, your users will expect to be able to
enter host names as well as IPv4 or IPv6 address strings. In addition, when
presenting socket-related information on the destination, users will expect host
names and not numerical expressions of the IPv4 or IPv6 address strings. To
convert host names to their corresponding IP addresses and back, the Wind River
Network Stack provides hostLib, inetLib, and the following routines:
getaddrinfo( ) – node name-to-address translation
getnameinfo( ) – translate a socket address to a node name and service name
gethostbyname( ) – name-to-address translation routine
gethostbyaddr( ) – address-to-name translation routine
getsockname( ) – get a socket name
getpeername( ) – get the name of a connected peer
These routines check first in the local host table to retrieve the requested
information. If the host table cannot supply the information, they access DNS.
Among the hostLib routines, note that hostGetByName( ) and hostGetByAddr( ) 12
are IPv4-only. The same is true for the inetLib routines, inet_ntoa( ) and
inet_addr( ). If you are writing an application that must work in both the IPv4 and
IPv6 Internet domains, you should probably avoid using IPv4-only routines.
253
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
254
13
Writing Sample Applications
Using Sockets
13.1 Introduction
This chapter provides code for sample applications using datagram (UDP) sockets
and TCP stream sockets.
255
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The following code example uses a client-server communication model. The server
communicates with clients using datagram-oriented (UDP) sockets. The main
server loop, in udpServer( ), reads requests and optionally displays the client’s
message. The client builds the request by prompting the user for input. Note that
this code assumes that it executes on machines that have the same data sizes and
alignment.
If this is not done prior to calling sendmsg( ) for example, the call will fail with an
EINVAL (0x22) error.
struct request
{
int display; /* TRUE = display message */
char message[REQUEST_MSG_SIZE]; /* message buffer */
};
/*
DESCRIPTION
This file contains the client-side of the UDP example code.
The example code demonstrates the usage of several BSD 4.4-style
socket routine calls.
*/
/* includes */
#include "vxWorks.h"
#include "sockLib.h"
#include "inetLib.h"
#include "stdioLib.h"
#include "strLib.h"
#include "hostLib.h"
#include "ioLib.h"
#include "udpExample.h"
256
13 Writing Sample Applications Using Sockets
13.2 Writing Applications Using Datagram Sockets (UDP)
/****************************************************************************
*
* udpClient - send a message to a server over a UDP socket
*
* This routine sends a user-provided message to a server over a UDP socket.
* Optionally, this routine can request that the server display the message.
* This routine may be invoked as follows:
* -> udpClient "remoteSystem"
* Message to send:
* Greetings from UDP client
* Would you like server to display your message (Y or N):
* y
* value = 0 = 0x0
*
* RETURNS: OK, or ERROR if the message could not be sent to the server.
*/
STATUS udpClient
(
char * serverName /* name or IP address of server */
)
{
struct request myRequest; /* request to send to server */
struct sockaddr_in serverAddr; /* server's socket address */
char display; /* if TRUE, server prints message */
int sockAddrSize; /* size of socket address structure */ 13
int sFd; /* socket file descriptor */
int mlen; /* length of message */
257
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
printf ("Would you like the server to display your message (Y or N): \n");
read (STD_IN, &display, 1);
switch (display)
{
case 'y':
case 'Y': myRequest.display = TRUE;
break;
default: myRequest.display = FALSE;
break;
}
close (sFd);
return (OK);
}
/*
DESCRIPTION
This file contains the server-side of the VxWorks UDP example code.
The example code demonstrates the usage of several BSD 4.4-style
socket routine calls.
*/
/* includes */
#include "vxWorks.h"
#include "sockLib.h"
#include "inetLib.h"
#include "stdioLib.h"
#include "strLib.h"
#include "ioLib.h"
#include "fioLib.h"
#include "udpExample.h"
/*********************************************************************
*
* udpServer - read from UDP socket and display client's message if requested
*
* Example UDP server:
258
13 Writing Sample Applications Using Sockets
13.2 Writing Applications Using Datagram Sockets (UDP)
* -> sp udpServer
* task spawned: id = 0x3a1f6c, name = t2
* value = 3809132 = 0x3a1f6c
* -> MESSAGE FROM CLIENT (Internet Address 192.0.2.11, port 1028):
* Greetings from UDP client
*
* RETURNS: Never, or ERROR if a resources could not be allocated.
*/
FOREVER
{
if (recvfrom (sFd, (char *) &clientRequest, sizeof (clientRequest), 0,
(struct sockaddr *) &clientAddr, &sockAddrSize) == ERROR)
{
perror ("recvfrom");
close (sFd);
return (ERROR);
}
259
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
if (clientRequest.display)
{
/* convert inet address to dot notation */
260
13 Writing Sample Applications Using Sockets
13.2 Writing Applications Using Datagram Sockets (UDP)
The following code samples define two routines, mcastSend( ) and mcastRcv( ).
13
These routines demonstrate how to use UDP sockets to handle sending and
receiving multicast traffic.
mcastSend( )
Transmits a buffer to the specified multicast address. As input, this routine
expects a multicast destination, a port number, a buffer pointer, and a buffer
length. For example:
status = mcastSend ("224.1.0.1", 7777, bufPtr, 100);
mcastRcv( )
Receives any packet sent to a specified multicast address. As input, this
routine expects the interface address from which the packet is coming, a
multicast address, a port number, and the number of bytes to read from the
packet. The returned value of the routine is a pointer a buffer containing the
read bytes. For example:
buf = mcastRcv (ifAddress, "224.1.0.1", 7777, 100) ;
/* includes */
#include "vxWorks.h"
#include "taskLib.h"
#include "socket.h"
#include "netinet/in.h"
#include "stdio.h"
261
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
#include "stdlib.h"
#include "string.h"
#include "sockLib.h"
#include "inetLib.h"
#include "ioLib.h"
#include "routeLib.h"
/* defines */
/* globals */
/* forward declarations */
/************************************************************************
* mcastSend - send a message to the multicast address
* This routine sends a message to the multicast address
* The multicast group address to send, the port number, the pointer to the
* send buffer and the send buffer length are given as input parameters.
* RETURNS: OK if sucessful or ERROR
*/
STATUS mcastSend
(
char * mcastAddr, /* multicast address */
USHORT mcastPort, /* udp port number */
char * sendBuf, /* send Buffer */
int sendLen /* length of send buffer */
)
{
struct sockaddr_in sin;
struct sockaddr_in toAddr;
int toAddrLen;
int sockDesc;
char * bufPtr;
int len;
struct in_addr ifAddr;
262
13 Writing Sample Applications Using Sockets
13.2 Writing Applications Using Datagram Sockets (UDP)
sendLen -= len;
bufPtr += len;
if (sockDesc != ERROR)
close (sockDesc);
return (OK);
}
263
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
/************************************************************************
* mcastRcv - receive a message from a multicast address
* This routine receives a message from a multicast address
* The interface address from which to receive the multicast packet,
* the multicast address to recv from, the port number and the number of
* bytes to read are given as input parameters to this routine.
* RETURNS: Pointer to the Buffer or NULL if error.
*/
char * mcastRcv
(
char * ifAddr, /* interface address to recv mcast packets */
char * mcastAddr, /* multicast address */
USHORT mcastPort, /* udp port number to recv */
int numRead /* number of bytes to read */
)
{
struct sockaddr_in fromAddr;
struct sockaddr_in sin;
int fromLen;
struct ip_mreq ipMreq;
int recvLen;
int sockDesc;
char * bufPtr;
int status = OK;
char * recvBuf = NULL;
264
13 Writing Sample Applications Using Sockets
13.2 Writing Applications Using Datagram Sockets (UDP)
goto cleanUp;
}
cleanUp:
{
if (sockDesc != ERROR)
close (sockDesc);
if ((status != OK) && (recvBuf != NULL))
{
free (recvBuf);
recvBuf = NULL;
}
}
return (recvBuf);
}
265
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Task 1 Task 2
Waits Calls Routine Analogy
The following code example uses a client-server communication model. The server
communicates with clients using stream-oriented (TCP) sockets. The main server
loop, in tcpServerWorkTask( ), reads requests, prints the client’s message to the
console, and, if requested, sends a reply back to the client. The client builds the
request by prompting for input. It sends a message to the server and, optionally,
266
13 Writing Sample Applications Using Sockets
13.3 Writing Applications Using Stream Sockets (TCP)
waits for a reply to be sent back. To simplify the example, assume that the code is
executed on machines that have the same data sizes and alignment.
/* tcpExample.h - header used by both TCP server and client examples */
/* defines */
#define SERVER_PORT_NUM 5001 /* server's port number for bind() */
#define SERVER_WORK_PRIORITY 100 /* priority of server's work task */
#define SERVER_STACK_SIZE 10000 /* stack size of server's work task */
#define SERVER_MAX_CONNECTIONS 4 /* max clients connected at a time */
#define REQUEST_MSG_SIZE 1024 /* max size of request message */
#define REPLY_MSG_SIZE 500 /* max size of reply message */
/*
DESCRIPTION 13
This file contains the client-side of the TCP example code.
The example code demonstrates the usage of several BSD 4.4-style
socket routine calls.
*/
/* includes */
#include "vxWorks.h"
#include "sockLib.h"
#include "inetLib.h"
#include "stdioLib.h"
#include "strLib.h"
#include "hostLib.h"
#include "ioLib.h"
#include "tcpExample.h"
/****************************************************************************
*
* tcpClient - send requests to server over a TCP socket
*
* This routine connects over a TCP socket to a server, and sends a
* user-provided message to the server. Optionally, this routine
* waits for the server's reply message.
*
* This routine may be invoked as follows:
* -> tcpClient "remoteSystem"
* Message to send:
* Hello out there
* Would you like a reply (Y or N):
* y
267
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
* value = 0 = 0x0
* -> MESSAGE FROM SERVER:
* Server received your message
*
* RETURNS: OK, or ERROR if the message could not be sent to the server.
*/
STATUS tcpClient
(
char * serverName /* name or IP address of server */
)
{
struct request myRequest; /* request to send to server */
struct sockaddr_in serverAddr; /* server's socket address */
char replyBuf[REPLY_MSG_SIZE]; /* buffer for reply */
char reply; /* if TRUE, expect reply back */
int sockAddrSize; /* size of socket address structure */
int sFd; /* socket file descriptor */
int mlen; /* length of message */
/* connect to server */
if (connect (sFd, (struct sockaddr *) &serverAddr, sockAddrSize) == ERROR)
{
perror ("connect");
close (sFd);
return (ERROR);
}
268
13 Writing Sample Applications Using Sockets
13.3 Writing Applications Using Stream Sockets (TCP)
close (sFd);
return (OK);
}
/*
DESCRIPTION
This file contains the server-side of the TCP example code.
The example code demonstrates the usage of several BSD 4.4-style
socket routine calls.
*/
/* includes */
#include "vxWorks.h"
#include "sockLib.h"
#include "inetLib.h"
#include "taskLib.h"
#include "stdioLib.h"
#include "strLib.h"
#include "ioLib.h"
#include "fioLib.h"
#include "tcpExample.h"
269
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
/* routine declarations */
/****************************************************************************
*
* tcpServer - accept and process requests over a TCP socket
*
* This routine creates a TCP socket and accepts connections over the socket
* from clients. Each client connection is handled by spawning a separate
* task to handle client requests. This routine may be invoked as follows:
* -> sp tcpServer
* task spawned: id = 0x3a6f1c, name = t1
* value = 3829532 = 0x3a6f1c
* -> MESSAGE FROM CLIENT (Internet Address 192.0.2.10, port 1027):
* Hello out there
*
* RETURNS: Never, or ERROR if a resources could not be allocated.
*/
270
13 Writing Sample Applications Using Sockets
13.3 Writing Applications Using Stream Sockets (TCP)
FOREVER
{
if ((newFd = accept (sFd, (struct sockaddr *) &clientAddr,
&sockAddrSize)) == ERROR)
{
perror ("accept");
close (sFd);
return (ERROR);
}
perror ("taskSpawn");
close (newFd);
}
}
}
/****************************************************************************
*
* tcpServerWorkTask - process client requests
*
* This routine reads from the server's socket, and processes client
* requests. If the client requests a reply message, this routine
* will send a reply to the client.
*
* RETURNS: N/A.
*/
VOID tcpServerWorkTask
(
int sFd, /* server's socket fd */
char * address, /* client's socket address */
u_short port /* client's socket port */
)
{
struct request clientRequest; /* request/message from client */
int nRead; /* number of bytes read */
static char replyMsg[] = "Server received your message";
271
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
if (clientRequest.reply)
if (write (sFd, replyMsg, sizeof (replyMsg)) == ERROR)
perror ("write");
}
272
14
Using Fast UDP and
Zbuf Sockets
14.1 Introduction
This chapter describes two alternatives to using the standard socket interface:
■
Fast UDP
Fast UDP is a specialized library that provides faster throughput and less
complexity than the standard socket interface.
■ Zbuf Sockets
Zbuf sockets are an alternative set of socket calls based on a data abstraction
called a zbuf, a zero-copy buffer. Zbuf sockets can be used with either UDP or
TCP applications.
273
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The Wind River Network Stack supports the following Fast UDP configuration
components:
■
Fast UDPv4
■
Fast UDPv6
These components are listed under the
Network Components > Network Private Components folder in Workbench.
To add Fast UDP support, you must first rebuild the stack libraries with
-DFASTUDP option set. These libraries are not built for the default stack. For
information on building the network stack, see your Wind River Platforms Getting
Started or Wind River General Purpose Platform, VxWorks Edition, Getting Started.
Once you have rebuilt the stack, you must then add the appropriate Fast UDP
component to your VxWorks image.
Fast UDPv4
274
14 Using Fast UDP and Zbuf Sockets
14.3 Zbuf Sockets
FASTUDP_DEBUG_CFG
Fast UDPv6
FASTUDP6_DEBUG_CFG
NOTE: Zbuf Sockets are a kernel-only feature. They are not supported in an RTP.
275
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Zbuf-based socket calls are interoperable with the standard BSD socket interface:
the other end of a socket has no way of telling whether your end is using
zbuf-based calls or traditional calls. However, zbuf-based socket calls are not
source-compatible with the standard BSD socket interface: you must call different
socket routines to use the zbuf interface. Applications that use the zbuf interface
are thus less portable.
! WARNING: The send socket buffer size must exceed that of any zbufs sent over the
socket. To set the send socket buffer size, use either the TCP_SND_SIZE_DFLT or
UDP_SND_SIZE_DFLT configuration parameter.
The Wind River Network Stack supports the following zbuf socket configuration
component:
■
ZBUF Socket
This component is listed under the
Network Components > Network Socket Components folder in Workbench.
ZBUF Socket
NOTE: Zbuf sockets are a kernel-only feature. They are not supported in RTPs.
276
14 Using Fast UDP and Zbuf Sockets
14.3 Zbuf Sockets
The simplest way to use zbuf sockets is to call either zbufSockBufSend( ) (in place
of send( ) for a TCP connection) or zbufSockBufSendto( ) (in place of sendto( ) for
a UDP datagram). In either case, you supply a pointer to your application’s data
buffer containing the data or message to send, and the network protocol uses that
same buffer rather than copying the data out of it.
! WARNING: Using zbufs allows different modules to share the same buffers. This
lets your application avoid the performance hit associated with copying the buffer.
To make this work, your application must not modify (let alone free!) the data
buffer while network software is still using it. Instead of freeing your buffer
explicitly, you can supply a free-routine callback: a pointer to a routine that knows
how to free the buffer. The zbuf library keeps track of how many zbufs point to a
data buffer and calls the free routine when the data buffer is no longer in use.
To receive socket data using zbufs, see the following sections. 14.3.2 Manipulating
the Zbuf Data Structure, p.277 describes the routines to create and manage zbufs,
and 14.3.7 Calling Zbuf Socket Routines, p.286, introduces the remaining
zbuf-specific socket routines. See also the reference entries for zbufLib and
zbufSockLib. 14
277
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
You can address the contents of a zbuf by byte locations. A zbuf byte location has
two parts, an offset and a segment ID.
An offset is a signed integer (type int): the distance in bytes to a portion of data in
the zbuf, relative to the beginning of a particular segment. Zero refers to the first
byte in a segment; negative integers refer to bytes in previous segments; and
positive integers refer to bytes after the start of the current segment.
A segment ID is an arbitrary integer (type ZBUF_SEG) that identifies a particular
segment of a zbuf. You can always use NULL to refer to the first segment of a zbuf.
Figure 14-1 shows a simple zbuf with data organized into two segments. The
offsets are relative to the first segment. This is the most efficient addressing scheme
to use to refer to bytes a, b, or c in the figure.
a b c
0 1 2
d e f g
3 4 5 6
Figure 14-2 shows the same zbuf, but it is labeled with offsets relative to the second
segment. This is the most efficient addressing scheme to refer to bytes d, e, f, or g
in the figure.
–3 –2 –1
a b c
0 1 2 3
d e f g
278
14 Using Fast UDP and Zbuf Sockets
14.3 Zbuf Sockets
Two special shortcuts give the fastest access to either the beginning or the end of a
zbuf. The constant ZBUF_END refers to the position after all existing bytes in the
zbuf. Similarly, ZBUF_BEGIN refers to the position before all existing bytes. These
constants are the only offsets with meanings not relative to a particular segment.
When you insert data in a zbuf, the new data is always inserted before the byte
location you specify in the call to an insertion routine. That is, the byte location you
specify becomes the address of the newly inserted data.
To create a new zbuf, call zbufCreate( ). The routine takes no arguments, and
returns a zbuf identifier (type ZBUF_ID) for a zbuf containing no segments. After
you have the zbuf ID, you can attach segments or otherwise insert data. While the
zbuf is empty, NULL is the only valid segment ID, and 0 the only valid offset.
When you no longer need a particular zbuf, call zbufDelete( ). Its single argument
is the ID for the zbuf to delete. The zbufDelete( ) routine calls the free routine
associated with each segment in the zbuf, for segments that are not shared by other
zbufs. After you delete a zbuf, its zbuf ID is meaningless; any reference to a deleted
zbuf ID is an error. 14
Call Description
The usual way to place data in a zbuf is to call zbufInsertBuf( ). This routine builds
a zbuf segment pointing to an existing data buffer, and inserts the new segment at
whatever byte location you specify in a zbuf. You can also supply a callback
pointer to a free routine, which the zbuf library calls when no zbuf segments point
to that data buffer.
Because the purpose of the zbuf socket interface is to avoid data copying, the need
to actually copy data into a zbuf (rather than designating its location as a shareable
buffer) occurs much less frequently. When that need does arise, the routine
279
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Call Description
zbufInsertBuf( ) Create a zbuf segment from a buffer and insert into a zbuf.
The routines listed in Table 14-3 perform several fundamental operations on zbufs.
Call Description
280
14 Using Fast UDP and Zbuf Sockets
14.3 Zbuf Sockets
zbuf segments moves, yet after some byte location (the byte location where you
inserted data) addressing the two zbufs gives completely different data.
The zbufSplit( ) routine divides one zbuf into two; you specify the byte location
for the split, and the result of the routine is a new zbuf ID. The new zbuf’s data
begins after the specified byte location. The original zbuf ID also has a modified
view of the data: it is truncated to the byte location of the split. None of the data in
the underlying segments moves through all this. If you duplicate the original zbuf
before splitting it, three zbuf IDs share segments. The duplicate permits you to
view the entire original range of data, another zbuf contains a leading fragment,
and the third zbuf holds the trailing fragment.
Similarly, if you call zbufCut( ) to remove some range of bytes from within a zbuf,
the effects are visible only to callers who view the data through the same zbuf ID
you used for the deletion. Other zbuf segments can still address the original data
through a shared buffer.
For the most part, these routines do not free data buffers or delete zbufs, but there
are two exceptions:
■ zbufInsert( ) deletes the zbuf ID it inserts. No segments are freed, because they
now form part of the larger zbuf.
14
■ If the bytes you remove with zbufCut( ) span one or more complete segments,
the free routines for those segments can be called (if no other zbuf segment
refers to the same data).
The data-buffer free routine runs only when none of the data in a segment is part
of any zbuf. To avoid data copying, zbuf manipulation routines, such as
zbufCut( ), record which parts of a segment are currently in a zbuf, postponing the
deletion of a segment until no part of its data is in use.
The routines in Table 14-4 give your applications access to the underlying
segments in a zbuf.
By specifying a NULL segment ID, you can address the entire contents of a zbuf as
offsets from its very first data byte. It is always more efficient to address data in a
zbuf relative to the closest segment. Use zbufSegFind( ) to translate any zbuf byte
location into the most local form.
The pair zbufSegNext( ) and zbufSegPrev( ) are useful for going through the
segments of a zbuf in order, perhaps in conjunction with zbufSegLength( ).
281
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Call Description
Finally, zbufSegData( ) allows the most direct access to the data in zbufs: it gives
your application the address where a segment’s data begins. If you manage
segment data directly using this pointer, bear the following restrictions in mind:
■ Do not change data if any other zbuf segment is sharing it.
■ As with any other direct memory access, it is up to your own code to restrict
itself to meaningful data: remember that the next segment in a zbuf is usually
not contiguous. Use zbufSegLength( ) as a limit, and zbufSegNext( ) when
you exceed that limit.
The following interaction illustrates the use of some of the previously described
zbufLib routines, and their effect on zbuf segments and data sharing. To keep the
example manageable, the zbuf data used is artificially small, and the execution
environment is a shell.
To begin, create a zbuf, and use its ID zId to verify that a newly created zbuf
contains no data; zbufLength( ) returns a result of 0.
-> zId = zbufCreate()
new symbol "zId" added to symbol table.
zId = 0x3b58e8: value = 3886816 = 0x3b4ee0
-> zbufLength (zId)
value = 0 = 0x0
Next, create a data buffer buf1, insert it into zbuf zId, and verify that
zbufLength( ) now reports a positive length.
282
14 Using Fast UDP and Zbuf Sockets
14.3 Zbuf Sockets
To keep the example simple, buf1 is a literal string, and therefore we do not supply
a free-routine callback argument to zbufInsertBuf( ).
-> buf1 = "I cannot repeat enough!"
new symbol "buf1" added to symbol table.
buf1 = 0x3b5898: value = 3889320 = 0x3b58a8 = buf1 + 0x10
-> zbufInsertBuf (zId, 0, 0, buf1, strlen(buf1), 0, 0)
value = 3850240 = 0x3ac000
-> zbufLength (zId)
value = 23 = 0x17
When we copy the zbuf, the copy has its own IDs, but still uses the same data
address:
-> zId2 = zbufDup (zId,0,0,23)
new symbol "zId2" added to symbol table.
zId2 = 0x3b5ff0: value = 3886824 = 0x3b4ee8
-> zbufDisplay zId2
segID 0x3abf80 at 0x3b58a8 + 0x0 (23 bytes): I cannot repeat enough!
value = 0 = 0x0
If we insert a second buffer into the middle of the existing data in zId, there is still
no data copying. Inserting the new buffer gives us a zbuf made up of three
segments—but notice that the address of the first segment is still the start of buf1,
and the third segment points into the middle of buf1:
-> buf2 = " this"
new symbol "buf2" added to symbol table.
buf2 = 0x3b5fb0: value = 3891136 = 0x3b5fc0 = buf2 + 0x10
-> zbufInsertBuf (zId, 0, 15, buf2, strlen(buf2), 0, 0)
value = 3849984 = 0x3abf00
-> zbufDisplay zId
segID 0x3ac000 at 0x3b58a8 + 0x0 (15 bytes): I cannot repeat
segID 0x3abf00 at 0x3b5fc0 + 0x0 ( 5 bytes): this
segID 0x3abe80 at 0x3b58b7 + 0x0 ( 8 bytes): enough!
value = 0 = 0x0
283
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Because the underlying buffer is not modified, both buf1 and the duplicate zbuf
zId2 still contain the original string, rather than the modified one now in zId:
-> printf ("%s\n", buf1)
I cannot repeat enough!
value = 24 = 0x18
-> zbufDisplay zId2
segID 0x3abf80 at 0x3b58a8 + 0x0 (23 bytes): I cannot repeat enough!
value = 0 = 0x0
The zbufDup( ) routine can also select part of a zbuf without copying, for instance
to incorporate some of the same data into another zbuf—or even into the same
zbuf, as in the following example:
-> zTmp = zbufDup (zId, 0, 15, 5)
new symbol "zTmp" added to symbol table.
zTmp = 0x3b5f70: value = 3886832 = 0x3b4ef0
After zbufInsert( ) combines two zbufs, the second zbuf ID (zTmp in this example)
is automatically deleted. Thus, zTmp is no longer a valid zbuf ID—for example,
zbufLength( ) returns ERROR:
-> zbufLength (zTmp)
value = -1 = 0xffffffff = zId2 + 0xffc4a00f
You must still delete the remaining two zbuf IDs explicitly when they are no longer
needed. This releases all associated zbuf-structure storage. In a real application,
with free-routine callbacks filled in, it also calls the specified free routine on the
data buffers, as follows:
-> zbufDelete (zId)
value = 0 = 0x0
-> zbufDelete (zId2)
value = 0 = 0x0
284
14 Using Fast UDP and Zbuf Sockets
14.3 Zbuf Sockets
The following is the complete source code for the zbufDisplay( ) utility used in the
preceding example:
/* zbufDisplay.c - zbuf example display routine */
/* includes */
#include "vxWorks.h"
#include "zbufLib.h"
#include "ioLib.h"
#include "stdio.h"
/********************************************************************
*
* zbufDisplay - display contents of a zbuf
*
* RETURNS: OK, or ERROR if the specified data could not be displayed.
*/
STATUS zbufDisplay
(
ZBUF_ID zbufId, /* zbuf to display */
ZBUF_SEG zbufSeg, /* zbuf segment base for <offset> */
int offset, /* relative byte offset */
int len, /* number of bytes to display */
BOOL silent /* do not print out debug info */
) 14
{
int lenData;
char * pData;
/* find the most-local byte location */
if ((zbufSeg = zbufSegFind (zbufId, zbufSeg, &offset)) == NULL)
return (ERROR);
if (len <= 0)
len = ZBUF_END;
while ((len != 0) && (zbufSeg != NULL))
{
/* find location and data length of zbuf segment */
pData = zbufSegData (zbufId, zbufSeg) + offset;
lenData = zbufSegLength (zbufId, zbufSeg) - offset;
lenData = min (len, lenData); /* print all of seg ? */
if (!silent)
printf ("segID 0x%x at 0x%x + 0x%x (%2d bytes): ",
(int) zbufSeg, (int) pData, offset, lenData);
write (STD_OUT, pData, lenData); /* display data */
if (!silent)
printf ("\n");
zbufSeg = zbufSegNext (zbufId, zbufSeg); /* update segment */
len -= lenData; /* update length */
offset = 0; /* no more offset */
}
return (OK);
}
285
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The following zbuf limitations are due to the current implementation; they are not
inherent to the data abstraction. They are described because they can have an
impact on application performance.
■
With the current implementation, references to data in zbuf segments before a
particular location (whether with zbufSegPrev( ), or with a negative offset in
a byte location) are significantly slower than references to data after a
particular location.
■ The data in small zbuf segments (less than 512 bytes) is sometimes copied,
rather than having references propagated to it.
The zbuf socket calls listed in Table 14-5 are named to emphasize parallels with the
standard BSD socket calls: thus, zbufSockSend( ) is the zbuf version of send( ),
and zbufSockRecvfrom( ) is the zbuf version of recvfrom( ). The arguments also
correspond directly to those of the standard socket calls.
Call Description
For a detailed description of each routine, see the corresponding reference entry.
286
14 Using Fast UDP and Zbuf Sockets
14.3 Zbuf Sockets
The zbuf socket calls are particularly useful when large data transfer is a
significant part of your socket application. For example, many socket applications
contain sections of code like the following fragment:
pBuffer = malloc (BUFLEN);
while ((readLen = read (fdDevice, pBuffer, BUFLEN)) > 0)
write (fdSock, pBuffer, readLen);
You can eliminate the overhead of copying from the application buffer pBuffer
into the internal socket buffers by changing the code to use zbuf socket calls. For
example, the following fragment is a zbuf version of the preceding loop:
pBuffer = malloc (BUFLEN * BUFNUM); /* allocate memory */
for (ix = 0; ix < (BUFNUM - 1); ix++, pBuffer += BUFLEN)
appBufRetn (pBuffer); /* fill list of free bufs */
For a small but complete example that illustrates the mechanics of using the zbuf
socket library, consider the conversion of the client-server example in
Example 13-3 to use zbuf socket calls.
No conversion is needed for the client side of the example; the client operates the
same regardless of whether or not the server uses zbufs. The next example
illustrates the following changes to convert the server side to use zbufs:
■
Instead of including the header file sockLib.h, include zbufSockLib.h.
■
The data processing component must be capable of dealing with potentially
non-contiguous data in successive zbuf segments. In the TCP example, this
component displays a message using printf( ); we can use the zbufDisplay( )
routine from Example 14-1 instead.
287
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
■
The original TCP example exploits fioRead( ) to collect the complete message,
rather than calling recv( ) directly. To achieve the same end while avoiding
data copying by using zbufs, the following example defines a
zbufFioSockRecv( ) routine to call zbufSockRecv( ) repeatedly until the
complete message is received.
■
A new version of the worker routine tcpServerWorkTask( ) must tie together
these separate modifications, and must explicitly extract the reply and
msgLen fields from the client’s transmission to do so. When using zbufs, you
cannot extract these fields by reference to the C structure in tcpExample.h.
This is because of the possibility that the data is not contiguous.
The following example shows the auxiliary zbufFioSockRecv( ) routine and the
zbuf version of tcpServerWorkTask( ). To run this code:
1. Start with tcpServer.c as defined in Example 13-3.
2. Include the header file zbufSockLib.h.
3. Insert the zbufDisplay( ) routine from Example 14-1.
4. Replace the tcpServerWorkTask( ) definition with the following two routines:
/************************************************************************
*
* zbufFioSockRecv - receive <len> bytes from a socket into a zbuf
*
* This routine receives a specified amount of data from a socket into a
* zbuf, by repeatedly calling zbufSockRecv() until <len> bytes are read.
*
* RETURNS:
* The ID of the zbuf containing <len> bytes of data,
* or NULL if there is an error during the zbufSockRecv() operation.
*
* SEE ALSO: zbufSockRecv()
*/
ZBUF_ID zbufFioSockRecv
(
int fd, /* file descriptor of file to read */
int len /* maximum number of bytes to read */
)
{
BOOL first = TRUE; /* first time thru ? */
ZBUF_ID zRecvTotal = NULL; /* zbuf to return */
ZBUF_ID zRecv; /* zbuf read from sock */
int nbytes; /* number of recv bytes */
for (; len > 0; len -= nbytes)
{
nbytes = len; /* set number of bytes wanted */
/* read a zbuf from the socket */
288
14 Using Fast UDP and Zbuf Sockets
14.3 Zbuf Sockets
VOID tcpServerWorkTask
(
int sFd, /* server's socket fd */
char * address, /* client's socket address */
u_short port /* client's socket port */
)
{
static char replyMsg[] = "Server received your message";
ZBUF_ID zReplyOrig; /* original reply msg */
ZBUF_ID zReplyDup; /* duplicate reply msg */
ZBUF_ID zRequest; /* request msg from client */
int msgLen; /* request msg length */
int reply; /* reply requested ? */
289
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
! CAUTION: In the interests of brevity, the STATUS return values for several zbuf
socket calls are discarded with casts to void. In a real application, check these
return values for possible errors.
290
15
Working with Routing Sockets
15.1 Introduction
Routing sockets provide a two-way communication interface to the route table.
Using a routing socket, an application can monitor and make changes to the
contents of the routing table.
Traditionally, a route table stored only one entry per destination network. For
IPv4, a destination network is identified by an IPv4 address and a netmask value.
For IPv6, a destination network is identified by an IPv6 address and a prefix value.
A route table entry associates this destination with a gateway on a local network
or with an interface on a local network. In previous route table implementations,
adding a route entry to the table failed if the table already contained an entry for
that destination.
Under the current network stack, the route table has been enhanced to store
multiple same-destination routes that differ by gateway value, TOS value, or
291
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
protocol value. Thus, in the current route table, adding a route entry to a table that
already contains an entry for that destination can succeed provided the new entry
differs from the existing entry (or entries) in its gateway value, TOS value, or
protocol value.
NOTE: Multi-route support is the default behavior. If you have access to the route
table source code, you can rebuild the code to exclude multi-route support. For
more information, see the Getting Started guide for your Platform.
When IP queries the route table, it expects to get back only one route. To satisfy this
expectation, the route table ranks multiple same-destination routes. The highest
ranked route, known as the primary or representative route for the destination, is
the route reported to IP. How the system ranks same-destination routes depends
on how you build the code.
This ability to store multiple same-destination routes is also not anticipated by the
standard routing socket message set. Thus, the standard routing socket message
set does not include messages that allow you to detect the reappearance of
secondary routes or to manipulate secondary routes. For this reason, the
Wind River Network Stack supports an enhanced message set. One of these new
message types, RTM_NEWIPROUTE, is available in all network stack versions.
In addition, the -DROUTER_STACK set of routing socket message types is
extended to facilitate cooperation among protocols that might need to share the
route table that stores redundant entries. For information on building the network
stack, see the Getting Started guide for your Platform.
In the route table produced by a host stack build, multiple same-destination routes
are ranked by age. The oldest route is the primary route. All newer routes are
ranked below the primary route according to age. Deleting the current primary
route reveals the next oldest route, if any. Thus, the routes are ranked in FIFO
order.
As mentioned above, the route table for a host build of the network stack ranks
multiple same-destination routes by age. However, if you build the network stack
with the -DROUTER_STACK option, multiple same-destination routes are ranked
by a user-assigned weight. If there are multiple same-destination routes, the
lowest weight entry is used as the representative route. If this representative route
is deleted, the next lowest-weight route becomes the new representative route.
292
15 Working with Routing Sockets
15.2 Getting Started with Routing Sockets
This chapter makes frequent reference to the route.h and if.h files. The full
pathnames for these files are:
installDir/vxworks-6.n/target/h/wrn/coreip/net/if.h
installDir/vxworks-6.n/target/h/wrn/coreip/net/route.h
The Wind River Network Stack supports the following routing socket
configuration component:
■
Routing Socket 15
293
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
To create a socket descriptor for use as a socket in the routing domain, call socket( )
with a domain value of AF_ROUTE, a type value of SOCK_RAW, and a protocol value
of 0 (zero). For example:
myRouteSocket = socket (AF_ROUTE, SOCK_RAW, 0);
if (routeSocket < 0)
{
your response code for the socket call failure
}
After you have the socket descriptor, you can make it non-blocking by making an
FIONBIO call to ioctl( ).
For example:
on = 1;
if (ioctl (myRouteSocket, FIONBIO, (int) &on) == -1) {
your response code for the ioctl call failure
}
Another socket option you might want to clear is the SO_USELOOPBACK option.
When this option is cleared, you will not hear the response to the messages that
you write to your socket.
on = 0;
if (setsockopt (myRtSock, SOL_SOCKET, SO_USELOOPBACK, (char *)&on,
sizeof (on)) == ERROR) {
your response code for the setsockopt call failure
}
A routing socket typically only sends a response if the requested operation fails.
The only exceptions are the GET messages, which also send a response with the
retrieved results (if successful). Thus, disabling this option will require a separate
routing socket to read the search results. Whether it is desirable or not to hear the
response is up to you. It can be good to monitor the response and thus check the
success or failure of the message that you wrote to the routing socket.
294
15 Working with Routing Sockets
15.3 Preparing and Processing Routing Socket Messages
This structure describes the fixed length message header for all but the following
routing socket message types:
#define RTM_NEWADDR 0xc /* address being added to interface */
#define RTM_DELADDR 0xd /* address being removed from interface */
#define RTM_IFINFO 0xe /* interface going up/down etc. */ 15
#define RTM_NEWMADDR 0xf /* mcast group membership added to if */
#define RTM_DELMADDR 0x10 /* mcast group membership being deleted */
#define RTM_IFANNOUNCE 0x11 /* iface arrival/departure */
295
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
296
15 Working with Routing Sockets
15.3 Preparing and Processing Routing Socket Messages
The first three members of the routing socket message header structures are all of
the same type and carry the same meaning. Thus, when a message first arrives on
a socket, you can read the routing socket message type value using any structure
overlay that is convenient. To make it easier to do this, you could receive the
message into a union. Consider the following code fragment skeleton:1
union
{
struct rt_msghdr rtHdr; /* route message header */
struct if_msghdr ifHdr; /* interface message header */
struct ifa_msghdr ifaHdr; /* interface address message header */
struct ifma_msghdr ifmaHdr; /* new or delete multicast msg hdr */
struct if_announcemsghdr ifaAnnHdr; /* interface change anncmnt */
} aRtSockMsg; /* a routing socket message */
aRtSockMsg theRtSockMsg;
int count;
u_char cmd;
FOREVER
{
count = recv(myRtSock, (char *)&theRtSockMsg, sizeof(aRtSockMsg), 0);
if ( count <= 0) {return;}
if ( theRtSockMsg.rtHdr.rtm_version != RTM_VERSION )
{
response code for a routing socket version mis-match 15
}
cmd = theRtSockMsg.rtHdr.rtm_type;
switch (cmd)
{
case RTM_ADD:
response code
case RTM_DELETE:
response code
case RTM_CHANGE:
response code
case RTM_GET:
response code
case RTM_LOSING:
response code
case RTM_REDIRECT:
response code
case RTM_MISS:
response code
case RTM_LOCK:
response code
case RTM_RESOLVE:
response code
1. Although this union is useful for receiving messages, it would waste resources to use it
when creating a routing socket message.
297
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
case RTM_NEWADDR:
response code
case RTM_DELADDR:
response code
case RTM_IFINFO:
response code
case RTM_NEWMADDR:
response code
case RTM_DELMADDR:
response code
case RTM_IFANNOUNCE:
response code
case RTM_ADDEXTRA: /* DEPRECATED, enhanced message set only */
response code
case RTM_DELEXTRA: /* DEPRECATED, enhanced message set only */
response code
case RTM_NEWCHANGE: /* enhanced message set only */
response code
case RTM_NEWGET: /* DEPRECATED, enhanced message set only */
response code
case RTM_GETALL: /* enhanced message set only */
response code
case RTM_NEWIPROUTE: /* new, but present in all stacks */
response code
case RTM_OLDIPROUTE: /* new, but present in all stacks */
response code
default:
response code
} /* End of switch (cmd) */
} /* End of FOREVER */
This code skeleton includes both the standard routing socket message as well as
the enhanced message set, which is available only if you build the network stack
with the -DROUTER_STACK build option defined.
Routing sockets on a VxWorks target running a host stack build use the standard
set of routing socket messages described in the routing sockets section of TCP/IP
Illustrated, Volume 2. Constants for these message types are defined in route.h as
follows:
#define RTM_ADD 0x1 /* add route */
#define RTM_DELETE 0x2 /* delete route */
#define RTM_CHANGE 0x3 /* change metrics or flags */
#define RTM_GET 0x4 /* report metrics */
#define RTM_LOSING 0x5 /* route suspected to be failing */
#define RTM_REDIRECT 0x6 /* told to use different route */
#define RTM_MISS 0x7 /* lookup failed on this address */
#define RTM_LOCK 0x8 /* lock specified metrics */
#define RTM_OLDADD 0x9 /* caused by SIOCADDRT */
#define RTM_OLDDEL 0xa /* caused by SIOCDELRT */
298
15 Working with Routing Sockets
15.3 Preparing and Processing Routing Socket Messages
Of the messages above, only five are valid for transmission to the routing table.
These are:
#define RTM_ADD 0x1 /* add route */
#define RTM_CHANGE 0x3 /* change metrics or flags */
#define RTM_DELETE 0x2 /* delete route */
#define RTM_GET 0x4 /* report metrics */
#define RTM_LOCK 0x8 /* lock specified metrics */
The router stack build of the network stack supports an extension to the standard
routing socket message set so that it can report events associated with the route
table’s ability to store multiple redundant routes (routes to the same destination).
For the most part, these extra message types are available only in a router stack
build of the network stack. The exceptions to this are RTM_NEWIPROUTE, and
RTM_OLDIPROUTE, which can be used with all network stack variants.
The extra message types are as follows:
#define RTM_ADDEXTRA 0xf /* Report creation of duplicate route */
#define RTM_DELEXTRA 0x10 /* Report deletion of duplicate route */ 15
#define RTM_NEWCHANGE 0x11 /* Change gateway of duplicate rt */ sendable
#define RTM_NEWGET 0x12 /* Find any route with gateway */ sendable
#define RTM_GETALL 0x13 /* Get route to dst & duplicates */ sendable
#define RTM_NEWIPROUTE 0x14 /* Replacement for deleted primary IP rt */
#define RTM_OLDIPROUTE 0x15 /* Demoted IP rt replaced with new entry */
Of the extra message types listed immediately above, only those marked sendable
are valid for transmission to the routing table.
In addition, the router stack build of the network stack makes slight changes to the
behavior of the RTM_ADD and RTM_DELETE messages. The following sections
describe these two messages as well as the extra message types.
RTM_ADD
Receiving this message indicates that some agent has attempted to add a new
route to the routing table. To know whether the attempt succeeded or failed,
check the rt_msghdr.rtm_errno field.
299
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Writing an RTM_ADD message adds a new route to the routing table if the
message is well formed and at least one of the following elements
distinguishes the new route from a route already existing in the table:
– destination address
– netmask value (or IPv6 prefix value)
– gateway
– protocol ID
– TOS
To monitor the success of an add request under the standard message set,
check the errno value, which is available from the send results.
The header for an RTM_ADD message is described by an rt_msghdr structure,
which is defined in route.h.
RTM_DELETE
Receiving this message indicates that some agent has tried to delete a route
from the routing table. To know whether the attempt succeeded, check the
rtm_errno field in the message header.
If the deleted route is an interface route, this RTM_DELETE is followed by an
RTM_DELADDR.
300
15 Working with Routing Sockets
15.3 Preparing and Processing Routing Socket Messages
To check whether the deleted route was a primary route, test the
rt_msghdr.rtm_flags field for an RTF_PRIMARY flag.
If the flag is set, the deleted route was a primary route. This also means that
the deleted route was the only route for the destination/netmask. For a router
stack, if there had been at least one secondary route to the destination, this
RTM_DELETE would have been preceded by an RTM_NEWIPROUTE in which
the RTF_PRIMARY flag was set. Consequently in this (final) RTM_DELETE
message, the RTF_PRIMARY flag would not be set, although it was the primary
route before the deletion occurred.
Previously, an RTM_DELETE message never occurred in response to the
deletion of a secondary route. A deleted secondary route was indicated by an
RTM_DELEXTRA. In the current network stack, the deletion of a secondary
route generates both an RTM_DELETE and an RTM_DELEXTRA, which is now
deprecated. RTM_DELEXTRA will be dropped from the next major release.
■ Writing an RTM_DELETE Message
Writing an RTM_DELETE message deletes a route from the routing table if the
message is well formed and if it matches a route in the table. The criteria by
which a match is made are:
– destination address
– netmask value (or IPv6 prefix value) 15
– gateway (a value of NULL functions as a wildcard)
– protocol ID (a value of 0 functions as a wildcard)
– TOS (a value of -1 functions as a wildcard)
You need to specify a protocol ID, a TOS value, and a gateway value only if
you want to delete a secondary route. To delete the primary route, it is enough
to specify only the destination address and netmask value. You can use the full
set of identifiers if you want.
To check the success of a delete request, monitor the socket for an incoming
RTM_DELETE.
The header for an RTM_DELETE message is described by an rt_msghdr structure,
which is defined in route.h.
RTM_GET
You can both read and write RTM_GET messages. Writing this message checks the
route table for a route to the specified destination. To check the success of the
request, monitor the socket for an incoming RTM_GET message. If the request was
successful, the route information is appended to the message header. If the request
301
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
failed to find a matching route, this is indicated in the rtm_errno field of the
message header.
The criteria by which a match is made are:
– destination address
– netmask value (or IPv6 prefix value)
– gateway (a value of NULL functions as a wildcard)
– protocol ID (a value of 0 functions as a wildcard)
– TOS (a value of -1 functions as a wildcard)
You need to specify the protocol ID, the TOS value, and the gateway value only if
you want to retrieve a secondary route. To retrieve the primary route, you need
specify only the destination address and netmask (or prefix) value.
The header for an RTM_GET message is described by an rt_msghdr structure,
which is defined in route.h.
RTM_LOSING
This is a read-only message. It indicates that the specified route might not still be
valid. TCP originates this message after four or more consecutive failed
retransmissions over the route.
The header for an RTM_LOSING message is described by an rt_msghdr structure,
which is defined in route.h.
RTM_REDIRECT
This is a read-only message. It indicates that ICMP has sent a redirect for the
specified destination, the address appended to the header in the RTA_DST
location. The address of a preferred gateway is appended to the message in the
RTA_GATEWAY location. The address of the author for the redirect message is
appended to the header in the RTA_AUTHOR location.
To know whether this message indicates a change in the contents of the route table,
check the rtm_errno value in the message header. A non-zero rtm_errno value
indicates a failed RTM_REDIRECT. A zero indicates a successful RTM_REDIRECT.
In this case, the table will contain a new host-specific route. This new host route is
created only if the original mis-directed route was a non-host (or network) route.
Otherwise, that existing host route is modified.
The header for an RTM_REDIRECT message is described by an rt_msghdr
structure, which is defined in route.h.
302
15 Working with Routing Sockets
15.3 Preparing and Processing Routing Socket Messages
RTM_MISS
This is a read-only message. It indicates that some agent’s search of the route table
failed to find a route to the specified destination. The header for an RTM_MISS
message is described by an rt_msghdr structure, which is defined in route.h.
RTM_LOCK
You can both read and write RTM_LOCK messages. Receiving this message
indicates that the metrics associated with the specified route are now locked.
Writing this message locks the metrics for the specified route. The header for an
RTM_LOCK message is described by an rt_msghdr structure, which is defined in
route.h.
RTM_CHANGE
Receiving this message indicates that an agent has changed the gateway,
metrics, or some other property associated with the route to the specified
destination.
■ Writing an RTM_CHANGE Message
15
Writing this message lets you change the gateway or metrics associated with
the route to the specified destination, which is identified by:
– destination address
– netmask value (or IPv6 prefix value)
– gateway (a value of NULL does not function as a wildcard)
– protocol ID (a value of 0 functions as a wildcard)
– TOS (a value of -1 functions as a wildcard)
You need to specify a protocol ID and TOS value only if you want to modify a
particular route. You can set these to wildcard values if matching on them is
not important to you. If multiple routes exist, you must specify a gateway in
order to select the matching entry.
All information in the message other than the destination and netmask are
interpreted as values that you want written into the existing route entry. If
only one route exists for a destination address and netmask, you can change
the gateway by providing a new gateway value. If multiple routes exist, then
you cannot change the gateway because the gateway is used to select the route
that is the entry you want changed.
303
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
RTM_NEWADDR
This is a read-only message. This message is the first of two messages associated
with adding an IP address to an interface. The second, an RTM_ADD, describes the
route through that interface to the subnet associated with the address.
For an RTM_NEWADDR message, the message header is described by an
ifa_msghdr structure, which is defined in if.h.
RTM_DELADDR
This is a read-only message. This message is the second of two messages associated
with deleting an IP address from an interface. The first, an RTM_DELETE, describes
the now deleted route through that interface to the subnet with the associated
address.
For an RTM_DELADDR message, the message header is described by an
ifa_msghdr structure, which is defined in if.h.
RTM_IFINFO
This is a read-only message. This message reports a change in status for the
specified interface. All routes through that interface are affected by the change. For
an RTM_IFINFO message, the message header is described by an if_msghdr
structure, which is defined in if.h.
RTM_NEWMADDR
You can both read and write RTM_NEWMADDR messages. By writing this type of
message, you can add a multicast group membership to an interface. Receiving
this message indicates that a group membership has been added to an interface.
For an RTM_NEWMADDR message, the message header is described by an
ifma_msghdr structure, which is defined in if.h.
RTM_DELMADDR
You can both read and write RTM_DELMADDR messages. By writing this type of
message, you can delete a multicast group membership from an interface.
Receiving this message indicates that a group membership has been deleted from
an interface. For an RTM_DELMADDR message, the message header is described
by an ifma_msghdr structure, which is defined in if.h.
304
15 Working with Routing Sockets
15.3 Preparing and Processing Routing Socket Messages
RTM_IFANNOUNCE
RTM_ADDEXTRA
RTM_DELEXTRA
RTM_NEWCHANGE
This is a message from the enhanced message set pulled in when you compile the
stack using the -DROUTER_STACK option. You can both read and write
RTM_NEWCHANGE messages.
■ Receiving an RTM_NEWCHANGE Message
Receiving this message indicates that an agent has changed the gateway,
metrics, or some other property associated with the route to the specified
destination. The format of the message is similar to but not identical to that of
an RTM_CHANGE. If the agent changed the gateway, the message must
provide you with both the new and old gateway addresses. The new gateway
address is reported in the standard gateway location. The old gateway address
is reported in the RTAX_AUTHOR location.
305
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
■
Writing an RTM_NEWCHANGE Message
RTM_NEWGET
RTM_GETALL
This is a message from the enhanced message set pulled in when you compile the
stack using the -DROUTER_STACK option. Writing an RTM_GETALL is the same
as writing an RTM_GET. The response is an RTM_GETALL message that includes
descriptions for all route entries for the specified destination, TOS, and protocol.
To retrieve a list of all routes for the specified destination, use wildcard values for
the TOS and protocol (-1 and 0 respectively).
306
15 Working with Routing Sockets
15.3 Preparing and Processing Routing Socket Messages
To read the route descriptions in a received RTM_GETALL message, start after the
routing socket header. There you will find:
■
a destination address
■
gateway addresses for all matches
■
a netmask
Use successive sockaddr_gate structures (if working with IPv4) or successive
sockaddr_gate6 structures (if working with IPv6) to interpret the data between the
destination address and the netmask. Use this special structure overlay to access
the route weight, protocol ID, and the RFC 1213 metrics for the route associated
with each gateway address.
The sockaddr_gate structure is defined in route.h as follows:
struct sockaddr_gate
{
u_char gate_len;
u_char gate_family;
u_char routeProto;
u_char weight;
u_long gate_addr;
long value1;
long value2;
long value3;
long value4;
long value5; 15
long routeTag;
long routeTos;
struct sockaddr * ifa;
struct sockaddr * ifp;
};
307
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The weight field of these structures is relevant only if you are working with the
enhanced message set.
RTM_OLDIPROUTE
RTM_NEWIPROUTE
The RTF flags indicate a route's type and other attributes. The various flags are can
be used differently, depending on circumstance. The following is a complete
listing of the supported RTF_name flags.
308
15 Working with Routing Sockets
15.3 Preparing and Processing Routing Socket Messages
309
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
310
15 Working with Routing Sockets
15.4 Extracting Information from a Routing Socket Message
In all received messages except an RTM_GETALL message, the TOS value and
protocol ID value are embedded in the socket address structure that provides the
destination address. For more on how to extract information from an
RTM_GETALL message, see RTM_GETALL, p.306.
If all 8 socket address structures were present in a message, the structures would
follow the header in the order shown below:
■ destination address
■ gateway address
■ netmask
■ cloning mask
■ interface name
■ interface address
■ address of the author of a redirect
■ broadcast or point-to-point destination address
These appended socket address structures supply all the remaining information
needed to identify a route table entry for the events (add, change, delete, and so
on.) associated with that route.
15
To tell you which addresses are actually included and which are omitted, the
routing socket message header provides an 8-bit mask. The name of the field that
contains this bit-mask is of the form: structure_addrs, where structure is rtm, ifm,
ifmam, or ifam. Each bit in the mask corresponds to one of the 8 addresses listed
above. If the bit is set, the address is present. If the bit is clear, the address is
omitted.
Consider a bit-mask of 0x87, which is 1000 0111 in base 2. In this mask, only four
bits are set, which tells you that the message after the header contains only four
addresses. Because the lowest order bit is set, you know that the first address after
the header is a destination address. Because the second and third lowest order bits
are set, you know that the second address is a gateway address, which is followed
by a netmask. The only other set bit is the highest order bit, which tells you that the
final (fourth address) is a broadcast address.
311
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
For convenience, route.h defines a set of constants for the bits in a structure_addrs,
mask. You can AND these constants against structure_addrs to test whether a
particular address is present in the message. These constants are as follows:
#define RTA_DST 0x1 /* destination sockaddr present */
#define RTA_GATEWAY 0x2 /* gateway sockaddr present */
#define RTA_NETMASK 0x4 /* netmask sockaddr present */
#define RTA_GENMASK 0x8 /* cloning mask sockaddr present */
#define RTA_IFP 0x10 /* interface name sockaddr present */
#define RTA_IFA 0x20 /* interface addr sockaddr present */
#define RTA_AUTHOR 0x40 /* sockaddr of redirect author or other */
#define RTA_BRD 0x80 /* for NEWADDR, brdcst or p-p dest addr */
void routingSocketAddressesGet(
struct rt_addrinfo *pRtAddrInfo, /* output, & _addrs mask */
struct sockaddr *pStartSockAddr, /* start of socket addresses */
2. This ROUNDUP( ) macro expresses “a” twice. Thus, inputs such as “foo++” evaluate twice,
which might not be what you intend.
312
15 Working with Routing Sockets
15.4 Extracting Information from a Routing Socket Message
{
int i;
The purpose of the ROUNDUP( ) macro call is to advance the pointer by the size of
a socket address structure rounded up to the next four-byte multiple. The main
reason for rounding up to the next four-byte multiple is that this is consistent with
how the message is constructed in the BSD routing socket implementation.
When calling a routine such as that above to extract the addresses from a routing
socket message received into a union such as:
union
{
struct rt_msghdr rtHdr; /* route message header */
struct if_msghdr ifHdr; /* interface message header */
struct ifa_msghdr ifaHdr; /* interface address message header */
} aRtSockMsg; /* routing socket message */
15
Assuming that you have previously declared and allocated:
struct rt_addrinfo rtAddrInfo;
When extracting the messages from a routing socket message that uses an
if_msghdr or an ifa_msghdr, keep in mind that these structures are not necessarily
the same size as the rt_msghdr. Thus, you would have to adjust the calculation of
pFirstSockAddr with a sizeof( ) call for the appropriate structure.
In received messages, the TOS value and protocol ID value are embedded in the
socket address structure that provides the destination address. You can use the
TOS_GET( ) and RT_PROTO_GET( ) macros to extract the TOS value or the protocol
ID from this socket address structure.
313
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
#define RT_PROTO_GET(pSockaddr) \
(((struct sockaddr_rt *)(pSockaddr))->srt_proto)
A value of -1 for TOS indicates that the sender did not want to specify a TOS value.
Similarly, a value of 0 for the protocol ID indicates that the sender did not want to
specify a protocol ID.
#ifdef ROUTER_STACK
#define RTM_NEWCHANGE 0x12 /* Change gateway of duplicate route */
#define RTM_NEWGET 0x13 /* Find any route with gateway */
#define RTM_GETALL 0x14 /* Get IP route to dst and duplicates */
#endif /* ROUTER_STACK */
Within these messages, you specify a route table entry using the following values:
■
a destination address, in the RTAX_DST socket address structure
■
a netmask, in the RTAX_NETMASK socket address structure
■
a gateway address, in the RTAX_GATEWAY socket address structure
■
a TOS value, in the RTAX_DST socket address structure (optional)
■
a Protocol ID, in the RTAX_DST socket address structure (optional)
The socket address structures referred to above are appended after the routing
socket message header.
To specify route metrics in the routing socket message, use the rt_metrics structure
in the rtm_rmx field of the routing socket message header. For more information,
see rtm_rmx – optional, for setting metrics, p.318.
314
15 Working with Routing Sockets
15.5 Building a Routing Socket Message
NOTE: Depending on the message type and whether the table stores more than one
entry for a destination, you may need to specify a destination address only, or a
destination and netmask only, or a gateway value.
Each of the writable routing socket message types use an rt_msghdr structure for
its header. When building a routing socket message, fill in the rt_msghdr members
as follows:
rtm_msglen – required in an outgoing message
Expects the length of the entire socket message. The reported size includes the
header plus all appended socket addressees. The best time to assign this value
is after you have appended the last address to the routing socket message. See
below, rtm_addrs – required in an outgoing message, p.316.
rtm_version – required in an outgoing message
Expects the version ID of the routing socket message. Under VxWorks, there
is only one valid value for this field, RTM_VERSION, which is defined in
route.h.
rtm_type – required in an outgoing message 15
Expects a value indicating the routing socket message type:
RTM_ADD – add a route
RTM_CHANGE – change the metrics for a route
RTM_DELETE – delete a route
RTM_GET – get the route for the specified destination
RTM_LOCK – lock the metrics associated with the specified route
If you built the network stack using the -DROUTER_STACK build option,
the following are also valid:
RTM_NEWCHANGE – change gateway of duplicate route
RTM_NEWGET – find any route with gateway
RTM_GETALL – get IP route to destination and duplicates
These message types (described 15.3.2 Types of Routing Socket Messages, p.298)
let you add, change, delete, get, or lock an entry in the route table. The
response to an add, change, lock, get, or delete message is an incoming add,
change, lock, get, or delete message on your socket. You can determine the
success or failure of your request by reading the rtm_errno field in the header
of the response message.
315
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
316
15 Working with Routing Sockets
15.5 Building a Routing Socket Message
With the above already defined, and assuming you have already allocated and
appropriately populated instances of so_dst, so_gate, so_mask, and the other
elements you need to include in the message, you could do the following:
struct aRtSockMsg theRtSockMsg;
char * theNextAddrStart = theRtSockMsg.msgPayload;
int appendedLength = 0;
bzero((char *)&theRtSockMsg, sizeof(aRtSockMsg));
NEXTADDR (
RTA_DST, /* type of address appended */
theRtSockMsg.msgHdr.rtm_addrs, /* mask of addr types in msg */
so_dst, /* address to append to msg */
theNextAddrStart, /* where address is appended */
appendedLength /* length just added to msg */
);
This macro call would append the destination address in so_dst to the
message space after the header in theRtSockMsg. It would also set the
RTA_DST bit in theRtSockMsg.msgHdr.rtm_addrs.3
Leaving theNextAddrStart at its current value, you would then follow this
with NEXTADDR( ) calls for all the addresses that you want to append in the
appropriate order. It is critical that you get the order correct and that you do
not accidentally append the same element more than once. The correct order
is as follows:
15
RTA_DST – destination address
RTA_GATEWAY – gateway address
RTA_NETMASK – netmask
RTA_GENMASK – cloning mask
RTA_IFP – interface name
RTA_IFA – interface address
RTA_AUTHOR – address of author of redirect
RTA_BRD – broadcast or point-to-point destination address
You are also now ready to set the value of rtm_msglen:
theRtSockMsg.msgHdr.rtm_msglen = (char *)theNextAddrStart
- (char *)&theRtSockMsg;
3. Do not forget that NEXTADDR( ) is a macro not a C routine. Thus, it can (and, in this case,
must) change the value supplied for theNextAddrStart.
317
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
318
15 Working with Routing Sockets
15.5 Building a Routing Socket Message
long value1;
long value2;
long value3;
long value4;
long value5;
long routeTag;
u_long weight;
};
If you use this structure to specify metric values for a route, you must also set
the appropriate flags in the rtm_inits field.
15.5.2 Setting the TOS and Protocol Values in a Routing Socket Message
When preparing the socket address structure containing the destination address,
you must embed both a TOS value and a protocol ID. To do this, use the
TOS_SET( ) and RT_PROTO_SET( ) macros, which are defined in route.h as
follows:
#define TOS_SET(pSockaddr, tosVal)
(((struct sockaddr_rt *)(pSockaddr))->srt_tos = tosVal)
319
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
320
16
Adding Routing Support
RIP, ARP, NDP, and ICMPv4
16.1 Introduction
This chapter describes how to select a route table storage mechanism. It also
describes some of the protocols used to maintain the contents of the route table.
Implementation
The route table implementation included with the Wind River Network Stack
supports the storage of multiple same-destination same-mask routes provided the
routes differ by a gateway value, TOS value, or protocol value. When IP queries
the route table, it expects to get back only one route. To satisfy this expectation, the
route table ranks multiple same-destination routes. The highest ranked route,
321
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
known as the primary route for the destination, is the route reported to IP. How
the system ranks same-destination routes depends on how you build the code.
In the route table produced by a host stack build, multiple same-destination routes
are ranked by age. The oldest route is the primary route. All newer routes are
ranked below the primary route according to age.
If the ability to store multiple same-destination routes is not required for your
application, and if you need to minimize the footprint of the routing table, you can
rebuild the network stack code to eliminate multi-route support. For more
information on this build option, see the Wind River Platforms Getting Started.
Storage Mechanisms
In addition, you can choose among three route table storage mechanisms. One
storage mechanism uses a PATRICIA1 tree to store routes. This is a good solution
for tables of moderate size. For very large tables, Wind River provides an AVL
storage mechanism. For very small route tables, Wind River provides a linked-list
storage mechanism. For more information, see 16.2 Selecting a Route Storage
Mechanism, p.323.
To add or remove routes from the route table, you can use a routing socket
connection or the routec( ) routine.
By default, the route table is able to store multiple same-destination routes. For
IPv4, a PATRICIA tree serves as the default storage mechanism. For IPv6, the
default is an AVL (Adelson-Velskii and Landis balanced binary search) tree. For
both IPv6 and IPv4, you can change the storage mechanism. You can use a simple
linked list as the storage mechanism instead of a PATRICIA or AVL tree, but only
if you expect to need only a very small table.
If reducing the image size is critical, you can recompile the route table source code
to eliminate support for storing multiple same-destination routes.
322
16 Adding Routing Support
16.2 Selecting a Route Storage Mechanism
323
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
If none of these route table storage mechanisms is appropriate to your needs, you
may implement your own. Your implementation must support the entry points
expected in an ipRouteDispatchTable structure, and those entry points must
conform to the APIs shown in ptRouteNodeLib.c, avlRouteNodeLib.c, and
llRouteNodeLib.c.
Route Storage
ROUTE_DEFAULT_WEIGHT
Synopsis: Default route weight, applied when the user does not specify one.
Default: 100
324
16 Adding Routing Support
16.3 Configuring VxWorks for Route Storage
325
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
ROUTE_SHOW_MEM
The default buffer size supports about 50 route entries. If, at run-time, you find
that the ROUTE_SHOW_MEM value configured at build time is too small to
buffer the output for the whole routing table, you can increase the global
(integer) variable routeShowMem. If you do this, the next time you call
routeShow( ), mRouteShow( ), or arpShow( ), the old buffer (if any) is freed,
and a new buffer the size of the new value of routeShowMem is allocated. You
can also use this method to decrease the size of the buffer.
3. A packet takes a hop every time it crosses a subnet. If a packet leaves machine Q and must
pass through two subnet routers before it reaches its destination on machine N, the number
of hops is two.
326
16 Adding Routing Support
16.4 Working with RIP
The RIP router supports three modes of operation: Version 1 RIP, Version 2 RIP
with multicasting, and Version 2 RIP with broadcasting.
Version 1 RIP
This mode of operation follows RFC 1058. It uses subnet broadcasting to
communicate with other routers and sends out only a gateway and metric for
each subnet.
Version 2 RIP with Multicasting
In this mode, the router not only knows about other routers but can also
describe routes based on their subnet mask and can designate a gateway that
is not the router that sends the updates. Thus, the machine that hosts the RIP
router does not necessarily have to be the gateway. Because this mode uses
multicasting to communicate, only interested nodes in the network see routing
information and updates.
Version 2 RIP with Broadcasting
This mode is the same as Version 2 RIP with multicasting, except that it uses
broadcasting instead of multicasting. This mode is backwards compatible with
RIP version 1 and is the mode recommended in RFC 1388.
The RIP implementation also supports an interface exclusion list that you can use
to exclude RIP from specific interfaces as they are brought online.
The INCLUDE_RIP component supplies ripLib and other software modules that
implement the Routing Information Protocol (RIP) for the Wind River
Network Stack. Including INCLUDE_RIP in a VxWorks image sets up a call to the
usrNetRipInit( ) initialization routine, which is defined in the
net/coreip/apps/usrNetRipCfg.c file.
The externally callable API associated with this configuration component is
provided in ripLib. For more information on this API, see the ripLib reference
entry.
! CAUTION: The RIP router does not support separate routing domains. Only
routing domain 0, the default, is supported.
327
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Configuration Parameters
RIP_EXPIRE_TIME
RIP_GARBAGE_TIME
RIP_GATEWAY
! WARNING: Do not set RIP_GATEWAY to TRUE unless this really is the general
gateway. Setting RIP_GATEWAY to TRUE configures the RIP router to ignore any
advertisements for default routers received from other RIP peers.
RIP_MULTICAST
328
16 Adding Routing Support
16.4 Working with RIP
In addition, not all RIP routers necessarily support multicasting. For example,
the BSD and SunOS routed implementations do not support multicasting.
RIP_SUPPLIER
RIP_SUPPLY_INTERVAL
RIP_TIMER_RATE
RIP_VERSION
RIP_AUTH_TYPE
329
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Run-time Configuration
In addition to setting the defines shown above, there are two alternate methods
you can use to configure RIP:
■ Use the m2Rip routines to configure RIP. These routines are documented in
the reference entries. The parameters to these routines are described in
RFC 1389.
■ Use an SNMP agent to configure RIP.
For debugging purposes, the RIP router provides ripRouteShow( ), a routine you
can use to print the router’s internal tables to the console. The printed message
provides the following information:
■ the route being advertised
■ the router that routes the packets
■ a subnet mask
■ the timeout on the route (in seconds)4
■
the flags value (see Table 16-1)
RIP periodically pushes routing information into the Wind River Network Stack
routing table. Between updates, the two tables can diverge, but updating only
periodically avoids route thrashing (pushing transient routes into the system route
table but then removing them immediately).
4. The timeout is the length of time for which the route remains current. If a route is not
updated within 3 minutes, it is flushed from the routing table.
330
16 Adding Routing Support
16.4 Working with RIP
Constant Definition
p Route is a primary route. If this flag is set, the o flag must also be set.
NOTE: If you exclude RIP, but include SNMP, you might want to edit
snmpMib2.mib to exclude RIP MIB objects. Including these objects does no harm, 16
but it makes the image unnecessarily larger.
By default, RIP runs on all interfaces active when RIP is initialized. If you do not
want to run RIP on a particular interface, you can specify the interface on a RIP
exclusion list. To manage an interface exclusion list, ripLib provides the following
routines:
■ ripIfExcludeListAdd( ) – add an interface to the RIP exclusion list
■ ripIfExcludeListDelete( ) – remove an interface from the RIP exclusion list
■ ripIfExcludeListShow( ) – show the interfaces on the RIP exclusion list
■ ripIfAddrExcludeListAdd( ) – add an interface to the RIP exclusion list
■ ripIfAddrExcludeListDelete( ) – delete an interface from the RIP exclusion list
■ ripIfAddrReset( ) – alter the RIP configuration after an interface changes
■ ripIfReset( ) – alter the RIP configuration after an interface changes
331
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The first three routines identify the interface by name. The next set specify
interfaces by IP address and netmask values. The final routine, ripIfReset( ),
updates the interface list and routing table for the interface specified. For more
information on these routines, see the relevant ripLib reference entries.
if (pIfp->ifConf.rip2IfConfStatus != M2_rip2IfConfStatus_valid)
return (ERROR);
Stopping RIP on an interface this way does not require that you put the interface
on the exclusion list.
By design, RIP is interested in only those routes that it created or that were
propagated by a RIP peer. Because the current RIP implementation monitors
routing table events using a routing socket, RIP now receives routing socket
332
16 Adding Routing Support
16.4 Working with RIP
messages when other agents (such as OSPF or the system manager) make changes
to the routing table.
By default, RIP still ignores these events. If you want RIP to respond to these
events, use ripRouteHookAdd( ) to register a policy filter to handle these events
for purposes such as propagating static routes or routes from other protocols. The
callback that you register must be of the following form:
STATUS xxripRouteHookRtn
(
struct ROUTE_INFO * pRouteInfo,
int protoId,
BOOL primaryRoute,
int flags
)
333
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
In response to this event, RIP needs to be told whether to ignore or add the route.
RIP does this based on the returned function value of the route hook routine. In the
case of this event, RIP interprets the returned function value of the route hook
routine as the metric for the route.
If the metric is HOPCNT_INFINITY, RIP ignores the route. If the metric is greater
than zero but less than HOPCNT_INFINITY, RIP accepts the route entry. If the route
is new to RIP, RIP adds the new route to its internal database, and then propagates
5. This event does not occur for the route added to the routing table when an interface is
assigned an IP address. Such routes should not be included in the RIP route database. Thus,
RIP never calls the route hook routine when such routes are added to the routing table.
334
16 Adding Routing Support
16.4 Working with RIP
the route in its subsequent update messages. If RIP already stores a route for that
destination, RIP compares the metric of the new route and the stored route. If the
new route has a better (lower) metric, RIP adds the new route. Otherwise, RIP
ignores the new route.
When generating its returned function value, your policy filter can use the creator
of the event (protoID) as a factor in the decision on whether to include the route.
For example, if you wanted the route hook to tell RIP to ignore all routes except
static routes, your route hook would return HOPCNT_INFINITY if the protoID was
anything other than M2_ipRouteProto_other. Routes added to RIP by means of
this policy filter never timeout. They remain in the RIP database until one of the
following events occurs:
■ an agent deletes the route from the system routing table
■ an agent deletes the interface through which the route passes
■ a route change message for the route arrives
In addition, these routes take precedence over RIP routes to the same destination.
RIP ignores routes learned from RIP peers if the policy filter installed a route to the
same destination.
In response to this event, RIP needs to be told whether to delete the route or change
its metric. If the hook returns a value greater than or equal to HOPCNT_INFINITY,
RIP deletes the route from its internal routing database. If the hook routine returns 16
a valid metric (a value greater than zero but less than HOPCNT_INFINITY), RIP
reassigns the route’s metric to equal the returned value of the route hook routine.
If the returned value of the route hook route is invalid (less than zero) RIP ignores
the event. RIP also ignores the event if the route specified in pRouteInfo is not one
stored in its internal database.
In response to this event, RIP never needs to make any changes to its internal
routing database. Thus, RIP ignores the returned function value of the route hook
routine called in response to an ICMP redirect message. Because this event may
indicate an incorrect router entry, its execution of the route hook routine allows
you to take appropriate action.
Within your route hook routine, you can recognize an ICMP event by checking
whether the flags parameter value sets the RIP_REDIRECT_RECD bit. The
primaryRoute parameter passes in a boolean value that indicates whether the route
is a primary route.
335
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Use ripRouteHookDelete( ) to uninstall the RIP hook routine. This causes RIP to
revert to its default behavior of ignoring all routing table events. Any routes
previously installed through any hook routine remain in the internal database.
STATUS ripRouteHook
(
ROUTE_INFO * pRouteInfo, /* Route information */
int protoId, /* Routing protocol ID */
BOOL primaryRoute, /* Primary route ? */
int event /* Whether redirect */
)
336
16 Adding Routing Support
16.4 Working with RIP
{
int ifIndex;
int metric;
struct sockaddr * pDstAddr, * pNetmask, * pGateway, * pOldGateway;
ifIndex = pRouteInfo->rtm.rtm_index;
if (routedDebug)
{
logMsg ("\nripRouteHook:
called for proto: %d, ifIndex=%d, Redirect = %s,"
" Initial metric = %d Primary route=%s\n", protoId, ifIndex,
(int)((event == RIP_REDIRECT_RECD) ? "Yes" : "No"),
pRouteInfo->rtm.rtm_rmx.rmx_hopcount,
(int)(primaryRoute ? "TRUE" : "FALSE"), 0);
ripSockaddrPrint (pDstAddr);
ripSockaddrPrint (pNetmask);
ripSockaddrPrint (pGateway);
}
if (event == RIP_REDIRECT_RECD)
{
if (routedDebug) 16
{
logMsg ("ripRouteHook:
Redirect received from\n", 0, 0, 0, 0, 0, 0);
ripSockaddrPrint (pOldGateway);
}
return (HOPCNT_INFINITY);
}
if (event == RIP_ROUTE_CHANGE_RECD)
{
if (routedDebug)
{
logMsg ("ripRouteHook: route change:
Old gateway:\n", 0, 0, 0, 0, 0, 0);
ripSockaddrPrint (pOldGateway);
}
}
/*
* If it is not a primary route return an infinite metric
* to let RIP ignore this route.
*/
337
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
if (! primaryRoute)
return (HOPCNT_INFINITY);
/*
* Calculate metric. We give preference to static routes
* over other routes This is an arbitrary metric which is
* the sum of protocol ID, interface index and the initial
* route metric. Since the static route has the lowest
* protocol ID it gets the lowest metric.
*/
if (routedDebug)
logMsg ("ripRouteHook: returning metric
%d\n", metric, 0, 0, 0, 0, 0);
return (metric);
}
NOTE: RIPng does not support the ripRouteHookAdd( ), a RIP (IPv4) utility, that
lets you register a policy filter to notice non-RIP route table events, such as the
addition of a static route or routes from other protocols. Nearly equivalent
functionality and more is built into RIPng and is accessible through the options
you supply in the RIPNG_OPTIONS_STRING string.
338
16 Adding Routing Support
16.5 Adding RIPng Support
To start RIPng, the network initialization code calls ripngStart( ). When called
from the command line, the syntax for ripngStart( ) is as follows:
ripngStart "options", priority
When the initialization code calls this routine, it uses the INCLUDE_RIPNG
component parameters as follows:
ripngStart RIPNG_OPTIONS_STRING, RIPNG_PRIORITY
RIPNG_PRIORITY
RIPNG_OPTIONS_STRING
339
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
340
16 Adding Routing Support
16.5 Adding RIPng Support
341
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The Wind River Network Stack includes two Address Resolution Protocol (ARP)
components.
ARP Management
ARP_ENTRY_1_HOST
Synopsis: The host name or IP address of the first entry in the ARP table.
Default: NULL, adds no permanent entry to the ARP table.
342
16 Adding Routing Support
16.6 Adding ARP and NDP Support
ARP_ENTRY_1_ADDR
The flags values used in these arpAdd( ) calls are always ATF_PERM (0x04), a flag
that creates a permanent ARP entry that will not timeout. The default values and
types for the ARP_ENTRY_n_HOST and ARP_ENTRY_n_ADDR parameter pairs are
identical with the pair described above.
ARP_ENTRY_2_HOST – host name or IP address of the second ARP table entry
ARP_ENTRY_2_ADDR – the Ethernet address for ARP_ENTRY_2_HOST
ARP_ENTRY_3_HOST – host name or IP address of the third ARP table entry
ARP_ENTRY_3_ADDR – the Ethernet address for ARP_ENTRY_3_HOST
ARP_ENTRY_4_HOST – host name or IP address of the fourth ARP table entry
ARP_ENTRY_4_ADDR – the Ethernet address for ARP_ENTRY_4_HOST
ARP_ENTRY_5_HOST – host name or IP address of the fifth ARP table entry
ARP_ENTRY_5_ADDR – the Ethernet address for ARP_ENTRY_5_HOST
343
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
routing to access the managed devices on that subnet. This would require an entry
in the route table of each host interested in the managed devices. Proxy ARP lets
you avoid this configuration work.
For more information, see the proxyArpLib reference entries.
Related RFCs
Parameter Descriptions
The parameters below let you set up a Proxy ARP server that proxies for a single
proxied subnet. Using the API supplied by proxyArpLib, you can configure the
server to handle additional subnets. Thus, a single server can proxy for multiple
subnets. Devices on the proxied subnet must not open interfaces directly onto the
main network. You risk creating network circles and broadcast storms.
PROXYD_MAIN_ADDRESS
PROXYD_PROXY_ADDRESS
CLNT_TBL_SZ_CFG
344
16 Adding Routing Support
16.6 Adding ARP and NDP Support
PORT_TBL_SZ_CFG
ARP_DEBUG_CFG
PROXY_ARP_VERBOSE_CFG
PROXY_BROADCAST_VERBOSE_CFG
PROXY_BROADCAST_FWD_CFG
ARP_REGISTER_CFG
345
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Using NDP, same-link nodes can discover each other’s presence, determine their
respective link-layer addresses, and monitor changes in the addressing or
accessibility of neighbors on the local link. Because the monitoring is active, NDP
can purge cached information that has become invalid. It also lets a host notice
when a router (or the path to a router) fails, which not only lets the host purge the
old route but also triggers a search for a replacement router. This is accomplished
using the following ICMPv6 message types:
Router Solicitation
A host transmits a router solicitation to the local link to discover local routers.
If any IPv6 routers are present, they each respond with a router advertisement.
A host typically initiates a router solicitation through an interface just after
enabling that interface.
Router Advertisement
A router transmits this message to the local link periodically or in response to
a router solicitation. The message contains information such as a prefix that a
host can use for on-link determination, a suggested hop limit value, and the
like. To specify the prefixes that a router advertisement transmits through a
particular interface, use rtadvConfig( ).
Neighbor Solicitation
A node transmits a neighbor solicitation message to determine whether any
local node is using a specific IPv6 address. If a local node is using the address,
it responds with a neighbor advertisement message. A node uses periodic
neighbor solicitations to verify whether a neighbor is still reachable using a
cached link-layer address.
A node also uses neighbor solicitation messages for duplicate address
detection. At boot time, a node constructs a valid link-local IPv6 address for
each of its interfaces. The node may also construct global IPv6 addresses or
acquire them through DHCP. Before using any of these addresses, it sends out
a neighbor solicitation to test that the address is not already in use. Duplicate
address detection is an element of the IPv6 stateless address autoconfiguration
process, which is described in detail in RFC 2462.
Neighbor Advertisement
A node transmits a neighbor advertisement in response to a neighbor
solicitation, if it owns the solicited address. A node can also send an
unsolicited neighbor advertisement to announce a change to its link-layer
address.
346
16 Adding Routing Support
16.7 Using the ICMPv4 Router Discovery Server
Redirect
A router transmits a redirect message to inform hosts of a preferred router to
a destination or to a preferred host.
At build time, the INCLUDE_NDP configuration component supports a
mechanism for adding up to six NDP cache entries. At run-time, you can use
ndp( ) to manage the NDP cache. For more information, see the ndp( ) reference
entry.
NOTE: When using rdCtl( ) to adjust the minimum and maximum broadcast
interval, keep in mind that the minimum value must always be lower than that of 16
the maximum. Thus, if you want to change the current maximum to a value less
than that of the current minimum, you must first reduce the minimum to a value
less than the intended maximum. Likewise, if you want to increase the current
minimum to a value greater than the current maximum, you must first increase the
maximum to a value greater than the intended minimum.
Interested hosts on the local network can read the advertisement message and add
that information to their routing table. Interested hosts can also broadcast a router
discovery request message at any time. Hosts that depend on router discovery to
find a router can do this at boot time. In response to a host solicitation, the server
unicasts an advertisement back to the host.
347
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The rdiscLib library does not implement the host side of ICMP router discovery.
A host can solicit for a router at any time simply by multicasting an ICMP router
discovery message to address 224.0.0.2. The format of the solicitation and response
messages is as specified in RFC 1256.
RDISC_PRIORITY
RDISC_OPTIONS
RDISC_STACKSIZE
The rdiscLib functionality includes the control routine rdCtl( ). Using this routine,
you can control the router discovery application and the content of the
advertisements that it transmits.
■
Application control functionality includes:
– shutting down router discovery entirely
– turning router discovery on or off for a specific interface
– setting an IP address to which advertisements are broadcast
– setting the maximum interval between advertisement transmissions
– setting the minimum interval between advertisement transmissions
– turning debugging messages off or on
■
Advertisement content control functionality includes:
348
16 Adding Routing Support
16.7 Using the ICMPv4 Router Discovery Server
– advertisement lifetime
– advertisement preference level
For more information, see the rdCtl( ) reference entry.
The rdiscLib implementation was written before the network stack included a
registration mechanism for applications interested in interface status events. Thus,
if the Wind River Network Stack host adds or removes an interface after boot time,
the router discovery server will not automatically respond to the change. This can
result in failure to transmit advertisements on the newly started interfaces or in
attempts to transmit advertisements on missing interfaces. To inform rdiscLib of
an interface status changes, call rdiscIfReset( ) immediately after starting or
shutting down an interface.
16
349
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
350
17
Using Fast IP Forwarding
17.1 Introduction
A fast IP-forwarding mechanism, also known as a fast path application, intercepts
packets (either IPv4 or IPv6) before they are passed up to IP. If the packet is
destined for a location known to the fast path route cache (also known as the FIB,
the forwarding information base), the application forwards the packet. If the
destination is unknown to the FIB, the application leaves the packet to IP.
This two-level approach lets you bypass regular IP processing for selected packets.
This improves performance on packets headed for destinations known to the FIB.
It reduces performance for all other packets, but overall router performance is
improved if most traffic is headed for destinations known to the FIB. Thus, under
351
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
the right conditions, implementing fast path on a router can result in significant
performance improvements.
In addition to the forwarding mechanism, a fast path application requires a
populated FIB. To support the ability to populate and manage this FIB, the
network stack now supports fastPathLib. This library provides a registration
mechanism for fast path applications interested in the contents of the route table.
The network stack includes a sample fastPathLib application. This sample
application is for demonstration purposes only and is not intended for use as a
deployed fast path application.
352
17 Using Fast IP Forwarding
17.2 Configuring VxWorks for Fast Path
FF_IPV4_INIT_RTN
Use this parameter to specify the initialization routine for an IPv4 fast path
application. Enter a value of -1 if you do not want to initialize an IPv4 fast path
application.
FF_IPV6_INIT_RTN
Use this parameter to specify the initialization routine for an IPv6 fast path
application. Enter a value of -1 if you do not want to initialize an IPv6 fast path
application.
FF_IPV4_FIB_DISP_TBL
Synopsis: IPv6 FIB dispatch table storage method; default is an AVL tree.
Default: avlRibDispatchTable
Use this parameter to supply a storage method for the FIB used by the sample
IPv6 fast path application. A value is required if FF_IPV6_INIT_RTN is not set
to -1.
353
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
There are two ways to start a fast path application. One method uses the
parameters of the ffLibInit( ) routine to launch a fast path application.
Alternatively, you can call the application’s initialization routines directly at a
convenient time after the initial call to ffLibInit( ).
Including the INCLUDE_FASTPATH component in an image sets up an automatic
boot-time call to ffLibInit( ). This routine expects four parameters. The values
passed to this call are configurable at build time using the INCLUDE_FASTPATH
component parameters:
FF_IPV4_INIT_RTN
This parameter expects the initialization routine for an IPv4 fast forwarding
application, or -1 if you do not want to initialize an IPv4 fast path application
at boot time. The default value for this parameter is ipFFInit, the initialization
routine for the sample fast path application.
FF_IPV6_INIT_RTN
This parameter expects the initialization routine for an IPv6 fast forwarding
application, or -1 if you do not want to initialize an IPv6 fast path application
at boot time. The default value for this parameter is ipFFInit, the initialization
routine for the sample fast path application.
354
17 Using Fast IP Forwarding
17.3 Launching and Enabling a Fast Path Application
FF_IPV4_FIB_DISP_TBL
Expects NULL or a pointer to the FIB management routines for the IPv4 fast
path application. The default value for this parameter is ptRibDispatchTable,
which implements a PATRICIA tree FIB.
FF_IPV6_FIB_DISP_TBL
Expects NULL or a pointer to the FIB management routines for the IPv6 fast
path application. The default value for this parameter is
avlRibDispatchTable, which implements an AVL tree FIB. This is the
preferred choice for very large FIBs because, for very large FIBs, an AVL tree
FIB outperforms a PATRICIA tree FIB.
If you use these parameters to launch a fast path application, the system
automatically calls ffLibCachePopulate( ), which populates your application’s
route cache. It also automatically calls ffLibModeSet( ) to set the mode to
FF_START. Setting the mode to FF_START does not start packet forwarding, it just
initializes FIB management for the specified application.
If you set NULL values for the INCLUDE_FASTPATH component parameters, you
must call your application’s initialization routine directly. You also need to handle
the calls to ffLibCachePopulate( ) and ffLibModeSet( ).
After the application is started, you need to enable fast forwarding on at least two
interfaces and for the application as a whole. 17
355
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
NOTE: If you use ffLibInit( ) to start the fast path application, it internally
handles the ffLibModeSet( ) and ffLibCachePopulate( ) calls.
4. Enable IP forwarding:
Sysctl "net.inet.ip.forwarding=1"
The system should now be able to fast forward packets between the two
interfaces. Verify this by calling the ffLibCachePrint( ) to check the status:
-> ffLibCachePrint ffCookie
356
17 Using Fast IP Forwarding
17.4 Writing the Initialization Routine for a Fast Path Application
vc 10.0.0.0/24 0 0 0 /2
vc 30.0.0.0/24 0 0 0 /3
-------------------------------------------------------------------------
Direct routes
VC destination Gateway MAC Address MTU flags Refcnt UseCnt? Iname/Idx
-------------------------------------------------------------------------
-------------------------------------------------------------------------
value = 0 = 0x0
->
Within your initialization routine, you need to allocate resources for the interface
17
to fastPathLib. To be compatible with VxWorks configuration utilities, your
externally callable initialization routine should be of the following form:
FF_OBJ * xxInit /* FF_OBJ from internal ffLibObjInit() call. */
(
int numRoutes, /* Maximum number of routes in the FIB. */
int proto, /* Protocol for this FIB, e.g. IP v4. */
FIB_DISPATCH_TBL *pFibDispTbl /* FIB dispatch table. */
)
The numRoutes parameter should limit the number of routes stored in your fast
path FIB. Limiting the number of routes in the FIB can be critical to the efficiency
of the fast path application. The fewer entries there are in the FIB, the faster you
can search the FIB. How you enforce this limit depends on how you implement
your FIB.
Regardless of how you implement your FIB, you must remember that entries are
added to the FIB only when they are added to the route table. Thus, if you remove
357
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
an entry because the FIB is full (and not because the route was deleted from the
route table), the removed route can never make it back into the fast path FIB. In
addition, when you remove an entry to make room, you also must remove all less
specific entries. Otherwise, the less specific entries could be used to incorrectly
forward packets.
The proto parameter specifies the type of protocol (such as IPv4 or IPv6) for which
the application provides fast forwarding. Currently, there are only two valid
values, FF_PROTO_IPV4 and FF_PROTO_IPV6. This information is needed as part
of the input an application must provide when it registers with fastPathLib.
NOTE: fastPathLib never interacts directly with the FIB of an application. Thus,
the details of how you reserve and manage storage for your fast path FIB are
entirely up to you. This modularization of the FIB management routines is not
required by fastPathLib, but it was useful in the sample application.
Currently, the network stack supplies two FIB implementations. The FIB
implementation in ptRouteNodeLib.c defines ptRibDispatchTable, a table of
routines that manage a FIB implementation based on a PATRICIA tree. The FIB
supplied in avlRouteNodeLib.c defines avlRibDispatchTable, a table of routines
that manage a FIB implementation based on an AVL tree.
Within your initialization routine, you must allocate, initialize, and return an
FF_OBJ structure dedicated to your application instance. To initialize this
structure:
1. Zero-out the FF_OBJ structure.
2. Set FF_OBJ.ffVersion to FF_VERSION.
358
17 Using Fast IP Forwarding
17.4 Writing the Initialization Routine for a Fast Path Application
NOTE: Aside from the ffVersion field, never set any FF_OBJ members directly.
Treat the FF_OBJ members as read-only entities.
359
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
360
17 Using Fast IP Forwarding
17.6 Managing Your Fast Path Application
As routes in the route table are modified, deleted, or added, fastPathLib informs
the relevant registered fast path application of the changes. If the event concerned
an IPv4 route, the registered IPv4 fast path application (if any) is informed of the
event. Likewise, if the event concerned an IPv6 route, the registered IPv6 fast path
application (if any) is informed of the event. fastPathLib supports only one fast
path application per protocol.
When a route is deleted, fastPathLib calls the xxRouteDeleted( ) entry point (see
ffRouteDeleted, p.367) or the xxMacEntryDeleted( ) entry point (see
ffMacEntryDeleted, p.369) from the registered IPv4 or IPv6 application. A changed
route entry generates a call to the xxRouteModified( ) entry point (see
ffRouteModified, p.367).
The addition of a new route results in two different entry point calls. The first is a
call to the xxRouteAdded( ) entry point (see ffRouteAdded, p.366). This provides
information on a route when it is first added to the route table. Because the route
table does not yet have ARP or link layer information for the new route,
fastPathLib cannot supply the xxRouteAdded( ) call with forwarding information
17
(such as the MAC address of the next hop or destination). As soon as the ARP
information is available, fastPathLib supplies it by calling the registered IPv4 or
IPv6 xxRouteComplete( ) entry point (see ffRouteComplete, p.368).
361
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
362
17 Using Fast IP Forwarding
17.7 Writing Fast Path Application Entry Points
To ensure the integrity of the FIB and the application state, fastPathLib takes the
splnet lock whenever it calls an entry point in your fast path application.
363
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
In the following prototype descriptions, you will see the same parameters
appearing repeatedly. Below are generic descriptions of these common
parameters.
pFFObj
A pointer to the FF_OBJ used to register this fast path application instance with
fastPathLib. Never directly modify the members of this structure after it is
initialized in a call to ffLibObjInit( ).
weight
Indicates the weight associated with the route. FF_REP_ROUTE is passed in for
a representative route. Otherwise, this parameter passes in the actual route
weight, a value that is assigned to the route by the agent that creates the route.
pDstAddr
Points to the destination network protocol address.
pNetmask
Points to the destination netmask.
pGateway
Points to the gateway address.
flags
Passes in a value that describes whether the route is a gateway route, a host
route, an interface route, or a point-to-point route. Valid values are:
■ FFF_INDIRECT – indicates an indirect (gateway) route.
■ FFF_HOST – indicates a route to a host.
■ FFF_IF_ROUTE – indicates an interface route.
■ FFF_PTP – indicates a point-to-point interface route.
Although you do not use FFF_IF_ROUTE routes (interface routes) directly to
transmit packets, they do provide valuable information.
Thus, your application does need to store and manage them. Your application
needs to store the information in a way that prevents it from forwarding
packets destined to a local interface. In the sample application, such routes are
stored in the FIB, but they are marked as INCOMPLETE, which prevents
forwarding.
mtuSize
Specifies the MTU size (maximum transfer unit size) of the interface associated
with a route. Use this value to determine whether the packet needs to be
364
17 Using Fast IP Forwarding
17.7 Writing Fast Path Application Entry Points
ffShutdown
ffPktSend
365
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
ffRouteAdded
fastPathLib calls your xxRouteAdded( ) routine to tell your fast path application
that a route has just been added to the route table. fastPathLib also calls
xxRouteAdded( ) to respond to an ffLibCachePopulate( ) call.
When fastPathLib uses your xxRouteAdded( ) to report that a route has just been
added to the route table, the route description is necessarily incomplete, unless the
route is though a non-MAC interface, such as a PPP interface. This is because
fastPathLib calls your xxRouteAdded( ) before the route table has received the
366
17 Using Fast IP Forwarding
17.7 Writing Fast Path Application Entry Points
ARP information for the route. When the ARP information arrives, fastPathLib
calls your xxRouteComplete( ) to pass the information along to your fast path
application.
When fastPathLib calls your xxRouteAdded( ) as part of its response to a
ffLibCachePopulate( ) call, it calls it for each route in the slow path route table.
The routes that you create for these calls must all be incomplete, except for routes
through the non-MAC interface. The next time slow path transmits a packet over
one of these routes, fastPathLib will call your xxRouteComplete( ) to supply the
information needed to complete the route entry.
NOTE: It is within xxRouteAdded( ) that your fast path application must enforce a
filter policy that determines which routes are stored and which are ignored.
ffRouteDeleted
fastPathLib calls your xxRouteDeleted( ) routine to tell your fast path application
that a route has been deleted from the route table. Within this routine, your fast 17
path application should delete the specified route from your fast path FIB if it is
present. Failure to find the route in your FIB does not necessarily indicate a
problem. Depending on the filtering policy you implement (if any), you might not
have stored the route when fastPathLib informed you of its creation.
ffRouteModified
367
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
fastPathLib calls your xxRouteModified( ) to tell your fast path application that
the described route has changed.
ffRouteComplete
368
17 Using Fast IP Forwarding
17.7 Writing Fast Path Application Entry Points
ffMacEntryDeleted
ffRouteDemoted
17
The prototype for this entry point is as follows:
STATUS xxRouteDemoted
(
FF_OBJ *pFFObj, /* Fast Path Application Identifier. */
int flags, /* route: indirect, host, interface, p-to-p.*/
struct sockaddr *pDstAddr, /* Destination Address. */
struct sockaddr *pNetmask, /* Network mask (IPv4) or prefix (IPv6). */
struct sockaddr *pGateway, /* Gateway address. */
)
fastPathLib calls your xxRouteDemoted( ) to tell your fast path application that
the described route has been demoted. A demoted route should not be used for IP
forwarding.
369
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
ffRoutePromoted
fastPathLib calls your xxRouteDemoted( ) to tell your fast path application that
the described route has been promoted. A promoted route should be used for IP
forwarding instead of the previously representative route for the destination.
ffInterfaceModeChanged
NOTE: In a hardware-based forwarder, make sure that you forward packets only
if the system manager has enabled forwarding for both the application and the
interface. For a software based forwarder, this is handled for you. In a software
forwarder, the system will not call the ffPktSend( ) routine unless forwarding is
enabled for both the application and the interfaces.
370
17 Using Fast IP Forwarding
17.7 Writing Fast Path Application Entry Points
ffModeChanged
371
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
FF_IFADDR_DELETE
An address has been deleted from the interface. The address is identified
in the ffIfAddrArg structure referenced in pArg. Applications should
typically delete routes passing through the affected virtual interface. Note
that for a single physical interface, there can be many virtual interfaces,
each designated by its own ifaddr.
FF_IF_DELETE
The interface has been deleted. Your fast path application should flush all
routes going through this interface. For this value, pArg is always NULL.
FF_IF_ADD
The interface has been added.
FF_IF_UP
The interface has been brought up. Consider revalidating any FIB entries
associated with this interface.
FF_IF_DOWN
The interface has been brought down. Consider invalidating any FIB
entries associated with this interface.
pArg
If status is either FF_IFADDR_ADD or FF_IFADDR_DELETE, this parameter
passes in a pointer to an ffIfAddrArg structure that contains the address
added to or deleted from the interface identified in ifIndex. The ffIfAddrArg
structure is defined as follows:
struct ffIfAddrArg /* Defined in fastPathLib.h. */
{
struct sockaddr * pIfaAddr; /* Interface address. */
struct sockaddr * pIfaNetmask; /* Interface netmask or prefix. */
};
fastPathLib calls this routine to notify the application of an interface being added
or deleted, or of an address being added to or deleted from that interface.
ffFibFlush
fastPathLib calls this entry point when some agent has called ffLibCacheFlush( ).
Internally, your xxFibFlush( ) should do whatever is necessary to clear all route
entries currently stored in the fast path FIB.
372
17 Using Fast IP Forwarding
17.7 Writing Fast Path Application Entry Points
ffFibWalk
Your xxFibWalk( ) implementation must call this routine for each route in
your FIB and then return when it reaches the end of the FIB. For the first
parameter, pass in a FIB entry using a FF_PUB_FIB_ENTRY structure, which is
defined as:
typedef struct ffPubFibEntry
{
SOCKADDR_STORAGE_T dstAddr;
SOCKADDR_STORAGE_T netmask;
SOCKADDR_STORAGE_T gateAddr;
struct sockaddr_dl macAddr;
unsigned int routeMetric;
unsigned int ifMtu;
unsigned int ifIndex;
unsigned int useCount;
unsigned int refCount; 17
unsigned int flags;
void * pOutIfCookie;
} FF_PUB_FIB_ENTRY;
373
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
xxFibLookup
374
18
Adding IGMP, MLD, and
Multicast Routing Support
18.1 Introduction
The Wind River Network Stack implements IGMP and MLD to support
multicasting in the IPv4 and IPv6 domains.
In support of multicasting in the IPv4 domain, the Wind River Network Stack
implements the Internet Group Management Protocol (IGMP). An IGMPv2 host is
available to all builds of the network stack. The IGMPv3 host and the IGMPv2
router are only available in the Wind River Platforms builds. There is no router
implementation for IGMPv3 in any build of the network stack.
In support of multicasting in the IPv6 domain, the Wind River Network Stack
implements the Multicast Listener Discovery (MLD) protocol. An MLDv1 host is
375
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
available to all builds of the network stack. The MLDv2 host and MLDv2 router
implementations are only available in the Wind River Platforms.
Currently, Wind River does not supply a PIM implementation. Consequently, the
MLDv2 router implementation cannot act as a true MLDv2 router, but it can act as
a relay agent that proxies for a PIM-coupled MLDv2 router. However, because the
network stack does include the socket mechanisms required for accessing
multicasting functionality, you can port a PIM implementation (or an equivalent)
if necessary.
NOTE: The IGMPv2 router, the IGMPv3 host, and the MLDv2 protocols are
available only in the Wind River Platforms builds of the network stack. The Wind
River General Purpose Platform, VxWorks Edition, does not support these
features
IP Addressing
Both IGMP and MLD define a set of control messages that IP hosts can use to
inform routers of their interest in joining or leaving a multicast group. Hosts may
join or leave multicast groups freely and at any time.
Associated with each multicast group is a specific IP address. Any host that wants
to send data to the members of a multicast group need only transmit to the
appropriate multicast IP address. Hosts that want to transmit multicast data need
not be members of the multicast group to which they transmit. When an IP stack
on a router receives a packet with a multicast group destination address, the router
forwards the packet to any hosts that have registered with it for that multicast
group. Thus, although any host can transmit to a multicast group, only registered
group members receive the multicast.
IPv4
Under IPv4, multicast group addresses are restricted to the class D addresses,
which range from 224.0.0.0 to 239.255.255.255. Within this range, certain addresses
and address ranges are already registered to specific uses and protocols. For
example, 224.0.0.1 multicasts to all systems on the local subnet. The Internet
Assigned Numbers Authority (IANA) maintains a list of registered IPv4 multicast
groups. As described in RFC 3232, this list is now published online at:
http://www.iana.org/assignments/multicast-addresses
This online list obsoletes RFC 1700.
376
18 Adding IGMP, MLD, and Multicast Routing Support
18.1 Introduction
IPv6
Under IPv6, multicast addresses are those addresses that begin with an 8-bit prefix
of 11111111, or FF, followed by 8 additional bits used to indicate reserved
addresses, well-known addresses, and the scope of the address. The remaining bits
define the multicast group ID. Under IPv6, multicast addresses can be scoped to
the local node, link, site, and so on. IPv6 routers will not forward a multicast packet
beyond the scope of the packet address. For detailed information on IPv6 multicast
addresses, see RFC 3513 and RFC 2375. For information on assigned multicast
addresses, see the IANA online database at:
http://www.iana.org/assignments/ipv6-multicast-addresses
Although IP multicasting is not a link-layer feature, it does require some support
from the underlying network interface driver. You must be able to configure the
network interface to know which multicast groups (addresses) are of interest to it.
When packets addressed to those groups arrive on the interface, the driver passes
the packet up to IP. Otherwise, the driver ignores the packet. All END drivers
currently shipped with the Wind River Network Stack support this ability.
The mechanics by which an application adds its host to a multicast group and
transmits or receives multicast data are usually handled using a UDP socket
connection. An example of how to manage a multicast send and receive is
provided in 13.2.2 Using a Datagram (UDP) Socket to Access IPv4 Multicasting, p.260.
377
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
For the host side of the protocol, whether you get IGMPv2 or IGMPv3 depends on
how the network stack was compiled. The default build creates IGMPv2 modules.
However, if you build the stack with IGMPV3 defined, you create IGMPv3
modules. For the router side of the protocol, the stack supports a V2
implementation but not a V3 implementation.
NOTE: For information on building the network stack, see your Wind River
Platforms Getting Started.
The Wind River Network Stack supports the following host and router
components for IGMP, the protocol that provides multicasting support in the IPv4
domain:
■
IGMP v4
■
IGMP Router
These components are listed under the
Network Components > Network Protocol Components >
Network IPv4 Components folder in Workbench.
IGMP v4
378
18 Adding IGMP, MLD, and Multicast Routing Support
18.2 Adding IGMP Host and Router Support
Both IGMPv2 and IGMPv3 support the socket options MCAST_JOIN_GROUP and
MCAST_LEAVE_GROUP. As described in the RFCs, you can use these socket
options to join or leave multicast groups. To support source filtering, IGMPv3 (but
not IGMPv2) supports four additional options:
MCAST_JOIN_SOURCE_GROUP and MCAST_LEAVE_SOURCE_GROUP
Using the option MCAST_JOIN_SOURCE_GROUP, you identify not only the
group you want to join but also the IPv4 address of the source from which you
will accept multicast packets. To leave the group, you can use either the
standard MCAST_LEAVE_GROUP socket option or the new
MCAST_LEAVE_SOURCE_GROUP socket option. If you use the newer option,
you can be specific about the group and source you are leaving. If you are
registered for more than one source, those other sources remain active. The
MCAST_LEAVE_GROUP socket option removes all sources.
To register for more than one source, some circumstances allow multiple
MCAST_JOIN_SOURCE_GROUP calls. However, the least ambiguous method
is to use the SIOCMSFILTER ioctl, which lets you specify more than one source
in the leave or join command.
For more information on these socket options and the ioctl, see RFC 3678.
MCAST_BLOCK_SOURCE and MCAST_UNBLOCK_SOURCE 18
Using the option MCAST_BLOCK_SOURCE, you identify the group you want
to join as well as the IPv4 address of a source from which you will not accept
multicast packets. To unblock that source, you use
MCAST_UNBLOCK_SOURCE. To block more than one source, some
circumstances allow multiple MCAST_BLOCK_SOURCE calls. However, the
least ambiguous method is to use the SIOCMSFILTER ioctl, which lets you
specify more than one source in the command.
For more information on these socket options and the ioctl, see section 5 of
RFC 3678. The mechanisms described in section 5 are protocol independent.
Alternatively, you could see section 4 of the same RFC. This section describes
a parallel set of options that are IP-specific.
379
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
IGMP Router
NOTE: This component is available only in the Wind River Platforms builds of the
network stack. The Wind River General Purpose Platform, VxWorks Edition, does
not support the IGMP router.
If your custom PIM implementation implements the IGMP router portion of the
protocol, you can exclude INCLUDE_IGMP_ROUTER.
380
18 Adding IGMP, MLD, and Multicast Routing Support
18.2 Adding IGMP Host and Router Support
■
igmpRouterLibQuit( ) – shut down the IGMPv2 router
■
igmpInterfaceEnable( ) – enable IGMPv2 on the specified interface
■
igmpInterfaceDisable( ) – disable IGMPv2 on the specified interface
For detailed information on the above routines, see the igmpRouterLib reference
entries.
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.
381
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Note that if the router needs to open an IGMP control socket (for operations like
adding or deleting MFC entries or virtual interfaces), it should use the same socket
for sending and receiving the IGMP protocol messages.
After you have opened the multicast routing socket, you can use it to enable or
disable multicast forwarding.
Consider the following code:
int version = 1;
setsockopt( mRoutSock, IPPROTO_IP, MRT_INIT, (void *)&version,
sizeof(version) );
After you have enabled multicast forwarding, you can use the multicast routing
socket to enable PIM processing in the kernel. See 18.6 Using PIM, p.392.
382
18 Adding IGMP, MLD, and Multicast Routing Support
18.4 Adding and Deleting Virtual Interfaces for Multicast Routing
Where:
vif_index
Must be unique for each virtual interface.
vif_flags
Contains the VIFF_flagname flags as defined in <netinet/ip_mroute.h>.
18
min_ttl_threshold
Contains the minimum TTL a multicast data packet must have to be
forwarded on that virtual interface. Typically, it would have a value of 1.
max_rate_limit
Contains the maximum rate (in bits per second) of the multicast data
packets forwarded on that virtual interface. A value of 0 means no limit.
vif_local_address
Contains the local IP address of the corresponding local interface.
vif_remote_address
Contains the remote IP address in case of DVMRP multicast tunnels.
383
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
After multicast forwarding is enabled and the multicast virtual interfaces are
added, the kernel can deliver upcalls on the multicast routing socket that you
opened earlier and for which you have set the options MRT_INIT. The upcalls use
a struct igmpmsg header (see <netinet/ip_mroute.h>) with the im_mbz field set
to zero. Note that this header follows the structure of struct ip with the ip_p
protocol field set to zero.
The upcall header contains im_msgtype field with the type of the upcall
IGMPMSG_type. The values of the rest of the signal header fields and the body of
the signal message depend on the particular signal type.
If the upcall message type is IGMPMSG_NOCACHE, a multicast packet has reached
the multicast router, but the router has no forwarding state for that packet.
Typically, the message is a signal for the multicast routing user-level process to
install the appropriate Multicast Forwarding Cache (MFC) entry in the kernel.
To add an entry to an MFC:
struct mfcctl mc;
memset(&mc, 0, sizeof(mc));
memcpy(&mc.mfcc_origin, &source_addr, sizeof(mc.mfcc_origin));
memcpy(&mc.mfcc_mcastgrp, &group_addr, sizeof(mc.mfcc_mcastgrp));
mc.mfcc_parent = iif_index;
for (i = 0; i < maxvifs; i++)
{
mc.mfcc_ttls[i] = oifs_ttl[i];
}
setsockopt(mRoutSock, IPPROTO_IP, MRT_ADD_MFC, (void *)&mc, sizeof(mc));
384
18 Adding IGMP, MLD, and Multicast Routing Support
18.5 Using the Advanced Multicast Routing API
oifs_ttl[ ]
The minimum TTL (per interface) a multicast packet should have to be
forwarded on an outgoing interface. If the TTL value is zero, the
corresponding interface is not included in the set of outgoing interfaces.
Getting Statistics
Use the following method to get statistics for each installed MFC entry, such as the
number of forwarded packets per source and group address:
struct sioc_sg_req sgreq;
memset(&sgreq, 0, sizeof(sgreq));
memcpy(&sgreq.src, &source_addr, sizeof(sgreq.src));
memcpy(&sgreq.grp, &group_addr, sizeof(sgreq.grp));
ioctl(mRoutSock, SIOCGETSGCNT, &sgreq);
The following method can be used to get various statistics per multicast virtual
interface in the kernel, such as the number of forwarded packets for each interface:
struct sioc_vif_req vreq;
memset(&vreq, 0, sizeof(vreq));
vreq.vifi = vif_index;
ioctl(mRoutSock, SIOCGETVIFCNT, &vreq); 18
385
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
2. The kernel returns the (sub)set of features it knows about and will allow to be
enabled.
3. The application uses only that set of features the kernel has agreed to enable.
To support backward compatibility, if the application does not ask for any new
features, the kernel defaults to the basic multicast API. Below is a summary of the
expandable API solution. Note that all new options and structures are defined in
<netinet/ip_mroute.h>, unless stated otherwise.
The application uses new getsockopt( ) or setsockopt( ) options to negotiate the
API features with the kernel. You must conduct this negotiation right after the
multicast routing socket is open. The set of desired and allowed features is stored
as bits set in a uint32_t (thus, a maximum of 32 new features). The new
getsockopt( ) or setsockopt( ) options are MRT_API_SUPPORT and
MRT_API_CONFIG.
Example:
uint32_t supportedOptions;
getsockopt( mRoutSock, IPPROTO_IP, MRT_API_SUPPORT, (void
*)&supportedOptions,
sizeof(supportedOptions));
In supportedOptions, the getsockopt( ) call would set the pre-defined bits that the
kernel API supports. The 8 least-significant bits in the uint32_t are same as the 8
possible flags, MRT_MFC_FLAGS_flagname, that you can use in mfcc_flags as part of
the new definition of struct mfcctl. This leaves 24 flags for other new features. The
returned value of a call to getsockopt(MRT_API_SUPPORT) is read-only. A
setsockopt(MRT_API_SUPPORT) call would fail.
To modify the API and to set some specific feature in the kernel:
uint32_t v = MRT_MFC_FLAGS_DISABLE_WRONGVIF;
if (setsockopt(mRoutSock, IPPROTO_IP, MRT_API_CONFIG, (void *)&v,
sizeof(v)) != 0)
{
return (ERROR);
}
if (v & MRT_MFC_FLAGS_DISABLE_WRONGVIF)
{
return (OK); /* Success */
}
else
{
return (ERROR);
}
386
18 Adding IGMP, MLD, and Multicast Routing Support
18.5 Using the Advanced Multicast Routing API
returned in v is the actual (sub)set of features that were enabled in the kernel. To
check the enabled features at a later time, call:
getsockopt(mRoutSock, IPPROTO_IP, MRT_API_CONFIG, (void *)&v, sizeof(v));
The set of enabled features is global. In other words, you should call
setsockopt(MRT_API_CONFIG) right after your setsockopt(MRT_INIT) call.
The following set of new features is defined:
/* disable WRONGVIF signals */
#define MRT_MFC_FLAGS_DISABLE_WRONGVIF (1 << 0)
#define MRT_MFC_FLAGS_BORDER_VIF(1 << 1) /* border vif */
#define MRT_MFC_RP (1 << 8) /* enable RP address */
#define MRT_MFC_BW_UPCALL(1 << 9) /* enable bw upcalls */
The advanced multicast API uses a newly defined struct mfcctl2 instead of the
traditional struct mfcctl. The original struct mfcctl is kept as is. The new
struct mfcctl2 is as follows:
/*
* The new argument structure for MRT_ADD_MFC and MRT_DEL_MFC overlays
* and extends the old struct mfcctl.
*/
/* extension fields */
uint8_t mfcc_flags[MAXVIFS];/* the MRT_MFC_FLAGS_* flags*/
struct in_addr mfcc_rp; /* the RP address */
}; 18
The new fields are mfcc_flags[MAXVIFS] and mfcc_rp. Note that for
compatibility reasons they are added at the end. Use the
mfcc_flags[MAXVIFS] field to set various flags per interface per entry.
Currently, the defined flags are:
/* disable WRONGVIF signals */
#define MRT_MFC_FLAGS_DISABLE_WRONGVIF (1 << 0)
#define MRT_MFC_FLAGS_BORDER_VIF (1 << 1) /* border vif */
1. (S,G) refers to Source, Group. All multicast forward cache entries are based on those two
values. An MFC entry (S,G) states that for a packet coming from Source S and destined to
Group G should be forwarded on these interfaces.
387
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Usually, you use this signal to complete the shortest-path switch in case of PIM-SM
multicast routing, or to trigger a PIM assert message. It should not be delivered for
interfaces that are not in the outgoing interface set and that are not expecting to
become an incoming interface.
Thus, if the MRT_MFC_FLAGS_DISABLE_WRONGVIF flag is set for some of the
interfaces, then a data packet that arrives on that interface for that MFC entry will
not trigger a WRONGVIF signal. If that flag is not set, then a signal is triggered (the
default action).
Use the MRT_MFC_FLAGS_BORDER_VIF flag to specify whether the Border bit in
PIM Register messages should be set (in case when the Register encapsulation is
performed inside the kernel). If it is set for the special PIM Register kernel virtual
interface (see 18.6 Using PIM, p.392), the Border bit in the Register messages sent
to the RP will be set.
The remaining six bits are reserved for future development.
Use the mfcc_rp field to specify the RP address (in case of PIM- SM multicast
routing) for a multicast group G if we want to perform kernel-level PIM Register
encapsulation. Use the mfcc_rp field only if you have called
setsockopt(MRT_API_CONFIG) and successfully set the MRT_MFC_RP advanced
API capability.
If you successfully set the MRT_MFC_RP flag, the kernel tries to do the PIM
Register encapsulation itself instead of sending the packets to the application
(inside IGMPMSG_WHOLEPKT signals) for the application to encapsulate. The RP
address would be taken from the mfcc_rp field inside the new struct mfcctl2. Even
if the MRT_MFC_RP flag was successfully set, if the mfcc_rp field was set to
INADDR_ANY, the kernel still delivers an IGMPMSG_WHOLEPKT signal with the
multicast data packet to an application.
In addition, if the multicast data packet is too large to fit within a single IP packet
after the PIM Register encapsulation (for example, if its size was on the order of
65500 bytes), the data packet will be fragmented and each of the fragments will be
encapsulated separately. Typically, only a locally generated packet can be that
large. Otherwise, the transmission of the multicast data packet over Ethernet
would have already fragmented the packet into much smaller pieces.
In addition, a multicast routing application would need to know the forwarding
bandwidth for some data flow. For example, the multicast routing process may
want to timeout idle MFC entries, or in case of PIM- SM it can initiate (S,G)
shortest-path switch if the bandwidth rate is above a threshold for example.
388
18 Adding IGMP, MLD, and Multicast Routing Support
18.5 Using the Advanced Multicast Routing API
The original solution for measuring the bandwidth of a dataflow was that a
user-level process would periodically query the kernel about the number of
forwarded packets/bytes per (S,G), and then based on those numbers it would
estimate whether a source is idle, or whether the source’s transmission bandwidth
is above a threshold. That solution is far from being scalable, hence the need for a
new mechanism for bandwidth monitoring.
Below is a description of the new bandwidth monitoring mechanism.
■ If the bandwidth of a data flow satisfies some pre-defined filter, the kernel
delivers an upcall on the multicast routing socket to the multicast routing
process that has installed that filter.
■ The bandwidth-upcall filters are installed per (S,G). There can be more than
one filter per (S,G).
■ Instead of supporting all possible comparison operations (that is, <, <=, ==, !=,
>, >= ), there is support only for the <= and >= operations, because this makes
the kernel-level implementation simpler. The missing operations can be
simulated by secondary user-level filtering of the <= and >= filters. For
example, to simulate !=, then we need to install filter ‘‘bw <= 0xffffffff’’, and
after an upcall is received, we need to check whether ‘‘measured_bw !=
expected_bw’’.
■ To enable the bandwidth-signal mechanism for the MRT_MFC_BW_UPCALL
flag, call setsockopt(MRT_API_CONFIG).
■ For bandwidth-signal filters, call setsockopt(MRT_ADD_BW_UPCALL) or
setsockopt(MRT_DEL_BW_UPCALL) to delete or add the filter. Make sure that
you use the appropriate struct bw_upcall argument. 18
From an application point of view, you need to know about the following:
/*
* Structure for installing or delivering an upcall if the
* measured bandwidth is above or below a threshold.
*
* User programs might have a need to know when the bandwidth
* used by some data flow is above or below some threshold.
* This interface allows the userland to specify the threshold
* (in bytes and/or packets) and the measurement interval. Flows
* are all packet with the same source and destination IP address.
* At the moment the code is only used for multicast destinations
* but there is nothing that prevents its use for unicast.
*
* The measurement interval cannot be shorter than some Tmin (currently, 3s)
* The threshold is set in packets and/or bytes per_interval.
*
389
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
struct bw_data
{
struct timeval b_time;
uint64_t b_packets;
uint64_t b_bytes;
};
struct bw_upcall {
struct in_addr bu_src; /* source address */
struct in_addr bu_dst; /* destination address */
uint32_t bu_flags; /* misc flags (see below) */
#define BW_UPCALL_UNIT_PACKETS (1 << 0) /* threshold (in packets) */
#define BW_UPCALL_UNIT_BYTES (1 << 1) /* threshold (in bytes) */
#define BW_UPCALL_GEQ (1 << 2) /* upcall if bw >= threshold */
#define BW_UPCALL_LEQ (1 << 3) /* upcall if bw <= threshold */
#define BW_UPCALL_DELETE_ALL (1 << 4) /* delete(7,n) all upcalls for s,d */
struct bw_data bu_threshold; /* the bw threshold */
struct bw_data bu_measured; /* the measured bw */
};
/* max. number of upcalls to deliver together */
#define BW_UPCALLS_MAX 128
/* min. threshold time interval for bandwidth measurement */
#define BW_UPCALL_THRESHOLD_INTERVAL_MIN_SEC 3
#define BW_UPCALL_THRESHOLD_INTERVAL_MIN_USEC 0
390
18 Adding IGMP, MLD, and Multicast Routing Support
18.5 Using the Advanced Multicast Routing API
In the same bw_upcall the unit can be specified in both BYTES and PACKETS. The
GEQ and LEQ flags are mutually exclusive.
An upcall is delivered if the measured bandwidth is >= or <= the threshold
bandwidth (within the specified measurement interval). For practical reasons, the
smallest value for the measurement interval is 3 seconds. If smaller values were
allowed, then the bandwidth estimation may be less accurate, or the potentially
very high frequency of the generated upcalls may introduce too much overhead.
For the >= operation, the answer may be known before the end of
threshold_interval, therefore the upcall may be delivered earlier.
For the <= operation, one must wait until the threshold interval has expired to
know the answer.
Example usage:
struct bw_upcall bw_upcall;
/* Assign all bw_upcall fields as appropriate */
memset(&bw_upcall, 0, sizeof(bw_upcall));
memcpy(&bw_upcall.bu_src, &source, sizeof(bw_upcall.bu_src));
memcpy(&bw_upcall.bu_dst, &group, sizeof(bw_upcall.bu_dst));
bw_upcall.bu_threshold.b_data = threshold_interval;
bw_upcall.bu_threshold.b_packets = threshold_packets;
bw_upcall.bu_threshold.b_bytes = threshold_bytes;
if (is_threshold_in_packets) 18
{
bw_upcall.bu_flags |= BW_UPCALL_UNIT_PACKETS;
}
if (is_threshold_in_bytes)
{
bw_upcall.bu_flags |= BW_UPCALL_UNIT_BYTES;
}
do {
if (is_geq_upcall)
{
bw_upcall.bu_flags |= BW_UPCALL_GEQ;
break;
}
if (is_leq_upcall)
{
bw_upcall.bu_flags |= BW_UPCALL_LEQ;
break;
}
return (ERROR);
391
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
} while (0);
setsockopt(mRoutSock, IPPROTO_IP, MRT_ADD_BW_UPCALL,
(void *)&bw_upcall, sizeof(bw_upcall));
392
18 Adding IGMP, MLD, and Multicast Routing Support
18.6 Using PIM
What is PIM?
PIM is the common name for two multicast routing protocols: Protocol
Independent Multicast - Sparse Mode (PIM-SM) and Protocol Independent
Multicast - Dense Mode (PIM-DM).
PIM-SM
PIM-SM is a multicast routing protocol that can use the underlying unicast
routing information base or a separate multicast-capable routing information
base. It builds unidirectional shared trees rooted at a Rendezvous Point (RP)
per group, and optionally creates shortest-path trees per source.
PIM-DM
PIM-DM is a multicast routing protocol that uses the underlying unicast
routing information base to flood multicast datagrams to all multicast routers.
Prune messages are used to prevent future datagrams from propagating to
routers with no group membership information.
Both PIM-SM and PIM-DM are fairly complex protocols, although PIM-SM is
much more complex than PIM-DM. To enable PIM-SM or PIM-DM multicast
routing in a router, you must enable multicast routing and PIM processing in the
kernel, and run a PIM-SM or PIM-DM capable application.
After opening a multicast routing socket and enabling multicast forwarding, use
one of the following socket options to enable or disable PIM processing in the
18
kernel:
int version = 1;
setsockopt( mRoutSock, IPPROTO_IP, MRT_INIT, (void *)&version,
sizeof(version) );
After you have enabled PIM processing, add the multicast-capable interfaces (see
Adding Multicast Routing Virtual Interface, p.383). In case of PIM-SM, you must also
add the PIM-Register virtual interface. To do this, use the following options:
struct vifctl vc;
memset(&vc, 0, sizeof(vc)); /* Assign all vifctl fields as needed. */
...
if (is_pim_register_vif)
{
vc.vifc_flags |= VIFF_REGISTER;
}
setsockopt(mRoutSock, IPPROTO_IP, MRT_ADD_VIF, (void *)&vc, sizeof(vc));
393
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
To send or receive PIM packets, first you must open a “raw socket” (see the
socket( ) reference entry), with protocol value of IPPROTO_PIM:
int pim_s4;
pim_s4 = socket(AF_INET, SOCK_RAW, IPPROTO_PIM);
After opening the raw socket for PIM, send or receive PIM packets on that socket
by calling sendto( ), sendmsg( ), recvfrom( ), or recvmsg( ).
NOTE: The e MLD and MLDv2 protocols are available only in the Wind River
Platforms builds of the network stack. The Wind River General Purpose Platform,
VxWorks Edition, does not support these features
The network stack includes an implementation of the host and router sides of the
protocol for both MLDv1 and MLDv2. Because the network stack does not include
a PIM implementation, the MLDv2 router implementation cannot act as a true
MLDv2 router, but it can act as a relay agent that proxies for a PIM-coupled
MLDv2 router.
For the host side of the protocol, whether you get MLDv1 or MLDv2 depends on
how the network stack was compiled. The default build creates MLDv1 modules.
However, if you build the stack with MLDV2 defined, you create MLDv2 modules
that can be configured to operate in MLDv1-only mode, MLDv2-only mode, or
MLDv2 with MLDv1 compatible mode. For the router side of the protocol, the
stack supports a MLDv2 implementation that can be configured on a per-interface
basis to operate in MLDv1-only mode, MLDv2-only mode, or MLDv2 with
MLDv1 compatible mode. To create the MLDv2 modules, you must compile the
stack with MLDV2 defined.
394
18 Adding IGMP, MLD, and Multicast Routing Support
18.7 Configuring and Using MLD Hosts and Routers
NOTE: For information on building the network stack, see your Wind River
Platforms Getting Started.
The Wind River Network Stack supports the following MLD host and router
components:
■ MLD
■
IPv6 MLDv2 Proxy Router
These components are listed under the
Network Components > Network Protocol Components >
Network IPv6 Components folder in Workbench.
MLD
INCLUDE_MLD pulls in the mld6 and mldLib libraries, which implement the host
side of MLD. Whether it is an MLDv1 or MLDv2 implementation depends on
whether MLDV2 was defined when you built the network stack code. The MLDv1
implementation implements RFC 2710. The MLDv2 host implements RFC 3810,
18
and the multicasting socket interface extensions described in section 5 of RFC 3678.
ICMPV6CTL_MLD_MAXSRCFILTER_CFG
ICMPV6CTL_MLD_SOMAXSRC_CFG
395
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
ICMPV6CTL_MLD_VERSION_CFG
MLDv2 also adds support for two new ioctls, SIOCGMSFILTER and
SIOCSMSFILTER. For more information on these socket options and the ioctls, see
section 5 and 8.2 of RFC 3678.
To act as a relay agent, the target requires at least two interfaces. One interface (and
only one interface) is configured as an MLD proxy. This interface sits on a network
through which it can access a PIM-coupled MLD router. All other interfaces listed
in the configuration file without the proxy flag connect to subnets for which this
target acts as a proxy MLD router.
396
18 Adding IGMP, MLD, and Multicast Routing Support
18.7 Configuring and Using MLD Hosts and Routers
The following are known issues associated with the MLD router implementation:
■
MLD router does not work on an interface that is dynamically added after the
MLD router daemon has been started. To enable multicasting on such an
interface, you must edit the MLD configuration file, use mldrShutdown to
shutdown the MLD daemon, and then restart the MLD daemon using mldr.
■
SNMP for MLDv2 MIB is not supported.
■ If you are running more than one stack instance on a target (virtual stacks) be
aware that the MLDv2 proxy router is supported on a single stack instance
only.
■ When reading the source code, be aware that although the source code
contains comments with references to the PIM protocol, the PIM protocol is
not implemented.
The default setting for NUM_SYS_64 is not sufficient for multicast routing. Change
the NUM_SYS_64 allocation to a value of at least 500, and then rebuild your
VxWorks image. For details, see 3. Configuring and Managing Memory.
If you want to use netstat( ) to display information on the multicast interface
tables, multicast routing tables, and the multicast forwarding cache, include the
INCLUDE_NETSTAT_MROUTEV6 component in your image.
18
18.7.4 Run-time Configuration Considerations
Before attempting to enable the MLD router on a target, make sure that IPv6
routing is enabled. To do this, you can call Sysctl as follows:
-> Sysctl "net.inet6.ip6.forwarding=1"
You can now call mldr from the command line to start up the MLD router. For a
full listing of the options for this command, see the mldr reference entry. Among
the command-line options, the most fundamental is -c, which lets you specify the
configuration file that the MLD router daemon reads at startup. Using this file, you
can perform the following tasks:
■
Enable or disable multicasting on a given interface.
■
Set the MLD mode for each interface.
397
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
■
Set protocol-specific configuration parameters such as MLD version. Default
values apply if you do not specify a custom value.
Consider the following sample contents of an MLD proxy router configuration file,
for a target with four interfaces, dc0, fei0, fei1, and fei2:
phyint dc0 disable;
phyint fei0 mld_version any;
phyint fei1 mld_version any;
phyint fei2 mld_version any proxy_enable;
MLD is disabled on dc0 and enabled on the remaining three. The fei0 and fei1
interfaces listen to MLD hosts on their respective subnets. The fei2 interface
proxies MLD requests to a PIM-coupled MLD router accessible from its subnet.
Assuming this information is contained in the file, mldr.conf, you could use mldr
from the command line to startup the MLD router. For example:
-> mldr "-c mldr.conf"
For more information on the options available through mldr and its configuration
file, see the reference entry for mldr.
398
19
ALTQ
19.1 Introduction
A queueing discipline controls outgoing packets through either a scheduling
mechanism or the management of queue buffers. ALTQ (ALTernate Queueing)
provides queuing disciplines and other features that are useful for supporting
network Quality of Service (QoS). ALTQ was originally developed by the KAME
project (www.kame.net) and has been incorporated in several Unix-based
operating systems. The Wind River implementation of ALTQ is a port of the ALTQ
implementation in FreeBSD 6.0 (see http://www.freebsd.org). For information
399
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.0
about the queueing disciplines supported in the current release of Wind River’s
ALTQ, see 19.2 Supported Queueing Disciplines and Features, p.400.
To make use of a queueing discipline, there needs to be a way to assign packets to
queues. For Wind River ALTQ, this is done through rules and rule groups
provided by the Wind River Firewall product. Wind River Firewall uses
user-defined rules and rule groups to inspect packets and decide on which to
accept and which to reject. The current release of Firewall contains extensions that
also allow the assignment of packets to ALTQ queues. For information about rules
and rule groups in Wind River Firewall, see Wind River Firewall and NAT
Programmer’s Guide. For information on defining rules and rule groups for ALTQ,
see 19.6 Rules and Rule Groups for Assigning Packets to Queues, p.419 and
19.7 Examples, p.420.
A consequence of using Wind River Firewall with ALTQ is that when you build
VxWorks to include ALTQ, you must also include the Firewall IP Filter
(INCLUDE_FIREWALL_IP_FILTER) build component in your build (see
19.4 Building the Network Stack to Include ALTQ, p.406).
Central to using Wind River ALTQ is the the altqConfg command-line utility. You
use ALTQ to define all ALTQ queues, assign priorities and bandwidths to queues,
and assign queues to network interfaces. You can also use the altqConfg utility to
display information about queues and interfaces. For information on using
altqConfg, see 19.5 The altqConfig Utility, p.410.
NOTE: ALTQ is available only in Wind River Platforms builds of the network stack.
The Wind River General Purpose Platform, VxWorks Edition, does not support
ALTQ.
400
19 ALTQ
19.2 Supported Queueing Disciplines and Features
The current release of Wind River ALTQ does not support Hierarchical Fair Service
Curve (HFSC) packet scheduling, which is a part of FreeBSD’s ALTQ
implementation.
Wind River ALTQ supports the following queue buffer-management discipline:
■
Random Early Detection (RED; see 19.2.3 Random Early Detection (RED), p.403)
In addition, Wind River ALTQ supports Explicit Congestion Notification (ECN;
see 19.2.4 Explicit Congestion Notification (ECN), p.404) and control of
outgoing-packet flow through a token-bucket regulator mechanism (19.2.5 Token
Bucket Regulator, p.404).
In priority queueing, packets are assigned to queues and sent according to the
priority of their queue. The implementation provides 16 priority levels, 0-15,
with the higher number specifying a higher priority.
Figure 19-1 CBQ interface with root queue and user-defined queues 19
CBQ Interface
Root queue
401
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.0
CBQ Bandwidth
The user allocates a CBQ interface an over all bandwidth, which is either a
percentage of available bandwidth at the interface or a specific bit rate (for
example, 2 Mb/second), and assigns each user-defined queue both a bandwidth
and a priority. The root queue is always assigned the bandwidth of its interface. In
assigning bandwidth to user-defined queues, the bandwidth allocated to a parent
queue is distributed across its children. Figure 19-2 shows a possible allocation of
bandwidth for the hierarchy illustrated in Figure 19-1.
Figure 19-2 CBQ interface with queues, subqueues, and bandwidth assignments
CBQ Interface
(10 Mb/sec)
Queue4 Queue5
(3 Mb/sec) (2 Mb/sec)
402
19 ALTQ
19.2 Supported Queueing Disciplines and Features
CBQ Priority
Individual queues are assigned a priority. There are seven priority levels. Priority
level is used to determine the order in which packets are sent according to the
following rules:
■
No packets are sent from queues that have exceeded the average send rate
allowed by their bandwidth (unless borrowing is allowed, see Borrowing
Bandwidth, p.403).
■ Among queues that are within their bandwidth allocation, queues with the
highest level of priority always send queued packets before lower priority
queues.
■ Packets are sent round robin from queues at the same priority level
■ Packets in queues at a lower priority level are sent only when there are no
waiting packets at higher priority queues, as long as those queues are within
their bandwidth limit.
Borrowing Bandwidth
You can specify that an individual child queue is able to borrow bandwidth from
its parent. In this case, when the child queue is on the point of exceeding its
allocated bandwidth, it can make use of any unused bandwidth allocated to its
parent.
You have the option of specifying that individual queues use RED. 19
403
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.0
■
When the average length of a queue falls between the maximum and the
minimum, the action RED takes depends on whether explicit congestion
notification (ECN; see 19.2.4 Explicit Congestion Notification (ECN), p.404) is in
effect.
Without ECN, RED drops packets that it selects according to a probabilistic
algorithm based on the average size of the queue.
With ECN, instead of dropping packets, RED marks them by setting a bit in the
packet header. Packets are selected according to the same algorithm used for
dropping packets.
■ When the average length of a queue is above the maximum length, all packets
arriving at the queue are dropped.
■ If an interface has multiple connections with queues whose average size is
above the minimum, RED randomly chooses which connection to act on.
404
19 ALTQ
19.3 Compatibility with VxWorks Features
19
405
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.0
406
19 ALTQ
19.4 Building the Network Stack to Include ALTQ
Table 19-1 lists and describes the ALTQ build components. The first column gives
the names of build components as they appear in Workbench. The second column
gives the corresponding INCLUDE macros you need to enter in the config.h file
for a specific BSP when you perform a BSP command-line build.
RED with In and Out INCLUDE_ RIO is not supported in the current release. This
ALTQ_RIO component is automatically included when you
19
include either class-based queueing or priority
queueing, but has no effect.
WRS ALTQ INCLUDE_ALTQ The core ALTQ component, always required. This
component contains a number of parameters, some of
which apply to general queue settings for ALTQ (for
example, maximum number of ALTQ queues), and
others of which apply to the machine-clock used with
a processor. For information on the parameters, see
19.4.1 ALTQ Static Configuration Parameters, p.408.
407
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.0
Default
Workbench config.h Value Description
408
19 ALTQ
19.4 Building the Network Stack to Include ALTQ
Default
Workbench config.h Value Description
409
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.0
Default
Workbench config.h Value Description
Use machine clock ALTQ_USE_MACH_ FALSE Whether to use the machine clock. If
CLOCK FALSE, software emulation of a machine
clock is used.
If you set the value to TRUE, you need to
provide machine-clock initialization and
read routines (see the table entries for
Machine-clock init routine and
Machine-clock read routine).
410
19 ALTQ
19.5 The altqConfig Utility
Table 19-3 lists the basic altqConfig commands. Note that the entire command
following altqConfig is enclosed in quotes.
Command Description
411
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.0
You use altqConfig queue subcommands (see 19.5.3 The altqConfig queue Command
and Subcommands, p.413) to define and configure queues. The altqConfig "queue
queue_name enable" command makes a queue, once configured, available for use.
You use altqConfig altqif (see 19.5.4 The altqConfig altqif Command and
Subcommands, p.416) subcommands to configure interfaces and assign queues to
them. The altqConfig "altqif if_name enable" command makes an interface
available for use.
As long as no queues or interfaces have been enabled, you can make any
configuration changes you want. However, there are a number of constraints on
when you can enable queues and interfaces and what changes you can make after
enabling queues and interfaces:
■ Before an interface can be enabled, all the queues assigned to it must be
enabled.
■ If a queue has children (class-based queueing), all of its children must be
enabled before it can be enabled.
■ You can make changes to a queue, as long as it is not associated with an
enabled interface.
To make changes to a queue that has already been enabled, you must first
disable the queue (altqConfig "queue queue_name disable"
■ Once an interface has been enabled, you cannot make any changes in the way
it is configured.
The only way to make changes to the configuration of an interface is to remove
the interface from ALTQ (altqConfig "altqif interface_name remove") and then
add it back to ALTQ (altqConfig "altqif interface_name add") and completely
reconfigure it.
■ Before you can turn ALTQ on (altqConfig "altq on") at least one interface must
be enabled.
■
Once you have turned altqConfig on, if you want to enable additional
interfaces, you need to turn altqConfig off, make the changes, and then turn
altqConfig on, again.
The following is a simple sequence of altqConfig steps for initial setup:
1. Use altqConfig queue commands to define one or more queues and their
properties.
2. Use altqConfig altqif commands to configure and assign queues to interfaces.
412
19 ALTQ
19.5 The altqConfig Utility
3. Enable the queues you set up, then enable the interfaces they are associated
with.
4. To confirm you have configured queues and interfaces as wished, use either
altqConfig with no argument or altqConfig show to display the properties of
all ALTQ queues and interfaces.
For sample output see altqConfig "show", p.426.
5. If the output from the previous step is satisfactory, turn ALTQ on.
Use the altqConfig queue command with the name of a queue to configure a
queue for ALTQ or to display information about an individual queue. The form of
the command is:
altqConfig "queue if_name subcommand1[, subcommand2[, subcommand3[, ...]]"
Note that the portion of the command following altqConfig must be enclosed in
quotes.
Subcommands can be given in any order, following if_name. The following
altqConfig queue command creates the class-based queue Queue1 as the default
queue for its interface and assigns two subqueues to it, subQ1 and subQ2:
altqConfig "queue Queue1 scheduler cbq default qlist subQ1
subQ2"
In addition to the altqConfig queue commands that specify a queue name, there
are two altqConfig queue commands that do not take a queue name and display
19
configuration information about all queues:
altqConfig "queue"
altqConfig "queue show"
These commands are equivalent to each other and display the same configuration
information for queues that the altqConfig and altqConfig show commands do
(see 19.7.3 Sample Output from altqConfig, p.426).
413
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.0
Table 19-4 lists the altqConfig queue subcommands and the arguments they take.
scheduler priorityq | cbq [default] Specifies the queueing discipline that applies to the
[packet-drop-option] queue designated by altqConfig queue
[class-specific_option] queue_name and optionally sets any of the following
options:
■
default
■
packet-drop-option
■
class-specific_option
For information about these options, see scheduler
Command Options, p.416.
The following command creates a priority queue,
PQueue1, with Random Early Detection (RED) as the
default queue on its interface:
altqConfig "queue PQueue1 priorityq
default RED"
414
19 ALTQ
19.5 The altqConfig Utility
bandwidth int [%|b|Kb|Mb|Gb] For class-based queueing (CBQ), only. The amount of
bandwidth allocated to queue_name, where:
% = percentage of bandwidth allocated to a queue
b = bits per second allocated to a queue
Kb = kilobits per second
Mb = megabits per second
Gb = gigabits per second
Three commands follow. The first allocates two
megabits-per-second of bandwidth to Queue1 which
has subqueues subQ1 and subQ2. The second
command allocates 30% of Queue1’s bandwidth to
subQ1; the third command allocates Queue1’s
remaining bandwidth to subQ2:
altqConfig queue Queue1 bandwidth 2 MB
altqConfig queue subQ1 bandwidth 30%
altqConfig queue subQ2 bandwidth 70%
415
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.0
Use the altqConfig altqif command with the name of an interface to configure an
interface for ALTQ or to display information about an individual interface. The
form of the command is:
altqConfig “altqif if_name subcommand1[, subcommand2[, subcommand3[, ...]]”
Note that the portion of the command following altqConfig must be enclosed in
quotes.
416
19 ALTQ
19.5 The altqConfig Utility
qlist A space-separated list of For class-based queueing (CBQ), only. Lists child
queue names: subqueues of the root queue on the specified interface.
The following command, issued on one line, assigns
qlist q1 q2 q3 ...
subqueues, subQ1 and subqueue subQ2 to the root
queue on interface fei1:
altqConfig altqif qlist subQ1, subQ2
417
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.0
bandwidth int [%|b|Kb|Mb|Gb] For class-based queueing (CBQ), only. The amount of
bandwidth allocated to if_name, where:
% = percentage of available bandwidth allocated to the
interface
b = bits per second allocated to a queue
Kb = kilobits per second
Mb = megabits per second
Gb = gigabits per second
tbrsize token_bucket_size The size, in bytes, of the token bucket used to regulate
the sending of packets from the specified interface. For
information about token buckets, see 19.2.5 Token
Bucket Regulator, p.404.
enable N/A Enables the specified interface for use with ALTQ. Use
this subcommand only after assigning one or more
queues to the interface.
418
19 ALTQ
19.6 Rules and Rule Groups for Assigning Packets to Queues
419
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.0
5. Set the action field to accept packets that meet the preceding rules (outgoing
TCP packets):
fwRuleFieldSet(pRule,FW_FIELD_ACTION,FW_ACCEPT)
19.7 Examples
This section provides two sets of examples of how to use altqConfig to set up
class-based and priority queueing and how to define rule groups for assigning
packets to these queues. The examples are based on two departments, Engineering
and Sales, in a fictional softwaree company. The Engineering department is made
up of three subgroups: Developent (Dev), Test, Docs.
The first set of examples is for setting up class-based queueing on an interface, the
second set is for priority queueing.
420
19 ALTQ
19.7 Examples
Root queue
Table 19-6 Information Used in Defining Class-Based Queues and Filter Rules
Network usage
Department IP-address range (% of parent queue’s bandwidth) Priority
Engineering 10.10.1.3- 80 1
10.10.1.82 19
Dev 10.10.1.3- 50 1
10.10.1.52
Test 10.10.1.53- 25 1
10.10.1.77
Docs 10.10.1.78- 25 1
10.10.1.82
Sales 10.10.1.103- 15 4
10.10.1.142
Other [Any] 5 1
(with barrowing)
421
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.0
The following steps use the altqConfig utility to set up class-based queueing for
the departments and groups described in the previous section.
1. Configure an interface—in this case, fei1—for ALTQ; allocate 100% of the
bandwidth available at the interface to ALTQ:
altqConfig "altqif fei1 add bandwidth 100% scheduler cbq"
3. Assign the Eng queue 80% of the bandwidth at the interface and give it three
child queues: dev, test, and doc:
altqConfig "queue Eng bandwidth 80% qlist dev test doc"
5. Now that its child queues have been enabled, you can enable Eng:
altqConfig "queue Eng enable"
422
19 ALTQ
19.7 Examples
8. Now that all the queues on fei1 have been enabled, enable fei1:
altqConfig "altqif fei1 enable"
9. Turn on ALTQ:
altqConfig "altq on"
The following steps define Firewall rules and rule groups for assigning packets to
the queues defined in the preceding section.
1. As a convenience, set up definitions for frequently-used constants:
fwOutLoc = 3
fwfTcp = 8
fwfAction = 13
fwfIpField = 14
fwfAltq = 20
fwaReject = 0x00000000
fwaAccept = 0x80000000
dev_SourceIpMin = "10.10.1.0"
dev_SourceIpMax = "10.10.1.49"
test_SourceIpMin = "10.10.1.50"
test_SourceIpMax = "10.10.1.74"
doc_SourceIpMin = "10.10.1.50"
doc_SourceIpMax = "10.10.1.79"
sales_SourceIpMin = "10.10.1.100"
sales_SourceIpMax = "10.10.1.140"
destinationIPMin = destinationIPMax = 0
Note that there are maximum and minimum source IP addresses for each of
the queues, except Other. These values are needed for filtering packets based
on their sources. The Firewall routine used for filtering on a range of source IP 19
addresses also requires a range of destination addresses. Since destination
addresses are not used in the current example, they are set to 0.
2. Install a rule filter on output that automatically rejects all packets that are not
accepted by a user-defined rule:
fwRuleFilterInstall (fwOutLoc, fwaReject, 0, 0, 0, 0);
3. Create a rule group for outgoing TCP packets and set the action to accept so
that packets that don’t fit within the address range of any of the departmental
or subroup queues can be assigned to the default queue—Other:
cbqRuleGroup = fwRuleGroupCreate (fwOutLoc, "CBQ rules", 0);
fwRuleFieldSet (cbqRuleGroup, fwfAction, fwaAccept);
fwRuleFieldSet (cbqRuleGroup, fwfTcp , 0, 0, 0, 0, 0, 0, 0);
423
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.0
In this set of examples, priority queues are set up for the three subgroups under
Engineering and Sales. An additional queue—Other— is defined to represent
other users of the network that may send packets to the interface used for priority
queueing. As in the examples for class-based queueing, a rule group and rules are
defined that assign TCP packets to queues based on the IP addresses from which
they are sent.
424
19 ALTQ
19.7 Examples
Table 19-7 summarizes the information used to define queues and create rule
groups:
Table 19-7 Information Used in Defining Priority Queues and Filter Rules
Dev 10.10.1.0- 4
10.10.1.50
Test 10.10.1.51- 4
10.10.1.75
Docs 10.10.1.76- 2
10.10.1.80
Sales 10.10.1.100- 5
10.10.1.140
Other [Any] 1
The following steps use the altqConfig utility to set up priority queueing for the
queues listed in Table 19-7.
1. Configure an interface—in this case, fei0—for ALTQ; allocate 100% of the
bandwidth available at the interface to ALTQ:
altqConfig "altqif fei0 add bandwidth 100% scheduler priorityq"
19
2. Add the planned queues, aside from Other, to fei0 and enable them:
altqConfig "queue dev priority 4 enable"
altqConfig "queue test priority 3 enable"
altqConfig "queue doc priority 2 enable"
altqConfig "queue sales priority 5 enable"
3. Add Other as the default queue on the interface and enable it:
altqConfig "queue Other scheduler priorityq default enable"
425
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.0
5. Turn on ALTQ:
altqConfig "altq on"
Since the basis for assigning packets to queues is the same for both the class-based
and priority-based queues, you can the same rules. See Defining Filter Rules for the
CBQ Queues, p.423.
This section contains sample output from the following altqConfig commands:
■ altqConfig "show", p.426 (equivalent to altqConfig)
■ altqConfig "altqif if_name show stat" for CBQ, p.427
■ altqConfig "altqif if_name show stat" for Priority Queueing, p.428
altqConfig "show"
The altqConfig and altqConfig "show" commands are equivalent. The command
output is displayed under two headings, Interfaces and Queues. The output under
Interfaces is the same as the output for the altqConfig "altqif" and altqConfig
"altqif show" commands. The output under Queues is the same as the output for
the altqConfig "queue" and altqConfig "queue show" commands.
The following output was generated before ALTQ was turned on (altqConfig "altq
on”). That is the reason that queues and interfaces appear as disabled, not ready,
and not in use.
-> altqConfig “show”
Interfaces:
-----------
-- Queues currently in use --
No queue in use
426
19 ALTQ
19.7 Examples
Queues:
-------
Eng: Disabled, RefCount=1
qlimit=0, scheduler=cbq, bandwidth=80%, priority=1
Child queues: dev: NotReady test: NotReady doc: NotReady
Sales: NotReady, RefCount=1
qlimit=0, scheduler=cbq, bandwidth=0 b, priority=1
Other: NotReady, RefCount=1
qlimit=0, scheduler=cbq, bandwidth=0 b, priority=1
dev: NotReady, RefCount=1
qlimit=0, scheduler=cbq, bandwidth=0 b, priority=1
test: NotReady, RefCount=1
qlimit=0, scheduler=cbq, bandwidth=0 b, priority=1
doc: NotReady, RefCount=1
qlimit=0, scheduler=cbq, bandwidth=0 b, priority=1
dev1: NotReady, RefCount=1
qlimit=0, scheduler=priorityq,, bandwidth=0, priority=1
test1: NotReady, RefCount=1
qlimit=0, scheduler=priorityq,, bandwidth=0, priority=1
doc1: NotReady, RefCount=1
qlimit=0, scheduler=priorityq,, bandwidth=0, priority=1
Sales1: NotReady, RefCount=1
qlimit=0, scheduler=priorityq,, bandwidth=0, priority=1
Other1: NotReady, RefCount=1
qlimit=0, scheduler=priorityq,, bandwidth=0, priority=1
queue root_fei1 bandwidth 100Mb priority 0 cbq( wrr root ) {Eng, Sales, Other}
[ pkts: 196473 bytes: 237338236 drop pkts: 0 bytes: 0 ] 19
[ qlength: 0/ 50 borrows: 0 suspends: 0 ]
[ priority: 0 depth: 2 ]
[ offtime: 1us wrr_allot: 1500b nsPerByte: 80 rate: 100Mbps ]
[ overs: 150217 overacts: 0 ]
[ AvgIdle: -73us maxidle: 3us minidle: -120us ]
queue Eng bandwidth 80Mb {dev, test, doc}
[ pkts: 0 bytes: 0 drop pkts: 0 bytes: 0 ]
[ qlength: 0/ 50 borrows: 0 suspends: 0 ]
queue dev bandwidth 40Mb
[ pkts: 77110 bytes: 93148880 drop pkts: 2031 bytes: 2453448 ]
[ qlength: 0/ 50 borrows: 0 suspends: 1635 ]
queue test bandwidth 20Mb
[ pkts: 39612 bytes: 47851296 drop pkts: 0 bytes: 0 ]
[ qlength: 0/ 50 borrows: 0 suspends: 631 ]
queue doc bandwidth 20Mb
[ pkts: 39991 bytes: 48309128 drop pkts: 0 bytes: 0 ]
[ qlength: 0/ 50 borrows: 0 suspends: 596 ]
queue Sales bandwidth 15Mb
427
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.0
428
19 ALTQ
19.8 Sample Code for Pentium Processor Machine-Clock Routines
/*
* DESCRIPTION
*
* This module provides the sample Pentium machine dependent machine clock
* init and read routines. This module must be explicitly added to the
* BSP project (if using Workbench). If using command line build, add this
* module to the MACH_EXTRA found in the bsp's Makefile.
*
* To include these routines for ALTQ, configures the following parameters:
*
* ALTQ_USE_MACH_CLOCK: set to TRUE
* ALTQ_MACH_CLOCK_INIT_HOOK: set to init_machclk_pentium
* ALTQ_MACH_CLOCK_READ_HOOK: set to read_machclk_pentium
*
* The INCLUDE_TIMESTAMP component must also be included.
*
* NOTE:
* The rdtsc() uses the Pentium assembly language which is supported by the 19
* GNU compiler only. If using DIAB compiler, the appropriate substitution
* for rdtsc() must be implemented.
*/
#include <vxWorks.h>
#include <sys/times.h>
#include <taskLib.h>
#if defined(PRJ_BUILD)
#include "prjParams.h"
#else
#include "config.h"
#endif /* PRJ_BUILD */
#ifdef INCLUDE_TIMESTAMP_TSC
429
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.0
void init_machclk_pentium(void)
{
/*
* if the clock frequency (of Pentium TSC or Alpha PCC) is
* accessible, just use it.
*/
machclk_freq = sysTimestampFreq();
microtime(&tv_start);
start = (*readMachClk)();
taskDelay(hz); /* 1 sec */
microtime(&tv_end);
end = (*readMachClk)();
diff = (u_int64_t)(tv_end.tv_sec - tv_start.tv_sec) * 1000000
+ tv_end.tv_usec - tv_start.tv_usec;
if (diff != 0)
machclk_freq = (u_int)((end - start) * 1000000 / diff);
}
u_int64_t
read_machclk_pentium(void)
{
return rdtsc();
}
#endif /* INCLUDE_TIMESTAMP_TSC */
#endif /*_WRS_HAS_GCC_ASM_SYNTAX*/
430
20
Working with Device Instances
20.1 Introduction
This chapter describes how to create the following device type instances:
■
standard network interface devices
■
automatic IPv4 interface configuration
■
stf device instances for 6to4 tunneling
■
gif device instances for tunneling through an IPv4 Internet
■
a BPF device instance for filtering incoming packets
431
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
NOTE: If your target system will include more than one network interface, you
may need to increase the value of the configuration parameter IP_MAX_UNITS. For
information on configuring the Wind River Network Stack to automatically start
multiple network interfaces, see Adding an END, p.473, and Adding an NPT Driver,
p.490.
NOTE: When working with the network interface drivers and tunnel devices
supplied by Wind River, this step is usually handled for you. For example, if a
driver registers as an Ethernet driver and if you do not intend to multicast
through that driver instance, you can skip this step because registering as an
Ethernet driver automatically registers arpResolve( ) as the address resolution
routine. Similarly, if you are working with either of the supplied pseudo
devices, stf or gtf, you can skip this step. It is handled automatically when the
tunnel library is initialized.
432
20 Working with Device Instances
20.2 Working with Network Driver Instances
To separate out each aspect of the global up shown above, you would need to
do the following:
ifconfig "fei0 link up"
ifconfig "fei0 inet up"
ifconfig "fei0 inet6 up"
If you do not want to bring up both the IPv4 and IPv6 functionality for the
interface, omit any of the above calls as needed.
9. Check that the interface was loaded and configured correctly by calling the
following:
ifShow( ) – list configuration information for network devices.
netstat( ) – check that the routing table has an entry for the device.
hostShow( ) – check that the address/hostname was added to the host table.
NOTE: For information on the exact inputs expected by the routines named above,
see the relevant reference entries.
To communicate with remote peers, a protocol, such as IPv4, must attach itself to
one or more network interfaces. Attaching a protocol to an interface allows packets
addressed to that interface to flow up to the protocol. It also lets the protocol 20
transmit packets out through the interface.
If your build-time configuration includes INCLUDE_IPATTACH, the network stack
initialization code automatically attaches IPv4 to the network interface specified in
the boot parameters. Similarly, if you include INCLUDE_IP6ATTACH, IPv6 is also
attached to that network interface. For more information on these components, see
5. Configuring Transport and Network Protocols.
If your target supports more than one interface, there is no automatic attaching of
IPv4 or IPv6 to the additional interfaces. If you want to attach IPv4 or IPv6 to these
interfaces, you must call ipAttach( ) or ip6Attach( ) for each interface attachment
you want to create. If you need to remove an IPv4 attachment, call ipDetach( ). If
you need to remove an IPv6 attachment, call ip6Detach( ).
433
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Using ifconfig( )
The ifconfig( ) routine lets you assign an address and netmask or prefix to a
network interface all in one call. It also lets you retrieve configuration information
on an interface. The valid ifconfig( ) command-line syntax for assigning
information to a network interface is as follows:
-> ifconfig "interface [-flags] [protocol] [parameter parameterValue]"
For a detailed description of all possible flags and parameter values, see the
ifconfig( ) reference entry. From among the more than 20 valid parameter values,
ifconfig( ) chooses add, as the default. Thus, if you use ifconfig( ). without
specifying a parameter value, ifconfig( ) assumes add.
Whether ifconfig( ) configures an interface for IPv4 or IPv6 depends on the protocol
value you supply. For the Wind River Network Stack, the only valid protocol
values are inet, for IPv4 (the default) and inet6, for IPv6. Consider the following:
-> ifconfig "fei1 192.0.2.64"
This ifconfig( ) call configures the fei1 network interface to have an IPv4 address
of 192.0.2.64. Because no mask was specified for what would have been a class C
address pre-CIDR, the command assumes a default class B netmask value of
0xFFFFFF00. To override the default netmask associated with an IPv4 address, you
can use the CIDR slash notation. For example:
-> ifconfig "fei1 192.0.2.64/16"
434
20 Working with Device Instances
20.2 Working with Network Driver Instances
To use ifconfig( ) to configure an interface to use an IPv6 address, you need to use
the inet6 protocol value in the command explicitly. For example:
-> ifconfig "fei1 inet6 2002:C000:0240::66/16"
The ifconfig( ) call above configures the fei1 network interface to have an IPv6
address of 2002:C0000:0240:66. The “/16” indicates a prefix length of 16 bits.
Otherwise, the ifconfig( ) call would have assumed a default prefix of 64 bits.
Alternatively, you can use the inet6 and prefixlen options:
-> ifconfig "fei1 inet6 2002:C000:0240::66 prefixlen 16"
The example address shown above was chosen because it is a 6to4 IPv6 address for
192.0.2.64. The IPv4 notation uses base 10 numbers. The IPv6 notation uses
hexadecimal numbers. Thus, 192.0.2.64 is C0.0.2.40 which is C000:240.
The ifLib API provides the ifMaskSet( ) and ifAddrSet( ) routines for configuring
a network interface for use with IPv4. As their names suggest, you use
ifMaskSet( ) to set the mask associated with the route table entry for the interface;
and you use ifAddrSet( ) set to assign an IPv4 address for the interface.
The ifLib API imposes a sequence on the use of the ifMaskSet( ) and ifAddrSet( )
calls that you make to configure an interface. The ifMaskSet( ) call must come
before the ifAddrSet( ) call. If you call ifAddrSet( ) without a previous
ifMaskSet( ) call, the ifAddrSet( ) call assumes the default pre-CIDR netmask
associated with the address you specify. Such a mask will likely be too large. This
is not necessarily a disaster, but the routing table may incorrectly indicate that it 20
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 192.0.2.64 IPv4 address to the fei1 interface, enter:
-> ifAddrSet "fei1", "192.0.2.64"
This call made without a prior ifMaskSet( ) call assigns 192.0.2.64 to the fei1
interface and creates a route table entry for 192.0.2.64 with a 24-bit netmask. If you
had wanted a 16-bit netmask, you would have needed to precede the ifAddrSet( )
call with an ifMaskSet( ) call. For example:
-> ifMaskSet "fei1", 0xFFFF0000
-> ifAddrSet "fei1", "192.0.2.64"
435
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
If you mistakenly call ifAddrSet( ) before you call ifMaskSet( ), you cannot fix the
mistake simply by calling ifMaskSet( ). You must delete the problematic route
entry from the route table and then call ifMaskSet( ) and ifAddrSet( ) in the
proper order. For information on how to delete route table entries, see 20.2.4 Using
routec( ) to Add or Delete Route Table Entries, p.437.
The if6Lib API breaks out the ifconfig( ) options for IPv6 configuration into
individually callable routines suitable for use in compiled code or from a
command line. As much as possible, the if6Lib API parallels that provided by
ifLib. For example, if6AddrAdd( ) is the if6Lib parallel to the ifLib routine,
ifAddrAdd( ).
-> if6AddrAdd "fei1", "2002:C000:0240::66 ", 16
This if6AddrAdd( ) call above configures the fei1 network interface to have an
IPv6 address of 2002:C000:0240::66, a 6to4 IPv6 address for 192.0.2.64. The prefix
length is 16 bits. For more information, see the if6Lib reference entry.
If you have accidentally misconfigured a network interface, you will need to delete
the problematic entry from the route table. You may also want to edit the routing
table manually when first testing the routing stack software or a new application
that you have just written or ported for that stack. At this time, it is often
convenient to enter a default network route. In addition, setting up tunnels
through the IPv4 Internet requires some editing of the routing table, see
20.5 Working with IPv4 and IPv6 Tunneling, p.444.
For command-line editing of the route table, the stack also supports routec( ), a
port of the UNIX route( ) utility. This utility provides options for viewing the
routing table contents as well as for adding and deleting route entries.
All the APIs mentioned above are strongly oriented towards command-line use.
For a utility more appropriate to use within compiled code, use a standard routing
socket. For more information on routing socket messages, see 15. Working with
Routing Sockets.
436
20 Working with Device Instances
20.2 Working with Network Driver Instances
You can use routex( ) to add or delete route table entries for local losts and
gateways. Although the appendices to this manual include a reference entry that
describes the routec( ) utility, the following examples cover most uses of the
command. To verify the proper operation of a routec( ) command, use:
-> netstat "-r"
For example:
-> routec "add -net 192.168.10.0 192.168.1.1 -netmask 255.255.255.0"
For example:
-> routec "add -host -inet6 2001:DB8:84b1:7600:0205:00ff:fe00:0101
fe80::20f:ff:fe00:101%fei0"
437
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
For example:
-> routec "add default 192.168.1.1"
For example:
-> routec "add -inet6 default fe80::20f:ff:fe00:101%fei0"
If you are working with the ifconfig( ) interface, replace the ifMaskSet( ) and
ifAddrSet( ) calls with the appropriate ifconfig( ) call:
-> ifconfig "interface inet6 newIPv6address prefixlen newPrefixLengthValue" (for IPv6)
-> ifconfig "interface inet newIPv4address netmask newMaskValue" (for IPv4)
Alternatively, you can use the slash notation to specify the address and netmask
(or prefix length) in one string:
-> ifconfig "interface inet6 newIPv6address/newPrefixLengthValue" (for IPv6)
-> ifconfig "interface inet newIPv4address/newMaskValue" (for IPv4)
438
20 Working with Device Instances
20.2 Working with Network Driver Instances
The host table stores one entry per Internet address, but you can associate multiple
names with an address. The additional host names are added as aliases.
When specifying IPv6 link or site local addresses, you must supply a scope
delimiter, %, and corresponding interface ID. For more information, see the
hostAdd( ) reference entry.
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). 1
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). Some older systems use an Internet
address with a host part of all zeros as the broadcast address.
Most new network stacks, including the Wind River Network Stack, accept either
address on incoming packets as being a broadcast packet. When an application
sends a broadcast packet, it must use the correct broadcast address for its system.
The Wind River Network Stack normally uses a host part of all ones as the
20
broadcast address. Thus, a datagram sent to Internet address 10.255.255.255
(0x0AFFFFFF) is broadcast to all systems on network 10. To allow compatibility
with other systems, the Wind River Network Stack 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, the Wind River Network Stack supports multicasting – transmission
to a subset of hosts on the network. For more information on multicasting, see
13.2.2 Using a Datagram (UDP) Socket to Access IPv4 Multicasting, p.260.
1. IPv6 does not support broadcast messages. This is an IPv4 concept only.
439
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Similarly, you control the IPv4 and IPv6 functionality of the device using the inet
and inet6 options in an ifconfig( ) call. These options also take the up and down
modifiers. For example:
-> ifconfig "fei0 inet down"
-> ifconfig "fei0 inet6 down"
-> ifconfig "fei0 inet up"
-> ifconfig "fei0 inet6 up"
To bring up the link and IPv4 and IPv6 functionality all at once, you can use the up
modifier without specifying link or inet or inet6. For example:
-> ifconfig "fei0 up"
Similarly, to bring down the link or IPv4 or IPv6 functionality all at once, you can
use the down modifier without specifying link or inet or inet6. For example:
-> ifconfig "fei0 down"
By calling rtadvConfig( ), you can control which prefixes are advertised though a
particular interface. You cannot pause and enable the Router Advertisement or
Router Solicitation functionality on a per-interface basis. For information on how
to do this, see the rtadvConfig( ) reference entry.
For information on starting and stopping the Router Solicitation task, see the
rtsolStart( ) and rtsolStop( ) reference entries.
440
20 Working with Device Instances
20.3 Adding Automatic IPv4 Interface Configuration
For information on starting the Router Advertisement task, see the rtadv( )
reference entry. There is no publicly callable routine that you can use to stop the
Router Advertisement task. Router advertisement is a router (not host) feature. It
requires that IPv6 packet forwarding be enabled. You can enable IPv6 forwarding
as follows:
-> Sysctl "net.inet6.ip6.forwarding=1"
If you disable forwarding, you effectively pause router advertisement until you
turn on forwarding for IPv6.
The Wind River Network Stack supports automatic IPv4 interface configuration.
To add support for this feature, include the Auto IPv4 Address Configuration
component in your VxWorks image. This component is listed under the
Network Components > Network Applications folder in Workbench.
20
The INCLUDE_AIP component pulls in aipLib, a library that allows a target to
automatically configure an interface with a link-local IPv4 address. Including
INCLUDE_AIP in a VxWorks image sets up a call to the usrNetAutoIpInit( )
initialization routine, which is defined in the net/coreip/apps/usrNetAutoipCfg.c
file.
This component requires the following configuration components, which are
automatically included:
■
INCLUDE_IPV4
■
INCLUDE_BPF
■ INCLUDE_ARP_API
■
INCLUDE_SELECT
441
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Using Auto IP
Auto IP chooses an address at random from the 169.254/16 IPv4 address space.
The target then uses ARP requests to verify that the address is not already in use
on the local link. If the address is in use, another address is chosen from the
169.254/16 IPv4 address space. This process is repeated until an unused address is
found.
Using this address, the target can communicate with other IPv4 targets on the local
link, although the address is not suitable for communication beyond the local link.
Superficially, IPv4 auto configuration is similar to IPv6 auto configuration, and can
be used in much the same way. For example, one environment well suited to IPv4
auto configuration is an isolated IPv4 network of devices without access to a
DHCP server.
To add support for this feature, include the Reverse ARP Client component in
your VxWorks image. This component is listed under the
Network Components > Network Protocol Components >
Network IPv4 Components folder in Workbench.
The INCLUDE_RARP component pulls in rarpLib, a library that provides an
implementation of the Reverse Address Resolution Protocol (RARP) client that
conforms to RFC 903. Including INCLUDE_RARP in a VxWorks image sets up a call
to the usrNetRarpInit( ) initialization routine, which is defined in
net/coreip/usrNetRarpCfg.c.
442
20 Working with Device Instances
20.4 Using the Reverse ARP Client
Using the RARP client, a VxWorks target can broadcast a RARP request packet
containing its hardware address. If there is a RARP server on the local network, it
responds with a RARP response packet. This packet contains the IP address that
the RARP host associates with the hardware address in the RARP request packet.
Diskless workstations sometimes use RARP at boot time to request an IP address.
If you are writing boot code for a device that requires an external source to supply
more than an IP address, consider using BOOTP or DHCP.
For more information on the Wind River Network Stack RARP client, see the
rarpLib reference entry.
NOTE: RARP is an older protocol that, for most purposes, is now superseded by
BOOTP, which is largely superseded by DHCP.
To use the RARP client to get an IP address for a network interface, call rarpGet( ).
As input, this routine expects the name and unit number of the local network
interface for which you want to request an IP address. This routine also expects a
timeout value as well as a pointer to a structure into which it can write the IP
address if the call is successful. A rarpGet( ) call does not execute asynchronously. 20
Control does not return from rarpGet( ) until a RARP host supplies the address or
the timeout expires. For more information, see the rarpGet( ) reference entry.
By default, the RARP client does not generate debug messages. You can use
rarpDebugSet( ) to activate the RARP client debug facility. While active, this
facility sends debug messages to the logging task. For more information, see the
rarpDebugSet( ) reference entry.
443
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
NOTE: Although this chapter focuses on host-to-host tunnels, one can also set up
set up host-to-router tunnels, router-to-router tunnels, and all such permutations.
The Wind River Network Stack supports the following gif and stf pseudo device
tunneling configuration components:
■ GIF Tunnel Interface Driver
■ 6to4 Tunnel Interface Driver
These components are all listed under the
Network Components > Network Applications folder in Workbench. d
The INCLUDE_GIF component pulls in modules that implement the gif pseudo
tunneling device used with IPv4. This component has no configuration
parameters.
The INCLUDE_STF component pull in support for the 6to4 pseudo tunneling
device used with IPv6. This component requires the INCLUDE_IPV6 component
and has no configuration parameters.
444
20 Working with Device Instances
20.5 Working with IPv4 and IPv6 Tunneling
Using the stf and gif pseudo devices, it is possible to create 6to4 (stf) and RFC
2893-style (gif) tunnels.
The gif-based tunnels use a tunnel style sometimes described as configured
tunnels because you must specify the addresses of the endpoints at set up time.
These tunnels are essentially point-to-point links. To tunnel IPv6 traffic, these
gif-based tunnels require both tunnel ends to be dual IPv4/IPv6 nodes. They do
not require that you identify the tunnel endpoints in terms of 6to4 IPv6 addresses.
This is because the IPv4 addresses associated with the tunnels are configured into
the gif device instance when it is first loaded. Thus, you are free to configure the
tunnel endpoints using whatever IPv6 addresses are most appropriate.
IPv6 IPv4
MUX
etherOutput tunnelIfOutput 20
NOTE: For gif, only 6-in-4 tunnels are supported. Thus, 4-in-6, 4-in-4 and 6-in-6
tunnels are not supported for gif.
445
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The stf-based tunnels are one of the many tunnel-styles sometimes described as
automatic tunnels. Despite their name, automatic tunnels do require some
minimal configuration work. What is not explicitly configured is the endpoint of
the tunnel. That information is taken from the destination address of the packet,
which is possible because stf devices automatically tunnel to 6to4 IPv6 addresses
only. If you make appropriate entries in the route table, you can tunnel other IPv6
traffic through the stf tunnel for routing by the dual stack at the other end, but only
packets with IPv6 6to4 addresses are automatically tunneled.
Automatic tunnels are described below. Configured tunnels are described in
20.5.4 Using gif Devices to Create RFC 2893-Style Configured Tunnels, p.449.
IPv6 IPv4
MUX
NOTE: For gif, only 6-in-4 tunnels are supported. Thus, 4-in-6, 4-in-4 and 6-in-6
tunnels are not supported for gif.
446
20 Working with Device Instances
20.5 Working with IPv4 and IPv6 Tunneling
20.5.3 Using stf Devices to Create 6to4 Tunnels for IPv6 Packets
On a Wind River Network Stack dual stack, the creation of a 6to4 tunnel requires
that you create an stf pseudo device to encapsulate the IPv6 packets. After creating
the stf, you must create entries in the route table so that remotely destined (not link
local) IPv6 packets are directed to this pseudo device.
Consider the following set up code for automatic tunneling on a Wind River
Network Stack dual stack.
/*******************************************************************************/
/* code for STF tunnel setup */
#include "vxWorks.h"
#include "m2Lib.h"
#include "muxLib.h"
#include "ipProto.h"
#include "net/utils/ifconfig.h"
#include "net/utils/routeCmd.h"
#include "net/ethernet.h"
void stfTest ()
{
void * pCookie;
pCookie = muxDevLoad (0, stfLoad, "0:1:0:0:0", 0, 0);
if (pCookie == NULL)
{ 20
printf ("muxDevLoad failed.\n");
return;
}
muxDevStart (pCookie);
ip6Attach (0, "stf");
tunnelIfConfig ("stf0", AF_INET, "IPv4AddressForLocalInterface", NULL);
ifconfig ("stf0 inet6 6to4AddressForLocalInterface prefixlen 128");
routec ("add -inet6 2002:: 6to4AddressForLocalInterface -prefixlen 16");
}
447
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
From the command line, and, assuming a local interface with an IPv4 address of
192.0.2.1, you could set up an stf tunnel as follows:
-> ifconfig "fei1 192.0.2.1"
-> pcookie = muxDevLoad ( 0, stfLoad, "0:1:0:0:0", 0, 0 )
-> muxDevStart pcookie
-> ip6Attach 0, "stf"
-> tunnelIfConfig ("stf0", AF_INET, "192.0.2.1", NULL)
-> ifconfig "fei0 inet6 2002:C000:0201::66 prefixlen 48"
-> ifconfig "stf0 inet6 2002:C000:0201::66 prefixlen 128"
-> routec "add -inet6 2002:: 2002:C000:0201::66 -prefixlen 16"
-> routec "add default 192.0.2.1"
2. For information on the third parameter in the muxDevLoad( ) call, see the description of
stfLoad( ) provided in the reference entry for stf.
448
20 Working with Device Instances
20.5 Working with IPv4 and IPv6 Tunneling
This routec( ) call creates a route that directs packets with 6to4 addresses to
2002:C000:0201::66, which is also known as stf0.
Because ifconfig( ) for fei0 already created a route that matches better on local 6to4
addresses, this 2002::/16 route catches all packets destined to remote 6to4
addresses. The packets headed to these addresses are directed to stf0, which
encapsulates them in IPv4 packets and then transmits them using the default
interface for IPv4, fei1.
For example, consider a ping6( ) to 2002:C000:0202::33. This IPv6 destination
would not match on the fei0 route entry for local IPv6 hosts, so it would be
directed to stf0. This pseudo device would then encapsulate the IPv6 packet in an
IPv4 packet destined for 192.0.2.2.
To send packets to native IPv6 addresses, you could contract with an IPv6 router
with 6to4 addresses to relay your packets. You would then need to update your
routing table to forward your IPv6 packets to this router. For example:
-> routec "add -inet6 default 2002:C0000:0203::1"
This call would create a default route entry that forwarded IPv6 packets to the IPv6
router at 192.0.2.3. Make sure that you keep your normal 6to4 route to 2002::/16 to
ensure that this gateway is not used for all 6to4 packets as well. This helps to
ensure that the best route is taken for normal 6to4 traffic.
If you intend that the systems at the tunnel ends function as routers, make sure that
the network stack at those tunnel ends are configured to forward IPv6 packets. If
the stack is a VxWorks network stack, you can use Sysctl( ):
-> Sysctl "net.inet6.ip6.forwarding=1"
449
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
void gifTest ()
{
void * pCookie;
muxDevStart (pCookie);
ip6Attach (0, "gif");
tunnelIfConfig ("gif0", AF_INET, "sourceIPv4Address", "destinationIPv4Address");
Packets sent to this gif device are always transmitted from the specified local
interface to the specified remote interface. In the code above, the tunnelIfConfig( )
call specifies AF_INET as its address family. This indicates a tunnel is through an
IPv4 address space. Thus, the source and destination addresses are IPv4 addresses.
If the address family were AF_INET6, it would indicate a tunnel through the IPv6
address space, which would require IPv6 source and destination addresses in the
tunnelIfConfig( ).
Now that you have created a device to manage the tunnel, you need to add
configuration information that associates IPv6 addresses with the tunnel
endpoints. To do this, call ifconfig( ) as follows:
-> ifconfig "gif0 inet6 localIPv6Address remoteIPv6Address prefixlen 128"
Note that the IPv6 addresses supplied above need not be 6to4 addresses. They can
be any valid IPv6 addresses (of proper scope) validly associated with the tunnel
endpoints.
To direct IPv6 packets to this device by default, you can add an IPv6 default entry
to the route table. For example:
-> routec "add -inet6 default tunnelEndpointIPv6Address"
450
20 Working with Device Instances
20.5 Working with IPv4 and IPv6 Tunneling
Alternatively, you can direct only some IPv6 packets to the interface. For example,
the following entry would capture traffic destined for 2001:DB8:1::/64:
-> routec "add -inet6 2001:DB8:1:: tunnelEndpointIPv6Address -prefixlen 64"
An Example Configuration
Assume that you own the IPv4 address 10.1.0.1 and the IPv6 address
2001:DB8:1234::1. Assume also that the owner of IPv4 address 10.2.0.1 has agreed
to route your IPv6 traffic for 2001:DB8:3333::/32 and that the IPv4 node at 10.2.0.1
is a dual IPv4/IPv6 stack with an IPv6 address of 2001:DB8:5678::1. You can:
-> pcookie = muxDevLoad ( 0, gifLoad, "1:0:0:0", 0, 0 )
-> muxDevStart pcookie
-> ip6Attach 0, "gif"
-> tunnelIfConfig "gif0", AF_INET, "10.1.0.1", "10.2.0.1"
Then you would configure the interfaces and route table as follows:
-> ifconfig "fei0 inet6 2001:DB8:1234::1"
-> ifconfig "gif0 inet6 2001:DB8:1234::1 2001:DB8:5678::1 prefixlen 128"
-> routec "add -inet6 2001:DB8:3333:: 2001:DB8:5678::1 -prefixlen 48"
Your local node now supports the following devices and route table entries:
Addresses:
fei0 10.1.0.1
fei0 2001:DB8:1234::1
gif0 2001:DB8:1234::1 -> 2001:DB8:5678::1 (and configured from
10.1.0.1 to 10.2.0.1)
Routes:
10.1.0.1/8 fei0
2001:DB8:1234::/64 fei0
2001:DB8:3333::/32 gif0
If you have negotiated for routing services from more than one remote IPv6 router 20
that supports a dual IPv4/IPv6 stack, you can create additional gif devices to
manage configured tunnels through those routers. You would also want to set up
your route table to control which IPv6 packets went to which router.
For example, if the second remote dual IPv4/IPv6 stack was at 10.3.0.1 IPv4 and
2001:DB8:9999::1 IPv6, you would use the following set up code:
-> pcookie0 = muxDevLoad ( 0, gifLoad, "1:0:0:0", 0, 0 )
-> pcookie1 = muxDevLoad ( 1, gifLoad, "1:0:0:0", 0, 0 )
-> muxDevStart pcookie0
-> muxDevStart pcookie1
-> ip6Attach 0, "gif"
-> ip6Attach 1, "gif"
-> tunnelIfConfig "gif0", AF_INET, "10.1.0.1", "10.2.0.1"
-> tunnelIfConfig "gif1", AF_INET, "10.1.0.1", "10.3.0.1"
451
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
To add a route over gif0 use 5678::1 in a routec( ) call. For example:
-> routec "add -inet6 2001:DB8:1:: 2001:DB8:5678::1 -prefixlen 64"
To add a route over gif1 use 2001:DB8:9999::1 in a routec( ) call. For example:
-> routec "add -inet6 2001:DB8:4444 2001:DB8:9999::1 -prefixlen 48"
452
20 Working with Device Instances
20.6 Adding a BPF Device
To add support for this feature, include the BPF Support component in your
VxWorks image. This component is listed under the
Network Components > Network device Components folder in Workbench.
The INCLUDE_BPF component automatically executes usrNetBpfDrvInit( ), a
routine from the configlette, net/coreip/usrNetBpfDrv.c. Included in this routine
is a call to bpfDrv( ), which initializes the BPF driver, a prerequisite to creating BPF
device instances.
This component contains the following configuration parameter:
BPF_BUFSIZE_CFG
Synopsis: Specifies the BPF buffer size. For more information, see Creating a
BPF Device, p.453.
Default: 4096
For more information on the externally callable routines associated with the BPF
driver, see the bpfDrv reference entry.
20
To create a BPF device:
1. Call bpfDrv( ) to initialize the BPF driver. Ensure that this routine does not
return ERROR. The network stack initialization code should already have
called bpfDrv( ), but calling it again is safe and verifies that the driver
initialized successfully and has not been removed since initialization.
2. Call bpfDevCreate( ) to create a BPF device.
STATUS bpfDevCreate
(
char * pDevName, /* I/O system device name */
int numUnits, /* number of device units */
int bufSize /* block size for the BPF device */
)
453
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The device name should be something like /dev/bpf or /bpf/foo. The number
of units should be set to the maximum number of BPF units for the device – for
example, if you want to use /dev/bpf0 and /dev/bpf1, numUnits should be set
to at least 2. The buffer size should be less than or equal to the MTU, and the
buffer you use to read data from the BPF device should be at least as large as
this bufSize. If you specify a buffer size of zero, the call assumes
BPF_BUFSIZE_CFG as the buffer size.
3. Call open( ) to get a file descriptor for one of these BPF units, for example:
bpffd = open( "/dev/bpf0", 0, 0 );
4. Set any desired options for this unit by using ioctl commands – for instance:
int arg = 1;
int status = ioctl (bpffd, BIOCIMMEDIATE, (int)&arg);
5. Use the BIOCSETF ioctl command to set a filter for the BPF device. This filter
is written according to the bpf_program template. Incoming packets that
match this filter will be passed to the associated BPF device.
6. Use the BIOCSETIF ioctl command to attach the file descriptor associated with
your BPF device unit to a specific network interface.
The BPF_TYPE alias finds the type of link level frame. Use it in statements such as:
BPF_STMT(BPF_LD+BPF_TYPE,0) /* Save lltype in accumulator */
The BPF_HLEN alias determines the header length, independently of the variety of
link layer header in use. Use it in statements such as:
BPF_STMT(BPF_LD+BPF_H+BPF_ABS+BPF_HLEN, 6) /* IP fragment field */
454
21
Integrating a New Network
Interface Driver
21.1 Introduction
This chapter describes how to integrate a new network interface driver with
Wind River Network Stack. For this, you use the MUX, which is an interface that
insulates network services from the particulars of network interface drivers, and
vice versa. Currently, the MUX supports two network driver interface styles, the
Enhanced Network Driver (END) interface and the Network Protocol Toolkit
(NPT) driver interface.
455
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
END Interface
The END is the original MUX network driver interface. ENDs are frame-oriented
drivers that exchange frames with the MUX. The NPT-style drivers are
packet-oriented drivers that exchange packets with the MUX. These packets are
stripped of all datalink layer information. Currently, all network drivers supplied
by Wind River are ENDs, as is the generic driver template defined in
templateEnd.c. There is no generic template for an NPT driver.
Support for the NPT-style driver is part of a set of MUX extensions designed to
facilitate the implementation of MUX-compatible network services. These
extensions include a registration mechanism for an alternative address resolution
utility and support for back ends that let you extend the sockets API so that
applications can use sockets to access a new network service. Both of these features
are described in 22. Integrating a New Network Service.
Polled Mode
This chapter discusses APIs used by drivers to support polled-mode, and APIs
such as muxPollSend( ), which are used to send and receive packets. However, the
network stack itself does not use polled mode. Currently, polled mode is only used
by the WDB agent COMM_END backend in system mode. During system mode
debugging, the WDB agent calls muxPollSend( ) directly in order to pass packets
to the driver, in polled mode.
While it is possible for an application to use a driver that has implemented the
necessary APIs, and call muxPollSend( )—just as the WDB agent does—the
network stack itself does not support sending IP traffic, for example, in polled
mode. The stack will not detect that a driver is in polled mode and, consequently,
will not call the muxPollSend( ).
Thus, polled mode routines cannot be used as a high-performance polling
mechanism for increasing forwarding network performance. The polled mode
routines are recommended to be used only when implementing a driver that could
be used for system mode debugging over WDB.
456
21 Integrating a New Network Interface Driver
21.2 Configuring VxWorks for Network Interface Drivers
The INCLUDE_END component pulls in endLib, which provides support for ENDs
running under the MUX. For this reason, this component also requires
INCLUDE_MUX.
MUX Support
The INCLUDE_MUX component pulls in support for the MUX interface and the
muxLib and muxTkLib libraries.
Including this component pulls in support for the MUX interface and the muxLib
and muxTkLib modules. The END drivers depend directly on the functionality
supplied by muxLib. For more information on ENDs and their use of muxLib, see
the muxLib reference entries. 21
The NPT-style drivers are packet-oriented drivers that exchange packets with the
MUX. These packets are stripped of all datalink layer information. Support for the
NPT-style driver is provided by muxTkLib. For more information on NPT-style
drivers and their use of muxTkLib, see the muxTkLib reference entries.
The INCLUDE_MUX component has no component dependencies or configuration
parameters.
457
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The OSI Network Model describes seven layers through which data passes when
it is transmitted from an application on one machine to a peer on a remote but
network-connected machine. In practice, not all seven layers are implemented.
Starting in the application layer, data passes down through each layer of the stack
to the physical layer, which handles the physical transmission to the remote
machine. After arriving on the remote machine, data passes up through each layer
from the physical to the application.
In the abstract, each layer in the stack is independent of the other layers. A protocol
in one layer exchanges messages with peers in the same layer on remote machines
by passing the message to the layer immediately below it. Whether the message
passes down through other layers is not its concern. Ideally, the protocol is
insulated from such details.
In practice, network stacks that implement each layer with perfect independence
are rare. Within TCP/IP, the protocols that manage the Transport and Network
layer routines are sufficiently coupled that they are sometimes referred to as the
protocol layer. The MUX is an interface between the datalink and this protocol
layer. The MUX is not a new layer. There are no MUX-level protocols that
communicate with peers in the MUX of a remote machine. The MUX concerns
itself solely with standardizing communication between the protocol and datalink
458
21 Integrating a New Network Interface Driver
21.3 Overview of the MUX
layers of a single stack. Because of the MUX, no protocol or network driver needs
direct knowledge of the other’s internals.
459
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
460
21 Integrating a New Network Interface Driver
21.3 Overview of the MUX
To add an END or NPT device to the MUX, call muxDevLoad( ) for each driver
you want to add. This is done for you automatically in the standard network
initialization code if you name the driver’s load routine in the endDevTbl[ ]. The
stack initialization code uses this function pointer as input to a muxDevLoad( )
call.
The value returned by muxDevLoad( ) identifies the END or NPT device. You can
use this identifier in a subsequent call to muxDevStart( ), muxDevStop( ), or
muxDevUnload( ). In some previous versions of the stack, this value could also be
passed as an argument to muxIoctl( ) or muxTkSend( ) or muxSend( ). That no
longer works. These latter routines expect a protocol binding cookie returned from
muxBind( ) or muxTkBind( ). A pseudo-bind cookie returned by
muxTkCookieGet( ) also works. See the discussion of muxTkCookieGet( ) earlier
in this chapter.
Internally, the driver’s load routine must allocate, zero out, and partially populate
an END_OBJ structure and a NET_FUNCS structure. The END_OBJ structure
provides the MUX with a description of the device, and the NET_FUNCS structure
provides the MUX with pointers to the driver’s standard MUX interface routines,
xStart( ), xStop( ), xReceive( ), xIoctl( ), and so on.
The muxDevStart( ) call enables transmission and reception on a loaded END or
NPT device. After a device has been started, it can pass packets up to the MUX by
calling muxReceive( ), if it is an END, or muxTkReceive( ), if it is NPT. The MUX
delivers any of these packets to the appropriate bound protocols. If no bound
protocols match the packet type, the packet is discarded.1
NOTE: The Wind River Network Stack expects to borrow the buffers it receives
and thus avoid data copying. If a device cannot transfer incoming data directly
into clusters, the driver must explicitly copy the data from private memory into a
cluster in sharable memory before passing it in an mBlk up to the MUX. 21
When the MUX receive routine is passed a packet with network service type
matching a protocol bound to the device, it calls the protocol’s receive routine,
registered in the earlier call to muxBind( ) or muxTkBind( ). If the protocol receive
1. The mux[Tk]Receive( ) calls in the shipped ENDs and the template END are hard to iden-
tify as such when casually reading the code. When passing a packet up to the MUX, each of
these drivers uses the function pointer referenced in the receiveRtn field of its END_OBJ.
An earlier call to muxDevLoad( ) set the receiveRtn field to muxReceive( ) or
muxTkReceive( ), whichever was appropriate.
461
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
routine returns TRUE (or any non-zero value), the protocol has consumed the
packet. Otherwise, the MUX checks if any other bound protocol can accept the
packet, and if not, discards it, freeing the associated M_BLK tuples. When a
protocol consumes a packet, it is responsible for freeing the packet.
To disable transmission and reception on a device, call muxDevStop( ). Call
muxDevUnload( ) to remove the network interface from the MUX. Note that
muxDevUnload( ) forcibly shuts down any bound protocols; the protocol
shutdown routine should call muxUnbind( ) to unbind the protocol from the
device.
2. Although the API for both the END and the NPT xIoctl( ) are identical, the NPT xIoctl( )
must support two extra ioctl commands, EIOCGNPT and EIOCGMIB2233.
3. The xBind( ) entry point is not in the NET_FUNCS structure, but it can be returned if the
driver supports the EIOCQUERY ioctl for the END_BIND_QUERY query type.
462
21 Integrating a New Network Interface Driver
21.4 How ENDs and NPT Drivers Differ
In addition to the END_OBJ pointer for the device and the M_BLK pointer for the
packet to be transmitted, an NPT driver send routine takes three more arguments:
■
a pointer to a character buffer containing the destination MAC address
■
the network service type value (also known as the ethertype value)
■
an additional void* pointer.
This is provided for protocols that need to pass additional information to the
driver send routine; the protocol and the driver must both share the same
interpretation of this parameter, if it is used. Normally it is NULL.
The NPT send routine must use the provided destination MAC address and
network service type, and its own known source MAC address, to prepend an
appropriate MAC header to the frame. If the destination MAC address pointer is
NULL, the NPT driver should consider this to indicate that a complete MAC
header has already been prepended to the frame.
In addition to the END_OBJ pointer for the device passed and the M_BLK pointer
for the received packet passed to muxReceive( ), the muxTkReceive( ) routine
called (indirectly) by NPT drivers takes four additional arguments:
■ The offset from the start of the frame to the network-layer header. This is called
the network service offset and is the same as the link header size.
■ The network service type value (ethertype value).
■ A boolean value, which (if TRUE) indicates that the packet is a unicast or
multicast packet that would not have been received were the device not in
promiscuous mode. When this value is TRUE, the received frame is only
passed to SNARF or PROMISCUOUS protocols.
■ An extra void* pointer for additional information which should be passed to
the receiving protocol(s). The protocol and the driver must agree on the
interpretation of this value. Most protocols will ignore this value.
21
The NPT driver parses the link header and passes enough information to the MUX
(and to protocol receive routines) to let them easily strip the link header from the
frame. The NPT driver itself does not remove the link header.
The three END entry points not included in an NPT driver are:4
■
xAddressForm( ) – add addressing information to a packet
■
xAddrGet( ) – extract the addressing information from a packet
■
xPacketDataGet( ) – separate the addressing information and data in a packet
The above routines are optional for NPT drivers because these drivers construct
their own link headers on transmit and parse their link headers on receive.
463
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The following registration interface lets you manage an address resolution routine
for a protocol/interface pair.
■
muxAddrResFuncAdd( ) – add an address resolution routine
■
muxAddrResFuncGet( ) – get the resolution routine for ifType/protocol
■
muxAddrResFuncDel( ) – delete an address resolution routine
For Ethernet devices, the Wind River Network Stack automatically assigns
arpresolve( ) as the address resolution routine. If you are writing an END that does
not run over Ethernet, you also need to implement the xAddressForm( ),
xAddrGet( ), and xPacketDataGet( ) entry points explicitly. ENDs running over
Ethernet typically use the endLib implementations of these routines.
The Wind River Network Stack uses netBufLib to manage its internal system and
data memory pools. Similarly, almost all the shipped ENDs use netBufLib to
manage memory pools for their receive buffers. For best performance, drivers are
encouraged to use the linkBufPool back end plug-in to netBufLib, which
provides pools of pre-constructed M_BLK tuples of a single size, ideal for network
driver receive pools.
NOTE: The Wind River Network Stack expects to borrow the buffers it receives
and thus avoid data copying. If a device cannot transfer incoming data directly
into clusters, the driver must explicitly copy the data from private memory into a
cluster in sharable memory before passing it in an mBlk up to the MUX.
Some devices support breaking up a single network packet into separate chunks
of memory. This makes it possible to handle the outgoing network packets as a
chain of mBlk/clBlk/cluster constructs without any copying.
When a driver gets a chain of mBlks, it can decide how to transmit the clusters in
the chain. If it is able to do a gather-write, it does not need to do any data copying.
If it cannot, then it must collect all of the data from the chain into a single memory
area before transmitting it.
4. For Ethernet, these routines are implemented in endLib. Thus, if your driver runs over
Ethernet (using either 802.3 or DIX header formats), you can reference the existing routines
and do not need to implement them.
464
21 Integrating a New Network Interface Driver
21.4 How ENDs and NPT Drivers Differ
The NPT driver and its MUX support routines are automatically configured to
allocate extra room at the beginning of an outgoing packet to hold the network-
and transport-layer header information. This allows those layers to copy in their
headers without additional overhead in the form of memory allocation and buffer
chaining.
NOTE: The MUX and the NPT driver have nothing to do with the amount of space
reserved at the start of a packet for network, transport, or link header information.
It is the protocols that provide the buffers and the packets to be transmitted that
control this.
You can configure the NPT-supporting MUX routines to also allocate extra room
for the data-link-layer header by setting the MAX_LINKHDR_CFG configuration
parameter or #define in the configNet.h file for your BSP. You should set this
value to the largest of the data-link-layer header sizes used by the drivers in your
system. For instance, if you add the following line:
#define MAX_LINKHDR_CFG 16
sixteen extra bytes will be prepended to outgoing packets, and drivers with
data-link-layer headers of 16 bytes or fewer will have that space available in the
packet without having to prepend a new mBlk during their endAddressForm( ) or
nptSend( ) routines.
NOTE: MAX_LINKHDR_CFG controls the Wind River TCP/IP protocols, not the
MUX. Setting MAX_LINKHDR_CFG large enough for an NPT's MAC header
makes it more likely that the driver send routine will not have to allocate an
additional tuple to store the MAC header, but does not guarantee this.
When using the M_PREPEND( ) macro to add a header to a packet, this extra space
will be automatically used (or, if the space has not been pre-allocated, a new mBlk 21
will automatically be generated and prepended). See 3.4.4 Using Macros for Buffer
Manipulation, p.47.
The interface by which END and NPT drivers collect and report packet statistics to
the stack has changed. No longer does a driver need to use different code to
support RFC 2233 and RFC 1213. A unified interface lets network drivers pass
packet statistics to the stack on a per-packet basis. Alternatively, a driver can
465
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
collect supported statistics which will be polled (at fairly low frequency) by the
stack. This may give better performance, especially if the device hardware
maintains some of the needed statistics. The polled statistics mode requires that
the component INCLUDE_MIB2_IF be configured into the VxWorks image.
The Wind River Network Stack supports counter instrumentation. To add support
for this feature, include the Auto IPv4 Address Configuration component in your
VxWorks image. This component is listed under the
Network Components > Network Protocol Components >
Network Components for MIB2 folder in Workbench.
The INCLUDE_MIB2_IF component pulls in the software modules and MIB files
that SNMP needs to provide access to the network interface layer. Included in
these modules is m2IfLib, which describes the externally callable function
associated with INCLUDE_MIB2_IF. This library provides MIB-II services for the
interface group. It provides routines to initialize the group, access the group scalar
variables, read the table interfaces, and change the state of the interfaces.
There are no component dependencies for INCLUDE_MIB2_IF.
This component includes three configuration parameters. The first two let you
specify the parameter values that the stack initialization code uses when it calls
m2IfInit( ).
MIB2IF_TRAP_RTN
MIB2IF_TRAP_ARG
MIB2IF_LONG_COUNTERS
For more information on these parameters, see the reference entry for m2IfInit( ).
466
21 Integrating a New Network Interface Driver
21.4 How ENDs and NPT Drivers Differ
The driver's unload routine calls endM2Free( ) to release any MIB-related data
structures for which memory was allocated by endM2Init( ).
endM2Free (&pDrvCtrl->endObj);
If a driver wishes to support the polled statistics mode, it adds two members to its
device control structure:
END_IFDRVCONF endStatsConf;
END_IFCOUNTERS endStatsCounters;
The driver load routine should initialize these members after calling endM2Init( ):
bzero ((char *)&pDrvCtrl->endStatsCounters, sizeof(END_IFCOUNTERS));
pDrvCtrl->endStatsConf.ifPollInterval = sysClkRateGet();
pDrvCtrl->endStatsConf.ifEndObj = &pDrvCtrl->endObj;
pDrvCtrl->endStatsConf.ifValidCounters = (END_IFINUCASTPKTS_VALID |
END_IFINMULTICASTPKTS_VALID |
END_IFINBROADCASTPKTS_VALID |
END_IFINOCTETS_VALID |
END_IFOUTOCTETS_VALID |
END_IFOUTUCASTPKTS_VALID | 21
END_IFOUTMULTICASTPKTS_VALID |
END_IFOUTBROADCASTPKTS_VALID);
The ifValidCounters member is a set of bit flags indicating which statistics the
driver supports, i.e. which of the END_IFCOUNTERS members the driver will fill
in. The ifPollInterval member sets the period (in system clock ticks) at which the
stack polls statistics.
The ifEndObj merely points to the END_OBJ structure for the interface.
The remaining members of the END_IFDRVCONF structure are initialized by code
outside the driver.
467
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
break;
/*
* The EIOCGPOLLCONF and EIOCGPOLLSTATS commands are implemented
* only if the driver wishes to support polled statistics retrieval.
* EIOCGPOLLCONF retrieves a pointer to the polling configuration
* structure (as initialized by the driver load routine).
* EIOCGPOLLSTATS first collects the statistics into the
* END_IFCOUNTERS structure, retrieving them from the hardware if
* necessary, and the stores a pointer to that structure at the
* indicated address.
*/
case EIOCGPOLLCONF:
if ((data == NULL))
error = EINVAL;
else
*((END_IFDRVCONF **)data) = &pDrvCtrl->endStatsConf;
break;
case EIOCGPOLLSTATS:
if ((data == NULL))
error = EINVAL;
else
{
/* retrieve the statistics from the hardware */
error = motTsecEndStatsDump(pDrvCtrl);
if (error == OK)
*((END_IFCOUNTERS **)data) = &pDrvCtrl->endStatsCounters;
}
break;
Drivers loaded by the startup code that support polling will have polling started
automatically. For drivers loaded later, manually or by application code, the
endPollStatsInit( ) routine may be called to start polling:
endPollStatsInit (pCookie, m2PollStatsIfPoll);
468
21 Integrating a New Network Interface Driver
21.4 How ENDs and NPT Drivers Differ
Either way, polling takes place in the context of tNetTask, by calling the driver's
endIoctl routine with the EIOCGPOLLSTATS command. The handler for that
command should retrieve from the hardware the supported statistics and store
them in the appropriate members of the driver’s END_IFCOUNTERS structure
(endStatsCounters in the example above). The counts stored should be the counts
accumulated since the last polling call, or (on the first call only) those accumulated
since the interface was started.
NOTE: Poll mode should only be used for debugging. For details, see Polled Mode,
p.456.
A driver which does not support the polled mode statistics collection should not
implement the EIOCGPOLLCONF and EIOCGPOLLSTATS end ioctl commands.
Instead, it accumulates statistics per packet by calling the endM2Packet( ) routine,
as follows.
For successfully transmitted packets, the driver calls:
endM2Packet(&pDrvCtrl->endObj, pMblk, M2_PACKET_OUT);
For packets which could not be transmitted due to a resource limitation (not for
normal TX stalls), the driver should call:
endM2Packet (&pDrvCtrl->endObj, NULL, M2_PACKET_OUT_DISCARD);
For packets which the driver detected a transmission error (not a resource
limitation or a normal TX stall), the driver calls:
endM2Packet(&pDrvCtrl->endObj, NULL, M2_PACKET_OUT_ERROR);
469
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Unfortunately, when a packet first arrives, its datalink layer header might not end
on an absolute four-byte boundary. For example, the RFC 894 Ethernet packet (see
Figure 21-2) has a 14-byte header that precedes the payload data.
Figure 21-2 RFC 894 Ethernet Packets Are Problematic for Alignment-Sensitive Hardware
5. If the buffer contains a four-byte region that you access as an array of 8-bit or 16-bit values,
there is no alignment restriction. The restriction applies only when you access long words.
470
21 Integrating a New Network Interface Driver
21.5 Buffer Alignment
If you receive this type of Ethernet packet on a long word boundary, any four-byte
aligned payload data (such as an IP packet) following such a header would be
misaligned because the payload data would start on a two-byte boundary. If you
pass this misaligned data up to the MUX, the stack crashes.
To guarantee correctly aligned payload data, your driver can:
■
copy the data (the worst-case solution)
■ offset the receive buffers (often impossible on hardware that needs it)
■ use a scatter-gather receive (the most elegant solution)
The simplest solution to the alignment problem is for the driver to copy each
packet upon reception such that the data aligns properly. The driver can then
safely pass the data up to the MUX. Because such a copy is time consuming, it is a
worst-case solution.
Often, it is sufficient to copy just enough of the start of the packet to contain all
protocol headers into a separate tuple's cluster, with the network header at least
4-byte aligned. Protocol payload data (for example, TCP or UDP payload) is
typically copied into user application buffers, and this copy itself has no alignment
restrictions. Applications might need to be careful to align the data buffers they
receive this payload into, of course. Buffers allocated using malloc( ) will have
sufficient alignment.
On some hardware, the driver can offset the receive buffers that it gives to the
hardware such that the protocol headers within the received packets start at a
four-byte boundary. This mis-aligns the MAC header, but this is not usually a 21
problem. Neither the stack nor the MUX ever access Ethernet header data as
anything but 8-bit and 16-bit quantities. Thus, the access restriction that applies to
long words only does not apply.
To succeed, this approach relies on the ability to DMA data into a misaligned (non
four-byte aligned) buffer. Unfortunately, some DMA controllers do not allow
misaligned buffers. In fact, on boards that have CPUs with alignment issues, these
issues are usually pushed down into the rest of the hardware infrastructure,
including the DMA engines. Thus, this approach is often impossible on the very
hardware that requires it.
471
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
If the hardware can handle scatter-gather lists, your driver can use this feature to
handle the alignment problem elegantly. For each packet, your driver allocates
two buffers: one buffer for the MAC layer header data (Ethernet header), and a
second buffer for the payload data (such as an IP datagram). See Figure 21-4.
Figure 21-4 Receiving an RFC 894 Packet into Two Linked Scatter-Gather Buffers
RFC 894 2 Bytes Payload data, the internally four-byte aligned data is also
Header Empty correctly aligned relative to the absolute four-byte boundaries.
On reception, the device places the MAC header into one buffer and the payload
data into the other. The driver receive routine then links these together and
processes them as a buffer chain in which each component buffer automatically
starts on a four-byte boundary. Therefore, when the driver hands the buffer chain
up to the MUX, the payload data is correctly aligned. This solution assumes that
the length of the scatter-DMA buffers is arbitrary, and need not be (for instance) a
multiple of 4.
472
21 Integrating a New Network Interface Driver
21.6 Understanding END Implementation
NOTE: For instructions on starting additional drivers at run-time, see 20.2 Working
with Network Driver Instances, p.432.
For the most part, the NPT and the END handle these operations identically. The
major exception is in the area of receiving frames. NPT drivers pass up information
that makes it easy to strip the datalink header, but the header is still present when
the NPT driver passes a received frame to the MUX.
21
Adding an END
Adding your driver to the Wind River Network Stack is much like adding any
other application to a target image. The first step is to compile and include the
driver code in the image.
Because the Wind River Network Stack allows you to create more than one
network device, you must set up a table that groups the #define statements that
configure these devices into device-specific groups.
473
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
This table, endDevTbl[ ],is defined in the configNet.h file in your directory:
installDir/vxworks-6.n/target/config/bspname
Where bspname is the name of your board support package, such as mv162 or
pc486. For example, to add an ln7990 END, you would edit configNet.h to contain
lines such as:
/* Parameters for loading ln7990 END supporting buffer loaning. */
#define LOAD_FUNC_0 ln7990EndLoad
#define LOAD_STRING_0 "0xfffffe0:0xffffffe2:0:1:1"
#define BSP_0 NULL
You should define three constants, like those shown above, for each of the devices
you want to add. To set appropriate values for these constants, consider the
following:
LOAD_FUNC
Specifies the name of your driver’s endLoad( ) entry point. For example, if your
driver’s endLoad( ) entry point were ln7990EndLoad( ), you would edit
configNet.h to include the line:6
#define LOAD_FUNC_n ln7990EndLoad
LOAD_STRING
Specifies the initialization string passed into muxDevLoad( ) during network
initialization as the initString parameter. This string is passed along blindly to
the endLoad( ) routine of the driver, and its contents depend on what the
driver expects.
Some BSPs define LOAD_FUNC as a wrapper routine which is responsible for
calling the real driver load routine with appropriate arguments. In this case,
LOAD_STRING is often NULL.
You must also edit the definition of the endDevTbl[ ] (a table in configNet.h that
specifies the ENDs included in the image) to include entries for each of the devices
to be loaded:
END_TBL_ENTRY endDevTbl [] =
{
{ 0, LOAD_FUNC_0, LOAD_STRING_0, BSP_0, NULL, FALSE },
{ 1, LOAD_FUNC_1, LOAD_STRING_1, BSP_1, NULL, FALSE },
{ 0, END_TBL_END, NULL, 0, NULL, FALSE },
};
6. Do not confuse END entry points, indicated as endLoad( ), endStart( ), and so on, with
routines in endLib, an END support library that defines routines such as
endTxSemTake( ) and endTxSemGive( ).
474
21 Integrating a New Network Interface Driver
21.6 Understanding END Implementation
The first number in each table entry specifies the unit number for the device. The
first entry in the example above specifies a unit number of 0. Thus, the device it
loads is deviceName0. The FALSE at the end of each entry indicates that the entry
has not been processed. After the system has successfully loaded a driver, it
changes this value to TRUE in the run-time version of this table. To prevent the
system from automatically loading your driver, set this value to TRUE.
Some BSPs create entries in the endDevTbl[] at run-time. This could make it easier
to deal with dynamically discovered network hardware, and it can make device
configuration more flexible. When endDevTbl[] is generated at run-time, it is
typically pre-filled with a number of empty entries that can be consumed as
network devices are discovered.
At this point, you are ready to rebuild the Wind River Network Stack to include
your new drivers. When you boot this rebuilt image, the system calls
muxDevLoad( ) for each device specified in the table in the order listed.
NOTE: The endDevTbl[ ] can contain a mix of NPT drivers and ENDs.
At system startup, the Wind River Network Stack spawns the user root task,
which initializes the network. This task calls muxDevLoad( ), which calls the
endLoad( ) routine in your driver. This endLoad( ) routine creates and partially
populates an END_OBJ structure that describes the driver. Among the information
that endLoad( ) must supply in the END_OBJ is a reference to a NET_FUNCS
structure that endLoad( ) has allocated and populated with references to the driver
entry points. Typically, the END_FUNCS structure is static and is shared between
all network devices managed by the driver.
After muxDevLoad( ) loads your driver, a muxDevStart( ) call executes the
21
endStart( ) routine in your driver. The endStart( ) routine should activate the driver
and register an interrupt service routine for the driver with the appropriate
interrupt connect routine for your architecture and BSP.
Binding to a Service
An END typically does not react when a service binds to a device. An END may
take advantage of the same facility used by an NPT driver to exchange data with a
service during the bind phase. See Responding to Network Service Bind Calls, p.491,
for more complete information on this process.
475
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Receiving Frames
When a device receive interrupt occurs, the Wind River Network Stack invokes
the interrupt service routine that was registered by the endStart( ) routine. This
interrupt service routine should do the minimum amount of work necessary to
transfer the frame from the local hardware into accessible memory (ideally a
cluster: see 21.3.3 The Data-Link-to-MUX Interface, p.461).
To minimize interrupt lockout time, your ISR should handle directly (at interrupt
level) only those actions that require minimum execution time, such as error
checking or device status change. The ISR should queue all time-consuming work
for processing at task level.
The ISR should disable further receive interrupts and set a flag indicating that it
has posted work to task level. If this flag is already set when the ISR is entered,
another job (for the same type of event, that is, frame reception) need not be posted.
This could occur when more than one device shares the same interrupt line.
To queue frame reception work for processing at the task level, your ISR can use
netJobAdd( ). This routine takes a function pointer and up to five additional
arguments (representing parameters to the routine referenced by the function
pointer).
The netJobAdd( ) routine prototype is:
STATUS netJobAdd
(
FUNCPTR routine,
int param1,
int param2,
int param3,
int param4,
int param5
)
The routine in this case should be the routine in your driver that performs frame
processing at the task level. The netJobAdd( ) routine puts that routine on
tNetTask’s work queue and gives a semaphore that awakens tNetTask.
Upon awakening, tNetTask dequeues routine calls and associated arguments
from its work queue. It then executes these routines in its context until the queue
is empty.
Your task-level frame reception routine should do whatever is necessary to
construct an mBlk chain containing the frame to hand off to the MUX, such as
assuring data coherency. When all is ready, your driver passes the frame up to the
MUX by calling the routine referenced in the receiveRtn field of the END_OBJ
structure that represents your device (see B.3.3 END_OBJ, p.594).
476
21 Integrating a New Network Interface Driver
21.6 Understanding END Implementation
The receive routine should continue processing received frames until either there
are no more to be processed, or a (modest) limit number of frames has been
processed. If there are no more frames to process, the receive routine should clear
the flag set by the ISR indicating that receive work has been posted, then re-enable
receive interrupts, and return. If the frame limit is reached, the receive routine may
repost itself using another netJobAdd( ) call, and return. It should not re-enable
receive interrupts in this case. Reposting another net job rather than simply
continuing to process within the same net job, allows other enqueued net jobs to
run, which is necessary for good performance.
Transmission complete interrupts should be handled similarly: disable further
transmit complete interrupts, and post a net job to do transmit resource clean-up
work, such as freeing M_BLK chains, at task level. The transmit clean-up routine
cleans up as many packets as are ready. If the device was previously stalled and
there are now sufficient free transmit DMA descriptors, muxTxRestart( ) is posted
as a net job to restart transmission, and the stall flag is cleared. The transmit
clean-up routine then re-enables transmit complete interrupts and returns. Some
drivers may choose to use a combined routine for both transmit cleanup and
receive work.
This subsection describes the driver entry points and the shared data structures
that comprise an END’s interface to the MUX.
The core data structure for an END is the END object, or END_OBJ. This structure
is defined in target/h/end.h (see also B.3.3 END_OBJ, p.594). The driver’s load
routine returns a pointer to an END_OBJ that it allocated, zeroed out, and partially 21
populated. This structure supplies the MUX with information that describes the
driver as well as a pointer to a NET_FUNCS structure populated with references to
the END’s standard entry points.
Although the driver’s load routine is responsible for populating much of the
END_OBJ structure, some of its members are set within the MUX when a protocol
binds to the device. Specifically, the MUX maintains the array of protocols bound
to the END_OBJ. When the driver calls its registered receive routine (a
muxReceive( ) or a muxTkReceive( ) call), this routine calls the bound protocol
receive routines appropriate for the received packet.
477
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Table 21-1 lists the standard driver entry points that the NET_FUNCS structure
exports to the MUX. In this manual, the routines use a generic “end” prefix, but in
practice this prefix is usually replaced with a driver-specific identifier, such as
"ln7990" for the Lance Ethernet driver.
Routine Description
endLoad( ) Load a device into the MUX and associate a driver with the
device.
endSend( ) Accept data from the MUX and send it on to the physical
layer.
478
21 Integrating a New Network Interface Driver
21.6 Understanding END Implementation
endLoad( )
Before a network interface can be used to send and receive frames, the appropriate
device must be loaded into the MUX and configured. The muxDevLoad( ) routine
calls your driver’s endLoad( ).
This routine takes an initialization string, the contents of which are user-defined
but generally include such items as the unit number identifying the physical
interface7, an interrupt vector number, and the address of memory mapped
registers.
The endLoad( ) routine must be written as a two-pass algorithm. The MUX calls it
twice during the load procedure. In the first pass, the initialization string is blank
(all zeros). The endLoad( ) routine is expected to check for the blank string and
return with the name of the device copied into the string. A second call is then
made to endLoad( ) with the actual initialization string that was supplied to
muxDevLoad( ). The endLoad( ) then must return a pointer to the END_OBJ that it
allocates or a NULL if the load fails.
Typically, the endLoad( ) routine, in its second pass, will:
■ Initialize the device and interface.
■ Allocate, zero out, and then populate the END_OBJ structure.
■ Initialize any necessary private structures.
■ Parse and process the initialization string.
■ Call endM2Init( ) to initialize MIB interface statistics structures.
■ Create and initialize a private pool of memory using the API in netBufLib.
The endLoad( ) routine is based on the following skeleton:
END_OBJ * endLoad
(
char * initString, /* defined in endTbl */
void * pBsp /* BSP-specific information (optional) */
)
{ 21
END_OBJ * newEndObj;
7. Although a driver is only loaded once, the driver’s endLoad( ) routine will be called for
each port to be activated within the driver. This is so the MUX may allocate an entry for each
port. The MUX interface does not impose restrictions on how drivers handle multiple ports
as long as a separate END_OBJ is allocated for each port.
479
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
endUnload( )
480
21 Integrating a New Network Interface Driver
21.6 Understanding END Implementation
endSend( )
The network driver’s send routine is referenced from the NET_FUNCS table that is
created during the load process. The MUX calls this routine when the network
service issues a send request. The send routine is supplied a reference to an mBlk
chain representing the link-level frame to be sent.
The endSend( ) prototype is:
STATUS endSend
(
END_OBJ * pEND, /* END object */
M_BLK_ID pPkt /* mBlk chain containing the frame */
)
endMCastAddrAdd( )
This routine registers a physical-layer multicast address with the device. It takes as
arguments a pointer to the END_OBJ returned by endLoad( ) and a string
containing the physical address to be added.
This routine should reconfigure the interface in a hardware-specific way that lets
the driver receive frames from the specified address.
481
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
NOTE: To help you manage a list of Ethernet multicast addresses, the Wind River
Network Stack provides the etherMultiLib library.
This routine should return a status OK or ERROR (in which case, errno should be
set appropriately).
endMCastAddrDel( )
This routine removes a previously registered multicast address from the list
maintained for a device. It takes as arguments a pointer to the END_OBJ returned
by endLoad( ), and a string containing the physical address to be removed.
The endMCastAddrDel( ) prototype is:
STATUS endMCastAddrDel
(
END_OBJ * pEND, /* END object */
char * pAddress /* physical address, or a reference thereto */
)
This routine should return a status OK or ERROR (in which case, errno should be
set appropriately).
endMCastAddrGet( )
This routine retrieves a list of all multicast addresses that are currently active on
the device. It takes as arguments a pointer to the END_OBJ returned by endLoad( ),
and a pointer to a MULTI_TABLE structure into which the list will be put.
The endMCastAddrGet( ) prototype is:
STATUS endMCastAddrGet
(
END_OBJ * pEND, /* driver's control structure */
MULTI_TABLE * pMultiTable /* container for address list */
)
This routine should return a status OK or ERROR (in which case, errno should be
set appropriately).
482
21 Integrating a New Network Interface Driver
21.6 Understanding END Implementation
endPollSend( )
NOTE: Poll mode should only be used for debugging. For details, see Polled Mode,
p.456.
NOTE: When the system calls your endPollSend( ) routine, it is probably in a mode
that cannot service kernel calls. Therefore, this routine must not perform any
kernel operations, such as taking a semaphore or allocating memory. Likewise, this
routine must not block or delay because the entire system might halt.
endPollReceive( )
NOTE: Poll mode should only be used for debugging. For details, see Polled Mode,
p.456.
483
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
If a frame has been received, this routine retrieves the frame and copies it into the
buffer of length pPkt->mBlkHdr.mLen at address pPkt->mBlkHdr.mData, and
returns OK. When copying the frame to the destination buffer, the driver should
advance pPkt->mBlkHdr.mData by a small offset if necessary to properly align
the network layer header on a 4-byte boundary, and should adjust
pPkt->mBlkHdr.mLen and pPkt->mBlkBlkHdr.len to indicate the actual
pPkt->length of the frame. (The routine should verify that the original buffer is
large enough to hold the frame, taking the offset into account; if not, it should drop
the frame and return EAGAIN. This is merely for safety. It is the caller’s
responsibility to provide buffers large enough to receive the largest frame allowed
by the link type.)
If no frame is currently available, the routine returns EAGAIN, indicating that the
caller should try again later.
Within the endPollReceive( ) routine, verify that the device has been set to
polled-mode (by a previous endIoctl( ) call). The routine should then retrieve the
frame directly from the network and copy it into the mBlk passed in to the routine.
It takes as arguments a pointer to the END_OBJ structure returned by endLoad( )
and a reference to an mBlk or mBlk chain into which the incoming data should be
put.
The endPollReceive( ) prototype is:
STATUS endPollReceive
(
END_OBJ * pEND, /* returned from endLoad() */
M_BLK_ID pPkt /* mBlk chain: data being received */
)
This routine should return OK or an error value of EAGAIN if the received data is
too large to fit in the provided mBlk, or if no data is available.
endStart( )
The driver’s endStart( ) routine connects device interrupts and makes the interface
active and available. This routine takes as its argument the unique interface
identifier returned from the endLoad( ) call. As with endLoad( ), this call is made
for each port that is to be activated within the driver.
The endStart( ) prototype is:
STATUS endStart
(
END_OBJ * pEND, /* END object */
)
484
21 Integrating a New Network Interface Driver
21.6 Understanding END Implementation
This routine should return a status OK or ERROR (in which case, errno should be
set appropriately).
endStop( )
This routine should return a status OK or ERROR (in which case, errno should be
set appropriately).
endAddressForm( )
485
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
NOTE: The endLib library contains an address formation routine that generates
and prepends Ethernet frame headers. Thus, you probably do not need to
implement this routine if you are running over Ethernet.
endAddrGet( )
This routine retrieves the address values for an incoming frame provided in an
mBlk chain. If the additional mBlk parameters are not NULL, it sets the
mBlk.mBlkHdr.mData and mBlk.mBlkHdr.mLen fields to indicate the location
and size of the corresponding data-link layer addresses. The additional mBlk
parameters are:
pSrc
The local source address of the frame.
pDst
The local destination of the frame.
pESrc
The original link-level source address, or the pSrc settings if none.
pEDst
The final link-level destination address, or the pDst settings if none.
NOTE: The endLib library contains a routine for retrieving address values from
Ethernet frame headers. Thus, you probably do not need to implement this routine
if your driver runs over Ethernet.
This routine should return a status OK or ERROR (in which case, errno should be
set appropriately).
endPacketDataGet( )
This routine parses an incoming frame provided in an mBlk chain. It places the
address information, including the size and offset of the address information, the
486
21 Integrating a New Network Interface Driver
21.6 Understanding END Implementation
offset of the frame payload, and the frame type, in the LL_HDR_INFO structure that
is passed in as a parameter.
NOTE: The endLib library contains a routine for retrieving the address and data
offsets and sizes and the type information from Ethernet frames. Thus, you
probably do not need to implement this routine if your driver runs over Ethernet.
This routine should return a status OK or ERROR (in which case, errno should be
set appropriately).
endIoctl( )
! WARNING: If you are porting a driver from the BSD 4.3 model, you might be
tempted to use the existing xxIoctl( ) routine as your endIoctl( ) routine, skipping
the creation of separate routines for the multicast address table maintenance
routines. Do not do this! Your driver must implement the multicast address table
maintenance routines.
NOTE: Wind River reserves command constants (such as EIOCGFBUF) that are in
the range of 0-128. If you want to use your own custom ioctl commands, define
their command constants to be equivalent to numbers outside this range.
21
The endIoctl( ) routine takes the following arguments:
■
the unique interface identifier returned from the muxDevLoad( ) call
■
the ioctl command being issued
■
a buffer for additional data given in the command or for data to be returned
on completion of the command (defined as a caddr_t structure)
487
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
488
21 Integrating a New Network Interface Driver
21.7 Understanding NPT Driver Implementation
NOTE: The design situations that require an NPT driver instead of an END are
rare. If you are writing a new driver, think first of implementing it as an END, for
which there exists a template as well as working driver implementations that you
can study. If porting a packet-oriented driver, feel free to port it as an NPT driver.
The Wind River Network Stack supports mixing the two driver styles.
NOTE: For instructions on starting additional drivers at run-time, see 20.2 Working
with Network Driver Instances, p.432.
489
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Adding your driver is much like adding any other application to a target image.
The first step is to compile and include the driver code in the image.
Because the Wind River Network Stack allows you to create more than one
network device, you must set up a table that groups the #define configuration
statements for these devices into device-specific groups. This table, endDevTbl, is
defined in the configNet.h file in your target/config/bspname directory where
bspname is the name of your board support package, such as mv162 or pc486. For
example, to add an ln7990 NPT driver, edit configNet.h to contain lines such as:
/* Parameters for loading ln7990 NPT driver supporting buffer loaning. */
#define LOAD_FUNC_0 ln7990nptLoad
#define LOAD_STRING_0 "0xfffffe0:0xffffffe2:0:1:1"
#define BSP_0 NULL
Define three constants, like those shown above, for each of the devices you want to
add. To set appropriate values for these constants, consider the following:
LOAD_FUNC
Specifies the name of your driver’s nptLoad( ) entry point. For example, if your
driver’s nptLoad( ) entry point were ln7990nptLoad( ), you would edit
configNet.h to include the line:
#define LOAD_FUNC_n ln7990nptLoad
LOAD_STRING
Specifies the initialization string passed into muxDevLoad( ) as the initString
parameter. This string contains information that is passed blindly to the
driver’s nptLoad( ) routine. Its contents depend on what the driver expects.
You must also edit the definition of the endDevTbl (a table in configNet.h that
specifies the drivers included in the image) to list the devices to be loaded:
END_TBL_ENTRY endDevTbl [] =
{
{ 0, LOAD_FUNC_0, LOAD_STRING_0, BSP_0, NULL, FALSE },
{ 1, LOAD_FUNC_1, LOAD_STRING_1, BSP_1, NULL, FALSE },
...
{ 0, END_TBL_END, NULL, 0, NULL, FALSE },
};
The first number in each table entry specifies the unit number for the device. The
first entry in the example above specifies a unit number of 0. Thus, the device it
loads is deviceName0. The FALSE at the end of each entry indicates that the entry
has not been processed. After the system successfully loads a driver, it changes this
value to TRUE in the run-time version of this table. To prevent the system from
automatically loading your driver, set this value to TRUE.
490
21 Integrating a New Network Interface Driver
21.7 Understanding NPT Driver Implementation
After constructing these entries in configNet.h, you are ready to rebuild the
Wind River Network Stack to include your new drivers. When you boot this
rebuilt image, the system calls muxDevLoad( ) for each device specified in the
table in the order listed.
NOTE: The endDevTbl[ ] can contain a mix of NPT drivers and ENDs.
At system startup, the Wind River Network Stack spawns the user root task to
initialize the network. The task calls muxDevLoad( ), which calls the nptLoad( )
routine in your driver. The nptLoad( ) routine creates and partially populates an
END_OBJ structure and a NET_FUNCS structure. The END_OBJ structure describes
the driver to the MUX. The NET_FUNCS structure provides the MUX with
references to the MUX-callable driver routines.
After muxDevLoad( ) loads your driver, a muxDevStart( ) call executes the
nptStart( ) routine in your driver. The nptStart( ) routine should activate the driver
and register an interrupt service routine for the driver with the appropriate
interrupt connect routine for your architecture and BSP.
A driver is not required to respond when a service binds to a device. If you want
your driver to respond to a bind event, your driver can support an nptBind( )
routine. When a service binds to an interface controlled by your driver, the MUX
uses the driver’s nptIoctl( ) routine to retrieve a pointer to that driver’s nptBind( )
routine (if any). The MUX then executes that routine before continuing with the
bind.
21
To get a pointer to a driver’s nptBind( ), the MUX issues an EIOCQUERY command
to the driver’s nptIoctl( ) routine. As input, the call supplies an END_QUERY
structure whose members are used as follows:
query
Set by MUX to END_BIND_QUERY.
queryLen
Set by MUX to the expected size of the data in queryData.
queryData
Set by your driver’s nptIoctl( ) to point to the driver’s nptBind( ).
491
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Receiving Frames
When an interrupt is received, the Wind River Network Stack invokes the
interrupt service routine that was registered by the nptStart( ) routine. This
interrupt service routine should do the minimum amount of work necessary to
transfer the frame from the local hardware into accessible memory (ideally a
cluster: see 21.3.3 The Data-Link-to-MUX Interface, p.461).
To minimize interrupt lockout time, the routine should handle at interrupt level
only those tasks that require minimum execution time, such as error checking or
device status change. The routine should queue all time-consuming work for
processing at task level.
To queue frame reception work for processing at the task level, use the
netJobAdd( ) routine. This routine takes a routine pointer and up to five additional
arguments (representing parameters to the routine referenced by the routine
pointer). The netJobAdd( ) routine prototype is:
STATUS netJobAdd
(
FUNCPTR routine,
int param1,
int param2,
int param3,
int param4,
int param5
)
The routine in this case should be the routine in your driver that completes frame
processing at the task level. The netJobAdd( ) routine puts the job request on
tNetTask’s work queue and gives the appropriate semaphore that awakens
tNetTask.
Upon awakening, tNetTask dequeues routine calls and associated arguments
from its work queue. It then executes these routines in its context until the queue
is empty.
Your task-level frame reception routine should do whatever is necessary to
construct an mBlk chain containing the frame to hand off to the MUX, such as
assuring data coherency. This routine should also set M_MCAST and M_BCAST
flags in the mBlk header if appropriate. When all is ready, your driver passes the
frame up to the MUX by calling the routine referenced as the receiveRtn field of
the END_OBJ structure representing your device.
492
21 Integrating a New Network Interface Driver
21.7 Understanding NPT Driver Implementation
To deliver a packet to the stack, NPT driver's receive routine calls a function
pointer set by the MUX, using the TK_RCV_RTN_CALL( ) macro defined in
endLib.h. This macro takes arguments as if it were a routine declared just like
muxTkReceive( ). See sections 21.4 How ENDs and NPT Drivers Differ, p.462, and
B.2.23 muxTkReceive( ), p.590, for more information on the arguments passed to
this routine.
This subsection describes the driver entry points and the shared data structures
that comprise the NPT driver’s interface to the MUX.
The core data structure for an NPT driver is the END object, or END_OBJ. The
structure is defined in target/h/end.h (see also B.3.3 END_OBJ, p.594). The driver’s
load routine returns a pointer to an END_OBJ that it allocated, zeroed out, and
partially populated. This structure supplies the MUX with information that
describes the driver as well as a pointer to a NET_FUNCS structure populated with
references to the NPT’s standard entry points.
Although the driver’s load routine is responsible for populating much of the
END_OBJ structure, some of its members are set within the MUX when a protocol
binds to the device. Specifically, the MUX maintains the array of protocols bound
to the END_OBJ. When the driver calls its registered receive routine (usually an
indirect call to muxTkReceive( ) for an NPT driver), this routine calls the bound
protocol receive routines appropriate for the received packet.
Table 21-3 lists the standard driver entry points that the NET_FUNCS structure
exports to the MUX. In this manual, the routines use a generic “npt” prefix, but in
practice this prefix is usually replaced with a driver-specific identifier, such as
"ln7990" for the Lance Ethernet driver.
493
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Routine Description
nptLoad( ) Load a device into the MUX and associate a driver with
the device.
nptSend( ) Accept data from the MUX and send it on to the physical
layer.
nptLoad( )
Before you can use a network interface to send and receive frames, you must load
the appropriate device driver into the MUX and then configure that driver for the
interface. The user root task loads network device drivers into the MUX by calling
muxDevLoad( ) for all the drivers referenced in endDevTbl[ ]. The entries in this
table provide all the information needed to call muxDevLoad( ). This includes the
actual name of your driver’s nptLoad( ) routine.
494
21 Integrating a New Network Interface Driver
21.7 Understanding NPT Driver Implementation
As input, the nptLoad( ) routine takes an initialization string. The contents of this
string are user-defined but generally include such items as the unit number
identifying the physical interface8, an interrupt vector number, and the address of
memory mapped registers.
You must write your nptLoad( ) routine as a two-pass algorithm. The MUX calls it
twice during the load procedure. In the first pass, it calls your nptLoad( ) routine
using a blank (all zeros) initialization string. Your nptLoad( ) routine is expected to
check for the blank string and return with the name of the device copied into the
string.
The MUX then calls your nptLoad( ) a second time using the actual initialization
string that was supplied to muxDevLoad( ). Your nptLoad( ) routine must then
return a pointer to the END_OBJ that it allocates, or a NULL if the load fails.
Typically, the nptLoad( ) routine, in its second pass, does the following:
■ Initialize the device and interface.
■ Allocate, zero out, and fill the END_OBJ structure.
■ Initialize any necessary private structures.
■ Parse and process the initialization string.
■ Create and initialize a private pool of memory using the API in netBufLib.
■ Allocate one or more network buffer pools using netBufLib.
■ Create and populate the MIB II interface table.
■ Fill the NET_FUNCS table referenced by pNetFuncs in the END_OBJ structure.
The nptLoad( ) routine is based on the following skeleton:
END_OBJ * nptLoad
(
char * initString, /* defined in endTbl */
void * pBsp /* BSP-specific information (optional) */
)
{
END_OBJ * newEndObj;
if( !initString ) /* initString is NULL, error condition */ 21
{
/* set errno perhaps */
return ((END_OBJ *) ERROR);
}
8. Although a driver is only loaded once, the driver’s nptLoad( ) routine is called for
each port to be activated within the driver. This lets the MUX allocate an entry for
each port. The MUX interface does not impose restrictions on how drivers handle
multiple ports as long as the driver allocates a separate END_OBJ for each port.
495
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
nptUnload( )
The MUX calls your driver’s nptUnload( ) when a system application calls
muxDevUnload( ). In its nptUnload( ), your driver is responsible for doing
whatever it takes to “release” the device. It should also free the memory allocated
for the END object.
The MUX calls your driver’s nptUnload( ) for each port that has been activated by
a call to the driver’s nptLoad( ). If the device has loaded multiple ports, the driver’s
nptLoad( ) must not free up any shared resources until an unload request has been
received for each of the loaded ports.
The nptUnload( ) routine does not need to notify services about unloading the
device. Before calling nptUnload( ), the MUX first sends a shutdown notice to each
service attached to the device.
The nptUnload( ) prototype is:
STATUS nptUnload
(
END_OBJ * pEND /* END object */
)
nptBind( )
The nptBind( ) routine is an optional driver routine that gives your driver the
ability to respond to bind events. Using nptBind( ), your driver can support the
exchange of information between a service and a driver whenever the service
binds to a device through that driver.
496
21 Integrating a New Network Interface Driver
21.7 Understanding NPT Driver Implementation
The MUX calls your driver’s nptBind( ) routine (if any), in response to bind events
through that driver. To get an executable reference to a driver’s nptBind( ) routine,
the MUX uses the driver’s nptIoctl( ) routine.
The MUX calls nptBind( ) while processing a bind request from the network
service. Arguments passed to nptBind( ) include:
■
a reference to information supplied by the network service
(although the network service may choose to supply no information at all)
■ a reference to a template for network driver information
(if your driver cares to provide any)
■ the network service type
The routine is expected to return OK if the bind request is accepted. The driver may
also reject the bind request by returning ERROR, in which case the MUX will deny
the bind request to the network service.
The nptBind( ) prototype is:
STATUS nptBind
(
END_OBJ * pEND, /* END object */
void * pNetSvcInfo, /* info provided by the network service */
void * pNetDrvInfo, /* template for network driver info */
long type /* of network service trying to bind */
)
nptSend( )
The network driver send routine is referenced from the NET_FUNCS table. The
MUX calls this routine when the network service issues a send request. The send
routine is supplied a reference to an mBlk chain representing the packet to be sent.
This routine should prepend the link-level header to the packet (for information on
making this more efficient, see 21.4.3 Early Link-Level Header Allocation in an NPT
Driver, p.465). 21
The nptSend( ) prototype is:
STATUS nptSend
(
END_OBJ * pEND, /* END object */
M_BLK_ID pMblk, /* network packet to transmit */
char * dstAddr, /* destination MAC address */
int netSvcType, /* network service type */
void * pSpare /* optional network service data */
)
497
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
nptMCastAddrAdd( )
This routine should return a status OK or ERROR (in which case, errno should be
set appropriately).
nptMCastAddrDel( )
This routine removes a previously registered multicast address from the list
maintained for a device. It takes as arguments a pointer to the END_OBJ structure
returned by nptLoad( ), and a string containing the physical address to be removed
or a reference to that address.
The nptMCastAddrDel( ) prototype is:
STATUS nptMCastAddrDel
(
END_OBJ * pEND, /* END object */
char * pAddress /* physical address, or a reference to it */
)
This routine should return a status OK or ERROR (in which case, errno should be
set appropriately).
498
21 Integrating a New Network Interface Driver
21.7 Understanding NPT Driver Implementation
nptMCastAddrGet( )
This routine retrieves a list of all multicast addresses that have been registered
with the device. It takes as arguments a pointer to the END_OBJ structure returned
by nptLoad( ), and a pointer to a MULTI_TABLE structure into which the list will
be put.
The nptMCastAddrGet( ) prototype is:
STATUS nptMCastAddrGet
(
END_OBJ * pEND, /* END object */
MULTI_TABLE * pMultiTable /* container for address list */
)
This routine should return a status OK or ERROR (in which case, errno should be
set appropriately).
nptPollSend( )
NOTE: Poll mode should only be used for debugging. For details, see Polled Mode,
p.456.
NOTE: When the system calls your nptPollSend( ) routine, it is probably in a mode
that cannot service kernel calls. Therefore, this routine must not perform any
kernel operations, such as taking a semaphore or allocating memory. Likewise, this
routine should not block or delay because the entire system might halt.
Within your nptPollSend( ) routine, verify that the device has been set to
polled-mode (by a previous nptIoctl( ) call). Your nptPollSend( ) routine should
then put the outgoing packet directly onto the network, without queuing the 21
packet on any output queue.
This routine takes as arguments a pointer to the END_OBJ structure returned by
nptLoad( ), a reference to an mBlk or mBlk chain containing the outgoing packet,
a pointer to a buffer containing the destination MAC address, the network service
type (in network byte order), and a pointer to optional additional data (or NULL).
Like the nptSend( ) routine, the nptPollSend( ) routine must add the link header.
However, it should not modify the M_BLK chain, which is owned by the caller.
Because the poll send routine is a low-performance interface used primarily for the
WDB connection, the driver typically copies the data contents of the passed mBlk
chain into a separate contiguous buffer following the constructed MAC header.
499
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
nptPollReceive( )
This routine receives frames using polling instead of an interrupt-driven model.
The routine retrieves the frame directly from the network and copies it into the
provide mBlk passed to the routine. If no frame is available, it returns ERROR.
Within the nptPollReceive( ) routine, verify that the device has been set to
polled-mode (by a previous nptIoctl( ) call). The routine should then retrieve the
frame directly from the network and copy it into the mBlk passed in to the routine.
It takes as arguments a pointer to the END_OBJ structure returned by nptLoad( )
and a reference to an mBlk or mBlk chain into which the incoming data should be
put, as well as information about the frame type and the offset within the packet
to the network frame.
The nptPollReceive( ) prototype is:
STATUS nptPollReceive
(
END_OBJ * pEND, /* END object */
M_BLK_ID pMblk, /* received frame */
long * pNetSvc, /* payload/network frame type */
long * pNetOffset, /* offset to network frame */
void * pSpareData /* optional network service data */
)
This routine should return OK or an error value of EAGAIN if the received data is
too large to fit in the provided mBlk, or if no data is available.
500
21 Integrating a New Network Interface Driver
21.7 Understanding NPT Driver Implementation
nptStart( )
The driver’s nptStart( ) routine connects device interrupts and makes the interface
active and available. This routine takes as its argument the END_OBJ structure
pointer returned from the nptLoad( ) call. As with nptLoad( ), this call is made for
each port that is to be activated within the driver.
The nptStart( ) prototype is:
STATUS nptStart
(
END_OBJ * pEND, /* END object */
)
This routine should return a status OK or ERROR (in which case, errno should be
set appropriately).
nptStop( )
This routine should return a status OK or ERROR (in which case, errno should be
set appropriately).
nptIoctl( )
An NPT driver must support the ioctl command defined as EIOCGNPT. This
command is used to determine if the driver is of the NPT variety. All the driver 21
needs to do upon receiving this command is to return 0 (zero), indicating success.
For other drivers, this ioctl command is undefined and therefore returns EINVAL,
indicating that it is not an NPT driver.
Like an END driver, an NPT driver should support the EIOCGMIB2 and
EIOCGMIB2233 commands by calling the endM2Ioctl( ) routine.
An NPT driver may also need to support other ioctl commands, particularly if it is
to be used with the existing IP network service sublayer. See Table 21-4 for a list of
commonly used ioctl commands.
501
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
502
21 Integrating a New Network Interface Driver
21.7 Understanding NPT Driver Implementation
! WARNING: If you are porting a driver from the BSD 4.3 model, you might be
tempted to use the existing xxIoctl( ) routine as your nptIoctl( ) routine, skipping
the creation of separate routines for the multicast address table maintenance
routines. Do not do this! Your driver must implement the multicast address table
maintenance routines.
503
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Under the MUX, each device is independent. Your BSD model may consider each
device to be part of an array of devices, each with a unit number. BSD driver
routines are sometimes written to take unit numbers as parameters, and to
distinguish between devices based on these unit numbers. In the MUX model, the
END Object is the distinguishing feature of devices, and MUX routines distinguish
between devices based on the END Object pointer that is passed in to the routines.
The head of your driver control object should be an END_OBJ structure that
includes all hardware- and driver-specific elements.
The END and NPT models for network interface drivers contain standard entry
points that are not present in the BSD model. Table 21-5 shows some of the
analogies. You should be able to reuse much of the code from the BSD driver.
! CAUTION: When porting a BSD network driver to the MUX, you must replace all
calls into the protocol with appropriate calls into the MUX. In addition, you must
remove all code that implements or uses etherInputHook( ) or
etherOutputHook( ) routines.
504
21 Integrating a New Network Interface Driver
21.8 Porting a BSD Driver to the MUX
xLoad( ) xxattach( )
N/A xxReceive( )
xSend( ) xxOutput( )
xIoctl( ) xxIoctl( )
505
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Because the MUX does not directly call the driver’s packet reception code, there is
no npt/endReceive( ) entry point. Your driver still needs to handle packet reception
at the task level. Unfortunately, most of the code in this driver routine will require
extensive revision. Instead of calling the service directly, this routine uses a
MUX-supplied routine to pass a packet up to the service. Likewise, your receive
routine should use a MUX-managed memory pool as its receive buffer area.
Rewrite the interface of your output routine to match the npt/endSend( ) entry
point described in nptSend( ), p.497 or endSend( ), p.481.
Much of the code that dealt directly with putting the packet on the hardware
should need little if any revision. You should change your code to use mBlk chains
allocated out of a netBufLib-managed memory pool. See the reference entry for
netBufLib for details.
506
21 Integrating a New Network Interface Driver
21.9 Supporting Multiple Network Interface Drivers
Table 21-5 lists a handful of driver points unique to ENDs and NPT drivers. Both
an END and an NPT require you to implement the xSend( ), xStart( ), and xStop( )
entry points. There are no BSD equivalents for these entry points. In addition, if
you are implementing an END, you must implement entry points for
endAddressForm( ), endAddrGet( ), and endPacketDataGet( ). These routines are
already implemented for Ethernet in endLib. If your driver will run over Ethernet,
you may use the routines supplied in endLib.
To configure the Wind River Network Stack to support multiple drivers, make 21
sure that the drivers are compiled into your image. Follow the directions in Adding
an NPT Driver, p.490 (for an NPT driver) or Adding an END, p.473 (for an END).
You may also need to increase the value of the configuration parameters
IP_MAX_UNITS and MUX_MAX_BINDS.
9. Some BSPs and drivers may have their own limitations on the number of interfaces and
units they support.
507
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
To separate out each aspect of the global up shown above, you would need to
do the following:
-> ifconfig "fei0 link up"
-> ifconfig "fei0 inet up"
-> ifconfig "fei0 inet6 up"
508
21 Integrating a New Network Interface Driver
21.10 Avoiding Memory Leaks
If you do not want to bring up both the IPv4 and IPv6 functionality for the
interface, omit the inet up or inet6 up calls as needed.
8. Check that the interface was loaded and configured correctly:
■
ifShow( ) – list configuration information for network devices
■
routec( ) – check that the routing table has an entry for the device
NOTE: For information on the exact inputs expected by the routines named above,
see the relevant reference entries.
21
10. Note that endObjInit( ) is an actual routine defined in endLib.c. It is not an END entry
point, which would have been indicated as endObjInit( ).
509
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
510
22
Integrating a New Network
Service
22.1 Introduction
This chapter describes how to integrate a new network service with Wind River
Network Stack. A network service, such as a network protocol, is an
implementation of the network and transport layers of the OSI network model.
As shown in Figure 21-1, network services communicate with the data link layer
through the MUX interface. Part of porting a new network service to the
Wind River Network Stack is porting its data link layer access code to use the MUX
interface. Everything specific to the network interface is handled in the drivers of
the data link layer, which are described in 21. Integrating a New Network Interface
Driver.
NOTE: Currently, well-known service port numbers and other such information is
hard coded in services.c. There is no API that you can use to add information to
this file for the new services that you create.
511
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
When the system constructs the network stack, it activates network interfaces that
include a network service and a network driver. The activation routine that you
provide in your network service sublayer, by convention, is named fooAttach( ),
where foo is replaced by an abbreviation for the network service. This naming
convention is a generalization based on the name of ipAttach( ). Your fooAttach( )
routine typically allocates and initializes data structures that represent the
interface being attached to, determines the network driver paradigm (END or
NPT), and binds to the driver interface through the MUX.
The network service must bind to a driver before it can send and receive packets
through it. Binding to a network driver is accomplished by calling the
muxTkBind( ) routine (see B.2.19 muxTkBind( ), p.586).
The protocol type supplied to the bind routine is used by the MUX to prioritize the
services, and determines which service sees which packets. A
MUX_PROTO_SNARF type service sees all the packets that are processed by any
driver to which it is bound. A MUX_PROTO_PROMISC type service sees a packet
only after all other services bound to a driver have had a chance to consume it. A
MUX_PROTO_OUTPUT type service sees outgoing rather than incoming packets.
512
22 Integrating a New Network Service
22.2 Writing a Network Service Sublayer
After the bind operation has completed successfully, the sublayer should
determine which (if any) registered service address mapping routines are relevant
to the network interface. The sublayer should obtain references to those that apply
and retain these references for later use within the interface.
The network service sublayer may allocate buffer pools in the form of mBlk
clusters for receiving and sending packets. The network buffer management 22
library netBufLib facilitates the implementation of an effective scheme for this
purpose. The sublayer may also make use of the system mBlk pools. For details,
see 21.4.1 Managing Memory for Network Drivers and Services, p.464, and
3. Configuring and Managing Memory.
Other resources commonly used by network services include receive/transmit
queues and data structures that represent each active network interface controlled
by the sublayer. Data that should be collected and maintained for each interface
includes:
513
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
■
the network driver’s paradigm
■
the state of the interface (for instance: attached, stopped, flow-controlled)
■
the cookie supplied by the MUX, this cookie identifies the binding instance
■
references to the service address mapping routines for the interface
Sending Packets
Network layer packets are sent down through the MUX by using the
muxTkSend( ) routine (see B.2.24 muxTkSend( ), p.591). Data to be sent arrives
from an upper layer in the form of an mBlk chain, and is modified by your
network service before being sent.
The muxTkSend( ) routine may return an error indicating that the driver is out of
resources and cannot transmit the packet. A network service can use this error to
establish a flow control mechanism (see Flow Control, p.516).
Sending packets through an END requires that the mBlk chain being sent contains
fully formed physical layer frames. If necessary, a protocol must use the address
resolution routine registered for the interface to determine the destination address,
and then use the muxAddressForm( ) routine to add the necessary frame header
to the packet.
When sending packets through an NPT driver, if the interface over which packets
are being sent has a registered address resolution routine, it should be called at
send-time and the resolved address should be passed into muxTkSend( ).
514
22 Integrating a New Network Service
22.2 Writing a Network Service Sublayer
Receiving Packets
Error Reporting
515
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Flow Control
Device Control
1. Some less-carefully written drivers may simply return ERROR in this case, and it would not
be possible for your service to determine whether this was due to a temporary problem such
as insufficient resources or a more serious problem.
516
22 Integrating a New Network Service
22.3 Interfacing with the MUX
This section describes the four service routines referenced in a muxTkBind( ) call.
stackShutdownRtn( )
This routine is typically called by the MUX when it has received a call to
muxDevUnload( ) for a specific network device. Before unloading the driver,
every network service bound to that device is issued a shutdown message by
calling the stackShutdownRtn( ) routine registered for that service.
Within this routine, the network service must call muxUnbind( ) to release itself
from the device, and it should bring itself to an orderly halt.
The stackShutdownRtn( ) prototype is:
STATUS stackShutdownRtn
(
void * netCallbackId /* the handle/ID installed at bind time */
)
stackRcvRtn( )
The MUX forwards packets received by the driver to the protocol layer by using
the stackRcvRtn( ) callback that was installed with muxTkBind( ). This routine
receives:
■ a pointer to an mBlk chain containing the incoming packet
■ the callback ID specific to the binding instance of the service/driver pair
■ a network service type
■ a pointer to additional data, the format of which, and the need for which,
depends on the requirements of the driver
The stackRcvRtn( ) prototype is:
BOOL stackRcvRtn
( 22
void * netCallbackId, /* the handle/ID installed at bind time */
long type, /* network service type */
M_BLK_ID pNetBuf, /* network service datagram */
void * pSpareData /* pointer to optional data from driver */
)
If a network protocol accepts the frame by returning TRUE, it must free the given
mBlk chain when processing is complete.
517
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
stackErrorRtn( )
Error conditions encountered by a driver are passed to the network service when
the MUX calls stackErrorRtn( ). It is up to the network service to take the necessary
action upon receiving the error.
This routine takes two arguments: the callback identifier supplied to the service at
bind-time, and a pointer to an END_ERR structure that describes the error (see
B.3.2 END_ERR, p.594).
The stackErrorRtn( ) prototype is:
void stackErrorRtn
(
void * netCallbackId, /* the handle/ID installed at bind time */
END_ERR * pError /* pointer to structure containing error */
)
stackRestartRtn( )
This routine is called by the MUX to restart network services that had previously
stopped, perhaps because muxTkSend( ) had returned an error indicating that the
network service should wait before transmitting more packets.
When the device has determined that it has enough resources to resume
transmission, it will indicate this to the MUX, which will then call
stackRestartRtn( ).
This routine takes a single argument: the identifier specific to the service/driver
pair that was supplied at bind-time.
The stackRestartRtn( ) prototype is:
STATUS stackRestartRtn
(
void * netCallbackId /* the handle/ID installed at bind time */
)
These routine prototypes are included in this chapter to help people maintaining
network services that were designed to work with muxBind( ), which predated the
NPT. If you are designing a new network service, implement the routines
associated with muxTkBind( ).
518
22 Integrating a New Network Service
22.3 Interfacing with the MUX
stackENDShutdownRtn( )
This routine is typically called by the MUX when it has received a call to
muxDevUnload( ) for the specified network interface. Before unloading the END,
every network service bound to that END’s device is issued a shutdown message
by calling the stackENDShutdownRtn( ) routine registered for the interface at bind
time.
Within this routine, the network service must call muxUnbind( ) to release itself
from the device, and it should bring itself to an orderly halt.
The stackENDShutdownRtn( ) prototype is:
STATUS stackENDShutdownRtn
(
void * pEND, /* END_OBJ from the driver’s load routine */
void * pSpare /* defined on a per-service basis */
)
stackENDRcvRtn( )
The MUX forwards packets received by the END to the protocol layer by using the
stackENDRcvRtn( ) callback that is installed with muxBind( ). The pNetBuff
contains the entire driver-level frame, and pLinkHdr contains information about
offsets to the network payload in the frame.
The stackENDRcvRtn( ) prototype is:
BOOL stackENDRcvRtn
(
void * pCookie, /* returned by muxBind() */
long type, /* from RFC 1700, or user-defined */
M_BLK_ID pNetBuff, /* packet with link-level info */
LL_HDR_INFO * pLinkHdr, /* link-level header info structure */
void * pCallbackId /* registered by the network svc with MUX */
)
If a network protocol accepts the frame by returning TRUE, it must free the given
mBlk chain when processing is complete.
22
stackENDErrorRtn( )
Error conditions encountered by an END are passed to the network service when
the MUX calls stackENDErrorRtn( ). It is up to the network service to take the
necessary action upon receiving the error.
This routine takes three arguments: the callback identifier supplied to the service
at bind-time, a pointer to an END_ERR structure, and the spare data, if any, defined
for the service during the bind phase.
519
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
stackENDRestartRtn( )
This routine is called by the MUX to restart network services that had previously
stopped, perhaps because muxTkSend( ) had returned an error indicating that the
network service should wait before transmitting more packets.
When the device has determined that it has enough resources to resume
transmission, it will indicate this to the MUX, which will then call
stackENDRestartRtn( ).
This routine takes a single argument: the identifier specific to the service/driver
pair that was supplied at bind-time.
The stackENDRestartRtn( ) prototype is:
STATUS stackENDRestartRtn
(
void * pEND, /* END_OBJ passed to the MUX by the driver */
void * pSpare, /* defined on a per-service basis */
)
520
22 Integrating a New Network Service
22.4 Adding a Socket Interface to Your Service
The standard socket interface is designed so that socket back ends for multiple
protocol layer implementations can be used simultaneously. A layered
architecture makes this possible. The Wind River standard socket interface is a
layer above your back end socket layer, as shown in Figure 22-1.
This chapter introduces the process of implementing a socket back end.
An application makes
standard socket calls.
MUX
22
Socket calls made by an application are directed to the correct underlying socket
back end based on the domain parameter that is passed to the socket( ) call when
the application creates the socket. If this parameter matches the domainReal
parameter that you use when you add your new socket back end with the
sockLibAdd( ) routine, the socket calls are directed to your back end.
521
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
When you register your socket back end, you give the system a table that is filled
with references to socket routines that you have created to support your
implementation (see The Socket Functional Interface, p.522). The system is then able
to support standard socket calls that are made using your back end.
To provide a socket back end requires that you implement socket functionality for
your service and that you make the system aware of this new sockets
implementation. The following sections show how this is done.
NOTE: You need not support all possible socket routines. A user application
calling a non-supported routine in your socket back end (indicated by a NULL
pointer in the SOCK_FUNC table) returns ENOTSUP to the calling application.
522
22 Integrating a New Network Service
22.4 Adding a Socket Interface to Your Service
Use the sockLibAdd( ) routine to add new socket functionality to the system’s list
of socket implementations. As input, this routine expects a reference to the
usrSockLibInit( ) routine and the domain and service for which this socket
implementation is to be registered.
The routine returns OK, or ERROR if the socket back end could not be added.
523
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
This subsection provides implementation details for the routines you must supply
in a SOCK_FUNC structure:
typedef struct sockFunc /* SOCK_FUNC */
{
FUNCPTR libInitRtn; /* sockLibInit() */
FUNCPTR acceptRtn; /* accept() */
FUNCPTR bindRtn; /* bind() */
FUNCPTR connectRtn; /* connect() */
FUNCPTR connectWithTimeoutRtn; /* connectWithTimeout() */
FUNCPTR getpeernameRtn; /* getpeername() */
FUNCPTR getsocknameRtn; /* getsockname() */
FUNCPTR listenRtn; /* listen() */
FUNCPTR recvRtn; /* recv() */
FUNCPTR recvfromRtn; /* recvfrom() */
FUNCPTR recvmsgRtn; /* recvmsg() */
FUNCPTR sendRtn; /* send() */
FUNCPTR sendtoRtn; /* sendto() */
FUNCPTR sendmsgRtn; /* sendmsg() */
FUNCPTR shutdownRtn; /* shutdown() */
FUNCPTR socketRtn; /* socket() */
FUNCPTR getsockoptRtn; /* getsockopt() */
FUNCPTR setsockoptRtn; /* setsockopt() */
FUNCPTR zbufRtn; /* ZBUF support */
All socket back-ends must provide non-null function pointers for closeRtn,
readRtn, writeRtn, and ioctlRtn. If a back end does not want to support read,
write, and ioctl, it can return ERROR from these routines. Support for close is
required. The entry point descriptions below are in the same order as the structure
members listed above.
524
22 Integrating a New Network Service
22.4 Adding a Socket Interface to Your Service
usrSockLibInit( )
The usrSockLibInit( ) routine should install the socket back end as a driver within
the Wind River Network Stack I/O system by calling iosDrvInstall( ), and then
should return a pointer to a SOCK_FUNC structure.
The iosDrvInstall( ) routine takes pointers to seven socket routines, four of which
must be supported by a socket back end: usrSockClose( ), usrSockRead( ),
usrSockWrite( ) and usrSockIoctl( )2. The iosDrvInstall( ) returns a driver
number, which should be stored by the socket back end.
Your usrSockLibInit( ) routine, which should be declared public, can be based on
the following skeleton:
SOCK_FUNC * usrSockLibInit (void)
{
/* install driver for socket */
int driverNum = iosDrvInstall( (FUNCPTR) NULL, (FUNCPTR) NULL,
(FUNCPTR) NULL, (FUNCPTR) usrSockClose,
(FUNCPTR) usrSockRead, (FUNCPTR) usrSockWrite),
(FUNCPTR) usrSockIoctl) );
if( driverNum == ERROR ) return( (SOCK_FUNC *) NULL );
/* Store driverNum somewhere convnient for future reference */
/* Initialize SOCK_FUNC table */
SOCK_FUNC * usrSockFuncs = (SOCK_FUNC *) malloc(sizeof(SOCK_FUNC));
if( !usrSockFuncs )
{
errno = ENOMEM;
return( (SOCK_FUNC *) NULL );
}
usrSockFuncs->libInitRtn = (FUNCPTR) usrSockLibInit;
usrSockFuncs->acceptRtn = (FUNCPTR) usrSockAccept;
/* and so forth... */
usrSockFuncs->setsockoptRtn = (FUNCPTR) usrSockSetSockOpt;
usrSockFuncs->zbufRtn = (FUNCPTR) usrSockZbufRtn;
usrSockFuncs->closeRtn = (FUNCPTR) usrSockCloseRtn;
return (usrSockFuncs);
}
usrSockAccept( )
22
This routine accepts a connection on a socket and returns a file descriptor
representing the new socket created for the connection. Typically for this routine
to succeed, the socket represented by fd must have been previously bound to an
address with usrSockBind( ) and enabled for connections by a call to
usrSockListen( ). When usrSockAccept( ) is called, addr should be an available
buffer, and addrlen should indicate the size of the buffer.
2. The others may be skipped as NULL pointers. For more information on these essential
routines, see Socket Routines Passed to iosDrvInstall( ), p.534.
525
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The usrSockAccept( ) routine will block the caller until a connection is present,
unless the socket has been explicitly marked as non-blocking.
The usrSockAccept( ) routine is of the form:
int usrSockAccept
(
struct socket ** pSo, /* pointer to pointer of parent socket */
struct sockaddr * addr, /* peer address */
int * addrlen /* peer address length */
)
This routine returns a file descriptor representing a new socket with the same
properties as the one represented by fd (or ERROR if the accept fails). In addition,
on a successful return, addr should be filled with the address of the machine
making the connection, and addrlen should be set to the length of that address.
usrSockBind( )
usrSockConnect( )
This routine initiates a connection between a socket, fd, and another socket, which
is specified by name.
The usrSockConnect( ) routine is of the form:
STATUS usrSockConnect
(
struct socket * so, /* socket pointer */
struct sockaddr * name, /* addr of socket to connect */
int namelen /* length of name, in bytes */
)
526
22 Integrating a New Network Service
22.4 Adding a Socket Interface to Your Service
usrSockConnectWithTimeout( )
This routine tries to initiate a connection between socket, fd, and the socket
specified by name, for a duration specified by timeout, reporting an error if it cannot
do so in the time required. If timeout is NULL, this routine should act exactly like
usrSockConnect( ).
The usrSockConnectWithTimeout( ) routine is of the form:
STATUS usrSockConnectWithTimeout
(
struct socket * pSo, /* socket pointer */
struct sockaddr *adrs, /* addr of the socket to connect */
int adrsLen, /* length of the socket, in bytes */
struct timeval *timeVal /* time-out value */
)
This routine returns OK, or ERROR if the connection is not made in time.
usrSockGetpeername( )
This routine gets the name of the peer connected to the socket fd, placing this name
in the sockaddr structure of length namelen that was passed in.
The usrSockGetpeername( ) routine is of the form:
STATUS usrSockGetpeername
(
struct socket *so, /* socket descriptor */
struct sockaddr *name, /* where to put name */
int *namelen /* space available in name, later */
/* filled in with actual name size */
)
This routine should place the name of the peer in name and sets namelen to the size
of this name in bytes, then return OK, or ERROR if a name could not be retrieved
for the specified socket.
usrSockGetsockname( )
This routine gets the current name for the socket fd, placing this name in the 22
available sockaddr structure of size namelen that was passed in.
The usrSockGetsockname( ) routine is of the form:
STATUS usrSockGetsockname
(
struct socket *so, /* socket descriptor */
struct sockaddr *name, /* where to return name */
int *namelen /* space available in name, later */
/* filled in with actual name size */
)
527
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
This routine places the name of the socket in name and set namelen to the size of this
name in bytes, then returns OK, or ERROR if a name could not be retrieved for the
specified socket.
usrSockListen( )
This routine enables connections to a socket. The backlog parameter specifies the
maximum number of unaccepted connections that can be pending at any given
time. After enabling connections with usrSockListen( ), connections are actually
accepted by usrSockAccept( ).
The usrSockListen( ) routine is of the form:
STATUS usrSockListen
(
struct socket * so, /* socket pointer */
int backlog /* max number of unaccepted pending connections */
)
usrSockRecv( )
This routine receives data from a connection-based (stream) socket. How the flags
parameter should be set depends on the nature of the sockets involved and the
requirements of the connection. This will differ for different socket and service
implementations.
The usrSockRecv( ) routine is of the form:
int usrSockRecv
(
struct socket *so, /* socket to receive data from */
char *buf, /* buffer to write data to */
int bufLen, /* length of buffer */
int flags /* flags to underlying protocols */
)
NOTE: If the MSG_MBUF flag is set in the flags parameter, this means that a
zero-copy buffer (zbuf) is being received. A non-NULL mbuf ID is passed to the
back-end (that is, an mbuf ID structure is created). The mbuf ID will not point to
data.
The usrSockRecv( ) routine should set buf to point to the mbuf chain holding the
incoming data.
This routine returns the number of bytes received, or ERROR if the receive fails.
528
22 Integrating a New Network Service
22.4 Adding a Socket Interface to Your Service
usrSockRecvFrom( )
NOTE: If the MSG_MBUF flag is set in the flags parameter, this means that a
zero-copy buffer (zbuf) is being received. In this case, the buf parameter is a pointer
to a NULL mbuf pointer and not the char * specified in the parameter list. In other
words, *buf = (struct mbuf *) NULL. The usrSockRecvFrom( ) routine should set buf
to point to the mbuf chain holding the incoming data.
If from is not NULL, the address of the sending socket is copied into it, and
pFromLen is set to the length of this address. This routine returns the number of
bytes received, or ERROR if the receive fails.
usrSockRecvMsg( )
This routine receives a message from a datagram socket. It may be used in place of
usrSockRecvFrom( ) to decrease the overhead of breaking down the
message-header structure in each message. How the flags parameter should be set
depends on the nature of the sockets involved and the requirements of the 22
connection. This will differ for different socket and service implementations.
The usrSockRecvMsg( ) routine is of the form:
int usrSockRecvMsg
(
struct socket * so, /* socket to receive from */
struct msghdr * pMsgHdr, /* the message header */
int flags /* flags describing nature of the data */
)
This routine returns the number of bytes received, or ERROR if the receive fails.
529
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
usrSockSend( )
This routine returns the number of bytes sent, or ERROR if the send fails.
usrSockSendto( )
This routine transmits data from the socket specified by fd to the datagram socket
specified by to. How the flags parameter should be set depends on the nature of the
sockets involved and the requirements of the connection. This will differ for
different socket and service implementations.
The usrSockSendto( ) routine is of the form:
int usrSockSendto
(
struct socket * so, /* socket to send to */
caddr_t buf, /* buffer with message to be sent */
int bufLen, /* length of this buffer */
int flags, /* flags describing nature of the data */
struct sockaddr * to, /* recipient's address */
int tolen /* length of the to structure */
)
This routine returns the number of bytes sent, or ERROR if the send fails.
usrSockSendMsg( )
530
22 Integrating a New Network Service
22.4 Adding a Socket Interface to Your Service
This routine returns the number of bytes sent, or ERROR if the send fails.
usrSockShutdown( )
This routine shuts down all, or part, of the connection-based socket fd. The how
value allows for some control over how this shutdown takes place if sends and
receives are still pending.
The usrSockShutdown( ) routine is of the form:
STATUS usrSockShutdown
(
struct socket * so, /* socket to shut down */
int how /* directs how shutdown proceeds when activity is pending */
)
This routine returns OK, or ERROR if the specified socket was invalid or could not
be shut down.
usrSocket( )
When you call socket( ), the standard socket interface searches for a back end that
corresponds to the domain parameter passed to socket( ). This domain parameter
must be the actual protocol family value. That is, it must match the domainReal
parameter passed to the sockLibAdd( ) that registered the socket back end for the
specified family.
If a back end is found for the domain, this triggers a call to the usrSocket( ) routine
from the SOCK_FUNC structure that was registered for that domain. In some
previous stack releases, domain could have been the domainMap value passed to
sockLibAdd( ), which might have differed from domainReal. In the current 22
implementation, sockLibAdd( ) ignores its domainMap parameter.
The usrSocket( ) routine should create a socket structure and then generate a new
file descriptor representing the socket by calling iosFdNew( ) with the address of
the new socket structure. Other back end routines will receive this file descriptor
as a reference, and will use it to retrieve the associated socket structure by calling
iosFdValue( ) with the file descriptor as an argument.
531
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The domain argument refers to the socket domain or address family the socket
belongs to (a particular back end may potentially be invoked for more than one
domain). The type argument can be used to further define the nature of the socket
(examples of types in the AF_INET domain include SOCK_STREAM, SOCK_RAW
and SOCK_DGRAM). The protocol argument refers to the protocol variety of the
socket (in the AF_INET_BSD back end, an example of a protocol variety is
IPPROTO_TCP).
The usrSocket( ) routine returns the file descriptor that was generated for the
socket, or ERROR if it was unable to open a socket.
usrGetSockOpt( )
This routine retrieves socket option values3 associated with a specified socket. To
find options set at the socket level, level is set to SOL_SOCKET. To find options set
for a particular service, level is set to the identifying number of that service. The
optval parameter points to an available buffer of size optlen. The buffer itself,
although passed in as a char *, is treated as a pointer to whatever data type or
structure is appropriate to the option being referenced.
The usrGetSockOpt( ) routine is of the form:
STATUS usrGetSockOpt
(
struct socket *so, /* socket */
int level, /* protocol level for options */
int optname, /* name of option */
char *optval, /* where to put option */
int *optlen /* where to put option length */
)
This routine fills optval with the setting of the specified option, and sets optlen to
the actual size of this value. The routine returns OK, or ERROR if it was unable to
retrieve a value for this option given these parameters.
532
22 Integrating a New Network Service
22.4 Adding a Socket Interface to Your Service
usrSetSockOpt( )
This routine sets the options associated with a socket4. To manipulate options at
the socket level, level is set to SOL_SOCKET. Otherwise, level is set to the service
number of the service for which the option is being set.
The usrSetSockOpt( ) routine is of the form:
STATUS usrSetSockOpt
(
struct socket * so, /* target socket */
int level, /* protocol level of option */
int optname, /* name of option being set */
char * optval, /* value the option is being set to */
int optlen /* length of the value field */
)
This routine returns OK, or ERROR if the request to set the socket option for the
specified socket fails.
usrSockZbufRtn( )
This routine returns TRUE if the back end supports the zero-copy interface (zbufs),
otherwise it returns FALSE. The usrSockZbufRtn( ) routine is of the form:
STATUS usrSockZbufRtn( )
usrSockClose( )
This routine is called by the I/O system to close a socket. It is also passed to the
iosDrvInstall( ) call in the initialization routine and is described below.
usrSockReadRtn( )
This routine is called by the I/O system to read a socket. It is also passed to the
iosDrvInstall( ) call in the initialization routine and is described below.
usrSockWriteRtn( )
This routine is called by the I/O system to write to a socket. It is also passed to the 22
iosDrvInstall( ) call in the initialization routine and is described below.
usrSockIoctlRtn( )
This routine, described below, is called by the I/O system to perform an ioctl call
on a socket and is passed to the iosDrvInstall( ) call in the initialization routine.
533
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
usrSockClose( )
The usrSockClose( ) routine is called by the I/O system to close a socket and is of
the form:
int usrSockClose
(
[socket structure] * so /* socket being closed */
)
usrSockRead( )
This routine returns the number of bytes read, or -1 if the read fails.
usrSockWrite( )
This routine returns the number of bytes written, or -1 if the write fails.
534
22 Integrating a New Network Service
22.4 Adding a Socket Interface to Your Service
usrSockIoctl( )
This routine returns a positive number whose value depends on the ioctl routine
being invoked, or -1 in the case of an error.
22
535
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
536
23
Working with the
802.1Q VLAN Tag
23.1 Introduction
This chapter tells you how to use the implementation of 802.1Q VLAN tagging for
VxWorks. It assumes that you are familiar with the principles and operations of
Layer 2 network services.
NOTE: 802.1Q VLAN tagging is available in the Wind River Platforms builds of the
network stack. The Wind River General Purpose Platform, VxWorks Edition, does
not support 802.1Q VLAN tagging.
537
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Previously, support for 802.1Q VLAN tagging was supplied by vlanTagLib. In the
current stack, the 802.1Q VLAN support is integrated with the network stack as
MUX-L2 functionality. You can access this functionality by any of the following
methods:
■
through the muxL2name( ) routines
■
through extensions to the socket interface
■ through a new pseudo interface that you can use to manage the VLAN as a
subnet
You can also access this functionality through vlanTagLib, but keep in mind that
vlanTagLib is now deprecated.
NOTE: Although the MUX provides functionality for managing packets tagged
with an 802.1Q tag header, it does not implement the IEEE 802.1P/Q protocols.
To assure that the components required for VLAN support are available when
configuring an image, you need to build the network stack code using the
following options:
■
-DSOCKET_VLAN builds the socket-based VLAN support into the socket
backend code.
■
-DSUBNET_VLAN builds in support for the FreeBSD-style VLAN
pseudo-interface for subnet-based VLAN support.
For information on building the network stack, see your Wind River Platforms
Getting Started.
538
23 Working with the 802.1Q VLAN Tag
23.3 Configuring VxWorks for 802.1Q VLAN Tagging
The INCLUDE_MUX_L2 component pulls in the MUX network interface library for
layer 2. Including this component initializes the MUX-L2 infrastructure for VLAN
support.
This component is automatically included when the INCLUDE_SUBNET_VLAN
component is included, and it requires the following configuration components:
■ INCLUDE_END
■
INCLUDE_ETHERNET
MUX_L2_MAX_VLANS_CFG
MUX_L2_NUM_PORTS_CFG 23
539
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Subnet-Based VLAN
L2Config
540
23 Working with the 802.1Q VLAN Tag
23.5 MUX Extensions for Layer 2 VLAN Support
TPID TCI
4 bytes (Tag Control
Tag Protocol
VLAN Tag Information)
ID
The two-byte Tag Control Information is broken into a 3-bit priority (0-7) value, a
Canonical Format Indicator (CFI) field (0 for Ethernet), and a 12-bit VLAN
Identifier (VID). Although the 12-bit VID field can take any value from 0 to 4095,
the only VID values you may use (in management operations) range from 1 to
4094. The value of all ones (0xFFF) is reserved and currently unused. The value of
all zeros (0x000) indicates a priority-tagged frame and that no VID is present in the
frame.
This section describes functionality you can use to programatically control the
MUX-L2 VLAN support functionality. For information on doing this from the
command line, see 23.7.1 MUX-L2 VLAN Management, p.548.
541
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
For an END device loaded to MUX, you can call the muxL2PortAttach( ) routine
to enable VLAN support for the port.
542
23 Working with the 802.1Q VLAN Tag
23.5 MUX Extensions for Layer 2 VLAN Support
543
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
To use this routine, the caller must set the updateNetFuncs boolean to TRUE and
provide nameFormAddress( ) and namePacketDataGet( ) routines that can handle
the 802.1Q VLAN tag header. The formAddress( ) routine is expected to perform
the egress rules checking and build the appropriate link-level header with the
appropriate address format that may or may not include a VLAN Tag header.
The namepacketDataGet( ) routine must perform the 802.1Q Ingress VLAN
classification as described in the IEEE 802.1Q specification. Thus, it must extract
the packet data and copy the link-level header information from the received
frame.
When a frame arrives on a port, the driver's interrupt service routine schedules the
frame processing work to tNetTask. The MUX receive routine would normally
schedule a call to the driver's namePacketDataGet( ) to separate the address
information and data in the frame.
544
23 Working with the 802.1Q VLAN Tag
23.5 MUX Extensions for Layer 2 VLAN Support
From MUX
Receive Routine EtherType No LLC DSAP Yes
> 1500 802.2 = 0x42
Address
Ethernet Type 2 Format
Yes No
Address Format
Port-Based
VLAN
VID = PVID
Ingress
No No
VID = 4095 Filter
Enabled
?
Yes Yes
Port is 23
member of Yes Fill in the link
VLAN header info.
?
No
Discard
Frame.
545
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
However, for a VLAN-enabled port, the MUX receive routine schedules a call to
muxL2IngressClassify( ) to filter the received frame according to its VLAN header
tag. Figure 23-2 shows how the ingress filter handles an incoming frame.
When the MUX needs to transmit a frame, it normally calls the driver's
nameFormAddress( ) routine to create and prepend a link-layer-appropriate frame
header to the mBlk chain containing outgoing data. However, for packets
transmitted over a VLAN-enabled port, some additional pre-processing is
required.
Yes Port-Based
VID = 0 VLAN
VID = PVID
No
Build Ethernet
Build a normal header with VLAN Discard
Ethernet header. Tag Header. Frame.
546
23 Working with the 802.1Q VLAN Tag
23.6 Current MUX-L2 Limitations
547
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Using the l2config utility, you can access the Layer 2 set routines supported by
muxL2Ioctl( ). The l2config utility does not provide access to the muxL2Ioctl( ) get
functionality, which, because of its use of structures, is more suited to
programmatic use. However, you can access much of the same information from
the command line using muxL2Show( ) or muxL2VlanShow( ), which are
described in their respective reference entries and in 23.8 Using the MUX-L2 Show
Routines, p.558.
548
23 Working with the 802.1Q VLAN Tag
23.7 VLAN Management
The following example enables the ingress frame filter for port fei1. It also sets the
fei1 ingress acceptable frame filter type to ADMIT_TAGGED_ONLY_FRAMES:
-> l2config "vlandev fei1 infilter on ingress admittag"
value = 0 = 0x0
The following example joins the fei1 port to the VLAN with VID 20 and configures
the egress frame type for the VLAN to transmit VLAN-tagged frames only:
-> l2config "vlandev fei1 join vid 20 egress tagged"
value = 0 = 0x0
The following example removes the fei1 port from VLAN 20, the VLAN to which
it was joined previously:
-> l2config "vlandev fei1 leave vid 20"
value = 0 = 0x0
549
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Because the traditional socket API does not provide a mechanism that can carry all
the information relevant to VLAN configuration, Wind River has extended the
socket API to include a new socket option, SO_VLAN, and a new structure, sovlan.
By treating the VID and the user priority as socket-level configuration options, you
can use these extensions in the getsockopt( ) and setsockopt( ) calls and thus get
or set VLAN membership information.
The sovlan structure is defined as follows:
struct sovlan {
/*
* If so_onff is set, the vlan id and/or user priority will be copied
* to the socket structure and SO_VLAN so_option will be set. If so_onff
* is not set, the SO_VLAN so_option for the socket will be cleared.
*/
int vlan_onoff; /* on/off option */
/*
* The priority_tagged boolean must be set to true if application using
* socket-based vlan requires to egress 802.1P priority-tagged frame
* (i.e. the value of vid is zero). Defaults to false. If set to true,
* the value specified by the vid will be ignored.
*/
BOOL priority_tagged;
After a socket is created, an application can use setsockopt( ) to configure the VID
and/or user priority for the given socket. In order to transmit a VLAN-tagged or
priority-tagged frame, the port/interface that the socket bound to must have
already attached to the MUX-L2 as described previously. If transmitting a
VLAN-tagged frame, the transmitting port must also be a member of the VLAN
that the socket-based VLAN is configured for.
/* setup the vlan_onoff to indicate that the VID and or User Priority
* are valid */
vl.vlan_onoff = 1;
550
23 Working with the 802.1Q VLAN Tag
23.7 VLAN Management
/*
* Informs lower-layers (such as subnet-based VLAN and MUX-L2) that the
* information provided is for Priority-tagged frame and that lower-layers
* must not alter the VLAN control information for VID configuration
*/
vl.priority_tagged = TRUE;
vl.vid = 0;
vl.upriority = 7;
if ( setsockopt(s, SOL_SOCKET, SO_VLAN, (char *)&vl, sizeof(struct sovlan))
< 0)
printf("setsockopt SO_VLAN for socket %d failed\n", s);
/* setup vlan_onoff to indicate that VID and/or User Priority * are valid */
vl.vlan_onoff = 1;
/*
* Informs lower-layers (such as Subnet-based VLAN and MUX-L2) that the
* information provided is for VLAN-tagged frame and that lower-layers should
* alter the VLAN control information for VID if the VID is not specified
*/
vl.priority_tagged = FALSE;
/*
* Specifies VID with value of 0 to allow lower-layers (such as Subnet-
* based VLAN or MUX-L2) to insert the appropriate VID to the VLAN
* control information for the outgoing VLAN-tagged frame. 23
*/
vl.vid = 0;
551
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
vl.vlan_onoff = 0;
NOTE: For the VLAN-tagged frame, if the returned VID value for getsockopt( ) is
0, it implies that the application uses the socket-based VLAN, chooses not to
configure the VID, and relies on the lower-layers (such as subnet-based VLAN or
MUX-L2) to insert the appropriate VID to the VLAN control information for the
outgoing VLAN-tagged frame.
552
23 Working with the 802.1Q VLAN Tag
23.7 VLAN Management
– The more restrictive naming style requires that the name of the VLAN
pseudo interface be in the format of vlannumber where number denotes the
unit number. If the interface is given without a unit number, the system
tries to create a new interface with an arbitrary unit number. Using this
more restrictive naming style, the VID and the association with the parent
interface must be specified with vlan and vlandev options.
553
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
vlann destroy
Destroy the specified VLAN pseudo interface.
vlann vlan vlan_tag
If vlann is a VLAN pseudo interface, set the VLAN tag value to vlan_tag. This
value is a 16-bit number that is used to create an 802.1Q VLAN header for
frames sent from the VLAN pseudo interface. Note that if an ifconfig call
contains the vlan option, you must set the vlandev in the same call.
vlandev iface
If the interface is a VLAN pseudo interface, associate it with the physical
interface, iface. Frames transmitted through the VLAN pseudo interface will be
diverted to the specified physical interface, iface, with 802.1Q VLAN
encapsulation by the MUX-L2. Frames with 802.1Q encapsulation received by
the parent interface with the correct VLAN tag will be diverted to the
associated VLAN pseudo interface. The VLAN pseudo interface is assigned a
copy of the parent interface's flags and the parent's Ethernet address.
Note that if an ifconfig( ) call contains the vlandev option, it must also use the
vlan option. The parent interface must be a member of the VLAN specified by
vlan_tag. Otherwise, this command will fail. If the VLAN pseudo interface
already has a physical interface associated with it, this command will also fail.
To change the association to another physical interface, the existing association
must first be cleared.
-vlandev iface
If the interface is a VLAN pseudo interface, this option disassociates it from the
physical interface, iface. This breaks the link between the VLAN pseudo
interface and its parent, clears its VLAN flag, its interface flags, its link
address, and shuts down the interface.
FreeBSD uses a link0 flag to indicate whether the parent interface supports the
insertion and extraction of a VLAN tag. VxWorks does not support this flag.
In fact, this flag is not required on VxWorks because when a port is attached to
the MUX-L2, the MUX-L2 will make the determination if the underlying
hardware supports VLAN insertion and extraction.
upriority user_priority
This option is a VxWorks-specific feature, not a ported Free BSD feature. If the
interface is a VLAN pseudo interface, set the VLAN user priority to
user_priority. This value, a 3-bit 802.1P user priority, is inserted to the 802.1Q
VLAN header for frames sent from the VLAN pseudo interface. Note that the
802.1P user priority is optional but the VLAN ID is mandatory. If you do not
specify a user_priority, it defaults to 0.
554
23 Working with the 802.1Q VLAN Tag
23.7 VLAN Management
Be aware that changing the VID for the VLAN pseudo interface does not
automatically remove the parent interface from the VLAN membership associated
with the old VID. It also does not automatically add the parent interface to the
member set specified by the new VID. Therefore, the parent interface must be a
member of the VLAN specified by the new VID before the new VID can be
assigned. The parent interface remains a member of the VLAN specified by the old
VID unless the membership is explicitly removed.
The following provides examples of creating VLAN pseudo interfaces. The first
examples rely on the compact interface naming style. The examples after that rely
on the restrictive interface naming style.
The following example uses the compact interface naming style to create a VLAN
pseudo interface fei1.50 with IP Address 190.0.2.234/24. It also specifies the parent
interface fei1 and VID 50 for the VLAN pseudo interface. It is assumed that fei1 is
already attached to the MUX-L2 and is a member of VLAN 50. Use l2config or
muxL2Ioctl( ) with the MUXL2IOCSVLANJOIN control command to join fei1 to
VLAN 50.
-> ifconfig "fei1.50 create inet 190.0.2.234/24"
value = 0 = 0x0
-> ifconfig "fei1.50"
fei1.50: flags=48043<UP,BROADCAST,RUNNING,MULTICAST,INET_UP> mtu 1496
inet 190.0.2.234 netmask 0xffffff00 broadcast 190.0.2.255
ether 00:08:c7:c9:24:76
vlan: 50 user priority: 0 parent interface: fei1
value = 0 = 0x0
The following example destroys the fei1.50 VLAN pseudo interface previously
created.
23
-> ifconfig "fei1.50 destroy"
value = 0 = 0x0
The following example uses the compact interface naming style to create a VLAN
pseudo interface, fei0.20, with IP Address 190.0.4.234/24. It also specifies the
parent interface fei0, VID 20, and user priority 5 for the VLAN pseudo interface. It
is assumed that fei0 is already attached to the MUX-L2 and is a member of VLAN
20. Use l2config or muxL2Ioctl( ) with the MUXL2IOCSVLANJOIN control
command to join fei0 to VLAN 20.
555
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The following example creates a VLAN pseudo interface, vlan0, with IP Address
190.0.2.123/24, assigns the pseudo interface with VID 20 and associates it with the
parent interface fei1. It is assumed that fei1 is attached to the MUX-L2 and is a
member of VLAN 20. Use l2config or muxL2Ioctl( ) with the
MUXL2IOCSVLANJOIN control command to join fei1 to VLAN 20.
-> ifconfig "vlan0 create"
value = 0 = 0x0
The following example creates a VLAN pseudo interface, vlan1, with IP Address
190.0.3.234/24, assigns the pseudo interface with VID 50, user priority 7 and
associates it with the parent interface fei0. It is assumed that fei0 is attached to the
MUX-L2 and is a member of VLAN 50. Use l2config or muxL2Ioctl( ) with the
MUXL2IOCSVLANJOIN control command to join fei0 to VLAN 50.
-> ifconfig "vlan1 create"
556
23 Working with the 802.1Q VLAN Tag
23.7 VLAN Management
value = 0 = 0x0
The following example destroys the vlan1 VLAN pseudo interface previously
created.
-> ifconfig "vlan1 destroy"
value = 0 = 0x0
NOTE: Be aware that destroying a VLAN pseudo interface does not automatically
remove the parent interface from the VLAN associated with the VLAN pseudo
interface. You must make an explicit call either to l2config or to muxL2Ioctl( ) with
MUXL2IOCSVLANLEAVE to remove the parent interface from the previous VLAN
membership.
For subnet-based VLANs to co-exist with socket-based VLANs, Wind River has
enhanced the implementation of the output routine for the VLAN pseudo interface
by applying the following rules:
23
■
If the frame does not contain any VLAN control information (that is, the VID
and user priority are not specified), the VID and user priority configured for
the VLAN pseudo interface will be assigned to the frame.
■
If the frame specifies a valid VID value (that is, the VID specifies any value
from 1 to 4094), the VLAN pseudo interface will not change the VLAN control
information in the frame. In other words, the socket-based VLAN
configuration takes precedence over the subnet-based VLAN configuration.
557
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
As long as the VID is specified, the VLAN pseudo interface assumes the frame
also carries a valid user priority assignment. If the frame contains user priority
assignment only (that is, the VID is zero), the VID configured for the VLAN
pseudo interface is applied the frame. The VLAN pseudo interface will not
override the user priority specified by the socket-based VLAN.
■
If the frame specifies a priority-tagged frame, the VLAN pseudo interface will
not change the VLAN control information in the frame.
558
23 Working with the 802.1Q VLAN Tag
23.8 Using the MUX-L2 Show Routines
value = 1 = 0x1
VLAN 20 staticstics:
Number of frames received: 166
Number of frames transmitted: 226
Number of received frames discarded: 0
559
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
VLAN 1 staticstics:
Number of frames received: 0
Number of frames transmitted: 0
Number of received frames discarded: 0
value = 0 = 0x0
-> muxL2VlanStatShow
fei1 VLAN 1 staticstics
Number of frames received: 0
Number of frames transmitted: 0
Number of received frames discarded: 0
value = 0 = 0x0
560
23 Working with the 802.1Q VLAN Tag
23.9 Using the Deprecated VLAN Tag Library
Backward Compatibility
Configuration Overview
To set up an interface for the 802.1Q VLAN tag, you must call ipVlanTagAttach( )
after the ipAttach( ) and/or ip6Attach( ) calls for the interface. The
ipVlanTagAttach( ) call determines whether the interface receives tagged,
priority-tagged, and/or untagged frames. It also registers ipVlanTagOutput( ) as
the output routine for the interface. This output routine has been written to
recognize the VLAN tagging mechanism.
After this initial configuration, you can specify the acceptable ingress frame type
filter, the ingress rules, the egress frame type filter, and the egress rules.
Optionally, you may need to set a VLAN ID value or a priority bits value.
In outline, the sequence of calls needed to configure an interface for VLAN tagged
frames is as follows:
1. Attach IPv4 or IPv6 to the interface: ipAttach( ) or ip6Attach( ).
2. Configure the interface to handle VLAN tagging: ipVlanTagAttach( ).
3. Set the acceptable ingress frame type filter: vlanTagIfIngressTypeSet( ).
If you do not explicitly specify the ingress frame type filter, it defaults to
VLAN_INGRESS_ALL_FRAMES, which configures the device to accept all
tagged, untagged, and priority-tagged frames.
4. Set the egress frame type filter: vlanTagIfEgressTypeSet( )
23
If you do not explicitly specify the egress frame type filter, it defaults to
VLAN_EGRESS_UNTAGGED_FRAMES, which configures the interface to
transmit untagged frames. This default egress behavior maintains backward
compatibility with frame transmission on VLAN-unaware interfaces (that is,
interfaces for which you have not called the ipVlanTagAttach( ) routine).
5. Optionally, adjust the ingress rules behavior: vlanTagIfIngressRulesSet( )
561
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
6. Set the VLAN ID, or set the priority bits value, or allow TOS-to-priority bits
translation: vlanTagIfVidSet( ) or vlanTagIfPriorityBitsSet( ) or
vlanTagIfEgressRulesSet( ) for the VLAN_EGRESS_IP_TOS rule.
7. Optionally, adjust the egress rules behavior: vlanTagIfEgressRulesSet( ).
8. Already mentioned in the previous step is a vlanTagIfEgressRulesSet( ) call
to activate the VLAN_EGRESS_IP_TOS rule.
9. Configure the IP address for the interface: ifconfig( )
VLAN_INGRESS_TAGGED_FRAMES
Accept only those frames explicitly tagged with a VLAN ID. All untagged and
priority-tagged frames are discarded.
VLAN_INGRESS_ALL_FRAMES
Accept all frames (tagged, untagged, and/or priority-tagged). This is the
default value. It applies if you do not explicitly specify a filter for an interface.
Use the vlanTagIfEgressTypeSet( ) routine to specify the egress frame type filter
for an interface. Using this filter, you can specify whether the interface transmits
tagged frames, priority-tagged frames, or untagged frames. If you do not define
this filter, it defaults to VLAN_EGRESS_UNTAGGED_FRAMES. The valid egress
frame type filters are as follows:
VLAN_EGRESS_TAGGED_FRAMES
Send tagged frames with non-zero VLAN IDs only.
VLAN_EGRESS_PRIORITY_FRAMES
Send priority-tagged frames with a VLAN ID of zero. For more on how to
configure the value of the priority bits, see 23.9.4 Configuring the Egress Rules,
p.563.
562
23 Working with the 802.1Q VLAN Tag
23.9 Using the Deprecated VLAN Tag Library
VLAN_EGRESS_UNTAGGED_FRAMES
Send untagged frames only. If the interface was previously configured to send
tagged or priority-tagged frames, this flag undoes that interface configuration
to send frames without any tag at all. This default applies when no value is
specified.
Depending on the egress filter, the egress rules determine the contents of the
VLAN tag (if any) and then add that tag to the header of an outgoing frame.
By default, the egress rules do not set the CFI bit. This indicates Ethernet. To
activate the rule that sets the CFI bit in outgoing frames, use
vlanTagIfEgressRulesSet( ) to activate the VLAN_EGRESS_CFI_SET rule. Whether
or not you activate the VLAN_EGRESS_CFI_SET rule, keep in mind that
vlanTagLib does not check whether the setting for CFI bit is appropriate for the
type of interface used. 23
563
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
The 3-bit priority value in the VLAN header can be configured using one of the
following methods:
1. Use vlanTagIfPriorityBitsSet( ) to configure the priority bits value that will be
used for all the egress frames on this interface.
2. Use vlanTagIfEgressRulesSet( ) to set the VLAN_EGRESS_IP_TOS egress rule
for the interface. This allows the IP TOS to 802.1P priority conversion. The
priority value configured for the interface (if any) will be ignored. To use this
option, a user-defined conversion function pointer must be registered via the
vlanTagIfTosToPriorityRegister( ) routine. This user-defined conversion
routine will be invoked with the current IP TOS value extracted from the IP
header. The conversion routine must return the proper 802.1P priority level
that will be assigned to the 3-bit VLAN priority field in the VLAN tag.
564
23 Working with the 802.1Q VLAN Tag
23.9 Using the Deprecated VLAN Tag Library
Tagging Frames with a Priority Bits Value Translated from the IP TOS Value
The following example unwinds the egress frame configuration for the interface to
send untagged frames only.
-> vlanTagIfEgressTypeSet ("motscc", 0, VLAN_EGRESS_UNTAGGED_FRAMES, NULL)
You can use the vlanTagIfShow( ) routine to display the interface VLAN tagging
information.
23
565
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
566
A
Glossary
A.1 Introduction
This chapter contains brief definitions of networking terms, acronyms, and
abbreviations used in discussions in this manual.
A.2 Terms
This section defines terms used in the Wind River Network Stack documentation.
It includes both standard industry terms and clarifies terms used in this book
whose meaning, in the context of this product, differs from another definition used
in the industry.
567
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
COMP protocol
datagram
The data link layer is the functionality in the OSI network model that transfers data
between adjacent network nodes in a wide area network or between nodes on the
same local area network segment. The data link layer prepares the packets for
transmission, and detects and handles errors, such as packet collision. Examples of
data link protocols are Ethernet for local area networks and PPP (Point-to-Point
Protocol) for point-to-point connections.
fast path
A fast path is a fast IP-forwarding mechanism that intercepts packets before they
are passed up to IP. If the packet is destined for a location known to the fast path
route cache (also known as the FIB, the Forwarding Information Base), the
application forwards the packet. If the destination is unknown to the FIB, the
application leaves the packet to IP.
firewall
egress filtering
568
A Glossary
A.2 Terms
Egress filtering makes a system less prone to attack from hackers by ensuring that
spoofed packets never leave an internal network. See also, ingress filtering, p.569.
END driver
An END driver is a frame-oriented drivers that exchange frames with the MUX. All
drivers now shipped with the standard network stack are ENDs. See also, NPT
driver, p.570 and MUX, p.570.
gif interface
A gif interface is a generic tunneling pseudo device for IPv4 and IPv6. It can tunnel
IPv[46] traffic over IPv[46]. Therefore, there can be four possible configurations.
The behavior of gif is mainly based on RFC2893 IPv6-over-IPv4 configured tunnel.
See also, stf interface, p.572.
ingress filtering
IPv6
IPv6 stands for Internet Protocol version 6, the latest level of the Internet Protocol.
The most obvious improvement in IPv6 over the IPv4 is that IP addresses are
lengthened from 32 bits to 128 bits. This extension anticipates future growth of the
Internet and provides relief for what was perceived as an impending shortage of
network addresses.
jumbogram
MAC
MAC (Medium Access Control) is the part of the data link layer that governs access
to the transmission media and is the method of determining which device has A
access to the Ethernet collision domain at any given time. See data link layer, p.568.
MAC Interface
The MAC interface is the Ethernet interface used by the SNMP agent in the network
device for communications to and from another device.
569
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
MLD
MUX
The MUX is an interface layer through which the network services communicate
with the data link layer. MUX decouples the network driver and network protocol
layers, thereby allowing you to add new network drivers without having to alter
the network protocol, or to add a new network protocol without having to alter the
MUX_based network interface drivers. Currently, the MUX supports two network
driver interface styles, the END interface and the Network Protocol Toolkit (NPT)
driver interface. Se e also, END driver, p.569 and NPT driver, p.570.
NPT driver
An NPT driver is an implementation of the OSI Data link layer that makes use of
MUX functions. The NPT (Network Protocol Toolkit) style drivers are
packet-oriented drivers that exchange packets with the MUX. See also, END driver,
p.569 and MUX, p.570.
The OSI network model is a description of seven layers through which data passes
when it is transmitted from an application on one machine to a peer on a remote
but network-connected machine. In practice, only four layers are usually
implemented: the application layer, the transport layer, the network layer, and the
data link layer.
packet
packet filtering
Packet filtering is the selective passing or blocking of data packets as they pass
through a network interface, specifically between the network and transport
layers. The most commonly-used criteria when inspecting packets are source and
destination address, source and destination port, and protocol. Filter rules specify
the criteria that a packet must match and the resulting action taken.
570
A Glossary
A.2 Terms
protocol
RFCs
RFCs (Request for Comments) are publicly available documents that contain
research, innovations, and methodologies applicable to Internet technologies. The
Internet Engineering Task Force (IETF) adopts some of the applied information
theory published in RFCs as Internet standards.
router
SACK
SNARF protocol
A SNARF protocol is a protocol that sees all packets first and that acts as a filter for
other protocols, by determining whether or not a packet is passed on.
socket
571
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
spoofing
stf interface
An stf interface is a 6to4 tunnel interface that can tunnel IPv6 traffic over IPv4, as
specified in RFC3056. For ordinary nodes in 6to4 site, you do not need stf interface.
The stf interface is necessary for site border router (called "6to4 router" in the
specification). See also, gif interface, p.569.
TCP/IP
TCP/IP is a suite of communication protocols that includes TCP and IP. It is used
to connect hosts on the Internet and is built into the UNIX operating system. See
also, protocol, p.571.
transport layer
The transport layer is the functionality in the OSI network model that provides
transparent, reliable, and cost-effective transfer of data between end users. The
transport layer controls the reliability of a given link, keeping track of the packets
and retransmitting those that fail. TCP, UDP, RTP, and SCTP (listed in Abbreviations
and Acronyms, p.573) are examples of transport layer protocols. See also, OSI
network model, p.570.
tunneling
UDP
UDP, which stands for User Datagram Protocol, is a relatively fast and
connectionless protocol that runs at the transport layer on top of IP networks.
Because it has very few error recovery services (unlike TCP), it is used primarily
for broadcasting messages and for other applications that do not require a
connection. See also, datagram, p.568, protocol, p.571, and transport layer, p.572.
572
A Glossary
A.3 Abbreviations and Acronyms
Abreviation Description
573
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
Abreviation Description
IP Internet Protocol
IPSec IP Security
574
A Glossary
A.3 Abbreviations and Acronyms
Abreviation Description
575
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
576
B
MUX/NPT Routines and Data
Structures
B.1 Introduction
This appendix describes the routines and data structures that comprise the
MUX/NPT API.
577
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
muxDevExists( )
muxDevLoad( )
muxDevStart( )
muxDevStop( )
muxDevUnload( )
muxError( )
muxIfFuncAdd( )
muxIfFuncDel( )
muxIfFuncGet( )
muxIoctl( )
muxMCastAddrAdd( )
muxMCastAddrDel( )
muxMCastAddrGet( )
muxTkBind( )
muxTkDrvCheck( )
muxTkPollReceive( )
muxTkPollSend( )
muxTkReceive( )
muxTkSend( )
muxTxRestart( )
muxUnbind( )
B.2.1 muxAddrResFuncAdd( )
NOTE: This routine is still supported but deprecated for future use. Its internals
have been replaced with a call to muxIfFuncAdd( ), the currently preferred API.
STATUS muxAddrResFuncAdd
(
long ifType, /* interface type from m2Lib.h, or driver type */
long protocol, /* protocol from RFC 1700, or service type */
FUNCPTR addrResFunc /* the routine being added. */
)
{
return (muxIfFuncAdd (ifType, protocol, ADDR_RES_FUNC, addrResFunc));
}
578
B MUX/NPT Routines and Data Structures
B.2 MUX Routines
B.2.2 muxIfFuncAdd( )
ifType
Expects a media interface or network driver type, such as can be found in
m2Lib.h.
protocol
Expects a network service or protocol type, such as can be found in RFC 1700.
Look for the values under ETHER TYPES. For example, Internet IP would be
identified as 2048 (0x800 hexadecimal).
funcType
Currently, the supported routine types are ADDR_RES_FUNC,
IF_OUTPUT_FUNC, and MULTI_ADDR_RES_FUNC. For example, the routines
registered (by default) for Ethernet drivers bound to IPv4 are arpResolve( ),
ether_output( ), and ether_resolvemulti( ) respectively. When writing
equivalents to these routines, your routines must match these routines in
prototype. If you are interested in tunneling, look at tunnelIfOutput( ), which
is defined in tunnelLib.
ifFunc
Expects a pointer to a routine for this combination of driver type and service B
type.
579
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
NOTE: If using the NPT architecture, the ifType and protocol arguments are not
restricted to the m2Lib.h or RFC 1700 values.
B.2.3 muxAddrResFuncDel( )
NOTE: This routine is still supported but deprecated for future use. Its internals
have been replaced with a call to muxIfFuncDel( ), the currently preferred API.
STATUS muxAddrResFuncDel
(
long ifType, /* ifType of function you want to delete */
long protocol, /* protocol from which to delete the function */
)
{
return (muxIfFuncDel (ifType, protocol, ADDR_RES_FUNC));
B.2.4 muxIfFuncDel( )
B.2.5 muxAddrResFuncGet( )
NOTE: This routine is still supported but deprecated for future use. Its internals
have been replaced with a call to muxIfFuncGet( ), the currently preferred API.
580
B MUX/NPT Routines and Data Structures
B.2 MUX Routines
STATUS muxAddrResFuncGet
(
long ifType, /* ifType of function you want to delete */
long protocol, /* protocol from which to delete the function */
)
{
return (muxIfFuncGet (ifType, protocol, ADDR_RES_FUNC));
}
B.2.6 muxIfFuncGet( )
B.2.7 muxAddressForm( )
581
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
This routine returns the head of an mBlk chain containing the data from pMblk
with a prepended link-level header, or NULL if the attempt fails.
B.2.8 muxBind( )
NOTE: This routine is deprecated for future use. Use muxTkBind( ) instead.
You can use muxBind( ) to bind a network service to an END. It is often better to
use muxTkBind( ), which works with both ENDs and NPT drivers.
void * muxBind
(
char * pName, /* interface name, for example, ln, ei,... */
int unit, /* unit number */
BOOL (* stackENDRcvRtn)(void *, long, M_BLK_ID, LL_HDR_INFO *, void *),
STATUS (* stackENDShutdownRtn)(void *, void *),
STATUS (* stackENDRestartRtn)(void *, void *),
void (* stackENDErrorRtn)(END_OBJ *, END_ERR *, void *),
long type, /* protocol type, from 1700 or user-defined */
char * pProtoName, /* string name for protocol */
void * pSpare /* identifies the binding instance */
)
Note that the stack*Rtn routines in the parameter list are defined differently than
in muxTkBind( ).
The muxBind( ) routine returns a cookie identifying the network driver to which
the MUX has bound the service. The service should keep track of this cookie for
use with other MUX routines.
B.2.9 muxDevExists( )
Use muxDevExists( ) to test whether a given device has already been loaded into
the network stack. As input, it expects the name and unit number of the device to
be tested.
BOOL muxDevExists
(
char * pName, /* string containing a device name (ln, ei, ...)*/
int unit /* unit number */
)
This routine returns TRUE if the device has already been loaded into the network
stack, or FALSE otherwise.
582
B MUX/NPT Routines and Data Structures
B.2 MUX Routines
B.2.10 muxDevLoad( )
This routine returns a cookie that can be passed to muxDevStart( ), or NULL, if the
device could not be loaded, in which case errno is set to S_muxLib_LOAD_FAILED.
B.2.11 muxDevStart( )
Use muxDevStart( ) to start a device after you have successfully loaded the device
using muxDevLoad( ). Internally, muxDevStart( ) activates the network interfaces
for a device by calling the drivers endStart( ) routine.
STATUS muxDevStart
(
void * pCookie /* the cookie returned from muxDevLoad() */
)
583
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
B.2.12 muxDevStop( )
B.2.13 muxDevUnload( )
This routine returns OK, on success; or ERROR, if the device could not be found, or
the error returned from the device’s endUnload( ) or nptUnload( ) routine if that
routine fails.
B.2.14 muxError( )
584
B MUX/NPT Routines and Data Structures
B.2 MUX Routines
void muxError
(
void * pEnd, /* END object pointer returned by end/nptLoad() */
END_ERR * pError /* error structure */
}
B.2.15 muxIoctl( )
Use muxIoctl( ) to access the ioctl services that network interfaces have registered
with the MUX. Typical uses of muxIoctl( ) include starting, stopping, or resetting
a network interface, or adding or configuring MAC and network addresses.
STATUS muxIoctl
(
void * pCookie, /* returned by muxTkBind() */
int cmd, /* ioctl command */
caddr_t data /* data needed to carry out the command */
)
B.2.16 muxMCastAddrAdd( )
This routine returns OK, if successful; ERROR, if the device was unable to
successfully add the address (if this is because the device does not support
multicasting, errno will be set to ENOTSUP); or ENETDOWN, if the cookie does not
represent a valid device.
B
585
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
B.2.17 muxMCastAddrDel( )
This routine returns OK, if successful. It returns ERROR if the device was unable to
successfully remove the address. If the failure is because the device does not
support multicasting, errno is set to ENOTSUP. If the failure was is because the
address was not found in the table, errno is set to EINVAL). The routine returns
ENETDOWN if the cookie does not represent a valid device.
B.2.18 muxMCastAddrGet( )
Use muxMCastAddrGet( ) to retrieve the list of multicast addresses that have been
registered for a driver. It expects two arguments: a cookie that was returned when
muxTkBind( ) was used to bind to the device, and a pointer to a pre-allocated
MULTI_TABLE structure into which the table contents will be written during this
routine call (see B.3.8 MULTI_TABLE, p.601).
int muxMCastAddrGet
(
void * pCookie, /* returned by muxTkBind() */
MULTI_TABLE * pTable /* structure that will hold retrieved table */
)
This routine returns OK, if successful; ERROR, if the device was unable to
successfully supply the list; or ENETDOWN, if the cookie does not represent a valid
device.
B.2.19 muxTkBind( )
586
B MUX/NPT Routines and Data Structures
B.2 MUX Routines
587
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
This routine returns a cookie that uniquely represents the binding instance, or
NULL if the bind fails.
NOTE: Although you can use muxTkBind( ) with both END and NPT devices, the
prototypes for the 4 registered routines differ as shown below.
END drivers:
BOOL (*stackRcvRtn) (void*, long, M_BLK_ID, LL_HDR_INFO *, void*),
STATUS (*stackShutdownRtn) (void*, void*),
STATUS (*stackTxRestartRtn) (void*, void*),
void (*stackErrorRtn) (END_OBJ*, END_ERR*, void*)
NPT devices:
BOOL (*stackRcvRtn) (void*,long, M_BLK_ID, void *),
STATUS (*stackShutdownRtn) (void *),
STATUS (*stackTxRestartRtn) (void *)
void (*stackErrorRtn) (void*, END_ERR*)
B.2.20 muxTkDrvCheck( )
This routine returns 1 if that device is an NPT driver, 0 (zero) otherwise, and
ERROR (-1) if the specified device could not be found.
588
B MUX/NPT Routines and Data Structures
B.2 MUX Routines
B.2.21 muxTkPollReceive( )
NOTE: Poll mode should only be used for debugging. For details, see Polled Mode,
p.456.
NOTE: This routine replaces muxPollReceive( ), which has been deprecated for
future use.
B.2.22 muxTkPollSend( )
NOTE: Poll mode should only be used for debugging. For details, see Polled Mode,
p.456.
589
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
STATUS muxTkPollSend
(
void * pCookie, /* returned by muxTkBind()*/
M_BLK_ID pNBuff, /* data to be sent */
char * dstMacAddr, /* destination MAC address */
USHORT netType, /* network service that is calling us */
void * pSpareData /* spare data passed to driver on each send */
)
This routine returns OK, on success; ENETDOWN, if the cookie passed in does not
represent a valid device; or an error value specific to the end/nptpollSend( ) routine
of the driver being used.
NOTE: This routine replaces muxPollSend( ), which has been deprecated for
future use.
B.2.23 muxTkReceive( )
1. This routine is registered by the MUX as the receiveRtn in the END_OBJ data structure for
the device. The driver should make a call to this reference rather than calling
muxTkReceive( ) directly.
2. Typically, this value can be found in the header of the received frame.
590
B MUX/NPT Routines and Data Structures
B.2 MUX Routines
The MUX strips off the frame header before forwarding the packet to the network
service, unless the network service is registered as MUX_PROTO_SNARF or
MUX_PROTO_PROMISC, in which case it will receive the complete frame.
The routine is defined as:
STATUS muxTkReceive
(
END_OBJ * pEnd, /* returned by nptLoad() */
M_BLK_ID pMblk, /* the buffer being received */
long netSvcOffset, /* offset to network datagram in the packet */
long netSvcType, /* network service type */
BOOL wrongDstAddr, /* not addressed to this interface */
void * pSpareData /* out-of-band data */
)
This routine returns OK, on success; ERROR, if the cookie is invalid; or FALSE, if no
services are bound to the referenced driver.
B.2.24 muxTkSend( )
591
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
B.2.25 muxTxRestart( )
B.2.26 muxUnbind( )
592
B MUX/NPT Routines and Data Structures
B.3 Data Structures
B.3.1 DEV_OBJ
The MUX uses the DEV_OBJ structure to store the name and control structure of
your device. The private control structure, held in the pDevice field of this
structure, stores information such as memory pool addresses and other essential
data. The DEV_OBJ structure is defined in end.h as:
typedef struct dev_obj
{
char name[END_NAME_MAX]; /* device name */
int unit; /* for multiple units */
char description[END_DESC_MAX]; /* text description */
void * pDevice; /* device control structure */
} DEV_OBJ;
name
A pointer to a string specifying the name of the network device.
unit
The unit number of the device. Unit numbers start at zero and increase for each
device controlled by the same driver.
description
A text description of the device driver. For example, the Lance Ethernet driver
uses the description string of “AMD 7990 Lance Ethernet Enhanced Network
Driver.” This string is displayed if muxShow( ) is called.
pDevice B
A pointer to the private control structure used by the device. A device can
access its own control structure by using the devObject.pDevice field of the
END_OBJ that the MUX passes into driver routines.
593
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
B.3.2 END_ERR
The errCode field of the END_ERR structure is 32 bits long. The lower 16 bits are
reserved for system error messages, while the upper 16 bits may be used for
custom error messages. Table B-2 lists currently defined error codes:
END_ERR_DOWN A fatal error occurred that forced the device to go down. The
device can no longer send or receive packets.
END_ERR_UP The device was down but has now come up and may again
send and receive packets.
B.3.3 END_OBJ
END_OBJ is the head of the structural interface between the MUX and a network
interface driver. The driver allocates this structure and initializes some of its
elements within its endLoad( ) or nptLoad( ) routine. The structure is defined in
target/h/end.h and is diagramed in Figure B-1.
594
B MUX/NPT Routines and Data Structures
B.3 Data Structures
END_OBJ
DEV_OBJ
node : NODE 1
pOutputFilterSpare : void * name : char[]
devObject unit : int
attached : BOOL description : char[]
txSem : SEM_ID pDevice : void *
flags : long
multiList : LIST
nMulti : int
protocols : LIST 1 NET_FUNCS
snarfCount : int pFuncTable start( )
pNetPool : NET_POOL_ID stop( )
receiveRtn( ) : STATUS unload( )
outputFilter( ) : BOOL ioctl( )
send( )
1 1
mCastAddrAdd( )
mib2Tbl pMib2Tbl
mCastAddrDel( )
(obsolete)
mCastAddrGet( )
M2_ID pollSend( )
pollRcv( )
formAddress( )
Manage the contents of the M2_ID structure packetDataGet( )
using the macros described in 21.4.4 MIB addrGet( )
endBind( )
Statistics Collection in END and NPT Drivers,
The MUX manages some of the elements in this structure, but the driver is
responsible for setting and managing others:
node
The root of the device hierarchy. The MUX sets the value of this field. The
driver should not modify the value of this item.
devObject
A pointer to the DEV_OBJ structure for this device (see B.3.1 DEV_OBJ, p.593).
The driver must set this value when its endLoad( ) or nptLoad( ) routine is
called.
receiveRtn
A function pointer that references a muxTkReceive( ) routine. The MUX
supplies this pointer when the driver is loaded. Any time after the completion B
of the muxDevLoad( ) call, the driver can use this receiveRtn( ) to pass data up
to the protocol layer.
595
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
596
B MUX/NPT Routines and Data Structures
B.3 Data Structures
IFF_NOARP
There is no address resolution protocol.
IFF_NOTRAILERS
The device must avoid using trailers.
IFF_OACTIVE
Transmission in progress.
IFF_POINTOPOINT
The interface is a point-to-point link.
IFF_PROMISC
This device receives all packets.
IFF_RUNNING
The device has successfully allocated needed resources.
IFF_SIMPLEX
The device cannot hear its own transmissions.
IFF_UP
The interface driver is up.
! WARNING: If the driver changes the state of the flags element (for example,
marking itself as “down” by setting the IFF_DOWN flag), the driver should export
this change by calling muxError( ) with the errCode field of the END_ERR structure
set to END_ERR_FLAGS.
pFuncTable
A pointer to a NET_FUNCS structure (see B.3.9 NET_FUNCS, p.601). This
structure contains pointers to driver routines for handling standard requests
such as stop or send. Your driver must allocate and initialize this structure
when the endLoad( ) or nptLoad( ) routine is called.
mib2Tbl
An M2_INTERFACETBL structure used to track the MIB-II variables used in the
driver (see B.3.6 M2_INTERFACETBL, p.599). The driver should initialize this
structure, although the elements in the structure will be used and adjusted
both by the driver and by the MUX. For appropriate values for the elements in
this structure, see RFC 1158.
B
NOTE: Although mib2Tbl is still included and supported in this structure, it
is deprecated for future use. The maintenance of the interface group MIB
variables is now handled using an M2_ID structure, which is referenced using
the pMib2Tbl field of this structure.
597
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
multiList
A list of multicast addresses. The MUX sets and manages this list, but it uses
the driver’s nptMCastAddrAdd( ), nptMCastAddrDel( ), and
nptMCastAddrGet( ) to do so.
nMulti
The number of addresses on the list referenced by the multiList field described
above. The MUX sets this value using the information returned by the driver’s
nptMCastAddrGet( ) routine.
outputFilter
A function pointer that references an optional output filtering routine. This is
set by the MUX to the stackRcvRtn( ) of a network service that registers itself
as of the MUX_PROTO_OUTPUT type, if there is such a service.
pNetPool
A pointer to a netBufLib-managed memory pool. This pool, which is used
internally by the NPT, should be initialized in the endLoad( ) or nptLoad( )
routine.
pMib2Tbl
A pointer to an M2_ID structure, which is used to manage the interface group
MIB variables for this interface. You should only rarely need to access the
pMib2Tbl field, and you should never need to directly access the contents of
the M2_ID structure. Instead, you manage the interface group MIB variables
using macros that access function pointers registered with endLib. For more
information on these macros, see 21.4.4 MIB Statistics Collection in END and
NPT Drivers, p.465.
B.3.4 END_QUERY
This structure is designed specifically for use within the EIOCQUERY ioctl
command.
typedef struct
{
int query; /* the query*/
int queryLen; /* length of expected/returned data */
char queryData[4]; /* 4 byte minimum; 120 byte maximum */
} END_QUERY;
598
B MUX/NPT Routines and Data Structures
B.3 Data Structures
B.3.5 LL_HDR_INFO
The MUX uses the LL_HDR_INFO structure to keep track of link-level header
information associated with packets passed from an END to the MUX and from
there up to a protocol. An LL_HDR_INFO structure is passed as an argument to an
END’s stack receive routine.
The LL_HDR_INFO structure is defined as:
typedef struct llHdrInfo
{
int destAddrOffset; /* destination address offset into mBlk */
int destSize; /* size of destination address */
int srcAddrOffset; /* source address offset into mBlk */
int srcSize; /* size of source address */
int ctrlAddrOffset; /* control info offset into mBlk */
int ctrlSize; /* size of control info */
int pktType; /* type of the packet */
int dataOffset; /* offset into mBlk where data starts */
} LL_HDR_INFO;
B.3.6 M2_INTERFACETBL
599
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
B.3.7 mBlk
Use mBlk structures as a vehicle for passing packets between the driver and
protocol layers. The mBlk structure is defined in netBufLib.h as:
typedef struct mBlk
{
M_BLK_HDR mBlkHdr; /* block header, pointer to mHdr structure */
M_PKT_HDR mBlkPktHdr; /* packet header, pointer to pktHdr structure */
CL_BLK * pClBlk; /* pointer to cluster block */
} M_BLK;
600
B MUX/NPT Routines and Data Structures
B.3 Data Structures
B.3.8 MULTI_TABLE
B.3.9 NET_FUNCS
The MUX uses this structure to reference the routines implemented for a driver.
The NET_FUNCS structure is defined as:
typedef struct net_funcs
{
STATUS (* start)(void *);
STATUS (* stop)(void *);
STATUS (* unload)(void *);
int (* ioctl)(void *, int, caddr_t);
STATUS (* send)(void *, M_BLK_ID);
STATUS (* mCastAddrAdd)(void *, char*);
STATUS (* mCastAddrDel)(void *, char*);
STATUS (* mCastAddrGet)(void *, MULTI_TABLE*);
STATUS (* pollSend)(void *, M_BLK_ID);
STATUS (* pollRcv)(void *, M_BLK_ID);
M_BLK_ID (* formAddress)(M_BLK_ID, M_BLK_ID, M_BLK_ID, BOOL );
STATUS (* packetDataGet)(M_BLK_ID, LL_HDR_INFO *);
STATUS (* addrGet)(M_BLK_ID, M_BLK_ID, M_BLK_ID, M_BLK_ID, M_BLK_ID);
} NET_FUNCS;
The driver routines referred to in this structure are described in greater detail
elsewhere (see NPT Driver Entry Points Exported to the MUX, p.493 and END Entry
Points Exported to the MUX, p.478).
601
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
602
Index
603
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
altqConfig
CBQ and 422
B
examples 420 Berkeley Packet Filter (BPF)
overview 410 BPF devices,creating 453
RTPs and 405 header length, determining 454
show commands 426 type of link level frame, finding 454
always_keepalive, TCP run-time configuration binding names to sockets, bind( ) 244
parameter 58 BIOCSETF ioctl command 454
anonymous FTP 158 BIOCSETIF ioctl command 454
application protocols blackhole
configuring VxWorks for 146 TCP build-time configuration parameter 76
ARP TCP run-time configuration parameter 58
default table entries 342 UDP build-time configuration parameter 78
Ethernet configuration parameters 81 UDP run-time configuration parameter 62
ARP_DEBUG_CFG 345 blocking socket, avoiding 294
ARP_ENTRY_numbef_ADDR parameters 343 bmcastecho, ICMP, configuration parameter 51
ARP_ENTRY_number_HOST parameters 342 boot network interface, automatic stack attach 85
ARP_HOST_DOWN_TIME_CFG 81 BOOT_LINE_ADRS 186
ARP_MAX_AGE_CFG 81 BOOTP
ARP_MAX_ENTRIES_CFG 81 abbreviation for 573
ARP_MAXTRIES_CFG 81 compare with RARP 443
ARP_PROXYALL_CFG 81, 82 in an RTP 208
ARP_PRUNE_INTVL_CFG 81 BPF_BUFSIZE_CFG 453
ARP_REGISTER_CFG 345 BPF_HLEN 454
ARP_USELOOPBACK_CFG 81 BPF_TYPE 454
arpAdd( ), creating default and permanent ARP bpfDevCreate( ) 453
table entries 342 bpfDrv( ) 453
arpLib, configuration component 342 broadcasting
assoc_rtx_max, SCTP configuration parameter 57 IP, configuring addresses 439
attaching a stack to a network interface RIP, using 327
overview of 433 BSD drivers
automatic, boot interface, IPv4 85 entry points, implementing 504
automatic, boot interface, IPv6 16, 90 porting to MUX 504
explicitly, manually started interfaces 432 bsdSockLib 236
INCLUDE_IPATTACH 16 bucketlimit, TCP syncache configuration
AUTH_UNIX (RPC) 135 parameter 62
authentication, NFS 135 buffer alignment in network interface drivers 470
auto_asconf, SCTP configuration parameter 56 buffers, manipulation macros for 47
auto_flowlabel, IPv6 configuration parameter 65
setting default value at build time 88
auto_linklocal, IPv6 configuration parameter 65
setting default value at build time 89 C
cached routes, IPv6, maximum 89
cachelimit, TCP syncache configuration
parameter 62
604
Index
605
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
606
Index
607
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
608
Index
F FF_IFADDR_ADD 371
FF_IFADDR_DELETE 372
fast IP-forwarding applications 351 FF_IPV4_FIB_DISP_TBL 353
cache maintenance 360 FF_IPV4_INIT_RTN 353
entry points for, writing 363 FF_IPV6_FIB_DISP_TBL 353
xxCacheFlush( ) 372 FF_IPV6_INIT_RTN 353
xxCacheLookup( ) 374 ffCacheFlush 372
xxCacheWalk( ) 373 ffCacheWalk 373
xxInterfaceModeChanged( ) 370 ffInterfaceModeChanged 370
xxInterfaceStatusChanged( ) 371 ffInterfaceStatusChanged 371
xxMacEntryDeleted( ) 369 ffLibObjInit( ) 359
xxModeChanged( ) 371 ffLibUpdateStats( ) 365
xxPktSend( ) 365 ffMacEntryDeleted 369
xxRouteAdded( ) 366 ffModeChanged 371
xxRouteDeleted( ) 367 ffPktSend 365
xxRouteModified( ) 367 ffRouteAdded 366
xxRouteMoreInfo( ) 368 ffRouteDemoted 369
xxShutDown( ) 365 ffRouteModified 367
xxinit( ) 357 ffRouteMoreInfo 368
initializing 357 ffShutDown 365
populating cache for 360 File Transfer Protocol
registration with fastPathLib 359 Client IPv4, configuration of 156
supporting system management functions Client IPv6, configuration of 159
in 361 login security, configuration of 158
fast path Server IPv6, configuration of 160
defined 568 filter rules, ALTQ and 421
Fast UDP FIONBIO 294
building source for, -FASTUDP option 274 firewall
configuring VxWorks for 274 defined 568
writing socket applications 274 Firewall IP Filter, required by ALTQ 406
fastforwarding, IP parameter Firewall, required by ALTQ 400
setting at run-time 53 first, IP portrange parameter 54
fastforwarding,IP parameter flight size, slow start 61
setting at build time 82 setting at build time 76
FASTFORWARDING_CFG 82 flooding algorithm interval, ARP 68
fastPathLib 352 setting at build time 81
FASTUDP_DEBUG_CFG 275 flow control 516
FASTUDP6_DEBUG_CFG 275 folders, network component 14
fastUdp6Lib 275 forwarding
fastUdpLib 274 IP parameter 53
features in Platforms, see Wind River Platforms IPv4, enabling at build-time 79
FF_IF_ADD 372 IPv6, enabling at build time 87
Index
FF_IF_DELETE 372 IPv6, enabling at run time 66
FF_IF_DOWN 372 source-routed packets, enable at build time 80
FF_IF_UP 372
609
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
610
Index
611
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
612
Index
613
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
J LOAD_STRING
ENDS, adding 474
jumbogram NPT drivers, adding 490
defined 569 local domain sockets, working with 240
overview 71 including in an image 241
setting up 241
local_slowstart_flightsize, TCP parameter 59
setting at build time 76
K log_arp_wrong_iface, link layer Ethernet
parameter 68
keepalive: idle, see keepidle setting at build time 82
keepalive: interval, see keepintvl LOG_ARP_WRONG_IFACE_CFG 82
keepfaith log_in_vain
IPv6 parameter 66 TCP parameter 60
setting at build time 87 setting at build time 75
keepidle UDP parameter 62
TCP parameter 59 setting at build time 77
setting at build time 74 log_interval, IPv6 parameter 66
keepinit, TCP parameter 59 log_redirect, ICMP parameter 52
keepintvl, TCP parameter 59 setting at build time 84
setting at build time 75 LOGIN_PASSWORD 171
kern, run-time configuration parameters 50 LOGIN_USERNAME 171
loginLib 171
loopback driver for local traffic, ARP 81
loopback_nocsum, SCTP configuration
L parameter 56
lowfirst, also known as ipport_lowfirstauto 55
last
build time value derived from
IP port range parameter, ipport_lastauto 54
IPPORT_RESERVED_CFG
last, IP port range parameter, ipport_lastauto
lowlast
setting at build time, reserved first port 79
also known as ipport_lowlastauto 55
link layer Ethernet run-time configuration
setting at build time 79
parameters 69
link layer functionality, enabling for an
interface 440
linkBufPool 29 M
link-level header
muxTkSend( ), and 591 M_BCAST
nptSend( ), and 497 NPT drivers, and 492
link-local address, IPv6, automatic assigning 89 M_CL_CONFIG
listen( ), listening for socket connection defined 32
requests 248 mapping to system and data pool
LL_HDR_INFO data structure 599 parameters 32
LOAD_FUNC setting up a memory pool 45
ENDs, adding 474 M_LEADINGSPACE( ) 48
NPT drivers, adding 490
614
Index
615
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
616
Index
N netPoolCreate( ) 39
netPoolInit( ) 28
nd6_debug, ICMPv6 configuration parameter 63 mapping configuration parameters to elements
nd6_delay, ICMPv6 configuration parameter 63 in 32
nd6_drlist, ICMPv6 configuration parameter 63 netShow, configuration component 92
nd6_maxnudhint, ICMPv6 configuration netStackDataPoolShow( )
parameter 64 estimating memory pool usage 31
nd6_maxquelen, ICMPv6 configuration netStackSysPoolShow( )
parameter 64 estimating memory pool usage 31
nd6_mmaxtries, ICMPv6 configuration Network Buffer Library Additional Features
parameter 64 component 30
nd6_prlist, ICMPv6 configuration parameter 64 network connectivity, testing
nd6_prune, ICMPv6 configuration parameter 64 under IPv4 23
nd6_umaxtries, ICMPv6 configuration under IPv6 25
parameter 64 network information display routines, configuration
nd6_useloopback, ICMPv6 configuration component for 92
parameter 64 network interface configuration
Neighbor Discovery Protocol (NDP) 342 ifconfig( ), using 434
net.inet.icmp, ICMP parameters 52 ifMaskSet( ), ifAddrSet( ), using 435, 436
net.inet.ip, IPv4 parameters 52 network interface driver, including 20
net.inet.ip.portrange, IPv4 parameters 54, 55 network interface drivers
net.inet.raw, raw IP parameters 55 see also END (Enhanced Network Driver);
net.inet.sctp, SCTP parameters 55 Network Protocol Toolkit (NPT)
net.inet.tcp, TCP parameters 58 driver
net.inet.udp, UDP parameters 62 buffer alignment 470
net.inet6.icmp6, ICMPv6 parameters 64 link-level header allocation, early 465
net.inet6.ip6, IPv6 parameters 65 memory, managing 464
net.link.ether, link layer Ethernet parameters 69 multiple drivers, supporting 507
net.link.ether.inet parameters 68 scatter-gather, supporting 464
NET_FUNCS table network interfaces
filling 495 additional, starting at run-time 432
listing of 601 attaching to stack 433
NET_JOB_NUM_CFG 22 fixing IP address assignment errors 438
NET_TASK_OPTIONS 23 pausing 440
NET_TASK_PRIORITY 22 Network Protocol Toolkit (NPT) drivers
NET_TASK_STACKSIZE 23 see also network interface drivers
netBufLib 464 adding to an image 490
netDevCreate( ) 178 bind events, responding to 491
netDrv BSD drivers to, porting 504
downloading run-time images 178 compared to END drivers 462
general usage information 177 END_OBJ data structure 493
netJobAdd( ) entry points 462
Index
ENDs, and 476 exported to MUX 493
INCLUDE_NET_DAEMON 21 implementing 489
NPT drivers, and 492 ioctl support 501
617
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
618
Index
619
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
620
Index
621
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
622
Index
623
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
624
Index
625
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
626
Index
627
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
628
Index
629
Wind River Network Stack for VxWorks 6
Programmer’s Guide, 3.1
X using 273
zero-copy TCP 275
XDR (External Data Representation) ZBUF_BEGIN 279
basic networking support 20 ZBUF_END 279
RPC and 166 ZBUF_SEG 278
zbufCreate( ) 279
zbufCut( ) 281
freeing data buffers 281
Z zbufDelete( ) 279
zbufDup( ) 280
zbuf sockets zbufExtractCopy( ) 280
see online zbufLib; zbufSockLib zbufInsert( ) 280
advantages 287 zbufInsertBuf( ) 279
buffer size issues 276 zbufInsertCopy( ) 280
code examples zbufLength( ) 280
display routine 285 zbufLib 276
TCP server, converting a 287 zbufSegData( ) 282
configuration component for 276 zbufSegFind( ) 281
data structures 277 zbufSegLength( ) 281
byte locations 278 zbufSegNext( ) 281
creating 279 zbufSegPrev( ) 281
deleting 279 zbufSockBufSend( ) 277
dividing in two 281 zbufSockBufSendto( ) 277
example 282 zbufSockLib 276
handling 279 zbufSockLibInit( ) 286
illustrated 278 zbufSockRecv( ) 286
length, determining 280 zbufSockRecvfrom( ) 286
offsets 278 zbufSockSend( ) 286
segment IDs 278 zbufSockSendto( ) 286
segments 281 zbufSplit( ) 281
data, inserting 280 zero-copy TCP 275
example 282
including support for 276
interoperability 276
limitations 286
removing data 281
segments
byte locations, determining 281
data location, determining 282
length, determining 281
reading 281
sharing 280
sending existing buffers 277
shared buffers, managing 277
socket calls 286
630