This patch adds TLS_TX and TLS_RX TCP socket options. Setting these socket options will change the sk->sk_prot operations of the TCP socket. The user is responsible to prevent races between calls to the previous operations and the new operations. After successful return, data sent on this socket will be encapsulated in TLS. Signed-off-by: Aviad Yehezkel <aviadye@xxxxxxxxxxxx> Signed-off-by: Boris Pismenny <borisp@xxxxxxxxxxxx> Signed-off-by: Ilya Lesokhin <ilyal@xxxxxxxxxxxx> --- include/uapi/linux/tcp.h | 2 ++ net/ipv4/tcp.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h index c53de26..f9f0e29 100644 --- a/include/uapi/linux/tcp.h +++ b/include/uapi/linux/tcp.h @@ -116,6 +116,8 @@ enum { #define TCP_SAVE_SYN 27 /* Record SYN headers for new connections */ #define TCP_SAVED_SYN 28 /* Get SYN headers recorded for connection */ #define TCP_REPAIR_WINDOW 29 /* Get/set window parameters */ +#define TCP_TLS_TX 30 +#define TCP_TLS_RX 31 struct tcp_repair_opt { __u32 opt_code; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 302fee9..2d190e3 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -273,6 +273,7 @@ #include <net/icmp.h> #include <net/inet_common.h> #include <net/tcp.h> +#include <net/tls.h> #include <net/xfrm.h> #include <net/ip.h> #include <net/sock.h> @@ -2676,6 +2677,21 @@ static int do_tcp_setsockopt(struct sock *sk, int level, tp->notsent_lowat = val; sk->sk_write_space(sk); break; + case TCP_TLS_TX: + case TCP_TLS_RX: { + int (*fn)(struct sock *sk, int optname, + char __user *optval, unsigned int optlen); + + fn = symbol_get(tls_sk_attach); + if (!fn) { + err = -EINVAL; + break; + } + + err = fn(sk, optname, optval, optlen); + symbol_put(tls_sk_attach); + break; + } default: err = -ENOPROTOOPT; break; @@ -3064,6 +3080,22 @@ static int do_tcp_getsockopt(struct sock *sk, int level, } return 0; } + case TCP_TLS_TX: + case TCP_TLS_RX: { + int err; + int (*fn)(struct sock *sk, int optname, + char __user *optval, int __user *optlen); + + fn = symbol_get(tls_sk_query); + if (!fn) { + err = -EINVAL; + break; + } + + err = fn(sk, optname, optval, optlen); + symbol_put(tls_sk_query); + return err; + } default: return -ENOPROTOOPT; } -- 2.7.4