On Tue, Aug 11, 2026 at 01:57:01PM +0200, Dion Bosschieter wrote: > Resolves issue: https://gitlab.com/libvirt/libvirt/-/issues/603 > Benchmarks showed that the amount of iifname jumps for each > interface is the cause for this. > Switched the nftables driver towards a vmap (verdict map) so we > can have 1 rule that jumps to the correct root input/output chain > per interface. Which improves throughput as when the number of > interface check and jump rules increases the throughput decreases. > The issue describes the interface matching works using the interface > name and the majority of the effort is the strncpy, this commit also > switches nftables to an interface_index compare instead. > However, just using the interface_index is not enough, the amount of > oif and iif jump rules causes quite the performance degradation, > the vmap instead solves this. > > Split rules into separate tables: "libvirt_nwfilter_ethernet" and > "libvirt_nwfilter_inet" to preserve existing ebip firewall behavior. > > Reworked chain logic for clarity with root -input/-output chains per > interface. input in the VM interface is filtered in the -input > chain(s), output out of the VM inteface is filtered in the -output > chain(s). > Ethernet table has support for subchains where the inet table puts > everything in one chain. This is for compatibility reasons with how > nwfilter ebiptables behaved, so that users may switch to nftables and > expect the same firewalling behavior. > > Stuck with two tables for compatibility reasons with ebiptables. > Unifying into a single table would break user firewall definitions, which > depend on being able to accept traffic at the Ethernet layer > (currently defined via ebtables) and apply additional filtering > via IP rules (currently defined via ip(6)tables). > The nwfilter_nftables_driver splits the ethernet and > inet rules in seperate tables "libvirt_nwfilter_ethernet" and > "libvirt_nwfilter_inet", for above mentioned compatibility reasons. > > Simplified conntrack handling: rules with accept+conntrack are > duplicated to the opposite chain for symmetric behavior, to support > the existing ebiptables logic. > > Firewall updates continue to use tmp names for atomic replacement. > > Unsupported nwfilter features (for now): > - IPSets (potential future support via nft sets) > - rejects (not allowed in bridge table and POST/PREROUTING hook) > > Signed-off-by: Dion Bosschieter <[email protected]> > --- > po/POTFILES | 1 + > src/nwfilter/meson.build | 1 + > src/nwfilter/nwfilter_nftables_driver.c | 2876 +++++++++++++++++++++++ > src/nwfilter/nwfilter_nftables_driver.h | 28 + > 4 files changed, 2906 insertions(+) > create mode 100644 src/nwfilter/nwfilter_nftables_driver.c > create mode 100644 src/nwfilter/nwfilter_nftables_driver.h > +static void nftablesCreateSameIPSet(virFirewall *fw, > + virFirewallLayer layer, > + const char *tableName) > +{ > + virFirewallCmd *fwrule = NULL; > + size_t i, j; > + virFirewallAddCmd(fw, layer, "add", "set", "bridge", tableName, > + SAME_IP_SET_NAME, "{ type ipv4_addr . ipv4_addr; }", > NULL); > + > + fwrule = virFirewallAddCmd(fw, layer, "add", "element", "bridge", > + tableName, SAME_IP_SET_NAME, "{", NULL); > + > + for (i = 1; i <= 4; i++) { > + for (j = 0; j < 256; j++) { > + virFirewallCmdAddArgFormat(fw, fwrule, "%ld.%ld.%ld.%ld", > + i == 1 ? j : 0, i == 2 ? j : 0, > + i == 3 ? j : 0, i == 4 ? j : 0); > + virFirewallCmdAddArg(fw, fwrule, "."); > + virFirewallCmdAddArgFormat(fw, fwrule, "%ld.%ld.%ld.%ld",
These needed changing to %zu to match the 'size_t' type to fix the 32-bit platform build. > + i == 1 ? j : 0, i == 2 ? j : 0, > + i == 3 ? j : 0, i == 4 ? j : 0); > + virFirewallCmdAddArg(fw, fwrule, ","); > + } > + } > + > + virFirewallCmdAddArg(fw, fwrule, "}"); > +} With regards, Daniel -- |: https://berrange.com ~~ https://hachyderm.io/@berrange :| |: https://libvirt.org ~~ https://entangle-photo.org :| |: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
