I've taken Stefano's draft implementation of dynamic updates, and polished it up to have a read-only implementation of the dynamic update protocol. So far it retrieves the pif names and ruleset from passt/pasta and displays it. Sending a new ruleset back comes next. Patches 1..6/15 are preliminary reworks that make moderate sense even without pesto - feel free to apply if you're happy with them. Changes in v2: * Removed already applied cleanups * Reworked assert() patch to handle -DNDEBUG properly * Numerous extra patches: * Factored out serialisation helpers and use them for migration as well * Reworked to allow ip.[ch] and inany.[ch] to be shared with pesto * Reworks to share some forwarding rule datatypes with pesto * Implemented sending pif names and current ruleset to pesto David Gibson (15): treewide: Spell ASSERT() as assert() serialise: Split functions user for serialisation from util.c serialise: Add helpers for serialising unsigned integers fwd: Move selecting correct scan bitmap into fwd_sync_one() fwd: Look up rule index in fwd_sync_one() fwd: Store forwarding tables indexed by (origin) pif pesto: Introduce stub configuration interface and tool pesto: Add command line option parsing and debug messages pesto: Expose list of pifs to pesto ip: Prepare ip.[ch] for sharing with pesto tool inany: Prepare inany.[ch] for sharing with pesto tool fwd: Split forwading rule specification from its implementation state ip: Define a bound for the string returned by ipproto_name() fwd_rule: Move forwarding rule text formatting to common code pesto: Read current ruleset from passt/pasta and display it .gitignore | 2 + Makefile | 43 ++++--- common.h | 79 ++++++++++++ conf.c | 294 ++++++++++++++++++++++++++++++++++++++++---- conf.h | 2 + epoll_type.h | 4 + flow.c | 117 +++++++++--------- flow_table.h | 2 +- fwd.c | 218 +++++++++++++++----------------- fwd.h | 35 ++---- fwd_rule.c | 113 +++++++++++++++++ fwd_rule.h | 59 +++++++++ icmp.c | 14 +-- inany.c | 16 ++- inany.h | 20 +-- iov.c | 4 +- ip.c | 74 +++-------- ip.h | 4 +- isolation.c | 2 +- lineread.c | 5 +- log.c | 1 + migrate.c | 9 +- netlink.c | 2 +- packet.c | 4 +- passt.1 | 5 + passt.c | 11 +- passt.h | 9 +- pcap.c | 3 +- pesto.1 | 46 +++++++ pesto.c | 341 +++++++++++++++++++++++++++++++++++++++++++++++++++ pesto.h | 34 +++++ pif.c | 4 +- serialise.c | 147 ++++++++++++++++++++++ serialise.h | 27 ++++ siphash.h | 13 ++ tap.c | 58 ++++++++- tcp.c | 43 +++---- tcp_splice.c | 10 +- tcp_vu.c | 8 +- udp.c | 22 ++-- udp_flow.c | 4 +- udp_vu.c | 4 +- util.c | 82 ++----------- util.h | 84 ++----------- vhost_user.c | 8 +- virtio.c | 6 +- vu_common.c | 4 +- 47 files changed, 1535 insertions(+), 561 deletions(-) create mode 100644 common.h create mode 100644 fwd_rule.c create mode 100644 fwd_rule.h create mode 100644 pesto.1 create mode 100644 pesto.c create mode 100644 pesto.h create mode 100644 serialise.c create mode 100644 serialise.h -- 2.53.0
The standard library assert(3), at least with glibc, hits our seccomp
filter and dies with SIGSYS before it's able to print a message, making it
near useless. Therefore, since 7a8ed9459dfe ("Make assertions actually
useful") we've instead used our own implementation, named ASSERT().
This makes our code look slightly odd though - ASSERT() has the same
overall effect as assert(), it's just a different implementation. More
importantly this makes it awkward to share code between passt/pasta proper
and things that compile in a more typical environment. We're going to want
that for our upcoming dynamic configuration tool.
Address this by overriding the standard library's assert() implementation
with our own, instead of giving ours its own name.
The standard assert() is supposed to be omitted if NDEBUG is defined,
which ours doesn't do. Implement that as well, so ours doesn't
unexpectedly differ. For the -DNDEBUG case we do this by *not* overriding
assert(), since it will be a no-op anyway. This requires a few places to
add a #include
Most of the fields in struct fwd_rule give the parameters of the forwarding
rule itself. The @socks field gives the list of listening sockets we use
to implement it. In order to share code with the configuraiton update tool
pesto, we want to split these. Move the rule specification itself into
fwd_rule.h, which can be shared with pesto.
Signed-off-by: David Gibson
Add basic command line option parsing using getopt_long() to pesto.
Implement --help, --version, --quiet and --verbose options, along with a
debug() macro to print debugging messages when given the verbose option.
Signed-off-by: David Gibson
Currently we have the slightly silly setup that fwd_listen_sync_() looks
up the pointer to a rule based on its index, then fwd_sync_one() turns it
back into an index. Avoid this by passing the index directly into
fwd_sync_one().
Signed-off-by: David Gibson
Currently we store the inbound (PIF_HOST) and outbound (PIF_SPLICE)
forwarding tables in separate fields of struct ctx. In a number of places
this requires somewhat awkward if or switch constructs to select the
right table for updates. Conceptually simplify that by using an index of
forwarding tables by pif, which as a bonus keeps track generically which
pifs have implemented forwarding tables so far.
For now this doesn't simplify a lot textually, because many places that
need this also have other special cases to apply by pif. It does simplify
a few crucial places though, and we expect it will become more useful as
the flexibility of the forwarding table is improved.
Signed-off-by: David Gibson
Extend the dynamic update protocol to expose the pif indices and names
from a running passt/pasta to the pesto tool. pesto records that data
and (for now) prints it out.
Signed-off-by: David Gibson
inany contains a number of helpful functions for dealing with addresses
which might be IPv4 or IPv6. We're going to want to use that in pesto.
For the most part inany doesn't depend on other passt/pasta internals,
however it does depend on siphash.h, which pesto doesn't need.
Move the single dependent function, inany_siphash_feed() to siphash.h,
renaming to match. Use that include inany.[ch] into pesto as well as
passt/pasta. While we're there reformat pesto.c's header comment to match
the convention used in most other files.
Signed-off-by: David Gibson
ipproto_name() returns a static string of theoretically unbounded length.
That's going to be inconvenient in future, so introduce IPPROTO_STRLEN
giving an explicit bound on the length. Use static_assert() and some
macros to ensure nothing we return can exceed this.
Signed-off-by: David Gibson
Most things in ip.[ch] related purely to IP addresses and headers with
no dependency on other passt/pasta internals. A number of these will be
useful to re-use in pesto. The exception is ipv6_l4hdr() which uses
iov_tail.
The only caller of this is in tap.c, so move the function there. Along
with moving the constant byteswapping functions to common.h, that lets
ip.[ch] to be linked into pesto as well as passt/pasta.
Signed-off-by: David Gibson
Add a control socket to passt/pasta for updating configuration at runtime.
Add a tool (pesto) for communicating with the control socket.
For now this is a stub implementation that forms the connection and sends
some version information, but nothing more.
Example:
./pasta --debug --config-net -c /tmp/pasta.conf -t none
./pesto /tmp/pasta.conf
Signed-off-by: Stefano Brivio
Move the logic for formatting forwarding rules into strings from
fwd_rules_print() into fwd_rule.c where it can be shared with pesto.
We also make the function explicitly construct a string, rather than
directly printing with info(), for greater flexibility.
Signed-off-by: David Gibson
Implement serialisation of our current forwarding rules in conf.c,
deserialising it to display in the pesto client.
Signed-off-by: David Gibson
On Thu, 19 Mar 2026 17:11:48 +1100
David Gibson
Currently we store the inbound (PIF_HOST) and outbound (PIF_SPLICE) forwarding tables in separate fields of struct ctx. In a number of places this requires somewhat awkward if or switch constructs to select the right table for updates. Conceptually simplify that by using an index of forwarding tables by pif, which as a bonus keeps track generically which pifs have implemented forwarding tables so far.
For now this doesn't simplify a lot textually, because many places that need this also have other special cases to apply by pif. It does simplify a few crucial places though, and we expect it will become more useful as the flexibility of the forwarding table is improved.
Signed-off-by: David Gibson
--- conf.c | 53 +++++++++++++++++++++++++++------------------- flow.c | 22 +++++++------------ fwd.c | 65 ++++++++++++++++++++++++++++++--------------------------- fwd.h | 4 ++-- passt.h | 3 +-- 5 files changed, 77 insertions(+), 70 deletions(-) diff --git a/conf.c b/conf.c index 940fb9e9..6af3c8a5 100644 --- a/conf.c +++ b/conf.c @@ -1252,11 +1252,12 @@ dns6: } }
- info("Inbound forwarding:"); - fwd_rules_print(&c->fwd_in); - if (c->mode == MODE_PASTA) { - info("Outbound forwarding:"); - fwd_rules_print(&c->fwd_out); + for (i = 0; i < PIF_NUM_TYPES; i++) { + if (!c->fwd[i]) + continue; + + info("Forwarding from %s:", pif_name(i));
I don't have a good solution to propose but it's slightly annoying that we're changing very clear "Inbound forwarding" and "Outbound forwarding" indications to "Forwarding from: " HOST | TAP | SPLICE. Should we perhaps introduce a PIF_INBOUND_MAX value that's the same as HOST, and then: if (i <= PIF_INBOUND_MAX) info("Inbound forwarding:"); else info("Outbound forwarding:"); ? I'm fine keeping it as it is, I would just have a slight preference to make it as clear as it was before. This is something users can now look at to double check things and I have the feeling we're avoid a bunch of bug reports as a result.
+ fwd_rules_print(c->fwd[i]); } }
@@ -2154,18 +2155,24 @@ void conf(struct ctx *c, int argc, char **argv)
/* Forwarding options can be parsed now, after IPv4/IPv6 settings */ fwd_probe_ephemeral(); + fwd_rule_init(c); optind = 0; do { name = getopt_long(argc, argv, optstring, options, NULL);
- if (name == 't') - conf_ports(c, name, optarg, &c->fwd_in, &tcp_in_mode); - else if (name == 'u') - conf_ports(c, name, optarg, &c->fwd_in, &udp_in_mode); - else if (name == 'T') - conf_ports(c, name, optarg, &c->fwd_out, &tcp_out_mode); - else if (name == 'U') - conf_ports(c, name, optarg, &c->fwd_out, &udp_out_mode); + if (name == 't') { + conf_ports(c, name, optarg, c->fwd[PIF_HOST], + &tcp_in_mode); + } else if (name == 'u') { + conf_ports(c, name, optarg, c->fwd[PIF_HOST], + &udp_in_mode); + } else if (name == 'T') { + conf_ports(c, name, optarg, c->fwd[PIF_SPLICE], + &tcp_out_mode); + } else if (name == 'U') { + conf_ports(c, name, optarg, c->fwd[PIF_SPLICE], + &udp_out_mode); + } } while (name != -1);
if (c->mode == MODE_PASTA) @@ -2224,20 +2231,24 @@ void conf(struct ctx *c, int argc, char **argv) udp_out_mode = fwd_default;
if (tcp_in_mode == FWD_MODE_AUTO) { - conf_ports_range_except(c, 't', "auto", &c->fwd_in, NULL, NULL, - 1, NUM_PORTS - 1, NULL, 1, FWD_SCAN); + conf_ports_range_except(c, 't', "auto", c->fwd[PIF_HOST], + NULL, NULL, 1, NUM_PORTS - 1, NULL, 1, + FWD_SCAN); } if (tcp_out_mode == FWD_MODE_AUTO) { - conf_ports_range_except(c, 'T', "auto", &c->fwd_out, NULL, "lo", - 1, NUM_PORTS - 1, NULL, 1, FWD_SCAN); + conf_ports_range_except(c, 'T', "auto", c->fwd[PIF_SPLICE], + NULL, "lo", 1, NUM_PORTS - 1, NULL, 1, + FWD_SCAN); } if (udp_in_mode == FWD_MODE_AUTO) { - conf_ports_range_except(c, 'u', "auto", &c->fwd_in, NULL, NULL, - 1, NUM_PORTS - 1, NULL, 1, FWD_SCAN); + conf_ports_range_except(c, 'u', "auto", c->fwd[PIF_HOST], + NULL, NULL, 1, NUM_PORTS - 1, NULL, 1, + FWD_SCAN); } if (udp_out_mode == FWD_MODE_AUTO) { - conf_ports_range_except(c, 'U', "auto", &c->fwd_out, NULL, "lo", - 1, NUM_PORTS - 1, NULL, 1, FWD_SCAN); + conf_ports_range_except(c, 'U', "auto", c->fwd[PIF_SPLICE], + NULL, "lo", 1, NUM_PORTS - 1, NULL, 1, + FWD_SCAN); }
if (!c->quiet) diff --git a/flow.c b/flow.c index 81333dbc..11cd5752 100644 --- a/flow.c +++ b/flow.c @@ -503,10 +503,10 @@ struct flowside *flow_target(const struct ctx *c, union flow *flow, { char estr[INANY_ADDRSTRLEN], ostr[INANY_ADDRSTRLEN]; struct flow_common *f = &flow->f; + const struct fwd_table *fwd = c->fwd[f->pif[INISIDE]]; const struct flowside *ini = &f->side[INISIDE]; struct flowside *tgt = &f->side[TGTSIDE]; const struct fwd_rule *rule = NULL; - const struct fwd_table *fwd; uint8_t tgtpif = PIF_NONE;
assert(flow_new_entry == flow && f->state == FLOW_STATE_INI); @@ -514,6 +514,11 @@ struct flowside *flow_target(const struct ctx *c, union flow *flow, assert(f->pif[INISIDE] != PIF_NONE && f->pif[TGTSIDE] == PIF_NONE); assert(flow->f.state == FLOW_STATE_INI);
+ if (fwd) { + if (!(rule = fwd_rule_search(fwd, ini, proto, rule_hint))) + goto norule; + } + switch (f->pif[INISIDE]) { case PIF_TAP: memcpy(f->tap_omac, MAC_UNDEF, ETH_ALEN); @@ -521,20 +526,10 @@ struct flowside *flow_target(const struct ctx *c, union flow *flow, break;
case PIF_SPLICE: - fwd = &c->fwd_out; - - if (!(rule = fwd_rule_search(fwd, ini, proto, rule_hint))) - goto norule; - tgtpif = fwd_nat_from_splice(rule, proto, ini, tgt); break;
case PIF_HOST: - fwd = &c->fwd_in; - - if (!(rule = fwd_rule_search(fwd, ini, proto, rule_hint))) - goto norule; - tgtpif = fwd_nat_from_host(c, rule, proto, ini, tgt); fwd_neigh_mac_get(c, &tgt->oaddr, f->tap_omac); break; @@ -1014,8 +1009,7 @@ static int flow_migrate_source_rollback(struct ctx *c, unsigned bound, int ret)
debug("...roll back migration");
- if (fwd_listen_sync(c, &c->fwd_in, PIF_HOST, - &c->tcp.scan_in, &c->udp.scan_in) < 0) + if (fwd_listen_sync(c, PIF_HOST, &c->tcp.scan_in, &c->udp.scan_in) < 0) die("Failed to re-establish listening sockets");
foreach_established_tcp_flow(flow) { @@ -1148,7 +1142,7 @@ int flow_migrate_source(struct ctx *c, const struct migrate_stage *stage, * fix that is to not allow local to local migration, which arguably we * should (use namespaces for testing instead). */ debug("Stop listen()s"); - fwd_listen_close(&c->fwd_in); + fwd_listen_close(c->fwd[PIF_HOST]);
debug("Sending %u flows", count);
diff --git a/fwd.c b/fwd.c index 7844a674..3395a28e 100644 --- a/fwd.c +++ b/fwd.c @@ -331,6 +331,21 @@ bool fwd_port_is_ephemeral(in_port_t port) return (port >= fwd_ephemeral_min) && (port <= fwd_ephemeral_max); }
+/* Forwarding table storage, generally accessed via pointers in struct ctx */ +static struct fwd_table fwd_in; +static struct fwd_table fwd_out; + +/** + * fwd_rule_init() - Initialise forwarding tables + * @c: Execution context + */ +void fwd_rule_init(struct ctx *c) +{ + c->fwd[PIF_HOST] = &fwd_in; + if (c->mode == MODE_PASTA) + c->fwd[PIF_SPLICE] = &fwd_out; +} + /** * fwd_rule_add() - Add a rule to a forwarding table * @fwd: Table to add to @@ -505,19 +520,17 @@ void fwd_rules_print(const struct fwd_table *fwd)
/** fwd_sync_one() - Create or remove listening sockets for a forward entry * @c: Execution context - * @fwd: Forwarding table - * @idx: Rule index * @pif: Interface to create listening sockets for + * @idx: Rule index * @tcp: Bitmap of TCP ports to listen for on FWD_SCAN entries * @udp: Bitmap of UDP ports to listen for on FWD_SCAN entries * * Return: 0 on success, -1 on failure */ -static int fwd_sync_one(const struct ctx *c, const struct fwd_table *fwd, - unsigned idx, uint8_t pif, +static int fwd_sync_one(const struct ctx *c, uint8_t pif, unsigned idx, const uint8_t *tcp, const uint8_t *udp) { - const struct fwd_rule *rule = &fwd->rules[idx]; + const struct fwd_rule *rule = &c->fwd[pif]->rules[idx]; const union inany_addr *addr = fwd_rule_addr(rule); const char *ifname = rule->ifname; const uint8_t *map = NULL; @@ -598,7 +611,6 @@ static int fwd_sync_one(const struct ctx *c, const struct fwd_table *fwd,
/** struct fwd_listen_args - arguments for fwd_listen_init_() * @c: Execution context - * @fwd: Forwarding table * @tcpmap: Bitmap of TCP ports to auto-forward * @udpmap: Bitmap of TCP ports to auto-forward * @pif: Interface to create listening sockets for @@ -606,7 +618,6 @@ static int fwd_sync_one(const struct ctx *c, const struct fwd_table *fwd, */ struct fwd_listen_args { const struct ctx *c; - const struct fwd_table *fwd; const uint8_t *tcpmap, *udpmap; uint8_t pif; int ret; @@ -625,9 +636,8 @@ static int fwd_listen_sync_(void *arg) if (a->pif == PIF_SPLICE) ns_enter(a->c);
- for (i = 0; i < a->fwd->count; i++) { - a->ret = fwd_sync_one(a->c, a->fwd, i, a->pif, - a->tcpmap, a->udpmap); + for (i = 0; i < a->c->fwd[a->pif]->count; i++) { + a->ret = fwd_sync_one(a->c, a->pif, i, a->tcpmap, a->udpmap); if (a->ret < 0) break; } @@ -637,21 +647,17 @@ static int fwd_listen_sync_(void *arg)
/** fwd_listen_sync() - Call fwd_listen_sync_() in correct namespace * @c: Execution context - * @fwd: Forwarding information * @pif: Interface to create listening sockets for * @tcp: Scanning state for TCP * @udp: Scanning state for UDP * * Return: 0 on success, -1 on failure */ -int fwd_listen_sync(const struct ctx *c, const struct fwd_table *fwd, - uint8_t pif, +int fwd_listen_sync(const struct ctx *c, uint8_t pif, const struct fwd_scan *tcp, const struct fwd_scan *udp) { struct fwd_listen_args a = { - .c = c, .fwd = fwd, - .tcpmap = tcp->map, .udpmap = udp->map, - .pif = pif, + .c = c, .tcpmap = tcp->map, .udpmap = udp->map, .pif = pif, };
if (pif == PIF_SPLICE) @@ -695,12 +701,11 @@ void fwd_listen_close(const struct fwd_table *fwd) */ int fwd_listen_init(const struct ctx *c) { - if (fwd_listen_sync(c, &c->fwd_in, PIF_HOST, - &c->tcp.scan_in, &c->udp.scan_in) < 0) + if (fwd_listen_sync(c, PIF_HOST, &c->tcp.scan_in, &c->udp.scan_in) < 0) return -1;
if (c->mode == MODE_PASTA) { - if (fwd_listen_sync(c, &c->fwd_out, PIF_SPLICE, + if (fwd_listen_sync(c, PIF_SPLICE, &c->tcp.scan_out, &c->udp.scan_out) < 0) return -1; } @@ -851,16 +856,16 @@ static void fwd_scan_ports(struct ctx *c) uint8_t excl_tcp_out[PORT_BITMAP_SIZE], excl_udp_out[PORT_BITMAP_SIZE]; uint8_t excl_tcp_in[PORT_BITMAP_SIZE], excl_udp_in[PORT_BITMAP_SIZE];
- current_listen_map(excl_tcp_out, &c->fwd_in, IPPROTO_TCP); - current_listen_map(excl_tcp_in, &c->fwd_out, IPPROTO_TCP); - current_listen_map(excl_udp_out, &c->fwd_in, IPPROTO_UDP); - current_listen_map(excl_udp_in, &c->fwd_out, IPPROTO_UDP); + current_listen_map(excl_tcp_out, c->fwd[PIF_HOST], IPPROTO_TCP); + current_listen_map(excl_tcp_in, c->fwd[PIF_SPLICE], IPPROTO_TCP); + current_listen_map(excl_udp_out, c->fwd[PIF_HOST], IPPROTO_UDP); + current_listen_map(excl_udp_in, c->fwd[PIF_SPLICE], IPPROTO_UDP);
- fwd_scan_ports_tcp(&c->fwd_out, &c->tcp.scan_out, excl_tcp_out); - fwd_scan_ports_tcp(&c->fwd_in, &c->tcp.scan_in, excl_tcp_in); - fwd_scan_ports_udp(&c->fwd_out, &c->udp.scan_out, + fwd_scan_ports_tcp(c->fwd[PIF_SPLICE], &c->tcp.scan_out, excl_tcp_out); + fwd_scan_ports_tcp(c->fwd[PIF_HOST], &c->tcp.scan_in, excl_tcp_in); + fwd_scan_ports_udp(c->fwd[PIF_SPLICE], &c->udp.scan_out, &c->tcp.scan_out, excl_udp_out); - fwd_scan_ports_udp(&c->fwd_in, &c->udp.scan_in, + fwd_scan_ports_udp(c->fwd[PIF_HOST], &c->udp.scan_in, &c->tcp.scan_in, excl_udp_in); }
@@ -912,10 +917,8 @@ void fwd_scan_ports_timer(struct ctx *c, const struct timespec *now)
fwd_scan_ports(c);
- fwd_listen_sync(c, &c->fwd_in, PIF_HOST, - &c->tcp.scan_in, &c->udp.scan_in); - fwd_listen_sync(c, &c->fwd_out, PIF_SPLICE, - &c->tcp.scan_out, &c->udp.scan_out); + fwd_listen_sync(c, PIF_HOST, &c->tcp.scan_in, &c->udp.scan_in); + fwd_listen_sync(c, PIF_SPLICE, &c->tcp.scan_out, &c->udp.scan_out); }
/** diff --git a/fwd.h b/fwd.h index 958eee25..b387d926 100644 --- a/fwd.h +++ b/fwd.h @@ -108,6 +108,7 @@ struct fwd_scan {
#define FWD_PORT_SCAN_INTERVAL 1000 /* ms */
+void fwd_rule_init(struct ctx *c); void fwd_rule_add(struct fwd_table *fwd, uint8_t proto, uint8_t flags, const union inany_addr *addr, const char *ifname, in_port_t first, in_port_t last, in_port_t to); @@ -119,8 +120,7 @@ void fwd_rules_print(const struct fwd_table *fwd); void fwd_scan_ports_init(struct ctx *c); void fwd_scan_ports_timer(struct ctx * c, const struct timespec *now);
-int fwd_listen_sync(const struct ctx *c, const struct fwd_table *fwd, - uint8_t pif, +int fwd_listen_sync(const struct ctx *c, uint8_t pif, const struct fwd_scan *tcp, const struct fwd_scan *udp); void fwd_listen_close(const struct fwd_table *fwd); int fwd_listen_init(const struct ctx *c); diff --git a/passt.h b/passt.h index b614bdf0..5fc4e07f 100644 --- a/passt.h +++ b/passt.h @@ -264,8 +264,7 @@ struct ctx { unsigned int pasta_ifi; int pasta_conf_ns;
- struct fwd_table fwd_in; - struct fwd_table fwd_out; + struct fwd_table *fwd[PIF_NUM_TYPES];
Nit: the struct documentation should be updated accordingly.
int no_tcp; struct tcp_ctx tcp;
-- Stefano
On Thu, 19 Mar 2026 17:11:43 +1100
David Gibson
The standard library assert(3), at least with glibc, hits our seccomp filter and dies with SIGSYS before it's able to print a message, making it near useless. Therefore, since 7a8ed9459dfe ("Make assertions actually useful") we've instead used our own implementation, named ASSERT().
This makes our code look slightly odd though - ASSERT() has the same overall effect as assert(), it's just a different implementation. More importantly this makes it awkward to share code between passt/pasta proper and things that compile in a more typical environment. We're going to want that for our upcoming dynamic configuration tool.
Address this by overriding the standard library's assert() implementation with our own, instead of giving ours its own name.
The standard assert() is supposed to be omitted if NDEBUG is defined, which ours doesn't do. Implement that as well, so ours doesn't unexpectedly differ. For the -DNDEBUG case we do this by *not* overriding assert(), since it will be a no-op anyway. This requires a few places to add a #include
to let us compile (albeit with warnings) when -DNDEBUG. Signed-off-by: David Gibson
Applied (just this patch). I fixed up some (expected) trivial conflicts in tcp_vu.c and udp_vu.c with "vu_common: Move iovec management into vu_collect()". -- Stefano
Move conf_ports_range_except(), conf_ports(), and related to helpers
to ports.c, so that they can be used from pesto in the future. We'll
need to make those independent from passt-specific bits, but this
patch just moves them out, first.
Signed-off-by: Stefano Brivio
...so that pesto can reuse functions parsing port forwarding
specifications from ports.c:
- checks on validity of some forwarding options (auto with pasta only
all with passt only) move to the caller, conf()
- some other checks (availability of IPv4, IPv6, SO_BINDTODEVICE) are
now based on specific parameters passed to conf_ports() and
conf_ports_range_except(), so that we don't need struct ctx there
- bitmap operations and some convenience macros move to common.h
- fwd_probe_ephemeral(), fwd_port_is_ephemeral(), and fwd_rule_add()
move to ports.c and fwd_rule.c, without any renaming for the moment
- forwarding table definitions move to fwd_rule.h
- selection of the definition of some logging functions now depends on
a gross but unintrusive hack, a PESTO define (this will needs a
cleaner solution later)
Signed-off-by: Stefano Brivio
*** DO NOT USE ***: this introduces a security weakness as it allows
passt to dynamically allocate memory based on external input (needed
by fwd_rule_seread(), which will need either a replacement or a
rewrite).
This adds parsing of options using conf_ports() in pesto, builds
rules, takes them out of the table (!) and sends them one by one to
passt, which now receives them and uses them to replace the current
forwarding table. This part works.
This also adds a convenience implementation that closes all current
sockets and tries to synchronise listening sockets from the new set
of rules. This partially works, but for some reason sockets don't bind
correctly, and I couldn't quite wrap my head around the complexity of
the new "fwd_rule_state" and the fact that with this we can't simply
dump rules in the tables and re-sync them (this part was very simple
and it worked in my earlier draft).
I'm sharing this part as well anyway as it might be convenient if
it's useful to build a quick hack that makes the whole flow work with
Podman, but that's about it.
Signed-off-by: Stefano Brivio
participants (2)
-
David Gibson
-
Stefano Brivio