Page MenuHomeVyOS Platform

Optimize nftables Set Generation for Performance
Open, NormalPublicFEATURE REQUEST

Description

Summary

Optimize nftables set generation in VyOS firewall groups so that the Jinja2 template emits flags interval and auto‑merge only when they are truly needed - i.e., when at least one ranged element (CIDR wider than a host mask, explicit address span, service/port range, etc.) is present.

Add an optional autoexpand CLI flag that, when enabled, converts those ranges into individual elements so the set can stay on the constant‑time hash backend (nft_set_hash).

An additional policy performance|memory knob lets operators hint the kernel which metric matters. With these changes, discrete‑only groups (and expandable ranges) avoid the O(log n) red‑black‑tree path and recover O(1) lookups and lower CPU usage on large rulesets.


Use case

Enterprise and ISP edge routers routinely load:

  • Threat‑feed blacklists (10 k-100 k individual IPs).
  • Micro‑segmentation rule sets (thousands of discrete TCP/UDP ports).
  • Small subnets such as /24 allowlists that could be expanded to hosts.

Today every VyOS “firewall group” carries flags interval, forcing the rbtree backend even when 100 % of elements are discrete. On low‑end CPE hardware or with large sets, this degrades throughput. Conditional interval flags - plus optional auto‑expansion - let these sets remain hash‑indexed and restore maximum forwarding performance.


Additional information

Template logic changes

  • Detect ranges while rendering: for each element token inspect for
    • a hyphen (-),
    • a slash with prefix length < host mask (IPv4 /32, IPv6 /128).
  • Emission rules
    1. *No ranges detected* → emit without interval/auto‑merge → kernel picks hash backend.
    2. *Ranges detected & autoexpand off* → keep current behaviour (interval, optional auto‑merge).
    3. *Ranges detected & autoexpand on* → expand each detected range into discrete tokens, emit hash‑friendly set. If expansion exceeds a configurable element limit (default UINT_MAX), fall back to rbtree and warn the user.
  • domain_group and interface_group sets can never contain ranges → always hash.

Implementation: expansion can leverage Python’s ipaddress module for CIDRs and a simple loop for port ranges; all executed at firewall group build‑time.

New CLI nodes

set firewall group ... policy (performance|memory)
set firewall group ... autoexpand (enable|disable)
  • policy maps directly to the nftables policy keyword.
  • autoexpand defaults to disable; when enabled, the template performs the expansion logic described above.
  • Validation: if autoexpand enable and the result would exceed the element limit, the commit script emits a clear warning and retains the rbtree implementation.

Compatibility & fallback

  • Existing configurations load unchanged. Without autoexpand, behaviour is identical except that purely discrete sets lose interval/auto‑merge automatically.

Reference implementation details

Details

Version
-
Is it a breaking change?
Perfectly compatible
Issue type
Performance optimization