嵌入式linux中文站在线图书

Previous Page
Next Page

28.6. ARP Protocol Initialization

The ARP protocol is initialized by arp_init in net/ipv4/arp.c.

The skeleton of a general protocol initialization routine was shown in the section "Protocol Initialization and Cleanup" in Chapter 27. In this chapter we'll examine what is ARP-specific.

The first step in the function is to register a table of virtual functions and other general parameters used by ARP; this is done by neigh_table_init. The contents of the table, arp_tbl, are described in the next section.

We saw in Chapter 13 how dev_add_pack is used to install a protocol handler. If you remember how that routine is used, from the following definition of arp_packet_type it should be clear that ARP packets will be processed by the arp_rcv function (defined in the same net/ipv4/arp.c file).

static struct packet_type arp_packet_type = {
    .type:    _ _constant_htons(ETH_P_ARP),
    .func:    arp_rcv,
};

arp_proc_init creates the /proc/net/arp file, which can be read to see the contents of the ARP cache (including proxy destinations).

Figure 28-10. arp_fwd_proxy function


When the kernel is compiled with support for sysctl, the directory /proc/sys/net/ipv4/neigh is created to export the default tuning parameters of the neigh_parms structure by means of neigh_sysctl_register. Note that the first input parameter to the latter is set to NULL, which, as we will see in the section "Directory creation," in Chapter 29, means that the caller (arp_init) wants to register the default directory.

register_netdevice_notifier registers a callback function with the kernel to receive notifications about changes to the configurations and status of devices. See the section "External Events" for more details.

28.6.1. The arp_tbl Table

This is the basic data structure that contains essential variables to which the ARP protocol refers. The role of the structure, which is of type neigh_table, was described in the section "Main Data Structures" in Chapter 27. ARP initializes its table as follows:

struct neigh_table arp_tbl = {
    .family:      AF_INET,
    .entry_size:  sizeof(struct neighbour) + 4,
    .key_len:     4,
    .hash:        arp_hash,
    .constructor: arp_constructor,
    .proxy_redo:  parp_redo,
    .id:          "arp_cache",
    .parms: {
        .tbl:            &arp_tbl,
        .base_reachable_time: 30 * HZ,
        .retrans_time:        1 * HZ,
        .gc_staletime:        60 * HZ,
        .reachable_time:      30 * HZ,
        .delay_probe_time:    5 * HZ,
        .queue_len:           3,
        .ucast_probes:        3,
        .mcast_probes:        3,
        .anycast_delay:       1 * HZ,
        .proxy_delay:         (8 * HZ) / 10,
        .proxy_qlen:          64,
        .locktime:            1 * HZ,
    },
    .gc_interval:   30 * HZ,
    .gc_thresh1:    128,
    .gc_thresh2:    512,
    .gc_thresh3:    1024,
};

As an example of the significance of these fields, the value of the base_reachable_time field (described in the section "neigh_parms Structure" in Chapter 29) indicates that ARP considers an entry NUD_REACHABLE only if the last proof of reachability arrived within the last 30 seconds. Similarly, the retrans_time field (described in the same section) indicates that if no reply is received to a solicitation, a new one will be sent after 1 second.

In the following sections, we'll examine the hash, constructor, and proxy_redo methods. We will also see how arp_rcv processes ingress ARP packets.


Previous Page
Next Page