static int
 mlxsw_sp_fib4_node_list_insert(struct mlxsw_sp_fib_node *fib_node,
                               struct mlxsw_sp_fib_entry *new_entry,
-                              bool append)
+                              bool replace, bool append)
 {
        struct mlxsw_sp_fib_entry *fib_entry;
 
 
        if (append)
                return mlxsw_sp_fib4_node_list_append(fib_entry, new_entry);
+       if (replace && WARN_ON(!fib_entry))
+               return -EINVAL;
 
+       /* Insert new entry before replaced one, so that we can later
+        * remove the second.
+        */
        if (fib_entry) {
                list_add_tail(&new_entry->list, &fib_entry->list);
        } else {
 
 static int mlxsw_sp_fib4_node_entry_link(struct mlxsw_sp *mlxsw_sp,
                                         struct mlxsw_sp_fib_entry *fib_entry,
-                                        bool append)
+                                        bool replace, bool append)
 {
        struct mlxsw_sp_fib_node *fib_node = fib_entry->fib_node;
        int err;
 
-       err = mlxsw_sp_fib4_node_list_insert(fib_node, fib_entry, append);
+       err = mlxsw_sp_fib4_node_list_insert(fib_node, fib_entry, replace,
+                                            append);
        if (err)
                return err;
 
        mlxsw_sp_fib4_node_list_remove(fib_entry);
 }
 
+static void mlxsw_sp_fib4_entry_replace(struct mlxsw_sp *mlxsw_sp,
+                                       struct mlxsw_sp_fib_entry *fib_entry,
+                                       bool replace)
+{
+       struct mlxsw_sp_fib_node *fib_node = fib_entry->fib_node;
+       struct mlxsw_sp_fib_entry *replaced;
+
+       if (!replace)
+               return;
+
+       /* We inserted the new entry before replaced one */
+       replaced = list_next_entry(fib_entry, list);
+
+       mlxsw_sp_fib4_node_entry_unlink(mlxsw_sp, replaced);
+       mlxsw_sp_fib4_entry_destroy(mlxsw_sp, replaced);
+       mlxsw_sp_fib4_node_put(mlxsw_sp, fib_node);
+}
+
 static int
 mlxsw_sp_router_fib4_add(struct mlxsw_sp *mlxsw_sp,
                         const struct fib_entry_notifier_info *fen_info,
-                        bool append)
+                        bool replace, bool append)
 {
        struct mlxsw_sp_fib_entry *fib_entry;
        struct mlxsw_sp_fib_node *fib_node;
                goto err_fib4_entry_create;
        }
 
-       err = mlxsw_sp_fib4_node_entry_link(mlxsw_sp, fib_entry, append);
+       err = mlxsw_sp_fib4_node_entry_link(mlxsw_sp, fib_entry, replace,
+                                           append);
        if (err) {
                dev_warn(mlxsw_sp->bus_info->dev, "Failed to link FIB entry to node\n");
                goto err_fib4_node_entry_link;
        }
 
+       mlxsw_sp_fib4_entry_replace(mlxsw_sp, fib_entry, replace);
+
        return 0;
 
 err_fib4_node_entry_link:
        struct mlxsw_sp_fib_event_work *fib_work =
                container_of(work, struct mlxsw_sp_fib_event_work, work);
        struct mlxsw_sp *mlxsw_sp = fib_work->mlxsw_sp;
-       bool append;
+       bool replace, append;
        int err;
 
        /* Protect internal structures from changes */
        rtnl_lock();
        switch (fib_work->event) {
+       case FIB_EVENT_ENTRY_REPLACE: /* fall through */
        case FIB_EVENT_ENTRY_APPEND: /* fall through */
        case FIB_EVENT_ENTRY_ADD:
+               replace = fib_work->event == FIB_EVENT_ENTRY_REPLACE;
                append = fib_work->event == FIB_EVENT_ENTRY_APPEND;
                err = mlxsw_sp_router_fib4_add(mlxsw_sp, &fib_work->fen_info,
-                                              append);
+                                              replace, append);
                if (err)
                        mlxsw_sp_router_fib4_abort(mlxsw_sp);
                fib_info_put(fib_work->fen_info.fi);
        fib_work->event = event;
 
        switch (event) {
+       case FIB_EVENT_ENTRY_REPLACE: /* fall through */
        case FIB_EVENT_ENTRY_APPEND: /* fall through */
        case FIB_EVENT_ENTRY_ADD: /* fall through */
        case FIB_EVENT_ENTRY_DEL: