Linux kernel Analysis

Source: Internet
Author: User
Tags continue goto

Kernel version: 2.6.34

This is about the IP layer protocol to receive the message processing, highlighting the routing table lookup, and IP fragmentation reorganization.

IP_RCV into IP Shong receive function

Discard the message is not sent to this machine, skb->pkt_type in the network card receiving packet processing Ethernet head will be based on DST Mac settings, the protocol stack book will not be sent to the local broadcast message would be discarded in the two layer, actually discarded is occurring in the beginning of the upper level.

if (skb-

>pkt_type = = packet_otherhost)     
 goto drop;

Note that you may have options when you take the IP header, so the message length should be IPH->IHL * 4. Here you need to try two times, the first attempt to sizeof (struct IPHDR), just to make sure that the SKB can accommodate the standard header (20 bytes), and then Ip_hdr (SKB) to get the header, and the second attempt IHL * 4, which is the true length of the message, Then call IP_HDR (SKB) again to get the header. The reason to recall Ip_hdr () after two attempts pull is that pskb_may_pull () may invoke __pskb_pull_tail () to alter the existing SKB structure.

if (!pskb_may_pull (SKB, sizeof (struct 

iphdr))     
 goto Inhdr_error;     
IPH = IP_HDR (SKB);     
..... if (!pskb_may_pull (SKB, iph->ihl*4))     
 goto Inhdr_error;     
IPH = IP_HDR (SKB);

After obtaining the IP header after some checks, get to the total length of the message Len = Iph->tot_len, at this time call Pskb_trim_rcsum () to remove the extra bytes, that is, greater than Len.

if (Pskb_trim_rcsum (SKB, Len)) {     
 ip_inc_stats_bh (dev_net (Dev), ipstats_mib_indiscards);     
 goto drop;     
}

Then call Ip_rcv_finish () to continue the processing of the IP layer, IP_RCV () can be seen as the IP layer processing before the route is found, and the next Ip_rcv_finish () will look for the routing table, which calls the inserted netfilter (about NetFilter, Refer to the previous article http://blog.csdn.net/qy532846454/article/details/6605592).

Return Nf_hook (Pf_inet, nf_inet_pre_routing, SKB, Dev, NULL, ip_rcv_finish);

Enter Ip_rcv_finish function

Ip_rcv_finish () The main task is to complete the routing table query, the decision message after the IP layer processing, is to continue to pass up, or forwarding, or discard.

No routing Table query was started, so there is no corresponding routing table entry: SKB_DST (SKB) = NULL. Ip_route_input () is found in the routing table, and the routing table for the kernel can be seen in the preceding article http://blog.csdn.net/qy532846454/article/details/6726171:

if (SKB_DST (SKB) = = NULL) {     
 int err = Ip_route_input (SKB, Iph->daddr, Iph->saddr, Iph->tos, Skb->dev     
  
     );     
 if (unlikely (err)) {     
  if (err = =-ehostunreach)     
   ip_inc_stats_bh (Dev_net (Skb->dev),     
     ipstats_mib_ inaddrerrors);     
  else if (err = =-enetunreach)     
   ip_inc_stats_bh (Dev_net (Skb->dev),     
     ipstats_mib_innoroutes);     
  goto drop;     
 }     
}

By routing table lookup, we know:

-If the message is discarded, direct drop;

-If the message is not received or forwarded, then input = Ip_error

-If it is sent to the native message, input = Ip_local_deliver;

-If the broadcast message, then input = Ip_local_deliver;

-If it is a group broadcast text, input = Ip_local_deliver;

-If the message is forwarded, then input = Ip_forward;

At the end of Ip_rcv_finish (), the found Route entry _skb_dst->input () is called to continue to pass up:

Return Dst_input (SKB);

Specific look at the message delivery under various circumstances, if it is discarded messages, the message is released, and from the IP protocol layer back to complete the message delivery process.

Drop:     
 kfree_skb (SKB);     
 return net_rx_drop;

If the message is not processed, execute ip_error and send the corresponding ICMP error message according to the error type.

 static int ip_error (struct sk_buff *skb) {struct rtable *rt = skb_rtable (SKB);     
 unsigned long now;     
         
 int code;     
  Switch (rt->u.dst.error) {case EINVAL:default:goto out;     
   Case ehostunreach:code = Icmp_host_unreach;     
  Break     
   Case enetunreach:code = Icmp_net_unreach;     
   IP_INC_STATS_BH (Dev_net (Rt->u.dst.dev), ipstats_mib_innoroutes);     
  Break     
   Case eacces:code = icmp_pkt_filtered;     
 Break     
 now = jiffies;     
 Rt->u.dst.rate_tokens + + now-rt->u.dst.rate_last;     
 if (Rt->u.dst.rate_tokens > Ip_rt_error_burst) rt->u.dst.rate_tokens = Ip_rt_error_burst;     
 Rt->u.dst.rate_last = Now;     
  if (Rt->u.dst.rate_tokens >= ip_rt_error_cost) {rt->u.dst.rate_tokens-= Ip_rt_error_cost;     
 Icmp_send (SKB, Icmp_dest_unreach, code, 0); } out:kfree_skb (SKB);     
 return 0; }

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.