This series carries fixes for issues that emerged from testing on architectures other than x86_64, older kernels and older versions of gcc and glibc (1/22 to 7/22, 9/22, 11/22 to 12/22), some logic bugs that appeared during further testing (8/22, 10/22, 20/22) and fixes for tests, scripts and documentation (remaining patches). passt and pasta should now work on multiple architectures, build starting from gcc 4.7 and glibc 2.19, and actually work on kernel versions >= 4.4 with glibc >= 2.25. Tests checking this are introduced in the next series. Note to package maintainers: ausyscall(8) is not used anymore to generate seccomp profiles. Stefano Brivio (22): tcp: Cover all usages of tcpi_snd_wnd with HAS_SND_WND tap, tcp: Fix two comparisons with different signedness reported by gcc 7 passt: Drop <linux/ipv6.h> include, carry own ipv6hdr and opt_hdr definitions Makefile, seccomp: Fix build for i386, ppc64, ppc64le util: Fall-back definitions for SECCOMP_RET_KILL_PROCESS, ETH_{MAX,MIN}_MTU seccomp: Introduce mechanism to allow per-arch syscalls tcp, netlink, HAS{BYTES_ACKED,MIN_RTT,GETRANDOM} and NETLINK_GET_STRICT_CHK conf, pasta: Explicitly pass CLONE_{NEWUSER,NEWNET} to setns() tcp, udp, util: Fixes for bitmap handling on big-endian, casts netlink: Fix swapped v4/v6-only flags in external interface detection pasta: Check for zero d_reclen returned by getdents64() syscall tcp: Don't round down MSS to >= 64KiB page size, but clamp it in any case seccomp: Add a number of alternate and per-arch syscalls demo/pasta: Don't wait for pasta to return to a prompt test/two_guests: Drop stray spaces after sleep directives perf/passt_udp: Lower failure throughput thresholds with big MTUs test/lib/setup: Don't rely on IFS to properly separate qemu arguments test/lib/video: Drop -preset ultrafast from ffmpeg arguments hooks/pre-push: Delete old versions, add -DGLIBC_NO_STATIC_NSS, disable legacy builds conf: Fix support for --stderr as short option (-e) README: Fix anchor for Performance section README: Fix link to IGMP/MLD proxy ticket Makefile | 29 ++++++++++++++++++-- README.md | 6 ++-- arp.c | 2 -- conf.c | 18 ++++++++---- dhcp.c | 2 -- dhcpv6.c | 2 -- hooks/pre-push | 18 +++++++----- icmp.c | 1 - ndp.c | 1 - netlink.c | 14 ++++++---- passt.c | 17 +++++++----- passt.h | 3 +- pasta.c | 13 +++++---- pcap.c | 2 -- qrap.c | 2 -- seccomp.sh | 63 +++++++++++++++++++++++++++++++++++------- tap.c | 5 ++-- tcp.c | 51 +++++++++++++++++++++++++++++----- test/demo/pasta | 2 +- test/lib/setup | 64 +++++++++++++++++++++---------------------- test/lib/video | 2 +- test/perf/passt_udp | 8 +++--- test/two_guests/basic | 8 +++--- udp.c | 6 ++-- util.c | 18 +++++++----- util.h | 40 +++++++++++++++++++++++++++ 26 files changed, 275 insertions(+), 122 deletions(-) -- 2.33.0
...I forgot two of them. Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- tcp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tcp.c b/tcp.c index df8a57f..b0d5f40 100644 --- a/tcp.c +++ b/tcp.c @@ -1586,12 +1586,14 @@ static int tcp_update_seqack_wnd(struct ctx *c, struct tcp_tap_conn *conn, goto out; } +#ifdef HAS_SND_WND if (conn->local || tcp_rtt_dst_low(conn)) { conn->wnd_to_tap = tinfo->tcpi_snd_wnd; } else { tcp_get_sndbuf(conn); conn->wnd_to_tap = MIN((int)tinfo->tcpi_snd_wnd, conn->snd_buf); } +#endif conn->wnd_to_tap = MIN(conn->wnd_to_tap, MAX_WINDOW); -- 2.33.0
For some reason, those are not reported by recent versions of gcc. Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- tap.c | 2 +- tcp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tap.c b/tap.c index d6bad5a..a3fc249 100644 --- a/tap.c +++ b/tap.c @@ -340,7 +340,7 @@ resume: iph = (struct iphdr *)(eh + 1); if ((iph->ihl * 4) + sizeof(*eh) > len) continue; - if (iph->ihl * 4 < sizeof(*iph)) + if (iph->ihl * 4 < (int)sizeof(*iph)) continue; if (iph->saddr && c->addr4_seen != iph->saddr) { diff --git a/tcp.c b/tcp.c index b0d5f40..2a842bd 100644 --- a/tcp.c +++ b/tcp.c @@ -1034,7 +1034,7 @@ static int tcp_opt_get(struct tcphdr *th, size_t len, uint8_t type_search, uint8_t type, optlen; char *p; - if (len > th->doff * 4) + if (len > (unsigned)th->doff * 4) len = th->doff * 4; len -= sizeof(*th); -- 2.33.0
This is the only remaining Linux-specific include -- drop it to avoid clang-tidy warnings and to make code more portable. Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- arp.c | 2 -- conf.c | 2 -- dhcp.c | 2 -- dhcpv6.c | 2 -- icmp.c | 1 - ndp.c | 1 - netlink.c | 1 - passt.c | 1 - pasta.c | 2 -- pcap.c | 2 -- qrap.c | 2 -- tap.c | 1 - tcp.c | 1 - udp.c | 2 -- util.c | 2 -- util.h | 28 ++++++++++++++++++++++++++++ 16 files changed, 28 insertions(+), 24 deletions(-) diff --git a/arp.c b/arp.c index 2f3e3ac..b5af49f 100644 --- a/arp.c +++ b/arp.c @@ -23,8 +23,6 @@ #include <unistd.h> #include <string.h> -#include <linux/ipv6.h> - #include "util.h" #include "arp.h" #include "dhcp.h" diff --git a/conf.c b/conf.c index 8ec67fc..ab91b7f 100644 --- a/conf.c +++ b/conf.c @@ -31,8 +31,6 @@ #include <netinet/in.h> #include <netinet/if_ether.h> -#include <linux/ipv6.h> - #include "util.h" #include "passt.h" #include "netlink.h" diff --git a/dhcp.c b/dhcp.c index 5169f56..0d6d698 100644 --- a/dhcp.c +++ b/dhcp.c @@ -23,8 +23,6 @@ #include <unistd.h> #include <string.h> -#include <linux/ipv6.h> - #include "util.h" #include "checksum.h" #include "passt.h" diff --git a/dhcpv6.c b/dhcpv6.c index 5fe7cd0..e4113bc 100644 --- a/dhcpv6.c +++ b/dhcpv6.c @@ -25,8 +25,6 @@ #include <string.h> #include <time.h> -#include <linux/ipv6.h> - #include "util.h" #include "passt.h" #include "tap.h" diff --git a/icmp.c b/icmp.c index cc76da7..67859e0 100644 --- a/icmp.c +++ b/icmp.c @@ -30,7 +30,6 @@ #include <time.h> #include <linux/icmpv6.h> -#include <linux/ipv6.h> #include "util.h" #include "passt.h" diff --git a/ndp.c b/ndp.c index ec6b5ef..386098c 100644 --- a/ndp.c +++ b/ndp.c @@ -24,7 +24,6 @@ #include <net/if_arp.h> #include <netinet/if_ether.h> -#include <linux/ipv6.h> #include <linux/icmpv6.h> #include "checksum.h" diff --git a/netlink.c b/netlink.c index cea32fd..0948f45 100644 --- a/netlink.c +++ b/netlink.c @@ -25,7 +25,6 @@ #include <netinet/in.h> #include <netinet/if_ether.h> -#include <linux/ipv6.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> diff --git a/passt.c b/passt.c index 6436a45..3581428 100644 --- a/passt.c +++ b/passt.c @@ -54,7 +54,6 @@ #include <linux/audit.h> #include <linux/filter.h> #include <linux/capability.h> -#include <linux/ipv6.h> #include <linux/icmpv6.h> #include "seccomp.h" diff --git a/pasta.c b/pasta.c index 5150a3e..a2b842b 100644 --- a/pasta.c +++ b/pasta.c @@ -35,8 +35,6 @@ #include <net/ethernet.h> #include <sys/syscall.h> -#include <linux/ipv6.h> - #include "util.h" #include "passt.h" #include "netlink.h" diff --git a/pcap.c b/pcap.c index 0c61cd8..e00fc45 100644 --- a/pcap.c +++ b/pcap.c @@ -28,8 +28,6 @@ #include <unistd.h> #include <net/if.h> -#include <linux/ipv6.h> - #include "util.h" #include "passt.h" diff --git a/qrap.c b/qrap.c index 5a0a7fd..1eb82fa 100644 --- a/qrap.c +++ b/qrap.c @@ -26,8 +26,6 @@ #include <netinet/in.h> #include <netinet/if_ether.h> -#include <linux/ipv6.h> - #include "util.h" #include "passt.h" #include "arp.h" diff --git a/tap.c b/tap.c index a3fc249..d2f234d 100644 --- a/tap.c +++ b/tap.c @@ -40,7 +40,6 @@ #include <netinet/if_ether.h> #include <linux/if_tun.h> -#include <linux/ipv6.h> #include <linux/icmpv6.h> #include "checksum.h" diff --git a/tcp.c b/tcp.c index 2a842bd..96d462f 100644 --- a/tcp.c +++ b/tcp.c @@ -328,7 +328,6 @@ #include <unistd.h> #include <time.h> -#include <linux/ipv6.h> #include <linux/tcp.h> /* For struct tcp_info */ #include "checksum.h" diff --git a/udp.c b/udp.c index 3b8a70a..15e0c96 100644 --- a/udp.c +++ b/udp.c @@ -110,8 +110,6 @@ #include <unistd.h> #include <time.h> -#include <linux/ipv6.h> - #include "checksum.h" #include "util.h" #include "passt.h" diff --git a/util.c b/util.c index 3c4ba33..d172ad8 100644 --- a/util.c +++ b/util.c @@ -32,8 +32,6 @@ #include <time.h> #include <errno.h> -#include <linux/ipv6.h> - #include "util.h" #include "passt.h" diff --git a/util.h b/util.h index 0d50868..44c85db 100644 --- a/util.h +++ b/util.h @@ -149,6 +149,34 @@ enum bind_type { struct ctx; +struct ipv6hdr { +#pragma GCC diagnostic ignored "-Wpedantic" +#if __BYTE_ORDER == __BIG_ENDIAN + __u8 version:4, + priority:4; +#else + uint8_t priority:4, + version:4; +#endif +#pragma GCC diagnostic pop + uint8_t flow_lbl[3]; + + __be16 payload_len; + __u8 nexthdr; + __u8 hop_limit; + + struct in6_addr saddr; + struct in6_addr daddr; +}; + +struct ipv6_opt_hdr { + __u8 nexthdr; + __u8 hdrlen; + /* + * TLV encoded option data follows. + */ +} __attribute__((packed)); /* required for some archs */ + __attribute__ ((weak)) int ffsl(long int i) { return __builtin_ffsl(i); } void __openlog(const char *ident, int option, int facility); void passt_vsyslog(int pri, const char *format, va_list ap); -- 2.33.0
On some distributions, on ppc64, ulimit -s returns 'unlimited': add a reasonable default, and also make sure ulimit is invoked using the default shell, which should ensure ulimit is actually implemented. Also note that AUDIT_ARCH doesn't follow closely the naming reported by 'uname -m': convert for i386 and ppc as needed. While at it, move inclusion of seccomp.h after util.h, the former is less generic (cosmetic/clang-tidy only). Older kernel headers might lack a definition for AUDIT_ARCH_PPC64LE: define that explicitly if it's not available. Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- Makefile | 14 ++++++++++++-- passt.c | 2 +- seccomp.sh | 6 +++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index c73a786..4647210 100644 --- a/Makefile +++ b/Makefile @@ -9,11 +9,21 @@ # Copyright (c) 2021 Red Hat GmbH # Author: Stefano Brivio <sbrivio(a)redhat.com> +RLIMIT_STACK_VAL := $(shell /bin/sh -c 'ulimit -s') +ifeq ($(RLIMIT_STACK_VAL),unlimited) +RLIMIT_STACK_VAL := 1024 +endif + +AUDIT_ARCH := $(shell uname -m | tr [a-z] [A-Z]) +AUDIT_ARCH := $(shell echo $(AUDIT_ARCH) | sed 's/I[456]86/I386/') +AUDIT_ARCH := $(shell echo $(AUDIT_ARCH) | sed 's/PPC64/PPC/') +AUDIT_ARCH := $(shell echo $(AUDIT_ARCH) | sed 's/PPCLE/PPC64LE/') + CFLAGS += -Wall -Wextra -pedantic -std=c99 -D_XOPEN_SOURCE=700 -D_GNU_SOURCE -CFLAGS += -DRLIMIT_STACK_VAL=$(shell ulimit -s) CFLAGS += -DPAGE_SIZE=$(shell getconf PAGE_SIZE) CFLAGS += -DNETNS_RUN_DIR=\"/run/netns\" -CFLAGS += -DPASST_AUDIT_ARCH=AUDIT_ARCH_$(shell uname -m | tr [a-z] [A-Z]) +CFLAGS += -DPASST_AUDIT_ARCH=AUDIT_ARCH_$(AUDIT_ARCH) +CFLAGS += -DRLIMIT_STACK_VAL=$(RLIMIT_STACK_VAL) CFLAGS += -DARCH=\"$(shell uname -m)\" # On gcc 11.2, with -O2 and -flto, tcp_hash() and siphash_20b(), if inlined, diff --git a/passt.c b/passt.c index 3581428..4f2b896 100644 --- a/passt.c +++ b/passt.c @@ -56,8 +56,8 @@ #include <linux/capability.h> #include <linux/icmpv6.h> -#include "seccomp.h" #include "util.h" +#include "seccomp.h" #include "passt.h" #include "dhcp.h" #include "dhcpv6.h" diff --git a/seccomp.sh b/seccomp.sh index a055420..c710ce4 100755 --- a/seccomp.sh +++ b/seccomp.sh @@ -16,7 +16,11 @@ TMP="$(mktemp)" OUT="seccomp.h" -HEADER="/* This file was automatically generated by $(basename ${0}) */" +HEADER="/* This file was automatically generated by $(basename ${0}) */ + +#ifndef AUDIT_ARCH_PPC64LE +#define AUDIT_ARCH_PPC64LE (AUDIT_ARCH_PPC64 | __AUDIT_ARCH_LE) +#endif" # Prefix for each profile: check that 'arch' in seccomp_data is matching PRE=' -- 2.33.0
They're not available on some older toolchains. Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- util.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/util.h b/util.h index 44c85db..63cd8f9 100644 --- a/util.h +++ b/util.h @@ -8,6 +8,16 @@ void warn(const char *format, ...); void info(const char *format, ...); void debug(const char *format, ...); +#ifndef SECCOMP_RET_KILL_PROCESS +#define SECCOMP_RET_KILL_PROCESS SECCOMP_RET_KILL +#endif +#ifndef ETH_MAX_MTU +#define ETH_MAX_MTU USHRT_MAX +#endif +#ifndef ETH_MIN_MTU +#define ETH_MIN_MTU 68 +#endif + #define CHECK_SET_MIN_MAX(basename, fd) \ do { \ if ((fd) < basename##min) \ -- 2.33.0
Some C library functions are commonly implemented by different syscalls on different architectures. Add a mechanism to allow selected syscalls for a single architecture, syntax in #syscalls comment is: #syscalls <arch>:<name> e.g. s390x:socketcall, given that socketcall() is commonly used there instead of socket(). This is now implemented by a compiler probe for syscall numbers, auditd tools (ausyscall) are not required anymore as a result. Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- seccomp.sh | 57 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/seccomp.sh b/seccomp.sh index c710ce4..f5ee98e 100755 --- a/seccomp.sh +++ b/seccomp.sh @@ -63,6 +63,7 @@ sub() { sed -i "${__line_no}s#.*#${__template}#" "${TMP}" + IFS=' ' for __def in ${@}; do __key="@${__def%%:*}@" __value="${__def#*:}" @@ -79,6 +80,7 @@ finish() { __out="$(eval printf '%s' "\${${1}}")" shift + IFS=' ' for __def in ${@}; do __key="@${__def%%:*}@" __value="${__def#*:}" @@ -101,15 +103,54 @@ log2() { echo ${__x} } -# cc_syscall_nr - Try to get syscall number from compiler +# syscall_nr - Get syscall number from compiler # $1: Name of syscall -cc_syscall_nr() { - __in="$(printf "#include <sys/syscall.h>\n__NR_%s" ${1})" +syscall_nr() { + __in="$(printf "#include <asm-generic/unistd.h>\n#include <sys/syscall.h>\n__NR_%s" ${1})" __out="$(echo "${__in}" | cc -E -xc - -o - | tail -1)" [ "${__out}" = "__NR_$1" ] && return 1 echo "${__out}" } +filter() { + __filtered= + for __c in ${@}; do + __arch_match=0 + case ${__c} in + *:*) + case ${__c} in + $(uname -m):*) + __arch_match=1 + __c=${__c##*:} + ;; + esac + ;; + *) + __arch_match=1 + ;; + esac + [ ${__arch_match} -eq 0 ] && continue + + IFS='| ' + __found=0 + for __name in ${__c}; do + syscall_nr "${__name}" >/dev/null && __found=1 && break + done + unset IFS + + if [ ${__found} -eq 0 ]; then + echo + echo "Warning: no syscall number for ${__c}" >&2 + echo " none of these syscalls will be allowed" >&2 + continue + fi + + __filtered="${__filtered} ${__name}" + done + + echo "${__filtered}" | tr ' ' '\n' | sort -u +} + # gen_profile() - Build struct sock_filter for a single profile # $1: Profile name # $@: Names of allowed system calls, amount padded to next power of two @@ -127,9 +168,7 @@ gen_profile() { done for __i in $(seq 1 ${__statements_calls} ); do __syscall_name="$(eval echo \${${__i}})" - if { ! command -V ausyscall >/dev/null 2>&1 || \ - ! ausyscall "${__syscall_name}" --exact >> "${TMP}"; } && \ - ! cc_syscall_nr "${__syscall_name}" >> "${TMP}"; then + if ! syscall_nr ${__syscall_name} >> "${TMP}"; then echo "Cannot get syscall number for ${__syscall_name}" exit 1 fi @@ -191,8 +230,8 @@ gen_profile() { printf '%s\n' "${HEADER}" > "${OUT}" __profiles="$(sed -n 's/[\t ]*\*[\t ]*#syscalls:\([^ ]*\).*/\1/p' *.[ch] | sort -u)" for __p in ${__profiles}; do - __calls="$(sed -n 's/[\t ]*\*[\t ]*#syscalls\(:'"${__p}"'\|\)[\t ]\{1,\}\(.*\)/\2/p' *.[ch] | tr ' ' '\n' | sort -u)" - + __calls="$(sed -n 's/[\t ]*\*[\t ]*#syscalls\(:'"${__p}"'\|\)[\t ]\{1,\}\(.*\)/\2/p' *.[ch])" + __calls="$(filter ${__calls})" echo "seccomp profile ${__p} allows: ${__calls}" | tr '\n' ' ' | fmt -t # Pad here to keep gen_profile() "simple" @@ -200,7 +239,7 @@ for __p in ${__profiles}; do for __c in ${__calls}; do __count=$(( __count + 1 )); done __padded=$(( 1 << (( $(log2 ${__count}) + 1 )) )) for __i in $( seq ${__count} $(( __padded - 1 )) ); do - __calls="${__calls} tuxcall" + __calls="${__calls} read" done gen_profile "${__p}" ${__calls} -- 2.33.0
tcpi_bytes_acked and tcpi_min_rtt are only available on recent kernel versions: provide fall-back paths (incurring some grade of performance penalty). Support for getrandom() was introduced in Linux 3.17 and glibc 2.25: provide an alternate mechanism for that as well, reading from /dev/random. Also check if NETLINK_GET_STRICT_CHK is defined before using it: it's not strictly needed, we'll filter out irrelevant results from netlink anyway. Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- Makefile | 15 +++++++++++++++ netlink.c | 9 +++++++-- tcp.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 4647210..443c39d 100644 --- a/Makefile +++ b/Makefile @@ -45,6 +45,21 @@ ifeq ($(shell printf "$(C)" | $(CC) -S -xc - -o - >/dev/null 2>&1; echo $$?),0) CFLAGS += -DHAS_SND_WND endif +C := \#include <linux/tcp.h>\nstruct tcp_info x = { .tcpi_bytes_acked = 0 }; +ifeq ($(shell printf "$(C)" | $(CC) -S -xc - -o - >/dev/null 2>&1; echo $$?),0) + CFLAGS += -DHAS_BYTES_ACKED +endif + +C := \#include <linux/tcp.h>\nstruct tcp_info x = { .tcpi_min_rtt = 0 }; +ifeq ($(shell printf "$(C)" | $(CC) -S -xc - -o - >/dev/null 2>&1; echo $$?),0) + CFLAGS += -DHAS_MIN_RTT +endif + +C := \#include <sys/random.h>\nint main(){int a=getrandom(0, 0, 0);} +ifeq ($(shell printf "$(C)" | $(CC) -S -xc - -o - >/dev/null 2>&1; echo $$?),0) + CFLAGS += -DHAS_GETRANDOM +endif + prefix ?= /usr/local all: passt pasta passt4netns qrap diff --git a/netlink.c b/netlink.c index 0948f45..3ba5f05 100644 --- a/netlink.c +++ b/netlink.c @@ -46,7 +46,10 @@ static int nl_seq; static int nl_sock_init_do(void *arg) { struct sockaddr_nl addr = { .nl_family = AF_NETLINK, }; - int *s = &nl_sock, v = 1; + int *s = &nl_sock; +#ifdef NETLINK_GET_STRICT_CHK + int y = 1; +#endif ns: if (((*s) = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) < 0 || @@ -56,7 +59,9 @@ ns: if (*s == -1 || !arg || s == &nl_sock_ns) return 0; - setsockopt(*s, SOL_NETLINK, NETLINK_GET_STRICT_CHK, &v, sizeof(v)); +#ifdef NETLINK_GET_STRICT_CHK + setsockopt(*s, SOL_NETLINK, NETLINK_GET_STRICT_CHK, &y, sizeof(y)); +#endif ns_enter((struct ctx *)arg); s = &nl_sock_ns; diff --git a/tcp.c b/tcp.c index 96d462f..839bf30 100644 --- a/tcp.c +++ b/tcp.c @@ -321,7 +321,9 @@ #include <stddef.h> #include <string.h> #include <sys/epoll.h> +#ifdef HAS_GETRANDOM #include <sys/random.h> +#endif #include <sys/socket.h> #include <sys/types.h> #include <sys/uio.h> @@ -760,6 +762,7 @@ static int tcp_rtt_dst_low(struct tcp_tap_conn *conn) */ static void tcp_rtt_dst_check(struct tcp_tap_conn *conn, struct tcp_info *tinfo) { +#ifdef HAS_MIN_RTT int i, hole = -1; if (!tinfo->tcpi_min_rtt || @@ -777,6 +780,10 @@ static void tcp_rtt_dst_check(struct tcp_tap_conn *conn, struct tcp_info *tinfo) if (hole == LOW_RTT_TABLE_SIZE) hole = 0; memcpy(low_rtt_dst + hole, &in6addr_any, sizeof(conn->a.a6)); +#else + (void)conn; + (void)tinfo; +#endif /* HAS_MIN_RTT */ } /** @@ -1552,6 +1559,13 @@ static int tcp_update_seqack_wnd(struct ctx *c, struct tcp_tap_conn *conn, struct tcp_info tinfo_new; int s = conn->sock; +#ifndef HAS_BYTES_ACKED + (void)flags; + + conn->seq_ack_to_tap = conn->seq_from_tap; + if (SEQ_LT(conn->seq_ack_to_tap, prev_ack_to_tap)) + conn->seq_ack_to_tap = prev_ack_to_tap; +#else if (conn->state > ESTABLISHED || (flags & (DUP_ACK | FORCE_ACK)) || conn->local || tcp_rtt_dst_low(conn) || conn->snd_buf < SNDBUF_SMALL) { @@ -1569,6 +1583,7 @@ static int tcp_update_seqack_wnd(struct ctx *c, struct tcp_tap_conn *conn, if (SEQ_LT(conn->seq_ack_to_tap, prev_ack_to_tap)) conn->seq_ack_to_tap = prev_ack_to_tap; } +#endif /* !HAS_BYTES_ACKED */ if (!KERNEL_REPORTS_SND_WND(c)) { tcp_get_sndbuf(conn); @@ -3586,9 +3601,30 @@ int tcp_sock_init(struct ctx *c, struct timespec *now) { struct tcp_sock_refill_arg refill_arg = { c, 0 }; int i, port; +#ifndef HAS_GETRANDOM + int dev_random = open("/dev/random", O_RDONLY); + unsigned int random_read = 0; + + while (dev_random && random_read < sizeof(c->tcp.hash_secret)) { + int ret = read(dev_random, + (uint8_t *)&c->tcp.hash_secret + random_read, + sizeof(c->tcp.hash_secret) - random_read); + if (ret == -1 && errno == EINTR) + continue; + + if (ret <= 0) + break; + + random_read += ret; + } + if (dev_random >= 0) + close(dev_random); + if (random_read < sizeof(c->tcp.hash_secret)) { +#else if (getrandom(&c->tcp.hash_secret, sizeof(c->tcp.hash_secret), GRND_RANDOM) < 0) { +#endif /* !HAS_GETRANDOM */ perror("TCP initial sequence getrandom"); exit(EXIT_FAILURE); } -- 2.33.0
Only allow the intended types of namespaces to be joined via setns() as a defensive measure. Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- conf.c | 4 ++-- pasta.c | 6 ++++-- util.c | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/conf.c b/conf.c index ab91b7f..6810144 100644 --- a/conf.c +++ b/conf.c @@ -347,8 +347,8 @@ static int conf_ns_check(void *arg) { struct ctx *c = (struct ctx *)arg; - if ((!c->netns_only && setns(c->pasta_userns_fd, 0)) || - setns(c->pasta_netns_fd, 0)) + if ((!c->netns_only && setns(c->pasta_userns_fd, CLONE_NEWUSER)) || + setns(c->pasta_netns_fd, CLONE_NEWNET)) c->pasta_userns_fd = c->pasta_netns_fd = -1; return 0; diff --git a/pasta.c b/pasta.c index a2b842b..bcc1261 100644 --- a/pasta.c +++ b/pasta.c @@ -148,13 +148,15 @@ static int pasta_wait_for_ns(void *arg) snprintf(ns, PATH_MAX, "/proc/%i/ns/user", pasta_child_pid); do while ((c->pasta_userns_fd = open(ns, O_RDONLY)) < 0); - while (setns(c->pasta_userns_fd, 0) && !close(c->pasta_userns_fd)); + while (setns(c->pasta_userns_fd, CLONE_NEWUSER) && + !close(c->pasta_userns_fd)); netns: snprintf(ns, PATH_MAX, "/proc/%i/ns/net", pasta_child_pid); do while ((c->pasta_netns_fd = open(ns, O_RDONLY)) < 0); - while (setns(c->pasta_netns_fd, 0) && !close(c->pasta_netns_fd)); + while (setns(c->pasta_netns_fd, CLONE_NEWNET) && + !close(c->pasta_netns_fd)); return 0; } diff --git a/util.c b/util.c index d172ad8..7a3ea51 100644 --- a/util.c +++ b/util.c @@ -469,10 +469,10 @@ void procfs_scan_listen(char *name, uint8_t *map, uint8_t *exclude) */ int ns_enter(struct ctx *c) { - if (!c->netns_only && setns(c->pasta_userns_fd, 0)) + if (!c->netns_only && setns(c->pasta_userns_fd, CLONE_NEWUSER)) return -errno; - if (setns(c->pasta_netns_fd, 0)) + if (setns(c->pasta_netns_fd, CLONE_NEWNET)) return -errno; return 0; -- 2.33.0
Bitmap manipulating functions would otherwise refer to inconsistent sets of bits on big-endian architectures. While at it, fix up a couple of casts. Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- passt.h | 3 ++- tcp.c | 2 +- udp.c | 4 ++-- util.c | 12 +++++++++--- util.h | 2 ++ 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/passt.h b/passt.h index ae3035f..0ef1897 100644 --- a/passt.h +++ b/passt.h @@ -67,7 +67,8 @@ extern char pkt_buf [PKT_BUF_BYTES]; extern char *ip_proto_str[]; #define IP_PROTO_STR(n) \ - (((n) <= IPPROTO_SCTP && ip_proto_str[(n)]) ? ip_proto_str[(n)] : "?") + (((uint8_t)(n) <= IPPROTO_SCTP && ip_proto_str[(n)]) ? \ + ip_proto_str[(n)] : "?") #include <resolv.h> /* For MAXNS below */ diff --git a/tcp.c b/tcp.c index 839bf30..18f07b6 100644 --- a/tcp.c +++ b/tcp.c @@ -2518,7 +2518,7 @@ eintr: } - if (n < (seq_from_tap - conn->seq_from_tap)) { + if (n < (int)(seq_from_tap - conn->seq_from_tap)) { partial_send = 1; conn->seq_from_tap += n; tcp_send_to_tap(c, conn, 0, now); diff --git a/udp.c b/udp.c index 15e0c96..e1a9ecb 100644 --- a/udp.c +++ b/udp.c @@ -684,7 +684,7 @@ void udp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events, cur_mh->msg_iov = &udp6_l2_iov_tap[0]; msg_i = msglen = iov_in_msg = 0; - for (i = 0; i < n; i++) { + for (i = 0; i < (unsigned)n; i++) { struct udp6_l2_buf_t *b = &udp6_l2_buf[i]; size_t ip_len, iov_len; @@ -770,7 +770,7 @@ void udp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events, cur_mh->msg_iov = &udp4_l2_iov_tap[0]; msg_i = msglen = iov_in_msg = 0; - for (i = 0; i < n; i++) { + for (i = 0; i < (unsigned)n; i++) { struct udp4_l2_buf_t *b = &udp4_l2_buf[i]; size_t ip_len, iov_len; in_addr_t s_addr; diff --git a/util.c b/util.c index 7a3ea51..46a539b 100644 --- a/util.c +++ b/util.c @@ -342,7 +342,9 @@ int timespec_diff_ms(struct timespec *a, struct timespec *b) */ void bitmap_set(uint8_t *map, int bit) { - map[bit / 8] |= 1 << (bit % 8); + unsigned long *word = (unsigned long *)map + BITMAP_WORD(bit); + + *word |= BITMAP_BIT(bit); } /** @@ -352,7 +354,9 @@ void bitmap_set(uint8_t *map, int bit) */ void bitmap_clear(uint8_t *map, int bit) { - map[bit / 8] &= ~(1 << (bit % 8)); + unsigned long *word = (unsigned long *)map + BITMAP_WORD(bit); + + *word &= ~BITMAP_BIT(bit); } /** @@ -364,7 +368,9 @@ void bitmap_clear(uint8_t *map, int bit) */ int bitmap_isset(const uint8_t *map, int bit) { - return map[bit / 8] & (1 << bit % 8); + unsigned long *word = (unsigned long *)map + BITMAP_WORD(bit); + + return *word & BITMAP_BIT(bit); } /** diff --git a/util.h b/util.h index 63cd8f9..800a91d 100644 --- a/util.h +++ b/util.h @@ -43,6 +43,8 @@ void debug(const char *format, ...); #define ROUND_DOWN(x, y) ((x) & ~((y) - 1)) #define ROUND_UP(x, y) (((x) + (y) - 1) & ~((y) - 1)) +#define BITMAP_BIT(n) (1UL << (n) % (sizeof(long) * 8)) +#define BITMAP_WORD(n) (n / (sizeof(long) * 8)) #define SWAP(a, b) \ do { \ -- 2.33.0
The effect of this typo became visible in an IPv6-only environment, where passt wouldn't work at all. Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- netlink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netlink.c b/netlink.c index 3ba5f05..532868d 100644 --- a/netlink.c +++ b/netlink.c @@ -231,8 +231,8 @@ v6: } if (first_v6) { - *v4 = IP_VERSION_ENABLED; - *v6 = IP_VERSION_DISABLED; + *v4 = IP_VERSION_DISABLED; + *v6 = IP_VERSION_ENABLED; return first_v6; } -- 2.33.0
Seen on PPC with some older kernel versions: we seemingly have bytes left to read from the returned array of dirent structs, but d_reclen is zero: this, and all the subsequent entries, are not valid. Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- pasta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pasta.c b/pasta.c index bcc1261..3928ad0 100644 --- a/pasta.c +++ b/pasta.c @@ -63,7 +63,7 @@ loop: struct dirent *dp = (struct dirent *)buf; int pos = 0; - while (pos < n) { + while (dp->d_reclen && pos < n) { pid_t pid; errno = 0; -- 2.33.0
On some architectures, the page size is bigger than the maximum size of an Ethernet frame. Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- tcp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tcp.c b/tcp.c index 18f07b6..36c2bb5 100644 --- a/tcp.c +++ b/tcp.c @@ -1671,7 +1671,7 @@ static int tcp_send_to_tap(struct ctx *c, struct tcp_tap_conn *conn, int flags, } if (flags & SYN) { - uint16_t mss; + int mss; /* Options: MSS, NOP and window scale (8 bytes) */ optlen = OPT_MSS_LEN + 1 + OPT_WS_LEN; @@ -1691,10 +1691,10 @@ static int tcp_send_to_tap(struct ctx *c, struct tcp_tap_conn *conn, int flags, if (c->low_wmem && !conn->local && !tcp_rtt_dst_low(conn)) mss = MIN(mss, PAGE_SIZE); - else + else if (mss > PAGE_SIZE) mss = ROUND_DOWN(mss, PAGE_SIZE); } - *(uint16_t *)data = htons(mss); + *(uint16_t *)data = htons(MIN(USHRT_MAX, mss)); data += OPT_MSS_LEN - 2; th->doff += OPT_MSS_LEN / 4; -- 2.33.0
Depending on the C library, but not necessarily in all the functions we use, statx() might be used instead of stat(), getdents() instead of getdents64(), readlinkat() instead of readlink(), openat() instead of open(). On aarch64, it's clone() and not fork(), and dup3() instead of dup2() -- just allow the existing alternative instead of dealing with per-arch selections. Since glibc commit 9a7565403758 ("posix: Consolidate fork implementation"), we need to allow set_robust_list() for fork()/clone(), even in a single-threaded context. On some architectures, epoll_pwait() is provided instead of epoll_wait(), but never both. Same with newfstat() and fstat(), sigreturn() and rt_sigreturn(), getdents64() and getdents(), readlink() and readlinkat(), unlink() and unlinkat(), whereas pipe() might not be available, but pipe2() always is, exclusively or not. Seen on Fedora 34: newfstatat() is used on top of fstat(). syslog() is an actual system call on some glibc/arch combinations, instead of a connect()/send() implementation. On ppc64 and ppc64le, _llseek(), recv(), send() and getuid() are used. For ppc64 only: ugetrlimit() for the getrlimit() implementation, plus sigreturn() and fcntl64(). On s390x, additionally, we need to allow socketcall() (on top of socket()), and sigreturn() also for passt (not just for pasta). Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- README.md | 2 +- conf.c | 2 +- passt.c | 14 +++++++++----- pasta.c | 3 ++- tap.c | 2 +- tcp.c | 2 +- 6 files changed, 15 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 8345656..ee689f5 100644 --- a/README.md +++ b/README.md @@ -233,7 +233,7 @@ speeding up local connections, and usually requiring NAT. _pasta_: * ✅ root operation not allowed outside user namespaces * ✅ all capabilities dropped, other than `CAP_NET_BIND_SERVICE` (if granted) * ✅ no external dependencies (other than a standard C library) -* ✅ restrictive seccomp profiles (46 syscalls allowed for _passt_, 58 for +* ✅ restrictive seccomp profiles (50 syscalls allowed for _passt_, 62 for _pasta_) * ✅ static checkers in continuous integration (clang-tidy, cppcheck) * 🛠️ rework of TCP state machine (flags instead of states), TCP timers, and code diff --git a/conf.c b/conf.c index 6810144..7859f25 100644 --- a/conf.c +++ b/conf.c @@ -11,7 +11,7 @@ * Copyright (c) 2020-2021 Red Hat GmbH * Author: Stefano Brivio <sbrivio(a)redhat.com> * - * #syscalls stat + * #syscalls stat|statx */ #include <arpa/inet.h> diff --git a/passt.c b/passt.c index 4f2b896..3c9fb90 100644 --- a/passt.c +++ b/passt.c @@ -273,12 +273,16 @@ static void pid_file(struct ctx *c) { * * Return: non-zero on failure * - * #syscalls read write open close fork dup2 exit chdir ioctl writev syslog - * #syscalls prlimit64 epoll_ctl epoll_create1 epoll_wait accept4 accept listen + * #syscalls read write open|openat close fork|clone dup2|dup3 ioctl writev * #syscalls socket bind connect getsockopt setsockopt recvfrom sendto shutdown - * #syscalls openat fstat fcntl lseek clone setsid exit_group getpid - * #syscalls clock_gettime newfstatat - * #syscalls:pasta rt_sigreturn + * #syscalls accept4 accept listen set_robust_list getrlimit setrlimit + * #syscalls openat fcntl lseek clone setsid exit exit_group getpid chdir + * #syscalls epoll_ctl epoll_create1 epoll_wait|epoll_pwait epoll_pwait + * #syscalls prlimit64 clock_gettime fstat|newfstat newfstatat syslog + * #syscalls ppc64le:_llseek ppc64le:recv ppc64le:send ppc64le:getuid + * #syscalls ppc64:_llseek ppc64:recv ppc64:send ppc64:getuid ppc64:ugetrlimit + * #syscalls s390x:socketcall s390x:sigreturn + * #syscalls:pasta rt_sigreturn|sigreturn ppc64:sigreturn ppc64:fcntl64 */ int main(int argc, char **argv) { diff --git a/pasta.c b/pasta.c index 3928ad0..bce30d4 100644 --- a/pasta.c +++ b/pasta.c @@ -12,7 +12,8 @@ * Author: Stefano Brivio <sbrivio(a)redhat.com> * * #syscalls:pasta clone unshare waitid kill execve exit_group rt_sigprocmask - * #syscalls:pasta geteuid getdents64 readlink setsid nanosleep clock_nanosleep + * #syscalls:pasta geteuid getdents64|getdents readlink|readlinkat setsid + * #syscalls:pasta nanosleep clock_nanosleep */ #include <sched.h> diff --git a/tap.c b/tap.c index d2f234d..2bf6f71 100644 --- a/tap.c +++ b/tap.c @@ -772,7 +772,7 @@ restart: * tap_sock_init_unix() - Create and bind AF_UNIX socket, wait for connection * @c: Execution context * - * #syscalls:passt unlink + * #syscalls:passt unlink|unlinkat */ static void tap_sock_init_unix(struct ctx *c) { diff --git a/tcp.c b/tcp.c index 36c2bb5..01f09e9 100644 --- a/tcp.c +++ b/tcp.c @@ -304,7 +304,7 @@ * - SPLICE_FIN_TO: FIN (EPOLLRDHUP) seen from connected socket * - SPLICE_FIN_BOTH: FIN (EPOLLRDHUP) seen from both sides * - * #syscalls pipe pipe2 + * #syscalls pipe|pipe2 pipe2 */ #include <sched.h> -- 2.33.0
Debug information might be printed after a prompt is seen, just wait those 3 seconds and be done with it. Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- test/demo/pasta | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/demo/pasta b/test/demo/pasta index ffdd961..f8f0cd0 100644 --- a/test/demo/pasta +++ b/test/demo/pasta @@ -49,7 +49,7 @@ nl say without PID, it will create a namespace. sleep 3 passt cd __TEMPDIR__/passt -passt ./pasta +passtb ./pasta sleep 3 nl -- 2.33.0
Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- test/two_guests/basic | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/two_guests/basic b/test/two_guests/basic index d23b6e9..24352c0 100644 --- a/test/two_guests/basic +++ b/test/two_guests/basic @@ -47,7 +47,7 @@ g1out GW1 ip -j -4 ro sh|jq -rM '.[] | select(.dst == "default").gateway' guest2b nc -4 -l 10004 > msg guest1 echo "Hello_from_guest_1" | nc -N __GW1__ 10004 guest2w -sleep 1 +sleep 1 g2out MSG2 cat msg check [ "__MSG2__" = "Hello_from_guest_1" ] @@ -56,7 +56,7 @@ g2out GW2_6 ip -j -6 ro sh|jq -rM '.[] | select(.dst == "default").gateway' guest1b nc -6 -l 10001 > msg guest2 echo "Hello_from_guest_2" | nc -N __GW2_6__%__IFNAME2__ 10001 guest1w -sleep 1 +sleep 1 g1out MSG1 cat msg check [ "__MSG1__" = "Hello_from_guest_2" ] @@ -64,7 +64,7 @@ test UDP/IPv4: guest 1 > guest 2 guest2b nc -u -W1 -4 -l 10004 > msg guest1 echo "Hello_from_guest_1" | nc -u -q1 __GW1__ 10004 guest2w -sleep 1 +sleep 1 g2out MSG2 cat msg check [ "__MSG2__" = "Hello_from_guest_1" ] @@ -72,6 +72,6 @@ test UDP/IPv6: guest 2 > guest 1 guest1b nc -u -W1 -6 -l 10001 > msg guest2 echo "Hello_from_guest_2" | nc -u -q1 -N __GW2_6__%__IFNAME2__ 10001 guest1w -sleep 1 +sleep 1 g1out MSG1 cat msg check [ "__MSG1__" = "Hello_from_guest_2" ] -- 2.33.0
The throughput results in this test look quite variable, slightly lower figures look reasonable anyway. Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- test/perf/passt_udp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/perf/passt_udp b/test/perf/passt_udp index a5d43fc..349f429 100644 --- a/test/perf/passt_udp +++ b/test/perf/passt_udp @@ -124,11 +124,11 @@ bw __BW__ 1.0 1.5 ns ip link set dev lo mtu 9000 iperf3c ns ::1 100${i}1 __THREADS__ __OPTS__ -b 3G iperf3s BW guest 100${i}1 __THREADS__ -bw __BW__ 4.0 5.0 +bw __BW__ 3.0 4.0 ns ip link set dev lo mtu 65520 iperf3c ns ::1 100${i}1 __THREADS__ __OPTS__ -b 3G iperf3s BW guest 100${i}1 __THREADS__ -bw __BW__ 5.0 5.5 +bw __BW__ 3.0 4.0 tl UDP RR latency over IPv6: host to guest lat - @@ -163,11 +163,11 @@ bw __BW__ 1.0 1.5 ns ip link set dev lo mtu 9000 iperf3c ns 127.0.0.1 100${i}1 __THREADS__ __OPTS__ -b 3G iperf3s BW guest 100${i}1 __THREADS__ -bw __BW__ 4.0 5.0 +bw __BW__ 3.0 4.0 ns ip link set dev lo mtu 65520 iperf3c ns 127.0.0.1 100${i}1 __THREADS__ __OPTS__ -b 3G iperf3s BW guest 100${i}1 __THREADS__ -bw __BW__ 5.0 5.5 +bw __BW__ 3.0 4.0 tl UDP RR latency over IPv4: host to guest lat - -- 2.33.0
...this gets needlessly annoying while playing with test cases. Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- test/lib/setup | 64 +++++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/test/lib/setup b/test/lib/setup index 124e35b..ab51787 100755 --- a/test/lib/setup +++ b/test/lib/setup @@ -52,14 +52,14 @@ setup_passt() { pane_run PASST "./passt ${__opts} -f -t 10001 -u 10001" sleep 1 - pane_run GUEST './qrap 5 kvm -m '${VMEM}' -cpu host -smp '${VCPUS} \ - '-kernel' "/boot/vmlinuz-$(uname -r)" \ - '-initrd mbuto.img -nographic -serial stdio' \ - '-nodefaults ' \ - '-append "console=ttyS0 mitigations=off apparmor=0 ' \ - 'virtio-net.napi_tx=1"' \ - "-device virtio-net-pci,netdev=hostnet0,x-txburst=16384"\ - "-netdev socket,fd=5,id=hostnet0" + pane_run GUEST './qrap 5 kvm -m '${VMEM}' -cpu host -smp '${VCPUS} \ + ' -kernel ' "/boot/vmlinuz-$(uname -r)" \ + ' -initrd mbuto.img -nographic -serial stdio' \ + ' -nodefaults' \ + ' -append "console=ttyS0 mitigations=off apparmor=0 ' \ + 'virtio-net.napi_tx=1"' \ + " -device virtio-net-pci,netdev=hostnet0,x-txburst=16384" \ + " -netdev socket,fd=5,id=hostnet0" pane_wait GUEST } @@ -145,14 +145,14 @@ setup_passt_in_ns() { pane_run PASST "./passt -f ${__opts} -t 10001,10011,10021,10031 -u 10001,10011,10021,10031" sleep 1 - pane_run GUEST './qrap 5 kvm -m '${VMEM}' -cpu host -smp '${VCPUS} \ - '-kernel' "/boot/vmlinuz-$(uname -r)" \ - '-initrd mbuto.img -nographic -serial stdio' \ - '-nodefaults ' \ - '-append "console=ttyS0 mitigations=off apparmor=0 ' \ - 'virtio-net.napi_tx=1"' \ - "-device virtio-net-pci,netdev=hostnet0,x-txburst=262144"\ - "-netdev socket,fd=5,id=hostnet0" + pane_run GUEST './qrap 5 kvm -m '${VMEM}' -cpu host -smp '${VCPUS} \ + ' -kernel ' "/boot/vmlinuz-$(uname -r)" \ + ' -initrd mbuto.img -nographic -serial stdio' \ + ' -nodefaults' \ + ' -append "console=ttyS0 mitigations=off apparmor=0 ' \ + 'virtio-net.napi_tx=1"' \ + " -device virtio-net-pci,netdev=hostnet0,x-txburst=524288" \ + " -netdev socket,fd=5,id=hostnet0" pane_wait GUEST } @@ -226,22 +226,22 @@ setup_two_guests() { pane_run GUEST_2 'cp mbuto.img mbuto_2.img' pane_wait GUEST_2 - pane_run GUEST_1 './qrap 5 kvm -m '${VMEM}' -cpu host -smp '${VCPUS} \ - '-kernel' "/boot/vmlinuz-$(uname -r)" \ - '-initrd mbuto.img -nographic -serial stdio' \ - '-nodefaults ' \ - '-append "console=ttyS0 mitigations=off apparmor=0 ' \ - 'virtio-net.napi_tx=1"' \ - "-device virtio-net-pci,netdev=hostnet0,x-txburst=16384"\ - "-netdev socket,fd=5,id=hostnet0" - pane_run GUEST_2 './qrap 5 kvm -m '${VMEM}' -cpu host -smp '${VCPUS} \ - '-kernel' "/boot/vmlinuz-$(uname -r)" \ - '-initrd mbuto_2.img -nographic -serial stdio' \ - '-nodefaults ' \ - '-append "console=ttyS0 mitigations=off apparmor=0 ' \ - 'virtio-net.napi_tx=1"' \ - "-device virtio-net-pci,netdev=hostnet0,x-txburst=16384"\ - "-netdev socket,fd=5,id=hostnet0" + pane_run GUEST_1 './qrap 5 kvm -m '${VMEM}' -cpu host -smp '${VCPUS} \ + ' -kernel ' "/boot/vmlinuz-$(uname -r)" \ + ' -initrd mbuto.img -nographic -serial stdio' \ + ' -nodefaults' \ + ' -append "console=ttyS0 mitigations=off apparmor=0 ' \ + 'virtio-net.napi_tx=1"' \ + " -device virtio-net-pci,netdev=hostnet0,x-txburst=16384" \ + " -netdev socket,fd=5,id=hostnet0" + pane_run GUEST_2 './qrap 5 kvm -m '${VMEM}' -cpu host -smp '${VCPUS} \ + ' -kernel ' "/boot/vmlinuz-$(uname -r)" \ + ' -initrd mbuto_2.img -nographic -serial stdio' \ + ' -nodefaults' \ + ' -append "console=ttyS0 mitigations=off apparmor=0 ' \ + 'virtio-net.napi_tx=1"' \ + " -device virtio-net-pci,netdev=hostnet0,x-txburst=16384" \ + " -netdev socket,fd=5,id=hostnet0" pane_wait GUEST_1 pane_wait GUEST_2 } -- 2.33.0
It's not really needed on a reasonably powered CPU, and makes the video contents way less readable. Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- test/lib/video | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lib/video b/test/lib/video index d4c0680..6db9c1d 100755 --- a/test/lib/video +++ b/test/lib/video @@ -89,7 +89,7 @@ video_grab() { sleep 3 VIDEO_START_SECONDS=$(sed -n 's/\([0-9]*\).[0-9]* [0-9]*.[0-9]*/\1/p' /proc/uptime) [ ${XVFB} -eq 1 ] && __disp=":99.0" || __disp= - ffmpeg -f x11grab -framerate 15 -video_size "${__width}x${__height}" -i "${__disp}+${__x},${__y}" -vcodec libx264 -preset ultrafast -qp 0 -pix_fmt yuv444p -draw_mouse 0 "${BASEPATH}/${VIDEO_NAME}.mp4" & echo $! > "${FFMPEG_PID_FILE}" + ffmpeg -f x11grab -framerate 15 -video_size "${__width}x${__height}" -i "${__disp}+${__x},${__y}" -vcodec libx264 -qp 0 -draw_mouse 0 "${BASEPATH}/${VIDEO_NAME}.mp4" & echo $! > "${FFMPEG_PID_FILE}" } # video_time_now() - Print current video timestamp, in seconds -- 2.33.0
Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- hooks/pre-push | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/hooks/pre-push b/hooks/pre-push index fb86c0b..a5e4790 100755 --- a/hooks/pre-push +++ b/hooks/pre-push @@ -21,15 +21,15 @@ BASE="/var/www/passt" BUILDS="${BASE}/builds" LATEST="${BUILDS}/latest" TEMP="${BUILDS}/temp" +AWAY="${BUILDS}/away" -WEB="${LATEST}/web" -TEST="${LATEST}/test" +WEB="${TEMP}/web" +TEST="${TEMP}/test" ARCH="$(uname -m)" -BIN="${LATEST}/${ARCH}" +BIN="${TEMP}/${ARCH}" ssh "${USER_HOST}" "mkdir -p ${WEB} ${TEST} ${BIN}" -ssh "${USER_HOST}" "cp -a ${LATEST} ${TEMP}" cd test @@ -50,7 +50,7 @@ ssh "${USER_HOST}" "rm -f ${BIN}/*.deb" ssh "${USER_HOST}" "rm -f ${BIN}/*.rpm" scp *.deb *.rpm "${USER_HOST}:${BIN}/" -CFLAGS="-static" make avx2 +CFLAGS="-static -DGLIBC_NO_STATIC_NSS" make avx2 ssh "${USER_HOST}" "mkdir -p ${BIN}/avx2" scp passt pasta qrap passt.1 pasta.1 qrap.1 "${USER_HOST}:${BIN}/avx2/" @@ -59,6 +59,10 @@ ssh "${USER_HOST}" "rm -f ${BIN}/avx2/*.deb" ssh "${USER_HOST}" "rm -f ${BIN}/avx2/*.rpm" scp *.deb *.rpm "${USER_HOST}:${BIN}/avx2/" +ssh "${USER_HOST}" "mv ${LATEST} ${AWAY}" +ssh "${USER_HOST}" "mv ${TEMP} ${LATEST}" +ssh "${USER_HOST}" "rm -rf ${AWAY}" + # Legacy, for KubeVirt tests -CFLAGS="-DPASST_LEGACY_NO_OPTIONS -static" make avx2 -scp passt qrap "${USER_HOST}:${BUILDS}/static/" +# CFLAGS="-DPASST_LEGACY_NO_OPTIONS -static" make avx2 +# scp passt qrap "${USER_HOST}:${BUILDS}/static/" -- 2.33.0
I forgot --stderr could also be -e, fix handling. Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- conf.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/conf.c b/conf.c index 7859f25..9a9dade 100644 --- a/conf.c +++ b/conf.c @@ -766,7 +766,7 @@ void conf(struct ctx *c, int argc, char **argv) {"debug", no_argument, NULL, 'd' }, {"quiet", no_argument, NULL, 'q' }, {"foreground", no_argument, NULL, 'f' }, - {"stderr", no_argument, &c->stderr, 1 }, + {"stderr", no_argument, NULL, 'e' }, {"help", no_argument, NULL, 'h' }, {"socket", required_argument, NULL, 's' }, {"ns-ifname", required_argument, NULL, 'I' }, @@ -889,6 +889,14 @@ void conf(struct ctx *c, int argc, char **argv) c->debug = 1; c->foreground = 1; break; + case 'e': + if (c->stderr) { + err("Multiple --stderr options given"); + usage(argv[0]); + } + + c->stderr = 1; + break; case 'q': if (c->quiet) { err("Multiple --quiet options given"); -- 2.33.0
It shouldn't refer to the subsection under "Features". Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ee689f5..835a2fb 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ for TCP and UDP, respectively. - [Ports](#ports) - [Demo](#demo) - [Continuous Integration](#continuous-integration) -- [Performance](#performance) +- [Performance](#performance_1) - [Try it](#try-it) - [Contribute](#contribute) - [Security and Vulnerability Reports](#security-and-vulnerability-reports) -- 2.33.0
Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 835a2fb..7f3cd58 100644 --- a/README.md +++ b/README.md @@ -211,7 +211,7 @@ speeding up local connections, and usually requiring NAT. _pasta_: * ❌ Selective Acknowledgment (RFC 2018) * ✅ [UDP](/passt/tree/udp.c) * ✅ ICMP/ICMPv6 Echo -* ⌚ [IGMP/MLD](https://bugs.passt.top/show_bug.cgi?id=1) proxy +* ⌚ [IGMP/MLD](https://bugs.passt.top/show_bug.cgi?id=2) proxy * ⌚ [SCTP](https://bugs.passt.top/show_bug.cgi?id=3) ### Portability -- 2.33.0