aboutsummaryrefslogtreecommitdiffstats
path: root/net/atm/clip.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/atm/clip.c')
-rw-r--r--net/atm/clip.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/net/atm/clip.c b/net/atm/clip.c
index 1c416934b7c1..5f8a1d222720 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -38,7 +38,6 @@
38 38
39#include "common.h" 39#include "common.h"
40#include "resources.h" 40#include "resources.h"
41#include "ipcommon.h"
42#include <net/atmclip.h> 41#include <net/atmclip.h>
43 42
44 43
@@ -469,8 +468,9 @@ static struct net_device_stats *clip_get_stats(struct net_device *dev)
469static int clip_mkip(struct atm_vcc *vcc, int timeout) 468static int clip_mkip(struct atm_vcc *vcc, int timeout)
470{ 469{
471 struct clip_vcc *clip_vcc; 470 struct clip_vcc *clip_vcc;
472 struct sk_buff_head copy;
473 struct sk_buff *skb; 471 struct sk_buff *skb;
472 struct sk_buff_head *rq;
473 unsigned long flags;
474 474
475 if (!vcc->push) 475 if (!vcc->push)
476 return -EBADFD; 476 return -EBADFD;
@@ -490,10 +490,26 @@ static int clip_mkip(struct atm_vcc *vcc, int timeout)
490 clip_vcc->old_pop = vcc->pop; 490 clip_vcc->old_pop = vcc->pop;
491 vcc->push = clip_push; 491 vcc->push = clip_push;
492 vcc->pop = clip_pop; 492 vcc->pop = clip_pop;
493 skb_queue_head_init(&copy); 493
494 skb_migrate(&sk_atm(vcc)->sk_receive_queue, &copy); 494 rq = &sk_atm(vcc)->sk_receive_queue;
495
496 spin_lock_irqsave(&rq->lock, flags);
497 if (skb_queue_empty(rq)) {
498 skb = NULL;
499 } else {
500 /* NULL terminate the list. */
501 rq->prev->next = NULL;
502 skb = rq->next;
503 }
504 rq->prev = rq->next = (struct sk_buff *)rq;
505 rq->qlen = 0;
506 spin_unlock_irqrestore(&rq->lock, flags);
507
495 /* re-process everything received between connection setup and MKIP */ 508 /* re-process everything received between connection setup and MKIP */
496 while ((skb = skb_dequeue(&copy)) != NULL) 509 while (skb) {
510 struct sk_buff *next = skb->next;
511
512 skb->next = skb->prev = NULL;
497 if (!clip_devs) { 513 if (!clip_devs) {
498 atm_return(vcc, skb->truesize); 514 atm_return(vcc, skb->truesize);
499 kfree_skb(skb); 515 kfree_skb(skb);
@@ -506,6 +522,9 @@ static int clip_mkip(struct atm_vcc *vcc, int timeout)
506 PRIV(skb->dev)->stats.rx_bytes -= len; 522 PRIV(skb->dev)->stats.rx_bytes -= len;
507 kfree_skb(skb); 523 kfree_skb(skb);
508 } 524 }
525
526 skb = next;
527 }
509 return 0; 528 return 0;
510} 529}
511 530