public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [PATCH container/docs/manager/network/proxmox{-ebpf,-perl-rs,-ve-rs}/qemu-server v5 00/15] sdn: implement DHCP for all zones using eBPF
@ 2026-11-02 15:18 Hannes Laimer
  2026-11-02 15:18 ` [PATCH proxmox-ebpf v5 01/15] dhcp: add the per-tap DHCPv4 responder program Hannes Laimer
                   ` (14 more replies)
  0 siblings, 15 replies; 16+ messages in thread
From: Hannes Laimer @ 2026-11-02 15:18 UTC (permalink / raw)
  To: pve-devel

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 is proxied to the
guest's node and updates the backend there. 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. An apply 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 VXLAN and EVPN MTU taken from the underlay
   interface, the ebpf backend, the hooks that keep a backend current
   when a guest interface changes, and dhcp on every zone type
 - qemu-server and pve-container, the reports of a guest NIC coming,
   going or moving
 - pve-manager, the backend and subnet options in the UI, and the
   backends brought up at boot ahead of the guests
 - proxmox-ve-rs, the ebpf variant of the dhcp backend type
 - pve-docs, documentation

 - proxmox-ebpf applies on top of the v5 of its own series [1]
 - pve-network and qemu-server apply on top of [2]
 - 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
 - proxmox-ve-config needs nothing, and proxmox-firewall needs its
   dependency on it bumped, since an older one fails to parse a zone
   with the ebpf backend and the firewall then cannot load its config
An older pve-network fails its apply on the unknown backend, so every
node needs the new one before a zone gets ebpf.


v5:
 * rebased onto ebpf-lib v5 [1]
 * the MAC cache and dnsmasq fixes moved to [2], as did running a
   mapping edit on the guest's node and the push on resume
 * a mapping edit only changes the answers on its own vnet
 * the VXLAN and EVPN bridges get the MTU that DHCP hands out, both
   take it from the underlay interface
 * a MAC change on the same vnet is no longer undone by an apply
   running meanwhile

v4, thanks @Stefan!:
 * a mapping edit runs on the guest's node instead of being pushed to
   it, the node endpoint is gone
 * the MAC cache is read and written with lower-case keys, and its
   three fixes are three commits
 * the guest NIC list is keyed by MAC
 * add the missing proxmox-ve-rs patch, the ebpf variant of the dhcp
   backend type
 * reword log lines and warnings
 * (notes on patches with changes)

v3:
 * 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 are on sani(`packages/ebpf-dhcp-v5`)

[1] https://lore.proxmox.com/pve-devel/20261102150047.1584789-1-h.laimer@proxmox.com/
[2] https://lore.proxmox.com/pve-devel/20261102145630.1555953-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                | 1131 ++++++++++++++++++++++++++++++++
 src/dhcp/types.rs              |   65 ++
 src/lib.rs                     |    3 +
 src/subsystem.rs               |    2 +-
 tests/common/mod.rs            |   63 +-
 tests/dhcp.rs                  |  825 +++++++++++++++++++++++
 12 files changed, 2523 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 | 237 ++++++++++++++++++++++++++++++++
 pve-rs/src/bindings/sdn/mod.rs  |   1 +
 5 files changed, 245 insertions(+)
 create mode 100644 pve-rs/src/bindings/sdn/dhcp.rs


pve-network:

Hannes Laimer (6):
  sdn: zones: take the VXLAN and EVPN MTU from the underlay interface
  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: zones: allow the ebpf DHCP backend on every zone type

 debian/libpve-network-perl.prerm              |  13 +
 src/PVE/API2/Network/SDN/Zones.pm             |  11 +-
 src/PVE/Network/SDN/Dhcp.pm                   | 103 +-
 src/PVE/Network/SDN/Dhcp/Dnsmasq.pm           |   3 +-
 src/PVE/Network/SDN/Dhcp/Ebpf.pm              | 301 ++++++
 src/PVE/Network/SDN/Dhcp/Makefile             |   2 +-
 src/PVE/Network/SDN/Dhcp/Plugin.pm            |  24 +-
 src/PVE/Network/SDN/SubnetPlugin.pm           |  11 +
 src/PVE/Network/SDN/Vnets.pm                  |   2 +-
 src/PVE/Network/SDN/Zones.pm                  |  29 +-
 src/PVE/Network/SDN/Zones/EvpnPlugin.pm       |  40 +-
 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      |  31 +-
 src/test/run_test_vnets_blackbox.pl           | 999 +++++++++++++++++-
 .../underlay_mtu/expected_controller_config   |  44 +
 .../evpn/underlay_mtu/expected_sdn_interfaces |  42 +
 src/test/zones/evpn/underlay_mtu/interfaces   |   8 +
 src/test/zones/evpn/underlay_mtu/sdn_config   |  26 +
 .../underlay_mtu/expected_sdn_interfaces      |  15 +
 src/test/zones/vxlan/underlay_mtu/interfaces  |   8 +
 src/test/zones/vxlan/underlay_mtu/sdn_config  |  11 +
 24 files changed, 1704 insertions(+), 36 deletions(-)
 create mode 100755 debian/libpve-network-perl.prerm
 create mode 100644 src/PVE/Network/SDN/Dhcp/Ebpf.pm
 create mode 100644 src/test/zones/evpn/underlay_mtu/expected_controller_config
 create mode 100644 src/test/zones/evpn/underlay_mtu/expected_sdn_interfaces
 create mode 100644 src/test/zones/evpn/underlay_mtu/interfaces
 create mode 100644 src/test/zones/evpn/underlay_mtu/sdn_config
 create mode 100644 src/test/zones/vxlan/underlay_mtu/expected_sdn_interfaces
 create mode 100644 src/test/zones/vxlan/underlay_mtu/interfaces
 create mode 100644 src/test/zones/vxlan/underlay_mtu/sdn_config


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                    | 4 ++--
 src/test/hotplug/net-change-bridge.conf.expected | 3 ++-
 src/usr/pve-bridge                               | 8 +++++++-
 src/usr/pve-bridgedown                           | 4 ++--
 6 files changed, 19 insertions(+), 8 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                   |  4 ++++
 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, 45 insertions(+), 11 deletions(-)


proxmox-ve-rs:

Hannes Laimer (1):
  ve-config: sdn: add the ebpf dhcp backend

 proxmox-ve-config/src/sdn/config.rs | 3 +++
 1 file changed, 3 insertions(+)


pve-docs:

Hannes Laimer (1):
  sdn: dhcp: add eBPF backend section

 pvesdn.adoc | 127 ++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 98 insertions(+), 29 deletions(-)


Summary over all repositories:
  57 files changed, 4653 insertions(+), 96 deletions(-)

-- 
Generated by murpp 0.12.0




^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2026-11-02 15:21 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-02 15:18 [PATCH container/docs/manager/network/proxmox{-ebpf,-perl-rs,-ve-rs}/qemu-server v5 00/15] sdn: implement DHCP for all zones using eBPF Hannes Laimer
2026-11-02 15:18 ` [PATCH proxmox-ebpf v5 01/15] dhcp: add the per-tap DHCPv4 responder program Hannes Laimer
2026-11-02 15:18 ` [PATCH proxmox-ebpf v5 02/15] dhcp: add the subsystem that loads the responder and keeps its records Hannes Laimer
2026-11-02 15:18 ` [PATCH proxmox-perl-rs v5 03/15] pve-rs: sdn: add bindings for the eBPF DHCP responder Hannes Laimer
2026-11-02 15:18 ` [PATCH pve-network v5 04/15] sdn: zones: take the VXLAN and EVPN MTU from the underlay interface Hannes Laimer
2026-11-02 15:18 ` [PATCH pve-network v5 05/15] sdn: dhcp: make the lease time configurable per subnet Hannes Laimer
2026-11-02 15:18 ` [PATCH pve-network v5 06/15] sdn: dhcp: require a backend only if a zone on this node uses it Hannes Laimer
2026-11-02 15:18 ` [PATCH pve-network v5 07/15] sdn: dhcp: add an eBPF backend answering on each guest interface Hannes Laimer
2026-11-02 15:18 ` [PATCH pve-network v5 08/15] sdn: zones: report interface plugs and unplugs to the DHCP backends Hannes Laimer
2026-11-02 15:18 ` [PATCH pve-network v5 09/15] sdn: zones: allow the ebpf DHCP backend on every zone type Hannes Laimer
2026-11-02 15:18 ` [PATCH qemu-server v5 10/15] network: sdn: keep the DHCP backends current on guest NICs Hannes Laimer
2026-11-02 15:18 ` [PATCH pve-container v5 11/15] net: report NIC plugs and removals to the SDN DHCP backends Hannes Laimer
2026-11-02 15:18 ` [PATCH pve-manager v5 12/15] ui: sdn: add zone DHCP backend selector and subnet DHCP options Hannes Laimer
2026-11-02 15:18 ` [PATCH pve-manager v5 13/15] sdn: bring up the DHCP backends at boot before the guests start Hannes Laimer
2026-11-02 15:18 ` [PATCH proxmox-ve-rs v5 14/15] ve-config: sdn: add the ebpf dhcp backend Hannes Laimer
2026-11-02 15:18 ` [PATCH pve-docs v5 15/15] sdn: dhcp: add eBPF backend section Hannes Laimer

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