@@ -119,17 +119,27 @@ static struct mlx5_flow_rule *mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
119
119
struct mlx5_esw_flow_attr * attr )
120
120
{
121
121
struct mlx5_eswitch * esw = priv -> mdev -> priv .eswitch ;
122
+ int err ;
123
+
124
+ err = mlx5_eswitch_add_vlan_action (esw , attr );
125
+ if (err )
126
+ return ERR_PTR (err );
122
127
123
128
return mlx5_eswitch_add_offloaded_rule (esw , spec , attr );
124
129
}
125
130
126
131
static void mlx5e_tc_del_flow (struct mlx5e_priv * priv ,
127
- struct mlx5_flow_rule * rule )
132
+ struct mlx5_flow_rule * rule ,
133
+ struct mlx5_esw_flow_attr * attr )
128
134
{
135
+ struct mlx5_eswitch * esw = priv -> mdev -> priv .eswitch ;
129
136
struct mlx5_fc * counter = NULL ;
130
137
131
138
counter = mlx5_flow_rule_counter (rule );
132
139
140
+ if (esw && esw -> mode == SRIOV_OFFLOADS )
141
+ mlx5_eswitch_del_vlan_action (esw , attr );
142
+
133
143
mlx5_del_flow_rule (rule );
134
144
135
145
mlx5_fc_destroy (priv -> mdev , counter );
@@ -369,13 +379,9 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
369
379
370
380
tcf_exts_to_list (exts , & actions );
371
381
list_for_each_entry (a , & actions , list ) {
372
- /* Only support a single action per rule */
373
- if (attr -> action )
374
- return - EINVAL ;
375
-
376
382
if (is_tcf_gact_shot (a )) {
377
- attr -> action = MLX5_FLOW_CONTEXT_ACTION_DROP |
378
- MLX5_FLOW_CONTEXT_ACTION_COUNT ;
383
+ attr -> action | = MLX5_FLOW_CONTEXT_ACTION_DROP |
384
+ MLX5_FLOW_CONTEXT_ACTION_COUNT ;
379
385
continue ;
380
386
}
381
387
@@ -392,12 +398,25 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
392
398
return - EINVAL ;
393
399
}
394
400
395
- attr -> action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST ;
401
+ attr -> action | = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST ;
396
402
out_priv = netdev_priv (out_dev );
397
403
attr -> out_rep = out_priv -> ppriv ;
398
404
continue ;
399
405
}
400
406
407
+ if (is_tcf_vlan (a )) {
408
+ if (tcf_vlan_action (a ) == VLAN_F_POP ) {
409
+ attr -> action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_POP ;
410
+ } else if (tcf_vlan_action (a ) == VLAN_F_PUSH ) {
411
+ if (tcf_vlan_push_proto (a ) != htons (ETH_P_8021Q ))
412
+ return - EOPNOTSUPP ;
413
+
414
+ attr -> action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH ;
415
+ attr -> vlan = tcf_vlan_push_vid (a );
416
+ }
417
+ continue ;
418
+ }
419
+
401
420
return - EINVAL ;
402
421
}
403
422
return 0 ;
@@ -413,6 +432,7 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol,
413
432
struct mlx5e_tc_flow * flow ;
414
433
struct mlx5_flow_spec * spec ;
415
434
struct mlx5_flow_rule * old = NULL ;
435
+ struct mlx5_esw_flow_attr * old_attr ;
416
436
struct mlx5_eswitch * esw = priv -> mdev -> priv .eswitch ;
417
437
418
438
if (esw && esw -> mode == SRIOV_OFFLOADS )
@@ -422,6 +442,7 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol,
422
442
tc -> ht_params );
423
443
if (flow ) {
424
444
old = flow -> rule ;
445
+ old_attr = flow -> attr ;
425
446
} else {
426
447
if (fdb_flow )
427
448
flow = kzalloc (sizeof (* flow ) + sizeof (struct mlx5_esw_flow_attr ),
@@ -466,7 +487,7 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol,
466
487
goto err_del_rule ;
467
488
468
489
if (old )
469
- mlx5e_tc_del_flow (priv , old );
490
+ mlx5e_tc_del_flow (priv , old , old_attr );
470
491
471
492
goto out ;
472
493
@@ -494,7 +515,7 @@ int mlx5e_delete_flower(struct mlx5e_priv *priv,
494
515
495
516
rhashtable_remove_fast (& tc -> ht , & flow -> node , tc -> ht_params );
496
517
497
- mlx5e_tc_del_flow (priv , flow -> rule );
518
+ mlx5e_tc_del_flow (priv , flow -> rule , flow -> attr );
498
519
499
520
kfree (flow );
500
521
@@ -551,7 +572,7 @@ static void _mlx5e_tc_del_flow(void *ptr, void *arg)
551
572
struct mlx5e_tc_flow * flow = ptr ;
552
573
struct mlx5e_priv * priv = arg ;
553
574
554
- mlx5e_tc_del_flow (priv , flow -> rule );
575
+ mlx5e_tc_del_flow (priv , flow -> rule , flow -> attr );
555
576
kfree (flow );
556
577
}
557
578
0 commit comments