Repository navigation
Description
Part of #14.
rukernel has classic BPF only: the seccomp filters (core/rk-proc/src/bpf.rs) and SO_ATTACH_FILTER (net/rk-net/src/filter.rs). There is no bpf(2) system call, no eBPF interpreter, no map and no bpffs. LTP bpf_map01 and bpf_prog01 to bpf_prog07 do not apply now ("__NR_bpf not supported"). spec/11-bpf.md section 11.7 puts the interpreter, the maps and the helpers for networking and cgroups in R5, and the JIT, BTF and CO-RE in R7.
Scope
- The
bpf(2)entry with the size rules ofunion bpf_attr, map file descriptors with their fdinfo, andBPF_MAP_CREATE,BPF_MAP_LOOKUP_ELEM,BPF_MAP_UPDATE_ELEM,BPF_MAP_DELETE_ELEMandBPF_MAP_GET_NEXT_KEYfor the hash, array, per CPU hash, per CPU array and LPM trie maps. Add the sysctlkernel.unprivileged_bpf_disabledwith the value 2. Test: LTP bpf_map01. Exit: bpf_map01 passes. bpf: add bpf(2) with hash, array, per CPU and LPM trie maps #568: bpf_map01 passes on x86_64, and the new init boot checks pass on x86_64 and arm64. - The verifier, first part: a port of the checks of kernel/bpf/verifier.c for the program types of this issue. It tracks the register types and bounds, the stack, the bounds of map values and the argument types of each helper, and it refuses back edges that it cannot bound. It gives the verifier log. Test: LTP bpf_prog02 and bpf_prog05, and kselftest test_verifier (add
bpf/test_verifierto tools/kselftest/build.sh). Exit: for each program of test_verifier that this issue covers, rukernel accepts or refuses as the reference does. Write the result to tools/kselftest/bpf.md. bpf: the verifier gives the result of Linux for test_verifier #701: test_verifier gives 281 PASSED, 510 SKIPPED and 0 FAILED for the five program types of this issue. bpf_prog02 passes, and bpf_prog05 gives TCONF, as on the reference withkernel.unprivileged_bpf_disabled=2. - The interpreter: all ALU64, ALU32, JMP, JMP32, load, store and atomic instructions of RFC 9669, tail calls, and the helpers that systemd uses (
map_lookup_elem,map_update_elem,map_delete_elem,get_current_pid_tgid,get_current_uid_gid,get_current_cgroup_id,ktime_get_ns,get_prandom_u32,skb_load_bytes). Test: LTP bpf_prog01, bpf_prog03, bpf_prog04, bpf_prog06 and bpf_prog07. Exit: all bpf_prog tests reach the pass set of the reference. bpf: run calls of functions, BPF_LD_[ABS|IND] and loads of map values #678: calls of functions of the program,BPF_LD_[ABS|IND]and loads of map values. bpf: add BPF_MAP_TYPE_PROG_ARRAY and bpf_tail_call #686:BPF_MAP_TYPE_PROG_ARRAYand tail calls. bpf_prog01 to bpf_prog04 pass, and bpf_prog05 to bpf_prog07 give TCONF, as on the reference withkernel.unprivileged_bpf_disabled=2. - bpffs at
/sys/fs/bpf, withBPF_OBJ_PINandBPF_OBJ_GETfor maps, programs and links. Test: a new check in thesystemdboot test pins a map, gets it again and reads a value. Exit: the check passes, andsys-fs-bpf.mountis active. xtask: pin a BPF map in the systemd boot test #607, xtask: check the bpf mount of the systemd test in mountinfo #614, bpf: check the pins of a program and a link in bpffs #630: thesystemdboot test pins a map, a program and a link in /sys/fs/bpf and gets them again, and /proc/self/mountinfo shows a bpf file system at /sys/fs/bpf. systemd mounts /sys/fs/bpf itself and makes nosys-fs-bpf.mountunit, also on Linux, so the test checks mountinfo and not the unit. - Cgroup programs:
BPF_PROG_ATTACH,BPF_PROG_DETACH,BPF_PROG_QUERYandBPF_LINK_CREATEwithBPF_F_ALLOW_MULTIandBPF_F_ALLOW_OVERRIDE, and the effective program arrays of each cgroup. RunBPF_PROG_TYPE_CGROUP_DEVICEat the open and themknodof a device file. RunBPF_PROG_TYPE_CGROUP_SKBat the ingress and egress of IPv4 and IPv6, andBPF_PROG_TYPE_CGROUP_SOCKandBPF_PROG_TYPE_CGROUP_SOCK_ADDRatsocket,bindandconnect. Test: the systemd unit tests test-bpf-devices, test-bpf-firewall and test-bpf-foreign-programs from the systemd-tests package. Exit: the three tests pass. xtask: the sdbpf boot test runs the systemd unit tests for cgroup BPF programs #705: thesdbpfboot test runs the three tests on x86_64, and all three exit 0. The kernel needed no change. xtask has no systemd tests on arm64, so the init-- only bpftest covers the cgroup programs on arm64. - systemd IP accounting and the device controller in the
systemdboot test. Start a unit withIPAccounting=yesthat pings the host, and a unit withDevicePolicy=closedthat opens/dev/vda. Exit:systemctl show -p IPIngressBytes,IPEgressBytesgives values that are not zero, and the open of/dev/vdagivesEPERM. xtask: check IP accounting and DevicePolicy=closed in the systemd boot test #632:IPIngressBytesandIPEgressBytesare 84 and 84 after one ping of the gateway, and the open of /dev/vda givesEPERM.
Done when
systemd IP accounting and the device controller work. This is the exit of the second item of #14.
Test each task on x86_64 and on arm64. Give the result of both in the PR body.
Linux reference: kernel/bpf/syscall.c, kernel/bpf/verifier.c, kernel/bpf/core.c, kernel/bpf/cgroup.c, kernel/bpf/hashtab.c, kernel/bpf/lpm_trie.c, kernel/bpf/inode.c.
Activity
tamnd commentedon Nov 4, 2026
The first item is done in #568. It adds
bpf(2)in the new crate rk-bpf, with the size rules ofunion bpf_attr, map fdinfo,BPF_MAP_FREEZE, and the hash, array, per CPU hash, per CPU array and LPM trie maps. The sysctlkernel.unprivileged_bpf_disabledhas the value 2. LTP bpf_map01 passes on x86_64 and is now in tools/ltp/tests.txt. The 20 new bpf checks of the init boot test pass on x86_64 and arm64. #569 is empty because the PR script ran again after the merge. Next: the interpreter,BPF_PROG_LOADand a first verifier.tamnd commentedon Nov 4, 2026
PR #577 merged the second item: BPF_PROG_LOAD, the interpreter of RFC 9669 with the helpers, and a first safe verifier. LTP bpf_map01 and bpf_prog01 to bpf_prog04 pass on x86_64, and bpf_prog05 to bpf_prog07 give TCONF as on Linux. The init checks pass on x86_64 and arm64. The item stays open, because calls to functions of the program, tail calls, kfuncs, BPF_LD_[ABS|IND] and state pruning are not done.
tamnd commentedon Nov 4, 2026
PR #583 merged bpffs with
BPF_OBJ_PINandBPF_OBJ_GETfor maps and programs.mount -t bpf bpf /sys/fs/bpfworks, a pinned map stays after its last descriptor closes, andBPF_OBJ_GETgives the map again. The new init checks pass on x86_64 and arm64. The item stays open, because rukernel has no BPF links yet, and the check in thesystemdboot test andsys-fs-bpf.mountare not done.tamnd commentedon Nov 4, 2026
#589 is merged. It adds the object IDs,
BPF_OBJ_GET_INFO_BY_FDand the BPF links of kernel/bpf/syscall.c of Linux. bpffs can pin a link. The systemd boot test checks that sys-fs-bpf.mount is active, and init takesonly bpfto run only the BPF checks.Tests:
cargo test -p rk-bpfpassed. In QEMU on x86_64, all 31 BPF checks of the init test are ok. The boot test timed out under load (load average 30 to 43). It stopped in the test "1000 threads start" and at "cpu.max limits a busy loop", before or after the BPF checks. On arm64,RK_CMDLINE="-- only bpf" RK_AARCH64_TESTS=init cargo xtask boot-test aarch64passed with 44 checks ok at load 47.The bpffs item is not ticked yet. The pin, get and read check in the systemd boot test comes in the next PR.
tamnd commentedon Nov 4, 2026
#591 is merged. It adds
BPF_PROG_ATTACH,BPF_PROG_DETACH,BPF_PROG_QUERYandBPF_LINK_CREATEfor a cgroup, withBPF_F_ALLOW_MULTI,BPF_F_ALLOW_OVERRIDE,BPF_F_REPLACE,BPF_F_BEFOREandBPF_F_AFTER, and the effective arrays of each cgroup. The verifier takes the cgroup program types.Tests:
cargo test -p rk-bpf -p rk-fs-cgrouppassed (58 and 5).RK_CMDLINE="-- only bpf"boot tests passed on x86_64 (pvh, bzImage and UEFI) and on arm64, with 53 checks ok. The load average was 28 to 37.The cgroup programs item is not ticked yet. The hooks remain: DEVICE at open and mknod, CGROUP_SOCK at socket, CGROUP_SKB at ingress and egress, and SOCK_ADDR at bind and connect. The systemd unit tests test-bpf-devices, test-bpf-firewall and test-bpf-foreign-programs also remain.
tamnd commentedon Nov 5, 2026
#595 runs the device and socket programs of cgroup2.
BPF_PROG_TYPE_CGROUP_DEVICEruns at the open and themknodof a device file, andBPF_CGROUP_INET_SOCK_CREATEruns atsocketof IPv4 and IPv6. A program that gives 0 refuses the access withEPERM.Tests:
cargo test -p rk-vfs -p rk-bpf -p rk-syscallpassed (91, 58 and 0).RK_CMDLINE="-- only bpf"boot tests passed on x86_64 (pvh, bzImage and UEFI) and on arm64, with 57 checks ok. The load average was 26 to 34.The cgroup programs item is not ticked yet. These parts remain: CGROUP_SKB at ingress and egress, SOCK_ADDR at bind and connect, and the systemd unit tests test-bpf-devices, test-bpf-firewall and test-bpf-foreign-programs.
tamnd commentedon Nov 5, 2026
#597 runs the packet programs of cgroup2 on IPv4 and IPv6 sockets.
BPF_CGROUP_INET_INGRESSruns on each datagram and TCP segment that a socket of the cgroup gets, andBPF_CGROUP_INET_EGRESSruns on each packet that it sends. A socket keeps the cgroup of its creator. A program that gives 0 drops the packet, and a send then givesEPERM.Tests:
cargo test -p rk-net -p rk-net-inet -p rk-bpf -p rk-syscallpassed (58, 74, 108 and 0). The x86_64-- only bpfboot tests passed with pvh, bzImage and UEFI (62 checks ok, load average 38). The arm64 kernel did not build because other jobs filled the disk of server2.The cgroup programs item is not ticked yet. These parts remain: SOCK_ADDR at bind and connect (the next PR), and the systemd unit tests test-bpf-devices, test-bpf-firewall and test-bpf-foreign-programs.
tamnd commentedon Nov 5, 2026
#600 adds the address programs of cgroup2,
BPF_PROG_TYPE_CGROUP_SOCK_ADDR, atbindandconnectof TCP and UDP sockets for IPv4 and IPv6. The verifier takes the contextstruct bpf_sock_addrwith the access rules of Linux. A program can change the address and the port, a program that gives 0 makes the call giveEPERM, and a bind program can let a low port skip the check ofCAP_NET_BIND_SERVICE.Tests:
cargo test -p rk-bpf -p rk-syscallpassed (60 and 0). The-- only bpfboot tests passed on x86_64 (pvh, bzImage and UEFI) and on arm64, with 69 checks ok. The load average was 18 to 28.The cgroup programs item is not ticked yet. These parts remain: the
sendmsg,recvmsg,getpeernameandgetsocknameaddress types,BPF_CGROUP_INET_SOCK_RELEASEand the post-bind types, and the systemd unit tests test-bpf-devices, test-bpf-firewall and test-bpf-foreign-programs.tamnd commentedon Nov 5, 2026
#607 adds a bpffs check to the systemd boot test: rk-bpfpin pins an array map in /sys/fs/bpf, which sys-fs-bpf.mount mounts, gets it again with
BPF_OBJ_GETand reads the value. The rk-check service runs it.Tests: the kernel and the initramfs built. On server2 under load (load average 27), systemd stopped at the generators with "Failed to fork off sandboxing environment for executing generators: Protocol error", which is known on main under load. On the idle server1, systemd reached basic.target, but systemd-logind.service failed to start again and again, and the boot did not get to rk-check in 900 seconds. So rk-bpfpin has not run in a full boot yet.
The bpffs item is not ticked yet. What remains: find why systemd-logind.service fails, then see the systemd boot test pass with rk-bpfpin.
tamnd commentedon Nov 5, 2026
The bpffs item: #614 fixes the check of the
systemdboot test. The test asked forsystemctl is-active sys-fs-bpf.mount, but systemd mounts /sys/fs/bpf itself as an API file system (mount_tablein src/shared/mount-setup.c), andmount_setup_unitmakes no unit for an API mount point. Sosys-fs-bpf.mountcannot be active, also on Linux. The test now reads /proc/self/mountinfo and checks that /sys/fs/bpf has the typebpf.Result on server1 (load average 0.75, 0.89, 0.82), with #611 for systemd-logind: "rk-systemd: state running", "rk-systemd: /sys/fs/bpf bpf", "rk-bpfpin: pass", "rk-systemd: pass". rk-bpfpin pins an array map, gets it again with
BPF_OBJ_GETand reads a value.I did not tick the item. The exit text names
sys-fs-bpf.mount, which cannot exist, so it needs a change to "/sys/fs/bpf is a bpf mount". The item also asks for the pin of programs and links, and the boot test checks only a map.tamnd commentedon Nov 6, 2026
#623 adds the cgroup programs that were missing, as kernel/bpf/cgroup.c of Linux:
BPF_CGROUP_UDP4_SENDMSGandBPF_CGROUP_UDP6_SENDMSGon the address of a UDP send. A program ofBPF_CGROUP_UDP6_SENDMSGcan change the source ofIPV6_PKTINFO.BPF_CGROUP_UDP4_RECVMSGandBPF_CGROUP_UDP6_RECVMSGon the source address of a UDP receive.accept.BPF_CGROUP_INET4_POST_BINDandBPF_CGROUP_INET6_POST_BIND. A program that gives 0 frees the port, andbindgivesEPERM.BPF_CGROUP_INET_SOCK_RELEASEat the last close of an IPv4 or IPv6 socket.The programs use the cgroup of the socket, as Linux does.
Test: the systemd unit tests test-bpf-devices, test-bpf-firewall and test-bpf-foreign-programs are not in the systemd image. tools/systemd/build.sh installs only systemd, kmod, systemd-sysv and dbus, and there is no systemd-tests package. So a new focused check in the
initboot test (test_bpf_cgroup_sock_msg) tests each new hook in a cgroup.RK_CMDLINE="-- only bpf"passes on x86_64 and arm64, load average 13 to 14 on server2.The item stays open: the code of the item is done, but its exit (the three systemd unit tests) cannot run until the image has them. Next: the bpffs pin checks for a program and a link, then IP accounting and the device controller in the
systemdboot test.tamnd commentedon Nov 6, 2026
#630 adds checks of
BPF_OBJ_PINandBPF_OBJ_GETfor programs and links:systemdboot test pins a program ofBPF_PROG_TYPE_CGROUP_SKBand a link of the program to the root cgroup, gets them again withBPF_OBJ_GET, and checks the type and the IDs. The pinned link keeps the program attached after its descriptors close, and the unlink of the pin detaches it.test_bpffsof theinitboot test does the same checks on a new cgroup.Results: the
-- only bpfinit boot test passes on x86_64 and arm64 (server2, load average 16 to 19). Thesystemdboot test passes in 168 s on server1 (load average 0.1 to 1.0, TCG):rk-systemd: /sys/fs/bpf bpf,rk-bpfpin: map pass,program pass,link pass, andrk-systemd: pass.systemd mounts /sys/fs/bpf itself (
mount_tablein src/shared/mount-setup.c) and makes nosys-fs-bpf.mountunit, also on Linux. So the test checks /proc/self/mountinfo, and I ticked the bpffs item with #607, #614 and #630.What remains: the cgroup item waits for the systemd unit tests, which are not in the image. Next is the IP accounting and
DevicePolicy=closeditem in thesystemdboot test.tamnd commentedon Nov 7, 2026
#632 adds checks of systemd IP accounting and the device controller to the
systemdboot test:IPAccounting=yesand runsrk-cgunit ping. The program sets 10.0.2.15/24 on the network device and pings the gateway 10.0.2.2 of the user network of QEMU on a raw socket.DevicePolicy=closedand runsrk-cgunit open /dev/vda. The program exits with 0 only if the open givesEPERM.Result: the
systemdboot test passes in 161 s on server1 (load average 0.1 to 1.1, TCG).IPIngressBytesandIPEgressBytesare 84 and 84 (one echo request and one reply), and the open of /dev/vda givesEPERM. I ticked the item with #632.What remains of #537:
tamnd commentedon Nov 9, 2026
#678 adds calls of functions of the program,
BPF_LD_[ABS|IND],BPF_PSEUDO_MAP_VALUEandfd_arrayto the interpreter and the verifier, with the errors and messages of Linux without a JIT.Test results:
cargo test -p rk-bpf: 69 passed. clippy: no new warning.-- only bpf, built on server2 and run on server1: bzImage and UEFI pass (load 0.30).-- only bpfon server2: pass (load 14.5).The interpreter item stays open. Tail calls (
BPF_MAP_TYPE_PROG_ARRAY) and the LTP bpf_prog runs come next.tamnd commentedon Nov 10, 2026
#686 adds
BPF_MAP_TYPE_PROG_ARRAYandbpf_tail_call, as kernel/bpf/arraymap.c andJMP_TAIL_CALLof Linux. With #678, the interpreter item is done.Test results:
cargo test -p rk-bpf: 75 passed. Clippy gives no new warnings.boot-test initwith-- only bpf(server1, load 0.13 to 0.35): exit 33, each check passed, with 9 new checks for tail calls.ltp(server1, load 0.35 to 0.60): bpf_map01 and bpf_prog01 to bpf_prog04 pass. bpf_prog05, bpf_prog06 and bpf_prog07 give TCONF, as on Linux 7.3 withkernel.unprivileged_bpf_disabled=2, because they dropCAP_BPF.boot-test aarch64withRK_AARCH64_TESTS=initand-- only bpf(server2, load 11.3 to 29.1): pass.bpf: the verifier gives the result of Linux for test_verifier (#537) (#…
tamnd commentedon Nov 12, 2026
#701 finishes the first part of the verifier. For each program of bpf/test_verifier of the program types of this issue (
SOCKET_FILTER,CGROUP_SKB,CGROUP_SOCK,CGROUP_SOCK_ADDRandCGROUP_DEVICE), rukernel now accepts or refuses the program as Linux does, with the same message. It adds state pruning, the Linux rules for back edges withCAP_BPF, the bounds afterBPF_JSETandBPF_JMP32, the alignment and context access rules, andBPF_PROG_TEST_RUN. tools/kselftest/bpf.md gives the result.Test results:
cargo test -p rk-bpf -p rk-abi(server2): 80 and 7 passed. Clippy gives no new warnings. Load of server2: 14.6 to 18.5.kselftestwith bpf/test_verifier (server1, load 2.6 to 3.3):Summary: 281 PASSED, 510 SKIPPED, 0 FAILED. Before, 259 passed and 22 failed. The skips are the unprivileged runs, the program types outside this issue, thebpf_loopinline that needs a JIT, andBPF_MAP_TYPE_PERF_EVENT_ARRAY.ltp(server1, load 0.18 to 0.44): bpf_map01, bpf_prog01, bpf_prog02, bpf_prog03 and bpf_prog04 pass. bpf_prog05, bpf_prog06 and bpf_prog07 give TCONF, as on Linux withkernel.unprivileged_bpf_disabled=2.boot-test initwith-- only bpf(server1, load 0.03 to 0.11): exit 33, 94 checks ok.boot-test aarch64withRK_AARCH64_TESTS=initand-- only bpf(server2, load 5.4 to 5.7): pass, 94 checks ok.xtask: the sdbpf boot test runs the systemd unit tests for cgroup BPF…
tamnd commentedon Nov 12, 2026
#705 adds the
sdbpfboot test. It runs test-bpf-devices, test-bpf-firewall and test-bpf-foreign-programs of systemd, which useBPF_PROG_ATTACH,BPF_PROG_DETACH,BPF_PROG_QUERYandBPF_LINK_CREATEwith the effective arrays. The kernel needed no change.sdbpfon server1: the three tests exit 0,rk-sdbpf: pass, QEMU exit 1. Load average 2.1 to 3.4.-- only bpfon server1: exit 33, 94 ok. Load average 0.03 to 0.11.-- only bpfon server2: pass, 94 ok. Load average 5.4 to 5.7. xtask has no systemd tests on arm64.Remaining: systemd logs "Failed to get cgroup ID ... Operation not supported", probably from
name_to_handle_aton cgroupfs. systemd ignores it.tamnd commentedon Nov 12, 2026
All items of this issue are done. The last PR is #705. The verifier is in #701, the interpreter in #678 and #686, and bpffs and the systemd checks in #607, #614, #630 and #632. Release 0.5.23 has #701, and the next release will have #705.