@@ -296,6 +296,124 @@ mlx5_eswitch_set_rule_source_port(struct mlx5_eswitch *esw,
296
296
}
297
297
}
298
298
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
+
299
417
struct mlx5_flow_handle *
300
418
mlx5_eswitch_add_offloaded_rule (struct mlx5_eswitch * esw ,
301
419
struct mlx5_flow_spec * spec ,
@@ -309,7 +427,7 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
309
427
struct mlx5_vport_tbl_attr fwd_attr ;
310
428
struct mlx5_flow_handle * rule ;
311
429
struct mlx5_flow_table * fdb ;
312
- int j , i = 0 ;
430
+ int i = 0 ;
313
431
314
432
if (esw -> mode != MLX5_ESWITCH_OFFLOADS )
315
433
return ERR_PTR (- EOPNOTSUPP );
@@ -331,49 +449,12 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
331
449
}
332
450
333
451
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 ;
377
458
}
378
459
}
379
460
@@ -437,8 +518,7 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
437
518
else if (attr -> chain || attr -> prio )
438
519
mlx5_chains_put_table (chains , attr -> chain , attr -> prio , 0 );
439
520
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 );
442
522
err_create_goto_table :
443
523
return rule ;
444
524
}
@@ -474,18 +554,8 @@ mlx5_eswitch_add_fwd_rule(struct mlx5_eswitch *esw,
474
554
}
475
555
476
556
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);
489
559
dest [i ].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE ;
490
560
dest [i ].ft = fwd_fdb ;
491
561
i ++ ;
@@ -552,8 +622,7 @@ __mlx5_eswitch_del_rule(struct mlx5_eswitch *esw,
552
622
esw_vport_tbl_put (esw , & fwd_attr );
553
623
else if (attr -> chain || attr -> prio )
554
624
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 );
557
626
}
558
627
}
559
628
0 commit comments