[PATCH 0/2] ethdev: add group set miss actions API
Introduce new group set miss actions API: rte_flow_group_set_miss_actions(). A group's miss actions are a set of actions to be performed in case of a miss on a group, i.e. when a packet didn't hit any flow rules in the group. Currently, the expected behavior in this case is undefined. In order to achieve such functionality, a user can add a flow rule that matches on all traffic with the lowest priority in the group - this is not explicit however, and can be overridden by another flow rule with a lower priority. This new API function allows a user to set a group's miss actions in an explicit way. RFC discussion: http://patches.dpdk.org/project/dpdk/patch/20230807133601.164018-1-tshmilov...@nvidia.com/ Tomer Shmilovich (2): ethdev: add group set miss actions API app/testpmd: add group set miss actions CLI commands .mailmap | 1 + app/test-pmd/cmdline_flow.c| 112 + app/test-pmd/config.c | 27 ++ app/test-pmd/testpmd.h | 2 + doc/guides/prog_guide/rte_flow.rst | 30 +++ doc/guides/rel_notes/release_23_11.rst | 5 ++ lib/ethdev/rte_flow.c | 22 + lib/ethdev/rte_flow.h | 35 lib/ethdev/rte_flow_driver.h | 7 ++ lib/ethdev/version.map | 3 + 10 files changed, 244 insertions(+) -- 2.34.1
[PATCH 2/2] app/testpmd: add group set miss actions CLI commands
Add testpmd CLI interface for the group set miss actions API: flow group 0 group_id 1 ingress set_miss_actions jump group 3 / end flow group 0 group_id 1 ingress set_miss_actions end Signed-off-by: Tomer Shmilovich Acked-by: Ori Kam --- app/test-pmd/cmdline_flow.c | 112 app/test-pmd/config.c | 27 + app/test-pmd/testpmd.h | 2 + 3 files changed, 141 insertions(+) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 94827bcc4a..b3b8893e37 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -86,6 +86,7 @@ enum index { PATTERN_TEMPLATE, ACTIONS_TEMPLATE, TABLE, + FLOW_GROUP, INDIRECT_ACTION, VALIDATE, CREATE, @@ -206,6 +207,13 @@ enum index { TABLE_PATTERN_TEMPLATE, TABLE_ACTIONS_TEMPLATE, + /* Group arguments */ + GROUP_ID, + GROUP_INGRESS, + GROUP_EGRESS, + GROUP_TRANSFER, + GROUP_SET_MISS_ACTIONS, + /* Tunnel arguments. */ TUNNEL_CREATE, TUNNEL_CREATE_TYPE, @@ -1293,6 +1301,14 @@ static const enum index next_at_destroy_attr[] = { ZERO, }; +static const enum index next_group_attr[] = { + GROUP_INGRESS, + GROUP_EGRESS, + GROUP_TRANSFER, + GROUP_SET_MISS_ACTIONS, + ZERO, +}; + static const enum index next_table_subcmd[] = { TABLE_CREATE, TABLE_DESTROY, @@ -2678,6 +2694,9 @@ static int parse_push(struct context *, const struct token *, static int parse_pull(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); +static int parse_group(struct context *, const struct token *, + const char *, unsigned int, + void *, unsigned int); static int parse_tunnel(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); @@ -3021,6 +3040,7 @@ static const struct token token_list[] = { PATTERN_TEMPLATE, ACTIONS_TEMPLATE, TABLE, + FLOW_GROUP, INDIRECT_ACTION, VALIDATE, CREATE, @@ -3411,6 +3431,46 @@ static const struct token token_list[] = { .call = parse_table, }, /* Top-level command. */ + [FLOW_GROUP] = { + .name = "group", + .help = "manage flow groups", + .next = NEXT(NEXT_ENTRY(GROUP_ID), NEXT_ENTRY(COMMON_PORT_ID)), + .args = ARGS(ARGS_ENTRY(struct buffer, port)), + .call = parse_group, + }, + /* Sub-level commands. */ + [GROUP_SET_MISS_ACTIONS] = { + .name = "set_miss_actions", + .help = "set group miss actions", + .next = NEXT(next_action), + .call = parse_group, + }, + /* Group arguments */ + [GROUP_ID] = { + .name = "group_id", + .help = "group id", + .next = NEXT(next_group_attr, NEXT_ENTRY(COMMON_GROUP_ID)), + .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), + }, + [GROUP_INGRESS] = { + .name = "ingress", + .help = "group ingress attr", + .next = NEXT(next_group_attr), + .call = parse_group, + }, + [GROUP_EGRESS] = { + .name = "egress", + .help = "group egress attr", + .next = NEXT(next_group_attr), + .call = parse_group, + }, + [GROUP_TRANSFER] = { + .name = "transfer", + .help = "group transfer attr", + .next = NEXT(next_group_attr), + .call = parse_group, + }, + /* Top-level command. */ [QUEUE] = { .name = "queue", .help = "queue a flow rule operation", @@ -10449,6 +10509,54 @@ parse_pull(struct context *ctx, const struct token *token, return len; } +static int +parse_group(struct context *ctx, const struct token *token, + const char *str, unsigned int len, + void *buf, unsigned int size) +{ + struct buffer *out = buf; + + /* Token name must match. */ + if (parse_default(ctx, token, str, len, NULL, 0) < 0) + return -1; + /* Nothing else to do if there is no buffer. */ + if (!out) + return len; + if (!out->command) { + if (ctx->curr != FLOW_GROUP) + return -1; + if (sizeof(*ou
[PATCH 1/2] ethdev: add group set miss actions API
Introduce new group set miss actions API: rte_flow_group_set_miss_actions(). A group's miss actions are a set of actions to be performed in case of a miss on a group, meaning a packet didn't hit any rules in the group. This API function allows a user to set a group's miss actions. Signed-off-by: Tomer Shmilovich Acked-by: Ori Kam --- .mailmap | 1 + doc/guides/prog_guide/rte_flow.rst | 30 ++ doc/guides/rel_notes/release_23_11.rst | 5 lib/ethdev/rte_flow.c | 22 lib/ethdev/rte_flow.h | 35 ++ lib/ethdev/rte_flow_driver.h | 7 ++ lib/ethdev/version.map | 3 +++ 7 files changed, 103 insertions(+) diff --git a/.mailmap b/.mailmap index 864d33ee46..0cd6be849e 100644 --- a/.mailmap +++ b/.mailmap @@ -1411,6 +1411,7 @@ Tom Barbette Tom Crugnale Tom Millington Tom Rix +Tomer Shmilovich Tone Zhang Tonghao Zhang Tony Nguyen diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index 5bc998a433..590d2a770e 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -3758,6 +3758,36 @@ Information about the number of available resources can be retrieved via struct rte_flow_queue_info *queue_info, struct rte_flow_error *error); +Group Miss Actions +~~ + +In an application, many flow rules share common group attributes, meaning they can be grouped and +classified together. A user can explicitly specify a set of actions performed on a packet when it +did not match any flows rules in a group using the following API: + +.. code-block:: c + + int + rte_flow_group_set_miss_actions(uint16_t port_id, + uint32_t group_id, + const struct rte_flow_group_attr *attr, + const struct rte_flow_action actions[], + struct rte_flow_error *error); + +For example, to configure a RTE_FLOW_TYPE_JUMP action as a miss action for ingress group 1: + +.. code-block:: c + + struct rte_flow_group_attr attr = {.ingress = 1}; + struct rte_flow_action act[] = { + /* Setting miss actions to jump to group 3 */ + [0] = {.type = RTE_FLOW_ACTION_TYPE_JUMP, + .conf = &(struct rte_flow_action_jump){.group = 3}}, + [1] = {.type = RTE_FLOW_ACTION_TYPE_END}, + }; + struct rte_flow_error err; + rte_flow_group_set_miss_actions(port, 1, &attr, act, &err); + Flow templates ~~ diff --git a/doc/guides/rel_notes/release_23_11.rst b/doc/guides/rel_notes/release_23_11.rst index 333e1d95a2..da0ddc2078 100644 --- a/doc/guides/rel_notes/release_23_11.rst +++ b/doc/guides/rel_notes/release_23_11.rst @@ -41,6 +41,11 @@ DPDK Release 23.11 New Features +* **Added flow group set miss actions.** + Introduced ``rte_flow_group_set_miss_actions()`` API to explicitly set a group's miss actions, + which are the actions to be performed on packets that didn't match any of the flow rules + in the group. + .. This section should contain new features added in this release. Sample format: diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index 271d854f78..a98d87265f 100644 --- a/lib/ethdev/rte_flow.c +++ b/lib/ethdev/rte_flow.c @@ -1973,6 +1973,28 @@ rte_flow_template_table_destroy(uint16_t port_id, NULL, rte_strerror(ENOTSUP)); } +int +rte_flow_group_set_miss_actions(uint16_t port_id, + uint32_t group_id, + const struct rte_flow_group_attr *attr, + const struct rte_flow_action actions[], + struct rte_flow_error *error) +{ + struct rte_eth_dev *dev = &rte_eth_devices[port_id]; + const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error); + + if (unlikely(!ops)) + return -rte_errno; + if (likely(!!ops->group_set_miss_actions)) { + return flow_err(port_id, + ops->group_set_miss_actions(dev, group_id, attr, actions, error), + error); + } + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, rte_strerror(ENOTSUP)); +} + struct rte_flow * rte_flow_async_create(uint16_t port_id, uint32_t queue_id, diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index 2ebb76dbc0..82548a8b93 100644 --- a/lib/ethdev/rte_flow.h +++ b/lib/ethdev/rte_flow.h @@ -129,6 +129,12 @@ struct rte_flow_attr { uint32_t reserved:29; /**< Reserved, must be zero. */ }
[PATCH] net/mlx5: supporting group set miss actions API
Add implementation for rte_flow_group_set_miss_actions() API. Signed-off-by: Tomer Shmilovich --- Depends-on: series-29572 ("ethdev: add group set miss actions API") Depends-on: patch-130772 ("net/mlx5: fix jump ipool entry size") Depends-on: patch-131567 ("net/mlx5/hws: supporting default miss table in HWS") drivers/net/mlx5/mlx5.h | 2 + drivers/net/mlx5/mlx5_flow.c| 41 + drivers/net/mlx5/mlx5_flow.h| 9 + drivers/net/mlx5/mlx5_flow_hw.c | 301 4 files changed, 353 insertions(+) diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index c587e13c63..1323bb4165 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -1848,6 +1848,8 @@ struct mlx5_priv { struct mlx5_hw_q *hw_q; /* HW steering rte flow table list header. */ LIST_HEAD(flow_hw_tbl, rte_flow_template_table) flow_hw_tbl; + /* HW steering rte flow group list header */ + LIST_HEAD(flow_hw_grp, mlx5_flow_group) flow_hw_grp; struct mlx5dr_action *hw_push_vlan[MLX5DR_TABLE_TYPE_MAX]; struct mlx5dr_action *hw_pop_vlan[MLX5DR_TABLE_TYPE_MAX]; struct mlx5dr_action **hw_vport; diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index f7f8f54eb4..2204fa05d2 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -1027,6 +1027,12 @@ static int mlx5_flow_table_destroy(struct rte_eth_dev *dev, struct rte_flow_template_table *table, struct rte_flow_error *error); +static int +mlx5_flow_group_set_miss_actions(struct rte_eth_dev *dev, +uint32_t group_id, +const struct rte_flow_group_attr *attr, +const struct rte_flow_action actions[], +struct rte_flow_error *error); static struct rte_flow * mlx5_flow_async_flow_create(struct rte_eth_dev *dev, uint32_t queue, @@ -1151,6 +1157,7 @@ static const struct rte_flow_ops mlx5_flow_ops = { .actions_template_destroy = mlx5_flow_actions_template_destroy, .template_table_create = mlx5_flow_table_create, .template_table_destroy = mlx5_flow_table_destroy, + .group_set_miss_actions = mlx5_flow_group_set_miss_actions, .async_create = mlx5_flow_async_flow_create, .async_create_by_index = mlx5_flow_async_flow_create_by_index, .async_destroy = mlx5_flow_async_flow_destroy, @@ -9286,6 +9293,40 @@ mlx5_flow_table_destroy(struct rte_eth_dev *dev, return fops->template_table_destroy(dev, table, error); } +/** + * PMD group set miss actions. + * + * @param[in] dev + * Pointer to the rte_eth_dev structure. + * @param[in] attr + * Pointer to group attributes + * @param[in] actions + * Array of actions + * @param[out] error + * Pointer to error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_flow_group_set_miss_actions(struct rte_eth_dev *dev, +uint32_t group_id, +const struct rte_flow_group_attr *attr, +const struct rte_flow_action actions[], +struct rte_flow_error *error) +{ + const struct mlx5_flow_driver_ops *fops; + struct rte_flow_attr fattr = {0}; + + if (flow_get_drv_type(dev, &fattr) != MLX5_FLOW_TYPE_HW) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "group set miss actions with incorrect steering mode"); + fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW); + return fops->group_set_miss_actions(dev, group_id, attr, actions, error); +} + /** * Enqueue flow creation. * diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 3a97975d69..5963474e10 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -1369,9 +1369,11 @@ struct mlx5_hw_action_template { /* mlx5 flow group struct. */ struct mlx5_flow_group { struct mlx5_list_entry entry; + LIST_ENTRY(mlx5_flow_group) next; struct rte_eth_dev *dev; /* Reference to corresponding device. */ struct mlx5dr_table *tbl; /* HWS table object. */ struct mlx5_hw_jump_action jump; /* Jump action. */ + struct mlx5_flow_group *miss_group; /* Group pointed to by miss action. */ enum mlx5dr_table_type type; /* Table type. */ uint32_t group_id; /* Group id. */ uint32_t idx; /* Group memory index. */ @@ -1872,6 +1874,12 @@ typedef int (*mlx5_flow_table_destroy_t) (struct rte_eth_dev *dev, struct rte_flow_template_table *table,
[RFC] ethdev: add group set miss actions API
Introduce new group set miss actions API: rte_flow_group_set_miss_actions(). A group's miss actions are a set of actions to be performed in case of a miss on a group, i.e. when a packet didn't hit any flow rules in the group. Currently, the expected behavior in this case is undefined. In order to achieve such functionality, a user can add a flow rule that matches on all traffic with the lowest priority in the group - this is not explicit however, and can be overridden by another flow rule with a lower priority. This new API function allows a user to set a group's miss actions in an explicit way. Signed-off-by: Tomer Shmilovich --- doc/guides/prog_guide/rte_flow.rst | 30 + lib/ethdev/rte_flow.c | 22 +++ lib/ethdev/rte_flow.h | 35 ++ lib/ethdev/rte_flow_driver.h | 7 ++ lib/ethdev/version.map | 3 +++ 5 files changed, 97 insertions(+) diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index 5bc998a433..590d2a770e 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -3758,6 +3758,36 @@ Information about the number of available resources can be retrieved via struct rte_flow_queue_info *queue_info, struct rte_flow_error *error); +Group Miss Actions +~~ + +In an application, many flow rules share common group attributes, meaning they can be grouped and +classified together. A user can explicitly specify a set of actions performed on a packet when it +did not match any flows rules in a group using the following API: + +.. code-block:: c + + int + rte_flow_group_set_miss_actions(uint16_t port_id, + uint32_t group_id, + const struct rte_flow_group_attr *attr, + const struct rte_flow_action actions[], + struct rte_flow_error *error); + +For example, to configure a RTE_FLOW_TYPE_JUMP action as a miss action for ingress group 1: + +.. code-block:: c + + struct rte_flow_group_attr attr = {.ingress = 1}; + struct rte_flow_action act[] = { + /* Setting miss actions to jump to group 3 */ + [0] = {.type = RTE_FLOW_ACTION_TYPE_JUMP, + .conf = &(struct rte_flow_action_jump){.group = 3}}, + [1] = {.type = RTE_FLOW_ACTION_TYPE_END}, + }; + struct rte_flow_error err; + rte_flow_group_set_miss_actions(port, 1, &attr, act, &err); + Flow templates ~~ diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index 271d854f78..a98d87265f 100644 --- a/lib/ethdev/rte_flow.c +++ b/lib/ethdev/rte_flow.c @@ -1973,6 +1973,28 @@ rte_flow_template_table_destroy(uint16_t port_id, NULL, rte_strerror(ENOTSUP)); } +int +rte_flow_group_set_miss_actions(uint16_t port_id, + uint32_t group_id, + const struct rte_flow_group_attr *attr, + const struct rte_flow_action actions[], + struct rte_flow_error *error) +{ + struct rte_eth_dev *dev = &rte_eth_devices[port_id]; + const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error); + + if (unlikely(!ops)) + return -rte_errno; + if (likely(!!ops->group_set_miss_actions)) { + return flow_err(port_id, + ops->group_set_miss_actions(dev, group_id, attr, actions, error), + error); + } + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, rte_strerror(ENOTSUP)); +} + struct rte_flow * rte_flow_async_create(uint16_t port_id, uint32_t queue_id, diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index 86ed98c562..2d4fd49eb7 100644 --- a/lib/ethdev/rte_flow.h +++ b/lib/ethdev/rte_flow.h @@ -129,6 +129,12 @@ struct rte_flow_attr { uint32_t reserved:29; /**< Reserved, must be zero. */ }; +struct rte_flow_group_attr { + uint32_t ingress:1; + uint32_t egress:1; + uint32_t transfer:1; +}; + /** * Matching pattern item types. * @@ -5839,6 +5845,35 @@ rte_flow_template_table_destroy(uint16_t port_id, struct rte_flow_template_table *template_table, struct rte_flow_error *error); +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Set group miss actions. + * + * @param port_id + * Port identifier of Ethernet device. + * @param group_id + * Identifier of a group to set miss actions for. + * @param attr + * Group attributes. + * @param actions + * List of g
RE: [RFC] ethdev: add group set miss actions API
Hi Ivan, please see inline comments. Thanks, Tomer > -Original Message- > From: Ivan Malov > Sent: Tuesday, 8 August 2023 2:03 > To: Tomer Shmilovich > Cc: Ori Kam ; NBU-Contact-Thomas Monjalon > (EXTERNAL) ; Ferruh Yigit ; > Andrew Rybchenko ; dev@dpdk.org > Subject: Re: [RFC] ethdev: add group set miss actions API > > External email: Use caution opening links or attachments > > > Hi Tomer, > > This is a good proposal overall, but it's a bit questionable with regard to > the > transfer domain and precisely group 0. > > Say, the user starts a DPDK application and plugs a PF to it, also plugs a > representor for a VF. If I'm not mistaken, in this case, default behaviour is > hardly "undefined" for group 0. Packets sent by a VF are expected to reach the > representor (and vice versa). Also, packets arriving on the physical port are > expected to hit the PF port, ethdev 0, for instance. > True. > Does this new API intend to re-define this? I mean, if the application fails > to set > the default action for group 0 (ENOTSUP), shall it assume that the behaviour > will be as described above? And if it succeeds, then assume that such implicit > interconnections cease functioning? > > So, this API is something like "isolated mode" > in the case of non-transfer API, but allowing to choose a "default" action > rather than DROP? You have a point. These are the default "miss actions" for all use cases as I understand them: Transfer - miss group 0 - goes to the other side of the connection: rep --> VF, VF --> rep. Transfer - miss group > 0 - goes to E-switch manager (proxy port). Ingress - miss group 0 - goes to application when expected (i.e. promiscuous mode); otherwise drop/go to kernel in case of bifurcated driver. Ingress - miss group > 0 - drop. Egress - miss any group - goes to wire. I suggest documenting these default "miss actions", and have the new function update the miss actions for a given group. If an application sets the group's miss actions as none (i.e. actions[0].type == RTE_FLOW_ACTION_TYPE_END), the miss actions should be restored to the aforementioned default miss actions. Also, a different PMD may define other default miss actions and they should be documented in the NIC doc. > > Also, it is not quite clear how the new API is supposed to co-exist with the > transfer proxy concept. Has this been properly considered? All transfer groups are created on the proxy port, so I don't see any conflict when taking into consideration the above definition. > > Thank you. > > On Mon, 7 Aug 2023, Tomer Shmilovich wrote: > > > Introduce new group set miss actions API: > > rte_flow_group_set_miss_actions(). > > > > A group's miss actions are a set of actions to be performed in case of > > a miss on a group, i.e. when a packet didn't hit any flow rules in the > > group. > > > > Currently, the expected behavior in this case is undefined. > > In order to achieve such functionality, a user can add a flow rule > > that matches on all traffic with the lowest priority in the group - > > this is not explicit however, and can be overridden by another flow > > rule with a lower priority. > > > > This new API function allows a user to set a group's miss actions in > > an explicit way. > > > > Signed-off-by: Tomer Shmilovich > > --- > > doc/guides/prog_guide/rte_flow.rst | 30 + > > lib/ethdev/rte_flow.c | 22 +++ > > lib/ethdev/rte_flow.h | 35 ++ > > lib/ethdev/rte_flow_driver.h | 7 ++ > > lib/ethdev/version.map | 3 +++ > > 5 files changed, 97 insertions(+) > > > > diff --git a/doc/guides/prog_guide/rte_flow.rst > > b/doc/guides/prog_guide/rte_flow.rst > > index 5bc998a433..590d2a770e 100644 > > --- a/doc/guides/prog_guide/rte_flow.rst > > +++ b/doc/guides/prog_guide/rte_flow.rst > > @@ -3758,6 +3758,36 @@ Information about the number of available > resources can be retrieved via > > struct rte_flow_queue_info *queue_info, > > struct rte_flow_error *error); > > > > +Group Miss Actions > > +~~ > > + > > +In an application, many flow rules share common group attributes, > > +meaning they can be grouped and classified together. A user can > > +explicitly specify a set of actions performed on a packet when it did not > match any flows rules in a group using the following API: > > + > > +.. code-block:: c > > + > > + int > &