]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/ipv4/ip_fragment.c
net/ipv4: EXPORT_SYMBOL cleanups
[net-next-2.6.git] / net / ipv4 / ip_fragment.c
index 75347ea70ea071d6fef5223535b6bb83973b602b..b7c41654dde543ff310ac63aa696d65a58fd4d36 100644 (file)
@@ -124,11 +124,8 @@ static int ip4_frag_match(struct inet_frag_queue *q, void *a)
 }
 
 /* Memory Tracking Functions. */
-static __inline__ void frag_kfree_skb(struct netns_frags *nf,
-               struct sk_buff *skb, int *work)
+static void frag_kfree_skb(struct netns_frags *nf, struct sk_buff *skb)
 {
-       if (work)
-               *work -= skb->truesize;
        atomic_sub(skb->truesize, &nf->mem);
        kfree_skb(skb);
 }
@@ -309,7 +306,7 @@ static int ip_frag_reinit(struct ipq *qp)
        fp = qp->q.fragments;
        do {
                struct sk_buff *xp = fp->next;
-               frag_kfree_skb(qp->q.net, fp, NULL);
+               frag_kfree_skb(qp->q.net, fp);
                fp = xp;
        } while (fp);
 
@@ -317,6 +314,7 @@ static int ip_frag_reinit(struct ipq *qp)
        qp->q.len = 0;
        qp->q.meat = 0;
        qp->q.fragments = NULL;
+       qp->q.fragments_tail = NULL;
        qp->iif = 0;
 
        return 0;
@@ -389,6 +387,11 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
         * in the chain of fragments so far.  We must know where to put
         * this fragment, right?
         */
+       prev = qp->q.fragments_tail;
+       if (!prev || FRAG_CB(prev)->offset < offset) {
+               next = NULL;
+               goto found;
+       }
        prev = NULL;
        for (next = qp->q.fragments; next != NULL; next = next->next) {
                if (FRAG_CB(next)->offset >= offset)
@@ -396,6 +399,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
                prev = next;
        }
 
+found:
        /* We found where to put this one.  Check for overlap with
         * preceding fragment, and, if needed, align things so that
         * any overlaps are eliminated.
@@ -446,7 +450,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
                                qp->q.fragments = next;
 
                        qp->q.meat -= free_it->len;
-                       frag_kfree_skb(qp->q.net, free_it, NULL);
+                       frag_kfree_skb(qp->q.net, free_it);
                }
        }
 
@@ -454,6 +458,8 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
 
        /* Insert this fragment in the chain of fragments. */
        skb->next = next;
+       if (!next)
+               qp->q.fragments_tail = skb;
        if (prev)
                prev->next = skb;
        else
@@ -507,6 +513,8 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
                        goto out_nomem;
 
                fp->next = head->next;
+               if (!fp->next)
+                       qp->q.fragments_tail = fp;
                prev->next = fp;
 
                skb_morph(head, qp->q.fragments);
@@ -556,7 +564,6 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
 
        skb_shinfo(head)->frag_list = head->next;
        skb_push(head, head->data - skb_network_header(head));
-       atomic_sub(head->truesize, &qp->q.net->mem);
 
        for (fp=head->next; fp; fp = fp->next) {
                head->data_len += fp->len;
@@ -566,8 +573,8 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
                else if (head->ip_summed == CHECKSUM_COMPLETE)
                        head->csum = csum_add(head->csum, fp->csum);
                head->truesize += fp->truesize;
-               atomic_sub(fp->truesize, &qp->q.net->mem);
        }
+       atomic_sub(head->truesize, &qp->q.net->mem);
 
        head->next = NULL;
        head->dev = dev;
@@ -578,6 +585,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
        iph->tot_len = htons(len);
        IP_INC_STATS_BH(net, IPSTATS_MIB_REASMOKS);
        qp->q.fragments = NULL;
+       qp->q.fragments_tail = NULL;
        return 0;
 
 out_nomem:
@@ -624,6 +632,7 @@ int ip_defrag(struct sk_buff *skb, u32 user)
        kfree_skb(skb);
        return -ENOMEM;
 }
+EXPORT_SYMBOL(ip_defrag);
 
 #ifdef CONFIG_SYSCTL
 static int zero;
@@ -777,5 +786,3 @@ void __init ipfrag_init(void)
        ip4_frags.secret_interval = 10 * 60 * HZ;
        inet_frags_init(&ip4_frags);
 }
-
-EXPORT_SYMBOL(ip_defrag);