From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: passt.top; dkim=pass (2048-bit key; secure) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.a=rsa-sha256 header.s=202602 header.b=JhTDyO+z; dkim-atps=neutral Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 7FCD45A0652 for ; Thu, 19 Mar 2026 07:12:13 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202602; t=1773900722; bh=Gw930iOT7iC3S372m4AmqBYvAeAqmqWhhAjwBH0uxEc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JhTDyO+zxL8qfbVtCCADfY/Y83aBz1tG+9PLZwa8bNH10ruuSx+TCuIl9Ib/2z6fX vDeV88+PXOFyu/A6aYgnO4WXJoZokvyyeRbWzZ4obL9vi0eaQPfDpjtXDZEx4zvObN LWdb78TuqZowkxk1afR0/Rwsp42bKo/nhkUL/uu1zYB++5yNpfwOv8vOl5YCbjoYtM LMxEgTqbdjknN5rj+Fc7e/N4/K9+1zQaDUj3L78OUNcJWrOf19b3BS6838rqVb6MMx r5KIpH15eRczOBa5/tdDuVEk2B6KQ+1GwmGUYu/t011B+/iWMCaXYksblCI+vU2BhU nDRAKH4G8JB6g== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4fbwMQ1Kg1z4wT2; Thu, 19 Mar 2026 17:12:02 +1100 (AEDT) From: David Gibson To: Stefano Brivio , passt-dev@passt.top Subject: [PATCH v2 15/15] pesto: Read current ruleset from passt/pasta and display it Date: Thu, 19 Mar 2026 17:11:57 +1100 Message-ID: <20260319061157.1983818-16-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260319061157.1983818-1-david@gibson.dropbear.id.au> References: <20260319061157.1983818-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: RWXY7M3524MBMKKGZCE63FNFYUYJSHVU X-Message-ID-Hash: RWXY7M3524MBMKKGZCE63FNFYUYJSHVU X-MailFrom: dgibson@gandalf.ozlabs.org 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: 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: Implement serialisation of our current forwarding rules in conf.c, deserialising it to display in the pesto client. Signed-off-by: David Gibson --- conf.c | 44 +++++++++++++++++++++++++++++++ fwd_rule.c | 40 ++++++++++++++++++++++++++++ fwd_rule.h | 3 +++ pesto.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 160 insertions(+), 4 deletions(-) diff --git a/conf.c b/conf.c index 603ca2ac..b235221f 100644 --- a/conf.c +++ b/conf.c @@ -2339,6 +2339,47 @@ static int conf_send_pifs(const struct ctx *c, int fd) return 0; } +/** + * conf_send_rules() - Send current forwarding rules to dynamic update client (pesto) + * @c: Execution context + * @fd: Socket to the client + * + * Return: 0 on success, -1 on failure + */ +static int conf_send_rules(const struct ctx *c, int fd) +{ + unsigned pif; + + for (pif = 0; pif < PIF_NUM_TYPES; pif++) { + const struct fwd_table *fwd = c->fwd[pif]; + unsigned i; + + if (!fwd) + continue; + + assert(pif); + + /* PIF id */ + if (sewrite_u8(fd, pif)) + return -1; + + /* Number of rules */ + if (sewrite_u32(fd, fwd->count)) + return -1; + + for (i = 0; i < fwd->count; i++) { + if (fwd_rule_sewrite(fd, &fwd->rules[i].rule)) + return -1; + } + } + + /* Write 0 PIF id to finish */ + if (sewrite_u8(fd, 0)) + return -1; + + return 0; +} + /** * conf_listen_handler() - Handle events on configuration listening socket * @c: Execution context @@ -2398,6 +2439,9 @@ void conf_listen_handler(struct ctx *c, uint32_t events) if (conf_send_pifs(c, fd) < 0) goto fail; + if (conf_send_rules(c, fd) < 0) + goto fail; + return; fail: diff --git a/fwd_rule.c b/fwd_rule.c index dfbdf683..3e39b4f9 100644 --- a/fwd_rule.c +++ b/fwd_rule.c @@ -17,6 +17,8 @@ #include +#include "serialise.h" + #include "fwd_rule.h" /** @@ -71,3 +73,41 @@ const char *fwd_rule_ntop(const struct fwd_rule *rule, char *dst, size_t size) return dst; } + +/** + * fwd_rule_seread() - Read erialised rule from an fd + * @fd: fd to serialise to + * @rule: Buffer to store rule into + * + * Return: 0 on success, -1 on error (with errno set) + */ +int fwd_rule_seread(int fd, struct fwd_rule *rule) +{ + if (seread_var(fd, rule)) + return -1; + + /* Byteswap for host */ + rule->first = ntohs(rule->first); + rule->last = ntohs(rule->last); + rule->to = htons(rule->to); + return 0; +} + +/** + * fwd_rule_sewrite() - Serialise rule to an fd + * @fd: fd to serialise to + * @rule: Rule to send + * + * Return: 0 on success, -1 on error (with errno set) + */ +int fwd_rule_sewrite(int fd, const struct fwd_rule *rule) +{ + struct fwd_rule tmp = *rule; + + /* Byteswap for transport */ + tmp.first = htons(tmp.first); + tmp.last = htons(tmp.last); + tmp.to = htons(tmp.to); + + return sewrite_var(fd, &tmp); +} diff --git a/fwd_rule.h b/fwd_rule.h index 59db0e95..500b955d 100644 --- a/fwd_rule.h +++ b/fwd_rule.h @@ -53,4 +53,7 @@ const union inany_addr *fwd_rule_addr(const struct fwd_rule *rule); + 15) const char *fwd_rule_ntop(const struct fwd_rule *rule, char *dst, size_t size); +int fwd_rule_seread(int fd, struct fwd_rule *rule); +int fwd_rule_sewrite(int fd, const struct fwd_rule *rule); + #endif /* FWD_RULE_H */ diff --git a/pesto.c b/pesto.c index dbc27a58..f021cdb6 100644 --- a/pesto.c +++ b/pesto.c @@ -34,6 +34,7 @@ #include "common.h" #include "seccomp_pesto.h" #include "serialise.h" +#include "fwd_rule.h" #include "pesto.h" static int verbosity = 1; @@ -108,6 +109,8 @@ static const char *pesto_recv_str(int fd) struct pif_state { uint8_t pif; const char *name; + uint32_t count; + struct fwd_rule *rule; }; struct conf_state { @@ -119,7 +122,7 @@ struct conf_state { * pesto_read_pifs() - Read pif names and IDs from passt/pasta * @fd: Control socket */ -static const struct conf_state *pesto_read_pifs(int fd) +static struct conf_state *pesto_read_pifs(int fd) { uint32_t num; struct conf_state *state; @@ -146,18 +149,81 @@ static const struct conf_state *pesto_read_pifs(int fd) return state; } +/** + * find_pif_state() - Find the pif state structure for a given pif id + * @state: Rule state information + * @pif: pif id + * + * Return: pointer to the pif_state for @pif, or NULL if not found + */ +static struct pif_state *find_pif_state(struct conf_state *state, uint8_t pif) +{ + unsigned i; + + for (i = 0; i < state->npifs; i++) { + if (state->pif[i].pif == pif) + return &state->pif[i]; + } + + return NULL; +} + +/** + * pesto_read_rules() - Read a set of rules for one pif + * @fd: Control socket + * @state: Rule state information to update + * + * Return: true if there may be more rules to read, false if finished + */ +static bool pesto_read_rules(int fd, struct conf_state *state) +{ + struct pif_state *ps; + uint8_t pif; + unsigned i; + + if (seread_u8(fd, &pif) < 0) + die("Error reading from control socket"); + + if (!pif) + return false; + + ps = find_pif_state(state, pif); + if (!ps) + die("Received rules for an unknown pif"); + + if (seread_u32(fd, &ps->count) < 0) + die("Error reading from control socket"); + + debug("Receiving rules %"PRIu32" rules for %s", ps->count, ps->name); + + ps->rule = xmalloc(sizeof(*ps->rule) * ps->count); + + for (i = 0; i < ps->count; i++) { + if (fwd_rule_seread(fd, &ps->rule[i]) < 0) + die("Error reading from control socket"); + } + + return true; +} + /** * show_state() - Show current rule state obtained from passt/pasta * @pifs: PIF name information */ static void show_state(const struct conf_state *state) { - unsigned i; + unsigned i, j; for (i = 0; i < state->npifs; i++) { const struct pif_state *ps = &state->pif[i]; printf("Forwarding rules for %s interface\n", ps->name); - printf("\tTBD\n"); + for (j = 0; j < ps->count; j++) { + const struct fwd_rule *rule = &ps->rule[j]; + char rulestr[FWD_RULE_STRLEN]; + + printf(" %s\n", fwd_rule_ntop(rule, rulestr, + sizeof(rulestr))); + } } } @@ -183,9 +249,9 @@ int main(int argc, char **argv) { 0 }, }; struct sockaddr_un a = { AF_UNIX, "" }; - const struct conf_state *state; const char *optstring = "vh"; struct pesto_hello hello; + struct conf_state *state; struct sock_fprog prog; int optname, ret, s; uint32_t s_version; @@ -266,6 +332,9 @@ int main(int argc, char **argv) state = pesto_read_pifs(s); + while (pesto_read_rules(s, state)) + ; + show_state(state); exit(0); -- 2.53.0