// 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) Config() map[string]interface{} { mod := table.module.p return map[string]interface{}{ "name": C.GoString(C.bpf_table_name(mod, table.id)), "fd": int(C.bpf_table_fd_id(mod, table.id)), "key_size": uint64(C.bpf_table_key_size_id(mod, table.id)), "leaf_size": uint64(C.bpf_table_leaf_size_id(mod, table.id)), "key_desc": C.GoString(C.bpf_table_key_desc_id(mod, table.id)), "leaf_desc": C.GoString(C.bpf_table_leaf_desc_id(mod, table.id)), } }
func (bpf *BpfModule) TableDesc(id uint64) map[string]interface{} { i := C.size_t(id) return map[string]interface{}{ "name": C.GoString(C.bpf_table_name(bpf.p, i)), "fd": int(C.bpf_table_fd_id(bpf.p, i)), "key_size": uint64(C.bpf_table_key_size_id(bpf.p, i)), "leaf_size": uint64(C.bpf_table_leaf_size_id(bpf.p, i)), "key_desc": C.GoString(C.bpf_table_key_desc_id(bpf.p, i)), "leaf_desc": C.GoString(C.bpf_table_leaf_desc_id(bpf.p, i)), } }
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 }
func (table *BpfTable) Delete(keyX interface{}) error { fd := C.bpf_table_fd_id(table.module.p, table.id) key, err := table.keyToBytes(keyX) if err != nil { return err } keyP := unsafe.Pointer(&key[0]) r := C.bpf_delete_elem(fd, keyP) if r != 0 { return fmt.Errorf("BpfTable.Delete: unable to delete element") } return nil }
func (table *BpfTable) Set(keyX, leafX interface{}) error { fd := C.bpf_table_fd_id(table.module.p, table.id) key, err := table.keyToBytes(keyX) if err != nil { return err } leaf, err := table.leafToBytes(leafX) if err != nil { return err } keyP := unsafe.Pointer(&key[0]) leafP := unsafe.Pointer(&leaf[0]) r := C.bpf_update_elem(fd, keyP, leafP, 0) if r != 0 { return fmt.Errorf("BpfTable.Set: unable to update element") } return nil }
func (table *BpfTable) Set(keyStr, leafStr string) error { if table == nil || table.module.p == nil { panic("table is nil") } fd := C.bpf_table_fd_id(table.module.p, table.id) key, err := table.keyToBytes(keyStr) if err != nil { return err } leaf, err := table.leafToBytes(leafStr) if err != nil { return err } keyP := unsafe.Pointer(&key[0]) leafP := unsafe.Pointer(&leaf[0]) r, err := C.bpf_update_elem(fd, keyP, leafP, 0) if r != 0 { return fmt.Errorf("BpfTable.Set: unable to update element (%s=%s): %s", keyStr, leafStr, err) } return nil }