From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 4653F9B30A for ; Tue, 17 Oct 2023 15:55:13 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 3038334329 for ; Tue, 17 Oct 2023 15:55:13 +0200 (CEST) Received: from lana.proxmox.com (unknown [94.136.29.99]) by firstgate.proxmox.com (Proxmox) with ESMTP for ; Tue, 17 Oct 2023 15:55:11 +0200 (CEST) Received: by lana.proxmox.com (Postfix, from userid 10043) id 0B9EC2C2533; Tue, 17 Oct 2023 15:55:10 +0200 (CEST) From: Stefan Hanreich To: pve-devel@lists.proxmox.com Date: Tue, 17 Oct 2023 15:55:03 +0200 Message-Id: <20231017135507.2220948-7-s.hanreich@proxmox.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231017135507.2220948-1-s.hanreich@proxmox.com> References: <20231017135507.2220948-1-s.hanreich@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.466 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment KAM_LAZY_DOMAIN_SECURITY 1 Sending domain does not have any anti-forgery methods RDNS_NONE 0.793 Delivered to internal network by a host with no rDNS SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_NONE 0.001 SPF: sender does not publish an SPF Record Subject: [pve-devel] [WIP v2 pve-network 06/10] ipam: Add helper methods for DHCP to PVE IPAM X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Oct 2023 13:55:13 -0000 Those methods are used by the DHCP plugins to attain the next free IP address for a given DHCP range, as well as delete all entries with a certain MAC address. Signed-off-by: Stefan Hanreich --- src/PVE/Network/SDN/Ipams/PVEPlugin.pm | 64 ++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/PVE/Network/SDN/Ipams/PVEPlugin.pm b/src/PVE/Network/SDN/Ipams/PVEPlugin.pm index 3e8ffc5..fcc8282 100644 --- a/src/PVE/Network/SDN/Ipams/PVEPlugin.pm +++ b/src/PVE/Network/SDN/Ipams/PVEPlugin.pm @@ -156,6 +156,70 @@ sub add_next_freeip { return "$freeip/$mask"; } +sub add_dhcp_ip { + my ($class, $subnet, $dhcp_range, $data) = @_; + + my $cidr = $subnet->{cidr}; + my $zone = $subnet->{zone}; + + cfs_lock_file($ipamdb_file, undef, sub { + my $db = read_db(); + + my $dbzone = $db->{zones}->{$zone}; + die "zone '$zone' doesn't exist in IPAM DB\n" if !$dbzone; + + my $dbsubnet = $dbzone->{subnets}->{$cidr}; + die "subnet '$cidr' doesn't exist in IPAM DB\n" if !$dbsubnet; + + my $ip = new Net::IP ("$dhcp_range->{'start-address'} - $dhcp_range->{'end-address'}") + or die "Invalid IP address(es) in DHCP Range!\n"; + + do { + my $ip_address = $ip->ip(); + if (!$dbsubnet->{ips}->{$ip_address}) { + $dbsubnet->{ips}->{$ip_address} = $data; + write_db($db); + + return $ip_address; + } + } while (++$ip); + + die "No free IP left in DHCP Range $dhcp_range->{'start-address'}:$dhcp_range->{'end-address'}}\n"; + }); +} + +sub del_dhcp_ip { + my ($class, $subnet, $mac) = @_; + + my $cidr = $subnet->{cidr}; + my $zone = $subnet->{zone}; + + my $returned_ip = undef; + + cfs_lock_file($ipamdb_file, undef, sub { + my $db = read_db(); + + die "zone $zone don't exist in ipam db" if !$db->{zones}->{$zone}; + my $dbzone = $db->{zones}->{$zone}; + + die "subnet $cidr don't exist in ipam db" if !$dbzone->{subnets}->{$cidr}; + my $dbsubnet = $dbzone->{subnets}->{$cidr}; + + foreach my $ip_address (keys %{$dbsubnet->{ips}}) { + my $data = $dbsubnet->{ips}->{$ip_address}; + next if !$data->{mac} || $data->{mac} ne $mac; + + delete $dbsubnet->{ips}->{$ip_address}; + write_db($db); + + $returned_ip = $ip_address; + } + }); + die "$@" if $@; + + return $returned_ip; +} + sub del_ip { my ($class, $plugin_config, $subnetid, $subnet, $ip) = @_; -- 2.39.2