Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

SUNRPC: Recognize control messages in server-side TCP socket code

To support kTLS, the server-side TCP socket receive path needs to
watch for CMSGs.

Acked-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>

+48 -2
+2
include/net/tls.h
··· 69 69 70 70 #define TLS_CRYPTO_INFO_READY(info) ((info)->cipher_type) 71 71 72 + #define TLS_RECORD_TYPE_ALERT 0x15 73 + #define TLS_RECORD_TYPE_HANDSHAKE 0x16 72 74 #define TLS_RECORD_TYPE_DATA 0x17 73 75 74 76 #define TLS_AAD_SPACE_SIZE 13
+46 -2
net/sunrpc/svcsock.c
··· 43 43 #include <net/udp.h> 44 44 #include <net/tcp.h> 45 45 #include <net/tcp_states.h> 46 + #include <net/tls.h> 46 47 #include <linux/uaccess.h> 47 48 #include <linux/highmem.h> 48 49 #include <asm/ioctls.h> ··· 217 216 return len; 218 217 } 219 218 219 + static int 220 + svc_tcp_sock_process_cmsg(struct svc_sock *svsk, struct msghdr *msg, 221 + struct cmsghdr *cmsg, int ret) 222 + { 223 + if (cmsg->cmsg_level == SOL_TLS && 224 + cmsg->cmsg_type == TLS_GET_RECORD_TYPE) { 225 + u8 content_type = *((u8 *)CMSG_DATA(cmsg)); 226 + 227 + switch (content_type) { 228 + case TLS_RECORD_TYPE_DATA: 229 + /* TLS sets EOR at the end of each application data 230 + * record, even though there might be more frames 231 + * waiting to be decrypted. 232 + */ 233 + msg->msg_flags &= ~MSG_EOR; 234 + break; 235 + case TLS_RECORD_TYPE_ALERT: 236 + ret = -ENOTCONN; 237 + break; 238 + default: 239 + ret = -EAGAIN; 240 + } 241 + } 242 + return ret; 243 + } 244 + 245 + static int 246 + svc_tcp_sock_recv_cmsg(struct svc_sock *svsk, struct msghdr *msg) 247 + { 248 + union { 249 + struct cmsghdr cmsg; 250 + u8 buf[CMSG_SPACE(sizeof(u8))]; 251 + } u; 252 + int ret; 253 + 254 + msg->msg_control = &u; 255 + msg->msg_controllen = sizeof(u); 256 + ret = sock_recvmsg(svsk->sk_sock, msg, MSG_DONTWAIT); 257 + if (unlikely(msg->msg_controllen != sizeof(u))) 258 + ret = svc_tcp_sock_process_cmsg(svsk, msg, &u.cmsg, ret); 259 + return ret; 260 + } 261 + 220 262 #if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 221 263 static void svc_flush_bvec(const struct bio_vec *bvec, size_t size, size_t seek) 222 264 { ··· 307 263 iov_iter_advance(&msg.msg_iter, seek); 308 264 buflen -= seek; 309 265 } 310 - len = sock_recvmsg(svsk->sk_sock, &msg, MSG_DONTWAIT); 266 + len = svc_tcp_sock_recv_cmsg(svsk, &msg); 311 267 if (len > 0) 312 268 svc_flush_bvec(bvec, len, seek); 313 269 ··· 921 877 iov.iov_base = ((char *)&svsk->sk_marker) + svsk->sk_tcplen; 922 878 iov.iov_len = want; 923 879 iov_iter_kvec(&msg.msg_iter, ITER_DEST, &iov, 1, want); 924 - len = sock_recvmsg(svsk->sk_sock, &msg, MSG_DONTWAIT); 880 + len = svc_tcp_sock_recv_cmsg(svsk, &msg); 925 881 if (len < 0) 926 882 return len; 927 883 svsk->sk_tcplen += len;