my $scfg = dclone(PVE::Network::SDN::Subnets::sdn_subnets_config($cfg, $id));
$scfg->{subnet} = $id;
- $scfg->{cidr} = $id =~ s/-/\//r;
$scfg->{digest} = $cfg->{digest};
return $scfg;
my $type = extract_param($param, 'type');
my $cidr = extract_param($param, 'subnet');
- my $id = $cidr =~ s/\//-/r;
# create /etc/pve/sdn directory
PVE::Cluster::check_cfs_quorum();
my $vnet = $param->{vnet};
my $zoneid = $vnet_cfg->{ids}->{$vnet}->{zone};
my $zone = $zone_cfg->{ids}->{$zoneid};
-
+ my $id = $cidr =~ s/\//-/r;
+ $id = "$zoneid-$id";
+
my $opts = PVE::Network::SDN::SubnetPlugin->check_config($id, $param, 1, 1);
my $scfg = undef;
}
$cfg->{ids}->{$id} = $opts;
- PVE::Network::SDN::SubnetPlugin->on_update_hook($zone, $id, $opts);
+
+ my $subnet = PVE::Network::SDN::Subnets::sdn_subnets_config($cfg, $id);
+ PVE::Network::SDN::SubnetPlugin->on_update_hook($zone, $id, $subnet);
PVE::Network::SDN::Subnets::write_config($cfg);
raise_param_exc({ ipam => "you can't change ipam"}) if $opts->{ipam} && $scfg->{ipam} && $opts->{ipam} ne $scfg->{ipam};
- PVE::Network::SDN::SubnetPlugin->on_update_hook($zone, $id, $opts, $scfg);
+ my $subnet = PVE::Network::SDN::Subnets::sdn_subnets_config($cfg, $id);
+ PVE::Network::SDN::SubnetPlugin->on_update_hook($zone, $id, $subnet);
PVE::Network::SDN::Subnets::write_config($cfg);
use Storable qw(dclone);
use PVE::JSONSchema qw(get_standard_option);
use PVE::RPCEnvironment;
+use PVE::Exception qw(raise raise_param_exc);
use PVE::RESTHandler;
my $plugin = PVE::Network::SDN::Zones::Plugin->lookup($plugin_config->{type});
$plugin->vnet_update_hook($cfg->{ids}->{$id});
- my $subnet_cfg = PVE::Network::SDN::Subnets::config();
-
- PVE::Network::SDN::VnetPlugin->on_update_hook($id, $cfg, $subnet_cfg);
+ PVE::Network::SDN::VnetPlugin->on_update_hook($id, $cfg);
PVE::Network::SDN::Vnets::write_config($cfg);
PVE::SectionConfig::assert_if_modified($cfg, $digest);
+
my $opts = PVE::Network::SDN::VnetPlugin->check_config($id, $param, 0, 1);
+ raise_param_exc({ zone => "missing zone"}) if !$opts->{zone};
+ my $subnets = PVE::Network::SDN::Vnets::get_subnets($id);
+ raise_param_exc({ zone => "can't change zone if subnets exists"}) if($subnets && $opts->{zone} ne $cfg->{ids}->{$id}->{zone});
+
$cfg->{ids}->{$id} = $opts;
my $zone_cfg = PVE::Network::SDN::Zones::config();
my $plugin = PVE::Network::SDN::Zones::Plugin->lookup($plugin_config->{type});
$plugin->vnet_update_hook($cfg->{ids}->{$id});
- my $subnet_cfg = PVE::Network::SDN::Subnets::config();
-
- PVE::Network::SDN::VnetPlugin->on_update_hook($id, $cfg, $subnet_cfg);
+ PVE::Network::SDN::VnetPlugin->on_update_hook($id, $cfg);
PVE::Network::SDN::Vnets::write_config($cfg);
use PVE::Network::SDN;
use PVE::Network::SDN::Vnets;
use PVE::Network::SDN::Zones;
+use PVE::Network::SDN::Subnets;
use PVE::Network::SDN::Dns;
use PVE::Network::SDN::Zones::Plugin;
use PVE::Network::SDN::Zones::VlanPlugin;
my $plugin = PVE::Network::SDN::Zones::Plugin->lookup($scfg->{type});
my $opts = $plugin->check_config($id, $param, 0, 1);
+ if($opts->{ipam} ne $scfg->{ipam}) {
+
+ #don't allow ipam change if subnet are defined
+ my $subnets_cfg = PVE::Network::SDN::Subnets::config();
+ foreach my $subnetid (sort keys %{$subnets_cfg->{ids}}) {
+ my $subnet = PVE::Network::SDN::Subnets::sdn_subnets_config($subnets_cfg, $subnetid);
+ raise_param_exc({ ipam => "can't change ipam if subnet if already defined for this zone"}) if $subnet->{zone} eq $id;
+ }
+ }
+
foreach my $k (%$opts) {
$scfg->{$k} = $opts->{$k};
}
}
sub get_reversedns_zone {
- my ($class, $plugin_config, $subnetid, $ip) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip) = @_;
- my ($network, $mask) = split(/-/, $subnetid);
+ my $cidr = $subnet->{cidr};
+ my $mask = $subnet->{mask};
- my $cidr = "$ip/$mask";
my $zone = "";
if (Net::IP::ip_is_ipv4($ip)) {
sub add_subnet {
my ($class, $plugin_config, $subnetid, $subnet) = @_;
- my $cidr = $subnetid =~ s/-/\//r;
+ my $cidr = $subnet->{cidr};
my $gateway = $subnet->{gateway};
my $url = $plugin_config->{url};
my $token = $plugin_config->{token};
#create subnet
if (!$internalid) {
- my ($network, $mask) = split(/-/, $subnetid);
my $params = { prefix => $cidr };
eval {
my $result = PVE::Network::SDN::Ipams::Plugin::api_request("POST", "$url/ipam/prefixes/", $headers, $params);
- $subnet->{ipamid} = $result->{id} if defined($result->{id});
};
if ($@) {
die "error add subnet to ipam: $@";
sub del_subnet {
my ($class, $plugin_config, $subnetid, $subnet) = @_;
- my $cidr = $subnetid =~ s/-/\//r;
+ my $cidr = $subnet->{cidr};
my $url = $plugin_config->{url};
my $token = $plugin_config->{token};
my $gateway = $subnet->{gateway};
my $internalid = get_prefix_id($url, $cidr, $headers);
return if !$internalid;
- #fixme: check that prefix is empty exluding gateway, before delete
- PVE::Network::SDN::Ipams::NetboxPlugin::del_ip($class, $plugin_config, $subnetid, $gateway) if $gateway;
+ return; #fixme: check that prefix is empty exluding gateway, before delete
eval {
PVE::Network::SDN::Ipams::Plugin::api_request("DELETE", "$url/ipam/prefixes/$internalid/", $headers);
}
sub add_ip {
- my ($class, $plugin_config, $subnetid, $ip, $is_gateway) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $is_gateway) = @_;
- my ($network, $mask) = split(/-/, $subnetid);
+ my $mask = $subnet->{mask};
my $url = $plugin_config->{url};
my $token = $plugin_config->{token};
my $section = $plugin_config->{section};
sub add_next_freeip {
my ($class, $plugin_config, $subnetid, $subnet) = @_;
- my $cidr = $subnetid =~ s/-/\//r;
+ my $cidr = $subnet->{cidr};
+
my $url = $plugin_config->{url};
my $token = $plugin_config->{token};
my $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "token $token"];
}
sub del_ip {
- my ($class, $plugin_config, $subnetid, $ip) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip) = @_;
return if !$ip;
use PVE::Tools;
use JSON;
use NetAddr::IP;
+use Net::IP;
use Digest::SHA;
use base('PVE::Network::SDN::Ipams::Plugin');
sub add_subnet {
my ($class, $plugin_config, $subnetid, $subnet) = @_;
- my $cidr = $subnetid =~ s/-/\//r;
+ my $cidr = $subnet->{cidr};
+ my $zone = $subnet->{zone};
my $gateway = $subnet->{gateway};
+
cfs_lock_file($ipamdb_file, undef, sub {
- my $config = read_db();
- #create subnet
- if (!defined($config->{subnets}->{$cidr})) {
- $config->{subnets}->{$cidr}->{ips} = {};
- write_db($config);
+ my $db = {};
+ $db = read_db();
+
+ $db->{zones}->{$zone} = {} if !$db->{zones}->{$zone};
+ my $zonedb = $db->{zones}->{$zone};
+
+ if(!$zonedb->{subnets}->{$cidr}) {
+ #create subnet
+ $zonedb->{subnets}->{$cidr}->{ips} = {};
+ write_db($db);
}
});
die "$@" if $@;
sub del_subnet {
my ($class, $plugin_config, $subnetid, $subnet) = @_;
- my $cidr = $subnetid =~ s/-/\//r;
+ my $cidr = $subnet->{cidr};
+ my $zone = $subnet->{zone};
cfs_lock_file($ipamdb_file, undef, sub {
my $db = read_db();
- my $ips = $db->{subnets}->{$cidr}->{ips};
- die "cannot delete subnet '$cidr', not empty\n" if keys %{$ips} > 0;
- delete $db->{subnets}->{$cidr};
+
+ 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;
+
+ die "cannot delete subnet '$cidr', not empty\n" if keys %{$dbsubnet->{ips}} > 0;
+
+ delete $dbzone->{subnets}->{$cidr};
+
write_db($db);
});
die "$@" if $@;
}
sub add_ip {
- my ($class, $plugin_config, $subnetid, $ip, $is_gateway) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $is_gateway) = @_;
- my $cidr = $subnetid =~ s/-/\//r;
+ my $cidr = $subnet->{cidr};
+ my $zone = $subnet->{zone};
cfs_lock_file($ipamdb_file, undef, sub {
my $db = read_db();
- my $s = $db->{subnets}->{$cidr};
- die "IP '$ip' already exist\n" if defined($s->{ips}->{$ip});
+ 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;
+
+ die "IP '$ip' already exist\n" if defined($dbsubnet->{ips}->{$ip});
+
+ $dbsubnet->{ips}->{$ip} = 1;
- #verify that ip is valid for this subnet
- $s->{ips}->{$ip} = 1;
write_db($db);
});
die "$@" if $@;
sub add_next_freeip {
my ($class, $plugin_config, $subnetid, $subnet) = @_;
- my $cidr = $subnetid =~ s/-/\//r;
+ my $cidr = $subnet->{cidr};
+ my $network = $subnet->{network};
+ my $zone = $subnet->{zone};
+ my $mask = $subnet->{mask};
my $freeip = undef;
cfs_lock_file($ipamdb_file, undef, sub {
my $db = read_db();
- my $s = $db->{subnets}->{$cidr};
- my $iplist = new NetAddr::IP($cidr);
- my $broadcast = $iplist->broadcast();
-
- while (1) {
- $iplist++;
- last if $iplist eq $broadcast;
- my $ip = $iplist->addr();
- next if defined($s->{ips}->{$ip});
- $freeip = $ip;
- last;
+ 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" if !$dbsubnet;
+
+ if (Net::IP::ip_is_ipv4($network) && $mask == 32) {
+ die "cannot find free IP in subnet '$cidr'\n" if defined($dbsubnet->{ips}->{$network});
+ $freeip = $network;
+ } else {
+ my $iplist = new NetAddr::IP($cidr);
+ my $broadcast = $iplist->broadcast();
+
+ while(1) {
+ $iplist++;
+ last if $iplist eq $broadcast;
+ my $ip = $iplist->addr();
+ next if defined($dbsubnet->{ips}->{$ip});
+ $freeip = $ip;
+ last;
+ }
}
die "can't find free ip in subnet '$cidr'\n" if !$freeip;
- $s->{ips}->{$freeip} = 1;
+ $dbsubnet->{ips}->{$freeip} = 1;
write_db($db);
});
die "$@" if $@;
- my ($network, $mask) = split(/-/, $subnetid);
return "$freeip/$mask";
}
sub del_ip {
- my ($class, $plugin_config, $subnetid, $ip) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip) = @_;
- my $cidr = $subnetid =~ s/-/\//r;
+ my $cidr = $subnet->{cidr};
+ my $zone = $subnet->{zone};
cfs_lock_file($ipamdb_file, undef, sub {
my $db = read_db();
- my $s = $db->{subnets}->{$cidr};
- return if !$ip;
+ 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};
+
+ die "IP '$ip' does not exist in IPAM DB\n" if !defined($dbsubnet->{ips}->{$ip});
+ delete $dbsubnet->{ips}->{$ip};
- die "IP '$ip' does not exist in IPAM DB\n" if !defined($s->{ips}->{$ip});
- delete $s->{ips}->{$ip};
write_db($db);
});
die "$@" if $@;
sub add_subnet {
my ($class, $plugin_config, $subnetid, $subnet) = @_;
- my $cidr = $subnetid =~ s/-/\//r;
+ my $cidr = $subnet->{cidr};
+ my $network = $subnet->{network};
+ my $mask = $subnet->{mask};
+
my $gateway = $subnet->{gateway};
my $url = $plugin_config->{url};
my $token = $plugin_config->{token};
#create subnet
if (!$internalid) {
- my ($network, $mask) = split(/-/, $subnetid);
my $params = { subnet => $network,
mask => $mask,
sub del_subnet {
my ($class, $plugin_config, $subnetid, $subnet) = @_;
- my $cidr = $subnetid =~ s/-/\//r;
+ my $cidr = $subnet->{cidr};
my $url = $plugin_config->{url};
my $token = $plugin_config->{token};
my $section = $plugin_config->{section};
my $internalid = get_internalid($url, $cidr, $headers);
return if !$internalid;
- #fixme: check that prefix is empty exluding gateway, before delete
+ return; #fixme: check that prefix is empty exluding gateway, before delete
eval {
PVE::Network::SDN::Ipams::Plugin::api_request("DELETE", "$url/subnets/$internalid", $headers);
}
sub add_ip {
- my ($class, $plugin_config, $subnetid, $ip, $is_gateway) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $is_gateway) = @_;
- my $cidr = $subnetid =~ s/-/\//r;
+ my $cidr = $subnet->{cidr};
my $url = $plugin_config->{url};
my $token = $plugin_config->{token};
my $section = $plugin_config->{section};
sub add_next_freeip {
my ($class, $plugin_config, $subnetid, $subnet, $internalid, $hostname) = @_;
- my $cidr = $subnetid =~ s/-/\//r;
+ my $cidr = $subnet->{cidr};
+ my $mask = $subnet->{mask};
my $url = $plugin_config->{url};
my $token = $plugin_config->{token};
my $section = $plugin_config->{section};
die "can't find free ip in subnet $cidr: $@";
}
- my ($network, $mask) = split(/-/, $subnetid);
return "$ip/$mask";
}
sub del_ip {
- my ($class, $plugin_config, $subnetid, $ip) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip) = @_;
return if !$ip;
}
sub add_ip {
- my ($class, $plugin_config, $subnetid, $subnet, $internalid, $ip, $hostname, $is_gateway) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip, $is_gateway) = @_;
}
sub add_next_freeip {
- my ($class, $plugin_config) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet) = @_;
}
sub del_ip {
- my ($class, $plugin_config, $subnetid, $ip) = @_;
+ my ($class, $plugin_config, $subnetid, $subnet, $ip) = @_;
}
sub on_update_hook {
use Net::Subnet qw(subnet_matcher);
use PVE::Network::SDN::Vnets;
use PVE::Network::SDN::Ipams;
+use Net::IP;
PVE::Cluster::cfs_register_file('sdn/subnets.cfg',
sub { __PACKAGE__->parse_config(@_); },
sub parse_sdn_subnet_id {
my ($id, $noerr) = @_;
- my $cidr = $id =~ s/-/\//r;
+ my $cidr = "";
+ if($id =~ /\//) {
+ $cidr = $id;
+ } else {
+ my ($zone, $ip, $mask) = split(/-/, $id);
+ $cidr = "$ip/$mask";
+ }
if (!(PVE::JSONSchema::pve_verify_cidrv4($cidr, 1) ||
PVE::JSONSchema::pve_verify_cidrv6($cidr, 1)))
sub on_update_hook {
my ($class, $zone, $subnetid, $subnet, $old_subnet) = @_;
- my $cidr = $subnetid =~ s/-/\//r;
+ my $cidr = $subnet->{cidr};
+ my $mask = $subnet->{mask};
+
my $subnet_matcher = subnet_matcher($cidr);
my $vnetid = $subnet->{vnet};
raise_param_exc({ vnet => "you can't add a subnet on a vlanaware vnet"}) if $vnet->{vlanaware};
}
- my ($ip, $mask) = split(/\//, $cidr);
+ my $pointopoint = 1 if Net::IP::ip_is_ipv4($gateway) && $mask == 32;
+
#for /32 pointopoint, we allow gateway outside the subnet
- raise_param_exc({ gateway => "$gateway is not in subnet $subnetid"}) if $gateway && !$subnet_matcher->($gateway) && $mask != 32;
+ raise_param_exc({ gateway => "$gateway is not in subnet $cidr"}) if $gateway && !$subnet_matcher->($gateway) && !$pointopoint;
+
if ($ipam) {
my $ipam_cfg = PVE::Network::SDN::Ipams::config();
my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
$plugin->add_subnet($plugin_config, $subnetid, $subnet);
- #delete on removal
+ #don't register gateway for pointopoint
+ return if $pointopoint;
+
+ #delete gateway on removal
if (!defined($gateway) && $old_gateway) {
eval {
PVE::Network::SDN::Subnets::del_ip($zone, $subnetid, $old_subnet, $old_gateway);
PVE::Network::SDN::Subnets::add_ip($zone, $subnetid, $subnet, $gateway);
}
- #delete old ip after update
+ #delete old gateway after update
if($gateway && $old_gateway && $gateway ne $old_gateway) {
eval {
PVE::Network::SDN::Subnets::del_ip($zone, $subnetid, $old_subnet, $old_gateway);
my $scfg = $cfg->{ids}->{$id};
die "sdn subnet '$id' does not exist\n" if (!$noerr && !$scfg);
+ if($scfg) {
+ my ($zone, $network, $mask) = split(/-/, $id);
+ $scfg->{cidr} = "$network/$mask";
+ $scfg->{zone} = $zone;
+ $scfg->{network} = $network;
+ $scfg->{mask} = $mask;
+ }
+
return $scfg;
}
}
sub find_ip_subnet {
- my ($ip, $subnets) = @_;
+ my ($ip, $mask, $subnets) = @_;
my $subnet = undef;
my $subnetid = undef;
foreach my $id (sort keys %{$subnets}) {
- my $cidr = $id =~ s/-/\//r;
+
+ next if $mask ne $subnets->{$id}->{mask};
+ my $cidr = $subnets->{$id}->{cidr};
my $subnet_matcher = subnet_matcher($cidr);
next if !$subnet_matcher->($ip);
$subnet = $subnets->{$id};
};
my $get_reversedns_zone = sub {
- my ($subnetid, $dns, $ip) = @_;
+ my ($subnetid, $subnet, $dns, $ip) = @_;
return if !$subnetid || !$dns || !$ip;
my $dns_cfg = PVE::Network::SDN::Dns::config();
my $plugin_config = $dns_cfg->{ids}->{$dns};
my $plugin = PVE::Network::SDN::Dns::Plugin->lookup($plugin_config->{type});
- $plugin->get_reversedns_zone($plugin_config, $subnetid, $ip);
+ $plugin->get_reversedns_zone($plugin_config, $subnetid, $subnet, $ip);
};
my $add_dns_record = sub {
}
eval {
- my $reversednszone = &$get_reversedns_zone($subnetid, $reversedns, $ip);
+ my $reversednszone = &$get_reversedns_zone($subnetid, $subnet, $reversedns, $ip);
#add dns
&$add_dns_record($dnszone, $dns, $hostname, $dnszoneprefix, $ip);
my $dns = $zone->{dns};
my $dnszone = $zone->{dnszone};
my $reversedns = $zone->{reversedns};
- my $reversednszone = &$get_reversedns_zone($subnetid, $reversedns, $ip);
+ my $reversednszone = &$get_reversedns_zone($subnetid, $subnet, $reversedns, $ip);
my $dnszoneprefix = $subnet->{dnszoneprefix};
#verify dns zones before ipam
my $plugin_config = $ipam_cfg->{ids}->{$ipamid};
my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
eval {
- $plugin->add_ip($plugin_config, $subnetid, $ip);
+ $plugin->add_ip($plugin_config, $subnetid, $subnet, $ip);
};
die $@ if $@;
}
my $dns = $zone->{dns};
my $dnszone = $zone->{dnszone};
my $reversedns = $zone->{reversedns};
- my $reversednszone = &$get_reversedns_zone($subnetid, $reversedns, $ip);
+ my $reversednszone = &$get_reversedns_zone($subnetid, $subnet, $reversedns, $ip);
my $dnszoneprefix = $subnet->{dnszoneprefix};
&$verify_dns_zone($dnszone, $dns);
my $ipam_cfg = PVE::Network::SDN::Ipams::config();
my $plugin_config = $ipam_cfg->{ids}->{$ipamid};
my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
- $plugin->del_ip($plugin_config, $subnetid, $ip);
+ $plugin->del_ip($plugin_config, $subnetid, $subnet, $ip);
}
eval {
#verify if subnets are associated
my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid);
- my @subnetlist = ();
- foreach my $subnetid (sort keys %{$subnets}) {
- push @subnetlist, $subnetid;
- }
- raise_param_exc({ vnet => "Vnet is attached to following subnets:". join(',', @subnetlist)}) if @subnetlist > 0;
+ raise_param_exc({ vnet => "Can't delete vnet if subnets exists"}) if $subnets;
}
sub on_update_hook {
- my ($class, $vnetid, $vnet_cfg, $subnet_cfg) = @_;
+ my ($class, $vnetid, $vnet_cfg) = @_;
+
+ my $vnet = $vnet_cfg->{ids}->{$vnetid};
+ my $tag = $vnet->{tag};
+ my $vlanaware = $vnet->{vlanaware};
+
+ #don't allow vlanaware change if subnets are defined
+ if($vnet->{vlanaware}) {
+ my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid);
+ raise_param_exc({ vlanaware => "vlanaware vnet is not compatible with subnets"}) if $subnets;
+ }
- #fixme : don't allow change zone if subnets are defined
- #fixme : don't vlanaware change if subnets are defined
-# my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid);
-
# verify that tag is not already defined in another vnet
- if (defined($vnet_cfg->{ids}->{$vnetid}->{tag})) {
- my $tag = $vnet_cfg->{ids}->{$vnetid}->{tag};
+ if (defined($tag)) {
foreach my $id (keys %{$vnet_cfg->{ids}}) {
next if $id eq $vnetid;
- my $vnet = $vnet_cfg->{ids}->{$id};
- if ($vnet->{type} eq 'vnet' && defined($vnet->{tag})) {
- raise_param_exc({ tag => "tag $tag already exist in vnet $id"}) if $tag eq $vnet->{tag};
- }
+ my $othervnettag = $vnet_cfg->{ids}->{$id}->{tag};
+ raise_param_exc({ tag => "tag $tag already exist in vnet $id"}) if $othervnettag && $tag eq $othervnettag;
}
}
}
sub get_subnets {
my ($vnetid) = @_;
- my $subnets = {};
+ my $subnets = undef;
my $subnets_cfg = PVE::Network::SDN::Subnets::config();
foreach my $subnetid (sort keys %{$subnets_cfg->{ids}}) {
- my $subnet = $subnets_cfg->{ids}->{$subnetid};
+ my $subnet = PVE::Network::SDN::Subnets::sdn_subnets_config($subnets_cfg, $subnetid);
next if !$subnet->{vnet} || $subnet->{vnet} ne $vnetid;
$subnets->{$subnetid} = $subnet;
}
}
-sub get_next_free_ip {
+sub get_next_free_cidr {
my ($vnetid, $hostname, $ipversion) = @_;
my $vnet = PVE::Network::SDN::Vnets::get_vnet($vnetid);
foreach my $subnetid (sort keys %{$subnets}) {
my $subnet = $subnets->{$subnetid};
- my ($network, $mask) = split(/-/, $subnetid);
+ my $network = $subnet->{network};
next if $ipversion != Net::IP::ip_get_version($network);
$subnetcount++;
return $ip;
}
-sub add_ip {
+sub add_cidr {
my ($vnetid, $cidr, $hostname) = @_;
my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid, 1);
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);
+ die "ip address is not in cidr format" if !$mask;
+ my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $mask, $subnets);
PVE::Network::SDN::Subnets::add_ip($zone, $subnetid, $subnet, $ip, $hostname);
}
-sub del_ip {
+sub del_cidr {
my ($vnetid, $cidr, $hostname) = @_;
my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid, 1);
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);
+ die "ip address is not in cidr format" if !$mask;
+ my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $mask, $subnets);
PVE::Network::SDN::Subnets::del_ip($zone, $subnetid, $subnet, $ip, $hostname);
}
my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid, 1);
foreach my $subnetid (sort keys %{$subnets}) {
my $subnet = $subnets->{$subnetid};
- my $cidr = $subnetid =~ s/-/\//r;
+ my $cidr = $subnet->{cidr};
+
my $gateway = $subnet->{gateway};
if ($gateway) {
push @iface_config, "address $gateway" if !defined($address->{$gateway});
my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid, 1);
foreach my $subnetid (sort keys %{$subnets}) {
my $subnet = $subnets->{$subnetid};
- my $cidr = $subnetid =~ s/-/\//r;
+ my $cidr = $subnet->{cidr};
+ my $mask = $subnet->{mask};
+
my $gateway = $subnet->{gateway};
if ($gateway) {
push @iface_config, "address $gateway" if !defined($address->{$gateway});
$address->{$gateway} = 1;
}
#add route for /32 pointtopoint
- my ($ip, $mask) = split(/\//, $cidr);
push @iface_config, "up ip route add $cidr dev $vnetid" if $mask == 32;
if ($subnet->{snat}) {
#find outgoing interface