[pve-devel] [RFC pve-network 4/9] ipam : add macs.db for fast mac lookup
Alexandre Derumier
aderumier at odiso.com
Mon Nov 13 11:04:13 CET 2023
Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
src/PVE/Network/SDN/Ipams.pm | 61 +++++++++++++++++++++++++-
src/PVE/Network/SDN/Ipams/PVEPlugin.pm | 4 +-
src/PVE/Network/SDN/Subnets.pm | 8 +++-
src/test/run_test_subnets.pl | 6 +++
4 files changed, 75 insertions(+), 4 deletions(-)
diff --git a/src/PVE/Network/SDN/Ipams.pm b/src/PVE/Network/SDN/Ipams.pm
index e8a4b0b..a459441 100644
--- a/src/PVE/Network/SDN/Ipams.pm
+++ b/src/PVE/Network/SDN/Ipams.pm
@@ -4,9 +4,10 @@ use strict;
use warnings;
use JSON;
+use Net::IP;
use PVE::Tools qw(extract_param dir_glob_regex run_command);
-use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_lock_file);
+use PVE::Cluster qw(cfs_register_file cfs_read_file cfs_write_file cfs_lock_file);
use PVE::Network;
use PVE::Network::SDN::Ipams::PVEPlugin;
@@ -19,6 +20,64 @@ PVE::Network::SDN::Ipams::NetboxPlugin->register();
PVE::Network::SDN::Ipams::PhpIpamPlugin->register();
PVE::Network::SDN::Ipams::Plugin->init();
+my $macdb_filename = 'priv/macs.db';
+
+cfs_register_file($macdb_filename, \&json_reader, \&json_writer);
+
+sub json_reader {
+ my ($filename, $data) = @_;
+
+ return defined($data) && length($data) > 0 ? decode_json($data) : {};
+}
+
+sub json_writer {
+ my ($filename, $data) = @_;
+
+ return encode_json($data);
+}
+
+sub read_macdb {
+ my () = @_;
+
+ return cfs_read_file($macdb_filename);
+}
+
+sub write_macdb {
+ my ($data) = @_;
+
+ cfs_write_file($macdb_filename, $data);
+}
+
+sub add_cache_mac_ip {
+ my ($mac, $ip) = @_;
+
+ cfs_lock_file($macdb_filename, undef, sub {
+ my $db = read_macdb();
+ if (Net::IP::ip_is_ipv4($ip)) {
+ $db->{macs}->{$mac}->{ip4} = $ip;
+ } else {
+ $db->{macs}->{$mac}->{ip6} = $ip;
+ }
+ write_macdb($db);
+ });
+ warn "$@" if $@;
+}
+
+sub del_cache_mac_ip {
+ my ($mac, $ip) = @_;
+
+ cfs_lock_file($macdb_filename, undef, sub {
+ my $db = read_macdb();
+ if (Net::IP::ip_is_ipv4($ip)) {
+ delete $db->{macs}->{$mac}->{ip4};
+ } else {
+ delete $db->{macs}->{$mac}->{ip6};
+ }
+ delete $db->{macs}->{$mac} if !defined($db->{macs}->{$mac}->{ip4}) && !defined($db->{macs}->{$mac}->{ip6});
+ write_macdb($db);
+ });
+ warn "$@" if $@;
+}
sub sdn_ipams_config {
my ($cfg, $id, $noerr) = @_;
diff --git a/src/PVE/Network/SDN/Ipams/PVEPlugin.pm b/src/PVE/Network/SDN/Ipams/PVEPlugin.pm
index 37b47e4..5790715 100644
--- a/src/PVE/Network/SDN/Ipams/PVEPlugin.pm
+++ b/src/PVE/Network/SDN/Ipams/PVEPlugin.pm
@@ -173,13 +173,14 @@ sub add_range_next_freeip {
my $ip = new Net::IP ("$range->{'start-address'} - $range->{'end-address'}")
or die "Invalid IP address(es) in Range!\n";
+ my $mac = $data->{mac};
do {
my $ip_address = $ip->ip();
if (!$dbsubnet->{ips}->{$ip_address}) {
$dbsubnet->{ips}->{$ip_address} = $data;
write_db($db);
-
+
return $ip_address;
}
} while (++$ip);
@@ -236,7 +237,6 @@ sub del_ip {
die "IP '$ip' does not exist in IPAM DB\n" if !defined($dbsubnet->{ips}->{$ip});
delete $dbsubnet->{ips}->{$ip};
-
write_db($db);
});
die "$@" if $@;
diff --git a/src/PVE/Network/SDN/Subnets.pm b/src/PVE/Network/SDN/Subnets.pm
index 9f953a6..b2125a1 100644
--- a/src/PVE/Network/SDN/Subnets.pm
+++ b/src/PVE/Network/SDN/Subnets.pm
@@ -240,6 +240,9 @@ sub add_next_free_ip {
};
die $@ if $@;
+
+ eval { PVE::Network::SDN::Ipams::add_cache_mac_ip($mac, $ip); };
+ warn $@ if $@;
}
eval {
@@ -364,7 +367,7 @@ sub update_ip {
}
sub del_ip {
- my ($zone, $subnetid, $subnet, $ip, $hostname, $skipdns) = @_;
+ my ($zone, $subnetid, $subnet, $ip, $hostname, $mac, $skipdns) = @_;
return if !$subnet || !$ip;
@@ -389,6 +392,9 @@ sub del_ip {
my $plugin_config = $ipam_cfg->{ids}->{$ipamid};
my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
$plugin->del_ip($plugin_config, $subnetid, $subnet, $ip);
+
+ eval { PVE::Network::SDN::Ipams::del_cache_mac_ip($mac, $ip); };
+ warn $@ if $@;
}
eval {
diff --git a/src/test/run_test_subnets.pl b/src/test/run_test_subnets.pl
index 9692f4c..c98359a 100755
--- a/src/test/run_test_subnets.pl
+++ b/src/test/run_test_subnets.pl
@@ -109,6 +109,12 @@ foreach my $path (@plugins) {
my $ipam_config = read_sdn_config ("$path/ipam_config");
return $ipam_config;
},
+ add_cache_mac_ip => sub {
+ return;
+ },
+ del_cache_mac_ip => sub {
+ return;
+ }
);
## add_subnet
--
2.39.2
More information about the pve-devel
mailing list