Hi, Please see comments below.
On Fri, Apr 17, 2026 at 06:21:04PM -0400, Rayane Boussanni wrote: > This patch implements missing validation logic for RSS and Connection > Tracking (ConnTrack) indirect actions in the Hardware Steering (HWS) > flow engine. > > Previously, these actions were accepted without being validated > against hardware capabilities, which could lead to unexpected behavior > when applying flow rules. The specialist validation functions > (mlx5_hw_validate_action_rss and mlx5_hw_validate_action_conntrack) > already existed but were not wired up to the indirect action handler. > > The signature of flow_hw_validate_action_indirect was updated to > include the actions template attributes (attr), allowing it to pass > the necessary traffic direction context (ingress/egress/transfer) > to the underlying validation specialists. > > Signed-off-by: Rayane Boussanni <[email protected]> > --- > drivers/net/mlx5/mlx5_flow_hw.c | 29 +++++++++++++++++++++++++++-- > 1 file changed, 27 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c > index bca5b2769e..ec1cdbe1fa 100644 > --- a/drivers/net/mlx5/mlx5_flow_hw.c > +++ b/drivers/net/mlx5/mlx5_flow_hw.c > @@ -346,6 +346,21 @@ mlx5_flow_ct_init(struct rte_eth_dev *dev, > uint32_t nb_conn_tracks, > uint16_t nb_queue); > > +static int > +mlx5_hw_validate_action_rss(struct rte_eth_dev *dev, > + const struct rte_flow_action *action, > + const struct rte_flow_action *mask, > + const struct rte_flow_actions_template_attr *attr, > + uint64_t action_flags, > + struct rte_flow_error *error); > +static int > +mlx5_hw_validate_action_conntrack(struct rte_eth_dev *dev, > + const struct rte_flow_action *action, > + const struct rte_flow_action *mask, > + const struct rte_flow_actions_template_attr > *attr, > + uint64_t action_flags, > + struct rte_flow_error *error); > + > static __rte_always_inline uint32_t flow_hw_tx_tag_regc_mask(struct > rte_eth_dev *dev); > static __rte_always_inline uint32_t flow_hw_tx_tag_regc_value(struct > rte_eth_dev *dev); > > @@ -6604,6 +6619,8 @@ flow_hw_validate_action_meter_mark(struct rte_eth_dev > *dev, > * Pointer to the indirect action. > * @param[in] mask > * Pointer to the indirect action mask. > + * @param[in] attr > + * Pointer to the action template attributes. > * @param[in, out] action_flags > * Holds the actions detected until now. > * @param[in, out] fixed_cnt > @@ -6618,6 +6635,7 @@ static int > flow_hw_validate_action_indirect(struct rte_eth_dev *dev, > const struct rte_flow_action *action, > const struct rte_flow_action *mask, > + const struct rte_flow_actions_template_attr > *attr, > uint64_t *action_flags, bool *fixed_cnt, > struct rte_flow_error *error) > { > @@ -6637,11 +6655,17 @@ flow_hw_validate_action_indirect(struct rte_eth_dev > *dev, > *action_flags |= MLX5_FLOW_ACTION_METER; > break; > case RTE_FLOW_ACTION_TYPE_RSS: > - /* TODO: Validation logic (same as flow_hw_actions_validate) */ > + ret = mlx5_hw_validate_action_rss(dev, action, mask, attr, > + *action_flags, error); > + if (ret < 0) > + return ret; > *action_flags |= MLX5_FLOW_ACTION_RSS; > break; This change causes a segfault (see at [1] below). mlx5_hw_validate_action_rss() and cannot be used here to validate indirect RSS. This function expects action param to contain valid action configuration i.e., filled in rte_flow_action_rss struct. For indirect actions, action->conf will contain opaque action handle (pointer to rte_flow_action_handle). RSS indirect action will be created before flow_hw_validate_action_indirect() is called and it will already be validated (see flow_hw_action_handle_validate()). In this function, it will be enough to check if attributes are good for RSS. Could you please adjust mlx5_hw_validate_action_rss() to only validate template's attributes for indirect actions? > case RTE_FLOW_ACTION_TYPE_CONNTRACK: > - /* TODO: Validation logic (same as flow_hw_actions_validate) */ > + ret = mlx5_hw_validate_action_conntrack(dev, action, mask, attr, > + *action_flags, error); > + if (ret < 0) > + return ret; > *action_flags |= MLX5_FLOW_ACTION_CT; > break; > case RTE_FLOW_ACTION_TYPE_COUNT: > @@ -7352,6 +7376,7 @@ mlx5_flow_hw_actions_validate(struct rte_eth_dev *dev, > case RTE_FLOW_ACTION_TYPE_INDIRECT: > ret = flow_hw_validate_action_indirect(dev, action, > mask, > + attr, > &action_flags, > &fixed_cnt, > error); Best regards, Dariusz Sosnowski --- [1]: testpmd command line: dpdk-testpmd -a 08:00.0,dv_flow_en=2 -- --flow-isolate-all --rxq=4 --txq=4 -i testpmd commands: port stop 0 flow configure 0 queues_number 4 queues_size 64 port start 0 flow queue 0 indirect_action 0 create ingress action_id 10 action rss func toeplitz types ipv4 end queues 0 1 2 3 end / end flow push 0 queue 0 flow pull 0 queue 0 flow actions_template 0 create ingress actions_template_id 1000 template indirect 10 / end mask rss / end segfault backtrace: Thread 1 "dpdk-testpmd" received signal SIGSEGV, Segmentation fault. 0x0000555556aebb0c in mlx5_validate_action_rss (dev=0x55555a436a80 <rte_eth_devices>, action=0x7fffffff8718, error=0x7fffffff8560) at ../drivers/net/mlx5/mlx5_flow.c:2225 2225 if (rss->func == RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) { (gdb) bt #0 0x0000555556aebb0c in mlx5_validate_action_rss (dev=0x55555a436a80 <rte_eth_devices>, action=0x7fffffff8718, error=0x7fffffff8560) at ../drivers/net/mlx5/mlx5_flow.c:2225 #1 0x000055555998f553 in mlx5_hw_validate_action_rss (dev=0x55555a436a80 <rte_eth_devices>, template_action=0x7fffffff8718, template_mask=0x7fffffff8738, template_attr=0x7fffffff85b4, action_flags=0, error=0x7fffffff8560) at ../drivers/net/mlx5/mlx5_flow_hw.c:7176 #2 0x000055555998e3ca in flow_hw_validate_action_indirect (dev=0x55555a436a80 <rte_eth_devices>, action=0x7fffffff8718, mask=0x7fffffff8738, attr=0x7fffffff85b4, action_flags=0x7fffffff78e0, fixed_cnt=0x7fffffff78d8, error=0x7fffffff8560) at ../drivers/net/mlx5/mlx5_flow_hw.c:6658 #3 0x000055555998fd44 in mlx5_flow_hw_actions_validate (dev=0x55555a436a80 <rte_eth_devices>, attr=0x7fffffff85b4, actions=0x7fffffff8718, masks=0x7fffffff8738, act_flags=0x7fffffff79a8, error=0x7fffffff8560) at ../drivers/net/mlx5/mlx5_flow_hw.c:7377 #4 0x00005555599a0c71 in __flow_hw_actions_template_create (dev=0x55555a436a80 <rte_eth_devices>, attr=0x7fffffff85b4, actions=0x7fffffff8718, masks=0x7fffffff8738, nt_mode=false, error=0x7fffffff8560) at ../drivers/net/mlx5/mlx5_flow_hw.c:8149 #5 0x00005555599a1a48 in flow_hw_actions_template_create (dev=0x55555a436a80 <rte_eth_devices>, attr=0x7fffffff85b4, actions=0x7fffffff8718, masks=0x7fffffff8738, error=0x7fffffff8560) at ../drivers/net/mlx5/mlx5_flow_hw.c:8372 #6 0x0000555556b4e6c1 in mlx5_flow_actions_template_create (dev=0x55555a436a80 <rte_eth_devices>, attr=0x7fffffff85b4, actions=0x7fffffff8718, masks=0x7fffffff8738, error=0x7fffffff8560) at ../drivers/net/mlx5/mlx5_flow.c:9496 #7 0x0000555556890e21 in rte_flow_actions_template_create (port_id=0, template_attr=0x7fffffff85b4, actions=0x7fffffff8718, masks=0x7fffffff8738, error=0x7fffffff8560) at ../lib/ethdev/rte_flow.c:1908 #8 0x00005555557335d6 in port_flow_actions_template_create (port_id=0, id=1000, attr=0x7fffffff85b4, actions=0x7fffffff8718, masks=0x7fffffff8738) at ../app/test-pmd/config.c:2545 #9 0x0000555555681a97 in cmd_flow_parsed (in=0x7fffffff8670) at ../app/test-pmd/cmdline_flow.c:13410 #10 0x00005555556823d5 in cmd_flow_cb (arg0=0x7fffffff8670, cl=0x55555a6f4a50, arg2=0x0) at ../app/test-pmd/cmdline_flow.c:13634 #11 0x00005555567df3ae in __cmdline_parse (cl=0x55555a6f4a50, buf=0x55555a6f4a98 "flow actions_template 0 create ingress actions_template_id 1000 template indirect 10 / end mask rss / end\n", call_fn=true) at ../lib/cmdline/cmdline_parse.c:296 #12 0x00005555567df3f6 in cmdline_parse (cl=0x55555a6f4a50, buf=0x55555a6f4a98 "flow actions_template 0 create ingress actions_template_id 1000 template indirect 10 / end mask rss / end\n") at ../lib/cmdline/cmdline_parse.c:305 #13 0x00005555567dd719 in cmdline_valid_buffer (rdl=0x55555a6f4a60, buf=0x55555a6f4a98 "flow actions_template 0 create ingress actions_template_id 1000 template indirect 10 / end mask rss / end\n", size=107) at ../lib/cmdline/cmdline.c:25 #14 0x00005555567e28f5 in rdline_char_in (rdl=0x55555a6f4a60, c=10 '\n') at ../lib/cmdline/cmdline_rdline.c:470 #15 0x00005555567ddb6f in cmdline_in (cl=0x55555a6f4a50, buf=0x7fffffffe7b7 "\n", size=1) at ../lib/cmdline/cmdline.c:154 #16 0x00005555567ddd24 in cmdline_interact (cl=0x55555a6f4a50) at ../lib/cmdline/cmdline.c:202 #17 0x000055555567469b in cmdline_read_from_file (filename=0x55555a03de00 <cmdline_files> "indirect-rss-segfault.txt", echo=true) at ../app/test-pmd/cmdline.c:14550 #18 0x00005555557bc83c in main (argc=6, argv=0x7fffffffea70) at ../app/test-pmd/testpmd.c:4780 (gdb) p rss $1 = (const void *) 0x1

