From patchwork Wed Jun 3 14:20:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Iremonger, Bernard" X-Patchwork-Id: 70834 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 17ED0A04A4; Wed, 3 Jun 2020 16:21:35 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 527BB1D597; Wed, 3 Jun 2020 16:20:53 +0200 (CEST) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id 7A21A1D567 for ; Wed, 3 Jun 2020 16:20:50 +0200 (CEST) IronPort-SDR: qZWBJ9C5Nn8cFDdfEgSB3A9IRENI+/rSQtZNsD/U+4gH1t6AvcTZSwpzd87x8w/7LR4al8/nG/ OIRBCJ24n+7w== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Jun 2020 07:20:34 -0700 IronPort-SDR: Lx5EwmL0mN+VlBoV+W0/FE9J1iSuzJt99dtzWb82skHHoXy8cNQnotlma7/Fgc+Nvtc38cnL84 E5E8NqowAx4A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,467,1583222400"; d="scan'208";a="416572806" Received: from sivswdev08.ir.intel.com (HELO localhost.localdomain) ([10.237.217.47]) by orsmga004.jf.intel.com with ESMTP; 03 Jun 2020 07:20:32 -0700 From: Bernard Iremonger To: dev@dpdk.org, beilei.xing@intel.com, qi.z.zhang@intel.com, declan.doherty@intel.com, orika@mellanox.com Cc: Bernard Iremonger Date: Wed, 3 Jun 2020 15:20:08 +0100 Message-Id: <1591194009-4086-8-git-send-email-bernard.iremonger@intel.com> X-Mailer: git-send-email 1.7.0.7 In-Reply-To: <1591194009-4086-1-git-send-email-bernard.iremonger@intel.com> References: <1591194009-4086-1-git-send-email-bernard.iremonger@intel.com> Subject: [dpdk-dev] [PATCH 7/8] net/i40e: parse map pattern and action 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" Parse the map pattern and action in i40e_flow.c Add the following functions: i40e_flow_parse_map_pattern() i40e_flow_parse_map_action() i40e_parse_map_filter() i40e_config_map_filter_set() i40e_config_map_filter_del() Signed-off-by: Bernard Iremonger --- drivers/net/i40e/i40e_flow.c | 196 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c index 8f8df6f..9616a87 100644 --- a/drivers/net/i40e/i40e_flow.c +++ b/drivers/net/i40e/i40e_flow.c @@ -4996,6 +4996,185 @@ i40e_config_rss_filter_del(struct rte_eth_dev *dev, } static int +i40e_flow_parse_map_pattern(__rte_unused struct rte_eth_dev *dev, + const struct rte_flow_item *pattern, + struct i40e_map_pattern_info *p_info, + struct rte_flow_error *error) +{ + const struct rte_flow_item *item = pattern; + enum rte_flow_item_type item_type; + struct rte_flow_item *items; + uint32_t item_num = 0; /* non-void item number of pattern*/ + uint32_t i = 0; + + if (item->type == RTE_FLOW_ITEM_TYPE_END) { + p_info->action_flag = 1; + return 0; + } + + /* Convert pattern to item types */ + while ((pattern + i)->type != RTE_FLOW_ITEM_TYPE_END) { + if ((pattern + i)->type != RTE_FLOW_ITEM_TYPE_VOID) + item_num++; + i++; + } + item_num++; + + items = rte_zmalloc("i40e_pattern", + item_num * sizeof(struct rte_flow_item), 0); + if (!items) { + rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_ITEM_NUM, + NULL, "No memory for PMD internal items."); + return -ENOMEM; + } + + i40e_pattern_skip_void_item(items, pattern); + + rte_free(items); + + for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { + if (item->last) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, + "Not supported"); + return -rte_errno; + } + item_type = item->type; + switch (item_type) { + case RTE_FLOW_ITEM_TYPE_ETH: + p_info->action_flag = 1; + break; + + default: + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, + "item not supported"); + return -rte_errno; + } + } + + return 0; +} + +static int +i40e_flow_parse_map_action(__rte_unused struct rte_eth_dev *dev, + const struct rte_flow_action *actions, + struct i40e_map_pattern_info *p_info, + struct rte_flow_error *error, + union i40e_filter_t *filter) +{ + const struct rte_flow_action *act; + const struct rte_flow_action_map *map; + struct i40e_rte_flow_map_conf *map_conf = &filter->map_conf; + uint32_t index = 0; + + NEXT_ITEM_OF_ACTION(act, actions, index); + + /** + * check if the first not void action is MAP. + */ + if ((act->type != RTE_FLOW_ACTION_TYPE_MAP) || + (p_info->action_flag == 0)) { + memset(map_conf, 0, sizeof(struct i40e_rte_flow_map_conf)); + rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, + act, "Not supported action."); + return -rte_errno; + } + + map = act->conf; + + if (i40e_map_conf_init(map_conf, map)) + return rte_flow_error_set + (error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, act, + "MAP context initialization failure"); + + map_conf->valid = true; + + return 0; +} + +static int +i40e_parse_map_filter(struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_flow_item pattern[], + const struct rte_flow_action actions[], + union i40e_filter_t *filter, + struct rte_flow_error *error) +{ + struct i40e_map_pattern_info p_info; + int ret; + + memset(&p_info, 0, sizeof(struct i40e_map_pattern_info)); + + ret = i40e_flow_parse_map_pattern(dev, pattern, &p_info, error); + if (ret) + return ret; + + ret = i40e_flow_parse_map_action(dev, actions, &p_info, error, filter); + if (ret) + return ret; + + ret = i40e_flow_parse_attr(attr, error); + if (ret) + return ret; + + cons_filter_type = RTE_ETH_FILTER_MAP; + + return 0; +} + +static int +i40e_config_map_filter_set(struct rte_eth_dev *dev, + struct i40e_rte_flow_map_conf *conf) +{ + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); + struct i40e_map_filter *map_filter; + int ret; + + ret = i40e_config_map_filter(pf, conf, 1); + if (ret) + return ret; + + map_filter = rte_zmalloc("i40e_map_filter", sizeof(*map_filter), 0); + if (map_filter == NULL) { + PMD_DRV_LOG(ERR, "Failed to alloc memory."); + return -ENOMEM; + } + map_filter->map_filter_info = *conf; + + /* the rule newly created is always valid + * the existing rule covered by new rule will be set invalid + */ + map_filter->map_filter_info.valid = true; + + TAILQ_INSERT_TAIL(&pf->map_config_list, map_filter, next); + + return 0; +} + +static int +i40e_config_map_filter_del(struct rte_eth_dev *dev, + struct i40e_rte_flow_map_conf *conf) +{ + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); + struct i40e_map_filter *map_filter; + void *temp; + + i40e_config_map_filter(pf, conf, 0); + + TAILQ_FOREACH_SAFE(map_filter, &pf->map_config_list, next, temp) { + if (!memcmp(&map_filter->map_filter_info, conf, + sizeof(struct rte_flow_action_map))) { + TAILQ_REMOVE(&pf->map_config_list, map_filter, next); + rte_free(map_filter); + } + } + return 0; +} + +static int i40e_flow_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, const struct rte_flow_item pattern[], @@ -5041,6 +5220,12 @@ i40e_flow_validate(struct rte_eth_dev *dev, return ret; } + if ((actions + i)->type == RTE_FLOW_ACTION_TYPE_MAP) { + ret = i40e_parse_map_filter(dev, attr, pattern, + actions, &cons_filter, error); + return ret; + } + i = 0; /* Get the non-void item number of pattern */ while ((pattern + i)->type != RTE_FLOW_ITEM_TYPE_END) { @@ -5137,6 +5322,13 @@ i40e_flow_create(struct rte_eth_dev *dev, flow->rule = TAILQ_LAST(&pf->rss_config_list, i40e_rss_conf_list); break; + case RTE_ETH_FILTER_MAP: + ret = i40e_config_map_filter_set(dev, &cons_filter.map_conf); + if (ret) + goto free_flow; + flow->rule = TAILQ_LAST(&pf->map_config_list, + i40e_map_conf_list); + break; default: goto free_flow; } @@ -5184,6 +5376,10 @@ i40e_flow_destroy(struct rte_eth_dev *dev, ret = i40e_config_rss_filter_del(dev, &((struct i40e_rss_filter *)flow->rule)->rss_filter_info); break; + case RTE_ETH_FILTER_MAP: + ret = i40e_config_map_filter_del(dev, + &((struct i40e_map_filter *)flow->rule)->map_filter_info); + break; default: PMD_DRV_LOG(WARNING, "Filter type (%d) not supported", filter_type);