path: root/net/bridge/br_netfilter.c
diff options
authorDavid S. Miller <davem@davemloft.net>2015-05-23 01:22:35 -0400
committerDavid S. Miller <davem@davemloft.net>2015-05-23 01:22:35 -0400
commit36583eb54d46c36a447afd6c379839f292397429 (patch)
tree70f5399529dc2135a986947b37c655194da60e9d /net/bridge/br_netfilter.c
parentMerge branch 'pktgen-new-scripts' (diff)
parentMerge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts: drivers/net/ethernet/cadence/macb.c drivers/net/phy/phy.c include/linux/skbuff.h net/ipv4/tcp.c net/switchdev/switchdev.c Switchdev was a case of RTNH_H_{EXTERNAL --> OFFLOAD} renaming overlapping with net-next changes of various sorts. phy.c was a case of two changes, one adding a local variable to a function whilst the second was removing one. tcp.c overlapped a deadlock fix with the addition of new tcp_info statistic values. macb.c involved the addition of two zyncq device entries. skbuff.h involved adding back ipv4_daddr to nf_bridge_info whilst net-next changes put two other existing members of that struct into a union. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br_netfilter.c')
1 files changed, 9 insertions, 18 deletions
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 1d2eb32d8270..46660a28feef 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -37,10 +37,6 @@
#include <net/route.h>
#include <net/netfilter/br_netfilter.h>
-#include <net/netfilter/nf_conntrack.h>
#include <asm/uaccess.h>
#include "br_private.h"
@@ -358,24 +354,15 @@ free_skb:
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)
- 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);
- return false;
+ return ip_hdr(skb)->daddr != nf_bridge->ipv4_daddr;
/* This requires some explaining. If DNAT has taken place,
* 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:
* 1. The packet was DNAT'ed to a device in the same bridge
@@ -429,7 +416,7 @@ static int br_nf_pre_routing_finish(struct sock *sk, struct sk_buff *skb)
nf_bridge->pkt_otherhost = false;
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))) {
struct in_device *in_dev = __in_dev_get_rcu(dev);
@@ -640,6 +627,7 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops,
struct sk_buff *skb,
const struct nf_hook_state *state)
+ struct nf_bridge_info *nf_bridge;
struct net_bridge_port *p;
struct net_bridge *br;
__u32 len = nf_bridge_encap_header_len(skb);
@@ -677,6 +665,9 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops,
if (!setup_pre_routing(skb))
return NF_DROP;
+ nf_bridge = nf_bridge_info_get(skb);
+ nf_bridge->ipv4_daddr = ip_hdr(skb)->daddr;
skb->protocol = htons(ETH_P_IP);