嵌入式linux中文站在线图书

Previous Page
Next Page

28.8. Transmitting and Receiving ARP Packets

The functions used to send and receive ARP packets are:


arp_send

The neighboring subsystem calls neigh_ops->solicit to transmit a solicitation request. In the case of ARP, the solicit function (arp_solicit) is a simple wrapper around arp_send. arp_send fills in the ARP header and payload and uses the dev_queue_xmit function to transmit the request.


arp_rcv

Because ARP is a protocol in its own right (unlike ND for IPv6), it registers a handler in arp_init. The next section describes arp_rcv in detail, along with how the two main ARP packet types are processed.

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:

  • Bridging is configured. A bridge receiving an ARP packet may just forward it to other bridge interfaces without processing it.

  • The ingress packet is an ARPOP_REQUEST and the neighboring subsystem decides it can reply according to its configuration. The subsystem generates an ARPOP_REPLY.

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


28.8.2. Solicitations

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)


neigh

Neighbor whose L3 address needs to be resolved.


skb

Buffer holding the data packets whose transmission attempts triggered the generation of the solicitation request.

To understand the implementation of arp_solicit, it is important to understand the relationships and differences between the following two groups of parameters:

  • The source IP addresses in the IP header of the skb buffer, and the source IP address selected by arp_solicit to put in the ARP header (see Figure 28-1 for the ARP header format).

    When the traffic is generated locally, the source IP address in the IP header is local to the system. When the packet is being forwarded, the source IP address is that of the original sender.

  • The destination IP address in the IP header of the skb buffer, and the destination IP address that arp_solicit is asked to resolve (neigh->primary_key).

    The address that ARP is asked to resolve is the address of the next hop used to route skb. This matches the destination IP address in the IP header only when the next hop is also the final destination.

The main tasks of arp_solicit are:

  • Select the source IP address to put in the ARP header. This can be influenced by the ARP_ANNOUNCE configuration mentioned in the section "/proc Options." Figure 28-15 shows the internals of arp_solicit and in particular how the source IP address is selected.

  • Update the number of solicitation requests generated.

  • Transmit the solicitation using arp_send.

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:

  • For kernel-generated requests, the solicitation is transmitted with arp_send.

  • For user-space requests, arp_solicit makes a call to neigh_app_ns to notify the interested user-space application about the need to generate a solicitation request. If the kernel has not been compiled with support for ARPD, arp_solicit simply returns without making the solicitation request.

28.8.2.1. 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:


inet_addr_type

Given an IP address in input, this function returns the address type. In the context of this chapter, we are interested in the value RTN_LOCAL, which indicates an address that belongs to the local host.


inet_addr_onlink

Given a device and two IP addresses, this function checks whether the two addresses belong to the same subnet.


inet_select_addr

Given a device, an IP address (usually not local to the system), and a scope, this function searches the device configuration for an IP address that falls within the same subnet as the ingress address and with a scope that is the same or smaller. The scope typically covers a site, a link, or a host. An input address of 0 makes any primary address configured on the input device eligible for selection. You can find a more detailed description in Chapter 30.

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



Previous Page
Next Page