netfilter: flowtable: add vlan match offload support

This patch adds support for vlan_id, vlan_priority and vlan_proto match
for flowtable offload.

Signed-off-by: wenxu <wenxu@ucloud.cn>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
wenxu 2021-04-03 21:59:42 +08:00 committed by Pablo Neira Ayuso
parent 8ef7adc6be
commit 3e1b0c168f
2 changed files with 39 additions and 0 deletions

View File

@ -21,6 +21,8 @@ struct nf_flow_key {
struct flow_dissector_key_control control;
struct flow_dissector_key_control enc_control;
struct flow_dissector_key_basic basic;
struct flow_dissector_key_vlan vlan;
struct flow_dissector_key_vlan cvlan;
union {
struct flow_dissector_key_ipv4_addrs ipv4;
struct flow_dissector_key_ipv6_addrs ipv6;

View File

@ -78,6 +78,16 @@ static void nf_flow_rule_lwt_match(struct nf_flow_match *match,
match->dissector.used_keys |= enc_keys;
}
static void nf_flow_rule_vlan_match(struct flow_dissector_key_vlan *key,
struct flow_dissector_key_vlan *mask,
u16 vlan_id, __be16 proto)
{
key->vlan_id = vlan_id;
mask->vlan_id = VLAN_VID_MASK;
key->vlan_tpid = proto;
mask->vlan_tpid = 0xffff;
}
static int nf_flow_rule_match(struct nf_flow_match *match,
const struct flow_offload_tuple *tuple,
struct dst_entry *other_dst)
@ -85,6 +95,7 @@ static int nf_flow_rule_match(struct nf_flow_match *match,
struct nf_flow_key *mask = &match->mask;
struct nf_flow_key *key = &match->key;
struct ip_tunnel_info *tun_info;
bool vlan_encap = false;
NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_META, meta);
NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_CONTROL, control);
@ -102,6 +113,32 @@ static int nf_flow_rule_match(struct nf_flow_match *match,
key->meta.ingress_ifindex = tuple->iifidx;
mask->meta.ingress_ifindex = 0xffffffff;
if (tuple->encap_num > 0 && !(tuple->in_vlan_ingress & BIT(0)) &&
tuple->encap[0].proto == htons(ETH_P_8021Q)) {
NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_VLAN, vlan);
nf_flow_rule_vlan_match(&key->vlan, &mask->vlan,
tuple->encap[0].id,
tuple->encap[0].proto);
vlan_encap = true;
}
if (tuple->encap_num > 1 && !(tuple->in_vlan_ingress & BIT(1)) &&
tuple->encap[1].proto == htons(ETH_P_8021Q)) {
if (vlan_encap) {
NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_CVLAN,
cvlan);
nf_flow_rule_vlan_match(&key->cvlan, &mask->cvlan,
tuple->encap[1].id,
tuple->encap[1].proto);
} else {
NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_VLAN,
vlan);
nf_flow_rule_vlan_match(&key->vlan, &mask->vlan,
tuple->encap[1].id,
tuple->encap[1].proto);
}
}
switch (tuple->l3proto) {
case AF_INET:
key->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;