public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [PATCH manager/network/proxmox{-ebpf,-perl-rs} 00/12] sdn: implement DHCP for all zones using eBPF
@ 2026-09-04  9:38 Hannes Laimer
  2026-09-04  9:38 ` [PATCH proxmox-ebpf 01/12] dhcp: add per-tap responder BPF program Hannes Laimer
                   ` (11 more replies)
  0 siblings, 12 replies; 14+ messages in thread
From: Hannes Laimer @ 2026-09-04  9:38 UTC (permalink / raw)
  To: pve-devel

Adds a second DHCP backend, `ebpf`, next to dnsmasq, selectable per
zone. It aims to replace dnsmasq eventually, for now it is a second
implementation, which keeps a migration simple. Every zone type can
enable DHCP through a dropdown selector, `dnsmasq` stays limited to
simple zones.

The responder is a subsystem of `proxmox-ebpf` [1], Perl reaches it
through new pve-rs bindings (PVE::RS::SDN::Dhcp), so the pve-network
patches need the pve-rs of this series.

Currently only supports DHCPv4, but adding v6 is very possible once
we're happy with the overall design.

# How
An eBPF program on the ingress of every guest tap parses DHCP requests,
looks the client MAC up in a mac -> ip+options map and rewrites the
request into the reply in place, redirected back out of the tap. The
exchange never reaches the bridge. Everything else, including MACs
without a map entry, passes untouched, so attaching is a no-op for
unmanaged MACs.

IPAM is the source of the assignments, the map is a per-node copy of
the records. Every trigger below runs the same full pass, the plugin
collects all records of the ebpf zones and the guest interfaces on
their vnets, the responder diffs both against the kernel state, so
programs, links and records converge from any starting point:
 - guest start / NIC hotplug / migration: add_dhcp_mapping already
   fires here, before the interface is plugged, a new tap_plug hook of
   the dhcp plugins then attaches the program.
 - mapping create/update/delete through the API: the editing node runs
   it and pokes the node running the guest to do the same through a
   new node endpoint (POST /nodes/{node}/sdn/dhcp-mapping), detached
   from the request. Best effort, an unreachable node catches up on its
   next apply or the guest's next start.
 - SDN apply: also refreshes the programs, a rebuild on a schema change
   is refilled in the same pass, and a zone switching its backend takes
   effect for running guests too.
 - boot: nothing is pinned, the first pass after boot loads the
   programs and fills the map.

Subnets get a `dhcp-lease-time` property, used by both backends,
dnsmasq keeps handing out infinite leases without it and the responder
defaults to ten minutes. The responder identifies itself with the
subnet gateway, so a subnet without one is not served, and it hands out
IPv4 resolvers only, a v6 one configured on a v4 subnet is left out of
the answers.

Changes made directly on an external IPAM service are not detectable
and the per-MAC answers are cached, so they are not picked up on apply
either, exactly like with dnsmasq today.

The pve-network patches apply on top of the separately posted patch
pushing ipam API mapping changes to the dhcp backend [2].

pre-build packages are on sani(`packages/ebpf-dhcp-v1`)

since the RFC:
 - every trigger runs the same full pass instead of per-trigger map
   updates, the responder diffs programs, links and records against
   the kernel state, so a schema rebuild is refilled by the pass that
   caused it and a zone switching to ebpf serves its running guests
 - the guest node is poked through a node endpoint, not all nodes
 - the tap plug goes through a hook of the dhcp plugin base
 - the bridge-change paths of guests push their record changes too
 - the records are collected under the macdb lock
 - a v6 resolver on a v4 subnet is left out instead of failing the
   pass, a subnet without a gateway is skipped with a warning
 - dnsmasq honours dhcp-lease-time as well
 - the mapping push endpoint checks the vnet belongs to the zone


[1] https://lore.proxmox.com/pve-devel/20260904090458.990888-1-h.laimer@proxmox.com/T/#t 
[2] https://lore.proxmox.com/pve-devel/20260902125357.757029-1-h.laimer@proxmox.com/T/#u


proxmox-ebpf:

Hannes Laimer (2):
  dhcp: add per-tap responder BPF program
  dhcp: add responder subsystem

 Cargo.toml              |   5 +
 debian/control          |   6 +-
 src/dhcp/bpf/dhcp.bpf.c | 324 +++++++++++++++++++
 src/dhcp/bpf/types.h    |  25 ++
 src/dhcp/mod.rs         | 247 +++++++++++++++
 src/dhcp/types.rs       |  53 ++++
 src/lib.rs              |   3 +
 tests/dhcp.rs           | 668 ++++++++++++++++++++++++++++++++++++++++
 8 files changed, 1330 insertions(+), 1 deletion(-)
 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 dhcp responder bindings

 pve-rs/Cargo.toml               |  2 +
 pve-rs/Makefile                 |  1 +
 pve-rs/debian/control           |  2 +
 pve-rs/src/bindings/sdn/dhcp.rs | 81 +++++++++++++++++++++++++++++++++
 pve-rs/src/bindings/sdn/mod.rs  |  1 +
 5 files changed, 87 insertions(+)
 create mode 100644 pve-rs/src/bindings/sdn/dhcp.rs


pve-network:

Hannes Laimer (8):
  sdn: ipam: do not cache negative per-MAC answers, lock the write
  sdn: subnets: add dhcp-lease-time property
  sdn: dhcp: only assert a backend's availability for zones using it
  sdn: dhcp: add ebpf plugin
  sdn: zones: attach the dhcp responder on tap plug
  sdn: dhcp: apply mapping edits on the node serving the guest
  sdn: zones: offer dhcp on all zone types, keep dnsmasq simple-only
  tests: cover the ebpf dhcp backend and ipam API mapping pushes

 src/PVE/API2/Network/SDN/Ips.pm           |   3 +
 src/PVE/API2/Network/SDN/Nodes/Status.pm  |  42 +++-
 src/PVE/API2/Network/SDN/Zones.pm         |   8 +-
 src/PVE/Network/SDN/Dhcp.pm               |  87 +++++++-
 src/PVE/Network/SDN/Dhcp/Dnsmasq.pm       |   3 +-
 src/PVE/Network/SDN/Dhcp/Ebpf.pm          | 187 ++++++++++++++++++
 src/PVE/Network/SDN/Dhcp/Makefile         |   2 +-
 src/PVE/Network/SDN/Dhcp/Plugin.pm        |   6 +
 src/PVE/Network/SDN/Ipams.pm              |  24 ++-
 src/PVE/Network/SDN/SubnetPlugin.pm       |   9 +
 src/PVE/Network/SDN/Zones.pm              |   3 +
 src/PVE/Network/SDN/Zones/EvpnPlugin.pm   |   1 +
 src/PVE/Network/SDN/Zones/FaucetPlugin.pm |   1 +
 src/PVE/Network/SDN/Zones/QinQPlugin.pm   |   7 +
 src/PVE/Network/SDN/Zones/VlanPlugin.pm   |   7 +
 src/PVE/Network/SDN/Zones/VxlanPlugin.pm  |   9 +
 src/test/run_test_vnets_blackbox.pl       | 231 ++++++++++++++++++++++
 17 files changed, 619 insertions(+), 11 deletions(-)
 create mode 100644 src/PVE/Network/SDN/Dhcp/Ebpf.pm


pve-manager:

Hannes Laimer (1):
  ui: sdn: dhcp backend selector on all zones, expose dhcp options

 www/manager6/sdn/SubnetEdit.js       | 24 ++++++++++++++++++++++++
 www/manager6/sdn/zones/Base.js       | 17 +++++++++++++++++
 www/manager6/sdn/zones/SimpleEdit.js | 11 -----------
 3 files changed, 41 insertions(+), 11 deletions(-)


Summary over all repositories:
  33 files changed, 2077 insertions(+), 23 deletions(-)

-- 
Generated by murpp 0.12.0




^ permalink raw reply	[flat|nested] 14+ messages in thread
* [RFC manager/network/proxmox{-ebpf,-perl-rs} 00/12] sdn: implement DHCP for all zones using eBPF
@ 2026-09-02 12:47 Hannes Laimer
  2026-09-02 12:47 ` [PATCH pve-network 11/12] tests: cover the ebpf dhcp backend and ipam API mapping pushes Hannes Laimer
  0 siblings, 1 reply; 14+ messages in thread
From: Hannes Laimer @ 2026-09-02 12:47 UTC (permalink / raw)
  To: pve-devel

Adds a second DHCP backend, `ebpf`, next to dnsmasq, selectable per
zone. It aims to replace dnsmasq eventually, for now it is a second
implementation, which keeps a migration simple. Every zone type can
enable DHCP through a dropdown selector, `dnsmasq` stays limited to
simple zones.

The responder is a subsystem of `proxmox-ebpf` [1], Perl reaches it
through new pve-rs bindings (PVE::RS::SDN::Dhcp), so the pve-network
patches need the pve-rs of this series.

Currently only supports DHCPv4, but adding v6 is very possible once we're happy
with the overall design.

# How
An eBPF program on the ingress of every guest tap parses DHCP requests,
looks the client MAC up in a mac -> ip+options map and rewrites the
request into the reply in place, redirected back out of the tap. The
exchange never reaches the bridge. Everything else, including MACs
without a map entry, passes untouched, so attaching is a no-op for
unmanaged MACs.

IPAM is the source of the assignments, the map is a per-node copy of
the records, kept current by:
 - guest start / NIC hotplug / migration: add_dhcp_mapping already
   fires here and pushes the MAC's record before the interface is
   plugged, tap_plug then attaches the program.
 - mapping create/update/delete through the API: the editing node
   updates its own map and pokes the node running the guest to do the
   same, detached from the request. Best effort, an unreachable node
   catches up on its next apply or the guest's next start.
 - SDN apply: refreshes the programs, drops the link pins of departed
   guests and rebuilds the map from the current records.
 - boot: maps start empty, every guest start seeds its own record.

Changes made directly on an external IPAM service are not detectable
and the per-MAC answers are cached, so they are not picked up on apply
either, exactly like with dnsmasq today.

The pve-network part applies on top of the separately posted patch
pushing ipam API mapping changes to the dhcp backend. Its first
patches are preparatory, no negative per-MAC cache entries and a
locked cache write, a lease time property on subnets, and asserting a
backend's availability only for zones using it.

[1] https://lore.proxmox.com/pve-devel/8d63974f-0a73-480b-9407-c6bdc2d576d7@proxmox.com


proxmox-ebpf:

Hannes Laimer (2):
  dhcp: add per-tap responder BPF program
  dhcp: add responder subsystem

 Cargo.toml              |   5 +
 debian/control          |   6 +-
 src/dhcp/bpf/dhcp.bpf.c | 324 +++++++++++++++++++
 src/dhcp/bpf/types.h    |  25 ++
 src/dhcp/mod.rs         | 288 +++++++++++++++++
 src/dhcp/types.rs       |  53 ++++
 src/lib.rs              |   3 +
 src/subsystem.rs        |  35 +++
 tests/dhcp.rs           | 668 ++++++++++++++++++++++++++++++++++++++++
 9 files changed, 1406 insertions(+), 1 deletion(-)
 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 dhcp responder bindings

 pve-rs/Cargo.toml               |  2 +
 pve-rs/Makefile                 |  1 +
 pve-rs/debian/control           |  2 +
 pve-rs/src/bindings/sdn/dhcp.rs | 91 +++++++++++++++++++++++++++++++++
 pve-rs/src/bindings/sdn/mod.rs  |  1 +
 5 files changed, 97 insertions(+)
 create mode 100644 pve-rs/src/bindings/sdn/dhcp.rs


pve-network:

Hannes Laimer (8):
  sdn: ipam: do not cache negative per-MAC answers, lock the write
  sdn: subnets: add dhcp-lease-time property
  sdn: dhcp: only assert a backend's availability for zones using it
  sdn: dhcp: add ebpf plugin
  sdn: zones: attach the dhcp responder on tap plug
  sdn: dhcp: apply mapping edits on the node serving the guest
  sdn: zones: offer dhcp on all zone types, keep dnsmasq simple-only
  tests: cover the ebpf dhcp backend and ipam API mapping pushes

 src/PVE/API2/Network/SDN/Ips.pm           |   5 +-
 src/PVE/API2/Network/SDN/Nodes/Status.pm  |  37 ++++-
 src/PVE/API2/Network/SDN/Zones.pm         |   8 +-
 src/PVE/Network/SDN/Dhcp.pm               |  87 ++++++++++-
 src/PVE/Network/SDN/Dhcp/Ebpf.pm          | 173 ++++++++++++++++++++++
 src/PVE/Network/SDN/Dhcp/Makefile         |   2 +-
 src/PVE/Network/SDN/Ipams.pm              |  20 ++-
 src/PVE/Network/SDN/SubnetPlugin.pm       |   7 +
 src/PVE/Network/SDN/Zones.pm              |   4 +
 src/PVE/Network/SDN/Zones/EvpnPlugin.pm   |   1 +
 src/PVE/Network/SDN/Zones/FaucetPlugin.pm |   1 +
 src/PVE/Network/SDN/Zones/QinQPlugin.pm   |   7 +
 src/PVE/Network/SDN/Zones/VlanPlugin.pm   |   7 +
 src/PVE/Network/SDN/Zones/VxlanPlugin.pm  |   9 ++
 src/test/run_test_vnets_blackbox.pl       | 147 ++++++++++++++++++
 15 files changed, 502 insertions(+), 13 deletions(-)
 create mode 100644 src/PVE/Network/SDN/Dhcp/Ebpf.pm


pve-manager:

Hannes Laimer (1):
  ui: sdn: dhcp backend selector on all zones, expose dhcp options

 www/manager6/sdn/SubnetEdit.js       | 24 ++++++++++++++++++++++++
 www/manager6/sdn/zones/Base.js       | 17 +++++++++++++++++
 www/manager6/sdn/zones/SimpleEdit.js | 11 -----------
 3 files changed, 41 insertions(+), 11 deletions(-)


Summary over all repositories:
  32 files changed, 2046 insertions(+), 25 deletions(-)

-- 
Generated by murpp 0.12.0




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

end of thread, other threads:[~2026-09-04  9:40 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-04  9:38 [PATCH manager/network/proxmox{-ebpf,-perl-rs} 00/12] sdn: implement DHCP for all zones using eBPF Hannes Laimer
2026-09-04  9:38 ` [PATCH proxmox-ebpf 01/12] dhcp: add per-tap responder BPF program Hannes Laimer
2026-09-04  9:38 ` [PATCH proxmox-ebpf 02/12] dhcp: add responder subsystem Hannes Laimer
2026-09-04  9:38 ` [PATCH proxmox-perl-rs 03/12] pve-rs: sdn: add dhcp responder bindings Hannes Laimer
2026-09-04  9:38 ` [PATCH pve-network 04/12] sdn: ipam: do not cache negative per-MAC answers, lock the write Hannes Laimer
2026-09-04  9:38 ` [PATCH pve-network 05/12] sdn: subnets: add dhcp-lease-time property Hannes Laimer
2026-09-04  9:38 ` [PATCH pve-network 06/12] sdn: dhcp: only assert a backend's availability for zones using it Hannes Laimer
2026-09-04  9:38 ` [PATCH pve-network 07/12] sdn: dhcp: add ebpf plugin Hannes Laimer
2026-09-04  9:38 ` [PATCH pve-network 08/12] sdn: zones: attach the dhcp responder on tap plug Hannes Laimer
2026-09-04  9:38 ` [PATCH pve-network 09/12] sdn: dhcp: apply mapping edits on the node serving the guest Hannes Laimer
2026-09-04  9:38 ` [PATCH pve-network 10/12] sdn: zones: offer dhcp on all zone types, keep dnsmasq simple-only Hannes Laimer
2026-09-04  9:38 ` [PATCH pve-network 11/12] tests: cover the ebpf dhcp backend and ipam API mapping pushes Hannes Laimer
2026-09-04  9:38 ` [PATCH pve-manager 12/12] ui: sdn: dhcp backend selector on all zones, expose dhcp options Hannes Laimer
  -- strict thread matches above, loose matches on Subject: below --
2026-09-02 12:47 [RFC manager/network/proxmox{-ebpf,-perl-rs} 00/12] sdn: implement DHCP for all zones using eBPF Hannes Laimer
2026-09-02 12:47 ` [PATCH pve-network 11/12] tests: cover the ebpf dhcp backend and ipam API mapping pushes 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