src/dpdk/drivers/net/hns3/hns3_flow.c
static struct rte_flow *
hns3_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)
{
	struct hns3_process_private *process_list = dev->process_private;
	struct hns3_adapter *hns = dev->data->dev_private;
	struct hns3_hw *hw = &hns->hw;
	const struct hns3_rss_conf *rss_conf;
	struct hns3_fdir_rule_ele *fdir_rule_ptr;
	struct hns3_rss_conf_ele *rss_filter_ptr;
	struct hns3_flow_mem *flow_node;
	const struct rte_flow_action *act;
	struct rte_flow *flow;
	struct hns3_fdir_rule fdir_rule;
	int ret;

	ret = hns3_flow_validate(dev, attr, pattern, actions, error);
	if (ret)
		return NULL;

	flow = rte_zmalloc("hns3 flow", sizeof(struct rte_flow), 0);
	if (flow == NULL) {
		rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE,
				   NULL, "Failed to allocate flow memory");
		return NULL;
	}
	flow_node = rte_zmalloc("hns3 flow node",
				sizeof(struct hns3_flow_mem), 0);
	if (flow_node == NULL) {
		rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE,
				   NULL, "Failed to allocate flow list memory");
		rte_free(flow);
		return NULL;
	}

	flow_node->flow = flow;
	TAILQ_INSERT_TAIL(&process_list->flow_list, flow_node, entries);

	act = hns3_find_rss_general_action(pattern, actions);
	if (act) {
		rss_conf = act->conf;

		ret = hns3_flow_parse_rss(dev, rss_conf, true);
		if (ret)
			goto err;

		rss_filter_ptr = rte_zmalloc("hns3 rss filter",
					     sizeof(struct hns3_rss_conf_ele),
					     0);
		if (rss_filter_ptr == NULL) {
			hns3_err(hw,
				    "Failed to allocate hns3_rss_filter memory");
			ret = -ENOMEM;
			goto err;
		}
		hns3_rss_conf_copy(&rss_filter_ptr->filter_info,
				   &rss_conf->conf);
		rss_filter_ptr->filter_info.valid = true;
		TAILQ_INSERT_TAIL(&process_list->filter_rss_list,
				  rss_filter_ptr, entries);

		flow->rule = rss_filter_ptr;
		flow->filter_type = RTE_ETH_FILTER_HASH;
		return flow;
	}

	memset(&fdir_rule, 0, sizeof(struct hns3_fdir_rule));
	ret = hns3_parse_fdir_filter(dev, pattern, actions, &fdir_rule, error);
	if (ret)
		goto out;

	if (fdir_rule.flags & HNS3_RULE_FLAG_COUNTER) {
		ret = hns3_counter_new(dev, fdir_rule.act_cnt.shared,
				       fdir_rule.act_cnt.id, error);
		if (ret)
			goto out;

		flow->counter_id = fdir_rule.act_cnt.id;
	}

	fdir_rule_ptr = rte_zmalloc("hns3 fdir rule",
				    sizeof(struct hns3_fdir_rule_ele),
				    0);
	if (fdir_rule_ptr == NULL) {
		hns3_err(hw, "failed to allocate fdir_rule memory.");
		ret = -ENOMEM;
		goto err_fdir;
	}

	ret = hns3_fdir_filter_program(hns, &fdir_rule, false);
	if (!ret) {
		memcpy(&fdir_rule_ptr->fdir_conf, &fdir_rule,
			sizeof(struct hns3_fdir_rule));
		TAILQ_INSERT_TAIL(&process_list->fdir_list,
				  fdir_rule_ptr, entries);
		flow->rule = fdir_rule_ptr;
		flow->filter_type = RTE_ETH_FILTER_FDIR;

		return flow;
	}

	rte_free(fdir_rule_ptr);
err_fdir:
	if (fdir_rule.flags & HNS3_RULE_FLAG_COUNTER)
		hns3_counter_release(dev, fdir_rule.act_cnt.id);
err:
	rte_flow_error_set(error, -ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
			   "Failed to create flow");
out:
	TAILQ_REMOVE(&process_list->flow_list, flow_node, entries);
	rte_free(flow_node);
	rte_free(flow);
	return NULL;
}
/*
 * Create or destroy a flow rule.
 * Theorically one rule can match more than one filters.
 * We will let it use the filter which it hit first.
 * So, the sequence matters.
 */
Create or destroy a flow rule.
Theorically one rule can match more than one filters.
We will let it use the filter which it hit first.
So, the sequence matters.
Create or destroy a flow rule . Theorically one rule can match more than one filters . We will let it use the filter which it hit first . So the sequence matters .
static struct rte_flow *
hns3_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)
{
	struct hns3_process_private *process_list = dev->process_private;
	struct hns3_adapter *hns = dev->data->dev_private;
	struct hns3_hw *hw = &hns->hw;
	const struct hns3_rss_conf *rss_conf;
	struct hns3_fdir_rule_ele *fdir_rule_ptr;
	struct hns3_rss_conf_ele *rss_filter_ptr;
	struct hns3_flow_mem *flow_node;
	const struct rte_flow_action *act;
	struct rte_flow *flow;
	struct hns3_fdir_rule fdir_rule;
	int ret;
	ret = hns3_flow_validate(dev, attr, pattern, actions, error);
	if (ret)
		return NULL;
	flow = rte_zmalloc("hns3 flow", sizeof(struct rte_flow), 0);
	if (flow == NULL) {
		rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE,
				   NULL, "Failed to allocate flow memory");
		return NULL;
	}
	flow_node = rte_zmalloc("hns3 flow node",
				sizeof(struct hns3_flow_mem), 0);
	if (flow_node == NULL) {
		rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE,
				   NULL, "Failed to allocate flow list memory");
		rte_free(flow);
		return NULL;
	}
	flow_node->flow = flow;
	TAILQ_INSERT_TAIL(&process_list->flow_list, flow_node, entries);
	act = hns3_find_rss_general_action(pattern, actions);
	if (act) {
		rss_conf = act->conf;
		ret = hns3_flow_parse_rss(dev, rss_conf, true);
		if (ret)
			goto err;
		rss_filter_ptr = rte_zmalloc("hns3 rss filter",
					     sizeof(struct hns3_rss_conf_ele),
					     0);
		if (rss_filter_ptr == NULL) {
			hns3_err(hw,
				    "Failed to allocate hns3_rss_filter memory");
			ret = -ENOMEM;
			goto err;
		}
		hns3_rss_conf_copy(&rss_filter_ptr->filter_info,
				   &rss_conf->conf);
		rss_filter_ptr->filter_info.valid = true;
		TAILQ_INSERT_TAIL(&process_list->filter_rss_list,
				  rss_filter_ptr, entries);
		flow->rule = rss_filter_ptr;
		flow->filter_type = RTE_ETH_FILTER_HASH;
		return flow;
	}
	memset(&fdir_rule, 0, sizeof(struct hns3_fdir_rule));
	ret = hns3_parse_fdir_filter(dev, pattern, actions, &fdir_rule, error);
	if (ret)
		goto out;
	if (fdir_rule.flags & HNS3_RULE_FLAG_COUNTER) {
		ret = hns3_counter_new(dev, fdir_rule.act_cnt.shared,
				       fdir_rule.act_cnt.id, error);
		if (ret)
			goto out;
		flow->counter_id = fdir_rule.act_cnt.id;
	}
	fdir_rule_ptr = rte_zmalloc("hns3 fdir rule",
				    sizeof(struct hns3_fdir_rule_ele),
				    0);
	if (fdir_rule_ptr == NULL) {
		hns3_err(hw, "failed to allocate fdir_rule memory.");
		ret = -ENOMEM;
		goto err_fdir;
	}
	ret = hns3_fdir_filter_program(hns, &fdir_rule, false);
	if (!ret) {
		memcpy(&fdir_rule_ptr->fdir_conf, &fdir_rule,
			sizeof(struct hns3_fdir_rule));
		TAILQ_INSERT_TAIL(&process_list->fdir_list,
				  fdir_rule_ptr, entries);
		flow->rule = fdir_rule_ptr;
		flow->filter_type = RTE_ETH_FILTER_FDIR;
		return flow;
	}
	rte_free(fdir_rule_ptr);
err_fdir:
	if (fdir_rule.flags & HNS3_RULE_FLAG_COUNTER)
		hns3_counter_release(dev, fdir_rule.act_cnt.id);
err:
	rte_flow_error_set(error, -ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
			   "Failed to create flow");
out:
	TAILQ_REMOVE(&process_list->flow_list, flow_node, entries);
	rte_free(flow_node);
	rte_free(flow);
	return NULL;
}
static struct rte_flow * hns3_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 ) { struct hns3_process_private * process_list = dev -> process_private ; struct hns3_adapter * hns = dev -> data -> dev_private ; struct hns3_hw * hw = & hns -> hw ; const struct hns3_rss_conf * rss_conf ; struct hns3_fdir_rule_ele * fdir_rule_ptr ; struct hns3_rss_conf_ele * rss_filter_ptr ; struct hns3_flow_mem * flow_node ; const struct rte_flow_action * act ; struct rte_flow * flow ; struct hns3_fdir_rule fdir_rule ; int ret ; ret = hns3_flow_validate ( dev , attr , pattern , actions , error ) ; if ( ret ) return NULL ; flow = rte_zmalloc ( " " , sizeof ( struct rte_flow ) , 0 ) ; if ( flow == NULL ) { rte_flow_error_set ( error , ENOMEM , RTE_FLOW_ERROR_TYPE_HANDLE , NULL , " " ) ; return NULL ; } flow_node = rte_zmalloc ( " " , sizeof ( struct hns3_flow_mem ) , 0 ) ; if ( flow_node == NULL ) { rte_flow_error_set ( error , ENOMEM , RTE_FLOW_ERROR_TYPE_HANDLE , NULL , " " ) ; rte_free ( flow ) ; return NULL ; } flow_node -> flow = flow ; TAILQ_INSERT_TAIL ( & process_list -> flow_list , flow_node , entries ) ; act = hns3_find_rss_general_action ( pattern , actions ) ; if ( act ) { rss_conf = act -> conf ; ret = hns3_flow_parse_rss ( dev , rss_conf , true ) ; if ( ret ) goto err ; rss_filter_ptr = rte_zmalloc ( " " , sizeof ( struct hns3_rss_conf_ele ) , 0 ) ; if ( rss_filter_ptr == NULL ) { hns3_err ( hw , " " ) ; ret = - ENOMEM ; goto err ; } hns3_rss_conf_copy ( & rss_filter_ptr -> filter_info , & rss_conf -> conf ) ; rss_filter_ptr -> filter_info . valid = true ; TAILQ_INSERT_TAIL ( & process_list -> filter_rss_list , rss_filter_ptr , entries ) ; flow -> rule = rss_filter_ptr ; flow -> filter_type = RTE_ETH_FILTER_HASH ; return flow ; } memset ( & fdir_rule , 0 , sizeof ( struct hns3_fdir_rule ) ) ; ret = hns3_parse_fdir_filter ( dev , pattern , actions , & fdir_rule , error ) ; if ( ret ) goto out ; if ( fdir_rule . flags & HNS3_RULE_FLAG_COUNTER ) { ret = hns3_counter_new ( dev , fdir_rule . act_cnt . shared , fdir_rule . act_cnt . id , error ) ; if ( ret ) goto out ; flow -> counter_id = fdir_rule . act_cnt . id ; } fdir_rule_ptr = rte_zmalloc ( " " , sizeof ( struct hns3_fdir_rule_ele ) , 0 ) ; if ( fdir_rule_ptr == NULL ) { hns3_err ( hw , " " ) ; ret = - ENOMEM ; goto err_fdir ; } ret = hns3_fdir_filter_program ( hns , & fdir_rule , false ) ; if ( ! ret ) { memcpy ( & fdir_rule_ptr -> fdir_conf , & fdir_rule , sizeof ( struct hns3_fdir_rule ) ) ; TAILQ_INSERT_TAIL ( & process_list -> fdir_list , fdir_rule_ptr , entries ) ; flow -> rule = fdir_rule_ptr ; flow -> filter_type = RTE_ETH_FILTER_FDIR ; return flow ; } rte_free ( fdir_rule_ptr ) ; err_fdir : if ( fdir_rule . flags & HNS3_RULE_FLAG_COUNTER ) hns3_counter_release ( dev , fdir_rule . act_cnt . id ) ; err : rte_flow_error_set ( error , - ret , RTE_FLOW_ERROR_TYPE_HANDLE , NULL , " " ) ; out : TAILQ_REMOVE ( & process_list -> flow_list , flow_node , entries ) ; rte_free ( flow_node ) ; rte_free ( flow ) ; return NULL ; }
Create or destroy a flow rule.
Create or destroy a flow rule .