24.2. L4 Protocol RegistrationThe L4 protocols that rest on IPv4 are defined by net_protocol data structures, defined in include/net/protocol.h, which consist of the following three fields:
The include/linux/in.h file contains a list of L4 protocols defined as IPPROTO_XXX symbols. (For a more complete list, see the /etc/protocols file, or RFC 1700 and its successor RFCs.) The maximum value for an L4 protocol identifier is 28-1 or 255, because the field in the IP header allocated to specify the L4 protocol is 8 bits. The highest number, 255, is reserved for Raw IP, IPPROTO_RAW. Not all of the protocols defined in the list of symbols are handled at the kernel layer; some of them (notably Resource Reservation Protocol, or RSVP, and the various routing protocols) are usually handled in user space. This is, for example, why RSVP and routing protocols like OSPF are not included in the list of L4 protocols supported by the kernel that is in the previous section. 24.2.1. Registration: inet_add_protocol and inet_del_protocolProtocols register themselves with the inet_add_protocol function and, when implemented as modules, unregister themselves with the inet_del_protocol function. Both routines are defined in net/ipv4/protocol.c. All of the inet_protocol structures of the L4 protocols registered with the kernel are inserted into a table named inet_protos, represented in Figure 24-2. In earlier versions of the kernel, this was a hash table, and the word hash still appears in the code that handles the table, but currently it is a simple flat array with one item for each of the possible 256 protocols. The protocol number from /etc/protocols is the slot in the table where the protocol is inserted. If you'd like to see how the table was handled as a hash table in the 2.4 kernel, look in the 2.4 sources at the ip_run_ipprot function. Figure 24-2 shows the numbers and initials of the most common protocols; for instance, ICMP is protocol 1 and occupies slot 1 in the inet_protos table. Figure 24-2. IPv4 protocol tableConcurrent accesses to the inet_protos table are managed in this way:
inet_del_protocol, which may remove an entry of the table currently held by an RCU reader, calls synchronize_net to wait for all the currently executing RCU readers to complete their critical section before returning. There is another hash table used by protocols that rest on IPv6. Note that IPv6 appears in the IPv4 inet_protos table as well: the kernel can tunnel IPv6 over IPv4 (also called SIT, for Simple Internet Transition). See the section "IPv6 Versus IPv4." As mentioned in the previous section, the ICMP, UDP, and TCP protocols are always part of the kernel and therefore are statically added to the hash table at boot time by inet_init in net/ipv4/af_inet.c. The following excerpts show the definitions of their structures and the actual inet_add_protocol calls that register them:
The IGMP handler is registered only when the kernel is compiled with support for IP multicast. As an example of how other protocols are dynamically registered, the following snapshot is taken from the Zebra user-space routing daemon's implementation of the Open Shortest Path First IGP (OSPFIGP) protocol
For each L4 protocol there can be only one handler in kernel space (but multiple handlers could be present in user space, as discussed later in the section "Raw Sockets and Raw IP"). inet_add_protocol complains (returns -1) when it is called to install a handler for an L4 protocol that already has one. |
Monday, October 26, 2009
Section 24.2. L4 Protocol Registration
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment