mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	SUNRPC: Capture CMSG metadata on client-side receive
kTLS sockets use CMSG to report decryption errors and the need for session re-keying. For RPC-with-TLS, an "application data" message contains a ULP payload, and that is passed along to the RPC client. An "alert" message triggers connection reset. Everything else is discarded. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
This commit is contained in:
		
							parent
							
								
									0d3ca07ffd
								
							
						
					
					
						commit
						dea034b963
					
				
					 1 changed files with 47 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -47,6 +47,8 @@
 | 
			
		|||
#include <net/checksum.h>
 | 
			
		||||
#include <net/udp.h>
 | 
			
		||||
#include <net/tcp.h>
 | 
			
		||||
#include <net/tls.h>
 | 
			
		||||
 | 
			
		||||
#include <linux/bvec.h>
 | 
			
		||||
#include <linux/highmem.h>
 | 
			
		||||
#include <linux/uio.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -347,13 +349,56 @@ xs_alloc_sparse_pages(struct xdr_buf *buf, size_t want, gfp_t gfp)
 | 
			
		|||
	return want;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
xs_sock_process_cmsg(struct socket *sock, struct msghdr *msg,
 | 
			
		||||
		     struct cmsghdr *cmsg, int ret)
 | 
			
		||||
{
 | 
			
		||||
	if (cmsg->cmsg_level == SOL_TLS &&
 | 
			
		||||
	    cmsg->cmsg_type == TLS_GET_RECORD_TYPE) {
 | 
			
		||||
		u8 content_type = *((u8 *)CMSG_DATA(cmsg));
 | 
			
		||||
 | 
			
		||||
		switch (content_type) {
 | 
			
		||||
		case TLS_RECORD_TYPE_DATA:
 | 
			
		||||
			/* TLS sets EOR at the end of each application data
 | 
			
		||||
			 * record, even though there might be more frames
 | 
			
		||||
			 * waiting to be decrypted.
 | 
			
		||||
			 */
 | 
			
		||||
			msg->msg_flags &= ~MSG_EOR;
 | 
			
		||||
			break;
 | 
			
		||||
		case TLS_RECORD_TYPE_ALERT:
 | 
			
		||||
			ret = -ENOTCONN;
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			ret = -EAGAIN;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
xs_sock_recv_cmsg(struct socket *sock, struct msghdr *msg, int flags)
 | 
			
		||||
{
 | 
			
		||||
	union {
 | 
			
		||||
		struct cmsghdr	cmsg;
 | 
			
		||||
		u8		buf[CMSG_SPACE(sizeof(u8))];
 | 
			
		||||
	} u;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	msg->msg_control = &u;
 | 
			
		||||
	msg->msg_controllen = sizeof(u);
 | 
			
		||||
	ret = sock_recvmsg(sock, msg, flags);
 | 
			
		||||
	if (msg->msg_controllen != sizeof(u))
 | 
			
		||||
		ret = xs_sock_process_cmsg(sock, msg, &u.cmsg, ret);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ssize_t
 | 
			
		||||
xs_sock_recvmsg(struct socket *sock, struct msghdr *msg, int flags, size_t seek)
 | 
			
		||||
{
 | 
			
		||||
	ssize_t ret;
 | 
			
		||||
	if (seek != 0)
 | 
			
		||||
		iov_iter_advance(&msg->msg_iter, seek);
 | 
			
		||||
	ret = sock_recvmsg(sock, msg, flags);
 | 
			
		||||
	ret = xs_sock_recv_cmsg(sock, msg, flags);
 | 
			
		||||
	return ret > 0 ? ret + seek : ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -379,7 +424,7 @@ xs_read_discard(struct socket *sock, struct msghdr *msg, int flags,
 | 
			
		|||
		size_t count)
 | 
			
		||||
{
 | 
			
		||||
	iov_iter_discard(&msg->msg_iter, ITER_DEST, count);
 | 
			
		||||
	return sock_recvmsg(sock, msg, flags);
 | 
			
		||||
	return xs_sock_recv_cmsg(sock, msg, flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue