diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/reassembly.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 0b97230a3251..545c4141b755 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
@@ -333,6 +333,11 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, | |||
333 | * in the chain of fragments so far. We must know where to put | 333 | * in the chain of fragments so far. We must know where to put |
334 | * this fragment, right? | 334 | * this fragment, right? |
335 | */ | 335 | */ |
336 | prev = fq->q.fragments_tail; | ||
337 | if (!prev || FRAG6_CB(prev)->offset < offset) { | ||
338 | next = NULL; | ||
339 | goto found; | ||
340 | } | ||
336 | prev = NULL; | 341 | prev = NULL; |
337 | for(next = fq->q.fragments; next != NULL; next = next->next) { | 342 | for(next = fq->q.fragments; next != NULL; next = next->next) { |
338 | if (FRAG6_CB(next)->offset >= offset) | 343 | if (FRAG6_CB(next)->offset >= offset) |
@@ -340,6 +345,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, | |||
340 | prev = next; | 345 | prev = next; |
341 | } | 346 | } |
342 | 347 | ||
348 | found: | ||
343 | /* We found where to put this one. Check for overlap with | 349 | /* We found where to put this one. Check for overlap with |
344 | * preceding fragment, and, if needed, align things so that | 350 | * preceding fragment, and, if needed, align things so that |
345 | * any overlaps are eliminated. | 351 | * any overlaps are eliminated. |
@@ -397,6 +403,8 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, | |||
397 | 403 | ||
398 | /* Insert this fragment in the chain of fragments. */ | 404 | /* Insert this fragment in the chain of fragments. */ |
399 | skb->next = next; | 405 | skb->next = next; |
406 | if (!next) | ||
407 | fq->q.fragments_tail = skb; | ||
400 | if (prev) | 408 | if (prev) |
401 | prev->next = skb; | 409 | prev->next = skb; |
402 | else | 410 | else |
@@ -463,6 +471,8 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, | |||
463 | goto out_oom; | 471 | goto out_oom; |
464 | 472 | ||
465 | fp->next = head->next; | 473 | fp->next = head->next; |
474 | if (!fp->next) | ||
475 | fq->q.fragments_tail = fp; | ||
466 | prev->next = fp; | 476 | prev->next = fp; |
467 | 477 | ||
468 | skb_morph(head, fq->q.fragments); | 478 | skb_morph(head, fq->q.fragments); |
@@ -549,6 +559,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, | |||
549 | IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMOKS); | 559 | IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMOKS); |
550 | rcu_read_unlock(); | 560 | rcu_read_unlock(); |
551 | fq->q.fragments = NULL; | 561 | fq->q.fragments = NULL; |
562 | fq->q.fragments_tail = NULL; | ||
552 | return 1; | 563 | return 1; |
553 | 564 | ||
554 | out_oversize: | 565 | out_oversize: |