From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: passt.top; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=e0CxYIs4; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by passt.top (Postfix) with ESMTPS id B18085A004E for ; Tue, 13 Jan 2026 23:12:41 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1768342360; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pkuOrIoKoRHQS1RLaqLRntyVeC6xkF+1feH02b2VZZE=; b=e0CxYIs4AhQGFE1OYOzTOX4kpB4wA87/x0QcWea8U7l2BB9d754V8dWzzzfpUlvyDfHF+/ I7kMFNiioabRoHik+vxkOeJRGb0+54At3oVqiiAu4D1Xqa41b6oOPx9qI2BIVtGiwvK0ug Bx70oxNNA6xBFdsgejA/AB6xiz5iS+E= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-252-PVxvZlY4NW-ehq-ZnPC-iA-1; Tue, 13 Jan 2026 17:12:39 -0500 X-MC-Unique: PVxvZlY4NW-ehq-ZnPC-iA-1 X-Mimecast-MFC-AGG-ID: PVxvZlY4NW-ehq-ZnPC-iA_1768342358 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-42fb1c2c403so5881683f8f.3 for ; Tue, 13 Jan 2026 14:12:39 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768342358; x=1768947158; h=content-transfer-encoding:mime-version:organization:references :in-reply-to:message-id:subject:cc:to:from:date:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=pkuOrIoKoRHQS1RLaqLRntyVeC6xkF+1feH02b2VZZE=; b=LbJvMiS4ivg0MmCt43UVIx4GbcKvgxHIEyRjFWDtbk/gVQkmOp0XfncwzDFFZwJe+L M1/4XTiEywiJhoxVEmDnpFXl/n/oJB4SNgqKJLVp9fy/+EeeOl/CE6tD/1dFKy2htfR6 /ZNWwq61YZ3k+T5NGSlDsb0qsQmOVTjydhlzPb5i/9ialjmi3ngXXEhJn+m+MAq5KDsw bMXqO/fJU//6/kEPQgNDekbHC11FfJASBowfMwPwMCcoufMhQfWk5aowOylVPa8tgVeC S7LSMRuf2cUfVKg3eqwMmnuBmkaDzfysnT1hvmA36zPi+br4Orz3+3p5x6XHWro6dr8z VOjA== X-Gm-Message-State: AOJu0Yxoc87FkBfA0ahETNUitTsEcYzAAsvuV4iMPhIY766+yVlWsviz Zou4A7WPnqDKTBD77G1nL1641WKS8ynfsYRNtDp1O7ApclJ2/LuLK0YiR7fKeRkRGhqu7qUrBbK 8pr7hqxKpboW++gXTbGT45FtcJ6uqyxJ27y4gGR3ECKwmSoyfcY/rMg== X-Gm-Gg: AY/fxX5WeIrNePIRjG2JfPW0upMh0Y8bNcAcrY+VqfjutQ9ZElMvbaWJN6EF/pXMoiQ E220KcEVo3tb5RV+wHuMB/XM/NFwiJQAHFLsGYOiR36E5VBvUnQS5LAom3cv12w0Rx1QkD/HPNh TnvJduw9+jGXHjq+HBtgMt0f//8jUSxFcCDetKALilC2Uj2fmuhB3wJrm3oHFuEYWM0zwX63Dhd NeQ3Zm+UhoaTo+bLMkRq1LAorRuR1hsCzhD02JVNk3hvZmZL9BsC3ehpHLwWV7FwEP2r1SDWOj7 koTKPzfSVrHWZ6McrJrIsaYGq4kmfF1MGNbW0a2ll8guO73WeFq7+5NHS3C+ByQDOIHQK5wT6H/ LlgbUgD40i7eaNgIQY9IabWIq974YPeYsw3dx+Q== X-Received: by 2002:a05:6000:c83:b0:431:701:4a1a with SMTP id ffacd0b85a97d-4342d391e17mr12703f8f.26.1768342358247; Tue, 13 Jan 2026 14:12:38 -0800 (PST) X-Received: by 2002:a05:6000:c83:b0:431:701:4a1a with SMTP id ffacd0b85a97d-4342d391e17mr12692f8f.26.1768342357792; Tue, 13 Jan 2026 14:12:37 -0800 (PST) Received: from maya.myfinge.rs (ifcgrfdd.trafficplex.cloud. [176.103.220.4]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-432bd5ff1e9sm48369622f8f.41.2026.01.13.14.12.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Jan 2026 14:12:36 -0800 (PST) Date: Tue, 13 Jan 2026 23:12:35 +0100 From: Stefano Brivio To: David Gibson Subject: Re: [PATCH v3 13/14] fwd, tcp, udp: Add forwarding rule to listening socket epoll references Message-ID: <20260113231235.544d72f8@elisabeth> In-Reply-To: <20260108022948.2657573-14-david@gibson.dropbear.id.au> References: <20260108022948.2657573-1-david@gibson.dropbear.id.au> <20260108022948.2657573-14-david@gibson.dropbear.id.au> Organization: Red Hat X-Mailer: Claws Mail 4.2.0 (GTK 3.24.49; x86_64-pc-linux-gnu) MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: p2JSZhXAkxh_Pvn7qGDY1_5OYfQVLEsdNGAQW8TkF9E_1768342358 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Message-ID-Hash: OSZPSCIBTKLYJEHWQYXGJ63NEZ5B4ESM X-Message-ID-Hash: OSZPSCIBTKLYJEHWQYXGJ63NEZ5B4ESM X-MailFrom: sbrivio@redhat.com 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: passt-dev@passt.top 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: On Thu, 8 Jan 2026 13:29:47 +1100 David Gibson wrote: > 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 > --- > fwd.c | 15 ++++++++++----- > fwd.h | 5 +++++ > tcp.c | 4 +++- > tcp.h | 5 ++--- > udp.c | 4 +++- > udp.h | 5 ++--- > 6 files changed, 25 insertions(+), 13 deletions(-) > > diff --git a/fwd.c b/fwd.c > index 7c4575ff..6727d26f 100644 > --- a/fwd.c > +++ b/fwd.c > @@ -474,6 +474,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 > @@ -481,19 +482,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]; > > @@ -514,9 +519,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); > > @@ -588,7 +593,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 cfe9ed46..435f422a 100644 > --- a/fwd.h > +++ b/fwd.h > @@ -48,14 +48,19 @@ 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; > +#define FWD_RULE_BITS 8 > + unsigned rule :FWD_RULE_BITS; > }; > uint32_t u32; > }; > +static_assert(sizeof(union fwd_listen_ref) == sizeof(uint32_t)); Why do we need this, specifically? > +static_assert(MAX_FWD_RULES <= (1U << FWD_RULE_BITS)); I start wondering if instead of having a 'rule' field supporting 256 rules, with 128 as maximum number of rules, we could just have 256 as maximum number of rules and use the usual MAX_FROM_BITS() macro to keep things simpler. After all, it's not really rules[] taking space: struct fwd_ports { enum fwd_ports_mode mode; /* 0 4 */ int scan4; /* 4 4 */ int scan6; /* 8 4 */ unsigned int count; /* 12 4 */ struct fwd_rule rules[128]; /* 16 7168 */ /* --- cacheline 112 boundary (7168 bytes) was 16 bytes ago --- */ uint8_t map[8192]; /* 7184 8192 */ /* --- cacheline 240 boundary (15360 bytes) was 16 bytes ago --- */ unsigned int listen_sock_count; /* 15376 4 */ int listen_socks[196608]; /* 15380 786432 */ /* size: 801816, cachelines: 12529, members: 8 */ /* padding: 4 */ /* last cacheline: 24 bytes */ }; > enum fwd_ports_mode { > FWD_UNSET = 0, > diff --git a/tcp.c b/tcp.c > index e9b440da..fc03e38f 100644 > --- a/tcp.c > +++ b/tcp.c > @@ -2672,18 +2672,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 45f97d93..24b90870 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 92a87198..761221f6 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 3c6f90a9..2b91d728 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); > -- Stefano