Processing of GRO at link layer in Section 8 of linux protocol stack Learning

Source: Internet
Author: User

Receiving matching function _ napi_gro_receive (napi, skb) of The Link Layer ):

This function matches messages and does not merge messages.

The matching rule must meet both of the following conditions ):

1. The received dev packets must be the same.

2. The two packets must have the same Ethernet header.


Static int _ napi_gro_receive (struct napi_struct * napi, struct sk_buff * skb) {struct sk_buff * p;/* traverses the skb mounted on the gro_list on the napi instance, set the same field */for (p = napi-> gro_list; p = p-> next) {NAPI_GRO_CB (p) -> same_flow = (p-> dev = skb-> dev )&&! Compare_ether_header (skb_mac_header (p), skb_gro_mac_header (skb); NAPI_GRO_CB (p)-> flush = 0;} return dev_gro_receive (napi, skb );}
Int dev_gro_receive (struct napi_struct * napi, struct sk_buff * skb) {struct sk_buff ** pp = NULL; struct packet_type * ptype; _ be16 type = skb-> protocol; struct list_head * head = & ptype_base [ntohs (type) & PTYPE_HASH_MASK]; int same_flow; int mac_len; int ret;/* If the receiving network device is set to not support GRO, no GRO merge processing */if (! (Skb-> dev-> features & NETIF_F_GRO) {goto normal;}/* If the ip address is a multipart packet, GRO is not processed, * In the ip layer, the ip segment packets are merged */if (skb_is_gso (skb) | skb_has_frags (skb) {goto normal ;} /* Add the RCU read lock to protect the ptype_base hahs linked list */rcu_read_lock ();/* The traversal chain table to find the ptype that processes this type of packets, * This type of ptype implements the gro processing function */list_for_each_entry_rcu (ptype, head, list) {if (ptype-> type! = Type | ptype-> dev |! Ptype-> gro_receive) continue;/* If found, initialize the packet header pointer, * and reset the private field used by GRO in skb, * These fields will be set in the GRO handler implemented by the corresponding protocol */skb_set_network_header (skb, skb_gro_offset (skb); mac_len = skb-> network> _header-skb-> mac_header; skb-> mac_len = mac_len; NAPI_GRO_CB (skb)-> same_flow = 0; NAPI_GRO_CB (skb)-> flush = 0; NAPI_GRO_CB (skb)-> free = 0; /* call the GRO processing function registered for this protocol type to process packets */pp = ptype-> gro_receive (& napi-> gro_list, skb); break;} rcu _ Read_unlock ();/* if the GRO for processing the protocol type message is not found, GRO operations are not performed */if (& ptype-> list = head) {goto normal;} same_flow = NAPI_GRO_CB (skb)-> same_flow; ret = NAPI_GRO_CB (skb)-> free? GRO_MERGED_FREE: GRO_MERGED;/* if the GRO processing function of the Protocol returns the merged packet, * Call napi_gro_complete to send the packet to the protocol stack for processing */if (pp) {struct sk_buff * nskb = * pp; * pp = nskb-> next; nskb-> next = NULL; napi_gro_complete (nskb); napi-> gro_count --;} /* if the same is set, it indicates that a matched message is found on the linked list. * The message has been merged and no longer needs to be cached */if (same_flow) {goto OK;}/* If the matched message is not found, it must be cached. * Determine whether the queue is full or whether the message should be cached */if (NAPI_GRO_CB (skb)-> flush | napi-> gro_count> = MAX_GRO_SKBS) {goto normal ;} /* No matched packets are cached to gro_list, and the returned value is GRO_HELD */napi-> gro_count ++; NAPI_GRO_CB (skb)-> count = 1; skb_shinfo (skb) -> gso_size = skb_gro_len (skb); skb-> next = napi-> gro_list; napi-> gro_list = skb; ret = GRO_HELD; pull: /* after GRO receive processing of this protocol stack, * the NAPI_GRO_CB (skb)-> data_offset field has been set. * If the data to be processed by GRO is not in the skb linear zone, * copy the required data to the linear zone to facilitate subsequent operations */if (skb_headlen (skb) <skb_gro_offset (skb )) {int grow = skb_gro_offset (skb)-skb_headlen (skb); BUG_ON (skb-> end-skb-> tail <group); memcpy (skb_tail_pointer (skb), NAPI_GRO_CB (skb) -> frag0, grow); skb-> tail + = grow; skb-> data_len-= grow; skb_shinfo (skb)-> frags [0]. page_offset + = grow; skb_shinfo (skb)-> frags [0]. size-= grow;/* if the data is moved to the linear zone, the first page is blank. * release null. Page and move the subsequent pages forward in turn */if (unlikely (! Skb_shinfo (skb)-> frags [0]. size) {put_page (skb_shinfo (skb)-> frags [0]. page); memmove (skb_shinfo (skb)-> frags, skb_shinfo (skb)-> frags + 1, (-- skb_shinfo (skb) -> nr_frags * sizeof (skb_frag_t);} OK: return ret; normal: ret = GRO_NORMAL; goto pull ;}

GRO completion function of Link Layer:


The merged packets call this function to send messages to the protocol stack.



Static int napi_gro_complete (struct sk_buff * skb) {struct packet_type * ptype; _ be16 type = skb-> protocol; struct list_head * head = & ptype_base [ntohs (type) & PTYPE_HASH_MASK]; int err =-ENOENT;/* if it has not been merged with other packets, * the protocol stack can be directly sent for processing */if (NAPI_GRO_CB (skb) -> count = 1) {skb_shinfo (skb)-> gso_size = 0; goto out ;} /* Find the grp_complete function for sending packets to the Protocol */rcu_read_lock (); list_for_each_entry_rcu (ptype, head, lis T) {if (ptype-> type! = Type | ptype-> dev |! Ptype-> gro_complete) continue; err = ptype-> gro_complete (skb); break;} rcu_read_unlock (); if (err) {WARN_ON (& ptype-> list = head); kfree_skb (skb); return NET_RX_SUCCESS;}/* Send the layer-Layer Protocol to the Protocol Stack for processing */out: return netif_receive_skb (skb );}


This article is from the "Yao Yang blog" blog, please be sure to keep this source http://yaoyang.blog.51cto.com/7657153/1303144

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.