diff options
Diffstat (limited to 'net/tls/tls_main.c')
-rw-r--r-- | net/tls/tls_main.c | 52 |
1 files changed, 37 insertions, 15 deletions
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index e9b4b53ab53e..d824d548447e 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c | |||
@@ -46,16 +46,26 @@ MODULE_DESCRIPTION("Transport Layer Security Support"); | |||
46 | MODULE_LICENSE("Dual BSD/GPL"); | 46 | MODULE_LICENSE("Dual BSD/GPL"); |
47 | 47 | ||
48 | enum { | 48 | enum { |
49 | TLSV4, | ||
50 | TLSV6, | ||
51 | TLS_NUM_PROTS, | ||
52 | }; | ||
53 | |||
54 | enum { | ||
49 | TLS_BASE_TX, | 55 | TLS_BASE_TX, |
50 | TLS_SW_TX, | 56 | TLS_SW_TX, |
51 | TLS_NUM_CONFIG, | 57 | TLS_NUM_CONFIG, |
52 | }; | 58 | }; |
53 | 59 | ||
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]; | ||
55 | 63 | ||
56 | static inline void update_sk_prot(struct sock *sk, struct tls_context *ctx) | 64 | static inline void update_sk_prot(struct sock *sk, struct tls_context *ctx) |
57 | { | 65 | { |
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]; | ||
59 | } | 69 | } |
60 | 70 | ||
61 | int wait_on_pending_writer(struct sock *sk, long *timeo) | 71 | 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, | |||
453 | return do_tls_setsockopt(sk, optname, optval, optlen); | 463 | return do_tls_setsockopt(sk, optname, optval, optlen); |
454 | } | 464 | } |
455 | 465 | ||
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 | |||
456 | static int tls_init(struct sock *sk) | 478 | static int tls_init(struct sock *sk) |
457 | { | 479 | { |
480 | int ip_ver = sk->sk_family == AF_INET6 ? TLSV6 : TLSV4; | ||
458 | struct inet_connection_sock *icsk = inet_csk(sk); | 481 | struct inet_connection_sock *icsk = inet_csk(sk); |
459 | struct tls_context *ctx; | 482 | struct tls_context *ctx; |
460 | int rc = 0; | 483 | int rc = 0; |
@@ -479,6 +502,17 @@ static int tls_init(struct sock *sk) | |||
479 | ctx->getsockopt = sk->sk_prot->getsockopt; | 502 | ctx->getsockopt = sk->sk_prot->getsockopt; |
480 | ctx->sk_proto_close = sk->sk_prot->close; | 503 | ctx->sk_proto_close = sk->sk_prot->close; |
481 | 504 | ||
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 | |||
482 | ctx->tx_conf = TLS_BASE_TX; | 516 | ctx->tx_conf = TLS_BASE_TX; |
483 | update_sk_prot(sk, ctx); | 517 | update_sk_prot(sk, ctx); |
484 | out: | 518 | out: |
@@ -493,21 +527,9 @@ static struct tcp_ulp_ops tcp_tls_ulp_ops __read_mostly = { | |||
493 | .init = tls_init, | 527 | .init = tls_init, |
494 | }; | 528 | }; |
495 | 529 | ||
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 | |||
508 | static int __init tls_register(void) | 530 | static int __init tls_register(void) |
509 | { | 531 | { |
510 | build_protos(tls_prots, &tcp_prot); | 532 | build_protos(tls_prots[TLSV4], &tcp_prot); |
511 | 533 | ||
512 | tcp_register_ulp(&tcp_tls_ulp_ops); | 534 | tcp_register_ulp(&tcp_tls_ulp_ops); |
513 | 535 | ||