DPDK patches and discussions
 help / color / mirror / Atom feed
From: Bernard Iremonger <bernard.iremonger@intel.com>
To: dev@dpdk.org, beilei.xing@intel.com, qi.z.zhang@intel.com,
	declan.doherty@intel.com, orika@mellanox.com
Cc: Bernard Iremonger <bernard.iremonger@intel.com>
Subject: [dpdk-dev] [PATCH 7/8] net/i40e: parse map pattern and action
Date: Wed,  3 Jun 2020 15:20:08 +0100
Message-ID: <1591194009-4086-8-git-send-email-bernard.iremonger@intel.com> (raw)
In-Reply-To: <1591194009-4086-1-git-send-email-bernard.iremonger@intel.com>

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 <bernard.iremonger@intel.com>
---
 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);
-- 
2.7.4


  parent reply	other threads:[~2020-06-03 14:21 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-03 14:20 [dpdk-dev] [PATCH 0/8] add flow action map Bernard Iremonger
2020-06-03 14:20 ` [dpdk-dev] [PATCH 1/8] librte_ethdev: add new flow types and action Bernard Iremonger
2020-06-03 14:20 ` [dpdk-dev] [PATCH 2/8] librte_ethdev: add map filter type Bernard Iremonger
2020-06-03 14:20 ` [dpdk-dev] [PATCH 3/8] librte_ethdev: add map action Bernard Iremonger
2020-06-03 14:20 ` [dpdk-dev] [PATCH 4/8] app/testpmd: parse map actions Bernard Iremonger
2020-06-03 14:20 ` [dpdk-dev] [PATCH 5/8] net/i40e: add map filter Bernard Iremonger
2020-06-03 14:20 ` [dpdk-dev] [PATCH 6/8] net/i40e: add map functions Bernard Iremonger
2020-06-03 14:20 ` Bernard Iremonger [this message]
2020-06-03 14:20 ` [dpdk-dev] [PATCH 8/8] doc: release note Bernard Iremonger
2020-06-04  6:05 ` [dpdk-dev] [PATCH 0/8] add flow action map Ori Kam
2020-06-04 11:21   ` Iremonger, Bernard
2020-06-04 13:12     ` Thomas Monjalon

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=1591194009-4086-8-git-send-email-bernard.iremonger@intel.com \
    --to=bernard.iremonger@intel.com \
    --cc=beilei.xing@intel.com \
    --cc=declan.doherty@intel.com \
    --cc=dev@dpdk.org \
    --cc=orika@mellanox.com \
    --cc=qi.z.zhang@intel.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

DPDK patches and discussions

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://inbox.dpdk.org/dev/0 dev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 dev dev/ https://inbox.dpdk.org/dev \
		dev@dpdk.org
	public-inbox-index dev

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.dpdk.org/inbox.dpdk.dev


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git