Skip to content

Commit 9e51c0a

Browse files
w1ldptrSaeed Mahameed
authored andcommitted
net/mlx5: E-Switch, Refactor rule offload forward action processing
Following patches in the series extend forwarding functionality with VF tunnel TX and RX handling. Extract action forwarding processing code into dedicated functions to simplify further extensions: - Handle every forwarding case with dedicated function instead of inline code. - Extract forwarding dest dispatch conditional into helper function esw_setup_dests(). - Unify forwaring cleanup code in error path of mlx5_eswitch_add_offloaded_rule() and in rule deletion code of __mlx5_eswitch_del_rule() in new helper function esw_cleanup_dests() (dual to new esw_setup_dests() helper). This patch does not change functionality. Co-developed-by: Dmytro Linkin <[email protected]> Signed-off-by: Dmytro Linkin <[email protected]> Signed-off-by: Vlad Buslov <[email protected]> Reviewed-by: Roi Dayan <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 275c21d commit 9e51c0a

File tree

1 file changed

+129
-60
lines changed

1 file changed

+129
-60
lines changed

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

Lines changed: 129 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,124 @@ mlx5_eswitch_set_rule_source_port(struct mlx5_eswitch *esw,
296296
}
297297
}
298298

299+
static void
300+
esw_setup_ft_dest(struct mlx5_flow_destination *dest,
301+
struct mlx5_flow_act *flow_act,
302+
struct mlx5_flow_attr *attr,
303+
int i)
304+
{
305+
flow_act->flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
306+
dest[i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
307+
dest[i].ft = attr->dest_ft;
308+
}
309+
310+
static void
311+
esw_setup_slow_path_dest(struct mlx5_flow_destination *dest,
312+
struct mlx5_flow_act *flow_act,
313+
struct mlx5_fs_chains *chains,
314+
int i)
315+
{
316+
flow_act->flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
317+
dest[i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
318+
dest[i].ft = mlx5_chains_get_tc_end_ft(chains);
319+
}
320+
321+
static int
322+
esw_setup_chain_dest(struct mlx5_flow_destination *dest,
323+
struct mlx5_flow_act *flow_act,
324+
struct mlx5_fs_chains *chains,
325+
u32 chain, u32 prio, u32 level,
326+
int i)
327+
{
328+
struct mlx5_flow_table *ft;
329+
330+
flow_act->flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
331+
ft = mlx5_chains_get_table(chains, chain, prio, level);
332+
if (IS_ERR(ft))
333+
return PTR_ERR(ft);
334+
335+
dest[i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
336+
dest[i].ft = ft;
337+
return 0;
338+
}
339+
340+
static void
341+
esw_cleanup_chain_dest(struct mlx5_fs_chains *chains, u32 chain, u32 prio, u32 level)
342+
{
343+
mlx5_chains_put_table(chains, chain, prio, level);
344+
}
345+
346+
static void
347+
esw_setup_vport_dest(struct mlx5_flow_destination *dest, struct mlx5_flow_act *flow_act,
348+
struct mlx5_eswitch *esw, struct mlx5_esw_flow_attr *esw_attr,
349+
int attr_idx, int dest_idx, bool pkt_reformat)
350+
{
351+
dest[dest_idx].type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
352+
dest[dest_idx].vport.num = esw_attr->dests[attr_idx].rep->vport;
353+
dest[dest_idx].vport.vhca_id =
354+
MLX5_CAP_GEN(esw_attr->dests[attr_idx].mdev, vhca_id);
355+
if (MLX5_CAP_ESW(esw->dev, merged_eswitch))
356+
dest[dest_idx].vport.flags |= MLX5_FLOW_DEST_VPORT_VHCA_ID;
357+
if (esw_attr->dests[attr_idx].flags & MLX5_ESW_DEST_ENCAP) {
358+
if (pkt_reformat) {
359+
flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
360+
flow_act->pkt_reformat = esw_attr->dests[attr_idx].pkt_reformat;
361+
}
362+
dest[dest_idx].vport.flags |= MLX5_FLOW_DEST_VPORT_REFORMAT_ID;
363+
dest[dest_idx].vport.pkt_reformat = esw_attr->dests[attr_idx].pkt_reformat;
364+
}
365+
}
366+
367+
static int
368+
esw_setup_vport_dests(struct mlx5_flow_destination *dest, struct mlx5_flow_act *flow_act,
369+
struct mlx5_eswitch *esw, struct mlx5_esw_flow_attr *esw_attr,
370+
int i)
371+
{
372+
int j;
373+
374+
for (j = esw_attr->split_count; j < esw_attr->out_count; j++, i++)
375+
esw_setup_vport_dest(dest, flow_act, esw, esw_attr, j, i, true);
376+
return i;
377+
}
378+
379+
static int
380+
esw_setup_dests(struct mlx5_flow_destination *dest,
381+
struct mlx5_flow_act *flow_act,
382+
struct mlx5_eswitch *esw,
383+
struct mlx5_flow_attr *attr,
384+
int *i)
385+
{
386+
struct mlx5_esw_flow_attr *esw_attr = attr->esw_attr;
387+
struct mlx5_fs_chains *chains = esw_chains(esw);
388+
int err = 0;
389+
390+
if (attr->dest_ft) {
391+
esw_setup_ft_dest(dest, flow_act, attr, *i);
392+
(*i)++;
393+
} else if (attr->flags & MLX5_ESW_ATTR_FLAG_SLOW_PATH) {
394+
esw_setup_slow_path_dest(dest, flow_act, chains, *i);
395+
(*i)++;
396+
} else if (attr->dest_chain) {
397+
err = esw_setup_chain_dest(dest, flow_act, chains, attr->dest_chain,
398+
1, 0, *i);
399+
(*i)++;
400+
} else {
401+
*i = esw_setup_vport_dests(dest, flow_act, esw, esw_attr, *i);
402+
}
403+
404+
return err;
405+
}
406+
407+
static void
408+
esw_cleanup_dests(struct mlx5_eswitch *esw,
409+
struct mlx5_flow_attr *attr)
410+
{
411+
struct mlx5_fs_chains *chains = esw_chains(esw);
412+
413+
if (!(attr->flags & MLX5_ESW_ATTR_FLAG_SLOW_PATH) && attr->dest_chain)
414+
esw_cleanup_chain_dest(chains, attr->dest_chain, 1, 0);
415+
}
416+
299417
struct mlx5_flow_handle *
300418
mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
301419
struct mlx5_flow_spec *spec,
@@ -309,7 +427,7 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
309427
struct mlx5_vport_tbl_attr fwd_attr;
310428
struct mlx5_flow_handle *rule;
311429
struct mlx5_flow_table *fdb;
312-
int j, i = 0;
430+
int i = 0;
313431

314432
if (esw->mode != MLX5_ESWITCH_OFFLOADS)
315433
return ERR_PTR(-EOPNOTSUPP);
@@ -331,49 +449,12 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
331449
}
332450

333451
if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
334-
struct mlx5_flow_table *ft;
335-
336-
if (attr->dest_ft) {
337-
flow_act.flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
338-
dest[i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
339-
dest[i].ft = attr->dest_ft;
340-
i++;
341-
} else if (attr->flags & MLX5_ESW_ATTR_FLAG_SLOW_PATH) {
342-
flow_act.flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
343-
dest[i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
344-
dest[i].ft = mlx5_chains_get_tc_end_ft(chains);
345-
i++;
346-
} else if (attr->dest_chain) {
347-
flow_act.flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
348-
ft = mlx5_chains_get_table(chains, attr->dest_chain,
349-
1, 0);
350-
if (IS_ERR(ft)) {
351-
rule = ERR_CAST(ft);
352-
goto err_create_goto_table;
353-
}
354-
355-
dest[i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
356-
dest[i].ft = ft;
357-
i++;
358-
} else {
359-
for (j = esw_attr->split_count; j < esw_attr->out_count; j++) {
360-
dest[i].type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
361-
dest[i].vport.num = esw_attr->dests[j].rep->vport;
362-
dest[i].vport.vhca_id =
363-
MLX5_CAP_GEN(esw_attr->dests[j].mdev, vhca_id);
364-
if (MLX5_CAP_ESW(esw->dev, merged_eswitch))
365-
dest[i].vport.flags |=
366-
MLX5_FLOW_DEST_VPORT_VHCA_ID;
367-
if (esw_attr->dests[j].flags & MLX5_ESW_DEST_ENCAP) {
368-
flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
369-
flow_act.pkt_reformat =
370-
esw_attr->dests[j].pkt_reformat;
371-
dest[i].vport.flags |= MLX5_FLOW_DEST_VPORT_REFORMAT_ID;
372-
dest[i].vport.pkt_reformat =
373-
esw_attr->dests[j].pkt_reformat;
374-
}
375-
i++;
376-
}
452+
int err;
453+
454+
err = esw_setup_dests(dest, &flow_act, esw, attr, &i);
455+
if (err) {
456+
rule = ERR_PTR(err);
457+
goto err_create_goto_table;
377458
}
378459
}
379460

@@ -437,8 +518,7 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
437518
else if (attr->chain || attr->prio)
438519
mlx5_chains_put_table(chains, attr->chain, attr->prio, 0);
439520
err_esw_get:
440-
if (!(attr->flags & MLX5_ESW_ATTR_FLAG_SLOW_PATH) && attr->dest_chain)
441-
mlx5_chains_put_table(chains, attr->dest_chain, 1, 0);
521+
esw_cleanup_dests(esw, attr);
442522
err_create_goto_table:
443523
return rule;
444524
}
@@ -474,18 +554,8 @@ mlx5_eswitch_add_fwd_rule(struct mlx5_eswitch *esw,
474554
}
475555

476556
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
477-
for (i = 0; i < esw_attr->split_count; i++) {
478-
dest[i].type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
479-
dest[i].vport.num = esw_attr->dests[i].rep->vport;
480-
dest[i].vport.vhca_id =
481-
MLX5_CAP_GEN(esw_attr->dests[i].mdev, vhca_id);
482-
if (MLX5_CAP_ESW(esw->dev, merged_eswitch))
483-
dest[i].vport.flags |= MLX5_FLOW_DEST_VPORT_VHCA_ID;
484-
if (esw_attr->dests[i].flags & MLX5_ESW_DEST_ENCAP) {
485-
dest[i].vport.flags |= MLX5_FLOW_DEST_VPORT_REFORMAT_ID;
486-
dest[i].vport.pkt_reformat = esw_attr->dests[i].pkt_reformat;
487-
}
488-
}
557+
for (i = 0; i < esw_attr->split_count; i++)
558+
esw_setup_vport_dest(dest, &flow_act, esw, esw_attr, i, i, false);
489559
dest[i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
490560
dest[i].ft = fwd_fdb;
491561
i++;
@@ -552,8 +622,7 @@ __mlx5_eswitch_del_rule(struct mlx5_eswitch *esw,
552622
esw_vport_tbl_put(esw, &fwd_attr);
553623
else if (attr->chain || attr->prio)
554624
mlx5_chains_put_table(chains, attr->chain, attr->prio, 0);
555-
if (attr->dest_chain)
556-
mlx5_chains_put_table(chains, attr->dest_chain, 1, 0);
625+
esw_cleanup_dests(esw, attr);
557626
}
558627
}
559628

0 commit comments

Comments
 (0)