Merge "ipv4/GRO: Make GRO conform to RFC 6864"
This commit is contained in:
commit
20a10f5e22
3 changed files with 19 additions and 10 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue