From c1eff9a3c622516c7bb9194a1df50dfe01281c56 Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Fri, 7 Oct 2022 04:53:40 +0200 Subject: conf, tcp, udp: Allow specification of interface to bind to Since kernel version 5.7, commit c427bfec18f2 ("net: core: enable SO_BINDTODEVICE for non-root users"), we can bind sockets to interfaces, if they haven't been bound yet (as in bind()). Introduce an optional interface specification for forwarded ports, prefixed by %, that can be passed together with an address. Reported use case: running local services that use ports we want to have externally forwarded: https://github.com/containers/podman/issues/14425 Signed-off-by: Stefano Brivio Reviewed-by: David Gibson --- udp.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'udp.c') diff --git a/udp.c b/udp.c index 5422fdd..cac9c65 100644 --- a/udp.c +++ b/udp.c @@ -1005,7 +1005,7 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr, union udp_epoll_ref uref = { .udp.bound = 1, .udp.port = src }; - s = sock_l4(c, AF_INET, IPPROTO_UDP, NULL, src, + s = sock_l4(c, AF_INET, IPPROTO_UDP, NULL, NULL, src, uref.u32); if (s < 0) return p->count; @@ -1057,8 +1057,8 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr, .udp.v6 = 1, .udp.port = src }; - s = sock_l4(c, AF_INET6, IPPROTO_UDP, bind_addr, src, - uref.u32); + s = sock_l4(c, AF_INET6, IPPROTO_UDP, bind_addr, NULL, + src, uref.u32); if (s < 0) return p->count; @@ -1111,10 +1111,11 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr, * @ns: In pasta mode, if set, bind with loopback address in namespace * @af: Address family to select a specific IP version, or AF_UNSPEC * @addr: Pointer to address for binding, NULL if not configured + * @ifname: Name of interface to bind to, NULL if not configured * @port: Port, host order */ void udp_sock_init(const struct ctx *c, int ns, sa_family_t af, - const void *addr, in_port_t port) + const void *addr, const char *ifname, in_port_t port) { union udp_epoll_ref uref = { .udp.bound = 1 }; const void *bind_addr; @@ -1138,8 +1139,8 @@ void udp_sock_init(const struct ctx *c, int ns, sa_family_t af, if (!ns) { uref.udp.splice = 0; - s = sock_l4(c, AF_INET, IPPROTO_UDP, bind_addr, port, - uref.u32); + s = sock_l4(c, AF_INET, IPPROTO_UDP, bind_addr, ifname, + port, uref.u32); udp_tap_map[V4][uref.udp.port].sock = s; } @@ -1148,16 +1149,16 @@ void udp_sock_init(const struct ctx *c, int ns, sa_family_t af, bind_addr = &(uint32_t){ htonl(INADDR_LOOPBACK) }; uref.udp.splice = UDP_TO_NS; - sock_l4(c, AF_INET, IPPROTO_UDP, bind_addr, port, - uref.u32); + sock_l4(c, AF_INET, IPPROTO_UDP, bind_addr, ifname, + port, uref.u32); } if (ns) { bind_addr = &(uint32_t){ htonl(INADDR_LOOPBACK) }; uref.udp.splice = UDP_TO_INIT; - sock_l4(c, AF_INET, IPPROTO_UDP, bind_addr, port, - uref.u32); + sock_l4(c, AF_INET, IPPROTO_UDP, bind_addr, ifname, + port, uref.u32); } } @@ -1171,8 +1172,8 @@ void udp_sock_init(const struct ctx *c, int ns, sa_family_t af, if (!ns) { uref.udp.splice = 0; - s = sock_l4(c, AF_INET6, IPPROTO_UDP, bind_addr, port, - uref.u32); + s = sock_l4(c, AF_INET6, IPPROTO_UDP, bind_addr, ifname, + port, uref.u32); udp_tap_map[V6][uref.udp.port].sock = s; } @@ -1181,16 +1182,16 @@ void udp_sock_init(const struct ctx *c, int ns, sa_family_t af, bind_addr = &in6addr_loopback; uref.udp.splice = UDP_TO_NS; - sock_l4(c, AF_INET6, IPPROTO_UDP, bind_addr, port, - uref.u32); + sock_l4(c, AF_INET6, IPPROTO_UDP, bind_addr, ifname, + port, uref.u32); } if (ns) { bind_addr = &in6addr_loopback; uref.udp.splice = UDP_TO_INIT; - sock_l4(c, AF_INET6, IPPROTO_UDP, bind_addr, port, - uref.u32); + sock_l4(c, AF_INET6, IPPROTO_UDP, bind_addr, ifname, + port, uref.u32); } } } @@ -1213,7 +1214,7 @@ int udp_sock_init_ns(void *arg) if (!bitmap_isset(c->udp.fwd_out.f.map, dst)) continue; - udp_sock_init(c, 1, AF_UNSPEC, NULL, dst); + udp_sock_init(c, 1, AF_UNSPEC, NULL, NULL, dst); } return 0; -- cgit v1.2.3