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=FriPmVRN; 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 AD0C65A0265 for ; Wed, 06 May 2026 14:27:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1778070452; 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=dHcd3F1rVvaysL2cfkWO5lz8jnGYXUjXk4Hnse2g5WI=; b=FriPmVRNGve8cuaVlXOixG1kdD9FjPNLe9jzDoZWTjPKu51vj6TE8Fl0jl3qf4ksBBd/5f oV+IbLNDQj39qo/ODXUU/V7l0BQPhHFFHS2ysM2cX8ubQN1V2ka+C1y9zHk9QFtK0hk/jC a/Hi1vho6lbHJkq5BU1AqYeumrA6d5o= 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-676-vfgDUglYNP-qEmhDj0UMbw-1; Wed, 06 May 2026 08:27:31 -0400 X-MC-Unique: vfgDUglYNP-qEmhDj0UMbw-1 X-Mimecast-MFC-AGG-ID: vfgDUglYNP-qEmhDj0UMbw_1778070450 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-43d7730e9e3so4006927f8f.2 for ; Wed, 06 May 2026 05:27:31 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778070450; x=1778675250; 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=dHcd3F1rVvaysL2cfkWO5lz8jnGYXUjXk4Hnse2g5WI=; b=AeeoBL/83mbn75svpi0zqIfUHEswJwN2760Gvexf9tdjrmugeUno8jo7M+e/AMKbUP ZDI5Q8pcgndBG52AtYf8dhZ1JeT8MfRB79uX2XgSTSjz+aTpUe8LeolW/flpH/DQjKoT yNME4vMGAmWI08HbdSYMVWLWG3/WkDukqvwrU+kS1AqI6wQPQBeqIbh9g2LiN5U2GYtG 2rzbZ13/bU9hqiHe8F/Ms/7yPDSFbrd0uxepfNvHn7Hc1pUhAIpe68njs2aO2OZg6CMb qzQ8Yyt7F3dSoTSyyWvcomnXXBnGVPTdR9s1qMLBLmQRPbqVjFpVuXjYckjqZOz5ps7A glNg== X-Gm-Message-State: AOJu0YzpZTgkggWDEvlpUZeCKKcbrUo097eOOpnfPgPIlVrK/OihTVVy TMXKLgA0DFkXjn1dkEmfVNVtEZf+6QFE9Gn0pWXAhDYQGckVExnsLWO6vgkNcbusEZIon2a+wPQ 2hUEItJtS7cRQSQ+neHP+wNicTI3Yb2+A1UObL4ZmtkKKswC8tZeFvg== X-Gm-Gg: AeBDievM6Z7SzgzCECzObDvn8dZWi9XYblZYVPziaff9DO0tESCpsXTtH/Nx3AiepWF ayKJX3peRKc+osLWe+jAHltW5IS58YJSgOisZw8UopLGU3KlPRT63rnE7cImyvvD2MgIEOCMlrW Wfexw8cL1KcbNWTPoPAWp3O5BD8p+WhP6WJCWbwSnndj4ki8x5FfH9BttO8KzRHoYiqp8fQSMKM g8ukG40NvwRrMrclj0HrtzLJq2/GTz2kbMIPVbWHmEO4DcWq+cGjiFNiF0zQPJq0eQLEWZzIgON UQvd+sl3JrpjmZYBXB4t63r2ZFMhlJLNCyBvSHM9rk7ah3KIUUhD1FqLXUESGp77vzuOJ24ndeK ah7iTIT9cb3zbVHLxcY9/ue6DfTSdCO1pVZowKdiZCnE= X-Received: by 2002:a05:600c:3f18:b0:48e:5990:9698 with SMTP id 5b1f17b1804b1-48e5990978bmr10189705e9.24.1778070450317; Wed, 06 May 2026 05:27:30 -0700 (PDT) X-Received: by 2002:a05:600c:3f18:b0:48e:5990:9698 with SMTP id 5b1f17b1804b1-48e5990978bmr10189135e9.24.1778070449774; Wed, 06 May 2026 05:27:29 -0700 (PDT) Received: from maya.myfinge.rs (ifcgrfdd.trafficplex.cloud. [2a10:fc81:a806:d6a9::1]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48e538acf23sm43130255e9.8.2026.05.06.05.27.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 May 2026 05:27:29 -0700 (PDT) From: Stefano Brivio To: Laurent Vivier Subject: Re: [PATCH v9 19/23] pesto, conf, fwd_rule: Add options and modes to add, delete, clear rules Message-ID: <20260506142728.461652b6@elisabeth> In-Reply-To: <20260506140737.76a2c852@elisabeth> References: <20260506092241.1607480-1-sbrivio@redhat.com> <20260506092241.1607480-20-sbrivio@redhat.com> <16808ac4-263d-47cd-9ef1-65bbe4c15493@redhat.com> <20260506140737.76a2c852@elisabeth> 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, 06 May 2026 14:27:28 +0200 (CEST) X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: d6-TCFN8v7N9nVxuJvtLzOCMMdcVLuqIV8H0HlDtEPs_1778070450 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Message-ID-Hash: WIUF7HUPEBJOJRVAWHFFZBBBRNEUJZB6 X-Message-ID-Hash: WIUF7HUPEBJOJRVAWHFFZBBBRNEUJZB6 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, Jon Maloy , David Gibson 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 Wed, 6 May 2026 14:07:37 +0200 Stefano Brivio wrote: > On Wed, 6 May 2026 13:43:07 +0200 > Laurent Vivier wrote: > > > On 5/6/26 11:22, Stefano Brivio wrote: > > > Instead of just being able to add to the existing tables, implement > > > an explicit --clear option to replace them, which now becomes the > > > default behaviour, and implement explicit --add and --delete options > > > to maintain the table and add or delete specific ports. > > > > > > The option --clear PIF forces the clearing of a table, instead. > > > > > > These options can be combined arbitrarily and are handled as > > > sequential commands, as now described in pesto(1). > > > > > > If no option is given before forwarding specifiers for a matching > > > table, the command line is interpreted as a replacement of the > > > existing rules. > > > > > > To this end: > > > > > > - there's no protocol change, as pesto is anyway sending updated > > > copies of the table > > > > > > - the forwarding table functions now include a new fwd_rule_del(), > > > which deletes existing rule only if a matching one is found > > > > > > - a trivial fwd_rule_clear() is factored out from the existing > > > conf_handler() implementation, so that it can be directly used > > > in pesto > > > > > > The entry points for parsing of port specifiers now take an additional > > > 'del' parameter which is passed down all the way before reaching the > > > fwd_rule_add() implementation. If a rule should be deleted, at that > > > point, fwd_rule_del() is called instead. > > > > > > Signed-off-by: Stefano Brivio > > > --- > > > conf.c | 26 ++++++-------- > > > fwd_rule.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++------ > > > fwd_rule.h | 4 ++- > > > pesto.1 | 85 +++++++++++++++++++++++++++++++++++++++++++++ > > > pesto.c | 55 ++++++++++++++++++++++++++--- > > > 5 files changed, 238 insertions(+), 32 deletions(-) > > > > > > diff --git a/conf.c b/conf.c > > > index d7c837d..929a889 100644 > > > --- a/conf.c > > > +++ b/conf.c > > > @@ -1849,16 +1849,16 @@ void conf(struct ctx *c, int argc, char **argv) > > > > > > if (name == 't') { > > > opt_t = true; > > > - fwd_rule_parse(name, optarg, c->fwd[PIF_HOST]); > > > + fwd_rule_parse(name, false, optarg, c->fwd[PIF_HOST]); > > > } else if (name == 'u') { > > > opt_u = true; > > > - fwd_rule_parse(name, optarg, c->fwd[PIF_HOST]); > > > + fwd_rule_parse(name, false, optarg, c->fwd[PIF_HOST]); > > > } else if (name == 'T') { > > > opt_T = true; > > > - fwd_rule_parse(name, optarg, c->fwd[PIF_SPLICE]); > > > + fwd_rule_parse(name, false, optarg, c->fwd[PIF_SPLICE]); > > > } else if (name == 'U') { > > > opt_U = true; > > > - fwd_rule_parse(name, optarg, c->fwd[PIF_SPLICE]); > > > + fwd_rule_parse(name, false, optarg, c->fwd[PIF_SPLICE]); > > > } > > > } while (name != -1); > > > > > > @@ -1910,13 +1910,13 @@ void conf(struct ctx *c, int argc, char **argv) > > > > > > if (c->mode == MODE_PASTA) { > > > if (!opt_t) > > > - fwd_rule_parse('t', "auto", c->fwd[PIF_HOST]); > > > + fwd_rule_parse('t', false, "auto", c->fwd[PIF_HOST]); > > > if (!opt_T) > > > - fwd_rule_parse('T', "auto", c->fwd[PIF_SPLICE]); > > > + fwd_rule_parse('T', false, "auto", c->fwd[PIF_SPLICE]); > > > if (!opt_u) > > > - fwd_rule_parse('u', "auto", c->fwd[PIF_HOST]); > > > + fwd_rule_parse('u', false, "auto", c->fwd[PIF_HOST]); > > > if (!opt_U) > > > - fwd_rule_parse('U', "auto", c->fwd[PIF_SPLICE]); > > > + fwd_rule_parse('U', false, "auto", c->fwd[PIF_SPLICE]); > > > } > > > > > > conf_sock_listen(c); > > > @@ -2135,14 +2135,8 @@ void conf_handler(struct ctx *c, uint32_t events) > > > unsigned pif; > > > > > > /* Clear pending tables */ > > > - for (pif = 0; pif < PIF_NUM_TYPES; pif++) { > > > - struct fwd_table *fwd = c->fwd_pending[pif]; > > > - > > > - if (!fwd) > > > - continue; > > > - fwd->count = 0; > > > - fwd->sock_count = 0; > > > - } > > > + for (pif = 0; pif < PIF_NUM_TYPES; pif++) > > > + fwd_rule_clear(c->fwd_pending[pif]); > > > > > > /* FIXME: this could block indefinitely if the client doesn't > > > * write as much as it should > > > diff --git a/fwd_rule.c b/fwd_rule.c > > > index 200f4b5..c886ef3 100644 > > > --- a/fwd_rule.c > > > +++ b/fwd_rule.c > > > @@ -180,6 +180,75 @@ static bool fwd_rule_conflicts(const struct fwd_rule *a, const struct fwd_rule * > > > return true; > > > } > > > > > > +/** > > > + * fwd_rule_clear() - Clear a forwarding table > > > + * @fwd: Table to clear (might be NULL) > > > + */ > > > +void fwd_rule_clear(struct fwd_table *fwd) > > > +{ > > > + if (!fwd) > > > + return; > > > + > > > + /* TODO: check that there are no open sockets in the table before > > > + * going on. See also a related item in fwd_rule_del(). > > > + */ > > > + > > > + fwd->count = 0; > > > + fwd->sock_count = 0; > > > +} > > > + > > > +/** > > > + * fwd_rule_del() - Partially validate and delete a rule from a forwarding table > > > + * @fwd: Table to delete from > > > + * @rule: Rule to delete (must conflict with an existing rule) > > > + * > > > + * Return: 0 on success, negative error code on failure (-ENOENT if not found) > > > + * > > > + * NOTE: This function can't be used for a forwarding table with any open socket > > > + * stored in fwd->rulesocks. > > > + */ > > > +static int fwd_rule_del(struct fwd_table *fwd, const struct fwd_rule *rule) > > > +{ > > > + unsigned num, i; > > > + > > > + for (i = 0; i < fwd->count; i++) { > > > + /* FIXME: This isn't entirely correct, as ideally we would like > > > + * to match only *matching* rules here, not just conflicting > > > + * ones. This is convenient at the moment for the current > > > + * implementation, though. > > > + */ > > > + if (fwd_rule_conflicts(rule, &fwd->rules[i])) > > > + break; > > > + } > > > + > > > + if (i == fwd->count) { > > > + char newstr[FWD_RULE_STRLEN]; > > > + > > > + warn("Couldn't find forwarding rule to delete: %s", > > > + fwd_rule_fmt(rule, newstr, sizeof(newstr))); > > > + return -ENOENT; > > > + } > > > + > > > + /* Don't use anything else from 'rule' as passed, it's not validated */ > > > + rule = &fwd->rules[i]; > > > > So we remove the entire rule that matches, not only the part of the new rule that matches? > > We could / should split ranges derived from a rule, yes, but it's not > implemented here. For now, for simplicity, we'll just drop the whole > thing. > > Podman doesn't allow overlapping ranges between different containers > anyway, so this isn't a practical problem anybody is going to hit in > the short term. In the slightly longer term, we should definitely do > better than this. > > > And what if a new rule conflicts with two existing rules? > > David raised that concern in: > > > https://archives.passt.top/passt-dev/afsASt0TWXFQovjJ@zatzit/ > > ...we'll delete the first one which conflicts, at the moment. It's not > great but again it's fine for Podman usage, and we can improve the > implementation in a bit. ...on the other hand, I just checked things with a trivial function just doing memcmp(), to implement David's proposal about sticking to exact matches only, and it all seems to work (with or without interface names, with or without IPv4 / IPv6 mix-ups, etc.). I didn't expect it to be so simple. Let me change that in v10 as well. -- Stefano