From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: passt.top; dkim=pass (2048-bit key; secure) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.a=rsa-sha256 header.s=202606 header.b=hz/mbyth; dkim-atps=neutral Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 1D7BA5A0272 for ; Tue, 09 Jun 2026 08:30:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202606; t=1780986609; bh=e9UKJnS5u8b/zSFCBaVIjz1SGdj8vXW7df95hDO2H2c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hz/mbythXl7bsx6vk9qnFJ2QtNYLRHrjvsQnomfvdb7MdEPZ9Rd0TSzx5jghSelq0 xcf1qfuare0JCuuySIXgVqkSJyG3/cUaHKSdA3+dxdaXXujOAQbUC7FVAxrot4I2DW Ic+p5VG3uOVapT/thO454riLoXJ43e6PZk5wSd8o4c3JpxCb6SuqhrKeEY/XBdnlel sZE3kIKmz4a6Wh2DcAPVcW8v7nf8DYj9xRBBLtAEu/ohZ8cXkfunvlC2nZ++v+126y +u3Z8wre8M1fhXc9qqDvDz5ZXv5pcrRqD1jv6+skn1gvD/8aAfOk9NoEo4On5rciHv KavaXYDz+nC2Q== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4gZJtT0hfnz4wSX; Tue, 09 Jun 2026 16:30:09 +1000 (AEST) From: David Gibson To: Stefano Brivio , passt-dev@passt.top Subject: [PATCH 3/4] fwd, pif: Remove duplicated logic between tcp_listen() and udp_listen() Date: Tue, 9 Jun 2026 16:30:04 +1000 Message-ID: <20260609063005.113744-4-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260609063005.113744-1-david@gibson.dropbear.id.au> References: <20260609063005.113744-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: WWBN2QD46HSOIMKNOQTUJB573RIKHONU X-Message-ID-Hash: WWBN2QD46HSOIMKNOQTUJB573RIKHONU X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: David Gibson X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: 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 --- fwd.c | 8 +------- pif.c | 31 ++++++++++++++++++++++++++----- pif.h | 2 +- tcp.c | 38 -------------------------------------- tcp.h | 2 -- udp.c | 38 -------------------------------------- udp.h | 2 -- 7 files changed, 28 insertions(+), 93 deletions(-) diff --git a/fwd.c b/fwd.c index c0a6adac..042158cf 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 d5e31613..ede2f903 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,7 +76,7 @@ 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) { @@ -85,19 +85,40 @@ int pif_listen(const struct ctx *c, enum epoll_type type, uint8_t pif, assert(pif_is_socket(pif)); + 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 (proto == IPPROTO_TCP) + ref.type = EPOLL_TYPE_TCP_LISTEN; + else if (proto == IPPROTO_UDP) + ref.type = EPOLL_TYPE_UDP_LISTEN; + else + return -EPROTONOSUPPORT; + if (!addr) { - ref.fd = sock_l4_dualstack_any(c, type, port, ifname); + ref.fd = sock_l4_dualstack_any(c, ref.type, port, ifname); } else { union sockaddr_inany sa; pif_sockaddr(c, &sa, pif, addr, port); - ref.fd = sock_l4(c, type, &sa, ifname); + ref.fd = sock_l4(c, ref.type, &sa, ifname); } if (ref.fd < 0) return ref.fd; - ref.type = type; ref.listen.port = port; ref.listen.pif = pif; ref.listen.rule = rule; diff --git a/pif.h b/pif.h index 62223d12..3a1e2e57 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 c4000754..36add423 100644 --- a/tcp.c +++ b/tcp.c @@ -2739,44 +2739,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 diff --git a/tcp.h b/tcp.h index 3262a807..57deef57 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 c28d6ee2..375befa7 100644 --- a/udp.c +++ b/udp.c @@ -1124,44 +1124,6 @@ int udp_tap_handler(const struct ctx *c, uint8_t pif, return count; } -/** - * 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 */ diff --git a/udp.h b/udp.h index a75d5aea..9ea7de68 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); -- 2.54.0