aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2026-06-16 11:09:35 +1000
committerStefano Brivio <sbrivio@redhat.com>2026-06-16 23:49:57 +0200
commit50e3dcc44074dea26ed8486f65aa02d1dc2291ec (patch)
treef05166a51e5e2ed51c1d9d660e3f34ce4419e58b
parentd5ef43da648dbd83db1feddd662cdb8e095b8c11 (diff)
downloadpasst-50e3dcc44074dea26ed8486f65aa02d1dc2291ec.tar
passt-50e3dcc44074dea26ed8486f65aa02d1dc2291ec.tar.gz
passt-50e3dcc44074dea26ed8486f65aa02d1dc2291ec.tar.bz2
passt-50e3dcc44074dea26ed8486f65aa02d1dc2291ec.tar.lz
passt-50e3dcc44074dea26ed8486f65aa02d1dc2291ec.tar.xz
passt-50e3dcc44074dea26ed8486f65aa02d1dc2291ec.tar.zst
passt-50e3dcc44074dea26ed8486f65aa02d1dc2291ec.zip
fwd, pif: Remove duplicated logic between tcp_listen() and udp_listen()
tcp_listen() and udp_listen() have only some simple logic around a call to pif_listen(), and it's basically identical in each case. If we move the common logic into pif_listen() we can then remove {tcp,udp}_listen() entirely, with their caller in fwd_sync_one() calling pif_listen() directly. We also move the logic converting from a protocol id to an epoll type from fwd_sync_one() into pif_listen(). It's a bit arbitrary, but seems slightly nicer that way. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--fwd.c8
-rw-r--r--pif.c27
-rw-r--r--pif.h2
-rw-r--r--tcp.c38
-rw-r--r--tcp.h2
-rw-r--r--udp.c38
-rw-r--r--udp.h2
7 files changed, 27 insertions, 90 deletions
diff --git a/fwd.c b/fwd.c
index c0a6ada..042158c 100644
--- a/fwd.c
+++ b/fwd.c
@@ -389,13 +389,7 @@ static int fwd_sync_one(const struct ctx *c, uint8_t pif, unsigned idx,
continue;
}
- if (rule->proto == IPPROTO_TCP)
- fd = tcp_listen(c, pif, idx, addr, ifname, port);
- else if (rule->proto == IPPROTO_UDP)
- fd = udp_listen(c, pif, idx, addr, ifname, port);
- else
- assert(0);
-
+ fd = pif_listen(c, rule->proto, pif, addr, ifname, port, idx);
if (fd < 0) {
char astr[INANY_ADDRSTRLEN];
diff --git a/pif.c b/pif.c
index d5e3161..4cf0f6e 100644
--- a/pif.c
+++ b/pif.c
@@ -64,7 +64,7 @@ void pif_sockaddr(const struct ctx *c, union sockaddr_inany *sa,
/** pif_listen() - Open a listening socket on a specified pif
* @c: Execution context
- * @type: Socket epoll type
+ * @proto: Socket protocol (IPPROTO_TCP or IPPROTO_UDP)
* @pif: Interface for this socket
* @addr: Address to bind to, or NULL for dual-stack any
* @ifname: Interface for binding, NULL for any
@@ -76,15 +76,38 @@ void pif_sockaddr(const struct ctx *c, union sockaddr_inany *sa,
*
* Return: newly created socket, negative error code on failure
*/
-int pif_listen(const struct ctx *c, enum epoll_type type, uint8_t pif,
+int pif_listen(const struct ctx *c, uint8_t proto, uint8_t pif,
const union inany_addr *addr, const char *ifname,
in_port_t port, unsigned rule)
{
+ enum epoll_type type;
union epoll_ref ref;
int ret;
assert(pif_is_socket(pif));
+ if (proto == IPPROTO_TCP)
+ type = EPOLL_TYPE_TCP_LISTEN;
+ else if (proto == IPPROTO_UDP)
+ type = EPOLL_TYPE_UDP_LISTEN;
+ else
+ return -EPROTONOSUPPORT;
+
+ if (!c->ifi4) {
+ if (!addr)
+ /* Restrict to v6 only */
+ addr = &inany_any6;
+ else if (inany_v4(addr))
+ return -EAFNOSUPPORT;
+ }
+ if (!c->ifi6) {
+ if (!addr)
+ /* Restrict to v4 only */
+ addr = &inany_any4;
+ else if (!inany_v4(addr))
+ return -EAFNOSUPPORT;
+ }
+
if (!addr) {
ref.fd = sock_l4_dualstack_any(c, type, port, ifname);
} else {
diff --git a/pif.h b/pif.h
index 62223d1..3a1e2e5 100644
--- a/pif.h
+++ b/pif.h
@@ -66,7 +66,7 @@ static inline bool pif_is_socket(uint8_t pif)
void pif_sockaddr(const struct ctx *c, union sockaddr_inany *sa,
uint8_t pif, const union inany_addr *addr, in_port_t port);
-int pif_listen(const struct ctx *c, enum epoll_type type, uint8_t pif,
+int pif_listen(const struct ctx *c, uint8_t proto, uint8_t pif,
const union inany_addr *addr, const char *ifname,
in_port_t port, unsigned rule);
diff --git a/tcp.c b/tcp.c
index 10d9d0d..097ab72 100644
--- a/tcp.c
+++ b/tcp.c
@@ -2761,44 +2761,6 @@ void tcp_sock_handler(const struct ctx *c, union epoll_ref ref,
}
/**
- * tcp_listen() - Create listening socket
- * @c: Execution context
- * @pif: Interface to open the socket for (PIF_HOST or PIF_SPLICE)
- * @rule: Index of relevant forwarding rule
- * @addr: Pointer to address for binding, NULL for any
- * @ifname: Name of interface to bind to, NULL for any
- * @port: Port, host order
- *
- * Return: socket fd on success, negative error code on failure
- */
-int tcp_listen(const struct ctx *c, uint8_t pif, unsigned rule,
- const union inany_addr *addr, const char *ifname, in_port_t port)
-{
- int s;
-
- assert(!c->no_tcp);
-
- if (!c->ifi4) {
- if (!addr)
- /* Restrict to v6 only */
- addr = &inany_any6;
- else if (inany_v4(addr))
- return -EAFNOSUPPORT;
- }
- if (!c->ifi6) {
- if (!addr)
- /* Restrict to v4 only */
- addr = &inany_any4;
- else if (!inany_v4(addr))
- return -EAFNOSUPPORT;
- }
-
- s = pif_listen(c, EPOLL_TYPE_TCP_LISTEN, pif, addr, ifname, port, rule);
-
- return s;
-}
-
-/**
* tcp_sock_refill_pool() - Refill one pool of pre-opened sockets
* @pool: Pool of sockets to refill
* @af: Address family to use
diff --git a/tcp.h b/tcp.h
index 3262a80..57deef5 100644
--- a/tcp.h
+++ b/tcp.h
@@ -26,8 +26,6 @@ void tcp_sock_handler(const struct ctx *c, union epoll_ref ref,
int tcp_tap_handler(const struct ctx *c, uint8_t pif, sa_family_t af,
const void *saddr, const void *daddr, uint32_t flow_lbl,
const struct pool *p, int idx, const struct timespec *now);
-int tcp_listen(const struct ctx *c, uint8_t pif, unsigned rule,
- const union inany_addr *addr, const char *ifname, in_port_t port);
int tcp_init(struct ctx *c);
void tcp_defer_handler(struct ctx *c, const struct timespec *now);
diff --git a/udp.c b/udp.c
index c28d6ee..375befa 100644
--- a/udp.c
+++ b/udp.c
@@ -1125,44 +1125,6 @@ int udp_tap_handler(const struct ctx *c, uint8_t pif,
}
/**
- * udp_listen() - Initialise listening socket for a given port
- * @c: Execution context
- * @pif: Interface to open the socket for (PIF_HOST or PIF_SPLICE)
- * @rule: Index of relevant forwarding rule
- * @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
- *
- * Return: socket fd on success, negative error code on failure
- */
-int udp_listen(const struct ctx *c, uint8_t pif, unsigned rule,
- const union inany_addr *addr, const char *ifname, in_port_t port)
-{
- int s;
-
- assert(!c->no_udp);
-
- if (!c->ifi4) {
- if (!addr)
- /* Restrict to v6 only */
- addr = &inany_any6;
- else if (inany_v4(addr))
- return -EAFNOSUPPORT;
- }
- if (!c->ifi6) {
- if (!addr)
- /* Restrict to v4 only */
- addr = &inany_any4;
- else if (!inany_v4(addr))
- return -EAFNOSUPPORT;
- }
-
- s = pif_listen(c, EPOLL_TYPE_UDP_LISTEN, pif, addr, ifname, port, rule);
-
- return s;
-}
-
-/**
* udp_splice_iov_init() - Set up buffers and descriptors for recvmmsg/sendmmsg
*/
static void udp_splice_iov_init(void)
diff --git a/udp.h b/udp.h
index a75d5ae..9ea7de6 100644
--- a/udp.h
+++ b/udp.h
@@ -19,8 +19,6 @@ int udp_tap_handler(const struct ctx *c, uint8_t pif,
sa_family_t af, const void *saddr, const void *daddr,
uint8_t ttl, const struct pool *p, int idx,
const struct timespec *now);
-int udp_listen(const struct ctx *c, uint8_t pif, unsigned rule,
- const union inany_addr *addr, const char *ifname, in_port_t port);
int udp_init(struct ctx *c);
void udp_update_l2_buf(const unsigned char *eth_d);