Files
tomswall/internal/config/stoppedrules.go
T
unkinben 8d9a76c751 Add comprehensive nftables compiler with shorewall feature parity
Rewrites the compiler from ~440 to ~1700 lines covering all major shorewall
firewall features: loopback, conntrack fast-path, anti-spoof, DHCP, intra-zone,
blacklist/whitelist, conntrack notrack, tunnels (13 types), rules with sections,
DNAT/redirect, SNAT/masquerade, static NAT, policies with zone exclusions,
MSS clamping, rate limiting, connection limiting, negated addresses, ICMP type
matching, TCP RST reject, user/UID matching, mark match/set, NFQUEUE, NONAT,
and policy-level rate/conn limiting.

Adds full config types for all shorewall subsystems (mangle, accounting, maclist,
netmap, providers, tunnels, conntrack, blrules, proxyarp/ndp, routes, tc, secmarks),
shorewall migration tooling, expanded CLI commands, expression-level diff engine,
and 49 unit tests.
2026-07-01 23:56:44 +10:00

59 lines
1.7 KiB
Go

package config
import "fmt"
type StoppedAction string
const (
StoppedAccept StoppedAction = "accept"
StoppedNoTrack StoppedAction = "notrack"
StoppedDrop StoppedAction = "drop"
)
// StoppedRule defines traffic that is permitted when the firewall is stopped
// or being stopped. Without these rules, all traffic is blocked in the
// stopped state.
type StoppedRule struct {
Action StoppedAction `yaml:"action"`
// Source: $FW (firewall), interface name, or interface:address.
Source string `yaml:"source,omitempty"`
// Dest: $FW (firewall), interface name, or interface:address.
// May not be specified with NOTRACK or DROP actions.
Dest string `yaml:"dest,omitempty"`
Proto string `yaml:"proto,omitempty"`
DPort PortSpec `yaml:"dport,omitempty"`
SPort PortSpec `yaml:"sport,omitempty"`
Comment string `yaml:"comment,omitempty"`
}
var validStoppedActions = map[StoppedAction]bool{
StoppedAccept: true, StoppedNoTrack: true, StoppedDrop: true,
}
func (c *Config) validateStoppedRules() error {
for i, r := range c.StoppedRules {
if !validStoppedActions[r.Action] {
return fmt.Errorf("stoppedrules[%d]: unknown action %q", i, r.Action)
}
if r.Source == "" && r.Dest == "" {
return fmt.Errorf("stoppedrules[%d]: source or dest required", i)
}
if (r.Action == StoppedNoTrack || r.Action == StoppedDrop) && r.Dest != "" && r.Dest != "-" {
if r.Dest != "" && r.Dest != "-" {
srcIsIface := r.Source != "" && r.Source != "$FW" && r.Source != "-"
destIsIface := r.Dest != "$FW"
if srcIsIface && destIsIface {
return fmt.Errorf("stoppedrules[%d]: dest not allowed with %s action (except $FW)", i, r.Action)
}
}
}
}
return nil
}