Files
tomswall/internal/config/policy.go
T
unkinben 2a3eb3b04d Initial scaffold for tomswall
Spiritual successor to shorewall — manages nftables directly via
google/nftables. Reads a single YAML config covering zones, interfaces,
hosts, policy, rules, snat, and named portgroups. Computes differential
changes against the running nftables state and applies them atomically.
Supports detecting and purging rules added outside of tomswall.
2026-06-28 23:43:16 +10:00

54 lines
1.3 KiB
Go

package config
import "fmt"
type PolicyAction string
const (
PolicyAccept PolicyAction = "accept"
PolicyDrop PolicyAction = "drop"
PolicyReject PolicyAction = "reject"
PolicyContinue PolicyAction = "continue"
PolicyNone PolicyAction = "none"
)
type Policy struct {
Source string `yaml:"source"`
Dest string `yaml:"dest"`
Action PolicyAction `yaml:"action"`
Log string `yaml:"log,omitempty"`
RateLimit string `yaml:"rate_limit,omitempty"`
ConnLimit int `yaml:"conn_limit,omitempty"`
}
func (c *Config) validatePolicy() error {
if len(c.Policy) == 0 {
return fmt.Errorf("no policies defined")
}
for i, p := range c.Policy {
if p.Source == "" {
return fmt.Errorf("policy[%d]: source required", i)
}
if p.Dest == "" {
return fmt.Errorf("policy[%d]: dest required", i)
}
if p.Source != "all" {
if _, ok := c.Zones[p.Source]; !ok {
return fmt.Errorf("policy[%d]: source zone %q not defined", i, p.Source)
}
}
if p.Dest != "all" {
if _, ok := c.Zones[p.Dest]; !ok {
return fmt.Errorf("policy[%d]: dest zone %q not defined", i, p.Dest)
}
}
switch p.Action {
case PolicyAccept, PolicyDrop, PolicyReject, PolicyContinue, PolicyNone:
default:
return fmt.Errorf("policy[%d]: unknown action %q", i, p.Action)
}
}
return nil
}