From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id 36ADF1FF0B3 for ; Wed, 09 Sep 2026 12:45:04 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id B8898215AA; Wed, 09 Sep 2026 12:44:28 +0200 (CEST) Message-ID: Date: Wed, 9 Sep 2026 12:43:36 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: superseded: [PATCH manager/network/proxmox{-ebpf,-perl-rs} 00/12] sdn: implement DHCP for all zones using eBPF To: pve-devel@lists.proxmox.com References: <20260904093835.1050030-1-h.laimer@proxmox.com> From: Hannes Laimer Content-Language: en-US In-Reply-To: <20260904093835.1050030-1-h.laimer@proxmox.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1788950608791 X-SPAM-LEVEL: Spam detection results: 0 AWL -1.134 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) POISEN_SPAM_PILL 0.1 Meta: its spam POISEN_SPAM_PILL_1 0.1 random spam to be learned in bayes POISEN_SPAM_PILL_3 0.1 random spam to be learned in bayes RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLACK 3 Contains an URL listed in the URIBL blacklist [types.rs] Message-ID-Hash: X7EPSI5QO4BVJU6LI2LFGZQ5OZFWEM3Y X-Message-ID-Hash: X7EPSI5QO4BVJU6LI2LFGZQ5OZFWEM3Y X-MailFrom: h.laimer@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: superseded-by: https://lore.proxmox.com/pve-devel/20260909104144.1110031-1-h.laimer@proxmox.com/T/#t On 2026-09-04 11:38, Hannes Laimer wrote: > 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(-) >