From 4fed02b227b70638e33c2250cdeab7f5ab4488d9 Mon Sep 17 00:00:00 2001 From: Maxime Demode Date: Wed, 23 Oct 2019 15:45:10 +0200 Subject: [PATCH] [test] Add FlushTable case. --- nftables_test.go | 227 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) diff --git a/nftables_test.go b/nftables_test.go index fff4452..73cbd32 100644 --- a/nftables_test.go +++ b/nftables_test.go @@ -1765,6 +1765,233 @@ func TestFlushChain(t *testing.T) { } } +func TestFlushTable(t *testing.T) { + // Create a new network namespace to test these operations, + // and tear down the namespace at test completion. + c, newNS := openSystemNFTConn(t) + defer cleanupSystemNFTConn(t, newNS) + // Clear all rules at the beginning + end of the test. + c.FlushRuleset() + defer c.FlushRuleset() + + filter := c.AddTable(&nftables.Table{ + Family: nftables.TableFamilyIPv4, + Name: "filter", + }) + + nat := c.AddTable(&nftables.Table{ + Family: nftables.TableFamilyIPv4, + Name: "nat", + }) + + forward := c.AddChain(&nftables.Chain{ + Table: filter, + Name: "forward", + }) + + input := c.AddChain(&nftables.Chain{ + Table: filter, + Name: "input", + }) + + prerouting := c.AddChain(&nftables.Chain{ + Table: nat, + Name: "prerouting", + }) + + c.AddRule(&nftables.Rule{ + Table: filter, + Chain: forward, + Exprs: []expr.Any{ + // [ meta load l4proto => reg 1 ] + &expr.Meta{Key: expr.MetaKeyL4PROTO, Register: 1}, + // [ cmp eq reg 1 0x00000006 ] + &expr.Cmp{ + Op: expr.CmpOpEq, + Register: 1, + Data: []byte{unix.IPPROTO_TCP}, + }, + + // [ payload load 2b @ transport header + 2 => reg 1 ] + &expr.Payload{ + DestRegister: 1, + Base: expr.PayloadBaseTransportHeader, + Offset: 2, + Len: 2, + }, + // [ cmp eq reg 1 0x0000d204 ] + &expr.Cmp{ + Op: expr.CmpOpEq, + Register: 1, + Data: []byte{0x04, 0xd2}, + }, + // [ immediate reg 0 drop ] + &expr.Verdict{ + Kind: expr.VerdictDrop, + }, + }, + }) + + c.AddRule(&nftables.Rule{ + Table: filter, + Chain: forward, + Exprs: []expr.Any{ + // [ meta load l4proto => reg 1 ] + &expr.Meta{Key: expr.MetaKeyL4PROTO, Register: 1}, + // [ cmp eq reg 1 0x00000006 ] + &expr.Cmp{ + Op: expr.CmpOpEq, + Register: 1, + Data: []byte{unix.IPPROTO_TCP}, + }, + + // [ payload load 2b @ transport header + 2 => reg 1 ] + &expr.Payload{ + DestRegister: 1, + Base: expr.PayloadBaseTransportHeader, + Offset: 2, + Len: 2, + }, + // [ cmp eq reg 1 0x000010e1 ] + &expr.Cmp{ + Op: expr.CmpOpEq, + Register: 1, + Data: []byte{0xe1, 0x10}, + }, + // [ immediate reg 0 drop ] + &expr.Verdict{ + Kind: expr.VerdictDrop, + }, + }, + }) + + c.AddRule(&nftables.Rule{ + Table: filter, + Chain: input, + Exprs: []expr.Any{ + // [ meta load l4proto => reg 1 ] + &expr.Meta{Key: expr.MetaKeyL4PROTO, Register: 1}, + // [ cmp eq reg 1 0x00000006 ] + &expr.Cmp{ + Op: expr.CmpOpEq, + Register: 1, + Data: []byte{unix.IPPROTO_TCP}, + }, + + // [ payload load 2b @ transport header + 2 => reg 1 ] + &expr.Payload{ + DestRegister: 1, + Base: expr.PayloadBaseTransportHeader, + Offset: 2, + Len: 2, + }, + // [ cmp eq reg 1 0x0000162e ] + &expr.Cmp{ + Op: expr.CmpOpEq, + Register: 1, + Data: []byte{0x2e, 0x16}, + }, + // [ immediate reg 0 drop ] + &expr.Verdict{ + Kind: expr.VerdictDrop, + }, + }, + }) + + c.AddRule(&nftables.Rule{ + Table: nat, + Chain: prerouting, + Exprs: []expr.Any{ + // [ meta load l4proto => reg 1 ] + &expr.Meta{Key: expr.MetaKeyL4PROTO, Register: 1}, + // [ cmp eq reg 1 0x00000006 ] + &expr.Cmp{ + Op: expr.CmpOpEq, + Register: 1, + Data: []byte{unix.IPPROTO_TCP}, + }, + + // [ payload load 2b @ transport header + 2 => reg 1 ] + &expr.Payload{ + DestRegister: 1, + Base: expr.PayloadBaseTransportHeader, + Offset: 2, // TODO + Len: 2, // TODO + }, + // [ cmp eq reg 1 0x00001600 ] + &expr.Cmp{ + Op: expr.CmpOpEq, + Register: 1, + Data: []byte{0x00, 0x16}, + }, + + // [ immediate reg 1 0x0000ae08 ] + &expr.Immediate{ + Register: 1, + Data: binaryutil.BigEndian.PutUint16(2222), + }, + + // [ redir proto_min reg 1 ] + &expr.Redir{ + RegisterProtoMin: 1, + }, + }, + }) + + if err := c.Flush(); err != nil { + t.Errorf("c.Flush() failed: %v", err) + } + rules, err := c.GetRule(filter, forward) + if err != nil { + t.Errorf("c.GetRule() failed: %v", err) + } + if len(rules) != 2 { + t.Fatalf("len(rules) = %d, want 2", len(rules)) + } + rules, err = c.GetRule(filter, input) + if err != nil { + t.Errorf("c.GetRule() failed: %v", err) + } + if len(rules) != 1 { + t.Fatalf("len(rules) = %d, want 1", len(rules)) + } + rules, err = c.GetRule(nat, prerouting) + if err != nil { + t.Errorf("c.GetRule() failed: %v", err) + } + if len(rules) != 1 { + t.Fatalf("len(rules) = %d, want 1", len(rules)) + } + + c.FlushTable(filter) + + if err := c.Flush(); err != nil { + t.Errorf("Second c.Flush() failed: %v", err) + } + + rules, err = c.GetRule(filter, forward) + if err != nil { + t.Errorf("c.GetRule() failed: %v", err) + } + if len(rules) != 0 { + t.Fatalf("len(rules) = %d, want 0", len(rules)) + } + rules, err = c.GetRule(filter, input) + if err != nil { + t.Errorf("c.GetRule() failed: %v", err) + } + if len(rules) != 0 { + t.Fatalf("len(rules) = %d, want 0", len(rules)) + } + rules, err = c.GetRule(nat, prerouting) + if err != nil { + t.Errorf("c.GetRule() failed: %v", err) + } + if len(rules) != 1 { + t.Fatalf("len(rules) = %d, want 1", len(rules)) + } +} + func TestGetRuleLookupVerdictImmediate(t *testing.T) { // Create a new network namespace to test these operations, // and tear down the namespace at test completion.