diff options
author | Florian Westphal <fw@strlen.de> | 2018-12-18 11:15:17 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-12-19 14:21:37 -0500 |
commit | de8bda1d22d38b7d5cd08b33f86efd94d4c86630 (patch) | |
tree | 7acdf2397b31eb8b1601c9183ef30b8ebbe8400a | |
parent | df5042f4c5b9326c593bf2e31ed859ebc3b4130a (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.h | 4 | ||||
-rw-r--r-- | include/linux/skbuff.h | 28 | ||||
-rw-r--r-- | include/net/netfilter/br_netfilter.h | 8 | ||||
-rw-r--r-- | net/Kconfig | 1 | ||||
-rw-r--r-- | net/bridge/br_netfilter_hooks.c | 20 | ||||
-rw-r--r-- | net/bridge/br_netfilter_ipv6.c | 4 | ||||
-rw-r--r-- | net/core/skbuff.c | 3 |
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) | |||
20 | static inline struct nf_bridge_info * | 20 | static inline struct nf_bridge_info * |
21 | nf_bridge_info_get(const struct sk_buff *skb) | 21 | nf_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 | ||
26 | static inline bool nf_bridge_info_exists(const struct sk_buff *skb) | 26 | static 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 | ||
31 | static inline int nf_bridge_get_physinif(const struct sk_buff *skb) | 31 | static 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) |
257 | struct nf_bridge_info { | 257 | struct 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) {} | |||
4005 | static inline void skb_ext_copy(struct sk_buff *dst, const struct sk_buff *s) {} | 4001 | static 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) | ||
4009 | static 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 | } | ||
4014 | static 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 */ | ||
4020 | static inline void nf_reset(struct sk_buff *skb) | 4004 | static 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. */ |
4047 | static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src, | 4030 | static 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 | ||
7 | static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb) | 7 | static 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 | ||
17 | void nf_bridge_update_protocol(struct sk_buff *skb); | 17 | void 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 | ||
133 | static void nf_bridge_info_free(struct sk_buff *skb) | 133 | static 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 | ||
141 | static inline struct net_device *bridge_parent(const struct net_device *dev) | 138 | 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) | |||
148 | 145 | ||
149 | static inline struct nf_bridge_info *nf_bridge_unshare(struct sk_buff *skb) | 146 | static 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 | ||
166 | unsigned int nf_bridge_encap_header_len(const struct sk_buff *skb) | 151 | 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, | |||
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 | ||