mlxsw_sp_nexthop_ht_params);
 }
 
+static struct mlxsw_sp_nexthop *
+mlxsw_sp_nexthop_lookup(struct mlxsw_sp *mlxsw_sp,
+                       struct mlxsw_sp_nexthop_key key)
+{
+       return rhashtable_lookup_fast(&mlxsw_sp->router.nexthop_ht, &key,
+                                     mlxsw_sp_nexthop_ht_params);
+}
+
 static int mlxsw_sp_adj_index_mass_update_vr(struct mlxsw_sp *mlxsw_sp,
                                             struct mlxsw_sp_vr *vr,
                                             u32 adj_index, u16 ecmp_size,
        u8 nud_state, dead;
        int err;
 
-       if (!nh->nh_grp->gateway)
+       if (!nh->nh_grp->gateway || nh->neigh_entry)
                return 0;
 
        /* Take a reference of neigh here ensuring that neigh would
        mlxsw_sp_nexthop_remove(mlxsw_sp, nh);
 }
 
+static void mlxsw_sp_nexthop_event(struct mlxsw_sp *mlxsw_sp,
+                                  unsigned long event, struct fib_nh *fib_nh)
+{
+       struct mlxsw_sp_nexthop_key key;
+       struct mlxsw_sp_nexthop *nh;
+       struct mlxsw_sp_rif *r;
+
+       if (mlxsw_sp->router.aborted)
+               return;
+
+       key.fib_nh = fib_nh;
+       nh = mlxsw_sp_nexthop_lookup(mlxsw_sp, key);
+       if (WARN_ON_ONCE(!nh))
+               return;
+
+       r = mlxsw_sp_rif_find_by_dev(mlxsw_sp, fib_nh->nh_dev);
+       if (!r)
+               return;
+
+       switch (event) {
+       case FIB_EVENT_NH_ADD:
+               nh->r = r;
+               mlxsw_sp_nexthop_neigh_init(mlxsw_sp, nh);
+               break;
+       case FIB_EVENT_NH_DEL:
+               mlxsw_sp_nexthop_neigh_fini(mlxsw_sp, nh);
+               nh->r = NULL;
+               break;
+       }
+
+       mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nh_grp);
+}
+
 static struct mlxsw_sp_nexthop_group *
 mlxsw_sp_nexthop_group_create(struct mlxsw_sp *mlxsw_sp, struct fib_info *fi)
 {
 
 struct mlxsw_sp_fib_event_work {
        struct work_struct work;
-       struct fib_entry_notifier_info fen_info;
+       union {
+               struct fib_entry_notifier_info fen_info;
+               struct fib_nh_notifier_info fnh_info;
+       };
        struct mlxsw_sp *mlxsw_sp;
        unsigned long event;
 };
        case FIB_EVENT_RULE_DEL:
                mlxsw_sp_router_fib4_abort(mlxsw_sp);
                break;
+       case FIB_EVENT_NH_ADD: /* fall through */
+       case FIB_EVENT_NH_DEL:
+               mlxsw_sp_nexthop_event(mlxsw_sp, fib_work->event,
+                                      fib_work->fnh_info.fib_nh);
+               fib_info_put(fib_work->fnh_info.fib_nh->nh_parent);
+               break;
        }
        rtnl_unlock();
        kfree(fib_work);
                 */
                fib_info_hold(fib_work->fen_info.fi);
                break;
+       case FIB_EVENT_NH_ADD: /* fall through */
+       case FIB_EVENT_NH_DEL:
+               memcpy(&fib_work->fnh_info, ptr, sizeof(fib_work->fnh_info));
+               fib_info_hold(fib_work->fnh_info.fib_nh->nh_parent);
+               break;
        }
 
        mlxsw_core_schedule_work(&fib_work->work);