mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: hengyul@cs.unc.edu
To: netdev@vger.kernel.org
Cc: "David S . Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@kernel.org>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Simon Horman <horms@kernel.org>, David Ahern <dsahern@kernel.org>,
	Ido Schimmel <idosch@nvidia.com>,
	Jiayuan Chen <jiayuan.chen@shopee.com>,
	Jiayuan Chen <jiayuan.chen@linux.dev>,
	Shuah Khan <shuah@kernel.org>,
	linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org,
	Hengyu Liang <hengyul@cs.unc.edu>,
	stable@vger.kernel.org
Subject: [PATCH net 1/2] ipv6: route: do not validate nexthop of routes promoted to reject routes
Date: Wed, 30 Sep 2026 11:22:28 -0400	[thread overview]
Message-ID: <20260930152229.1453929-2-hengyul@cs.unc.edu> (raw)
In-Reply-To: <20260930152229.1453929-1-hengyul@cs.unc.edu>

From: Hengyu Liang <hengyul@cs.unc.edu>

ip6_route_info_create_nh() promotes routes that use the loopback device
as their nexthop device to reject routes, except for local and anycast
routes and routes to the loopback address, as true routes via the
loopback device would result in kernel looping.

Before commit 21ec92774d15 ("net: ipv6: fix panic when IPv4 route
references loopback IPv6 nexthop"), fib6_nh_init() also treated these
routes as reject routes, so it neither validated their gateway nor
checked the state of the loopback device. That commit restricted the
check in fib6_nh_init() to explicit reject routes to fix IPv6 nexthop
objects that use the loopback device. As a side effect, the nexthop of a
route via the loopback device is now validated like the nexthop of a
regular route before the route is promoted to a reject route, and adding
such a route fails in cases that used to work:

  # ip link set dev lo down
  # ip -6 route add 2001:db8::/32 dev lo
  Error: Nexthop device is not up.
  # ip link set dev lo up
  # ip -6 route add 2001:db8::/32 via 2001:db8:1::1 dev lo
  RTNETLINK answers: No route to host
  # ip -6 route add default via ::ffff:192.0.2.1 dev lo
  RTNETLINK answers: No route to host
  # sysctl -qw net.ipv6.conf.lo.disable_ipv6=1
  # ip -6 route add 2001:db8::/32 dev lo
  Error: IPv6 is disabled on nexthop device.

As the loopback device is down in a new network namespace, the first
case affects routes added before the loopback device is brought up. The
SIOCADDRT ioctl fails in the same way.

Restore the previous check in fib6_nh_init() for routes created by
ip6_route_info_create_nh(). IPv6 nexthop objects and IPv4 routes with an
IPv6 gateway are never promoted to reject routes, so they keep the
current check and the panic fixed by the above commit does not come
back.

Fixes: 21ec92774d15 ("net: ipv6: fix panic when IPv4 route references loopback IPv6 nexthop")
Cc: stable@vger.kernel.org
Signed-off-by: Hengyu Liang <hengyul@cs.unc.edu>
---
 net/ipv6/route.c | 29 +++++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 153ce16628c1..49ff87aa3756 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -3592,13 +3592,14 @@ static bool fib6_is_reject(u32 flags, struct net_device *dev, int addr_type)
 	return false;
 }
 
-int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh,
-		 struct fib6_config *cfg, gfp_t gfp_flags,
-		 struct netlink_ext_ack *extack)
+static int __fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh,
+			  struct fib6_config *cfg, bool lo_reject,
+			  gfp_t gfp_flags, struct netlink_ext_ack *extack)
 {
 	netdevice_tracker *dev_tracker = &fib6_nh->fib_nh_dev_tracker;
 	struct net_device *dev = NULL;
 	struct inet6_dev *idev = NULL;
+	bool reject;
 	int err;
 
 	if (!ipv6_mod_enabled()) {
@@ -3646,9 +3647,17 @@ int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh,
 	fib6_nh->fib_nh_weight = 1;
 
 	/* Reset the nexthop device to the loopback device in case of reject
-	 * routes.
+	 * routes. If requested, also treat routes via the loopback device as
+	 * reject routes, as ip6_route_info_create_nh() promotes them to reject
+	 * routes and their nexthop does not need to be validated.
 	 */
-	if (cfg->fc_flags & RTF_REJECT) {
+	if (lo_reject)
+		reject = fib6_is_reject(cfg->fc_flags, dev,
+					ipv6_addr_type(&cfg->fc_dst));
+	else
+		reject = cfg->fc_flags & RTF_REJECT;
+
+	if (reject) {
 		/* hold loopback dev/idev if we haven't done so. */
 		if (dev != net->loopback_dev) {
 			if (dev) {
@@ -3725,6 +3734,13 @@ int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh,
 	return err;
 }
 
+int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh,
+		 struct fib6_config *cfg, gfp_t gfp_flags,
+		 struct netlink_ext_ack *extack)
+{
+	return __fib6_nh_init(net, fib6_nh, cfg, false, gfp_flags, extack);
+}
+
 void fib6_nh_release(struct fib6_nh *fib6_nh)
 {
 	struct rt6_exception_bucket *bucket;
@@ -3917,7 +3933,8 @@ static int ip6_route_info_create_nh(struct fib6_info *rt,
 	} else {
 		int addr_type;
 
-		err = fib6_nh_init(net, rt->fib6_nh, cfg, gfp_flags, extack);
+		err = __fib6_nh_init(net, rt->fib6_nh, cfg, true, gfp_flags,
+				     extack);
 		if (err)
 			goto out_release;
 
-- 
2.53.0


  reply	other threads:[~2026-09-30 15:23 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-30 15:22 [PATCH net 0/2] ipv6: route: fix adding routes via the loopback device hengyul
2026-09-30 15:22 ` hengyul [this message]
2026-10-01 15:46   ` [PATCH net 1/2] ipv6: route: do not validate nexthop of routes promoted to reject routes Ido Schimmel
2026-10-02  3:21     ` Hengyu Liang
2026-09-30 15:22 ` [PATCH net 2/2] selftests: net: fib_tests: add tests for IPv6 routes via loopback device hengyul
2026-09-30 15:28 ` [PATCH net 0/2] ipv6: route: fix adding routes via the " netdev-bot+sinfo
2026-10-01 20:44 ` [syzbot ci] " syzbot ci

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260930152229.1453929-2-hengyul@cs.unc.edu \
    --to=hengyul@cs.unc.edu \
    --cc=davem@davemloft.net \
    --cc=dsahern@kernel.org \
    --cc=edumazet@kernel.org \
    --cc=horms@kernel.org \
    --cc=idosch@nvidia.com \
    --cc=jiayuan.chen@linux.dev \
    --cc=jiayuan.chen@shopee.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=shuah@kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®