Documentation
¶
Overview ¶
Package sync provides nftables synchronization utilities
Index ¶
- Constants
- func ApplyDiffToSetWithStats(nft *NFTManager, set *nftables.Set, diff util.DiffResult[string]) (added, removed, unchanged int, err error)
- func ApplyStringDiffToSet(nft *NFTManager, set *nftables.Set, diff util.DiffResult[string]) error
- func BatchApplyDiff(nft *NFTManager, applications []DiffApplication) error
- func GetSyncEfficiency(stats *SyncStats) float64
- func IsFastSync(stats *SyncStats, threshold int) bool
- func NftListSet(family, table, setName string) (string, error)
- func PrintSyncResult(result *SyncResult)
- func PrintSyncStats(stats *SyncStats)
- type DiffApplication
- type DiffResult
- type IPRange
- type MergeStats
- type NFTManager
- func (m *NFTManager) AddCIDRElements(set *nftables.Set, cidrs []string) error
- func (m *NFTManager) AddCIDRElementsWithStats(set *nftables.Set, cidrs []string) (*MergeStats, error)
- func (m *NFTManager) AddDropRuleForSet(chain *nftables.Chain, set *nftables.Set, ipv4 bool) error
- func (m *NFTManager) AddIPWithTimeout(set *nftables.Set, ipStr string, timeout time.Duration) error
- func (m *NFTManager) AddPortElements(set *nftables.Set, ports []int) error
- func (m *NFTManager) AddSetElements(set *nftables.Set, ips []string) error
- func (m *NFTManager) Close()
- func (m *NFTManager) CreateChainIfNotExists(table *nftables.Table, chainName string, chainType nftables.ChainType, ...) (*nftables.Chain, error)
- func (m *NFTManager) DeleteFromIntervalSetCLI(set *nftables.Set, ipStr string) error
- func (m *NFTManager) DeletePortElements(set *nftables.Set, ports []int) error
- func (m *NFTManager) DeleteSetElements(set *nftables.Set, ips []string) error
- func (m *NFTManager) FlushSet(set *nftables.Set) error
- func (m *NFTManager) GetOrCreateIntervalSet(table *nftables.Table, setName string, ipv4 bool) (*nftables.Set, error)
- func (m *NFTManager) GetOrCreatePortSet(table *nftables.Table, setName string) (*nftables.Set, error)
- func (m *NFTManager) GetOrCreateSet(table *nftables.Table, setName string, ipv4 bool) (*nftables.Set, error)
- func (m *NFTManager) GetOrCreateTable(family nftables.TableFamily) (*nftables.Table, error)
- func (m *NFTManager) GetSetCount(set *nftables.Set) (int, error)
- func (m *NFTManager) GetSetElements(set *nftables.Set) ([]string, error)
- func (m *NFTManager) InvalidateTableCache()
- type SyncResult
- type SyncStats
Constants ¶
const ( ErrFileExists = "File exists" ErrIntervalOverlaps = "interval overlaps" ErrElementNotExist = "element does not exist" ErrNoSuchFile = "No such file or directory" )
Common ignorable error patterns
Variables ¶
This section is empty.
Functions ¶
func ApplyDiffToSetWithStats ¶
func ApplyDiffToSetWithStats( nft *NFTManager, set *nftables.Set, diff util.DiffResult[string], ) (added, removed, unchanged int, err error)
ApplyDiffToSetWithStats is like ApplyStringDiffToSet but also returns statistics. This is useful for operations that need detailed metrics.
The stats include: - Number of IPs successfully added - Number of IPs successfully removed - Number of IPs that were unchanged
Example usage:
stats := ApplyDiffToSetWithStats(nft, set, diff)
log.Printf("Applied: +%d -%d =%d", stats.Added, stats.Removed, stats.Unchanged)
func ApplyStringDiffToSet ¶
func ApplyStringDiffToSet( nft *NFTManager, set *nftables.Set, diff util.DiffResult[string], ) error
ApplyStringDiffToSet applies a DiffResult[string] to a nftables set via NFTManager. This centralizes all add/remove logic so it can be reused by: - Full sync operations (SyncSetToNFT) - Incremental API operations (single IP add/remove) - Batch API operations (multiple IPs at once) - Suricata alert processing (future v1.0)
Benefits of centralization: - Single place for all nftables set updates - Consistent error handling - Easy to add hooks (logging, metrics, validation) - Reusable across all v1.0 features
Performance characteristics: - Batched operations (not one-by-one) - Atomic updates via NFTManager - Efficient for both small and large diffs
Example usage:
// Single IP add
diff := util.DiffResult[string]{
ToAdd: []string{"1.2.3.4"},
}
err := ApplyStringDiffToSet(nft, whitelistSet, diff)
// Batch update
diff := util.DiffResult[string]{
ToAdd: []string{"1.2.3.4", "5.6.7.8"},
ToRemove: []string{"9.9.9.9"},
}
err := ApplyStringDiffToSet(nft, blacklistSet, diff)
func BatchApplyDiff ¶
func BatchApplyDiff(nft *NFTManager, applications []DiffApplication) error
func GetSyncEfficiency ¶
GetSyncEfficiency returns the percentage of IPs that were already in sync
func IsFastSync ¶
IsFastSync checks if a sync operation is "fast" (few changes) This can be used for metrics/alerting
func NftListSet ¶ added in v1.0.22
NftListSet lists elements of a set (exported for emulate command)
func PrintSyncResult ¶
func PrintSyncResult(result *SyncResult)
PrintSyncResult prints a complete sync result
func PrintSyncStats ¶
func PrintSyncStats(stats *SyncStats)
PrintSyncStats prints sync statistics in a readable format
Types ¶
type DiffApplication ¶
type DiffApplication struct {
Set *nftables.Set
Diff util.DiffResult[string]
}
BatchApplyDiff applies multiple diffs to multiple sets in sequence. This is useful for operations that need to update several sets atomically.
All diffs are applied in order. If any diff fails, the function stops and returns the error immediately.
Example usage:
diffs := []DiffApplication{
{Set: whitelistIPv4Set, Diff: whitelistIPv4Diff},
{Set: whitelistIPv6Set, Diff: whitelistIPv6Diff},
{Set: blacklistIPv4Set, Diff: blacklistIPv4Diff},
}
err := BatchApplyDiff(nft, diffs)
type DiffResult ¶
type DiffResult = util.DiffResult[string]
DiffResult is a type alias for the generic util.DiffResult[string] This maintains backwards compatibility while using the optimized generic implementation
func ComputeDiff ¶
func ComputeDiff(desiredIPs []string, currentIPs []string) *DiffResult
ComputeDiff compares desired state with current nftables state Returns IPs that need to be added or removed
This now uses the optimized generic diff engine from pkg/util Benefits: - Preallocated maps (no resizing) - Zero allocations for struct{} map values - Same algorithm, better performance
type MergeStats ¶
type MergeStats struct {
InputCIDRs int // Number of input CIDRs
OutputRanges int // Number of output ranges after merging
OverlapsMerged int // Number of overlaps/duplicates that were merged
ReductionPct float64 // Percentage reduction in entries
}
MergeStats contains statistics about CIDR canonicalization
func MergeCIDRs ¶ added in v1.0.22
func MergeCIDRs(cidrs []string) ([]string, *MergeStats, error)
MergeCIDRs merges overlapping and adjacent CIDRs (auto-detects IPv4/IPv6) Returns minimal CIDR set and statistics
type NFTManager ¶
type NFTManager struct {
// contains filtered or unexported fields
}
NFTManager handles nftables operations via netlink
func NewNFTManager ¶
func NewNFTManager() (*NFTManager, error)
NewNFTManager creates a new nftables manager
func (*NFTManager) AddCIDRElements ¶
func (m *NFTManager) AddCIDRElements(set *nftables.Set, cidrs []string) error
AddCIDRElements adds CIDR ranges to an interval set (batch operation with chunking) Uses nft command-line tool with a temporary file to avoid argument list limits Automatically canonicalizes and merges overlapping CIDRs before loading
func (*NFTManager) AddCIDRElementsWithStats ¶
func (m *NFTManager) AddCIDRElementsWithStats(set *nftables.Set, cidrs []string) (*MergeStats, error)
AddCIDRElementsWithStats adds CIDR elements to an interval set and returns merge statistics
func (*NFTManager) AddDropRuleForSet ¶
AddDropRuleForSet adds a rule to drop packets from IPs in a set
func (*NFTManager) AddIPWithTimeout ¶
AddIPWithTimeout adds a single IP to a set with optional timeout If timeout is 0, IP is added permanently If timeout > 0, IP will auto-expire after the specified duration
IMPORTANT: For interval sets, uses nft CLI to avoid corrupted ranges. The netlink library doesn't properly handle interval markers for single IPs, which can cause corrupted ranges like "1.2.3.4-255.255.255.255".
func (*NFTManager) AddPortElements ¶
func (m *NFTManager) AddPortElements(set *nftables.Set, ports []int) error
AddPortElements adds port numbers to a port set
func (*NFTManager) AddSetElements ¶
func (m *NFTManager) AddSetElements(set *nftables.Set, ips []string) error
AddSetElements adds IPs to a set (batch operation with chunking) Processes in batches of 10000 IPs to avoid netlink message size limits
func (*NFTManager) CreateChainIfNotExists ¶
func (m *NFTManager) CreateChainIfNotExists(table *nftables.Table, chainName string, chainType nftables.ChainType, hook *nftables.ChainHook, priority *nftables.ChainPriority) (*nftables.Chain, error)
CreateChainIfNotExists creates a chain if it doesn't exist
func (*NFTManager) DeleteFromIntervalSetCLI ¶
func (m *NFTManager) DeleteFromIntervalSetCLI(set *nftables.Set, ipStr string) error
DeleteFromIntervalSetCLI removes a single IP from an interval set, handling merged ranges. If the IP is inside a merged range (e.g., 7.7.7.7 inside 7.7.7.0-8.8.8.0), it will: 1. Delete the containing range 2. Re-add the sub-ranges before and after the IP
This works correctly with nftables auto-merge interval sets.
func (*NFTManager) DeletePortElements ¶
func (m *NFTManager) DeletePortElements(set *nftables.Set, ports []int) error
DeletePortElements removes port numbers from a port set
func (*NFTManager) DeleteSetElements ¶
func (m *NFTManager) DeleteSetElements(set *nftables.Set, ips []string) error
DeleteSetElements removes IPs from a set (batch operation)
func (*NFTManager) FlushSet ¶
func (m *NFTManager) FlushSet(set *nftables.Set) error
FlushSet removes all elements from a set
func (*NFTManager) GetOrCreateIntervalSet ¶
func (m *NFTManager) GetOrCreateIntervalSet(table *nftables.Table, setName string, ipv4 bool) (*nftables.Set, error)
GetOrCreateIntervalSet gets or creates an interval set for CIDR ranges
func (*NFTManager) GetOrCreatePortSet ¶
func (m *NFTManager) GetOrCreatePortSet(table *nftables.Table, setName string) (*nftables.Set, error)
GetOrCreatePortSet creates or gets an existing port set for TCP or UDP Port sets use TypeInetService (uint16) for port numbers
func (*NFTManager) GetOrCreateSet ¶
func (m *NFTManager) GetOrCreateSet(table *nftables.Table, setName string, ipv4 bool) (*nftables.Set, error)
GetOrCreateSet gets or creates a named set in the table
func (*NFTManager) GetOrCreateTable ¶
func (m *NFTManager) GetOrCreateTable(family nftables.TableFamily) (*nftables.Table, error)
GetOrCreateTable gets or creates the nftban table Uses caching to avoid repeated ListTables() calls for performance
func (*NFTManager) GetSetCount ¶
func (m *NFTManager) GetSetCount(set *nftables.Set) (int, error)
GetSetCount returns the number of elements in a set
func (*NFTManager) GetSetElements ¶
func (m *NFTManager) GetSetElements(set *nftables.Set) ([]string, error)
GetSetElements retrieves all elements from a set
func (*NFTManager) InvalidateTableCache ¶
func (m *NFTManager) InvalidateTableCache()
InvalidateTableCache clears the table cache (use after external table changes)
type SyncResult ¶
type SyncResult struct {
WhitelistIPv4 *SyncStats
WhitelistIPv6 *SyncStats
BlacklistIPv4 *SyncStats
BlacklistIPv6 *SyncStats
TotalDuration time.Duration
Success bool
}
SyncResult holds results of syncing multiple sets
func FullSync ¶
func FullSync( nft *NFTManager, whitelistIPv4Set, whitelistIPv6Set *nftables.Set, blacklistIPv4Set, blacklistIPv6Set *nftables.Set, whitelistIPv4, whitelistIPv6 []string, blacklistIPv4, blacklistIPv6 []string, ) (*SyncResult, error)
FullSync performs a complete sync of all whitelist/blacklist sets
type SyncStats ¶
type SyncStats struct {
SetName string
IPsAdded int
IPsRemoved int
IPsUnchanged int
TotalDesired int
TotalCurrent int
Duration time.Duration
Error error
}
SyncStats holds statistics about a sync operation
func SyncSetToNFT ¶
SyncSetToNFT performs differential sync of a set Only adds/removes IPs that have changed