Compare commits
No commits in common. "1510be9a554a67c6e5b34b552a5fc79f7f78c050" and "a93939a185685e29106a4760fba8a6bbf73595b0" have entirely different histories.
1510be9a55
...
a93939a185
|
@ -1,42 +0,0 @@
|
||||||
package nftest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/google/nftables"
|
|
||||||
"github.com/vishvananda/netns"
|
|
||||||
)
|
|
||||||
|
|
||||||
// OpenSystemConn returns a netlink connection that tests against
|
|
||||||
// the running kernel in a separate network namespace.
|
|
||||||
// nftest.CleanupSystemConn() must be called from a defer to cleanup
|
|
||||||
// created network namespace.
|
|
||||||
func OpenSystemConn(t *testing.T, enableSysTests bool) (*nftables.Conn, netns.NsHandle) {
|
|
||||||
t.Helper()
|
|
||||||
if !enableSysTests {
|
|
||||||
t.SkipNow()
|
|
||||||
}
|
|
||||||
// We lock the goroutine into the current thread, as namespace operations
|
|
||||||
// such as those invoked by `netns.New()` are thread-local. This is undone
|
|
||||||
// in nftest.CleanupSystemConn().
|
|
||||||
runtime.LockOSThread()
|
|
||||||
|
|
||||||
ns, err := netns.New()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("netns.New() failed: %v", err)
|
|
||||||
}
|
|
||||||
c, err := nftables.New(nftables.WithNetNSFd(int(ns)))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("nftables.New() failed: %v", err)
|
|
||||||
}
|
|
||||||
return c, ns
|
|
||||||
}
|
|
||||||
|
|
||||||
func CleanupSystemConn(t *testing.T, newNS netns.NsHandle) {
|
|
||||||
defer runtime.UnlockOSThread()
|
|
||||||
|
|
||||||
if err := newNS.Close(); err != nil {
|
|
||||||
t.Fatalf("newNS.Close() failed: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
180
nftables_test.go
180
nftables_test.go
|
@ -22,6 +22,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -32,10 +33,13 @@ import (
|
||||||
"github.com/google/nftables/internal/nftest"
|
"github.com/google/nftables/internal/nftest"
|
||||||
"github.com/google/nftables/xt"
|
"github.com/google/nftables/xt"
|
||||||
"github.com/mdlayher/netlink"
|
"github.com/mdlayher/netlink"
|
||||||
|
"github.com/vishvananda/netns"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
var enableSysTests = flag.Bool("run_system_tests", false, "Run tests that operate against the live kernel")
|
var (
|
||||||
|
enableSysTests = flag.Bool("run_system_tests", false, "Run tests that operate against the live kernel")
|
||||||
|
)
|
||||||
|
|
||||||
// nfdump returns a hexdump of 4 bytes per line (like nft --debug=all), allowing
|
// nfdump returns a hexdump of 4 bytes per line (like nft --debug=all), allowing
|
||||||
// users to make sense of large byte literals more easily.
|
// users to make sense of large byte literals more easily.
|
||||||
|
@ -83,11 +87,45 @@ func ifname(n string) []byte {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// openSystemNFTConn returns a netlink connection that tests against
|
||||||
|
// the running kernel in a separate network namespace.
|
||||||
|
// cleanupSystemNFTConn() must be called from a defer to cleanup
|
||||||
|
// created network namespace.
|
||||||
|
func openSystemNFTConn(t *testing.T) (*nftables.Conn, netns.NsHandle) {
|
||||||
|
t.Helper()
|
||||||
|
if !*enableSysTests {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
// We lock the goroutine into the current thread, as namespace operations
|
||||||
|
// such as those invoked by `netns.New()` are thread-local. This is undone
|
||||||
|
// in cleanupSystemNFTConn().
|
||||||
|
runtime.LockOSThread()
|
||||||
|
|
||||||
|
ns, err := netns.New()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("netns.New() failed: %v", err)
|
||||||
|
}
|
||||||
|
c, err := nftables.New(nftables.WithNetNSFd(int(ns)))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("nftables.New() failed: %v", err)
|
||||||
|
}
|
||||||
|
return c, ns
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanupSystemNFTConn(t *testing.T, newNS netns.NsHandle) {
|
||||||
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
|
if err := newNS.Close(); err != nil {
|
||||||
|
t.Fatalf("newNS.Close() failed: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRuleOperations(t *testing.T) {
|
func TestRuleOperations(t *testing.T) {
|
||||||
|
|
||||||
// Create a new network namespace to test these operations,
|
// Create a new network namespace to test these operations,
|
||||||
// and tear down the namespace at test completion.
|
// and tear down the namespace at test completion.
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
// Clear all rules at the beginning + end of the test.
|
// Clear all rules at the beginning + end of the test.
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
@ -543,8 +581,8 @@ func TestConfigureNATSourceAddress(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMasqMarshalUnmarshal(t *testing.T) {
|
func TestMasqMarshalUnmarshal(t *testing.T) {
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
|
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
@ -620,8 +658,8 @@ func TestMasqMarshalUnmarshal(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExprLogOptions(t *testing.T) {
|
func TestExprLogOptions(t *testing.T) {
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
|
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
@ -765,8 +803,8 @@ func TestExprLogOptions(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExprLogPrefix(t *testing.T) {
|
func TestExprLogPrefix(t *testing.T) {
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
|
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
@ -841,15 +879,15 @@ func TestGetRules(t *testing.T) {
|
||||||
// strace -f -v -x -s 2048 -eraw=sendto nft list chain ip filter forward
|
// strace -f -v -x -s 2048 -eraw=sendto nft list chain ip filter forward
|
||||||
|
|
||||||
want := [][]byte{
|
want := [][]byte{
|
||||||
{0x2, 0x0, 0x0, 0x0, 0xb, 0x0, 0x1, 0x0, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x0, 0x0, 0xa, 0x0, 0x2, 0x0, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x0, 0x0, 0x0},
|
[]byte{0x2, 0x0, 0x0, 0x0, 0xb, 0x0, 0x1, 0x0, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x0, 0x0, 0xa, 0x0, 0x2, 0x0, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x0, 0x0, 0x0},
|
||||||
}
|
}
|
||||||
|
|
||||||
// The reply messages come from adding log.Printf("msgs: %#v", msgs) to
|
// The reply messages come from adding log.Printf("msgs: %#v", msgs) to
|
||||||
// (*github.com/mdlayher/netlink/Conn).receive
|
// (*github.com/mdlayher/netlink/Conn).receive
|
||||||
reply := [][]netlink.Message{
|
reply := [][]netlink.Message{
|
||||||
nil,
|
nil,
|
||||||
{{Header: netlink.Header{Length: 0x68, Type: 0xa06, Flags: 0x802, Sequence: 0x9acb0443, PID: 0xba38ef3c}, Data: []uint8{0x2, 0x0, 0x0, 0xc, 0xb, 0x0, 0x1, 0x0, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x0, 0x0, 0xc, 0x0, 0x2, 0x0, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x0, 0xc, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x30, 0x0, 0x4, 0x0, 0x2c, 0x0, 0x1, 0x0, 0xc, 0x0, 0x1, 0x0, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x0, 0x1c, 0x0, 0x2, 0x0, 0xc, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6d, 0x92, 0x20, 0x20, 0xc, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x48, 0xd9}}},
|
[]netlink.Message{netlink.Message{Header: netlink.Header{Length: 0x68, Type: 0xa06, Flags: 0x802, Sequence: 0x9acb0443, PID: 0xba38ef3c}, Data: []uint8{0x2, 0x0, 0x0, 0xc, 0xb, 0x0, 0x1, 0x0, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x0, 0x0, 0xc, 0x0, 0x2, 0x0, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x0, 0xc, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x30, 0x0, 0x4, 0x0, 0x2c, 0x0, 0x1, 0x0, 0xc, 0x0, 0x1, 0x0, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x0, 0x1c, 0x0, 0x2, 0x0, 0xc, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6d, 0x92, 0x20, 0x20, 0xc, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x48, 0xd9}}},
|
||||||
{{Header: netlink.Header{Length: 0x14, Type: 0x3, Flags: 0x2, Sequence: 0x9acb0443, PID: 0xba38ef3c}, Data: []uint8{0x0, 0x0, 0x0, 0x0}}},
|
[]netlink.Message{netlink.Message{Header: netlink.Header{Length: 0x14, Type: 0x3, Flags: 0x2, Sequence: 0x9acb0443, PID: 0xba38ef3c}, Data: []uint8{0x0, 0x0, 0x0, 0x0}}},
|
||||||
}
|
}
|
||||||
|
|
||||||
c, err := nftables.New(nftables.WithTestDial(
|
c, err := nftables.New(nftables.WithTestDial(
|
||||||
|
@ -1622,6 +1660,7 @@ func TestListChains(t *testing.T) {
|
||||||
validate(chain.Policy, want[i].Policy, "policy pointer", i)
|
validate(chain.Policy, want[i].Policy, "policy pointer", i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddChain(t *testing.T) {
|
func TestAddChain(t *testing.T) {
|
||||||
|
@ -1783,22 +1822,21 @@ func TestDelChain(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetObjReset(t *testing.T) {
|
func TestGetObjReset(t *testing.T) {
|
||||||
// The want byte sequences come from stracing nft(8), e.g.:
|
// The want byte sequences come from stracing nft(8), e.g.:
|
||||||
// strace -f -v -x -s 2048 -eraw=sendto nft list chain ip filter forward
|
// strace -f -v -x -s 2048 -eraw=sendto nft list chain ip filter forward
|
||||||
|
|
||||||
want := [][]byte{
|
want := [][]byte{
|
||||||
{0x2, 0x0, 0x0, 0x0, 0xb, 0x0, 0x1, 0x0, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x0, 0x0, 0xa, 0x0, 0x2, 0x0, 0x66, 0x77, 0x64, 0x65, 0x64, 0x0, 0x0, 0x0, 0x8, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x1},
|
[]byte{0x2, 0x0, 0x0, 0x0, 0xb, 0x0, 0x1, 0x0, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x0, 0x0, 0xa, 0x0, 0x2, 0x0, 0x66, 0x77, 0x64, 0x65, 0x64, 0x0, 0x0, 0x0, 0x8, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x1},
|
||||||
}
|
}
|
||||||
|
|
||||||
// The reply messages come from adding log.Printf("msgs: %#v", msgs) to
|
// The reply messages come from adding log.Printf("msgs: %#v", msgs) to
|
||||||
// (*github.com/mdlayher/netlink/Conn).receive
|
// (*github.com/mdlayher/netlink/Conn).receive
|
||||||
reply := [][]netlink.Message{
|
reply := [][]netlink.Message{
|
||||||
nil,
|
nil,
|
||||||
{{Header: netlink.Header{Length: 0x64, Type: 0xa12, Flags: 0x802, Sequence: 0x9acb0443, PID: 0xde9}, Data: []uint8{0x2, 0x0, 0x0, 0x10, 0xb, 0x0, 0x1, 0x0, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x0, 0x0, 0xa, 0x0, 0x2, 0x0, 0x66, 0x77, 0x64, 0x65, 0x64, 0x0, 0x0, 0x0, 0x8, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x1, 0x8, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1c, 0x0, 0x4, 0x0, 0xc, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x61, 0xc, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xc, 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2}}},
|
[]netlink.Message{netlink.Message{Header: netlink.Header{Length: 0x64, Type: 0xa12, Flags: 0x802, Sequence: 0x9acb0443, PID: 0xde9}, Data: []uint8{0x2, 0x0, 0x0, 0x10, 0xb, 0x0, 0x1, 0x0, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x0, 0x0, 0xa, 0x0, 0x2, 0x0, 0x66, 0x77, 0x64, 0x65, 0x64, 0x0, 0x0, 0x0, 0x8, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x1, 0x8, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1c, 0x0, 0x4, 0x0, 0xc, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x61, 0xc, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xc, 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2}}},
|
||||||
{{Header: netlink.Header{Length: 0x14, Type: 0x3, Flags: 0x2, Sequence: 0x9acb0443, PID: 0xde9}, Data: []uint8{0x0, 0x0, 0x0, 0x0}}},
|
[]netlink.Message{netlink.Message{Header: netlink.Header{Length: 0x14, Type: 0x3, Flags: 0x2, Sequence: 0x9acb0443, PID: 0xde9}, Data: []uint8{0x0, 0x0, 0x0, 0x0}}},
|
||||||
{{Header: netlink.Header{Length: 36, Type: netlink.Error, Flags: 0x100, Sequence: 0x9acb0443, PID: 0xde9}, Data: []uint8{0, 0, 0, 0, 88, 0, 0, 0, 12, 10, 5, 4, 143, 109, 199, 146, 236, 9, 0, 0}}},
|
[]netlink.Message{netlink.Message{Header: netlink.Header{Length: 36, Type: netlink.Error, Flags: 0x100, Sequence: 0x9acb0443, PID: 0xde9}, Data: []uint8{0, 0, 0, 0, 88, 0, 0, 0, 12, 10, 5, 4, 143, 109, 199, 146, 236, 9, 0, 0}}},
|
||||||
}
|
}
|
||||||
|
|
||||||
c, err := nftables.New(nftables.WithTestDial(
|
c, err := nftables.New(nftables.WithTestDial(
|
||||||
|
@ -1834,6 +1872,7 @@ func TestGetObjReset(t *testing.T) {
|
||||||
Table: filter,
|
Table: filter,
|
||||||
Name: "fwded",
|
Name: "fwded",
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -1863,8 +1902,8 @@ func TestObjAPI(t *testing.T) {
|
||||||
|
|
||||||
// Create a new network namespace to test these operations,
|
// Create a new network namespace to test these operations,
|
||||||
// and tear down the namespace at test completion.
|
// and tear down the namespace at test completion.
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
|
|
||||||
// Clear all rules at the beginning + end of the test.
|
// Clear all rules at the beginning + end of the test.
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
|
@ -1925,6 +1964,7 @@ func TestObjAPI(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
objs, err := c.GetObjects(table)
|
objs, err := c.GetObjects(table)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("c.GetObjects(table) failed: %v failed", err)
|
t.Errorf("c.GetObjects(table) failed: %v failed", err)
|
||||||
}
|
}
|
||||||
|
@ -1934,6 +1974,7 @@ func TestObjAPI(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
objsOther, err := c.GetObjects(tableOther)
|
objsOther, err := c.GetObjects(tableOther)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("c.GetObjects(tableOther) failed: %v failed", err)
|
t.Errorf("c.GetObjects(tableOther) failed: %v failed", err)
|
||||||
}
|
}
|
||||||
|
@ -1943,6 +1984,7 @@ func TestObjAPI(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
obj1, err := c.GetObject(counter1)
|
obj1, err := c.GetObject(counter1)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("c.GetObject(counter1) failed: %v failed", err)
|
t.Errorf("c.GetObject(counter1) failed: %v failed", err)
|
||||||
}
|
}
|
||||||
|
@ -1958,6 +2000,7 @@ func TestObjAPI(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
obj2, err := c.GetObject(counter2)
|
obj2, err := c.GetObject(counter2)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("c.GetObject(counter2) failed: %v failed", err)
|
t.Errorf("c.GetObject(counter2) failed: %v failed", err)
|
||||||
}
|
}
|
||||||
|
@ -1999,6 +2042,7 @@ func TestObjAPI(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
legacy, err := c.GetObj(counter1)
|
legacy, err := c.GetObj(counter1)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("c.GetObj(counter1) failed: %v failed", err)
|
t.Errorf("c.GetObj(counter1) failed: %v failed", err)
|
||||||
}
|
}
|
||||||
|
@ -2008,6 +2052,7 @@ func TestObjAPI(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
legacyReset, err := c.GetObjReset(counter1)
|
legacyReset, err := c.GetObjReset(counter1)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("c.GetObjReset(counter1) failed: %v failed", err)
|
t.Errorf("c.GetObjReset(counter1) failed: %v failed", err)
|
||||||
}
|
}
|
||||||
|
@ -2015,6 +2060,7 @@ func TestObjAPI(t *testing.T) {
|
||||||
if len(legacyReset) != 2 {
|
if len(legacyReset) != 2 {
|
||||||
t.Errorf("unexpected number of objects: got %d, want %d", len(legacyReset), 2)
|
t.Errorf("unexpected number of objects: got %d, want %d", len(legacyReset), 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConfigureClamping(t *testing.T) {
|
func TestConfigureClamping(t *testing.T) {
|
||||||
|
@ -2491,12 +2537,12 @@ func TestCreateUseAnonymousSet(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCappedErrMsgOnSets(t *testing.T) {
|
func TestCappedErrMsgOnSets(t *testing.T) {
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
c, err := nftables.New(nftables.WithNetNSFd(int(newNS)), nftables.AsLasting())
|
c, err := nftables.New(nftables.WithNetNSFd(int(newNS)), nftables.AsLasting())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("nftables.New() failed: %v", err)
|
t.Fatalf("nftables.New() failed: %v", err)
|
||||||
}
|
}
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
|
||||||
|
@ -2571,8 +2617,8 @@ func TestCappedErrMsgOnSets(t *testing.T) {
|
||||||
func TestCreateUseNamedSet(t *testing.T) {
|
func TestCreateUseNamedSet(t *testing.T) {
|
||||||
// Create a new network namespace to test these operations,
|
// Create a new network namespace to test these operations,
|
||||||
// and tear down the namespace at test completion.
|
// and tear down the namespace at test completion.
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
// Clear all rules at the beginning + end of the test.
|
// Clear all rules at the beginning + end of the test.
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
@ -2625,10 +2671,11 @@ func TestCreateUseNamedSet(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIP6SetAddElements(t *testing.T) {
|
func TestIP6SetAddElements(t *testing.T) {
|
||||||
|
|
||||||
// Create a new network namespace to test these operations,
|
// Create a new network namespace to test these operations,
|
||||||
// and tear down the namespace at test completion.
|
// and tear down the namespace at test completion.
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
// Clear all rules at the beginning + end of the test.
|
// Clear all rules at the beginning + end of the test.
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
@ -2676,8 +2723,8 @@ func TestIP6SetAddElements(t *testing.T) {
|
||||||
func TestCreateUseCounterSet(t *testing.T) {
|
func TestCreateUseCounterSet(t *testing.T) {
|
||||||
// Create a new network namespace to test these operations,
|
// Create a new network namespace to test these operations,
|
||||||
// and tear down the namespace at test completion.
|
// and tear down the namespace at test completion.
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
// Clear all rules at the beginning + end of the test.
|
// Clear all rules at the beginning + end of the test.
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
@ -2719,8 +2766,8 @@ func TestCreateUseCounterSet(t *testing.T) {
|
||||||
func TestCreateDeleteNamedSet(t *testing.T) {
|
func TestCreateDeleteNamedSet(t *testing.T) {
|
||||||
// Create a new network namespace to test these operations,
|
// Create a new network namespace to test these operations,
|
||||||
// and tear down the namespace at test completion.
|
// and tear down the namespace at test completion.
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
// Clear all rules at the beginning + end of the test.
|
// Clear all rules at the beginning + end of the test.
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
@ -2760,8 +2807,8 @@ func TestCreateDeleteNamedSet(t *testing.T) {
|
||||||
func TestDeleteElementNamedSet(t *testing.T) {
|
func TestDeleteElementNamedSet(t *testing.T) {
|
||||||
// Create a new network namespace to test these operations,
|
// Create a new network namespace to test these operations,
|
||||||
// and tear down the namespace at test completion.
|
// and tear down the namespace at test completion.
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
// Clear all rules at the beginning + end of the test.
|
// Clear all rules at the beginning + end of the test.
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
@ -2807,8 +2854,8 @@ func TestFlushNamedSet(t *testing.T) {
|
||||||
}
|
}
|
||||||
// Create a new network namespace to test these operations,
|
// Create a new network namespace to test these operations,
|
||||||
// and tear down the namespace at test completion.
|
// and tear down the namespace at test completion.
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
// Clear all rules at the beginning + end of the test.
|
// Clear all rules at the beginning + end of the test.
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
@ -2848,8 +2895,8 @@ func TestFlushNamedSet(t *testing.T) {
|
||||||
func TestSetElementsInterval(t *testing.T) {
|
func TestSetElementsInterval(t *testing.T) {
|
||||||
// Create a new network namespace to test these operations,
|
// Create a new network namespace to test these operations,
|
||||||
// and tear down the namespace at test completion.
|
// and tear down the namespace at test completion.
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
// Clear all rules at the beginning + end of the test.
|
// Clear all rules at the beginning + end of the test.
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
@ -2916,8 +2963,8 @@ func TestSetElementsInterval(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateListFlowtable(t *testing.T) {
|
func TestCreateListFlowtable(t *testing.T) {
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
|
||||||
|
@ -2949,8 +2996,8 @@ func TestCreateListFlowtable(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateListFlowtableWithDevices(t *testing.T) {
|
func TestCreateListFlowtableWithDevices(t *testing.T) {
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
|
||||||
|
@ -3015,8 +3062,8 @@ func TestCreateListFlowtableWithDevices(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateDeleteFlowtable(t *testing.T) {
|
func TestCreateDeleteFlowtable(t *testing.T) {
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
|
||||||
|
@ -3068,8 +3115,8 @@ func TestCreateDeleteFlowtable(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOffload(t *testing.T) {
|
func TestOffload(t *testing.T) {
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
|
||||||
|
@ -3146,8 +3193,8 @@ func TestOffload(t *testing.T) {
|
||||||
func TestFlushChain(t *testing.T) {
|
func TestFlushChain(t *testing.T) {
|
||||||
// Create a new network namespace to test these operations,
|
// Create a new network namespace to test these operations,
|
||||||
// and tear down the namespace at test completion.
|
// and tear down the namespace at test completion.
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
// Clear all rules at the beginning + end of the test.
|
// Clear all rules at the beginning + end of the test.
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
@ -3260,8 +3307,8 @@ func TestFlushTable(t *testing.T) {
|
||||||
}
|
}
|
||||||
// Create a new network namespace to test these operations,
|
// Create a new network namespace to test these operations,
|
||||||
// and tear down the namespace at test completion.
|
// and tear down the namespace at test completion.
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
// Clear all rules at the beginning + end of the test.
|
// Clear all rules at the beginning + end of the test.
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
@ -3485,8 +3532,8 @@ func TestFlushTable(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetLookupExprDestSet(t *testing.T) {
|
func TestGetLookupExprDestSet(t *testing.T) {
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
|
||||||
|
@ -3583,8 +3630,8 @@ func TestGetLookupExprDestSet(t *testing.T) {
|
||||||
func TestGetRuleLookupVerdictImmediate(t *testing.T) {
|
func TestGetRuleLookupVerdictImmediate(t *testing.T) {
|
||||||
// Create a new network namespace to test these operations,
|
// Create a new network namespace to test these operations,
|
||||||
// and tear down the namespace at test completion.
|
// and tear down the namespace at test completion.
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
// Clear all rules at the beginning + end of the test.
|
// Clear all rules at the beginning + end of the test.
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
@ -3710,8 +3757,8 @@ func TestGetRuleLookupVerdictImmediate(t *testing.T) {
|
||||||
func TestDynset(t *testing.T) {
|
func TestDynset(t *testing.T) {
|
||||||
// Create a new network namespace to test these operations,
|
// Create a new network namespace to test these operations,
|
||||||
// and tear down the namespace at test completion.
|
// and tear down the namespace at test completion.
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
// Clear all rules at the beginning + end of the test.
|
// Clear all rules at the beginning + end of the test.
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
@ -3801,8 +3848,8 @@ func TestDynset(t *testing.T) {
|
||||||
func TestDynsetWithOneExpression(t *testing.T) {
|
func TestDynsetWithOneExpression(t *testing.T) {
|
||||||
// Create a new network namespace to test these operations,
|
// Create a new network namespace to test these operations,
|
||||||
// and tear down the namespace at test completion.
|
// and tear down the namespace at test completion.
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
// Clear all rules at the beginning + end of the test.
|
// Clear all rules at the beginning + end of the test.
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
@ -3903,8 +3950,8 @@ func TestDynsetWithOneExpression(t *testing.T) {
|
||||||
func TestDynsetWithMultipleExpressions(t *testing.T) {
|
func TestDynsetWithMultipleExpressions(t *testing.T) {
|
||||||
// Create a new network namespace to test these operations,
|
// Create a new network namespace to test these operations,
|
||||||
// and tear down the namespace at test completion.
|
// and tear down the namespace at test completion.
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
// Clear all rules at the beginning + end of the test.
|
// Clear all rules at the beginning + end of the test.
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
@ -4612,6 +4659,7 @@ func TestSet4(t *testing.T) {
|
||||||
// Additional details can be obtained by specifying the --debug=all option
|
// Additional details can be obtained by specifying the --debug=all option
|
||||||
// when calling nft(8).
|
// when calling nft(8).
|
||||||
want := [][]byte{
|
want := [][]byte{
|
||||||
|
|
||||||
// batch begin
|
// batch begin
|
||||||
[]byte("\x00\x00\x00\x0a"),
|
[]byte("\x00\x00\x00\x0a"),
|
||||||
|
|
||||||
|
@ -4685,7 +4733,7 @@ func TestSet4(t *testing.T) {
|
||||||
Anonymous: false,
|
Anonymous: false,
|
||||||
Constant: true,
|
Constant: true,
|
||||||
Name: "test-set",
|
Name: "test-set",
|
||||||
ID: uint32(1), // rand.Intn(0xffff)),
|
ID: uint32(1), //rand.Intn(0xffff)),
|
||||||
Table: tbl,
|
Table: tbl,
|
||||||
KeyType: nftables.TypeInetService,
|
KeyType: nftables.TypeInetService,
|
||||||
}
|
}
|
||||||
|
@ -5545,6 +5593,7 @@ func TestJHash(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDup(t *testing.T) {
|
func TestDup(t *testing.T) {
|
||||||
|
|
||||||
// The want byte sequences come from stracing nft(8), e.g.:
|
// The want byte sequences come from stracing nft(8), e.g.:
|
||||||
// strace -f -v -x -s 2048 -eraw=sendto nft add rule filter prerouting mark set jhash ip saddr mod 2
|
// strace -f -v -x -s 2048 -eraw=sendto nft add rule filter prerouting mark set jhash ip saddr mod 2
|
||||||
//
|
//
|
||||||
|
@ -5612,6 +5661,7 @@ func TestDup(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
lo, err := net.InterfaceByName("lo")
|
lo, err := net.InterfaceByName("lo")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -5645,6 +5695,7 @@ func TestDup(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDupWoDev(t *testing.T) {
|
func TestDupWoDev(t *testing.T) {
|
||||||
|
|
||||||
// The want byte sequences come from stracing nft(8), e.g.:
|
// The want byte sequences come from stracing nft(8), e.g.:
|
||||||
// strace -f -v -x -s 2048 -eraw=sendto nft add rule filter prerouting mark set jhash ip saddr mod 2
|
// strace -f -v -x -s 2048 -eraw=sendto nft add rule filter prerouting mark set jhash ip saddr mod 2
|
||||||
//
|
//
|
||||||
|
@ -5782,6 +5833,7 @@ func TestNotrack(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestQuota(t *testing.T) {
|
func TestQuota(t *testing.T) {
|
||||||
|
|
||||||
want := [][]byte{
|
want := [][]byte{
|
||||||
// batch begin
|
// batch begin
|
||||||
[]byte("\x00\x00\x00\x0a"),
|
[]byte("\x00\x00\x00\x0a"),
|
||||||
|
@ -5947,8 +5999,8 @@ func TestStatelessNAT(t *testing.T) {
|
||||||
func TestGetRulesObjref(t *testing.T) {
|
func TestGetRulesObjref(t *testing.T) {
|
||||||
// Create a new network namespace to test these operations,
|
// Create a new network namespace to test these operations,
|
||||||
// and tear down the namespace at test completion.
|
// and tear down the namespace at test completion.
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
// Clear all rules at the beginning + end of the test.
|
// Clear all rules at the beginning + end of the test.
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
@ -6012,8 +6064,8 @@ func TestGetRulesObjref(t *testing.T) {
|
||||||
func TestGetRulesQueue(t *testing.T) {
|
func TestGetRulesQueue(t *testing.T) {
|
||||||
// Create a new network namespace to test these operations,
|
// Create a new network namespace to test these operations,
|
||||||
// and tear down the namespace at test completion.
|
// and tear down the namespace at test completion.
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
// Clear all rules at the beginning + end of the test.
|
// Clear all rules at the beginning + end of the test.
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
@ -6069,8 +6121,8 @@ func TestGetRulesQueue(t *testing.T) {
|
||||||
func TestNftablesCompat(t *testing.T) {
|
func TestNftablesCompat(t *testing.T) {
|
||||||
// Create a new network namespace to test these operations,
|
// Create a new network namespace to test these operations,
|
||||||
// and tear down the namespace at test completion.
|
// and tear down the namespace at test completion.
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
c, newNS := openSystemNFTConn(t)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer cleanupSystemNFTConn(t, newNS)
|
||||||
// Clear all rules at the beginning + end of the test.
|
// Clear all rules at the beginning + end of the test.
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
defer c.FlushRuleset()
|
defer c.FlushRuleset()
|
||||||
|
|
|
@ -1,94 +0,0 @@
|
||||||
// Copyright 2018 Google LLC. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package userdata implements a TLV parser/serializer for libnftables-compatible comments
|
|
||||||
package userdata
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Type byte
|
|
||||||
|
|
||||||
// TLV type values are defined in:
|
|
||||||
// https://git.netfilter.org/iptables/tree/iptables/nft.c?id=73611d5582e72367a698faf1b5301c836e981465#n1659
|
|
||||||
const (
|
|
||||||
TypeComment Type = iota
|
|
||||||
TypeEbtablesPolicy
|
|
||||||
|
|
||||||
TypesCount
|
|
||||||
)
|
|
||||||
|
|
||||||
func Append(udata []byte, typ Type, data []byte) []byte {
|
|
||||||
udata = append(udata, byte(typ), byte(len(data)))
|
|
||||||
udata = append(udata, data...)
|
|
||||||
|
|
||||||
return udata
|
|
||||||
}
|
|
||||||
|
|
||||||
func Get(udata []byte, styp Type) []byte {
|
|
||||||
for {
|
|
||||||
if len(udata) < 2 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
typ := Type(udata[0])
|
|
||||||
length := int(udata[1])
|
|
||||||
data := udata[2 : 2+length]
|
|
||||||
|
|
||||||
if styp == typ {
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(udata) < 2+length {
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
udata = udata[2+length:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func AppendUint32(udata []byte, typ Type, num uint32) []byte {
|
|
||||||
data := binary.LittleEndian.AppendUint32(nil, num)
|
|
||||||
|
|
||||||
return Append(udata, typ, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetUint32(udata []byte, typ Type) (uint32, bool) {
|
|
||||||
data := Get(udata, typ)
|
|
||||||
if data == nil {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
return binary.LittleEndian.Uint32(data), true
|
|
||||||
}
|
|
||||||
|
|
||||||
func AppendString(udata []byte, typ Type, str string) []byte {
|
|
||||||
data := append([]byte(str), 0)
|
|
||||||
return Append(udata, typ, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetString(udata []byte, typ Type) (string, bool) {
|
|
||||||
data := Get(udata, typ)
|
|
||||||
if data == nil {
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
|
|
||||||
data, _ = bytes.CutSuffix(data, []byte{0})
|
|
||||||
|
|
||||||
return string(data), true
|
|
||||||
}
|
|
|
@ -1,233 +0,0 @@
|
||||||
// Copyright 2018 Google LLC. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package userdata_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"flag"
|
|
||||||
"os/exec"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/google/nftables"
|
|
||||||
"github.com/google/nftables/internal/nftest"
|
|
||||||
"github.com/google/nftables/userdata"
|
|
||||||
)
|
|
||||||
|
|
||||||
var enableSysTests = flag.Bool("run_system_tests", false, "Run tests that operate against the live kernel")
|
|
||||||
|
|
||||||
type nftCliMetainfo struct {
|
|
||||||
Version string `json:"version,omitempty"`
|
|
||||||
ReleaseName string `json:"release_name,omitempty"`
|
|
||||||
JSONSchemaVersion int `json:"json_schema_version,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type nftCliTable struct {
|
|
||||||
Family string `json:"family,omitempty"`
|
|
||||||
Name string `json:"name,omitempty"`
|
|
||||||
Handle int `json:"handle,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type nftCliChain struct {
|
|
||||||
Family string `json:"family,omitempty"`
|
|
||||||
Table string `json:"table,omitempty"`
|
|
||||||
Name string `json:"name,omitempty"`
|
|
||||||
Handle int `json:"handle,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type nftCliExpr struct{}
|
|
||||||
|
|
||||||
type nftCliRule struct {
|
|
||||||
Family string `json:"family,omitempty"`
|
|
||||||
Table string `json:"table,omitempty"`
|
|
||||||
Chain string `json:"chain,omitempty"`
|
|
||||||
Handle int `json:"handle,omitempty"`
|
|
||||||
Comment string `json:"comment,omitempty"`
|
|
||||||
Expr []nftCliExpr `json:"expr"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type nftCommand struct {
|
|
||||||
Ruleset interface{} `json:"ruleset"`
|
|
||||||
Table *nftCliTable `json:"table,omitempty"`
|
|
||||||
Chain *nftCliChain `json:"chain,omitempty"`
|
|
||||||
Rule *nftCliRule `json:"rule,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type nftCliObject struct {
|
|
||||||
Metainfo *nftCliMetainfo `json:"metainfo,omitempty"`
|
|
||||||
Table *nftCliTable `json:"table,omitempty"`
|
|
||||||
Chain *nftCliChain `json:"chain,omitempty"`
|
|
||||||
Rule *nftCliRule `json:"rule,omitempty"`
|
|
||||||
Add *nftCommand `json:"add,omitempty"`
|
|
||||||
Flush *nftCommand `json:"flush,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type nftCli struct {
|
|
||||||
Nftables []nftCliObject `json:"nftables"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCommentInteropGo2Cli(t *testing.T) {
|
|
||||||
wantComment := "my comment"
|
|
||||||
|
|
||||||
// Create a new network namespace to test these operations,
|
|
||||||
// and tear down the namespace at test completion.
|
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
|
||||||
|
|
||||||
c.FlushRuleset()
|
|
||||||
|
|
||||||
table := c.AddTable(&nftables.Table{
|
|
||||||
Name: "userdata-table",
|
|
||||||
Family: nftables.TableFamilyIPv4,
|
|
||||||
})
|
|
||||||
|
|
||||||
chain := c.AddChain(&nftables.Chain{
|
|
||||||
Name: "userdata-chain",
|
|
||||||
Table: table,
|
|
||||||
})
|
|
||||||
|
|
||||||
c.AddRule(&nftables.Rule{
|
|
||||||
Table: table,
|
|
||||||
Chain: chain,
|
|
||||||
UserData: userdata.AppendString(nil, userdata.TypeComment, wantComment),
|
|
||||||
})
|
|
||||||
|
|
||||||
if err := c.Flush(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
out := bytes.NewBuffer(nil)
|
|
||||||
d := exec.Command("nft", "-j", "list", "table", "userdata-table")
|
|
||||||
d.Stdout = out
|
|
||||||
if err := d.Run(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var outJson nftCli
|
|
||||||
if err := json.Unmarshal(out.Bytes(), &outJson); err != nil {
|
|
||||||
t.Fatal()
|
|
||||||
}
|
|
||||||
|
|
||||||
found := 0
|
|
||||||
for _, e := range outJson.Nftables {
|
|
||||||
if e.Rule == nil || e.Rule.Handle == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if e.Rule.Comment != wantComment {
|
|
||||||
t.Fatal()
|
|
||||||
}
|
|
||||||
|
|
||||||
found++
|
|
||||||
}
|
|
||||||
|
|
||||||
if found != 1 {
|
|
||||||
t.Fatalf("found %d rules", found)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.DelTable(table)
|
|
||||||
|
|
||||||
if err := c.Flush(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCommentInteropCli2Go(t *testing.T) {
|
|
||||||
wantComment := "my comment"
|
|
||||||
|
|
||||||
inJson := nftCli{
|
|
||||||
Nftables: []nftCliObject{
|
|
||||||
{
|
|
||||||
Metainfo: &nftCliMetainfo{
|
|
||||||
JSONSchemaVersion: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Flush: &nftCommand{
|
|
||||||
Ruleset: nil,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Add: &nftCommand{
|
|
||||||
Table: &nftCliTable{
|
|
||||||
Family: "ip",
|
|
||||||
Name: "userdata-table",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Add: &nftCommand{
|
|
||||||
Chain: &nftCliChain{
|
|
||||||
Family: "ip",
|
|
||||||
Name: "userdata-chain",
|
|
||||||
Table: "userdata-table",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Add: &nftCommand{
|
|
||||||
Rule: &nftCliRule{
|
|
||||||
Family: "ip",
|
|
||||||
Table: "userdata-table",
|
|
||||||
Chain: "userdata-chain",
|
|
||||||
Comment: wantComment,
|
|
||||||
Expr: []nftCliExpr{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
in := bytes.NewBuffer(nil)
|
|
||||||
if err := json.NewEncoder(in).Encode(inJson); err != nil {
|
|
||||||
t.Fatal()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new network namespace to test these operations,
|
|
||||||
// and tear down the namespace at test completion.
|
|
||||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
|
||||||
|
|
||||||
d := exec.Command("nft", "-j", "-f", "-")
|
|
||||||
d.Stdin = in
|
|
||||||
if err := d.Run(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
table := &nftables.Table{
|
|
||||||
Name: "userdata-table",
|
|
||||||
Family: nftables.TableFamilyIPv4,
|
|
||||||
}
|
|
||||||
|
|
||||||
chain := &nftables.Chain{
|
|
||||||
Name: "userdata-chain",
|
|
||||||
Table: table,
|
|
||||||
}
|
|
||||||
|
|
||||||
rules, err := c.GetRules(table, chain)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(rules) != 1 {
|
|
||||||
t.Fatal()
|
|
||||||
}
|
|
||||||
|
|
||||||
if comment, ok := userdata.GetString(rules[0].UserData, userdata.TypeComment); !ok {
|
|
||||||
t.Fatalf("failed to find comment")
|
|
||||||
} else if comment != wantComment {
|
|
||||||
t.Fatalf("comment mismatch %q != %q", comment, wantComment)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
// Copyright 2018 Google LLC. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package userdata_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/hex"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/google/nftables"
|
|
||||||
"github.com/google/nftables/userdata"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestUserDataComment(t *testing.T) {
|
|
||||||
r := nftables.Rule{}
|
|
||||||
|
|
||||||
wantComment := "this is my comment"
|
|
||||||
want := []byte{
|
|
||||||
byte(userdata.TypeComment), // Type
|
|
||||||
byte(len(wantComment) + 1), // Length (including terminating null byte)
|
|
||||||
}
|
|
||||||
want = append(want, []byte(wantComment)...) // Payload
|
|
||||||
want = append(want, 0) // Terminating null byte
|
|
||||||
|
|
||||||
r.UserData = userdata.AppendString(r.UserData, userdata.TypeComment, wantComment)
|
|
||||||
|
|
||||||
if !bytes.Equal(r.UserData, want) {
|
|
||||||
t.Fatalf("UserData mismatch: %s != %s",
|
|
||||||
hex.EncodeToString(r.UserData),
|
|
||||||
hex.EncodeToString(want))
|
|
||||||
}
|
|
||||||
|
|
||||||
if comment, ok := userdata.GetString(r.UserData, userdata.TypeComment); !ok {
|
|
||||||
t.Fatalf("failed to get comment")
|
|
||||||
} else if comment != wantComment {
|
|
||||||
t.Fatalf("comment does not match: %s != %s", comment, wantComment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUint32(t *testing.T) {
|
|
||||||
// Define a custom type for storing a rule ID
|
|
||||||
const TypeRuleID = userdata.TypesCount
|
|
||||||
|
|
||||||
r := nftables.Rule{}
|
|
||||||
|
|
||||||
wantRuleID := uint32(1234)
|
|
||||||
want := []byte{byte(TypeRuleID), 4, 210, 4, 0, 0}
|
|
||||||
|
|
||||||
r.UserData = userdata.AppendUint32(r.UserData, TypeRuleID, wantRuleID)
|
|
||||||
|
|
||||||
if !bytes.Equal(r.UserData, want) {
|
|
||||||
t.Fatalf("UserData mismatch: %x != %x", r.UserData, want)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ruleID, ok := userdata.GetUint32(r.UserData, TypeRuleID); !ok {
|
|
||||||
t.Fatalf("failed to get id")
|
|
||||||
} else if ruleID != wantRuleID {
|
|
||||||
t.Fatalf("id mismatch")
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue