]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
netfilter: bridge: query conntrack about skb dnat
authorFlorian Westphal <fw@strlen.de>
Tue, 10 Mar 2015 04:08:19 +0000 (05:08 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 16 Mar 2015 13:34:34 +0000 (14:34 +0100)
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>
include/linux/netfilter_bridge.h
net/bridge/br_netfilter.c

index bb39113ea5965f07cae1862d0e9c64980307a3e8..de123d769ffc7c55fab505e09057384dcdd66e7b 100644 (file)
@@ -54,12 +54,6 @@ static inline unsigned int nf_bridge_pad(const struct sk_buff *skb)
        return 0;
 }
 
-struct bridge_skb_cb {
-       union {
-               __be32 ipv4;
-       } daddr;
-};
-
 static inline void br_drop_fake_rtable(struct sk_buff *skb)
 {
        struct dst_entry *dst = skb_dst(skb);
index b260a97275db30fbe5a7e301c989e95996d36afb..261fcd5a42d6b64bac5ef704ae7e3b76c302e87e 100644 (file)
 #include <net/route.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 "br_private.h"
 #ifdef CONFIG_SYSCTL
 #include <linux/sysctl.h>
 #endif
 
-#define skb_origaddr(skb)       (((struct bridge_skb_cb *) \
-                                (skb->nf_bridge->data))->daddr.ipv4)
-#define store_orig_dstaddr(skb)         (skb_origaddr(skb) = ip_hdr(skb)->daddr)
-#define dnat_took_place(skb)    (skb_origaddr(skb) != ip_hdr(skb)->daddr)
-
 #ifdef CONFIG_SYSCTL
 static struct ctl_table_header *brnf_sysctl_header;
 static int brnf_call_iptables __read_mostly = 1;
@@ -322,6 +321,22 @@ free_skb:
        return 0;
 }
 
+static bool dnat_took_place(const struct sk_buff *skb)
+{
+#if IS_ENABLED(CONFIG_NF_CONNTRACK)
+       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,
  * we will need to fix up the destination Ethernet address.
  *
@@ -625,7 +640,7 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops,
                return NF_DROP;
        if (!setup_pre_routing(skb))
                return NF_DROP;
-       store_orig_dstaddr(skb);
+
        skb->protocol = htons(ETH_P_IP);
 
        NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,