aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2022-11-30 15:13:03 +1100
committerStefano Brivio <sbrivio@redhat.com>2022-12-06 07:41:22 +0100
commit9ef31b7619b45e3b109d17c5f79f4231d0f6e67b (patch)
tree720244d7cef0afc8a62b78ff932c0088f7d03a37
parent729edc241d04d64dcd5804ab7bc5c2735b7aaf48 (diff)
downloadpasst-9ef31b7619b45e3b109d17c5f79f4231d0f6e67b.tar
passt-9ef31b7619b45e3b109d17c5f79f4231d0f6e67b.tar.gz
passt-9ef31b7619b45e3b109d17c5f79f4231d0f6e67b.tar.bz2
passt-9ef31b7619b45e3b109d17c5f79f4231d0f6e67b.tar.lz
passt-9ef31b7619b45e3b109d17c5f79f4231d0f6e67b.tar.xz
passt-9ef31b7619b45e3b109d17c5f79f4231d0f6e67b.tar.zst
passt-9ef31b7619b45e3b109d17c5f79f4231d0f6e67b.zip
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 <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--udp.c40
1 files 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;