[v4,05/86] net/ntnic: add minimal NT flow inline profile

Message ID 20241029164243.1648775-6-sil-plv@napatech.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series Provide flow filter API and statistics |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Serhii Iliushyk Oct. 29, 2024, 4:41 p.m. UTC
The flow profile implements a all flow related operations

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 drivers/net/ntnic/include/flow_api.h          | 15 +++++
 drivers/net/ntnic/meson.build                 |  1 +
 drivers/net/ntnic/nthw/flow_api/flow_api.c    | 28 +++++++-
 .../profile_inline/flow_api_profile_inline.c  | 65 +++++++++++++++++++
 .../profile_inline/flow_api_profile_inline.h  | 33 ++++++++++
 drivers/net/ntnic/ntnic_mod_reg.c             | 12 +++-
 drivers/net/ntnic/ntnic_mod_reg.h             | 23 +++++++
 7 files changed, 174 insertions(+), 3 deletions(-)
 create mode 100644 drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
 create mode 100644 drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
  

Comments

Ferruh Yigit Oct. 30, 2024, 1:56 a.m. UTC | #1
On 10/29/2024 4:41 PM, Serhii Iliushyk wrote:
> The flow profile implements a all flow related operations
> 

Can you please give some more details about the profiles, and "inline
profile" mentioned?

> Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
> ---
>  drivers/net/ntnic/include/flow_api.h          | 15 +++++
>  drivers/net/ntnic/meson.build                 |  1 +
>  drivers/net/ntnic/nthw/flow_api/flow_api.c    | 28 +++++++-
>  .../profile_inline/flow_api_profile_inline.c  | 65 +++++++++++++++++++
>  .../profile_inline/flow_api_profile_inline.h  | 33 ++++++++++
>  drivers/net/ntnic/ntnic_mod_reg.c             | 12 +++-
>  drivers/net/ntnic/ntnic_mod_reg.h             | 23 +++++++
>  7 files changed, 174 insertions(+), 3 deletions(-)
>  create mode 100644 drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
>  create mode 100644 drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
> 
> diff --git a/drivers/net/ntnic/include/flow_api.h b/drivers/net/ntnic/include/flow_api.h
> index c80906ec50..3bdfdd4f94 100644
> --- a/drivers/net/ntnic/include/flow_api.h
> +++ b/drivers/net/ntnic/include/flow_api.h
> @@ -74,6 +74,21 @@ struct flow_nic_dev {
>  	struct flow_nic_dev *next;
>  };
>  
> +enum flow_nic_err_msg_e {
> +	ERR_SUCCESS = 0,
> +	ERR_FAILED = 1,
> +	ERR_OUTPUT_TOO_MANY = 3,
> +	ERR_MATCH_INVALID_OR_UNSUPPORTED_ELEM = 12,
> +	ERR_MATCH_RESOURCE_EXHAUSTION = 14,
> +	ERR_ACTION_UNSUPPORTED = 28,
> +	ERR_REMOVE_FLOW_FAILED = 29,
> +	ERR_OUTPUT_INVALID = 33,
> +	ERR_ACTION_MULTIPLE_PORT_ID_UNSUPPORTED = 40,
> +	ERR_MSG_NO_MSG
> +};
> +
> +void flow_nic_set_error(enum flow_nic_err_msg_e msg, struct rte_flow_error *error);
> +
>  /*
>   * Resources
>   */
> diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build
> index d272c73c62..f5605e81cb 100644
> --- a/drivers/net/ntnic/meson.build
> +++ b/drivers/net/ntnic/meson.build
> @@ -47,6 +47,7 @@ sources = files(
>          'nthw/core/nthw_sdc.c',
>          'nthw/core/nthw_si5340.c',
>          'nthw/flow_api/flow_api.c',
> +        'nthw/flow_api/profile_inline/flow_api_profile_inline.c',
>          'nthw/flow_api/flow_backend/flow_backend.c',
>          'nthw/flow_api/flow_filter.c',
>          'nthw/flow_api/flow_kcc.c',
> diff --git a/drivers/net/ntnic/nthw/flow_api/flow_api.c b/drivers/net/ntnic/nthw/flow_api/flow_api.c
> index d779dc481f..d0dad8e8f8 100644
> --- a/drivers/net/ntnic/nthw/flow_api/flow_api.c
> +++ b/drivers/net/ntnic/nthw/flow_api/flow_api.c
> @@ -36,6 +36,29 @@ const char *dbg_res_descr[] = {
>  static struct flow_nic_dev *dev_base;
>  static pthread_mutex_t base_mtx = PTHREAD_MUTEX_INITIALIZER;
>  
> +/*
> + * Error handling
> + */
> +
> +static const struct {
> +	const char *message;
> +} err_msg[] = {
> +	/* 00 */ { "Operation successfully completed" },
> +	/* 01 */ { "Operation failed" },
> +	/* 29 */ { "Removing flow failed" },
> +};
> +
> +void flow_nic_set_error(enum flow_nic_err_msg_e msg, struct rte_flow_error *error)
> +{
> +	assert(msg < ERR_MSG_NO_MSG);
> +
> +	if (error) {
> +		error->message = err_msg[msg].message;
> +		error->type = (msg == ERR_SUCCESS) ? RTE_FLOW_ERROR_TYPE_NONE :
> +			RTE_FLOW_ERROR_TYPE_UNSPECIFIED;
> +	}
> +}
> +
>  /*
>   * Resources
>   */
> @@ -136,7 +159,8 @@ static struct flow_handle *flow_create(struct flow_eth_dev *dev __rte_unused,
>  		return NULL;
>  	}
>  
> -	return NULL;
> +	return profile_inline_ops->flow_create_profile_inline(dev, attr,
> +		forced_vlan_vid, caller_id,  item, action, error);
>  }
>  
>  static int flow_destroy(struct flow_eth_dev *dev __rte_unused,
> @@ -149,7 +173,7 @@ static int flow_destroy(struct flow_eth_dev *dev __rte_unused,
>  		return -1;
>  	}
>  
> -	return -1;
> +	return profile_inline_ops->flow_destroy_profile_inline(dev, flow, error);
>  }
>  
>  /*
> diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
> new file mode 100644
> index 0000000000..a6293f5f82
> --- /dev/null
> +++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
> @@ -0,0 +1,65 @@
> +/*
> + * SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2023 Napatech A/S
> + */
> +
> +#include "ntlog.h"
> +
> +#include "flow_api_profile_inline.h"
> +#include "ntnic_mod_reg.h"
> +
> +struct flow_handle *flow_create_profile_inline(struct flow_eth_dev *dev,
> +	const struct rte_flow_attr *attr,
> +	uint16_t forced_vlan_vid,
> +	uint16_t caller_id,
> +	const struct rte_flow_item elem[],
> +	const struct rte_flow_action action[],
> +	struct rte_flow_error *error)
> +{
> +	return NULL;
> +}
> +
> +int flow_destroy_locked_profile_inline(struct flow_eth_dev *dev,
> +	struct flow_handle *fh,
> +	struct rte_flow_error *error)
> +{
> +	assert(dev);
> +	assert(fh);
> +
> +	int err = 0;
> +
> +	flow_nic_set_error(ERR_SUCCESS, error);
> +
> +	return err;
> +}
> +
> +int flow_destroy_profile_inline(struct flow_eth_dev *dev, struct flow_handle *flow,
> +	struct rte_flow_error *error)
> +{
> +	int err = 0;
> +
> +	flow_nic_set_error(ERR_SUCCESS, error);
> +
> +	if (flow) {
> +		/* Delete this flow */
> +		pthread_mutex_lock(&dev->ndev->mtx);
> +		err = flow_destroy_locked_profile_inline(dev, flow, error);
> +		pthread_mutex_unlock(&dev->ndev->mtx);
> +	}
> +
> +	return err;
> +}
> +
> +static const struct profile_inline_ops ops = {
> +	/*
> +	 * Flow functionality
> +	 */
> +	.flow_destroy_locked_profile_inline = flow_destroy_locked_profile_inline,
> +	.flow_create_profile_inline = flow_create_profile_inline,
> +	.flow_destroy_profile_inline = flow_destroy_profile_inline,
> +};
> +
> +void profile_inline_init(void)
> +{
> +	register_profile_inline_ops(&ops);
> +}
> diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
> new file mode 100644
> index 0000000000..a83cc299b4
> --- /dev/null
> +++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
> @@ -0,0 +1,33 @@
> +/*
> + * SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2023 Napatech A/S
> + */
> +
> +#ifndef _FLOW_API_PROFILE_INLINE_H_
> +#define _FLOW_API_PROFILE_INLINE_H_
> +
> +#include <stdint.h>
> +
> +#include "flow_api.h"
> +#include "stream_binary_flow_api.h"
> +
> +/*
> + * Flow functionality
> + */
> +int flow_destroy_locked_profile_inline(struct flow_eth_dev *dev,
> +	struct flow_handle *fh,
> +	struct rte_flow_error *error);
> +
> +struct flow_handle *flow_create_profile_inline(struct flow_eth_dev *dev,
> +	const struct rte_flow_attr *attr,
> +	uint16_t forced_vlan_vid,
> +	uint16_t caller_id,
> +	const struct rte_flow_item elem[],
> +	const struct rte_flow_action action[],
> +	struct rte_flow_error *error);
> +
> +int flow_destroy_profile_inline(struct flow_eth_dev *dev,
> +	struct flow_handle *flow,
> +	struct rte_flow_error *error);
> +
> +#endif	/* _FLOW_API_PROFILE_INLINE_H_ */
> diff --git a/drivers/net/ntnic/ntnic_mod_reg.c b/drivers/net/ntnic/ntnic_mod_reg.c
> index ad2266116f..593b56bf5b 100644
> --- a/drivers/net/ntnic/ntnic_mod_reg.c
> +++ b/drivers/net/ntnic/ntnic_mod_reg.c
> @@ -118,9 +118,19 @@ const struct flow_backend_ops *get_flow_backend_ops(void)
>  	return flow_backend_ops;
>  }
>  
> +static const struct profile_inline_ops *profile_inline_ops;
> +
> +void register_profile_inline_ops(const struct profile_inline_ops *ops)
> +{
> +	profile_inline_ops = ops;
> +}
> +
>  const struct profile_inline_ops *get_profile_inline_ops(void)
>  {
> -	return NULL;
> +	if (profile_inline_ops == NULL)
> +		profile_inline_init();
> +
> +	return profile_inline_ops;
>  }
>  
>  static const struct flow_filter_ops *flow_filter_ops;
> diff --git a/drivers/net/ntnic/ntnic_mod_reg.h b/drivers/net/ntnic/ntnic_mod_reg.h
> index ec8c1612d1..d133336fad 100644
> --- a/drivers/net/ntnic/ntnic_mod_reg.h
> +++ b/drivers/net/ntnic/ntnic_mod_reg.h
> @@ -225,7 +225,30 @@ void register_flow_backend_ops(const struct flow_backend_ops *ops);
>  const struct flow_backend_ops *get_flow_backend_ops(void);
>  void flow_backend_init(void);
>  
> +struct profile_inline_ops {
> +	/*
> +	 * Flow functionality
> +	 */
> +	int (*flow_destroy_locked_profile_inline)(struct flow_eth_dev *dev,
> +		struct flow_handle *fh,
> +		struct rte_flow_error *error);
> +
> +	struct flow_handle *(*flow_create_profile_inline)(struct flow_eth_dev *dev,
> +		const struct rte_flow_attr *attr,
> +		uint16_t forced_vlan_vid,
> +		uint16_t caller_id,
> +		const struct rte_flow_item elem[],
> +		const struct rte_flow_action action[],
> +		struct rte_flow_error *error);
> +
> +	int (*flow_destroy_profile_inline)(struct flow_eth_dev *dev,
> +		struct flow_handle *flow,
> +		struct rte_flow_error *error);
> +};
> +
> +void register_profile_inline_ops(const struct profile_inline_ops *ops);
>  const struct profile_inline_ops *get_profile_inline_ops(void);
> +void profile_inline_init(void);
>  
>  struct flow_filter_ops {
>  	int (*flow_filter_init)(nthw_fpga_t *p_fpga, struct flow_nic_dev **p_flow_device,
  
Serhii Iliushyk Oct. 30, 2024, 9:08 p.m. UTC | #2
>On 30.10.2024, 03:56, "Ferruh Yigit" wrote:
>
>On 10/29/2024 4:41 PM, Serhii Iliushyk wrote:
>> The flow profile implements a all flow related operations
>> 
>
>
>Can you please give some more details about the profiles, and "inline
>profile" mentioned?
>
>
>> Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com <mailto:sil-plv@napatech.com>>
>> ---
>> drivers/net/ntnic/include/flow_api.h | 15 +++++
>> drivers/net/ntnic/https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fmeson.build&c=E,1,3-LUdenxfqOoBy-HbMvK5R_o9qtMZZNE0F19ALnszQbAj5cUU-GdmZiycNh09BY4nVE_Qlw-Pr13vddTJpmb_0oBZCfzAMcNRtVlIfRA&typo=1 <https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fmeson.build&amp;c=E,1,3-LUdenxfqOoBy-HbMvK5R_o9qtMZZNE0F19ALnszQbAj5cUU-GdmZiycNh09BY4nVE_Qlw-Pr13vddTJpmb_0oBZCfzAMcNRtVlIfRA&amp;typo=1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;> | 1 +
>> drivers/net/ntnic/nthw/flow_api/flow_api.c | 28 +++++++-
>> .../profile_inline/flow_api_profile_inline.c | 65 +++++++++++++++++++
>> .../profile_inline/flow_api_profile_inline.h | 33 ++++++++++
>> drivers/net/ntnic/ntnic_mod_reg.c | 12 +++-
>> drivers/net/ntnic/ntnic_mod_reg.h | 23 +++++++
>> 7 files changed, 174 insertions(+), 3 deletions(-)
>> create mode 100644 drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
>> create mode 100644 drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
>> 
>> diff --git a/drivers/net/ntnic/include/flow_api.h b/drivers/net/ntnic/include/flow_api.h
>> index c80906ec50..3bdfdd4f94 100644
>> --- a/drivers/net/ntnic/include/flow_api.h
>> +++ b/drivers/net/ntnic/include/flow_api.h
>> @@ -74,6 +74,21 @@ struct flow_nic_dev {
>> struct flow_nic_dev *next;
>> };
>> 
>> +enum flow_nic_err_msg_e {
>> + ERR_SUCCESS = 0,
>> + ERR_FAILED = 1,
>> + ERR_OUTPUT_TOO_MANY = 3,
>> + ERR_MATCH_INVALID_OR_UNSUPPORTED_ELEM = 12,
>> + ERR_MATCH_RESOURCE_EXHAUSTION = 14,
>> + ERR_ACTION_UNSUPPORTED = 28,
>> + ERR_REMOVE_FLOW_FAILED = 29,
>> + ERR_OUTPUT_INVALID = 33,
>> + ERR_ACTION_MULTIPLE_PORT_ID_UNSUPPORTED = 40,
>> + ERR_MSG_NO_MSG
>> +};
>> +
>> +void flow_nic_set_error(enum flow_nic_err_msg_e msg, struct rte_flow_error *error);
>> +
>> /*
>> * Resources
>> */
>> diff --git a/drivers/net/ntnic/https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fmeson.build&c=E,1,JkeJQE_rpALNHr8SqBaVRLlDDbEL5EdOBXNqajuwseGrtrDcbtJEThEZxS8SOYA81WEBENa4Y3YVoU0q_IAzScErc1y1KOeKOG99MB9Xfls_jQyJnQ,,&typo=1 <https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fmeson.build&amp;c=E,1,JkeJQE_rpALNHr8SqBaVRLlDDbEL5EdOBXNqajuwseGrtrDcbtJEThEZxS8SOYA81WEBENa4Y3YVoU0q_IAzScErc1y1KOeKOG99MB9Xfls_jQyJnQ,,&amp;typo=1> b/drivers/net/ntnic/https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fmeson.build&c=E,1,0M6paR3-EwN18O8adbL-tbzs-1s_8MHatakMugSL_h3LzyBrM9gdLleDiJDSh-akPcT9y4YbgcIw_odTVAvhaO6sFcomFQaVYHdXdzYM5vJHpbdY&typo=1 <https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fmeson.build&amp;c=E,1,0M6paR3-EwN18O8adbL-tbzs-1s_8MHatakMugSL_h3LzyBrM9gdLleDiJDSh-akPcT9y4YbgcIw_odTVAvhaO6sFcomFQaVYHdXdzYM5vJHpbdY&amp;typo=1>
>> index d272c73c62..f5605e81cb 100644
>> --- a/drivers/net/ntnic/https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fmeson.build&c=E,1,A4iLxNwVi_0mKCG6VrkXqjF93-MHs6mtooOFwRaFDaHTcSDkkK6guLOt1nG5JZNlJjv7l6PvxOokDrUSTYNSixtC8VdSvOP5Ze1-Epx52R3YyVQ0et9K6w,,&typo=1 <https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fmeson.build&amp;c=E,1,A4iLxNwVi_0mKCG6VrkXqjF93-MHs6mtooOFwRaFDaHTcSDkkK6guLOt1nG5JZNlJjv7l6PvxOokDrUSTYNSixtC8VdSvOP5Ze1-Epx52R3YyVQ0et9K6w,,&amp;typo=1>
>> +++ b/drivers/net/ntnic/https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fmeson.build&c=E,1,VgoRksF64gHnqsTKesLw3bGf08ELIO9hZPpjBLt-omKH3u6vgrZl_u-Ww9dNMHJbawVJsQ0h6eYuZqQtne7BN6_EQDXfZN___5w0U_xS67C9YF59&typo=1 <https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fmeson.build&amp;c=E,1,VgoRksF64gHnqsTKesLw3bGf08ELIO9hZPpjBLt-omKH3u6vgrZl_u-Ww9dNMHJbawVJsQ0h6eYuZqQtne7BN6_EQDXfZN___5w0U_xS67C9YF59&amp;typo=1>
>> @@ -47,6 +47,7 @@ sources = files(
>> 'nthw/core/nthw_sdc.c',
>> 'nthw/core/nthw_si5340.c',
>> 'nthw/flow_api/flow_api.c',
>> + 'nthw/flow_api/profile_inline/flow_api_profile_inline.c',
>> 'nthw/flow_api/flow_backend/flow_backend.c',
>> 'nthw/flow_api/flow_filter.c',
>> 'nthw/flow_api/flow_kcc.c',
>> diff --git a/drivers/net/ntnic/nthw/flow_api/flow_api.c b/drivers/net/ntnic/nthw/flow_api/flow_api.c
>> index d779dc481f..d0dad8e8f8 100644
>> --- a/drivers/net/ntnic/nthw/flow_api/flow_api.c
>> +++ b/drivers/net/ntnic/nthw/flow_api/flow_api.c
>> @@ -36,6 +36,29 @@ const char *dbg_res_descr[] = {
>> static struct flow_nic_dev *dev_base;
>> static pthread_mutex_t base_mtx = PTHREAD_MUTEX_INITIALIZER;
>> 
>> +/*
>> + * Error handling
>> + */
>> +
>> +static const struct {
>> + const char *message;
>> +} err_msg[] = {
>> + /* 00 */ { "Operation successfully completed" },
>> + /* 01 */ { "Operation failed" },
>> + /* 29 */ { "Removing flow failed" },
>> +};
>> +
>> +void flow_nic_set_error(enum flow_nic_err_msg_e msg, struct rte_flow_error *error)
>> +{
>> + assert(msg < ERR_MSG_NO_MSG);
>> +
>> + if (error) {
>> + error->message = err_msg[msg].message;
>> + error->type = (msg == ERR_SUCCESS) ? RTE_FLOW_ERROR_TYPE_NONE :
>> + RTE_FLOW_ERROR_TYPE_UNSPECIFIED;
>> + }
>> +}
>> +
>> /*
>> * Resources
>> */
>> @@ -136,7 +159,8 @@ static struct flow_handle *flow_create(struct flow_eth_dev *dev __rte_unused,
>> return NULL;
>> }
>> 
>> - return NULL;
>> + return profile_inline_ops->flow_create_profile_inline(dev, attr,
>> + forced_vlan_vid, caller_id, item, action, error);
>> }
>> 
>> static int flow_destroy(struct flow_eth_dev *dev __rte_unused,
>> @@ -149,7 +173,7 @@ static int flow_destroy(struct flow_eth_dev *dev __rte_unused,
>> return -1;
>> }
>> 
>> - return -1;
>> + return profile_inline_ops->flow_destroy_profile_inline(dev, flow, error);
>> }
>> 
>> /*
>> diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
>> new file mode 100644
>> index 0000000000..a6293f5f82
>> --- /dev/null
>> +++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
>> @@ -0,0 +1,65 @@
>> +/*
>> + * SPDX-License-Identifier: BSD-3-Clause
>> + * Copyright(c) 2023 Napatech A/S
>> + */
>> +
>> +#include "ntlog.h"
>> +
>> +#include "flow_api_profile_inline.h"
>> +#include "ntnic_mod_reg.h"
>> +
>> +struct flow_handle *flow_create_profile_inline(struct flow_eth_dev *dev,
>> + const struct rte_flow_attr *attr,
>> + uint16_t forced_vlan_vid,
>> + uint16_t caller_id,
>> + const struct rte_flow_item elem[],
>> + const struct rte_flow_action action[],
>> + struct rte_flow_error *error)
>> +{
>> + return NULL;
>> +}
>> +
>> +int flow_destroy_locked_profile_inline(struct flow_eth_dev *dev,
>> + struct flow_handle *fh,
>> + struct rte_flow_error *error)
>> +{
>> + assert(dev);
>> + assert(fh);
>> +
>> + int err = 0;
>> +
>> + flow_nic_set_error(ERR_SUCCESS, error);
>> +
>> + return err;
>> +}
>> +
>> +int flow_destroy_profile_inline(struct flow_eth_dev *dev, struct flow_handle *flow,
>> + struct rte_flow_error *error)
>> +{
>> + int err = 0;
>> +
>> + flow_nic_set_error(ERR_SUCCESS, error);
>> +
>> + if (flow) {
>> + /* Delete this flow */
>> + pthread_mutex_lock(&dev->ndev->mtx);
>> + err = flow_destroy_locked_profile_inline(dev, flow, error);
>> + pthread_mutex_unlock(&dev->ndev->mtx);
>> + }
>> +
>> + return err;
>> +}
>> +
>> +static const struct profile_inline_ops ops = {
>> + /*
>> + * Flow functionality
>> + */
>> + .flow_destroy_locked_profile_inline = flow_destroy_locked_profile_inline,
>> + .flow_create_profile_inline = flow_create_profile_inline,
>> + .flow_destroy_profile_inline = flow_destroy_profile_inline,
>> +};
>> +
>> +void profile_inline_init(void)
>> +{
>> + register_profile_inline_ops(&ops);
>> +}
>> diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
>> new file mode 100644
>> index 0000000000..a83cc299b4
>> --- /dev/null
>> +++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
>> @@ -0,0 +1,33 @@
>> +/*
>> + * SPDX-License-Identifier: BSD-3-Clause
>> + * Copyright(c) 2023 Napatech A/S
>> + */
>> +
>> +#ifndef _FLOW_API_PROFILE_INLINE_H_
>> +#define _FLOW_API_PROFILE_INLINE_H_
>> +
>> +#include <stdint.h>
>> +
>> +#include "flow_api.h"
>> +#include "stream_binary_flow_api.h"
>> +
>> +/*
>> + * Flow functionality
>> + */
>> +int flow_destroy_locked_profile_inline(struct flow_eth_dev *dev,
>> + struct flow_handle *fh,
>> + struct rte_flow_error *error);
>> +
>> +struct flow_handle *flow_create_profile_inline(struct flow_eth_dev *dev,
>> + const struct rte_flow_attr *attr,
>> + uint16_t forced_vlan_vid,
>> + uint16_t caller_id,
>> + const struct rte_flow_item elem[],
>> + const struct rte_flow_action action[],
>> + struct rte_flow_error *error);
>> +
>> +int flow_destroy_profile_inline(struct flow_eth_dev *dev,
>> + struct flow_handle *flow,
>> + struct rte_flow_error *error);
>> +
>> +#endif /* _FLOW_API_PROFILE_INLINE_H_ */
>> diff --git a/drivers/net/ntnic/ntnic_mod_reg.c b/drivers/net/ntnic/ntnic_mod_reg.c
>> index ad2266116f..593b56bf5b 100644
>> --- a/drivers/net/ntnic/ntnic_mod_reg.c
>> +++ b/drivers/net/ntnic/ntnic_mod_reg.c
>> @@ -118,9 +118,19 @@ const struct flow_backend_ops *get_flow_backend_ops(void)
>> return flow_backend_ops;
>> }
>> 
>> +static const struct profile_inline_ops *profile_inline_ops;
>> +
>> +void register_profile_inline_ops(const struct profile_inline_ops *ops)
>> +{
>> + profile_inline_ops = ops;
>> +}
>> +
>> const struct profile_inline_ops *get_profile_inline_ops(void)
>> {
>> - return NULL;
>> + if (profile_inline_ops == NULL)
>> + profile_inline_init();
>> +
>> + return profile_inline_ops;
>> }
>> 
>> static const struct flow_filter_ops *flow_filter_ops;
>> diff --git a/drivers/net/ntnic/ntnic_mod_reg.h b/drivers/net/ntnic/ntnic_mod_reg.h
>> index ec8c1612d1..d133336fad 100644
>> --- a/drivers/net/ntnic/ntnic_mod_reg.h
>> +++ b/drivers/net/ntnic/ntnic_mod_reg.h
>> @@ -225,7 +225,30 @@ void register_flow_backend_ops(const struct flow_backend_ops *ops);
>> const struct flow_backend_ops *get_flow_backend_ops(void);
>> void flow_backend_init(void);
>> 
>> +struct profile_inline_ops {
>> + /*
>> + * Flow functionality
>> + */
>> + int (*flow_destroy_locked_profile_inline)(struct flow_eth_dev *dev,
>> + struct flow_handle *fh,
>> + struct rte_flow_error *error);
>> +
>> + struct flow_handle *(*flow_create_profile_inline)(struct flow_eth_dev *dev,
>> + const struct rte_flow_attr *attr,
>> + uint16_t forced_vlan_vid,
>> + uint16_t caller_id,
>> + const struct rte_flow_item elem[],
>> + const struct rte_flow_action action[],
>> + struct rte_flow_error *error);
>> +
>> + int (*flow_destroy_profile_inline)(struct flow_eth_dev *dev,
>> + struct flow_handle *flow,
>> + struct rte_flow_error *error);
>> +};
>> +
>> +void register_profile_inline_ops(const struct profile_inline_ops *ops);
>> const struct profile_inline_ops *get_profile_inline_ops(void);
>> +void profile_inline_init(void);
>> 
>> struct flow_filter_ops {
>> int (*flow_filter_init)(nthw_fpga_t *p_fpga, struct flow_nic_dev **p_flow_device,
>

Hi Ferruh

Please find below the description of NT FPGA profiles.

The Napatech adapters support more different functionality than can fit into a single FPGA.
This functionality is grouped into a number of profiles called inline, capture, vswitch, and basic.
The adapter support we aim to upstream this time around, is for the inline profile.
The code contains some of the structures and enums needed to add other profiles,
mainly for future compatibility, and for compatibility with our legacy code base.

Here is a short description of each profile:
Inline: Uses a scatter gather packet system, which is quite fast and lightweight.
The FPGA contains functionality for hardware offload use-cases, such as stateful flow matching,
encap/decap, packet steering etc.
vSwitch: Also uses the scatter gather system. The FPGA features are selected to support
the functionality of OVS.
Capture: Uses Napatech’s proprietary packet buffer system,
which requires a lot of space on the FPGA, but is extremely fast, guarantees zero packet loss,
and zero copy packet handling on the host cpu.
Basic: The same feature set as one might expect from a basic nic.
Mostly used in Kubernetes containers to reduce complexity.
  
Ferruh Yigit Oct. 31, 2024, 1:05 a.m. UTC | #3
On 10/30/2024 9:08 PM, Serhii Iliushyk wrote:
>> On 30.10.2024, 03:56, "Ferruh Yigit" wrote:
>>
>> On 10/29/2024 4:41 PM, Serhii Iliushyk wrote:
>>> The flow profile implements a all flow related operations
>>>
>>
>>
>> Can you please give some more details about the profiles, and "inline
>> profile" mentioned?
>>
>>
>>> Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com <mailto:sil-plv@napatech.com>>
>>> ---
>>> drivers/net/ntnic/include/flow_api.h | 15 +++++
>>> drivers/net/ntnic/https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fmeson.build&c=E,1,3-LUdenxfqOoBy-HbMvK5R_o9qtMZZNE0F19ALnszQbAj5cUU-GdmZiycNh09BY4nVE_Qlw-Pr13vddTJpmb_0oBZCfzAMcNRtVlIfRA&typo=1 <https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fmeson.build&amp;c=E,1,3-LUdenxfqOoBy-HbMvK5R_o9qtMZZNE0F19ALnszQbAj5cUU-GdmZiycNh09BY4nVE_Qlw-Pr13vddTJpmb_0oBZCfzAMcNRtVlIfRA&amp;typo=1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;> | 1 +
>>> drivers/net/ntnic/nthw/flow_api/flow_api.c | 28 +++++++-
>>> .../profile_inline/flow_api_profile_inline.c | 65 +++++++++++++++++++
>>> .../profile_inline/flow_api_profile_inline.h | 33 ++++++++++
>>> drivers/net/ntnic/ntnic_mod_reg.c | 12 +++-
>>> drivers/net/ntnic/ntnic_mod_reg.h | 23 +++++++
>>> 7 files changed, 174 insertions(+), 3 deletions(-)
>>> create mode 100644 drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
>>> create mode 100644 drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
>>>
>>> diff --git a/drivers/net/ntnic/include/flow_api.h b/drivers/net/ntnic/include/flow_api.h
>>> index c80906ec50..3bdfdd4f94 100644
>>> --- a/drivers/net/ntnic/include/flow_api.h
>>> +++ b/drivers/net/ntnic/include/flow_api.h
>>> @@ -74,6 +74,21 @@ struct flow_nic_dev {
>>> struct flow_nic_dev *next;
>>> };
>>>
>>> +enum flow_nic_err_msg_e {
>>> + ERR_SUCCESS = 0,
>>> + ERR_FAILED = 1,
>>> + ERR_OUTPUT_TOO_MANY = 3,
>>> + ERR_MATCH_INVALID_OR_UNSUPPORTED_ELEM = 12,
>>> + ERR_MATCH_RESOURCE_EXHAUSTION = 14,
>>> + ERR_ACTION_UNSUPPORTED = 28,
>>> + ERR_REMOVE_FLOW_FAILED = 29,
>>> + ERR_OUTPUT_INVALID = 33,
>>> + ERR_ACTION_MULTIPLE_PORT_ID_UNSUPPORTED = 40,
>>> + ERR_MSG_NO_MSG
>>> +};
>>> +
>>> +void flow_nic_set_error(enum flow_nic_err_msg_e msg, struct rte_flow_error *error);
>>> +
>>> /*
>>> * Resources
>>> */
>>> diff --git a/drivers/net/ntnic/https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fmeson.build&c=E,1,JkeJQE_rpALNHr8SqBaVRLlDDbEL5EdOBXNqajuwseGrtrDcbtJEThEZxS8SOYA81WEBENa4Y3YVoU0q_IAzScErc1y1KOeKOG99MB9Xfls_jQyJnQ,,&typo=1 <https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fmeson.build&amp;c=E,1,JkeJQE_rpALNHr8SqBaVRLlDDbEL5EdOBXNqajuwseGrtrDcbtJEThEZxS8SOYA81WEBENa4Y3YVoU0q_IAzScErc1y1KOeKOG99MB9Xfls_jQyJnQ,,&amp;typo=1> b/drivers/net/ntnic/https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fmeson.build&c=E,1,0M6paR3-EwN18O8adbL-tbzs-1s_8MHatakMugSL_h3LzyBrM9gdLleDiJDSh-akPcT9y4YbgcIw_odTVAvhaO6sFcomFQaVYHdXdzYM5vJHpbdY&typo=1 <https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fmeson.build&amp;c=E,1,0M6paR3-EwN18O8adbL-tbzs-1s_8MHatakMugSL_h3LzyBrM9gdLleDiJDSh-akPcT9y4YbgcIw_odTVAvhaO6sFcomFQaVYHdXdzYM5vJHpbdY&amp;typo=1>
>>> index d272c73c62..f5605e81cb 100644
>>> --- a/drivers/net/ntnic/https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fmeson.build&c=E,1,A4iLxNwVi_0mKCG6VrkXqjF93-MHs6mtooOFwRaFDaHTcSDkkK6guLOt1nG5JZNlJjv7l6PvxOokDrUSTYNSixtC8VdSvOP5Ze1-Epx52R3YyVQ0et9K6w,,&typo=1 <https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fmeson.build&amp;c=E,1,A4iLxNwVi_0mKCG6VrkXqjF93-MHs6mtooOFwRaFDaHTcSDkkK6guLOt1nG5JZNlJjv7l6PvxOokDrUSTYNSixtC8VdSvOP5Ze1-Epx52R3YyVQ0et9K6w,,&amp;typo=1>
>>> +++ b/drivers/net/ntnic/https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fmeson.build&c=E,1,VgoRksF64gHnqsTKesLw3bGf08ELIO9hZPpjBLt-omKH3u6vgrZl_u-Ww9dNMHJbawVJsQ0h6eYuZqQtne7BN6_EQDXfZN___5w0U_xS67C9YF59&typo=1 <https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fmeson.build&amp;c=E,1,VgoRksF64gHnqsTKesLw3bGf08ELIO9hZPpjBLt-omKH3u6vgrZl_u-Ww9dNMHJbawVJsQ0h6eYuZqQtne7BN6_EQDXfZN___5w0U_xS67C9YF59&amp;typo=1>
>>> @@ -47,6 +47,7 @@ sources = files(
>>> 'nthw/core/nthw_sdc.c',
>>> 'nthw/core/nthw_si5340.c',
>>> 'nthw/flow_api/flow_api.c',
>>> + 'nthw/flow_api/profile_inline/flow_api_profile_inline.c',
>>> 'nthw/flow_api/flow_backend/flow_backend.c',
>>> 'nthw/flow_api/flow_filter.c',
>>> 'nthw/flow_api/flow_kcc.c',
>>> diff --git a/drivers/net/ntnic/nthw/flow_api/flow_api.c b/drivers/net/ntnic/nthw/flow_api/flow_api.c
>>> index d779dc481f..d0dad8e8f8 100644
>>> --- a/drivers/net/ntnic/nthw/flow_api/flow_api.c
>>> +++ b/drivers/net/ntnic/nthw/flow_api/flow_api.c
>>> @@ -36,6 +36,29 @@ const char *dbg_res_descr[] = {
>>> static struct flow_nic_dev *dev_base;
>>> static pthread_mutex_t base_mtx = PTHREAD_MUTEX_INITIALIZER;
>>>
>>> +/*
>>> + * Error handling
>>> + */
>>> +
>>> +static const struct {
>>> + const char *message;
>>> +} err_msg[] = {
>>> + /* 00 */ { "Operation successfully completed" },
>>> + /* 01 */ { "Operation failed" },
>>> + /* 29 */ { "Removing flow failed" },
>>> +};
>>> +
>>> +void flow_nic_set_error(enum flow_nic_err_msg_e msg, struct rte_flow_error *error)
>>> +{
>>> + assert(msg < ERR_MSG_NO_MSG);
>>> +
>>> + if (error) {
>>> + error->message = err_msg[msg].message;
>>> + error->type = (msg == ERR_SUCCESS) ? RTE_FLOW_ERROR_TYPE_NONE :
>>> + RTE_FLOW_ERROR_TYPE_UNSPECIFIED;
>>> + }
>>> +}
>>> +
>>> /*
>>> * Resources
>>> */
>>> @@ -136,7 +159,8 @@ static struct flow_handle *flow_create(struct flow_eth_dev *dev __rte_unused,
>>> return NULL;
>>> }
>>>
>>> - return NULL;
>>> + return profile_inline_ops->flow_create_profile_inline(dev, attr,
>>> + forced_vlan_vid, caller_id, item, action, error);
>>> }
>>>
>>> static int flow_destroy(struct flow_eth_dev *dev __rte_unused,
>>> @@ -149,7 +173,7 @@ static int flow_destroy(struct flow_eth_dev *dev __rte_unused,
>>> return -1;
>>> }
>>>
>>> - return -1;
>>> + return profile_inline_ops->flow_destroy_profile_inline(dev, flow, error);
>>> }
>>>
>>> /*
>>> diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
>>> new file mode 100644
>>> index 0000000000..a6293f5f82
>>> --- /dev/null
>>> +++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
>>> @@ -0,0 +1,65 @@
>>> +/*
>>> + * SPDX-License-Identifier: BSD-3-Clause
>>> + * Copyright(c) 2023 Napatech A/S
>>> + */
>>> +
>>> +#include "ntlog.h"
>>> +
>>> +#include "flow_api_profile_inline.h"
>>> +#include "ntnic_mod_reg.h"
>>> +
>>> +struct flow_handle *flow_create_profile_inline(struct flow_eth_dev *dev,
>>> + const struct rte_flow_attr *attr,
>>> + uint16_t forced_vlan_vid,
>>> + uint16_t caller_id,
>>> + const struct rte_flow_item elem[],
>>> + const struct rte_flow_action action[],
>>> + struct rte_flow_error *error)
>>> +{
>>> + return NULL;
>>> +}
>>> +
>>> +int flow_destroy_locked_profile_inline(struct flow_eth_dev *dev,
>>> + struct flow_handle *fh,
>>> + struct rte_flow_error *error)
>>> +{
>>> + assert(dev);
>>> + assert(fh);
>>> +
>>> + int err = 0;
>>> +
>>> + flow_nic_set_error(ERR_SUCCESS, error);
>>> +
>>> + return err;
>>> +}
>>> +
>>> +int flow_destroy_profile_inline(struct flow_eth_dev *dev, struct flow_handle *flow,
>>> + struct rte_flow_error *error)
>>> +{
>>> + int err = 0;
>>> +
>>> + flow_nic_set_error(ERR_SUCCESS, error);
>>> +
>>> + if (flow) {
>>> + /* Delete this flow */
>>> + pthread_mutex_lock(&dev->ndev->mtx);
>>> + err = flow_destroy_locked_profile_inline(dev, flow, error);
>>> + pthread_mutex_unlock(&dev->ndev->mtx);
>>> + }
>>> +
>>> + return err;
>>> +}
>>> +
>>> +static const struct profile_inline_ops ops = {
>>> + /*
>>> + * Flow functionality
>>> + */
>>> + .flow_destroy_locked_profile_inline = flow_destroy_locked_profile_inline,
>>> + .flow_create_profile_inline = flow_create_profile_inline,
>>> + .flow_destroy_profile_inline = flow_destroy_profile_inline,
>>> +};
>>> +
>>> +void profile_inline_init(void)
>>> +{
>>> + register_profile_inline_ops(&ops);
>>> +}
>>> diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
>>> new file mode 100644
>>> index 0000000000..a83cc299b4
>>> --- /dev/null
>>> +++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
>>> @@ -0,0 +1,33 @@
>>> +/*
>>> + * SPDX-License-Identifier: BSD-3-Clause
>>> + * Copyright(c) 2023 Napatech A/S
>>> + */
>>> +
>>> +#ifndef _FLOW_API_PROFILE_INLINE_H_
>>> +#define _FLOW_API_PROFILE_INLINE_H_
>>> +
>>> +#include <stdint.h>
>>> +
>>> +#include "flow_api.h"
>>> +#include "stream_binary_flow_api.h"
>>> +
>>> +/*
>>> + * Flow functionality
>>> + */
>>> +int flow_destroy_locked_profile_inline(struct flow_eth_dev *dev,
>>> + struct flow_handle *fh,
>>> + struct rte_flow_error *error);
>>> +
>>> +struct flow_handle *flow_create_profile_inline(struct flow_eth_dev *dev,
>>> + const struct rte_flow_attr *attr,
>>> + uint16_t forced_vlan_vid,
>>> + uint16_t caller_id,
>>> + const struct rte_flow_item elem[],
>>> + const struct rte_flow_action action[],
>>> + struct rte_flow_error *error);
>>> +
>>> +int flow_destroy_profile_inline(struct flow_eth_dev *dev,
>>> + struct flow_handle *flow,
>>> + struct rte_flow_error *error);
>>> +
>>> +#endif /* _FLOW_API_PROFILE_INLINE_H_ */
>>> diff --git a/drivers/net/ntnic/ntnic_mod_reg.c b/drivers/net/ntnic/ntnic_mod_reg.c
>>> index ad2266116f..593b56bf5b 100644
>>> --- a/drivers/net/ntnic/ntnic_mod_reg.c
>>> +++ b/drivers/net/ntnic/ntnic_mod_reg.c
>>> @@ -118,9 +118,19 @@ const struct flow_backend_ops *get_flow_backend_ops(void)
>>> return flow_backend_ops;
>>> }
>>>
>>> +static const struct profile_inline_ops *profile_inline_ops;
>>> +
>>> +void register_profile_inline_ops(const struct profile_inline_ops *ops)
>>> +{
>>> + profile_inline_ops = ops;
>>> +}
>>> +
>>> const struct profile_inline_ops *get_profile_inline_ops(void)
>>> {
>>> - return NULL;
>>> + if (profile_inline_ops == NULL)
>>> + profile_inline_init();
>>> +
>>> + return profile_inline_ops;
>>> }
>>>
>>> static const struct flow_filter_ops *flow_filter_ops;
>>> diff --git a/drivers/net/ntnic/ntnic_mod_reg.h b/drivers/net/ntnic/ntnic_mod_reg.h
>>> index ec8c1612d1..d133336fad 100644
>>> --- a/drivers/net/ntnic/ntnic_mod_reg.h
>>> +++ b/drivers/net/ntnic/ntnic_mod_reg.h
>>> @@ -225,7 +225,30 @@ void register_flow_backend_ops(const struct flow_backend_ops *ops);
>>> const struct flow_backend_ops *get_flow_backend_ops(void);
>>> void flow_backend_init(void);
>>>
>>> +struct profile_inline_ops {
>>> + /*
>>> + * Flow functionality
>>> + */
>>> + int (*flow_destroy_locked_profile_inline)(struct flow_eth_dev *dev,
>>> + struct flow_handle *fh,
>>> + struct rte_flow_error *error);
>>> +
>>> + struct flow_handle *(*flow_create_profile_inline)(struct flow_eth_dev *dev,
>>> + const struct rte_flow_attr *attr,
>>> + uint16_t forced_vlan_vid,
>>> + uint16_t caller_id,
>>> + const struct rte_flow_item elem[],
>>> + const struct rte_flow_action action[],
>>> + struct rte_flow_error *error);
>>> +
>>> + int (*flow_destroy_profile_inline)(struct flow_eth_dev *dev,
>>> + struct flow_handle *flow,
>>> + struct rte_flow_error *error);
>>> +};
>>> +
>>> +void register_profile_inline_ops(const struct profile_inline_ops *ops);
>>> const struct profile_inline_ops *get_profile_inline_ops(void);
>>> +void profile_inline_init(void);
>>>
>>> struct flow_filter_ops {
>>> int (*flow_filter_init)(nthw_fpga_t *p_fpga, struct flow_nic_dev **p_flow_device,
>>
> 
> Hi Ferruh
> 
> Please find below the description of NT FPGA profiles.
> 
> The Napatech adapters support more different functionality than can fit into a single FPGA.
> This functionality is grouped into a number of profiles called inline, capture, vswitch, and basic.
> The adapter support we aim to upstream this time around, is for the inline profile.
> The code contains some of the structures and enums needed to add other profiles,
> mainly for future compatibility, and for compatibility with our legacy code base.
> 
> Here is a short description of each profile:
> Inline: Uses a scatter gather packet system, which is quite fast and lightweight.
> The FPGA contains functionality for hardware offload use-cases, such as stateful flow matching,
> encap/decap, packet steering etc.
> vSwitch: Also uses the scatter gather system. The FPGA features are selected to support
> the functionality of OVS.
> Capture: Uses Napatech’s proprietary packet buffer system,
> which requires a lot of space on the FPGA, but is extremely fast, guarantees zero packet loss,
> and zero copy packet handling on the host cpu.
> Basic: The same feature set as one might expect from a basic nic.
> Mostly used in Kubernetes containers to reduce complexity.
> 

Thanks Serhii,

It is good to have this information in the driver documentation, and I
will reflect some of this in to the relevant commit log.
  

Patch

diff --git a/drivers/net/ntnic/include/flow_api.h b/drivers/net/ntnic/include/flow_api.h
index c80906ec50..3bdfdd4f94 100644
--- a/drivers/net/ntnic/include/flow_api.h
+++ b/drivers/net/ntnic/include/flow_api.h
@@ -74,6 +74,21 @@  struct flow_nic_dev {
 	struct flow_nic_dev *next;
 };
 
+enum flow_nic_err_msg_e {
+	ERR_SUCCESS = 0,
+	ERR_FAILED = 1,
+	ERR_OUTPUT_TOO_MANY = 3,
+	ERR_MATCH_INVALID_OR_UNSUPPORTED_ELEM = 12,
+	ERR_MATCH_RESOURCE_EXHAUSTION = 14,
+	ERR_ACTION_UNSUPPORTED = 28,
+	ERR_REMOVE_FLOW_FAILED = 29,
+	ERR_OUTPUT_INVALID = 33,
+	ERR_ACTION_MULTIPLE_PORT_ID_UNSUPPORTED = 40,
+	ERR_MSG_NO_MSG
+};
+
+void flow_nic_set_error(enum flow_nic_err_msg_e msg, struct rte_flow_error *error);
+
 /*
  * Resources
  */
diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build
index d272c73c62..f5605e81cb 100644
--- a/drivers/net/ntnic/meson.build
+++ b/drivers/net/ntnic/meson.build
@@ -47,6 +47,7 @@  sources = files(
         'nthw/core/nthw_sdc.c',
         'nthw/core/nthw_si5340.c',
         'nthw/flow_api/flow_api.c',
+        'nthw/flow_api/profile_inline/flow_api_profile_inline.c',
         'nthw/flow_api/flow_backend/flow_backend.c',
         'nthw/flow_api/flow_filter.c',
         'nthw/flow_api/flow_kcc.c',
diff --git a/drivers/net/ntnic/nthw/flow_api/flow_api.c b/drivers/net/ntnic/nthw/flow_api/flow_api.c
index d779dc481f..d0dad8e8f8 100644
--- a/drivers/net/ntnic/nthw/flow_api/flow_api.c
+++ b/drivers/net/ntnic/nthw/flow_api/flow_api.c
@@ -36,6 +36,29 @@  const char *dbg_res_descr[] = {
 static struct flow_nic_dev *dev_base;
 static pthread_mutex_t base_mtx = PTHREAD_MUTEX_INITIALIZER;
 
+/*
+ * Error handling
+ */
+
+static const struct {
+	const char *message;
+} err_msg[] = {
+	/* 00 */ { "Operation successfully completed" },
+	/* 01 */ { "Operation failed" },
+	/* 29 */ { "Removing flow failed" },
+};
+
+void flow_nic_set_error(enum flow_nic_err_msg_e msg, struct rte_flow_error *error)
+{
+	assert(msg < ERR_MSG_NO_MSG);
+
+	if (error) {
+		error->message = err_msg[msg].message;
+		error->type = (msg == ERR_SUCCESS) ? RTE_FLOW_ERROR_TYPE_NONE :
+			RTE_FLOW_ERROR_TYPE_UNSPECIFIED;
+	}
+}
+
 /*
  * Resources
  */
@@ -136,7 +159,8 @@  static struct flow_handle *flow_create(struct flow_eth_dev *dev __rte_unused,
 		return NULL;
 	}
 
-	return NULL;
+	return profile_inline_ops->flow_create_profile_inline(dev, attr,
+		forced_vlan_vid, caller_id,  item, action, error);
 }
 
 static int flow_destroy(struct flow_eth_dev *dev __rte_unused,
@@ -149,7 +173,7 @@  static int flow_destroy(struct flow_eth_dev *dev __rte_unused,
 		return -1;
 	}
 
-	return -1;
+	return profile_inline_ops->flow_destroy_profile_inline(dev, flow, error);
 }
 
 /*
diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
new file mode 100644
index 0000000000..a6293f5f82
--- /dev/null
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
@@ -0,0 +1,65 @@ 
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#include "ntlog.h"
+
+#include "flow_api_profile_inline.h"
+#include "ntnic_mod_reg.h"
+
+struct flow_handle *flow_create_profile_inline(struct flow_eth_dev *dev,
+	const struct rte_flow_attr *attr,
+	uint16_t forced_vlan_vid,
+	uint16_t caller_id,
+	const struct rte_flow_item elem[],
+	const struct rte_flow_action action[],
+	struct rte_flow_error *error)
+{
+	return NULL;
+}
+
+int flow_destroy_locked_profile_inline(struct flow_eth_dev *dev,
+	struct flow_handle *fh,
+	struct rte_flow_error *error)
+{
+	assert(dev);
+	assert(fh);
+
+	int err = 0;
+
+	flow_nic_set_error(ERR_SUCCESS, error);
+
+	return err;
+}
+
+int flow_destroy_profile_inline(struct flow_eth_dev *dev, struct flow_handle *flow,
+	struct rte_flow_error *error)
+{
+	int err = 0;
+
+	flow_nic_set_error(ERR_SUCCESS, error);
+
+	if (flow) {
+		/* Delete this flow */
+		pthread_mutex_lock(&dev->ndev->mtx);
+		err = flow_destroy_locked_profile_inline(dev, flow, error);
+		pthread_mutex_unlock(&dev->ndev->mtx);
+	}
+
+	return err;
+}
+
+static const struct profile_inline_ops ops = {
+	/*
+	 * Flow functionality
+	 */
+	.flow_destroy_locked_profile_inline = flow_destroy_locked_profile_inline,
+	.flow_create_profile_inline = flow_create_profile_inline,
+	.flow_destroy_profile_inline = flow_destroy_profile_inline,
+};
+
+void profile_inline_init(void)
+{
+	register_profile_inline_ops(&ops);
+}
diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
new file mode 100644
index 0000000000..a83cc299b4
--- /dev/null
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
@@ -0,0 +1,33 @@ 
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#ifndef _FLOW_API_PROFILE_INLINE_H_
+#define _FLOW_API_PROFILE_INLINE_H_
+
+#include <stdint.h>
+
+#include "flow_api.h"
+#include "stream_binary_flow_api.h"
+
+/*
+ * Flow functionality
+ */
+int flow_destroy_locked_profile_inline(struct flow_eth_dev *dev,
+	struct flow_handle *fh,
+	struct rte_flow_error *error);
+
+struct flow_handle *flow_create_profile_inline(struct flow_eth_dev *dev,
+	const struct rte_flow_attr *attr,
+	uint16_t forced_vlan_vid,
+	uint16_t caller_id,
+	const struct rte_flow_item elem[],
+	const struct rte_flow_action action[],
+	struct rte_flow_error *error);
+
+int flow_destroy_profile_inline(struct flow_eth_dev *dev,
+	struct flow_handle *flow,
+	struct rte_flow_error *error);
+
+#endif	/* _FLOW_API_PROFILE_INLINE_H_ */
diff --git a/drivers/net/ntnic/ntnic_mod_reg.c b/drivers/net/ntnic/ntnic_mod_reg.c
index ad2266116f..593b56bf5b 100644
--- a/drivers/net/ntnic/ntnic_mod_reg.c
+++ b/drivers/net/ntnic/ntnic_mod_reg.c
@@ -118,9 +118,19 @@  const struct flow_backend_ops *get_flow_backend_ops(void)
 	return flow_backend_ops;
 }
 
+static const struct profile_inline_ops *profile_inline_ops;
+
+void register_profile_inline_ops(const struct profile_inline_ops *ops)
+{
+	profile_inline_ops = ops;
+}
+
 const struct profile_inline_ops *get_profile_inline_ops(void)
 {
-	return NULL;
+	if (profile_inline_ops == NULL)
+		profile_inline_init();
+
+	return profile_inline_ops;
 }
 
 static const struct flow_filter_ops *flow_filter_ops;
diff --git a/drivers/net/ntnic/ntnic_mod_reg.h b/drivers/net/ntnic/ntnic_mod_reg.h
index ec8c1612d1..d133336fad 100644
--- a/drivers/net/ntnic/ntnic_mod_reg.h
+++ b/drivers/net/ntnic/ntnic_mod_reg.h
@@ -225,7 +225,30 @@  void register_flow_backend_ops(const struct flow_backend_ops *ops);
 const struct flow_backend_ops *get_flow_backend_ops(void);
 void flow_backend_init(void);
 
+struct profile_inline_ops {
+	/*
+	 * Flow functionality
+	 */
+	int (*flow_destroy_locked_profile_inline)(struct flow_eth_dev *dev,
+		struct flow_handle *fh,
+		struct rte_flow_error *error);
+
+	struct flow_handle *(*flow_create_profile_inline)(struct flow_eth_dev *dev,
+		const struct rte_flow_attr *attr,
+		uint16_t forced_vlan_vid,
+		uint16_t caller_id,
+		const struct rte_flow_item elem[],
+		const struct rte_flow_action action[],
+		struct rte_flow_error *error);
+
+	int (*flow_destroy_profile_inline)(struct flow_eth_dev *dev,
+		struct flow_handle *flow,
+		struct rte_flow_error *error);
+};
+
+void register_profile_inline_ops(const struct profile_inline_ops *ops);
 const struct profile_inline_ops *get_profile_inline_ops(void);
+void profile_inline_init(void);
 
 struct flow_filter_ops {
 	int (*flow_filter_init)(nthw_fpga_t *p_fpga, struct flow_nic_dev **p_flow_device,