29.2. Tuning via /proc FilesystemAs we saw in an earlier chapter, the neighboring protocols follow the common kernel practice of offering a convenient interface in the /proc directory to let administrators tune the subsystem's parameters. The neighboring subsystem 's parameters reside in four directories, two for IPv4 and two for IPv6:
Each directory contains a subdirectory for each NIC device on the system, a default subdirectory, and (in the case of the conf directory) an all subdirectory that can be used to apply a change to all the devices at once. Under conf, the default subdirectory shows the global status of each feature, while under neigh, the default subdirectory shows the default setting (i.e., configuration parameters) of each feature. The values of the default subdirectories are used to initialize the per-device subdirectories when the latter are created. The directories for individual devices take precedence over the more general directories. But not all devices pay attention to all the parameters; if a parameter is not relevant to a device, the associated directory contains a file for the parameter but the kernel ignores it. For instance, the gc_thresh1 value is not used by any protocol, and only IPv4 uses locktime. Figure 29-3 shows the layout of the files and the routines that register them. The three files arp, arp_cache, and ndisc_cache at the top-right corner of Figure 29-3 are not used to configure anything, but just to export read-only data. Note that they are in the /proc/net directory, not in /proc/sys. /proc/net/arp is used by the arp command to dump the contents of the ARP cache (there is no counterpart for ND), as discussed in the section "Old-Generation Tool: net-tools's arp Command." The /proc/net/stat/xxx_cache files export statistics about the protocol caches. Most of their files represent fields of neigh_statistics structures, described in the section "neigh_statistics Structure." 29.2.1. The /proc/sys/net/ipv4/neigh DirectoryThis directory contains parameters from neigh_parms structures, which were introduced in Chapter 27. As that chapter explained, each device has one neigh_parms structure for each neighboring protocol that it interacts with (see Figure 27-2 in Chapter 27). We have also seen that another neigh_parms instance is included in the neigh_table structure to store default values. However, not all fields of the neigh_parms structure are exported to /proc. For instance, reachable_time is a derived field whose value is indirectly calculated from base_reachable_time and therefore cannot be changed by the user. In addition, tbl and neigh_setup are used by the kernel to organize its data structures and do not have anything to do with the protocol itself, so they are not exported. In addition to exporting most of the parameters in the neigh_parms structure to /proc, the neighboring subsystem exports a few from the neigh_table structure, too. 29.2.1.1. Initialization of global and per-device directoriesBecause the default values are provided by the protocol itself, the default subdirectory is installed when the protocol is initialized (see the arp_init and ndisc_init functions) and populated with files whose names are based on those of the associated fields in the neigh_parms structure. You can find the default values of the fields in Table 29-3 directly in the initializations of the xxx_tbl tables; Chapter 28 shows an example for ARP. Figure 29-3. Example of /proc/sys file registration for the neighboring subsystem![]() The relationships between the kernel variables and the names of the files in /proc/sys/net/ipv4/neigh/xxx/ are shown in Table 29-3. See the initialization of neigh_sysctl_template in net/core/neighbour.c; a guide to reading the template is in Chapter 3.
Each device's directories are created when the device is first configured. The first time an address is configured on device D, a directory with the name D is created under /proc/sys/net/ipv4/neigh. All of the parameters apply to the device rather than to a specific address, so there is only a single directory for each device, even if it is configured with multiple addresses. Figure 29-3 shows the directory tree you would see if a host had three devices named eth0, eth1, and eth2; if eth0 and eth1 had been given IPv4 addresses; if eth0 had also been given an IPv6 address; and if eth2 has not been configured yet. The two functions in charge of configuring IPv4 and IPv6 devices are inetdev_init and ip6_add_dev, respectively. Each calls neigh_sysctl_register to create the device's subdirectory under /proc, as described in the following section. 29.2.1.2. Directory creationBoth the default and the per-device directories in /proc/sys/net/ipv4/neigh are created with the neigh_sysctl_register function. The latter differentiates between the two cases by using the value of the input parameter dev. If we take IPv4 as an example, you can compare the way arp_init (a protocol initialization function) and inetdev_init (a device's configuration block initializer) call neigh_sysctl_register. neigh_sysctl_register needs to differentiate between the two cases to:
Here is the meaning of the input parameters to neigh_sysctl_register:
The only tricky part in the function is how the four gc_xxx parameters are extracted from the neigh_table structure. It relies on a trick of memory layout: the four parameters related to garbage collection are stored in the neigh_table structure right after the neigh_parms structure, as shown here: struct neigh_table ... struct neigh_parms parms; int gc_interval; int gc_thresh1; int gc_thresh2; int gc_thresh3; ... Thus, all the function needs to do to retrieve the neigh_table values is to go past neigh_parms, cast the pointer to an integer, and extract four integers in a row: if (dev) { dev_name_source = dev->name; t->neigh_dev[0].ctl_name = dev->ifindex; memset(&t->neigh_vars[12], 0, sizeof(ctl_table)); } else { t->neigh_vars[12].data = (int *)(p + 1); t->neigh_vars[13].data = (int *)(p + 1) + 1; t->neigh_vars[14].data = (int *)(p + 1) + 2; t->neigh_vars[15].data = (int *)(p + 1) + 3; } 29.2.2. The /proc/sys/net/ipv4/conf DirectoryThe files in the /proc/sys/net/ipv4/conf subdirectories are associated with the fields of the ipv4_devconf structure, which is defined in include/linux/inetdevice.h. Not all of its fields are used by the neighboring protocols (see Chapters 23 and 36 for the other fields). Table 29-4 lists the parameters relevant to the neighboring protocols; their meanings were described in the section "Tunable ARP Options" in Chapter 28.
As shown in Figure 29-3, in addition to the per-device subdirectories, there are also two special ones named default and all. See Chapter 36 for more details. |