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=Ktthj0uT; dkim-atps=neutral Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id B024C5A026D for ; Thu, 07 May 2026 01:55:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202602; t=1778111697; bh=zS+4MTyZVaS7zhwbslhECQ++PaCyHqMZhJuhH4bhsIg=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=Ktthj0uTBUDyaGnJ3ChhzXao0PHgWDEC9EL64pHAUv7c98SDq5FPxp72kQMhMkAMX /25zYkTfq8aeitPABFbSCozfjkPRg3R7LFT0hk/B1kpVOmxD/vC0/d3Y/7azYSiM14 lafMjGXmd4YE9090MZg7esAsWTuHiGLhUuV9SNRsMWDcqHxUvP5YpldUIbE9iqUgGZ bCGJrlWKqxQdrFAMIEIo8cAsd8Rt0X1GBJvATpPCDX8DSDJ5gxN+B01ReWTiCVRl3i E1GQ0noMeHDqcveLX7kUYTtvCaq0sEp2vChcz7nXSUK5dCML8xgvmZZimq5Z+yXjx/ 1gnT6ithsGjfw== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4g9sgj0dC8z4wJS; Thu, 07 May 2026 09:54:57 +1000 (AEST) Date: Thu, 7 May 2026 09:25:13 +1000 From: David Gibson To: Stefano Brivio Subject: Re: [PATCH v9 11/23] pesto: Expose list of pifs to pesto and display them Message-ID: References: <20260506092241.1607480-1-sbrivio@redhat.com> <20260506092241.1607480-12-sbrivio@redhat.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="RJxiV/SL464xD530" Content-Disposition: inline In-Reply-To: <20260506092241.1607480-12-sbrivio@redhat.com> Message-ID-Hash: RTUEM3RUM5HZH4HLSGAHEHS7M7WJ5N2G X-Message-ID-Hash: RTUEM3RUM5HZH4HLSGAHEHS7M7WJ5N2G 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, Jon Maloy , Laurent Vivier 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: --RJxiV/SL464xD530 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, May 06, 2026 at 11:22:29AM +0200, Stefano Brivio wrote: > From: David Gibson >=20 > Extend the dynamic update protocol to expose the pif indices and names > from a running passt/pasta to the pesto tool. pesto records that data > and prints it out. >=20 > Signed-off-by: David Gibson > Reviewed-by: Laurent Vivier > [sbrivio: In read_pif_conf(), force a redundant termination of the > interface name, the existing check isn't obvious enough for static > checkers] > [sbrivio: Drop @resv_ left-over in description of struct > pesto_pif_info, reported by Jon Maloy] > [sbrivio: Fix minor nits reported by Laurent] > [sbrivio: Initialise struct pesto_pif_info in conf_send_rules() with > zeroes, otherwise the pif name might be seen as not terminated, and > we'll expose memory from the back-end] Oops, good catch. > [sbrivio: Fix conflicts in Makefile] > Signed-off-by: Stefano Brivio > --- > common.h | 2 + > conf.c | 41 ++++++++++++++++ > pesto.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > pesto.h | 18 ++++++- > pif.h | 5 +- > serialise.c | 4 ++ > serialise.h | 1 + > util.h | 2 - > 8 files changed, 200 insertions(+), 7 deletions(-) >=20 > diff --git a/common.h b/common.h > index 4251781..68573b4 100644 > --- a/common.h > +++ b/common.h > @@ -53,4 +53,6 @@ static inline const char *strerror_(int errnum) > =20 > #define strerror(x) @ "Don't call strerror() directly, use strerror_() i= nstead" > =20 > +#define ARRAY_SIZE(a) ((int)(sizeof(a) / sizeof((a)[0]))) > + > #endif /* COMMON_H */ > diff --git a/conf.c b/conf.c > index 5ec0072..f8c2134 100644 > --- a/conf.c > +++ b/conf.c > @@ -1927,6 +1927,43 @@ void conf(struct ctx *c, int argc, char **argv) > =20 > static void conf_accept(struct ctx *c); > =20 > +/** > + * conf_send_rules() - Send current forwarding rules to config client (p= esto) > + * @c: Execution context > + * @fd: Socket to the client > + * > + * Return: 0 on success, -1 on failure > + * > + * FIXME: So far only sends pif ids and names > + */ > +static int conf_send_rules(const struct ctx *c, int fd) > +{ > + unsigned pif; > + > + for (pif =3D 0; pif < PIF_NUM_TYPES; pif++) { > + struct pesto_pif_info info =3D { 0 }; > + int rc; > + > + if (!c->fwd[pif]) > + continue; > + > + assert(pif !=3D PIF_NONE); > + > + rc =3D snprintf(info.name, sizeof(info.name), "%s", pif_name(pif)); > + assert(rc >=3D 0 && (size_t)rc < sizeof(info.name)); > + > + if (write_u8(fd, pif) < 0) > + return -1; > + if (write_all_buf(fd, &info, sizeof(info)) < 0) > + return -1; > + } > + > + if (write_u8(fd, PIF_NONE) < 0) > + return -1; > + > + return 0; > +} > + > /** > * conf_close() - Close configuration / control socket and clean up > * @c: Execution context > @@ -1970,6 +2007,7 @@ static void conf_accept(struct ctx *c) > struct pesto_hello hello =3D { > .magic =3D PESTO_SERVER_MAGIC, > .version =3D htonl(PESTO_PROTOCOL_VERSION), > + .pif_name_size =3D htonl(PIF_NAME_SIZE), > }; > union epoll_ref ref =3D { .type =3D EPOLL_TYPE_CONF }; > struct ucred uc =3D { 0 }; > @@ -2010,6 +2048,9 @@ retry: > "Warning: Using experimental unsupported configuration protocol"); > } > =20 > + if (conf_send_rules(c, fd) < 0) > + goto fail; > + > return; > =20 > fail: > diff --git a/pesto.c b/pesto.c > index ab476c5..b33492a 100644 > --- a/pesto.c > +++ b/pesto.c > @@ -60,6 +60,127 @@ static void usage(const char *name, FILE *f, int stat= us) > exit(status); > } > =20 > +/* Maximum number of pifs with rule tables */ > +#define MAX_PIFS 3 > + > +struct pif_configuration { > + uint8_t pif; > + char name[PIF_NAME_SIZE]; > +}; > + > +struct configuration { > + uint32_t npifs; > + struct pif_configuration pif[MAX_PIFS]; > +}; > + > +/** > + * pif_conf_by_num() - Find a pif's configuration by pif id > + * @conf: Configuration description > + * @pif: pif id > + * > + * Return: pointer to the pif_configuration for @pif, or NULL if not fou= nd > + */ > +static struct pif_configuration *pif_conf_by_num(struct configuration *c= onf, > + uint8_t pif) > +{ > + unsigned i; > + > + for (i =3D 0; i < conf->npifs; i++) { > + if (conf->pif[i].pif =3D=3D pif) > + return &conf->pif[i]; > + } > + > + return NULL; > +} > + > +/** > + * pif_conf_by_name() - Find a pif's configuration by name > + * @conf: Configuration description > + * @name: Interface name > + * > + * Return: pif_configuration for pif named @name, or NULL if not found > + */ > +static struct pif_configuration *pif_conf_by_name(struct configuration *= conf, > + const char *name) > +{ > + unsigned i; > + > + for (i =3D 0; i < conf->npifs; i++) { > + if (strcmp(conf->pif[i].name, name) =3D=3D 0) > + return &conf->pif[i]; > + } > + > + return NULL; > +} > + > +/** > + * pesto_read_rules() - Read rulestate from passt/pasta > + * @fd: Control socket > + * @conf: Configuration description to update > + */ > +static bool read_pif_conf(int fd, struct configuration *conf) > +{ > + struct pif_configuration *pc; > + struct pesto_pif_info info; > + uint8_t pif; > + > + if (read_u8(fd, &pif) < 0) > + die("Error reading from control socket"); > + > + if (pif =3D=3D PIF_NONE) > + return false; > + > + debug("Receiving config for PIF %"PRIu8, pif); > + > + if (conf->npifs >=3D ARRAY_SIZE(conf->pif)) { > + die("passt has more pifs than pesto can manage (max %d)", > + ARRAY_SIZE(conf->pif)); > + } > + > + pc =3D &conf->pif[conf->npifs]; > + pc->pif =3D pif; > + > + if (read_all_buf(fd, &info, sizeof(info)) < 0) > + die("Error reading from control socket"); > + > + if (info.name[sizeof(info.name)-1]) > + die("Interface name was not NULL terminated"); > + /* Redundant, to make static checkers happy */ > + info.name[sizeof(info.name) - 1] =3D '\0'; > + > + static_assert(sizeof(info.name) =3D=3D sizeof(pc->name), > + "Mismatching pif name lengths"); > + memcpy(pc->name, info.name, sizeof(pc->name)); > + > + debug("PIF %"PRIu8": %s", pc->pif, pc->name); > + > + /* O(n^2), but n is bounded by MAX_PIFS */ > + if (pif_conf_by_num(conf, pc->pif)) > + die("Received duplicate interface identifier"); > + > + /* O(n^2), but n is bounded by MAX_PIFS */ > + if (pif_conf_by_name(conf, pc->name)) > + die("Received duplicate interface name"); > + > + conf->npifs++; > + return true; > +} > + > +/** > + * show_conf() - Show current configuration obtained from passt/pasta > + * @conf: Configuration description > + */ > +static void show_conf(const struct configuration *conf) > +{ > + unsigned i; > + > + for (i =3D 0; i < conf->npifs; i++) { > + const struct pif_configuration *pc =3D &conf->pif[i]; > + printf(" %s\n", pc->name); > + printf(" TBD\n"); > + } > +} > + > /** > * main() - Dynamic reconfiguration client main program > * @argc: Argument count > @@ -80,6 +201,7 @@ int main(int argc, char **argv) > { 0 }, > }; > struct sockaddr_un a =3D { AF_UNIX, "" }; > + struct configuration conf =3D { 0 }; > const char *optstring =3D "dh"; > struct pesto_hello hello; > struct sock_fprog prog; > @@ -162,6 +284,18 @@ int main(int argc, char **argv) > "Warning: Using experimental protocol version, client and server must ma= tch\n"); > } > =20 > + if (ntohl(hello.pif_name_size) !=3D PIF_NAME_SIZE) { > + die("Server has unexpected pif name size (%" > + PRIu32" not %"PRIu32 ")", > + ntohl(hello.pif_name_size), PIF_NAME_SIZE); > + } > + > + while (read_pif_conf(s, &conf)) > + ; > + > + printf("passt/pasta configuration (%s)\n", a.sun_path); > + show_conf(&conf); > + > if (shutdown(s, SHUT_RDWR) < 0 || close(s) < 0) > die_perror("Error shutting down control socket"); > =20 > diff --git a/pesto.h b/pesto.h > index 3c93d3e..fda0ef6 100644 > --- a/pesto.h > +++ b/pesto.h > @@ -17,18 +17,32 @@ > /* Version 0 is reserved for unreleased / unsupported experimental versi= ons */ > #define PESTO_PROTOCOL_VERSION 1 > =20 > +/* Maximum size of a pif name, including \0 */ > +#define PIF_NAME_SIZE (128) > +#define PIF_NONE 0 > + > /** > * struct pesto_hello - Server introduction message > - * @magic: PESTO_SERVER_MAGIC > - * @version: Version number > + * @magic: PESTO_SERVER_MAGIC > + * @version: Version number > + * @pif_name_size: Server's value for PIF_NAME_SIZE > */ > struct pesto_hello { > char magic[8]; > uint32_t version; > + uint32_t pif_name_size; > } __attribute__ ((__packed__)); > =20 > static_assert(sizeof(PESTO_SERVER_MAGIC) > =3D=3D sizeof(((struct pesto_hello *)0)->magic), > "PESTO_SERVER_MAGIC has wrong size"); > =20 > +/** > + * struct pesto_pif_info - Message with basic metadata about a pif > + * @name: Name (\0 terminated) > + */ > +struct pesto_pif_info { > + char name[PIF_NAME_SIZE]; > +} __attribute__ ((__packed__)); > + > #endif /* PESTO_H */ > diff --git a/pif.h b/pif.h > index 553c742..48d4919 100644 > --- a/pif.h > +++ b/pif.h > @@ -11,6 +11,7 @@ > =20 > #include > =20 > +#include "pesto.h" > #include "epoll_type.h" > =20 > union inany_addr; > @@ -24,7 +25,7 @@ union sockaddr_inany; > */ > enum pif_type { > /* Invalid or not present pif */ > - PIF_NONE =3D 0, > + PIF_NONE_ =3D PIF_NONE, > /* Host socket interface */ > PIF_HOST, > /* Qemu socket or namespace tuntap interface */ > @@ -35,8 +36,6 @@ enum pif_type { > PIF_NUM_TYPES, > }; > =20 > -/* Maximum size of a pif name, including \0 */ > -#define PIF_NAME_SIZE (128) > extern const char pif_type_str[][PIF_NAME_SIZE]; > =20 > static inline const char *pif_type(enum pif_type pt) > diff --git a/serialise.c b/serialise.c > index 346df99..e083112 100644 > --- a/serialise.c > +++ b/serialise.c > @@ -121,6 +121,10 @@ int write_all_buf(int fd, const void *buf, size_t le= n) > return write_all_buf(fd, &beval, sizeof(beval)); \ > } > =20 > +#define be8toh(x) (x) > +#define htobe8(x) (x) > + > +SERIALISE_UINT(8) > SERIALISE_UINT(32) > =20 > #undef SERIALISE_UINT > diff --git a/serialise.h b/serialise.h > index a88f3de..4714f4c 100644 > --- a/serialise.h > +++ b/serialise.h > @@ -16,6 +16,7 @@ int write_all_buf(int fd, const void *buf, size_t len); > int read_u##bits(int fd, uint##bits##_t *val); \ > int write_u##bits(int fd, uint##bits##_t val); > =20 > +SERIALISE_UINT_DECL(8) > SERIALISE_UINT_DECL(32) > =20 > #endif /* SERIALISE_H */ > diff --git a/util.h b/util.h > index e90be47..c788382 100644 > --- a/util.h > +++ b/util.h > @@ -87,8 +87,6 @@ void abort_with_msg(const char *fmt, ...) > #define V6 1 > #define IP_VERSIONS 2 > =20 > -#define ARRAY_SIZE(a) ((int)(sizeof(a) / sizeof((a)[0]))) > - > #define foreach(item, array) \ > for ((item) =3D (array); (item) - (array) < ARRAY_SIZE(array); (item)++) > =20 > --=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 --RJxiV/SL464xD530 Content-Type: application/pgp-signature; name=signature.asc -----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEEO+dNsU4E3yXUXRK2zQJF27ox2GcFAmn7zcYACgkQzQJF27ox 2GdOAA/7B0mUfyO/dYx8LwB5I1Px+2P4V/xUquS9icmExy7jbY0m4e/iXlAmyCma JwLw1NKg7qN5cx9m+fpn80QstpKjzKpBL4vNdKY0DJAd2vbdsNKXnkDRsAvQMaZt Nn3dE2FOJs//zxMKX+S6+qXJu/wb7IyFqI2n6Ypor6TCdWpeDTs+Wi7raqaXnJ3r 2d5HoMjNCiPQUu2OZzT/D7auA5mYay6K7MFdTaFzWPglr7/y0KutXqu47HAxY2+x Ow7DHXUeZlgBcNdgXCUpSDrG5+RBlLJ0f6VR6T0dhc4P9MRqIh0tuN0s0cK9Kd8I +GZA1w5MPVT3bw2lDUyMm9KFfJO5VJrEZ5zGduxQU31yTcZXIOIK3RfQ9s0r8evY 4nvDdXKA6QpDjcgEOcQ2IDxBQ39urcgvzicbMNzHKrRWB+gOzqeJhXnWn7fH9jIk qXu7LgFyGflAVlLwCz0uaQvz86wX07MGHTez0NAFD9g4KX9SvMduZAO/qQxOYn8u IaxKlDzCU5yjEJC8PF30N4ExB3YAS9ByvyBl+kuihatwGU0SSAAtIakL7wsxBJSt kPnHLWYZGtcZk8uYSRyedNPXWjX7dvu2GL6JhzmanXXBcqemxuXRSsD1AVwzO3v+ d2+0+5WaqdyEAIg6xNOUCG5Z5IOCMB0kiqFOyU7oAOrflgWjSuI= =2JRT -----END PGP SIGNATURE----- --RJxiV/SL464xD530--