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=U7GrlDNS; 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 179EE5A0265 for ; Wed, 08 Apr 2026 23:40:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775684421; 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=cjotGGuJ/7qD98yzX2QonP8tosZeJwkezXKmRB4Uu6M=; b=U7GrlDNSowqTWeU60kMKfjzbDtKVhxbAepH06fcg3vTL/noFxiE+RcJl3vWhhHSVaVBBBO 7yH7Jb6Y38/+Bn4BMJQA4zFnOXEax0ff25pQ3Dzub0XsUZS6jjnrwoT6iS7+UBDQshxESf x/VKfgRA2iEs1j8B8SYeth23YW1uXMw= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-116-GTVMUxh_MBGyXuhmCcTZ6Q-1; Wed, 08 Apr 2026 17:40:20 -0400 X-MC-Unique: GTVMUxh_MBGyXuhmCcTZ6Q-1 X-Mimecast-MFC-AGG-ID: GTVMUxh_MBGyXuhmCcTZ6Q_1775684419 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-43d06133455so96997f8f.3 for ; Wed, 08 Apr 2026 14:40:20 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775684418; x=1776289218; h=date:content-transfer-encoding:mime-version:organization:references :in-reply-to:message-id:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=cjotGGuJ/7qD98yzX2QonP8tosZeJwkezXKmRB4Uu6M=; b=LqqQPOtY+zSdD4A/pmTJTLXSHpi9b47dOpIbe2uwc0zN9bQsZJaGx+7BQsBRpXFDTT iGrCiJ8z87KaZk5ldZGK4gRwIrBJ7zkv63mU1GymiqQa1Nq3Vo2Jae5BIYXBgjINobBB BqGtjfpFEMoHECp6/lGmfR+tNfzkLrva1p8ueF0hUqIY8f6Vw8AMTf0dpa+Ps52ZXRuE vIPVRvvvJISUsQqr1k807D57EDjSHMR3/hmp4cIIRMdNykvH8j0hu3iHO/0dSmiWA65h RfqZWDPCYCHrWUFtsX0zoKCYU5Nip4cd5DhT3OZka+5qx1ThLxsO+KZpgq/iG+8O6tyu MX5Q== X-Gm-Message-State: AOJu0YyG5Z7NR8QvD3Os19R8iu9p9a5B8gZsvWYpcs73QxbJMAkr8tS3 x6m1qjUyHJgP0GgiUezwr+LZ1iyaGHSoJ8XK68G/wwnACeyLrS9N6Dd6xade6X7qO8i7zEQbXwQ /yRca0z0A68LRmgT8Eaho2DF3pm1lupcb+t2e52VaA6Q2cY0MJI+vsPX/jPwJpw== X-Gm-Gg: AeBDies6XMzuj/ZNGOG2wcJa+ktK2RkLcCuXrWEiHLLfN3mg0f/mBZWklGifFYdF4Cb rMcunfO4jWLTUnd/X27N05VIdh7BtJxRuP6uF/AEKSxmD5AQ4DBMcmSTYsLy0PJ571h+fZ4+p+n jcRh6Hf/isMKDG+7UTshz/Jk7ktRdWswjQECXbDwTx2gZGqpfYdD/5Tl/cELOTz6dVFjF041AyZ yPDu4cscc5LnFW4CmsE1PjOLCe8QoihPpah8l23Cb7OKqOXmLf+XJGaIkcNSHhX9HKYznEgQJ/I FfTbLx8zRQvxxnzdSnbrROrye5412XaYVCvV1UEj5xZrjClJoiroLMFHVu8j/gOPK6tpJzJEqRD 8TFDkX5YBAvYS5wmsbnzSgUseADfJ/+zF X-Received: by 2002:a05:600c:3549:b0:483:64b4:79da with SMTP id 5b1f17b1804b1-488997d5e84mr293123305e9.26.1775684418336; Wed, 08 Apr 2026 14:40:18 -0700 (PDT) X-Received: by 2002:a05:600c:3549:b0:483:64b4:79da with SMTP id 5b1f17b1804b1-488997d5e84mr293122995e9.26.1775684417688; Wed, 08 Apr 2026 14:40:17 -0700 (PDT) Received: from maya.myfinge.rs (ifcgrfdd.trafficplex.cloud. [2a10:fc81:a806:d6a9::1]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-488cf9e8808sm1225995e9.5.2026.04.08.14.40.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Apr 2026 14:40:16 -0700 (PDT) From: Stefano Brivio To: David Gibson Subject: Re: [PATCH 12/18] conf: Don't be strict about exclusivity of forwarding mode Message-ID: <20260408234015.242166e9@elisabeth> In-Reply-To: <20260407031630.2457081-13-david@gibson.dropbear.id.au> References: <20260407031630.2457081-1-david@gibson.dropbear.id.au> <20260407031630.2457081-13-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 Date: Wed, 08 Apr 2026 23:40:16 +0200 (CEST) X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: bCdXJH1xXUugWycs3ykrwl1haZYETUI7HFML_P1YALk_1775684419 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Message-ID-Hash: PD4R3ZQEU4COSRPEZNYNGPH6725F2G4B X-Message-ID-Hash: PD4R3ZQEU4COSRPEZNYNGPH6725F2G4B 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 Tue, 7 Apr 2026 13:16:24 +1000 David Gibson wrote: > Currently as well as building the forwarding tables, conf() maintains a > "forwarding mode" value for each protocol and direction. This prevents, > for example "-t all" and "-t 40000" being given on the same command line. > > This restriction predates the forwarding table and is no longer really > necessary. Remove the restriction, instead doing our best to apply all the > given options simultaneously. > > * Many combinations previously disallowed will still be disallowed because > of conflicts between the specific generated rules, e.g. > -t all -t 8888 > (because -t all already listens on port 8888) > * Some new combinations are now allowed and will work, e.g. > -t all -t 40000 > because 'all' excludes ephemeral ports (which includes 40000 on default > Linux configurations). This is slightly confusing though: $ ./pasta -t auto -t 31337 Forwarding configuration conflict: TCP [*]:31337 => 31337 versus TCP [*]:1-32767 => 1-32767 (best effort) (auto-scan) but I don't see a practical way to "fix" it for the moment being, and overall I'd say the new behaviour is better than the original one, so I don't really care. > * We remove our mode variables, but keep boolean variables to track if > any forwarding config option has been given. This is needed in order to > correctly default to -t auto -T auto -u auto -U auto for pasta. > * -[tTuU] none after any other rules is still considered an error. > However -t none *before* other rules is allowed. This is potentially > confusing, but is awkward to avoid for the time being. > > Signed-off-by: David Gibson > --- > conf.c | 97 ++++++++++++++++------------------------------------------ > 1 file changed, 27 insertions(+), 70 deletions(-) > > diff --git a/conf.c b/conf.c > index cd30f2f8..1e456361 100644 > --- a/conf.c > +++ b/conf.c > @@ -232,22 +232,6 @@ fail: > fwd_rule_fmt(&rule, rulestr, sizeof(rulestr))); > } > > -/** > - * enum fwd_mode - Overall forwarding mode for a direction and protocol > - * @FWD_MODE_UNSET Initial value, not parsed/configured yet > - * @FWD_MODE_SPEC Forward specified ports > - * @FWD_MODE_NONE No forwarded ports > - * @FWD_MODE_AUTO Automatic detection and forwarding based on bound ports > - * @FWD_MODE_ALL Bind all free ports > - */ > -enum fwd_mode { > - FWD_MODE_UNSET = 0, > - FWD_MODE_SPEC, > - FWD_MODE_NONE, > - FWD_MODE_AUTO, > - FWD_MODE_ALL, > -}; > - > /** > * conf_ports_spec() - Parse port range(s) specifier > * @c: Execution context > @@ -350,13 +334,12 @@ bad: > * @optname: Short option name, t, T, u, or U > * @optarg: Option argument (port specification) > * @fwd: Forwarding table to be updated > - * @mode: Overall port forwarding mode (updated) > */ > static void conf_ports(const struct ctx *c, char optname, const char *optarg, > - struct fwd_table *fwd, enum fwd_mode *mode) > + struct fwd_table *fwd) > { > union inany_addr addr_buf = inany_any6, *addr = &addr_buf; > - char buf[BUFSIZ], *spec, *ifname = NULL, *p; > + char buf[BUFSIZ], *spec, *ifname = NULL; > uint8_t proto; > > if (optname == 't' || optname == 'T') > @@ -367,10 +350,14 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg, > assert(0); > > if (!strcmp(optarg, "none")) { > - if (*mode) > - goto mode_conflict; > + unsigned i; > > - *mode = FWD_MODE_NONE; > + for (i = 0; i < fwd->count; i++) { > + if (fwd->rules[i].proto == proto) { > + die("-%c none conflicts with previous options", > + optname); > + } > + } > return; > } > > @@ -380,14 +367,9 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg, > die("UDP port forwarding requested but UDP is disabled"); > > if (!strcmp(optarg, "auto")) { > - if (*mode) > - goto mode_conflict; > - > if (c->mode != MODE_PASTA) > die("'auto' port forwarding is only allowed for pasta"); > > - *mode = FWD_MODE_AUTO; > - > conf_ports_range_except(c, optname, optarg, fwd, > proto, NULL, NULL, > 1, NUM_PORTS - 1, NULL, 1, FWD_SCAN); > @@ -398,11 +380,6 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg, > if (!strcmp(optarg, "all")) { > uint8_t exclude[PORT_BITMAP_SIZE] = { 0 }; > > - if (*mode) > - goto mode_conflict; > - > - *mode = FWD_MODE_ALL; > - > /* Exclude ephemeral ports */ > fwd_port_map_ephemeral(exclude); > > @@ -413,11 +390,6 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg, > return; > } > > - if (*mode > FWD_MODE_SPEC) > - die("Specific ports cannot be specified together with all/none/auto"); > - > - *mode = FWD_MODE_SPEC; > - > strncpy(buf, optarg, sizeof(buf) - 1); > > if ((spec = strchr(buf, '/'))) { > @@ -445,7 +417,7 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg, > if (ifname == buf + 1) { /* Interface without address */ > addr = NULL; > } else { > - p = buf; > + char *p = buf; > > /* Allow square brackets for IPv4 too for convenience */ > if (*p == '[' && p[strlen(p) - 1] == ']') { > @@ -482,10 +454,6 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg, > ifname = "lo"; > > conf_ports_spec(c, optname, optarg, fwd, proto, addr, ifname, spec); > - return; > - > -mode_conflict: > - die("Port forwarding mode '%s' conflicts with previous mode", optarg); > } > > /** > @@ -1594,12 +1562,9 @@ void conf(struct ctx *c, int argc, char **argv) > }; > const char *optstring = "+dqfel:hs:F:I:p:P:m:a:n:M:g:i:o:D:S:H:461t:u:T:U:"; > const char *logname = (c->mode == MODE_PASTA) ? "pasta" : "passt"; > + bool opt_t = false, opt_T = false, opt_u = false, opt_U = false; > char userns[PATH_MAX] = { 0 }, netns[PATH_MAX] = { 0 }; > bool copy_addrs_opt = false, copy_routes_opt = false; > - enum fwd_mode tcp_out_mode = FWD_MODE_UNSET; > - enum fwd_mode udp_out_mode = FWD_MODE_UNSET; > - enum fwd_mode tcp_in_mode = FWD_MODE_UNSET; > - enum fwd_mode udp_in_mode = FWD_MODE_UNSET; > bool v4_only = false, v6_only = false; > unsigned dns4_idx = 0, dns6_idx = 0; > unsigned long max_mtu = IP_MAX_MTU; > @@ -2204,17 +2169,17 @@ void conf(struct ctx *c, int argc, char **argv) > name = getopt_long(argc, argv, optstring, options, NULL); > > if (name == 't') { > - conf_ports(c, name, optarg, c->fwd[PIF_HOST], > - &tcp_in_mode); > + opt_t = true; > + conf_ports(c, name, optarg, c->fwd[PIF_HOST]); > } else if (name == 'u') { > - conf_ports(c, name, optarg, c->fwd[PIF_HOST], > - &udp_in_mode); > + opt_u = true; > + conf_ports(c, name, optarg, c->fwd[PIF_HOST]); > } else if (name == 'T') { > - conf_ports(c, name, optarg, c->fwd[PIF_SPLICE], > - &tcp_out_mode); > + opt_T = true; > + conf_ports(c, name, optarg, c->fwd[PIF_SPLICE]); > } else if (name == 'U') { > - conf_ports(c, name, optarg, c->fwd[PIF_SPLICE], > - &udp_out_mode); > + opt_U = true; > + conf_ports(c, name, optarg, c->fwd[PIF_SPLICE]); > } > } while (name != -1); > > @@ -2265,22 +2230,14 @@ void conf(struct ctx *c, int argc, char **argv) > } > > if (c->mode == MODE_PASTA) { > - if (!tcp_in_mode) { > - conf_ports(c, 't', "auto", > - c->fwd[PIF_HOST], &tcp_in_mode); > - } > - if (!tcp_out_mode) { > - conf_ports(c, 'T', "auto", > - c->fwd[PIF_SPLICE], &tcp_out_mode); > - } > - if (!udp_in_mode) { > - conf_ports(c, 'u', "auto", > - c->fwd[PIF_HOST], &udp_in_mode); > - } > - if (!udp_out_mode) { > - conf_ports(c, 'U', "auto", > - c->fwd[PIF_SPLICE], &udp_out_mode); > - } > + if (!opt_t) > + conf_ports(c, 't', "auto", c->fwd[PIF_HOST]); > + if (!opt_T) > + conf_ports(c, 'T', "auto", c->fwd[PIF_SPLICE]); > + if (!opt_u) > + conf_ports(c, 'u', "auto", c->fwd[PIF_HOST]); > + if (!opt_U) > + conf_ports(c, 'U', "auto", c->fwd[PIF_SPLICE]); > } > > if (!c->quiet) -- Stefano