[PATCH v1 1/5] net/cpfl: setup rte flow skeleton

Xing, Beilei beilei.xing at intel.com
Fri Aug 25 05:55:31 CEST 2023



> -----Original Message-----
> From: Zhang, Yuying <yuying.zhang at intel.com>
> Sent: Saturday, August 12, 2023 3:55 PM
> To: dev at dpdk.org; Xing, Beilei <beilei.xing at intel.com>; Zhang, Qi Z
> <qi.z.zhang at intel.com>; Wu, Jingjing <jingjing.wu at intel.com>
> Cc: Zhang, Yuying <yuying.zhang at intel.com>
> Subject: [PATCH v1 1/5] net/cpfl: setup rte flow skeleton
> 
> Setup the rte_flow backend skeleton. Introduce the framework to support
> different engines as rte_flow backend. Bridge rte_flow driver API to flow
> engines.
> 
> Signed-off-by: Yuying Zhang <yuying.zhang at intel.com>
> Signed-off-by: Qi Zhang <qi.z.zhang at intel.com>
> ---
>  drivers/net/cpfl/cpfl_ethdev.c |  54 ++++++
>  drivers/net/cpfl/cpfl_ethdev.h |   5 +
>  drivers/net/cpfl/cpfl_flow.c   | 331 +++++++++++++++++++++++++++++++++
>  drivers/net/cpfl/cpfl_flow.h   |  88 +++++++++
>  drivers/net/cpfl/meson.build   |   3 +-
>  5 files changed, 480 insertions(+), 1 deletion(-)  create mode 100644
> drivers/net/cpfl/cpfl_flow.c  create mode 100644 drivers/net/cpfl/cpfl_flow.h
> 
<...>
> 
> +static int
> +cpfl_dev_flow_ops_get(struct rte_eth_dev *dev,
> +		      const struct rte_flow_ops **ops) {
> +	struct cpfl_itf *itf;
> +
> +	if (!dev)
> +		return -EINVAL;
> +
> +	itf = CPFL_DEV_TO_ITF(dev);
> +
> +	/* only vport support rte_flow */
> +	if (itf->type != CPFL_ITF_TYPE_VPORT)
> +		return -ENOTSUP;

Do we need this check? Seems this function is only for vport but not representor.

> +#ifdef CPFL_FLOW_JSON_SUPPORT
> +	*ops = &cpfl_flow_ops;
> +#else
> +	*ops = NULL;
> +	PMD_DRV_LOG(NOTICE, "not support rte_flow, please install json-c
> +library."); #endif
> +	return 0;
> +}
> +
<...>
> +
> +static int
> +cpfl_flow_valid_attr(const struct rte_flow_attr *attr,
> +		     struct rte_flow_error *error)

Better to use cpfl_flow_attr_valid to align with cpfl_flow_param_valid.

> +{
> +	if (attr->priority > 6) {

What's 6's meaning? Better to define macro to describe it.

> +		rte_flow_error_set(error, EINVAL,
> +				   RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
> +				   attr, "Only support priority 0-6.");
> +		return -rte_errno;
> +	}
> +
> +	return 0;
> +}
> +
<...>
> +struct rte_flow *
> +cpfl_flow_create(struct rte_eth_dev *dev __rte_unused,
> +		 const struct rte_flow_attr *attr __rte_unused,
> +		 const struct rte_flow_item pattern[] __rte_unused,
> +		 const struct rte_flow_action actions[] __rte_unused,
> +		 struct rte_flow_error *error __rte_unused) {
> +	struct cpfl_itf *itf = CPFL_DEV_TO_ITF(dev);
> +	struct cpfl_flow_engine *engine;
> +	struct rte_flow *flow;
> +	void *meta;
> +	int ret;
> +
> +	flow = rte_malloc(NULL, sizeof(struct rte_flow), 0);
> +	if (!flow) {
> +		rte_flow_error_set(error, ENOMEM,
> +				   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
> +				   "Failed to allocate memory");
> +		return NULL;
> +	}
> +
> +	ret = cpfl_flow_param_valid(attr, pattern, actions, error);
> +	if (ret) {
> +		rte_free(flow);
> +		return NULL;
> +	}
> +
> +	engine = cpfl_flow_engine_match(dev, attr, pattern, actions, &meta);
> +	if (!engine) {
> +		rte_flow_error_set(error, ENOTSUP,
> RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
> +				   NULL, "No matched engine");
> +		rte_free(flow);
> +		return NULL;
> +	}

cpfl_flow_param_valid and cpfl_flow_engine_match can be replaced with cpfl_flow_validate function.

> +
> +	if (!engine->create) {
> +		rte_flow_error_set(error, ENOTSUP,
> RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
> +				   NULL, "No matched flow creation function");
> +		rte_free(flow);
> +		return NULL;
> +	}
> +
> +	ret = engine->create(dev, flow, meta, error);
> +	if (ret) {
> +		rte_free(flow);
> +		return NULL;
> +	}
> +
> +	flow->engine = engine;
> +	TAILQ_INSERT_TAIL(&itf->flow_list, flow, next);
> +
> +	return flow;
> +}
> +

<...>

> +
> +int
> +cpfl_flow_query(struct rte_eth_dev *dev __rte_unused,
> +		struct rte_flow *flow __rte_unused,
> +		const struct rte_flow_action *actions __rte_unused,
> +		void *data __rte_unused,
> +		struct rte_flow_error *error __rte_unused) {

Why is __rte_unused used here?

> +	struct rte_flow_query_count *count = data;
> +	int ret = -EINVAL;
> +
> +	if (!flow || !flow->engine || !flow->engine->query_count) {
> +		rte_flow_error_set(error, EINVAL,
> +				   RTE_FLOW_ERROR_TYPE_HANDLE,
> +				   NULL, "Invalid flow");
> +		return -rte_errno;
> +	}
> +
> +	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
> +		switch (actions->type) {
> +		case RTE_FLOW_ACTION_TYPE_VOID:
> +			break;
> +		case RTE_FLOW_ACTION_TYPE_COUNT:
> +			ret = flow->engine->query_count(dev, flow, count,
> error);
> +			break;
> +		default:
> +			ret = rte_flow_error_set(error, ENOTSUP,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> +						 actions,
> +						 "action not supported");
> +			break;
> +		}
> +	}
> +
> +	return ret;
> +}
> +

<...>
> +void cpfl_flow_engine_register(struct cpfl_flow_engine *engine);
> +
> +struct cpfl_flow_engine *
> +cpfl_flow_engine_match(struct rte_eth_dev *dev,
> +		       const struct rte_flow_attr *attr,
> +		       const struct rte_flow_item pattern[],
> +		       const struct rte_flow_action actions[],
> +		       void **meta);
> +int
> +cpfl_flow_engine_init(struct cpfl_adapter_ext *adapter); void
> +cpfl_flow_engine_uninit(struct cpfl_adapter_ext *adapter);
> +
> +int cpfl_flow_init(struct cpfl_adapter_ext *ad); void
> +cpfl_flow_uninit(struct cpfl_adapter_ext *ad); struct rte_flow
> +*cpfl_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);
> +int cpfl_flow_validate(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); int cpfl_flow_destroy(struct
> +rte_eth_dev *dev, struct rte_flow *flow, struct rte_flow_error *error);
> +int cpfl_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error
> +*error); int cpfl_flow_query(struct rte_eth_dev *dev,
> +		    struct rte_flow *flow,
> +		    const struct rte_flow_action *actions,
> +		    void *data,
> +		    struct rte_flow_error *error);

Please check all functions' declaration, no need new line.

> +#endif
> diff --git a/drivers/net/cpfl/meson.build b/drivers/net/cpfl/meson.build index
> 84ba994469..222497f7c2 100644
> --- a/drivers/net/cpfl/meson.build
> +++ b/drivers/net/cpfl/meson.build
> @@ -42,10 +42,11 @@ endif
>  js_dep = dependency('json-c', required: false, method : 'pkg-config')  if
> js_dep.found()
>      sources += files(
> +        'cpfl_flow.c',
>          'cpfl_flow_parser.c',
>          'cpfl_rules.c',
>          'cpfl_controlq.c',
>      )
>      dpdk_conf.set('CPFL_FLOW_JSON_SUPPORT', true)
>      ext_deps += js_dep
> -endif
> \ No newline at end of file
> +endif
> --
> 2.25.1



More information about the dev mailing list