From 2c6b9695a7e83724b22b45621299a491dbe75e59 Mon Sep 17 00:00:00 2001 From: Martin Dvorak Date: Tue, 17 Oct 2023 16:23:36 +0200 Subject: [PATCH 1/4] mark filter fix --- bpf.go | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 6 deletions(-) diff --git a/bpf.go b/bpf.go index c0d1270..6645d07 100644 --- a/bpf.go +++ b/bpf.go @@ -22,6 +22,8 @@ var ( const ( bpfMAXINSTR = 4096 + failedJump = uint8(255) + bpfVerdictAccept = 0xffffffff bpfVerdictReject = 0x00000000 ) @@ -185,7 +187,6 @@ func compareValues(filters []ConnAttr) []bpf.RawInstruction { func filterAttribute(filters []ConnAttr) []bpf.RawInstruction { var raw []bpf.RawInstruction nested := len(filterCheck[filters[0].Type].nest) - failed := uint8(255) // sizeof(nlmsghdr) + sizeof(nfgenmsg) = 20 tmp := bpf.RawInstruction{Op: unix.BPF_LD | unix.BPF_IMM, K: 0x14} @@ -200,7 +201,7 @@ func filterAttribute(filters []ConnAttr) []bpf.RawInstruction { raw = append(raw, tmp) // jump, if nest not found - tmp = bpf.RawInstruction{Op: unix.BPF_JMP | unix.BPF_JEQ | unix.BPF_K, K: 0, Jt: failed} + tmp = bpf.RawInstruction{Op: unix.BPF_JMP | unix.BPF_JEQ | unix.BPF_K, K: 0, Jt: failedJump} raw = append(raw, tmp) tmp = bpf.RawInstruction{Op: unix.BPF_ALU | unix.BPF_ADD | unix.BPF_K, K: 4} @@ -214,7 +215,7 @@ func filterAttribute(filters []ConnAttr) []bpf.RawInstruction { tmp = bpf.RawInstruction{Op: unix.BPF_LD | unix.BPF_B | unix.BPF_ABS, K: 0xfffff00c} raw = append(raw, tmp) - tmp = bpf.RawInstruction{Op: unix.BPF_JMP | unix.BPF_JEQ | unix.BPF_K, K: 0, Jt: failed} + tmp = bpf.RawInstruction{Op: unix.BPF_JMP | unix.BPF_JEQ | unix.BPF_K, K: 0, Jt: failedJump} raw = append(raw, tmp) tmp = bpf.RawInstruction{Op: unix.BPF_MISC | unix.BPF_TAX} @@ -234,9 +235,9 @@ func filterAttribute(filters []ConnAttr) []bpf.RawInstruction { // Failed jumps are set to 255. Now we correct them to the actual failed jump instruction j := uint8(1) for i := len(raw) - 1; i > 0; i-- { - if (raw[i].Jt == 255) && (raw[i].Op == unix.BPF_JMP|unix.BPF_JEQ|unix.BPF_K) { + if (raw[i].Jt == failedJump) && (raw[i].Op == unix.BPF_JMP|unix.BPF_JEQ|unix.BPF_K) { raw[i].Jt = j - jump - } else if (raw[i].Jf == 255) && (raw[i].Op == unix.BPF_JMP|unix.BPF_JEQ|unix.BPF_K) { + } else if (raw[i].Jf == failedJump) && (raw[i].Op == unix.BPF_JMP|unix.BPF_JEQ|unix.BPF_K) { raw[i].Jf = j - 1 } j++ @@ -302,7 +303,12 @@ func constructFilter(subsys Table, filters []ConnAttr) ([]bpf.RawInstruction, er // We can not simple range over the map, because the order of selected items can vary for key := 0; key <= int(attrMax); key++ { if x, ok := filterMap[ConnAttrType(key)]; ok { - tmp = filterAttribute(x) + switch key { + case int(AttrMark): + tmp = filterMarkAttribute(x) + default: + tmp = filterAttribute(x) + } raw = append(raw, tmp...) } } @@ -317,6 +323,67 @@ func constructFilter(subsys Table, filters []ConnAttr) ([]bpf.RawInstruction, er return raw, nil } +func filterMarkAttribute(filters []ConnAttr) []bpf.RawInstruction { + var raw []bpf.RawInstruction + + // sizeof(nlmsghdr) + sizeof(nfgenmsg) = 20 + tmp := bpf.RawInstruction{Op: unix.BPF_LD | unix.BPF_IMM, K: 0x14} + raw = append(raw, tmp) + + // find final attribute + tmp = bpf.RawInstruction{Op: unix.BPF_LDX | unix.BPF_IMM, K: uint32(filterCheck[filters[0].Type].ct)} + raw = append(raw, tmp) + tmp = bpf.RawInstruction{Op: unix.BPF_LD | unix.BPF_B | unix.BPF_ABS, K: 0xfffff00c} + raw = append(raw, tmp) + + tmp = bpf.RawInstruction{Op: unix.BPF_JMP | unix.BPF_JEQ | unix.BPF_K, K: 0, Jt: 2} + raw = append(raw, tmp) + + tmp = bpf.RawInstruction{Op: unix.BPF_MISC | unix.BPF_TAX} + raw = append(raw, tmp) + + tmp = bpf.RawInstruction{Op: unix.BPF_LD | unix.BPF_W | unix.BPF_IND, K: uint32(len(filters[0].Data))} + raw = append(raw, tmp) + + tmp = bpf.RawInstruction{Op: unix.BPF_MISC | unix.BPF_TAX} + raw = append(raw, tmp) + + for _, filter := range filters { + var dataLen = len(filter.Data) + for i := 0; i < (int(dataLen) / 4); i++ { + mask := encodeValue(filter.Mask[i*4 : (i+1)*4]) + tmp = bpf.RawInstruction{Op: unix.BPF_ALU | unix.BPF_AND | unix.BPF_K, K: mask} + raw = append(raw, tmp) + val := encodeValue(filter.Data[i*4 : (i+1)*4]) + val &= mask + tmp = bpf.RawInstruction{Op: unix.BPF_JMP | unix.BPF_JEQ | unix.BPF_K, K: val, Jt: failedJump} + raw = append(raw, tmp) + tmp = bpf.RawInstruction{Op: unix.BPF_MISC | unix.BPF_TXA} + raw = append(raw, tmp) + } + } + + var j uint8 = 1 + + // Failed jumps are set to 255. Now we correct them to the actual failed jump instruction + for i := len(raw) - 1; i > 0; i-- { + if (raw[i].Jt == failedJump) && (raw[i].Op == unix.BPF_JMP|unix.BPF_JEQ|unix.BPF_K) { + raw[i].Jt = j + } + j++ + } + + // negate filter + if filters[0].Negate { + raw = append(raw, bpf.RawInstruction{Op: unix.BPF_JMP | unix.BPF_JA, K: 1}) + } + + // reject + raw = append(raw, bpf.RawInstruction{Op: unix.BPF_RET | unix.BPF_K, K: bpfVerdictReject}) + + return raw +} + func (nfct *Nfct) attachFilter(subsys Table, filters []ConnAttr) error { bpfFilters, err := constructFilter(subsys, filters) From 8655c22e774bddf817575ffe527d72cd3015b3de Mon Sep 17 00:00:00 2001 From: Martin Dvorak Date: Tue, 21 Nov 2023 16:44:09 +0100 Subject: [PATCH 2/4] added tests for mark filter, possibility to print created filters --- bpf.go | 60 +++++++++++++++++++++++- bpf_test.go | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++ conntrack.go | 5 ++ types.go | 2 + 4 files changed, 196 insertions(+), 1 deletion(-) diff --git a/bpf.go b/bpf.go index 6645d07..a1b2145 100644 --- a/bpf.go +++ b/bpf.go @@ -3,7 +3,9 @@ package conntrack import ( "encoding/binary" "errors" + "fmt" "sort" + "strings" "github.com/florianl/go-conntrack/internal/unix" "golang.org/x/net/bpf" @@ -385,14 +387,70 @@ func filterMarkAttribute(filters []ConnAttr) []bpf.RawInstruction { } func (nfct *Nfct) attachFilter(subsys Table, filters []ConnAttr) error { - bpfFilters, err := constructFilter(subsys, filters) if err != nil { return err } + if nfct.debug { + fmtInstructions := fmtRawInstructions(bpfFilters) + fmt.Print(strings.Join(fmtInstructions, "")) + } + return nfct.Con.SetBPF(bpfFilters) } func (nfct *Nfct) removeFilter() error { return nfct.Con.RemoveBPF() } + +func fmtRawInstruction(index int, raw bpf.RawInstruction) string { + code := code2str(raw.Op & 0xFFFF) + return fmt.Sprintf("(%.4x) code=%30s\tjt=%.2x jf=%.2x k=%.8x\n", + index, + code, + raw.Jt&0xFF, + raw.Jf&0xFF, + raw.K&0xFFFFFFFF) +} + +func fmtRawInstructions(raw []bpf.RawInstruction) []string { + output := make([]string, len(raw)) + + for i, instr := range raw { + output[i] = fmtRawInstruction(i, instr) + } + + return output +} + +func code2str(op uint16) string { + switch op { + case unix.BPF_LD | unix.BPF_IMM: + return "BPF_LD|BPF_IMM" + case unix.BPF_LDX | unix.BPF_IMM: + return "BPF_LDX|BPF_IMM" + case unix.BPF_LD | unix.BPF_B | unix.BPF_ABS: + return "BPF_LD|BPF_B|BPF_ABS" + case unix.BPF_JMP | unix.BPF_JEQ | unix.BPF_K: + return "BPF_JMP|BPF_JEQ|BPF_K" + case unix.BPF_ALU | unix.BPF_AND | unix.BPF_K: + return "BPF_ALU|BPF_AND|BPF_K" + case unix.BPF_JMP | unix.BPF_JA: + return "BPF_JMP|BPF_JA" + case unix.BPF_RET | unix.BPF_K: + return "BPF_RET|BPF_K" + case unix.BPF_ALU | unix.BPF_ADD | unix.BPF_K: + return "BPF_ALU|BPF_ADD|BPF_K" + case unix.BPF_MISC | unix.BPF_TAX: + return "BPF_MISC|BPF_TAX" + case unix.BPF_MISC | unix.BPF_TXA: + return "BPF_MISC|BPF_TXA" + case unix.BPF_LD | unix.BPF_B | unix.BPF_IND: + return "BPF_LD|BPF_B|BPF_IND" + case unix.BPF_LD | unix.BPF_H | unix.BPF_IND: + return "BPF_LD|BPF_H|BPF_IND" + case unix.BPF_LD | unix.BPF_W | unix.BPF_IND: + return "BPF_LD|BPF_W|BPF_IND" + } + return "UNKNOWN_INSTRUCTION" +} diff --git a/bpf_test.go b/bpf_test.go index 709e61f..0df6e12 100644 --- a/bpf_test.go +++ b/bpf_test.go @@ -1,6 +1,9 @@ package conntrack import ( + "encoding/binary" + "github.com/florianl/go-conntrack/internal/unix" + "strings" "testing" "golang.org/x/net/bpf" @@ -170,3 +173,130 @@ func TestConstructFilter(t *testing.T) { }) } } + +func TestAttrMarkFilter(t *testing.T) { + mark1ByteValue := make([]byte, 4) + binary.BigEndian.PutUint32(mark1ByteValue, 1) + mark10ByteValue := make([]byte, 4) + binary.BigEndian.PutUint32(mark10ByteValue, 10) + mark11ByteValue := make([]byte, 4) + binary.BigEndian.PutUint32(mark11ByteValue, 11) + mark50ByteValue := make([]byte, 4) + binary.BigEndian.PutUint32(mark50ByteValue, 50) + mark1000ByteValue := make([]byte, 4) + binary.BigEndian.PutUint32(mark1000ByteValue, 1000) + + tests := []struct { + name string + table Table + filters []ConnAttr + rawInstr []bpf.RawInstruction + err error + }{ + {name: "mark positive filter: [1]", table: Conntrack, filters: []ConnAttr{ + {Type: AttrMark, Data: mark1ByteValue, Mask: []byte{255, 255, 255, 255}, Negate: false}, + }, rawInstr: []bpf.RawInstruction{ + //--- check subsys --- + {Op: unix.BPF_LDX | unix.BPF_IMM, Jt: 0x00, Jf: 0x00, K: 0x00000004}, + {Op: unix.BPF_LD | unix.BPF_B | unix.BPF_IND, Jt: 0x00, Jf: 0x00, K: 0x00000001}, + {Op: unix.BPF_JMP | unix.BPF_JEQ | unix.BPF_K, Jt: 0x01, Jf: 0x00, K: 0x00000001}, + {Op: unix.BPF_RET | unix.BPF_K, Jt: 0x00, Jf: 0x00, K: 0xffffffff}, + //--- check mark --- + {Op: unix.BPF_LD | unix.BPF_IMM, Jt: 0x00, Jf: 0x00, K: 0x00000014}, + {Op: unix.BPF_LDX | unix.BPF_IMM, Jt: 0x00, Jf: 0x00, K: 0x00000008}, + {Op: unix.BPF_LD | unix.BPF_B | unix.BPF_ABS, Jt: 0x00, Jf: 0x00, K: 0xfffff00c}, + {Op: unix.BPF_JMP | unix.BPF_JEQ | unix.BPF_K, Jt: 0x02, Jf: 0x00, K: 0x00000000}, + {Op: unix.BPF_MISC | unix.BPF_TAX, Jt: 0x00, Jf: 0x00, K: 0x00000000}, + {Op: unix.BPF_LD | unix.BPF_W | unix.BPF_IND, Jt: 0x00, Jf: 0x00, K: 0x00000004}, + {Op: unix.BPF_MISC | unix.BPF_TAX, Jt: 0x00, Jf: 0x00, K: 0x00000000}, + {Op: unix.BPF_ALU | unix.BPF_AND | unix.BPF_K, Jt: 0x00, Jf: 0x00, K: 0xffffffff}, + {Op: unix.BPF_JMP | unix.BPF_JEQ | unix.BPF_K, Jt: 0x02, Jf: 0x00, K: 0x00000001}, + {Op: unix.BPF_MISC | unix.BPF_TXA, Jt: 0x00, Jf: 0x00, K: 0x00000000}, + {Op: unix.BPF_RET | unix.BPF_K, Jt: 0x00, Jf: 0x00, K: 0x00000000}, + //---- final verdict ---- + {Op: unix.BPF_RET | unix.BPF_K, Jt: 0x00, Jf: 0x00, K: 0xffffffff}, + }}, + {name: "mark positive filter: [10,50,1000]", table: Conntrack, filters: []ConnAttr{ + {Type: AttrMark, Data: mark10ByteValue, Mask: []byte{255, 255, 255, 255}, Negate: false}, + {Type: AttrMark, Data: mark50ByteValue, Mask: []byte{255, 255, 255, 255}, Negate: false}, + {Type: AttrMark, Data: mark1000ByteValue, Mask: []byte{255, 255, 255, 255}, Negate: false}, + }, rawInstr: []bpf.RawInstruction{ + //--- check subsys --- + {Op: unix.BPF_LDX | unix.BPF_IMM, Jt: 0x00, Jf: 0x00, K: 0x00000004}, + {Op: unix.BPF_LD | unix.BPF_B | unix.BPF_IND, Jt: 0x00, Jf: 0x00, K: 0x00000001}, + {Op: unix.BPF_JMP | unix.BPF_JEQ | unix.BPF_K, Jt: 0x01, Jf: 0x00, K: 0x00000001}, + {Op: unix.BPF_RET | unix.BPF_K, Jt: 0x00, Jf: 0x00, K: 0xffffffff}, + //--- check mark --- + {Op: unix.BPF_LD | unix.BPF_IMM, Jt: 0x00, Jf: 0x00, K: 0x00000014}, + {Op: unix.BPF_LDX | unix.BPF_IMM, Jt: 0x00, Jf: 0x00, K: 0x00000008}, + {Op: unix.BPF_LD | unix.BPF_B | unix.BPF_ABS, Jt: 0x00, Jf: 0x00, K: 0xfffff00c}, + {Op: unix.BPF_JMP | unix.BPF_JEQ | unix.BPF_K, Jt: 0x02, Jf: 0x00, K: 0x00000000}, + {Op: unix.BPF_MISC | unix.BPF_TAX, Jt: 0x00, Jf: 0x00, K: 0x00000000}, + {Op: unix.BPF_LD | unix.BPF_W | unix.BPF_IND, Jt: 0x00, Jf: 0x00, K: 0x00000004}, + {Op: unix.BPF_MISC | unix.BPF_TAX, Jt: 0x00, Jf: 0x00, K: 0x00000000}, + {Op: unix.BPF_ALU | unix.BPF_AND | unix.BPF_K, Jt: 0x00, Jf: 0x00, K: 0xffffffff}, + {Op: unix.BPF_JMP | unix.BPF_JEQ | unix.BPF_K, Jt: 0x08, Jf: 0x00, K: 0x0000000a}, + {Op: unix.BPF_MISC | unix.BPF_TXA, Jt: 0x00, Jf: 0x00, K: 0x00000000}, + {Op: unix.BPF_ALU | unix.BPF_AND | unix.BPF_K, Jt: 0x00, Jf: 0x00, K: 0xffffffff}, + {Op: unix.BPF_JMP | unix.BPF_JEQ | unix.BPF_K, Jt: 0x05, Jf: 0x00, K: 0x00000032}, + {Op: unix.BPF_MISC | unix.BPF_TXA, Jt: 0x00, Jf: 0x00, K: 0x00000000}, + {Op: unix.BPF_ALU | unix.BPF_AND | unix.BPF_K, Jt: 0x00, Jf: 0x00, K: 0xffffffff}, + {Op: unix.BPF_JMP | unix.BPF_JEQ | unix.BPF_K, Jt: 0x02, Jf: 0x00, K: 0x000003e8}, + {Op: unix.BPF_MISC | unix.BPF_TXA, Jt: 0x00, Jf: 0x00, K: 0x00000000}, + {Op: unix.BPF_RET | unix.BPF_K, Jt: 0x00, Jf: 0x00, K: 0x00000000}, + //---- final verdict ---- + {Op: unix.BPF_RET | unix.BPF_K, Jt: 0x00, Jf: 0x00, K: 0xffffffff}, + }}, + {name: "mark negative filter: [10,11]", table: Conntrack, filters: []ConnAttr{ + {Type: AttrMark, Data: mark10ByteValue, Mask: []byte{255, 255, 255, 255}, Negate: true}, + {Type: AttrMark, Data: mark11ByteValue, Mask: []byte{255, 255, 255, 255}, Negate: true}, + }, rawInstr: []bpf.RawInstruction{ + //--- check subsys --- + {Op: unix.BPF_LDX | unix.BPF_IMM, Jt: 0x00, Jf: 0x00, K: 0x00000004}, + {Op: unix.BPF_LD | unix.BPF_B | unix.BPF_IND, Jt: 0x00, Jf: 0x00, K: 0x00000001}, + {Op: unix.BPF_JMP | unix.BPF_JEQ | unix.BPF_K, Jt: 0x01, Jf: 0x00, K: 0x00000001}, + {Op: unix.BPF_RET | unix.BPF_K, Jt: 0x00, Jf: 0x00, K: 0xffffffff}, + //--- check mark --- + {Op: unix.BPF_LD | unix.BPF_IMM, Jt: 0x00, Jf: 0x00, K: 0x00000014}, + {Op: unix.BPF_LDX | unix.BPF_IMM, Jt: 0x00, Jf: 0x00, K: 0x00000008}, + {Op: unix.BPF_LD | unix.BPF_B | unix.BPF_ABS, Jt: 0x00, Jf: 0x00, K: 0xfffff00c}, + {Op: unix.BPF_JMP | unix.BPF_JEQ | unix.BPF_K, Jt: 0x02, Jf: 0x00, K: 0x00000000}, + {Op: unix.BPF_MISC | unix.BPF_TAX, Jt: 0x00, Jf: 0x00, K: 0x00000000}, + {Op: unix.BPF_LD | unix.BPF_W | unix.BPF_IND, Jt: 0x00, Jf: 0x00, K: 0x00000004}, + {Op: unix.BPF_MISC | unix.BPF_TAX, Jt: 0x00, Jf: 0x00, K: 0x00000000}, + {Op: unix.BPF_ALU | unix.BPF_AND | unix.BPF_K, Jt: 0x00, Jf: 0x00, K: 0xffffffff}, + {Op: unix.BPF_JMP | unix.BPF_JEQ | unix.BPF_K, Jt: 0x05, Jf: 0x00, K: 0x0000000a}, + {Op: unix.BPF_MISC | unix.BPF_TXA, Jt: 0x00, Jf: 0x00, K: 0x00000000}, + {Op: unix.BPF_ALU | unix.BPF_AND | unix.BPF_K, Jt: 0x00, Jf: 0x00, K: 0xffffffff}, + {Op: unix.BPF_JMP | unix.BPF_JEQ | unix.BPF_K, Jt: 0x02, Jf: 0x00, K: 0x0000000b}, + {Op: unix.BPF_MISC | unix.BPF_TXA, Jt: 0x00, Jf: 0x00, K: 0x00000000}, + {Op: unix.BPF_JMP | unix.BPF_JA, Jt: 0x00, Jf: 0x00, K: 0x00000001}, + {Op: unix.BPF_RET | unix.BPF_K, Jt: 0x00, Jf: 0x00, K: 0x00000000}, + //---- final verdict ---- + {Op: unix.BPF_RET | unix.BPF_K, Jt: 0x00, Jf: 0x00, K: 0xffffffff}, + }}, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + rawInstr, err := constructFilter(tc.table, tc.filters) + if err != tc.err { + t.Fatal(err) + } + if len(rawInstr) != len(tc.rawInstr) { + t.Fatalf("different length:\n- want:\n%s\n- got:\n%s", strings.Join(fmtRawInstructions(tc.rawInstr), ""), strings.Join(fmtRawInstructions(rawInstr), "")) + } + var isErr bool + for i, v := range rawInstr { + if v != tc.rawInstr[i] { + t.Errorf("unexpected instruction:\n- want:\n%s\n- got:\n%s", fmtRawInstruction(i, tc.rawInstr[i]), fmtRawInstruction(i, rawInstr[i])) + isErr = true + } + } + + if isErr { + t.Fatalf("unexpected reply:\n- want:\n%s\n- got:\n%s", strings.Join(fmtRawInstructions(tc.rawInstr), ""), strings.Join(fmtRawInstructions(rawInstr), "")) + } + }) + } +} diff --git a/conntrack.go b/conntrack.go index 990b069..b1fe15f 100644 --- a/conntrack.go +++ b/conntrack.go @@ -367,6 +367,11 @@ func (nfct *Nfct) RegisterFiltered(ctx context.Context, t Table, group NetlinkGr return nfct.register(ctx, t, group, filter, fn) } +// EnableDebug print bpf filter for RegisterFiltered function +func (nfct *Nfct) EnableDebug() { + nfct.debug = true +} + func (nfct *Nfct) register(ctx context.Context, t Table, groups NetlinkGroup, filter []ConnAttr, fn func(c Con) int) error { nfct.ctx, nfct.ctxCancel = context.WithCancel(ctx) nfct.shutdown = make(chan struct{}) diff --git a/types.go b/types.go index 6e42cb0..810febb 100644 --- a/types.go +++ b/types.go @@ -75,6 +75,8 @@ type Nfct struct { errChan chan error + debug bool + setWriteTimeout func() error ctx context.Context From 5525e3f4506237abbcce6a115c510c47e65728e1 Mon Sep 17 00:00:00 2001 From: Martin Dvorak Date: Thu, 23 Nov 2023 13:56:37 +0100 Subject: [PATCH 3/4] updated bpf filter print flow --- bpf.go | 14 +++++++------- bpf_test.go | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/bpf.go b/bpf.go index a1b2145..5abe3a3 100644 --- a/bpf.go +++ b/bpf.go @@ -4,11 +4,9 @@ import ( "encoding/binary" "errors" "fmt" - "sort" - "strings" - "github.com/florianl/go-conntrack/internal/unix" "golang.org/x/net/bpf" + "sort" ) // Various errors which may occur when processing filters @@ -393,7 +391,9 @@ func (nfct *Nfct) attachFilter(subsys Table, filters []ConnAttr) error { } if nfct.debug { fmtInstructions := fmtRawInstructions(bpfFilters) - fmt.Print(strings.Join(fmtInstructions, "")) + fmt.Println("---BPF filter start---") + fmt.Print(fmtInstructions) + fmt.Println("---BPF filter end---") } return nfct.Con.SetBPF(bpfFilters) @@ -413,11 +413,11 @@ func fmtRawInstruction(index int, raw bpf.RawInstruction) string { raw.K&0xFFFFFFFF) } -func fmtRawInstructions(raw []bpf.RawInstruction) []string { - output := make([]string, len(raw)) +func fmtRawInstructions(raw []bpf.RawInstruction) string { + var output string for i, instr := range raw { - output[i] = fmtRawInstruction(i, instr) + output += fmtRawInstruction(i, instr) } return output diff --git a/bpf_test.go b/bpf_test.go index 0df6e12..508b563 100644 --- a/bpf_test.go +++ b/bpf_test.go @@ -2,8 +2,8 @@ package conntrack import ( "encoding/binary" + "errors" "github.com/florianl/go-conntrack/internal/unix" - "strings" "testing" "golang.org/x/net/bpf" @@ -280,11 +280,11 @@ func TestAttrMarkFilter(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { rawInstr, err := constructFilter(tc.table, tc.filters) - if err != tc.err { + if !errors.Is(err, tc.err) { t.Fatal(err) } if len(rawInstr) != len(tc.rawInstr) { - t.Fatalf("different length:\n- want:\n%s\n- got:\n%s", strings.Join(fmtRawInstructions(tc.rawInstr), ""), strings.Join(fmtRawInstructions(rawInstr), "")) + t.Fatalf("different length:\n- want:\n%s\n- got:\n%s", fmtRawInstructions(tc.rawInstr), fmtRawInstructions(rawInstr)) } var isErr bool for i, v := range rawInstr { @@ -295,7 +295,7 @@ func TestAttrMarkFilter(t *testing.T) { } if isErr { - t.Fatalf("unexpected reply:\n- want:\n%s\n- got:\n%s", strings.Join(fmtRawInstructions(tc.rawInstr), ""), strings.Join(fmtRawInstructions(rawInstr), "")) + t.Fatalf("unexpected reply:\n- want:\n%s\n- got:\n%s", fmtRawInstructions(tc.rawInstr), fmtRawInstructions(rawInstr)) } }) } From 60b543d6f87e1921be816c3c1a303bd07690570f Mon Sep 17 00:00:00 2001 From: dvomartin Date: Fri, 24 Nov 2023 17:01:56 +0100 Subject: [PATCH 4/4] use nfct logger Co-authored-by: Florian Lehner --- bpf.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bpf.go b/bpf.go index 5abe3a3..59aef4a 100644 --- a/bpf.go +++ b/bpf.go @@ -391,9 +391,9 @@ func (nfct *Nfct) attachFilter(subsys Table, filters []ConnAttr) error { } if nfct.debug { fmtInstructions := fmtRawInstructions(bpfFilters) - fmt.Println("---BPF filter start---") - fmt.Print(fmtInstructions) - fmt.Println("---BPF filter end---") + nfct.logger.Println("---BPF filter start---") + nfct.logger.Print(fmtInstructions) + nfct.logger.Println("---BPF filter end---") } return nfct.Con.SetBPF(bpfFilters)