* [PATCH] fwd, conf: Roll back to old rules if switching to new ones fails
@ 2026-10-29 16:28 Hayato Kiwata
2026-11-11 7:03 ` Stefano Brivio
0 siblings, 1 reply; 3+ messages in thread
From: Hayato Kiwata @ 2026-10-29 16:28 UTC (permalink / raw)
To: passt-dev; +Cc: Hayato Kiwata
If fwd_listen_init() fails while switching to new forwarding rules
received from pesto, we currently close the old listening sockets,
report an error and keep the (partially bound) new rules. That leaves
pasta in a state the user didn't ask for.
Make fwd_listen_switch() return the result of fwd_listen_init(), and
call it a second time from conf_handler() on failure to switch back
to the old rules.
Don't reset the count of the old table after closing its sockets, so
that the old rules stay in c->fwd_pending and can be restored. The
pending tables are cleared by conf_handler() before receiving new
rules anyway.
Note that reporting the failure to the client is left for a later patch.
Link: https://archives.passt.top/passt-dev/20261025153025.600a4fe9@elisabeth/
Signed-off-by: Hayato Kiwata <dev@haytok.jp>
---
This is a follow-up to the discussion on the dropped patch linked above.
Tested with:
$ pasta --ns-ifname=tap0 --mtu=65520 --config-net --address=10.0.2.100 \
--netmask=24 --gateway=10.0.2.2 --dns-forward=10.0.2.3 --no-map-gw \
--tcp-ns=none --udp-ns=none --ipv4-only --tcp-ports=none \
--udp-ports=none --conf-path=/tmp/.pasta.sock \
-- python3 -m http.server 80
$ pesto -A --tcp-ports=127.0.0.1/8085:80 /tmp/.pasta.sock
$ pesto -A --tcp-ports=192.0.2.1/8080:80 /tmp/.pasta.sock
$ pesto -s /tmp/.pasta.sock
passt/pasta configuration (/tmp/.pasta.sock)
HOST
TCP [127.0.0.1]:8085 => 80
SPLICE
$ curl -sI localhost:8085 | head -1
HTTP/1.0 200 OK
pasta logs:
Listen failed for HOST TCP port 192.0.2.1/8080: Cannot assign requested address
Couldn't listen on requested ports
Error switching to new forwarding rules
and the rule for port 8085 keeps working. Adding another valid rule
afterwards works as before.
conf.c | 7 ++++++-
fwd.c | 10 +++++-----
fwd.h | 2 +-
3 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/conf.c b/conf.c
index 149a4c7..0d10ea4 100644
--- a/conf.c
+++ b/conf.c
@@ -2222,7 +2222,12 @@ void conf_handler(struct ctx *c, uint32_t events)
" ", "");
}
- fwd_listen_switch(c);
+ if (fwd_listen_switch(c) < 0) {
+ err("Error switching to new forwarding rules");
+ /* Switch back to old rules (still in c->fwd_pending) */
+ if (fwd_listen_switch(c) < 0)
+ err("Couldn't restore old forwarding rules");
+ }
}
if (events & EPOLLHUP) {
diff --git a/fwd.c b/fwd.c
index 5679a3d..a081664 100644
--- a/fwd.c
+++ b/fwd.c
@@ -536,8 +536,10 @@ int fwd_listen_init(const struct ctx *c)
/**
* fwd_listen_switch() - Switch from current to pending rules table
* @c: Execution context
+ *
+ * Return: 0 on success, -1 on failure
*/
-void fwd_listen_switch(struct ctx *c)
+int fwd_listen_switch(struct ctx *c)
{
struct fwd_table *tmp[PIF_NUM_TYPES];
unsigned i;
@@ -549,9 +551,8 @@ void fwd_listen_switch(struct ctx *c)
if (!fwd)
continue;
- debug("Flushing %u old %s rules", fwd->count, pif_name(i));
+ debug("Flushing %u %s rules", fwd->count, pif_name(i));
fwd_listen_close(fwd);
- fwd->count = fwd->sock_count = 0;
}
/* Swap active and pending tables */
@@ -563,8 +564,7 @@ void fwd_listen_switch(struct ctx *c)
memcpy((void *)c->fwd_pending, &tmp, sizeof(c->fwd_pending));
/* Start listening on the new tables */
- if (fwd_listen_init(c) < 0)
- err("Error switching to new forwarding rules");
+ return fwd_listen_init(c);
}
/* See enum in kernel's include/net/tcp_states.h */
diff --git a/fwd.h b/fwd.h
index b60697d..a6c7bd8 100644
--- a/fwd.h
+++ b/fwd.h
@@ -61,7 +61,7 @@ int fwd_listen_sync(const struct ctx *c, uint8_t pif,
const struct fwd_scan *tcp, const struct fwd_scan *udp);
void fwd_listen_close(const struct fwd_table *fwd);
int fwd_listen_init(const struct ctx *c);
-void fwd_listen_switch(struct ctx *c);
+int fwd_listen_switch(struct ctx *c);
bool nat_inbound(const struct ctx *c, const union inany_addr *addr,
union inany_addr *translated);
--
2.50.1 (Apple Git-155)
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] fwd, conf: Roll back to old rules if switching to new ones fails
2026-10-29 16:28 [PATCH] fwd, conf: Roll back to old rules if switching to new ones fails Hayato Kiwata
@ 2026-11-11 7:03 ` Stefano Brivio
2026-11-11 8:57 ` David Gibson
0 siblings, 1 reply; 3+ messages in thread
From: Stefano Brivio @ 2026-11-11 7:03 UTC (permalink / raw)
To: Hayato Kiwata; +Cc: passt-dev
On Fri, 30 Oct 2026 01:28:58 +0900
Hayato Kiwata <dev@haytok.jp> wrote:
> If fwd_listen_init() fails while switching to new forwarding rules
> received from pesto, we currently close the old listening sockets,
> report an error and keep the (partially bound) new rules. That leaves
> pasta in a state the user didn't ask for.
>
> Make fwd_listen_switch() return the result of fwd_listen_init(), and
> call it a second time from conf_handler() on failure to switch back
> to the old rules.
Ah, right, brilliant! I didn't realise that it doesn't actually need
any further change because the other rules are always in c->fwd_pending.
> Don't reset the count of the old table after closing its sockets, so
> that the old rules stay in c->fwd_pending and can be restored. The
> pending tables are cleared by conf_handler() before receiving new
> rules anyway.
>
> Note that reporting the failure to the client is left for a later patch.
>
> Link: https://archives.passt.top/passt-dev/20261025153025.600a4fe9@elisabeth/
> Signed-off-by: Hayato Kiwata <dev@haytok.jp>
Applied, sorry for the delay.
--
Stefano
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] fwd, conf: Roll back to old rules if switching to new ones fails
2026-11-11 7:03 ` Stefano Brivio
@ 2026-11-11 8:57 ` David Gibson
0 siblings, 0 replies; 3+ messages in thread
From: David Gibson @ 2026-11-11 8:57 UTC (permalink / raw)
To: Stefano Brivio; +Cc: Hayato Kiwata, passt-dev
[-- Attachment #1: Type: text/plain, Size: 1015 bytes --]
On Wed, Nov 11, 2026 at 08:03:26AM +0100, Stefano Brivio wrote:
> On Fri, 30 Oct 2026 01:28:58 +0900
> Hayato Kiwata <dev@haytok.jp> wrote:
>
> > If fwd_listen_init() fails while switching to new forwarding rules
> > received from pesto, we currently close the old listening sockets,
> > report an error and keep the (partially bound) new rules. That leaves
> > pasta in a state the user didn't ask for.
> >
> > Make fwd_listen_switch() return the result of fwd_listen_init(), and
> > call it a second time from conf_handler() on failure to switch back
> > to the old rules.
>
> Ah, right, brilliant! I didn't realise that it doesn't actually need
> any further change because the other rules are always in
> c->fwd_pending.
Right, I made it that way on purpose to support this kind of revert.
--
David Gibson (he or they) | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you, not the other way
| around.
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-11-11 9:01 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-29 16:28 [PATCH] fwd, conf: Roll back to old rules if switching to new ones fails Hayato Kiwata
2026-11-11 7:03 ` Stefano Brivio
2026-11-11 8:57 ` David Gibson
Code repositories for project(s) associated with this public inbox
https://passt.top/passt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).