Loading include/linux/netdevice.h +1 −4 Original line number Diff line number Diff line Loading @@ -2169,13 +2169,10 @@ struct napi_gro_cb { /* Used in GRE, set in fou/gue_gro_receive */ u8 is_fou:1; /* Used to determine if flush_id can be ignored */ u8 is_atomic:1; /* Number of gro_receive callbacks this packet already went through */ u8 recursion_counter:4; /* 1 bit hole */ /* 2 bit hole */ /* used to support CHECKSUM_COMPLETE for tunneling protocols */ __wsum csum; Loading net/core/dev.c +1 −1 Original line number Diff line number Diff line Loading @@ -4568,6 +4568,7 @@ static void gro_list_prepare(struct napi_struct *napi, struct sk_buff *skb) unsigned long diffs; NAPI_GRO_CB(p)->flush = 0; NAPI_GRO_CB(p)->flush_id = 0; if (hash != skb_get_hash_raw(p)) { NAPI_GRO_CB(p)->same_flow = 0; Loading Loading @@ -4659,7 +4660,6 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff NAPI_GRO_CB(skb)->encap_mark = 0; NAPI_GRO_CB(skb)->recursion_counter = 0; NAPI_GRO_CB(skb)->is_fou = 0; NAPI_GRO_CB(skb)->is_atomic = 1; NAPI_GRO_CB(skb)->gro_remcsum_start = 0; /* Setup for GRO checksum validation */ Loading net/ipv4/af_inet.c +12 −24 Original line number Diff line number Diff line Loading @@ -1362,7 +1362,6 @@ struct sk_buff **inet_gro_receive(struct sk_buff **head, struct sk_buff *skb) for (p = *head; p; p = p->next) { struct iphdr *iph2; u16 flush_id; if (!NAPI_GRO_CB(p)->same_flow) continue; Loading @@ -1388,34 +1387,23 @@ struct sk_buff **inet_gro_receive(struct sk_buff **head, struct sk_buff *skb) NAPI_GRO_CB(p)->flush |= flush; /* We need to store of the IP ID check to be included later * when we can verify that this packet does in fact belong * to a given flow. /* For non-atomic datagrams we need to save the IP ID offset * to be included later. If the frame has the DF bit set * we must ignore the IP ID value as per RFC 6864. */ flush_id = (u16)(id - ntohs(iph2->id)); /* This bit of code makes it much easier for us to identify * the cases where we are doing atomic vs non-atomic IP ID * checks. Specifically an atomic check can return IP ID * values 0 - 0xFFFF, while a non-atomic check can only * return 0 or 0xFFFF. */ if (!NAPI_GRO_CB(p)->is_atomic || !(iph->frag_off & htons(IP_DF))) { flush_id ^= NAPI_GRO_CB(p)->count; flush_id = flush_id ? 0xFFFF : 0; } if (iph2->frag_off & htons(IP_DF)) continue; /* If the previous IP ID value was based on an atomic * datagram we can overwrite the value and ignore it. /* We must save the offset as it is possible to have multiple * flows using the same protocol and address pairs so we * need to wait until we can validate this is part of the * same flow with a 5-tuple or better to avoid unnecessary * collisions between flows. */ if (NAPI_GRO_CB(skb)->is_atomic) NAPI_GRO_CB(p)->flush_id = flush_id; else NAPI_GRO_CB(p)->flush_id |= flush_id; NAPI_GRO_CB(p)->flush_id |= ntohs(iph2->id) ^ (u16)(id - NAPI_GRO_CB(p)->count); } NAPI_GRO_CB(skb)->is_atomic = !!(iph->frag_off & htons(IP_DF)); NAPI_GRO_CB(skb)->flush |= flush; skb_set_network_header(skb, off); /* The above will be needed by the transport layer if there is one Loading net/ipv4/tcp_offload.c +1 −15 Original line number Diff line number Diff line Loading @@ -230,7 +230,7 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb) found: /* Include the IP ID check below from the inner most IP hdr */ flush = NAPI_GRO_CB(p)->flush; flush = NAPI_GRO_CB(p)->flush | NAPI_GRO_CB(p)->flush_id; flush |= (__force int)(flags & TCP_FLAG_CWR); flush |= (__force int)((flags ^ tcp_flag_word(th2)) & ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH)); Loading @@ -239,17 +239,6 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb) flush |= *(u32 *)((u8 *)th + i) ^ *(u32 *)((u8 *)th2 + i); /* When we receive our second frame we can made a decision on if we * continue this flow as an atomic flow with a fixed ID or if we use * an incrementing ID. */ if (NAPI_GRO_CB(p)->flush_id != 1 || NAPI_GRO_CB(p)->count != 1 || !NAPI_GRO_CB(p)->is_atomic) flush |= NAPI_GRO_CB(p)->flush_id; else NAPI_GRO_CB(p)->is_atomic = false; mss = skb_shinfo(p)->gso_size; flush |= (len - 1) >= mss; Loading Loading @@ -318,9 +307,6 @@ static int tcp4_gro_complete(struct sk_buff *skb, int thoff) iph->daddr, 0); skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4; if (NAPI_GRO_CB(skb)->is_atomic) skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_FIXEDID; return tcp_gro_complete(skb); } Loading net/ipv6/ip6_offload.c +0 −7 Original line number Diff line number Diff line Loading @@ -237,15 +237,8 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, /* flush if Traffic Class fields are different */ NAPI_GRO_CB(p)->flush |= !!(first_word & htonl(0x0FF00000)); NAPI_GRO_CB(p)->flush |= flush; /* If the previous IP ID value was based on an atomic * datagram we can overwrite the value and ignore it. */ if (NAPI_GRO_CB(skb)->is_atomic) NAPI_GRO_CB(p)->flush_id = 0; } NAPI_GRO_CB(skb)->is_atomic = true; NAPI_GRO_CB(skb)->flush |= flush; skb_gro_postpull_rcsum(skb, iph, nlen); Loading Loading
include/linux/netdevice.h +1 −4 Original line number Diff line number Diff line Loading @@ -2169,13 +2169,10 @@ struct napi_gro_cb { /* Used in GRE, set in fou/gue_gro_receive */ u8 is_fou:1; /* Used to determine if flush_id can be ignored */ u8 is_atomic:1; /* Number of gro_receive callbacks this packet already went through */ u8 recursion_counter:4; /* 1 bit hole */ /* 2 bit hole */ /* used to support CHECKSUM_COMPLETE for tunneling protocols */ __wsum csum; Loading
net/core/dev.c +1 −1 Original line number Diff line number Diff line Loading @@ -4568,6 +4568,7 @@ static void gro_list_prepare(struct napi_struct *napi, struct sk_buff *skb) unsigned long diffs; NAPI_GRO_CB(p)->flush = 0; NAPI_GRO_CB(p)->flush_id = 0; if (hash != skb_get_hash_raw(p)) { NAPI_GRO_CB(p)->same_flow = 0; Loading Loading @@ -4659,7 +4660,6 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff NAPI_GRO_CB(skb)->encap_mark = 0; NAPI_GRO_CB(skb)->recursion_counter = 0; NAPI_GRO_CB(skb)->is_fou = 0; NAPI_GRO_CB(skb)->is_atomic = 1; NAPI_GRO_CB(skb)->gro_remcsum_start = 0; /* Setup for GRO checksum validation */ Loading
net/ipv4/af_inet.c +12 −24 Original line number Diff line number Diff line Loading @@ -1362,7 +1362,6 @@ struct sk_buff **inet_gro_receive(struct sk_buff **head, struct sk_buff *skb) for (p = *head; p; p = p->next) { struct iphdr *iph2; u16 flush_id; if (!NAPI_GRO_CB(p)->same_flow) continue; Loading @@ -1388,34 +1387,23 @@ struct sk_buff **inet_gro_receive(struct sk_buff **head, struct sk_buff *skb) NAPI_GRO_CB(p)->flush |= flush; /* We need to store of the IP ID check to be included later * when we can verify that this packet does in fact belong * to a given flow. /* For non-atomic datagrams we need to save the IP ID offset * to be included later. If the frame has the DF bit set * we must ignore the IP ID value as per RFC 6864. */ flush_id = (u16)(id - ntohs(iph2->id)); /* This bit of code makes it much easier for us to identify * the cases where we are doing atomic vs non-atomic IP ID * checks. Specifically an atomic check can return IP ID * values 0 - 0xFFFF, while a non-atomic check can only * return 0 or 0xFFFF. */ if (!NAPI_GRO_CB(p)->is_atomic || !(iph->frag_off & htons(IP_DF))) { flush_id ^= NAPI_GRO_CB(p)->count; flush_id = flush_id ? 0xFFFF : 0; } if (iph2->frag_off & htons(IP_DF)) continue; /* If the previous IP ID value was based on an atomic * datagram we can overwrite the value and ignore it. /* We must save the offset as it is possible to have multiple * flows using the same protocol and address pairs so we * need to wait until we can validate this is part of the * same flow with a 5-tuple or better to avoid unnecessary * collisions between flows. */ if (NAPI_GRO_CB(skb)->is_atomic) NAPI_GRO_CB(p)->flush_id = flush_id; else NAPI_GRO_CB(p)->flush_id |= flush_id; NAPI_GRO_CB(p)->flush_id |= ntohs(iph2->id) ^ (u16)(id - NAPI_GRO_CB(p)->count); } NAPI_GRO_CB(skb)->is_atomic = !!(iph->frag_off & htons(IP_DF)); NAPI_GRO_CB(skb)->flush |= flush; skb_set_network_header(skb, off); /* The above will be needed by the transport layer if there is one Loading
net/ipv4/tcp_offload.c +1 −15 Original line number Diff line number Diff line Loading @@ -230,7 +230,7 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb) found: /* Include the IP ID check below from the inner most IP hdr */ flush = NAPI_GRO_CB(p)->flush; flush = NAPI_GRO_CB(p)->flush | NAPI_GRO_CB(p)->flush_id; flush |= (__force int)(flags & TCP_FLAG_CWR); flush |= (__force int)((flags ^ tcp_flag_word(th2)) & ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH)); Loading @@ -239,17 +239,6 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb) flush |= *(u32 *)((u8 *)th + i) ^ *(u32 *)((u8 *)th2 + i); /* When we receive our second frame we can made a decision on if we * continue this flow as an atomic flow with a fixed ID or if we use * an incrementing ID. */ if (NAPI_GRO_CB(p)->flush_id != 1 || NAPI_GRO_CB(p)->count != 1 || !NAPI_GRO_CB(p)->is_atomic) flush |= NAPI_GRO_CB(p)->flush_id; else NAPI_GRO_CB(p)->is_atomic = false; mss = skb_shinfo(p)->gso_size; flush |= (len - 1) >= mss; Loading Loading @@ -318,9 +307,6 @@ static int tcp4_gro_complete(struct sk_buff *skb, int thoff) iph->daddr, 0); skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4; if (NAPI_GRO_CB(skb)->is_atomic) skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_FIXEDID; return tcp_gro_complete(skb); } Loading
net/ipv6/ip6_offload.c +0 −7 Original line number Diff line number Diff line Loading @@ -237,15 +237,8 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, /* flush if Traffic Class fields are different */ NAPI_GRO_CB(p)->flush |= !!(first_word & htonl(0x0FF00000)); NAPI_GRO_CB(p)->flush |= flush; /* If the previous IP ID value was based on an atomic * datagram we can overwrite the value and ignore it. */ if (NAPI_GRO_CB(skb)->is_atomic) NAPI_GRO_CB(p)->flush_id = 0; } NAPI_GRO_CB(skb)->is_atomic = true; NAPI_GRO_CB(skb)->flush |= flush; skb_gro_postpull_rcsum(skb, iph, nlen); Loading