Skip to content

Commit c113187

Browse files
Boris Pismennydavem330
Boris Pismenny
authored andcommitted
tls: Use correct sk->sk_prot for IPV6
The tls ulp overrides sk->prot with a new tls specific proto structs. The tls specific structs were previously based on the ipv4 specific tcp_prot sturct. As a result, attaching the tls ulp to an ipv6 tcp socket replaced some ipv6 callback with the ipv4 equivalents. This patch adds ipv6 tls proto structs and uses them when attached to ipv6 sockets. Fixes: 3c4d755 ('tls: kernel TLS support') Signed-off-by: Boris Pismenny <borisp@mellanox.com> Signed-off-by: Ilya Lesokhin <ilyal@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 55ea874 commit c113187

File tree

1 file changed

+37
-15
lines changed

1 file changed

+37
-15
lines changed

net/tls/tls_main.c

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,27 @@ MODULE_AUTHOR("Mellanox Technologies");
4545
MODULE_DESCRIPTION("Transport Layer Security Support");
4646
MODULE_LICENSE("Dual BSD/GPL");
4747

48+
enum {
49+
TLSV4,
50+
TLSV6,
51+
TLS_NUM_PROTS,
52+
};
53+
4854
enum {
4955
TLS_BASE_TX,
5056
TLS_SW_TX,
5157
TLS_NUM_CONFIG,
5258
};
5359

54-
static struct proto tls_prots[TLS_NUM_CONFIG];
60+
static struct proto *saved_tcpv6_prot;
61+
static DEFINE_MUTEX(tcpv6_prot_mutex);
62+
static struct proto tls_prots[TLS_NUM_PROTS][TLS_NUM_CONFIG];
5563

5664
static inline void update_sk_prot(struct sock *sk, struct tls_context *ctx)
5765
{
58-
sk->sk_prot = &tls_prots[ctx->tx_conf];
66+
int ip_ver = sk->sk_family == AF_INET6 ? TLSV6 : TLSV4;
67+
68+
sk->sk_prot = &tls_prots[ip_ver][ctx->tx_conf];
5969
}
6070

6171
int wait_on_pending_writer(struct sock *sk, long *timeo)
@@ -453,8 +463,21 @@ static int tls_setsockopt(struct sock *sk, int level, int optname,
453463
return do_tls_setsockopt(sk, optname, optval, optlen);
454464
}
455465

466+
static void build_protos(struct proto *prot, struct proto *base)
467+
{
468+
prot[TLS_BASE_TX] = *base;
469+
prot[TLS_BASE_TX].setsockopt = tls_setsockopt;
470+
prot[TLS_BASE_TX].getsockopt = tls_getsockopt;
471+
prot[TLS_BASE_TX].close = tls_sk_proto_close;
472+
473+
prot[TLS_SW_TX] = prot[TLS_BASE_TX];
474+
prot[TLS_SW_TX].sendmsg = tls_sw_sendmsg;
475+
prot[TLS_SW_TX].sendpage = tls_sw_sendpage;
476+
}
477+
456478
static int tls_init(struct sock *sk)
457479
{
480+
int ip_ver = sk->sk_family == AF_INET6 ? TLSV6 : TLSV4;
458481
struct inet_connection_sock *icsk = inet_csk(sk);
459482
struct tls_context *ctx;
460483
int rc = 0;
@@ -479,6 +502,17 @@ static int tls_init(struct sock *sk)
479502
ctx->getsockopt = sk->sk_prot->getsockopt;
480503
ctx->sk_proto_close = sk->sk_prot->close;
481504

505+
/* Build IPv6 TLS whenever the address of tcpv6_prot changes */
506+
if (ip_ver == TLSV6 &&
507+
unlikely(sk->sk_prot != smp_load_acquire(&saved_tcpv6_prot))) {
508+
mutex_lock(&tcpv6_prot_mutex);
509+
if (likely(sk->sk_prot != saved_tcpv6_prot)) {
510+
build_protos(tls_prots[TLSV6], sk->sk_prot);
511+
smp_store_release(&saved_tcpv6_prot, sk->sk_prot);
512+
}
513+
mutex_unlock(&tcpv6_prot_mutex);
514+
}
515+
482516
ctx->tx_conf = TLS_BASE_TX;
483517
update_sk_prot(sk, ctx);
484518
out:
@@ -493,21 +527,9 @@ static struct tcp_ulp_ops tcp_tls_ulp_ops __read_mostly = {
493527
.init = tls_init,
494528
};
495529

496-
static void build_protos(struct proto *prot, struct proto *base)
497-
{
498-
prot[TLS_BASE_TX] = *base;
499-
prot[TLS_BASE_TX].setsockopt = tls_setsockopt;
500-
prot[TLS_BASE_TX].getsockopt = tls_getsockopt;
501-
prot[TLS_BASE_TX].close = tls_sk_proto_close;
502-
503-
prot[TLS_SW_TX] = prot[TLS_BASE_TX];
504-
prot[TLS_SW_TX].sendmsg = tls_sw_sendmsg;
505-
prot[TLS_SW_TX].sendpage = tls_sw_sendpage;
506-
}
507-
508530
static int __init tls_register(void)
509531
{
510-
build_protos(tls_prots, &tcp_prot);
532+
build_protos(tls_prots[TLSV4], &tcp_prot);
511533

512534
tcp_register_ulp(&tcp_tls_ulp_ops);
513535

0 commit comments

Comments
 (0)