Skip to content

Commit 0508ff8

Browse files
idoschdavem330
authored andcommitted
mlxsw: spectrum_router: Prevent incorrect replacement of local table routes
The driver uses the same table to represent both the main and local routing tables. Prevent routes in the main table from replacing routes in the local table to reflect the fact that the local table is consulted first during lookup. Fixes: b6a1d87 ("mlxsw: spectrum_router: Start using new IPv4 route notifications") Fixes: dacad7b ("mlxsw: spectrum_router: Start using new IPv6 route notifications") Signed-off-by: Ido Schimmel <[email protected]> Acked-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f8c2afa commit 0508ff8

File tree

1 file changed

+51
-1
lines changed

1 file changed

+51
-1
lines changed

drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4844,6 +4844,23 @@ mlxsw_sp_fib_node_entry_unlink(struct mlxsw_sp *mlxsw_sp,
48444844
fib_node->fib_entry = NULL;
48454845
}
48464846

4847+
static bool mlxsw_sp_fib4_allow_replace(struct mlxsw_sp_fib4_entry *fib4_entry)
4848+
{
4849+
struct mlxsw_sp_fib_node *fib_node = fib4_entry->common.fib_node;
4850+
struct mlxsw_sp_fib4_entry *fib4_replaced;
4851+
4852+
if (!fib_node->fib_entry)
4853+
return true;
4854+
4855+
fib4_replaced = container_of(fib_node->fib_entry,
4856+
struct mlxsw_sp_fib4_entry, common);
4857+
if (fib4_entry->tb_id == RT_TABLE_MAIN &&
4858+
fib4_replaced->tb_id == RT_TABLE_LOCAL)
4859+
return false;
4860+
4861+
return true;
4862+
}
4863+
48474864
static int
48484865
mlxsw_sp_router_fib4_replace(struct mlxsw_sp *mlxsw_sp,
48494866
const struct fib_entry_notifier_info *fen_info)
@@ -4872,6 +4889,12 @@ mlxsw_sp_router_fib4_replace(struct mlxsw_sp *mlxsw_sp,
48724889
goto err_fib4_entry_create;
48734890
}
48744891

4892+
if (!mlxsw_sp_fib4_allow_replace(fib4_entry)) {
4893+
mlxsw_sp_fib4_entry_destroy(mlxsw_sp, fib4_entry);
4894+
mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
4895+
return 0;
4896+
}
4897+
48754898
replaced = fib_node->fib_entry;
48764899
err = mlxsw_sp_fib_node_entry_link(mlxsw_sp, &fib4_entry->common);
48774900
if (err) {
@@ -4908,7 +4931,7 @@ static void mlxsw_sp_router_fib4_del(struct mlxsw_sp *mlxsw_sp,
49084931
return;
49094932

49104933
fib4_entry = mlxsw_sp_fib4_entry_lookup(mlxsw_sp, fen_info);
4911-
if (WARN_ON(!fib4_entry))
4934+
if (!fib4_entry)
49124935
return;
49134936
fib_node = fib4_entry->common.fib_node;
49144937

@@ -5408,6 +5431,27 @@ mlxsw_sp_fib6_entry_lookup(struct mlxsw_sp *mlxsw_sp,
54085431
return NULL;
54095432
}
54105433

5434+
static bool mlxsw_sp_fib6_allow_replace(struct mlxsw_sp_fib6_entry *fib6_entry)
5435+
{
5436+
struct mlxsw_sp_fib_node *fib_node = fib6_entry->common.fib_node;
5437+
struct mlxsw_sp_fib6_entry *fib6_replaced;
5438+
struct fib6_info *rt, *rt_replaced;
5439+
5440+
if (!fib_node->fib_entry)
5441+
return true;
5442+
5443+
fib6_replaced = container_of(fib_node->fib_entry,
5444+
struct mlxsw_sp_fib6_entry,
5445+
common);
5446+
rt = mlxsw_sp_fib6_entry_rt(fib6_entry);
5447+
rt_replaced = mlxsw_sp_fib6_entry_rt(fib6_replaced);
5448+
if (rt->fib6_table->tb6_id == RT_TABLE_MAIN &&
5449+
rt_replaced->fib6_table->tb6_id == RT_TABLE_LOCAL)
5450+
return false;
5451+
5452+
return true;
5453+
}
5454+
54115455
static int mlxsw_sp_router_fib6_replace(struct mlxsw_sp *mlxsw_sp,
54125456
struct fib6_info **rt_arr,
54135457
unsigned int nrt6)
@@ -5442,6 +5486,12 @@ static int mlxsw_sp_router_fib6_replace(struct mlxsw_sp *mlxsw_sp,
54425486
goto err_fib6_entry_create;
54435487
}
54445488

5489+
if (!mlxsw_sp_fib6_allow_replace(fib6_entry)) {
5490+
mlxsw_sp_fib6_entry_destroy(mlxsw_sp, fib6_entry);
5491+
mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
5492+
return 0;
5493+
}
5494+
54455495
replaced = fib_node->fib_entry;
54465496
err = mlxsw_sp_fib_node_entry_link(mlxsw_sp, &fib6_entry->common);
54475497
if (err)

0 commit comments

Comments
 (0)