28.8. Transmitting and Receiving ARP Packets
As shown in Figure 28-13, both transmission and reception of ARP packets can be controlled by Netfilter.
The dotted lines between arp_rcv and arp_send indicate that in some cases, the reception of an ARP packet triggers the transmission of at least one other ARP packet. This occurs when:
As Figure 28-13 shows, arp_send is also triggered by external events and a few kernel features such as bonding; details are provided in later sections.
28.8.1. Transmitting ARP Packets: Introduction to arp_send
arp_send is the routine provided by ARP to transmit both solicitation requests and replies, as shown in Figure 28-14. Chapter 27 explained on a protocol-independent level how the neighbor infrastructure takes care of solicitation transmissions and retransmissions. Here we'll see how arp_send accomplishes its job.
Figure 28-13. (a) arp_rcv; (b) arp_send
As shown in Figure 28-13(b), arp_send is split into two parts: arp_create initializes the ARP packet, and arp_xmit hooks into Netfilter and then invokes dev_queue_xmit.
arp_send is split into these two parts so that drivers that need to manipulate a packetfor instance, by inserting extra headerscan call arp_create and arp_xmit separately. The driver can thus perform some customization in between. See, for example, how the bonding code manages to add the 802.1Q tag if needed (rlb_update_client in drivers/net/bonding/bond_alb.c).
Figure 28-14. Examples of contexts where arp_send is used
We saw in the section "Creating a neighbour Entry" in Chapter 27, the times when the kernel may need to generate a solicitation request. In this section, we analyze arp_solicit, the routine used by ARP to accomplish this task.
The caller of arp_solicit is responsible for counting the number of probes (solicitation transmission attempts) made and ensuring that the maximum has not yet been reached. arp_solicit, therefore, doesn't have to worry about this task.
Here is its prototype and the meaning of the two input parameters:
static void arp_solicit(struct neighbour * neigh, struct sk_buff *skb)
To understand the implementation of arp_solicit, it is important to understand the relationships and differences between the following two groups of parameters:
The main tasks of arp_solicit are:
The next section will go into detail on the selection of the source IP address. Let's briefly see how the other two tasks are accomplished.
arp_solicit differentiates between requests that should be generated by the kernel and requests that should be generated from user space. The latter can happen when an arpd ARP daemon is running; this requires that the kernel be compiled with the ARPD option, and is discussed in the section "ARPD." The two cases are handled as follows:
126.96.36.199. ARP_ANNOUNCE and selection of source IP address
Most hosts have just one IP address, so this can be copied into the ARP header. When a host offers multiple IP addresses, the choice can be influenced by ARP_ANNOUNCE. arp_solicit simply applies the logic described in Table 28-1 and depicted in Figure 28-15. In order to accomplish its job, it makes use of three routines made available by the routing and configuration subsystems:
Note that when ARP_ANNOUNCE is configured at level 0 or 1 and the source IP address in the IP header cannot be used, arp_solicit falls back to level 2. inet_select_addr is invoked with a scope of RT_SCOPE_LINK. Given a device dev and a target IP address IP, inet_select_addr browses the IP addresses configured on dev and selects the first one that matches the subnet of the target IP address IP and has a scope greater than or equal to RT_SCOPE_LINK. Scopes are described in the section "Scope" in Chapter 30.
Figure 28-15. Selection of source IP in arp_solicit