nftables_test: add test for issue #26

This commit is contained in:
Michael Stapelberg 2019-07-20 18:34:59 +02:00
parent 37c3f0e9eb
commit c123f7dc7d
1 changed files with 129 additions and 0 deletions

View File

@ -2281,3 +2281,132 @@ func TestConfigureRangeIPv6(t *testing.T) {
t.Fatal(err)
}
}
func TestSet4(t *testing.T) {
// The want byte sequences come from stracing nft(8), e.g.:
// strace-4.21 -f -v -x -s 2048 -etrace=sendto nft add table ip nat
//
// Until https://github.com/strace/strace/issues/100 is resolved,
// you need to use strace 4.21 or apply the patch in the issue.
//
// Additional details can be obtained by specifying the --debug=all option
// when calling nft(8).
want := [][]byte{
// batch begin
[]byte("\x00\x00\x00\x0a"),
// table ip ipv4table {
// set test-set {
// type inet_service
// flags constant
// elements = { 12000, 12001, 12345, 12346 }
// }
//
// chain ipv4chain-2 {
// type nat hook prerouting priority dstnat; policy accept;
// tcp dport @test-set
// }
// }
[]byte("\x02\x00\x00\x00\x0e\x00\x01\x00\x69\x70\x76\x34\x74\x61\x62\x6c\x65\x00\x00\x00\x08\x00\x02\x00\x00\x00\x00\x00"),
[]byte("\x02\x00\x00\x00\x0e\x00\x01\x00\x69\x70\x76\x34\x74\x61\x62\x6c\x65\x00\x00\x00\x10\x00\x03\x00\x69\x70\x76\x34\x63\x68\x61\x69\x6e\x2d\x32\x00\x14\x00\x04\x80\x08\x00\x01\x00\x00\x00\x00\x00\x08\x00\x02\x00\xff\xff\xff\x9c\x08\x00\x05\x00\x00\x00\x00\x01\x08\x00\x07\x00\x6e\x61\x74\x00"),
[]byte("\x02\x00\x00\x00\x0e\x00\x01\x00\x69\x70\x76\x34\x74\x61\x62\x6c\x65\x00\x00\x00\x0d\x00\x02\x00\x74\x65\x73\x74\x2d\x73\x65\x74\x00\x00\x00\x00\x08\x00\x03\x00\x00\x00\x00\x02\x08\x00\x04\x00\x00\x00\x00\x0d\x08\x00\x05\x00\x00\x00\x00\x02\x08\x00\x0a\x00\x00\x00\x00\x01\x0c\x00\x09\x80\x08\x00\x01\x00\x00\x00\x00\x04\x0a\x00\x0d\x00\x00\x04\x02\x00\x00\x00\x00\x00"),
[]byte("\x02\x00\x00\x00\x0d\x00\x02\x00\x74\x65\x73\x74\x2d\x73\x65\x74\x00\x00\x00\x00\x08\x00\x04\x00\x00\x00\x00\x01\x0e\x00\x01\x00\x69\x70\x76\x34\x74\x61\x62\x6c\x65\x00\x00\x00\x44\x00\x03\x80\x10\x00\x01\x80\x0c\x00\x01\x80\x06\x00\x01\x00\x2e\xe0\x00\x00\x10\x00\x02\x80\x0c\x00\x01\x80\x06\x00\x01\x00\x2e\xe1\x00\x00\x10\x00\x03\x80\x0c\x00\x01\x80\x06\x00\x01\x00\x30\x39\x00\x00\x10\x00\x04\x80\x0c\x00\x01\x80\x06\x00\x01\x00\x30\x3a\x00\x00"),
[]byte("\x02\x00\x00\x00\x0e\x00\x01\x00\x69\x70\x76\x34\x74\x61\x62\x6c\x65\x00\x00\x00\x10\x00\x02\x00\x69\x70\x76\x34\x63\x68\x61\x69\x6e\x2d\x32\x00\xbc\x00\x04\x80\x24\x00\x01\x80\x09\x00\x01\x00\x6d\x65\x74\x61\x00\x00\x00\x00\x14\x00\x02\x80\x08\x00\x02\x00\x00\x00\x00\x10\x08\x00\x01\x00\x00\x00\x00\x01\x2c\x00\x01\x80\x08\x00\x01\x00\x63\x6d\x70\x00\x20\x00\x02\x80\x08\x00\x01\x00\x00\x00\x00\x01\x08\x00\x02\x00\x00\x00\x00\x00\x0c\x00\x03\x80\x05\x00\x01\x00\x06\x00\x00\x00\x34\x00\x01\x80\x0c\x00\x01\x00\x70\x61\x79\x6c\x6f\x61\x64\x00\x24\x00\x02\x80\x08\x00\x01\x00\x00\x00\x00\x01\x08\x00\x02\x00\x00\x00\x00\x02\x08\x00\x03\x00\x00\x00\x00\x02\x08\x00\x04\x00\x00\x00\x00\x02\x34\x00\x01\x80\x0b\x00\x01\x00\x6c\x6f\x6f\x6b\x75\x70\x00\x00\x24\x00\x02\x80\x08\x00\x02\x00\x00\x00\x00\x01\x0d\x00\x01\x00\x74\x65\x73\x74\x2d\x73\x65\x74\x00\x00\x00\x00\x08\x00\x04\x00\x00\x00\x00\x01"),
// batch end
[]byte("\x00\x00\x00\x0a"),
}
c := &nftables.Conn{
TestDial: func(req []netlink.Message) ([]netlink.Message, error) {
for idx, msg := range req {
b, err := msg.MarshalBinary()
if err != nil {
t.Fatal(err)
}
if len(b) < 16 {
continue
}
b = b[16:]
if len(want) == 0 {
t.Errorf("no want entry for message %d: %x", idx, b)
continue
}
if got, want := b, want[0]; !bytes.Equal(got, want) {
t.Errorf("message %d: %s", idx, linediff(nfdump(got), nfdump(want)))
}
want = want[1:]
}
return req, nil
},
}
tbl := &nftables.Table{
Name: "ipv4table",
Family: nftables.TableFamilyIPv4,
}
ch := &nftables.Chain{
Name: "ipv4chain-2",
Table: tbl,
Type: nftables.ChainTypeNAT,
Priority: nftables.ChainPriorityNATDest,
Hooknum: nftables.ChainHookPrerouting,
Policy: 1, // TODO
}
set := nftables.Set{
Anonymous: false,
Constant: true,
Name: "test-set",
ID: uint32(1), //rand.Intn(0xffff)),
Table: tbl,
KeyType: nftables.TypeInetService,
}
c.AddTable(tbl)
c.AddChain(ch)
re := []expr.Any{}
re = append(re, &expr.Meta{Key: expr.MetaKeyL4PROTO, Register: 1})
re = append(re, &expr.Cmp{
Op: expr.CmpOpEq,
Register: 1,
Data: []byte{unix.IPPROTO_TCP},
})
re = append(re, &expr.Payload{
DestRegister: 1,
Base: expr.PayloadBaseTransportHeader,
Offset: 2, // Offset for a transport protocol header
Len: 2, // 2 bytes for port
})
re = append(re, &expr.Lookup{
SourceRegister: 1,
Invert: false,
SetID: set.ID,
SetName: set.Name,
})
ports := []uint16{12000, 12001, 12345, 12346}
setElements := make([]nftables.SetElement, len(ports))
for i := 0; i < len(ports); i++ {
setElements[i].Key = binaryutil.BigEndian.PutUint16(ports[i])
}
if err := c.AddSet(&set, setElements); err != nil {
t.Fatal(err)
}
c.AddRule(&nftables.Rule{
Table: tbl,
Chain: ch,
Exprs: re,
})
if err := c.Flush(); err != nil {
t.Fatal(err)
}
}