@@ -158,7 +158,8 @@ struct mlx5_vdpa_net {
158
158
struct mutex reslock ;
159
159
struct mlx5_flow_table * rxft ;
160
160
struct mlx5_fc * rx_counter ;
161
- struct mlx5_flow_handle * rx_rule ;
161
+ struct mlx5_flow_handle * rx_rule_ucast ;
162
+ struct mlx5_flow_handle * rx_rule_mcast ;
162
163
bool setup ;
163
164
u32 cur_num_vqs ;
164
165
struct notifier_block nb ;
@@ -1383,59 +1384,98 @@ static int add_fwd_to_tir(struct mlx5_vdpa_net *ndev)
1383
1384
struct mlx5_flow_table_attr ft_attr = {};
1384
1385
struct mlx5_flow_act flow_act = {};
1385
1386
struct mlx5_flow_namespace * ns ;
1387
+ struct mlx5_flow_spec * spec ;
1388
+ void * headers_c ;
1389
+ void * headers_v ;
1390
+ u8 * dmac_c ;
1391
+ u8 * dmac_v ;
1386
1392
int err ;
1387
1393
1388
- /* for now, one entry, match all, forward to tir */
1389
- ft_attr .max_fte = 1 ;
1390
- ft_attr .autogroup .max_num_groups = 1 ;
1394
+ spec = kvzalloc (sizeof (* spec ), GFP_KERNEL );
1395
+ if (!spec )
1396
+ return - ENOMEM ;
1397
+
1398
+ spec -> match_criteria_enable = MLX5_MATCH_OUTER_HEADERS ;
1399
+ ft_attr .max_fte = 2 ;
1400
+ ft_attr .autogroup .max_num_groups = 2 ;
1391
1401
1392
1402
ns = mlx5_get_flow_namespace (ndev -> mvdev .mdev , MLX5_FLOW_NAMESPACE_BYPASS );
1393
1403
if (!ns ) {
1394
- mlx5_vdpa_warn (& ndev -> mvdev , "get flow namespace\n" );
1395
- return - EOPNOTSUPP ;
1404
+ mlx5_vdpa_warn (& ndev -> mvdev , "failed to get flow namespace\n" );
1405
+ err = - EOPNOTSUPP ;
1406
+ goto err_ns ;
1396
1407
}
1397
1408
1398
1409
ndev -> rxft = mlx5_create_auto_grouped_flow_table (ns , & ft_attr );
1399
- if (IS_ERR (ndev -> rxft ))
1400
- return PTR_ERR (ndev -> rxft );
1410
+ if (IS_ERR (ndev -> rxft )) {
1411
+ err = PTR_ERR (ndev -> rxft );
1412
+ goto err_ns ;
1413
+ }
1401
1414
1402
1415
ndev -> rx_counter = mlx5_fc_create (ndev -> mvdev .mdev , false);
1403
1416
if (IS_ERR (ndev -> rx_counter )) {
1404
1417
err = PTR_ERR (ndev -> rx_counter );
1405
1418
goto err_fc ;
1406
1419
}
1407
1420
1421
+ headers_c = MLX5_ADDR_OF (fte_match_param , spec -> match_criteria , outer_headers );
1422
+ dmac_c = MLX5_ADDR_OF (fte_match_param , headers_c , outer_headers .dmac_47_16 );
1423
+ memset (dmac_c , 0xff , ETH_ALEN );
1424
+ headers_v = MLX5_ADDR_OF (fte_match_param , spec -> match_value , outer_headers );
1425
+ dmac_v = MLX5_ADDR_OF (fte_match_param , headers_v , outer_headers .dmac_47_16 );
1426
+ ether_addr_copy (dmac_v , ndev -> config .mac );
1427
+
1408
1428
flow_act .action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | MLX5_FLOW_CONTEXT_ACTION_COUNT ;
1409
1429
dest [0 ].type = MLX5_FLOW_DESTINATION_TYPE_TIR ;
1410
1430
dest [0 ].tir_num = ndev -> res .tirn ;
1411
1431
dest [1 ].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER ;
1412
1432
dest [1 ].counter_id = mlx5_fc_id (ndev -> rx_counter );
1413
- ndev -> rx_rule = mlx5_add_flow_rules (ndev -> rxft , NULL , & flow_act , dest , 2 );
1414
- if (IS_ERR (ndev -> rx_rule )) {
1415
- err = PTR_ERR (ndev -> rx_rule );
1416
- ndev -> rx_rule = NULL ;
1417
- goto err_rule ;
1433
+ ndev -> rx_rule_ucast = mlx5_add_flow_rules (ndev -> rxft , spec , & flow_act , dest , 2 );
1434
+
1435
+ if (IS_ERR (ndev -> rx_rule_ucast )) {
1436
+ err = PTR_ERR (ndev -> rx_rule_ucast );
1437
+ ndev -> rx_rule_ucast = NULL ;
1438
+ goto err_rule_ucast ;
1439
+ }
1440
+
1441
+ memset (dmac_c , 0 , ETH_ALEN );
1442
+ memset (dmac_v , 0 , ETH_ALEN );
1443
+ dmac_c [0 ] = 1 ;
1444
+ dmac_v [0 ] = 1 ;
1445
+ flow_act .action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST ;
1446
+ ndev -> rx_rule_mcast = mlx5_add_flow_rules (ndev -> rxft , spec , & flow_act , dest , 1 );
1447
+ if (IS_ERR (ndev -> rx_rule_mcast )) {
1448
+ err = PTR_ERR (ndev -> rx_rule_mcast );
1449
+ ndev -> rx_rule_mcast = NULL ;
1450
+ goto err_rule_mcast ;
1418
1451
}
1419
1452
1453
+ kvfree (spec );
1420
1454
return 0 ;
1421
1455
1422
- err_rule :
1456
+ err_rule_mcast :
1457
+ mlx5_del_flow_rules (ndev -> rx_rule_ucast );
1458
+ ndev -> rx_rule_ucast = NULL ;
1459
+ err_rule_ucast :
1423
1460
mlx5_fc_destroy (ndev -> mvdev .mdev , ndev -> rx_counter );
1424
1461
err_fc :
1425
1462
mlx5_destroy_flow_table (ndev -> rxft );
1463
+ err_ns :
1464
+ kvfree (spec );
1426
1465
return err ;
1427
1466
}
1428
1467
1429
1468
static void remove_fwd_to_tir (struct mlx5_vdpa_net * ndev )
1430
1469
{
1431
- if (!ndev -> rx_rule )
1470
+ if (!ndev -> rx_rule_ucast )
1432
1471
return ;
1433
1472
1434
- mlx5_del_flow_rules (ndev -> rx_rule );
1473
+ mlx5_del_flow_rules (ndev -> rx_rule_mcast );
1474
+ ndev -> rx_rule_mcast = NULL ;
1475
+ mlx5_del_flow_rules (ndev -> rx_rule_ucast );
1476
+ ndev -> rx_rule_ucast = NULL ;
1435
1477
mlx5_fc_destroy (ndev -> mvdev .mdev , ndev -> rx_counter );
1436
1478
mlx5_destroy_flow_table (ndev -> rxft );
1437
-
1438
- ndev -> rx_rule = NULL ;
1439
1479
}
1440
1480
1441
1481
static virtio_net_ctrl_ack handle_ctrl_mac (struct mlx5_vdpa_dev * mvdev , u8 cmd )
0 commit comments