From: Hannes Laimer <h.laimer@proxmox.com>
To: Stefan Hanreich <s.hanreich@proxmox.com>, pve-devel@lists.proxmox.com
Subject: Re: [PATCH container/docs/manager/network/proxmox{-ebpf,-perl-rs}/qemu-server v3 00/17] sdn: implement DHCP for all zones using eBPF
Date: Wed, 21 Oct 2026 09:35:31 +0200 [thread overview]
Message-ID: <379a9844-db93-493b-88e6-3a2ab4c6535d@proxmox.com> (raw)
In-Reply-To: <10d049a5-09ab-4b06-8efb-5de7629df91f@proxmox.com>
On 2026-10-20 15:11, Stefan Hanreich wrote:
> Did some testing:
>
> * PVE IPAM / All zones / eBPF backend
> * PVE IPAM / Simple zone / dnsmasq backend
> * Netbox IPAM / All zones / eBPF backend
> * Netbox IPAM / Simple zone / dnsmasq backend
> * switching from dnsmasq -> eBPF and vice-versa
> -> pre-existing: dnsmasq doesn't clean its config folder
> * changing bridge on network devices
> * changing subnets on the vnet and then reacquiring a lease
>
> Everything worked really well, also the pre-existing dnsmasq zone. This
> revision seems a lot nicer already without the generation counter, which
> seemed a bit clunky. This is a more elegant solution imo.
>
> One thing I found:
>
> The new DHCP backend type needs to be added to proxmox-ve-rs as well,
> otherwise the config fails to parse (firewall). We should add fallback
> variants there...
could have caught that :) thanks!
>
> for code-related stuff see the respective patches.
Thanks for taking a look and the feedback! I'll prepare a v4
>
> On 10/20/26 10:00 AM, Hannes Laimer wrote:
>> This series adds a second DHCP backend, ebpf, next to dnsmasq. A zone
>> picks its backend. dnsmasq stays limited to simple zones, while ebpf
>> answers on the guest's own interface and works on every zone type. A
>> guest on a zone with the ebpf backend gets the address its NIC has in
>> the IPAM. There is no daemon per zone and no lease file. The answers
>> are held in the kernel and do not depend on the IPAM being reachable.
>>
>> The responder is a BPF program on the ingress of each guest interface
>> of a zone with the ebpf backend. It answers a request from the record
>> of that interface, and the exchange never reaches the bridge. A
>> request whose client MAC is not the interface's own passes on
>> unanswered. So a guest cannot read another guest's record, and a
>> nested client does not get the outer guest's address.
>>
>> An edit through /cluster/sdn/vnets/{vnet}/ips reaches the guest's node
>> by a detached call to a new node endpoint, POST
>> /nodes/{node}/sdn/dhcp-mapping. The guest sees the change at its next
>> renewal, so the lease time bounds how long an old answer survives.
>> Subnets get a dhcp-lease-time property for both backends. Without it
>> dnsmasq hands out infinite leases and the responder ten minutes. A
>> failed push is logged in the journal, and the responder on the guest's
>> node catches up at the node's next apply or the guest's next start. An
>> apply also attaches the responder to running guests, so a zone
>> switched to ebpf serves them without a restart.
>>
>> Changes reach the kernel in the order they read their input. So no
>> change overwrites a newer one with older input. A hotplug moves the
>> interface before the guest config names the new bridge. An apply or an
>> edit that read the older config in between leaves the moved interface
>> as its plug left it. A change that fails only warns, and what was
>> served stays served. Nothing of the responder survives a reboot, so it
>> is loaded again at boot before the guests start.
>>
>> Only DHCPv4 is answered. A request the guest tagged itself passes
>> unanswered as well, so a trunk port keeps working as before. The
>> request is answered on the guest interface, so the guest's firewall
>> rules, its DHCP firewall option and its rate limit do not apply to it.
>> The reply leaves through the interface's egress, where the rate limit
>> shapes it. A request the responder does not answer passes on to the
>> bridge and through the firewall as before. Mappings changed directly
>> in an external IPAM are not picked up, as with dnsmasq.
>>
>> In patch order, the series adds
>> - proxmox-ebpf, the dhcp subsystem, a tc program answering on the
>> guest interface and the per-interface map it answers from
>> - pve-rs, the bindings
>> - pve-network, the ebpf backend, the hooks that keep a backend current
>> when a guest interface or a mapping changes, dhcp on every zone
>> type, and fixes to the dnsmasq reservations and the MAC cache
>> - qemu-server and pve-container, the reports of a guest NIC coming,
>> going or moving, and for VMs the push at a migration's resume
>> - pve-manager, the backend and subnet options in the UI, and the
>> backends brought up at boot ahead of the guests
>> - pve-docs, documentation
>>
>> - proxmox-ebpf applies on top of the v4 of its own series [1]
>> - pve-rs needs proxmox-ebpf with the dhcp feature
>> - pve-network needs pve-rs, at build and run time
>> - qemu-server, pve-container and pve-manager need pve-network
>> An older pve-network fails its apply on the unknown backend, so every
>> node needs the new one before a zone gets ebpf.
>>
>> Changes since v2:
>> * drop the generation counter. Every change takes the responder's
>> lock before it reads its input instead. An edit takes it
>> exclusively
>> * the resume at the end of a live migration pushes the guest's
>> mappings again on the target, so an edit made during the migration
>> reaches it
>> * new first pve-network commit, a dnsmasq fix that replaces a stale
>> reservation of another MAC instead of dropping it
>> * no MTU option for a zone without an MTU, where v2 handed out 1500
>> * a mapping edit without a MAC no longer reaches the backends
>> * rewrite commit messages, cover letter and parts of the docs
>> * rebase onto current master
>>
>> (pre-build packages on sani)
>>
>> [1] https://lore.proxmox.com/pve-devel/20261019142413.2255644-1-h.laimer@proxmox.com/
>>
>>
>> proxmox-ebpf:
>>
>> Hannes Laimer (2):
>> dhcp: add the per-tap DHCPv4 responder program
>> dhcp: add the subsystem that loads the responder and keeps its records
>>
>> Cargo.toml | 5 +
>> debian/control | 6 +-
>> src/bpf-shim/bpf/bpf_helpers.h | 3 +
>> src/bpf-shim/vmlinux.h | 1 +
>> src/dhcp/bpf/dhcp.bpf.c | 401 +++++++++++++
>> src/dhcp/bpf/types.h | 24 +
>> src/dhcp/mod.rs | 1031 ++++++++++++++++++++++++++++++++
>> src/dhcp/types.rs | 64 ++
>> src/lib.rs | 3 +
>> src/subsystem.rs | 2 +-
>> tests/common/mod.rs | 63 +-
>> tests/dhcp.rs | 825 +++++++++++++++++++++++++
>> 12 files changed, 2422 insertions(+), 6 deletions(-)
>> create mode 100644 src/dhcp/bpf/dhcp.bpf.c
>> create mode 100644 src/dhcp/bpf/types.h
>> create mode 100644 src/dhcp/mod.rs
>> create mode 100644 src/dhcp/types.rs
>> create mode 100644 tests/dhcp.rs
>>
>>
>> proxmox-perl-rs:
>>
>> Hannes Laimer (1):
>> pve-rs: sdn: add bindings for the eBPF DHCP responder
>>
>> pve-rs/Cargo.toml | 2 +
>> pve-rs/Makefile | 3 +
>> pve-rs/debian/control | 2 +
>> pve-rs/src/bindings/sdn/dhcp.rs | 229 ++++++++++++++++++++++++++++++++
>> pve-rs/src/bindings/sdn/mod.rs | 1 +
>> 5 files changed, 237 insertions(+)
>> create mode 100644 pve-rs/src/bindings/sdn/dhcp.rs
>>
>>
>> pve-network:
>>
>> Hannes Laimer (9):
>> sdn: dhcp: replace a stale dnsmasq reservation instead of dropping it
>> sdn: dhcp: update reservations when ip mappings change
>> sdn: ipam: key the MAC cache by lower-case MAC, stop caching misses
>> sdn: dhcp: make the lease time configurable per subnet
>> sdn: dhcp: require a backend only if a zone on this node uses it
>> sdn: dhcp: add an eBPF backend answering on each guest interface
>> sdn: zones: report interface plugs and unplugs to the DHCP backends
>> sdn: dhcp: push IP mapping edits to the guest's node
>> sdn: zones: allow the ebpf DHCP backend on every zone type
>>
>> debian/libpve-network-perl.prerm | 13 +
>> src/PVE/API2/Network/SDN/Ips.pm | 10 +
>> src/PVE/API2/Network/SDN/Nodes/Status.pm | 37 +
>> src/PVE/API2/Network/SDN/Zones.pm | 11 +-
>> src/PVE/Network/SDN/Dhcp.pm | 200 ++-
>> src/PVE/Network/SDN/Dhcp/Dnsmasq.pm | 114 +-
>> src/PVE/Network/SDN/Dhcp/Ebpf.pm | 308 +++++
>> src/PVE/Network/SDN/Dhcp/Makefile | 2 +-
>> src/PVE/Network/SDN/Dhcp/Plugin.pm | 26 +-
>> src/PVE/Network/SDN/Ipams.pm | 61 +-
>> src/PVE/Network/SDN/SubnetPlugin.pm | 11 +
>> src/PVE/Network/SDN/Vnets.pm | 5 +-
>> src/PVE/Network/SDN/Zones.pm | 29 +-
>> src/PVE/Network/SDN/Zones/EvpnPlugin.pm | 32 +
>> src/PVE/Network/SDN/Zones/FaucetPlugin.pm | 1 +
>> src/PVE/Network/SDN/Zones/QinQPlugin.pm | 7 +
>> src/PVE/Network/SDN/Zones/SimplePlugin.pm | 2 +-
>> src/PVE/Network/SDN/Zones/VlanPlugin.pm | 7 +
>> src/PVE/Network/SDN/Zones/VxlanPlugin.pm | 25 +
>> src/test/run_test_vnets_blackbox.pl | 1442 ++++++++++++++++++++-
>> 20 files changed, 2263 insertions(+), 80 deletions(-)
>> create mode 100755 debian/libpve-network-perl.prerm
>> create mode 100644 src/PVE/Network/SDN/Dhcp/Ebpf.pm
>>
>>
>> qemu-server:
>>
>> Hannes Laimer (1):
>> network: sdn: keep the DHCP backends current on guest NICs
>>
>> src/PVE/CLI/qm.pm | 4 ++--
>> src/PVE/QemuServer.pm | 4 ++++
>> src/PVE/QemuServer/Network.pm | 19 +++++++++++++++++--
>> src/PVE/QemuServer/RunState.pm | 2 ++
>> src/usr/pve-bridge | 8 +++++++-
>> src/usr/pve-bridgedown | 4 ++--
>> 6 files changed, 34 insertions(+), 7 deletions(-)
>>
>>
>> pve-container:
>>
>> Hannes Laimer (1):
>> net: report NIC plugs and removals to the SDN DHCP backends
>>
>> src/PVE/LXC.pm | 13 +++++++++++--
>> src/PVE/LXC/Config.pm | 3 ++-
>> src/lxc-pve-poststop-hook | 6 +++---
>> 3 files changed, 16 insertions(+), 6 deletions(-)
>>
>>
>> pve-manager:
>>
>> Hannes Laimer (2):
>> ui: sdn: add zone DHCP backend selector and subnet DHCP options
>> sdn: bring up the DHCP backends at boot before the guests start
>>
>> bin/pve-sdn-commit | 3 +++
>> services/pve-sdn-commit.service | 1 +
>> www/manager6/sdn/SubnetEdit.js | 23 +++++++++++++++++++++++
>> www/manager6/sdn/zones/Base.js | 17 +++++++++++++++++
>> www/manager6/sdn/zones/SimpleEdit.js | 11 -----------
>> 5 files changed, 44 insertions(+), 11 deletions(-)
>>
>>
>> pve-docs:
>>
>> Hannes Laimer (1):
>> sdn: dhcp: add eBPF backend section
>>
>> pvesdn.adoc | 101 ++++++++++++++++++++++++++++++++++++++++++----------
>> 1 file changed, 83 insertions(+), 18 deletions(-)
>>
>>
>> Summary over all repositories:
>> 52 files changed, 5099 insertions(+), 128 deletions(-)
>>
>
>
>
>
>
next prev parent reply other threads:[~2026-10-21 7:35 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-20 7:59 [PATCH container/docs/manager/network/proxmox{-ebpf,-perl-rs}/qemu-server v3 00/17] sdn: implement DHCP for all zones using eBPF Hannes Laimer
2026-10-20 7:59 ` [PATCH proxmox-ebpf v3 01/17] dhcp: add the per-tap DHCPv4 responder program Hannes Laimer
2026-10-20 7:59 ` [PATCH proxmox-ebpf v3 02/17] dhcp: add the subsystem that loads the responder and keeps its records Hannes Laimer
2026-10-20 13:09 ` Stefan Hanreich
2026-10-21 7:09 ` Hannes Laimer
2026-10-20 7:59 ` [PATCH proxmox-perl-rs v3 03/17] pve-rs: sdn: add bindings for the eBPF DHCP responder Hannes Laimer
2026-10-20 13:10 ` Stefan Hanreich
2026-10-21 7:32 ` Hannes Laimer
2026-10-20 7:59 ` [PATCH pve-network v3 04/17] sdn: dhcp: replace a stale dnsmasq reservation instead of dropping it Hannes Laimer
2026-10-20 13:15 ` Stefan Hanreich
2026-10-20 7:59 ` [PATCH pve-network v3 05/17] sdn: dhcp: update reservations when ip mappings change Hannes Laimer
2026-10-20 13:42 ` Stefan Hanreich
2026-10-21 7:21 ` Hannes Laimer
2026-10-20 7:59 ` [PATCH pve-network v3 06/17] sdn: ipam: key the MAC cache by lower-case MAC, stop caching misses Hannes Laimer
2026-10-20 13:10 ` Stefan Hanreich
2026-10-21 6:17 ` Hannes Laimer
2026-10-20 7:59 ` [PATCH pve-network v3 07/17] sdn: dhcp: make the lease time configurable per subnet Hannes Laimer
2026-10-20 13:17 ` Stefan Hanreich
2026-10-20 7:59 ` [PATCH pve-network v3 08/17] sdn: dhcp: require a backend only if a zone on this node uses it Hannes Laimer
2026-10-20 13:17 ` Stefan Hanreich
2026-10-20 7:59 ` [PATCH pve-network v3 09/17] sdn: dhcp: add an eBPF backend answering on each guest interface Hannes Laimer
2026-10-20 13:10 ` Stefan Hanreich
2026-10-21 6:16 ` Hannes Laimer
2026-10-20 7:59 ` [PATCH pve-network v3 10/17] sdn: zones: report interface plugs and unplugs to the DHCP backends Hannes Laimer
2026-10-20 13:17 ` Stefan Hanreich
2026-10-20 7:59 ` [PATCH pve-network v3 11/17] sdn: dhcp: push IP mapping edits to the guest's node Hannes Laimer
2026-10-20 13:09 ` Stefan Hanreich
2026-10-21 6:44 ` Hannes Laimer
2026-10-20 8:00 ` [PATCH pve-network v3 12/17] sdn: zones: allow the ebpf DHCP backend on every zone type Hannes Laimer
2026-10-20 8:00 ` [PATCH qemu-server v3 13/17] network: sdn: keep the DHCP backends current on guest NICs Hannes Laimer
2026-10-20 13:38 ` Stefan Hanreich
2026-10-20 8:00 ` [PATCH pve-container v3 14/17] net: report NIC plugs and removals to the SDN DHCP backends Hannes Laimer
2026-10-20 13:36 ` Stefan Hanreich
2026-10-21 7:29 ` Hannes Laimer
2026-10-20 8:00 ` [PATCH pve-manager v3 15/17] ui: sdn: add zone DHCP backend selector and subnet DHCP options Hannes Laimer
2026-10-20 13:19 ` Stefan Hanreich
2026-10-20 8:00 ` [PATCH pve-manager v3 16/17] sdn: bring up the DHCP backends at boot before the guests start Hannes Laimer
2026-10-20 13:21 ` Stefan Hanreich
2026-10-21 7:17 ` Hannes Laimer
2026-10-20 8:00 ` [PATCH pve-docs v3 17/17] sdn: dhcp: add eBPF backend section Hannes Laimer
2026-10-20 13:11 ` [PATCH container/docs/manager/network/proxmox{-ebpf,-perl-rs}/qemu-server v3 00/17] sdn: implement DHCP for all zones using eBPF Stefan Hanreich
2026-10-21 7:35 ` Hannes Laimer [this message]
2026-10-21 8:46 ` superseded: " Hannes Laimer
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=379a9844-db93-493b-88e6-3a2ab4c6535d@proxmox.com \
--to=h.laimer@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
--cc=s.hanreich@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