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=lPU1rDvC; dkim-atps=neutral Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id B88355A0626 for ; Tue, 21 Apr 2026 08:25:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202602; t=1776752718; bh=gZuITm3+QxY780sJ4jqd+nwjFkzbNVSqnJ6UlnOVPbk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lPU1rDvCK1gJv3AXE/YPwELrCmud+qUoVG0BMMq+8f83fuzRbtKkj2YMXfN5KR98/ KMKQHEA449lQeZuDM9vCg/pseKdZ5R/P76SI70DRvp7pGgLkqkcUMZC/nkuITB7eMU 7aYls+puc9dGkFHBIfbAefDBGa+YF14ERjPHUVtNnLlIuE6aysX7cxbd0Br3DonjkI A4pmUJbkaMdLYbTBWTome7XuAhwjzK2IZaB7Px1lEOZusuROR9qAX4+nPNJOEKh4W/ 2gdiDvmoG7Nr6MmrcO2AA1OrJzsONipZAJzvhyTO4mTm+oziFUtlUCoW/d0mliaNEw flLZpFjYrxpBA== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4g0C5V2kwCz4wJh; Tue, 21 Apr 2026 16:25:18 +1000 (AEST) From: David Gibson To: Stefano Brivio , passt-dev@passt.top Subject: [PATCH v5 09/18] pesto: Introduce stub configuration tool Date: Tue, 21 Apr 2026 16:25:07 +1000 Message-ID: <20260421062516.2601204-10-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260421062516.2601204-1-david@gibson.dropbear.id.au> References: <20260421062516.2601204-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: 77DAEEWN4JHOKUPOHNFCQSBPATBO2F67 X-Message-ID-Hash: 77DAEEWN4JHOKUPOHNFCQSBPATBO2F67 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: David Gibson 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: Build a new "pesto" binary, which will become the tool to update a running passt/pasta's configuration. For now, we just build a stub binary which sets up a basic environment, parses trivial command line options but does nothing else. Signed-off-by: David Gibson --- .gitignore | 2 + Makefile | 42 +++++++++++------ common.h | 24 ++++++++++ pesto.1 | 46 +++++++++++++++++++ pesto.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++ pesto.h | 12 +++++ util.h | 12 +---- 7 files changed, 244 insertions(+), 26 deletions(-) create mode 100644 common.h create mode 100644 pesto.1 create mode 100644 pesto.c create mode 100644 pesto.h diff --git a/.gitignore b/.gitignore index 3c16adc7..3e40d9f7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,9 +4,11 @@ /pasta /pasta.avx2 /passt-repair +/pesto /qrap /pasta.1 /seccomp.h +/seccomp_pesto.h /seccomp_repair.h /c*.json README.plain.md diff --git a/Makefile b/Makefile index 7875d23b..030681b1 100644 --- a/Makefile +++ b/Makefile @@ -47,19 +47,21 @@ PASST_SRCS = arch.c arp.c bitmap.c checksum.c conf.c dhcp.c dhcpv6.c \ vhost_user.c virtio.c vu_common.c QRAP_SRCS = qrap.c PASST_REPAIR_SRCS = passt-repair.c -SRCS = $(PASST_SRCS) $(QRAP_SRCS) $(PASST_REPAIR_SRCS) - -MANPAGES = passt.1 pasta.1 qrap.1 passt-repair.1 - -PASST_HEADERS = arch.h arp.h bitmap.h checksum.h conf.h dhcp.h dhcpv6.h \ - epoll_ctl.h flow.h fwd.h fwd_rule.h flow_table.h icmp.h icmp_flow.h \ - inany.h iov.h ip.h isolation.h lineread.h log.h migrate.h ndp.h \ - netlink.h packet.h passt.h pasta.h pcap.h pif.h repair.h serialise.h \ - siphash.h tap.h tcp.h tcp_buf.h tcp_conn.h tcp_internal.h tcp_splice.h \ - tcp_vu.h udp.h udp_flow.h udp_internal.h udp_vu.h util.h vhost_user.h \ - virtio.h vu_common.h +PESTO_SRCS = pesto.c +SRCS = $(PASST_SRCS) $(QRAP_SRCS) $(PASST_REPAIR_SRCS) $(PESTO_SRCS) + +MANPAGES = passt.1 pasta.1 pesto.1 qrap.1 passt-repair.1 + +PASST_HEADERS = arch.h arp.h bitmap.h checksum.h common.h conf.h dhcp.h \ + dhcpv6.h epoll_ctl.h flow.h fwd.h fwd_rule.h flow_table.h icmp.h \ + icmp_flow.h inany.h iov.h ip.h isolation.h lineread.h log.h migrate.h \ + ndp.h netlink.h packet.h passt.h pasta.h pcap.h pesto.h pif.h repair.h \ + serialise.h siphash.h tap.h tcp.h tcp_buf.h tcp_conn.h tcp_internal.h \ + tcp_splice.h tcp_vu.h udp.h udp_flow.h udp_internal.h udp_vu.h util.h \ + vhost_user.h virtio.h vu_common.h QRAP_HEADERS = arp.h ip.h passt.h util.h PASST_REPAIR_HEADERS = linux_dep.h +PESTO_HEADERS = common.h pesto.h C := \#include \nint main(){int a=getrandom(0, 0, 0);} ifeq ($(shell printf "$(C)" | $(CC) -S -xc - -o - >/dev/null 2>&1; echo $$?),0) @@ -78,7 +80,7 @@ docdir ?= $(datarootdir)/doc/passt mandir ?= $(datarootdir)/man man1dir ?= $(mandir)/man1 -BASEBIN = passt qrap passt-repair +BASEBIN = passt qrap passt-repair pesto ifeq ($(TARGET_ARCH),x86_64) BASEBIN += passt.avx2 endif @@ -100,6 +102,9 @@ seccomp.h: seccomp.sh $(PASST_SRCS) $(PASST_HEADERS) seccomp_repair.h: seccomp.sh $(PASST_REPAIR_SRCS) $(PASST_REPAIR_HEADERS) @ ARCH="$(TARGET_ARCH)" CC="$(CC)" ./seccomp.sh seccomp_repair.h $(PASST_REPAIR_SRCS) +seccomp_pesto.h: seccomp.sh $(PESTO_SRCS) + @ ARCH="$(TARGET_ARCH)" CC="$(CC)" ./seccomp.sh seccomp_pesto.h $(PESTO_SRCS) + $(BASEBIN): %: $(CC) $(BASE_CPPFLAGS) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(filter %.c,$^) -o $@ @@ -116,6 +121,8 @@ qrap: $(QRAP_SRCS) $(QRAP_HEADERS) passt-repair: $(PASST_REPAIR_SRCS) $(PASST_REPAIR_HEADERS) seccomp_repair.h +pesto: $(PESTO_SRCS) $(PESTO_HEADERS) seccomp_pesto.h + valgrind: EXTRA_SYSCALLS += rt_sigprocmask rt_sigtimedwait rt_sigaction \ rt_sigreturn getpid gettid kill clock_gettime \ mmap|mmap2 munmap open unlink gettimeofday futex \ @@ -126,7 +133,7 @@ valgrind: all .PHONY: clean clean: - $(RM) $(BIN) *~ *.o seccomp.h seccomp_repair.h pasta.1 \ + $(RM) $(BIN) *~ *.o seccomp.h seccomp_repair.h seccomp_pesto.h pasta.1 \ passt.tar passt.tar.gz *.deb *.rpm \ passt.pid README.plain.md @@ -183,7 +190,8 @@ docs: README.md CLANG_TIDY = clang-tidy CLANG_TIDY_FLAGS = -DCLANG_TIDY_58992 -clang-tidy: passt.clang-tidy passt-repair.clang-tidy qrap.clang-tidy +clang-tidy: passt.clang-tidy passt-repair.clang-tidy pesto.clang-tidy \ + qrap.clang-tidy .PHONY: %.clang-tidy %.clang-tidy: @@ -191,6 +199,7 @@ clang-tidy: passt.clang-tidy passt-repair.clang-tidy qrap.clang-tidy passt.clang-tidy: $(PASST_SRCS) $(PASST_HEADERS) seccomp.h passt-repair.clang-tidy: $(PASST_REPAIR_SRCS) $(PASST_REPAIR_HEADERS) seccomp_repair.h +pesto.clang-tidy: $(PESTO_SRCS) $(PESTO_HEADERS) seccomp_pesto.h qrap.clang-tidy: $(QRAP_SRCS) $(QRAP_HEADERS) CPPCHECK = cppcheck @@ -206,7 +215,7 @@ CPPCHECK_FLAGS = --std=c11 --error-exitcode=1 --enable=all --force \ --suppress=unusedStructMember \ -D CPPCHECK_6936 -cppcheck: passt.cppcheck passt-repair.cppcheck qrap.cppcheck +cppcheck: passt.cppcheck passt-repair.cppcheck pesto.cppcheck qrap.cppcheck .PHONY: %.cppcheck %.cppcheck: @@ -215,6 +224,9 @@ cppcheck: passt.cppcheck passt-repair.cppcheck qrap.cppcheck passt.cppcheck: $(PASST_SRCS) $(PASST_HEADERS) seccomp.h passt-repair.cppcheck: $(PASST_REPAIR_SRCS) $(PASST_REPAIR_HEADERS) seccomp_repair.h +pesto.cppcheck: CPPCHECK_FLAGS += --suppress=unmatchedSuppression +pesto.cppcheck: $(PESTO_SRCS) $(PESTO_HEADERS) seccomp_pesto.h + qrap.cppcheck: BASE_CPPFLAGS += -DARCH=\"$(TARGET_ARCH)\" qrap.cppcheck: CPPCHECK_FLAGS += --suppress=unusedFunction qrap.cppcheck: $(QRAP_SRCS) $(QRAP_HEADERS) diff --git a/common.h b/common.h new file mode 100644 index 00000000..a9c115a5 --- /dev/null +++ b/common.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright Red Hat + * Author: David Gibson + * + * Definitions used by both passt/pasta and other tools + */ + +#ifndef COMMON_H +#define COMMON_H + +#include + +#define VERSION_BLOB \ + VERSION "\n" \ + "Copyright Red Hat\n" \ + "GNU General Public License, version 2 or later\n" \ + " \n" \ + "This is free software: you are free to change and redistribute it.\n" \ + "There is NO WARRANTY, to the extent permitted by law.\n\n" + +/* FPRINTF() intentionally silences cert-err33-c clang-tidy warnings */ +#define FPRINTF(f, ...) (void)fprintf(f, __VA_ARGS__) + +#endif /* _COMMON_H */ diff --git a/pesto.1 b/pesto.1 new file mode 100644 index 00000000..338fb8a6 --- /dev/null +++ b/pesto.1 @@ -0,0 +1,46 @@ +.\" SPDX-License-Identifier: GPL-2.0-or-later +.\" Copyright Red Hat +.\" Author: David Gibson +.TH pesto 1 + +.SH NAME +.B pesto +\- Configure a running \fBpasst\fR(1) or \fBpasta\fR(1) instance. + +.SH SYNOPSIS +.B pesto +\fIPATH\fR + +.SH DESCRIPTION + +.B pesto +is an experimental client to view and update the port forwarding +configuration of a running \fBpasst\fR(1) or \fBpasta\fR(1) instance. + +\fIPATH\fR gives the path to the UNIX domain socket created by +\fBpasst\fR or \fBpasta\fR. It should match the \fB-c\fR command line +option given to that instance. + +.SH AUTHORS + +Stefano Brivio , +David Gibson . + +.SH REPORTING BUGS + +Please report issues on the bug tracker at https://bugs.passt.top/, or +send a message to the passt-user@passt.top mailing list, see +https://lists.passt.top/. + +.SH COPYRIGHT + +Copyright Red Hat + +\fBpesto\fR is free software: you can redistribute them and/or modify +them under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or (at +your option) any later version. + +.SH SEE ALSO + +\fBpasst\fR(1), \fBpasta\fR(1), \fBunix\fR(7). diff --git a/pesto.c b/pesto.c new file mode 100644 index 00000000..9f2fa5d5 --- /dev/null +++ b/pesto.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/* PESTO - Programmable Extensible Socket Translation Orchestrator + * front-end for passt(1) and pasta(1) forwarding configuration + * + * pesto.c - Main program (it's not actually extensible) + * + * Copyright (c) 2026 Red Hat GmbH + * Author: Stefano Brivio + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "common.h" +#include "seccomp_pesto.h" +#include "pesto.h" + +static bool debug_flag = false; + +static char stdout_buf[BUFSIZ]; + +#define die(...) \ + do { \ + FPRINTF(stderr, __VA_ARGS__); \ + FPRINTF(stderr, "\n"); \ + exit(EXIT_FAILURE); \ + } while (0) + +/** + * usage() - Print usage, exit with given status code + * @name: Executable name + * @f: Stream to print usage info to + * @status: Status code for exit(2) + * + * #syscalls:pesto exit_group fstat write + */ +static void usage(const char *name, FILE *f, int status) +{ + FPRINTF(f, "Usage: %s [OPTION]... PATH\n", name); + FPRINTF(f, + "\n" + " -d, --debug Print debugging messages\n" + " -h, --help Display this help message and exit\n" + " --version Show version and exit\n"); + exit(status); +} + +/** + * main() - Dynamic reconfiguration client main program + * @argc: Argument count + * @argv: Arguments: socket path, operation, port specifiers + * + * Return: 0 on success, won't return on failure + * + * #syscalls:pesto exit_group fstat read write + */ +int main(int argc, char **argv) +{ + const struct option options[] = { + {"debug", no_argument, NULL, 'd' }, + {"help", no_argument, NULL, 'h' }, + {"version", no_argument, NULL, 1 }, + { 0 }, + }; + const char *optstring = "dh"; + struct sock_fprog prog; + int optname; + + prctl(PR_SET_DUMPABLE, 0); + + prog.len = (unsigned short)sizeof(filter_pesto) / + sizeof(filter_pesto[0]); + prog.filter = filter_pesto; + if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) || + prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) + die("Failed to apply seccomp filter"); + + /* Explicitly set stdout buffer, otherwise printf() might allocate, + * breaking our seccomp profile. + */ + if (setvbuf(stdout, stdout_buf, _IOFBF, sizeof(stdout_buf))) + die("Failed to set stdout buffer"); + + do { + optname = getopt_long(argc, argv, optstring, options, NULL); + + switch (optname) { + case -1: + case 0: + break; + case 'h': + usage(argv[0], stdout, EXIT_SUCCESS); + break; + case 'd': + debug_flag = true; + break; + case 1: + FPRINTF(stdout, "pesto "); + FPRINTF(stdout, VERSION_BLOB); + exit(EXIT_SUCCESS); + default: + usage(argv[0], stderr, EXIT_FAILURE); + } + } while (optname != -1); + + if (argc - optind != 1) + usage(argv[0], stderr, EXIT_FAILURE); + + printf("debug_flag=%d, path=\"%s\"\n", debug_flag, argv[optind]); + + die("pesto is not implemented yet"); +} diff --git a/pesto.h b/pesto.h new file mode 100644 index 00000000..e9b329f4 --- /dev/null +++ b/pesto.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright Red Hat + * Author: David Gibson + * + * Definitions and functions used by both client and server of the configuration + * update protocol (pesto). + */ + +#ifndef PESTO_H +#define PESTO_H + +#endif /* PESTO_H */ diff --git a/util.h b/util.h index 92aeabc8..770ff93f 100644 --- a/util.h +++ b/util.h @@ -19,16 +19,9 @@ #include #include +#include "common.h" #include "log.h" -#define VERSION_BLOB \ - VERSION "\n" \ - "Copyright Red Hat\n" \ - "GNU General Public License, version 2 or later\n" \ - " \n" \ - "This is free software: you are free to change and redistribute it.\n" \ - "There is NO WARRANTY, to the extent permitted by law.\n\n" - #ifndef SECCOMP_RET_KILL_PROCESS #define SECCOMP_RET_KILL_PROCESS SECCOMP_RET_KILL #endif @@ -307,9 +300,6 @@ static inline bool mod_between(unsigned x, unsigned i, unsigned j, unsigned m) return mod_sub(x, i, m) < mod_sub(j, i, m); } -/* FPRINTF() intentionally silences cert-err33-c clang-tidy warnings */ -#define FPRINTF(f, ...) (void)fprintf(f, __VA_ARGS__) - void raw_random(void *buf, size_t buflen); /* -- 2.53.0