Linux kernel Analysis

Source: Internet
Author: User
Tags data structures goto htons

Kernel version: 2.6.34

This section focuses on three core data structures-the neighbor table, the neighbor cache, the Proxy neighbor table, and the Nud state transition diagram.

In general, to successfully add a neighbor table entry, you need to meet two conditions: 1. This table entry is used by this machine; 2. The other host is confirmed. Also, the addition of table entries introduces the Nud (neighbour unreachability detection) mechanism, which requires a series of state transitions from creating nud_none to usable nud_reachable, depending on the order of two conditions, Can be divided into two lines:

Reference and reconfirm-Nud_none-> nud_incomplete-> nud_reachable

First confirm re-reference-Nud_none-> nud_stale-> nud_delay-> nud_probe-> nud_reachable

The following or starting from the receive function, when the matching number protocol number is 0x0806, will invoke the ARP module's receive function ARP_RCV ().

ARP_RCV () ARP receive function

The first is to check the ARP protocol header, such as whether the size is sufficient, the number of the head is correct, and here skip the code, directly downward look. Each protocol is handled in the same way, if it is occupied by multiple protocols, a copy is copied.

if ((SKB = Skb_share_check (SKB, 

gfp_atomic)) = = NULL)     
 goto Out_of_mem;

NEIGH_CB (SKB) is actually SKB->CB, declared in SKB as U8 char[48], as the private data area (control buffer) for each protocol module, where private data can be stored in each protocol module according to its own requirements. The ARP module takes advantage of its storage control structure NEIGHBOUR_CB, which is declared as follows, accounting for 8 bytes. The control structure works when working queues are used in proxy ARP, and the Sched_next represents the next scheduled time, flags are flags.

memset (NEIGH_CB (SKB), 0, sizeof (struct NEIGHBOUR_CB));     
struct NEIGHBOUR_CB {     
 unsigned long sched_next;     
 unsigned int flags;     

The function finally invokes the arp_process, in which the NetFilter is inserted (for NetFilter, see previous: http://hi.csdn.net/link.php? url=http://blog.csdn.net% 2fqy532846454), as a starting point for dealing with ARP messages.

Return Nf_hook (Nfproto_arp, nf_arp_in, SKB, Dev, NULL, arp_process);

Arp_process ()

This function begins to process the message, first from the SKB to remove the ARP header part of the information, such as Sha, sip, tha, tip, and so on, this part of the code can be read, here skip. ARP does not query the loop address and multicast address because they do not have a corresponding MAC address, so they encounter both types of addresses and exit directly.

if (Ipv4_is_loopback (tip) 

| | ipv4_is_multicast (TIP))     
 goto out;

If a duplicate address detection message is received and the computer occupies the detected address, the call Arp_send sends the response. For the duplicate Address detection message (the source IP in the ARP message is all 0), it has a neighbor table entry information that has not yet been detected, and it obviously doesn't make sense to cache it, and there may be other hosts declaring it illegal at the next moment, so the information in the duplicate address detection message is not added to the neighbor table.

if (sip = = 0) {     
 if (Arp->ar_op = = htons (arpop_request) &&     
  inet_addr_type (NET, tip) = = Rtn_local &&A MP;     
  ! Arp_ignore (In_dev, sip, Tip))     
  arp_send (arpop_reply, eth_p_arp, sip, dev, Tip, Sha, Dev->dev_addr, SHA);     
 goto out;     
}

The address resolution message to be processed below, and the address to resolve is present in the routing table

if (Arp->ar_op = = htons

(arpop_request) &&     
 ip_route_input (SKB, Tip, sip, 0, dev) = = 0)

In the first case, if you want to resolve the native address, call Neigh_event_ns () and send an ARP response message based on the neighbor table entry n that is found. The Neigh_event_ns function here is to find out if the address information for the other host is already included in the ARP_TBL, if not, create it, and then invoke Neigh_update to update the status. Receiving the request message from the other host will cause the state to migrate to Nud_stale.

if (Addr_type = = rtn_local) {     
 ...     
 if (!dont_send) {     
  n = Neigh_event_ns (&arp_tbl, Sha, &sip, Dev);     
  if (n) {     
   arp_send (Arpop_reply,eth_p_arp,sip,dev,tip,sha,dev->dev_addr,sha);     
   Neigh_release (n);     
  }     
 }     
 goto out;     
}

#NUD_INCOMPLETE也迁移到NUD_STALE, what's the explanation?

In the second case, if you want to resolve is not a native address, you have to determine whether to support forwarding, whether or not to support proxy ARP (proxy ARP is the function of the land by the device, so can be forwarded is the prerequisite), if the conditions, then the agent ARP process to deal with. First of all, the host has access to such a neighbor, so to find it in ARP_TBL and (if it does not exist) to create the corresponding neighbor table entry, and then, for Proxy ARP, the process actually executes two times, takes the else part first, and the second passes the if part. The first else code snippet triggers the timer, triggers the message through the timer, and then executes the arp_process function, and goes to the if part.

-The else part of the first time: Invoke Pneigh_enqueue () to add the message SKB to the Tbl->proxy_queue queue, set the value of NEIGH_CB (SKB), and see the proxy table entries that you see later.

-The second time if part, sends the ARP response message, exercises the proxy arp the function.

else if (In_dev_forward (In_dev)) {     
 if Addr_type = = Rtn_unicast  &&     
  (Arp_fwd_proxy (In_dev, DEV, RT) ||     
  Arp_fwd_pvlan (In_dev, Dev, rt, sip, Tip) | |     
  Pneigh_lookup (&ARP_TBL, net, &tip, Dev, 0))     
 {     
  n = Neigh_event_ns (&arp_tbl, Sha, &sip, Dev);     
  if (n)     
   neigh_release (n);     
         
  if (NEIGH_CB (SKB)->flags & locally_enqueued | |     
   Skb->pkt_type = = Packet_host | |     
   In_dev->arp_parms->proxy_delay = = 0) {     
   arp_send (arpop_reply,eth_p_arp,sip,dev,tip,sha,dev->dev_addr , SHA);     
  } else {     
   pneigh_enqueue (&arp_tbl, in_dev->arp_parms, SKB);     
   In_dev_put (In_dev);     
   return 0;     
  }     
  goto out;     
 }     
}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.