Merge "ipv4/GRO: Make GRO conform to RFC 6864"

This commit is contained in:
Linux Build Service Account 2016-09-02 13:52:39 -07:00 committed by Gerrit - the friendly Code Review server
commit 20a10f5e22
3 changed files with 19 additions and 10 deletions

View file

@ -4142,6 +4142,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;

View file

@ -1345,6 +1345,7 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head,
for (p = *head; p; p = p->next) {
struct iphdr *iph2;
u16 flush_id;
if (!NAPI_GRO_CB(p)->same_flow)
continue;
@ -1368,14 +1369,24 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head,
(iph->tos ^ iph2->tos) |
((iph->frag_off ^ iph2->frag_off) & htons(IP_DF));
/* Save the IP ID check to be included later when we get to
* the transport layer so only the inner most IP ID is checked.
* This is because some GSO/TSO implementations do not
* correctly increment the IP ID for the outer hdrs.
*/
NAPI_GRO_CB(p)->flush_id =
((u16)(ntohs(iph2->id) + NAPI_GRO_CB(p)->count) ^ id);
NAPI_GRO_CB(p)->flush |= flush;
/* 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. We can support one of two
* possible scenarios, either a fixed value with DF bit set
* or an incrementing value with DF either set or unset.
* In the case of a fixed value we will end up losing the
* data that the IP ID was a fixed value, however per RFC
* 6864 in such a case the actual value of the IP ID is
* meant to be ignored anyway.
*/
flush_id = (u16)(id - ntohs(iph2->id));
if (flush_id || !(iph2->frag_off & htons(IP_DF)))
NAPI_GRO_CB(p)->flush_id |= flush_id ^
NAPI_GRO_CB(p)->count;
}
NAPI_GRO_CB(skb)->flush |= flush;

View file

@ -238,9 +238,6 @@ 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;
/* Clear flush_id, there's really no concept of ID in IPv6. */
NAPI_GRO_CB(p)->flush_id = 0;
}
NAPI_GRO_CB(skb)->flush |= flush;