Commit a00eac0c authored by David S. Miller's avatar David S. Miller

ppp: Use a real SKB control block in fragmentation engine.

Do this instead of subverting fields in skb proper.

The macros that could very easily match variable or function
names were also just asking for trouble.
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c61393ea
...@@ -1547,9 +1547,11 @@ ppp_channel_push(struct channel *pch) ...@@ -1547,9 +1547,11 @@ ppp_channel_push(struct channel *pch)
* Receive-side routines. * Receive-side routines.
*/ */
/* misuse a few fields of the skb for MP reconstruction */ struct ppp_mp_skb_parm {
#define sequence priority u32 sequence;
#define BEbits cb[0] u8 BEbits;
};
#define PPP_MP_CB(skb) ((struct ppp_mp_skb_parm *)((skb)->cb))
static inline void static inline void
ppp_do_recv(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) 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,13 +1880,13 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
seq = (skb->data[3] << 16) | (skb->data[4] << 8)| skb->data[5]; seq = (skb->data[3] << 16) | (skb->data[4] << 8)| skb->data[5];
mask = 0xffffff; mask = 0xffffff;
} }
skb->BEbits = skb->data[2]; PPP_MP_CB(skb)->BEbits = skb->data[2];
skb_pull(skb, mphdrlen); /* pull off PPP and MP headers */ skb_pull(skb, mphdrlen); /* pull off PPP and MP headers */
/* /*
* Do protocol ID decompression on the first fragment of each packet. * Do protocol ID decompression on the first fragment of each packet.
*/ */
if ((skb->BEbits & B) && (skb->data[0] & 1)) if ((PPP_MP_CB(skb)->BEbits & B) && (skb->data[0] & 1))
*skb_push(skb, 1) = 0; *skb_push(skb, 1) = 0;
/* /*
...@@ -1896,7 +1898,7 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) ...@@ -1896,7 +1898,7 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
seq += mask + 1; seq += mask + 1;
else if ((int)(seq - ppp->minseq) > (int)(mask >> 1)) else if ((int)(seq - ppp->minseq) > (int)(mask >> 1))
seq -= mask + 1; /* should never happen */ seq -= mask + 1; /* should never happen */
skb->sequence = seq; PPP_MP_CB(skb)->sequence = seq;
pch->lastseq = seq; pch->lastseq = seq;
/* /*
...@@ -1932,8 +1934,8 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) ...@@ -1932,8 +1934,8 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
before the start of the queue. */ before the start of the queue. */
if (skb_queue_len(&ppp->mrq) >= PPP_MP_MAX_QLEN) { if (skb_queue_len(&ppp->mrq) >= PPP_MP_MAX_QLEN) {
struct sk_buff *mskb = skb_peek(&ppp->mrq); struct sk_buff *mskb = skb_peek(&ppp->mrq);
if (seq_before(ppp->minseq, mskb->sequence)) if (seq_before(ppp->minseq, PPP_MP_CB(mskb)->sequence))
ppp->minseq = mskb->sequence; ppp->minseq = PPP_MP_CB(mskb)->sequence;
} }
/* Pull completed packets off the queue and receive them. */ /* Pull completed packets off the queue and receive them. */
...@@ -1963,12 +1965,12 @@ ppp_mp_insert(struct ppp *ppp, struct sk_buff *skb) ...@@ -1963,12 +1965,12 @@ ppp_mp_insert(struct ppp *ppp, struct sk_buff *skb)
{ {
struct sk_buff *p; struct sk_buff *p;
struct sk_buff_head *list = &ppp->mrq; struct sk_buff_head *list = &ppp->mrq;
u32 seq = skb->sequence; u32 seq = PPP_MP_CB(skb)->sequence;
/* N.B. we don't need to lock the list lock because we have the /* N.B. we don't need to lock the list lock because we have the
ppp unit receive-side lock. */ ppp unit receive-side lock. */
skb_queue_walk(list, p) { skb_queue_walk(list, p) {
if (seq_before(seq, p->sequence)) if (seq_before(seq, PPP_MP_CB(p)->sequence))
break; break;
} }
__skb_queue_before(list, p, skb); __skb_queue_before(list, p, skb);
...@@ -1997,22 +1999,22 @@ ppp_mp_reconstruct(struct ppp *ppp) ...@@ -1997,22 +1999,22 @@ ppp_mp_reconstruct(struct ppp *ppp)
tail = NULL; tail = NULL;
for (p = head; p != (struct sk_buff *) list; p = next) { for (p = head; p != (struct sk_buff *) list; p = next) {
next = p->next; next = p->next;
if (seq_before(p->sequence, seq)) { if (seq_before(PPP_MP_CB(p)->sequence, seq)) {
/* this can't happen, anyway ignore the skb */ /* this can't happen, anyway ignore the skb */
printk(KERN_ERR "ppp_mp_reconstruct bad seq %u < %u\n", printk(KERN_ERR "ppp_mp_reconstruct bad seq %u < %u\n",
p->sequence, seq); PPP_MP_CB(p)->sequence, seq);
head = next; head = next;
continue; continue;
} }
if (p->sequence != seq) { if (PPP_MP_CB(p)->sequence != seq) {
/* Fragment `seq' is missing. If it is after /* Fragment `seq' is missing. If it is after
minseq, it might arrive later, so stop here. */ minseq, it might arrive later, so stop here. */
if (seq_after(seq, minseq)) if (seq_after(seq, minseq))
break; break;
/* Fragment `seq' is lost, keep going. */ /* Fragment `seq' is lost, keep going. */
lost = 1; lost = 1;
seq = seq_before(minseq, p->sequence)? seq = seq_before(minseq, PPP_MP_CB(p)->sequence)?
minseq + 1: p->sequence; minseq + 1: PPP_MP_CB(p)->sequence;
next = p; next = p;
continue; continue;
} }
...@@ -2026,7 +2028,7 @@ ppp_mp_reconstruct(struct ppp *ppp) ...@@ -2026,7 +2028,7 @@ ppp_mp_reconstruct(struct ppp *ppp)
*/ */
/* B bit set indicates this fragment starts a packet */ /* B bit set indicates this fragment starts a packet */
if (p->BEbits & B) { if (PPP_MP_CB(p)->BEbits & B) {
head = p; head = p;
lost = 0; lost = 0;
len = 0; len = 0;
...@@ -2035,7 +2037,8 @@ ppp_mp_reconstruct(struct ppp *ppp) ...@@ -2035,7 +2037,8 @@ ppp_mp_reconstruct(struct ppp *ppp)
len += p->len; len += p->len;
/* Got a complete packet yet? */ /* Got a complete packet yet? */
if (lost == 0 && (p->BEbits & E) && (head->BEbits & B)) { if (lost == 0 && (PPP_MP_CB(p)->BEbits & E) &&
(PPP_MP_CB(head)->BEbits & B)) {
if (len > ppp->mrru + 2) { if (len > ppp->mrru + 2) {
++ppp->dev->stats.rx_length_errors; ++ppp->dev->stats.rx_length_errors;
printk(KERN_DEBUG "PPP: reconstructed packet" printk(KERN_DEBUG "PPP: reconstructed packet"
...@@ -2061,7 +2064,7 @@ ppp_mp_reconstruct(struct ppp *ppp) ...@@ -2061,7 +2064,7 @@ ppp_mp_reconstruct(struct ppp *ppp)
* and we haven't found a complete valid packet yet, * and we haven't found a complete valid packet yet,
* we can discard up to and including this fragment. * we can discard up to and including this fragment.
*/ */
if (p->BEbits & E) if (PPP_MP_CB(p)->BEbits & E)
head = next; head = next;
++seq; ++seq;
...@@ -2071,10 +2074,11 @@ ppp_mp_reconstruct(struct ppp *ppp) ...@@ -2071,10 +2074,11 @@ ppp_mp_reconstruct(struct ppp *ppp)
if (tail != NULL) { if (tail != NULL) {
/* If we have discarded any fragments, /* If we have discarded any fragments,
signal a receive error. */ signal a receive error. */
if (head->sequence != ppp->nextseq) { if (PPP_MP_CB(head)->sequence != ppp->nextseq) {
if (ppp->debug & 1) if (ppp->debug & 1)
printk(KERN_DEBUG " missed pkts %u..%u\n", printk(KERN_DEBUG " missed pkts %u..%u\n",
ppp->nextseq, head->sequence-1); ppp->nextseq,
PPP_MP_CB(head)->sequence-1);
++ppp->dev->stats.rx_dropped; ++ppp->dev->stats.rx_dropped;
ppp_receive_error(ppp); ppp_receive_error(ppp);
} }
...@@ -2083,7 +2087,7 @@ ppp_mp_reconstruct(struct ppp *ppp) ...@@ -2083,7 +2087,7 @@ ppp_mp_reconstruct(struct ppp *ppp)
/* copy to a single skb */ /* copy to a single skb */
for (p = head; p != tail->next; p = p->next) for (p = head; p != tail->next; p = p->next)
skb_copy_bits(p, 0, skb_put(skb, p->len), p->len); skb_copy_bits(p, 0, skb_put(skb, p->len), p->len);
ppp->nextseq = tail->sequence + 1; ppp->nextseq = PPP_MP_CB(tail)->sequence + 1;
head = tail->next; head = tail->next;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment