feat(nft): generate and apply the inet prx ruleset atomically
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package nft
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestScriptGolden(t *testing.T) {
|
||||
got, err := Script(Params{
|
||||
WANInterface: "wlan0",
|
||||
Mark: 0x100,
|
||||
Local4: []string{"192.168.1.100"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Script: %v", err)
|
||||
}
|
||||
want := `destroy table inet prx
|
||||
table inet prx {
|
||||
set wan_local4 {
|
||||
type ipv4_addr;
|
||||
elements = { 192.168.1.100 }
|
||||
}
|
||||
chain pre {
|
||||
type filter hook prerouting priority mangle; policy accept;
|
||||
iifname "wlan0" ct state new ct mark set 0x100
|
||||
}
|
||||
chain out {
|
||||
type filter hook output priority mangle; policy accept;
|
||||
ct mark 0x100 meta mark set 0x100
|
||||
ct original ip daddr @wan_local4 meta mark set 0x100
|
||||
}
|
||||
}
|
||||
`
|
||||
if got != want {
|
||||
t.Fatalf("unexpected script:\n--- got ---\n%s\n--- want ---\n%s", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestScriptIncludesIPv6(t *testing.T) {
|
||||
got, err := Script(Params{
|
||||
WANInterface: "eth0",
|
||||
Mark: 0x200,
|
||||
Local4: []string{"203.0.113.5"},
|
||||
Local6: []string{"2001:db8::5"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Script: %v", err)
|
||||
}
|
||||
for _, needle := range []string{
|
||||
"set wan_local6",
|
||||
"elements = { 2001:db8::5 }",
|
||||
"ct original ip6 daddr @wan_local6 meta mark set 0x200",
|
||||
} {
|
||||
if !strings.Contains(got, needle) {
|
||||
t.Errorf("script missing %q", needle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestScriptAlwaysDestroysFirst(t *testing.T) {
|
||||
got, _ := Script(Params{WANInterface: "wlan0", Mark: 1, Local4: []string{"1.2.3.4"}})
|
||||
if !strings.HasPrefix(got, "destroy table inet prx\n") {
|
||||
t.Fatal("script must start with destroy table to stay idempotent")
|
||||
}
|
||||
}
|
||||
|
||||
func TestScriptRejectsInjection(t *testing.T) {
|
||||
for _, bad := range []string{`wlan0" ; flush ruleset`, "wlan0;x", "", "this-name-is-way-too-long"} {
|
||||
if _, err := Script(Params{WANInterface: bad, Mark: 1, Local4: []string{"1.2.3.4"}}); err == nil {
|
||||
t.Errorf("expected error for interface %q", bad)
|
||||
}
|
||||
}
|
||||
if _, err := Script(Params{WANInterface: "wlan0", Mark: 0}); err == nil {
|
||||
t.Error("expected error for zero mark")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user