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=202410 header.b=Avz4qdr4; dkim-atps=neutral Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 5F8A15A061C for ; Thu, 24 Oct 2024 06:59:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202410; t=1729745963; bh=nRA2eEVz7wW0JOT94IGwvl+AP7Hm5IdP/FQsXOg/QzY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Avz4qdr4dLI3C2Gr2/mtoSQBVR8nBJTur8/hBbvKeVJC3r4yMWYyOkCb+KReXUGQX bzx1VZho7XOs9NS80j8Hx5qQx3jDGXHRjYWePt5sTDJ+sWYuCgD+nGAtrDZS1AWqVX TpNAJZdGEJbDDWTxvhHVpVTN6gzXQJhhl8pLtbz30HKijiTRPhQyUDzBvPsGPqvHEO DkOKxnrDG3WgtoeE+4vlqfUg8ukZCMPB7n3q2hjB3X/xMvSQ1jRx9sL9WyxCcJTeLC i0/fIE98MPR8BISrx0Liw8Smtagkdj7p+wxw/467QU+aWBkefjRTwGnOrVBuShhIHn TN8nVOj1NLX4Q== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4XYtxR1mRfz4x11; Thu, 24 Oct 2024 15:59:23 +1100 (AEDT) From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH v2 3/3] tcp: Use runtime tests for TCP_INFO fields Date: Thu, 24 Oct 2024 15:59:22 +1100 Message-ID: <20241024045922.3900584-4-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241024045922.3900584-1-david@gibson.dropbear.id.au> References: <20241024045922.3900584-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: DG66L43GEFB34JVTMPKFGYXZVWRGPZ55 X-Message-ID-Hash: DG66L43GEFB34JVTMPKFGYXZVWRGPZ55 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: In order to use particular fields from the TCP_INFO getsockopt() we need them to be in structure returned by the runtime kernel. We attempt to determine that with the HAS_BYTES_ACKED and HAS_MIN_RTT defines, probed in the Makefile. However, that's not correct, because the kernel headers we compile against may not be the same as the runtime kernel. We instead should check against the size of structure returned from the TCP_INFO getsockopt() as we already do for tcpi_snd_wnd. Switch from the compile time flags to a runtime test. Signed-off-by: David Gibson --- Makefile | 10 ---------- tcp.c | 52 ++++++++++++++++++++++++++-------------------------- 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/Makefile b/Makefile index 6faa501..4c2d020 100644 --- a/Makefile +++ b/Makefile @@ -67,16 +67,6 @@ PASST_HEADERS = arch.h arp.h checksum.h conf.h dhcp.h dhcpv6.h flow.h fwd.h \ udp.h udp_flow.h util.h HEADERS = $(PASST_HEADERS) seccomp.h -C := \#include \nstruct tcp_info x = { .tcpi_bytes_acked = 0 }; -ifeq ($(shell printf "$(C)" | $(CC) -S -xc - -o - >/dev/null 2>&1; echo $$?),0) - FLAGS += -DHAS_BYTES_ACKED -endif - -C := \#include \nstruct tcp_info x = { .tcpi_min_rtt = 0 }; -ifeq ($(shell printf "$(C)" | $(CC) -S -xc - -o - >/dev/null 2>&1; echo $$?),0) - FLAGS += -DHAS_MIN_RTT -endif - C := \#include \nint main(){int a=getrandom(0, 0, 0);} ifeq ($(shell printf "$(C)" | $(CC) -S -xc - -o - >/dev/null 2>&1; echo $$?),0) FLAGS += -DHAS_GETRANDOM diff --git a/tcp.c b/tcp.c index 998e56d..0569dc6 100644 --- a/tcp.c +++ b/tcp.c @@ -370,6 +370,10 @@ socklen_t tcp_info_size; /* Kernel reports sending window in TCP_INFO (kernel commit 8f7baad7f035) */ #define snd_wnd_cap tcp_info_cap(snd_wnd) +/* Kernel reports bytes acked in TCP_INFO (kernel commit 0df48c26d84) */ +#define bytes_acked_cap tcp_info_cap(bytes_acked) +/* Kernel reports minimum RTT in TCP_INFO (kernel commit cd9b266095f4) */ +#define min_rtt_cap tcp_info_cap(min_rtt) /* sendmsg() to socket */ static struct iovec tcp_iov [UIO_MAXIOV]; @@ -677,11 +681,10 @@ static int tcp_rtt_dst_low(const struct tcp_tap_conn *conn) static void tcp_rtt_dst_check(const struct tcp_tap_conn *conn, const struct tcp_info_linux *tinfo) { -#ifdef HAS_MIN_RTT const struct flowside *tapside = TAPFLOW(conn); int i, hole = -1; - if (!tinfo->tcpi_min_rtt || + if (!min_rtt_cap || (int)tinfo->tcpi_min_rtt > LOW_RTT_THRESHOLD) return; @@ -702,10 +705,6 @@ static void tcp_rtt_dst_check(const struct tcp_tap_conn *conn, if (hole == LOW_RTT_TABLE_SIZE) hole = 0; inany_from_af(low_rtt_dst + hole, AF_INET6, &in6addr_any); -#else - (void)conn; - (void)tinfo; -#endif /* HAS_MIN_RTT */ } /** @@ -1121,30 +1120,29 @@ int tcp_update_seqack_wnd(const struct ctx *c, struct tcp_tap_conn *conn, uint32_t new_wnd_to_tap = prev_wnd_to_tap; int s = conn->sock; -#ifndef HAS_BYTES_ACKED - (void)force_seq; - - 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 ((unsigned)SNDBUF_GET(conn) < SNDBUF_SMALL || tcp_rtt_dst_low(conn) - || CONN_IS_CLOSING(conn) || (conn->flags & LOCAL) || force_seq) { + if (!bytes_acked_cap) { conn->seq_ack_to_tap = conn->seq_from_tap; - } else if (conn->seq_ack_to_tap != conn->seq_from_tap) { - if (!tinfo) { - tinfo = &tinfo_new; - if (getsockopt(s, SOL_TCP, TCP_INFO, tinfo, &sl)) - return 0; - } - - conn->seq_ack_to_tap = tinfo->tcpi_bytes_acked + - conn->seq_init_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 ((unsigned)SNDBUF_GET(conn) < SNDBUF_SMALL || + tcp_rtt_dst_low(conn) || CONN_IS_CLOSING(conn) || + (conn->flags & LOCAL) || force_seq) { + conn->seq_ack_to_tap = conn->seq_from_tap; + } else if (conn->seq_ack_to_tap != conn->seq_from_tap) { + if (!tinfo) { + tinfo = &tinfo_new; + if (getsockopt(s, SOL_TCP, TCP_INFO, tinfo, &sl)) + return 0; + } + + conn->seq_ack_to_tap = tinfo->tcpi_bytes_acked + + conn->seq_init_from_tap; + + 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 (!snd_wnd_cap) { tcp_get_sndbuf(conn); @@ -2641,6 +2639,8 @@ int tcp_init(struct ctx *c) #define dbg_tcpi(f_) debug("TCP_INFO tcpi_%s field%s supported", \ STRINGIFY(f_), tcp_info_cap(f_) ? " " : " not ") dbg_tcpi(snd_wnd); + dbg_tcpi(bytes_acked); + dbg_tcpi(min_rtt); #undef dbg_tcpi return 0; -- 2.47.0