From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 9DB34A2E1B for ; Wed, 4 Sep 2019 16:46:36 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 71D941EE07; Wed, 4 Sep 2019 16:46:36 +0200 (CEST) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by dpdk.org (Postfix) with ESMTP id 1F9211B99D for ; Wed, 4 Sep 2019 16:46:33 +0200 (CEST) X-Amp-Result: UNSCANNABLE X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 04 Sep 2019 07:46:33 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,467,1559545200"; d="scan'208";a="185134672" Received: from yexl-server.sh.intel.com (HELO localhost) ([10.67.117.5]) by orsmga003.jf.intel.com with ESMTP; 04 Sep 2019 07:46:30 -0700 Date: Wed, 4 Sep 2019 22:44:35 +0800 From: Ye Xiaolong To: Ying Wang Cc: qi.z.zhang@intel.com, qiming.yang@intel.com, dev@dpdk.org, wei.zhao1@intel.com Message-ID: <20190904144435.GC54897@intel.com> References: <20190903221522.151382-1-ying.a.wang@intel.com> <20190903221522.151382-3-ying.a.wang@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20190903221522.151382-3-ying.a.wang@intel.com> User-Agent: Mutt/1.9.4 (2018-02-28) Subject: Re: [dpdk-dev] [PATCH 2/4] net/ice: rework for generic flow enabling X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" On 09/04, Ying Wang wrote: >The patch reworks the generic flow API (rte_flow) implementation. >It introduces an abstract layer which provides a unified interface >for low-level filter engine (switch, fdir, hash) to register supported >patterns and actions and implement flow validate/create/destroy/flush/ >query activities. > >The patch also removes the existing switch filter implementation to >avoid compile error. Switch filter implementation for the new framework >will be added in the following patch. > >Signed-off-by: Ying Wang >--- > drivers/net/ice/ice_ethdev.c | 22 +- > drivers/net/ice/ice_ethdev.h | 15 +- > drivers/net/ice/ice_generic_flow.c | 768 +++++++++++++++-------------------- > drivers/net/ice/ice_generic_flow.h | 782 ++++++++---------------------------- > drivers/net/ice/ice_switch_filter.c | 511 ----------------------- > drivers/net/ice/ice_switch_filter.h | 18 - > 6 files changed, 525 insertions(+), 1591 deletions(-) Please add update to document and release notes. > >diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c >index 4e0645db1..647aca3ed 100644 >--- a/drivers/net/ice/ice_ethdev.c >+++ b/drivers/net/ice/ice_ethdev.c [snip] >+int >+ice_flow_init(struct ice_adapter *ad) >+{ >+ int ret = 0; >+ struct ice_pf *pf = &ad->pf; >+ void *temp; >+ struct ice_flow_engine *engine = NULL; >+ >+ TAILQ_INIT(&pf->flow_list); >+ TAILQ_INIT(&pf->rss_parser_list); >+ TAILQ_INIT(&pf->perm_parser_list); >+ TAILQ_INIT(&pf->dist_parser_list); >+ >+ TAILQ_FOREACH_SAFE(engine, &engine_list, node, temp) { >+ if (engine->init == NULL) >+ return -EINVAL; I think ENOTSUP is more preferred here. >+ >+ ret = engine->init(ad); >+ if (ret) >+ return ret; >+ } >+ return 0; >+} >+ >+void >+ice_flow_uninit(struct ice_adapter *ad) >+{ >+ struct ice_pf *pf = &ad->pf; >+ struct ice_flow_engine *engine; >+ struct rte_flow *p_flow; >+ struct ice_flow_parser *p_parser; >+ void *temp; >+ >+ TAILQ_FOREACH_SAFE(engine, &engine_list, node, temp) { >+ if (engine->uninit) >+ engine->uninit(ad); >+ } >+ >+ /* Remove all flows */ >+ while ((p_flow = TAILQ_FIRST(&pf->flow_list))) { >+ TAILQ_REMOVE(&pf->flow_list, p_flow, node); >+ if (p_flow->engine->free) >+ p_flow->engine->free(p_flow); >+ rte_free(p_flow); >+ } >+ >+ /* Cleanup parser list */ >+ while ((p_parser = TAILQ_FIRST(&pf->rss_parser_list))) >+ TAILQ_REMOVE(&pf->rss_parser_list, p_parser, node); >+ >+ while ((p_parser = TAILQ_FIRST(&pf->perm_parser_list))) >+ TAILQ_REMOVE(&pf->perm_parser_list, p_parser, node); >+ >+ while ((p_parser = TAILQ_FIRST(&pf->dist_parser_list))) >+ TAILQ_REMOVE(&pf->dist_parser_list, p_parser, node); >+} >+ >+int >+ice_register_parser(struct ice_flow_parser *parser, >+ struct ice_adapter *ad) >+{ >+ struct ice_parser_list *list = NULL; >+ struct ice_pf *pf = &ad->pf; >+ >+ switch (parser->stage) { >+ case ICE_FLOW_STAGE_RSS: >+ list = &pf->rss_parser_list; >+ break; >+ case ICE_FLOW_STAGE_PERMISSION: >+ list = &pf->perm_parser_list; >+ break; >+ case ICE_FLOW_STAGE_DISTRIBUTOR: >+ list = &pf->dist_parser_list; >+ break; >+ default: >+ return -EINVAL; >+ } >+ >+ if (ad->devargs.pipeline_mode_support) >+ TAILQ_INSERT_TAIL(list, parser, node); >+ else { >+ if (parser->engine->type == ICE_FLOW_ENGINE_SWITCH >+ || parser->engine->type == ICE_FLOW_ENGINE_HASH) >+ TAILQ_INSERT_TAIL(list, parser, node); >+ else if (parser->engine->type == ICE_FLOW_ENGINE_FDIR) >+ TAILQ_INSERT_HEAD(list, parser, node); >+ else >+ return -EINVAL; >+ } >+ return 0; >+} >+ >+void >+ice_unregister_parser(struct ice_flow_parser *parser, >+ struct ice_adapter *ad) >+{ >+ struct ice_pf *pf = &ad->pf; >+ struct ice_parser_list *list; >+ struct ice_flow_parser *p_parser; >+ void *temp; >+ >+ switch (parser->stage) { >+ case ICE_FLOW_STAGE_RSS: >+ list = &pf->rss_parser_list; >+ break; >+ case ICE_FLOW_STAGE_PERMISSION: >+ list = &pf->perm_parser_list; >+ break; >+ case ICE_FLOW_STAGE_DISTRIBUTOR: >+ list = &pf->dist_parser_list; >+ break; >+ default: >+ return; >+ } >+ >+ TAILQ_FOREACH_SAFE(p_parser, list, node, temp) { >+ if (p_parser->engine->type == parser->engine->type) >+ TAILQ_REMOVE(list, p_parser, node); >+ } >+ >+} >+ > static int >-ice_flow_valid_attr(const struct rte_flow_attr *attr, >- struct rte_flow_error *error) >+ice_flow_valid_attr(struct ice_adapter *ad, >+ const struct rte_flow_attr *attr, >+ struct rte_flow_error *error) > { > /* Must be input direction */ > if (!attr->ingress) { >@@ -61,15 +212,25 @@ ice_flow_valid_attr(const struct rte_flow_attr *attr, > attr, "Not support egress."); > return -rte_errno; > } >- >- /* Not supported */ >- if (attr->priority) { >- rte_flow_error_set(error, EINVAL, >- RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, >- attr, "Not support priority."); >- return -rte_errno; >+ /* Check pipeline mode support to set classification stage */ >+ if (ad->devargs.pipeline_mode_support) { >+ if (0 == attr->priority) >+ ice_pipeline_stage = >+ ICE_FLOW_CLASSIFY_STAGE_PERMISSION; >+ else >+ ice_pipeline_stage = >+ ICE_FLOW_CLASSIFY_STAGE_DISTRIBUTOR; >+ } else { >+ ice_pipeline_stage = >+ ICE_FLOW_CLASSIFY_STAGE_DISTRIBUTOR_ONLY; >+ /* Not supported */ >+ if (attr->priority) { >+ rte_flow_error_set(error, EINVAL, >+ RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, >+ attr, "Not support priority."); >+ return -rte_errno; >+ } > } >- > /* Not supported */ > if (attr->group) { > rte_flow_error_set(error, EINVAL, >@@ -102,7 +263,7 @@ ice_find_first_item(const struct rte_flow_item *item, bool is_void) > /* Skip all VOID items of the pattern */ > static void > ice_pattern_skip_void_item(struct rte_flow_item *items, >- const struct rte_flow_item *pattern) >+ const struct rte_flow_item *pattern) Unnecessary change here, only indentation changes. > { > uint32_t cpy_count = 0; > const struct rte_flow_item *pb = pattern, *pe = pattern; >@@ -124,7 +285,6 @@ ice_pattern_skip_void_item(struct rte_flow_item *items, > items += cpy_count; > > if (pe->type == RTE_FLOW_ITEM_TYPE_END) { >- pb = pe; seems this is some code cleanup, prefer a separate patch, not a strong opinion though. > break; > } > >@@ -151,11 +311,15 @@ ice_match_pattern(enum rte_flow_item_type *item_array, > item->type == RTE_FLOW_ITEM_TYPE_END); > } > >-static uint64_t ice_flow_valid_pattern(const struct rte_flow_item pattern[], >+struct ice_pattern_match_item * >+ice_search_pattern_match_item(const struct rte_flow_item pattern[], >+ struct ice_pattern_match_item *array, >+ uint32_t array_len, > struct rte_flow_error *error) > { > uint16_t i = 0; >- uint64_t inset; >+ struct ice_pattern_match_item *pattern_match_item; >+ /* need free by each filter */ > struct rte_flow_item *items; /* used for pattern without VOID items */ > uint32_t item_num = 0; /* non-void item number */ > >@@ -172,451 +336,149 @@ static uint64_t ice_flow_valid_pattern(const struct rte_flow_item pattern[], > if (!items) { > rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_ITEM_NUM, > NULL, "No memory for PMD internal items."); >- return -ENOMEM; >+ return NULL; >+ } >+ pattern_match_item = rte_zmalloc("ice_pattern_match_item", >+ sizeof(struct ice_pattern_match_item), 0); >+ if (!pattern_match_item) { >+ PMD_DRV_LOG(ERR, "Failed to allocate memory."); >+ return NULL; > } >- > ice_pattern_skip_void_item(items, pattern); > >- for (i = 0; i < RTE_DIM(ice_supported_patterns); i++) [snip] > >+static int >+ice_flow_validate(struct rte_eth_dev *dev, >+ const struct rte_flow_attr *attr, >+ const struct rte_flow_item pattern[], >+ const struct rte_flow_action actions[], >+ struct rte_flow_error *error) >+{ >+ int ret = ICE_ERR_NOT_SUPPORTED; Unnecessary initialization. >+ void *meta = NULL; >+ struct ice_flow_engine *engine = NULL; >+ >+ ret = ice_flow_validate_filter(dev, attr, pattern, actions, >+ &engine, &meta, error); >+ return ret; >+} >+ > static struct rte_flow * > ice_flow_create(struct rte_eth_dev *dev, >- const struct rte_flow_attr *attr, >- const struct rte_flow_item pattern[], >- const struct rte_flow_action actions[], >- struct rte_flow_error *error) >+ const struct rte_flow_attr *attr, >+ const struct rte_flow_item pattern[], >+ const struct rte_flow_action actions[], >+ struct rte_flow_error *error) > { > struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private); > struct rte_flow *flow = NULL; >- int ret; >+ int ret = 0; Unnecessary initialization. >+ struct ice_adapter *ad = >+ ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); >+ struct ice_flow_engine *engine = NULL; >+ void *meta = NULL; > > flow = rte_zmalloc("ice_flow", sizeof(struct rte_flow), 0); > if (!flow) { >@@ -626,65 +488,105 @@ ice_flow_create(struct rte_eth_dev *dev, > return flow; > } > >- ret = ice_flow_validate(dev, attr, pattern, actions, error); >+ ret = ice_flow_validate_filter(dev, attr, pattern, actions, >+ &engine, &meta, error); > if (ret < 0) > goto free_flow; > >- ret = ice_create_switch_filter(pf, pattern, actions, flow, error); >+ if (engine->create == NULL) >+ goto free_flow; >+ >+ ret = engine->create(ad, flow, meta, error); > if (ret) > goto free_flow; > >+ flow->engine = engine; > TAILQ_INSERT_TAIL(&pf->flow_list, flow, node); > return flow; > > free_flow: >- rte_flow_error_set(error, -ret, >- RTE_FLOW_ERROR_TYPE_HANDLE, NULL, >- "Failed to create flow."); >+ PMD_DRV_LOG(ERR, "Failed to create flow"); > rte_free(flow); > return NULL; > } > > static int > ice_flow_destroy(struct rte_eth_dev *dev, >- struct rte_flow *flow, >- struct rte_flow_error *error) >+ struct rte_flow *flow, >+ struct rte_flow_error *error) > { > struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private); >+ struct ice_adapter *ad = >+ ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); > int ret = 0; > >- ret = ice_destroy_switch_filter(pf, flow, error); >- >+ if (!flow || !flow->engine->destroy) { >+ rte_flow_error_set(error, EINVAL, >+ RTE_FLOW_ERROR_TYPE_HANDLE, >+ NULL, "NULL flow or NULL destroy"); >+ return -rte_errno; >+ } >+ ret = flow->engine->destroy(ad, flow, error); > if (!ret) { > TAILQ_REMOVE(&pf->flow_list, flow, node); > rte_free(flow); >- } else { >- rte_flow_error_set(error, -ret, >- RTE_FLOW_ERROR_TYPE_HANDLE, NULL, >- "Failed to destroy flow."); >- } >+ } else >+ PMD_DRV_LOG(ERR, "Failed to destroy flow"); > > return ret; > } > > static int > ice_flow_flush(struct rte_eth_dev *dev, >- struct rte_flow_error *error) >+ struct rte_flow_error *error) Unnecessary change. > { > struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private); >- struct rte_flow *p_flow; >+ struct rte_flow *p_flow = NULL; Unnecessary initialization. > void *temp; > int ret = 0; > > TAILQ_FOREACH_SAFE(p_flow, &pf->flow_list, node, temp) { > ret = ice_flow_destroy(dev, p_flow, error); > if (ret) { >- rte_flow_error_set(error, -ret, >- RTE_FLOW_ERROR_TYPE_HANDLE, NULL, >- "Failed to flush SW flows."); >- return -rte_errno; >+ PMD_DRV_LOG(ERR, "Failed to flush flows"); >+ return -EINVAL; > } > } > > return ret; > } >+ >+static int >+ice_flow_query_count(struct rte_eth_dev *dev, >+ struct rte_flow *flow, >+ const struct rte_flow_action *actions, >+ void *data, >+ struct rte_flow_error *error) >+{ >+ int ret = -EINVAL; >+ struct ice_adapter *ad = >+ ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); >+ >+ if (!flow || !flow->engine->query) { >+ rte_flow_error_set(error, EINVAL, >+ RTE_FLOW_ERROR_TYPE_HANDLE, >+ NULL, "NULL flow or NULL query"); >+ return -rte_errno; >+ } >+ >+ for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { >+ switch (actions->type) { >+ case RTE_FLOW_ACTION_TYPE_VOID: >+ break; >+ case RTE_FLOW_ACTION_TYPE_COUNT: >+ ret = flow->engine->query(ad, flow, data, error); >+ break; >+ default: >+ return rte_flow_error_set(error, ENOTSUP, >+ RTE_FLOW_ERROR_TYPE_ACTION, >+ actions, >+ "action not supported"); >+ } >+ } >+ return ret; >+} [snip] >+TAILQ_HEAD(ice_engine_list, ice_flow_engine); >+ >+/* Struct to store flow created. */ >+struct rte_flow { >+TAILQ_ENTRY(rte_flow) node; Indentation is needed here. >+ struct ice_flow_engine *engine; >+ void *rule; >+}; >+ >+/* Struct to store parser created. */ >+struct ice_flow_parser { >+ TAILQ_ENTRY(ice_flow_parser) node; >+ struct ice_flow_engine *engine; >+ struct ice_pattern_match_item *array; >+ uint32_t array_len; >+ parse_pattern_action_t parse_pattern_action; >+ enum ice_flow_classification_stage stage; >+}; >+ >+void ice_register_flow_engine(struct ice_flow_engine *engine); >+int ice_flow_init(struct ice_adapter *ad); >+void ice_flow_uninit(struct ice_adapter *ad); >+int ice_register_parser(struct ice_flow_parser *parser, >+ struct ice_adapter *ad); >+void ice_unregister_parser(struct ice_flow_parser *parser, >+ struct ice_adapter *ad); >+struct ice_pattern_match_item * >+ice_search_pattern_match_item( >+ const struct rte_flow_item pattern[], >+ struct ice_pattern_match_item *array, >+ uint32_t array_len, >+ struct rte_flow_error *error); > > #endif >diff --git a/drivers/net/ice/ice_switch_filter.c b/drivers/net/ice/ice_switch_filter.c >index b88b4f59a..6b72bf252 100644 >--- a/drivers/net/ice/ice_switch_filter.c >+++ b/drivers/net/ice/ice_switch_filter.c >@@ -2,515 +2,4 @@ > * Copyright(c) 2019 Intel Corporation > */ > >-#include >-#include >-#include >-#include >-#include >-#include >-#include > >-#include >-#include >-#include >-#include >-#include >-#include >-#include >-#include >- >-#include "ice_logs.h" >-#include "base/ice_type.h" >-#include "ice_switch_filter.h" >- >-static int >-ice_parse_switch_filter(const struct rte_flow_item pattern[], >- const struct rte_flow_action actions[], >- struct rte_flow_error *error, >- struct ice_adv_lkup_elem *list, >- uint16_t *lkups_num, >- enum ice_sw_tunnel_type tun_type) >-{ >- const struct rte_flow_item *item = pattern; >- enum rte_flow_item_type item_type; >- const struct rte_flow_item_eth *eth_spec, *eth_mask; >- const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_mask; >- const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask; >- const struct rte_flow_item_tcp *tcp_spec, *tcp_mask; >- const struct rte_flow_item_udp *udp_spec, *udp_mask; >- const struct rte_flow_item_sctp *sctp_spec, *sctp_mask; >- const struct rte_flow_item_nvgre *nvgre_spec, *nvgre_mask; >- const struct rte_flow_item_vxlan *vxlan_spec, *vxlan_mask; >- uint16_t j, t = 0; >- uint16_t tunnel_valid = 0; >- >- for (item = pattern; item->type != >- RTE_FLOW_ITEM_TYPE_END; item++) { >- item_type = item->type; >- >- switch (item_type) { >- case RTE_FLOW_ITEM_TYPE_ETH: >- eth_spec = item->spec; >- eth_mask = item->mask; >- if (eth_spec && eth_mask) { >- list[t].type = (tun_type == ICE_NON_TUN) ? >- ICE_MAC_OFOS : ICE_MAC_IL; >- struct ice_ether_hdr *h; >- struct ice_ether_hdr *m; >- uint16_t i = 0; >- h = &list[t].h_u.eth_hdr; >- m = &list[t].m_u.eth_hdr; >- for (j = 0; j < RTE_ETHER_ADDR_LEN; j++) { >- if (eth_mask->src.addr_bytes[j] == >- UINT8_MAX) { >- h->src_addr[j] = >- eth_spec->src.addr_bytes[j]; >- m->src_addr[j] = >- eth_mask->src.addr_bytes[j]; >- i = 1; >- } >- if (eth_mask->dst.addr_bytes[j] == >- UINT8_MAX) { >- h->dst_addr[j] = >- eth_spec->dst.addr_bytes[j]; >- m->dst_addr[j] = >- eth_mask->dst.addr_bytes[j]; >- i = 1; >- } >- } >- if (i) >- t++; >- if (eth_mask->type == UINT16_MAX) { >- list[t].type = ICE_ETYPE_OL; >- list[t].h_u.ethertype.ethtype_id = >- eth_spec->type; >- list[t].m_u.ethertype.ethtype_id = >- UINT16_MAX; >- t++; >- } >- } else if (!eth_spec && !eth_mask) { >- list[t].type = (tun_type == ICE_NON_TUN) ? >- ICE_MAC_OFOS : ICE_MAC_IL; >- } >- break; >- >- case RTE_FLOW_ITEM_TYPE_IPV4: >- ipv4_spec = item->spec; >- ipv4_mask = item->mask; >- if (ipv4_spec && ipv4_mask) { >- list[t].type = (tun_type == ICE_NON_TUN) ? >- ICE_IPV4_OFOS : ICE_IPV4_IL; >- if (ipv4_mask->hdr.src_addr == UINT32_MAX) { >- list[t].h_u.ipv4_hdr.src_addr = >- ipv4_spec->hdr.src_addr; >- list[t].m_u.ipv4_hdr.src_addr = >- UINT32_MAX; >- } >- if (ipv4_mask->hdr.dst_addr == UINT32_MAX) { >- list[t].h_u.ipv4_hdr.dst_addr = >- ipv4_spec->hdr.dst_addr; >- list[t].m_u.ipv4_hdr.dst_addr = >- UINT32_MAX; >- } >- if (ipv4_mask->hdr.time_to_live == UINT8_MAX) { >- list[t].h_u.ipv4_hdr.time_to_live = >- ipv4_spec->hdr.time_to_live; >- list[t].m_u.ipv4_hdr.time_to_live = >- UINT8_MAX; >- } >- if (ipv4_mask->hdr.next_proto_id == UINT8_MAX) { >- list[t].h_u.ipv4_hdr.protocol = >- ipv4_spec->hdr.next_proto_id; >- list[t].m_u.ipv4_hdr.protocol = >- UINT8_MAX; >- } >- if (ipv4_mask->hdr.type_of_service == >- UINT8_MAX) { >- list[t].h_u.ipv4_hdr.tos = >- ipv4_spec->hdr.type_of_service; >- list[t].m_u.ipv4_hdr.tos = UINT8_MAX; >- } >- t++; >- } else if (!ipv4_spec && !ipv4_mask) { >- list[t].type = (tun_type == ICE_NON_TUN) ? >- ICE_IPV4_OFOS : ICE_IPV4_IL; >- } >- break; >- >- case RTE_FLOW_ITEM_TYPE_IPV6: >- ipv6_spec = item->spec; >- ipv6_mask = item->mask; >- if (ipv6_spec && ipv6_mask) { >- list[t].type = (tun_type == ICE_NON_TUN) ? >- ICE_IPV6_OFOS : ICE_IPV6_IL; >- struct ice_ipv6_hdr *f; >- struct ice_ipv6_hdr *s; >- f = &list[t].h_u.ipv6_hdr; >- s = &list[t].m_u.ipv6_hdr; >- for (j = 0; j < ICE_IPV6_ADDR_LENGTH; j++) { >- if (ipv6_mask->hdr.src_addr[j] == >- UINT8_MAX) { >- f->src_addr[j] = >- ipv6_spec->hdr.src_addr[j]; >- s->src_addr[j] = >- ipv6_mask->hdr.src_addr[j]; >- } >- if (ipv6_mask->hdr.dst_addr[j] == >- UINT8_MAX) { >- f->dst_addr[j] = >- ipv6_spec->hdr.dst_addr[j]; >- s->dst_addr[j] = >- ipv6_mask->hdr.dst_addr[j]; >- } >- } >- if (ipv6_mask->hdr.proto == UINT8_MAX) { >- f->next_hdr = >- ipv6_spec->hdr.proto; >- s->next_hdr = UINT8_MAX; >- } >- if (ipv6_mask->hdr.hop_limits == UINT8_MAX) { >- f->hop_limit = >- ipv6_spec->hdr.hop_limits; >- s->hop_limit = UINT8_MAX; >- } >- t++; >- } else if (!ipv6_spec && !ipv6_mask) { >- list[t].type = (tun_type == ICE_NON_TUN) ? >- ICE_IPV4_OFOS : ICE_IPV4_IL; >- } >- break; >- >- case RTE_FLOW_ITEM_TYPE_UDP: >- udp_spec = item->spec; >- udp_mask = item->mask; >- if (udp_spec && udp_mask) { >- if (tun_type == ICE_SW_TUN_VXLAN && >- tunnel_valid == 0) >- list[t].type = ICE_UDP_OF; >- else >- list[t].type = ICE_UDP_ILOS; >- if (udp_mask->hdr.src_port == UINT16_MAX) { >- list[t].h_u.l4_hdr.src_port = >- udp_spec->hdr.src_port; >- list[t].m_u.l4_hdr.src_port = >- udp_mask->hdr.src_port; >- } >- if (udp_mask->hdr.dst_port == UINT16_MAX) { >- list[t].h_u.l4_hdr.dst_port = >- udp_spec->hdr.dst_port; >- list[t].m_u.l4_hdr.dst_port = >- udp_mask->hdr.dst_port; >- } >- t++; >- } else if (!udp_spec && !udp_mask) { >- list[t].type = ICE_UDP_ILOS; >- } >- break; >- >- case RTE_FLOW_ITEM_TYPE_TCP: >- tcp_spec = item->spec; >- tcp_mask = item->mask; >- if (tcp_spec && tcp_mask) { >- list[t].type = ICE_TCP_IL; >- if (tcp_mask->hdr.src_port == UINT16_MAX) { >- list[t].h_u.l4_hdr.src_port = >- tcp_spec->hdr.src_port; >- list[t].m_u.l4_hdr.src_port = >- tcp_mask->hdr.src_port; >- } >- if (tcp_mask->hdr.dst_port == UINT16_MAX) { >- list[t].h_u.l4_hdr.dst_port = >- tcp_spec->hdr.dst_port; >- list[t].m_u.l4_hdr.dst_port = >- tcp_mask->hdr.dst_port; >- } >- t++; >- } else if (!tcp_spec && !tcp_mask) { >- list[t].type = ICE_TCP_IL; >- } >- break; >- >- case RTE_FLOW_ITEM_TYPE_SCTP: >- sctp_spec = item->spec; >- sctp_mask = item->mask; >- if (sctp_spec && sctp_mask) { >- list[t].type = ICE_SCTP_IL; >- if (sctp_mask->hdr.src_port == UINT16_MAX) { >- list[t].h_u.sctp_hdr.src_port = >- sctp_spec->hdr.src_port; >- list[t].m_u.sctp_hdr.src_port = >- sctp_mask->hdr.src_port; >- } >- if (sctp_mask->hdr.dst_port == UINT16_MAX) { >- list[t].h_u.sctp_hdr.dst_port = >- sctp_spec->hdr.dst_port; >- list[t].m_u.sctp_hdr.dst_port = >- sctp_mask->hdr.dst_port; >- } >- t++; >- } else if (!sctp_spec && !sctp_mask) { >- list[t].type = ICE_SCTP_IL; >- } >- break; >- >- case RTE_FLOW_ITEM_TYPE_VXLAN: >- vxlan_spec = item->spec; >- vxlan_mask = item->mask; >- tunnel_valid = 1; >- if (vxlan_spec && vxlan_mask) { >- list[t].type = ICE_VXLAN; >- if (vxlan_mask->vni[0] == UINT8_MAX && >- vxlan_mask->vni[1] == UINT8_MAX && >- vxlan_mask->vni[2] == UINT8_MAX) { >- list[t].h_u.tnl_hdr.vni = >- (vxlan_spec->vni[2] << 16) | >- (vxlan_spec->vni[1] << 8) | >- vxlan_spec->vni[0]; >- list[t].m_u.tnl_hdr.vni = >- UINT32_MAX; >- } >- t++; >- } else if (!vxlan_spec && !vxlan_mask) { >- list[t].type = ICE_VXLAN; >- } >- break; >- >- case RTE_FLOW_ITEM_TYPE_NVGRE: >- nvgre_spec = item->spec; >- nvgre_mask = item->mask; >- tunnel_valid = 1; >- if (nvgre_spec && nvgre_mask) { >- list[t].type = ICE_NVGRE; >- if (nvgre_mask->tni[0] == UINT8_MAX && >- nvgre_mask->tni[1] == UINT8_MAX && >- nvgre_mask->tni[2] == UINT8_MAX) { >- list[t].h_u.nvgre_hdr.tni_flow = >- (nvgre_spec->tni[2] << 16) | >- (nvgre_spec->tni[1] << 8) | >- nvgre_spec->tni[0]; >- list[t].m_u.nvgre_hdr.tni_flow = >- UINT32_MAX; >- } >- t++; >- } else if (!nvgre_spec && !nvgre_mask) { >- list[t].type = ICE_NVGRE; >- } >- break; >- >- case RTE_FLOW_ITEM_TYPE_VOID: >- case RTE_FLOW_ITEM_TYPE_END: >- break; >- >- default: >- rte_flow_error_set(error, EINVAL, >- RTE_FLOW_ERROR_TYPE_ITEM, actions, >- "Invalid pattern item."); >- goto out; >- } >- } >- >- *lkups_num = t; >- >- return 0; >-out: >- return -rte_errno; >-} >- >-/* By now ice switch filter action code implement only >- * supports QUEUE or DROP. >- */ >-static int >-ice_parse_switch_action(struct ice_pf *pf, >- const struct rte_flow_action *actions, >- struct rte_flow_error *error, >- struct ice_adv_rule_info *rule_info) >-{ >- struct ice_vsi *vsi = pf->main_vsi; >- const struct rte_flow_action_queue *act_q; >- uint16_t base_queue; >- const struct rte_flow_action *action; >- enum rte_flow_action_type action_type; >- >- base_queue = pf->base_queue; >- for (action = actions; action->type != >- RTE_FLOW_ACTION_TYPE_END; action++) { >- action_type = action->type; >- switch (action_type) { >- case RTE_FLOW_ACTION_TYPE_QUEUE: >- act_q = action->conf; >- rule_info->sw_act.fltr_act = >- ICE_FWD_TO_Q; >- rule_info->sw_act.fwd_id.q_id = >- base_queue + act_q->index; >- break; >- >- case RTE_FLOW_ACTION_TYPE_DROP: >- rule_info->sw_act.fltr_act = >- ICE_DROP_PACKET; >- break; >- >- case RTE_FLOW_ACTION_TYPE_VOID: >- break; >- >- default: >- rte_flow_error_set(error, >- EINVAL, >- RTE_FLOW_ERROR_TYPE_ITEM, >- actions, >- "Invalid action type"); >- return -rte_errno; >- } >- } >- >- rule_info->sw_act.vsi_handle = vsi->idx; >- rule_info->rx = 1; >- rule_info->sw_act.src = vsi->idx; >- rule_info->priority = 5; >- >- return 0; >-} >- >-static int >-ice_switch_rule_set(struct ice_pf *pf, >- struct ice_adv_lkup_elem *list, >- uint16_t lkups_cnt, >- struct ice_adv_rule_info *rule_info, >- struct rte_flow *flow, >- struct rte_flow_error *error) >-{ >- struct ice_hw *hw = ICE_PF_TO_HW(pf); >- int ret; >- struct ice_rule_query_data rule_added = {0}; >- struct ice_rule_query_data *filter_ptr; >- >- if (lkups_cnt > ICE_MAX_CHAIN_WORDS) { >- rte_flow_error_set(error, EINVAL, >- RTE_FLOW_ERROR_TYPE_ITEM, NULL, >- "item number too large for rule"); >- return -rte_errno; >- } >- if (!list) { >- rte_flow_error_set(error, EINVAL, >- RTE_FLOW_ERROR_TYPE_ITEM, NULL, >- "lookup list should not be NULL"); >- return -rte_errno; >- } >- >- ret = ice_add_adv_rule(hw, list, lkups_cnt, rule_info, &rule_added); >- >- if (!ret) { >- filter_ptr = rte_zmalloc("ice_switch_filter", >- sizeof(struct ice_rule_query_data), 0); >- if (!filter_ptr) { >- PMD_DRV_LOG(ERR, "failed to allocate memory"); >- return -EINVAL; >- } >- flow->rule = filter_ptr; >- rte_memcpy(filter_ptr, >- &rule_added, >- sizeof(struct ice_rule_query_data)); >- } >- >- return ret; >-} >- >-int >-ice_create_switch_filter(struct ice_pf *pf, >- const struct rte_flow_item pattern[], >- const struct rte_flow_action actions[], >- struct rte_flow *flow, >- struct rte_flow_error *error) >-{ >- int ret = 0; >- struct ice_adv_rule_info rule_info = {0}; >- struct ice_adv_lkup_elem *list = NULL; >- uint16_t lkups_num = 0; >- const struct rte_flow_item *item = pattern; >- uint16_t item_num = 0; >- enum ice_sw_tunnel_type tun_type = ICE_NON_TUN; >- >- for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { >- item_num++; >- if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN) >- tun_type = ICE_SW_TUN_VXLAN; >- if (item->type == RTE_FLOW_ITEM_TYPE_NVGRE) >- tun_type = ICE_SW_TUN_NVGRE; >- /* reserve one more memory slot for ETH which may >- * consume 2 lookup items. >- */ >- if (item->type == RTE_FLOW_ITEM_TYPE_ETH) >- item_num++; >- } >- rule_info.tun_type = tun_type; >- >- list = rte_zmalloc(NULL, item_num * sizeof(*list), 0); >- if (!list) { >- rte_flow_error_set(error, EINVAL, >- RTE_FLOW_ERROR_TYPE_HANDLE, NULL, >- "No memory for PMD internal items"); >- return -rte_errno; >- } >- >- ret = ice_parse_switch_filter(pattern, actions, error, >- list, &lkups_num, tun_type); >- if (ret) >- goto error; >- >- ret = ice_parse_switch_action(pf, actions, error, &rule_info); >- if (ret) >- goto error; >- >- ret = ice_switch_rule_set(pf, list, lkups_num, &rule_info, flow, error); >- if (ret) >- goto error; >- >- rte_free(list); >- return 0; >- >-error: >- rte_free(list); >- >- return -rte_errno; >-} >- >-int >-ice_destroy_switch_filter(struct ice_pf *pf, >- struct rte_flow *flow, >- struct rte_flow_error *error) >-{ >- struct ice_hw *hw = ICE_PF_TO_HW(pf); >- int ret; >- struct ice_rule_query_data *filter_ptr; >- >- filter_ptr = (struct ice_rule_query_data *) >- flow->rule; >- >- if (!filter_ptr) { >- rte_flow_error_set(error, EINVAL, >- RTE_FLOW_ERROR_TYPE_HANDLE, NULL, >- "no such flow" >- " create by switch filter"); >- return -rte_errno; >- } >- >- ret = ice_rem_adv_rule_by_id(hw, filter_ptr); >- if (ret) { >- rte_flow_error_set(error, EINVAL, >- RTE_FLOW_ERROR_TYPE_HANDLE, NULL, >- "fail to destroy switch filter rule"); >- return -rte_errno; >- } >- >- rte_free(filter_ptr); >- return ret; >-} >- >-void >-ice_free_switch_filter_rule(void *rule) >-{ >- struct ice_rule_query_data *filter_ptr; >- >- filter_ptr = (struct ice_rule_query_data *)rule; >- >- rte_free(filter_ptr); >-} >diff --git a/drivers/net/ice/ice_switch_filter.h b/drivers/net/ice/ice_switch_filter.h >index cea47990e..5afcddeaf 100644 >--- a/drivers/net/ice/ice_switch_filter.h >+++ b/drivers/net/ice/ice_switch_filter.h >@@ -2,23 +2,5 @@ > * Copyright(c) 2019 Intel Corporation > */ > >-#ifndef _ICE_SWITCH_FILTER_H_ >-#define _ICE_SWITCH_FILTER_H_ > >-#include "base/ice_switch.h" >-#include "base/ice_type.h" >-#include "ice_ethdev.h" > >-int >-ice_create_switch_filter(struct ice_pf *pf, >- const struct rte_flow_item pattern[], >- const struct rte_flow_action actions[], >- struct rte_flow *flow, >- struct rte_flow_error *error); >-int >-ice_destroy_switch_filter(struct ice_pf *pf, >- struct rte_flow *flow, >- struct rte_flow_error *error); >-void >-ice_free_switch_filter_rule(void *rule); >-#endif /* _ICE_SWITCH_FILTER_H_ */ >-- >2.15.1 >