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 :|

Reply via email to