[client] Unify peer and route ACL filtering with multi-source rules (#6322)

* Unify peer and route ACL filtering with multi-source peer rules

* Remove partial userspace firewall mode and open foreign chains via a table-less allower

* Snapshot iptables rule maps before persisting state

* Scope userspace firewall wildcard source rules per address family

* Install nftables peer filter and mangle rules in a single transaction

* Share the iptables jump rule spec between install and cleanup

* Fix legacy ACL source wildcard and keep rollback tracking on delete failure

* Fix CI: recognize multi-value port set lookups in tests and correct PeerIP lint suppression

* Fall back to per-prefix filter rules when ipset is unavailable

* Annotate legacy PeerIP usages in ACL tests and fix import formatting

* Keep firewall rule bookkeeping in step with the kernel on replace and teardown

* Release the routing reference when the route manager shuts down

* Keep set references and rule tracking consistent when a routing rule fails
This commit is contained in:
Viktor Liu
2026-09-03 10:02:50 +02:00
committed by GitHub
parent 6aaeed744e
commit 778b3b3264
81 changed files with 9046 additions and 6686 deletions
+29 -10
View File
@@ -1,18 +1,37 @@
package iptables
// Rule to handle management of rules
type Rule struct {
ruleID string
ipsetName string
import "github.com/netbirdio/netbird/client/firewall/manager"
// Rule to handle management of rules. Source set membership (when the
// rule was built against a shared hash:net ipset) is encoded in specs;
// DeleteFilterRule recovers it via findSets so the refcounter can drop
// the right reference.
type Rule struct {
id manager.RuleID
specs []string
mangleSpecs []string
ip string
chain string
v6 bool
// extraRules holds the rules beyond the first when the ipset
// fallback expands a multi-source rule into one rule per prefix.
extraRules []filterSpecs
chain string
v6 bool
}
// GetRuleID returns the rule id
func (r *Rule) ID() string {
return r.ruleID
// filterSpecs is one installed iptables rule: its filter-table spec and
// the paired mangle redirect-mark spec (nil for route rules or when the
// mangle rule could not be added).
type filterSpecs struct {
specs []string
mangleSpecs []string
}
// allSpecs returns the spec pairs of every iptables rule backing this
// Rule, the primary one first.
func (r *Rule) allSpecs() []filterSpecs {
return append([]filterSpecs{{specs: r.specs, mangleSpecs: r.mangleSpecs}}, r.extraRules...)
}
// ID returns the rule id
func (r *Rule) ID() manager.RuleID {
return r.id
}