From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from gandalf.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 10B305A026F for ; Thu, 21 Mar 2024 05:04:58 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202312; t=1710993893; bh=Ws3a83mtWB9HYo5NIhux9c/pAstmTgejvKfQhuElewI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rLTnJxWHwJigg/nWeGL8fcuROM8cE6uiqhWfQq40bMHPS+ENNlA727fLCYpLJgkhT gdSWAukTTEeUQb+XgBecyOXg6ADpLDLIz4ZEL0vCtz3tlFBNG2UWnMI2Dv5Af0MoGg IqZ+2QW0EPcA0629xiNxG5NossCfqvdym2Cpea5C66f5VpTLdSUeXAmvmhrOZyOmSh NN4BPa1YR31+Xsa3oqeG3yTg1e92c3+uHPhdK6MisLOSa9c+otmP0Oho93PB+W9gUu h1SLOBVJL+i5wHR9tHGP5cn3XURUl05ABOJu7ovD403qmjGWp9ZStqXHjn94fpAVY9 PPVs+DXHE11UQ== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4V0X0j05Jwz4wqM; Thu, 21 Mar 2024 15:04:53 +1100 (AEDT) From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH 2/2] netlink: Ignore routes to link-local addresses for selecting interface Date: Thu, 21 Mar 2024 15:04:49 +1100 Message-ID: <20240321040449.1889385-3-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240321040449.1889385-1-david@gibson.dropbear.id.au> References: <20240321040449.1889385-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: SXL4VNIYR4HECXKVMRVSVI6ISKYT5UQU X-Message-ID-Hash: SXL4VNIYR4HECXKVMRVSVI6ISKYT5UQU X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Paul Holzinger , David Gibson X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Since f919dc7a4b1c ("conf, netlink: Don't require a default route to start"), and since 639fdf06ede ("netlink: Fix selection of template interface") less buggily, we haven't required a default route on the host in order to operate. Instead, if we lack a default route we'll pick an interface with any route, as long as there's only one such interface. If there's more than one, we don't have a good criterion to pick, so we give up with an informational message. Paul Holzinger pointed out that this code considers it ambiguous even if all but one of the interfaces has only routes to link-local addresses (fe80::/10). A route to link-local addresses isn't really useful from pasta's point of view, so ignore them instead. This removes a misleading message in many cases, and a spurious failure in some cases. Suggested-by: Paul Holzinger Signed-off-by: David Gibson --- ip.h | 9 +++++++++ netlink.c | 15 ++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/ip.h b/ip.h index b9aedf65..b8d4a5bf 100644 --- a/ip.h +++ b/ip.h @@ -24,6 +24,11 @@ #define IN4ADDR_ANY_INIT \ { .s_addr = htonl_constant(INADDR_ANY) } +#define IN4_IS_ADDR_LINKLOCAL(a) \ + ((ntohl(((struct in_addr *)(a))->s_addr) >> 16) == 0xa9fe) +#define IN4_IS_PREFIX_LINKLOCAL(a, len) \ + ((len) >= 16 && IN4_IS_ADDR_LINKLOCAL(a)) + #define L2_BUF_IP4_INIT(proto) \ { \ .version = 4, \ @@ -40,6 +45,10 @@ #define L2_BUF_IP4_PSUM(proto) ((uint32_t)htons_constant(0x4500) + \ (uint32_t)htons(0xff00 | (proto))) + +#define IN6_IS_PREFIX_LINKLOCAL(a, len) \ + ((len) >= 10 && IN6_IS_ADDR_LINKLOCAL(a)) + #define L2_BUF_IP6_INIT(proto) \ { \ .priority = 0, \ diff --git a/netlink.c b/netlink.c index b068aef2..a722d272 100644 --- a/netlink.c +++ b/netlink.c @@ -33,6 +33,7 @@ #include "util.h" #include "passt.h" #include "log.h" +#include "ip.h" #include "netlink.h" /* Netlink expects a buffer of at least 8kiB or the system page size, @@ -270,6 +271,7 @@ unsigned int nl_get_ext_if(int s, sa_family_t af) seq = nl_send(s, &req, RTM_GETROUTE, NLM_F_DUMP, sizeof(req)); nl_foreach_oftype(nh, status, s, buf, seq, RTM_NEWROUTE) { struct rtmsg *rtm = (struct rtmsg *)NLMSG_DATA(nh); + const void *dst = NULL; unsigned thisifi = 0; if (rtm->rtm_family != af) @@ -284,12 +286,23 @@ unsigned int nl_get_ext_if(int s, sa_family_t af) rtnh = (struct rtnexthop *)RTA_DATA(rta); thisifi = rtnh->rtnh_ifindex; + } else if (rta->rta_type == RTA_DST) { + dst = RTA_DATA(rta); } } if (!thisifi) continue; /* No interface for this route */ + /* Skip routes to link-local addresses */ + if (af == AF_INET && dst && + IN4_IS_PREFIX_LINKLOCAL(dst, rtm->rtm_dst_len)) + continue; + + if (af == AF_INET6 && dst && + IN6_IS_PREFIX_LINKLOCAL(dst, rtm->rtm_dst_len)) + continue; + if (rtm->rtm_dst_len == 0) { /* Default route */ ndef++; @@ -322,7 +335,7 @@ unsigned int nl_get_ext_if(int s, sa_family_t af) } if (!nany) - info("No interfaces with %s routes", af_name(af)); + info("No interfaces with usable %s routes", af_name(af)); return 0; } -- 2.44.0