aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-10-14 03:38:32 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-15 15:26:25 -0400
commit776c729e8d91b2740583a2169678f2d3f383458b (patch)
tree16ad06616e8d04c127266bf323fb35fbed03b96d /net/ipv4
parent1706d58763c36133d7fce6cc78b1444fd40db28c (diff)
[IPV4]: Change ip_defrag to return an integer
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>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/ip_fragment.c6
-rw-r--r--net/ipv4/ip_input.c6
-rw-r--r--net/ipv4/ipvs/ip_vs_core.c26
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c20
4 files changed, 25 insertions, 33 deletions
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index d7fa2bf3a0c1..32108cf2a784 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -739,7 +739,7 @@ out_fail:
739} 739}
740 740
741/* Process an incoming IP datagram fragment. */ 741/* Process an incoming IP datagram fragment. */
742struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user) 742int ip_defrag(struct sk_buff *skb, u32 user)
743{ 743{
744 struct ipq *qp; 744 struct ipq *qp;
745 745
@@ -759,12 +759,12 @@ struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user)
759 759
760 spin_unlock(&qp->lock); 760 spin_unlock(&qp->lock);
761 ipq_put(qp, NULL); 761 ipq_put(qp, NULL);
762 return ret ? NULL : skb; 762 return ret;
763 } 763 }
764 764
765 IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); 765 IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);
766 kfree_skb(skb); 766 kfree_skb(skb);
767 return NULL; 767 return -ENOMEM;
768} 768}
769 769
770void __init ipfrag_init(void) 770void __init ipfrag_init(void)
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 41d8964591e7..8f75e43ad3b3 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -172,8 +172,7 @@ int ip_call_ra_chain(struct sk_buff *skb)
172 (!sk->sk_bound_dev_if || 172 (!sk->sk_bound_dev_if ||
173 sk->sk_bound_dev_if == skb->dev->ifindex)) { 173 sk->sk_bound_dev_if == skb->dev->ifindex)) {
174 if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { 174 if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
175 skb = ip_defrag(skb, IP_DEFRAG_CALL_RA_CHAIN); 175 if (ip_defrag(skb, IP_DEFRAG_CALL_RA_CHAIN)) {
176 if (skb == NULL) {
177 read_unlock(&ip_ra_lock); 176 read_unlock(&ip_ra_lock);
178 return 1; 177 return 1;
179 } 178 }
@@ -265,8 +264,7 @@ int ip_local_deliver(struct sk_buff *skb)
265 */ 264 */
266 265
267 if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { 266 if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
268 skb = ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER); 267 if (ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER))
269 if (!skb)
270 return 0; 268 return 0;
271 } 269 }
272 270
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index fbca2a2ff29f..3487337192c6 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -541,13 +541,14 @@ __sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset)
541 return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0)); 541 return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0));
542} 542}
543 543
544static inline struct sk_buff * 544static inline int ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user)
545ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user)
546{ 545{
547 skb = ip_defrag(skb, user); 546 int err = ip_defrag(skb, user);
548 if (skb) 547
548 if (!err)
549 ip_send_check(ip_hdr(skb)); 549 ip_send_check(ip_hdr(skb));
550 return skb; 550
551 return err;
551} 552}
552 553
553/* 554/*
@@ -619,10 +620,8 @@ static int ip_vs_out_icmp(struct sk_buff **pskb, int *related)
619 620
620 /* reassemble IP fragments */ 621 /* reassemble IP fragments */
621 if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { 622 if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
622 skb = ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT); 623 if (ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT))
623 if (!skb)
624 return NF_STOLEN; 624 return NF_STOLEN;
625 *pskb = skb;
626 } 625 }
627 626
628 iph = ip_hdr(skb); 627 iph = ip_hdr(skb);
@@ -756,11 +755,9 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
756 /* reassemble IP fragments */ 755 /* reassemble IP fragments */
757 if (unlikely(iph->frag_off & htons(IP_MF|IP_OFFSET) && 756 if (unlikely(iph->frag_off & htons(IP_MF|IP_OFFSET) &&
758 !pp->dont_defrag)) { 757 !pp->dont_defrag)) {
759 skb = ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT); 758 if (ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT))
760 if (!skb)
761 return NF_STOLEN; 759 return NF_STOLEN;
762 iph = ip_hdr(skb); 760 iph = ip_hdr(skb);
763 *pskb = skb;
764 } 761 }
765 762
766 ihl = iph->ihl << 2; 763 ihl = iph->ihl << 2;
@@ -861,12 +858,9 @@ ip_vs_in_icmp(struct sk_buff **pskb, int *related, unsigned int hooknum)
861 858
862 /* reassemble IP fragments */ 859 /* reassemble IP fragments */
863 if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { 860 if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
864 skb = ip_vs_gather_frags(skb, 861 if (ip_vs_gather_frags(skb, hooknum == NF_IP_LOCAL_IN ?
865 hooknum == NF_IP_LOCAL_IN ? 862 IP_DEFRAG_VS_IN : IP_DEFRAG_VS_FWD))
866 IP_DEFRAG_VS_IN : IP_DEFRAG_VS_FWD);
867 if (!skb)
868 return NF_STOLEN; 863 return NF_STOLEN;
869 *pskb = skb;
870 } 864 }
871 865
872 iph = ip_hdr(skb); 866 iph = ip_hdr(skb);
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 2fcb9249a8da..48fdd9eb1c71 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -63,19 +63,20 @@ static int ipv4_print_conntrack(struct seq_file *s,
63} 63}
64 64
65/* Returns new sk_buff, or NULL */ 65/* Returns new sk_buff, or NULL */
66static struct sk_buff * 66static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
67nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
68{ 67{
68 int err;
69
69 skb_orphan(skb); 70 skb_orphan(skb);
70 71
71 local_bh_disable(); 72 local_bh_disable();
72 skb = ip_defrag(skb, user); 73 err = ip_defrag(skb, user);
73 local_bh_enable(); 74 local_bh_enable();
74 75
75 if (skb) 76 if (!err)
76 ip_send_check(ip_hdr(skb)); 77 ip_send_check(ip_hdr(skb));
77 78
78 return skb; 79 return err;
79} 80}
80 81
81static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, 82static 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,
148 149
149 /* Gather fragments. */ 150 /* Gather fragments. */
150 if (ip_hdr(*pskb)->frag_off & htons(IP_MF | IP_OFFSET)) { 151 if (ip_hdr(*pskb)->frag_off & htons(IP_MF | IP_OFFSET)) {
151 *pskb = nf_ct_ipv4_gather_frags(*pskb, 152 if (nf_ct_ipv4_gather_frags(*pskb,
152 hooknum == NF_IP_PRE_ROUTING ? 153 hooknum == NF_IP_PRE_ROUTING ?
153 IP_DEFRAG_CONNTRACK_IN : 154 IP_DEFRAG_CONNTRACK_IN :
154 IP_DEFRAG_CONNTRACK_OUT); 155 IP_DEFRAG_CONNTRACK_OUT))
155 if (!*pskb)
156 return NF_STOLEN; 156 return NF_STOLEN;
157 } 157 }
158 return NF_ACCEPT; 158 return NF_ACCEPT;