Commit 3e1b0c16 authored by wenxu's avatar wenxu Committed by Pablo Neira Ayuso
Browse files

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: default avatarwenxu <wenxu@ucloud.cn>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 8ef7adc6
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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;
+37 −0
Original line number Diff line number Diff line
@@ -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;