map.go 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424
  1. package ebpf
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "io"
  7. "math/rand"
  8. "path/filepath"
  9. "reflect"
  10. "time"
  11. "unsafe"
  12. "github.com/cilium/ebpf/btf"
  13. "github.com/cilium/ebpf/internal"
  14. "github.com/cilium/ebpf/internal/sys"
  15. "github.com/cilium/ebpf/internal/unix"
  16. )
  17. // Errors returned by Map and MapIterator methods.
  18. var (
  19. ErrKeyNotExist = errors.New("key does not exist")
  20. ErrKeyExist = errors.New("key already exists")
  21. ErrIterationAborted = errors.New("iteration aborted")
  22. ErrMapIncompatible = errors.New("map spec is incompatible with existing map")
  23. errMapNoBTFValue = errors.New("map spec does not contain a BTF Value")
  24. )
  25. // MapOptions control loading a map into the kernel.
  26. type MapOptions struct {
  27. // The base path to pin maps in if requested via PinByName.
  28. // Existing maps will be re-used if they are compatible, otherwise an
  29. // error is returned.
  30. PinPath string
  31. LoadPinOptions LoadPinOptions
  32. }
  33. // MapID represents the unique ID of an eBPF map
  34. type MapID uint32
  35. // MapSpec defines a Map.
  36. type MapSpec struct {
  37. // Name is passed to the kernel as a debug aid. Must only contain
  38. // alpha numeric and '_' characters.
  39. Name string
  40. Type MapType
  41. KeySize uint32
  42. ValueSize uint32
  43. MaxEntries uint32
  44. // Flags is passed to the kernel and specifies additional map
  45. // creation attributes.
  46. Flags uint32
  47. // Automatically pin and load a map from MapOptions.PinPath.
  48. // Generates an error if an existing pinned map is incompatible with the MapSpec.
  49. Pinning PinType
  50. // Specify numa node during map creation
  51. // (effective only if unix.BPF_F_NUMA_NODE flag is set,
  52. // which can be imported from golang.org/x/sys/unix)
  53. NumaNode uint32
  54. // The initial contents of the map. May be nil.
  55. Contents []MapKV
  56. // Whether to freeze a map after setting its initial contents.
  57. Freeze bool
  58. // InnerMap is used as a template for ArrayOfMaps and HashOfMaps
  59. InnerMap *MapSpec
  60. // Extra trailing bytes found in the ELF map definition when using structs
  61. // larger than libbpf's bpf_map_def. nil if no trailing bytes were present.
  62. // Must be nil or empty before instantiating the MapSpec into a Map.
  63. Extra *bytes.Reader
  64. // The key and value type of this map. May be nil.
  65. Key, Value btf.Type
  66. // The BTF associated with this map.
  67. BTF *btf.Spec
  68. }
  69. func (ms *MapSpec) String() string {
  70. return fmt.Sprintf("%s(keySize=%d, valueSize=%d, maxEntries=%d, flags=%d)", ms.Type, ms.KeySize, ms.ValueSize, ms.MaxEntries, ms.Flags)
  71. }
  72. // Copy returns a copy of the spec.
  73. //
  74. // MapSpec.Contents is a shallow copy.
  75. func (ms *MapSpec) Copy() *MapSpec {
  76. if ms == nil {
  77. return nil
  78. }
  79. cpy := *ms
  80. cpy.Contents = make([]MapKV, len(ms.Contents))
  81. copy(cpy.Contents, ms.Contents)
  82. cpy.InnerMap = ms.InnerMap.Copy()
  83. return &cpy
  84. }
  85. // hasBTF returns true if the MapSpec has a valid BTF spec and if its
  86. // map type supports associated BTF metadata in the kernel.
  87. func (ms *MapSpec) hasBTF() bool {
  88. return ms.BTF != nil && ms.Type.hasBTF()
  89. }
  90. func (ms *MapSpec) clampPerfEventArraySize() error {
  91. if ms.Type != PerfEventArray {
  92. return nil
  93. }
  94. n, err := internal.PossibleCPUs()
  95. if err != nil {
  96. return fmt.Errorf("perf event array: %w", err)
  97. }
  98. if n := uint32(n); ms.MaxEntries > n {
  99. ms.MaxEntries = n
  100. }
  101. return nil
  102. }
  103. // dataSection returns the contents and BTF Datasec descriptor of the spec.
  104. func (ms *MapSpec) dataSection() ([]byte, *btf.Datasec, error) {
  105. if ms.Value == nil {
  106. return nil, nil, errMapNoBTFValue
  107. }
  108. ds, ok := ms.Value.(*btf.Datasec)
  109. if !ok {
  110. return nil, nil, fmt.Errorf("map value BTF is a %T, not a *btf.Datasec", ms.Value)
  111. }
  112. if n := len(ms.Contents); n != 1 {
  113. return nil, nil, fmt.Errorf("expected one key, found %d", n)
  114. }
  115. kv := ms.Contents[0]
  116. value, ok := kv.Value.([]byte)
  117. if !ok {
  118. return nil, nil, fmt.Errorf("value at first map key is %T, not []byte", kv.Value)
  119. }
  120. return value, ds, nil
  121. }
  122. // MapKV is used to initialize the contents of a Map.
  123. type MapKV struct {
  124. Key interface{}
  125. Value interface{}
  126. }
  127. func (ms *MapSpec) checkCompatibility(m *Map) error {
  128. switch {
  129. case m.typ != ms.Type:
  130. return fmt.Errorf("expected type %v, got %v: %w", ms.Type, m.typ, ErrMapIncompatible)
  131. case m.keySize != ms.KeySize:
  132. return fmt.Errorf("expected key size %v, got %v: %w", ms.KeySize, m.keySize, ErrMapIncompatible)
  133. case m.valueSize != ms.ValueSize:
  134. return fmt.Errorf("expected value size %v, got %v: %w", ms.ValueSize, m.valueSize, ErrMapIncompatible)
  135. case !(ms.Type == PerfEventArray && ms.MaxEntries == 0) &&
  136. m.maxEntries != ms.MaxEntries:
  137. return fmt.Errorf("expected max entries %v, got %v: %w", ms.MaxEntries, m.maxEntries, ErrMapIncompatible)
  138. case m.flags != ms.Flags:
  139. return fmt.Errorf("expected flags %v, got %v: %w", ms.Flags, m.flags, ErrMapIncompatible)
  140. }
  141. return nil
  142. }
  143. // Map represents a Map file descriptor.
  144. //
  145. // It is not safe to close a map which is used by other goroutines.
  146. //
  147. // Methods which take interface{} arguments by default encode
  148. // them using binary.Read/Write in the machine's native endianness.
  149. //
  150. // Implement encoding.BinaryMarshaler or encoding.BinaryUnmarshaler
  151. // if you require custom encoding.
  152. type Map struct {
  153. name string
  154. fd *sys.FD
  155. typ MapType
  156. keySize uint32
  157. valueSize uint32
  158. maxEntries uint32
  159. flags uint32
  160. pinnedPath string
  161. // Per CPU maps return values larger than the size in the spec
  162. fullValueSize int
  163. }
  164. // NewMapFromFD creates a map from a raw fd.
  165. //
  166. // You should not use fd after calling this function.
  167. func NewMapFromFD(fd int) (*Map, error) {
  168. f, err := sys.NewFD(fd)
  169. if err != nil {
  170. return nil, err
  171. }
  172. return newMapFromFD(f)
  173. }
  174. func newMapFromFD(fd *sys.FD) (*Map, error) {
  175. info, err := newMapInfoFromFd(fd)
  176. if err != nil {
  177. fd.Close()
  178. return nil, fmt.Errorf("get map info: %w", err)
  179. }
  180. return newMap(fd, info.Name, info.Type, info.KeySize, info.ValueSize, info.MaxEntries, info.Flags)
  181. }
  182. // NewMap creates a new Map.
  183. //
  184. // It's equivalent to calling NewMapWithOptions with default options.
  185. func NewMap(spec *MapSpec) (*Map, error) {
  186. return NewMapWithOptions(spec, MapOptions{})
  187. }
  188. // NewMapWithOptions creates a new Map.
  189. //
  190. // Creating a map for the first time will perform feature detection
  191. // by creating small, temporary maps.
  192. //
  193. // The caller is responsible for ensuring the process' rlimit is set
  194. // sufficiently high for locking memory during map creation. This can be done
  195. // by calling rlimit.RemoveMemlock() prior to calling NewMapWithOptions.
  196. //
  197. // May return an error wrapping ErrMapIncompatible.
  198. func NewMapWithOptions(spec *MapSpec, opts MapOptions) (*Map, error) {
  199. handles := newHandleCache()
  200. defer handles.close()
  201. m, err := newMapWithOptions(spec, opts, handles)
  202. if err != nil {
  203. return nil, fmt.Errorf("creating map: %w", err)
  204. }
  205. if err := m.finalize(spec); err != nil {
  206. m.Close()
  207. return nil, fmt.Errorf("populating map: %w", err)
  208. }
  209. return m, nil
  210. }
  211. func newMapWithOptions(spec *MapSpec, opts MapOptions, handles *handleCache) (_ *Map, err error) {
  212. closeOnError := func(c io.Closer) {
  213. if err != nil {
  214. c.Close()
  215. }
  216. }
  217. switch spec.Pinning {
  218. case PinByName:
  219. if spec.Name == "" {
  220. return nil, fmt.Errorf("pin by name: missing Name")
  221. }
  222. if opts.PinPath == "" {
  223. return nil, fmt.Errorf("pin by name: missing MapOptions.PinPath")
  224. }
  225. path := filepath.Join(opts.PinPath, spec.Name)
  226. m, err := LoadPinnedMap(path, &opts.LoadPinOptions)
  227. if errors.Is(err, unix.ENOENT) {
  228. break
  229. }
  230. if err != nil {
  231. return nil, fmt.Errorf("load pinned map: %w", err)
  232. }
  233. defer closeOnError(m)
  234. if err := spec.checkCompatibility(m); err != nil {
  235. return nil, fmt.Errorf("use pinned map %s: %w", spec.Name, err)
  236. }
  237. return m, nil
  238. case PinNone:
  239. // Nothing to do here
  240. default:
  241. return nil, fmt.Errorf("pin type %d: %w", int(spec.Pinning), ErrNotSupported)
  242. }
  243. var innerFd *sys.FD
  244. if spec.Type == ArrayOfMaps || spec.Type == HashOfMaps {
  245. if spec.InnerMap == nil {
  246. return nil, fmt.Errorf("%s requires InnerMap", spec.Type)
  247. }
  248. if spec.InnerMap.Pinning != PinNone {
  249. return nil, errors.New("inner maps cannot be pinned")
  250. }
  251. template, err := spec.InnerMap.createMap(nil, opts, handles)
  252. if err != nil {
  253. return nil, fmt.Errorf("inner map: %w", err)
  254. }
  255. defer template.Close()
  256. // Intentionally skip populating and freezing (finalizing)
  257. // the inner map template since it will be removed shortly.
  258. innerFd = template.fd
  259. }
  260. m, err := spec.createMap(innerFd, opts, handles)
  261. if err != nil {
  262. return nil, err
  263. }
  264. defer closeOnError(m)
  265. if spec.Pinning == PinByName {
  266. path := filepath.Join(opts.PinPath, spec.Name)
  267. if err := m.Pin(path); err != nil {
  268. return nil, fmt.Errorf("pin map: %w", err)
  269. }
  270. }
  271. return m, nil
  272. }
  273. // createMap validates the spec's properties and creates the map in the kernel
  274. // using the given opts. It does not populate or freeze the map.
  275. func (spec *MapSpec) createMap(inner *sys.FD, opts MapOptions, handles *handleCache) (_ *Map, err error) {
  276. closeOnError := func(closer io.Closer) {
  277. if err != nil {
  278. closer.Close()
  279. }
  280. }
  281. spec = spec.Copy()
  282. // Kernels 4.13 through 5.4 used a struct bpf_map_def that contained
  283. // additional 'inner_map_idx' and later 'numa_node' fields.
  284. // In order to support loading these definitions, tolerate the presence of
  285. // extra bytes, but require them to be zeroes.
  286. if spec.Extra != nil {
  287. if _, err := io.Copy(internal.DiscardZeroes{}, spec.Extra); err != nil {
  288. return nil, errors.New("extra contains unhandled non-zero bytes, drain before creating map")
  289. }
  290. }
  291. switch spec.Type {
  292. case ArrayOfMaps, HashOfMaps:
  293. if err := haveNestedMaps(); err != nil {
  294. return nil, err
  295. }
  296. if spec.ValueSize != 0 && spec.ValueSize != 4 {
  297. return nil, errors.New("ValueSize must be zero or four for map of map")
  298. }
  299. spec.ValueSize = 4
  300. case PerfEventArray:
  301. if spec.KeySize != 0 && spec.KeySize != 4 {
  302. return nil, errors.New("KeySize must be zero or four for perf event array")
  303. }
  304. spec.KeySize = 4
  305. if spec.ValueSize != 0 && spec.ValueSize != 4 {
  306. return nil, errors.New("ValueSize must be zero or four for perf event array")
  307. }
  308. spec.ValueSize = 4
  309. if spec.MaxEntries == 0 {
  310. n, err := internal.PossibleCPUs()
  311. if err != nil {
  312. return nil, fmt.Errorf("perf event array: %w", err)
  313. }
  314. spec.MaxEntries = uint32(n)
  315. }
  316. }
  317. if spec.Flags&(unix.BPF_F_RDONLY_PROG|unix.BPF_F_WRONLY_PROG) > 0 || spec.Freeze {
  318. if err := haveMapMutabilityModifiers(); err != nil {
  319. return nil, fmt.Errorf("map create: %w", err)
  320. }
  321. }
  322. if spec.Flags&unix.BPF_F_MMAPABLE > 0 {
  323. if err := haveMmapableMaps(); err != nil {
  324. return nil, fmt.Errorf("map create: %w", err)
  325. }
  326. }
  327. if spec.Flags&unix.BPF_F_INNER_MAP > 0 {
  328. if err := haveInnerMaps(); err != nil {
  329. return nil, fmt.Errorf("map create: %w", err)
  330. }
  331. }
  332. if spec.Flags&unix.BPF_F_NO_PREALLOC > 0 {
  333. if err := haveNoPreallocMaps(); err != nil {
  334. return nil, fmt.Errorf("map create: %w", err)
  335. }
  336. }
  337. attr := sys.MapCreateAttr{
  338. MapType: sys.MapType(spec.Type),
  339. KeySize: spec.KeySize,
  340. ValueSize: spec.ValueSize,
  341. MaxEntries: spec.MaxEntries,
  342. MapFlags: spec.Flags,
  343. NumaNode: spec.NumaNode,
  344. }
  345. if inner != nil {
  346. attr.InnerMapFd = inner.Uint()
  347. }
  348. if haveObjName() == nil {
  349. attr.MapName = sys.NewObjName(spec.Name)
  350. }
  351. if spec.hasBTF() {
  352. handle, err := handles.btfHandle(spec.BTF)
  353. if err != nil && !errors.Is(err, btf.ErrNotSupported) {
  354. return nil, fmt.Errorf("load BTF: %w", err)
  355. }
  356. if handle != nil {
  357. keyTypeID, err := spec.BTF.TypeID(spec.Key)
  358. if err != nil {
  359. return nil, err
  360. }
  361. valueTypeID, err := spec.BTF.TypeID(spec.Value)
  362. if err != nil {
  363. return nil, err
  364. }
  365. attr.BtfFd = uint32(handle.FD())
  366. attr.BtfKeyTypeId = uint32(keyTypeID)
  367. attr.BtfValueTypeId = uint32(valueTypeID)
  368. }
  369. }
  370. fd, err := sys.MapCreate(&attr)
  371. if err != nil {
  372. if errors.Is(err, unix.EPERM) {
  373. return nil, fmt.Errorf("map create: %w (MEMLOCK may be too low, consider rlimit.RemoveMemlock)", err)
  374. }
  375. if !spec.hasBTF() {
  376. return nil, fmt.Errorf("map create without BTF: %w", err)
  377. }
  378. if errors.Is(err, unix.EINVAL) && attr.MaxEntries == 0 {
  379. return nil, fmt.Errorf("map create: %w (MaxEntries may be incorrectly set to zero)", err)
  380. }
  381. return nil, fmt.Errorf("map create: %w", err)
  382. }
  383. defer closeOnError(fd)
  384. m, err := newMap(fd, spec.Name, spec.Type, spec.KeySize, spec.ValueSize, spec.MaxEntries, spec.Flags)
  385. if err != nil {
  386. return nil, fmt.Errorf("map create: %w", err)
  387. }
  388. return m, nil
  389. }
  390. // newMap allocates and returns a new Map structure.
  391. // Sets the fullValueSize on per-CPU maps.
  392. func newMap(fd *sys.FD, name string, typ MapType, keySize, valueSize, maxEntries, flags uint32) (*Map, error) {
  393. m := &Map{
  394. name,
  395. fd,
  396. typ,
  397. keySize,
  398. valueSize,
  399. maxEntries,
  400. flags,
  401. "",
  402. int(valueSize),
  403. }
  404. if !typ.hasPerCPUValue() {
  405. return m, nil
  406. }
  407. possibleCPUs, err := internal.PossibleCPUs()
  408. if err != nil {
  409. return nil, err
  410. }
  411. m.fullValueSize = internal.Align(int(valueSize), 8) * possibleCPUs
  412. return m, nil
  413. }
  414. func (m *Map) String() string {
  415. if m.name != "" {
  416. return fmt.Sprintf("%s(%s)#%v", m.typ, m.name, m.fd)
  417. }
  418. return fmt.Sprintf("%s#%v", m.typ, m.fd)
  419. }
  420. // Type returns the underlying type of the map.
  421. func (m *Map) Type() MapType {
  422. return m.typ
  423. }
  424. // KeySize returns the size of the map key in bytes.
  425. func (m *Map) KeySize() uint32 {
  426. return m.keySize
  427. }
  428. // ValueSize returns the size of the map value in bytes.
  429. func (m *Map) ValueSize() uint32 {
  430. return m.valueSize
  431. }
  432. // MaxEntries returns the maximum number of elements the map can hold.
  433. func (m *Map) MaxEntries() uint32 {
  434. return m.maxEntries
  435. }
  436. // Flags returns the flags of the map.
  437. func (m *Map) Flags() uint32 {
  438. return m.flags
  439. }
  440. // Info returns metadata about the map.
  441. func (m *Map) Info() (*MapInfo, error) {
  442. return newMapInfoFromFd(m.fd)
  443. }
  444. // MapLookupFlags controls the behaviour of the map lookup calls.
  445. type MapLookupFlags uint64
  446. // LookupLock look up the value of a spin-locked map.
  447. const LookupLock MapLookupFlags = 4
  448. // Lookup retrieves a value from a Map.
  449. //
  450. // Calls Close() on valueOut if it is of type **Map or **Program,
  451. // and *valueOut is not nil.
  452. //
  453. // Returns an error if the key doesn't exist, see ErrKeyNotExist.
  454. func (m *Map) Lookup(key, valueOut interface{}) error {
  455. valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize)
  456. if err := m.lookup(key, valuePtr, 0); err != nil {
  457. return err
  458. }
  459. return m.unmarshalValue(valueOut, valueBytes)
  460. }
  461. // LookupWithFlags retrieves a value from a Map with flags.
  462. //
  463. // Passing LookupLock flag will look up the value of a spin-locked
  464. // map without returning the lock. This must be specified if the
  465. // elements contain a spinlock.
  466. //
  467. // Calls Close() on valueOut if it is of type **Map or **Program,
  468. // and *valueOut is not nil.
  469. //
  470. // Returns an error if the key doesn't exist, see ErrKeyNotExist.
  471. func (m *Map) LookupWithFlags(key, valueOut interface{}, flags MapLookupFlags) error {
  472. valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize)
  473. if err := m.lookup(key, valuePtr, flags); err != nil {
  474. return err
  475. }
  476. return m.unmarshalValue(valueOut, valueBytes)
  477. }
  478. // LookupAndDelete retrieves and deletes a value from a Map.
  479. //
  480. // Returns ErrKeyNotExist if the key doesn't exist.
  481. func (m *Map) LookupAndDelete(key, valueOut interface{}) error {
  482. return m.lookupAndDelete(key, valueOut, 0)
  483. }
  484. // LookupAndDeleteWithFlags retrieves and deletes a value from a Map.
  485. //
  486. // Passing LookupLock flag will look up and delete the value of a spin-locked
  487. // map without returning the lock. This must be specified if the elements
  488. // contain a spinlock.
  489. //
  490. // Returns ErrKeyNotExist if the key doesn't exist.
  491. func (m *Map) LookupAndDeleteWithFlags(key, valueOut interface{}, flags MapLookupFlags) error {
  492. return m.lookupAndDelete(key, valueOut, flags)
  493. }
  494. // LookupBytes gets a value from Map.
  495. //
  496. // Returns a nil value if a key doesn't exist.
  497. func (m *Map) LookupBytes(key interface{}) ([]byte, error) {
  498. valueBytes := make([]byte, m.fullValueSize)
  499. valuePtr := sys.NewSlicePointer(valueBytes)
  500. err := m.lookup(key, valuePtr, 0)
  501. if errors.Is(err, ErrKeyNotExist) {
  502. return nil, nil
  503. }
  504. return valueBytes, err
  505. }
  506. func (m *Map) lookup(key interface{}, valueOut sys.Pointer, flags MapLookupFlags) error {
  507. keyPtr, err := m.marshalKey(key)
  508. if err != nil {
  509. return fmt.Errorf("can't marshal key: %w", err)
  510. }
  511. attr := sys.MapLookupElemAttr{
  512. MapFd: m.fd.Uint(),
  513. Key: keyPtr,
  514. Value: valueOut,
  515. Flags: uint64(flags),
  516. }
  517. if err = sys.MapLookupElem(&attr); err != nil {
  518. return fmt.Errorf("lookup: %w", wrapMapError(err))
  519. }
  520. return nil
  521. }
  522. func (m *Map) lookupAndDelete(key, valueOut interface{}, flags MapLookupFlags) error {
  523. valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize)
  524. keyPtr, err := m.marshalKey(key)
  525. if err != nil {
  526. return fmt.Errorf("can't marshal key: %w", err)
  527. }
  528. attr := sys.MapLookupAndDeleteElemAttr{
  529. MapFd: m.fd.Uint(),
  530. Key: keyPtr,
  531. Value: valuePtr,
  532. Flags: uint64(flags),
  533. }
  534. if err := sys.MapLookupAndDeleteElem(&attr); err != nil {
  535. return fmt.Errorf("lookup and delete: %w", wrapMapError(err))
  536. }
  537. return m.unmarshalValue(valueOut, valueBytes)
  538. }
  539. // MapUpdateFlags controls the behaviour of the Map.Update call.
  540. //
  541. // The exact semantics depend on the specific MapType.
  542. type MapUpdateFlags uint64
  543. const (
  544. // UpdateAny creates a new element or update an existing one.
  545. UpdateAny MapUpdateFlags = iota
  546. // UpdateNoExist creates a new element.
  547. UpdateNoExist MapUpdateFlags = 1 << (iota - 1)
  548. // UpdateExist updates an existing element.
  549. UpdateExist
  550. // UpdateLock updates elements under bpf_spin_lock.
  551. UpdateLock
  552. )
  553. // Put replaces or creates a value in map.
  554. //
  555. // It is equivalent to calling Update with UpdateAny.
  556. func (m *Map) Put(key, value interface{}) error {
  557. return m.Update(key, value, UpdateAny)
  558. }
  559. // Update changes the value of a key.
  560. func (m *Map) Update(key, value interface{}, flags MapUpdateFlags) error {
  561. keyPtr, err := m.marshalKey(key)
  562. if err != nil {
  563. return fmt.Errorf("can't marshal key: %w", err)
  564. }
  565. valuePtr, err := m.marshalValue(value)
  566. if err != nil {
  567. return fmt.Errorf("can't marshal value: %w", err)
  568. }
  569. attr := sys.MapUpdateElemAttr{
  570. MapFd: m.fd.Uint(),
  571. Key: keyPtr,
  572. Value: valuePtr,
  573. Flags: uint64(flags),
  574. }
  575. if err = sys.MapUpdateElem(&attr); err != nil {
  576. return fmt.Errorf("update: %w", wrapMapError(err))
  577. }
  578. return nil
  579. }
  580. // Delete removes a value.
  581. //
  582. // Returns ErrKeyNotExist if the key does not exist.
  583. func (m *Map) Delete(key interface{}) error {
  584. keyPtr, err := m.marshalKey(key)
  585. if err != nil {
  586. return fmt.Errorf("can't marshal key: %w", err)
  587. }
  588. attr := sys.MapDeleteElemAttr{
  589. MapFd: m.fd.Uint(),
  590. Key: keyPtr,
  591. }
  592. if err = sys.MapDeleteElem(&attr); err != nil {
  593. return fmt.Errorf("delete: %w", wrapMapError(err))
  594. }
  595. return nil
  596. }
  597. // NextKey finds the key following an initial key.
  598. //
  599. // See NextKeyBytes for details.
  600. //
  601. // Returns ErrKeyNotExist if there is no next key.
  602. func (m *Map) NextKey(key, nextKeyOut interface{}) error {
  603. nextKeyPtr, nextKeyBytes := makeBuffer(nextKeyOut, int(m.keySize))
  604. if err := m.nextKey(key, nextKeyPtr); err != nil {
  605. return err
  606. }
  607. if err := m.unmarshalKey(nextKeyOut, nextKeyBytes); err != nil {
  608. return fmt.Errorf("can't unmarshal next key: %w", err)
  609. }
  610. return nil
  611. }
  612. // NextKeyBytes returns the key following an initial key as a byte slice.
  613. //
  614. // Passing nil will return the first key.
  615. //
  616. // Use Iterate if you want to traverse all entries in the map.
  617. //
  618. // Returns nil if there are no more keys.
  619. func (m *Map) NextKeyBytes(key interface{}) ([]byte, error) {
  620. nextKey := make([]byte, m.keySize)
  621. nextKeyPtr := sys.NewSlicePointer(nextKey)
  622. err := m.nextKey(key, nextKeyPtr)
  623. if errors.Is(err, ErrKeyNotExist) {
  624. return nil, nil
  625. }
  626. return nextKey, err
  627. }
  628. func (m *Map) nextKey(key interface{}, nextKeyOut sys.Pointer) error {
  629. var (
  630. keyPtr sys.Pointer
  631. err error
  632. )
  633. if key != nil {
  634. keyPtr, err = m.marshalKey(key)
  635. if err != nil {
  636. return fmt.Errorf("can't marshal key: %w", err)
  637. }
  638. }
  639. attr := sys.MapGetNextKeyAttr{
  640. MapFd: m.fd.Uint(),
  641. Key: keyPtr,
  642. NextKey: nextKeyOut,
  643. }
  644. if err = sys.MapGetNextKey(&attr); err != nil {
  645. // Kernels 4.4.131 and earlier return EFAULT instead of a pointer to the
  646. // first map element when a nil key pointer is specified.
  647. if key == nil && errors.Is(err, unix.EFAULT) {
  648. var guessKey []byte
  649. guessKey, err = m.guessNonExistentKey()
  650. if err != nil {
  651. return err
  652. }
  653. // Retry the syscall with a valid non-existing key.
  654. attr.Key = sys.NewSlicePointer(guessKey)
  655. if err = sys.MapGetNextKey(&attr); err == nil {
  656. return nil
  657. }
  658. }
  659. return fmt.Errorf("next key: %w", wrapMapError(err))
  660. }
  661. return nil
  662. }
  663. // guessNonExistentKey attempts to perform a map lookup that returns ENOENT.
  664. // This is necessary on kernels before 4.4.132, since those don't support
  665. // iterating maps from the start by providing an invalid key pointer.
  666. func (m *Map) guessNonExistentKey() ([]byte, error) {
  667. // Provide an invalid value pointer to prevent a copy on the kernel side.
  668. valuePtr := sys.NewPointer(unsafe.Pointer(^uintptr(0)))
  669. randKey := make([]byte, int(m.keySize))
  670. for i := 0; i < 4; i++ {
  671. switch i {
  672. // For hash maps, the 0 key is less likely to be occupied. They're often
  673. // used for storing data related to pointers, and their access pattern is
  674. // generally scattered across the keyspace.
  675. case 0:
  676. // An all-0xff key is guaranteed to be out of bounds of any array, since
  677. // those have a fixed key size of 4 bytes. The only corner case being
  678. // arrays with 2^32 max entries, but those are prohibitively expensive
  679. // in many environments.
  680. case 1:
  681. for r := range randKey {
  682. randKey[r] = 0xff
  683. }
  684. // Inspired by BCC, 0x55 is an alternating binary pattern (0101), so
  685. // is unlikely to be taken.
  686. case 2:
  687. for r := range randKey {
  688. randKey[r] = 0x55
  689. }
  690. // Last ditch effort, generate a random key.
  691. case 3:
  692. rand.New(rand.NewSource(time.Now().UnixNano())).Read(randKey)
  693. }
  694. err := m.lookup(randKey, valuePtr, 0)
  695. if errors.Is(err, ErrKeyNotExist) {
  696. return randKey, nil
  697. }
  698. }
  699. return nil, errors.New("couldn't find non-existing key")
  700. }
  701. // BatchLookup looks up many elements in a map at once.
  702. //
  703. // "keysOut" and "valuesOut" must be of type slice, a pointer
  704. // to a slice or buffer will not work.
  705. // "prevKey" is the key to start the batch lookup from, it will
  706. // *not* be included in the results. Use nil to start at the first key.
  707. //
  708. // ErrKeyNotExist is returned when the batch lookup has reached
  709. // the end of all possible results, even when partial results
  710. // are returned. It should be used to evaluate when lookup is "done".
  711. func (m *Map) BatchLookup(prevKey, nextKeyOut, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error) {
  712. return m.batchLookup(sys.BPF_MAP_LOOKUP_BATCH, prevKey, nextKeyOut, keysOut, valuesOut, opts)
  713. }
  714. // BatchLookupAndDelete looks up many elements in a map at once,
  715. //
  716. // It then deletes all those elements.
  717. // "keysOut" and "valuesOut" must be of type slice, a pointer
  718. // to a slice or buffer will not work.
  719. // "prevKey" is the key to start the batch lookup from, it will
  720. // *not* be included in the results. Use nil to start at the first key.
  721. //
  722. // ErrKeyNotExist is returned when the batch lookup has reached
  723. // the end of all possible results, even when partial results
  724. // are returned. It should be used to evaluate when lookup is "done".
  725. func (m *Map) BatchLookupAndDelete(prevKey, nextKeyOut, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error) {
  726. return m.batchLookup(sys.BPF_MAP_LOOKUP_AND_DELETE_BATCH, prevKey, nextKeyOut, keysOut, valuesOut, opts)
  727. }
  728. func (m *Map) batchLookup(cmd sys.Cmd, startKey, nextKeyOut, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error) {
  729. if err := haveBatchAPI(); err != nil {
  730. return 0, err
  731. }
  732. if m.typ.hasPerCPUValue() {
  733. return 0, ErrNotSupported
  734. }
  735. keysValue := reflect.ValueOf(keysOut)
  736. if keysValue.Kind() != reflect.Slice {
  737. return 0, fmt.Errorf("keys must be a slice")
  738. }
  739. valuesValue := reflect.ValueOf(valuesOut)
  740. if valuesValue.Kind() != reflect.Slice {
  741. return 0, fmt.Errorf("valuesOut must be a slice")
  742. }
  743. count := keysValue.Len()
  744. if count != valuesValue.Len() {
  745. return 0, fmt.Errorf("keysOut and valuesOut must be the same length")
  746. }
  747. keyBuf := make([]byte, count*int(m.keySize))
  748. keyPtr := sys.NewSlicePointer(keyBuf)
  749. valueBuf := make([]byte, count*int(m.fullValueSize))
  750. valuePtr := sys.NewSlicePointer(valueBuf)
  751. nextPtr, nextBuf := makeBuffer(nextKeyOut, int(m.keySize))
  752. attr := sys.MapLookupBatchAttr{
  753. MapFd: m.fd.Uint(),
  754. Keys: keyPtr,
  755. Values: valuePtr,
  756. Count: uint32(count),
  757. OutBatch: nextPtr,
  758. }
  759. if opts != nil {
  760. attr.ElemFlags = opts.ElemFlags
  761. attr.Flags = opts.Flags
  762. }
  763. var err error
  764. if startKey != nil {
  765. attr.InBatch, err = marshalPtr(startKey, int(m.keySize))
  766. if err != nil {
  767. return 0, err
  768. }
  769. }
  770. _, sysErr := sys.BPF(cmd, unsafe.Pointer(&attr), unsafe.Sizeof(attr))
  771. sysErr = wrapMapError(sysErr)
  772. if sysErr != nil && !errors.Is(sysErr, unix.ENOENT) {
  773. return 0, sysErr
  774. }
  775. err = m.unmarshalKey(nextKeyOut, nextBuf)
  776. if err != nil {
  777. return 0, err
  778. }
  779. err = unmarshalBytes(keysOut, keyBuf)
  780. if err != nil {
  781. return 0, err
  782. }
  783. err = unmarshalBytes(valuesOut, valueBuf)
  784. if err != nil {
  785. return 0, err
  786. }
  787. return int(attr.Count), sysErr
  788. }
  789. // BatchUpdate updates the map with multiple keys and values
  790. // simultaneously.
  791. // "keys" and "values" must be of type slice, a pointer
  792. // to a slice or buffer will not work.
  793. func (m *Map) BatchUpdate(keys, values interface{}, opts *BatchOptions) (int, error) {
  794. if err := haveBatchAPI(); err != nil {
  795. return 0, err
  796. }
  797. if m.typ.hasPerCPUValue() {
  798. return 0, ErrNotSupported
  799. }
  800. keysValue := reflect.ValueOf(keys)
  801. if keysValue.Kind() != reflect.Slice {
  802. return 0, fmt.Errorf("keys must be a slice")
  803. }
  804. valuesValue := reflect.ValueOf(values)
  805. if valuesValue.Kind() != reflect.Slice {
  806. return 0, fmt.Errorf("values must be a slice")
  807. }
  808. var (
  809. count = keysValue.Len()
  810. valuePtr sys.Pointer
  811. err error
  812. )
  813. if count != valuesValue.Len() {
  814. return 0, fmt.Errorf("keys and values must be the same length")
  815. }
  816. keyPtr, err := marshalPtr(keys, count*int(m.keySize))
  817. if err != nil {
  818. return 0, err
  819. }
  820. valuePtr, err = marshalPtr(values, count*int(m.valueSize))
  821. if err != nil {
  822. return 0, err
  823. }
  824. attr := sys.MapUpdateBatchAttr{
  825. MapFd: m.fd.Uint(),
  826. Keys: keyPtr,
  827. Values: valuePtr,
  828. Count: uint32(count),
  829. }
  830. if opts != nil {
  831. attr.ElemFlags = opts.ElemFlags
  832. attr.Flags = opts.Flags
  833. }
  834. err = sys.MapUpdateBatch(&attr)
  835. if err != nil {
  836. return int(attr.Count), fmt.Errorf("batch update: %w", wrapMapError(err))
  837. }
  838. return int(attr.Count), nil
  839. }
  840. // BatchDelete batch deletes entries in the map by keys.
  841. // "keys" must be of type slice, a pointer to a slice or buffer will not work.
  842. func (m *Map) BatchDelete(keys interface{}, opts *BatchOptions) (int, error) {
  843. if err := haveBatchAPI(); err != nil {
  844. return 0, err
  845. }
  846. if m.typ.hasPerCPUValue() {
  847. return 0, ErrNotSupported
  848. }
  849. keysValue := reflect.ValueOf(keys)
  850. if keysValue.Kind() != reflect.Slice {
  851. return 0, fmt.Errorf("keys must be a slice")
  852. }
  853. count := keysValue.Len()
  854. keyPtr, err := marshalPtr(keys, count*int(m.keySize))
  855. if err != nil {
  856. return 0, fmt.Errorf("cannot marshal keys: %v", err)
  857. }
  858. attr := sys.MapDeleteBatchAttr{
  859. MapFd: m.fd.Uint(),
  860. Keys: keyPtr,
  861. Count: uint32(count),
  862. }
  863. if opts != nil {
  864. attr.ElemFlags = opts.ElemFlags
  865. attr.Flags = opts.Flags
  866. }
  867. if err = sys.MapDeleteBatch(&attr); err != nil {
  868. return int(attr.Count), fmt.Errorf("batch delete: %w", wrapMapError(err))
  869. }
  870. return int(attr.Count), nil
  871. }
  872. // Iterate traverses a map.
  873. //
  874. // It's safe to create multiple iterators at the same time.
  875. //
  876. // It's not possible to guarantee that all keys in a map will be
  877. // returned if there are concurrent modifications to the map.
  878. func (m *Map) Iterate() *MapIterator {
  879. return newMapIterator(m)
  880. }
  881. // Close the Map's underlying file descriptor, which could unload the
  882. // Map from the kernel if it is not pinned or in use by a loaded Program.
  883. func (m *Map) Close() error {
  884. if m == nil {
  885. // This makes it easier to clean up when iterating maps
  886. // of maps / programs.
  887. return nil
  888. }
  889. return m.fd.Close()
  890. }
  891. // FD gets the file descriptor of the Map.
  892. //
  893. // Calling this function is invalid after Close has been called.
  894. func (m *Map) FD() int {
  895. return m.fd.Int()
  896. }
  897. // Clone creates a duplicate of the Map.
  898. //
  899. // Closing the duplicate does not affect the original, and vice versa.
  900. // Changes made to the map are reflected by both instances however.
  901. // If the original map was pinned, the cloned map will not be pinned by default.
  902. //
  903. // Cloning a nil Map returns nil.
  904. func (m *Map) Clone() (*Map, error) {
  905. if m == nil {
  906. return nil, nil
  907. }
  908. dup, err := m.fd.Dup()
  909. if err != nil {
  910. return nil, fmt.Errorf("can't clone map: %w", err)
  911. }
  912. return &Map{
  913. m.name,
  914. dup,
  915. m.typ,
  916. m.keySize,
  917. m.valueSize,
  918. m.maxEntries,
  919. m.flags,
  920. "",
  921. m.fullValueSize,
  922. }, nil
  923. }
  924. // Pin persists the map on the BPF virtual file system past the lifetime of
  925. // the process that created it .
  926. //
  927. // Calling Pin on a previously pinned map will overwrite the path, except when
  928. // the new path already exists. Re-pinning across filesystems is not supported.
  929. // You can Clone a map to pin it to a different path.
  930. //
  931. // This requires bpffs to be mounted above fileName. See https://docs.cilium.io/en/k8s-doc/admin/#admin-mount-bpffs
  932. func (m *Map) Pin(fileName string) error {
  933. if err := internal.Pin(m.pinnedPath, fileName, m.fd); err != nil {
  934. return err
  935. }
  936. m.pinnedPath = fileName
  937. return nil
  938. }
  939. // Unpin removes the persisted state for the map from the BPF virtual filesystem.
  940. //
  941. // Failed calls to Unpin will not alter the state returned by IsPinned.
  942. //
  943. // Unpinning an unpinned Map returns nil.
  944. func (m *Map) Unpin() error {
  945. if err := internal.Unpin(m.pinnedPath); err != nil {
  946. return err
  947. }
  948. m.pinnedPath = ""
  949. return nil
  950. }
  951. // IsPinned returns true if the map has a non-empty pinned path.
  952. func (m *Map) IsPinned() bool {
  953. return m.pinnedPath != ""
  954. }
  955. // Freeze prevents a map to be modified from user space.
  956. //
  957. // It makes no changes to kernel-side restrictions.
  958. func (m *Map) Freeze() error {
  959. if err := haveMapMutabilityModifiers(); err != nil {
  960. return fmt.Errorf("can't freeze map: %w", err)
  961. }
  962. attr := sys.MapFreezeAttr{
  963. MapFd: m.fd.Uint(),
  964. }
  965. if err := sys.MapFreeze(&attr); err != nil {
  966. return fmt.Errorf("can't freeze map: %w", err)
  967. }
  968. return nil
  969. }
  970. // finalize populates the Map according to the Contents specified
  971. // in spec and freezes the Map if requested by spec.
  972. func (m *Map) finalize(spec *MapSpec) error {
  973. for _, kv := range spec.Contents {
  974. if err := m.Put(kv.Key, kv.Value); err != nil {
  975. return fmt.Errorf("putting value: key %v: %w", kv.Key, err)
  976. }
  977. }
  978. if spec.Freeze {
  979. if err := m.Freeze(); err != nil {
  980. return fmt.Errorf("freezing map: %w", err)
  981. }
  982. }
  983. return nil
  984. }
  985. func (m *Map) marshalKey(data interface{}) (sys.Pointer, error) {
  986. if data == nil {
  987. if m.keySize == 0 {
  988. // Queues have a key length of zero, so passing nil here is valid.
  989. return sys.NewPointer(nil), nil
  990. }
  991. return sys.Pointer{}, errors.New("can't use nil as key of map")
  992. }
  993. return marshalPtr(data, int(m.keySize))
  994. }
  995. func (m *Map) unmarshalKey(data interface{}, buf []byte) error {
  996. if buf == nil {
  997. // This is from a makeBuffer call, nothing do do here.
  998. return nil
  999. }
  1000. return unmarshalBytes(data, buf)
  1001. }
  1002. func (m *Map) marshalValue(data interface{}) (sys.Pointer, error) {
  1003. if m.typ.hasPerCPUValue() {
  1004. return marshalPerCPUValue(data, int(m.valueSize))
  1005. }
  1006. var (
  1007. buf []byte
  1008. err error
  1009. )
  1010. switch value := data.(type) {
  1011. case *Map:
  1012. if !m.typ.canStoreMap() {
  1013. return sys.Pointer{}, fmt.Errorf("can't store map in %s", m.typ)
  1014. }
  1015. buf, err = marshalMap(value, int(m.valueSize))
  1016. case *Program:
  1017. if !m.typ.canStoreProgram() {
  1018. return sys.Pointer{}, fmt.Errorf("can't store program in %s", m.typ)
  1019. }
  1020. buf, err = marshalProgram(value, int(m.valueSize))
  1021. default:
  1022. return marshalPtr(data, int(m.valueSize))
  1023. }
  1024. if err != nil {
  1025. return sys.Pointer{}, err
  1026. }
  1027. return sys.NewSlicePointer(buf), nil
  1028. }
  1029. func (m *Map) unmarshalValue(value interface{}, buf []byte) error {
  1030. if buf == nil {
  1031. // This is from a makeBuffer call, nothing do do here.
  1032. return nil
  1033. }
  1034. if m.typ.hasPerCPUValue() {
  1035. return unmarshalPerCPUValue(value, int(m.valueSize), buf)
  1036. }
  1037. switch value := value.(type) {
  1038. case **Map:
  1039. if !m.typ.canStoreMap() {
  1040. return fmt.Errorf("can't read a map from %s", m.typ)
  1041. }
  1042. other, err := unmarshalMap(buf)
  1043. if err != nil {
  1044. return err
  1045. }
  1046. // The caller might close the map externally, so ignore errors.
  1047. _ = (*value).Close()
  1048. *value = other
  1049. return nil
  1050. case *Map:
  1051. if !m.typ.canStoreMap() {
  1052. return fmt.Errorf("can't read a map from %s", m.typ)
  1053. }
  1054. return errors.New("require pointer to *Map")
  1055. case **Program:
  1056. if !m.typ.canStoreProgram() {
  1057. return fmt.Errorf("can't read a program from %s", m.typ)
  1058. }
  1059. other, err := unmarshalProgram(buf)
  1060. if err != nil {
  1061. return err
  1062. }
  1063. // The caller might close the program externally, so ignore errors.
  1064. _ = (*value).Close()
  1065. *value = other
  1066. return nil
  1067. case *Program:
  1068. if !m.typ.canStoreProgram() {
  1069. return fmt.Errorf("can't read a program from %s", m.typ)
  1070. }
  1071. return errors.New("require pointer to *Program")
  1072. }
  1073. return unmarshalBytes(value, buf)
  1074. }
  1075. // LoadPinnedMap loads a Map from a BPF file.
  1076. func LoadPinnedMap(fileName string, opts *LoadPinOptions) (*Map, error) {
  1077. fd, err := sys.ObjGet(&sys.ObjGetAttr{
  1078. Pathname: sys.NewStringPointer(fileName),
  1079. FileFlags: opts.Marshal(),
  1080. })
  1081. if err != nil {
  1082. return nil, err
  1083. }
  1084. m, err := newMapFromFD(fd)
  1085. if err == nil {
  1086. m.pinnedPath = fileName
  1087. }
  1088. return m, err
  1089. }
  1090. // unmarshalMap creates a map from a map ID encoded in host endianness.
  1091. func unmarshalMap(buf []byte) (*Map, error) {
  1092. if len(buf) != 4 {
  1093. return nil, errors.New("map id requires 4 byte value")
  1094. }
  1095. id := internal.NativeEndian.Uint32(buf)
  1096. return NewMapFromID(MapID(id))
  1097. }
  1098. // marshalMap marshals the fd of a map into a buffer in host endianness.
  1099. func marshalMap(m *Map, length int) ([]byte, error) {
  1100. if length != 4 {
  1101. return nil, fmt.Errorf("can't marshal map to %d bytes", length)
  1102. }
  1103. buf := make([]byte, 4)
  1104. internal.NativeEndian.PutUint32(buf, m.fd.Uint())
  1105. return buf, nil
  1106. }
  1107. // MapIterator iterates a Map.
  1108. //
  1109. // See Map.Iterate.
  1110. type MapIterator struct {
  1111. target *Map
  1112. prevKey interface{}
  1113. prevBytes []byte
  1114. count, maxEntries uint32
  1115. done bool
  1116. err error
  1117. }
  1118. func newMapIterator(target *Map) *MapIterator {
  1119. return &MapIterator{
  1120. target: target,
  1121. maxEntries: target.maxEntries,
  1122. prevBytes: make([]byte, target.keySize),
  1123. }
  1124. }
  1125. // Next decodes the next key and value.
  1126. //
  1127. // Iterating a hash map from which keys are being deleted is not
  1128. // safe. You may see the same key multiple times. Iteration may
  1129. // also abort with an error, see IsIterationAborted.
  1130. //
  1131. // Returns false if there are no more entries. You must check
  1132. // the result of Err afterwards.
  1133. //
  1134. // See Map.Get for further caveats around valueOut.
  1135. func (mi *MapIterator) Next(keyOut, valueOut interface{}) bool {
  1136. if mi.err != nil || mi.done {
  1137. return false
  1138. }
  1139. // For array-like maps NextKeyBytes returns nil only on after maxEntries
  1140. // iterations.
  1141. for mi.count <= mi.maxEntries {
  1142. var nextBytes []byte
  1143. nextBytes, mi.err = mi.target.NextKeyBytes(mi.prevKey)
  1144. if mi.err != nil {
  1145. return false
  1146. }
  1147. if nextBytes == nil {
  1148. mi.done = true
  1149. return false
  1150. }
  1151. // The user can get access to nextBytes since unmarshalBytes
  1152. // does not copy when unmarshaling into a []byte.
  1153. // Make a copy to prevent accidental corruption of
  1154. // iterator state.
  1155. copy(mi.prevBytes, nextBytes)
  1156. mi.prevKey = mi.prevBytes
  1157. mi.count++
  1158. mi.err = mi.target.Lookup(nextBytes, valueOut)
  1159. if errors.Is(mi.err, ErrKeyNotExist) {
  1160. // Even though the key should be valid, we couldn't look up
  1161. // its value. If we're iterating a hash map this is probably
  1162. // because a concurrent delete removed the value before we
  1163. // could get it. This means that the next call to NextKeyBytes
  1164. // is very likely to restart iteration.
  1165. // If we're iterating one of the fd maps like
  1166. // ProgramArray it means that a given slot doesn't have
  1167. // a valid fd associated. It's OK to continue to the next slot.
  1168. continue
  1169. }
  1170. if mi.err != nil {
  1171. return false
  1172. }
  1173. mi.err = mi.target.unmarshalKey(keyOut, nextBytes)
  1174. return mi.err == nil
  1175. }
  1176. mi.err = fmt.Errorf("%w", ErrIterationAborted)
  1177. return false
  1178. }
  1179. // Err returns any encountered error.
  1180. //
  1181. // The method must be called after Next returns nil.
  1182. //
  1183. // Returns ErrIterationAborted if it wasn't possible to do a full iteration.
  1184. func (mi *MapIterator) Err() error {
  1185. return mi.err
  1186. }
  1187. // MapGetNextID returns the ID of the next eBPF map.
  1188. //
  1189. // Returns ErrNotExist, if there is no next eBPF map.
  1190. func MapGetNextID(startID MapID) (MapID, error) {
  1191. attr := &sys.MapGetNextIdAttr{Id: uint32(startID)}
  1192. return MapID(attr.NextId), sys.MapGetNextId(attr)
  1193. }
  1194. // NewMapFromID returns the map for a given id.
  1195. //
  1196. // Returns ErrNotExist, if there is no eBPF map with the given id.
  1197. func NewMapFromID(id MapID) (*Map, error) {
  1198. fd, err := sys.MapGetFdById(&sys.MapGetFdByIdAttr{
  1199. Id: uint32(id),
  1200. })
  1201. if err != nil {
  1202. return nil, err
  1203. }
  1204. return newMapFromFD(fd)
  1205. }