From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from gandalf.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id A1DC65A027F for ; Mon, 22 May 2023 10:54:02 +0200 (CEST) Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4QPrpb3Tv3z4x4L; Mon, 22 May 2023 18:53:59 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=201602; t=1684745639; bh=lWu/4qAv9bU6QqBBHnSSGhUbvqvZranzJXfIrZKTgNU=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=N6qMEV0ngIovR1InJK1PNeamb2R2yxJ2SCqHvzpcpbqpkTGDyan3qJgY/PAVRf3qO 2CEJvTFAL6NZ+J1m3zu2J9xueccVe7B0/QvBCM6fRK4hhuHvjxmI2Ldx/+aeszm3nl dYDe9Ecc7+ea1NXk5oV9MQ3IrBe+pZeQdVwUIvtc= Date: Mon, 22 May 2023 18:51:28 +1000 From: David Gibson To: Stefano Brivio Subject: Re: [PATCH v2 08/10] netlink: Add functionality to copy addresses from outer namespace Message-ID: References: <20230521234224.2770015-1-sbrivio@redhat.com> <20230521234224.2770015-9-sbrivio@redhat.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="/E/vbzKnoJJu2GhG" Content-Disposition: inline In-Reply-To: <20230521234224.2770015-9-sbrivio@redhat.com> Message-ID-Hash: C67NNFAUVHHG2XLVEJIKCLMBGJYPYZCR X-Message-ID-Hash: C67NNFAUVHHG2XLVEJIKCLMBGJYPYZCR 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, Callum Parsey , me@yawnt.com, lemmi@nerd2nerd.org, Andrea Arcangeli 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: --/E/vbzKnoJJu2GhG Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Mon, May 22, 2023 at 01:42:22AM +0200, Stefano Brivio wrote: > Similarly to what we've just done with routes, support NL_DUP for > addresses (currently not exposed): nl_addr() can optionally copy > mulitple addresses to the target namespace, by fixing up data from > the dump with appropriate flags and interface index, and repeating > it back to the kernel on the socket opened in the target namespace. >=20 > Link-local addresses are not copied: the family is set to AF_UNSPEC, > which means the kernel will ignore them. Same for addresses from a > mismatching address (pre-4.19 kernels without support for > NETLINK_GET_STRICT_CHK). >=20 > Ignore IFA_LABEL attributes by changing their type to IFA_UNSPEC, > because in general they will report mismatching names, and we don't > really need to use labels as we already know the interface index. >=20 > Signed-off-by: Stefano Brivio Reviewed-by: David Gibson > --- > conf.c | 8 ++++--- > netlink.c | 62 +++++++++++++++++++++++++++++++++++++++++-------------- > netlink.h | 4 ++-- > pasta.c | 8 +++---- > 4 files changed, 58 insertions(+), 24 deletions(-) >=20 > diff --git a/conf.c b/conf.c > index c07b697..1ffd05c 100644 > --- a/conf.c > +++ b/conf.c > @@ -645,8 +645,10 @@ static unsigned int conf_ip4(unsigned int ifi, > if (IN4_IS_ADDR_UNSPECIFIED(&ip4->gw)) > nl_route(NL_GET, ifi, 0, AF_INET, &ip4->gw); > =20 > - if (IN4_IS_ADDR_UNSPECIFIED(&ip4->addr)) > - nl_addr(0, ifi, AF_INET, &ip4->addr, &ip4->prefix_len, NULL); > + if (IN4_IS_ADDR_UNSPECIFIED(&ip4->addr)) { > + nl_addr(NL_GET, ifi, 0, AF_INET, > + &ip4->addr, &ip4->prefix_len, NULL); > + } > =20 > if (!ip4->prefix_len) { > in_addr_t addr =3D ntohl(ip4->addr.s_addr); > @@ -696,7 +698,7 @@ static unsigned int conf_ip6(unsigned int ifi, > if (IN6_IS_ADDR_UNSPECIFIED(&ip6->gw)) > nl_route(NL_GET, ifi, 0, AF_INET6, &ip6->gw); > =20 > - nl_addr(0, ifi, AF_INET6, > + nl_addr(NL_GET, ifi, 0, AF_INET6, > IN6_IS_ADDR_UNSPECIFIED(&ip6->addr) ? &ip6->addr : NULL, > &prefix_len, &ip6->addr_ll); > =20 > diff --git a/netlink.c b/netlink.c > index d93ecda..bc5b2bf 100644 > --- a/netlink.c > +++ b/netlink.c > @@ -334,19 +334,18 @@ next: > } > =20 > /** > - * nl_addr() - Get/set IP addresses > - * @ns: Use netlink socket in namespace > - * @ifi: Interface index > + * nl_addr() - Get/set/copy IP addresses for given interface and address= family > + * @op: Requested operation > + * @ifi: Interface index in outer network namespace > + * @ifi_ns: Interface index in target namespace for NL_SET, NL_DUP > * @af: Address family > - * @addr: Global address to fill if zero, to set if not, ignored if NULL > + * @addr: Global address to fill on NL_GET, to set on NL_SET > * @prefix_len: Mask or prefix length, set or fetched (for IPv4) > - * @addr_l: Link-scoped address to fill, NULL if not requested > + * @addr_l: Link-scoped address to fill on NL_GET > */ > -void nl_addr(int ns, unsigned int ifi, sa_family_t af, > - void *addr, int *prefix_len, void *addr_l) > +void nl_addr(enum nl_op op, unsigned int ifi, unsigned int ifi_ns, > + sa_family_t af, void *addr, int *prefix_len, void *addr_l) > { > - int set =3D addr && ((af =3D=3D AF_INET6 && !IN6_IS_ADDR_UNSPECIFIED(ad= dr)) || > - (af =3D=3D AF_INET && *(uint32_t *)addr)); > struct req_t { > struct nlmsghdr nlh; > struct ifaddrmsg ifa; > @@ -365,23 +364,23 @@ void nl_addr(int ns, unsigned int ifi, sa_family_t = af, > } a6; > } set; > } req =3D { > - .nlh.nlmsg_type =3D set ? RTM_NEWADDR : RTM_GETADDR, > + .nlh.nlmsg_type =3D op =3D=3D NL_SET ? RTM_NEWADDR : RTM_GETADDR, > .nlh.nlmsg_flags =3D NLM_F_REQUEST, > .nlh.nlmsg_len =3D NLMSG_LENGTH(sizeof(struct ifaddrmsg)), > .nlh.nlmsg_seq =3D nl_seq++, > =20 > .ifa.ifa_family =3D af, > .ifa.ifa_index =3D ifi, > - .ifa.ifa_prefixlen =3D *prefix_len, > + .ifa.ifa_prefixlen =3D op =3D=3D NL_SET ? *prefix_len : 0, > }; > + ssize_t n, nlmsgs_size; > struct ifaddrmsg *ifa; > struct nlmsghdr *nh; > struct rtattr *rta; > char buf[NLBUFSIZ]; > - ssize_t n; > size_t na; > =20 > - if (set) { > + if (op =3D=3D NL_SET) { > if (af =3D=3D AF_INET6) { > size_t rta_len =3D RTA_LENGTH(sizeof(req.set.a6.l)); > =20 > @@ -416,21 +415,47 @@ void nl_addr(int ns, unsigned int ifi, sa_family_t = af, > req.nlh.nlmsg_flags |=3D NLM_F_DUMP; > } > =20 > - if ((n =3D nl_req(ns, buf, &req, req.nlh.nlmsg_len)) < 0 || set) > + if ((n =3D nl_req(op =3D=3D NL_SET, buf, &req, req.nlh.nlmsg_len)) < 0) > + return; > + > + if (op =3D=3D NL_SET) > return; > =20 > nh =3D (struct nlmsghdr *)buf; > + nlmsgs_size =3D n; > + > for ( ; NLMSG_OK(nh, n); nh =3D NLMSG_NEXT(nh, n)) { > if (nh->nlmsg_type !=3D RTM_NEWADDR) > goto next; > =20 > + if (op =3D=3D NL_DUP) { > + nh->nlmsg_seq =3D nl_seq++; > + nh->nlmsg_pid =3D 0; > + nh->nlmsg_flags &=3D ~NLM_F_DUMP_FILTERED; > + nh->nlmsg_flags |=3D NLM_F_REQUEST | NLM_F_ACK | > + NLM_F_CREATE; > + } > + > ifa =3D (struct ifaddrmsg *)NLMSG_DATA(nh); > + > + if (op =3D=3D NL_DUP && (ifa->ifa_scope =3D=3D RT_SCOPE_LINK || > + ifa->ifa_index !=3D ifi)) { > + ifa->ifa_family =3D AF_UNSPEC; > + goto next; > + } > + > if (ifa->ifa_index !=3D ifi) > goto next; > =20 > + if (op =3D=3D NL_DUP) > + ifa->ifa_index =3D ifi_ns; > + > for (rta =3D IFA_RTA(ifa), na =3D RTM_PAYLOAD(nh); RTA_OK(rta, na); > rta =3D RTA_NEXT(rta, na)) { > - if (rta->rta_type !=3D IFA_ADDRESS) > + if (op =3D=3D NL_DUP && rta->rta_type =3D=3D IFA_LABEL) > + rta->rta_type =3D IFA_UNSPEC; > + > + if (op =3D=3D NL_DUP || rta->rta_type !=3D IFA_ADDRESS) > continue; > =20 > if (af =3D=3D AF_INET && addr && !*(uint32_t *)addr) { > @@ -451,6 +476,13 @@ next: > if (nh->nlmsg_type =3D=3D NLMSG_DONE) > break; > } > + > + if (op =3D=3D NL_DUP) { > + char resp[NLBUFSIZ]; > + > + nh =3D (struct nlmsghdr *)buf; > + nl_req(1, resp, nh, nlmsgs_size); > + } > } > =20 > /** > diff --git a/netlink.h b/netlink.h > index 217cf1e..cd0e666 100644 > --- a/netlink.h > +++ b/netlink.h > @@ -16,8 +16,8 @@ void nl_sock_init(const struct ctx *c, bool ns); > unsigned int nl_get_ext_if(sa_family_t af); > void nl_route(enum nl_op op, unsigned int ifi, unsigned int ifi_ns, > sa_family_t af, void *gw); > -void nl_addr(int ns, unsigned int ifi, sa_family_t af, > - void *addr, int *prefix_len, void *addr_l); > +void nl_addr(enum nl_op op, unsigned int ifi, unsigned int ifi_ns, > + sa_family_t af, void *addr, int *prefix_len, void *addr_l); > void nl_link(int ns, unsigned int ifi, void *mac, int up, int mtu); > =20 > #endif /* NETLINK_H */ > diff --git a/pasta.c b/pasta.c > index b546c93..99ef3fc 100644 > --- a/pasta.c > +++ b/pasta.c > @@ -278,16 +278,16 @@ void pasta_ns_conf(struct ctx *c) > nl_link(1, c->pasta_ifi, c->mac_guest, 1, c->mtu); > =20 > if (c->ifi4) { > - nl_addr(1, c->pasta_ifi, AF_INET, &c->ip4.addr, > - &c->ip4.prefix_len, NULL); > + nl_addr(NL_SET, c->ifi4, c->pasta_ifi, AF_INET, > + &c->ip4.addr, &c->ip4.prefix_len, NULL); > nl_route(op_routes, c->ifi4, c->pasta_ifi, AF_INET, > &c->ip4.gw); > } > =20 > if (c->ifi6) { > int prefix_len =3D 64; > - nl_addr(1, c->pasta_ifi, AF_INET6, &c->ip6.addr, > - &prefix_len, NULL); > + nl_addr(NL_SET, c->ifi6, c->pasta_ifi, AF_INET6, > + &c->ip6.addr, &prefix_len, NULL); > nl_route(op_routes, c->ifi6, c->pasta_ifi, AF_INET6, > &c->ip6.gw); > } --=20 David Gibson | 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 --/E/vbzKnoJJu2GhG Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAEBCAAdFiEEO+dNsU4E3yXUXRK2zQJF27ox2GcFAmRrLQkACgkQzQJF27ox 2GfnnBAApoDBJ89mdVWD2YRxv+gjlvA//ZLR7odzncQA/frZbv8cZ4vCn64Cghsr QE8Ru3D60F/FB8il5VGMqMqEQphhuYhA/CihOUMVhnLqlUAx3R20Cj8z3Y8JJGMy Iam4BriItFcKkzUlJHp4/sK5yXTLQPX9neNmtGFMQz9964iS/hnqKyaBcofGKNcP E7GvgyggT5btCzJMFpPNdw7DjmdI5Ucz92nJzSszSSq71Vx0HZ88fA9Or8K5+v08 Ihbsdhrbp9Bb6bOnQ+bMQJDzkGnn45HTRPeiR24ZN2ifG03U70ZaYiI60cm5GfVz dVl2CcvOnqCBE8jvJA9BOFDZLM/3C/xPFeOEDef0XwWLsDGQ/tyqEZuZXY+PUuiJ W6pBKSk5Ua3b51tW9C9b3NwCemm+G5XgDIVMy8Oxscm2DNAOP4SV9HVJ7q0iJoH7 k+tcyAwAwz3R4/I2CU34ElT98qvlPWEpUuLlLcKtF5tTmsxnjdJ0yOx4zzuKJgN3 i/cTAkw/2czELLmWN2NgrwdzTE59UO2cSHmZwpX/MinMCM1Hr+q5jNFKno3WqRWE cB3BVEG0S9n2m65qaYM3PvKCUQG3kVMq1W0reBmvSc5IQ6KqdQen6elj5jhh5pFt Mnf0J3dTGDEGtV0h0+QGLhYJGvWgC2lrMfeKr5KVUfm76O4S2TQ= =svNW -----END PGP SIGNATURE----- --/E/vbzKnoJJu2GhG--