@@ -1369,11 +1369,20 @@ static int mlx5_ib_destroy_flow(struct ib_flow *flow_id)
1369
1369
return 0 ;
1370
1370
}
1371
1371
1372
+ static int ib_prio_to_core_prio (unsigned int priority , bool dont_trap )
1373
+ {
1374
+ priority *= 2 ;
1375
+ if (!dont_trap )
1376
+ priority ++ ;
1377
+ return priority ;
1378
+ }
1379
+
1372
1380
#define MLX5_FS_MAX_TYPES 10
1373
1381
#define MLX5_FS_MAX_ENTRIES 32000UL
1374
1382
static struct mlx5_ib_flow_prio * get_flow_table (struct mlx5_ib_dev * dev ,
1375
1383
struct ib_flow_attr * flow_attr )
1376
1384
{
1385
+ bool dont_trap = flow_attr -> flags & IB_FLOW_ATTR_FLAGS_DONT_TRAP ;
1377
1386
struct mlx5_flow_namespace * ns = NULL ;
1378
1387
struct mlx5_ib_flow_prio * prio ;
1379
1388
struct mlx5_flow_table * ft ;
@@ -1383,10 +1392,12 @@ static struct mlx5_ib_flow_prio *get_flow_table(struct mlx5_ib_dev *dev,
1383
1392
int err = 0 ;
1384
1393
1385
1394
if (flow_attr -> type == IB_FLOW_ATTR_NORMAL ) {
1386
- if (flow_is_multicast_only (flow_attr ))
1395
+ if (flow_is_multicast_only (flow_attr ) &&
1396
+ !dont_trap )
1387
1397
priority = MLX5_IB_FLOW_MCAST_PRIO ;
1388
1398
else
1389
- priority = flow_attr -> priority ;
1399
+ priority = ib_prio_to_core_prio (flow_attr -> priority ,
1400
+ dont_trap );
1390
1401
ns = mlx5_get_flow_namespace (dev -> mdev ,
1391
1402
MLX5_FLOW_NAMESPACE_BYPASS );
1392
1403
num_entries = MLX5_FS_MAX_ENTRIES ;
@@ -1434,6 +1445,7 @@ static struct mlx5_ib_flow_handler *create_flow_rule(struct mlx5_ib_dev *dev,
1434
1445
unsigned int spec_index ;
1435
1446
u32 * match_c ;
1436
1447
u32 * match_v ;
1448
+ u32 action ;
1437
1449
int err = 0 ;
1438
1450
1439
1451
if (!is_valid_attr (flow_attr ))
@@ -1459,9 +1471,11 @@ static struct mlx5_ib_flow_handler *create_flow_rule(struct mlx5_ib_dev *dev,
1459
1471
1460
1472
/* Outer header support only */
1461
1473
match_criteria_enable = (!outer_header_zero (match_c )) << 0 ;
1474
+ action = dst ? MLX5_FLOW_CONTEXT_ACTION_FWD_DEST :
1475
+ MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO ;
1462
1476
handler -> rule = mlx5_add_flow_rule (ft , match_criteria_enable ,
1463
1477
match_c , match_v ,
1464
- MLX5_FLOW_CONTEXT_ACTION_FWD_DEST ,
1478
+ action ,
1465
1479
MLX5_FS_DEFAULT_FLOW_TAG ,
1466
1480
dst );
1467
1481
@@ -1481,6 +1495,29 @@ static struct mlx5_ib_flow_handler *create_flow_rule(struct mlx5_ib_dev *dev,
1481
1495
return err ? ERR_PTR (err ) : handler ;
1482
1496
}
1483
1497
1498
+ static struct mlx5_ib_flow_handler * create_dont_trap_rule (struct mlx5_ib_dev * dev ,
1499
+ struct mlx5_ib_flow_prio * ft_prio ,
1500
+ struct ib_flow_attr * flow_attr ,
1501
+ struct mlx5_flow_destination * dst )
1502
+ {
1503
+ struct mlx5_ib_flow_handler * handler_dst = NULL ;
1504
+ struct mlx5_ib_flow_handler * handler = NULL ;
1505
+
1506
+ handler = create_flow_rule (dev , ft_prio , flow_attr , NULL );
1507
+ if (!IS_ERR (handler )) {
1508
+ handler_dst = create_flow_rule (dev , ft_prio ,
1509
+ flow_attr , dst );
1510
+ if (IS_ERR (handler_dst )) {
1511
+ mlx5_del_flow_rule (handler -> rule );
1512
+ kfree (handler );
1513
+ handler = handler_dst ;
1514
+ } else {
1515
+ list_add (& handler_dst -> list , & handler -> list );
1516
+ }
1517
+ }
1518
+
1519
+ return handler ;
1520
+ }
1484
1521
enum {
1485
1522
LEFTOVERS_MC ,
1486
1523
LEFTOVERS_UC ,
@@ -1558,7 +1595,7 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp,
1558
1595
1559
1596
if (domain != IB_FLOW_DOMAIN_USER ||
1560
1597
flow_attr -> port > MLX5_CAP_GEN (dev -> mdev , num_ports ) ||
1561
- flow_attr -> flags )
1598
+ ( flow_attr -> flags & ~ IB_FLOW_ATTR_FLAGS_DONT_TRAP ) )
1562
1599
return ERR_PTR (- EINVAL );
1563
1600
1564
1601
dst = kzalloc (sizeof (* dst ), GFP_KERNEL );
@@ -1577,8 +1614,13 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp,
1577
1614
dst -> tir_num = to_mqp (qp )-> raw_packet_qp .rq .tirn ;
1578
1615
1579
1616
if (flow_attr -> type == IB_FLOW_ATTR_NORMAL ) {
1580
- handler = create_flow_rule (dev , ft_prio , flow_attr ,
1581
- dst );
1617
+ if (flow_attr -> flags & IB_FLOW_ATTR_FLAGS_DONT_TRAP ) {
1618
+ handler = create_dont_trap_rule (dev , ft_prio ,
1619
+ flow_attr , dst );
1620
+ } else {
1621
+ handler = create_flow_rule (dev , ft_prio , flow_attr ,
1622
+ dst );
1623
+ }
1582
1624
} else if (flow_attr -> type == IB_FLOW_ATTR_ALL_DEFAULT ||
1583
1625
flow_attr -> type == IB_FLOW_ATTR_MC_DEFAULT ) {
1584
1626
handler = create_leftovers_rule (dev , ft_prio , flow_attr ,
0 commit comments