Lunatik

bpfModule

Lua interface to eBPF.

This module provides typed access to pinned eBPF maps; one constructor per map type, each validating the type on open:

hash, array and lru_hash open key-value maps, with lookup, update, delete, remove and next.

queue (FIFO) and stack (LIFO) open keyless maps, with push, pop and peek.

Keys and values are exchanged as packed Lua strings whose sizes must match the map’s configured key and value sizes. Queues and stacks have no keys, so only value_size applies to them.

Needs CONFIG_BPF_SYSCALL and a map pinned on bpffs, as bpftool map pin leaves one. The flags update and push take come from linux.bpf.update: ANY, NOEXIST and EXIST.

Class bpf_hash

bpf_hash:close () Releases the map reference.
bpf_hash:delete (key) Deletes a key from the map.
bpf_hash:info () Returns the map properties.
bpf_hash:lookup (key) Looks up a key from the map.
bpf_hash:next ([key]) Returns the next key in the map.
bpf_hash:remove (key) Looks up and deletes a key from the map.
bpf_hash:update (key, value[, flags=BPF_ANY]) Updates a key in the map.

Class bpf_queue

bpf_queue:peek () Peeks at the next value of the map without removing it.
bpf_queue:pop () Pops (removes and returns) the next value from the map.
bpf_queue:push (value[, flags=BPF_ANY]) Pushes a value onto the map.

bpf

array (path) Opens an array map from a pinned bpffs path.
hash (path) Opens a hash map from a pinned bpffs path.
lru_hash (path) Opens an LRU hash map from a pinned bpffs path.
queue (path) Opens a queue (FIFO) map from a pinned bpffs path.
stack (path) Opens a stack (LIFO) map from a pinned bpffs path.

Class bpf_hash in detail

Represents an open key-value map handle. This is a userdata object returned by bpf.hash(), bpf.array() and bpf.lru_hash(). It holds a reference to a pinned struct bpf_map.
bpf_hash:close ()
Releases the map reference. This is an alias for the __close metamethod.
bpf_hash:delete (key)
Deletes a key from the map.

Parameters

Returns

    boolean success

Raises

invalid key size when the key does not match the map, or the kernel’s errno, such as EINVAL on an array map.
bpf_hash:info ()
Returns the map properties.

Returns

    table type, key_size, value_size and max_entries, named as in the kernel’s struct bpf_map_info; type is a value of linux.bpf.map_type.
bpf_hash:lookup (key)
Looks up a key from the map.

Parameters

Returns

    string value Packed value, or nil if the key is not present.

Raises

invalid key size when the key does not match the map, or the kernel’s errno.
bpf_hash:next ([key])
Returns the next key in the map. Mirrors Lua’s next(t, key), so it can drive a generic for directly. On hash and LRU hash maps, next given a key the map does not hold starts again from the first key, so deleting entries during the walk, or an eBPF program deleting them meanwhile, can visit keys again; collect the keys first when the loop deletes.

Parameters

  • key string Packed key; returns the first key if nothing is passed. (optional)

Returns

    string next_key Packed next key, or nil if there are no more keys.

Raises

invalid key size when the key does not match the map, or the kernel’s errno.

Usage

local hash = require("bpf").hash
local flow = hash("/sys/fs/bpf/flow_cache")
for key in flow.next, flow do
	print(key)
end
flow:close()
bpf_hash:remove (key)
Looks up and deletes a key from the map.

Parameters

Returns

    string value Packed value, or nil if the key is not present.

Raises

invalid key size when the key does not match the map, EOPNOTSUPP when the map does not support it (e.g. array maps), or the kernel’s errno.
bpf_hash:update (key, value[, flags=BPF_ANY])
Updates a key in the map.

Parameters

  • key string Packed key.
  • value string Packed value.
  • flags integer Update flags. One of: - BPF_ANY (default): Create a new element or update an existing one. - BPF_NOEXIST: Create a new element only if the key does not exist. - BPF_EXIST: Update an existing element only if the key exists. (default BPF_ANY)

Returns

    boolean success; false when the flag condition is not met (BPF_EXIST on an absent key, BPF_NOEXIST on a present one) or a hash map is full.

Raises

invalid key size or invalid value size when a string does not match the map, or the kernel’s errno, such as E2BIG for an array index past its end or EINVAL for bad flags.

Class bpf_queue in detail

Represents an open queue or stack handle, as returned by bpf.queue() and bpf.stack(). It also exposes info and close, as bpf_hash.
bpf_queue:peek ()
Peeks at the next value of the map without removing it.

Returns

    string value Packed value, or nil if the map is empty.
bpf_queue:pop ()
Pops (removes and returns) the next value from the map. Queues pop in FIFO order; stacks pop in LIFO order.

Returns

    string value Packed value, or nil if the map is empty.
bpf_queue:push (value[, flags=BPF_ANY])
Pushes a value onto the map.

Parameters

  • value string Packed value.
  • flags integer Update flags. BPF_EXIST may be set to overwrite the oldest element once the map is full. (default BPF_ANY)

Returns

    boolean success; false when the map is full and BPF_EXIST was not given.

Raises

invalid value size when the value does not match the map, or the kernel’s errno, such as EINVAL for bad flags.

bpf in detail

array (path)
Opens an array map from a pinned bpffs path. Keys are 32-bit indexes, packed as 4-byte strings. Same interrupt-context restriction as hash.

Parameters

  • path string Path to a pinned eBPF array map.

Returns

    bpf_hash Opened map handle.

Raises

Error if the path does not resolve to a pinned eBPF array map.
hash (path)
Opens a hash map from a pinned bpffs path.

Parameters

  • path string Path to a pinned eBPF hash map.

Returns

    bpf_hash Opened map handle.

Raises

Error if the path does not resolve to a pinned eBPF hash map, or not allowed once the runtime is armed (its script body has returned): the path lookup sleeps, so on an interrupt-context runtime (softirq/hardirq) the constructors are only allowed while the script body runs; the returned handle can then be used from handlers.

Usage

local bpf = require("bpf")
local counter = bpf.hash("/sys/fs/bpf/counters")
-- 32-bit key/value encoded as packed strings.
local key = string.pack("I4", 1)
local value = string.pack("I4", 42)
assert(counter:update(key, value))
local result = counter:lookup(key)
if result then
    print(string.unpack("I4", result))
end
counter:delete(key)
counter:close()
lru_hash (path)
Opens an LRU hash map from a pinned bpffs path. Same interrupt-context restriction as hash.

Parameters

  • path string Path to a pinned eBPF LRU hash map.

Returns

    bpf_hash Opened map handle.

Raises

Error if the path does not resolve to a pinned eBPF LRU hash map.
queue (path)
Opens a queue (FIFO) map from a pinned bpffs path. Same interrupt-context restriction as hash.

Parameters

  • path string Path to a pinned eBPF queue map.

Returns

    bpf_queue Opened queue handle.

Raises

Error if the path does not resolve to a pinned eBPF queue map.

Usage

local bpf = require("bpf")
local jobs = bpf.queue("/sys/fs/bpf/job_queue")
assert(jobs:push(string.pack("I4", 7)))
local job = jobs:peek()          -- inspect without removing
job = jobs:pop()                 -- remove and return
jobs:close()
stack (path)
Opens a stack (LIFO) map from a pinned bpffs path. Same interrupt-context restriction as hash.

Parameters

  • path string Path to a pinned eBPF stack map.

Returns

    bpf_queue Opened stack handle.

Raises

Error if the path does not resolve to a pinned eBPF stack map.