ppp: fix 'ppp_mp_reconstruct bad seq' errors
[pandora-kernel.git] / drivers / net / ppp / ppp_generic.c
index edfa15d..486b404 100644 (file)
@@ -2024,14 +2024,22 @@ ppp_mp_reconstruct(struct ppp *ppp)
                        continue;
                }
                if (PPP_MP_CB(p)->sequence != seq) {
+                       u32 oldseq;
                        /* Fragment `seq' is missing.  If it is after
                           minseq, it might arrive later, so stop here. */
                        if (seq_after(seq, minseq))
                                break;
                        /* Fragment `seq' is lost, keep going. */
                        lost = 1;
+                       oldseq = seq;
                        seq = seq_before(minseq, PPP_MP_CB(p)->sequence)?
                                minseq + 1: PPP_MP_CB(p)->sequence;
+
+                       if (ppp->debug & 1)
+                               netdev_printk(KERN_DEBUG, ppp->dev,
+                                             "lost frag %u..%u\n",
+                                             oldseq, seq-1);
+
                        goto again;
                }
 
@@ -2076,6 +2084,10 @@ ppp_mp_reconstruct(struct ppp *ppp)
                        struct sk_buff *tmp2;
 
                        skb_queue_reverse_walk_from_safe(list, p, tmp2) {
+                               if (ppp->debug & 1)
+                                       netdev_printk(KERN_DEBUG, ppp->dev,
+                                                     "discarding frag %u\n",
+                                                     PPP_MP_CB(p)->sequence);
                                __skb_unlink(p, list);
                                kfree_skb(p);
                        }
@@ -2091,6 +2103,17 @@ ppp_mp_reconstruct(struct ppp *ppp)
                /* If we have discarded any fragments,
                   signal a receive error. */
                if (PPP_MP_CB(head)->sequence != ppp->nextseq) {
+                       skb_queue_walk_safe(list, p, tmp) {
+                               if (p == head)
+                                       break;
+                               if (ppp->debug & 1)
+                                       netdev_printk(KERN_DEBUG, ppp->dev,
+                                                     "discarding frag %u\n",
+                                                     PPP_MP_CB(p)->sequence);
+                               __skb_unlink(p, list);
+                               kfree_skb(p);
+                       }
+
                        if (ppp->debug & 1)
                                netdev_printk(KERN_DEBUG, ppp->dev,
                                              "  missed pkts %u..%u\n",