Section 12.4. Interface Between Protocol and Network Interface

   


12.4. Interface Between Protocol and Network Interface

The lowest layer in the set of protocols that constitutes a protocol family must interact with one or more network interfaces to transmit and receive packets. It is assumed that any routing decisions have been made before a packet is sent to a network interface; a routing decision is necessary to locate any interface at all. Although there are four paths through any network stack, there are only two cases with which we should be concerned in the interaction between protocols and network interfaces: transmission of a packet and receipt of a packet. We shall consider each separately.

Packet Transmission

If a protocol has chosen an interface identified by ifp, a pointer to a network interface structure, the protocol transmits a fully formatted network-level packet with the following call:

 int (*if_output)(     struct ifnet *ifp,     struct mbuf *msg,     struct sockaddr *dst,     struct rtentry *rt); 

The output routine for the network interface transmits the packet msg to the protocol address specified in dst or returns an error number. In reality, transmission may not be immediate or successful; typically, the output routine validates the destination address, queues the packet on its send queue, and primes an interrupt-driven routine to transmit the packet if the interface is not busy. For unreliable media, such as Ethernet, successful transmission simply means that the packet has been placed on the cable without a collision. In contrast, a reliable, point-to-point network such as X.25, can guarantee proper delivery of a packet or give an error indication for each packet that was not successfully transmitted. The model employed in the networking system attaches no promise of delivery to the packets presented to a network interface and thus corresponds most closely to the Ethernet. Errors returned by the output routine are only those that can be detected immediately and are normally trivial in nature (network down, no buffer space, address format not handled, etc.). If errors are detected after the call has returned, the protocol is not notified.

When messages are transmitted in a broadcast network such as Ethernet, each network interface must formulate a link-layer address for each outgoing packet. The interface layer must understand each protocol address format that it supports to formulate corresponding link-layer addresses. The network layer for each protocol family selects a destination address for each message and then uses that address to select the appropriate network interface to use. This destination address is passed to the interface's output routine as a sockaddr structure. Presuming that the address format is supported by the interface, the interface must map the destination protocol address into an address for the link-layer protocol associated with the transmission medium that the interface supports. This mapping may be a simple algorithm, it may require a table lookup, or it may require more involved techniques, such as use of the address resolution protocol described in Section 12.8.

Packet Reception

Network interfaces receive packets and dispatch packets to the appropriate network-layer protocol according to information encoded in the link-layer protocol header. Each protocol family must have one or more protocols that constitute the network layer described in Section 12.1. In this system, each network-layer protocol has an input-packet queue assigned to it. Incoming packets received by a network interface are queued in a protocol's input packet queue, and the network thread handles network-layer processing; see Figure 12.6. Similar queues are used to store packets awaiting transmission by network device drivers.

Figure 12.6. Input packets dispatched to protocol input queues.


Several macros are available for manipulating packet queues:

IF_ENQUEUE ( if q, m)

Place the packet m at the tail of the queue ifq.

IF_DEQUEUE (ifq, m)

Place a pointer to the packet at the head of queue ifq in m and remove the packet from the queue; m will be zero if the queue is empty.

IF_PREPEND(ifq, m)

Place the packet m at the head of the queue ifq.


Packet queues have a maximum length associated with them as a simple form of congestion control. The macro IF_QFULL() can be used to determine whether a queue is full; if it is, another macro, IF_DROP(), can then be used to record the event in statistics kept for the queue. Each queue is protected by a mutex so that threads on different processors cannot accidentally interfere with each other's transmissions. Any macro that manipulates the queue first locks the mutex, then makes its change, and finally releases the mutex.

As an example, the following code fragment could be used in a network interface's output routine:

 if (IF_QFULL(ifp >if_snd)) {     IF_DROP(ifp >if_snd);     m_freem(m);      /* discard packet */     error = ENOBUFS; } else     IF_ENQUEUE(ifp >if_snd, m); 

On receiving a packet, a network interface decodes the packet type, strips the link-layer protocol header, records the identity of the receiving interface, and then dispatches the packet to the appropriate link-layer module. Above the link layer each protocol has an input handler routine and input queue, which are registered with the network thread via the netisr_register() routine.

For example, an Ethernet device driver queues its packets in the Ethernet link layer by calling ether_demux(), which then calls netisr_dispatch() to enqueue packets for a particular protocol. netisr_dispatch() is a generic routine that hands packets to protocols. It in turn uses a generic routine if_handoff() to actually enqueue the packet with the following code:

 IF_LOCK_(ifq) ; if (_IF_QFULL(ifq) ) {     _IF_DROP(ifq);     IF_UNLOCK(ifq);     m_freem(m);     return (0); } _IF_ENQUEUE(ifq, m); IF_UNLOCK(ifq); 

Once the packet is placed in the queue, the schednetisr() macro schedules the network thread so that it will carry on the processing of the packet.

Entries on a protocol's input queue are mbuf chains with a valid packet header containing the packet's length and a pointer to the network interface on which the packet was received. The pointer to the interface has many potential uses, such as deciding when to generate routing redirect messages. The protocol's input routine does not dequeue the packet but is handed an mbuf pointing to the packet by the network thread. It is the network thread that dequeues packets and then calls the protocol's input routine.

While an entry is being dequeued from an input queue, the network thread blocks all other packets from entering the protocol by locking the network thread mutex. The lock is held to ensure that pointers in the queue data structure are not altered. Once a message is dequeued, it is processed; if there is information in the packet for a higher-level protocol, the message is passed upward.


   
 


The Design and Implementation of the FreeBSD Operating System
The Design and Implementation of the FreeBSD Operating System
ISBN: 0201702452
EAN: 2147483647
Year: 2003
Pages: 183

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net