diff options
| author | Florian Westphal <fw@strlen.de> | 2015-05-20 07:42:25 -0400 |
|---|---|---|
| committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2015-05-20 07:51:25 -0400 |
| commit | faecbb45ebefb20260ad4a631e011e93c896cb73 (patch) | |
| tree | b03c38d28eb48c1ee2f64abb43338f7457ec95ad /net | |
| parent | 1086bbe97a074844188c6c988fa0b1a98c3ccbb9 (diff) | |
Revert "netfilter: bridge: query conntrack about skb dnat"
This reverts commit c055d5b03bb4cb69d349d787c9787c0383abd8b2.
There are two issues:
'dnat_took_place' made me think that this is related to
-j DNAT/MASQUERADE.
But thats only one part of the story. This is also relevant for SNAT
when we undo snat translation in reverse/reply direction.
Furthermore, I originally wanted to do this mainly to avoid
storing ipv6 addresses once we make DNAT/REDIRECT work
for ipv6 on bridges.
However, I forgot about SNPT/DNPT which is stateless.
So we can't escape storing address for ipv6 anyway. Might as
well do it for ipv4 too.
Reported-and-tested-by: Bernhard Thaler <bernhard.thaler@wvnet.at>
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, 9 insertions, 18 deletions
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index ab55e2472beb..60ddfbeb47f5 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
| @@ -37,10 +37,6 @@ | |||
| 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 | |||
| 44 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
| 45 | #include "br_private.h" | 41 | #include "br_private.h" |
| 46 | #ifdef CONFIG_SYSCTL | 42 | #ifdef CONFIG_SYSCTL |
| @@ -350,24 +346,15 @@ free_skb: | |||
| 350 | return 0; | 346 | return 0; |
| 351 | } | 347 | } |
| 352 | 348 | ||
| 353 | static bool dnat_took_place(const struct sk_buff *skb) | 349 | static bool daddr_was_changed(const struct sk_buff *skb, |
| 350 | const struct nf_bridge_info *nf_bridge) | ||
| 354 | { | 351 | { |
| 355 | #if IS_ENABLED(CONFIG_NF_CONNTRACK) | 352 | return ip_hdr(skb)->daddr != nf_bridge->ipv4_daddr; |
| 356 | enum ip_conntrack_info ctinfo; | ||
| 357 | struct nf_conn *ct; | ||
| 358 | |||
| 359 | ct = nf_ct_get(skb, &ctinfo); | ||
| 360 | if (!ct || nf_ct_is_untracked(ct)) | ||
| 361 | return false; | ||
| 362 | |||
| 363 | return test_bit(IPS_DST_NAT_BIT, &ct->status); | ||
| 364 | #else | ||
| 365 | return false; | ||
| 366 | #endif | ||
| 367 | } | 353 | } |
| 368 | 354 | ||
| 369 | /* This requires some explaining. If DNAT has taken place, | 355 | /* This requires some explaining. If DNAT has taken place, |
| 370 | * we will need to fix up the destination Ethernet address. | 356 | * we will need to fix up the destination Ethernet address. |
| 357 | * This is also true when SNAT takes place (for the reply direction). | ||
| 371 | * | 358 | * |
| 372 | * There are two cases to consider: | 359 | * There are two cases to consider: |
| 373 | * 1. The packet was DNAT'ed to a device in the same bridge | 360 | * 1. The packet was DNAT'ed to a device in the same bridge |
| @@ -421,7 +408,7 @@ static int br_nf_pre_routing_finish(struct sock *sk, struct sk_buff *skb) | |||
| 421 | nf_bridge->pkt_otherhost = false; | 408 | nf_bridge->pkt_otherhost = false; |
| 422 | } | 409 | } |
| 423 | nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; | 410 | nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; |
| 424 | if (dnat_took_place(skb)) { | 411 | if (daddr_was_changed(skb, nf_bridge)) { |
| 425 | if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) { | 412 | if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) { |
| 426 | struct in_device *in_dev = __in_dev_get_rcu(dev); | 413 | struct in_device *in_dev = __in_dev_get_rcu(dev); |
| 427 | 414 | ||
| @@ -632,6 +619,7 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops, | |||
| 632 | struct sk_buff *skb, | 619 | struct sk_buff *skb, |
| 633 | const struct nf_hook_state *state) | 620 | const struct nf_hook_state *state) |
| 634 | { | 621 | { |
| 622 | struct nf_bridge_info *nf_bridge; | ||
| 635 | struct net_bridge_port *p; | 623 | struct net_bridge_port *p; |
| 636 | struct net_bridge *br; | 624 | struct net_bridge *br; |
| 637 | __u32 len = nf_bridge_encap_header_len(skb); | 625 | __u32 len = nf_bridge_encap_header_len(skb); |
| @@ -669,6 +657,9 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops, | |||
| 669 | if (!setup_pre_routing(skb)) | 657 | if (!setup_pre_routing(skb)) |
| 670 | return NF_DROP; | 658 | return NF_DROP; |
| 671 | 659 | ||
| 660 | nf_bridge = nf_bridge_info_get(skb); | ||
| 661 | nf_bridge->ipv4_daddr = ip_hdr(skb)->daddr; | ||
| 662 | |||
| 672 | skb->protocol = htons(ETH_P_IP); | 663 | skb->protocol = htons(ETH_P_IP); |
| 673 | 664 | ||
| 674 | NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, state->sk, skb, | 665 | NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, state->sk, skb, |
