diff options
Diffstat (limited to 'drivers/net/ppp_generic.c')
-rw-r--r-- | drivers/net/ppp_generic.c | 46 |
1 files changed, 25 insertions, 21 deletions
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 736b91703b3e..866e221643ab 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
@@ -1547,9 +1547,11 @@ ppp_channel_push(struct channel *pch) | |||
1547 | * Receive-side routines. | 1547 | * Receive-side routines. |
1548 | */ | 1548 | */ |
1549 | 1549 | ||
1550 | /* misuse a few fields of the skb for MP reconstruction */ | 1550 | struct ppp_mp_skb_parm { |
1551 | #define sequence priority | 1551 | u32 sequence; |
1552 | #define BEbits cb[0] | 1552 | u8 BEbits; |
1553 | }; | ||
1554 | #define PPP_MP_CB(skb) ((struct ppp_mp_skb_parm *)((skb)->cb)) | ||
1553 | 1555 | ||
1554 | static inline void | 1556 | static inline void |
1555 | ppp_do_recv(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) | 1557 | ppp_do_recv(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) |
@@ -1878,13 +1880,13 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) | |||
1878 | seq = (skb->data[3] << 16) | (skb->data[4] << 8)| skb->data[5]; | 1880 | seq = (skb->data[3] << 16) | (skb->data[4] << 8)| skb->data[5]; |
1879 | mask = 0xffffff; | 1881 | mask = 0xffffff; |
1880 | } | 1882 | } |
1881 | skb->BEbits = skb->data[2]; | 1883 | PPP_MP_CB(skb)->BEbits = skb->data[2]; |
1882 | skb_pull(skb, mphdrlen); /* pull off PPP and MP headers */ | 1884 | skb_pull(skb, mphdrlen); /* pull off PPP and MP headers */ |
1883 | 1885 | ||
1884 | /* | 1886 | /* |
1885 | * Do protocol ID decompression on the first fragment of each packet. | 1887 | * Do protocol ID decompression on the first fragment of each packet. |
1886 | */ | 1888 | */ |
1887 | if ((skb->BEbits & B) && (skb->data[0] & 1)) | 1889 | if ((PPP_MP_CB(skb)->BEbits & B) && (skb->data[0] & 1)) |
1888 | *skb_push(skb, 1) = 0; | 1890 | *skb_push(skb, 1) = 0; |
1889 | 1891 | ||
1890 | /* | 1892 | /* |
@@ -1896,7 +1898,7 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) | |||
1896 | seq += mask + 1; | 1898 | seq += mask + 1; |
1897 | else if ((int)(seq - ppp->minseq) > (int)(mask >> 1)) | 1899 | else if ((int)(seq - ppp->minseq) > (int)(mask >> 1)) |
1898 | seq -= mask + 1; /* should never happen */ | 1900 | seq -= mask + 1; /* should never happen */ |
1899 | skb->sequence = seq; | 1901 | PPP_MP_CB(skb)->sequence = seq; |
1900 | pch->lastseq = seq; | 1902 | pch->lastseq = seq; |
1901 | 1903 | ||
1902 | /* | 1904 | /* |
@@ -1932,8 +1934,8 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) | |||
1932 | before the start of the queue. */ | 1934 | before the start of the queue. */ |
1933 | if (skb_queue_len(&ppp->mrq) >= PPP_MP_MAX_QLEN) { | 1935 | if (skb_queue_len(&ppp->mrq) >= PPP_MP_MAX_QLEN) { |
1934 | struct sk_buff *mskb = skb_peek(&ppp->mrq); | 1936 | struct sk_buff *mskb = skb_peek(&ppp->mrq); |
1935 | if (seq_before(ppp->minseq, mskb->sequence)) | 1937 | if (seq_before(ppp->minseq, PPP_MP_CB(mskb)->sequence)) |
1936 | ppp->minseq = mskb->sequence; | 1938 | ppp->minseq = PPP_MP_CB(mskb)->sequence; |
1937 | } | 1939 | } |
1938 | 1940 | ||
1939 | /* Pull completed packets off the queue and receive them. */ | 1941 | /* Pull completed packets off the queue and receive them. */ |
@@ -1963,12 +1965,12 @@ ppp_mp_insert(struct ppp *ppp, struct sk_buff *skb) | |||
1963 | { | 1965 | { |
1964 | struct sk_buff *p; | 1966 | struct sk_buff *p; |
1965 | struct sk_buff_head *list = &ppp->mrq; | 1967 | struct sk_buff_head *list = &ppp->mrq; |
1966 | u32 seq = skb->sequence; | 1968 | u32 seq = PPP_MP_CB(skb)->sequence; |
1967 | 1969 | ||
1968 | /* N.B. we don't need to lock the list lock because we have the | 1970 | /* N.B. we don't need to lock the list lock because we have the |
1969 | ppp unit receive-side lock. */ | 1971 | ppp unit receive-side lock. */ |
1970 | skb_queue_walk(list, p) { | 1972 | skb_queue_walk(list, p) { |
1971 | if (seq_before(seq, p->sequence)) | 1973 | if (seq_before(seq, PPP_MP_CB(p)->sequence)) |
1972 | break; | 1974 | break; |
1973 | } | 1975 | } |
1974 | __skb_queue_before(list, p, skb); | 1976 | __skb_queue_before(list, p, skb); |
@@ -1997,22 +1999,22 @@ ppp_mp_reconstruct(struct ppp *ppp) | |||
1997 | tail = NULL; | 1999 | tail = NULL; |
1998 | for (p = head; p != (struct sk_buff *) list; p = next) { | 2000 | for (p = head; p != (struct sk_buff *) list; p = next) { |
1999 | next = p->next; | 2001 | next = p->next; |
2000 | if (seq_before(p->sequence, seq)) { | 2002 | if (seq_before(PPP_MP_CB(p)->sequence, seq)) { |
2001 | /* this can't happen, anyway ignore the skb */ | 2003 | /* this can't happen, anyway ignore the skb */ |
2002 | printk(KERN_ERR "ppp_mp_reconstruct bad seq %u < %u\n", | 2004 | printk(KERN_ERR "ppp_mp_reconstruct bad seq %u < %u\n", |
2003 | p->sequence, seq); | 2005 | PPP_MP_CB(p)->sequence, seq); |
2004 | head = next; | 2006 | head = next; |
2005 | continue; | 2007 | continue; |
2006 | } | 2008 | } |
2007 | if (p->sequence != seq) { | 2009 | if (PPP_MP_CB(p)->sequence != seq) { |
2008 | /* Fragment `seq' is missing. If it is after | 2010 | /* Fragment `seq' is missing. If it is after |
2009 | minseq, it might arrive later, so stop here. */ | 2011 | minseq, it might arrive later, so stop here. */ |
2010 | if (seq_after(seq, minseq)) | 2012 | if (seq_after(seq, minseq)) |
2011 | break; | 2013 | break; |
2012 | /* Fragment `seq' is lost, keep going. */ | 2014 | /* Fragment `seq' is lost, keep going. */ |
2013 | lost = 1; | 2015 | lost = 1; |
2014 | seq = seq_before(minseq, p->sequence)? | 2016 | seq = seq_before(minseq, PPP_MP_CB(p)->sequence)? |
2015 | minseq + 1: p->sequence; | 2017 | minseq + 1: PPP_MP_CB(p)->sequence; |
2016 | next = p; | 2018 | next = p; |
2017 | continue; | 2019 | continue; |
2018 | } | 2020 | } |
@@ -2026,7 +2028,7 @@ ppp_mp_reconstruct(struct ppp *ppp) | |||
2026 | */ | 2028 | */ |
2027 | 2029 | ||
2028 | /* B bit set indicates this fragment starts a packet */ | 2030 | /* B bit set indicates this fragment starts a packet */ |
2029 | if (p->BEbits & B) { | 2031 | if (PPP_MP_CB(p)->BEbits & B) { |
2030 | head = p; | 2032 | head = p; |
2031 | lost = 0; | 2033 | lost = 0; |
2032 | len = 0; | 2034 | len = 0; |
@@ -2035,7 +2037,8 @@ ppp_mp_reconstruct(struct ppp *ppp) | |||
2035 | len += p->len; | 2037 | len += p->len; |
2036 | 2038 | ||
2037 | /* Got a complete packet yet? */ | 2039 | /* Got a complete packet yet? */ |
2038 | if (lost == 0 && (p->BEbits & E) && (head->BEbits & B)) { | 2040 | if (lost == 0 && (PPP_MP_CB(p)->BEbits & E) && |
2041 | (PPP_MP_CB(head)->BEbits & B)) { | ||
2039 | if (len > ppp->mrru + 2) { | 2042 | if (len > ppp->mrru + 2) { |
2040 | ++ppp->dev->stats.rx_length_errors; | 2043 | ++ppp->dev->stats.rx_length_errors; |
2041 | printk(KERN_DEBUG "PPP: reconstructed packet" | 2044 | printk(KERN_DEBUG "PPP: reconstructed packet" |
@@ -2061,7 +2064,7 @@ ppp_mp_reconstruct(struct ppp *ppp) | |||
2061 | * and we haven't found a complete valid packet yet, | 2064 | * and we haven't found a complete valid packet yet, |
2062 | * we can discard up to and including this fragment. | 2065 | * we can discard up to and including this fragment. |
2063 | */ | 2066 | */ |
2064 | if (p->BEbits & E) | 2067 | if (PPP_MP_CB(p)->BEbits & E) |
2065 | head = next; | 2068 | head = next; |
2066 | 2069 | ||
2067 | ++seq; | 2070 | ++seq; |
@@ -2071,10 +2074,11 @@ ppp_mp_reconstruct(struct ppp *ppp) | |||
2071 | if (tail != NULL) { | 2074 | if (tail != NULL) { |
2072 | /* If we have discarded any fragments, | 2075 | /* If we have discarded any fragments, |
2073 | signal a receive error. */ | 2076 | signal a receive error. */ |
2074 | if (head->sequence != ppp->nextseq) { | 2077 | if (PPP_MP_CB(head)->sequence != ppp->nextseq) { |
2075 | if (ppp->debug & 1) | 2078 | if (ppp->debug & 1) |
2076 | printk(KERN_DEBUG " missed pkts %u..%u\n", | 2079 | printk(KERN_DEBUG " missed pkts %u..%u\n", |
2077 | ppp->nextseq, head->sequence-1); | 2080 | ppp->nextseq, |
2081 | PPP_MP_CB(head)->sequence-1); | ||
2078 | ++ppp->dev->stats.rx_dropped; | 2082 | ++ppp->dev->stats.rx_dropped; |
2079 | ppp_receive_error(ppp); | 2083 | ppp_receive_error(ppp); |
2080 | } | 2084 | } |
@@ -2083,7 +2087,7 @@ ppp_mp_reconstruct(struct ppp *ppp) | |||
2083 | /* copy to a single skb */ | 2087 | /* copy to a single skb */ |
2084 | for (p = head; p != tail->next; p = p->next) | 2088 | for (p = head; p != tail->next; p = p->next) |
2085 | skb_copy_bits(p, 0, skb_put(skb, p->len), p->len); | 2089 | skb_copy_bits(p, 0, skb_put(skb, p->len), p->len); |
2086 | ppp->nextseq = tail->sequence + 1; | 2090 | ppp->nextseq = PPP_MP_CB(tail)->sequence + 1; |
2087 | head = tail->next; | 2091 | head = tail->next; |
2088 | } | 2092 | } |
2089 | 2093 | ||