[dpdk-dev,2/3] lib/librte_flow_classy: add run api for flow classification

Message ID 20171123113215.64757-2-jasvinder.singh@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK

Commit Message

Jasvinder Singh Nov. 23, 2017, 11:32 a.m. UTC
  This patch extends the flow classification library by
adding run api. This function classifies the packets
based on the flow rules stored in the classifier table.
During lookup operation, the table entry is identified on
lookup hit and based on meta-data stored at table
entry, actions are performed on the current packet.
The meta-information about the actions stored in the table
entry is determined from the actions fields specified in
flow rules.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 lib/librte_flow_classify/rte_flow_classify.c       | 56 ++++++++++++++++++++++
 lib/librte_flow_classify/rte_flow_classify.h       | 24 ++++++++++
 .../rte_flow_classify_version.map                  |  1 +
 3 files changed, 81 insertions(+)
  

Comments

Iremonger, Bernard Dec. 4, 2017, 4:46 p.m. UTC | #1
Hi Jasvinder,

> -----Original Message-----
> From: Singh, Jasvinder
> Sent: Thursday, November 23, 2017 11:32 AM
> To: dev@dpdk.org
> Cc: Iremonger, Bernard <bernard.iremonger@intel.com>
> Subject: [PATCH 2/3] lib/librte_flow_classy: add run api for flow classification
> 
> This patch extends the flow classification library by adding run api. This
> function classifies the packets based on the flow rules stored in the classifier
> table.
> During lookup operation, the table entry is identified on lookup hit and based
> on meta-data stored at table entry, actions are performed on the current
> packet.
> The meta-information about the actions stored in the table entry is
> determined from the actions fields specified in flow rules.
> 
> Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
> ---
>  lib/librte_flow_classify/rte_flow_classify.c       | 56
> ++++++++++++++++++++++
>  lib/librte_flow_classify/rte_flow_classify.h       | 24 ++++++++++
>  .../rte_flow_classify_version.map                  |  1 +
>  3 files changed, 81 insertions(+)
> 
> diff --git a/lib/librte_flow_classify/rte_flow_classify.c
> b/lib/librte_flow_classify/rte_flow_classify.c
> index ff1bc86..5433bfe 100644
> --- a/lib/librte_flow_classify/rte_flow_classify.c
> +++ b/lib/librte_flow_classify/rte_flow_classify.c
> @@ -37,6 +37,9 @@
>  #include <rte_table_acl.h>
>  #include <stdbool.h>
> 
> +#define RTE_PKT_METADATA_PTR(pkt, offset)         \
> +		(&((uint32_t *)(pkt))[offset])
> +
>  int librte_flow_classify_logtype;
> 
>  static uint32_t unique_id = 1;
> @@ -674,6 +677,59 @@ action_apply(struct rte_flow_classifier *cls,  }
> 
>  int
> +rte_flow_classifier_run(struct rte_flow_classifier *cls,
> +	struct rte_mbuf **pkts,
> +	const uint16_t nb_pkts,
> +	uint32_t pkt_offset)
> +{
> +	struct rte_flow_action_mark *mark;
> +	struct classify_action *action;
> +	uint64_t pkts_mask = RTE_LEN2MASK(nb_pkts, uint64_t);
> +	uint64_t action_mask;
> +	uint32_t *ptr, i, j;
> +	int ret = -EINVAL;
> +
> +	if (!cls || !pkts  || nb_pkts == 0)
> +		return ret;
> +
> +	for (i = 0; i < cls->num_tables; i++) {
> +		if (cls->table_mask & (1LU << i)) {
> +			struct rte_cls_table *table = &cls->tables[i];
> +			uint64_t lookup_hit_mask;
> +
> +			ret = table->ops.f_lookup(table->h_table,
> +				pkts, pkts_mask, &lookup_hit_mask,
> +				(void **)cls->entries);
> +			if (ret)
> +				return ret;
> +
> +			if (lookup_hit_mask) {
> +				for (j = 0; j < nb_pkts; j++) {
> +					uint64_t pkt_mask = 1LLU << j;
> +
> +					if ((lookup_hit_mask & pkt_mask) ==
> 0)
> +						continue;
> +					/* Meta-data */
> +					enum rte_flow_action_type act_type
> =
> +
> 	RTE_FLOW_ACTION_TYPE_MARK;
> +					action = &cls->entries[j]->action;
> +					action_mask = action->action_mask;
> +
> +					if (action_mask & (1LLU << act_type))
> {
> +						mark = &action->act.mark;
> +						ptr =
> RTE_PKT_METADATA_PTR(
> +							pkts[j], pkt_offset);
> +						*ptr = mark->id;
> +					}
> +				}
> +			}
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +int
>  rte_flow_classifier_query(struct rte_flow_classifier *cls,
>  		struct rte_mbuf **pkts,
>  		const uint16_t nb_pkts,
> diff --git a/lib/librte_flow_classify/rte_flow_classify.h
> b/lib/librte_flow_classify/rte_flow_classify.h
> index b9b669f..b74bd11 100644
> --- a/lib/librte_flow_classify/rte_flow_classify.h
> +++ b/lib/librte_flow_classify/rte_flow_classify.h
> @@ -273,6 +273,30 @@ rte_flow_classify_table_entry_delete(struct
> rte_flow_classifier *cls,
>  		struct rte_flow_classify_rule *rule);
> 
>  /**
> + * Flow classifier run.
> + *
> + * As a result of lookup operation, flow classifer idenfies the
> + * table entries that are hit and executes the actions on the packets.
> + *
> + * @param[in] cls
> + *   Flow classifier handle
> + * @param[in] pkts
> + *   Pointer to packets to process
> + * @param[in] nb_pkts
> + *   Number of packets to process
> + * @param[in] pkt_offset
> + *    Offset to store action metadata in the mbuf headroom
> + *
> + * @return
> + *   0 on success, error code otherwise.
> + */
> +int
> +rte_flow_classifier_run(struct rte_flow_classifier *cls,
> +		struct rte_mbuf **pkts,
> +		const uint16_t nb_pkts,
> +		uint32_t pkt_offset);
> +
> +/**
>   * Query flow classifier for given rule.
>   *
>   * @param[in] cls
> diff --git a/lib/librte_flow_classify/rte_flow_classify_version.map
> b/lib/librte_flow_classify/rte_flow_classify_version.map
> index 49bc25c..b51cb1a 100644
> --- a/lib/librte_flow_classify/rte_flow_classify_version.map
> +++ b/lib/librte_flow_classify/rte_flow_classify_version.map
> @@ -4,6 +4,7 @@ EXPERIMENTAL {
>  	rte_flow_classifier_create;
>  	rte_flow_classifier_free;
>  	rte_flow_classifier_query;
> +	rte_flow_classifier_run;
>  	rte_flow_classify_table_create;
>  	rte_flow_classify_table_entry_add;
>  	rte_flow_classify_table_entry_delete;
> --
> 2.9.3

This patch fails to apply to the 18.02 master branch, a rebase may be needed.

Regards,

Bernard.
  
Iremonger, Bernard Dec. 5, 2017, 11:01 a.m. UTC | #2
Hi Jasvinder,

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Iremonger, Bernard
> Sent: Monday, December 4, 2017 4:46 PM
> To: Singh, Jasvinder <jasvinder.singh@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 2/3] lib/librte_flow_classy: add run api for flow
> classification
> 
> Hi Jasvinder,
> 
> > -----Original Message-----
> > From: Singh, Jasvinder
> > Sent: Thursday, November 23, 2017 11:32 AM
> > To: dev@dpdk.org
> > Cc: Iremonger, Bernard <bernard.iremonger@intel.com>
> > Subject: [PATCH 2/3] lib/librte_flow_classy: add run api for flow
> > classification
> >
> > This patch extends the flow classification library by adding run api.
> > This function classifies the packets based on the flow rules stored in
> > the classifier table.
> > During lookup operation, the table entry is identified on lookup hit
> > and based on meta-data stored at table entry, actions are performed on
> > the current packet.
> > The meta-information about the actions stored in the table entry is
> > determined from the actions fields specified in flow rules.
> >
> > Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
> > ---
> >  lib/librte_flow_classify/rte_flow_classify.c       | 56
> > ++++++++++++++++++++++
> >  lib/librte_flow_classify/rte_flow_classify.h       | 24 ++++++++++
> >  .../rte_flow_classify_version.map                  |  1 +
> >  3 files changed, 81 insertions(+)
> >
> > diff --git a/lib/librte_flow_classify/rte_flow_classify.c
> > b/lib/librte_flow_classify/rte_flow_classify.c
> > index ff1bc86..5433bfe 100644
> > --- a/lib/librte_flow_classify/rte_flow_classify.c
> > +++ b/lib/librte_flow_classify/rte_flow_classify.c
> > @@ -37,6 +37,9 @@
> >  #include <rte_table_acl.h>
> >  #include <stdbool.h>
> >
> > +#define RTE_PKT_METADATA_PTR(pkt, offset)         \
> > +		(&((uint32_t *)(pkt))[offset])
> > +
> >  int librte_flow_classify_logtype;
> >
> >  static uint32_t unique_id = 1;
> > @@ -674,6 +677,59 @@ action_apply(struct rte_flow_classifier *cls,  }
> >
> >  int
> > +rte_flow_classifier_run(struct rte_flow_classifier *cls,
> > +	struct rte_mbuf **pkts,
> > +	const uint16_t nb_pkts,
> > +	uint32_t pkt_offset)
> > +{
> > +	struct rte_flow_action_mark *mark;
> > +	struct classify_action *action;
> > +	uint64_t pkts_mask = RTE_LEN2MASK(nb_pkts, uint64_t);
> > +	uint64_t action_mask;
> > +	uint32_t *ptr, i, j;
> > +	int ret = -EINVAL;
> > +
> > +	if (!cls || !pkts  || nb_pkts == 0)
> > +		return ret;
> > +
> > +	for (i = 0; i < cls->num_tables; i++) {
> > +		if (cls->table_mask & (1LU << i)) {
> > +			struct rte_cls_table *table = &cls->tables[i];
> > +			uint64_t lookup_hit_mask;
> > +
> > +			ret = table->ops.f_lookup(table->h_table,
> > +				pkts, pkts_mask, &lookup_hit_mask,
> > +				(void **)cls->entries);
> > +			if (ret)
> > +				return ret;
> > +
> > +			if (lookup_hit_mask) {
> > +				for (j = 0; j < nb_pkts; j++) {
> > +					uint64_t pkt_mask = 1LLU << j;
> > +
> > +					if ((lookup_hit_mask & pkt_mask) ==
> > 0)
> > +						continue;
> > +					/* Meta-data */
> > +					enum rte_flow_action_type act_type
> > =
> > +
> > 	RTE_FLOW_ACTION_TYPE_MARK;
> > +					action = &cls->entries[j]->action;
> > +					action_mask = action->action_mask;
> > +
> > +					if (action_mask & (1LLU << act_type))
> > {
> > +						mark = &action->act.mark;
> > +						ptr =
> > RTE_PKT_METADATA_PTR(
> > +							pkts[j], pkt_offset);
> > +						*ptr = mark->id;
> > +					}
> > +				}
> > +			}
> > +		}
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +int
> >  rte_flow_classifier_query(struct rte_flow_classifier *cls,
> >  		struct rte_mbuf **pkts,
> >  		const uint16_t nb_pkts,
> > diff --git a/lib/librte_flow_classify/rte_flow_classify.h
> > b/lib/librte_flow_classify/rte_flow_classify.h
> > index b9b669f..b74bd11 100644
> > --- a/lib/librte_flow_classify/rte_flow_classify.h
> > +++ b/lib/librte_flow_classify/rte_flow_classify.h
> > @@ -273,6 +273,30 @@ rte_flow_classify_table_entry_delete(struct
> > rte_flow_classifier *cls,
> >  		struct rte_flow_classify_rule *rule);
> >
> >  /**
> > + * Flow classifier run.
> > + *
> > + * As a result of lookup operation, flow classifer idenfies the
> > + * table entries that are hit and executes the actions on the packets.
> > + *
> > + * @param[in] cls
> > + *   Flow classifier handle
> > + * @param[in] pkts
> > + *   Pointer to packets to process
> > + * @param[in] nb_pkts
> > + *   Number of packets to process
> > + * @param[in] pkt_offset
> > + *    Offset to store action metadata in the mbuf headroom
> > + *
> > + * @return
> > + *   0 on success, error code otherwise.
> > + */
> > +int
> > +rte_flow_classifier_run(struct rte_flow_classifier *cls,
> > +		struct rte_mbuf **pkts,
> > +		const uint16_t nb_pkts,
> > +		uint32_t pkt_offset);
> > +
> > +/**
> >   * Query flow classifier for given rule.
> >   *
> >   * @param[in] cls
> > diff --git a/lib/librte_flow_classify/rte_flow_classify_version.map
> > b/lib/librte_flow_classify/rte_flow_classify_version.map
> > index 49bc25c..b51cb1a 100644
> > --- a/lib/librte_flow_classify/rte_flow_classify_version.map
> > +++ b/lib/librte_flow_classify/rte_flow_classify_version.map
> > @@ -4,6 +4,7 @@ EXPERIMENTAL {
> >  	rte_flow_classifier_create;
> >  	rte_flow_classifier_free;
> >  	rte_flow_classifier_query;
> > +	rte_flow_classifier_run;
> >  	rte_flow_classify_table_create;
> >  	rte_flow_classify_table_entry_add;
> >  	rte_flow_classify_table_entry_delete;
> > --
> > 2.9.3
> 
> This patch fails to apply to the 18.02 master branch, a rebase may be needed.
> 
> Regards,
> 
> Bernard.

False alarm, the patch applies ok on a fresh checkout.

Regards,

Bernard.
  
Iremonger, Bernard Dec. 6, 2017, 12:41 p.m. UTC | #3
Hi Jasvinder,

<snip>

> > > -----Original Message-----
> > > From: Singh, Jasvinder
> > > Sent: Thursday, November 23, 2017 11:32 AM
> > > To: dev@dpdk.org
> > > Cc: Iremonger, Bernard <bernard.iremonger@intel.com>
> > > Subject: [PATCH 2/3] lib/librte_flow_classy: add run api for flow
> > > classification
> > >
> > > This patch extends the flow classification library by adding run api.
> > > This function classifies the packets based on the flow rules stored
> > > in the classifier table.
> > > During lookup operation, the table entry is identified on lookup hit
> > > and based on meta-data stored at table entry, actions are performed
> > > on the current packet.
> > > The meta-information about the actions stored in the table entry is
> > > determined from the actions fields specified in flow rules.
> > >
> > > Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
> > > ---
> > >  lib/librte_flow_classify/rte_flow_classify.c       | 56
> > > ++++++++++++++++++++++
> > >  lib/librte_flow_classify/rte_flow_classify.h       | 24 ++++++++++
> > >  .../rte_flow_classify_version.map                  |  1 +
> > >  3 files changed, 81 insertions(+)
> > >
> > > diff --git a/lib/librte_flow_classify/rte_flow_classify.c
> > > b/lib/librte_flow_classify/rte_flow_classify.c
> > > index ff1bc86..5433bfe 100644
> > > --- a/lib/librte_flow_classify/rte_flow_classify.c
> > > +++ b/lib/librte_flow_classify/rte_flow_classify.c
> > > @@ -37,6 +37,9 @@
> > >  #include <rte_table_acl.h>
> > >  #include <stdbool.h>
> > >
> > > +#define RTE_PKT_METADATA_PTR(pkt, offset)         \
> > > +		(&((uint32_t *)(pkt))[offset])
> > > +
> > >  int librte_flow_classify_logtype;
> > >
> > >  static uint32_t unique_id = 1;
> > > @@ -674,6 +677,59 @@ action_apply(struct rte_flow_classifier *cls,
> > > }
> > >
> > >  int
> > > +rte_flow_classifier_run(struct rte_flow_classifier *cls,
> > > +	struct rte_mbuf **pkts,
> > > +	const uint16_t nb_pkts,
> > > +	uint32_t pkt_offset)
> > > +{
> > > +	struct rte_flow_action_mark *mark;
> > > +	struct classify_action *action;
> > > +	uint64_t pkts_mask = RTE_LEN2MASK(nb_pkts, uint64_t);
> > > +	uint64_t action_mask;
> > > +	uint32_t *ptr, i, j;
> > > +	int ret = -EINVAL;
> > > +
> > > +	if (!cls || !pkts  || nb_pkts == 0)
> > > +		return ret;
> > > +
> > > +	for (i = 0; i < cls->num_tables; i++) {
> > > +		if (cls->table_mask & (1LU << i)) {
> > > +			struct rte_cls_table *table = &cls->tables[i];
> > > +			uint64_t lookup_hit_mask;
> > > +
> > > +			ret = table->ops.f_lookup(table->h_table,
> > > +				pkts, pkts_mask, &lookup_hit_mask,
> > > +				(void **)cls->entries);
> > > +			if (ret)
> > > +				return ret;
> > > +
> > > +			if (lookup_hit_mask) {
> > > +				for (j = 0; j < nb_pkts; j++) {
> > > +					uint64_t pkt_mask = 1LLU << j;
> > > +
> > > +					if ((lookup_hit_mask & pkt_mask) ==
> > > 0)
> > > +						continue;
> > > +					/* Meta-data */
> > > +					enum rte_flow_action_type act_type
> > > =
> > > +
> > > 	RTE_FLOW_ACTION_TYPE_MARK;
> > > +					action = &cls->entries[j]->action;
> > > +					action_mask = action->action_mask;
> > > +
> > > +					if (action_mask & (1LLU << act_type))
> > > {
> > > +						mark = &action->act.mark;
> > > +						ptr =
> > > RTE_PKT_METADATA_PTR(
> > > +							pkts[j], pkt_offset);
> > > +						*ptr = mark->id;
> > > +					}
> > > +				}
> > > +			}
> > > +		}
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +int
> > >  rte_flow_classifier_query(struct rte_flow_classifier *cls,
> > >  		struct rte_mbuf **pkts,
> > >  		const uint16_t nb_pkts,
> > > diff --git a/lib/librte_flow_classify/rte_flow_classify.h
> > > b/lib/librte_flow_classify/rte_flow_classify.h
> > > index b9b669f..b74bd11 100644
> > > --- a/lib/librte_flow_classify/rte_flow_classify.h
> > > +++ b/lib/librte_flow_classify/rte_flow_classify.h
> > > @@ -273,6 +273,30 @@ rte_flow_classify_table_entry_delete(struct
> > > rte_flow_classifier *cls,
> > >  		struct rte_flow_classify_rule *rule);
> > >
> > >  /**
> > > + * Flow classifier run.
> > > + *
> > > + * As a result of lookup operation, flow classifer idenfies the
> > > + * table entries that are hit and executes the actions on the packets.
> > > + *
> > > + * @param[in] cls
> > > + *   Flow classifier handle
> > > + * @param[in] pkts
> > > + *   Pointer to packets to process
> > > + * @param[in] nb_pkts
> > > + *   Number of packets to process
> > > + * @param[in] pkt_offset
> > > + *    Offset to store action metadata in the mbuf headroom
> > > + *
> > > + * @return
> > > + *   0 on success, error code otherwise.
> > > + */
> > > +int
> > > +rte_flow_classifier_run(struct rte_flow_classifier *cls,
> > > +		struct rte_mbuf **pkts,
> > > +		const uint16_t nb_pkts,
> > > +		uint32_t pkt_offset);
> > > +
> > > +/**
> > >   * Query flow classifier for given rule.
> > >   *
> > >   * @param[in] cls
> > > diff --git a/lib/librte_flow_classify/rte_flow_classify_version.map
> > > b/lib/librte_flow_classify/rte_flow_classify_version.map
> > > index 49bc25c..b51cb1a 100644
> > > --- a/lib/librte_flow_classify/rte_flow_classify_version.map
> > > +++ b/lib/librte_flow_classify/rte_flow_classify_version.map
> > > @@ -4,6 +4,7 @@ EXPERIMENTAL {
> > >  	rte_flow_classifier_create;
> > >  	rte_flow_classifier_free;
> > >  	rte_flow_classifier_query;
> > > +	rte_flow_classifier_run;
> > >  	rte_flow_classify_table_create;
> > >  	rte_flow_classify_table_entry_add;
> > >  	rte_flow_classify_table_entry_delete;
> > > --
> > > 2.9.3
> >
<snip>

Tests should be added to test_flow_classify.c for the rte_flow_classifier_run() API.
The flow_classify sample application should exercise the rte_flow_classifier_run() API.

Regards,

Bernard.
  
Jasvinder Singh Dec. 11, 2017, 3:52 p.m. UTC | #4
> -----Original Message-----
> From: Iremonger, Bernard
> Sent: Wednesday, December 6, 2017 12:41 PM
> To: Iremonger, Bernard <bernard.iremonger@intel.com>; Singh, Jasvinder
> <jasvinder.singh@intel.com>; dev@dpdk.org
> Subject: RE: [PATCH 2/3] lib/librte_flow_classy: add run api for flow
> classification
> 
> Hi Jasvinder,
> 
> <snip>
> 
> > > > -----Original Message-----
> > > > From: Singh, Jasvinder
> > > > Sent: Thursday, November 23, 2017 11:32 AM
> > > > To: dev@dpdk.org
> > > > Cc: Iremonger, Bernard <bernard.iremonger@intel.com>
> > > > Subject: [PATCH 2/3] lib/librte_flow_classy: add run api for flow
> > > > classification
> > > >
> > > > This patch extends the flow classification library by adding run api.
> > > > This function classifies the packets based on the flow rules
> > > > stored in the classifier table.
> > > > During lookup operation, the table entry is identified on lookup
> > > > hit and based on meta-data stored at table entry, actions are
> > > > performed on the current packet.
> > > > The meta-information about the actions stored in the table entry
> > > > is determined from the actions fields specified in flow rules.
> > > >
> > > > Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
> > > > ---
> > > >  lib/librte_flow_classify/rte_flow_classify.c       | 56
> > > > ++++++++++++++++++++++
> > > >  lib/librte_flow_classify/rte_flow_classify.h       | 24 ++++++++++
> > > >  .../rte_flow_classify_version.map                  |  1 +
> > > >  3 files changed, 81 insertions(+)
> > > >
> > > > diff --git a/lib/librte_flow_classify/rte_flow_classify.c
> > > > b/lib/librte_flow_classify/rte_flow_classify.c
> > > > index ff1bc86..5433bfe 100644
> > > > --- a/lib/librte_flow_classify/rte_flow_classify.c
> > > > +++ b/lib/librte_flow_classify/rte_flow_classify.c
> > > > @@ -37,6 +37,9 @@
> > > >  #include <rte_table_acl.h>
> > > >  #include <stdbool.h>
> > > >
> > > > +#define RTE_PKT_METADATA_PTR(pkt, offset)         \
> > > > +		(&((uint32_t *)(pkt))[offset])
> > > > +
> > > >  int librte_flow_classify_logtype;
> > > >
> > > >  static uint32_t unique_id = 1;
> > > > @@ -674,6 +677,59 @@ action_apply(struct rte_flow_classifier *cls,
> > > > }
> > > >
> > > >  int
> > > > +rte_flow_classifier_run(struct rte_flow_classifier *cls,
> > > > +	struct rte_mbuf **pkts,
> > > > +	const uint16_t nb_pkts,
> > > > +	uint32_t pkt_offset)
> > > > +{
> > > > +	struct rte_flow_action_mark *mark;
> > > > +	struct classify_action *action;
> > > > +	uint64_t pkts_mask = RTE_LEN2MASK(nb_pkts, uint64_t);
> > > > +	uint64_t action_mask;
> > > > +	uint32_t *ptr, i, j;
> > > > +	int ret = -EINVAL;
> > > > +
> > > > +	if (!cls || !pkts  || nb_pkts == 0)
> > > > +		return ret;
> > > > +
> > > > +	for (i = 0; i < cls->num_tables; i++) {
> > > > +		if (cls->table_mask & (1LU << i)) {
> > > > +			struct rte_cls_table *table = &cls->tables[i];
> > > > +			uint64_t lookup_hit_mask;
> > > > +
> > > > +			ret = table->ops.f_lookup(table->h_table,
> > > > +				pkts, pkts_mask, &lookup_hit_mask,
> > > > +				(void **)cls->entries);
> > > > +			if (ret)
> > > > +				return ret;
> > > > +
> > > > +			if (lookup_hit_mask) {
> > > > +				for (j = 0; j < nb_pkts; j++) {
> > > > +					uint64_t pkt_mask = 1LLU << j;
> > > > +
> > > > +					if ((lookup_hit_mask & pkt_mask) ==
> > > > 0)
> > > > +						continue;
> > > > +					/* Meta-data */
> > > > +					enum rte_flow_action_type act_type
> > > > =
> > > > +
> > > > 	RTE_FLOW_ACTION_TYPE_MARK;
> > > > +					action = &cls->entries[j]->action;
> > > > +					action_mask = action->action_mask;
> > > > +
> > > > +					if (action_mask & (1LLU << act_type))
> > > > {
> > > > +						mark = &action->act.mark;
> > > > +						ptr =
> > > > RTE_PKT_METADATA_PTR(
> > > > +							pkts[j], pkt_offset);
> > > > +						*ptr = mark->id;
> > > > +					}
> > > > +				}
> > > > +			}
> > > > +		}
> > > > +	}
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +
> > > > +int
> > > >  rte_flow_classifier_query(struct rte_flow_classifier *cls,
> > > >  		struct rte_mbuf **pkts,
> > > >  		const uint16_t nb_pkts,
> > > > diff --git a/lib/librte_flow_classify/rte_flow_classify.h
> > > > b/lib/librte_flow_classify/rte_flow_classify.h
> > > > index b9b669f..b74bd11 100644
> > > > --- a/lib/librte_flow_classify/rte_flow_classify.h
> > > > +++ b/lib/librte_flow_classify/rte_flow_classify.h
> > > > @@ -273,6 +273,30 @@ rte_flow_classify_table_entry_delete(struct
> > > > rte_flow_classifier *cls,
> > > >  		struct rte_flow_classify_rule *rule);
> > > >
> > > >  /**
> > > > + * Flow classifier run.
> > > > + *
> > > > + * As a result of lookup operation, flow classifer idenfies the
> > > > + * table entries that are hit and executes the actions on the packets.
> > > > + *
> > > > + * @param[in] cls
> > > > + *   Flow classifier handle
> > > > + * @param[in] pkts
> > > > + *   Pointer to packets to process
> > > > + * @param[in] nb_pkts
> > > > + *   Number of packets to process
> > > > + * @param[in] pkt_offset
> > > > + *    Offset to store action metadata in the mbuf headroom
> > > > + *
> > > > + * @return
> > > > + *   0 on success, error code otherwise.
> > > > + */
> > > > +int
> > > > +rte_flow_classifier_run(struct rte_flow_classifier *cls,
> > > > +		struct rte_mbuf **pkts,
> > > > +		const uint16_t nb_pkts,
> > > > +		uint32_t pkt_offset);
> > > > +
> > > > +/**
> > > >   * Query flow classifier for given rule.
> > > >   *
> > > >   * @param[in] cls
> > > > diff --git
> > > > a/lib/librte_flow_classify/rte_flow_classify_version.map
> > > > b/lib/librte_flow_classify/rte_flow_classify_version.map
> > > > index 49bc25c..b51cb1a 100644
> > > > --- a/lib/librte_flow_classify/rte_flow_classify_version.map
> > > > +++ b/lib/librte_flow_classify/rte_flow_classify_version.map
> > > > @@ -4,6 +4,7 @@ EXPERIMENTAL {
> > > >  	rte_flow_classifier_create;
> > > >  	rte_flow_classifier_free;
> > > >  	rte_flow_classifier_query;
> > > > +	rte_flow_classifier_run;
> > > >  	rte_flow_classify_table_create;
> > > >  	rte_flow_classify_table_entry_add;
> > > >  	rte_flow_classify_table_entry_delete;
> > > > --
> > > > 2.9.3
> > >
> <snip>
> 
> Tests should be added to test_flow_classify.c for the
> rte_flow_classifier_run() API.
> The flow_classify sample application should exercise the
> rte_flow_classifier_run() API.

Ok, will do in v2.

Jasvinder
  

Patch

diff --git a/lib/librte_flow_classify/rte_flow_classify.c b/lib/librte_flow_classify/rte_flow_classify.c
index ff1bc86..5433bfe 100644
--- a/lib/librte_flow_classify/rte_flow_classify.c
+++ b/lib/librte_flow_classify/rte_flow_classify.c
@@ -37,6 +37,9 @@ 
 #include <rte_table_acl.h>
 #include <stdbool.h>
 
+#define RTE_PKT_METADATA_PTR(pkt, offset)         \
+		(&((uint32_t *)(pkt))[offset])
+
 int librte_flow_classify_logtype;
 
 static uint32_t unique_id = 1;
@@ -674,6 +677,59 @@  action_apply(struct rte_flow_classifier *cls,
 }
 
 int
+rte_flow_classifier_run(struct rte_flow_classifier *cls,
+	struct rte_mbuf **pkts,
+	const uint16_t nb_pkts,
+	uint32_t pkt_offset)
+{
+	struct rte_flow_action_mark *mark;
+	struct classify_action *action;
+	uint64_t pkts_mask = RTE_LEN2MASK(nb_pkts, uint64_t);
+	uint64_t action_mask;
+	uint32_t *ptr, i, j;
+	int ret = -EINVAL;
+
+	if (!cls || !pkts  || nb_pkts == 0)
+		return ret;
+
+	for (i = 0; i < cls->num_tables; i++) {
+		if (cls->table_mask & (1LU << i)) {
+			struct rte_cls_table *table = &cls->tables[i];
+			uint64_t lookup_hit_mask;
+
+			ret = table->ops.f_lookup(table->h_table,
+				pkts, pkts_mask, &lookup_hit_mask,
+				(void **)cls->entries);
+			if (ret)
+				return ret;
+
+			if (lookup_hit_mask) {
+				for (j = 0; j < nb_pkts; j++) {
+					uint64_t pkt_mask = 1LLU << j;
+
+					if ((lookup_hit_mask & pkt_mask) == 0)
+						continue;
+					/* Meta-data */
+					enum rte_flow_action_type act_type =
+						RTE_FLOW_ACTION_TYPE_MARK;
+					action = &cls->entries[j]->action;
+					action_mask = action->action_mask;
+
+					if (action_mask & (1LLU << act_type)) {
+						mark = &action->act.mark;
+						ptr = RTE_PKT_METADATA_PTR(
+							pkts[j], pkt_offset);
+						*ptr = mark->id;
+					}
+				}
+			}
+		}
+	}
+
+	return 0;
+}
+
+int
 rte_flow_classifier_query(struct rte_flow_classifier *cls,
 		struct rte_mbuf **pkts,
 		const uint16_t nb_pkts,
diff --git a/lib/librte_flow_classify/rte_flow_classify.h b/lib/librte_flow_classify/rte_flow_classify.h
index b9b669f..b74bd11 100644
--- a/lib/librte_flow_classify/rte_flow_classify.h
+++ b/lib/librte_flow_classify/rte_flow_classify.h
@@ -273,6 +273,30 @@  rte_flow_classify_table_entry_delete(struct rte_flow_classifier *cls,
 		struct rte_flow_classify_rule *rule);
 
 /**
+ * Flow classifier run.
+ *
+ * As a result of lookup operation, flow classifer idenfies the
+ * table entries that are hit and executes the actions on the packets.
+ *
+ * @param[in] cls
+ *   Flow classifier handle
+ * @param[in] pkts
+ *   Pointer to packets to process
+ * @param[in] nb_pkts
+ *   Number of packets to process
+ * @param[in] pkt_offset
+ *    Offset to store action metadata in the mbuf headroom
+ *
+ * @return
+ *   0 on success, error code otherwise.
+ */
+int
+rte_flow_classifier_run(struct rte_flow_classifier *cls,
+		struct rte_mbuf **pkts,
+		const uint16_t nb_pkts,
+		uint32_t pkt_offset);
+
+/**
  * Query flow classifier for given rule.
  *
  * @param[in] cls
diff --git a/lib/librte_flow_classify/rte_flow_classify_version.map b/lib/librte_flow_classify/rte_flow_classify_version.map
index 49bc25c..b51cb1a 100644
--- a/lib/librte_flow_classify/rte_flow_classify_version.map
+++ b/lib/librte_flow_classify/rte_flow_classify_version.map
@@ -4,6 +4,7 @@  EXPERIMENTAL {
 	rte_flow_classifier_create;
 	rte_flow_classifier_free;
 	rte_flow_classifier_query;
+	rte_flow_classifier_run;
 	rte_flow_classify_table_create;
 	rte_flow_classify_table_entry_add;
 	rte_flow_classify_table_entry_delete;