@@ -4756,12 +4756,6 @@ static void mlxsw_sp_rt6_destroy(struct mlxsw_sp_rt6 *mlxsw_sp_rt6)
4756
4756
kfree (mlxsw_sp_rt6 );
4757
4757
}
4758
4758
4759
- static bool mlxsw_sp_fib6_rt_can_mp (const struct fib6_info * rt )
4760
- {
4761
- /* RTF_CACHE routes are ignored */
4762
- return (rt -> fib6_flags & (RTF_GATEWAY | RTF_ADDRCONF )) == RTF_GATEWAY ;
4763
- }
4764
-
4765
4759
static struct fib6_info *
4766
4760
mlxsw_sp_fib6_entry_rt (const struct mlxsw_sp_fib6_entry * fib6_entry )
4767
4761
{
@@ -4771,11 +4765,11 @@ mlxsw_sp_fib6_entry_rt(const struct mlxsw_sp_fib6_entry *fib6_entry)
4771
4765
4772
4766
static struct mlxsw_sp_fib6_entry *
4773
4767
mlxsw_sp_fib6_node_mp_entry_find (const struct mlxsw_sp_fib_node * fib_node ,
4774
- const struct fib6_info * nrt , bool replace )
4768
+ const struct fib6_info * nrt , bool append )
4775
4769
{
4776
4770
struct mlxsw_sp_fib6_entry * fib6_entry ;
4777
4771
4778
- if (!mlxsw_sp_fib6_rt_can_mp ( nrt ) || replace )
4772
+ if (!append )
4779
4773
return NULL ;
4780
4774
4781
4775
list_for_each_entry (fib6_entry , & fib_node -> entry_list , common .list ) {
@@ -4790,8 +4784,7 @@ mlxsw_sp_fib6_node_mp_entry_find(const struct mlxsw_sp_fib_node *fib_node,
4790
4784
break ;
4791
4785
if (rt -> fib6_metric < nrt -> fib6_metric )
4792
4786
continue ;
4793
- if (rt -> fib6_metric == nrt -> fib6_metric &&
4794
- mlxsw_sp_fib6_rt_can_mp (rt ))
4787
+ if (rt -> fib6_metric == nrt -> fib6_metric )
4795
4788
return fib6_entry ;
4796
4789
if (rt -> fib6_metric > nrt -> fib6_metric )
4797
4790
break ;
@@ -5170,7 +5163,7 @@ static struct mlxsw_sp_fib6_entry *
5170
5163
mlxsw_sp_fib6_node_entry_find (const struct mlxsw_sp_fib_node * fib_node ,
5171
5164
const struct fib6_info * nrt , bool replace )
5172
5165
{
5173
- struct mlxsw_sp_fib6_entry * fib6_entry , * fallback = NULL ;
5166
+ struct mlxsw_sp_fib6_entry * fib6_entry ;
5174
5167
5175
5168
list_for_each_entry (fib6_entry , & fib_node -> entry_list , common .list ) {
5176
5169
struct fib6_info * rt = mlxsw_sp_fib6_entry_rt (fib6_entry );
@@ -5179,18 +5172,13 @@ mlxsw_sp_fib6_node_entry_find(const struct mlxsw_sp_fib_node *fib_node,
5179
5172
continue ;
5180
5173
if (rt -> fib6_table -> tb6_id != nrt -> fib6_table -> tb6_id )
5181
5174
break ;
5182
- if (replace && rt -> fib6_metric == nrt -> fib6_metric ) {
5183
- if (mlxsw_sp_fib6_rt_can_mp (rt ) ==
5184
- mlxsw_sp_fib6_rt_can_mp (nrt ))
5185
- return fib6_entry ;
5186
- if (mlxsw_sp_fib6_rt_can_mp (nrt ))
5187
- fallback = fallback ?: fib6_entry ;
5188
- }
5175
+ if (replace && rt -> fib6_metric == nrt -> fib6_metric )
5176
+ return fib6_entry ;
5189
5177
if (rt -> fib6_metric > nrt -> fib6_metric )
5190
- return fallback ?: fib6_entry ;
5178
+ return fib6_entry ;
5191
5179
}
5192
5180
5193
- return fallback ;
5181
+ return NULL ;
5194
5182
}
5195
5183
5196
5184
static int
@@ -5316,7 +5304,8 @@ static void mlxsw_sp_fib6_entry_replace(struct mlxsw_sp *mlxsw_sp,
5316
5304
}
5317
5305
5318
5306
static int mlxsw_sp_router_fib6_add (struct mlxsw_sp * mlxsw_sp ,
5319
- struct fib6_info * rt , bool replace )
5307
+ struct fib6_info * rt , bool replace ,
5308
+ bool append )
5320
5309
{
5321
5310
struct mlxsw_sp_fib6_entry * fib6_entry ;
5322
5311
struct mlxsw_sp_fib_node * fib_node ;
@@ -5342,14 +5331,22 @@ static int mlxsw_sp_router_fib6_add(struct mlxsw_sp *mlxsw_sp,
5342
5331
/* Before creating a new entry, try to append route to an existing
5343
5332
* multipath entry.
5344
5333
*/
5345
- fib6_entry = mlxsw_sp_fib6_node_mp_entry_find (fib_node , rt , replace );
5334
+ fib6_entry = mlxsw_sp_fib6_node_mp_entry_find (fib_node , rt , append );
5346
5335
if (fib6_entry ) {
5347
5336
err = mlxsw_sp_fib6_entry_nexthop_add (mlxsw_sp , fib6_entry , rt );
5348
5337
if (err )
5349
5338
goto err_fib6_entry_nexthop_add ;
5350
5339
return 0 ;
5351
5340
}
5352
5341
5342
+ /* We received an append event, yet did not find any route to
5343
+ * append to.
5344
+ */
5345
+ if (WARN_ON (append )) {
5346
+ err = - EINVAL ;
5347
+ goto err_fib6_entry_append ;
5348
+ }
5349
+
5353
5350
fib6_entry = mlxsw_sp_fib6_entry_create (mlxsw_sp , fib_node , rt );
5354
5351
if (IS_ERR (fib6_entry )) {
5355
5352
err = PTR_ERR (fib6_entry );
@@ -5367,6 +5364,7 @@ static int mlxsw_sp_router_fib6_add(struct mlxsw_sp *mlxsw_sp,
5367
5364
err_fib6_node_entry_link :
5368
5365
mlxsw_sp_fib6_entry_destroy (mlxsw_sp , fib6_entry );
5369
5366
err_fib6_entry_create :
5367
+ err_fib6_entry_append :
5370
5368
err_fib6_entry_nexthop_add :
5371
5369
mlxsw_sp_fib_node_put (mlxsw_sp , fib_node );
5372
5370
return err ;
@@ -5717,7 +5715,7 @@ static void mlxsw_sp_router_fib6_event_work(struct work_struct *work)
5717
5715
struct mlxsw_sp_fib_event_work * fib_work =
5718
5716
container_of (work , struct mlxsw_sp_fib_event_work , work );
5719
5717
struct mlxsw_sp * mlxsw_sp = fib_work -> mlxsw_sp ;
5720
- bool replace ;
5718
+ bool replace , append ;
5721
5719
int err ;
5722
5720
5723
5721
rtnl_lock ();
@@ -5728,8 +5726,10 @@ static void mlxsw_sp_router_fib6_event_work(struct work_struct *work)
5728
5726
case FIB_EVENT_ENTRY_APPEND : /* fall through */
5729
5727
case FIB_EVENT_ENTRY_ADD :
5730
5728
replace = fib_work -> event == FIB_EVENT_ENTRY_REPLACE ;
5729
+ append = fib_work -> event == FIB_EVENT_ENTRY_APPEND ;
5731
5730
err = mlxsw_sp_router_fib6_add (mlxsw_sp ,
5732
- fib_work -> fen6_info .rt , replace );
5731
+ fib_work -> fen6_info .rt , replace ,
5732
+ append );
5733
5733
if (err )
5734
5734
mlxsw_sp_router_fib_abort (mlxsw_sp );
5735
5735
mlxsw_sp_rt6_release (fib_work -> fen6_info .rt );
0 commit comments