net: convert bridge_nf to use skb extension infrastructure
authorFlorian Westphal <fw@strlen.de>
Tue, 18 Dec 2018 16:15:17 +0000 (17:15 +0100)
committerDavid S. Miller <davem@davemloft.net>
Wed, 19 Dec 2018 19:21:37 +0000 (11:21 -0800)
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>
include/linux/netfilter_bridge.h
include/linux/skbuff.h
include/net/netfilter/br_netfilter.h
net/Kconfig
net/bridge/br_netfilter_hooks.c
net/bridge/br_netfilter_ipv6.c
net/core/skbuff.c

index 0a65a422587ce89c7edb7a665b02da400f208f8c..5f2614d02e03a8e3944e9bf48781bc4212dcc9cb 100644 (file)
@@ -20,12 +20,12 @@ static inline void br_drop_fake_rtable(struct sk_buff *skb)
 static inline struct nf_bridge_info *
 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)
 {
-       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)
index 88f7541837e3437f3d0ef8850ccbf701ca1b1f2c..2f42d2e99f17fc32da6e4522a74780f9a476da40 100644 (file)
@@ -255,7 +255,6 @@ struct nf_conntrack {
 
 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
 struct nf_bridge_info {
-       refcount_t              use;
        enum {
                BRNF_PROTO_UNCHANGED,
                BRNF_PROTO_8021Q,
@@ -720,9 +719,6 @@ struct sk_buff {
 #endif
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
        unsigned long            _nfct;
-#endif
-#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
-       struct nf_bridge_info   *nf_bridge;
 #endif
        unsigned int            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) {}
 #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)
 {
 #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;
 #endif
 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
-       nf_bridge_put(skb->nf_bridge);
-       skb->nf_bridge = NULL;
+       skb_ext_del(skb, SKB_EXT_BRIDGE_NF);
 #endif
 }
 
@@ -4043,7 +4026,7 @@ static inline void ipvs_reset(struct sk_buff *skb)
 #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,
                             bool copy)
 {
@@ -4051,10 +4034,6 @@ static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src,
        dst->_nfct = src->_nfct;
        nf_conntrack_get(skb_nfct(src));
 #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 (copy)
                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)
        nf_conntrack_put(skb_nfct(dst));
-#endif
-#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
-       nf_bridge_put(dst->nf_bridge);
 #endif
        __nf_copy(dst, src, true);
 }
index 6efc0153987b36f2d2559aa4e2480acdaa827ff6..4cd56808ac4e143bda84c888000fd527b44e9217 100644 (file)
@@ -6,12 +6,12 @@
 
 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))
-               refcount_set(&(skb->nf_bridge->use), 1);
+       if (b)
+               memset(b, 0, sizeof(*b));
 
-       return skb->nf_bridge;
+       return b;
 }
 
 void nf_bridge_update_protocol(struct sk_buff *skb);
index 93b291292860998fc24bdb697fe257955d19ef89..5cb9de1aaf886a7f6d0dd1eb883241d5f5104ff6 100644 (file)
@@ -187,6 +187,7 @@ config BRIDGE_NETFILTER
        depends on NETFILTER && INET
        depends on NETFILTER_ADVANCED
        select NETFILTER_FAMILY_BRIDGE
+       select SKB_EXTENSIONS
        default m
        ---help---
          Enabling this option will let arptables resp. iptables see bridged
index c58cf68b45c5f414cd6066283f1240dfab4d736c..d21a23698410152d977576c0bd7973731077081f 100644 (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)
 {
-       if (skb->nf_bridge) {
-               nf_bridge_put(skb->nf_bridge);
-               skb->nf_bridge = NULL;
-       }
+       skb_ext_del(skb, SKB_EXT_BRIDGE_NF);
 }
 
 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)
 {
-       struct nf_bridge_info *nf_bridge = skb->nf_bridge;
-
-       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;
+       return skb_ext_add(skb, SKB_EXT_BRIDGE_NF);
 }
 
 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))
                return NF_DROP;
 
-       nf_bridge_put(skb->nf_bridge);
        if (!nf_bridge_alloc(skb))
                return NF_DROP;
        if (!setup_pre_routing(skb))
index 96c072e71ea2eb7bc904b100914dc098707eb4d1..94039f588f1dd1c390f5b65dd62c23f86ee2687e 100644 (file)
@@ -224,8 +224,8 @@ unsigned int br_nf_pre_routing_ipv6(void *priv,
        if (br_validate_ipv6(state->net, skb))
                return NF_DROP;
 
-       nf_bridge_put(skb->nf_bridge);
-       if (!nf_bridge_alloc(skb))
+       nf_bridge = nf_bridge_alloc(skb);
+       if (!nf_bridge)
                return NF_DROP;
        if (!setup_pre_routing(skb))
                return NF_DROP;
index d2dfad33e6864b45f06ce8de319f7133222ecd3c..0c65723591d7b0b1120e4e5d71707465713811fd 100644 (file)
@@ -616,9 +616,6 @@ void skb_release_head_state(struct sk_buff *skb)
        }
 #if IS_ENABLED(CONFIG_NF_CONNTRACK)
        nf_conntrack_put(skb_nfct(skb));
-#endif
-#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
-       nf_bridge_put(skb->nf_bridge);
 #endif
        skb_ext_put(skb);
 }