From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from gandalf.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id C9F975A028B for ; Thu, 17 Nov 2022 06:59:22 +0100 (CET) Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4NCTkl2H6Lz4xZq; Thu, 17 Nov 2022 16:59:11 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=201602; t=1668664751; bh=C8q0Oy2ZcBrOyczqv60EIN1I+r2r9SUufDTdUFF7olQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=S8PfjwWQe3hZDUF9yEg0Z3uZutmvXzfNdA/X28lSVWnXy8IOSQNU5i+xUXP9sRDOR pq+5uaJpN3WorR6B2E2ZHH0fe9OgPLfajLSuRF7p0KJ0u0+3aWsKLAdlYI7nyeKiFt tYD0QrMwsfsGkWkk6jSlu+zdfQGxTICVqrPSu3xw= From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH v2 08/32] tcp: Add connection union type Date: Thu, 17 Nov 2022 16:58:44 +1100 Message-Id: <20221117055908.2782981-9-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221117055908.2782981-1-david@gibson.dropbear.id.au> References: <20221117055908.2782981-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: 6R7UZL4A6MSXV2VOZY24LKB2YNOXXD3F X-Message-ID-Hash: 6R7UZL4A6MSXV2VOZY24LKB2YNOXXD3F 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.3 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: Currently, the tables for spliced and non-spliced connections are entirely separate, with different types in different arrays. We want to unify them. As a first step, create a union type which can represent either a spliced or non-spliced connection. For them to be distinguishable, the individual types need to have a common header added, with a bit indicating which type this structure is. This comes at the cost of increasing the size of tcp_tap_conn to over one (64 byte) cacheline. This isn't ideal, but it makes things simpler for now and we'll re-optimize this later. Signed-off-by: David Gibson --- tcp.c | 4 ++++ tcp_conn.h | 30 ++++++++++++++++++++++++++++++ tcp_splice.c | 2 ++ 3 files changed, 36 insertions(+) diff --git a/tcp.c b/tcp.c index 189041c..05eed85 100644 --- a/tcp.c +++ b/tcp.c @@ -288,6 +288,7 @@ #include #include #include +#include #include /* For struct tcp_info */ @@ -601,6 +602,7 @@ static inline struct tcp_tap_conn *conn_at_idx(int index) { if ((index < 0) || (index >= TCP_MAX_CONNS)) return NULL; + assert(!(CONN(index)->c.spliced)); return CONN(index); } @@ -2096,6 +2098,7 @@ static void tcp_conn_from_tap(struct ctx *c, int af, const void *addr, } conn = CONN(c->tcp.conn_count++); + conn->c.spliced = false; conn->sock = s; conn->timer = -1; conn_event(c, conn, TAP_SYN_RCVD); @@ -2764,6 +2767,7 @@ static void tcp_conn_from_sock(struct ctx *c, union epoll_ref ref, return; conn = CONN(c->tcp.conn_count++); + conn->c.spliced = false; conn->sock = s; conn->timer = -1; conn->ws_to_tap = conn->ws_from_tap = 0; diff --git a/tcp_conn.h b/tcp_conn.h index db4c2d9..39d104a 100644 --- a/tcp_conn.h +++ b/tcp_conn.h @@ -11,8 +11,19 @@ #define TCP_HASH_BUCKET_BITS (TCP_CONN_INDEX_BITS + 1) +/** + * struct tcp_conn_common - Common fields for spliced and non-spliced + * @spliced: Is this a spliced connection? + */ +struct tcp_conn_common { + bool spliced :1; +}; + +extern const char *tcp_common_flag_str[]; + /** * struct tcp_tap_conn - Descriptor for a TCP connection (not spliced) + * @c: Fields common with tcp_splice_conn * @next_index: Connection index of next item in hash chain, -1 for none * @tap_mss: MSS advertised by tap/guest, rounded to 2 ^ TCP_MSS_BITS * @sock: Socket descriptor number @@ -40,6 +51,9 @@ * @seq_init_from_tap: Initial sequence number from tap */ struct tcp_tap_conn { + /* Must be first element to match tcp_splice_conn */ + struct tcp_conn_common c; + int next_index :TCP_CONN_INDEX_BITS + 2; #define TCP_RETRANS_BITS 3 @@ -122,6 +136,7 @@ struct tcp_tap_conn { /** * struct tcp_splice_conn - Descriptor for a spliced TCP connection + * @c: Fields common with tcp_tap_conn * @a: File descriptor number of socket for accepted connection * @pipe_a_b: Pipe ends for splice() from @a to @b * @b: File descriptor number of peer connected socket @@ -134,6 +149,9 @@ struct tcp_tap_conn { * @b_written: Bytes written to @b (not fully written from one @a read) */ struct tcp_splice_conn { + /* Must be first element to match tcp_tap_conn */ + struct tcp_conn_common c; + int a; int pipe_a_b[2]; int b; @@ -165,4 +183,16 @@ struct tcp_splice_conn { uint32_t b_written; }; +/** + * union tcp_conn - Descriptor for a TCP connection (spliced or non-spliced) + * @c: Fields common between all variants + * @tap: Fields specific to non-spliced connections + * @splice: Fields specific to spliced connections +*/ +union tcp_conn { + struct tcp_conn_common c; + struct tcp_tap_conn tap; + struct tcp_splice_conn splice; +}; + #endif /* TCP_CONN_H */ diff --git a/tcp_splice.c b/tcp_splice.c index cbfab01..d8be91b 100644 --- a/tcp_splice.c +++ b/tcp_splice.c @@ -46,6 +46,7 @@ #include #include #include +#include #include "util.h" #include "passt.h" @@ -554,6 +555,7 @@ void tcp_sock_handler_splice(struct ctx *c, union epoll_ref ref, } conn = CONN(c->tcp.splice_conn_count++); + conn->c.spliced = true; conn->a = s; conn->flags = ref.r.p.tcp.tcp.v6 ? SPLICE_V6 : 0; -- 2.38.1