Saturday, October 24, 2009

Section 29.3.  Data Structures Featured in This Part of the Book










29.3. Data Structures Featured in This Part of the Book


In the section "Main Data Structures" in Chapter 27, we had a brief overview of the main data structures used by the neighboring subsystem. This section presents a detailed description of each data structure's field.


Figure 29-4 shows the files that define each data structure. The ones with a lighter color are not part of the neighboring subsystem, but I referred to them in this part of the book.



Figure 29-4. Distribution of data structures in kernel files




29.3.1. neighbour Structure




















Neighbors are represented by struct neighbour structures. The structure is complex and includes status fields, virtual functions to interface with L3 protocols, timers, and cached L2 headers.


Here is a field-by-field description:



struct neighbour *next


Each neighbour enTRy is inserted in a hash table. next links the structure to the other ones that collide and share the same bucket. Elements are always inserted at the head of the list (see the section "Creating a neighbour Entry," and Figure 27-2 in Chapter 27).


struct neigh_table *tbl


Pointer to the neigh_table structure that defines the protocol associated with this entry. If the neighbor is an IPv4 address, for instance, tbl points to arp_tbl.


struct neigh_parms *parms


Parameters used to tune the neighboring protocol behavior. When a neighbour structure is created, parms is initialized with the values of the default neigh_parms structure embedded in the protocol's associated neigh_table structure. When the protocol's constructor method is called by neigh_create (e.g., arp_constructor for ARP), that block is replaced with the configuration block of the associated device, if any. While most devices use the system defaults, a device can start up with different parameters or be configured by the administrator later to use different parameters, as discussed earlier in this chapter.


struct net_device *dev


The device through which the neighbor is reachable. Only one device can be used to reach each neighbor. Thus, the value NULL never appears here as it does in other kernel subsystems that use it as a wildcard to refer to all devices.


unsigned long confirmed


Timestamp (in jiffies) when the reachability of the entry was most recently confirmed. L4 protocols can update it with neigh_confirm (see Figure 26-14 in Chapter 26). The neighboring infrastructure updates it in neigh_update, described in .


unsigned long updated


Timestamp of the most recent time the entry was updated by neigh_update (the only exception is the first initialization by neigh_alloc). Do not confuse updated and confirmed, which keep track of very different things. The updated field is set when the state of a neighbor changes, whereas the confirmed field merely records one particular change of state: the one that occurs when the entry was most recently confirmed to be valid.


unsigned long used


Most recent time the entry was used. Its value is not always updated synchronously with the data transmissions. When the entry is not in the NUD_CONNECTED state, this field is updated by neigh_event_send, which is called by neigh_resolve_output. In contrast, when the entry is in the NUD_CONNECTED state, its value is sometimes updated by neigh_periodic_timer to the time the entry's reachability was most recently confirmed.


_ _u8 flags


Possible values for this field are listed in include/linux/rtnetlink.h and include/net/neighbour.h:



#define NTF_PROXY 0x08


When the ip neigh user-space command is used to add entries to the proxy tables (for instance, ip neigh add proxy 10.0.0.2 dev eth0), this flag is set in the data structure sent to the kernel, to let the kernel handler neigh_add know that the new entry has to be added to the proxy table (see the section "System Administration of Neighbors").


#define NTF_ROUTER 0x80


This flag is used only by IPv6. When set, it means the neighbor is a router. Unlike NTF_PROXY, this flag is not set by user-space tools. The IPv6 neighbor discovery code updates its value when receiving information from the neighbor.


_ _u8 nud_state


Indicates the entry's state. The possible values are defined in include/net/neighbour.h and include/linux/rtnetlink.h with names of form NUD_XXX. The role of states is described in the section "Transitions Between NUD States" in Chapter 26. Figure 26-13 in Chapter 26 shows how the state changes depending on various events.


_ _u8 type


This parameter is set when the entry is created with neigh_create by calling the protocol constructor method (e.g., arp_constructor for ARP). Its value is used in various circumstances, such as to decide what value to give nud_state. type can assume the values in Table 36-12 in Chapter 36, listed in include/linux/rtnetlink.h.


In the context of this chapter, not all of the values of that table are actually used: we are mostly interested in RTN_UNICAST, RTN_LOCAL, RTN_BROADCAST, RTN_ANYCAST, and RTN_MULTICAST.


Given an IPv4 address (such as the L3 address associated with a neighbour entry), the inet_addr_type function finds the associated RTN_XXX value (see Chapter 28). For IPv6, there is a similar function called ipv6_addr_type.


_ _u8 dead


When dead is set to 1 it means the structure is being removed and cannot be used anymore. See neigh_ifdown in the section "External Events" in Chapter 32, and neigh_forced_gc and neigh_periodic_timer for examples of usage.


atomic_t probes


Number of failed solicitation attempts. Its value is checked by the neigh_timer_handler timer, which puts the neighbour entry into the NUD_FAILED state when the number of attempts reaches the maximum allowed value.


rwlock_t lock


Used to protect the neighbour structure from race conditions.


unsigned char ha[]


The L2 address (e.g., Ethernet MAC address for Ethernet NICs) associated with the L3 address represented by primary_key (discussed shortly). The address is in binary format. The size of the vector ha is MAX_ADDR_LEN (defined as 32 in include/linux/netdevice.h), rounded up to the first multiple of a C long. An Ethernet address requires only six octets (i.e., 48 bits), but other link layer protocols may require more. For each hardware address type, the kernel defines a symbol that is assigned the size of the address. Most symbols use names like XXX_ALEN or XXX_ADDR_LEN. Ethernet, for example, defines the ETH_ALEN symbol in include/linux/if_ether.h.


struct hh_cache *hh


List of cached L2 headers. See the section "L2 Header Caching" in Chapter 27.


atomic_t refcnt


Reference count. See the sections "Caching" and "Reference Counts on neighbour Structures" in Chapter 27.


int (*output)(struct sk_buff *skb)


Function used to transmit frames to the neighbor. The actual routine this function pointer points to can change several times during the structure's lifetime, depending on several factors. It is first initialized by the neigh_table's constructor method (see the section "Initialization of a neighbour Structure" in Chapter 28). It can be updated by calling neigh_connect or neigh_suspect when the neighbor state goes to NUD_REACHABLE or NUD_STALE state, respectively.


struct sk_buff_head arp_queue


Packets whose destination L3 address has not been resolved yet are temporarily placed into this queue. Despite the name of this field, it can be used by all neighboring protocols, not just ARP. See the section "Egress Queuing" in Chapter 27.


struct timer_list timer


Timer used to handle several tasks. See the section "Timers" in Chapter 15.


struct neigh_ops *ops


VFT containing the methods used to manipulate the neighbour entry. Among the methods, for instance, are several used to transmit packets, each optimized for a different state or associated device type. Each protocol provides three or four different VFTs; which is used for a specific neighbour entry depends on the type of L3 address, the type of associated device, and the type of link (e.g., point-to- point). See the upcoming section "neigh_ops Structure," and the section "Initialization of neigh->ops" in Chapter 27.


u8 primary_key[0];


L3 address of the neighbor. It is used as the key by the cache lookup functions. It is an IPv4 address for ARP entries and an IPv6 address for neighbor discovery entries.




29.3.2. neigh_table Structure








































This structure is used to tune the behavior of a neighboring protocol. There are a few instances of neigh_table in the kernel, each for a different protocol:



arp_tbl


ARP protocol used by IPv4 (see net/ipv4/arp.c)


nd_tbl


Neighbor discovery protocol used by IPv6 (see net/ipv6/ndisc.c)


dn_neigh_table


Neighbor discovery protocol used by DECnet (see net/decnet/dn_neigh.c)


clip_tbl


ATM over IP protocol (see net/atm/clip.c)


These neigh_table structures are initialized when the associated subsystems are initialized in the kernel, and are inserted into a global list pointed to by neigh_tables, as shown in Figure 27-2 in Chapter 27.


The data structures contain most (if not all) of the information required by the neighboring protocol. Therefore, each neighbour enTRy has a neigh->tbl pointer to its associated neigh_table; for instance, a neighbour entry associated with an IPv4 address will have a pointer to the arp_tbl structure, whereas an IPv6 entry will have a pointer to nd_tbl.


To understand the field-by-field descriptions more easily, refer to the initializations of the four tables as examplesin particular, arp_tbl, which is also discussed in the section "The arp_tbl Table" in Chapter 28.



struct neigh_table *next


Links all the protocol tables in a list.


rwlock_t lock


Lock used to protect the table from possible race conditions. It is used in read-only mode by functions such as neigh_lookup that only need read permission, and in read/write mode by other functions such as neigh_periodic_timer.


Note that the whole table is protected by a single lock, as opposed to something more granular such as a different lock for each bucket of the table's cache.


char *id


This is just a string that identifies the protocol. It is used mainly as an ID when allocating the memory pool used to allocate neighbour structures (see neigh_table_init).


struct proc_dir_entry *pde


File registered in /proc/net/stat/ to export statistics about the protocol. For instance, ARP creates /proc/net/stat/arp_cache. The file is created by neigh_table_init when the protocol is initialized.


int family


Address family of the entries represented by the neighboring protocol. Its possible values are listed in the file include/linux/socket.h, with names in the form AF_XXX. For IPv4 and IPv6, the associated values are AF_INET and AF_INET6, respectively.


int entry_size


Size of the structures inserted into the cache. Since a neighbour structure includes a field whose size depends on the protocol (primary_key), entry_size is set to the sum of the size of a neighbour structure and the size of the primary_key provided by the protocol. In the case of IPv4/ARP, for instance, this field is initialized to sizeof(struct neighbour) + 4, where 4 is, of course, the size in bytes of an IPv4 address. The field is used, for instance, by neigh_alloc when clearing the content of the entries retrieved from the cache.[*]

[*] When a neighbour structure is put back into the memory pool by neigh_destroy, its content is not cleared.


int key_len


Length of the key used by the lookup functions (see the section "Caching" in Chapter 27). Because the key is the L3 address, this is 4 for IPv4, 8 for IPv6, and 2 for DECnet.


_ _u32 (*hash)(const void *pkey, const struct net_device *)


Hash function applied to the search key (e.g., L3 address) to select the right bucket of the hash table when doing a lookup.


int (*constructor)(struct neighbour *)


The constructor method is invoked by neigh_create when creating a new entry, and initializes the protocol-specific fields of a new neighbour entry. For example, the one used by ARP (arp_constructor) is described in detail in the section "Initialization of a neighbour Structure" in Chapter 28.


struct neigh_parms parms


This data structure contains some parameters used to tune the behavior of the protocol, such as how much time to wait before resending a solicitation request after not receiving a reply, and how many packets to keep in a queue waiting for the reply before transmitting them. See the section "neigh_parms Structure."


struct neigh_parms *parms_list


Not used.


kmem_cache_t *kmem_cachep


Memory pool used when allocating neighbour structures. It is allocated and initialized at protocol initialization time by neigh_table_init. You can check its status by dumping the contents of the /proc/slabinfo file.


atomic_t entries


Number of neighbour instances currently in the protocol's cache. Its value is incremented when allocating a new entry with neigh_alloc and decremented when deallocating an entry with neigh_destroy. See the description of gc_thresh1, gc_thresh2, and gc_thresh3 later in this section.


unsigned long last_rand


Time (expressed in jiffies) when the variable reachable_time of the neigh_parms structures associated with the table (there is one for each device) was most recently updated.


struct neigh_statistics *stats


Various statistics about the neighbour instances in the cache. See the section "neigh_statistics Structure."


struct neighbour **hash_buckets


Hash table that stores the neighbour enTRies.


unsigned int hash_mask


Size of the hash table. See Figure 27-6 in Chapter 27.


_ _u32 hash_rnd


Random value used to distribute neighbour enTRies in the cache when its size is increased. See the section "Caching" in Chapter 27.


The following variables and functions are used by the garbage collection algorithm described in the section "Garbage Collection" in Chapter 27:



int gc_interval


This controls how often the gc_timer timer expires, kicking off garbage collection. It used to be 30 seconds but now it is shorter. The timer causes garbage collection on only one bucket of the hash table each time. See the section "Garbage Collection" in Chapter 27 for more information.


int gc_thresh1



int gc_thresh2



int gc_thresh3


These three thresholds define different levels of memory usage granted to the neighbour enTRies currently cached by the neighboring protocol.


unsigned long last_flush


This variable, measured in jiffies, represents the most recent time neigh_forced_gc was executed. In other words, it represents the most recent time a garbage collection process was forced because of low memory conditions.


struct timer_list gc_timer


Garbage collector timer. See the section "Garbage Collection" in Chapter 27.


unsigned int hash_chain_gc


Keeps track of the next bucket of the hash table the periodic garbage collector timer should scan. The buckets are scanned sequentially.


The following fields are used when the system acts as a proxy. See the section "Acting As a Proxy" in Chapter 27.



struct pneigh_entry **phash_buckets


Table that stores the L3 addresses that must be proxied.


int (*pconstructor)(struct pneigh_entry *)



void (*pdestructor)(struct pneigh_entry *)


pconstructor is the counterpart of constructor. Right now, only IPv6 uses pconstructor; it registers a specific multicast address when the associated device is first configured.


pdestructor is called when releasing a proxy entry. It is used only by IPv6 and undoes the work of the pconstructor method.


struct sk_buff_head proxy_queue


Received solicit requests (e.g., received ARPOP_REQUEST packets in the case of ARP) are queued into this queue when proxying is enabled and configured with a non-null proxy_delay delay. New elements are queued at the tail.


void (*proxy_redo)(struct sk_buff *skb)


Function that processes the solicit requests (e.g., ARPOP_REQUEST packets for ARP) after they are extracted from the proxy queue neigh_table->proxy_queue. See the section "Delayed Processing of Solicitation Requests" in Chapter 27.


struct timer_list proxy_timer


This timer is started when there is at least one element in proxy_queue. The handler that is executed when the timer expires is neigh_proxy_process. The timer is initialized at protocol initialization by neigh_table_init. Unlike the timer neigh_table->gc_timer, this one is not periodic and is started only if needed (for instance, a protocol might start it when the first element is added to proxy_queue). The section "Acting As a Proxy" in Chapter 27 describes why and when elements are queued to proxy_queue and how proxy_timer processes them.




29.3.3. neigh_parms Structure




































The neigh_parms data structure stores the configurable parameters of the neighboring protocol. For each configured L3 protocol that uses a neighbor protocol, there is one instance of neigh_parms for each device[*] plus one that stores the default values.

[*] This statement is not 100% correct. Because a neigh_parms structure is used to tune the behavior of a neighboring protocol, its presence is needed only if there is at least one device whose L3 configuration uses the neighboring subsystem.


Here is the field-by-field description:



struct neigh_parms *next


Pointer that links neigh_parms instances associated with the same protocol family. This means that each neigh_table has its own list of neigh_parms structures, one instance for each configured device (see Figure 27-2 in Chapter 27).


int (*neigh_setup)(struct neighbour *)


Initialization function used mainly by those devices that are still using the old neighboring infrastructure. This function is normally used just to initialize neighbour->ops to the arp_broken_ops instance (see the section "neigh_ops Structure" later in this chapter, and the section "Initialization of neigh->ops" in Chapter 27). Look at shaper_neigh_setup in drivers/net/shaper.c for an example. To see when this initialization function is called during the initialization phase of a new neighbour instance, see Figure 28-11 in Chapter 28.


Do not confuse this virtual function with net_device->neigh_setup. The latter is called when the first L3 address is configured on a device, and normally initializes neigh_parms->neigh_setup, too. net_device->neigh_setup is called only once for each device, and neigh_parms->neigh_setup is called once for each neighbour structure that will be associated with the device.


struct neigh_table *tbl


Back pointer to the neigh_table structure that holds this structure.


int entries



void *priv


Not used.


void *sysctl_table


This table, initialized at the end of the file net/ipv4/neighbour.c, is involved in allowing users to modify the values of those parameters of the neigh_parms data structure that are exported via /proc, as described in the section "Tuning via /proc Filesystem."


int base_reachable_time



int reachable_time


base_reachable_time is the interval of time (expressed in jiffies) since the most recent proof of reachability was received. Note that this interval is used as a base value to compute the real one, which is stored in reachable_time[*] and is given a random (and uniformly distributed) value ranging between base_reachable_time and 3/2 base_reachable_time. This random value is updated every 300 seconds by neigh_periodic_timer, but it can also be updated by other events (especially for IPv6).

[*] With ND/IPv6, reachable_time can also be explicitly exchanged between routers and hosts using a field in the protocol header.


int retrans_time


When a host does not receive a reply to a solicitation request within retrans_time, a new one is sent, up to a given number of maximum attempts. retrans_time is expressed in jiffies.


int gc_staletime


A neighbour structure is removed if it has not been used for gc_staletime time and no one holds a reference to it. gc_staletime is expressed in jiffies.


int delay_probe_time


This indicates how long a neighbor in the NUD_DELAY state waits before entering the NUD_PROBE state. See Figure 26-13 in Chapter 26.


int queue_len


Maximum number of elements that can be queued in the arp_queue queue.


int proxy_qlen


Maximum number of elements that can be queued in the proxy_queue queue.


int ucast_probes



int app_probes



int mcast_probes


ucast_probes is the number of unicast solicitations that can be sent to confirm the reachability of an address.


app_probes is the number of solicitations that can be sent by a user-space application when resolving an address (see the section "ARPD" in Chapter 28 for the IPv4/ARP case).


mcast_probes is the number of multicast solicitations that can be sent to resolve a neighbor's address. For ARP/IPv4, this is actually the number of broadcast solicitations, because ARP does not use multicast solicitations. IPv6 does.


Note that mcast_probes and app_probes are mutually exclusive (only one can be non-null).


int anycast_delay


Not used.


int proxy_delay


Amount of time (expressed in jiffies) that neighboring protocol packets handled by a proxy should be kept in a queue before being processed. See the section "Delayed Processing of Solicitation Requests" in Chapter 27.


int locktime


Minimum time, expressed in jiffies, that has to pass between two updates of the fields of a neighbour enTRy (typically nud_state and ha). This window helps avoid some nasty ping-pong effects that can take place, for instance, when more than one proxy ARP server is present on the same network segment and all of them reply to the same query solicitations with conflicting addresses. Details of this behavior are discussed in the section "Final Common Processing" in Chapter 28.


int dead


Boolean flag that is set to mark the neighbor instance as "Being removed." See neigh_parms_release.


atomic_t refcnt


Reference count.


struct rcu_head rcu_head


Used to take care of mutual exclusion.


The use of the reference count refcnt deserves a few more words. Please refer to Figure 27-2 in Chapter 27 during this discussion. Because there is an instance of neigh_parms per device per protocol, and one instance embedded in the neigh_table structure to hold the default values, plus a pointer in each neighbour structure, it may be confusing to understand who points to whom and who is who. Let's try to clarify these points.


Each neigh_table, and therefore each protocol, has its own instance of neigh_parms. That instance holds the default values that the protocol provides. Each device's net_device can be configured with more than one L3 protocol. For each L3 protocol configured, net_device has a pointer to a protocol-specific structure that stores the configuration (e.g., in_device for IPv4). That structure includes a pointer to an instance of neigh_parms that is used to store the device-specific configuration of the neighboring protocol used by the L3 protocol (e.g., ARP for IPv4).


Table 29-5 lists the main protocol initialization routines, which allocate neigh_parms structures. For the two IP protocols, you can see the result in Figure 29-3.


Table 29-5. L3 protocol init functions

Protocol

Function

File

IPv4

inetdev_init

net/ipv4/devinet.c

IPv6

ipv6_add_dev

net/ipv6/addrconf.c

DECnet

dn_dev_create

net/decnet/dn_dev.v



Let's stick to IPv4 for the rest of the description. The neigh_parms instance used by ARP is allocated by inetdev_init, the IPv4 routine called when an IPv4 configuration is first applied to a device. The initial content of the new neigh_parms instance is copied from neigh_table->parms, where neigh_table is arp_tbl for ARP. Whenever a neighbour instance in created, neigh->parms is initialized to point to the neigh_parms instance of the associated device. As we saw in the section "Tuning via /proc Filesystem," both the global defaults (neigh_table->parms) and the per-device configuration can be changed by the administrator.


Because each per-device neigh_parms structure is referenced by all the neighbour instances associated with the device, neigh_parms->refcnt is used to keep track of them. The routines that directly or indirectly update the reference count are:



neigh_parms alloc



neigh_parms_destroy


Allocate and destroy an instance of neigh_parms. neigh_parms_destroy is called only when the structure can be freed because the reference count is 0.


_ _neigh_parms_put



neigh_parms_put


_ _neigh_parms_put only decrements the reference count, and neigh_parms_put also invokes neigh_parms_destroy if the reference count becomes 0.


neigh_parms_release


Marks the instance as dead and indirectly invokes neigh_parms_put.


neigh_parms_clone


Increases the reference count on a structure and returns a pointer to it.


neigh_rcu_free_parms


Called by neigh_parms_release to actually delete the structure (here is where neigh_parms->rcu_head is used).




29.3.4. neigh_ops Structure









The neigh_ops structure consists of pointers to functions invoked at various times during the lifetime of a neighbour entry. Most of them are virtual functions that act as the interface between the L3 protocol and the dev_queue_xmit API introduced in Chapter 11. Some of them are provided by the overarching neighboring infrastructure (neigh_xxx functions), and others are provided by individual neighboring protocols (e.g., arp_xxx for ARP). See the section "Initialization of a neighbour Structure" in Chapter 28.


The main difference between the functions lies in the context where they are used. The section "Special Cases" in Chapter 26 covered the two most common cases.


Here is the field-by-field description:



int family


We already saw this field when describing the analogous family field of the neigh_table structure.


void (*destructor)(struct neighbour *)


Function executed when a neighbour entry is removed by neigh_destroy. It basically is the complementary method of neigh_table->constructor. But for some reason, constructor is in the neigh_table structure and destructor is in the neigh_ops structure.


void (*solicit)(struct neighbour *, struct sk_buff*)


Function used to send solicitation requests.


void (*error_report)(struct neighbour *, struct sk_buff*)


Function invoked when a neighbor is classified as unreachable. See the section "Events Generated by the Neighboring Layer" in Chapter 27.


The following four methods are used to transmit data packets, not neighboring protocol packets. The difference between them lies in the context where they are used. See the section "Common Interface Between L3 Protocols and Neighboring Protocols" in Chapter 27.



int (*output)(struct sk_buff*)


This is the most generic function and can be used in all the contexts. It checks if the address has already been resolved and starts the resolution in case it has not. If the address is not ready yet, it stores the packet in a temporary queue and starts the resolution. Because it does everything necessary to ensure the recipient is reachable, it is a relatively expensive operation. Do not confuse neigh_ops->output with neighbour->output.


int (*connected_output)(struct sk_buff*)


Used when the neighbor is known to be reachable (i.e., the state is NUD_CONNECTED). It simply fills in the L2 header, because all the required information is available, and therefore is faster than output.


int (*hh_output)(struct sk_buff*)


Used when the address is resolved and a copy of the whole header has already been cached from a previous transmission. See the section "Interaction Between Neighboring Protocols and L3 Transmission Functions" in Chapter 27.


int (*queue_xmit)(struct sk_buff*)


The previous functions, with the exception of hh_output, do not actually transmit the packets. All they do is make sure the header is compiled and call the queue_xmit method when the buffer is ready for transmission. See Figure 27-3(b) in Chapter 27.




29.3.5. hh_cache Structure












The data structure used to store a cached L2 header is struct hh_cache, defined in include/linux/netdevice.h. (The name comes from "hardware header.") The following is a description of its fields; the section "L2 Header Caching" in Chapter 27 describes how it is used.



unsigned short hh_type


Protocol associated with the L3 address (see the ETH_P_XXX values in the file include/linux/if_ether.h).


struct hh_cache *hh_next


More than one cached L2 header can be associated with the same neighbour entry. However, there can be only one entry for any given value of hh_type (see neigh_hh_init).


atomic_t hh_refcnt


Reference count.


int hh_len


Length of the cached header expressed in bytes.


int (*hh_output)(struct sk_buff *skb)


Function used to transmit the packet. As with neigh->output, this method is initialized to one of the methods of the neigh->ops VFT.


rwlock_t hh_lock


Lock used to protect the hh_cache structure from possible race conditions. For instance, an IP function that wants to transmit a packet (see the section "Interaction Between Neighboring Protocols and L3 Transmission Functions" in Chapter 27) acquires the read lock before copying the header from the hh_cache structure to the skb buffer. The lock is held in exclusive mode when a field of the structure needs to be updated: for instance, the lock is acquired when hh_output needs to be initialized to a different function[*] or when the hh_cache->hh_data header needs to be updated because the destination link layer address has changed.

[*] A good illustration of the use of the hh_lock field can be found in neigh_destroy in net/core/neighbour.c. Here the lock is used to handle the case of a neighbour entry that cannot be removed because its reference count number is nonzero.


unsigned long hh_data[HH_DATA_ALIGN(LL_MAX_HEADER) / sizeof(long)]


Cached header.




29.3.6. neigh_statistics Structure















This structure stores statistics about
the neighboring protocols, available for users to peruse. Each protocol keeps its own instance of the structure. This is the definition of the structure from include/net/neighbour.h. The following is a description of its fields:



unsigned long allocs


Total number of neighbour structures allocated by the protocol. Includes ones that have already been removed.


unsigned long destroys


Number of removed neighbour enTRies. Updated in neigh_destroy.


unsigned long hash_grows


Number of times that the hash table has been increased in size. Updated in neigh_hash_grow (see the section "Caching" in Chapter 27).


unsigned long res_failed


Number of times an attempt to resolve a neighbor address failed. This value is not incremented every time a new solicitation is sent; it is incremented by neigh_timer_handler only when all the attempts have failed.


unsigned long lookups


Number of times the neigh_lookup routine has been invoked.


unsigned long hits


Number of times neigh_lookup returned success.


unsigned long rcv_probes_mcast



unsigned long rcv_probes_ucast


These two fields are used only by IPv6 and represent the number of solicitation requests (probes) received that were sent to multicast and unicast addresses, respectively.


unsigned long periodic_gc_runs



unsigned long forced_gc_runs


The number of times neigh_periodic_timer and neigh_forced_gc have been invoked, respectively. See the section "Garbage Collection" in Chapter 27.


The kernel keeps an instance of these counters for each CPU. The counters are updated with the NEIGH_CACHE_STAT_INC macro, defined in include/net/neighbour.h. Note that the macro updates the counter on the current CPU.


The fields of the neigh_statistic structure are exported in the per-protocol /proc/net/stat/{protocol_name}_cache files.




29.3.7. Data Structures Featured in This Part of the Book


























Table 29-6 summarizes the main functions, variables, and data structures introduced or referenced in the chapters of this book covering the neighboring subsystem.


Table 29-6. Functions, variables, and data structures in the neighboring subsystem

Functions

Description

dev_queue_xmit

neigh_compat_output

neigh_resolve_output

neigh_connected_output

neigh_blackhole

Main routines used for packet transmission. See the section "Routines used for neigh->output" in Chapter 27.

neigh_update

neigh_update_hhs

neigh_sync

Update the information stored in a neighbour structure. See the section "Updating a Neighbor's Information: neigh_update" in Chapter 27.

neigh_confirm

Confirms the reachability of a neighbor.

neigh_create

neigh_destroy

Create and delete a neighbour structure as a consequence of protocol events. See the sections "Creating a neighbour Entry" and "Neighbor Deletion" in Chapter 27.

neigh_add

neigh_delete

Create and delete a neighbour structure as a consequence of a user-space command. See the section "System Administration of Neighbors."

neigh_alloc

Allocates a neighbour structure.

neigh_connect

neigh_suspect

Used to implement reachability. See the section "Initialization of neigh->output and neigh->nud_state" in Chapter 27.

neigh_table_init

Registers a neighboring protocol.

neigh_ifdown

Handles changes of state in the L3 address when notified by external subsystems. See the section "Updates via neigh_ifdown" in Chapter 27.

neigh_proxy_process

Function handler executed when the proxy timer expires. See the section "Delayed Processing of Solicitation Requests" in Chapter 27.

neigh_timer_handler

See the section "Timers" in Chapter 15.

neigh_periodic_timer

neigh_forced_gc

Used by the garbage collection algorithm. See the section "Garbage Collection" in Chapter 27.

neigh_lookup

_ _neigh_lookup

_ _neigh_lookup_errno

arp_find

Check for an entry in the cache. See the section "Caching" in Chapter 27.

neigh_hold

neigh_release

Increment/decrement the reference count on a neighbour structure.

pneigh_enqueue

pneigh_lookup

Used for destination-based proxying. See the sections "Delayed Processing of Solicitation Requests" and "Per-Device Proxying and Per-Destination Proxying" in Chapter 27, and the section "Proxy ARP" in Chapter 28.

arp_rcv

ndisc_rcv

Protocol handlers for ARP and ND packets, respectively.

ip_finish_output2

ip6_output_finish

Transmission functions for IPv4 and IPv6, respectively. See the section "Interaction Between Neighboring Protocols and L3 Transmission Functions" in Chapter 27.

neigh_hh_init

Initializes an hh_cache structure with an L2 header and binds it to the associated routing table cache entry. See the section "Link Between Routing and L2 Header Caching" in Chapter 27.

Variables

 

neigh_tables

List of registered protocols.

arp_tbl

nd_tbl

dn_neigh_table

clip_tbl

The four neigh_table structures that define the four neighboring protocols implemented in the kernel.

Data structures

 

struct neighbour

struct neigh_table

struct neigh_parms

struct neigh_ops

struct hh_cache

struct neigh_statistics

Main data structures, described in Chapter 27 and detailed in reference style in the section "Functions and Variables Featured in This Part of the Book."














No comments:

Post a Comment