aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2026-01-16 11:59:15 +1100
committerStefano Brivio <sbrivio@redhat.com>2026-01-18 12:47:35 +0100
commit9323ab97c4abeba07b43060294069b43c8c32316 (patch)
tree9de58484e1bc93cfc779d25c69f951c9e4860cad
parentbd52f61e48458b4dd8a4bc4ae80d9bccca7e33d3 (diff)
downloadpasst-9323ab97c4abeba07b43060294069b43c8c32316.tar
passt-9323ab97c4abeba07b43060294069b43c8c32316.tar.gz
passt-9323ab97c4abeba07b43060294069b43c8c32316.tar.bz2
passt-9323ab97c4abeba07b43060294069b43c8c32316.tar.lz
passt-9323ab97c4abeba07b43060294069b43c8c32316.tar.xz
passt-9323ab97c4abeba07b43060294069b43c8c32316.tar.zst
passt-9323ab97c4abeba07b43060294069b43c8c32316.zip
conf: Accurately record ifname and address for outbound forwards
-T and -U options don't allow specifying a listening address. Usually this will listen on *%lo in the guest. However on kernels without unprivileged SO_BINDTODEVICE that's not possible so we instead listen separately on 127.0.0.1 and ::1. Currently that's handled at the point we actually set up the listens, we record both address and ifname as NULL in the forwarding table entry. That will cause trouble for future extensions we want, so update this to accurately create the forwarding table: either a single rule with ifname == "lo" or two rules with addresses of 127.0.0.1 and ::1. As a bonus, this gives the user a warning if they specify an explicit outbound forwarding on a kernel without SO_BINDTODEVICE. The existing warning for missing SO_BINDTODEVICE incorrectly covered only the case of -T auto or -U auto. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--conf.c38
1 files changed, 30 insertions, 8 deletions
diff --git a/conf.c b/conf.c
index 7ad0946..475dbe0 100644
--- a/conf.c
+++ b/conf.c
@@ -157,12 +157,6 @@ static void conf_ports_range_except(const struct ctx *c, char optname,
optname, optarg);
}
- if (ifname && c->no_bindtodevice) {
- die(
-"Device binding for '-%c %s' unsupported (requires kernel 5.7+)",
- optname, optarg);
- }
-
if (addr) {
if (!c->ifi4 && inany_v4(addr)) {
die("IPv4 is disabled, can't use -%c %s",
@@ -209,8 +203,27 @@ static void conf_ports_range_except(const struct ctx *c, char optname,
}
}
- fwd_rule_add(fwd, flags, addr, ifname, base, i - 1,
- base + delta);
+ if ((optname == 'T' || optname == 'U') && c->no_bindtodevice) {
+ /* FIXME: Once the fwd bitmaps are removed, move this
+ * workaround to the caller
+ */
+ ASSERT(!addr && ifname && !strcmp(ifname, "lo"));
+ warn(
+"SO_BINDTODEVICE unavailable, forwarding only 127.0.0.1 and ::1 for '-%c %s'",
+ optname, optarg);
+
+ if (c->ifi4) {
+ fwd_rule_add(fwd, flags, &inany_loopback4, NULL,
+ base, i - 1, base + delta);
+ }
+ if (c->ifi6) {
+ fwd_rule_add(fwd, flags, &inany_loopback6, NULL,
+ base, i - 1, base + delta);
+ }
+ } else {
+ fwd_rule_add(fwd, flags, addr, ifname,
+ base, i - 1, base + delta);
+ }
base = i - 1;
}
@@ -357,6 +370,15 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg,
}
} while ((p = next_chunk(p, ',')));
+ if (ifname && c->no_bindtodevice) {
+ die(
+"Device binding for '-%c %s' unsupported (requires kernel 5.7+)",
+ optname, optarg);
+ }
+ /* Outbound forwards come from guest loopback */
+ if ((optname == 'T' || optname == 'U') && !ifname)
+ ifname = "lo";
+
if (exclude_only) {
/* Exclude ephemeral ports */
for (i = 0; i < NUM_PORTS; i++)