[IPV4]: Change ip_defrag to return an integer
authorHerbert Xu <herbert@gondor.apana.org.au>
Sun, 14 Oct 2007 07:38:32 +0000 (00:38 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Mon, 15 Oct 2007 19:26:25 +0000 (12:26 -0700)
Now that ip_frag always returns the packet given to it on input, we can
change it to return an integer indicating error instead.  This patch does
that and updates all its callers accordingly.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/ip.h
net/ipv4/ip_fragment.c
net/ipv4/ip_input.c
net/ipv4/ipvs/ip_vs_core.c
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c

index 3af3ed9d320bbdeb1e996dfceb7b8cd10cdcfc21..875c5ed53343c1773069c01b16e5bf3212956578 100644 (file)
@@ -332,7 +332,7 @@ enum ip_defrag_users
        IP_DEFRAG_VS_FWD
 };
 
-struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user);
+int ip_defrag(struct sk_buff *skb, u32 user);
 extern int ip_frag_nqueues;
 extern atomic_t ip_frag_mem;
 
index d7fa2bf3a0c14b9e7cb9f5c8b80c15095a043866..32108cf2a7849eb2f54df6789bcbdcfbe5545e88 100644 (file)
@@ -739,7 +739,7 @@ out_fail:
 }
 
 /* Process an incoming IP datagram fragment. */
-struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user)
+int ip_defrag(struct sk_buff *skb, u32 user)
 {
        struct ipq *qp;
 
@@ -759,12 +759,12 @@ struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user)
 
                spin_unlock(&qp->lock);
                ipq_put(qp, NULL);
-               return ret ? NULL : skb;
+               return ret;
        }
 
        IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);
        kfree_skb(skb);
-       return NULL;
+       return -ENOMEM;
 }
 
 void __init ipfrag_init(void)
index 41d8964591e785420f6800ab3329d87cc2884704..8f75e43ad3b3581c3c6967f56c40418ddc818378 100644 (file)
@@ -172,8 +172,7 @@ int ip_call_ra_chain(struct sk_buff *skb)
                    (!sk->sk_bound_dev_if ||
                     sk->sk_bound_dev_if == skb->dev->ifindex)) {
                        if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
-                               skb = ip_defrag(skb, IP_DEFRAG_CALL_RA_CHAIN);
-                               if (skb == NULL) {
+                               if (ip_defrag(skb, IP_DEFRAG_CALL_RA_CHAIN)) {
                                        read_unlock(&ip_ra_lock);
                                        return 1;
                                }
@@ -265,8 +264,7 @@ int ip_local_deliver(struct sk_buff *skb)
         */
 
        if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
-               skb = ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER);
-               if (!skb)
+               if (ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER))
                        return 0;
        }
 
index fbca2a2ff29fa5c5435f9023b8da89b36641833d..3487337192c6f8651bc7c7ea17fc98b9fa5b7f39 100644 (file)
@@ -541,13 +541,14 @@ __sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset)
        return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0));
 }
 
-static inline struct sk_buff *
-ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user)
+static inline int ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user)
 {
-       skb = ip_defrag(skb, user);
-       if (skb)
+       int err = ip_defrag(skb, user);
+
+       if (!err)
                ip_send_check(ip_hdr(skb));
-       return skb;
+
+       return err;
 }
 
 /*
@@ -619,10 +620,8 @@ static int ip_vs_out_icmp(struct sk_buff **pskb, int *related)
 
        /* reassemble IP fragments */
        if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
-               skb = ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT);
-               if (!skb)
+               if (ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT))
                        return NF_STOLEN;
-               *pskb = skb;
        }
 
        iph = ip_hdr(skb);
@@ -756,11 +755,9 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
        /* reassemble IP fragments */
        if (unlikely(iph->frag_off & htons(IP_MF|IP_OFFSET) &&
                     !pp->dont_defrag)) {
-               skb = ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT);
-               if (!skb)
+               if (ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT))
                        return NF_STOLEN;
                iph = ip_hdr(skb);
-               *pskb = skb;
        }
 
        ihl = iph->ihl << 2;
@@ -861,12 +858,9 @@ ip_vs_in_icmp(struct sk_buff **pskb, int *related, unsigned int hooknum)
 
        /* reassemble IP fragments */
        if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
-               skb = ip_vs_gather_frags(skb,
-                                        hooknum == NF_IP_LOCAL_IN ?
-                                        IP_DEFRAG_VS_IN : IP_DEFRAG_VS_FWD);
-               if (!skb)
+               if (ip_vs_gather_frags(skb, hooknum == NF_IP_LOCAL_IN ?
+                                           IP_DEFRAG_VS_IN : IP_DEFRAG_VS_FWD))
                        return NF_STOLEN;
-               *pskb = skb;
        }
 
        iph = ip_hdr(skb);
index 2fcb9249a8da8184f22b17734a34863b8f098e12..48fdd9eb1c7110bea60ec20e7ae5e45695cae817 100644 (file)
@@ -63,19 +63,20 @@ static int ipv4_print_conntrack(struct seq_file *s,
 }
 
 /* Returns new sk_buff, or NULL */
-static struct sk_buff *
-nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
+static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
 {
+       int err;
+
        skb_orphan(skb);
 
        local_bh_disable();
-       skb = ip_defrag(skb, user);
+       err = ip_defrag(skb, user);
        local_bh_enable();
 
-       if (skb)
+       if (!err)
                ip_send_check(ip_hdr(skb));
 
-       return skb;
+       return err;
 }
 
 static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
@@ -148,11 +149,10 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
 
        /* Gather fragments. */
        if (ip_hdr(*pskb)->frag_off & htons(IP_MF | IP_OFFSET)) {
-               *pskb = nf_ct_ipv4_gather_frags(*pskb,
-                                               hooknum == NF_IP_PRE_ROUTING ?
-                                               IP_DEFRAG_CONNTRACK_IN :
-                                               IP_DEFRAG_CONNTRACK_OUT);
-               if (!*pskb)
+               if (nf_ct_ipv4_gather_frags(*pskb,
+                                           hooknum == NF_IP_PRE_ROUTING ?
+                                           IP_DEFRAG_CONNTRACK_IN :
+                                           IP_DEFRAG_CONNTRACK_OUT))
                        return NF_STOLEN;
        }
        return NF_ACCEPT;