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=X7Jtg3Br; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by passt.top (Postfix) with ESMTPS id 538505A0271 for ; Tue, 13 Jan 2026 00:26:33 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1768260392; 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=Ix2V4sMWDgAkt7hDuM+dghfZvN+chs93iFLG7/8EZv0=; b=X7Jtg3BrOF+P2x6n3+mhwu6Akw+TV+4UmUfn7xQ5ZHPQLK9QTe9Nos7ucfc1arB695LtUA +c9LzF2Q/PM/C1AXgiuzb9mXEyC5btiNMSGHymLd1Mc5nXyHMwOO+AisMrENqV5C33jxva bNMsErWKRGYMRHrfD6AKTMVvaG8VS3g= 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-655-_RZf-eX_Mwy1MCv6c3-neg-1; Mon, 12 Jan 2026 18:26:31 -0500 X-MC-Unique: _RZf-eX_Mwy1MCv6c3-neg-1 X-Mimecast-MFC-AGG-ID: _RZf-eX_Mwy1MCv6c3-neg_1768260390 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-432488a0ce8so5239839f8f.2 for ; Mon, 12 Jan 2026 15:26:31 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768260389; x=1768865189; 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=Ix2V4sMWDgAkt7hDuM+dghfZvN+chs93iFLG7/8EZv0=; b=SuWaKhTSHiqWYWJcmDz3esHxwM68SIr9hp62rx2h86VyC6igye/3E8wK+UhXYGgBax QnGR4qrWnuWpgWoghseM86aC19R3e/IG2MrrdiBD7UIWlojmF4d/gfQKaTlbICERzSxZ eT+XsmIe441ZMqUblVS5FIn0wlkA8NaCFjrcx10rL9qohEnmOrs8vMOKYGz2+ZxHW635 dH/mY1G0pRAGw/+HwbALvLBEpU1Jc06Kigdrx3y4xuhX2l8Njj2WRJr2cEUxaywZIDzg SpuWCv2QdUOvHv9dsR0rV5ebzLSbhKbkf272GXr9h4thVQV9ntNbnNWdJdE2PDuJ1VOs IcVg== X-Gm-Message-State: AOJu0Yx5TE8zi0vfB0cklqeoN84MTZQKQlyWV1lYjj4L22QtojJY2m+m sCVfh+OzYBe6WHrMOzZzN9aQfhoiEFUnGb7iL4YhVQpI9CPdj2tEf0NHeD0QEL1DJqEpifODrVF AZnUkrsexmDLrgnysGkmEFjJ+Tac7BKfKEGWTQVR/sW7c49OHc4tRhw4UiwH4sQ== X-Gm-Gg: AY/fxX4YiWush4Rskwp03OuW37vwzN4lgZUwZ8n2R37LoOPg+LajJWgh5SH2ySU1Z2c dcQZScQJRpv2ogWwgMUyhroY/g8I1kjf5HI8SGI3I/cfHo5BQSLdV0fxTp6SUBjYb31+8qVEba7 KUWXQ+QEgSBHXZ12jBggNBSWd6pCLUWcy3M+EuuDilPlWqZ7OMwCIYq7skl3duERkvdO7Kr7Ztp CNndSGo+1+zJyeNtafpifnGKQHZrd+OGYmm0h1lg2j9kqdmvcLqd/m2qCe/6o8kqBqd14gRv4f3 V/APjzowMZNhANW4HJMXI/vem5O4O9P6A7xq2B/+ZxMPZe1i7QbAftyh3wQMz/yTUc/3dzG9hhK oAQgPkGx7IX3ewfoehdti X-Received: by 2002:a05:6000:24c2:b0:430:f68f:ee96 with SMTP id ffacd0b85a97d-432c37c8649mr21517832f8f.36.1768260389514; Mon, 12 Jan 2026 15:26:29 -0800 (PST) X-Google-Smtp-Source: AGHT+IGWYswsxafhhebQfPKNtYk+GwuElstlxcExKIP5uOF4XbqPIcMgUd7QVHHa8/b48FrytMmzqQ== X-Received: by 2002:a05:6000:24c2:b0:430:f68f:ee96 with SMTP id ffacd0b85a97d-432c37c8649mr21517814f8f.36.1768260389096; Mon, 12 Jan 2026 15:26:29 -0800 (PST) Received: from maya.myfinge.rs (ifcgrfdd.trafficplex.cloud. [2a10:fc81:a806:d6a9::1]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-432dfa6dc4esm19116821f8f.23.2026.01.12.15.26.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Jan 2026 15:26:28 -0800 (PST) Date: Tue, 13 Jan 2026 00:26:22 +0100 From: Stefano Brivio To: David Gibson Subject: Re: [PATCH v3 05/14] fwd: Make space to store listening sockets in forward table Message-ID: <20260113002622.48f32d54@elisabeth> In-Reply-To: <20260108022948.2657573-6-david@gibson.dropbear.id.au> References: <20260108022948.2657573-1-david@gibson.dropbear.id.au> <20260108022948.2657573-6-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: 5Zc3owZy6R5dwDyKMnaFGulHjIK_PEGis_4oQRyU47g_1768260390 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Message-ID-Hash: CSFIYN2U4H5TA5MHDZ3QL7I4Y462KLWA X-Message-ID-Hash: CSFIYN2U4H5TA5MHDZ3QL7I4Y462KLWA 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:39 +1100 David Gibson wrote: > At present, we don't keep track of the fds for listening sockets (except > for "auto" ones). Since the fd is stored in the epoll reference, we didn't > need an alternative source of it for the various handlers. > > However, we're intending to allow dynamic changes to forwarding > configuration in future. That means we need a way to enumerate sockets so > we can close them on removal of a forward. > > Extend our forwarding table data structure to make space for all the > listening sockets. To avoid allocation, this imposes another limit: > we could run out of space for socket fds before we run out of slots > for forwarding rules. > > We don't actually do anything with the allocate spaced yet. For > "auto" forwards it's redundant with existing arrays. We'll fix both > of those in later patches. > > Signed-off-by: David Gibson > --- > fwd.c | 10 +++++++++- > fwd.h | 13 +++++++++++++ > 2 files changed, 22 insertions(+), 1 deletion(-) > > diff --git a/fwd.c b/fwd.c > index 69aca441..f27a4220 100644 > --- a/fwd.c > +++ b/fwd.c > @@ -345,6 +345,7 @@ void fwd_rule_add(struct fwd_ports *fwd, uint8_t flags, > { > /* Flags which can be set from the caller */ > const uint8_t allowed_flags = FWD_WEAK | FWD_SCAN; > + unsigned num = (unsigned)last - first + 1; > struct fwd_rule *new; > unsigned port; > > @@ -352,6 +353,8 @@ void fwd_rule_add(struct fwd_ports *fwd, uint8_t flags, > > if (fwd->count >= ARRAY_SIZE(fwd->rules)) > die("Too many port forwarding ranges"); > + if ((fwd->listen_sock_count + num) > ARRAY_SIZE(fwd->listen_socks)) > + die("Too many listening sockets"); Here, and above: we plan to trigger this from a client at runtime, and if there are too many listening sockets, or too many rules/ranges, we should fail and report failure (ENOBUFS I guess) instead of quitting. > > new = &fwd->rules[fwd->count++]; > new->flags = flags; > @@ -373,8 +376,13 @@ void fwd_rule_add(struct fwd_ports *fwd, uint8_t flags, > > new->to = to; > > + new->socks = &fwd->listen_socks[fwd->listen_sock_count]; > + fwd->listen_sock_count += num; > + > for (port = new->first; port <= new->last; port++) { > - /* Fill in the legacy data structures to match the table */ > + new->socks[port - new->first] = -1; It's probably saner to initialise these, but just to confirm my understanding: this is not needed as (unlike what you have for rules) the array is always compacted and its used length described, right? > + > + /* Fill in the legacy forwarding data structures to match the table */ > if (!(new->flags & FWD_SCAN)) > bitmap_set(fwd->map, port); > fwd->delta[port] = new->to - new->first; > diff --git a/fwd.h b/fwd.h > index 94869c2a..3ddcb91d 100644 > --- a/fwd.h > +++ b/fwd.h > @@ -23,6 +23,7 @@ bool fwd_port_is_ephemeral(in_port_t port); > * @first: First port number to forward > * @last: Last port number to forward > * @to: Port number to forward port @first to. > + * @socks: Array of listening sockets for this entry > * @flags: Flag mask > * FWD_DUAL_STACK_ANY - match any IPv4 or IPv6 address (@addr should be ::) > * FWD_WEAK - Don't give an error if binds fail for some forwards > @@ -34,6 +35,7 @@ struct fwd_rule { > union inany_addr addr; > char ifname[IFNAMSIZ]; > in_port_t first, last, to; > + int *socks; > #define FWD_DUAL_STACK_ANY BIT(0) > #define FWD_WEAK BIT(1) > #define FWD_SCAN BIT(2) > @@ -65,6 +67,13 @@ enum fwd_ports_mode { > > #define PORT_BITMAP_SIZE DIV_ROUND_UP(NUM_PORTS, 8) > > +/* Maximum number of listening sockets (per pif & protocol) > + * > + * Rationale: This lets us listen on every port for two addresses (which we need > + * for -T auto without SO_BINDTODEVICE), plus a comfortable number of extras. > + */ > +#define MAX_LISTEN_SOCKS (NUM_PORTS * 3) > + > /** > * fwd_ports() - Describes port forwarding for one protocol and direction > * @mode: Overall forwarding mode (all, none, auto, specific ports) > @@ -74,6 +83,8 @@ enum fwd_ports_mode { > * @rules: Array of forwarding rules > * @map: Bitmap describing which ports are forwarded > * @delta: Offset between the original destination and mapped port number > + * @listen_sock_count: Number of entries used in @listen_socks > + * @listen_socks: Listening sockets for forwarding To keep those aligned: /** * fwd_ports() - Describes port forwarding for one protocol and direction * @mode: Overall forwarding mode (all, none, auto, some ports) * @scan4: /proc/net fd to scan for IPv4 ports when in AUTO mode * @scan6: /proc/net fd to scan for IPv6 ports when in AUTO mode * @count: Number of forwarding rules * @rules: Array of forwarding rules * @map: Bitmap describing which ports are forwarded * @delta: Offset between original and mapped destination port * @listen_sock_count: Number of entries used in @listen_socks * @listen_socks: Listening sockets for forwarding */ > */ > struct fwd_ports { > enum fwd_ports_mode mode; > @@ -83,6 +94,8 @@ struct fwd_ports { > struct fwd_rule rules[MAX_FWD_RULES]; > uint8_t map[PORT_BITMAP_SIZE]; > in_port_t delta[NUM_PORTS]; > + unsigned listen_sock_count; > + int listen_socks[MAX_LISTEN_SOCKS]; > }; > > #define FWD_PORT_SCAN_INTERVAL 1000 /* ms */ -- Stefano