[pve-devel] [WIP pve-network 3/3] vnet|subnet: add_next_free_ip : implement dhcprange ipam search

Alexandre Derumier aderumier at odiso.com
Thu Nov 9 01:25:10 CET 2023


Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
 src/PVE/Network/SDN/Ipams/PVEPlugin.pm | 12 ++++++------
 src/PVE/Network/SDN/Ipams/Plugin.pm    |  7 +++++++
 src/PVE/Network/SDN/Subnets.pm         | 22 +++++++++++++++++++---
 src/PVE/Network/SDN/Vnets.pm           |  4 ++--
 4 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/src/PVE/Network/SDN/Ipams/PVEPlugin.pm b/src/PVE/Network/SDN/Ipams/PVEPlugin.pm
index fcc8282..9fff52a 100644
--- a/src/PVE/Network/SDN/Ipams/PVEPlugin.pm
+++ b/src/PVE/Network/SDN/Ipams/PVEPlugin.pm
@@ -110,7 +110,7 @@ sub update_ip {
 }
 
 sub add_next_freeip {
-    my ($class, $plugin_config, $subnetid, $subnet, $hostname, $mac, $description) = @_;
+    my ($class, $plugin_config, $subnetid, $subnet, $hostname, $mac, $description, $noerr) = @_;
 
     my $cidr = $subnet->{cidr};
     my $network = $subnet->{network};
@@ -156,8 +156,8 @@ sub add_next_freeip {
     return "$freeip/$mask";
 }
 
-sub add_dhcp_ip {
-    my ($class, $subnet, $dhcp_range, $data) = @_;
+sub add_range_next_freeip {
+    my ($class, $subnet, $range, $data) = @_;
 
     my $cidr = $subnet->{cidr};
     my $zone = $subnet->{zone};
@@ -171,8 +171,8 @@ sub add_dhcp_ip {
 	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";
+	my $ip = new Net::IP ("$range->{'start-address'} - $range->{'end-address'}")
+	    or die "Invalid IP address(es) in Range!\n";
 
 	do {
 	    my $ip_address = $ip->ip();
@@ -184,7 +184,7 @@ sub add_dhcp_ip {
 	    }
 	} while (++$ip);
 
-	die "No free IP left in DHCP Range $dhcp_range->{'start-address'}:$dhcp_range->{'end-address'}}\n";
+	die "No free IP left in Range $range->{'start-address'}:$range->{'end-address'}}\n";
     });
 }
 
diff --git a/src/PVE/Network/SDN/Ipams/Plugin.pm b/src/PVE/Network/SDN/Ipams/Plugin.pm
index c96eeda..8d69be4 100644
--- a/src/PVE/Network/SDN/Ipams/Plugin.pm
+++ b/src/PVE/Network/SDN/Ipams/Plugin.pm
@@ -98,6 +98,13 @@ sub add_next_freeip {
     die "please implement inside plugin";
 }
 
+
+sub add_range_next_freeip {
+    my ($class, $subnet, $range, $data) = @_;
+
+    die "please implement inside plugin";
+}
+
 sub del_ip {
     my ($class, $plugin_config, $subnetid, $subnet, $ip, $noerr) = @_;
 
diff --git a/src/PVE/Network/SDN/Subnets.pm b/src/PVE/Network/SDN/Subnets.pm
index dd9e697..42b84ab 100644
--- a/src/PVE/Network/SDN/Subnets.pm
+++ b/src/PVE/Network/SDN/Subnets.pm
@@ -11,6 +11,7 @@ use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_lock_file);
 use PVE::JSONSchema qw(parse_property_string);
 use PVE::Network::SDN::Dns;
 use PVE::Network::SDN::Ipams;
+use PVE::Network::SDN::Zones;
 
 use PVE::Network::SDN::SubnetPlugin;
 PVE::Network::SDN::SubnetPlugin->register();
@@ -203,7 +204,7 @@ sub del_subnet {
 }
 
 sub next_free_ip {
-    my ($zone, $subnetid, $subnet, $hostname, $mac, $description, $skipdns) = @_;
+    my ($zone, $subnetid, $subnet, $hostname, $mac, $description, $skipdns, $dhcprange) = @_;
 
     my $cidr = undef;
     my $ip = undef;
@@ -225,9 +226,24 @@ sub next_free_ip {
 	my $plugin_config = $ipam_cfg->{ids}->{$ipamid};
 	my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
 	eval {
-	    $cidr = $plugin->add_next_freeip($plugin_config, $subnetid, $subnet, $hostname, $mac, $description);
-	    ($ip, undef) = split(/\//, $cidr);
+	    if ($dhcprange) {
+		my ($zoneid, $subnet_network, $subnet_mask) = split(/-/, $subnetid);
+		my $zone = PVE::Network::SDN::Zones::get_zone($zoneid);
+
+		my $data = {
+		    mac => $mac,
+		};
+		
+		foreach my $range (@{$subnet->{'dhcp-range'}}) { 
+        	    $ip = $plugin->add_range_next_freeip($subnet, $range, $data);
+	            next if !$ip;
+		}
+	    } else {
+		$cidr = $plugin->add_next_freeip($plugin_config, $subnetid, $subnet, $hostname, $mac, $description);
+		($ip, undef) = split(/\//, $cidr);
+	    }
 	};
+
 	die $@ if $@;
     }
 
diff --git a/src/PVE/Network/SDN/Vnets.pm b/src/PVE/Network/SDN/Vnets.pm
index 39bdda0..4ba3523 100644
--- a/src/PVE/Network/SDN/Vnets.pm
+++ b/src/PVE/Network/SDN/Vnets.pm
@@ -97,7 +97,7 @@ sub get_subnet_from_vnet_cidr {
 }
 
 sub get_next_free_cidr {
-    my ($vnetid, $hostname, $mac, $description, $ipversion, $skipdns) = @_;
+    my ($vnetid, $hostname, $mac, $description, $ipversion, $skipdns, $dhcprange) = @_;
 
     my $vnet = PVE::Network::SDN::Vnets::get_vnet($vnetid);
     my $zoneid = $vnet->{zone};
@@ -118,7 +118,7 @@ sub get_next_free_cidr {
 	$subnetcount++;
 
 	eval {
-	    $ip = PVE::Network::SDN::Subnets::next_free_ip($zone, $subnetid, $subnet, $hostname, $mac, $description, $skipdns);
+	    $ip = PVE::Network::SDN::Subnets::next_free_ip($zone, $subnetid, $subnet, $hostname, $mac, $description, $skipdns, $dhcprange);
 	};
 	warn $@ if $@;
 	last if $ip;
-- 
2.39.2





More information about the pve-devel mailing list