Skip to contentSkip to conversation

net: Option to retrieve the pending data from send queue of UDP socket

PATCH Superseded Lese Doru Calin 2 participants 2 messages Apr 23, 2020 – May 1, 2020

Subsystems (4)

v5 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

PATCH v5 1/1 net: Option to retrieve the pending data from send queue of UDP socket

In this year's edition of GSoC, there is a project idea for CRIU to add support for checkpoint/restore of cork-ed UDP sockets. But to add it, the kernel API needs to be extended.
This is what this patch does. It adds a new command SIOUDPPENDGET to the ioctl syscall regarding UDP sockets, which stores the pending data from the write queue and the destination address in a struct msghdr. The arg for ioctl needs to be a pointer to a user space struct msghdr. To retrive the data requires the CAP_NET_ADMIN capability.

---
It a different approach from https://lore.kernel.org/netdev/20200416132242.GA2586@white/,
that has given up on UDP "Repair mode" in the fast path for a ioctl syscall.

 include/linux/socket.h       |   2 +
 include/uapi/linux/sockios.h |   3 +
 net/ipv4/udp.c               | 144 ++++++++++++++++++++++++++++++++---
 net/socket.c                 |   4 +-
 4 files changed, 139 insertions(+), 14 deletions(-)
include/linux/socket.h +2 -0
index 54338fac45cb..632ba0ea6709 100644
@@ -351,6 +351,8 @@ struct ucred {
 #define IPX_TYPE	1
 
 extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr);
+extern int move_addr_to_user(struct sockaddr_storage *kaddr, int klen,
+			      void __user *uaddr, int __user *ulen);
 extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
 
 struct timespec64;
include/uapi/linux/sockios.h +3 -0
index 7d1bccbbef78..3639fa906604 100644
@@ -153,6 +153,9 @@
 #define SIOCSHWTSTAMP	0x89b0		/* set and get config		*/
 #define SIOCGHWTSTAMP	0x89b1		/* get config			*/
 
+/* UDP socket calls*/
+#define SIOUDPPENDGET 0x89C0	/* get the pending data from write queue */
+
 /* Device private ioctl calls */
 
 /*
net/ipv4/udp.c +132 -12

162 lines not on this page · raw message

net/socket.c +2 -2
index 2dd739fba866..bd25d528c9a0 100644
@@ -217,8 +217,8 @@ int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *k
  *	specified. Zero is returned for a success.
  */
 
-static int move_addr_to_user(struct sockaddr_storage *kaddr, int klen,
-			     void __user *uaddr, int __user *ulen)
+int move_addr_to_user(struct sockaddr_storage *kaddr, int klen,
+		      void __user *uaddr, int __user *ulen)
 {
 	int err;
 	int len;
Signature · 1 line
2.17.1
maintainer
#1 lore raw

From: Lese Doru Calin <[email protected]>
Date: Fri, 24 Apr 2020 01:15:15 +0300

Quoted 8 lines
net/ipv4/udp.c +0 -4
@@ -1794,18 +1924,8 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
 
 	sock_recv_ts_and_drops(msg, sk, skb);
 
-	/* Copy the address. */
-	if (sin) {
-		sin->sin_family = AF_INET;
-		sin->sin_port = udp_hdr(skb)->source;

net/ipv4/udp.c int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock, · line 1928

Quoted 10 lines
net/ipv4/udp.c +2 -8
-		sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
-		memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
-		*addr_len = sizeof(*sin);
-
-		if (cgroup_bpf_enabled)
-			BPF_CGROUP_RUN_PROG_UDP4_RECVMSG_LOCK(sk,
-							(struct sockaddr *)sin);
-	}
+	udp_set_source_addr(sk, msg, addr_len, ip_hdr(skb)->saddr,
+			    udp_hdr(skb)->source);

The 'sin' variable is no longer used, please remove it.