]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
netfilter: nft_payload: add VLAN offload support
authorPablo Neira Ayuso <pablo@netfilter.org>
Tue, 19 Nov 2019 22:05:54 +0000 (23:05 +0100)
committerDavid S. Miller <davem@davemloft.net>
Wed, 20 Nov 2019 19:21:34 +0000 (11:21 -0800)
Match on ethertype and set up protocol dependency. Check for protocol
dependency before accessing the tci field. Allow to match on the
encapsulated ethertype too.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/flow_dissector.h
net/netfilter/nft_payload.c

index 1a0727d1acfa915aa7f38ae27211c717a1657969..f06b0239c32ba3c2017f945d299bc15e9fb97274 100644 (file)
@@ -48,9 +48,12 @@ struct flow_dissector_key_tags {
 };
 
 struct flow_dissector_key_vlan {
-       u16     vlan_id:12,
-               vlan_dei:1,
-               vlan_priority:3;
+       union {
+               u16     vlan_id:12,
+                       vlan_dei:1,
+                       vlan_priority:3;
+               __be16  vlan_tci;
+       };
        __be16  vlan_tpid;
 };
 
index 0877d46b8605f9e6739285c4fcff9f724dc757db..f17939fbf6c3ad2e391eb1fbe39ec8139148837b 100644 (file)
@@ -182,6 +182,28 @@ static int nft_payload_offload_ll(struct nft_offload_ctx *ctx,
                NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_ETH_ADDRS, eth_addrs,
                                  dst, ETH_ALEN, reg);
                break;
+       case offsetof(struct ethhdr, h_proto):
+               if (priv->len != sizeof(__be16))
+                       return -EOPNOTSUPP;
+
+               NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic,
+                                 n_proto, sizeof(__be16), reg);
+               nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_NETWORK);
+               break;
+       case offsetof(struct vlan_ethhdr, h_vlan_TCI):
+               if (priv->len != sizeof(__be16))
+                       return -EOPNOTSUPP;
+
+               NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_VLAN, vlan,
+                                 vlan_tci, sizeof(__be16), reg);
+               break;
+       case offsetof(struct vlan_ethhdr, h_vlan_encapsulated_proto):
+               if (priv->len != sizeof(__be16))
+                       return -EOPNOTSUPP;
+
+               NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_VLAN, vlan,
+                                 vlan_tpid, sizeof(__be16), reg);
+               break;
        default:
                return -EOPNOTSUPP;
        }