udp: Don't create double sockets for -U port

For each IP version udp_socket() has 3 possible calls to sock_l4().  One
is for the "non-spliced" bound socket in the init namespace, one for the
"spliced" bound socket in the init namespace and one for the "spliced"
bound socket in the pasta namespace.

However when this is called to create a socket in the pasta namspeace there
is a logic error which causes it to take the path for the init side spliced
socket as well as the ns socket.  This essentially tries to create two
identical sockets on the ns side.  Unsurprisingly the second bind() call
fails according to strace.

Correct this to only attempt to open one socket within the ns.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
David Gibson 2022-11-30 15:13:07 +11:00 committed by Stefano Brivio
parent d9394eb9b7
commit c277c6dd7d

8
udp.c
View file

@ -1090,7 +1090,6 @@ void udp_sock_init(const struct ctx *c, int ns, sa_family_t af,
port, uref.u32); port, uref.u32);
udp_tap_map[V4][uref.udp.port].sock = s; udp_tap_map[V4][uref.udp.port].sock = s;
}
if (c->mode == MODE_PASTA) { if (c->mode == MODE_PASTA) {
bind_addr = &(uint32_t){ htonl(INADDR_LOOPBACK) }; bind_addr = &(uint32_t){ htonl(INADDR_LOOPBACK) };
@ -1099,8 +1098,7 @@ void udp_sock_init(const struct ctx *c, int ns, sa_family_t af,
sock_l4(c, AF_INET, IPPROTO_UDP, bind_addr, ifname, sock_l4(c, AF_INET, IPPROTO_UDP, bind_addr, ifname,
port, uref.u32); port, uref.u32);
} }
} else {
if (ns) {
uref.udp.splice = uref.udp.orig = uref.udp.ns = true; uref.udp.splice = uref.udp.orig = uref.udp.ns = true;
bind_addr = &(uint32_t){ htonl(INADDR_LOOPBACK) }; bind_addr = &(uint32_t){ htonl(INADDR_LOOPBACK) };
@ -1124,7 +1122,6 @@ void udp_sock_init(const struct ctx *c, int ns, sa_family_t af,
port, uref.u32); port, uref.u32);
udp_tap_map[V6][uref.udp.port].sock = s; udp_tap_map[V6][uref.udp.port].sock = s;
}
if (c->mode == MODE_PASTA) { if (c->mode == MODE_PASTA) {
bind_addr = &in6addr_loopback; bind_addr = &in6addr_loopback;
@ -1133,8 +1130,7 @@ void udp_sock_init(const struct ctx *c, int ns, sa_family_t af,
sock_l4(c, AF_INET6, IPPROTO_UDP, bind_addr, ifname, sock_l4(c, AF_INET6, IPPROTO_UDP, bind_addr, ifname,
port, uref.u32); port, uref.u32);
} }
} else {
if (ns) {
bind_addr = &in6addr_loopback; bind_addr = &in6addr_loopback;
uref.udp.splice = uref.udp.orig = uref.udp.ns = true; uref.udp.splice = uref.udp.orig = uref.udp.ns = true;