aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2026-01-16 11:59:25 +1100
committerStefano Brivio <sbrivio@redhat.com>2026-01-18 12:48:06 +0100
commitfe37028466d3d29d74ebf53e9c53c9f139fbc74e (patch)
tree1463fd040d3a0cc1931ec8967f286695edc889c9
parent01bcdb925b0700faecec7dfaa1005147303ec0fb (diff)
downloadpasst-fe37028466d3d29d74ebf53e9c53c9f139fbc74e.tar
passt-fe37028466d3d29d74ebf53e9c53c9f139fbc74e.tar.gz
passt-fe37028466d3d29d74ebf53e9c53c9f139fbc74e.tar.bz2
passt-fe37028466d3d29d74ebf53e9c53c9f139fbc74e.tar.lz
passt-fe37028466d3d29d74ebf53e9c53c9f139fbc74e.tar.xz
passt-fe37028466d3d29d74ebf53e9c53c9f139fbc74e.tar.zst
passt-fe37028466d3d29d74ebf53e9c53c9f139fbc74e.zip
fwd, tcp, udp: Add forwarding rule to listening socket epoll references
Now that we have a table of all our forwarding rules, every listening socket can be associated with a specific rule. Add an index allowing us to locate that rule from the socket's epoll reference. We don't use it yet, but we'll use it to optimise rule lookup when forwarding new flows. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--fwd.c15
-rw-r--r--fwd.h3
-rw-r--r--tcp.c4
-rw-r--r--tcp.h5
-rw-r--r--udp.c4
-rw-r--r--udp.h5
6 files changed, 23 insertions, 13 deletions
diff --git a/fwd.c b/fwd.c
index 595fe4b..d224df5 100644
--- a/fwd.c
+++ b/fwd.c
@@ -484,6 +484,7 @@ void fwd_rules_print(const struct fwd_ports *fwd)
/** fwd_sync_one() - Create or remove listening sockets for a forward entry
* @c: Execution context
+ * @fwd: Forwarding table
* @rule: Forwarding rule
* @pif: Interface to create listening sockets for
* @proto: Protocol to listen for
@@ -491,19 +492,23 @@ void fwd_rules_print(const struct fwd_ports *fwd)
*
* Return: 0 on success, -1 on failure
*/
-static int fwd_sync_one(const struct ctx *c, const struct fwd_rule *rule,
+static int fwd_sync_one(const struct ctx *c,
+ const struct fwd_ports *fwd, const struct fwd_rule *rule,
uint8_t pif, uint8_t proto, const uint8_t *scanmap)
{
const union inany_addr *addr = fwd_rule_addr(rule);
const char *ifname = rule->ifname;
bool bound_one = false;
- unsigned port;
+ unsigned port, idx;
ASSERT(pif_is_socket(pif));
if (!*ifname)
ifname = NULL;
+ idx = rule - fwd->rules;
+ ASSERT(idx < MAX_FWD_RULES);
+
for (port = rule->first; port <= rule->last; port++) {
int fd = rule->socks[port - rule->first];
@@ -524,9 +529,9 @@ static int fwd_sync_one(const struct ctx *c, const struct fwd_rule *rule,
}
if (proto == IPPROTO_TCP)
- fd = tcp_listen(c, pif, addr, ifname, port);
+ fd = tcp_listen(c, pif, idx, addr, ifname, port);
else if (proto == IPPROTO_UDP)
- fd = udp_listen(c, pif, addr, ifname, port);
+ fd = udp_listen(c, pif, idx, addr, ifname, port);
else
ASSERT(0);
@@ -594,7 +599,7 @@ static int fwd_listen_sync_(void *arg)
ns_enter(a->c);
for (i = 0; i < a->fwd->count; i++) {
- a->ret = fwd_sync_one(a->c, &a->fwd->rules[i],
+ a->ret = fwd_sync_one(a->c, a->fwd, &a->fwd->rules[i],
a->pif, a->proto, a->fwd->map);
if (a->ret < 0)
break;
diff --git a/fwd.h b/fwd.h
index 184c176..5d914ec 100644
--- a/fwd.h
+++ b/fwd.h
@@ -51,14 +51,17 @@ struct fwd_rule {
* union fwd_listen_ref - information about a single listening socket
* @port: Bound port number of the socket
* @pif: pif in which the socket is listening
+ * @rule: Index of forwarding rule
*/
union fwd_listen_ref {
struct {
in_port_t port;
uint8_t pif;
+ unsigned rule :FWD_RULE_BITS;
};
uint32_t u32;
};
+static_assert(sizeof(union fwd_listen_ref) == sizeof(uint32_t));
enum fwd_ports_mode {
FWD_UNSET = 0,
diff --git a/tcp.c b/tcp.c
index a7fbff5..f49d953 100644
--- a/tcp.c
+++ b/tcp.c
@@ -2671,18 +2671,20 @@ 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,
+int tcp_listen(const struct ctx *c, uint8_t pif, unsigned rule,
const union inany_addr *addr, const char *ifname, in_port_t port)
{
union fwd_listen_ref ref = {
.port = port,
.pif = pif,
+ .rule = rule,
};
int s;
diff --git a/tcp.h b/tcp.h
index 45f97d9..24b9087 100644
--- a/tcp.h
+++ b/tcp.h
@@ -18,9 +18,8 @@ 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,
- const union inany_addr *addr, const char *ifname,
- in_port_t port);
+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_timer(const struct ctx *c, const struct timespec *now);
void tcp_defer_handler(struct ctx *c);
diff --git a/udp.c b/udp.c
index afb85df..7cb10a2 100644
--- a/udp.c
+++ b/udp.c
@@ -1115,18 +1115,20 @@ 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,
+int udp_listen(const struct ctx *c, uint8_t pif, unsigned rule,
const union inany_addr *addr, const char *ifname, in_port_t port)
{
union fwd_listen_ref ref = {
.pif = pif,
.port = port,
+ .rule = rule,
};
int s;
diff --git a/udp.h b/udp.h
index 3c6f90a..2b91d72 100644
--- a/udp.h
+++ b/udp.h
@@ -14,9 +14,8 @@ 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,
- const union inany_addr *addr, const char *ifname,
- in_port_t port);
+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);