Commit faecbb45 authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso

Revert "netfilter: bridge: query conntrack about skb dnat"

This reverts commit c055d5b0.

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: default avatarBernhard Thaler <bernhard.thaler@wvnet.at>
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 1086bbe9
...@@ -176,6 +176,7 @@ struct nf_bridge_info { ...@@ -176,6 +176,7 @@ struct nf_bridge_info {
struct net_device *physindev; struct net_device *physindev;
struct net_device *physoutdev; struct net_device *physoutdev;
char neigh_header[8]; char neigh_header[8];
__be32 ipv4_daddr;
}; };
#endif #endif
......
...@@ -37,10 +37,6 @@ ...@@ -37,10 +37,6 @@
#include <net/route.h> #include <net/route.h>
#include <net/netfilter/br_netfilter.h> #include <net/netfilter/br_netfilter.h>
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
#include <net/netfilter/nf_conntrack.h>
#endif
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "br_private.h" #include "br_private.h"
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
...@@ -350,24 +346,15 @@ static int br_nf_pre_routing_finish_bridge(struct sock *sk, struct sk_buff *skb) ...@@ -350,24 +346,15 @@ static int br_nf_pre_routing_finish_bridge(struct sock *sk, struct sk_buff *skb)
return 0; return 0;
} }
static bool dnat_took_place(const struct sk_buff *skb) static bool daddr_was_changed(const struct sk_buff *skb,
const struct nf_bridge_info *nf_bridge)
{ {
#if IS_ENABLED(CONFIG_NF_CONNTRACK) return ip_hdr(skb)->daddr != nf_bridge->ipv4_daddr;
enum ip_conntrack_info ctinfo;
struct nf_conn *ct;
ct = nf_ct_get(skb, &ctinfo);
if (!ct || nf_ct_is_untracked(ct))
return false;
return test_bit(IPS_DST_NAT_BIT, &ct->status);
#else
return false;
#endif
} }
/* This requires some explaining. If DNAT has taken place, /* This requires some explaining. If DNAT has taken place,
* we will need to fix up the destination Ethernet address. * we will need to fix up the destination Ethernet address.
* This is also true when SNAT takes place (for the reply direction).
* *
* There are two cases to consider: * There are two cases to consider:
* 1. The packet was DNAT'ed to a device in the same bridge * 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,7 +408,7 @@ static int br_nf_pre_routing_finish(struct sock *sk, struct sk_buff *skb)
nf_bridge->pkt_otherhost = false; nf_bridge->pkt_otherhost = false;
} }
nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
if (dnat_took_place(skb)) { if (daddr_was_changed(skb, nf_bridge)) {
if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) { if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) {
struct in_device *in_dev = __in_dev_get_rcu(dev); struct in_device *in_dev = __in_dev_get_rcu(dev);
...@@ -632,6 +619,7 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops, ...@@ -632,6 +619,7 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct nf_hook_state *state) const struct nf_hook_state *state)
{ {
struct nf_bridge_info *nf_bridge;
struct net_bridge_port *p; struct net_bridge_port *p;
struct net_bridge *br; struct net_bridge *br;
__u32 len = nf_bridge_encap_header_len(skb); __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,6 +657,9 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops,
if (!setup_pre_routing(skb)) if (!setup_pre_routing(skb))
return NF_DROP; return NF_DROP;
nf_bridge = nf_bridge_info_get(skb);
nf_bridge->ipv4_daddr = ip_hdr(skb)->daddr;
skb->protocol = htons(ETH_P_IP); skb->protocol = htons(ETH_P_IP);
NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, state->sk, skb, NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, state->sk, skb,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment