[dpdk-dev] [PATCH v4 05/16] ethdev: alter behavior of flow API actions
Adrien Mazarguil
adrien.mazarguil at 6wind.com
Wed Apr 18 16:58:38 CEST 2018
On Wed, Apr 18, 2018 at 03:26:00PM +0300, Andrew Rybchenko wrote:
> On 04/16/2018 07:22 PM, Adrien Mazarguil wrote:
> > This patch makes the following changes to flow rule actions:
> >
> > - List order now matters, they are redefined as performed first to last
> > instead of "all simultaneously".
> >
> > - Repeated actions are now supported (e.g. specifying QUEUE multiple times
> > now duplicates traffic among them). Previously only the last action of
> > any given kind was taken into account.
> >
> > - No more distinction between terminating/non-terminating/meta actions.
> > Flow rules themselves are now defined as always terminating unless a
> > PASSTHRU action is specified.
> >
> > These changes alter the behavior of flow rules in corner cases in order to
> > prepare the flow API for actions that modify traffic contents or properties
> > (e.g. encapsulation, compression) and for which order matter when combined.
> >
> > Previously one would have to do so through multiple flow rules by combining
> > PASSTRHU with priority levels, however this proved overly complex to
> > implement at the PMD level, hence this simpler approach.
> >
> > This breaks ABI compatibility for the following public functions:
> >
> > - rte_flow_create()
> > - rte_flow_validate()
> >
> > PMDs with rte_flow support are modified accordingly:
> >
> > - bnxt: no change, implementation already forbids multiple actions and does
> > not support PASSTHRU.
> >
> > - e1000: no change, same as bnxt.
> >
> > - enic: modified to forbid redundant actions, no support for default drop.
> >
> > - failsafe: no change needed.
> >
> > - i40e: no change, implementation already forbids multiple actions.
> >
> > - ixgbe: same as i40e.
> >
> > - mlx4: modified to forbid multiple fate-deciding actions and drop when
> > unspecified.
> >
> > - mlx5: same as mlx4, with other redundant actions also forbidden.
> >
> > - sfc: same as mlx4.
> >
> > - tap: implementation already complies with the new behavior except for
> > the default pass-through modified as a default drop.
> >
> > Signed-off-by: Adrien Mazarguil <adrien.mazarguil at 6wind.com>
> > Reviewed-by: Andrew Rybchenko <arybchenko at oktetlabs.ru>
> > Cc: Ajit Khaparde <ajit.khaparde at broadcom.com>
> > Cc: Wenzhuo Lu <wenzhuo.lu at intel.com>
> > Cc: John Daley <johndale at cisco.com>
> > Cc: Gaetan Rivet <gaetan.rivet at 6wind.com>
> > Cc: Beilei Xing <beilei.xing at intel.com>
> > Cc: Konstantin Ananyev <konstantin.ananyev at intel.com>
> > Cc: Nelio Laranjeiro <nelio.laranjeiro at 6wind.com>
> > Cc: Andrew Rybchenko <arybchenko at solarflare.com>
> > Cc: Pascal Mazon <pascal.mazon at 6wind.com>
> > ---
> > doc/guides/prog_guide/rte_flow.rst | 67 +++++++++++++-------------------
> > drivers/net/enic/enic_flow.c | 25 ++++++++++++
> > drivers/net/mlx4/mlx4_flow.c | 21 +++++++---
> > drivers/net/mlx5/mlx5_flow.c | 69 ++++++++++++++-------------------
> > drivers/net/sfc/sfc_flow.c | 22 +++++++----
> > drivers/net/tap/tap_flow.c | 11 ++++++
> > lib/librte_ether/rte_flow.h | 54 +++++++-------------------
> > 7 files changed, 138 insertions(+), 131 deletions(-)
>
> [...]
>
> > diff --git a/drivers/net/enic/enic_flow.c b/drivers/net/enic/enic_flow.c
> > index b9f36587c..a5c6a1670 100644
> > --- a/drivers/net/enic/enic_flow.c
> > +++ b/drivers/net/enic/enic_flow.c
> > @@ -975,6 +979,10 @@ enic_copy_action_v1(const struct rte_flow_action actions[],
> > const struct rte_flow_action_queue *queue =
> > (const struct rte_flow_action_queue *)
> > actions->conf;
> > +
> > + if (overlap & FATE)
> > + return ENOTSUP;
> > + overlap |= FATE;
> > enic_action->rq_idx =
> > enic_rte_rq_idx_to_sop_idx(queue->index);
> > break;
> > @@ -984,6 +992,8 @@ enic_copy_action_v1(const struct rte_flow_action actions[],
> > break;
> > }
> > }
> > + if (!overlap & FATE)
>
> Build using clang on Ubuntu 17.10 fails:
>
> /var/tmp/dpdk-next-net/drivers/net/enic/enic_flow.c:1000:6: fatal error:
> logical not is only applied to
> the left hand side of this bitwise operator
> [-Wlogical-not-parentheses]
> if (!overlap & FATE)
> ^ ~
> /var/tmp/dpdk-next-net/drivers/net/enic/enic_flow.c:1000:6: note: add
> parentheses after the '!' to
> evaluate the bitwise operator first
> if (!overlap & FATE)
> ^
> ( )
> /var/tmp/dpdk-next-net/drivers/net/enic/enic_flow.c:1000:6: note: add
> parentheses around left hand side
> expression to silence this warning
> if (!overlap & FATE)
> ^
> ( )
> 1 error generated.
> /var/tmp/dpdk-next-net/mk/internal/rte.compile-pre.mk:114: recipe for target
> 'enic_flow.o' failed
> make[4]: *** [enic_flow.o] Error 1
> /var/tmp/dpdk-next-net/mk/rte.subdir.mk:35: recipe for target 'enic' failed
> make[3]: *** [enic] Error 2
> CC nfp_cpp_pcie_ops.o
> make[3]: *** Waiting for unfinished jobs....
>
> $ clang --version
> clang version 4.0.1-6 (tags/RELEASE_401/final)
> Target: x86_64-pc-linux-gnu
> Thread model: posix
> InstalledDir: /usr/bin
>
>
> > + return ENOTSUP;
> > enic_action->type = FILTER_ACTION_RQ_STEERING;
> > return 0;
> > }
> > @@ -1001,6 +1011,9 @@ static int
> > enic_copy_action_v2(const struct rte_flow_action actions[],
> > struct filter_action_v2 *enic_action)
> > {
> > + enum { FATE = 1, MARK = 2, };
> > + uint32_t overlap = 0;
> > +
> > FLOW_TRACE();
> > for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
> > @@ -1009,6 +1022,10 @@ enic_copy_action_v2(const struct rte_flow_action actions[],
> > const struct rte_flow_action_queue *queue =
> > (const struct rte_flow_action_queue *)
> > actions->conf;
> > +
> > + if (overlap & FATE)
> > + return ENOTSUP;
> > + overlap |= FATE;
> > enic_action->rq_idx =
> > enic_rte_rq_idx_to_sop_idx(queue->index);
> > enic_action->flags |= FILTER_ACTION_RQ_STEERING_FLAG;
> > @@ -1019,6 +1036,9 @@ enic_copy_action_v2(const struct rte_flow_action actions[],
> > (const struct rte_flow_action_mark *)
> > actions->conf;
> > + if (overlap & MARK)
>
> Same
>
> > + return ENOTSUP;
> > + overlap |= MARK;
> > /* ENIC_MAGIC_FILTER_ID is reserved and is the highest
> > * in the range of allows mark ids.
> > */
> > @@ -1029,6 +1049,9 @@ enic_copy_action_v2(const struct rte_flow_action actions[],
> > break;
> > }
> > case RTE_FLOW_ACTION_TYPE_FLAG: {
> > + if (overlap & MARK)
> > + return ENOTSUP;
> > + overlap |= MARK;
> > enic_action->filter_id = ENIC_MAGIC_FILTER_ID;
> > enic_action->flags |= FILTER_ACTION_FILTER_ID_FLAG;
> > break;
> > @@ -1044,6 +1067,8 @@ enic_copy_action_v2(const struct rte_flow_action actions[],
> > break;
> > }
> > }
> > + if (!overlap & FATE)
>
> Same
>
> > + return ENOTSUP;
> > enic_action->type = FILTER_ACTION_V2;
> > return 0;
> > }
>
> [...]
Thanks for reporting. These "!overlap" checks are indeed messy, oddly my own
compilation tests with GCC and clang did not report them.
I'll submit an updated version.
--
Adrien Mazarguil
6WIND
More information about the dev
mailing list