diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2015-10-09 14:44:54 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-10-12 22:44:16 -0400 |
commit | 19bcf9f203c82c2028f5a0881b1f0690e3207190 (patch) | |
tree | a3d9cbc354d0c464f8485b298f25bab4bae7a73b /net/ipv4 | |
parent | 37fcbab61b8ecf75cb5fd81e5809b71c270f9632 (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.c | 7 | ||||
-rw-r--r-- | net/ipv4/ip_input.c | 7 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_defrag_ipv4.c | 7 |
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. */ |
657 | int ip_defrag(struct sk_buff *skb, u32 user) | 657 | int 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 | } |
684 | EXPORT_SYMBOL(ip_defrag); | 683 | EXPORT_SYMBOL(ip_defrag); |
685 | 684 | ||
686 | struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user) | 685 | struct 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 | ||
25 | static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user) | 25 | static 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; |