On Fri, Jan 16, 2026 at 05:18:29PM +0000, Daniel P. Berrangé via Devel wrote:
On Thu, Dec 11, 2025 at 03:00:49PM +0100, Dion Bosschieter wrote:
This series aims to implement nftables as a backend driver for the nwfilter feature. The idea is that eventually it will replace the ebiptables driver and provide an easy way for users to switch from one driver to another.
The first 2 patches are moving of functions and renames, meant to decouple nwfilter from the currently only existing ebiptables driver.
The 3rd patch introduces the new nwfilter driver. After which nwfilter allows users to choose it in the 4th patch.
The last patch introduces unit testing of the new nftables driver.
- Resolves issue https://gitlab.com/libvirt/libvirt/-/issues/603 benchmarks showed that the amount of iifname jumps for each interface with 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 a performance issue, the vmap instead solves this.
That's good.
- Split rules into separate tables: "libvirt-nwfilter-ethernet" and "libvirt-nwfilter-other" to preserve existing firewall behavior.
- Stuck with prerouting and postrouting as hooks for input / output on the -ethernet and -other table. This makes it easier to merge the tables in the future. Saving management of two tables and decreasing the amount of tables a packet sees. Currently ebtables filtering happens via PREROUTING and POSTROUTING hooks, while ip/ip6tables filtering happens in the output/forward hooks. - Stuck with 2 tables for compatibility reasons with eb iptables, unifying into 1 table will break users firewall definitions, which depend on being able to do accepts on ethernet rules (which currently get defined via ebtables) and additional filtering via the ip rules (which currently get defined via ip(6)tables). The nwfilter_nftables_driver keeps splitting the ethernet and non ethernet (other) rules in seperate tables "libvirt-nwfilter-ethernet" and "libvirt-nwfilter-other".
I guess with xtables, we would have effectively three - ebtables, iptables and ip6tables. "other" here covers both iptables and ip6tables which is fine because rules for those are mutually exclusive for any single packet. Perhaps call it "-inet" instead of '-other' ?
Unsupported nwfilter features (for now): - STP filtering - Gratuitous ARP filtering - IPSets (potential future support via nft sets) - Reject due to filtering in pre/postrouting, using drop instead of reject, copying logic from existing ebiptables ebtables actions
I don't know if it is related, but when I tried this patch series on an existing VM configured with the "clean-traffic" filter I get a failure:
2026-01-16 16:24:14.492+0000: 749946: error : virFirewallCmdNftablesApply:748 : internal error: Failed to apply firewall command 'nft add rule bridge libvirt-nwfilter-ethernet n-vnet0-rarp-out ether saddr == 52:54:00:5e:58:55 ether daddr == ff:ff:ff:ff:ff:ff ether type 0x8035 'arp operation' 3 arp saddr ip 0.0.0.0/32 arp daddr ip 0.0.0.0/32 'ether saddr' 52:54:00:5e:58:55 'ether daddr' 52:54:00:5e:58:55 accept comment '"priority=500"'': Error: conflicting statements
Also when this fails, the rollback code doesn't seem to work either, as the tables get left with a bunch of stale rules With regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|