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=f64rIta+; 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 E48A15A026D for ; Wed, 08 Apr 2026 23:40:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775684446; 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=V0/7UMjiDIROmMt2oMQrZ3CYCXmlPwvw1fCfw1i5CUc=; b=f64rIta+tXZ4B3o3hiLwXd64BhbjkO7V+pQ+5saVasKBfVcePm1C6b5CjOUqzvEV+wHVxl WBd2Y+6Lat4bA6TC2YU8iEV91mHi2cdXjzefU9aIirNP+3Av5wfX+MTZpopynQiqlOdtHd VvxpaZ+Zn+6ZmJqYKm1p4rVIWBfI6WI= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-62-Ji-fDIBZPSmSq5ZsV1tdLw-1; Wed, 08 Apr 2026 17:40:45 -0400 X-MC-Unique: Ji-fDIBZPSmSq5ZsV1tdLw-1 X-Mimecast-MFC-AGG-ID: Ji-fDIBZPSmSq5ZsV1tdLw_1775684444 Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-43d1fec59c9so80443f8f.0 for ; Wed, 08 Apr 2026 14:40:45 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775684444; x=1776289244; 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=V0/7UMjiDIROmMt2oMQrZ3CYCXmlPwvw1fCfw1i5CUc=; b=fUkBJ22KsMgiCMNboTtCa9rU0L74pZKnMVyUxO3PNmvUf42hCWQXy7gmB7Lg8zQyb+ /XKtDmYSrUWIrsESyONNyduuM6pjo07wgy463emJkCI8vq1DcA0JfUTvndS28DHrHGUF oyQFjZBuoUr4ubki0ULyjv1mvO5BR6vqPvPb0QO+GRWtFIVbQUE4CLYToD3wtmzMIbG4 AhReaKhEexBZRlKM1KE5fnZ88L7Rb3XA0L25vRYbxXlpkFDsk98aK9IpOjtAomfqwTej rfsyrfzL6Ynb1LY6Y3wRZMTrAktAFf8fjb8jkKumxH+hLMeRPTWwm9XLk2Iap00SiwBT wPNA== X-Gm-Message-State: AOJu0YzM29eyBEjxed/LQEyLZLG4QBY+lNhdg0C28VF2oxsPemJudkU4 L5jr2baDj1Gyz+7AP3IOhRRdo85zvv6gEgUH8Z335PZsG7yUjxt/NvzmG+pqk1KmH+sARAdktdL oWitc0JIsNgYr3slu4v16vYMU9m3L+NK7vuBoUbDA/WbHZpX2oaoHTGmfR5B3bQ== X-Gm-Gg: AeBDievECqe06r5CNFf8uyj3yDy7ltOS9+k1W0+fbPxByV3FE2bbm5B9nJ/+i35AFq0 WpmHjx6xBHuBEtoWpAKWaTHLBeEoD0XKQyqHRWLhnrGOC/wSKUavZICAgPgAVm2eeeTv3V25XnA XMJl7/OXZZPmW3uv8eL0KkJLoR0LZpbg1iWkutByWbjO0w9qSbj5Tcs8MS+4J/3FWg2nyv3cofn tF8ZF5r3uPuIJgP1koDOAntQbgjc3joK/2Mc/x/jtJcJNh1USNKGbDAkPwwLk/OBop20HPlPjFR or0vx1SYNQ19NShX9hxPIy20132ISTYuIldI6FYe/NaOAG9nRp5oZ9rBEmA0tV8MEUWXdhl6A8j cheyMrCEwC2JCeT7Ag0qxmYnYhnUhGOk+TePWr2qf2OlAgXptgg== X-Received: by 2002:a05:6000:1869:b0:43c:f650:cc97 with SMTP id ffacd0b85a97d-43d59584167mr1419153f8f.9.1775684443876; Wed, 08 Apr 2026 14:40:43 -0700 (PDT) X-Received: by 2002:a05:6000:1869:b0:43c:f650:cc97 with SMTP id ffacd0b85a97d-43d59584167mr1419123f8f.9.1775684443333; Wed, 08 Apr 2026 14:40:43 -0700 (PDT) Received: from maya.myfinge.rs (ifcgrfdd.trafficplex.cloud. [176.103.220.4]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43d1e4f1a99sm65445788f8f.32.2026.04.08.14.40.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Apr 2026 14:40:42 -0700 (PDT) From: Stefano Brivio To: David Gibson Subject: Re: [PATCH 16/18] conf: Allow user-specified auto-scanned port forwarding ranges Message-ID: <20260408234041.636a01af@elisabeth> In-Reply-To: <20260407031630.2457081-17-david@gibson.dropbear.id.au> References: <20260407031630.2457081-1-david@gibson.dropbear.id.au> <20260407031630.2457081-17-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:42 +0200 (CEST) X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 9tJURFtAsZIgnqSlD-ZZ3Eu_wx82QQeI7x7K7_y0HMg_1775684444 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Message-ID-Hash: EPU7HYZXUW2RO5SF6B5EN2U3FACGCEIK X-Message-ID-Hash: EPU7HYZXUW2RO5SF6B5EN2U3FACGCEIK 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:28 +1000 David Gibson wrote: > The forwarding table now allows for arbitrary port ranges to be marked as > FWD_SCAN, meaning we don't open sockets for every port, but only those we > scan as listening on the target side. However, there's currently no way > to create such rules, except -[tTuU] auto which always scans every port > with an unspecified listening address and interface. > > Allow user-specified "auto" ranges by moving the parsing of the "auto" > keyword from conf_ports(), to conf_ports_spec() as part of the port > specified. "auto" can be combined freely with other port ranges, e.g. > -t 127.0.0.1/auto > -u %lo/5000-7000,auto > -T auto,12345 > -U auto,~1-9000 > > Note that any address and interface given only affects where the automatic > forwards listen, not what addresses we consider when scanning. That is, > if the target side is listening on *any* address, we will create a forward > on the specified address. > > Link: https://bugs.passt.top/show_bug.cgi?id=180 > > Signed-off-by: David Gibson > --- > conf.c | 66 ++++++++++++++++++++++++++++++++++++++++++---------------- > 1 file changed, 48 insertions(+), 18 deletions(-) > > diff --git a/conf.c b/conf.c > index fcc75d25..86c30c7f 100644 > --- a/conf.c > +++ b/conf.c > @@ -13,6 +13,7 @@ > */ > > #include > +#include > #include > #include > #include > @@ -112,6 +113,28 @@ static int parse_port_range(const char *s, const char **endptr, > return 0; > } > > +/** > + * parse_keyword() - Parse a literal keyword Here, "parse" sounds overly generic. If I understand this correctly, it's a strstr() / memmem() implementation with the added 'endptr' functionality, so maybe... "Find the end of a substring"? > + * @s: String to parse > + * @endptr: Update to the character after the keyword > + * @kw: Keyword to accept > + * > + * Return: 0, if @s starts with @kw, -EINVAL if it does not > + */ > +static int parse_keyword(const char *s, const char **endptr, const char *kw) > +{ > + size_t len = strlen(kw); > + > + if (strlen(s) < len) > + return -EINVAL; > + > + if (memcmp(s, kw, len)) > + return -EINVAL; > + > + *endptr = s + len; > + return 0; > +} > + > /** > * conf_ports_range_except() - Set up forwarding for a range of ports minus a > * bitmap of exclusions > @@ -249,6 +272,7 @@ static void conf_ports_spec(const struct ctx *c, > uint8_t exclude[PORT_BITMAP_SIZE] = { 0 }; > bool exclude_only = true; > const char *p, *ep; > + uint8_t flags = 0; > unsigned i; > > if (!strcmp(spec, "all")) { > @@ -256,15 +280,32 @@ static void conf_ports_spec(const struct ctx *c, > spec = ""; > } > > - /* Mark all exclusions first, they might be given after base ranges */ > + /* Parse excluded ranges and "auto" in the first pass */ > for_each_chunk(p, ep, spec, ",") { > struct port_range xrange; > > - if (*p != '~') { > - /* Not an exclude range, parse later */ > + if (isdigit(*p)) { > + /* Include range, parse later */ > exclude_only = false; > continue; > } > + > + if (parse_keyword(p, &p, "auto") == 0) { > + if (p != ep) /* Garbage after the keyword */ > + goto bad; > + > + if (c->mode != MODE_PASTA) { > + die( > +"'auto' port forwarding is only allowed for pasta"); > + } > + > + flags |= FWD_SCAN; > + continue; > + } > + > + /* Should be an exclude range */ > + if (*p != '~') > + goto bad; > p++; > > if (parse_port_range(p, &p, &xrange)) > @@ -283,7 +324,7 @@ static void conf_ports_spec(const struct ctx *c, > conf_ports_range_except(c, optname, optarg, fwd, > proto, addr, ifname, > 1, NUM_PORTS - 1, exclude, > - 1, FWD_WEAK); > + 1, flags | FWD_WEAK); > return; > } > > @@ -291,8 +332,8 @@ static void conf_ports_spec(const struct ctx *c, > for_each_chunk(p, ep, spec, ",") { > struct port_range orig_range, mapped_range; > > - if (*p == '~') > - /* Exclude range, already parsed */ > + if (!isdigit(*p)) > + /* Already parsed */ > continue; > > if (parse_port_range(p, &p, &orig_range)) > @@ -320,7 +361,7 @@ static void conf_ports_spec(const struct ctx *c, > proto, addr, ifname, > orig_range.first, orig_range.last, > exclude, > - mapped_range.first, 0); > + mapped_range.first, flags); > } > > return; > @@ -366,17 +407,6 @@ static void conf_ports(const struct ctx *c, char optname, const char *optarg, > if (proto == IPPROTO_UDP && c->no_udp) > die("UDP port forwarding requested but UDP is disabled"); > > - if (!strcmp(optarg, "auto")) { > - if (c->mode != MODE_PASTA) > - die("'auto' port forwarding is only allowed for pasta"); > - > - conf_ports_range_except(c, optname, optarg, fwd, > - proto, NULL, NULL, > - 1, NUM_PORTS - 1, NULL, 1, FWD_SCAN); > - > - return; > - } > - > strncpy(buf, optarg, sizeof(buf) - 1); > > if ((spec = strchr(buf, '/'))) { The rest of the series looks good to me! -- Stefano