// Get takes a key and returns the value or nil, and an 'ok' style indicator func (table *BpfTable) Get(keyX interface{}) (interface{}, bool) { mod := table.module.p fd := C.bpf_table_fd_id(mod, table.id) leaf_size := C.bpf_table_leaf_size_id(mod, table.id) key, err := table.keyToBytes(keyX) if err != nil { return nil, false } leaf := make([]byte, leaf_size) keyP := unsafe.Pointer(&key[0]) leafP := unsafe.Pointer(&leaf[0]) r := C.bpf_lookup_elem(fd, keyP, leafP) if r != 0 { return nil, false } leafStr := make([]byte, leaf_size*8) leafStrP := (*C.char)(unsafe.Pointer(&leafStr[0])) r = C.bpf_table_leaf_snprintf(mod, table.id, leafStrP, C.size_t(len(leafStr)), leafP) if r != 0 { return nil, false } return AdapterTablePair{ Key: keyX, Value: string(leafStr[:bytes.IndexByte(leafStr, 0)]), }, true return nil, false }
func (table *BpfTable) leafToString(leaf []byte) string { leaf_size := C.bpf_table_leaf_size_id(table.module.p, table.id) leafP := unsafe.Pointer(&leaf[0]) leafStr := make([]byte, leaf_size*8) leafStrP := (*C.char)(unsafe.Pointer(&leafStr[0])) r := C.bpf_table_leaf_snprintf(table.module.p, table.id, leafStrP, C.size_t(len(leafStr)), leafP) if r == 0 { return string(leafStr) } return "" }
func (table *BpfTable) Iter() <-chan AdapterTablePair { mod := table.module.p ch := make(chan AdapterTablePair, 128) go func() { defer close(ch) fd := C.bpf_table_fd_id(mod, table.id) key_size := C.bpf_table_key_size_id(mod, table.id) leaf_size := C.bpf_table_leaf_size_id(mod, table.id) key := make([]byte, key_size) leaf := make([]byte, leaf_size) keyP := unsafe.Pointer(&key[0]) leafP := unsafe.Pointer(&leaf[0]) alternateKeys := []byte{0xff, 0x55} res := C.bpf_lookup_elem(fd, keyP, leafP) // make sure the start iterator is an invalid key for i := 0; i <= len(alternateKeys); i++ { if res < 0 { break } for j := range key { key[j] = alternateKeys[i] } res = C.bpf_lookup_elem(fd, keyP, leafP) } if res == 0 { Info.Println("BpfTable.Iter: No valid initial key found") return } keyStr := make([]byte, key_size*8) leafStr := make([]byte, leaf_size*8) keyStrP := (*C.char)(unsafe.Pointer(&keyStr[0])) leafStrP := (*C.char)(unsafe.Pointer(&leafStr[0])) for res = C.bpf_get_next_key(fd, keyP, keyP); res == 0; res = C.bpf_get_next_key(fd, keyP, keyP) { r := C.bpf_lookup_elem(fd, keyP, leafP) if r != 0 { continue } r = C.bpf_table_key_snprintf(mod, table.id, keyStrP, C.size_t(len(keyStr)), keyP) if r != 0 { break } r = C.bpf_table_leaf_snprintf(mod, table.id, leafStrP, C.size_t(len(leafStr)), leafP) if r != 0 { break } ch <- AdapterTablePair{ Key: string(keyStr[:bytes.IndexByte(keyStr, 0)]), Value: string(leafStr[:bytes.IndexByte(leafStr, 0)]), } } }() return ch }