Compare commits

...

6 Commits

Author SHA1 Message Date
benvin fff9967da0 Merge pull request 'Agent: translate blrules/conntrack/secmarks/vars' (#8) from benvin/agent-longtail-global2 into main
ci/woodpecker/tag/release Pipeline was successful
Reviewed-on: #8
2026-07-26 16:56:25 +10:00
benvin 4b703f854c Merge pull request 'Agent: translate traffic-control long-tail (mangle/accounting/tc_*)' (#7) from benvin/agent-longtail-tc into main
Reviewed-on: #7
2026-07-26 16:55:32 +10:00
benvin 8ae09c0941 Agent: translate blrules/conntrack/secmarks/vars
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
Map the rendered global-compiled tail into native config.Blrules/Conntrack/
Secmarks/Vars.
2026-07-26 16:07:28 +10:00
benvin 6d16035a0b Agent: translate traffic-control long-tail (mangle/accounting/tc_*)
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
Map the rendered mangle/accounting/tc_* sections into native tomswall config.
2026-07-26 15:57:05 +10:00
benvin 09f39ec9fe Merge pull request 'Agent: translate per-device L2/misc long-tail' (#6) from benvin/agent-longtail-l2 into main
Reviewed-on: #6
2026-07-26 15:46:07 +10:00
benvin b94cb96510 Agent: translate per-device L2/misc long-tail
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
Map the rendered tunnels/stopped_rules/proxy_arp/proxy_ndp/arp_rules/maclist
sections into native tomswall config.
2026-07-26 15:19:09 +10:00
2 changed files with 289 additions and 0 deletions
+179
View File
@@ -25,6 +25,185 @@ type RenderedConfig struct {
Providers []RenderedProvider `yaml:"providers,omitempty" json:"providers,omitempty"`
Routes []RenderedRoute `yaml:"routes,omitempty" json:"routes,omitempty"`
RoutingRules []RenderedRoutingRule `yaml:"routing_rules,omitempty" json:"routing_rules,omitempty"`
Tunnels []RenderedTunnel `yaml:"tunnels,omitempty" json:"tunnels,omitempty"`
StoppedRules []RenderedStoppedRule `yaml:"stopped_rules,omitempty" json:"stopped_rules,omitempty"`
ProxyARP []RenderedProxy `yaml:"proxy_arp,omitempty" json:"proxy_arp,omitempty"`
ProxyNDP []RenderedProxy `yaml:"proxy_ndp,omitempty" json:"proxy_ndp,omitempty"`
ArpRules []RenderedArpRule `yaml:"arp_rules,omitempty" json:"arp_rules,omitempty"`
Maclist []RenderedMaclist `yaml:"maclist,omitempty" json:"maclist,omitempty"`
Mangle []RenderedMangle `yaml:"mangle,omitempty" json:"mangle,omitempty"`
Accounting []RenderedAccounting `yaml:"accounting,omitempty" json:"accounting,omitempty"`
TCDevices []RenderedTCDevice `yaml:"tc_devices,omitempty" json:"tc_devices,omitempty"`
TCClasses []RenderedTCClass `yaml:"tc_classes,omitempty" json:"tc_classes,omitempty"`
TCFilters []RenderedTCFilter `yaml:"tc_filters,omitempty" json:"tc_filters,omitempty"`
TCInterfaces []RenderedTCInterface `yaml:"tc_interfaces,omitempty" json:"tc_interfaces,omitempty"`
TCPriorities []RenderedTCPriority `yaml:"tc_priorities,omitempty" json:"tc_priorities,omitempty"`
Blrules []RenderedBlrule `yaml:"blrules,omitempty" json:"blrules,omitempty"`
Conntrack []RenderedConntrack `yaml:"conntrack,omitempty" json:"conntrack,omitempty"`
Secmarks []RenderedSecmark `yaml:"secmarks,omitempty" json:"secmarks,omitempty"`
Vars map[string]string `yaml:"vars,omitempty" json:"vars,omitempty"`
}
type RenderedBlrule struct {
Priority int `yaml:"priority,omitempty" json:"priority,omitempty"`
Action string `yaml:"action" json:"action"`
Source string `yaml:"source,omitempty" json:"source,omitempty"`
Dest string `yaml:"dest,omitempty" json:"dest,omitempty"`
Proto string `yaml:"proto,omitempty" json:"proto,omitempty"`
DPort []string `yaml:"dport,omitempty" json:"dport,omitempty"`
SPort []string `yaml:"sport,omitempty" json:"sport,omitempty"`
Log string `yaml:"log,omitempty" json:"log,omitempty"`
Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
}
type RenderedConntrack struct {
Action string `yaml:"action" json:"action"`
Source string `yaml:"source,omitempty" json:"source,omitempty"`
Dest string `yaml:"dest,omitempty" json:"dest,omitempty"`
Proto string `yaml:"proto,omitempty" json:"proto,omitempty"`
DPort []string `yaml:"dport,omitempty" json:"dport,omitempty"`
SPort []string `yaml:"sport,omitempty" json:"sport,omitempty"`
Chain string `yaml:"chain,omitempty" json:"chain,omitempty"`
Helper string `yaml:"helper,omitempty" json:"helper,omitempty"`
User string `yaml:"user,omitempty" json:"user,omitempty"`
Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
}
type RenderedSecmark struct {
Secmark string `yaml:"secmark" json:"secmark"`
Chain string `yaml:"chain" json:"chain"`
Source string `yaml:"source,omitempty" json:"source,omitempty"`
Dest string `yaml:"dest,omitempty" json:"dest,omitempty"`
Proto string `yaml:"proto,omitempty" json:"proto,omitempty"`
DPort []string `yaml:"dport,omitempty" json:"dport,omitempty"`
SPort []string `yaml:"sport,omitempty" json:"sport,omitempty"`
Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
}
type RenderedMangle struct {
Action string `yaml:"action" json:"action"`
Chain string `yaml:"chain,omitempty" json:"chain,omitempty"`
MarkValue string `yaml:"mark_value,omitempty" json:"mark_value,omitempty"`
Source string `yaml:"source,omitempty" json:"source,omitempty"`
Dest string `yaml:"dest,omitempty" json:"dest,omitempty"`
Proto string `yaml:"proto,omitempty" json:"proto,omitempty"`
DPort []string `yaml:"dport,omitempty" json:"dport,omitempty"`
SPort []string `yaml:"sport,omitempty" json:"sport,omitempty"`
User string `yaml:"user,omitempty" json:"user,omitempty"`
Mark string `yaml:"mark,omitempty" json:"mark,omitempty"`
Length string `yaml:"length,omitempty" json:"length,omitempty"`
TOS string `yaml:"tos,omitempty" json:"tos,omitempty"`
Helper string `yaml:"helper,omitempty" json:"helper,omitempty"`
Probability *float64 `yaml:"probability,omitempty" json:"probability,omitempty"`
Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
}
type RenderedAccounting struct {
Action string `yaml:"action" json:"action"`
Section string `yaml:"section,omitempty" json:"section,omitempty"`
Chain string `yaml:"chain,omitempty" json:"chain,omitempty"`
Source string `yaml:"source,omitempty" json:"source,omitempty"`
Dest string `yaml:"dest,omitempty" json:"dest,omitempty"`
Proto string `yaml:"proto,omitempty" json:"proto,omitempty"`
DPort []string `yaml:"dport,omitempty" json:"dport,omitempty"`
SPort []string `yaml:"sport,omitempty" json:"sport,omitempty"`
Mark string `yaml:"mark,omitempty" json:"mark,omitempty"`
Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
}
type RenderedTCDevice struct {
Interface string `yaml:"interface" json:"interface"`
InBandwidth string `yaml:"in_bandwidth,omitempty" json:"in_bandwidth,omitempty"`
OutBandwidth string `yaml:"out_bandwidth,omitempty" json:"out_bandwidth,omitempty"`
Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
}
type RenderedTCClass struct {
Interface string `yaml:"interface" json:"interface"`
Mark int `yaml:"mark,omitempty" json:"mark,omitempty"`
Rate string `yaml:"rate,omitempty" json:"rate,omitempty"`
Ceil string `yaml:"ceil,omitempty" json:"ceil,omitempty"`
Priority int `yaml:"priority,omitempty" json:"priority,omitempty"`
Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
}
type RenderedTCFilter struct {
Class string `yaml:"class" json:"class"`
Source string `yaml:"source,omitempty" json:"source,omitempty"`
Dest string `yaml:"dest,omitempty" json:"dest,omitempty"`
Proto string `yaml:"proto,omitempty" json:"proto,omitempty"`
DPort []string `yaml:"dport,omitempty" json:"dport,omitempty"`
SPort []string `yaml:"sport,omitempty" json:"sport,omitempty"`
TOS string `yaml:"tos,omitempty" json:"tos,omitempty"`
Length int `yaml:"length,omitempty" json:"length,omitempty"`
Priority int `yaml:"priority,omitempty" json:"priority,omitempty"`
Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
}
type RenderedTCInterface struct {
Interface string `yaml:"interface" json:"interface"`
Type string `yaml:"type,omitempty" json:"type,omitempty"`
InBandwidth string `yaml:"in_bandwidth,omitempty" json:"in_bandwidth,omitempty"`
OutBandwidth string `yaml:"out_bandwidth,omitempty" json:"out_bandwidth,omitempty"`
Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
}
type RenderedTCPriority struct {
Band int `yaml:"band" json:"band"`
Proto string `yaml:"proto,omitempty" json:"proto,omitempty"`
DPort []string `yaml:"dport,omitempty" json:"dport,omitempty"`
SPort []string `yaml:"sport,omitempty" json:"sport,omitempty"`
Address string `yaml:"address,omitempty" json:"address,omitempty"`
Interface string `yaml:"interface,omitempty" json:"interface,omitempty"`
Helper string `yaml:"helper,omitempty" json:"helper,omitempty"`
Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
}
type RenderedTunnel struct {
Type string `yaml:"type" json:"type"`
Zone string `yaml:"zone" json:"zone"`
Gateways []string `yaml:"gateways,omitempty" json:"gateways,omitempty"`
GatewayZones []string `yaml:"gateway_zones,omitempty" json:"gateway_zones,omitempty"`
Port int `yaml:"port,omitempty" json:"port,omitempty"`
Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
}
type RenderedStoppedRule struct {
Action string `yaml:"action" json:"action"`
Source string `yaml:"source,omitempty" json:"source,omitempty"`
Dest string `yaml:"dest,omitempty" json:"dest,omitempty"`
Proto string `yaml:"proto,omitempty" json:"proto,omitempty"`
DPort []string `yaml:"dport,omitempty" json:"dport,omitempty"`
SPort []string `yaml:"sport,omitempty" json:"sport,omitempty"`
Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
}
type RenderedProxy struct {
Address string `yaml:"address" json:"address"`
Interface string `yaml:"interface,omitempty" json:"interface,omitempty"`
External string `yaml:"external" json:"external"`
HaveRoute bool `yaml:"haveroute,omitempty" json:"haveroute,omitempty"`
Persistent bool `yaml:"persistent,omitempty" json:"persistent,omitempty"`
Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
}
type RenderedArpRule struct {
Action string `yaml:"action" json:"action"`
ActionAddress string `yaml:"action_address,omitempty" json:"action_address,omitempty"`
ActionMAC string `yaml:"action_mac,omitempty" json:"action_mac,omitempty"`
Source string `yaml:"source,omitempty" json:"source,omitempty"`
Dest string `yaml:"dest,omitempty" json:"dest,omitempty"`
Opcode int `yaml:"opcode,omitempty" json:"opcode,omitempty"`
Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
}
type RenderedMaclist struct {
Action string `yaml:"action" json:"action"`
Interface string `yaml:"interface" json:"interface"`
MAC string `yaml:"mac,omitempty" json:"mac,omitempty"`
Addresses []string `yaml:"addresses,omitempty" json:"addresses,omitempty"`
Log string `yaml:"log,omitempty" json:"log,omitempty"`
Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
}
type RenderedHost struct {
+110
View File
@@ -106,6 +106,116 @@ func Translate(rc *RenderedConfig) (*config.Config, error) {
})
}
for _, t := range rc.Tunnels {
cfg.Tunnels = append(cfg.Tunnels, config.Tunnel{
Type: t.Type, Zone: t.Zone, Gateways: t.Gateways,
GatewayZones: t.GatewayZones, Port: t.Port, Comment: t.Comment,
})
}
for _, r := range rc.StoppedRules {
cfg.StoppedRules = append(cfg.StoppedRules, config.StoppedRule{
Action: config.StoppedAction(r.Action), Source: r.Source, Dest: r.Dest,
Proto: r.Proto, DPort: config.PortSpec(r.DPort), SPort: config.PortSpec(r.SPort), Comment: r.Comment,
})
}
for _, p := range rc.ProxyARP {
cfg.ProxyARP = append(cfg.ProxyARP, config.ProxyARP{
Address: p.Address, Interface: p.Interface, External: p.External,
HaveRoute: p.HaveRoute, Persistent: p.Persistent, Comment: p.Comment,
})
}
for _, p := range rc.ProxyNDP {
cfg.ProxyNDP = append(cfg.ProxyNDP, config.ProxyNDP{
Address: p.Address, Interface: p.Interface, External: p.External,
HaveRoute: p.HaveRoute, Persistent: p.Persistent, Comment: p.Comment,
})
}
for _, a := range rc.ArpRules {
cfg.ArpRules = append(cfg.ArpRules, config.ArpRule{
Action: config.ArpAction(a.Action), ActionAddress: a.ActionAddress, ActionMAC: a.ActionMAC,
Source: a.Source, Dest: a.Dest, Opcode: a.Opcode, Comment: a.Comment,
})
}
for _, m := range rc.Maclist {
cfg.Maclist = append(cfg.Maclist, config.MaclistEntry{
Action: config.MaclistAction(m.Action), Interface: m.Interface, MAC: m.MAC,
Addresses: m.Addresses, Log: m.Log, Comment: m.Comment,
})
}
for _, m := range rc.Mangle {
mr := config.MangleRule{
Action: config.MangleAction(m.Action), Chain: config.MangleChain(m.Chain), MarkValue: m.MarkValue,
Source: m.Source, Dest: m.Dest, Proto: m.Proto, DPort: config.PortSpec(m.DPort), SPort: config.PortSpec(m.SPort),
User: m.User, Mark: m.Mark, Length: m.Length, TOS: m.TOS, Helper: m.Helper, Comment: m.Comment,
}
if m.Probability != nil {
mr.Probability = *m.Probability
}
cfg.Mangle = append(cfg.Mangle, mr)
}
for _, a := range rc.Accounting {
cfg.Accounting = append(cfg.Accounting, config.AccountingRule{
Action: config.AccountingAction(a.Action), Section: config.AccountingSection(a.Section), Chain: a.Chain,
Source: a.Source, Dest: a.Dest, Proto: a.Proto, DPort: config.PortSpec(a.DPort), SPort: config.PortSpec(a.SPort),
Mark: a.Mark, Comment: a.Comment,
})
}
for _, t := range rc.TCDevices {
cfg.TCDevices = append(cfg.TCDevices, config.TCDevice{
Interface: t.Interface, InBandwidth: t.InBandwidth, OutBandwidth: t.OutBandwidth, Comment: t.Comment,
})
}
for _, t := range rc.TCClasses {
cfg.TCClasses = append(cfg.TCClasses, config.TCClass{
Interface: t.Interface, Mark: t.Mark, Rate: t.Rate, Ceil: t.Ceil, Priority: t.Priority, Comment: t.Comment,
})
}
for _, t := range rc.TCFilters {
cfg.TCFilters = append(cfg.TCFilters, config.TCFilter{
Class: t.Class, Source: t.Source, Dest: t.Dest, Proto: t.Proto,
DPort: config.PortSpec(t.DPort), SPort: config.PortSpec(t.SPort),
TOS: t.TOS, Length: t.Length, Priority: t.Priority, Comment: t.Comment,
})
}
for _, t := range rc.TCInterfaces {
cfg.TCInterfaces = append(cfg.TCInterfaces, config.TCInterface{
Interface: t.Interface, Type: t.Type, InBandwidth: t.InBandwidth, OutBandwidth: t.OutBandwidth, Comment: t.Comment,
})
}
for _, t := range rc.TCPriorities {
cfg.TCPriorities = append(cfg.TCPriorities, config.TCPriority{
Band: t.Band, Proto: t.Proto, DPort: config.PortSpec(t.DPort), SPort: config.PortSpec(t.SPort),
Address: t.Address, Interface: t.Interface, Helper: t.Helper, Comment: t.Comment,
})
}
for _, b := range rc.Blrules {
cfg.Blrules = append(cfg.Blrules, config.BlruleRule{
Action: config.BlruleAction(b.Action), Source: b.Source, Dest: b.Dest, Proto: b.Proto,
DPort: config.PortSpec(b.DPort), SPort: config.PortSpec(b.SPort), Log: b.Log, Comment: b.Comment,
})
}
for _, c := range rc.Conntrack {
cfg.Conntrack = append(cfg.Conntrack, config.ConntrackRule{
Action: config.ConntrackAction(c.Action), Source: c.Source, Dest: c.Dest, Proto: c.Proto,
DPort: config.PortSpec(c.DPort), SPort: config.PortSpec(c.SPort),
Chain: config.ConntrackChain(c.Chain), Helper: c.Helper, User: c.User, Comment: c.Comment,
})
}
for _, sm := range rc.Secmarks {
cfg.Secmarks = append(cfg.Secmarks, config.SecmarkRule{
Secmark: sm.Secmark, Chain: sm.Chain, Source: sm.Source, Dest: sm.Dest, Proto: sm.Proto,
DPort: config.PortSpec(sm.DPort), SPort: config.PortSpec(sm.SPort), Comment: sm.Comment,
})
}
if len(rc.Vars) > 0 {
cfg.Vars = make(map[string]string, len(rc.Vars))
for k, v := range rc.Vars {
cfg.Vars[k] = v
}
}
return cfg, nil
}