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=fail reason="key not found in DNS" header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.a=rsa-sha256 header.s=202312 header.b=EYvFhZHZ; dkim-atps=neutral Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 87E705A0277 for ; Thu, 15 Aug 2024 05:43:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202312; t=1723693394; bh=Bwtjnl1RTORzhBceloBZWX3s3aK3CSVqyrBolsp0EWc=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=EYvFhZHZoJetabJanx1bjLxCwaSMVBGcb2zK9MOFIhpgXYSunfRBh32vfsthR5kB3 7WYnH9qQbo82RBXLp67gtVkyE/FMch6FKdU3o+VaY91O/cWK6lSrd0PuUnjNnzW+uY ZBSiDcgktNl7Qxnpn1K8O2AvTQl9qweouMRzqLOXVN0Lp/PEH3CPGjENRdM/s/OuyM NrQwbN9aR6VvXwxWv7YcrIpdUwzH4L654p/P0r7tzVIhE3gTXNncyIoDxraAO9yTFs dV3jkrPZLZdESVBEHeOuy0vRK5j+OHpg/tw3mQwA8H0QzGSzYWLWZLkTgKCnl+Id1b p8y9FYfQ2MD0g== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4WkrYt0N6sz4x4c; Thu, 15 Aug 2024 13:43:14 +1000 (AEST) Date: Thu, 15 Aug 2024 13:01:08 +1000 From: David Gibson To: Stefano Brivio Subject: Re: [PATCH 4/7] netlink, pasta: Disable DAD for link-local addresses on namespace interface Message-ID: References: <20240814225429.3707908-1-sbrivio@redhat.com> <20240814225429.3707908-5-sbrivio@redhat.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="0zEiOM0hSgAaiZVs" Content-Disposition: inline In-Reply-To: <20240814225429.3707908-5-sbrivio@redhat.com> Message-ID-Hash: IHDG5MO5L7ROEY4VEN2FQLGQH7BVT5RK X-Message-ID-Hash: IHDG5MO5L7ROEY4VEN2FQLGQH7BVT5RK 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: passt-dev@passt.top, Paul Holzinger 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: --0zEiOM0hSgAaiZVs Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Thu, Aug 15, 2024 at 12:54:26AM +0200, Stefano Brivio wrote: > It makes no sense for a container or a guest to try and perform > duplicate address detection for their link-local address, as we'll > anyway not relay neighbour solicitations with an unspecified source > address. >=20 > While they perform duplicate address detection, the link-local address > is not usable, which prevents us from bringing up especially > containers and communicate with them right away via IPv6. >=20 > This is not enough to prevent DAD and reach the container right away: > we'll need a couple more patches. >=20 > A large part of the function setting the nodad attribute is copied^W > vendored from nl_routes_dup(), and we could probably refactor things > to avoid code duplication, eventually, but keep this simple for the > moment. I don't really care about the duplication, but I'm not sure nl_routes_dup() was the right thing to vendor. > Link: https://github.com/containers/podman/pull/23561#discussion_r1711639= 663 > Signed-off-by: Stefano Brivio > --- > netlink.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > netlink.h | 1 + > pasta.c | 6 ++++ > 3 files changed, 104 insertions(+) >=20 > diff --git a/netlink.c b/netlink.c > index 873e6c7..4b49de1 100644 > --- a/netlink.c > +++ b/netlink.c > @@ -673,6 +673,103 @@ int nl_route_dup(int s_src, unsigned int ifi_src, > return 0; > } > =20 > +/** > + * nl_addr_set_ll_nodad() - Set IFA_F_NODAD on IPv6 link-local addresses > + * @s: Netlink socket > + * @ifi: Interface index in target namespace > + * > + * Return: 0 on success, negative error code on failure > + */ > +int nl_addr_set_ll_nodad(int s, unsigned int ifi) > +{ > + struct req_t { > + struct nlmsghdr nlh; > + struct ifaddrmsg ifa; > + } req =3D { > + .ifa.ifa_family =3D AF_INET6, > + .ifa.ifa_index =3D ifi, > + }; > + ssize_t nlmsgs_size, left, status; > + unsigned ll_addrs =3D 0; > + struct nlmsghdr *nh; > + char buf[NLBUFSIZ]; > + uint32_t seq; > + unsigned i; > + > + seq =3D nl_send(s, &req, RTM_GETADDR, NLM_F_DUMP, sizeof(req)); > + > + /* nl_foreach() will step through multiple response datagrams, > + * which we don't want here because we need to have all the > + * addresses in the buffer at once. See also nl_route_dup(). Hmm.. do we need them all in the buffer at once, though? For routes_dup we needed it because we take multiple passes through the whole list, and that's not the case here. I guess we can't do an nl_do() within the loop, because that will expect the response to its own command while we're still getting reponses from the original NLM_F_DUMP. nl_addr_dup() gets away with it because the nl_do()s are on a different netlink socket. But.. I think we could nl_send() each NODAD request as we construct it, keep a count, then wait for all the queued responses. It means we can't easily match an error response to which thing caused it, but doesn't look like we were reporting in that much detail anyway. > + */ > + nh =3D nl_next(s, buf, NULL, &nlmsgs_size); > + for (left =3D nlmsgs_size; > + NLMSG_OK(nh, left) && (status =3D nl_status(nh, left, seq)) > 0; > + nh =3D NLMSG_NEXT(nh, left)) { > + struct ifaddrmsg *ifa =3D (struct ifaddrmsg *)NLMSG_DATA(nh); > + bool discard =3D false; > + struct rtattr *rta; > + size_t na; > + > + if (nh->nlmsg_type !=3D RTM_NEWADDR) > + continue; > + > + if (ifa->ifa_index !=3D ifi || ifa->ifa_scope !=3D RT_SCOPE_LINK) > + discard =3D true; > + > + ifa->ifa_flags |=3D IFA_F_NODAD; > + > + for (rta =3D IFA_RTA(ifa), na =3D IFA_PAYLOAD(nh); RTA_OK(rta, na); > + rta =3D RTA_NEXT(rta, na)) { > + /* If 32-bit flags are used, add IFA_F_NODAD there */ > + if (rta->rta_type =3D=3D IFA_FLAGS) > + *(uint32_t *)RTA_DATA(rta) |=3D IFA_F_NODAD; > + } > + > + if (discard) > + nh->nlmsg_type =3D NLMSG_NOOP; > + else > + ll_addrs++; > + } > + > + if (!NLMSG_OK(nh, left)) { > + /* Process any remaining datagrams in a different > + * buffer so we don't overwrite the first one. > + */ > + char tail[NLBUFSIZ]; > + unsigned extra =3D 0; > + > + nl_foreach_oftype(nh, status, s, tail, seq, RTM_NEWADDR) > + extra++; > + > + if (extra) { > + err("netlink: Too many link-local addresses"); > + return -E2BIG; > + } > + } > + > + if (status < 0) > + return status; > + > + for (i =3D 0; i < ll_addrs; i++) { > + for (nh =3D (struct nlmsghdr *)buf, left =3D nlmsgs_size; > + NLMSG_OK(nh, left); > + nh =3D NLMSG_NEXT(nh, left)) { > + int rc; > + > + if (nh->nlmsg_type !=3D RTM_NEWADDR) > + continue; > + > + rc =3D nl_do(s, nh, RTM_NEWADDR, NLM_F_REPLACE, > + nh->nlmsg_len); > + if (rc < 0) > + return rc; > + } > + } > + > + return 0; > +} > + > /** > * nl_addr_get() - Get most specific global address, given interface and= family > * @s: Netlink socket > diff --git a/netlink.h b/netlink.h > index 178f8ae..66a44ad 100644 > --- a/netlink.h > +++ b/netlink.h > @@ -19,6 +19,7 @@ int nl_addr_get(int s, unsigned int ifi, sa_family_t af, > void *addr, int *prefix_len, void *addr_l); > int nl_addr_set(int s, unsigned int ifi, sa_family_t af, > const void *addr, int prefix_len); > +int nl_addr_set_ll_nodad(int s, unsigned int ifi); > int nl_addr_dup(int s_src, unsigned int ifi_src, > int s_dst, unsigned int ifi_dst, sa_family_t af); > int nl_link_get_mac(int s, unsigned int ifi, void *mac); > diff --git a/pasta.c b/pasta.c > index 96545b1..838bbb3 100644 > --- a/pasta.c > +++ b/pasta.c > @@ -340,6 +340,12 @@ void pasta_ns_conf(struct ctx *c) > } > =20 > if (c->ifi6) { > + rc =3D nl_addr_set_ll_nodad(nl_sock_ns, c->pasta_ifi); > + if (rc < 0) { > + die("Can't disable DAD for LL in namespace: %s", > + strerror(-rc)); So... I'm usually the one arguing *for* ASSERT()s and die()s, but in this case it seems overly drastic. If we're unable to set DAD it will slow things down, but mostly things should still work. I'd prefer to see this as just a warn(). > + } > + > if (c->ip6.no_copy_addrs) { > rc =3D nl_addr_set(nl_sock_ns, c->pasta_ifi, > AF_INET6, &c->ip6.addr, 64); > --=20 > 2.43.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 --0zEiOM0hSgAaiZVs Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAEBCAAdFiEEO+dNsU4E3yXUXRK2zQJF27ox2GcFAma9b3MACgkQzQJF27ox 2GdEohAAmlnBiqxLrF3znXDEsr0ekbnOoN25z+6mm4K9XU4S4eUldgKLzogWv999 Smz80kclY8nbH8fNjqQdBrolGuOIMgwaUY93fabMDuE7mScN0ZRrgle9oJjTf+Ea nk0ET1HFTSGP+dUIrWZctoI5M8mCmqi7Bsyk0D4nHJXxiu7omdfq+Ei1HNirpTf6 GKdHq/fx4GgfffZ/S7H7hVJtn8BcP8AnPQL2hZgu2jN/YFJOsjEDqlriSZitRuEb +x62MTdJIhl+kRAFVfVVIyJLyAfEAR8F0wMqJeC58rKv1kgfWKv4q4loEEF3LENG tFsHFLNHIyEvwTcrqFxKE+f13GmRh8c7QPnNCCPNb1/euyk2ZsCmf9Jao+/jNu6J SMtt0pFQ0+f3APwXrOCGnDohv1/pLPlLzVCMU8wyeKPATI745akKC81xgvIU8C8U ru9FWQLcChNlr0+ZnvsQlE05dMJDLriGnK2T9eo7SriqMrnRYNS/2w7G3QPFigLk /U9GCDMTNvFfG9xSZzELDBAkRqc41/ycIDiMTECNhutL8sbdgpO1/uK/dLenzP/D XVsDT+vxGcHPIrdVWJRrpgguXZQJPSmtbL2krJQ5ifjpypY8VxAuLO8FgspgAc5I c5EOMQiucpeszAN2lNwneYG1SWxr0IaKWpzQIKKyYKxTnIeu4bQ= =t7q6 -----END PGP SIGNATURE----- --0zEiOM0hSgAaiZVs--