src/dpdk/drivers/net/igc/igc_flow.c
static struct rte_flow *
igc_flow_create(struct rte_eth_dev *dev,
		const struct rte_flow_attr *attr,
		const struct rte_flow_item patterns[],
		const struct rte_flow_action actions[],
		struct rte_flow_error *error)
{
	struct rte_flow *flow = NULL;
	struct igc_all_filter filter;
	int ret;

	ret = igc_parse_flow(dev, attr, patterns, actions, error, &filter);
	if (ret)
		return NULL;
	ret = -ENOMEM;

	switch (filter.mask) {
	case IGC_FILTER_MASK_ETHER:
		flow = igc_alloc_flow(&filter.ethertype,
				IGC_FILTER_TYPE_ETHERTYPE,
				sizeof(filter.ethertype));
		if (flow)
			ret = igc_add_ethertype_filter(dev, &filter.ethertype);
		break;
	case IGC_FILTER_MASK_NTUPLE:
		/* Check n-tuple filter is valid */
		if (filter.ntuple.tuple_info.dst_port_mask == 0 &&
			filter.ntuple.tuple_info.proto_mask == 0) {
			rte_flow_error_set(error, EINVAL,
					RTE_FLOW_ERROR_TYPE_NONE, NULL,
					"Flow can't be recognized");
			return NULL;
		}

		flow = igc_alloc_flow(&filter.ntuple, IGC_FILTER_TYPE_NTUPLE,
				sizeof(filter.ntuple));
		if (flow)
			ret = igc_add_ntuple_filter(dev, &filter.ntuple);
		break;
	case IGC_FILTER_MASK_TCP_SYN:
		flow = igc_alloc_flow(&filter.syn, IGC_FILTER_TYPE_SYN,
				sizeof(filter.syn));
		if (flow)
			ret = igc_set_syn_filter(dev, &filter.syn);
		break;
	case IGC_FILTER_MASK_RSS:
		flow = igc_alloc_flow(&filter.rss, IGC_FILTER_TYPE_HASH,
				sizeof(filter.rss));
		if (flow) {
			struct igc_rss_filter *rss =
					(struct igc_rss_filter *)flow->filter;
			rss->conf.key = rss->key;
			rss->conf.queue = rss->queue;
			ret = igc_add_rss_filter(dev, &filter.rss);
		}
		break;
	default:
		rte_flow_error_set(error, EINVAL,
				RTE_FLOW_ERROR_TYPE_NONE, NULL,
				"Flow can't be recognized");
		return NULL;
	}

	if (ret) {
		/* check and free the memory */
		if (flow)
			rte_free(flow);

		rte_flow_error_set(error, -ret,
				RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
				"Failed to create flow.");
		return NULL;
	}

	/* append the flow to the tail of the list */
	igc_append_flow(IGC_DEV_PRIVATE_FLOW_LIST(dev), flow);
	return flow;
}
/**
 * Create a flow rule.
 * Theoretically one rule can match more than one filters.
 * We will let it use the filter which it hit first.
 * So, the sequence matters.
 **/
Create a flow rule.
Theoretically one rule can match more than one filters.
We will let it use the filter which it hit first.
So, the sequence matters.
Create a flow rule . Theoretically 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 *
igc_flow_create(struct rte_eth_dev *dev,
		const struct rte_flow_attr *attr,
		const struct rte_flow_item patterns[],
		const struct rte_flow_action actions[],
		struct rte_flow_error *error)
{
	struct rte_flow *flow = NULL;
	struct igc_all_filter filter;
	int ret;
	ret = igc_parse_flow(dev, attr, patterns, actions, error, &filter);
	if (ret)
		return NULL;
	ret = -ENOMEM;
	switch (filter.mask) {
	case IGC_FILTER_MASK_ETHER:
		flow = igc_alloc_flow(&filter.ethertype,
				IGC_FILTER_TYPE_ETHERTYPE,
				sizeof(filter.ethertype));
		if (flow)
			ret = igc_add_ethertype_filter(dev, &filter.ethertype);
		break;
	case IGC_FILTER_MASK_NTUPLE:
		if (filter.ntuple.tuple_info.dst_port_mask == 0 &&
			filter.ntuple.tuple_info.proto_mask == 0) {
			rte_flow_error_set(error, EINVAL,
					RTE_FLOW_ERROR_TYPE_NONE, NULL,
					"Flow can't be recognized");
			return NULL;
		}
		flow = igc_alloc_flow(&filter.ntuple, IGC_FILTER_TYPE_NTUPLE,
				sizeof(filter.ntuple));
		if (flow)
			ret = igc_add_ntuple_filter(dev, &filter.ntuple);
		break;
	case IGC_FILTER_MASK_TCP_SYN:
		flow = igc_alloc_flow(&filter.syn, IGC_FILTER_TYPE_SYN,
				sizeof(filter.syn));
		if (flow)
			ret = igc_set_syn_filter(dev, &filter.syn);
		break;
	case IGC_FILTER_MASK_RSS:
		flow = igc_alloc_flow(&filter.rss, IGC_FILTER_TYPE_HASH,
				sizeof(filter.rss));
		if (flow) {
			struct igc_rss_filter *rss =
					(struct igc_rss_filter *)flow->filter;
			rss->conf.key = rss->key;
			rss->conf.queue = rss->queue;
			ret = igc_add_rss_filter(dev, &filter.rss);
		}
		break;
	default:
		rte_flow_error_set(error, EINVAL,
				RTE_FLOW_ERROR_TYPE_NONE, NULL,
				"Flow can't be recognized");
		return NULL;
	}
	if (ret) {
		if (flow)
			rte_free(flow);
		rte_flow_error_set(error, -ret,
				RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
				"Failed to create flow.");
		return NULL;
	}
	igc_append_flow(IGC_DEV_PRIVATE_FLOW_LIST(dev), flow);
	return flow;
}
static struct rte_flow * igc_flow_create ( struct rte_eth_dev * dev , const struct rte_flow_attr * attr , const struct rte_flow_item patterns [ ] , const struct rte_flow_action actions [ ] , struct rte_flow_error * error ) { struct rte_flow * flow = NULL ; struct igc_all_filter filter ; int ret ; ret = igc_parse_flow ( dev , attr , patterns , actions , error , & filter ) ; if ( ret ) return NULL ; ret = - ENOMEM ; switch ( filter . mask ) { case IGC_FILTER_MASK_ETHER : flow = igc_alloc_flow ( & filter . ethertype , IGC_FILTER_TYPE_ETHERTYPE , sizeof ( filter . ethertype ) ) ; if ( flow ) ret = igc_add_ethertype_filter ( dev , & filter . ethertype ) ; break ; case IGC_FILTER_MASK_NTUPLE : if ( filter . ntuple . tuple_info . dst_port_mask == 0 && filter . ntuple . tuple_info . proto_mask == 0 ) { rte_flow_error_set ( error , EINVAL , RTE_FLOW_ERROR_TYPE_NONE , NULL , " " ) ; return NULL ; } flow = igc_alloc_flow ( & filter . ntuple , IGC_FILTER_TYPE_NTUPLE , sizeof ( filter . ntuple ) ) ; if ( flow ) ret = igc_add_ntuple_filter ( dev , & filter . ntuple ) ; break ; case IGC_FILTER_MASK_TCP_SYN : flow = igc_alloc_flow ( & filter . syn , IGC_FILTER_TYPE_SYN , sizeof ( filter . syn ) ) ; if ( flow ) ret = igc_set_syn_filter ( dev , & filter . syn ) ; break ; case IGC_FILTER_MASK_RSS : flow = igc_alloc_flow ( & filter . rss , IGC_FILTER_TYPE_HASH , sizeof ( filter . rss ) ) ; if ( flow ) { struct igc_rss_filter * rss = ( struct igc_rss_filter * ) flow -> filter ; rss -> conf . key = rss -> key ; rss -> conf . queue = rss -> queue ; ret = igc_add_rss_filter ( dev , & filter . rss ) ; } break ; default : rte_flow_error_set ( error , EINVAL , RTE_FLOW_ERROR_TYPE_NONE , NULL , " " ) ; return NULL ; } if ( ret ) { if ( flow ) rte_free ( flow ) ; rte_flow_error_set ( error , - ret , RTE_FLOW_ERROR_TYPE_HANDLE , NULL , " " ) ; return NULL ; } igc_append_flow ( IGC_DEV_PRIVATE_FLOW_LIST ( dev ) , flow ) ; return flow ; }
Create a flow rule.
Create a flow rule .
/* Check n-tuple filter is valid */ /* check and free the memory */ /* append the flow to the tail of the list */