diff -urp v6.14/linux/net/ipv4/fib_frontend.c linux/net/ipv4/fib_frontend.c
--- v6.14/linux/net/ipv4/fib_frontend.c	2025-04-04 18:53:15.000000000 +0300
+++ linux/net/ipv4/fib_frontend.c	2025-04-04 18:54:34.701025578 +0300
@@ -1446,9 +1446,7 @@ static int fib_inetaddr_event(struct not
 	switch (event) {
 	case NETDEV_UP:
 		fib_add_ifaddr(ifa);
-#ifdef CONFIG_IP_ROUTE_MULTIPATH
 		fib_sync_up(dev, RTNH_F_DEAD);
-#endif
 		atomic_inc(&net->ipv4.dev_addr_genid);
 		rt_cache_flush(dev_net(dev));
 		break;
@@ -1493,9 +1491,7 @@ static int fib_netdev_event(struct notif
 		in_dev_for_each_ifa_rtnl(ifa, in_dev) {
 			fib_add_ifaddr(ifa);
 		}
-#ifdef CONFIG_IP_ROUTE_MULTIPATH
 		fib_sync_up(dev, RTNH_F_DEAD);
-#endif
 		atomic_inc(&net->ipv4.dev_addr_genid);
 		rt_cache_flush(net);
 		break;
diff -urp v6.14/linux/net/ipv4/fib_semantics.c linux/net/ipv4/fib_semantics.c
--- v6.14/linux/net/ipv4/fib_semantics.c	2025-04-04 18:53:15.000000000 +0300
+++ linux/net/ipv4/fib_semantics.c	2025-04-04 18:55:08.197553556 +0300
@@ -55,6 +55,7 @@ static struct hlist_head *fib_info_laddr
 static unsigned int fib_info_hash_size;
 static unsigned int fib_info_hash_bits;
 static unsigned int fib_info_cnt;
+DEFINE_RWLOCK(fib_nhflags_lock);
 
 /* for_nexthops and change_nexthops only used when nexthop object
  * is not set in a fib_info. The logic within can reference fib_nh.
@@ -1098,6 +1099,7 @@ static int fib_check_nh_v6_gw(struct net
 static int fib_check_nh_v4_gw(struct net *net, struct fib_nh *nh, u32 table,
 			      u8 scope, struct netlink_ext_ack *extack)
 {
+	struct fib_info *fi = nh->nh_parent;
 	struct net_device *dev;
 	struct fib_result res;
 	int err = 0;
@@ -1115,8 +1117,12 @@ static int fib_check_nh_v4_gw(struct net
 			return -ENODEV;
 		}
 		if (!(dev->flags & IFF_UP)) {
-			NL_SET_ERR_MSG(extack, "Nexthop device is not up");
-			return -ENETDOWN;
+			if (fi->fib_protocol != RTPROT_STATIC) {
+				NL_SET_ERR_MSG(extack,
+					       "Nexthop device is not up");
+				return -ENETDOWN;
+			}
+			nh->fib_nh_flags |= RTNH_F_DEAD;
 		}
 		addr_type = inet_addr_type_dev_table(net, dev, nh->fib_nh_gw4);
 		if (addr_type != RTN_UNICAST) {
@@ -1160,11 +1166,30 @@ static int fib_check_nh_v4_gw(struct net
 			err = fib_lookup(net, &fl4, &res,
 					 FIB_LOOKUP_IGNORE_LINKSTATE);
 		}
+	}
+
+	if (err) {
+		struct in_device *in_dev;
 
-		if (err) {
+		if (err != -ENETUNREACH ||
+		    fi->fib_protocol != RTPROT_STATIC) {
 			NL_SET_ERR_MSG(extack, "Nexthop has invalid gateway");
 			goto out;
 		}
+		in_dev = inetdev_by_index(net, nh->fib_nh_oif);
+		if (in_dev == NULL ||
+		    in_dev->dev->flags & IFF_UP) {
+			NL_SET_ERR_MSG(extack,
+				       "Nexthop has invalid gateway");
+			goto out;
+		}
+		nh->fib_nh_flags |= RTNH_F_DEAD;
+		nh->fib_nh_scope = RT_SCOPE_LINK;
+		nh->fib_nh_dev = in_dev->dev;
+		netdev_hold(nh->fib_nh_dev, &nh->fib_nh_dev_tracker,
+			    GFP_ATOMIC);
+		err = 0;
+		goto out;
 	}
 
 	err = -EINVAL;
@@ -1183,7 +1208,16 @@ static int fib_check_nh_v4_gw(struct net
 	netdev_hold(dev, &nh->fib_nh_dev_tracker, GFP_ATOMIC);
 	if (!netif_carrier_ok(dev))
 		nh->fib_nh_flags |= RTNH_F_LINKDOWN;
-	err = (dev->flags & IFF_UP) ? 0 : -ENETDOWN;
+	if (!(dev->flags & IFF_UP)) {
+		if (fi->fib_protocol != RTPROT_STATIC) {
+			err = -ENETDOWN;
+			NL_SET_ERR_MSG(extack,
+				       "Device for nexthop is not up");
+			goto out;
+		}
+		nh->fib_nh_flags |= RTNH_F_DEAD;
+	}
+	err = 0;
 out:
 	rcu_read_unlock();
 	return err;
@@ -1192,6 +1226,7 @@ out:
 static int fib_check_nh_nongw(struct net *net, struct fib_nh *nh,
 			      struct netlink_ext_ack *extack)
 {
+	struct fib_info *fi = nh->nh_parent;
 	struct in_device *in_dev;
 	int err;
 
@@ -1209,8 +1244,11 @@ static int fib_check_nh_nongw(struct net
 		goto out;
 	err = -ENETDOWN;
 	if (!(in_dev->dev->flags & IFF_UP)) {
-		NL_SET_ERR_MSG(extack, "Device for nexthop is not up");
-		goto out;
+		if (fi->fib_protocol != RTPROT_STATIC) {
+			NL_SET_ERR_MSG(extack, "Device for nexthop is not up");
+			goto out;
+		}
+		nh->fib_nh_flags |= RTNH_F_DEAD;
 	}
 
 	nh->fib_nh_dev = in_dev->dev;
@@ -1980,10 +2018,15 @@ int fib_sync_down_dev(struct net_device
 		prev_fi = fi;
 		dead = 0;
 		change_nexthops(fi) {
-			if (nexthop_nh->fib_nh_flags & RTNH_F_DEAD)
-				dead++;
-			else if (nexthop_nh->fib_nh_dev == dev &&
-				 nexthop_nh->fib_nh_scope != scope) {
+			if (nexthop_nh->fib_nh_flags & RTNH_F_DEAD) {
+				if (fi->fib_protocol != RTPROT_STATIC ||
+				    !nexthop_nh->fib_nh_dev ||
+				    !__in_dev_get_rtnl(nexthop_nh->fib_nh_dev) ||
+				    nexthop_nh->fib_nh_dev->flags&IFF_UP)
+					dead++;
+			} else if (nexthop_nh->fib_nh_dev == dev &&
+				   nexthop_nh->fib_nh_scope != scope) {
+				write_lock_bh(&fib_nhflags_lock);
 				switch (event) {
 				case NETDEV_DOWN:
 				case NETDEV_UNREGISTER:
@@ -1995,7 +2038,11 @@ int fib_sync_down_dev(struct net_device
 				}
 				call_fib_nh_notifiers(nexthop_nh,
 						      FIB_EVENT_NH_DEL);
-				dead++;
+				write_unlock_bh(&fib_nhflags_lock);
+				if (fi->fib_protocol != RTPROT_STATIC ||
+				    force ||
+				    !__in_dev_get_rtnl(dev))
+					dead++;
 			}
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
 			if (event == NETDEV_UNREGISTER &&
@@ -2102,8 +2149,7 @@ out:
 }
 
 /*
- * Dead device goes up. We wake up dead nexthops.
- * It takes sense only on multipath routes.
+ * Dead device goes up or new address is added. We wake up dead nexthops.
  *
  * only used when fib_nh is built into fib_info
  */
@@ -2112,8 +2158,10 @@ int fib_sync_up(struct net_device *dev,
 	struct fib_info *prev_fi;
 	struct hlist_head *head;
 	struct fib_nh *nh;
-	int ret;
+	struct fib_result res;
+	int ret, rep;
 
+repeat:
 	if (!(dev->flags & IFF_UP))
 		return 0;
 
@@ -2127,6 +2175,7 @@ int fib_sync_up(struct net_device *dev,
 	prev_fi = NULL;
 	head = fib_nh_head(dev);
 	ret = 0;
+	rep = 0;
 
 	hlist_for_each_entry(nh, head, nh_hash) {
 		struct fib_info *fi = nh->nh_parent;
@@ -2140,16 +2189,39 @@ int fib_sync_up(struct net_device *dev,
 		prev_fi = fi;
 		alive = 0;
 		change_nexthops(fi) {
-			if (!(nexthop_nh->fib_nh_flags & nh_flags)) {
-				alive++;
+			if (!(nexthop_nh->fib_nh_flags & nh_flags))
 				continue;
-			}
 			if (!nexthop_nh->fib_nh_dev ||
 			    !(nexthop_nh->fib_nh_dev->flags & IFF_UP))
 				continue;
 			if (nexthop_nh->fib_nh_dev != dev ||
 			    !__in_dev_get_rtnl(dev))
 				continue;
+			if ((nh_flags & RTNH_F_DEAD) &&
+			    nexthop_nh->fib_nh_gw4 &&
+			    nexthop_nh->fib_nh_gw_family == AF_INET &&
+			    fi->fib_protocol == RTPROT_STATIC) {
+				struct flowi4 fl4 = {
+					.daddr = nexthop_nh->fib_nh_gw4,
+					.flowi4_scope = nexthop_nh->fib_nh_scope,
+					.flowi4_oif = nexthop_nh->fib_nh_oif,
+				};
+
+				rcu_read_lock();
+				if (fib_lookup(dev_net_rcu(dev), &fl4, &res,
+					FIB_LOOKUP_IGNORE_LINKSTATE) != 0) {
+					rcu_read_unlock();
+					continue;
+				}
+				if (res.type != RTN_UNICAST &&
+				    res.type != RTN_LOCAL) {
+					rcu_read_unlock();
+					continue;
+				}
+				nexthop_nh->fib_nh_scope = res.scope;
+				rcu_read_unlock();
+				rep = 1;
+			}
 			alive++;
 			nexthop_nh->fib_nh_flags &= ~nh_flags;
 			call_fib_nh_notifiers(nexthop_nh, FIB_EVENT_NH_ADD);
@@ -2162,6 +2234,8 @@ int fib_sync_up(struct net_device *dev,
 
 		fib_rebalance(fi);
 	}
+	if (rep)
+		goto repeat;
 
 	return ret;
 }
