src/dpdk/drivers/net/mvpp2/mrvl_flow.c
static struct rte_flow *
mrvl_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 mrvl_priv *priv = dev->data->dev_private;
	struct rte_flow *flow, *first;
	int ret;

	if (!dev->data->dev_started) {
		rte_flow_error_set(error, EINVAL,
				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
				   "Port must be started first\n");
		return NULL;
	}

	flow = rte_zmalloc_socket(NULL, sizeof(*flow), 0, rte_socket_id());
	if (!flow)
		return NULL;

	ret = mrvl_flow_parse(priv, attr, pattern, actions, flow, error);
	if (ret)
		goto out;

	/*
	 * Four cases here:
	 *
	 * 1. In case table does not exist - create one.
	 * 2. In case table exists, is empty and new flow cannot be added
	 *    recreate table.
	 * 3. In case table is not empty and new flow matches table format
	 *    add it.
	 * 4. Otherwise flow cannot be added.
	 */
	first = LIST_FIRST(&priv->flows);
	if (!priv->cls_tbl) {
		ret = mrvl_create_cls_table(dev, flow);
	} else if (!first && !mrvl_flow_can_be_added(priv, flow)) {
		ret = mrvl_create_cls_table(dev, flow);
	} else if (mrvl_flow_can_be_added(priv, flow)) {
		ret = 0;
	} else {
		rte_flow_error_set(error, EINVAL,
				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
				   "Pattern does not match cls table format\n");
		goto out;
	}

	if (ret) {
		rte_flow_error_set(error, EINVAL,
				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
				   "Failed to create cls table\n");
		goto out;
	}

	ret = pp2_cls_tbl_add_rule(priv->cls_tbl, &flow->rule, &flow->action);
	if (ret) {
		rte_flow_error_set(error, EINVAL,
				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
				   "Failed to add rule\n");
		goto out;
	}

	LIST_INSERT_HEAD(&priv->flows, flow, next);

	return flow;
out:
	rte_free(flow);
	return NULL;
}
/**
 * DPDK flow create callback called when flow is to be created.
 *
 * @param dev Pointer to the device.
 * @param attr Pointer to the flow attribute.
 * @param pattern Pointer to the flow pattern.
 * @param actions Pointer to the flow actions.
 * @param error Pointer to the flow error.
 * @returns Pointer to the created flow in case of success, NULL otherwise.
 */
DPDK flow create callback called when flow is to be created.
@param dev Pointer to the device.
@param attr Pointer to the flow attribute.
@param pattern Pointer to the flow pattern.
@param actions Pointer to the flow actions.
@param error Pointer to the flow error.
@returns Pointer to the created flow in case of success, NULL otherwise.
DPDK flow create callback called when flow is to be created . @param dev Pointer to the device . @param attr Pointer to the flow attribute . @param pattern Pointer to the flow pattern . @param actions Pointer to the flow actions . @param error Pointer to the flow error . @returns Pointer to the created flow in case of success NULL otherwise .
static struct rte_flow *
mrvl_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 mrvl_priv *priv = dev->data->dev_private;
	struct rte_flow *flow, *first;
	int ret;
	if (!dev->data->dev_started) {
		rte_flow_error_set(error, EINVAL,
				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
				   "Port must be started first\n");
		return NULL;
	}
	flow = rte_zmalloc_socket(NULL, sizeof(*flow), 0, rte_socket_id());
	if (!flow)
		return NULL;
	ret = mrvl_flow_parse(priv, attr, pattern, actions, flow, error);
	if (ret)
		goto out;
	first = LIST_FIRST(&priv->flows);
	if (!priv->cls_tbl) {
		ret = mrvl_create_cls_table(dev, flow);
	} else if (!first && !mrvl_flow_can_be_added(priv, flow)) {
		ret = mrvl_create_cls_table(dev, flow);
	} else if (mrvl_flow_can_be_added(priv, flow)) {
		ret = 0;
	} else {
		rte_flow_error_set(error, EINVAL,
				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
				   "Pattern does not match cls table format\n");
		goto out;
	}
	if (ret) {
		rte_flow_error_set(error, EINVAL,
				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
				   "Failed to create cls table\n");
		goto out;
	}
	ret = pp2_cls_tbl_add_rule(priv->cls_tbl, &flow->rule, &flow->action);
	if (ret) {
		rte_flow_error_set(error, EINVAL,
				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
				   "Failed to add rule\n");
		goto out;
	}
	LIST_INSERT_HEAD(&priv->flows, flow, next);
	return flow;
out:
	rte_free(flow);
	return NULL;
}
static struct rte_flow * mrvl_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 mrvl_priv * priv = dev -> data -> dev_private ; struct rte_flow * flow , * first ; int ret ; if ( ! dev -> data -> dev_started ) { rte_flow_error_set ( error , EINVAL , RTE_FLOW_ERROR_TYPE_UNSPECIFIED , NULL , " \n " ) ; return NULL ; } flow = rte_zmalloc_socket ( NULL , sizeof ( * flow ) , 0 , rte_socket_id ( ) ) ; if ( ! flow ) return NULL ; ret = mrvl_flow_parse ( priv , attr , pattern , actions , flow , error ) ; if ( ret ) goto out ; first = LIST_FIRST ( & priv -> flows ) ; if ( ! priv -> cls_tbl ) { ret = mrvl_create_cls_table ( dev , flow ) ; } else if ( ! first && ! mrvl_flow_can_be_added ( priv , flow ) ) { ret = mrvl_create_cls_table ( dev , flow ) ; } else if ( mrvl_flow_can_be_added ( priv , flow ) ) { ret = 0 ; } else { rte_flow_error_set ( error , EINVAL , RTE_FLOW_ERROR_TYPE_UNSPECIFIED , NULL , " \n " ) ; goto out ; } if ( ret ) { rte_flow_error_set ( error , EINVAL , RTE_FLOW_ERROR_TYPE_UNSPECIFIED , NULL , " \n " ) ; goto out ; } ret = pp2_cls_tbl_add_rule ( priv -> cls_tbl , & flow -> rule , & flow -> action ) ; if ( ret ) { rte_flow_error_set ( error , EINVAL , RTE_FLOW_ERROR_TYPE_UNSPECIFIED , NULL , " \n " ) ; goto out ; } LIST_INSERT_HEAD ( & priv -> flows , flow , next ) ; return flow ; out : rte_free ( flow ) ; return NULL ; }
DPDK flow create callback called when flow is to be created.
DPDK flow create callback called when flow is to be created .
/*
	 * Four cases here:
	 *
	 * 1. In case table does not exist - create one.
	 * 2. In case table exists, is empty and new flow cannot be added
	 *    recreate table.
	 * 3. In case table is not empty and new flow matches table format
	 *    add it.
	 * 4. Otherwise flow cannot be added.
	 */