8d9a76c751
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.
64 lines
1.6 KiB
Go
64 lines
1.6 KiB
Go
package config
|
|
|
|
import "fmt"
|
|
|
|
type ArpAction string
|
|
|
|
const (
|
|
ArpAccept ArpAction = "accept"
|
|
ArpDrop ArpAction = "drop"
|
|
ArpSNAT ArpAction = "snat"
|
|
ArpDNAT ArpAction = "dnat"
|
|
ArpSMAT ArpAction = "smat"
|
|
ArpDMAT ArpAction = "dmat"
|
|
)
|
|
|
|
type ArpRule struct {
|
|
// Action to take on matching ARP packets.
|
|
Action ArpAction `yaml:"action"`
|
|
|
|
// ActionAddress is the IP address to rewrite to (required for snat/dnat).
|
|
ActionAddress string `yaml:"action_address,omitempty"`
|
|
|
|
// ActionMAC is the MAC address to rewrite to (required for smat/dmat).
|
|
ActionMAC string `yaml:"action_mac,omitempty"`
|
|
|
|
// Source zone/address spec.
|
|
Source string `yaml:"source,omitempty"`
|
|
|
|
// Dest zone/address spec.
|
|
Dest string `yaml:"dest,omitempty"`
|
|
|
|
// Opcode is the ARP operation code to match (e.g. 1=request, 2=reply).
|
|
Opcode int `yaml:"opcode,omitempty"`
|
|
|
|
Comment string `yaml:"comment,omitempty"`
|
|
}
|
|
|
|
var validArpActions = map[ArpAction]bool{
|
|
ArpAccept: true, ArpDrop: true,
|
|
ArpSNAT: true, ArpDNAT: true,
|
|
ArpSMAT: true, ArpDMAT: true,
|
|
}
|
|
|
|
func (c *Config) validateArpRules() error {
|
|
for i, a := range c.ArpRules {
|
|
if !validArpActions[a.Action] {
|
|
return fmt.Errorf("arprules[%d]: unknown action %q", i, a.Action)
|
|
}
|
|
|
|
if (a.Action == ArpSNAT || a.Action == ArpDNAT) && a.ActionAddress == "" {
|
|
return fmt.Errorf("arprules[%d]: action_address required for %s action", i, a.Action)
|
|
}
|
|
|
|
if (a.Action == ArpSMAT || a.Action == ArpDMAT) && a.ActionMAC == "" {
|
|
return fmt.Errorf("arprules[%d]: action_mac required for %s action", i, a.Action)
|
|
}
|
|
|
|
if a.Source == "" && a.Dest == "" {
|
|
return fmt.Errorf("arprules[%d]: source or dest required", i)
|
|
}
|
|
}
|
|
return nil
|
|
}
|