From 9b6ae46647bccb8bd609e253089afcabccc5edcf Mon Sep 17 00:00:00 2001 From: ffhan Date: Sun, 28 Mar 2021 23:08:12 +0200 Subject: [PATCH 1/7] check keySize in TableIterator Next method --- bcc/table.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bcc/table.go b/bcc/table.go index 34ae038..462d0fc 100644 --- a/bcc/table.go +++ b/bcc/table.go @@ -299,6 +299,9 @@ func (it *TableIterator) Next() bool { if it.key == nil { keySize := C.bpf_table_key_size_id(it.table.module.p, it.table.id) + if keySize == 0 { + return false + } key := make([]byte, keySize) keyP := unsafe.Pointer(&key[0]) From 23885d43c837ab272618701367d4e3174c2d3166 Mon Sep 17 00:00:00 2001 From: ffhan Date: Mon, 29 Mar 2021 23:24:42 +0200 Subject: [PATCH 2/7] pop from queue --- bcc/table.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/bcc/table.go b/bcc/table.go index 34ae038..fe5f806 100644 --- a/bcc/table.go +++ b/bcc/table.go @@ -270,6 +270,21 @@ func (table *Table) DeleteAll() error { return nil } +func (table *Table) Pop() ([]byte, error) { + fd := C.bpf_table_fd_id(table.module.p, table.id) + + leafSize := C.bpf_table_leaf_size_id(table.module.p, table.id) + leaf := make([]byte, leafSize) + leafP := unsafe.Pointer(&leaf[0]) + + r, err := C.bpf_pop_elem(fd, leafP) + if err != nil { + return nil, err + } + fmt.Printf("r: %v\n", r) + return leaf, nil +} + // TableIterator contains the current position for iteration over a *bcc.Table and provides methods for iteration. type TableIterator struct { table *Table From 7a15e23510dace748218627a40e06e459a6c66cc Mon Sep 17 00:00:00 2001 From: ffhan Date: Mon, 29 Mar 2021 23:33:21 +0200 Subject: [PATCH 3/7] pop_elem fix (reference bpf.h) --- bcc/table.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bcc/table.go b/bcc/table.go index fe5f806..0f6e385 100644 --- a/bcc/table.go +++ b/bcc/table.go @@ -277,7 +277,7 @@ func (table *Table) Pop() ([]byte, error) { leaf := make([]byte, leafSize) leafP := unsafe.Pointer(&leaf[0]) - r, err := C.bpf_pop_elem(fd, leafP) + r, err := C.bpf_map_pop_elem(fd, leafP) if err != nil { return nil, err } From 823c35b585ce34006f5fea2dc9ad06d7d60865dd Mon Sep 17 00:00:00 2001 From: ffhan Date: Sun, 4 Apr 2021 11:15:07 +0200 Subject: [PATCH 4/7] queue stack implementation --- bcc/queuestack.go | 100 ++++++++++++++++++++++++++++++++++++++++++++++ bcc/table.go | 15 ------- 2 files changed, 100 insertions(+), 15 deletions(-) create mode 100644 bcc/queuestack.go diff --git a/bcc/queuestack.go b/bcc/queuestack.go new file mode 100644 index 0000000..e0168b2 --- /dev/null +++ b/bcc/queuestack.go @@ -0,0 +1,100 @@ +package bcc + +/* +#cgo CFLAGS: -I/usr/include/bcc/compat +#cgo LDFLAGS: -lbcc +#include +#include +#include +*/ +import "C" +import ( + "fmt" + "unsafe" +) + +func IsQueueStack(table *Table) bool { + ttype := C.bpf_table_type_id(table.module, table.id) + return ttype == C.BPF_MAP_TYPE_QUEUE || ttype == C.BPF_MAP_TYPE_STACK +} + +type QueueStack struct { + Table +} + +func (queue *QueueStack) Push(leaf []byte, flags int) error { + fd := C.bpf_table_fd_id(queue.Table.module.p, queue.Table.id) + + leafP := unsafe.Pointer(&leaf[0]) + + r, err := C.bpf_update_elem(fd, nil, leafP, flags) + if r != 0 { + leafStr, errL := queue.Table.LeafBytesToStr(leaf) + if errL != nil { + leafStr = fmt.Sprintf("%v", leaf) + } + + return fmt.Errorf("QueueStack.Push: %v: %v", leafStr, err) + } + return nil +} + +func (queue *QueueStack) Pop() ([]byte, error) { + fd := C.bpf_table_fd_id(queue.Table.module.p, queue.Table.id) + + leafSize := C.bpf_table_leaf_size_id(queue.Table.module.p, queue.Table.id) + + leaf := make([]byte, leafSize) + leafP := unsafe.Pointer(&leaf[0]) + + r, err := C.bpf_lookup_and_delete(fd, nil, leafP) + if r != 0 { + return nil, fmt.Errorf("QueueStack.Pop: %v", err) + } + return leaf, nil +} + +func (queue *QueueStack) PopP() (unsafe.Pointer, error) { + fd := C.bpf_table_fd_id(queue.Table.module.p, queue.Table.id) + + leafSize := C.bpf_table_leaf_size_id(queue.Table.module.p, queue.Table.id) + + leaf := make([]byte, leafSize) + leafP := unsafe.Pointer(&leaf[0]) + + r, err := C.bpf_lookup_and_delete(fd, nil, leafP) + if r != 0 { + return nil, fmt.Errorf("QueueStack.PopP: %v", err) + } + return leafP, nil +} + +func (queue *QueueStack) Peek() ([]byte, error) { + fd := C.bpf_table_fd_id(queue.Table.module.p, queue.Table.id) + + leafSize := C.bpf_table_leaf_size_id(queue.Table.module.p, queue.Table.id) + + leaf := make([]byte, leafSize) + leafP := unsafe.Pointer(&leaf[0]) + + r, err := C.bpf_lookup_elem(fd, nil, leafP) + if r != 0 { + return nil, fmt.Errorf("QueueStack.Peek: %v", err) + } + return leaf, nil +} + +func (queue *QueueStack) PeekP() (unsafe.Pointer, error) { + fd := C.bpf_table_fd_id(queue.Table.module.p, queue.Table.id) + + leafSize := C.bpf_table_leaf_size_id(queue.Table.module.p, queue.Table.id) + + leaf := make([]byte, leafSize) + leafP := unsafe.Pointer(&leaf[0]) + + r, err := C.bpf_lookup_elem(fd, nil, leafP) + if r != 0 { + return nil, fmt.Errorf("QueueStack.Peek: %v", err) + } + return leafP, nil +} diff --git a/bcc/table.go b/bcc/table.go index 0f6e385..34ae038 100644 --- a/bcc/table.go +++ b/bcc/table.go @@ -270,21 +270,6 @@ func (table *Table) DeleteAll() error { return nil } -func (table *Table) Pop() ([]byte, error) { - fd := C.bpf_table_fd_id(table.module.p, table.id) - - leafSize := C.bpf_table_leaf_size_id(table.module.p, table.id) - leaf := make([]byte, leafSize) - leafP := unsafe.Pointer(&leaf[0]) - - r, err := C.bpf_map_pop_elem(fd, leafP) - if err != nil { - return nil, err - } - fmt.Printf("r: %v\n", r) - return leaf, nil -} - // TableIterator contains the current position for iteration over a *bcc.Table and provides methods for iteration. type TableIterator struct { table *Table From a99ffeef432880add9dedc81cfd245bcbb923c77 Mon Sep 17 00:00:00 2001 From: ffhan Date: Sun, 4 Apr 2021 11:24:13 +0200 Subject: [PATCH 5/7] queuestack use Table pointer --- bcc/queuestack.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bcc/queuestack.go b/bcc/queuestack.go index e0168b2..861742c 100644 --- a/bcc/queuestack.go +++ b/bcc/queuestack.go @@ -19,7 +19,11 @@ func IsQueueStack(table *Table) bool { } type QueueStack struct { - Table + *Table +} + +func NewQueueStack(table *Table) *QueueStack { + return &QueueStack{Table: table} } func (queue *QueueStack) Push(leaf []byte, flags int) error { From 39f8b477a838c8c19be4768a446e6b5a5f899c87 Mon Sep 17 00:00:00 2001 From: ffhan Date: Sun, 4 Apr 2021 11:29:30 +0200 Subject: [PATCH 6/7] queuestack implementation type bugfixes --- bcc/queuestack.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bcc/queuestack.go b/bcc/queuestack.go index 861742c..f088bf7 100644 --- a/bcc/queuestack.go +++ b/bcc/queuestack.go @@ -14,7 +14,7 @@ import ( ) func IsQueueStack(table *Table) bool { - ttype := C.bpf_table_type_id(table.module, table.id) + ttype := C.bpf_table_type_id(table.module.p, table.id) return ttype == C.BPF_MAP_TYPE_QUEUE || ttype == C.BPF_MAP_TYPE_STACK } @@ -31,7 +31,7 @@ func (queue *QueueStack) Push(leaf []byte, flags int) error { leafP := unsafe.Pointer(&leaf[0]) - r, err := C.bpf_update_elem(fd, nil, leafP, flags) + r, err := C.bpf_update_elem(fd, nil, leafP, C.ulonglong(flags)) if r != 0 { leafStr, errL := queue.Table.LeafBytesToStr(leaf) if errL != nil { From 2163258e3261740f745c84ddbb56b59824f65cf7 Mon Sep 17 00:00:00 2001 From: ffhan Date: Sun, 4 Apr 2021 12:45:55 +0200 Subject: [PATCH 7/7] queuestack documentation --- bcc/queuestack.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/bcc/queuestack.go b/bcc/queuestack.go index f088bf7..44ca2c9 100644 --- a/bcc/queuestack.go +++ b/bcc/queuestack.go @@ -13,19 +13,24 @@ import ( "unsafe" ) +// IsQueueStack determines if Table can be used as QueueStack func IsQueueStack(table *Table) bool { ttype := C.bpf_table_type_id(table.module.p, table.id) return ttype == C.BPF_MAP_TYPE_QUEUE || ttype == C.BPF_MAP_TYPE_STACK } +// QueueStack wraps Table pointer with queue & stack specific methods type QueueStack struct { *Table } +// NewQueueStack creates a QueueStack wrapper func NewQueueStack(table *Table) *QueueStack { return &QueueStack{Table: table} } +// Push pushes a new element to a BPF queue or stack. +// See https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md#28-mappush for flags reference func (queue *QueueStack) Push(leaf []byte, flags int) error { fd := C.bpf_table_fd_id(queue.Table.module.p, queue.Table.id) @@ -43,6 +48,8 @@ func (queue *QueueStack) Push(leaf []byte, flags int) error { return nil } +// Pop pops an element from a BPF queue or stack and returns it as a byte array. +// See https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md#29-mappop for flags reference func (queue *QueueStack) Pop() ([]byte, error) { fd := C.bpf_table_fd_id(queue.Table.module.p, queue.Table.id) @@ -58,6 +65,8 @@ func (queue *QueueStack) Pop() ([]byte, error) { return leaf, nil } +// PopP pops an element from a BPF queue or stack and returns it as a unsafe.Pointer. +// See https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md#29-mappop for flags reference func (queue *QueueStack) PopP() (unsafe.Pointer, error) { fd := C.bpf_table_fd_id(queue.Table.module.p, queue.Table.id) @@ -73,6 +82,7 @@ func (queue *QueueStack) PopP() (unsafe.Pointer, error) { return leafP, nil } +// Peek peeks an element from a BPF queue or stack and returns it as a byte array. func (queue *QueueStack) Peek() ([]byte, error) { fd := C.bpf_table_fd_id(queue.Table.module.p, queue.Table.id) @@ -88,6 +98,7 @@ func (queue *QueueStack) Peek() ([]byte, error) { return leaf, nil } +// PeekP peeks an element from a BPF queue or stack and returns it as an unsafe pointer. func (queue *QueueStack) PeekP() (unsafe.Pointer, error) { fd := C.bpf_table_fd_id(queue.Table.module.p, queue.Table.id)