- New Capabilities: PortPair, Negation, RejectAction,
FamilyWithoutAddress, DenyActionFromConfig, advertised per backend.
- coversDirection isolates DirForward even when output is unowned;
add splitNATDualRow so a concrete-family removal re-adds the opposite
family's NAT translation.
- Resolve ip6tables/ufw ICMPv6 type aliases; ParseNATKind rejects the
"invalid" sentinel as input while JSON round-trips it.
- Sync counts additions on mid-batch failure and uses RuleBatcher.
- NewManager runs a probe loop joining each backend's reason for
diagnosability; services.go drops "generated" from enabled, handles it
on enable, clears start-limit-hit on restart, and matches rc.local by
token.
- nftables: per-source connection limits (meter set), quoted-token
parsing preserving log-prefix spacing, digit-led prefix sanitizing.
- apf/csf: deny-action-from-config with cached STOP settings, port lists
and inexpressible shapes routed through the pre-hook, confKeyApplies
guard against a missing config line.
- atomic config writes fsync before rename and resolve symlinks;
readConfValue is last-assignment-wins; runCommand preserves the exit
code through the wrapped error.
- Move coreos/go-systemd to the maintained v22 module directly.
A temporary holding path until the library is ready to release.
The cmd module, its imports and the README referred to the library as
github.com/grmrgecko/firewall while the root go.mod declared it as
github.com/grmrgecko/go-firewall, so its require/replace pair never named the
module it was replacing. Point all of them at the new path, which makes them
agree for the first time. The go-firewalld dependency shares the old prefix and
is unrelated; it is left alone.
Introduce TCPUDP as the protocol analog of FamilyAny and DirAny: a merged
value spanning both transports, distinct from ProtocolAny (which matches
every IP protocol and carries no port). Backends whose native syntax holds
both transports in one row (nftables, ufw, apf) store and read it as one
rule; the rest fan it out with expandProtocols. Removing one transport of a
merged row splits it via splitMergedRow, which composes the family and
protocol splits so an nftables row merged on both axes leaves a correct,
non-overlapping remainder. NAT rejects TCPUDP with ErrUnsupportedNAT.
Remove read-side merging. GetRules now reports the firewall's actual rows
and never synthesizes a FamilyAny, TCPUDP, or DirAny rule by pairing up
separately-stored ones, so mergeFamilies, mergeDirections and their helpers
are gone and mergedInsertIndex becomes logicalInsertIndex. Rules are instead
compared by coverage: the new exported Rule.Covers / Rule.CoveredBy (and the
NATRule pair) expand a rule across family, transport and direction and decide
containment cell by cell, which is what lets Sync stay a no-op against its
own output whichever representation a backend chose.
Extract the systemd/SysV service helpers out of the iptables backend into
services.go so every Linux backend shares one implementation, and document
the multi-state rule model and the coverage helpers in the README.