aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2015-10-09 14:44:54 -0400
committerDavid S. Miller <davem@davemloft.net>2015-10-12 22:44:16 -0400
commit19bcf9f203c82c2028f5a0881b1f0690e3207190 (patch)
treea3d9cbc354d0c464f8485b298f25bab4bae7a73b /net/ipv4
parent37fcbab61b8ecf75cb5fd81e5809b71c270f9632 (diff)
ipv4: Pass struct net into ip_defrag and ip_check_defrag
The function ip_defrag is called on both the input and the output paths of the networking stack. In particular conntrack when it is tracking outbound packets from the local machine calls ip_defrag. So add a struct net parameter and stop making ip_defrag guess which network namespace it needs to defragment packets in. Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/ip_fragment.c7
-rw-r--r--net/ipv4/ip_input.c7
-rw-r--r--net/ipv4/netfilter/nf_defrag_ipv4.c7
3 files changed, 11 insertions, 10 deletions
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 9772b789adf3..5482745d5d68 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -654,11 +654,10 @@ out_fail:
654} 654}
655 655
656/* Process an incoming IP datagram fragment. */ 656/* Process an incoming IP datagram fragment. */
657int ip_defrag(struct sk_buff *skb, u32 user) 657int ip_defrag(struct net *net, struct sk_buff *skb, u32 user)
658{ 658{
659 struct net_device *dev = skb->dev ? : skb_dst(skb)->dev; 659 struct net_device *dev = skb->dev ? : skb_dst(skb)->dev;
660 int vif = l3mdev_master_ifindex_rcu(dev); 660 int vif = l3mdev_master_ifindex_rcu(dev);
661 struct net *net = dev_net(dev);
662 struct ipq *qp; 661 struct ipq *qp;
663 662
664 IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS); 663 IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS);
@@ -683,7 +682,7 @@ int ip_defrag(struct sk_buff *skb, u32 user)
683} 682}
684EXPORT_SYMBOL(ip_defrag); 683EXPORT_SYMBOL(ip_defrag);
685 684
686struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user) 685struct sk_buff *ip_check_defrag(struct net *net, struct sk_buff *skb, u32 user)
687{ 686{
688 struct iphdr iph; 687 struct iphdr iph;
689 int netoff; 688 int netoff;
@@ -712,7 +711,7 @@ struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user)
712 if (pskb_trim_rcsum(skb, netoff + len)) 711 if (pskb_trim_rcsum(skb, netoff + len))
713 return skb; 712 return skb;
714 memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); 713 memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
715 if (ip_defrag(skb, user)) 714 if (ip_defrag(net, skb, user))
716 return NULL; 715 return NULL;
717 skb_clear_hash(skb); 716 skb_clear_hash(skb);
718 } 717 }
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 804b86fd615f..b1209b63381f 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -170,7 +170,7 @@ bool ip_call_ra_chain(struct sk_buff *skb)
170 sk->sk_bound_dev_if == dev->ifindex) && 170 sk->sk_bound_dev_if == dev->ifindex) &&
171 net_eq(sock_net(sk), net)) { 171 net_eq(sock_net(sk), net)) {
172 if (ip_is_fragment(ip_hdr(skb))) { 172 if (ip_is_fragment(ip_hdr(skb))) {
173 if (ip_defrag(skb, IP_DEFRAG_CALL_RA_CHAIN)) 173 if (ip_defrag(net, skb, IP_DEFRAG_CALL_RA_CHAIN))
174 return true; 174 return true;
175 } 175 }
176 if (last) { 176 if (last) {
@@ -247,14 +247,15 @@ int ip_local_deliver(struct sk_buff *skb)
247 /* 247 /*
248 * Reassemble IP fragments. 248 * Reassemble IP fragments.
249 */ 249 */
250 struct net *net = dev_net(skb->dev);
250 251
251 if (ip_is_fragment(ip_hdr(skb))) { 252 if (ip_is_fragment(ip_hdr(skb))) {
252 if (ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER)) 253 if (ip_defrag(net, skb, IP_DEFRAG_LOCAL_DELIVER))
253 return 0; 254 return 0;
254 } 255 }
255 256
256 return NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_IN, 257 return NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_IN,
257 dev_net(skb->dev), NULL, skb, skb->dev, NULL, 258 net, NULL, skb, skb->dev, NULL,
258 ip_local_deliver_finish); 259 ip_local_deliver_finish);
259} 260}
260 261
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c
index b246346ee849..bf25f45b23d2 100644
--- a/net/ipv4/netfilter/nf_defrag_ipv4.c
+++ b/net/ipv4/netfilter/nf_defrag_ipv4.c
@@ -22,14 +22,15 @@
22#endif 22#endif
23#include <net/netfilter/nf_conntrack_zones.h> 23#include <net/netfilter/nf_conntrack_zones.h>
24 24
25static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user) 25static int nf_ct_ipv4_gather_frags(struct net *net, struct sk_buff *skb,
26 u_int32_t user)
26{ 27{
27 int err; 28 int err;
28 29
29 skb_orphan(skb); 30 skb_orphan(skb);
30 31
31 local_bh_disable(); 32 local_bh_disable();
32 err = ip_defrag(skb, user); 33 err = ip_defrag(net, skb, user);
33 local_bh_enable(); 34 local_bh_enable();
34 35
35 if (!err) { 36 if (!err) {
@@ -85,7 +86,7 @@ static unsigned int ipv4_conntrack_defrag(void *priv,
85 enum ip_defrag_users user = 86 enum ip_defrag_users user =
86 nf_ct_defrag_user(state->hook, skb); 87 nf_ct_defrag_user(state->hook, skb);
87 88
88 if (nf_ct_ipv4_gather_frags(skb, user)) 89 if (nf_ct_ipv4_gather_frags(state->net, skb, user))
89 return NF_STOLEN; 90 return NF_STOLEN;
90 } 91 }
91 return NF_ACCEPT; 92 return NF_ACCEPT;