aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ppp_generic.c31
1 files changed, 16 insertions, 15 deletions
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 1d4fb348488f..9f6d670748d1 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -1998,7 +1998,7 @@ ppp_mp_reconstruct(struct ppp *ppp)
1998 u32 seq = ppp->nextseq; 1998 u32 seq = ppp->nextseq;
1999 u32 minseq = ppp->minseq; 1999 u32 minseq = ppp->minseq;
2000 struct sk_buff_head *list = &ppp->mrq; 2000 struct sk_buff_head *list = &ppp->mrq;
2001 struct sk_buff *p, *next; 2001 struct sk_buff *p, *tmp;
2002 struct sk_buff *head, *tail; 2002 struct sk_buff *head, *tail;
2003 struct sk_buff *skb = NULL; 2003 struct sk_buff *skb = NULL;
2004 int lost = 0, len = 0; 2004 int lost = 0, len = 0;
@@ -2007,14 +2007,15 @@ ppp_mp_reconstruct(struct ppp *ppp)
2007 return NULL; 2007 return NULL;
2008 head = list->next; 2008 head = list->next;
2009 tail = NULL; 2009 tail = NULL;
2010 for (p = head; p != (struct sk_buff *) list; p = next) { 2010 skb_queue_walk_safe(list, p, tmp) {
2011 next = p->next; 2011 again:
2012 if (seq_before(PPP_MP_CB(p)->sequence, seq)) { 2012 if (seq_before(PPP_MP_CB(p)->sequence, seq)) {
2013 /* this can't happen, anyway ignore the skb */ 2013 /* this can't happen, anyway ignore the skb */
2014 netdev_err(ppp->dev, "ppp_mp_reconstruct bad " 2014 netdev_err(ppp->dev, "ppp_mp_reconstruct bad "
2015 "seq %u < %u\n", 2015 "seq %u < %u\n",
2016 PPP_MP_CB(p)->sequence, seq); 2016 PPP_MP_CB(p)->sequence, seq);
2017 head = next; 2017 __skb_unlink(p, list);
2018 kfree_skb(p);
2018 continue; 2019 continue;
2019 } 2020 }
2020 if (PPP_MP_CB(p)->sequence != seq) { 2021 if (PPP_MP_CB(p)->sequence != seq) {
@@ -2026,8 +2027,7 @@ ppp_mp_reconstruct(struct ppp *ppp)
2026 lost = 1; 2027 lost = 1;
2027 seq = seq_before(minseq, PPP_MP_CB(p)->sequence)? 2028 seq = seq_before(minseq, PPP_MP_CB(p)->sequence)?
2028 minseq + 1: PPP_MP_CB(p)->sequence; 2029 minseq + 1: PPP_MP_CB(p)->sequence;
2029 next = p; 2030 goto again;
2030 continue;
2031 } 2031 }
2032 2032
2033 /* 2033 /*
@@ -2067,9 +2067,17 @@ ppp_mp_reconstruct(struct ppp *ppp)
2067 * and we haven't found a complete valid packet yet, 2067 * and we haven't found a complete valid packet yet,
2068 * we can discard up to and including this fragment. 2068 * we can discard up to and including this fragment.
2069 */ 2069 */
2070 if (PPP_MP_CB(p)->BEbits & E) 2070 if (PPP_MP_CB(p)->BEbits & E) {
2071 head = next; 2071 struct sk_buff *tmp2;
2072 2072
2073 skb_queue_reverse_walk_from_safe(list, p, tmp2) {
2074 __skb_unlink(p, list);
2075 kfree_skb(p);
2076 }
2077 head = skb_peek(list);
2078 if (!head)
2079 break;
2080 }
2073 ++seq; 2081 ++seq;
2074 } 2082 }
2075 2083
@@ -2110,13 +2118,6 @@ ppp_mp_reconstruct(struct ppp *ppp)
2110 } 2118 }
2111 2119
2112 ppp->nextseq = PPP_MP_CB(tail)->sequence + 1; 2120 ppp->nextseq = PPP_MP_CB(tail)->sequence + 1;
2113 head = tail->next;
2114 }
2115
2116 /* Discard all the skbuffs that we can't use. */
2117 while ((p = list->next) != head) {
2118 __skb_unlink(p, list);
2119 kfree_skb(p);
2120 } 2121 }
2121 2122
2122 return skb; 2123 return skb;