public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Hannes Laimer <h.laimer@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: superseded: [PATCH proxmox v6 0/6] add proxmox-ebpf library
Date: Wed, 4 Nov 2026 17:02:40 +0100	[thread overview]
Message-ID: <b9d6f97b-5a54-4ce6-b3b9-c834701e77ea@proxmox.com> (raw)
In-Reply-To: <20261104134905.1623451-1-h.laimer@proxmox.com>

superseded-by:
https://lore.proxmox.com/pve-devel/20261104160105.2184145-1-h.laimer@proxmox.com/

On 2026-11-04 14:50, Hannes Laimer wrote:
> proxmox-ebpf holds the eBPF programs and the code that loads, attaches
> and updates them, grouped into subsystems. It is a library only, whoever
> needs a subsystem pulls in just that one through a cargo feature and
> calls it from their side. This series is the shared part, the actual
> subsystems come as their own series on top.
> 
> The core is the shared subsystem code. It takes care of everything from
> loading and attaching per interface to pinning in bpffs and tearing down
> again. So nothing has to keep running, and each call picks up where the
> last one left off. The build records a hash of the compiled object and a
> schema version per subsystem, so a call can tell what changed. A changed
> program or map schema is swapped onto the existing links without
> interrupting traffic. The new maps are filled before the links move onto
> them. The BPF C code is also built natively against a small shim, so the
> parsing and packet building logic can be tested without a kernel.
> Packaging is debcargo like the other Rust crates.
> 
> Every change runs under a lock per subsystem, a full apply takes it
> exclusively and a single-interface step shared, like the pmxcfs domain
> locks. The holder reads the input of its change under the lock and
> writes before it lets go. So a change and a full apply reach the kernel
> in the order they read their input, and nothing has to order them after
> the fact. A holder that never returns makes the waiters time out instead
> of hanging them. A subsystem can also hand over the whole content of its
> maps. The programs then move onto the new content one link at a time and
> never read a mix of old and new entries, and a write the kernel refuses
> leaves the old content in place. The programs of different subsystems on
> one interface run in a fixed order. An attach places its link relative
> to the links the other subsystems already hold there, so the order holds
> however the attaches are timed, and an update keeps every link in its
> place.
> 
> The crate goes into the proxmox workspace, as the first one there with a
> build script. Building needs clang-21, libbpf-dev and
> proxmox-kernel-libc-dev, the programs compile against the UAPI headers
> from there.
> 
> v6:
>  * loop all links at the start of every replace, moving links to live/
>    is done one-by-one, so it can fail. a failed pass then has some links
>    still on staging/, this makes sure we dont delete state that may
>    still be attached. the kernel checks if it already exists on a swap,
>    so this is a no-op, and at worst an atomic swap for links that still
>    has staging/ attached
>  * only allow adding to the run order, at least for live updates.
>    removal or re-orders are applied on the next reboot
>  * enforce that map refs live as long as the lock they were taken under
>  * a pin that cannot be opened stays and fails the step instead of
>    being unlinked, which under a descriptor shortage detached a working
>    link
>  * the harness tests run a C program of their own against the shim
>  * move the crate into the proxmox workspace, the vendored vmlinux.h is
>    gone, the programs build against the UAPI headers of
>    proxmox-kernel-libc-dev with a versioned clang
> 
> v5:
>  * add a call that replaces the maps as a whole, it uses more space and
>    writes everything instead of only what changed, but leaves the old
>    content in place instead of a mix, in cases where the write fails
>    with ENOMEM. Subsystems choose which they need
>  * install/upgrade now also use this newly added replace path, this
>    simplifies the process and also closes a hole where attached programs
>    would read empty maps, shortly before they were filled after a schema
>    version bump
>  * the run order of the subsystems is written to
>    `/run/proxmox-ebpf/order` by a full apply and every attach places by
>    it, so a stale process running an older version attaches correctly
>    against subsystems added by a process running a newer version
>  * set correct permissions on `/run/..`
>  * a build whose schema is older than the pinned one no longer counts
>    its state as current, so its single steps back off as well
>  * add `interrupted()` on the lock guard, true when a replacement left
>    its staged set or an old schema directory behind, a full pass
>    replaces then
>  * an attach checks after attaching that the interface still has the
>    index of its pin, one recreated under the same name in between is
>    reported as gone
>  * a map missing from a pinned set is reported by name
> 
> v4, thanks @Stefan!:
>  * drop the generation counter, a change takes the apply lock before it
>    reads its input instead, so the lock order is the input order
>  * new, the links of different subsystems on an interface are now
>    ordered
>  * the tc link plumbing is its own commit ahead of the subsystem code
>  * subsystem programs are now a list of direction and name pairs
>  * add short note for why not proxmox-sys's locking
>  * improve tc error handling
>  * fix smaller spacing and code stuff
> 
> 
> proxmox:
> 
> Hannes Laimer (6):
>   ebpf: add the crate with its BPF build
>   ebpf: tc: add the link plumbing
>   ebpf: subsystem: add the shared tc program handling
>   ebpf: subsystem: place the links of different subsystems in a fixed
>     order
>   ebpf: tests: add a native harness for the BPF C programs
>   ebpf: debian: package the crate as a Rust library
> 
>  Cargo.toml                                  |    2 +
>  proxmox-ebpf/Cargo.toml                     |   22 +
>  proxmox-ebpf/build.rs                       |  190 +++
>  proxmox-ebpf/debian/changelog               |    5 +
>  proxmox-ebpf/debian/control                 |   50 +
>  proxmox-ebpf/debian/copyright               |   18 +
>  proxmox-ebpf/debian/debcargo.toml           |   13 +
>  proxmox-ebpf/include/bpf_debug.h            |   12 +
>  proxmox-ebpf/src/bpf-shim/bpf/bpf_endian.h  |   15 +
>  proxmox-ebpf/src/bpf-shim/bpf/bpf_helpers.h |   32 +
>  proxmox-ebpf/src/bpf-shim/bpf_debug.h       |   10 +
>  proxmox-ebpf/src/bpf-shim/linux/bpf.h       |   25 +
>  proxmox-ebpf/src/lib.rs                     |    6 +
>  proxmox-ebpf/src/subsystem.rs               | 1207 +++++++++++++++++++
>  proxmox-ebpf/src/tc.rs                      |  323 +++++
>  proxmox-ebpf/tests/bpf/fixture.bpf.c        |   37 +
>  proxmox-ebpf/tests/common/mod.rs            |  211 ++++
>  proxmox-ebpf/tests/harness.rs               |   84 ++
>  18 files changed, 2262 insertions(+)
>  create mode 100644 proxmox-ebpf/Cargo.toml
>  create mode 100644 proxmox-ebpf/build.rs
>  create mode 100644 proxmox-ebpf/debian/changelog
>  create mode 100644 proxmox-ebpf/debian/control
>  create mode 100644 proxmox-ebpf/debian/copyright
>  create mode 100644 proxmox-ebpf/debian/debcargo.toml
>  create mode 100644 proxmox-ebpf/include/bpf_debug.h
>  create mode 100644 proxmox-ebpf/src/bpf-shim/bpf/bpf_endian.h
>  create mode 100644 proxmox-ebpf/src/bpf-shim/bpf/bpf_helpers.h
>  create mode 100644 proxmox-ebpf/src/bpf-shim/bpf_debug.h
>  create mode 100644 proxmox-ebpf/src/bpf-shim/linux/bpf.h
>  create mode 100644 proxmox-ebpf/src/lib.rs
>  create mode 100644 proxmox-ebpf/src/subsystem.rs
>  create mode 100644 proxmox-ebpf/src/tc.rs
>  create mode 100644 proxmox-ebpf/tests/bpf/fixture.bpf.c
>  create mode 100644 proxmox-ebpf/tests/common/mod.rs
>  create mode 100644 proxmox-ebpf/tests/harness.rs
> 
> 
> Summary over all repositories:
>   18 files changed, 2262 insertions(+), 0 deletions(-)
> 





      parent reply	other threads:[~2026-11-04 16:02 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-04 13:48 [PATCH proxmox v6 0/6] add proxmox-ebpf library Hannes Laimer
2026-11-04 13:49 ` [PATCH proxmox v6 1/6] ebpf: add the crate with its BPF build Hannes Laimer
2026-11-04 13:49 ` [PATCH proxmox v6 2/6] ebpf: tc: add the link plumbing Hannes Laimer
2026-11-04 13:49 ` [PATCH proxmox v6 3/6] ebpf: subsystem: add the shared tc program handling Hannes Laimer
2026-11-04 13:49 ` [PATCH proxmox v6 4/6] ebpf: subsystem: place the links of different subsystems in a fixed order Hannes Laimer
2026-11-04 13:49 ` [PATCH proxmox v6 5/6] ebpf: tests: add a native harness for the BPF C programs Hannes Laimer
2026-11-04 13:49 ` [PATCH proxmox v6 6/6] ebpf: debian: package the crate as a Rust library Hannes Laimer
2026-11-04 16:02 ` Hannes Laimer [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b9d6f97b-5a54-4ce6-b3b9-c834701e77ea@proxmox.com \
    --to=h.laimer@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal