Skip to content

Commit 599cf8f

Browse files
idoschdavem330
authored andcommitted
mlxsw: spectrum_router: Add support for route replace
Upon the reception of an ENTRY_REPLACE notification, resolve the FIB node corresponding to the prefix and length and insert the new route before the first matching entry. Since the notification also signals the deletion of the replaced route, delete it from the driver's cache. Signed-off-by: Ido Schimmel <[email protected]> Signed-off-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 4283bce commit 599cf8f

File tree

1 file changed

+37
-7
lines changed

1 file changed

+37
-7
lines changed

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

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2128,15 +2128,20 @@ static int mlxsw_sp_fib4_node_list_append(struct mlxsw_sp_fib_entry *fib_entry,
21282128
static int
21292129
mlxsw_sp_fib4_node_list_insert(struct mlxsw_sp_fib_node *fib_node,
21302130
struct mlxsw_sp_fib_entry *new_entry,
2131-
bool append)
2131+
bool replace, bool append)
21322132
{
21332133
struct mlxsw_sp_fib_entry *fib_entry;
21342134

21352135
fib_entry = mlxsw_sp_fib4_node_entry_find(fib_node, &new_entry->params);
21362136

21372137
if (append)
21382138
return mlxsw_sp_fib4_node_list_append(fib_entry, new_entry);
2139+
if (replace && WARN_ON(!fib_entry))
2140+
return -EINVAL;
21392141

2142+
/* Insert new entry before replaced one, so that we can later
2143+
* remove the second.
2144+
*/
21402145
if (fib_entry) {
21412146
list_add_tail(&new_entry->list, &fib_entry->list);
21422147
} else {
@@ -2207,12 +2212,13 @@ mlxsw_sp_fib4_node_entry_del(struct mlxsw_sp *mlxsw_sp,
22072212

22082213
static int mlxsw_sp_fib4_node_entry_link(struct mlxsw_sp *mlxsw_sp,
22092214
struct mlxsw_sp_fib_entry *fib_entry,
2210-
bool append)
2215+
bool replace, bool append)
22112216
{
22122217
struct mlxsw_sp_fib_node *fib_node = fib_entry->fib_node;
22132218
int err;
22142219

2215-
err = mlxsw_sp_fib4_node_list_insert(fib_node, fib_entry, append);
2220+
err = mlxsw_sp_fib4_node_list_insert(fib_node, fib_entry, replace,
2221+
append);
22162222
if (err)
22172223
return err;
22182224

@@ -2240,10 +2246,28 @@ mlxsw_sp_fib4_node_entry_unlink(struct mlxsw_sp *mlxsw_sp,
22402246
mlxsw_sp_fib4_node_list_remove(fib_entry);
22412247
}
22422248

2249+
static void mlxsw_sp_fib4_entry_replace(struct mlxsw_sp *mlxsw_sp,
2250+
struct mlxsw_sp_fib_entry *fib_entry,
2251+
bool replace)
2252+
{
2253+
struct mlxsw_sp_fib_node *fib_node = fib_entry->fib_node;
2254+
struct mlxsw_sp_fib_entry *replaced;
2255+
2256+
if (!replace)
2257+
return;
2258+
2259+
/* We inserted the new entry before replaced one */
2260+
replaced = list_next_entry(fib_entry, list);
2261+
2262+
mlxsw_sp_fib4_node_entry_unlink(mlxsw_sp, replaced);
2263+
mlxsw_sp_fib4_entry_destroy(mlxsw_sp, replaced);
2264+
mlxsw_sp_fib4_node_put(mlxsw_sp, fib_node);
2265+
}
2266+
22432267
static int
22442268
mlxsw_sp_router_fib4_add(struct mlxsw_sp *mlxsw_sp,
22452269
const struct fib_entry_notifier_info *fen_info,
2246-
bool append)
2270+
bool replace, bool append)
22472271
{
22482272
struct mlxsw_sp_fib_entry *fib_entry;
22492273
struct mlxsw_sp_fib_node *fib_node;
@@ -2265,12 +2289,15 @@ mlxsw_sp_router_fib4_add(struct mlxsw_sp *mlxsw_sp,
22652289
goto err_fib4_entry_create;
22662290
}
22672291

2268-
err = mlxsw_sp_fib4_node_entry_link(mlxsw_sp, fib_entry, append);
2292+
err = mlxsw_sp_fib4_node_entry_link(mlxsw_sp, fib_entry, replace,
2293+
append);
22692294
if (err) {
22702295
dev_warn(mlxsw_sp->bus_info->dev, "Failed to link FIB entry to node\n");
22712296
goto err_fib4_node_entry_link;
22722297
}
22732298

2299+
mlxsw_sp_fib4_entry_replace(mlxsw_sp, fib_entry, replace);
2300+
22742301
return 0;
22752302

22762303
err_fib4_node_entry_link:
@@ -2479,17 +2506,19 @@ static void mlxsw_sp_router_fib_event_work(struct work_struct *work)
24792506
struct mlxsw_sp_fib_event_work *fib_work =
24802507
container_of(work, struct mlxsw_sp_fib_event_work, work);
24812508
struct mlxsw_sp *mlxsw_sp = fib_work->mlxsw_sp;
2482-
bool append;
2509+
bool replace, append;
24832510
int err;
24842511

24852512
/* Protect internal structures from changes */
24862513
rtnl_lock();
24872514
switch (fib_work->event) {
2515+
case FIB_EVENT_ENTRY_REPLACE: /* fall through */
24882516
case FIB_EVENT_ENTRY_APPEND: /* fall through */
24892517
case FIB_EVENT_ENTRY_ADD:
2518+
replace = fib_work->event == FIB_EVENT_ENTRY_REPLACE;
24902519
append = fib_work->event == FIB_EVENT_ENTRY_APPEND;
24912520
err = mlxsw_sp_router_fib4_add(mlxsw_sp, &fib_work->fen_info,
2492-
append);
2521+
replace, append);
24932522
if (err)
24942523
mlxsw_sp_router_fib4_abort(mlxsw_sp);
24952524
fib_info_put(fib_work->fen_info.fi);
@@ -2533,6 +2562,7 @@ static int mlxsw_sp_router_fib_event(struct notifier_block *nb,
25332562
fib_work->event = event;
25342563

25352564
switch (event) {
2565+
case FIB_EVENT_ENTRY_REPLACE: /* fall through */
25362566
case FIB_EVENT_ENTRY_APPEND: /* fall through */
25372567
case FIB_EVENT_ENTRY_ADD: /* fall through */
25382568
case FIB_EVENT_ENTRY_DEL:

0 commit comments

Comments
 (0)