381 lines
13 KiB
Diff
381 lines
13 KiB
Diff
|
|
From a93a030ea0c817a229ce92df315a3cd72dcee6d5 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Dengdui Huang <huangdengdui@huawei.com>
|
||
|
|
Date: Wed, 30 Oct 2024 17:29:19 +0800
|
||
|
|
Subject: [PATCH] net/hns3: support flow rule priority
|
||
|
|
|
||
|
|
[ upstream commit ac72aae60f71b8716f65d1e2daf531a5ca38c998 ]
|
||
|
|
|
||
|
|
The hardware determines the priority of the flow rule based on the position
|
||
|
|
of the rule in the hardware flow director table. Lower index denotes higher
|
||
|
|
priority (it means when a packet matches multiple indexes, the smaller
|
||
|
|
index wins). This patch implements flow priority based on this feature.
|
||
|
|
|
||
|
|
To avoid affecting the current use, use runtime config 'fdir_index_config'
|
||
|
|
to select flow director index strategy. The options are as follows:
|
||
|
|
1. hash: Default config, the rule priority level cannot be set.
|
||
|
|
The driver generates a flow index based on the hash of the rte_flow key.
|
||
|
|
2. priority: The flow rule priority feature is supported.
|
||
|
|
The driver uses the rte_flow priority field as the flow director index.
|
||
|
|
|
||
|
|
Signed-off-by: Dengdui Huang <huangdengdui@huawei.com>
|
||
|
|
Signed-off-by: Jie Hai <haijie1@huawei.com>
|
||
|
|
---
|
||
|
|
doc/guides/nics/hns3.rst | 12 +++++++
|
||
|
|
drivers/net/hns3/hns3_common.c | 25 ++++++++++++++
|
||
|
|
drivers/net/hns3/hns3_common.h | 1 +
|
||
|
|
drivers/net/hns3/hns3_dump.c | 2 ++
|
||
|
|
drivers/net/hns3/hns3_ethdev.c | 3 +-
|
||
|
|
drivers/net/hns3/hns3_fdir.c | 62 ++++++++++++++++++++++++----------
|
||
|
|
drivers/net/hns3/hns3_fdir.h | 10 ++++++
|
||
|
|
drivers/net/hns3/hns3_flow.c | 45 +++++++++++++++++++++---
|
||
|
|
8 files changed, 136 insertions(+), 24 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst
|
||
|
|
index bdc10da..b8e79c1 100644
|
||
|
|
--- a/doc/guides/nics/hns3.rst
|
||
|
|
+++ b/doc/guides/nics/hns3.rst
|
||
|
|
@@ -193,6 +193,15 @@ Runtime Configuration
|
||
|
|
``+outvlan-sctptag``: means disable sctp tag tuple, and enable outer vlan tuple.
|
||
|
|
``+outvlan-tunvni``: means disable tunnel vni tuple, and enable outer vlan tuple.
|
||
|
|
|
||
|
|
+- ``fdir_index_config`` (default ``hash``)
|
||
|
|
+
|
||
|
|
+ Used to select flow director index strategy, the flow director index is the index
|
||
|
|
+ position in the hardware flow director table. Lower index denotes higher priority
|
||
|
|
+ (it means when a packet matches multiple indexes, the smaller index wins).
|
||
|
|
+ Current supported options are as follows:
|
||
|
|
+ ``hash``: The driver generates a flow index based on the hash of the rte_flow key.
|
||
|
|
+ ``priority``: the driver uses the rte_flow priority field as the flow director index.
|
||
|
|
+
|
||
|
|
Driver compilation and testing
|
||
|
|
------------------------------
|
||
|
|
|
||
|
|
@@ -322,6 +331,9 @@ Generic flow API
|
||
|
|
configuration for hardware which will affect other rules.
|
||
|
|
The rule just setting input tuple is completely independent.
|
||
|
|
|
||
|
|
+ In addition, if the rule priority level is set, no error is reported,
|
||
|
|
+ but the rule priority level does not take effect.
|
||
|
|
+
|
||
|
|
Run ``testpmd``:
|
||
|
|
|
||
|
|
.. code-block:: console
|
||
|
|
diff --git a/drivers/net/hns3/hns3_common.c b/drivers/net/hns3/hns3_common.c
|
||
|
|
index 99a1d59..25a4521 100644
|
||
|
|
--- a/drivers/net/hns3/hns3_common.c
|
||
|
|
+++ b/drivers/net/hns3/hns3_common.c
|
||
|
|
@@ -290,6 +290,27 @@ hns3_parse_fdir_tuple_config(const char *key, const char *value, void *args)
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
+static int
|
||
|
|
+hns3_parse_fdir_index_config(const char *key, const char *value, void *args)
|
||
|
|
+{
|
||
|
|
+ enum hns3_fdir_index_config cfg;
|
||
|
|
+
|
||
|
|
+ if (strcmp(value, "hash") == 0) {
|
||
|
|
+ cfg = HNS3_FDIR_INDEX_CONFIG_HASH;
|
||
|
|
+ } else if (strcmp(value, "priority") == 0) {
|
||
|
|
+ cfg = HNS3_FDIR_INDEX_CONFIG_PRIORITY;
|
||
|
|
+ } else {
|
||
|
|
+ PMD_INIT_LOG(WARNING, "invalid value:\"%s\" for key:\"%s\", "
|
||
|
|
+ "value must be 'hash' or 'priority'",
|
||
|
|
+ value, key);
|
||
|
|
+ return -1;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ *(enum hns3_fdir_index_config *)args = cfg;
|
||
|
|
+
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
void
|
||
|
|
hns3_parse_devargs(struct rte_eth_dev *dev)
|
||
|
|
{
|
||
|
|
@@ -333,6 +354,10 @@ hns3_parse_devargs(struct rte_eth_dev *dev)
|
||
|
|
HNS3_DEVARG_FDIR_TUPLE_CONFIG,
|
||
|
|
&hns3_parse_fdir_tuple_config,
|
||
|
|
&hns->pf.fdir.tuple_cfg);
|
||
|
|
+ (void)rte_kvargs_process(kvlist,
|
||
|
|
+ HNS3_DEVARG_FDIR_INDEX_CONFIG,
|
||
|
|
+ &hns3_parse_fdir_index_config,
|
||
|
|
+ &hns->pf.fdir.index_cfg);
|
||
|
|
}
|
||
|
|
|
||
|
|
rte_kvargs_free(kvlist);
|
||
|
|
diff --git a/drivers/net/hns3/hns3_common.h b/drivers/net/hns3/hns3_common.h
|
||
|
|
index ca90936..7b3f96b 100644
|
||
|
|
--- a/drivers/net/hns3/hns3_common.h
|
||
|
|
+++ b/drivers/net/hns3/hns3_common.h
|
||
|
|
@@ -29,6 +29,7 @@ enum {
|
||
|
|
|
||
|
|
#define HNS3_DEVARG_FDIR_VLAN_MATCH_MODE "fdir_vlan_match_mode"
|
||
|
|
#define HNS3_DEVARG_FDIR_TUPLE_CONFIG "fdir_tuple_config"
|
||
|
|
+#define HNS3_DEVARG_FDIR_INDEX_CONFIG "fdir_index_config"
|
||
|
|
|
||
|
|
#define MSEC_PER_SEC 1000L
|
||
|
|
#define USEC_PER_MSEC 1000L
|
||
|
|
diff --git a/drivers/net/hns3/hns3_dump.c b/drivers/net/hns3/hns3_dump.c
|
||
|
|
index fbe3716..dcdfcf4 100644
|
||
|
|
--- a/drivers/net/hns3/hns3_dump.c
|
||
|
|
+++ b/drivers/net/hns3/hns3_dump.c
|
||
|
|
@@ -169,6 +169,7 @@ hns3_get_fdir_basic_info(FILE *file, struct hns3_pf *pf)
|
||
|
|
"\t -- mode=%u max_key_len=%u rule_num:%u cnt_num:%u\n"
|
||
|
|
"\t -- key_sel=%u tuple_active=0x%x meta_data_active=0x%x\n"
|
||
|
|
"\t -- ipv6_word_en: in_s=%u in_d=%u out_s=%u out_d=%u\n"
|
||
|
|
+ "\t -- index_cfg: %s\n"
|
||
|
|
"\t -- tuple_config: %s\n"
|
||
|
|
"\t -- active_tuples:\n",
|
||
|
|
fdcfg->fd_mode, fdcfg->max_key_length,
|
||
|
|
@@ -181,6 +182,7 @@ hns3_get_fdir_basic_info(FILE *file, struct hns3_pf *pf)
|
||
|
|
fdcfg->key_cfg[HNS3_FD_STAGE_1].inner_dipv6_word_en,
|
||
|
|
fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_sipv6_word_en,
|
||
|
|
fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_dipv6_word_en,
|
||
|
|
+ hns3_fdir_index_config_name(pf->fdir.index_cfg),
|
||
|
|
hns3_tuple_config_name(pf->fdir.tuple_cfg));
|
||
|
|
|
||
|
|
for (i = 0; i < MAX_TUPLE; i++) {
|
||
|
|
diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
|
||
|
|
index 30b7aaa..12bb834 100644
|
||
|
|
--- a/drivers/net/hns3/hns3_ethdev.c
|
||
|
|
+++ b/drivers/net/hns3/hns3_ethdev.c
|
||
|
|
@@ -6672,7 +6672,8 @@ RTE_PMD_REGISTER_PARAM_STRING(net_hns3,
|
||
|
|
HNS3_DEVARG_FDIR_VLAN_MATCH_MODE "=strict|nostrict "
|
||
|
|
HNS3_DEVARG_FDIR_TUPLE_CONFIG "=+outvlan-insmac|+outvlan-indmac|"
|
||
|
|
"+outvlan-insip|+outvlan-indip"
|
||
|
|
- "+outvlan-sctptag|+outvlan-tunvni ");
|
||
|
|
+ "+outvlan-sctptag|+outvlan-tunvni "
|
||
|
|
+ HNS3_DEVARG_FDIR_INDEX_CONFIG "=hash|priority ");
|
||
|
|
RTE_LOG_REGISTER_SUFFIX(hns3_logtype_init, init, NOTICE);
|
||
|
|
RTE_LOG_REGISTER_SUFFIX(hns3_logtype_driver, driver, NOTICE);
|
||
|
|
#ifdef RTE_ETHDEV_DEBUG_RX
|
||
|
|
diff --git a/drivers/net/hns3/hns3_fdir.c b/drivers/net/hns3/hns3_fdir.c
|
||
|
|
index 389dec2..1e9932b 100644
|
||
|
|
--- a/drivers/net/hns3/hns3_fdir.c
|
||
|
|
+++ b/drivers/net/hns3/hns3_fdir.c
|
||
|
|
@@ -981,39 +981,44 @@ static int hns3_insert_fdir_filter(struct hns3_hw *hw,
|
||
|
|
{
|
||
|
|
struct hns3_fdir_key_conf *key;
|
||
|
|
hash_sig_t sig;
|
||
|
|
- int ret;
|
||
|
|
+ int index;
|
||
|
|
|
||
|
|
key = &fdir_filter->fdir_conf.key_conf;
|
||
|
|
sig = rte_hash_crc(key, sizeof(*key), 0);
|
||
|
|
- ret = rte_hash_add_key_with_hash(fdir_info->hash_handle, key, sig);
|
||
|
|
- if (ret < 0) {
|
||
|
|
- hns3_err(hw, "Hash table full? err:%d!", ret);
|
||
|
|
- return ret;
|
||
|
|
+ index = rte_hash_add_key_with_hash(fdir_info->hash_handle, key, sig);
|
||
|
|
+ if (index < 0) {
|
||
|
|
+ hns3_err(hw, "Hash table full? err:%d!", index);
|
||
|
|
+ return index;
|
||
|
|
}
|
||
|
|
|
||
|
|
- fdir_info->hash_map[ret] = fdir_filter;
|
||
|
|
+ if (fdir_info->index_cfg == HNS3_FDIR_INDEX_CONFIG_PRIORITY)
|
||
|
|
+ index = fdir_filter->fdir_conf.location;
|
||
|
|
+
|
||
|
|
+ fdir_info->hash_map[index] = fdir_filter;
|
||
|
|
TAILQ_INSERT_TAIL(&fdir_info->fdir_list, fdir_filter, entries);
|
||
|
|
|
||
|
|
- return ret;
|
||
|
|
+ return index;
|
||
|
|
}
|
||
|
|
|
||
|
|
static int hns3_remove_fdir_filter(struct hns3_hw *hw,
|
||
|
|
struct hns3_fdir_info *fdir_info,
|
||
|
|
- struct hns3_fdir_key_conf *key)
|
||
|
|
+ struct hns3_fdir_rule *rule)
|
||
|
|
{
|
||
|
|
struct hns3_fdir_rule_ele *fdir_filter;
|
||
|
|
hash_sig_t sig;
|
||
|
|
- int ret;
|
||
|
|
+ int index;
|
||
|
|
|
||
|
|
- sig = rte_hash_crc(key, sizeof(*key), 0);
|
||
|
|
- ret = rte_hash_del_key_with_hash(fdir_info->hash_handle, key, sig);
|
||
|
|
- if (ret < 0) {
|
||
|
|
- hns3_err(hw, "Delete hash key fail ret=%d", ret);
|
||
|
|
- return ret;
|
||
|
|
+ sig = rte_hash_crc(&rule->key_conf, sizeof(rule->key_conf), 0);
|
||
|
|
+ index = rte_hash_del_key_with_hash(fdir_info->hash_handle, &rule->key_conf, sig);
|
||
|
|
+ if (index < 0) {
|
||
|
|
+ hns3_err(hw, "Delete hash key fail ret=%d", index);
|
||
|
|
+ return index;
|
||
|
|
}
|
||
|
|
|
||
|
|
- fdir_filter = fdir_info->hash_map[ret];
|
||
|
|
- fdir_info->hash_map[ret] = NULL;
|
||
|
|
+ if (fdir_info->index_cfg == HNS3_FDIR_INDEX_CONFIG_PRIORITY)
|
||
|
|
+ index = rule->location;
|
||
|
|
+ fdir_filter = fdir_info->hash_map[index];
|
||
|
|
+ fdir_info->hash_map[index] = NULL;
|
||
|
|
TAILQ_REMOVE(&fdir_info->fdir_list, fdir_filter, entries);
|
||
|
|
|
||
|
|
rte_free(fdir_filter);
|
||
|
|
@@ -1042,7 +1047,7 @@ int hns3_fdir_filter_program(struct hns3_adapter *hns,
|
||
|
|
rule->key_conf.spec.src_port,
|
||
|
|
rule->key_conf.spec.dst_port, ret);
|
||
|
|
else
|
||
|
|
- ret = hns3_remove_fdir_filter(hw, fdir_info, &rule->key_conf);
|
||
|
|
+ ret = hns3_remove_fdir_filter(hw, fdir_info, rule);
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
@@ -1080,7 +1085,7 @@ int hns3_fdir_filter_program(struct hns3_adapter *hns,
|
||
|
|
rule->key_conf.spec.dst_ip[IP_ADDR_KEY_ID],
|
||
|
|
rule->key_conf.spec.src_port,
|
||
|
|
rule->key_conf.spec.dst_port, ret);
|
||
|
|
- (void)hns3_remove_fdir_filter(hw, fdir_info, &rule->key_conf);
|
||
|
|
+ (void)hns3_remove_fdir_filter(hw, fdir_info, rule);
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
@@ -1231,3 +1236,24 @@ hns3_tuple_config_name(enum hns3_fdir_tuple_config tuple_cfg)
|
||
|
|
|
||
|
|
return "unknown";
|
||
|
|
}
|
||
|
|
+
|
||
|
|
+static struct {
|
||
|
|
+ enum hns3_fdir_index_config cfg;
|
||
|
|
+ const char *name;
|
||
|
|
+} index_cfg_map[] = {
|
||
|
|
+ { HNS3_FDIR_INDEX_CONFIG_HASH, "hash"},
|
||
|
|
+ { HNS3_FDIR_INDEX_CONFIG_PRIORITY, "priority"},
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+const char *
|
||
|
|
+hns3_fdir_index_config_name(enum hns3_fdir_index_config cfg)
|
||
|
|
+{
|
||
|
|
+ uint32_t i;
|
||
|
|
+
|
||
|
|
+ for (i = 0; i < RTE_DIM(index_cfg_map); i++) {
|
||
|
|
+ if (cfg == index_cfg_map[i].cfg)
|
||
|
|
+ return index_cfg_map[i].name;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return "unknown";
|
||
|
|
+}
|
||
|
|
diff --git a/drivers/net/hns3/hns3_fdir.h b/drivers/net/hns3/hns3_fdir.h
|
||
|
|
index 2d0c9bf..5ba7b5b 100644
|
||
|
|
--- a/drivers/net/hns3/hns3_fdir.h
|
||
|
|
+++ b/drivers/net/hns3/hns3_fdir.h
|
||
|
|
@@ -228,6 +228,14 @@ enum hns3_fdir_tuple_config {
|
||
|
|
HNS3_FDIR_TUPLE_CONFIG_BUTT
|
||
|
|
};
|
||
|
|
|
||
|
|
+enum hns3_fdir_index_config {
|
||
|
|
+ /* Generate the hardware flow director index based on rte_hash (Default) */
|
||
|
|
+ HNS3_FDIR_INDEX_CONFIG_HASH,
|
||
|
|
+
|
||
|
|
+ /* Use the rte_flow priority field as the hardware flow director index. */
|
||
|
|
+ HNS3_FDIR_INDEX_CONFIG_PRIORITY
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
/*
|
||
|
|
* A structure used to define fields of a FDIR related info.
|
||
|
|
*/
|
||
|
|
@@ -238,6 +246,7 @@ struct hns3_fdir_info {
|
||
|
|
struct hns3_fd_cfg fd_cfg;
|
||
|
|
uint8_t vlan_match_mode;
|
||
|
|
enum hns3_fdir_tuple_config tuple_cfg;
|
||
|
|
+ enum hns3_fdir_index_config index_cfg;
|
||
|
|
};
|
||
|
|
|
||
|
|
struct hns3_adapter;
|
||
|
|
@@ -254,5 +263,6 @@ int hns3_restore_all_fdir_filter(struct hns3_adapter *hns);
|
||
|
|
|
||
|
|
enum hns3_fdir_tuple_config hns3_parse_tuple_config(const char *name);
|
||
|
|
const char *hns3_tuple_config_name(enum hns3_fdir_tuple_config tuple_cfg);
|
||
|
|
+const char *hns3_fdir_index_config_name(enum hns3_fdir_index_config cfg);
|
||
|
|
|
||
|
|
#endif /* HNS3_FDIR_H */
|
||
|
|
diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c
|
||
|
|
index 4674f74..40e2409 100644
|
||
|
|
--- a/drivers/net/hns3/hns3_flow.c
|
||
|
|
+++ b/drivers/net/hns3/hns3_flow.c
|
||
|
|
@@ -597,10 +597,6 @@ hns3_check_attr(const struct rte_flow_attr *attr, struct rte_flow_error *error)
|
||
|
|
return rte_flow_error_set(error, ENOTSUP,
|
||
|
|
RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
|
||
|
|
attr, "No support for transfer");
|
||
|
|
- if (attr->priority)
|
||
|
|
- return rte_flow_error_set(error, ENOTSUP,
|
||
|
|
- RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
|
||
|
|
- attr, "Not support priority");
|
||
|
|
if (attr->group)
|
||
|
|
return rte_flow_error_set(error, ENOTSUP,
|
||
|
|
RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
|
||
|
|
@@ -1441,6 +1437,40 @@ is_tunnel_packet(enum rte_flow_item_type type)
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
+static int
|
||
|
|
+hns3_handle_attributes(struct rte_eth_dev *dev,
|
||
|
|
+ const struct rte_flow_attr *attr,
|
||
|
|
+ struct hns3_fdir_rule *rule,
|
||
|
|
+ struct rte_flow_error *error)
|
||
|
|
+{
|
||
|
|
+ struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private);
|
||
|
|
+ struct hns3_fdir_info fdir = pf->fdir;
|
||
|
|
+ uint32_t rule_num;
|
||
|
|
+
|
||
|
|
+ if (fdir.index_cfg != HNS3_FDIR_INDEX_CONFIG_PRIORITY) {
|
||
|
|
+ if (attr->priority == 0)
|
||
|
|
+ return 0;
|
||
|
|
+ return rte_flow_error_set(error, ENOTSUP,
|
||
|
|
+ RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
|
||
|
|
+ attr, "Not support priority");
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ rule_num = fdir.fd_cfg.rule_num[HNS3_FD_STAGE_1];
|
||
|
|
+ if (attr->priority >= rule_num)
|
||
|
|
+ return rte_flow_error_set(error, EINVAL,
|
||
|
|
+ RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
|
||
|
|
+ attr, "Priority out of range");
|
||
|
|
+
|
||
|
|
+ if (fdir.hash_map[attr->priority] != NULL)
|
||
|
|
+ return rte_flow_error_set(error, EINVAL,
|
||
|
|
+ RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
|
||
|
|
+ attr, "Priority already exists");
|
||
|
|
+
|
||
|
|
+ rule->location = attr->priority;
|
||
|
|
+
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
/*
|
||
|
|
* Parse the flow director rule.
|
||
|
|
* The supported PATTERN:
|
||
|
|
@@ -1468,6 +1498,7 @@ is_tunnel_packet(enum rte_flow_item_type type)
|
||
|
|
*/
|
||
|
|
static int
|
||
|
|
hns3_parse_fdir_filter(struct rte_eth_dev *dev,
|
||
|
|
+ const struct rte_flow_attr *attr,
|
||
|
|
const struct rte_flow_item pattern[],
|
||
|
|
const struct rte_flow_action actions[],
|
||
|
|
struct hns3_fdir_rule *rule,
|
||
|
|
@@ -1484,6 +1515,10 @@ hns3_parse_fdir_filter(struct rte_eth_dev *dev,
|
||
|
|
RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
|
||
|
|
"Fdir not supported in VF");
|
||
|
|
|
||
|
|
+ ret = hns3_handle_attributes(dev, attr, rule, error);
|
||
|
|
+ if (ret)
|
||
|
|
+ return ret;
|
||
|
|
+
|
||
|
|
step_mngr.items = first_items;
|
||
|
|
step_mngr.count = RTE_DIM(first_items);
|
||
|
|
for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
|
||
|
|
@@ -2248,7 +2283,7 @@ hns3_flow_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
|
||
|
|
return hns3_parse_rss_filter(dev, pattern, actions,
|
||
|
|
&conf->rss_conf, error);
|
||
|
|
|
||
|
|
- return hns3_parse_fdir_filter(dev, pattern, actions,
|
||
|
|
+ return hns3_parse_fdir_filter(dev, attr, pattern, actions,
|
||
|
|
&conf->fdir_conf, error);
|
||
|
|
}
|
||
|
|
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|