X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=PVE%2FNetwork%2FSDN%2FVnets.pm;h=d08db51dc258576e26e6908af69a9626252efb46;hb=b184ebc3ad2ff63a264e7901d5ced209832dd171;hp=ef698e8617f418022a7ac56b2f76bbdec50e4a46;hpb=f703d2ae09b7f877c5afa23d1109426b83ed3b69;p=pve-network.git diff --git a/PVE/Network/SDN/Vnets.pm b/PVE/Network/SDN/Vnets.pm index ef698e8..d08db51 100644 --- a/PVE/Network/SDN/Vnets.pm +++ b/PVE/Network/SDN/Vnets.pm @@ -4,7 +4,9 @@ use strict; use warnings; use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_lock_file); - +use Net::IP; +use PVE::Network::SDN::Subnets; +use PVE::Network::SDN::Zones; use PVE::Network::SDN::VnetPlugin; PVE::Network::SDN::VnetPlugin->register(); @@ -22,7 +24,7 @@ sub sdn_vnets_config { } sub config { - my $config = cfs_read_file("sdn/vnets.cfg"); + return cfs_read_file("sdn/vnets.cfg"); } sub write_config { @@ -31,19 +33,10 @@ sub write_config { cfs_write_file("sdn/vnets.cfg", $cfg); } -sub lock_sdn_vnets_config { - my ($code, $errmsg) = @_; - - cfs_lock_file("sdn/vnets.cfg", undef, $code); - if (my $err = $@) { - $errmsg ? die "$errmsg: $err" : die $err; - } -} - sub sdn_vnets_ids { my ($cfg) = @_; - return keys %{$cfg->{ids}}; + return sort keys %{$cfg->{ids}}; } sub complete_sdn_vnet { @@ -55,11 +48,92 @@ sub complete_sdn_vnet { } sub get_vnet { - my ($vnetid) = @_; + my ($vnetid, $running) = @_; + + my $cfg = {}; + if($running) { + my $cfg = PVE::Network::SDN::config(); + $cfg = $cfg->{vnets}; + } else { + $cfg = PVE::Network::SDN::Vnets::config(); + } - my $cfg = PVE::Network::SDN::Vnets::config(); my $vnet = PVE::Network::SDN::Vnets::sdn_vnets_config($cfg, $vnetid, 1); + return $vnet; } +sub get_subnets { + my ($vnetid) = @_; + + my $subnets = {}; + my $subnets_cfg = PVE::Network::SDN::Subnets::config(); + foreach my $subnetid (sort keys %{$subnets_cfg->{ids}}) { + my $subnet = $subnets_cfg->{ids}->{$subnetid}; + next if !$subnet->{vnet} || $subnet->{vnet} ne $vnetid; + $subnets->{$subnetid} = $subnet; + } + return $subnets; + +} + +sub get_next_free_ip { + my ($vnetid, $hostname, $ipversion) = @_; + + my $vnet = PVE::Network::SDN::Vnets::get_vnet($vnetid); + my $zoneid = $vnet->{zone}; + my $zone = PVE::Network::SDN::Zones::get_zone($zoneid); + + $ipversion = 4 if !$ipversion; + my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid, 1); + my $ip = undef; + my $subnetcount = 0; + + foreach my $subnetid (sort keys %{$subnets}) { + my $subnet = $subnets->{$subnetid}; + my ($network, $mask) = split(/-/, $subnetid); + + next if $ipversion != Net::IP::ip_get_version($network); + $subnetcount++; + if ($zone->{ipam}) { + eval { + $ip = PVE::Network::SDN::Subnets::next_free_ip($zone, $subnetid, $subnet, $hostname); + }; + warn $@ if $@; + } + last if $ip; + } + die "can't find any free ip" if !$ip && $subnetcount > 0; + + return $ip; +} + +sub add_ip { + my ($vnetid, $cidr, $hostname) = @_; + + my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid, 1); + my $vnet = PVE::Network::SDN::Vnets::get_vnet($vnetid); + my $zoneid = $vnet->{zone}; + my $zone = PVE::Network::SDN::Zones::get_zone($zoneid); + + my ($ip, $mask) = split(/\//, $cidr); + my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $subnets); + + PVE::Network::SDN::Subnets::add_ip($zone, $subnetid, $subnet, $ip, $hostname); +} + +sub del_ip { + my ($vnetid, $cidr, $hostname) = @_; + + my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid, 1); + my $vnet = PVE::Network::SDN::Vnets::get_vnet($vnetid); + my $zoneid = $vnet->{zone}; + my $zone = PVE::Network::SDN::Zones::get_zone($zoneid); + + my ($ip, $mask) = split(/\//, $cidr); + my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $subnets); + + PVE::Network::SDN::Subnets::del_ip($zone, $subnetid, $subnet, $ip, $hostname); +} + 1;