|
@@ -57,14 +57,6 @@
|
|
*/
|
|
*/
|
|
static const char ip_frag_cache_name[] = "ip4-frags";
|
|
static const char ip_frag_cache_name[] = "ip4-frags";
|
|
|
|
|
|
-struct ipfrag_skb_cb
|
|
|
|
-{
|
|
|
|
- struct inet_skb_parm h;
|
|
|
|
- int offset;
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-#define FRAG_CB(skb) ((struct ipfrag_skb_cb *)((skb)->cb))
|
|
|
|
-
|
|
|
|
/* Describe an entry in the "incomplete datagrams" queue. */
|
|
/* Describe an entry in the "incomplete datagrams" queue. */
|
|
struct ipq {
|
|
struct ipq {
|
|
struct inet_frag_queue q;
|
|
struct inet_frag_queue q;
|
|
@@ -353,13 +345,13 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
|
|
* this fragment, right?
|
|
* this fragment, right?
|
|
*/
|
|
*/
|
|
prev = qp->q.fragments_tail;
|
|
prev = qp->q.fragments_tail;
|
|
- if (!prev || FRAG_CB(prev)->offset < offset) {
|
|
|
|
|
|
+ if (!prev || prev->ip_defrag_offset < offset) {
|
|
next = NULL;
|
|
next = NULL;
|
|
goto found;
|
|
goto found;
|
|
}
|
|
}
|
|
prev = NULL;
|
|
prev = NULL;
|
|
for (next = qp->q.fragments; next != NULL; next = next->next) {
|
|
for (next = qp->q.fragments; next != NULL; next = next->next) {
|
|
- if (FRAG_CB(next)->offset >= offset)
|
|
|
|
|
|
+ if (next->ip_defrag_offset >= offset)
|
|
break; /* bingo! */
|
|
break; /* bingo! */
|
|
prev = next;
|
|
prev = next;
|
|
}
|
|
}
|
|
@@ -370,7 +362,7 @@ found:
|
|
* any overlaps are eliminated.
|
|
* any overlaps are eliminated.
|
|
*/
|
|
*/
|
|
if (prev) {
|
|
if (prev) {
|
|
- int i = (FRAG_CB(prev)->offset + prev->len) - offset;
|
|
|
|
|
|
+ int i = (prev->ip_defrag_offset + prev->len) - offset;
|
|
|
|
|
|
if (i > 0) {
|
|
if (i > 0) {
|
|
offset += i;
|
|
offset += i;
|
|
@@ -387,8 +379,8 @@ found:
|
|
|
|
|
|
err = -ENOMEM;
|
|
err = -ENOMEM;
|
|
|
|
|
|
- while (next && FRAG_CB(next)->offset < end) {
|
|
|
|
- int i = end - FRAG_CB(next)->offset; /* overlap is 'i' bytes */
|
|
|
|
|
|
+ while (next && next->ip_defrag_offset < end) {
|
|
|
|
+ int i = end - next->ip_defrag_offset; /* overlap is 'i' bytes */
|
|
|
|
|
|
if (i < next->len) {
|
|
if (i < next->len) {
|
|
/* Eat head of the next overlapped fragment
|
|
/* Eat head of the next overlapped fragment
|
|
@@ -396,7 +388,7 @@ found:
|
|
*/
|
|
*/
|
|
if (!pskb_pull(next, i))
|
|
if (!pskb_pull(next, i))
|
|
goto err;
|
|
goto err;
|
|
- FRAG_CB(next)->offset += i;
|
|
|
|
|
|
+ next->ip_defrag_offset += i;
|
|
qp->q.meat -= i;
|
|
qp->q.meat -= i;
|
|
if (next->ip_summed != CHECKSUM_UNNECESSARY)
|
|
if (next->ip_summed != CHECKSUM_UNNECESSARY)
|
|
next->ip_summed = CHECKSUM_NONE;
|
|
next->ip_summed = CHECKSUM_NONE;
|
|
@@ -420,7 +412,13 @@ found:
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- FRAG_CB(skb)->offset = offset;
|
|
|
|
|
|
+ /* Note : skb->ip_defrag_offset and skb->dev share the same location */
|
|
|
|
+ dev = skb->dev;
|
|
|
|
+ if (dev)
|
|
|
|
+ qp->iif = dev->ifindex;
|
|
|
|
+ /* Makes sure compiler wont do silly aliasing games */
|
|
|
|
+ barrier();
|
|
|
|
+ skb->ip_defrag_offset = offset;
|
|
|
|
|
|
/* Insert this fragment in the chain of fragments. */
|
|
/* Insert this fragment in the chain of fragments. */
|
|
skb->next = next;
|
|
skb->next = next;
|
|
@@ -431,11 +429,6 @@ found:
|
|
else
|
|
else
|
|
qp->q.fragments = skb;
|
|
qp->q.fragments = skb;
|
|
|
|
|
|
- dev = skb->dev;
|
|
|
|
- if (dev) {
|
|
|
|
- qp->iif = dev->ifindex;
|
|
|
|
- skb->dev = NULL;
|
|
|
|
- }
|
|
|
|
qp->q.stamp = skb->tstamp;
|
|
qp->q.stamp = skb->tstamp;
|
|
qp->q.meat += skb->len;
|
|
qp->q.meat += skb->len;
|
|
qp->ecn |= ecn;
|
|
qp->ecn |= ecn;
|
|
@@ -511,7 +504,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
|
|
}
|
|
}
|
|
|
|
|
|
WARN_ON(!head);
|
|
WARN_ON(!head);
|
|
- WARN_ON(FRAG_CB(head)->offset != 0);
|
|
|
|
|
|
+ WARN_ON(head->ip_defrag_offset != 0);
|
|
|
|
|
|
/* Allocate a new buffer for the datagram. */
|
|
/* Allocate a new buffer for the datagram. */
|
|
ihlen = ip_hdrlen(head);
|
|
ihlen = ip_hdrlen(head);
|