DPDK patches and discussions
 help / color / mirror / Atom feed
From: Jie Hai <haijie1@huawei.com>
To: <dev@dpdk.org>, Yisen Zhuang <yisen.zhuang@huawei.com>
Cc: <lihuisong@huawei.com>, <fengchengwen@huawei.com>,
	<thomas@monjalon.net>,  <ferruh.yigit@amd.com>,
	<ivan.malov@arknetworks.am>
Subject: [PATCH] net/hns3: support more VLAN fields matching
Date: Thu, 4 Jul 2024 10:15:38 +0800	[thread overview]
Message-ID: <20240704021538.836403-1-haijie1@huawei.com> (raw)

The commit 09315fc83861 ("ethdev: add VLAN attributes to ethernet
and VLAN items") introduces ``has_vlan`` and ``has_more_vlan``
fields in items ETH and VLAN. This patch adds support for these
fields. The usage is documented in hns3.rst.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 doc/guides/nics/hns3.rst     | 65 ++++++++++++++++++++++++++++++++++++
 drivers/net/hns3/hns3_fdir.h |  4 +++
 drivers/net/hns3/hns3_flow.c | 47 +++++++++++++++++++++++---
 3 files changed, 112 insertions(+), 4 deletions(-)

diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst
index 3e84d1ff1c7f..8c2612bd85ab 100644
--- a/doc/guides/nics/hns3.rst
+++ b/doc/guides/nics/hns3.rst
@@ -234,6 +234,71 @@ src_port=32, dst_port=32`` to queue 1:
             dst is 2.2.2.5 / udp src is 32 dst is 32 / end \
             actions mark id 1 / queue index 1 / end
 
+The flow rules:
+
+   rule-0: flow create 0 ingress pattern eth / end \
+            queue index 1 / end
+   rule-1: flow create 0 ingress pattern eth / vlan vid is 10 / end \
+            queue index 1 / end
+   rule-2: flow create 0 ingress pattern eth / vlan / vlan vid is 10 / end \
+            queue index 1 / end
+   rule-3: flow create 0 ingress pattern eth / vlan vid is 10 / \
+            vlan vid is 11 / end queue index 1 / end
+
+will match the following packet types with specific VLAN ID at the specified
+VLAN layer and any VLAN ID at the rest VLAN layer.
+
+      +--------+------------------+-------------------------------------------+
+      | rules  | ``strict``       | ``nostrict``                              |
+      +========+==================+===========================================+
+      | rule-0 | untagged         | untagged || single-tagged || multi-tagged |
+      +--------+------------------+-------------------------------------------+
+      | rule-1 | single-tagged    | single-tagged || multi-tagged             |
+      +--------+------------------+-------------------------------------------+
+      | rule-2 | double-tagged    | multi-tagged                              |
+      +--------+------------------+-------------------------------------------+
+      | rule-3 | double-tagged    | multi-tagged                              |
+      +--------+------------------+-------------------------------------------+
+
+The attributes `has_vlan` and `has_more_vlan` are supported. The usage is as
+follows:
+
+   rule-4: flow create 0 ingress pattern eth has_vlan is 1 / end \
+            queue index 1 / end
+   rule-5: flow create 0 ingress pattern eth has_vlan is 0 / end \
+            queue index 1 / end
+   rule-6: flow create 0 ingress pattern eth / vlan has_more_vlan is 1 / \
+            end queue index 1 / end
+   rule-7: flow create 0 ingress pattern eth / vlan has_more_vlan is 0 / \
+            end queue index 1 / end
+
+They will match the following packet types with any VLAN ID.
+
+      +--------+------------------+-------------------------------------------+
+      | rules  |  ``strict``      | ``nostrict``                              |
+      +========+==================+===========================================+
+      | rule-4 | single-tagged    | untagged || single-tagged || multi-tagged |
+      +--------+------------------+-------------------------------------------+
+      | rule-5 | untagged         | untagged || single-tagged || multi-tagged |
+      +--------+------------------+-------------------------------------------+
+      | rule-6 | double-tagged    | untagged || single-tagged || multi-tagged |
+      +--------+------------------+-------------------------------------------+
+      | rule-7 | single-tagged    | untagged || single-tagged || multi-tagged |
+      +--------+------------------+-------------------------------------------+
+
+These two fields may be used followed by VLAN item, and may partially overlap
+or conflict with the VLAN item. For examples, the rule-8 will be rejected by
+the driver and rule-9, rule-10 are repeated with rule-4. Similar usage for
+``has_more_vlan``.
+
+   rule-8: flow create 0 ingress pattern eth has_vlan is 0 / vlan / end \
+            queue index 1 / end
+   rule-9: flow create 0 ingress pattern eth has_vlan is 1 / vlan / end \
+            queue index 1 / end
+   rule-10: flow create 0 ingress pattern eth / vlan / end \
+            queue index 1 / end
+
+
 Generic flow API
 ~~~~~~~~~~~~~~~~
 
diff --git a/drivers/net/hns3/hns3_fdir.h b/drivers/net/hns3/hns3_fdir.h
index 308cfbe56fc6..6ccd90a253f8 100644
--- a/drivers/net/hns3/hns3_fdir.h
+++ b/drivers/net/hns3/hns3_fdir.h
@@ -160,6 +160,10 @@ struct hns3_fdir_rule {
 	uint16_t nb_queues;
 	uint16_t location;
 	struct rte_flow_action_count act_cnt;
+	bool has_vlan_m;
+	bool has_vlan_v;
+	bool has_more_vlan_m;
+	bool has_more_vlan_v;
 };
 
 /* FDIR filter list structure */
diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c
index 7fbe65313ca2..37eb2b4c3807 100644
--- a/drivers/net/hns3/hns3_flow.c
+++ b/drivers/net/hns3/hns3_flow.c
@@ -616,8 +616,8 @@ hns3_parse_eth(const struct rte_flow_item *item, struct hns3_fdir_rule *rule,
 	if (item->spec == NULL && item->mask == NULL)
 		return 0;
 
-	if (item->mask) {
-		eth_mask = item->mask;
+	eth_mask = item->mask;
+	if (eth_mask) {
 		if (eth_mask->hdr.ether_type) {
 			hns3_set_bit(rule->input_set, INNER_ETH_TYPE, 1);
 			rule->key_conf.mask.ether_type =
@@ -633,9 +633,16 @@ hns3_parse_eth(const struct rte_flow_item *item, struct hns3_fdir_rule *rule,
 			memcpy(rule->key_conf.mask.dst_mac,
 			       eth_mask->hdr.dst_addr.addr_bytes, RTE_ETHER_ADDR_LEN);
 		}
+		if (eth_mask->has_vlan)
+			rule->has_vlan_m = true;
 	}
 
 	eth_spec = item->spec;
+	if (eth_mask && eth_mask->has_vlan && eth_spec->has_vlan) {
+		rule->key_conf.vlan_num++;
+		rule->has_vlan_v = true;
+	}
+
 	rule->key_conf.spec.ether_type = rte_be_to_cpu_16(eth_spec->hdr.ether_type);
 	memcpy(rule->key_conf.spec.src_mac, eth_spec->hdr.src_addr.addr_bytes,
 	       RTE_ETHER_ADDR_LEN);
@@ -651,6 +658,26 @@ hns3_parse_vlan(const struct rte_flow_item *item, struct hns3_fdir_rule *rule,
 	const struct rte_flow_item_vlan *vlan_spec;
 	const struct rte_flow_item_vlan *vlan_mask;
 
+	if (rule->has_vlan_m && !rule->has_vlan_v)
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ITEM, item,
+					  "VLAN item is conflict with 'has_vlan is 0' in ETH item");
+
+	if (rule->has_more_vlan_m && !rule->has_more_vlan_v)
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ITEM, item,
+					  "VLAN item is conflict with 'has_more_vlan is 0' in the previous VLAN item");
+
+	if (rule->has_vlan_m && rule->has_vlan_v) {
+		rule->has_vlan_m = false;
+		rule->key_conf.vlan_num--;
+	}
+
+	if (rule->has_more_vlan_m && rule->has_more_vlan_v) {
+		rule->has_more_vlan_m = false;
+		rule->key_conf.vlan_num--;
+	}
+
 	rule->key_conf.vlan_num++;
 	if (rule->key_conf.vlan_num > VLAN_TAG_NUM_MAX)
 		return rte_flow_error_set(error, EINVAL,
@@ -661,8 +688,8 @@ hns3_parse_vlan(const struct rte_flow_item *item, struct hns3_fdir_rule *rule,
 	if (item->spec == NULL && item->mask == NULL)
 		return 0;
 
-	if (item->mask) {
-		vlan_mask = item->mask;
+	vlan_mask = item->mask;
+	if (vlan_mask) {
 		if (vlan_mask->hdr.vlan_tci) {
 			if (rule->key_conf.vlan_num == 1) {
 				hns3_set_bit(rule->input_set, INNER_VLAN_TAG1,
@@ -676,6 +703,8 @@ hns3_parse_vlan(const struct rte_flow_item *item, struct hns3_fdir_rule *rule,
 				    rte_be_to_cpu_16(vlan_mask->hdr.vlan_tci);
 			}
 		}
+		if (vlan_mask->has_more_vlan)
+			rule->has_more_vlan_m = true;
 	}
 
 	vlan_spec = item->spec;
@@ -685,6 +714,16 @@ hns3_parse_vlan(const struct rte_flow_item *item, struct hns3_fdir_rule *rule,
 	else
 		rule->key_conf.spec.vlan_tag2 =
 		    rte_be_to_cpu_16(vlan_spec->hdr.vlan_tci);
+
+	if (vlan_mask && vlan_mask->has_more_vlan && vlan_spec->has_more_vlan) {
+		rule->key_conf.vlan_num++;
+		if (rule->key_conf.vlan_num > VLAN_TAG_NUM_MAX)
+			return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ITEM, item,
+					  "Vlan_num is more than 2");
+		rule->has_more_vlan_v = true;
+	}
+
 	return 0;
 }
 
-- 
2.33.0


             reply	other threads:[~2024-07-04  2:15 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-04  2:15 Jie Hai [this message]
2024-07-07 22:44 ` Ferruh Yigit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240704021538.836403-1-haijie1@huawei.com \
    --to=haijie1@huawei.com \
    --cc=dev@dpdk.org \
    --cc=fengchengwen@huawei.com \
    --cc=ferruh.yigit@amd.com \
    --cc=ivan.malov@arknetworks.am \
    --cc=lihuisong@huawei.com \
    --cc=thomas@monjalon.net \
    --cc=yisen.zhuang@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).