[PATCH v5 0/3] nwfilter: add nwfilter nftables driver

Dion Bosschieter posted 3 patches 5 months ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/libvirt tags/patchew/20260216104239.90941-1-dionbosschieter@gmail.com
There is a newer version of this series
libvirt.spec.in                               |    7 +
po/POTFILES                                   |    2 +
src/conf/virnwfilterobj.h                     |   20 -
src/nwfilter/libvirtd_nwfilter.aug            |   45 +
src/nwfilter/meson.build                      |   38 +
src/nwfilter/nwfilter.conf.in                 |   50 +
src/nwfilter/nwfilter_driver.c                |   66 +-
src/nwfilter/nwfilter_driver_conf.c           |  214 +
src/nwfilter/nwfilter_driver_conf.h           |   69 +
src/nwfilter/nwfilter_ebiptables_driver.c     |    4 +-
src/nwfilter/nwfilter_ebiptables_driver.h     |    2 +-
src/nwfilter/nwfilter_gentech_driver.c        |   65 +-
src/nwfilter/nwfilter_gentech_driver.h        |    5 +-
src/nwfilter/nwfilter_nftables_driver.c       | 2668 ++++++++++++
src/nwfilter/nwfilter_nftables_driver.h       |   28 +
src/nwfilter/nwfilter_tech_driver.h           |    3 +-
src/nwfilter/test_libvirtd_nwfilter.aug.in    |    7 +
tests/meson.build                             |    2 +
tests/nwfilternftablestest.c                  |  426 ++
.../ah-ipv6-linux.nftables.args               |  310 ++
.../ah-linux.nftables.args                    |  304 ++
.../all-ipv6-linux.nftables.args              |  292 ++
.../all-linux.nftables.args                   |  286 ++
.../arp-linux.nftables.args                   |  231 +
.../nwfilterxml2firewalldata/arp.nftables.xml |   27 +
.../comment-linux.nftables.args               |  510 +++
.../conntrack-linux.nftables.args             |  198 +
.../esp-ipv6-linux.nftables.args              |  310 ++
.../esp-linux.nftables.args                   |  304 ++
.../example-1-linux.nftables.args             |  268 ++
.../example-2-linux.nftables.args             |  352 ++
.../hex-data-linux.nftables.args              |  384 ++
.../icmp-direction-linux.nftables.args        |  238 ++
.../icmp-direction2-linux.nftables.args       |  238 ++
.../icmp-direction3-linux.nftables.args       |  184 +
.../icmp-linux.nftables.args                  |  256 ++
.../icmpv6-linux.nftables.args                |  328 ++
.../igmp-linux.nftables.args                  |  304 ++
.../ip-linux.nftables.args                    |  205 +
.../ipt-no-macspoof-linux.nftables.args       |  172 +
.../ipv6-linux.nftables.args                  |  511 +++
.../iter1-linux.nftables.args                 |  304 ++
.../iter2-linux.nftables.args                 | 3760 +++++++++++++++++
.../iter3-linux.nftables.args                 |  430 ++
.../mac-linux.nftables.args                   |  184 +
.../rarp-linux.nftables.args                  |  215 +
.../sctp-ipv6-linux.nftables.args             |  328 ++
.../sctp-linux.nftables.args                  |  328 ++
.../target-linux.nftables.args                |  466 ++
.../target2-linux.nftables.args               |  322 ++
.../tcp-ipv6-linux.nftables.args              |  328 ++
.../tcp-linux.nftables.args                   |  476 +++
.../udp-ipv6-linux.nftables.args              |  328 ++
.../udp-linux.nftables.args                   |  328 ++
.../udplite-ipv6-linux.nftables.args          |  310 ++
.../udplite-linux.nftables.args               |  304 ++
.../vlan-linux.nftables.args                  |  271 ++
.../ah-ipv6-linux.args                        |  304 ++
.../nwfilterxml2nftfirewalldata/ah-linux.args |  298 ++
.../all-ipv6-linux.args                       |  286 ++
.../all-linux.args                            |  280 ++
.../arp-linux.args                            |  215 +
tests/nwfilterxml2nftfirewalldata/arp.xml     |   27 +
.../comment-linux.args                        |  483 +++
.../conntrack-linux.args                      |  198 +
.../esp-ipv6-linux.args                       |  304 ++
.../esp-linux.args                            |  298 ++
.../example-1-linux.args                      |  266 ++
.../example-2-linux.args                      |  348 ++
.../hex-data-linux.args                       |  357 ++
.../icmp-direction-linux.args                 |  238 ++
.../icmp-direction2-linux.args                |  238 ++
.../icmp-direction3-linux.args                |  184 +
.../icmp-linux.args                           |  252 ++
.../icmpv6-linux.args                         |  322 ++
.../igmp-linux.args                           |  298 ++
.../nwfilterxml2nftfirewalldata/ip-linux.args |  198 +
.../ipt-no-macspoof-linux.args                |  169 +
.../ipv6-linux.args                           |  474 +++
.../iter1-linux.args                          |  298 ++
.../iter2-linux.args                          | 3598 ++++++++++++++++
.../iter3-linux.args                          |  418 ++
.../mac-linux.args                            |  180 +
.../rarp-linux.args                           |  215 +
.../sctp-ipv6-linux.args                      |  314 ++
.../sctp-linux.args                           |  314 ++
.../target-linux.args                         |  452 ++
.../target2-linux.args                        |  316 ++
.../tcp-ipv6-linux.args                       |  314 ++
.../tcp-linux.args                            |  468 ++
.../udp-ipv6-linux.args                       |  314 ++
.../udp-linux.args                            |  314 ++
.../udplite-ipv6-linux.args                   |  304 ++
.../udplite-linux.args                        |  298 ++
.../vlan-linux.args                           |  264 ++
tests/nwfilterxml2nftfirewalltest.c           |  438 ++
96 files changed, 33369 insertions(+), 102 deletions(-)
create mode 100644 src/nwfilter/libvirtd_nwfilter.aug
create mode 100644 src/nwfilter/nwfilter.conf.in
create mode 100644 src/nwfilter/nwfilter_driver_conf.c
create mode 100644 src/nwfilter/nwfilter_driver_conf.h
create mode 100644 src/nwfilter/nwfilter_nftables_driver.c
create mode 100644 src/nwfilter/nwfilter_nftables_driver.h
create mode 100644 src/nwfilter/test_libvirtd_nwfilter.aug.in
create mode 100644 tests/nwfilternftablestest.c
create mode 100755 tests/nwfilterxml2firewalldata/ah-ipv6-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/ah-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/all-ipv6-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/all-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/arp-linux.nftables.args
create mode 100644 tests/nwfilterxml2firewalldata/arp.nftables.xml
create mode 100755 tests/nwfilterxml2firewalldata/comment-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/conntrack-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/esp-ipv6-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/esp-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/example-1-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/example-2-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/hex-data-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/icmp-direction-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/icmp-direction2-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/icmp-direction3-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/icmp-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/icmpv6-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/igmp-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/ip-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/ipt-no-macspoof-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/ipv6-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/iter1-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/iter2-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/iter3-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/mac-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/rarp-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/sctp-ipv6-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/sctp-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/target-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/target2-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/tcp-ipv6-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/tcp-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/udp-ipv6-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/udp-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/udplite-ipv6-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/udplite-linux.nftables.args
create mode 100755 tests/nwfilterxml2firewalldata/vlan-linux.nftables.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/ah-ipv6-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/ah-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/all-ipv6-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/all-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/arp-linux.args
create mode 100644 tests/nwfilterxml2nftfirewalldata/arp.xml
create mode 100755 tests/nwfilterxml2nftfirewalldata/comment-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/conntrack-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/esp-ipv6-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/esp-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/example-1-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/example-2-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/hex-data-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/icmp-direction-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/icmp-direction2-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/icmp-direction3-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/icmp-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/icmpv6-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/igmp-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/ip-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/ipt-no-macspoof-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/ipv6-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/iter1-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/iter2-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/iter3-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/mac-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/rarp-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/sctp-ipv6-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/sctp-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/target-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/target2-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/tcp-ipv6-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/tcp-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/udp-ipv6-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/udp-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/udplite-ipv6-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/udplite-linux.args
create mode 100755 tests/nwfilterxml2nftfirewalldata/vlan-linux.args
create mode 100644 tests/nwfilterxml2nftfirewalltest.c
[PATCH v5 0/3] nwfilter: add nwfilter nftables driver
Posted by Dion Bosschieter 5 months ago
This series aims to implement nftables as a backend driver for
the nwfilter feature. The idea is that it will replace
the ebiptables driver and provide an easy way for users to switch
from one driver to another.

The 1st patch introduces the new nwfilter driver. After which nwfilter allows
users to choose it in the 2nd patch.

The last patch introduces unit testing of the new nftables driver.

- Implemented very basic nwfilter.conf reading and choosing a nwfilter
  driver based on the name of the drivers (nftables/ebiptables).
  Defaults to the nftables driver, based on the firewall_backend_priority
  meson option, following the bridge driver logic.
- 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.
- Split rules into separate tables: "libvirt-nwfilter-ethernet" and
  "libvirt-nwfilter-other" to preserve existing 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).
- 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".
- Rewrote chain logic, so it is easier to understand,
  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 and -other table follow the same style and
  hook in the same way.
- 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 use tmp names for atomic replacement.

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

Future improvements:
- Use `nft -f` for atomic rule application.
- Optional single-table mode via nwfilter.conf.
- Optimize boot phase with chain hash comparison.

---
Changes in v5:
- Fix rarp support via nft raw payload expression

Changes in v4:
- Fix rarp nft commands "arp saddr ether" "arp daddr ether"
- Filter chain creation, don't create unnecessary chains
- Apply danpb seperate argument suggestion
- Fix table not existing errors in drop all rules
- Fix table not existing errors in apply basic rules

Changes in v3:
- Renamed -other to -inet
- Renamed - to _ in table names
- Updated rule / chain sorting on ethernet table to to copy ebtables logic
- Fix possible broken revert path
- Fix remove rules not working in some cases, EBUSY
- Shared functions camel case commit
- Rename config option
- Add extra config params, enable_trace, enable_counters
  This required passing the config struct to the ebip/nft nwfilter drivers
- Add extra augeaus files

Changes in v2:
- Rename {ebip,nf}tables specific test files in 1 directory instead of
  seperating them in different directories.
- Added default nwfilter.conf file in git, documented including augeas files
- Replaced hardcoding of default driver based on existing
  firewall_backend_priority meson option.
- Added nwfilter_driver_conf.{h,c} for configuration handling,
  to match the common pattern used in other drivers.

Dion Bosschieter (3):
  nwfilter: add nwfilter nftables driver
  nwfilter: allow use of nftables nwfilter driver via nwfilter.conf
  nwfilter: add unit tests and test data for nwfilter nftables driver

 libvirt.spec.in                               |    7 +
 po/POTFILES                                   |    2 +
 src/conf/virnwfilterobj.h                     |   20 -
 src/nwfilter/libvirtd_nwfilter.aug            |   45 +
 src/nwfilter/meson.build                      |   38 +
 src/nwfilter/nwfilter.conf.in                 |   50 +
 src/nwfilter/nwfilter_driver.c                |   66 +-
 src/nwfilter/nwfilter_driver_conf.c           |  214 +
 src/nwfilter/nwfilter_driver_conf.h           |   69 +
 src/nwfilter/nwfilter_ebiptables_driver.c     |    4 +-
 src/nwfilter/nwfilter_ebiptables_driver.h     |    2 +-
 src/nwfilter/nwfilter_gentech_driver.c        |   65 +-
 src/nwfilter/nwfilter_gentech_driver.h        |    5 +-
 src/nwfilter/nwfilter_nftables_driver.c       | 2668 ++++++++++++
 src/nwfilter/nwfilter_nftables_driver.h       |   28 +
 src/nwfilter/nwfilter_tech_driver.h           |    3 +-
 src/nwfilter/test_libvirtd_nwfilter.aug.in    |    7 +
 tests/meson.build                             |    2 +
 tests/nwfilternftablestest.c                  |  426 ++
 .../ah-ipv6-linux.nftables.args               |  310 ++
 .../ah-linux.nftables.args                    |  304 ++
 .../all-ipv6-linux.nftables.args              |  292 ++
 .../all-linux.nftables.args                   |  286 ++
 .../arp-linux.nftables.args                   |  231 +
 .../nwfilterxml2firewalldata/arp.nftables.xml |   27 +
 .../comment-linux.nftables.args               |  510 +++
 .../conntrack-linux.nftables.args             |  198 +
 .../esp-ipv6-linux.nftables.args              |  310 ++
 .../esp-linux.nftables.args                   |  304 ++
 .../example-1-linux.nftables.args             |  268 ++
 .../example-2-linux.nftables.args             |  352 ++
 .../hex-data-linux.nftables.args              |  384 ++
 .../icmp-direction-linux.nftables.args        |  238 ++
 .../icmp-direction2-linux.nftables.args       |  238 ++
 .../icmp-direction3-linux.nftables.args       |  184 +
 .../icmp-linux.nftables.args                  |  256 ++
 .../icmpv6-linux.nftables.args                |  328 ++
 .../igmp-linux.nftables.args                  |  304 ++
 .../ip-linux.nftables.args                    |  205 +
 .../ipt-no-macspoof-linux.nftables.args       |  172 +
 .../ipv6-linux.nftables.args                  |  511 +++
 .../iter1-linux.nftables.args                 |  304 ++
 .../iter2-linux.nftables.args                 | 3760 +++++++++++++++++
 .../iter3-linux.nftables.args                 |  430 ++
 .../mac-linux.nftables.args                   |  184 +
 .../rarp-linux.nftables.args                  |  215 +
 .../sctp-ipv6-linux.nftables.args             |  328 ++
 .../sctp-linux.nftables.args                  |  328 ++
 .../target-linux.nftables.args                |  466 ++
 .../target2-linux.nftables.args               |  322 ++
 .../tcp-ipv6-linux.nftables.args              |  328 ++
 .../tcp-linux.nftables.args                   |  476 +++
 .../udp-ipv6-linux.nftables.args              |  328 ++
 .../udp-linux.nftables.args                   |  328 ++
 .../udplite-ipv6-linux.nftables.args          |  310 ++
 .../udplite-linux.nftables.args               |  304 ++
 .../vlan-linux.nftables.args                  |  271 ++
 .../ah-ipv6-linux.args                        |  304 ++
 .../nwfilterxml2nftfirewalldata/ah-linux.args |  298 ++
 .../all-ipv6-linux.args                       |  286 ++
 .../all-linux.args                            |  280 ++
 .../arp-linux.args                            |  215 +
 tests/nwfilterxml2nftfirewalldata/arp.xml     |   27 +
 .../comment-linux.args                        |  483 +++
 .../conntrack-linux.args                      |  198 +
 .../esp-ipv6-linux.args                       |  304 ++
 .../esp-linux.args                            |  298 ++
 .../example-1-linux.args                      |  266 ++
 .../example-2-linux.args                      |  348 ++
 .../hex-data-linux.args                       |  357 ++
 .../icmp-direction-linux.args                 |  238 ++
 .../icmp-direction2-linux.args                |  238 ++
 .../icmp-direction3-linux.args                |  184 +
 .../icmp-linux.args                           |  252 ++
 .../icmpv6-linux.args                         |  322 ++
 .../igmp-linux.args                           |  298 ++
 .../nwfilterxml2nftfirewalldata/ip-linux.args |  198 +
 .../ipt-no-macspoof-linux.args                |  169 +
 .../ipv6-linux.args                           |  474 +++
 .../iter1-linux.args                          |  298 ++
 .../iter2-linux.args                          | 3598 ++++++++++++++++
 .../iter3-linux.args                          |  418 ++
 .../mac-linux.args                            |  180 +
 .../rarp-linux.args                           |  215 +
 .../sctp-ipv6-linux.args                      |  314 ++
 .../sctp-linux.args                           |  314 ++
 .../target-linux.args                         |  452 ++
 .../target2-linux.args                        |  316 ++
 .../tcp-ipv6-linux.args                       |  314 ++
 .../tcp-linux.args                            |  468 ++
 .../udp-ipv6-linux.args                       |  314 ++
 .../udp-linux.args                            |  314 ++
 .../udplite-ipv6-linux.args                   |  304 ++
 .../udplite-linux.args                        |  298 ++
 .../vlan-linux.args                           |  264 ++
 tests/nwfilterxml2nftfirewalltest.c           |  438 ++
 96 files changed, 33369 insertions(+), 102 deletions(-)
 create mode 100644 src/nwfilter/libvirtd_nwfilter.aug
 create mode 100644 src/nwfilter/nwfilter.conf.in
 create mode 100644 src/nwfilter/nwfilter_driver_conf.c
 create mode 100644 src/nwfilter/nwfilter_driver_conf.h
 create mode 100644 src/nwfilter/nwfilter_nftables_driver.c
 create mode 100644 src/nwfilter/nwfilter_nftables_driver.h
 create mode 100644 src/nwfilter/test_libvirtd_nwfilter.aug.in
 create mode 100644 tests/nwfilternftablestest.c
 create mode 100755 tests/nwfilterxml2firewalldata/ah-ipv6-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/ah-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/all-ipv6-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/all-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/arp-linux.nftables.args
 create mode 100644 tests/nwfilterxml2firewalldata/arp.nftables.xml
 create mode 100755 tests/nwfilterxml2firewalldata/comment-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/conntrack-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/esp-ipv6-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/esp-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/example-1-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/example-2-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/hex-data-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/icmp-direction-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/icmp-direction2-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/icmp-direction3-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/icmp-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/icmpv6-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/igmp-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/ip-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/ipt-no-macspoof-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/ipv6-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/iter1-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/iter2-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/iter3-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/mac-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/rarp-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/sctp-ipv6-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/sctp-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/target-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/target2-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/tcp-ipv6-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/tcp-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/udp-ipv6-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/udp-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/udplite-ipv6-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/udplite-linux.nftables.args
 create mode 100755 tests/nwfilterxml2firewalldata/vlan-linux.nftables.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/ah-ipv6-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/ah-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/all-ipv6-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/all-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/arp-linux.args
 create mode 100644 tests/nwfilterxml2nftfirewalldata/arp.xml
 create mode 100755 tests/nwfilterxml2nftfirewalldata/comment-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/conntrack-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/esp-ipv6-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/esp-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/example-1-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/example-2-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/hex-data-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/icmp-direction-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/icmp-direction2-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/icmp-direction3-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/icmp-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/icmpv6-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/igmp-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/ip-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/ipt-no-macspoof-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/ipv6-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/iter1-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/iter2-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/iter3-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/mac-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/rarp-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/sctp-ipv6-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/sctp-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/target-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/target2-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/tcp-ipv6-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/tcp-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/udp-ipv6-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/udp-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/udplite-ipv6-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/udplite-linux.args
 create mode 100755 tests/nwfilterxml2nftfirewalldata/vlan-linux.args
 create mode 100644 tests/nwfilterxml2nftfirewalltest.c

-- 
2.43.0
Re: [PATCH v5 0/3] nwfilter: add nwfilter nftables driver
Posted by Daniel P. Berrangé via Devel 3 months, 3 weeks ago
On Mon, Feb 16, 2026 at 11:42:36AM +0100, Dion Bosschieter wrote:
> 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

What are your thoughts on these gaps ?

The Gratuituous ARP gap triggers a warning in libvirt-tck
tests.

I don't think we need to block for these, as the new driver is
already functional enough to be useful.

> 
> Future improvements:
> - Use `nft -f` for atomic rule application.
> - Optional single-table mode via nwfilter.conf.
> - Optimize boot phase with chain hash comparison.

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 :|
Re: [PATCH v5 0/3] nwfilter: add nwfilter nftables driver
Posted by Dion Bosschieter 3 months, 3 weeks ago
On 3/27/26 17:58, Daniel P. Berrangé wrote:
> On Mon, Feb 16, 2026 at 11:42:36AM +0100, Dion Bosschieter wrote:
>> Unsupported nwfilter features (for now):
>> - STP filtering
>> - Gratuitous ARP filtering
>> - IPSets (potential future support via nft sets)

IPSets via nft sets could work if the user predefines the nft sets in 
the table where they are going to be referenced. This requires the user 
to create the libvirt table first before starting libvirt.
That is not ideal, but could be a solution.

>> - Reject due to filtering in pre/postrouting, using drop instead
>>    of reject, copying logic from existing ebiptables ebtables actions

I should take a 2nd look at changing the _inet table to an inet table 
type, this way we can support reject and be more compatible with ebiptables.

> 
> What are your thoughts on these gaps ?

Looking at what worked for adding rarp support, I think the same can be 
done for STP, it requires a bit of, to see if the rules indeed match.

> 
> The Gratuituous ARP gap triggers a warning in libvirt-tck
> tests.

I finally was able to get garp support working, this also requires a bit 
of work and is not pretty. I'll describe below what solution seems to 
work. Tested by sending garp traffic using arping -I br0 -A 192.168.1.1

nftables nft command doesn't support field to field matching a simple 
arp saddr ip == arp daddr ip, would otherwise suffice.

 From ebtables man page:
        [!] --arp-gratuitous
               Checks for ARP gratuitous packets: checks equality of IPv4
               source address and IPv4 destination address inside the ARP
               header.

Something that could work though is creating an nftables concatenation 
set: { type ipv4_addr . ipv4_addr }

Creating 1 set to match against, would mean we will have list all ipv4 
ips in that set. That is not a solution.

Creating 4 sets to match against combined with netmasking would however 
work.

garp-1 { 0.0.0.0 . 0.0.0.0, 1.0.0.0 . 1.0.0.0, ...
garp-2 { 0.0.0.0 . 0.0.0.0, 0.1.0.0 . 0.1.0.0, ...
garp-3 { 0.0.0.0 . 0.0.0.0, 0.0.1.0 . 0.0.1.0, ...
garp-4 { 0.0.0.0 . 0.0.0.0, 0.0.0.1 . 0.0.0.1, ...

For full sets, see: 
https://gist.github.com/dionbosschieter/01665ef03d19950c37e8231bd00d1736

And finally the garp rule:

arp saddr ip & 255.0.0.0 . arp daddr ip & 255.0.0.0 @garp-1 arp saddr ip 
& 0.255.0.0 . arp daddr ip & 0.255.0.0 @garp-2 arp saddr ip & 0.0.255.0 
. arp daddr ip & 0.0.255.0 @garp-3 arp saddr ip & 0.0.0.255 . arp daddr 
ip & 0.0.0.255 @garp-4 counter packets 3 bytes 132 accept comment 
"priority=-500"

I can add that the garp sets get added to the _ethernet table. After 
that adding the rule itself is trivial.

This seems to work as the counter increases when running the arping 
command mentioned above.

Thoughts on this solution?

> 
> I don't think we need to block for these, as the new driver is
> already functional enough to be useful.

With regards,

Dion
Re: [PATCH v5 0/3] nwfilter: add nwfilter nftables driver
Posted by Dion Bosschieter 3 months, 3 weeks ago
On 3/30/26 15:21, Dion Bosschieter wrote:
> On 3/27/26 17:58, Daniel P. Berrangé wrote:
>> On Mon, Feb 16, 2026 at 11:42:36AM +0100, Dion Bosschieter wrote:
>>> Unsupported nwfilter features (for now):
>>> - STP filtering
>>> - Gratuitous ARP filtering
>>> - IPSets (potential future support via nft sets)
> 
> IPSets via nft sets could work if the user predefines the nft sets in 
> the table where they are going to be referenced. This requires the user 
> to create the libvirt table first before starting libvirt.
> That is not ideal, but could be a solution.

Not something that needs to happen premerge is my opinion.

>>> - Reject due to filtering in pre/postrouting, using drop instead
>>>    of reject, copying logic from existing ebiptables ebtables actions
> 
> I should take a 2nd look at changing the _inet table to an inet table 
> type, this way we can support reject and be more compatible with 
> ebiptables.
> 

I tried to use the inet type in combination with the forward and input 
hook, but I think this causes more issues than it solves (ability to 
reject).

Overall the nft prerouting & postrouting design is easier to read and 
understand than having the iptables libvirt-host-in, libvirt-in, 
libvirt-in-post, libvirt-out design.

I also seem to have issues seeing packets with the forward hook in nft, 
that might be due to the bridge-nf-call-iptables sysctl 
(https://netdevconf.info/1.1/proceedings/papers/Bridge-filter-with-nftables.pdf)

>>
>> What are your thoughts on these gaps ?
> 
> Looking at what worked for adding rarp support, I think the same can be 
> done for STP, it requires a bit of, to see if the rules indeed match.
> 
>>
>> The Gratuituous ARP gap triggers a warning in libvirt-tck
>> tests.
> 
> I finally was able to get garp support working, this also requires a bit 
> of work and is not pretty. I'll describe below what solution seems to 
> work. Tested by sending garp traffic using arping -I br0 -A 192.168.1.1
> 
> nftables nft command doesn't support field to field matching a simple 
> arp saddr ip == arp daddr ip, would otherwise suffice.
> 
>  From ebtables man page:
>         [!] --arp-gratuitous
>                Checks for ARP gratuitous packets: checks equality of IPv4
>                source address and IPv4 destination address inside the ARP
>                header.
> 
> Something that could work though is creating an nftables concatenation 
> set: { type ipv4_addr . ipv4_addr }
> 
> Creating 1 set to match against, would mean we will have list all ipv4 
> ips in that set. That is not a solution.
> 
> Creating 4 sets to match against combined with netmasking would however 
> work.
> 
> garp-1 { 0.0.0.0 . 0.0.0.0, 1.0.0.0 . 1.0.0.0, ...
> garp-2 { 0.0.0.0 . 0.0.0.0, 0.1.0.0 . 0.1.0.0, ...
> garp-3 { 0.0.0.0 . 0.0.0.0, 0.0.1.0 . 0.0.1.0, ...
> garp-4 { 0.0.0.0 . 0.0.0.0, 0.0.0.1 . 0.0.0.1, ...
> 
> For full sets, see: https://gist.github.com/ 
> dionbosschieter/01665ef03d19950c37e8231bd00d1736
> 
> And finally the garp rule:
> 
> arp saddr ip & 255.0.0.0 . arp daddr ip & 255.0.0.0 @garp-1 arp saddr ip 
> & 0.255.0.0 . arp daddr ip & 0.255.0.0 @garp-2 arp saddr ip & 
> 0.0.255.0 . arp daddr ip & 0.0.255.0 @garp-3 arp saddr ip & 0.0.0.255 . 
> arp daddr ip & 0.0.0.255 @garp-4 counter packets 3 bytes 132 accept 
> comment "priority=-500"
> 
> I can add that the garp sets get added to the _ethernet table. After 
> that adding the rule itself is trivial.

I can submit this in a v6 as well. I am not a fan of having a static set 
with 1024 entries in it. But I don't see other solutions to support garp 
filtering.

Kind regards,

Dion
Re: [PATCH v5 0/3] nwfilter: add nwfilter nftables driver
Posted by Dion Bosschieter 3 months, 3 weeks ago
On 3/30/26 15:21, Dion Bosschieter wrote:
> On 3/27/26 17:58, Daniel P. Berrangé wrote:
>> On Mon, Feb 16, 2026 at 11:42:36AM +0100, Dion Bosschieter wrote:
>>> Unsupported nwfilter features (for now):
>>> - STP filtering
>>> - Gratuitous ARP filtering
>>> - IPSets (potential future support via nft sets)
> 
> IPSets via nft sets could work if the user predefines the nft sets in 
> the table where they are going to be referenced. This requires the user 
> to create the libvirt table first before starting libvirt.
> That is not ideal, but could be a solution.
> 
>>> - Reject due to filtering in pre/postrouting, using drop instead
>>>    of reject, copying logic from existing ebiptables ebtables actions
> 
> I should take a 2nd look at changing the _inet table to an inet table 
> type, this way we can support reject and be more compatible with 
> ebiptables.
> 
>>
>> What are your thoughts on these gaps ?
> 
> Looking at what worked for adding rarp support, I think the same can be 
> done for STP, it requires a bit of, to see if the rules indeed match.
> 
>>
>> The Gratuituous ARP gap triggers a warning in libvirt-tck
>> tests.
> 
> I finally was able to get garp support working, this also requires a bit 
> of work and is not pretty. I'll describe below what solution seems to 
> work. Tested by sending garp traffic using arping -I br0 -A 192.168.1.1
> 
> nftables nft command doesn't support field to field matching a simple 
> arp saddr ip == arp daddr ip, would otherwise suffice.
> 
>  From ebtables man page:
>         [!] --arp-gratuitous
>                Checks for ARP gratuitous packets: checks equality of IPv4
>                source address and IPv4 destination address inside the ARP
>                header.
> 
> Something that could work though is creating an nftables concatenation 
> set: { type ipv4_addr . ipv4_addr }
> 
> Creating 1 set to match against, would mean we will have list all ipv4 
> ips in that set. That is not a solution.
> 
> Creating 4 sets to match against combined with netmasking would however 
> work.

One set with all 4 of these lists in it also works. It would create 1 
set, for example same-ip-set, with 1024 entries in it.

same-ip-set { 0.0.0.0 . 0.0.0.0, 1.0.0.0 . 1.0.0.0, ...

With the rule:

arp saddr ip & 255.0.0.0 . arp daddr ip & 255.0.0.0 @same-ip-set arp 
saddr ip & 0.255.0.0 . arp daddr ip & 0.255.0.0 @same-ip-set arp saddr 
ip & 0.0.255.0 . arp daddr ip & 0.0.255.0 @same-ip-set arp saddr ip & 
0.0.0.255 . arp daddr ip & 0.0.0.255 @same-ip-set counter packets 2 
bytes 88 accept

With regards,

Dion