diff options
author | Florian Westphal <fw@strlen.de> | 2015-03-10 00:08:19 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2015-03-16 09:34:34 -0400 |
commit | c055d5b03bb4cb69d349d787c9787c0383abd8b2 (patch) | |
tree | 92cd93d6fc0c8f0cad4e43afafe880e594124536 /net | |
parent | 169bf9121b19dd6029e0a354d33513f61bfbe3d3 (diff) |
netfilter: bridge: query conntrack about skb dnat
ask conntrack instead of storing ipv4 address in nf_bridge_info->data.
Ths avoids the need to use ->data during NF_PRE_ROUTING.
Only two functions that need ->data remain.
These will be addressed in followup patches.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/bridge/br_netfilter.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index b260a97275db..261fcd5a42d6 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
@@ -37,17 +37,16 @@ | |||
37 | #include <net/route.h> | 37 | #include <net/route.h> |
38 | #include <net/netfilter/br_netfilter.h> | 38 | #include <net/netfilter/br_netfilter.h> |
39 | 39 | ||
40 | #if IS_ENABLED(CONFIG_NF_CONNTRACK) | ||
41 | #include <net/netfilter/nf_conntrack.h> | ||
42 | #endif | ||
43 | |||
40 | #include <asm/uaccess.h> | 44 | #include <asm/uaccess.h> |
41 | #include "br_private.h" | 45 | #include "br_private.h" |
42 | #ifdef CONFIG_SYSCTL | 46 | #ifdef CONFIG_SYSCTL |
43 | #include <linux/sysctl.h> | 47 | #include <linux/sysctl.h> |
44 | #endif | 48 | #endif |
45 | 49 | ||
46 | #define skb_origaddr(skb) (((struct bridge_skb_cb *) \ | ||
47 | (skb->nf_bridge->data))->daddr.ipv4) | ||
48 | #define store_orig_dstaddr(skb) (skb_origaddr(skb) = ip_hdr(skb)->daddr) | ||
49 | #define dnat_took_place(skb) (skb_origaddr(skb) != ip_hdr(skb)->daddr) | ||
50 | |||
51 | #ifdef CONFIG_SYSCTL | 50 | #ifdef CONFIG_SYSCTL |
52 | static struct ctl_table_header *brnf_sysctl_header; | 51 | static struct ctl_table_header *brnf_sysctl_header; |
53 | static int brnf_call_iptables __read_mostly = 1; | 52 | static int brnf_call_iptables __read_mostly = 1; |
@@ -322,6 +321,22 @@ free_skb: | |||
322 | return 0; | 321 | return 0; |
323 | } | 322 | } |
324 | 323 | ||
324 | static bool dnat_took_place(const struct sk_buff *skb) | ||
325 | { | ||
326 | #if IS_ENABLED(CONFIG_NF_CONNTRACK) | ||
327 | enum ip_conntrack_info ctinfo; | ||
328 | struct nf_conn *ct; | ||
329 | |||
330 | ct = nf_ct_get(skb, &ctinfo); | ||
331 | if (!ct || nf_ct_is_untracked(ct)) | ||
332 | return false; | ||
333 | |||
334 | return test_bit(IPS_DST_NAT_BIT, &ct->status); | ||
335 | #else | ||
336 | return false; | ||
337 | #endif | ||
338 | } | ||
339 | |||
325 | /* This requires some explaining. If DNAT has taken place, | 340 | /* This requires some explaining. If DNAT has taken place, |
326 | * we will need to fix up the destination Ethernet address. | 341 | * we will need to fix up the destination Ethernet address. |
327 | * | 342 | * |
@@ -625,7 +640,7 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops, | |||
625 | return NF_DROP; | 640 | return NF_DROP; |
626 | if (!setup_pre_routing(skb)) | 641 | if (!setup_pre_routing(skb)) |
627 | return NF_DROP; | 642 | return NF_DROP; |
628 | store_orig_dstaddr(skb); | 643 | |
629 | skb->protocol = htons(ETH_P_IP); | 644 | skb->protocol = htons(ETH_P_IP); |
630 | 645 | ||
631 | NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, skb->dev, NULL, | 646 | NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, skb->dev, NULL, |