@@ -4376,6 +4376,66 @@ static void mlxsw_sp_nexthop_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
4376
4376
}
4377
4377
}
4378
4378
4379
+ static int mlxsw_sp_adj_trap_entry_init (struct mlxsw_sp * mlxsw_sp )
4380
+ {
4381
+ enum mlxsw_reg_ratr_trap_action trap_action ;
4382
+ char ratr_pl [MLXSW_REG_RATR_LEN ];
4383
+ int err ;
4384
+
4385
+ err = mlxsw_sp_kvdl_alloc (mlxsw_sp , MLXSW_SP_KVDL_ENTRY_TYPE_ADJ , 1 ,
4386
+ & mlxsw_sp -> router -> adj_trap_index );
4387
+ if (err )
4388
+ return err ;
4389
+
4390
+ trap_action = MLXSW_REG_RATR_TRAP_ACTION_TRAP ;
4391
+ mlxsw_reg_ratr_pack (ratr_pl , MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY , true,
4392
+ MLXSW_REG_RATR_TYPE_ETHERNET ,
4393
+ mlxsw_sp -> router -> adj_trap_index ,
4394
+ mlxsw_sp -> router -> lb_rif_index );
4395
+ mlxsw_reg_ratr_trap_action_set (ratr_pl , trap_action );
4396
+ mlxsw_reg_ratr_trap_id_set (ratr_pl , MLXSW_TRAP_ID_RTR_EGRESS0 );
4397
+ err = mlxsw_reg_write (mlxsw_sp -> core , MLXSW_REG (ratr ), ratr_pl );
4398
+ if (err )
4399
+ goto err_ratr_write ;
4400
+
4401
+ return 0 ;
4402
+
4403
+ err_ratr_write :
4404
+ mlxsw_sp_kvdl_free (mlxsw_sp , MLXSW_SP_KVDL_ENTRY_TYPE_ADJ , 1 ,
4405
+ mlxsw_sp -> router -> adj_trap_index );
4406
+ return err ;
4407
+ }
4408
+
4409
+ static void mlxsw_sp_adj_trap_entry_fini (struct mlxsw_sp * mlxsw_sp )
4410
+ {
4411
+ mlxsw_sp_kvdl_free (mlxsw_sp , MLXSW_SP_KVDL_ENTRY_TYPE_ADJ , 1 ,
4412
+ mlxsw_sp -> router -> adj_trap_index );
4413
+ }
4414
+
4415
+ static int mlxsw_sp_nexthop_group_inc (struct mlxsw_sp * mlxsw_sp )
4416
+ {
4417
+ int err ;
4418
+
4419
+ if (refcount_inc_not_zero (& mlxsw_sp -> router -> num_groups ))
4420
+ return 0 ;
4421
+
4422
+ err = mlxsw_sp_adj_trap_entry_init (mlxsw_sp );
4423
+ if (err )
4424
+ return err ;
4425
+
4426
+ refcount_set (& mlxsw_sp -> router -> num_groups , 1 );
4427
+
4428
+ return 0 ;
4429
+ }
4430
+
4431
+ static void mlxsw_sp_nexthop_group_dec (struct mlxsw_sp * mlxsw_sp )
4432
+ {
4433
+ if (!refcount_dec_and_test (& mlxsw_sp -> router -> num_groups ))
4434
+ return ;
4435
+
4436
+ mlxsw_sp_adj_trap_entry_fini (mlxsw_sp );
4437
+ }
4438
+
4379
4439
static void
4380
4440
mlxsw_sp_nh_grp_activity_get (struct mlxsw_sp * mlxsw_sp ,
4381
4441
const struct mlxsw_sp_nexthop_group * nh_grp ,
@@ -4790,6 +4850,9 @@ mlxsw_sp_nexthop_obj_group_info_init(struct mlxsw_sp *mlxsw_sp,
4790
4850
if (err )
4791
4851
goto err_nexthop_obj_init ;
4792
4852
}
4853
+ err = mlxsw_sp_nexthop_group_inc (mlxsw_sp );
4854
+ if (err )
4855
+ goto err_group_inc ;
4793
4856
err = mlxsw_sp_nexthop_group_refresh (mlxsw_sp , nh_grp );
4794
4857
if (err ) {
4795
4858
NL_SET_ERR_MSG_MOD (info -> extack , "Failed to write adjacency entries to the device" );
@@ -4808,6 +4871,8 @@ mlxsw_sp_nexthop_obj_group_info_init(struct mlxsw_sp *mlxsw_sp,
4808
4871
return 0 ;
4809
4872
4810
4873
err_group_refresh :
4874
+ mlxsw_sp_nexthop_group_dec (mlxsw_sp );
4875
+ err_group_inc :
4811
4876
i = nhgi -> count ;
4812
4877
err_nexthop_obj_init :
4813
4878
for (i -- ; i >= 0 ; i -- ) {
@@ -4832,6 +4897,7 @@ mlxsw_sp_nexthop_obj_group_info_fini(struct mlxsw_sp *mlxsw_sp,
4832
4897
cancel_delayed_work (& router -> nh_grp_activity_dw );
4833
4898
}
4834
4899
4900
+ mlxsw_sp_nexthop_group_dec (mlxsw_sp );
4835
4901
for (i = nhgi -> count - 1 ; i >= 0 ; i -- ) {
4836
4902
struct mlxsw_sp_nexthop * nh = & nhgi -> nexthops [i ];
4837
4903
@@ -5223,13 +5289,18 @@ mlxsw_sp_nexthop4_group_info_init(struct mlxsw_sp *mlxsw_sp,
5223
5289
if (err )
5224
5290
goto err_nexthop4_init ;
5225
5291
}
5292
+ err = mlxsw_sp_nexthop_group_inc (mlxsw_sp );
5293
+ if (err )
5294
+ goto err_group_inc ;
5226
5295
err = mlxsw_sp_nexthop_group_refresh (mlxsw_sp , nh_grp );
5227
5296
if (err )
5228
5297
goto err_group_refresh ;
5229
5298
5230
5299
return 0 ;
5231
5300
5232
5301
err_group_refresh :
5302
+ mlxsw_sp_nexthop_group_dec (mlxsw_sp );
5303
+ err_group_inc :
5233
5304
i = nhgi -> count ;
5234
5305
err_nexthop4_init :
5235
5306
for (i -- ; i >= 0 ; i -- ) {
@@ -5247,6 +5318,7 @@ mlxsw_sp_nexthop4_group_info_fini(struct mlxsw_sp *mlxsw_sp,
5247
5318
struct mlxsw_sp_nexthop_group_info * nhgi = nh_grp -> nhgi ;
5248
5319
int i ;
5249
5320
5321
+ mlxsw_sp_nexthop_group_dec (mlxsw_sp );
5250
5322
for (i = nhgi -> count - 1 ; i >= 0 ; i -- ) {
5251
5323
struct mlxsw_sp_nexthop * nh = & nhgi -> nexthops [i ];
5252
5324
@@ -5725,41 +5797,6 @@ static int mlxsw_sp_fib_entry_commit(struct mlxsw_sp *mlxsw_sp,
5725
5797
return err ;
5726
5798
}
5727
5799
5728
- static int mlxsw_sp_adj_discard_write (struct mlxsw_sp * mlxsw_sp )
5729
- {
5730
- enum mlxsw_reg_ratr_trap_action trap_action ;
5731
- char ratr_pl [MLXSW_REG_RATR_LEN ];
5732
- int err ;
5733
-
5734
- if (mlxsw_sp -> router -> adj_discard_index_valid )
5735
- return 0 ;
5736
-
5737
- err = mlxsw_sp_kvdl_alloc (mlxsw_sp , MLXSW_SP_KVDL_ENTRY_TYPE_ADJ , 1 ,
5738
- & mlxsw_sp -> router -> adj_discard_index );
5739
- if (err )
5740
- return err ;
5741
-
5742
- trap_action = MLXSW_REG_RATR_TRAP_ACTION_TRAP ;
5743
- mlxsw_reg_ratr_pack (ratr_pl , MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY , true,
5744
- MLXSW_REG_RATR_TYPE_ETHERNET ,
5745
- mlxsw_sp -> router -> adj_discard_index ,
5746
- mlxsw_sp -> router -> lb_rif_index );
5747
- mlxsw_reg_ratr_trap_action_set (ratr_pl , trap_action );
5748
- mlxsw_reg_ratr_trap_id_set (ratr_pl , MLXSW_TRAP_ID_RTR_EGRESS0 );
5749
- err = mlxsw_reg_write (mlxsw_sp -> core , MLXSW_REG (ratr ), ratr_pl );
5750
- if (err )
5751
- goto err_ratr_write ;
5752
-
5753
- mlxsw_sp -> router -> adj_discard_index_valid = true;
5754
-
5755
- return 0 ;
5756
-
5757
- err_ratr_write :
5758
- mlxsw_sp_kvdl_free (mlxsw_sp , MLXSW_SP_KVDL_ENTRY_TYPE_ADJ , 1 ,
5759
- mlxsw_sp -> router -> adj_discard_index );
5760
- return err ;
5761
- }
5762
-
5763
5800
static int mlxsw_sp_fib_entry_op_remote (struct mlxsw_sp * mlxsw_sp ,
5764
5801
struct mlxsw_sp_fib_entry_op_ctx * op_ctx ,
5765
5802
struct mlxsw_sp_fib_entry * fib_entry ,
@@ -5772,7 +5809,6 @@ static int mlxsw_sp_fib_entry_op_remote(struct mlxsw_sp *mlxsw_sp,
5772
5809
u16 trap_id = 0 ;
5773
5810
u32 adjacency_index = 0 ;
5774
5811
u16 ecmp_size = 0 ;
5775
- int err ;
5776
5812
5777
5813
/* In case the nexthop group adjacency index is valid, use it
5778
5814
* with provided ECMP size. Otherwise, setup trap and pass
@@ -5783,11 +5819,8 @@ static int mlxsw_sp_fib_entry_op_remote(struct mlxsw_sp *mlxsw_sp,
5783
5819
adjacency_index = nhgi -> adj_index ;
5784
5820
ecmp_size = nhgi -> ecmp_size ;
5785
5821
} else if (!nhgi -> adj_index_valid && nhgi -> count && nhgi -> nh_rif ) {
5786
- err = mlxsw_sp_adj_discard_write (mlxsw_sp );
5787
- if (err )
5788
- return err ;
5789
5822
trap_action = MLXSW_REG_RALUE_TRAP_ACTION_NOP ;
5790
- adjacency_index = mlxsw_sp -> router -> adj_discard_index ;
5823
+ adjacency_index = mlxsw_sp -> router -> adj_trap_index ;
5791
5824
ecmp_size = 1 ;
5792
5825
} else {
5793
5826
trap_action = MLXSW_REG_RALUE_TRAP_ACTION_TRAP ;
@@ -6641,13 +6674,18 @@ mlxsw_sp_nexthop6_group_info_init(struct mlxsw_sp *mlxsw_sp,
6641
6674
mlxsw_sp_rt6 = list_next_entry (mlxsw_sp_rt6 , list );
6642
6675
}
6643
6676
nh_grp -> nhgi = nhgi ;
6677
+ err = mlxsw_sp_nexthop_group_inc (mlxsw_sp );
6678
+ if (err )
6679
+ goto err_group_inc ;
6644
6680
err = mlxsw_sp_nexthop_group_refresh (mlxsw_sp , nh_grp );
6645
6681
if (err )
6646
6682
goto err_group_refresh ;
6647
6683
6648
6684
return 0 ;
6649
6685
6650
6686
err_group_refresh :
6687
+ mlxsw_sp_nexthop_group_dec (mlxsw_sp );
6688
+ err_group_inc :
6651
6689
i = nhgi -> count ;
6652
6690
err_nexthop6_init :
6653
6691
for (i -- ; i >= 0 ; i -- ) {
@@ -6665,6 +6703,7 @@ mlxsw_sp_nexthop6_group_info_fini(struct mlxsw_sp *mlxsw_sp,
6665
6703
struct mlxsw_sp_nexthop_group_info * nhgi = nh_grp -> nhgi ;
6666
6704
int i ;
6667
6705
6706
+ mlxsw_sp_nexthop_group_dec (mlxsw_sp );
6668
6707
for (i = nhgi -> count - 1 ; i >= 0 ; i -- ) {
6669
6708
struct mlxsw_sp_nexthop * nh = & nhgi -> nexthops [i ];
6670
6709
@@ -7340,16 +7379,6 @@ static void mlxsw_sp_router_fib_flush(struct mlxsw_sp *mlxsw_sp)
7340
7379
continue ;
7341
7380
mlxsw_sp_vr_fib_flush (mlxsw_sp , vr , MLXSW_SP_L3_PROTO_IPV6 );
7342
7381
}
7343
-
7344
- /* After flushing all the routes, it is not possible anyone is still
7345
- * using the adjacency index that is discarding packets, so free it in
7346
- * case it was allocated.
7347
- */
7348
- if (!mlxsw_sp -> router -> adj_discard_index_valid )
7349
- return ;
7350
- mlxsw_sp_kvdl_free (mlxsw_sp , MLXSW_SP_KVDL_ENTRY_TYPE_ADJ , 1 ,
7351
- mlxsw_sp -> router -> adj_discard_index );
7352
- mlxsw_sp -> router -> adj_discard_index_valid = false;
7353
7382
}
7354
7383
7355
7384
struct mlxsw_sp_fib6_event {
0 commit comments