[2/5] net/tcp: Use tcp_v6_md5_hash_skb() instead of .calc_md5_hash()

Message ID 20230509221608.2569333-3-dima@arista.com
State New
Headers
Series net/tcp-md5: Verify segments on TIME_WAIT sockets |

Commit Message

Dmitry Safonov May 9, 2023, 10:16 p.m. UTC
  Using af-specific callback requires the socket to be full (struct tcp_sock).
Using tcp_v6_md5_hash_skb() instead, depending on passed family
parameter makes it possible to use it for non-full sockets as well (if
key-lookup succeeds). Next commit uses tcp_inbound_md5_hash() to verify
segments on twsk.
This seems quite safe to do, as pre-commit 7bbb765b7349 ("net/tcp: Merge
TCP-MD5 inbound callbacks") ip-version-specific functions
tcp_v{4,6}_inbound_md5_hash were calling
tcp_v4_md5_hash_skb()/tcp_v6_md5_hash_skb().

Signed-off-by: Dmitry Safonov <dima@arista.com>
---
 include/net/tcp.h   | 11 +++++++++++
 net/ipv4/tcp.c      |  9 +++------
 net/ipv6/tcp_ipv6.c |  6 ++----
 3 files changed, 16 insertions(+), 10 deletions(-)
  

Patch

diff --git a/include/net/tcp.h b/include/net/tcp.h
index 04a31643cda3..e127fc685ca6 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1676,6 +1676,17 @@  struct tcp_md5sig_pool {
 /* - functions */
 int tcp_v4_md5_hash_skb(char *md5_hash, const struct tcp_md5sig_key *key,
 			const struct sock *sk, const struct sk_buff *skb);
+#if IS_ENABLED(CONFIG_IPV6)
+int tcp_v6_md5_hash_skb(char *md5_hash, const struct tcp_md5sig_key *key,
+			const struct sock *sk, const struct sk_buff *skb);
+#else
+static inline int tcp_v6_md5_hash_skb(char *md5_hash,
+			const struct tcp_md5sig_key *key,
+			const struct sock *sk, const struct sk_buff *skb)
+{
+	return -EPROTONOSUPPORT;
+}
+#endif
 int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr,
 		   int family, u8 prefixlen, int l3index, u8 flags,
 		   const u8 *newkey, u8 newkeylen);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 20db115c38c4..c1897a039ff5 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -4570,7 +4570,6 @@  tcp_inbound_md5_hash(const struct sock *sk, const struct sk_buff *skb,
 	const __u8 *hash_location = NULL;
 	struct tcp_md5sig_key *hash_expected;
 	const struct tcphdr *th = tcp_hdr(skb);
-	const struct tcp_sock *tp = tcp_sk(sk);
 	int genhash, l3index;
 	u8 newhash[16];
 
@@ -4601,13 +4600,11 @@  tcp_inbound_md5_hash(const struct sock *sk, const struct sk_buff *skb,
 	 * IPv4-mapped case.
 	 */
 	if (family == AF_INET)
-		genhash = tcp_v4_md5_hash_skb(newhash,
-					      hash_expected,
+		genhash = tcp_v4_md5_hash_skb(newhash, hash_expected,
 					      NULL, skb);
 	else
-		genhash = tp->af_specific->calc_md5_hash(newhash,
-							 hash_expected,
-							 NULL, skb);
+		genhash = tcp_v6_md5_hash_skb(newhash, hash_expected,
+					      NULL, skb);
 
 	if (genhash || memcmp(hash_location, newhash, 16) != 0) {
 		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5FAILURE);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 42792bc5b9bf..574398a89970 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -732,10 +732,8 @@  static int tcp_v6_md5_hash_hdr(char *md5_hash, const struct tcp_md5sig_key *key,
 	return 1;
 }
 
-static int tcp_v6_md5_hash_skb(char *md5_hash,
-			       const struct tcp_md5sig_key *key,
-			       const struct sock *sk,
-			       const struct sk_buff *skb)
+int tcp_v6_md5_hash_skb(char *md5_hash, const struct tcp_md5sig_key *key,
+			const struct sock *sk, const struct sk_buff *skb)
 {
 	const struct in6_addr *saddr, *daddr;
 	struct tcp_md5sig_pool *hp;