From 9ef31b7619b45e3b109d17c5f79f4231d0f6e67b Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 30 Nov 2022 15:13:03 +1100 Subject: [PATCH] udp: Always use sendto() rather than send() for forwarding spliced packets udp_sock_handler_splice() has two different ways of sending out packets once it has determined the correct destination socket. For the originating sockets (which are not connected) it uses sendto() to specify a specific address. For the forward socket (which is connected) we use send(). However we know the correct destination address even for the forward socket we do also know the correct destination address. We can use this to use sendto() instead of send(), removing the need for two different paths and some staging data structures. Signed-off-by: David Gibson Signed-off-by: Stefano Brivio --- udp.c | 40 +++++++--------------------------------- 1 file changed, 7 insertions(+), 33 deletions(-) diff --git a/udp.c b/udp.c index 63cfb92..3bf59bd 100644 --- a/udp.c +++ b/udp.c @@ -48,7 +48,8 @@ * - forward direction: 127.0.0.1:5000 -> 127.0.0.1:80 in init from bound * socket s, with epoll reference: index = 80, splice = UDP_TO_NS * - if udp_splice_to_ns[V4][5000].target_sock: - * - send packet to udp_splice_to_ns[V4][5000].target_sock + * - send packet to udp_splice_to_ns[V4][5000].target_sock, with + * destination port 80 * - otherwise: * - create new socket udp_splice_to_ns[V4][5000].target_sock * - bind in namespace to 127.0.0.1:5000 @@ -71,7 +72,8 @@ * - forward direction: 127.0.0.1:2000 -> 127.0.0.1:22 in namespace from bound * socket s, with epoll reference: index = 22, splice = UDP_TO_INIT * - if udp4_splice_to_init[V4][2000].target_sock: - * - send packet to udp_splice_to_init[V4][2000].target_sock + * - send packet to udp_splice_to_init[V4][2000].target_sock, with + * destination port 22 * - otherwise: * - create new socket udp_splice_to_init[V4][2000].target_sock * - bind in init to 127.0.0.1:2000 @@ -244,9 +246,6 @@ static struct mmsghdr udp6_l2_mh_tap [UDP_TAP_FRAMES_MEM]; static struct iovec udp_iov_recv [UDP_SPLICE_FRAMES]; static struct mmsghdr udp_mmh_recv [UDP_SPLICE_FRAMES]; -static struct iovec udp_iov_send [UDP_SPLICE_FRAMES]; -static struct mmsghdr udp_mmh_send [UDP_SPLICE_FRAMES]; - static struct iovec udp_iov_sendto [UDP_SPLICE_FRAMES]; static struct mmsghdr udp_mmh_sendto [UDP_SPLICE_FRAMES]; @@ -529,7 +528,7 @@ static int udp_splice_connect_ns(void *arg) static void udp_sock_handler_splice(const struct ctx *c, union epoll_ref ref, uint32_t events, const struct timespec *now) { - in_port_t src, dst = ref.r.p.udp.udp.port, send_dst = 0; + in_port_t src, dst = ref.r.p.udp.udp.port; struct msghdr *mh = &udp_mmh_recv[0].msg_hdr; struct sockaddr_storage *sa_s = mh->msg_name; int s, v6 = ref.r.p.udp.udp.v6, n, i; @@ -570,8 +569,6 @@ static void udp_sock_handler_splice(const struct ctx *c, union epoll_ref ref, case UDP_BACK_TO_INIT: if (!(s = udp_splice_to_ns[v6][dst].orig_sock)) return; - - send_dst = dst; break; case UDP_TO_INIT: src += c->udp.fwd_in.rdelta[src]; @@ -587,25 +584,11 @@ static void udp_sock_handler_splice(const struct ctx *c, union epoll_ref ref, case UDP_BACK_TO_NS: if (!(s = udp_splice_to_init[v6][dst].orig_sock)) return; - - send_dst = dst; break; default: return; } - if (ref.r.p.udp.udp.splice == UDP_TO_NS || - ref.r.p.udp.udp.splice == UDP_TO_INIT) { - for (i = 0; i < n; i++) { - struct msghdr *mh_s = &udp_mmh_send[i].msg_hdr; - - mh_s->msg_iov->iov_len = udp_mmh_recv[i].msg_len; - } - - sendmmsg(s, udp_mmh_send, n, MSG_NOSIGNAL); - return; - } - for (i = 0; i < n; i++) { struct msghdr *mh_s = &udp_mmh_sendto[i].msg_hdr; @@ -617,7 +600,7 @@ static void udp_sock_handler_splice(const struct ctx *c, union epoll_ref ref, ((struct sockaddr_in6) { .sin6_family = AF_INET6, .sin6_addr = IN6ADDR_LOOPBACK_INIT, - .sin6_port = htons(send_dst), + .sin6_port = htons(dst), .sin6_scope_id = 0, }); } else { @@ -625,7 +608,7 @@ static void udp_sock_handler_splice(const struct ctx *c, union epoll_ref ref, ((struct sockaddr_in) { .sin_family = AF_INET, .sin_addr = { .s_addr = htonl(INADDR_LOOPBACK) }, - .sin_port = htons(send_dst), + .sin_port = htons(dst), .sin_zero = { 0 }, }); } @@ -1228,15 +1211,6 @@ static void udp_splice_iov_init(void) iov->iov_len = sizeof(udp_splice_buf[i]); } - for (i = 0, h = udp_mmh_send; i < UDP_SPLICE_FRAMES; i++, h++) { - struct msghdr *mh = &h->msg_hdr; - - mh->msg_iov = &udp_iov_send[i]; - mh->msg_iovlen = 1; - } - for (i = 0, iov = udp_iov_send; i < UDP_SPLICE_FRAMES; i++, iov++) - iov->iov_base = udp_splice_buf[i]; - for (i = 0, h = udp_mmh_sendto; i < UDP_SPLICE_FRAMES; i++, h++) { struct msghdr *mh = &h->msg_hdr;