net: Option to retrieve the pending data from send queue of UDP socket
Subsystems (4)
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
@@ -351,6 +351,8 @@ struct ucred {#define IPX_TYPE 1extern 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
@@ -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
@@ -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
David Miller
maintainerFrom: 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.