public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: Stefano Brivio <sbrivio@redhat.com>, passt-dev@passt.top
Cc: David Gibson <david@gibson.dropbear.id.au>
Subject: [PATCH v2 09/15] pesto: Expose list of pifs to pesto
Date: Thu, 19 Mar 2026 17:11:51 +1100	[thread overview]
Message-ID: <20260319061157.1983818-10-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <20260319061157.1983818-1-david@gibson.dropbear.id.au>

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 (for now) prints it out.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 conf.c      | 38 +++++++++++++++++++++
 pesto.c     | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 serialise.c | 21 ++++++++++++
 serialise.h |  3 ++
 4 files changed, 159 insertions(+), 1 deletion(-)

diff --git a/conf.c b/conf.c
index e862b023..603ca2ac 100644
--- a/conf.c
+++ b/conf.c
@@ -2304,6 +2304,41 @@ void conf(struct ctx *c, int argc, char **argv)
 		conf_print(c);
 }
 
+/**
+ * conf_send_pifs() - Send list of pifs to dynamic update client (pesto)
+ * @c:		Execution context
+ * @fd:		Socket to the client
+ *
+ * Return: 0 on success, -1 on failure
+ */
+static int conf_send_pifs(const struct ctx *c, int fd)
+{
+	uint32_t num = 0;
+	unsigned pif;
+
+	/* First count the number of pifs with tables */
+	for (pif = 0; pif < PIF_NUM_TYPES; pif++) {
+		if (c->fwd[pif])
+			num++;
+	}
+
+	if (sewrite_u32(fd, num))
+		return -1;
+
+	for (pif = 0; pif < PIF_NUM_TYPES; pif++) {
+		if (!c->fwd[pif])
+			continue;
+
+		if (sewrite_u8(fd, pif))
+			return -1;
+
+		if (sewrite_str(fd, pif_name(pif)) < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
 /**
  * conf_listen_handler() - Handle events on configuration listening socket
  * @c:		Execution context
@@ -2360,6 +2395,9 @@ void conf_listen_handler(struct ctx *c, uint32_t events)
 "Warning: Using experimental unsupported configuration protocol");
 	}
 
+	if (conf_send_pifs(c, fd) < 0)
+		goto fail;
+
 	return;
 
 fail:
diff --git a/pesto.c b/pesto.c
index a8c134f5..dbc27a58 100644
--- a/pesto.c
+++ b/pesto.c
@@ -36,6 +36,8 @@
 #include "serialise.h"
 #include "pesto.h"
 
+static int verbosity = 1;
+
 #define die(...)							\
 	do {								\
 		FPRINTF(stderr, __VA_ARGS__);				\
@@ -51,6 +53,19 @@
 		}							\
 	} while (0)
 
+/**
+ * xmalloc() - Allocate memory, with fatal error on failure
+ * @size:	Number of bytes to allocate
+ */
+static void *xmalloc(size_t size)
+{
+	void *p = malloc(size);
+
+	if (!p)
+		die("Memory allocation failure");
+	return p;
+}
+
 /**
  * usage() - Print usage, exit with given status code
  * @name:	Executable name
@@ -69,6 +84,83 @@ static void usage(const char *name, FILE *f, int status)
 	exit(status);
 }
 
+/**
+ * pesto_recv_str() - Receive a string from passt/pasta
+ * @fd:		Control socket
+ *
+ * Return: pointer to malloc()ed string
+ */
+static const char *pesto_recv_str(int fd)
+{
+	uint32_t len;
+	char *buf;
+
+	if (seread_u32(fd, &len) < 0)
+		die("Error reading from control socket");
+
+	buf = xmalloc(len);
+	if (seread_buf(fd, buf, len) < 0)
+		die("Error reading from control socket");
+
+	return buf;
+}
+
+struct pif_state {
+	uint8_t pif;
+	const char *name;
+};
+
+struct conf_state {
+	uint32_t npifs;
+	struct pif_state pif[];
+};
+
+/**
+ * pesto_read_pifs() - Read pif names and IDs from passt/pasta
+ * @fd:		Control socket
+ */
+static const struct conf_state *pesto_read_pifs(int fd)
+{
+	uint32_t num;
+	struct conf_state *state;
+	unsigned i;
+
+	if (seread_u32(fd, &num) < 0)
+		die("Error reading from control socket");
+
+	debug("Receiving %"PRIu32" interface names", num);
+
+	state = xmalloc(sizeof(*state) + num * sizeof(struct pif_state));
+	state->npifs = num;
+
+	for (i = 0; i < num; i++) {
+		struct pif_state *ps = &state->pif[i];
+
+		if (seread_u8(fd, &ps->pif) < 0)
+			die("Error reading from control socket");
+		ps->name = pesto_recv_str(fd);
+
+		debug("%u: %s", ps->pif, ps->name);
+	}
+
+	return state;
+}
+
+/**
+ * show_state() - Show current rule state obtained from passt/pasta
+ * @pifs:	PIF name information
+ */
+static void show_state(const struct conf_state *state)
+{
+	unsigned i;
+
+	for (i = 0; i < state->npifs; i++) {
+		const struct pif_state *ps = &state->pif[i];
+		printf("Forwarding rules for %s interface\n", ps->name);
+		printf("\tTBD\n");
+	}
+}
+
 /**
  * main() - Entry point and whole program with loop
  * @argc:	Argument count
@@ -91,12 +183,12 @@ int main(int argc, char **argv)
 		{ 0 },
 	};
 	struct sockaddr_un a = { AF_UNIX, "" };
+	const struct conf_state *state;
 	const char *optstring = "vh";
 	struct pesto_hello hello;
 	struct sock_fprog prog;
 	int optname, ret, s;
 	uint32_t s_version;
-	int verbosity = 1;
 
 	prog.len = (unsigned short)sizeof(filter_pesto) /
 				   sizeof(filter_pesto[0]);
@@ -172,5 +264,9 @@ int main(int argc, char **argv)
 "Warning: Using experimental protocol version, client and server must match\n");
 	}
 
+	state = pesto_read_pifs(s);
+
+	show_state(state);
+
 	exit(0);
 }
diff --git a/serialise.c b/serialise.c
index 4fc0d116..4645c58e 100644
--- a/serialise.c
+++ b/serialise.c
@@ -19,6 +19,7 @@
 #include <endian.h>
 #include <errno.h>
 #include <stdint.h>
+#include <string.h>
 #include <unistd.h>
 
 #include "serialise.h"
@@ -121,6 +122,26 @@ int sewrite_buf(int fd, const void *buf, size_t len)
 		return sewrite_var(fd, &beval);				\
 	}
 
+#define be8toh(x)	(x)
+#define htobe8(x)	(x)
+
+SERIALISE_UINT(8)
 SERIALISE_UINT(32)
 
 #undef SERIALISE_UNIT
+
+/**
+ * sewrite_str() - Write a string to an fd in length/value format
+ * @fd:		Socket to the client
+ * @s:		String to send
+ *
+ * Return: 0 on success, -1 on error
+ */
+int sewrite_str(int fd, const char *s)
+{
+	uint32_t len = strlen(s) + 1; /* Include \0 */
+
+	if (sewrite_u32(fd, len) < 0)
+		return -1;
+	return sewrite_buf(fd, s, len);
+}
diff --git a/serialise.h b/serialise.h
index f2e0aa8d..1f0747c7 100644
--- a/serialise.h
+++ b/serialise.h
@@ -19,6 +19,9 @@ int sewrite_buf(int fd, const void *buf, size_t len);
 	int seread_u##bits(int fd, uint##bits##_t *val);		\
 	int sewrite_u##bits(int fd, uint##bits##_t val);
 
+SERIALISE_UINT_DECL(8)
 SERIALISE_UINT_DECL(32)
 
+int sewrite_str(int fd, const char *s);
+
 #endif /* _SERIALISE_H */
-- 
2.53.0


  parent reply	other threads:[~2026-03-19  6:12 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-19  6:11 [PATCH v2 00/15] RFC: Read-only dynamic update implementation David Gibson
2026-03-19  6:11 ` [PATCH v2 01/15] treewide: Spell ASSERT() as assert() David Gibson
2026-03-19  6:11 ` [PATCH v2 02/15] serialise: Split functions user for serialisation from util.c David Gibson
2026-03-19  6:11 ` [PATCH v2 03/15] serialise: Add helpers for serialising unsigned integers David Gibson
2026-03-19  6:11 ` [PATCH v2 04/15] fwd: Move selecting correct scan bitmap into fwd_sync_one() David Gibson
2026-03-19  6:11 ` [PATCH v2 05/15] fwd: Look up rule index in fwd_sync_one() David Gibson
2026-03-19  6:11 ` [PATCH v2 06/15] fwd: Store forwarding tables indexed by (origin) pif David Gibson
2026-03-19  6:11 ` [PATCH v2 07/15] pesto: Introduce stub configuration interface and tool David Gibson
2026-03-19  6:11 ` [PATCH v2 08/15] pesto: Add command line option parsing and debug messages David Gibson
2026-03-19  6:11 ` David Gibson [this message]
2026-03-19  6:11 ` [PATCH v2 10/15] ip: Prepare ip.[ch] for sharing with pesto tool David Gibson
2026-03-19  6:11 ` [PATCH v2 11/15] inany: Prepare inany.[ch] " David Gibson
2026-03-19  6:11 ` [PATCH v2 12/15] fwd: Split forwading rule specification from its implementation state David Gibson
2026-03-19  6:11 ` [PATCH v2 13/15] ip: Define a bound for the string returned by ipproto_name() David Gibson
2026-03-19  6:11 ` [PATCH v2 14/15] fwd_rule: Move forwarding rule text formatting to common code David Gibson
2026-03-19  6:11 ` [PATCH v2 15/15] pesto: Read current ruleset from passt/pasta and display it David Gibson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260319061157.1983818-10-david@gibson.dropbear.id.au \
    --to=david@gibson.dropbear.id.au \
    --cc=passt-dev@passt.top \
    --cc=sbrivio@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).