Lunatik

xdpModule

eXpress Data Path (XDP) integration.

This library allows Lua scripts to interact with the kernel’s XDP subsystem. It enables XDP/eBPF programs to call Lua functions for packet processing, providing a flexible way to implement custom packet handling logic in Lua at a very early stage in the network stack.

The primary mechanism involves an XDP program calling the bpf_luaxdp_run kfunc, which in turn invokes a Lua callback function previously registered using xdp.attach.

The module registers its kfunc through BTF: it needs a kernel built with CONFIG_DEBUG_INFO_BTF and a build made after make btf_install. Without the module BTF it loads with its kfunc unregistered, logging missing module BTF, and an eBPF program that calls the kfunc fails to load. The eBPF program is loaded apart, with bpftool, as an XDP program that declares bpf_luaxdp_run as a __ksym, as examples/filter does.

Class xdp_ctx

xdp_ctx:argument () Returns the argument data buffer passed from eBPF.
xdp_ctx:packet () Returns the packet data buffer for the current XDP context.

xdp

attach (callback) Registers a Lua callback function to be invoked by an XDP/eBPF program.
detach () Unregisters the Lua callback function associated with the current Lunatik runtime.

Class xdp_ctx in detail

XDP callback context, valid only while the callback runs. It is handed to the callback registered with xdp.attach; its methods raise once the callback returns.
xdp_ctx:argument ()
Returns the argument data buffer passed from eBPF.

Returns

    data argument buffer
xdp_ctx:packet ()
Returns the packet data buffer for the current XDP context.

Returns

    data packet buffer

xdp in detail

attach (callback)

Registers a Lua callback function to be invoked by an XDP/eBPF program. When an XDP program calls the bpf_luaxdp_run kfunc, Lunatik will execute the registered Lua callback associated with the current Lunatik runtime. The runtime must be softirq, lunatik run -c softirq <script>.

The bpf_luaxdp_run kfunc is called from an eBPF program with the following signature: int bpf_luaxdp_run(char key, size_t key_sz, struct xdp_md xdp_md, void *arg, size_t arg_sz)

  • key: A string identifying the Lunatik runtime: the script path under /lib/modules/lua without its .lua extension, as given to lunatik run (e.g. “examples/filter/sni”). This key is used to look up the runtime in Lunatik’s internal table of active runtimes.
  • key_sz: Length of the key string (including the null terminator).
  • xdp_md: The XDP metadata context (struct xdp_md *).
  • arg: A pointer to arbitrary data passed from eBPF to Lua.
  • arg_sz: The size of the arg data.

Parameters

  • callback function Lua function to call. It receives one argument:

    ctx: An xdp_ctx context object used to inspect the packet.

    It returns the verdict, a value of linux.xdp.action, which bpf_luaxdp_run returns to the eBPF program. When it returns nothing or nil, or raises, bpf_luaxdp_run returns -1 and the verdict is left to the eBPF program; a value that is not an XDP action is logged as invalid action and answered the same way.

Returns

    nil

Raises

runtime context mismatch outside a softirq runtime; not allowed while the runtime closes from a finalizer that runs at its close; or if internal setup fails.

See also

Usage

-- Lua script my_xdp_handler.lua, run with lunatik run -c softirq my_xdp_handler
local xdp = require("xdp")
local action = require("linux.xdp").action

local function my_packet_processor(ctx)
  local pkt = ctx:packet()
  print("Packet received, size:", #pkt)
  return action.PASS
end
xdp.attach(my_packet_processor)

-- In eBPF C code, to call the above Lua function:
-- char rt_key[] = "my_xdp_handler"; // the script name without .lua
-- int verdict = bpf_luaxdp_run(rt_key, sizeof(rt_key), ctx, NULL, 0);
detach ()
Unregisters the Lua callback function associated with the current Lunatik runtime. After calling this, bpf_luaxdp_run calls targeting this runtime invoke no Lua function: they log no callback attached, return -1 and leave the verdict to the eBPF program.

Returns

    nil

Usage

xdp.detach()