summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2018-12-18 11:15:17 -0500
committerDavid S. Miller <davem@davemloft.net>2018-12-19 14:21:37 -0500
commitde8bda1d22d38b7d5cd08b33f86efd94d4c86630 (patch)
tree7acdf2397b31eb8b1601c9183ef30b8ebbe8400a
parentdf5042f4c5b9326c593bf2e31ed859ebc3b4130a (diff)
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>
-rw-r--r--include/linux/netfilter_bridge.h4
-rw-r--r--include/linux/skbuff.h28
-rw-r--r--include/net/netfilter/br_netfilter.h8
-rw-r--r--net/Kconfig1
-rw-r--r--net/bridge/br_netfilter_hooks.c20
-rw-r--r--net/bridge/br_netfilter_ipv6.c4
-rw-r--r--net/core/skbuff.c3
7 files changed, 13 insertions, 55 deletions
diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h
index 0a65a422587c..5f2614d02e03 100644
--- a/include/linux/netfilter_bridge.h
+++ b/include/linux/netfilter_bridge.h
@@ -20,12 +20,12 @@ static inline void br_drop_fake_rtable(struct sk_buff *skb)
20static inline struct nf_bridge_info * 20static inline struct nf_bridge_info *
21nf_bridge_info_get(const struct sk_buff *skb) 21nf_bridge_info_get(const struct sk_buff *skb)
22{ 22{
23 return skb->nf_bridge; 23 return skb_ext_find(skb, SKB_EXT_BRIDGE_NF);
24} 24}
25 25
26static inline bool nf_bridge_info_exists(const struct sk_buff *skb) 26static inline bool nf_bridge_info_exists(const struct sk_buff *skb)
27{ 27{
28 return skb->nf_bridge != NULL; 28 return skb_ext_exist(skb, SKB_EXT_BRIDGE_NF);
29} 29}
30 30
31static inline int nf_bridge_get_physinif(const struct sk_buff *skb) 31static inline int nf_bridge_get_physinif(const struct sk_buff *skb)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 88f7541837e3..2f42d2e99f17 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -255,7 +255,6 @@ struct nf_conntrack {
255 255
256#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 256#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
257struct nf_bridge_info { 257struct nf_bridge_info {
258 refcount_t use;
259 enum { 258 enum {
260 BRNF_PROTO_UNCHANGED, 259 BRNF_PROTO_UNCHANGED,
261 BRNF_PROTO_8021Q, 260 BRNF_PROTO_8021Q,
@@ -721,9 +720,6 @@ struct sk_buff {
721#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 720#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
722 unsigned long _nfct; 721 unsigned long _nfct;
723#endif 722#endif
724#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
725 struct nf_bridge_info *nf_bridge;
726#endif
727 unsigned int len, 723 unsigned int len,
728 data_len; 724 data_len;
729 __u16 mac_len, 725 __u16 mac_len,
@@ -4005,18 +4001,6 @@ static inline void __skb_ext_copy(struct sk_buff *d, const struct sk_buff *s) {}
4005static inline void skb_ext_copy(struct sk_buff *dst, const struct sk_buff *s) {} 4001static inline void skb_ext_copy(struct sk_buff *dst, const struct sk_buff *s) {}
4006#endif /* CONFIG_SKB_EXTENSIONS */ 4002#endif /* CONFIG_SKB_EXTENSIONS */
4007 4003
4008#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
4009static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge)
4010{
4011 if (nf_bridge && refcount_dec_and_test(&nf_bridge->use))
4012 kfree(nf_bridge);
4013}
4014static inline void nf_bridge_get(struct nf_bridge_info *nf_bridge)
4015{
4016 if (nf_bridge)
4017 refcount_inc(&nf_bridge->use);
4018}
4019#endif /* CONFIG_BRIDGE_NETFILTER */
4020static inline void nf_reset(struct sk_buff *skb) 4004static inline void nf_reset(struct sk_buff *skb)
4021{ 4005{
4022#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 4006#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
@@ -4024,8 +4008,7 @@ static inline void nf_reset(struct sk_buff *skb)
4024 skb->_nfct = 0; 4008 skb->_nfct = 0;
4025#endif 4009#endif
4026#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 4010#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
4027 nf_bridge_put(skb->nf_bridge); 4011 skb_ext_del(skb, SKB_EXT_BRIDGE_NF);
4028 skb->nf_bridge = NULL;
4029#endif 4012#endif
4030} 4013}
4031 4014
@@ -4043,7 +4026,7 @@ static inline void ipvs_reset(struct sk_buff *skb)
4043#endif 4026#endif
4044} 4027}
4045 4028
4046/* Note: This doesn't put any conntrack and bridge info in dst. */ 4029/* Note: This doesn't put any conntrack info in dst. */
4047static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src, 4030static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src,
4048 bool copy) 4031 bool copy)
4049{ 4032{
@@ -4051,10 +4034,6 @@ static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src,
4051 dst->_nfct = src->_nfct; 4034 dst->_nfct = src->_nfct;
4052 nf_conntrack_get(skb_nfct(src)); 4035 nf_conntrack_get(skb_nfct(src));
4053#endif 4036#endif
4054#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
4055 dst->nf_bridge = src->nf_bridge;
4056 nf_bridge_get(src->nf_bridge);
4057#endif
4058#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) || defined(CONFIG_NF_TABLES) 4037#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) || defined(CONFIG_NF_TABLES)
4059 if (copy) 4038 if (copy)
4060 dst->nf_trace = src->nf_trace; 4039 dst->nf_trace = src->nf_trace;
@@ -4066,9 +4045,6 @@ static inline void nf_copy(struct sk_buff *dst, const struct sk_buff *src)
4066#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 4045#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
4067 nf_conntrack_put(skb_nfct(dst)); 4046 nf_conntrack_put(skb_nfct(dst));
4068#endif 4047#endif
4069#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
4070 nf_bridge_put(dst->nf_bridge);
4071#endif
4072 __nf_copy(dst, src, true); 4048 __nf_copy(dst, src, true);
4073} 4049}
4074 4050
diff --git a/include/net/netfilter/br_netfilter.h b/include/net/netfilter/br_netfilter.h
index 6efc0153987b..4cd56808ac4e 100644
--- a/include/net/netfilter/br_netfilter.h
+++ b/include/net/netfilter/br_netfilter.h
@@ -6,12 +6,12 @@
6 6
7static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb) 7static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb)
8{ 8{
9 skb->nf_bridge = kzalloc(sizeof(struct nf_bridge_info), GFP_ATOMIC); 9 struct nf_bridge_info *b = skb_ext_add(skb, SKB_EXT_BRIDGE_NF);
10 10
11 if (likely(skb->nf_bridge)) 11 if (b)
12 refcount_set(&(skb->nf_bridge->use), 1); 12 memset(b, 0, sizeof(*b));
13 13
14 return skb->nf_bridge; 14 return b;
15} 15}
16 16
17void nf_bridge_update_protocol(struct sk_buff *skb); 17void nf_bridge_update_protocol(struct sk_buff *skb);
diff --git a/net/Kconfig b/net/Kconfig
index 93b291292860..5cb9de1aaf88 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -187,6 +187,7 @@ config BRIDGE_NETFILTER
187 depends on NETFILTER && INET 187 depends on NETFILTER && INET
188 depends on NETFILTER_ADVANCED 188 depends on NETFILTER_ADVANCED
189 select NETFILTER_FAMILY_BRIDGE 189 select NETFILTER_FAMILY_BRIDGE
190 select SKB_EXTENSIONS
190 default m 191 default m
191 ---help--- 192 ---help---
192 Enabling this option will let arptables resp. iptables see bridged 193 Enabling this option will let arptables resp. iptables see bridged
diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
index c58cf68b45c5..d21a23698410 100644
--- a/net/bridge/br_netfilter_hooks.c
+++ b/net/bridge/br_netfilter_hooks.c
@@ -132,10 +132,7 @@ static DEFINE_PER_CPU(struct brnf_frag_data, brnf_frag_data_storage);
132 132
133static void nf_bridge_info_free(struct sk_buff *skb) 133static void nf_bridge_info_free(struct sk_buff *skb)
134{ 134{
135 if (skb->nf_bridge) { 135 skb_ext_del(skb, SKB_EXT_BRIDGE_NF);
136 nf_bridge_put(skb->nf_bridge);
137 skb->nf_bridge = NULL;
138 }
139} 136}
140 137
141static inline struct net_device *bridge_parent(const struct net_device *dev) 138static 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)
148 145
149static inline struct nf_bridge_info *nf_bridge_unshare(struct sk_buff *skb) 146static inline struct nf_bridge_info *nf_bridge_unshare(struct sk_buff *skb)
150{ 147{
151 struct nf_bridge_info *nf_bridge = skb->nf_bridge; 148 return skb_ext_add(skb, SKB_EXT_BRIDGE_NF);
152
153 if (refcount_read(&nf_bridge->use) > 1) {
154 struct nf_bridge_info *tmp = nf_bridge_alloc(skb);
155
156 if (tmp) {
157 memcpy(tmp, nf_bridge, sizeof(struct nf_bridge_info));
158 refcount_set(&tmp->use, 1);
159 }
160 nf_bridge_put(nf_bridge);
161 nf_bridge = tmp;
162 }
163 return nf_bridge;
164} 149}
165 150
166unsigned int nf_bridge_encap_header_len(const struct sk_buff *skb) 151unsigned int nf_bridge_encap_header_len(const struct sk_buff *skb)
@@ -508,7 +493,6 @@ static unsigned int br_nf_pre_routing(void *priv,
508 if (br_validate_ipv4(state->net, skb)) 493 if (br_validate_ipv4(state->net, skb))
509 return NF_DROP; 494 return NF_DROP;
510 495
511 nf_bridge_put(skb->nf_bridge);
512 if (!nf_bridge_alloc(skb)) 496 if (!nf_bridge_alloc(skb))
513 return NF_DROP; 497 return NF_DROP;
514 if (!setup_pre_routing(skb)) 498 if (!setup_pre_routing(skb))
diff --git a/net/bridge/br_netfilter_ipv6.c b/net/bridge/br_netfilter_ipv6.c
index 96c072e71ea2..94039f588f1d 100644
--- a/net/bridge/br_netfilter_ipv6.c
+++ b/net/bridge/br_netfilter_ipv6.c
@@ -224,8 +224,8 @@ unsigned int br_nf_pre_routing_ipv6(void *priv,
224 if (br_validate_ipv6(state->net, skb)) 224 if (br_validate_ipv6(state->net, skb))
225 return NF_DROP; 225 return NF_DROP;
226 226
227 nf_bridge_put(skb->nf_bridge); 227 nf_bridge = nf_bridge_alloc(skb);
228 if (!nf_bridge_alloc(skb)) 228 if (!nf_bridge)
229 return NF_DROP; 229 return NF_DROP;
230 if (!setup_pre_routing(skb)) 230 if (!setup_pre_routing(skb))
231 return NF_DROP; 231 return NF_DROP;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index d2dfad33e686..0c65723591d7 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -617,9 +617,6 @@ void skb_release_head_state(struct sk_buff *skb)
617#if IS_ENABLED(CONFIG_NF_CONNTRACK) 617#if IS_ENABLED(CONFIG_NF_CONNTRACK)
618 nf_conntrack_put(skb_nfct(skb)); 618 nf_conntrack_put(skb_nfct(skb));
619#endif 619#endif
620#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
621 nf_bridge_put(skb->nf_bridge);
622#endif
623 skb_ext_put(skb); 620 skb_ext_put(skb);
624} 621}
625 622