Attach conntrack helpers via ct helper objects
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful

This commit is contained in:
2026-10-03 23:50:31 +10:00
parent 9a7d1ab35b
commit c557c4b78a
5 changed files with 257 additions and 7 deletions
+50 -5
View File
@@ -20,15 +20,25 @@ type ManagedRule struct {
type FirewallState struct {
Rules map[string][]ManagedRule
// Helpers are the ct helper objects in kernel (insertion) order.
Helpers []Helper
}
// Helper is a named ct helper object.
type Helper struct {
Name string `json:"name"`
Helper expr.CtHelper `json:"helper"`
}
type ChangeSet struct {
Add []ManagedRule
Remove []ManagedRule
Add []ManagedRule
Remove []ManagedRule
AddHelpers []Helper
RemoveHelpers []string
}
func (cs *ChangeSet) Empty() bool {
return len(cs.Add) == 0 && len(cs.Remove) == 0
return len(cs.Add) == 0 && len(cs.Remove) == 0 && len(cs.AddHelpers) == 0 && len(cs.RemoveHelpers) == 0
}
func (cs *ChangeSet) Summary() string {
@@ -49,6 +59,12 @@ func (cs *ChangeSet) Summary() string {
fmt.Fprintf(&b, " - [%s] %s (handle %d)\n", r.Chain, r.Tag, r.Handle)
}
}
for _, h := range cs.AddHelpers {
fmt.Fprintf(&b, " + ct helper %q\n", h.Name)
}
for _, n := range cs.RemoveHelpers {
fmt.Fprintf(&b, " - ct helper %q\n", n)
}
return b.String()
}
@@ -56,7 +72,7 @@ func (cs *ChangeSet) Summary() string {
// each chain, replace the middle, and insert the new rules before the first kept
// suffix rule (or append when there is none).
func computeDiff(current, desired *FirewallState) *ChangeSet {
cs := &ChangeSet{}
cs := diffHelpers(current, desired)
chains := make([]string, 0, len(current.Rules)+len(desired.Rules))
for c := range current.Rules {
@@ -109,7 +125,10 @@ func ruleEqual(a, b ManagedRule) bool {
// restoreChangeSet replaces every managed rule in current with the snapshot's,
// in snapshot order, so a restore cannot reorder rules.
func restoreChangeSet(current, snap *FirewallState) *ChangeSet {
cs := &ChangeSet{}
cs := &ChangeSet{AddHelpers: snap.Helpers}
for _, h := range current.Helpers {
cs.RemoveHelpers = append(cs.RemoveHelpers, h.Name)
}
for _, rules := range current.Rules {
for _, r := range rules {
if r.Tag != "" {
@@ -131,3 +150,29 @@ func restoreChangeSet(current, snap *FirewallState) *ChangeSet {
}
return cs
}
// diffHelpers replaces any ct helper object that is missing or differs.
// L3Proto is ignored: the kernel narrows inet to ip/ip6 for single-family helpers such as pptp.
func diffHelpers(current, desired *FirewallState) *ChangeSet {
cs := &ChangeSet{}
same := func(a, b expr.CtHelper) bool { return a.Name == b.Name && a.L4Proto == b.L4Proto }
find := func(hs []Helper, name string) (expr.CtHelper, bool) {
for _, h := range hs {
if h.Name == name {
return h.Helper, true
}
}
return expr.CtHelper{}, false
}
for _, h := range current.Helpers {
if want, ok := find(desired.Helpers, h.Name); !ok || !same(want, h.Helper) {
cs.RemoveHelpers = append(cs.RemoveHelpers, h.Name)
}
}
for _, h := range desired.Helpers {
if have, ok := find(current.Helpers, h.Name); !ok || !same(have, h.Helper) {
cs.AddHelpers = append(cs.AddHelpers, h)
}
}
return cs
}