aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/reassembly.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/reassembly.c')
-rw-r--r--net/ipv6/reassembly.c11
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
348found:
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
554out_oversize: 565out_oversize: