aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2023-01-05 15:26:25 +1100
committerStefano Brivio <sbrivio@redhat.com>2023-01-13 01:07:12 +0100
commitb93d025d50dcc2c058b9eb3b67b76da56d27fcba (patch)
tree2cd3ba469f55642e3f0523bd0364507ffde58bf0
parent8d503e825f42289eb9d732b8354804f1f0e2ecfb (diff)
downloadpasst-b93d025d50dcc2c058b9eb3b67b76da56d27fcba.tar
passt-b93d025d50dcc2c058b9eb3b67b76da56d27fcba.tar.gz
passt-b93d025d50dcc2c058b9eb3b67b76da56d27fcba.tar.bz2
passt-b93d025d50dcc2c058b9eb3b67b76da56d27fcba.tar.lz
passt-b93d025d50dcc2c058b9eb3b67b76da56d27fcba.tar.xz
passt-b93d025d50dcc2c058b9eb3b67b76da56d27fcba.tar.zst
passt-b93d025d50dcc2c058b9eb3b67b76da56d27fcba.zip
udp: Don't use separate sockets to listen for spliced packets
Currently, when ports are forwarded inbound in pasta mode, we open two sockets for incoming traffic: one listens on the public IP address and will forward packets to the tuntap interface. The other listens on localhost and forwards via "splicing" (resending directly via sockets in the ns). Now that we've improved the logic about whether we "splice" any individual packet, we don't need this. Instead we can have a single socket bound to 0.0.0.0 or ::, marked as able to splice and udp_sock_handler() will deal with each packet as appropriate. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--udp.c53
1 files changed, 13 insertions, 40 deletions
diff --git a/udp.c b/udp.c
index 3f216ed..dbfdb61 100644
--- a/udp.c
+++ b/udp.c
@@ -1124,7 +1124,6 @@ void udp_sock_init(const struct ctx *c, int ns, sa_family_t af,
const void *addr, const char *ifname, in_port_t port)
{
union udp_epoll_ref uref = { .u32 = 0 };
- const void *bind_addr;
int s;
if (ns) {
@@ -1136,67 +1135,41 @@ void udp_sock_init(const struct ctx *c, int ns, sa_family_t af,
}
if ((af == AF_INET || af == AF_UNSPEC) && c->ifi4) {
- if (!addr && c->mode == MODE_PASTA)
- bind_addr = &c->ip4.addr;
- else
- bind_addr = addr;
-
uref.udp.v6 = 0;
+ uref.udp.splice = (c->mode == MODE_PASTA);
+ uref.udp.orig = true;
if (!ns) {
- uref.udp.splice = 0;
- s = sock_l4(c, AF_INET, IPPROTO_UDP, bind_addr, ifname,
+ s = sock_l4(c, AF_INET, IPPROTO_UDP, addr, ifname,
port, uref.u32);
udp_tap_map[V4][uref.udp.port].sock = s;
-
- if (c->mode == MODE_PASTA) {
- bind_addr = &(uint32_t){ htonl(INADDR_LOOPBACK) };
- uref.udp.splice = uref.udp.orig = true;
-
- s = sock_l4(c, AF_INET, IPPROTO_UDP, bind_addr,
- ifname, port, uref.u32);
- udp_splice_init[V4][port].sock = s;
- }
+ udp_splice_init[V4][port].sock = s;
} else {
- uref.udp.splice = uref.udp.orig = uref.udp.ns = true;
-
- bind_addr = &(uint32_t){ htonl(INADDR_LOOPBACK) };
+ struct in_addr loopback = { htonl(INADDR_LOOPBACK) };
+ uref.udp.ns = true;
- s = sock_l4(c, AF_INET, IPPROTO_UDP, bind_addr,
+ s = sock_l4(c, AF_INET, IPPROTO_UDP, &loopback,
ifname, port, uref.u32);
udp_splice_ns[V4][port].sock = s;
}
}
if ((af == AF_INET6 || af == AF_UNSPEC) && c->ifi6) {
- if (!addr && c->mode == MODE_PASTA)
- bind_addr = &c->ip6.addr;
- else
- bind_addr = addr;
-
uref.udp.v6 = 1;
+ uref.udp.splice = (c->mode == MODE_PASTA);
+ uref.udp.orig = true;
if (!ns) {
- uref.udp.splice = 0;
- s = sock_l4(c, AF_INET6, IPPROTO_UDP, bind_addr, ifname,
+ s = sock_l4(c, AF_INET6, IPPROTO_UDP, addr, ifname,
port, uref.u32);
udp_tap_map[V6][uref.udp.port].sock = s;
-
- if (c->mode == MODE_PASTA) {
- bind_addr = &in6addr_loopback;
- uref.udp.splice = uref.udp.orig = true;
-
- s = sock_l4(c, AF_INET6, IPPROTO_UDP, bind_addr,
- ifname, port, uref.u32);
- udp_splice_init[V6][port].sock = s;
- }
+ udp_splice_init[V6][port].sock = s;
} else {
- bind_addr = &in6addr_loopback;
- uref.udp.splice = uref.udp.orig = uref.udp.ns = true;
+ uref.udp.ns = true;
- s = sock_l4(c, AF_INET6, IPPROTO_UDP, bind_addr,
+ s = sock_l4(c, AF_INET6, IPPROTO_UDP, &in6addr_loopback,
ifname, port, uref.u32);
udp_splice_ns[V6][port].sock = s;
}