13.2. Executing the Right Protocol HandlerFor each network protocol, regardless of its layer, there is one initialization function. This includes L3 protocols such as IPv4 and IPv6, link layer protocols like ARP, and so on. For a protocol included statically in the kernel, the initialization function executes at boot time; for a protocol compiled as a module, the initialization function executes when the module is loaded. The function allocates internal data structures, notifies other subsystems about the protocol's existence, registers files in /proc, and so on. A key task is to register a handler in the kernel that handles the traffic for a protocol. In this section, for the sake of simplicity, I'll show how a device driver (which operates on L2) invokes an L3 protocol, but the same principle applies to any protocol on any layer. When the device driver receives a frame, it stores it into an sk_buff buffer data structure and it initializes the protocol field shown here: struct sk_buff { ... ... ... unsigned short protocol; ... ... ... }; The value in this field can be an arbitrary value used by the kernel to identify a given protocol, or a field of a MAC header in the incoming frame. The field is consulted by Figure 13-5. Frame decapsulation, layer by layer, at Server Y![]() the kernel function netif_receive_skb (described in Chapter 10) to determine which function handler to execute to process the packet at L3. See Figure 13-6. Figure 13-6. netif_receive_skb processes according to the protocol field of the sk_buff buffer![]() Most of the values used by the kernel to refer to the protocols in the protocol field are listed in include/linux/if_ether.h with the name ETH_P_XXX. Despite the ETH prefix, not all names refer to Ethernet hardware. As Table 13-1 shows, they can cover a wide range of activities. Table 13-1 lists the values used internally by the kernel, which are assigned directly to skb->protocol by device drivers instead of being extracted from a frame header. (The ones omitted from the table are not assigned a function handler.) The first row of the table, for instance, indicates that the kernel handler ipx_rcv is used to process an incoming packet whose skb->protocol field is ETH_P_802_3.
Not all the ETH_P_XXX values are assigned a handler. They can be left unassigned in two circumstances:
Unfortunately, it is not always sufficient to extract a field from the L2 header to figure out which handler to invoke; the association between skb->protocol and the protocol handler that will process the frame is not always one-to-one. There are cases where the protocol handler for a given ETH_P_XXX will actually just read other parameters from the frame header (without processing the frame) and hand the frame to another protocol handler that will process it. An example is the ETH_P_802_2 handler. As described in Chapter 10, netif_receive_skb is the function that dispatches ingress frames to the right protocol handlers. When there is no handler for a specific protocol, the frame is dropped. In special cases, a single packet can be delivered to multiple handlers. This is the case, for instance, when packet sniffers are running. This mode of operation, sometimes referred to as promiscuous mode , is listed as ETH_P_ALL in Table 13-1. This type of handler is generally not used to process packets for recipients, but just to snoop on a given device or set of devices for the purposes of debugging or collecting statistics. 13.2.1. Special Media EncapsulationEthernet is by far the most common mechanism used for implementing both shared and point-to-point network connections. In this book, we always refer to Ethernet device drivers when talking about L2. However, Linux allows you to use any of the most common media available on modern PCs to carry IP traffic (and sometimes any network protocol traffic). Examples of media that can be used to transport IP include the serial and parallel ports (SLIP/PLIP/PPP), FireWire (eth1394), USB, Bluetooth, Infrared Data Association (IrDA), etc. Such media define network devices as abstractions on top of the generic ports, usually by means of extensions to the generic media device driver. Such virtual devices look like real NICs to the upper layers. Here is how reception and transmission are implemented on these virtual network devices:
How exactly the generic device driver of a given media type interfaces to the virtual network device is an implementation detail. Depending on the medium, it may offer a synchronous or asynchronous interface, use of buffering both on receive and transmit paths, etc. |