public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: passt-dev@passt.top, Stefano Brivio <sbrivio@redhat.com>
Cc: David Gibson <david@gibson.dropbear.id.au>
Subject: [PATCH 08/10] tcp: Unify initial sequence numbers for IPv4 and IPv6
Date: Fri,  4 Nov 2022 19:43:31 +1100	[thread overview]
Message-ID: <20221104084333.3761760-9-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <20221104084333.3761760-1-david@gibson.dropbear.id.au>

tcp_seq_init() has separate paths for IPv4 and IPv6 addresses.  Convert it
to convert IPv4 addresses to IPv4-mapped IPv6 addresses then compute the
siphash as for IPv6.  This is slightly simpler, and means that "true" IPv4
connections and "IPv6" connections using mapped addresses will have
compatible sequence numbers.  This will allow additional improvements in
future.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 siphash.c |  1 +
 tcp.c     | 46 +++++++++++++++++++---------------------------
 2 files changed, 20 insertions(+), 27 deletions(-)

diff --git a/siphash.c b/siphash.c
index 516a508..811918b 100644
--- a/siphash.c
+++ b/siphash.c
@@ -123,6 +123,7 @@ uint64_t siphash_8b(const uint8_t *in, const uint64_t *k)
  *
  * Return: 32 bits obtained by XORing the two halves of the 64-bit hash output
  */
+/* cppcheck-suppress unusedFunction */
 uint32_t siphash_12b(const uint8_t *in, const uint64_t *k)
 {
 	uint32_t *in32 = (uint32_t *)in;
diff --git a/tcp.c b/tcp.c
index 6634abb..b9d0510 100644
--- a/tcp.c
+++ b/tcp.c
@@ -2011,38 +2011,30 @@ static uint32_t tcp_seq_init(const struct ctx *c, int af, const void *addr,
 			     in_port_t dstport, in_port_t srcport,
 			     const struct timespec *now)
 {
+	struct {
+		struct in6_addr src;
+		in_port_t srcport;
+		struct in6_addr dst;
+		in_port_t dstport;
+	} __attribute__((__packed__)) in = {
+		.srcport = srcport,
+		.dstport = dstport,
+	};
 	uint32_t ns, seq = 0;
 
 	if (af == AF_INET) {
-		struct {
-			struct in_addr src;
-			in_port_t srcport;
-			struct in_addr dst;
-			in_port_t dstport;
-		} __attribute__((__packed__)) in = {
-			.src = *(struct in_addr *)addr,
-			.srcport = srcport,
-			.dst = c->ip4.addr,
-			.dstport = dstport,
-		};
-
-		seq = siphash_12b((uint8_t *)&in, c->tcp.hash_secret);
-	} else if (af == AF_INET6) {
-		struct {
-			struct in6_addr src;
-			in_port_t srcport;
-			struct in6_addr dst;
-			in_port_t dstport;
-		} __attribute__((__packed__)) in = {
-			.src = *(struct in6_addr *)addr,
-			.srcport = srcport,
-			.dst = c->ip6.addr,
-			.dstport = dstport,
-		};
-
-		seq = siphash_36b((uint8_t *)&in, c->tcp.hash_secret);
+		struct in6_addr tmp;
+		encode_ip4mapped_ip6(&tmp, addr);
+		in.src = tmp;
+		encode_ip4mapped_ip6(&tmp, &c->ip4.addr);
+		in.dst = tmp;
+	} else {
+		in.src = *(struct in6_addr *)addr;
+		in.dst = c->ip6.addr;
 	}
 
+	seq = siphash_36b((uint8_t *)&in, c->tcp.hash_secret);
+
 	ns = now->tv_sec * 1E9;
 	ns += now->tv_nsec >> 5; /* 32ns ticks, overflows 32 bits every 137s */
 
-- 
@@ -2011,38 +2011,30 @@ static uint32_t tcp_seq_init(const struct ctx *c, int af, const void *addr,
 			     in_port_t dstport, in_port_t srcport,
 			     const struct timespec *now)
 {
+	struct {
+		struct in6_addr src;
+		in_port_t srcport;
+		struct in6_addr dst;
+		in_port_t dstport;
+	} __attribute__((__packed__)) in = {
+		.srcport = srcport,
+		.dstport = dstport,
+	};
 	uint32_t ns, seq = 0;
 
 	if (af == AF_INET) {
-		struct {
-			struct in_addr src;
-			in_port_t srcport;
-			struct in_addr dst;
-			in_port_t dstport;
-		} __attribute__((__packed__)) in = {
-			.src = *(struct in_addr *)addr,
-			.srcport = srcport,
-			.dst = c->ip4.addr,
-			.dstport = dstport,
-		};
-
-		seq = siphash_12b((uint8_t *)&in, c->tcp.hash_secret);
-	} else if (af == AF_INET6) {
-		struct {
-			struct in6_addr src;
-			in_port_t srcport;
-			struct in6_addr dst;
-			in_port_t dstport;
-		} __attribute__((__packed__)) in = {
-			.src = *(struct in6_addr *)addr,
-			.srcport = srcport,
-			.dst = c->ip6.addr,
-			.dstport = dstport,
-		};
-
-		seq = siphash_36b((uint8_t *)&in, c->tcp.hash_secret);
+		struct in6_addr tmp;
+		encode_ip4mapped_ip6(&tmp, addr);
+		in.src = tmp;
+		encode_ip4mapped_ip6(&tmp, &c->ip4.addr);
+		in.dst = tmp;
+	} else {
+		in.src = *(struct in6_addr *)addr;
+		in.dst = c->ip6.addr;
 	}
 
+	seq = siphash_36b((uint8_t *)&in, c->tcp.hash_secret);
+
 	ns = now->tv_sec * 1E9;
 	ns += now->tv_nsec >> 5; /* 32ns ticks, overflows 32 bits every 137s */
 
-- 
2.38.1


  parent reply	other threads:[~2022-11-04  8:43 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-04  8:43 [PATCH 00/10] RFC: Preliminaries for using share IPv4 & IPv6 sockets David Gibson
2022-11-04  8:43 ` [PATCH 01/10] tcp: no v6 flag in ref David Gibson
2022-11-07 18:07   ` Stefano Brivio
2022-11-08  0:35     ` David Gibson
2022-11-04  8:43 ` [PATCH 02/10] tcp: Helper to encode IPv4-mapped IPv6 addresses David Gibson
2022-11-07 18:08   ` Stefano Brivio
2022-11-08  0:46     ` David Gibson
2022-11-04  8:43 ` [PATCH 03/10] tcp: Partially unify IPv4 and IPv6 paths in tcp_hash_match() David Gibson
2022-11-07 18:08   ` Stefano Brivio
2022-11-08  0:51     ` David Gibson
2022-11-04  8:43 ` [PATCH 04/10] tcp: Hash IPv4 and IPv4-mapped-IPv6 addresses the same David Gibson
2022-11-04  8:43 ` [PATCH 05/10] tcp: Take tcp_hash_insert() address from struct tcp_conn David Gibson
2022-11-04  8:43 ` [PATCH 06/10] tcp: Unify IPv4 and IPv6 paths for hashing and matching David Gibson
2022-11-04  8:43 ` [PATCH 07/10] tcp: Remove ugly address union from struct tcp_conn David Gibson
2022-11-07 18:08   ` Stefano Brivio
2022-11-08  0:54     ` David Gibson
2022-11-04  8:43 ` David Gibson [this message]
2022-11-04  8:43 ` [PATCH 09/10] tcp: Have tcp_seq_init() take its parameters " David Gibson
2022-11-04  8:43 ` [PATCH 10/10] tcp: Fix small error in tcp_seq_init() time handling David Gibson
2022-11-07 18:08   ` Stefano Brivio
2022-11-08  0:59     ` David Gibson
2022-11-04  8:47 ` [PATCH 00/10] RFC: Preliminaries for using share IPv4 & IPv6 sockets Stefano Brivio

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=20221104084333.3761760-9-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).