From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: passt.top; dkim=pass (2048-bit key; secure) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.a=rsa-sha256 header.s=202602 header.b=LRVWjSnp; dkim-atps=neutral Received: from mail.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id 3C14A5A0269 for ; Tue, 24 Mar 2026 06:49:50 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202602; t=1774331387; bh=nS5o0iaRmq/gG2HAF5CqAlW8pN3L9LBDRGfOz20vwQs=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=LRVWjSnpmLBfbri1CM+3IYU2Vop0CibtkaEu6ym2XbjvqueNKKBQbPEl8YfHvYsPj OBHBO/cvjk9GvKCXQXm7mbnzNZCh0KnCubGFxr8aFix0QGYQLh3Zr6BtHvZ5ATJFfI +1YhFghD+ttN5swXpvgOVnFF9Wd/TZvfrNFCKwGAZOiX9UnBqPJ+siapKyz101N7yY AtgWBhvZmL7ZXbknuLZPyU/+2CzriFqVs4ZKFqSNoIuV0wvhErzFPdzhJMwsJHciTQ bkKsooW5PuntQbwMiN7J5BRCmxck0G6elpIXhGtyEanC1B2bQkAUpi9hE+/iFqWDzg bY6Q5jDZUf56g== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4ffzdR2sJtz4wG7; Tue, 24 Mar 2026 16:49:47 +1100 (AEDT) Date: Tue, 24 Mar 2026 16:36:02 +1100 From: David Gibson To: Jon Maloy Subject: Re: [PATCH v6 06/13] netlink, conf: Read all addresses from template interface at startup Message-ID: References: <20260322004333.365713-1-jmaloy@redhat.com> <20260322004333.365713-7-jmaloy@redhat.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="0m3R6fCjeMNt+RDn" Content-Disposition: inline In-Reply-To: <20260322004333.365713-7-jmaloy@redhat.com> Message-ID-Hash: OSAUFDWX2F6DOIEORH6YDYKXZ27WQUJC X-Message-ID-Hash: OSAUFDWX2F6DOIEORH6YDYKXZ27WQUJC 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: sbrivio@redhat.com, dgibson@redhat.com, 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: --0m3R6fCjeMNt+RDn Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Sat, Mar 21, 2026 at 08:43:26PM -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. >=20 > 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. >=20 > For IPv6, the function also captures the link-local address into > c->ip6.our_tap_ll as a side effect. >=20 > Update conf_ip4() and conf_ip6() to use nl_addr_get_all() when no > user-specified addresses are present. >=20 > Signed-off-by: Jon Maloy Reviewed-by: David Gibson > --- > conf.c | 51 ++++++++++++++++++++++++++++----------------------- > netlink.c | 53 +++++++++++++++++++++++++++++------------------------ > netlink.h | 3 +-- > 3 files changed, 58 insertions(+), 49 deletions(-) >=20 > 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 =3D &c->ip4; > + const struct guest_addr *a; > =20 > if (!ifi) > ifi =3D nl_get_ext_if(nl_sock, AF_INET); > @@ -755,24 +756,24 @@ static unsigned int conf_ip4(struct ctx *c, unsigne= d int ifi) > } > } > =20 > - if (!fwd_get_addr(c, AF_INET, 0, 0)) { > - struct in_addr addr; > - int prefix_len; > - int rc =3D nl_addr_get(nl_sock, ifi, AF_INET, > - &addr, &prefix_len, NULL); > + a =3D fwd_get_addr(c, AF_INET, CONF_ADDR_USER, 0); > + if (!a) { > + int rc =3D 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; > =20 > - fwd_set_addr(c, &inany_from_v4(addr), CONF_ADDR_HOST, > - prefix_len + 96); > - ip4->addr_seen =3D addr; > + a =3D fwd_get_addr(c, AF_INET, CONF_ADDR_HOST, 0); > } > =20 > + if (a) > + ip4->addr_seen =3D *inany_v4(&a->addr); > + > ip4->our_tap_addr =3D ip4->guest_gw; > =20 > 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 =3D fwd_get_addr(c, AF_INET6, 0, 0); > struct ip6_ctx *ip6 =3D &c->ip6; > - union inany_addr addr; > - int prefix_len =3D 0; > + const struct guest_addr *a; > int rc; > =20 > if (!ifi) > @@ -826,20 +825,26 @@ static unsigned int conf_ip6(struct ctx *c, unsigne= d int ifi) > } > } > =20 > - rc =3D 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 =3D 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 =3D addr.a6; > + rc =3D 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 =3D fwd_get_addr(c, AF_INET6, CONF_ADDR_HOST, 0); > } else { > - ip6->addr_seen =3D a->addr.a6; > + rc =3D nl_addr_get_ll(nl_sock, ifi, &ip6->our_tap_ll); > + if (rc < 0) { > + debug("Couldn't get link-local address: %s", > + strerror_(-rc)); > + } > } > =20 > + if (a) > + ip6->addr_seen =3D a->addr.a6; > + > if (IN6_IS_ADDR_LINKLOCAL(&ip6->guest_gw)) > ip6->our_tap_ll =3D ip6->guest_gw; > =20 > 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) > } > =20 > /** > - * 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 inter= face. > + * 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). > + * > + * 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 =3D 0, prefix_max_ll =3D 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 =3D 0; > uint32_t seq; > =20 > seq =3D 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, > =20 > for (rta =3D IFA_RTA(ifa), na =3D IFA_PAYLOAD(nh); RTA_OK(rta, na); > rta =3D RTA_NEXT(rta, na)) { > - if ((af =3D=3D AF_INET && rta->rta_type !=3D IFA_LOCAL) || > - (af =3D=3D AF_INET6 && rta->rta_type !=3D IFA_ADDRESS)) > - continue; > + union inany_addr addr; > + int prefix_len; > =20 > - if (ifa->ifa_prefixlen > prefix_max && addr && > - (af =3D=3D AF_INET || ifa->ifa_scope < RT_SCOPE_LINK)) { > - memcpy(addr, RTA_DATA(rta), RTA_PAYLOAD(rta)); > + if (af =3D=3D AF_INET && rta->rta_type !=3D IFA_LOCAL) > + continue; > + if (af =3D=3D AF_INET6 && rta->rta_type !=3D IFA_ADDRESS) > + continue; > =20 > - prefix_max =3D *prefix_len =3D ifa->ifa_prefixlen; > + if (af =3D=3D AF_INET6 && > + ifa->ifa_scope =3D=3D RT_SCOPE_LINK) { > + memcpy(&c->ip6.our_tap_ll, RTA_DATA(rta), > + sizeof(c->ip6.our_tap_ll)); > + continue; > } > =20 > - if (addr_l && > - af =3D=3D AF_INET6 && ifa->ifa_scope =3D=3D 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 =3D ifa->ifa_prefixlen + > + (af =3D=3D AF_INET ? 96 : 0); > =20 > - prefix_max_ll =3D ifa->ifa_prefixlen; > - } > + fwd_set_addr(c, &addr, CONF_ADDR_HOST, prefix_len); > + count++; > } > } > - return status; > + > + return status < 0 ? status : count; > } > =20 > /** > 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, > --=20 > 2.52.0 >=20 --=20 David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson --0m3R6fCjeMNt+RDn Content-Type: application/pgp-signature; name=signature.asc -----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEEO+dNsU4E3yXUXRK2zQJF27ox2GcFAmnCIsEACgkQzQJF27ox 2GeUIQ//Qj++eE3hfwVz+lT4PNlkBdpz0JJKcHn1X9BdFBj+kiLgU/yxYINv16s2 1ykbk2i0ymqpx0iEo1cmlSm1AhzjncDg7cGFvvny6FPI7ZwkhbHDPM5I+tl6RwXR UWBs+/0dHJtJz5RqazynwDyG82PnhgrMK8Ggf867Qd731u5KWpq5OQK419u+deNx 4MX1K1c/EifOJEkZKwpJgxjyLvgy8KTyvIB2xJnkXYOfVGfoW0I7xSuR97yuZfLl i9/ChicFzKe/IFmRpu7KVuimq5Q+G4p08t2i+BVwhoMl6BBJv0SxPPQD5SUEcSUh I8bLktKj3FcVk4EhdH/86iCqsFfTp0bzI4dt6eq/aKdUz18TMYrT7NV0b8xqFD34 eL8dmZxANG14TsrL4OKr/CnLU5x6fcda5oucMmZG77xwJ1tJ37pSvbOsOXpJcpkp PDQlhhnmnkATIf0k0DxP6SRukcO5qT1bPJuLDIXliuwBKBVgKfFoIL+gtPgicgWg J73OCyGN296zCNnXLcSPcLxGKna9YeAVKfIi/f3Ff2ydZcs3OOyCLPTFAyxn8yDu rNFJSv5TqE1W0rG6qVtW8eMCqtMaxMH1FToGruWi8opamN6TNZWhjNCwFoGIt3+I XP7AA5H61ugBzvg8vsXJVqj2GafFz7Qa74iFnmeDDUil6GrfjPc= =ShXm -----END PGP SIGNATURE----- --0m3R6fCjeMNt+RDn--