1
0
Fork 0

net: convert bridge_nf to use skb extension infrastructure

This converts the bridge netfilter (calling iptables hooks from bridge)
facility to use the extension infrastructure.

The bridge_nf specific hooks in skb clone and free paths are removed, they
have been replaced by the skb_ext hooks that do the same as the bridge nf
allocations hooks did.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
hifive-unleashed-5.1
Florian Westphal 2018-12-18 17:15:17 +01:00 committed by David S. Miller
parent df5042f4c5
commit de8bda1d22
7 changed files with 13 additions and 55 deletions

View File

@ -20,12 +20,12 @@ static inline void br_drop_fake_rtable(struct sk_buff *skb)
static inline struct nf_bridge_info * static inline struct nf_bridge_info *
nf_bridge_info_get(const struct sk_buff *skb) nf_bridge_info_get(const struct sk_buff *skb)
{ {
return skb->nf_bridge; return skb_ext_find(skb, SKB_EXT_BRIDGE_NF);
} }
static inline bool nf_bridge_info_exists(const struct sk_buff *skb) static inline bool nf_bridge_info_exists(const struct sk_buff *skb)
{ {
return skb->nf_bridge != NULL; return skb_ext_exist(skb, SKB_EXT_BRIDGE_NF);
} }
static inline int nf_bridge_get_physinif(const struct sk_buff *skb) static inline int nf_bridge_get_physinif(const struct sk_buff *skb)

View File

@ -255,7 +255,6 @@ struct nf_conntrack {
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
struct nf_bridge_info { struct nf_bridge_info {
refcount_t use;
enum { enum {
BRNF_PROTO_UNCHANGED, BRNF_PROTO_UNCHANGED,
BRNF_PROTO_8021Q, BRNF_PROTO_8021Q,
@ -720,9 +719,6 @@ struct sk_buff {
#endif #endif
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
unsigned long _nfct; unsigned long _nfct;
#endif
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
struct nf_bridge_info *nf_bridge;
#endif #endif
unsigned int len, unsigned int len,
data_len; data_len;
@ -4005,18 +4001,6 @@ static inline void __skb_ext_copy(struct sk_buff *d, const struct sk_buff *s) {}
static inline void skb_ext_copy(struct sk_buff *dst, const struct sk_buff *s) {} static inline void skb_ext_copy(struct sk_buff *dst, const struct sk_buff *s) {}
#endif /* CONFIG_SKB_EXTENSIONS */ #endif /* CONFIG_SKB_EXTENSIONS */
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge)
{
if (nf_bridge && refcount_dec_and_test(&nf_bridge->use))
kfree(nf_bridge);
}
static inline void nf_bridge_get(struct nf_bridge_info *nf_bridge)
{
if (nf_bridge)
refcount_inc(&nf_bridge->use);
}
#endif /* CONFIG_BRIDGE_NETFILTER */
static inline void nf_reset(struct sk_buff *skb) static inline void nf_reset(struct sk_buff *skb)
{ {
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
@ -4024,8 +4008,7 @@ static inline void nf_reset(struct sk_buff *skb)
skb->_nfct = 0; skb->_nfct = 0;
#endif #endif
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
nf_bridge_put(skb->nf_bridge); skb_ext_del(skb, SKB_EXT_BRIDGE_NF);
skb->nf_bridge = NULL;
#endif #endif
} }
@ -4043,7 +4026,7 @@ static inline void ipvs_reset(struct sk_buff *skb)
#endif #endif
} }
/* Note: This doesn't put any conntrack and bridge info in dst. */ /* Note: This doesn't put any conntrack info in dst. */
static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src, static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src,
bool copy) bool copy)
{ {
@ -4051,10 +4034,6 @@ static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src,
dst->_nfct = src->_nfct; dst->_nfct = src->_nfct;
nf_conntrack_get(skb_nfct(src)); nf_conntrack_get(skb_nfct(src));
#endif #endif
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
dst->nf_bridge = src->nf_bridge;
nf_bridge_get(src->nf_bridge);
#endif
#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) || defined(CONFIG_NF_TABLES) #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) || defined(CONFIG_NF_TABLES)
if (copy) if (copy)
dst->nf_trace = src->nf_trace; dst->nf_trace = src->nf_trace;
@ -4065,9 +4044,6 @@ static inline void nf_copy(struct sk_buff *dst, const struct sk_buff *src)
{ {
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
nf_conntrack_put(skb_nfct(dst)); nf_conntrack_put(skb_nfct(dst));
#endif
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
nf_bridge_put(dst->nf_bridge);
#endif #endif
__nf_copy(dst, src, true); __nf_copy(dst, src, true);
} }

View File

@ -6,12 +6,12 @@
static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb) static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb)
{ {
skb->nf_bridge = kzalloc(sizeof(struct nf_bridge_info), GFP_ATOMIC); struct nf_bridge_info *b = skb_ext_add(skb, SKB_EXT_BRIDGE_NF);
if (likely(skb->nf_bridge)) if (b)
refcount_set(&(skb->nf_bridge->use), 1); memset(b, 0, sizeof(*b));
return skb->nf_bridge; return b;
} }
void nf_bridge_update_protocol(struct sk_buff *skb); void nf_bridge_update_protocol(struct sk_buff *skb);

View File

@ -187,6 +187,7 @@ config BRIDGE_NETFILTER
depends on NETFILTER && INET depends on NETFILTER && INET
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
select NETFILTER_FAMILY_BRIDGE select NETFILTER_FAMILY_BRIDGE
select SKB_EXTENSIONS
default m default m
---help--- ---help---
Enabling this option will let arptables resp. iptables see bridged Enabling this option will let arptables resp. iptables see bridged

View File

@ -132,10 +132,7 @@ static DEFINE_PER_CPU(struct brnf_frag_data, brnf_frag_data_storage);
static void nf_bridge_info_free(struct sk_buff *skb) static void nf_bridge_info_free(struct sk_buff *skb)
{ {
if (skb->nf_bridge) { skb_ext_del(skb, SKB_EXT_BRIDGE_NF);
nf_bridge_put(skb->nf_bridge);
skb->nf_bridge = NULL;
}
} }
static inline struct net_device *bridge_parent(const struct net_device *dev) static inline struct net_device *bridge_parent(const struct net_device *dev)
@ -148,19 +145,7 @@ static inline struct net_device *bridge_parent(const struct net_device *dev)
static inline struct nf_bridge_info *nf_bridge_unshare(struct sk_buff *skb) static inline struct nf_bridge_info *nf_bridge_unshare(struct sk_buff *skb)
{ {
struct nf_bridge_info *nf_bridge = skb->nf_bridge; return skb_ext_add(skb, SKB_EXT_BRIDGE_NF);
if (refcount_read(&nf_bridge->use) > 1) {
struct nf_bridge_info *tmp = nf_bridge_alloc(skb);
if (tmp) {
memcpy(tmp, nf_bridge, sizeof(struct nf_bridge_info));
refcount_set(&tmp->use, 1);
}
nf_bridge_put(nf_bridge);
nf_bridge = tmp;
}
return nf_bridge;
} }
unsigned int nf_bridge_encap_header_len(const struct sk_buff *skb) unsigned int nf_bridge_encap_header_len(const struct sk_buff *skb)
@ -508,7 +493,6 @@ static unsigned int br_nf_pre_routing(void *priv,
if (br_validate_ipv4(state->net, skb)) if (br_validate_ipv4(state->net, skb))
return NF_DROP; return NF_DROP;
nf_bridge_put(skb->nf_bridge);
if (!nf_bridge_alloc(skb)) if (!nf_bridge_alloc(skb))
return NF_DROP; return NF_DROP;
if (!setup_pre_routing(skb)) if (!setup_pre_routing(skb))

View File

@ -224,8 +224,8 @@ unsigned int br_nf_pre_routing_ipv6(void *priv,
if (br_validate_ipv6(state->net, skb)) if (br_validate_ipv6(state->net, skb))
return NF_DROP; return NF_DROP;
nf_bridge_put(skb->nf_bridge); nf_bridge = nf_bridge_alloc(skb);
if (!nf_bridge_alloc(skb)) if (!nf_bridge)
return NF_DROP; return NF_DROP;
if (!setup_pre_routing(skb)) if (!setup_pre_routing(skb))
return NF_DROP; return NF_DROP;

View File

@ -616,9 +616,6 @@ void skb_release_head_state(struct sk_buff *skb)
} }
#if IS_ENABLED(CONFIG_NF_CONNTRACK) #if IS_ENABLED(CONFIG_NF_CONNTRACK)
nf_conntrack_put(skb_nfct(skb)); nf_conntrack_put(skb_nfct(skb));
#endif
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
nf_bridge_put(skb->nf_bridge);
#endif #endif
skb_ext_put(skb); skb_ext_put(skb);
} }