From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: passt.top; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=IaENOSD3; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by passt.top (Postfix) with ESMTPS id B6A9E5A0262 for ; Mon, 30 Mar 2026 23:58:02 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1774907881; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=izZ0t31USSxiFE19p+AWa/lPU1RHfY8VArextnHPr7Q=; b=IaENOSD3rk6KpPH95mo3LXlGWSHDpxiO25D3L/FqLiZ5D88xGLIJJKWGMNUqy8d94ESqcp pT5mT7CY0YmiMuWLFZDpJOpV5W/A5KfFT9YpPRSIDVGI4feBbb0RCCYGFD7D4RcJjm91Uy ojXCCIl1HNS1PDRcwXqRqjIzBxJJ9Wc= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-403-AMP1RrZnOj67-UO0uHu6Qw-1; Mon, 30 Mar 2026 17:58:00 -0400 X-MC-Unique: AMP1RrZnOj67-UO0uHu6Qw-1 X-Mimecast-MFC-AGG-ID: AMP1RrZnOj67-UO0uHu6Qw_1774907879 Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-4852ccff333so53435035e9.2 for ; Mon, 30 Mar 2026 14:58:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774907879; x=1775512679; h=date:content-transfer-encoding:mime-version:organization:references :in-reply-to:message-id:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=izZ0t31USSxiFE19p+AWa/lPU1RHfY8VArextnHPr7Q=; b=UQBbZzOiY9QPIP7DMFgXAusUgY8ZJbiENJcnDxeixQdX+dkImBwntk++rHb7ORLS8G qbqkIwdD/qGdBGGZ2xIl9ZMKyX09rfyWlu08bvKZInJVusrJiQSkLEFoiBcT3ODLykxJ lIY6B4Evi91MtdXmNmsuPKjvYzLewRlYy1jnTf4tI3N8Efb3UObG1SrMcMm1H99VehNK Ow5KqsQeE+BUwgYmTwN01tTj4LvmL0aAPIZQ2UIOhfJy65DRSz+ha8D+ZjE8EELNj647 4j0DN7/JKbankyrwBs/lf8RcJGej9pPJz1CmIF4AsBE01wdfzBL7+v/k/6ADQa3N03Lh cCAA== X-Forwarded-Encrypted: i=1; AJvYcCXwzIMZz4BiL+f0t8pJ/Wvd8qwPXe5WlagpHegShiWjhMMq2D0cTVX5u8Y1WU+kUS4uVXto4+Z52ZA=@passt.top X-Gm-Message-State: AOJu0YxH2L1HTli+6GH6sl9KjAPxc2Z52SwHSFBDP6XZJO5JgyXQRcAT 1PiGd4KHgWAL50UebUMa8tz4nfQJumX4GTc6phUNmxMB+BFtlVu1dI3cl+c9L/6VmT4sUQ1Fgfl fROge6J040ohAkt1nbQUznjOwoZ+nD3lakLcMR1/rA3LxUgCzSlFBCQ== X-Gm-Gg: ATEYQzxBB9MuTV5fiZZFgaN5BZ5GeeypkMVtkAD3JZlUYjaAFxvD+qG7OV0hbD55ZXC VjeNh362FOY0ZFhpnyt9rQDNu9WqgTWCtinZy+1cwuwQjFfp9aDkmYwWIYxPhagkyLDSGBs5leC J8XdpdRHnQwd2O78bv4Qut9fs81Bt2/5RgGvaaEI9PjKtxCm3gvPpAbhWPx2yh8iuubkItg5NWP YeotZgSRHU0IfzyYKvwadovA36hLaLu9anfloeb9b4+xkT6T1Vx7ylXFcC5KON3QtwwI/UCAa3B wM3TSObF7Hh42J3tZ6uGjYvKu8j4dYGOJZoEIG0hVfQet53UDOzXKGHwND9BQ6CO6d/wIGT4k9E cYw3wShEoKFCuFGKYKN4qe9EqTCFKDiT4 X-Received: by 2002:a05:600c:8b31:b0:485:30f7:6e88 with SMTP id 5b1f17b1804b1-48727efabdemr284837115e9.31.1774907878775; Mon, 30 Mar 2026 14:57:58 -0700 (PDT) X-Received: by 2002:a05:600c:8b31:b0:485:30f7:6e88 with SMTP id 5b1f17b1804b1-48727efabdemr284836865e9.31.1774907878184; Mon, 30 Mar 2026 14:57:58 -0700 (PDT) Received: from maya.myfinge.rs (ifcgrfdd.trafficplex.cloud. [2a10:fc81:a806:d6a9::1]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48722c957b9sm454138565e9.8.2026.03.30.14.57.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Mar 2026 14:57:57 -0700 (PDT) From: Stefano Brivio To: Jon Maloy Subject: Re: [PATCH v6 06/13] netlink, conf: Read all addresses from template interface at startup Message-ID: <20260330235755.64e2c34b@elisabeth> In-Reply-To: <20260322004333.365713-7-jmaloy@redhat.com> References: <20260322004333.365713-1-jmaloy@redhat.com> <20260322004333.365713-7-jmaloy@redhat.com> Organization: Red Hat X-Mailer: Claws Mail 4.2.0 (GTK 3.24.49; x86_64-pc-linux-gnu) MIME-Version: 1.0 Date: Mon, 30 Mar 2026 23:57:56 +0200 (CEST) X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: C1oi2lEl6icKEAKIxDjUjzM3hO76Qpc4TqS6RAM4RCE_1774907879 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Message-ID-Hash: 4BZAME53R7NACNCJ2E75DA7K6ECDK74M X-Message-ID-Hash: 4BZAME53R7NACNCJ2E75DA7K6ECDK74M X-MailFrom: sbrivio@redhat.com 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: david@gibson.dropbear.id.au, passt-dev@passt.top 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: On Sat, 21 Mar 2026 20:43:26 -0400 Jon Maloy wrote: > Add nl_addr_get_all() to read all addresses from the template interface > into c->addrs[] array, rather than just selecting the "best" one. > > This allows multi-address configurations where the template interface > has multiple IPv4 or IPv6 addresses assigned to it, all of which > will now be copied to the guest namespace when using --config-net. > > For IPv6, the function also captures the link-local address into > c->ip6.our_tap_ll as a side effect. > > Update conf_ip4() and conf_ip6() to use nl_addr_get_all() when no > user-specified addresses are present. > > Signed-off-by: Jon Maloy > --- > conf.c | 51 ++++++++++++++++++++++++++++----------------------- > netlink.c | 53 +++++++++++++++++++++++++++++------------------------ > netlink.h | 3 +-- > 3 files changed, 58 insertions(+), 49 deletions(-) > > diff --git a/conf.c b/conf.c > index 95f09cb..70435d3 100644 > --- a/conf.c > +++ b/conf.c > @@ -736,6 +736,7 @@ static int conf_ip4_prefix(const char *arg) > static unsigned int conf_ip4(struct ctx *c, unsigned int ifi) > { > struct ip4_ctx *ip4 = &c->ip4; > + const struct guest_addr *a; > > if (!ifi) > ifi = nl_get_ext_if(nl_sock, AF_INET); > @@ -755,24 +756,24 @@ static unsigned int conf_ip4(struct ctx *c, unsigned int ifi) > } > } > > - if (!fwd_get_addr(c, AF_INET, 0, 0)) { > - struct in_addr addr; > - int prefix_len; > - int rc = nl_addr_get(nl_sock, ifi, AF_INET, > - &addr, &prefix_len, NULL); > + a = fwd_get_addr(c, AF_INET, CONF_ADDR_USER, 0); > + if (!a) { > + int rc = nl_addr_get_all(c, nl_sock, ifi, AF_INET); > + > if (rc < 0) { > - debug("Couldn't discover IPv4 address: %s", > + debug("Couldn't discover IPv4 addresses: %s", > strerror_(-rc)); > return 0; > } > - if (IN4_IS_ADDR_UNSPECIFIED(&addr)) > + if (!rc || !fwd_get_addr(c, AF_INET, 0, 0)) > return 0; > > - fwd_set_addr(c, &inany_from_v4(addr), CONF_ADDR_HOST, > - prefix_len + 96); > - ip4->addr_seen = addr; > + a = fwd_get_addr(c, AF_INET, CONF_ADDR_HOST, 0); > } > > + if (a) > + ip4->addr_seen = *inany_v4(&a->addr); > + > ip4->our_tap_addr = ip4->guest_gw; > > return ifi; > @@ -803,10 +804,8 @@ static void conf_ip4_local(struct ctx *c) > */ > static unsigned int conf_ip6(struct ctx *c, unsigned int ifi) > { > - const struct guest_addr *a = fwd_get_addr(c, AF_INET6, 0, 0); > struct ip6_ctx *ip6 = &c->ip6; > - union inany_addr addr; > - int prefix_len = 0; > + const struct guest_addr *a; > int rc; > > if (!ifi) > @@ -826,20 +825,26 @@ static unsigned int conf_ip6(struct ctx *c, unsigned int ifi) > } > } > > - rc = nl_addr_get(nl_sock, ifi, AF_INET6, &addr.a6, > - &prefix_len, &ip6->our_tap_ll); > - if (rc < 0) { > - debug("Couldn't discover IPv6 address: %s", strerror_(-rc)); > - return 0; > - } > - > + a = fwd_get_addr(c, AF_INET6, CONF_ADDR_USER, 0); > if (!a) { > - fwd_set_addr(c, &addr, CONF_ADDR_HOST, prefix_len); > - ip6->addr_seen = addr.a6; > + rc = nl_addr_get_all(c, nl_sock, ifi, AF_INET6); > + if (rc < 0) { > + debug("Couldn't discover IPv6 addresses: %s", > + strerror_(-rc)); > + return 0; > + } > + a = fwd_get_addr(c, AF_INET6, CONF_ADDR_HOST, 0); > } else { > - ip6->addr_seen = a->addr.a6; > + rc = nl_addr_get_ll(nl_sock, ifi, &ip6->our_tap_ll); > + if (rc < 0) { > + debug("Couldn't get link-local address: %s", > + strerror_(-rc)); > + } > } > > + if (a) > + ip6->addr_seen = a->addr.a6; > + > if (IN6_IS_ADDR_LINKLOCAL(&ip6->guest_gw)) > ip6->our_tap_ll = ip6->guest_gw; > > diff --git a/netlink.c b/netlink.c > index e07b47f..2727eec 100644 > --- a/netlink.c > +++ b/netlink.c > @@ -747,20 +747,20 @@ int nl_addr_set_ll_nodad(int s, unsigned int ifi) > } > > /** > - * nl_addr_get() - Get most specific global address, given interface and family > + * nl_addr_get_all() - Get all addresses for a given interface into ctx > + * @c: Execution context > * @s: Netlink socket > - * @ifi: Interface index in outer network namespace > - * @af: Address family > - * @addr: Global address to fill > - * @prefix_len: Mask or prefix length, to fill > - * @addr_l: Link-scoped address to fill (for IPv6) > + * @ifi: Interface index > + * @af: Address family (AF_INET or AF_INET6) > * > - * Return: 0 on success, negative error code on failure > + * Populates c->addrs[] with all non-deprecated addresses from the interface. > + * For IPv6, also captures link-local address in c->ip6.our_tap_ll. > + * Skips link-local addresses for the main array (kernel auto-configures them). Skips IPv6 link-local addresses... > + * > + * Return: number of addresses added, or negative error code on failure > */ > -int nl_addr_get(int s, unsigned int ifi, sa_family_t af, > - void *addr, int *prefix_len, void *addr_l) > +int nl_addr_get_all(struct ctx *c, int s, unsigned int ifi, sa_family_t af) > { > - uint8_t prefix_max = 0, prefix_max_ll = 0; > struct req_t { > struct nlmsghdr nlh; > struct ifaddrmsg ifa; > @@ -771,6 +771,7 @@ int nl_addr_get(int s, unsigned int ifi, sa_family_t af, > struct nlmsghdr *nh; > char buf[NLBUFSIZ]; > ssize_t status; > + int count = 0; > uint32_t seq; > > seq = nl_send(s, &req, RTM_GETADDR, NLM_F_DUMP, sizeof(req)); > @@ -784,27 +785,31 @@ int nl_addr_get(int s, unsigned int ifi, sa_family_t af, > > for (rta = IFA_RTA(ifa), na = IFA_PAYLOAD(nh); RTA_OK(rta, na); > rta = RTA_NEXT(rta, na)) { > - if ((af == AF_INET && rta->rta_type != IFA_LOCAL) || > - (af == AF_INET6 && rta->rta_type != IFA_ADDRESS)) > - continue; > + union inany_addr addr; > + int prefix_len; > > - if (ifa->ifa_prefixlen > prefix_max && addr && > - (af == AF_INET || ifa->ifa_scope < RT_SCOPE_LINK)) { > - memcpy(addr, RTA_DATA(rta), RTA_PAYLOAD(rta)); > + if (af == AF_INET && rta->rta_type != IFA_LOCAL) > + continue; > + if (af == AF_INET6 && rta->rta_type != IFA_ADDRESS) > + continue; > > - prefix_max = *prefix_len = ifa->ifa_prefixlen; > + if (af == AF_INET6 && > + ifa->ifa_scope == RT_SCOPE_LINK) { > + memcpy(&c->ip6.our_tap_ll, RTA_DATA(rta), > + sizeof(c->ip6.our_tap_ll)); > + continue; > } > > - if (addr_l && > - af == AF_INET6 && ifa->ifa_scope == RT_SCOPE_LINK && > - ifa->ifa_prefixlen > prefix_max_ll) { > - memcpy(addr_l, RTA_DATA(rta), RTA_PAYLOAD(rta)); > + inany_from_af(&addr, af, RTA_DATA(rta)); > + prefix_len = ifa->ifa_prefixlen + > + (af == AF_INET ? 96 : 0); > > - prefix_max_ll = ifa->ifa_prefixlen; > - } > + fwd_set_addr(c, &addr, CONF_ADDR_HOST, prefix_len); > + count++; > } > } > - return status; > + > + return status < 0 ? status : count; > } > > /** > diff --git a/netlink.h b/netlink.h > index b22f485..3af6d58 100644 > --- a/netlink.h > +++ b/netlink.h > @@ -19,8 +19,7 @@ int nl_route_get_def(int s, unsigned int ifi, sa_family_t af, void *gw); > int nl_route_set_def(int s, unsigned int ifi, sa_family_t af, const void *gw); > int nl_route_dup(int s_src, unsigned int ifi_src, > int s_dst, unsigned int ifi_dst, sa_family_t af); > -int nl_addr_get(int s, unsigned int ifi, sa_family_t af, > - void *addr, int *prefix_len, void *addr_l); > +int nl_addr_get_all(struct ctx *c, int s, unsigned int ifi, sa_family_t af); > bool nl_neigh_mac_get(int s, const union inany_addr *addr, int ifi, > unsigned char *mac); > int nl_addr_set(int s, unsigned int ifi, sa_family_t af, I only reviewed up to 8/13, 7/13 looks good to me (minus comments from David), and I plan to finish reviewing the rest soon, but I thought I'd start sharing the comments I have so far, meanwhile. -- Stefano