On Tue, Mar 28, 2017 at 6:26 AM, Aviad Yehezkel <aviadye@xxxxxxxxxxxx> wrote: > 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; > + } This mechanism should be generalized. If we can do this with TLS then there will likely be other ULPs that we might want to set on a TCP socket. Maybe something like TCP_ULP_PUSH, TCP_ULP_POP (borrowing from STREAMS ever so slightly :-) ). I'd also suggest that the ULPs are indicated by a text string in the socket option argument, then have each ULP perform a registration for their service. > default: > return -ENOPROTOOPT; > } > -- > 2.7.4 >