From: Hannes Laimer <h.laimer@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: superseded: [PATCH pve-network] sdn: push mapping changes from the ipam API to the dhcp backend
Date: Sat, 5 Sep 2026 11:22:01 +0200 [thread overview]
Message-ID: <abe174b7-2b32-4010-bf1c-80d9501d500a@proxmox.com> (raw)
In-Reply-To: <20260902125357.757029-1-h.laimer@proxmox.com>
superseded-by:
https://lore.proxmox.com/pve-devel/20260905092106.10567-1-h.laimer@proxmox.com/T/#u
On 2026-09-02 14:54, Hannes Laimer wrote:
> Mapping edits through the API only wrote the IPAM record and the
> cache, the dhcp backend was never told, so dnsmasq kept serving
> stale reservations until a later guest start in the zone happened
> to sweep them.
>
> Push the MAC's current answer after each create, update and delete,
> removing the old reservation first, since a re-add alone leaves a
> stale address behind when only one of the MAC's two addresses was
> deleted. The push is best effort, the record write stays
> authoritative. Mapping removal was dispatched to the plugins but
> implemented nowhere and never called, add the dnsmasq
> implementation for it.
>
> Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
> ---
> src/PVE/API2/Network/SDN/Ips.pm | 18 ++++++++++++++++
> src/PVE/Network/SDN/Dhcp/Dnsmasq.pm | 32 ++++++++++++++++++++++++++++-
> src/PVE/Network/SDN/Dhcp/Plugin.pm | 5 +++++
> 3 files changed, 54 insertions(+), 1 deletion(-)
>
> diff --git a/src/PVE/API2/Network/SDN/Ips.pm b/src/PVE/API2/Network/SDN/Ips.pm
> index 5ff05e7..fc76c90 100644
> --- a/src/PVE/API2/Network/SDN/Ips.pm
> +++ b/src/PVE/API2/Network/SDN/Ips.pm
> @@ -13,6 +13,17 @@ use PVE::RESTHandler;
>
> use base qw(PVE::RESTHandler);
>
> +my sub update_dhcp_mapping {
> + my ($vnet, $mac) = @_;
> +
> + eval {
> + my ($ip4, $ip6) = PVE::Network::SDN::Vnets::get_ips_from_mac($vnet, $mac);
> + PVE::Network::SDN::Dhcp::remove_mapping($vnet, $mac);
> + PVE::Network::SDN::Dhcp::add_mapping($vnet, $mac, $ip4, $ip6) if $ip4 || $ip6;
> + };
> + warn "could not update dhcp mapping for $mac: $@" if $@;
> +}
> +
> __PACKAGE__->register_method({
> name => 'ipdelete',
> path => '',
> @@ -46,6 +57,8 @@ __PACKAGE__->register_method({
> eval { PVE::Network::SDN::Vnets::del_ip($vnet, $ip, '', $mac); };
> die "$@\n" if $@;
>
> + update_dhcp_mapping($vnet, $mac);
> +
> return undef;
> },
> });
> @@ -82,6 +95,8 @@ __PACKAGE__->register_method({
>
> PVE::Network::SDN::Vnets::add_ip($vnet, $ip, '', $mac, undef);
>
> + update_dhcp_mapping($vnet, $mac);
> +
> return undef;
> },
> });
> @@ -132,6 +147,9 @@ __PACKAGE__->register_method({
> }
>
> die "$error\n" if $error;
> +
> + update_dhcp_mapping($vnet, $mac);
> +
> return undef;
> },
> });
> diff --git a/src/PVE/Network/SDN/Dhcp/Dnsmasq.pm b/src/PVE/Network/SDN/Dhcp/Dnsmasq.pm
> index 477b700..4677330 100644
> --- a/src/PVE/Network/SDN/Dhcp/Dnsmasq.pm
> +++ b/src/PVE/Network/SDN/Dhcp/Dnsmasq.pm
> @@ -6,7 +6,7 @@ use warnings;
> use base qw(PVE::Network::SDN::Dhcp::Plugin);
>
> use Net::IP qw(:PROC);
> -use PVE::Tools qw(file_set_contents run_command lock_file);
> +use PVE::Tools qw(file_get_contents file_set_contents run_command lock_file);
>
> use File::Copy;
> use Net::DBus;
> @@ -136,6 +136,36 @@ sub add_ip_mapping {
> update_lease($dhcpid, $ip4, $mac);
> }
>
> +sub del_ip_mapping {
> + my ($class, $dhcpid, $mac) = @_;
> +
> + my $ethers_file = ethers_file($dhcpid);
> +
> + my $reload = undef;
> +
> + my $removeFn = sub {
> + my @lines = split(/\n/, file_get_contents($ethers_file));
> + my @remaining = grep {
> + my ($parsed_mac) = split(/,/, $_);
> + !defined($parsed_mac) || $parsed_mac ne $mac;
> + } @lines;
> +
> + return if scalar(@remaining) == scalar(@lines);
> +
> + file_set_contents($ethers_file, join("\n", @remaining) . "\n", 0644);
> + $reload = 1;
> + };
> +
> + PVE::Tools::lock_file($ethers_file, 10, $removeFn);
> +
> + if ($@) {
> + warn "Unable to remove $mac from the dnsmasq configuration: $@\n";
> + return;
> + }
> +
> + systemctl_service('reload', "dnsmasq\@$dhcpid") if $reload;
> +}
> +
> sub configure_subnet {
> my ($class, $config, $dhcpid, $vnetid, $subnet_config) = @_;
>
> diff --git a/src/PVE/Network/SDN/Dhcp/Plugin.pm b/src/PVE/Network/SDN/Dhcp/Plugin.pm
> index b5d32fa..6cbb8a2 100644
> --- a/src/PVE/Network/SDN/Dhcp/Plugin.pm
> +++ b/src/PVE/Network/SDN/Dhcp/Plugin.pm
> @@ -27,6 +27,11 @@ sub add_ip_mapping {
> die 'implement in sub class';
> }
>
> +sub del_ip_mapping {
> + my ($class, $dhcpid, $mac) = @_;
> + die 'implement in sub class';
> +}
> +
> sub configure_range {
> my ($class, $config, $dhcpid, $vnetid, $subnet_config, $range_config) = @_;
> die 'implement in sub class';
prev parent reply other threads:[~2026-09-05 9:22 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-02 12:53 [PATCH pve-network] sdn: push mapping changes from the ipam API to the dhcp backend Hannes Laimer
2026-09-05 9:22 ` 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=abe174b7-2b32-4010-bf1c-80d9501d500a@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