Skip to content

Commit 0f575c2

Browse files
ayalevinSaeed Mahameed
authored andcommitted
net/mlx5e: Introduce Flow Steering ANY API
Add a new FS API which captures the ANY traffic from the traffic classifier into a dedicated FS table. The table consists of a group matching the ethertype and a must-be-last group which contains a default rule redirecting the unmatched packets back to the RSS logic. Signed-off-by: Aya Levin <[email protected]> Reviewed-by: Tariq Toukan <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 1c80bd6 commit 0f575c2

File tree

4 files changed

+273
-1
lines changed

4 files changed

+273
-1
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en/fs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ enum {
138138
MLX5E_TTC_FT_LEVEL,
139139
MLX5E_INNER_TTC_FT_LEVEL,
140140
MLX5E_FS_TT_UDP_FT_LEVEL = MLX5E_INNER_TTC_FT_LEVEL + 1,
141+
MLX5E_FS_TT_ANY_FT_LEVEL = MLX5E_INNER_TTC_FT_LEVEL + 1,
141142
#ifdef CONFIG_MLX5_EN_TLS
142143
MLX5E_ACCEL_FS_TCP_FT_LEVEL = MLX5E_INNER_TTC_FT_LEVEL + 1,
143144
#endif
@@ -243,6 +244,7 @@ struct mlx5e_accel_fs_tcp;
243244
#endif
244245

245246
struct mlx5e_fs_udp;
247+
struct mlx5e_fs_any;
246248

247249
struct mlx5e_flow_steering {
248250
struct mlx5_flow_namespace *ns;
@@ -263,6 +265,7 @@ struct mlx5e_flow_steering {
263265
struct mlx5e_accel_fs_tcp *accel_tcp;
264266
#endif
265267
struct mlx5e_fs_udp *udp;
268+
struct mlx5e_fs_any *any;
266269
};
267270

268271
struct ttc_params {

drivers/net/ethernet/mellanox/mlx5/core/en/fs_tt_redirect.c

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ struct mlx5e_fs_udp {
1717
int ref_cnt;
1818
};
1919

20+
struct mlx5e_fs_any {
21+
struct mlx5e_flow_table table;
22+
struct mlx5_flow_handle *default_rule;
23+
int ref_cnt;
24+
};
25+
2026
static char *fs_udp_type2str(enum fs_udp_type i)
2127
{
2228
switch (i) {
@@ -341,3 +347,259 @@ int mlx5e_fs_tt_redirect_udp_create(struct mlx5e_priv *priv)
341347
priv->fs.udp = NULL;
342348
return err;
343349
}
350+
351+
static void fs_any_set_ethertype_flow(struct mlx5_flow_spec *spec, u16 ether_type)
352+
{
353+
spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
354+
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ethertype);
355+
MLX5_SET(fte_match_param, spec->match_value, outer_headers.ethertype, ether_type);
356+
}
357+
358+
struct mlx5_flow_handle *
359+
mlx5e_fs_tt_redirect_any_add_rule(struct mlx5e_priv *priv,
360+
u32 tir_num, u16 ether_type)
361+
{
362+
struct mlx5_flow_destination dest = {};
363+
struct mlx5_flow_table *ft = NULL;
364+
MLX5_DECLARE_FLOW_ACT(flow_act);
365+
struct mlx5_flow_handle *rule;
366+
struct mlx5_flow_spec *spec;
367+
struct mlx5e_fs_any *fs_any;
368+
int err;
369+
370+
spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
371+
if (!spec)
372+
return ERR_PTR(-ENOMEM);
373+
374+
fs_any = priv->fs.any;
375+
ft = fs_any->table.t;
376+
377+
fs_any_set_ethertype_flow(spec, ether_type);
378+
dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
379+
dest.tir_num = tir_num;
380+
381+
rule = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1);
382+
kvfree(spec);
383+
384+
if (IS_ERR(rule)) {
385+
err = PTR_ERR(rule);
386+
netdev_err(priv->netdev, "%s: add ANY rule failed, err %d\n",
387+
__func__, err);
388+
}
389+
return rule;
390+
}
391+
392+
static int fs_any_add_default_rule(struct mlx5e_priv *priv)
393+
{
394+
struct mlx5e_flow_table *fs_any_t;
395+
struct mlx5_flow_destination dest;
396+
MLX5_DECLARE_FLOW_ACT(flow_act);
397+
struct mlx5_flow_handle *rule;
398+
struct mlx5e_fs_any *fs_any;
399+
int err;
400+
401+
fs_any = priv->fs.any;
402+
fs_any_t = &fs_any->table;
403+
404+
dest = mlx5e_ttc_get_default_dest(priv, MLX5E_TT_ANY);
405+
rule = mlx5_add_flow_rules(fs_any_t->t, NULL, &flow_act, &dest, 1);
406+
if (IS_ERR(rule)) {
407+
err = PTR_ERR(rule);
408+
netdev_err(priv->netdev,
409+
"%s: add default rule failed, fs type=ANY, err %d\n",
410+
__func__, err);
411+
return err;
412+
}
413+
414+
fs_any->default_rule = rule;
415+
return 0;
416+
}
417+
418+
#define MLX5E_FS_ANY_NUM_GROUPS (2)
419+
#define MLX5E_FS_ANY_GROUP1_SIZE (BIT(16))
420+
#define MLX5E_FS_ANY_GROUP2_SIZE (BIT(0))
421+
#define MLX5E_FS_ANY_TABLE_SIZE (MLX5E_FS_ANY_GROUP1_SIZE +\
422+
MLX5E_FS_ANY_GROUP2_SIZE)
423+
424+
static int fs_any_create_groups(struct mlx5e_flow_table *ft)
425+
{
426+
int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
427+
void *outer_headers_c;
428+
int ix = 0;
429+
u32 *in;
430+
int err;
431+
u8 *mc;
432+
433+
ft->g = kcalloc(MLX5E_FS_UDP_NUM_GROUPS, sizeof(*ft->g), GFP_KERNEL);
434+
in = kvzalloc(inlen, GFP_KERNEL);
435+
if (!in || !ft->g) {
436+
kfree(ft->g);
437+
kvfree(in);
438+
return -ENOMEM;
439+
}
440+
441+
/* Match on ethertype */
442+
mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria);
443+
outer_headers_c = MLX5_ADDR_OF(fte_match_param, mc, outer_headers);
444+
MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, ethertype);
445+
MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
446+
MLX5_SET_CFG(in, start_flow_index, ix);
447+
ix += MLX5E_FS_ANY_GROUP1_SIZE;
448+
MLX5_SET_CFG(in, end_flow_index, ix - 1);
449+
ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
450+
if (IS_ERR(ft->g[ft->num_groups]))
451+
goto err;
452+
ft->num_groups++;
453+
454+
/* Default Flow Group */
455+
memset(in, 0, inlen);
456+
MLX5_SET_CFG(in, start_flow_index, ix);
457+
ix += MLX5E_FS_ANY_GROUP2_SIZE;
458+
MLX5_SET_CFG(in, end_flow_index, ix - 1);
459+
ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
460+
if (IS_ERR(ft->g[ft->num_groups]))
461+
goto err;
462+
ft->num_groups++;
463+
464+
kvfree(in);
465+
return 0;
466+
467+
err:
468+
err = PTR_ERR(ft->g[ft->num_groups]);
469+
ft->g[ft->num_groups] = NULL;
470+
kvfree(in);
471+
472+
return err;
473+
}
474+
475+
static int fs_any_create_table(struct mlx5e_priv *priv)
476+
{
477+
struct mlx5e_flow_table *ft = &priv->fs.any->table;
478+
struct mlx5_flow_table_attr ft_attr = {};
479+
int err;
480+
481+
ft->num_groups = 0;
482+
483+
ft_attr.max_fte = MLX5E_FS_UDP_TABLE_SIZE;
484+
ft_attr.level = MLX5E_FS_TT_ANY_FT_LEVEL;
485+
ft_attr.prio = MLX5E_NIC_PRIO;
486+
487+
ft->t = mlx5_create_flow_table(priv->fs.ns, &ft_attr);
488+
if (IS_ERR(ft->t)) {
489+
err = PTR_ERR(ft->t);
490+
ft->t = NULL;
491+
return err;
492+
}
493+
494+
netdev_dbg(priv->netdev, "Created fs ANY table id %u level %u\n",
495+
ft->t->id, ft->t->level);
496+
497+
err = fs_any_create_groups(ft);
498+
if (err)
499+
goto err;
500+
501+
err = fs_any_add_default_rule(priv);
502+
if (err)
503+
goto err;
504+
505+
return 0;
506+
507+
err:
508+
mlx5e_destroy_flow_table(ft);
509+
return err;
510+
}
511+
512+
static int fs_any_disable(struct mlx5e_priv *priv)
513+
{
514+
int err;
515+
516+
/* Modify ttc rules destination to point back to the indir TIRs */
517+
err = mlx5e_ttc_fwd_default_dest(priv, MLX5E_TT_ANY);
518+
if (err) {
519+
netdev_err(priv->netdev,
520+
"%s: modify ttc[%d] default destination failed, err(%d)\n",
521+
__func__, MLX5E_TT_ANY, err);
522+
return err;
523+
}
524+
return 0;
525+
}
526+
527+
static int fs_any_enable(struct mlx5e_priv *priv)
528+
{
529+
struct mlx5_flow_destination dest = {};
530+
int err;
531+
532+
dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
533+
dest.ft = priv->fs.any->table.t;
534+
535+
/* Modify ttc rules destination to point on the accel_fs FTs */
536+
err = mlx5e_ttc_fwd_dest(priv, MLX5E_TT_ANY, &dest);
537+
if (err) {
538+
netdev_err(priv->netdev,
539+
"%s: modify ttc[%d] destination to accel failed, err(%d)\n",
540+
__func__, MLX5E_TT_ANY, err);
541+
return err;
542+
}
543+
return 0;
544+
}
545+
546+
static void fs_any_destroy_table(struct mlx5e_fs_any *fs_any)
547+
{
548+
if (IS_ERR_OR_NULL(fs_any->table.t))
549+
return;
550+
551+
mlx5_del_flow_rules(fs_any->default_rule);
552+
mlx5e_destroy_flow_table(&fs_any->table);
553+
fs_any->table.t = NULL;
554+
}
555+
556+
void mlx5e_fs_tt_redirect_any_destroy(struct mlx5e_priv *priv)
557+
{
558+
struct mlx5e_fs_any *fs_any = priv->fs.any;
559+
560+
if (!fs_any)
561+
return;
562+
563+
if (--fs_any->ref_cnt)
564+
return;
565+
566+
fs_any_disable(priv);
567+
568+
fs_any_destroy_table(fs_any);
569+
570+
kfree(fs_any);
571+
priv->fs.any = NULL;
572+
}
573+
574+
int mlx5e_fs_tt_redirect_any_create(struct mlx5e_priv *priv)
575+
{
576+
int err;
577+
578+
if (priv->fs.any) {
579+
priv->fs.any->ref_cnt++;
580+
return 0;
581+
}
582+
583+
priv->fs.any = kzalloc(sizeof(*priv->fs.any), GFP_KERNEL);
584+
if (!priv->fs.any)
585+
return -ENOMEM;
586+
587+
err = fs_any_create_table(priv);
588+
if (err)
589+
return err;
590+
591+
err = fs_any_enable(priv);
592+
if (err)
593+
goto err_destroy_table;
594+
595+
priv->fs.any->ref_cnt = 1;
596+
597+
return 0;
598+
599+
err_destroy_table:
600+
fs_any_destroy_table(priv->fs.any);
601+
602+
kfree(priv->fs.any);
603+
priv->fs.any = NULL;
604+
return err;
605+
}

drivers/net/ethernet/mellanox/mlx5/core/en/fs_tt_redirect.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,11 @@ mlx5e_fs_tt_redirect_udp_add_rule(struct mlx5e_priv *priv,
1616
u32 tir_num, u16 d_port);
1717
void mlx5e_fs_tt_redirect_udp_destroy(struct mlx5e_priv *priv);
1818
int mlx5e_fs_tt_redirect_udp_create(struct mlx5e_priv *priv);
19+
20+
/* ANY traffic type redirect*/
21+
struct mlx5_flow_handle *
22+
mlx5e_fs_tt_redirect_any_add_rule(struct mlx5e_priv *priv,
23+
u32 tir_num, u16 ether_type);
24+
void mlx5e_fs_tt_redirect_any_destroy(struct mlx5e_priv *priv);
25+
int mlx5e_fs_tt_redirect_any_create(struct mlx5e_priv *priv);
1926
#endif

drivers/net/ethernet/mellanox/mlx5/core/fs_core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@
105105
#define ETHTOOL_PRIO_NUM_LEVELS 1
106106
#define ETHTOOL_NUM_PRIOS 11
107107
#define ETHTOOL_MIN_LEVEL (KERNEL_MIN_LEVEL + ETHTOOL_NUM_PRIOS)
108-
/* Promiscuous, Vlan, mac, ttc, inner ttc, {UDP/aRFS/accel/{esp, esp_err}} */
108+
/* Promiscuous, Vlan, mac, ttc, inner ttc, {UDP/ANY/aRFS/accel/{esp, esp_err}} */
109109
#define KERNEL_NIC_PRIO_NUM_LEVELS 7
110110
#define KERNEL_NIC_NUM_PRIOS 1
111111
/* One more level for tc */

0 commit comments

Comments
 (0)