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>
This commit is contained in:
committed by
Pablo Neira Ayuso
parent
169bf9121b
commit
c055d5b03b
@@ -54,12 +54,6 @@ static inline unsigned int nf_bridge_pad(const struct sk_buff *skb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct bridge_skb_cb {
|
|
||||||
union {
|
|
||||||
__be32 ipv4;
|
|
||||||
} daddr;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void br_drop_fake_rtable(struct sk_buff *skb)
|
static inline void br_drop_fake_rtable(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct dst_entry *dst = skb_dst(skb);
|
struct dst_entry *dst = skb_dst(skb);
|
||||||
|
|||||||
@@ -37,17 +37,16 @@
|
|||||||
#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
|
||||||
#include <linux/sysctl.h>
|
#include <linux/sysctl.h>
|
||||||
#endif
|
#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
|
#ifdef CONFIG_SYSCTL
|
||||||
static struct ctl_table_header *brnf_sysctl_header;
|
static struct ctl_table_header *brnf_sysctl_header;
|
||||||
static int brnf_call_iptables __read_mostly = 1;
|
static int brnf_call_iptables __read_mostly = 1;
|
||||||
@@ -322,6 +321,22 @@ free_skb:
|
|||||||
return 0;
|
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,
|
/* 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.
|
||||||
*
|
*
|
||||||
@@ -625,7 +640,7 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops,
|
|||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
if (!setup_pre_routing(skb))
|
if (!setup_pre_routing(skb))
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
store_orig_dstaddr(skb);
|
|
||||||
skb->protocol = htons(ETH_P_IP);
|
skb->protocol = htons(ETH_P_IP);
|
||||||
|
|
||||||
NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
|
NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
|
||||||
|
|||||||
Reference in New Issue
Block a user