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 6FF705A026A for ; Fri, 4 Nov 2022 09:43:47 +0100 (CET) Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4N3Z0W2hxlz4xwy; Fri, 4 Nov 2022 19:43:39 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=201602; t=1667551419; bh=4p6ATvgCa8cxtao3oFn2k4OkQ+7gAH8N00wmRme2oQk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fh27NlGFf7T6MgK94tQyG/pMnA9DNAyuP95fn9jgbqFodEKouBUjmayqrg5fIXHEB r/K0vimZD2SV8H0MCMOAKSUayc4Fywdd8L7YbztLT560+Mrwhtz2U7+6Lbwemk7QhR SX7pbhxQz1+LYUhfZZJQEAr/+zjFPRD6fyMAO1Lo= From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH 06/10] tcp: Unify IPv4 and IPv6 paths for hashing and matching Date: Fri, 4 Nov 2022 19:43:29 +1100 Message-Id: <20221104084333.3761760-7-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221104084333.3761760-1-david@gibson.dropbear.id.au> References: <20221104084333.3761760-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: U3NPYTCNRTHUBQKXXSQQWA5EQ76TCHSH X-Message-ID-Hash: U3NPYTCNRTHUBQKXXSQQWA5EQ76TCHSH 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: IPv4 are now hashed to match equivalent IPv4-mapped IPv6 addresses. This means we can avoid having IPv4 specific paths in the lower level hash and match functions, instead just dealing with the equivalent IPv4-mapped IPv6 addresses. Signed-off-by: David Gibson --- tcp.c | 44 +++++++++++++++++--------------------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/tcp.c b/tcp.c index dfa73a3..3816a1c 100644 --- a/tcp.c +++ b/tcp.c @@ -1275,23 +1275,16 @@ static int tcp_opt_get(const char *opts, size_t len, uint8_t type_find, /** * tcp_hash_match() - Check if a connection entry matches address and ports * @conn: Connection entry to match against - * @af: Address family, AF_INET or AF_INET6 - * @addr: Remote address, pointer to in_addr or in6_addr + * @addr: Remote address, may be IPv4-mapped * @tap_port: tap-facing port * @sock_port: Socket-facing port * * Return: 1 on match, 0 otherwise */ -static int tcp_hash_match(const struct tcp_conn *conn, int af, const void *addr, +static int tcp_hash_match(const struct tcp_conn *conn, + const struct in6_addr *addr, in_port_t tap_port, in_port_t sock_port) { - struct in6_addr v4mapped; - - if (af == AF_INET) { - encode_ip4mapped_ip6(&v4mapped, addr); - addr = &v4mapped; - } - if (IN6_ARE_ADDR_EQUAL(&conn->a.a6, addr) && conn->tap_port == tap_port && conn->sock_port == sock_port) return 1; @@ -1302,8 +1295,7 @@ static int tcp_hash_match(const struct tcp_conn *conn, int af, const void *addr, /** * tcp_hash() - Calculate hash value for connection given address and ports * @c: Execution context - * @af: Address family, AF_INET or AF_INET6 - * @addr: Remote address, pointer to in_addr or in6_addr + * @addr: Remote address, may be IPv4-mapped * @tap_port: tap-facing port * @sock_port: Socket-facing port * @@ -1312,7 +1304,7 @@ static int tcp_hash_match(const struct tcp_conn *conn, int af, const void *addr, #if TCP_HASH_NOINLINE __attribute__((__noinline__)) /* See comment in Makefile */ #endif -static unsigned int tcp_hash(const struct ctx *c, int af, const void *addr, +static unsigned int tcp_hash(const struct ctx *c, const struct in6_addr *addr, in_port_t tap_port, in_port_t sock_port) { struct { @@ -1320,20 +1312,10 @@ static unsigned int tcp_hash(const struct ctx *c, int af, const void *addr, in_port_t tap_port; in_port_t sock_port; } __attribute__((__packed__)) in = { - .tap_port = tap_port, - .sock_port = sock_port, + *addr, tap_port, sock_port, }; uint64_t b = 0; - if (af == AF_INET) { - struct in6_addr v4mapped; - - encode_ip4mapped_ip6(&v4mapped, addr); - in.addr = v4mapped; - } else { - in.addr = *(struct in6_addr *)addr; - } - b = siphash_20b((uint8_t *)&in, c->tcp.hash_secret); return (unsigned int)(b % TCP_HASH_TABLE_SIZE); @@ -1348,7 +1330,7 @@ static void tcp_hash_insert(const struct ctx *c, struct tcp_conn *conn) { int b; - b = tcp_hash(c, AF_INET6, &conn->a.a6, conn->tap_port, conn->sock_port); + b = tcp_hash(c, &conn->a.a6, conn->tap_port, conn->sock_port); conn->next_index = tc_hash[b] ? tc_hash[b] - tc : -1; tc_hash[b] = conn; conn->hash_bucket = b; @@ -1422,11 +1404,19 @@ static struct tcp_conn *tcp_hash_lookup(const struct ctx *c, int af, const void *addr, in_port_t tap_port, in_port_t sock_port) { - int b = tcp_hash(c, af, addr, tap_port, sock_port); + struct in6_addr v4mapped; struct tcp_conn *conn; + int b; + + if (af == AF_INET) { + encode_ip4mapped_ip6(&v4mapped, addr); + addr = &v4mapped; + } + + b = tcp_hash(c, addr, tap_port, sock_port); for (conn = tc_hash[b]; conn; conn = CONN_OR_NULL(conn->next_index)) { - if (tcp_hash_match(conn, af, addr, tap_port, sock_port)) + if (tcp_hash_match(conn, addr, tap_port, sock_port)) return conn; } -- 2.38.1