netfilter: bridge: start splitting mask into public/private chunks
authorFlorian Westphal <fw@strlen.de>
Thu, 2 Apr 2015 12:31:44 +0000 (14:31 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 8 Apr 2015 14:49:11 +0000 (16:49 +0200)
->mask is a bit info field that mixes various use cases.

In particular, we have flags that are mutually exlusive, and flags that
are only used within br_netfilter while others need to be exposed to
other parts of the kernel.

Remove BRNF_8021Q/PPPoE flags.  They're mutually exclusive and only
needed within br_netfilter context.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/linux/netfilter_bridge.h
include/linux/skbuff.h
net/bridge/br_netfilter.c

index e1d96bc2767cf0f4da711075c885cdee7ac14baf..d47a32dffa1567fefe4888b29e8d8794c87a9017 100644 (file)
@@ -20,12 +20,10 @@ enum nf_br_hook_priorities {
 #define BRNF_PKT_TYPE                  0x01
 #define BRNF_BRIDGED_DNAT              0x02
 #define BRNF_NF_BRIDGE_PREROUTING      0x08
-#define BRNF_8021Q                     0x10
-#define BRNF_PPPoE                     0x20
 
 static inline unsigned int nf_bridge_mtu_reduction(const struct sk_buff *skb)
 {
-       if (unlikely(skb->nf_bridge->mask & BRNF_PPPoE))
+       if (skb->nf_bridge->orig_proto == BRNF_PROTO_PPPOE)
                return PPPOE_SES_HLEN;
        return 0;
 }
index f66a089afc41c8dc4ad9b9663d7bc04d4ade799f..6f75fb5c6ed7537f8a5c8465e9fdaf448f1ab5c6 100644 (file)
@@ -166,6 +166,11 @@ struct nf_conntrack {
 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
 struct nf_bridge_info {
        atomic_t                use;
+       enum {
+               BRNF_PROTO_UNCHANGED,
+               BRNF_PROTO_8021Q,
+               BRNF_PROTO_PPPOE
+       } orig_proto;
        unsigned int            mask;
        struct net_device       *physindev;
        struct net_device       *physoutdev;
index 301f12b0a7cde4da84c728d19ce2f507e4700df4..ab1e988ca4b8d191ef8f82adeb4dd1dd58cf0b36 100644 (file)
@@ -262,10 +262,16 @@ drop:
 
 static void nf_bridge_update_protocol(struct sk_buff *skb)
 {
-       if (skb->nf_bridge->mask & BRNF_8021Q)
+       switch (skb->nf_bridge->orig_proto) {
+       case BRNF_PROTO_8021Q:
                skb->protocol = htons(ETH_P_8021Q);
-       else if (skb->nf_bridge->mask & BRNF_PPPoE)
+               break;
+       case BRNF_PROTO_PPPOE:
                skb->protocol = htons(ETH_P_PPP_SES);
+               break;
+       case BRNF_PROTO_UNCHANGED:
+               break;
+       }
 }
 
 /* PF_BRIDGE/PRE_ROUTING *********************************************/
@@ -503,10 +509,11 @@ static struct net_device *setup_pre_routing(struct sk_buff *skb)
        nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING;
        nf_bridge->physindev = skb->dev;
        skb->dev = brnf_get_logical_dev(skb, skb->dev);
+
        if (skb->protocol == htons(ETH_P_8021Q))
-               nf_bridge->mask |= BRNF_8021Q;
+               nf_bridge->orig_proto = BRNF_PROTO_8021Q;
        else if (skb->protocol == htons(ETH_P_PPP_SES))
-               nf_bridge->mask |= BRNF_PPPoE;
+               nf_bridge->orig_proto = BRNF_PROTO_PPPOE;
 
        /* Must drop socket now because of tproxy. */
        skb_orphan(skb);