github.com/dylandreimerink/gobpfld@v0.6.1-0.20220205171531-e79c330ad608/map_hash.go (about) 1 package gobpfld 2 3 import ( 4 "fmt" 5 6 "github.com/dylandreimerink/gobpfld/bpfsys" 7 "github.com/dylandreimerink/gobpfld/kernelsupport" 8 ) 9 10 var _ BPFMap = (*HashMap)(nil) 11 12 // HashMap is a generic map type, both the key and value may be of any type. The value of the key is hashed so values 13 // do not need to be contiguous. 14 type HashMap struct { 15 AbstractMap 16 } 17 18 func (m *HashMap) Load() error { 19 // NOTE: do not enforce definition type of map since hash map is currently still a catch all map type 20 err := m.load(nil) 21 if err != nil { 22 return err 23 } 24 25 err = mapRegister.add(m) 26 if err != nil { 27 return fmt.Errorf("map register: %w", err) 28 } 29 30 return nil 31 } 32 33 // Close closes the file descriptor associate with the map, this will cause the map to unload from the kernel 34 // if it is not still in use by a eBPF program, bpf FS, or a userspace program still holding a fd to the map. 35 func (m *HashMap) Close() error { 36 err := mapRegister.delete(m) 37 if err != nil { 38 return fmt.Errorf("map register: %w", err) 39 } 40 41 return m.close() 42 } 43 44 func (m *HashMap) Get(key interface{}, value interface{}) error { 45 return m.get(key, value) 46 } 47 48 // GetBatch fills the keys and values array/slice with the keys and values inside the map up to a maximum of 49 // maxBatchSize entries. The keys and values array/slice must have at least a length of maxBatchSize. 50 // The key and value of an entry is has the same index, so for example the value for keys[2] is in values[2]. 51 // Count is the amount of entries returns, partial is true if not all elements of keys and values could be set. 52 // 53 // This function is intended for small maps which can be read into userspace all at once since 54 // GetBatch can only read from the beginning of the map. If the map is to large to read all at once 55 // a iterator should be used instead of the Get or GetBatch function. 56 func (m *HashMap) GetBatch( 57 keys interface{}, 58 values interface{}, 59 maxBatchSize uint32, 60 ) ( 61 count int, 62 partial bool, 63 err error, 64 ) { 65 return m.getBatch(keys, values, maxBatchSize) 66 } 67 68 func (m *HashMap) Set(key interface{}, value interface{}, flags bpfsys.BPFAttrMapElemFlags) error { 69 return m.set(key, value, flags) 70 } 71 72 func (m *HashMap) SetBatch( 73 keys interface{}, 74 values interface{}, 75 flags bpfsys.BPFAttrMapElemFlags, 76 maxBatchSize uint32, 77 ) ( 78 count int, 79 err error, 80 ) { 81 return m.setBatch(keys, values, flags, maxBatchSize) 82 } 83 84 func (m *HashMap) Delete(key interface{}) error { 85 return m.delete(key) 86 } 87 88 func (m *HashMap) DeleteBatch( 89 keys interface{}, 90 maxBatchSize uint32, 91 ) ( 92 count int, 93 err error, 94 ) { 95 return m.deleteBatch(keys, maxBatchSize) 96 } 97 98 func (m *HashMap) GetAndDelete(key interface{}, value interface{}) error { 99 return m.getAndDelete(key, value) 100 } 101 102 func (m *HashMap) GetAndDeleteBatch( 103 keys interface{}, 104 values interface{}, 105 maxBatchSize uint32, 106 ) ( 107 count int, 108 err error, 109 ) { 110 return m.getAndDeleteBatch(keys, values, maxBatchSize) 111 } 112 113 func (m *HashMap) Iterator() MapIterator { 114 // If the kernel doesn't have support for batch lookup, use single lookup 115 if !kernelsupport.CurrentFeatures.API.Has(kernelsupport.KFeatAPIMapBatchOps) { 116 return &singleLookupIterator{ 117 BPFMap: m, 118 } 119 } 120 121 // TODO change batch lookup iterator to support per-cpu values 122 if m.isPerCPUMap() { 123 return &singleLookupIterator{ 124 BPFMap: m, 125 } 126 } 127 128 // If there is no reason not to use the batch lookup iterator, use it 129 return &batchLookupIterator{ 130 BPFMap: m, 131 } 132 }