mirror of
git://git.proxmox.com/git/pve-network.git
synced 2025-01-09 01:18:06 +03:00
Fix vnet gateway for routed setup + /32 pointopoint subnet
add vnet to subnets && remove subnetlist from vnet Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
This commit is contained in:
parent
3926d9a7b6
commit
e612faf6ba
@ -144,17 +144,7 @@ __PACKAGE__->register_method ({
|
||||
}
|
||||
|
||||
$cfg->{ids}->{$id} = $opts;
|
||||
PVE::Network::SDN::SubnetPlugin->on_update_hook($id, $cfg);
|
||||
|
||||
my $ipam_cfg = PVE::Network::SDN::Ipams::config();
|
||||
my $ipam = $cfg->{ids}->{$id}->{ipam};
|
||||
if ($ipam) {
|
||||
raise_param_exc({ ipam => "$ipam not existing"}) if !$ipam_cfg->{ids}->{$ipam};
|
||||
my $plugin_config = $ipam_cfg->{ids}->{$ipam};
|
||||
my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
|
||||
$plugin->add_subnet($plugin_config, $id, $cfg->{ids}->{$id});
|
||||
$plugin->add_ip($plugin_config, $id, $opts->{gateway}, 1) if $opts->{gateway};
|
||||
}
|
||||
PVE::Network::SDN::SubnetPlugin->on_update_hook($id, $opts);
|
||||
|
||||
PVE::Network::SDN::Subnets::write_config($cfg);
|
||||
PVE::Network::SDN::increase_version();
|
||||
@ -192,24 +182,7 @@ __PACKAGE__->register_method ({
|
||||
my $opts = PVE::Network::SDN::SubnetPlugin->check_config($id, $param, 0, 1);
|
||||
$cfg->{ids}->{$id} = $opts;
|
||||
|
||||
PVE::Network::SDN::SubnetPlugin->on_update_hook($id, $cfg);
|
||||
|
||||
my $ipam_cfg = PVE::Network::SDN::Ipams::config();
|
||||
my $ipam = $cfg->{ids}->{$id}->{ipam};
|
||||
if ($ipam) {
|
||||
raise_param_exc({ ipam => "$ipam not existing"}) if !$ipam_cfg->{ids}->{$ipam};
|
||||
my $plugin_config = $ipam_cfg->{ids}->{$ipam};
|
||||
my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
|
||||
$plugin->add_subnet($plugin_config, $id, $cfg->{ids}->{$id});
|
||||
|
||||
if($opts->{gateway} && $scfg->{gateway} && $opts->{gateway} ne $scfg->{gateway}) {
|
||||
$plugin->del_ip($plugin_config, $id, $scfg->{gateway});
|
||||
}
|
||||
if (!defined($opts->{gateway}) && $scfg->{gateway}) {
|
||||
$plugin->del_ip($plugin_config, $id, $scfg->{gateway});
|
||||
}
|
||||
$plugin->add_ip($plugin_config, $id, $opts->{gateway}, 1) if $opts->{gateway};
|
||||
}
|
||||
PVE::Network::SDN::SubnetPlugin->on_update_hook($id, $opts, $scfg);
|
||||
|
||||
PVE::Network::SDN::Subnets::write_config($cfg);
|
||||
PVE::Network::SDN::increase_version();
|
||||
|
@ -8,6 +8,8 @@ use base qw(PVE::SectionConfig);
|
||||
use PVE::JSONSchema qw(get_standard_option);
|
||||
use PVE::Exception qw(raise raise_param_exc);
|
||||
use Net::Subnet qw(subnet_matcher);
|
||||
use PVE::Network::SDN::Vnets;
|
||||
use PVE::Network::SDN::Ipams;
|
||||
|
||||
PVE::Cluster::cfs_register_file('sdn/subnets.cfg',
|
||||
sub { __PACKAGE__->parse_config(@_); },
|
||||
@ -52,6 +54,10 @@ sub private {
|
||||
|
||||
sub properties {
|
||||
return {
|
||||
vnet => {
|
||||
type => 'string',
|
||||
description => "associated vnet",
|
||||
},
|
||||
gateway => {
|
||||
type => 'string', format => 'ip',
|
||||
description => "Subnet Gateway: Will be assign on vnet for layer3 zones",
|
||||
@ -108,21 +114,29 @@ sub options {
|
||||
}
|
||||
|
||||
sub on_update_hook {
|
||||
my ($class, $subnetid, $subnet_cfg) = @_;
|
||||
my ($class, $subnetid, $subnet, $old_subnet) = @_;
|
||||
|
||||
my $cidr = $subnetid =~ s/-/\//r;
|
||||
my $subnet_matcher = subnet_matcher($cidr);
|
||||
|
||||
my $subnet = $subnet_cfg->{ids}->{$subnetid};
|
||||
|
||||
my $vnetid = $subnet->{vnet};
|
||||
my $gateway = $subnet->{gateway};
|
||||
my $ipam = $subnet->{ipam};
|
||||
my $dns = $subnet->{dns};
|
||||
my $dnszone = $subnet->{dnszone};
|
||||
my $reversedns = $subnet->{reversedns};
|
||||
my $reversednszone = $subnet->{reversednszone};
|
||||
|
||||
#to: for /32 pointotoping, allow gateway outside the subnet
|
||||
raise_param_exc({ gateway => "$gateway is not in subnet $subnet"}) if $gateway && !$subnet_matcher->($gateway);
|
||||
my $old_gateway = $old_subnet->{gateway} if $old_subnet;
|
||||
|
||||
if($vnetid) {
|
||||
my $vnet = PVE::Network::SDN::Vnets::get_vnet($vnetid);
|
||||
raise_param_exc({ vnet => "$vnetid don't exist"}) if !$vnet;
|
||||
}
|
||||
|
||||
my ($ip, $mask) = split(/\//, $cidr);
|
||||
#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({ dns => "missing dns provider"}) if $dnszone && !$dns;
|
||||
raise_param_exc({ dnszone => "missing dns zone"}) if $dns && !$dnszone;
|
||||
@ -130,21 +144,37 @@ sub on_update_hook {
|
||||
raise_param_exc({ reversednszone => "missing dns zone"}) if $reversedns && !$reversednszone;
|
||||
raise_param_exc({ reversedns => "missing forward dns zone"}) if $reversednszone && !$dnszone;
|
||||
|
||||
if ($ipam) {
|
||||
my $ipam_cfg = PVE::Network::SDN::Ipams::config();
|
||||
my $plugin_config = $ipam_cfg->{ids}->{$ipam};
|
||||
raise_param_exc({ ipam => "$ipam not existing"}) if !$plugin_config;
|
||||
my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
|
||||
$plugin->add_subnet($plugin_config, $subnetid, $subnet);
|
||||
|
||||
#delete on removal
|
||||
if (!defined($gateway) && $old_gateway) {
|
||||
eval {
|
||||
PVE::Network::SDN::Subnets::del_ip($subnetid, $old_subnet, $old_gateway);
|
||||
};
|
||||
warn if $@;
|
||||
}
|
||||
if(!$old_gateway || $gateway && $gateway ne $old_gateway) {
|
||||
PVE::Network::SDN::Subnets::add_ip($subnetid, $subnet, $gateway);
|
||||
}
|
||||
|
||||
#delete old ip after update
|
||||
if($gateway && $old_gateway && $gateway ne $old_gateway) {
|
||||
eval {
|
||||
PVE::Network::SDN::Subnets::del_ip($subnetid, $old_subnet, $old_gateway);
|
||||
};
|
||||
warn if $@;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub on_delete_hook {
|
||||
my ($class, $subnetid, $subnet_cfg, $vnet_cfg) = @_;
|
||||
|
||||
#verify if vnets have subnet
|
||||
foreach my $vnetid (keys %{$vnet_cfg->{ids}}) {
|
||||
my $vnet = $vnet_cfg->{ids}->{$vnetid};
|
||||
my @subnets = PVE::Tools::split_list($vnet->{subnets}) if $vnet->{subnets};
|
||||
foreach my $subnet (@subnets) {
|
||||
my $id = $subnet =~ s/\//-/r;
|
||||
raise_param_exc({ subnet => "$subnet is attached to vnet $vnetid"}) if $id eq $subnetid;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -57,20 +57,18 @@ sub get_subnet {
|
||||
}
|
||||
|
||||
sub find_ip_subnet {
|
||||
my ($ip, $subnetslist) = @_;
|
||||
|
||||
my $subnets_cfg = PVE::Network::SDN::Subnets::config();
|
||||
my @subnets = PVE::Tools::split_list($subnetslist) if $subnetslist;
|
||||
my ($ip, $subnets) = @_;
|
||||
|
||||
my $subnet = undef;
|
||||
my $subnetid = undef;
|
||||
|
||||
foreach my $s (@subnets) {
|
||||
my $subnet_matcher = subnet_matcher($s);
|
||||
next if !$subnet_matcher->($ip);
|
||||
$subnetid = $s =~ s/\//-/r;
|
||||
$subnet = $subnets_cfg->{ids}->{$subnetid};
|
||||
last;
|
||||
foreach my $id (sort keys %{$subnets}) {
|
||||
my $cidr = $id =~ s/-/\//r;
|
||||
my $subnet_matcher = subnet_matcher($cidr);
|
||||
next if !$subnet_matcher->($ip);
|
||||
$subnet = $subnets->{$id};
|
||||
$subnetid = $id;
|
||||
last;
|
||||
}
|
||||
die "can't find any subnet for ip $ip" if !$subnet;
|
||||
|
||||
@ -159,8 +157,11 @@ sub next_free_ip {
|
||||
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});
|
||||
$cidr = $plugin->add_next_freeip($plugin_config, $subnetid, $subnet);
|
||||
($ip, undef) = split(/\//, $cidr);
|
||||
eval {
|
||||
$cidr = $plugin->add_next_freeip($plugin_config, $subnetid, $subnet);
|
||||
($ip, undef) = split(/\//, $cidr);
|
||||
};
|
||||
die $@ if $@;
|
||||
}
|
||||
|
||||
eval {
|
||||
@ -183,6 +184,8 @@ sub next_free_ip {
|
||||
sub add_ip {
|
||||
my ($subnetid, $subnet, $ip, $hostname) = @_;
|
||||
|
||||
return if !$subnet;
|
||||
|
||||
my $ipamid = $subnet->{ipam};
|
||||
my $dns = $subnet->{dns};
|
||||
my $dnszone = $subnet->{dnszone};
|
||||
@ -198,7 +201,10 @@ sub add_ip {
|
||||
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->add_ip($plugin_config, $subnetid, $ip);
|
||||
eval {
|
||||
$plugin->add_ip($plugin_config, $subnetid, $ip);
|
||||
};
|
||||
die $@ if $@;
|
||||
}
|
||||
|
||||
eval {
|
||||
@ -220,6 +226,8 @@ sub add_ip {
|
||||
sub del_ip {
|
||||
my ($subnetid, $subnet, $ip, $hostname) = @_;
|
||||
|
||||
return if !$subnet;
|
||||
|
||||
my $ipamid = $subnet->{ipam};
|
||||
my $dns = $subnet->{dns};
|
||||
my $dnszone = $subnet->{dnszone};
|
||||
|
@ -68,11 +68,6 @@ sub properties {
|
||||
description => "alias name of the vnet",
|
||||
optional => 1,
|
||||
},
|
||||
subnets => {
|
||||
type => 'string',
|
||||
description => "Subnets list",
|
||||
optional => 1,
|
||||
},
|
||||
mac => {
|
||||
type => 'string',
|
||||
description => "Anycast router mac address",
|
||||
@ -86,16 +81,21 @@ sub options {
|
||||
zone => { optional => 0},
|
||||
tag => { optional => 1},
|
||||
alias => { optional => 1 },
|
||||
subnets => { optional => 1 },
|
||||
mac => { optional => 1 },
|
||||
vlanaware => { optional => 1 },
|
||||
};
|
||||
}
|
||||
|
||||
sub on_delete_hook {
|
||||
my ($class, $sdnid, $vnet_cfg) = @_;
|
||||
my ($class, $vnetid, $vnet_cfg) = @_;
|
||||
|
||||
return;
|
||||
#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;
|
||||
}
|
||||
|
||||
sub on_update_hook {
|
||||
@ -111,13 +111,6 @@ sub on_update_hook {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#verify subnet
|
||||
my @subnets = PVE::Tools::split_list($vnet_cfg->{ids}->{$vnetid}->{subnets}) if $vnet_cfg->{ids}->{$vnetid}->{subnets};
|
||||
foreach my $subnet (@subnets) {
|
||||
my $id = $subnet =~ s/\//-/r;
|
||||
raise_param_exc({ subnet => "$subnet not existing"}) if !$subnet_cfg->{ids}->{$id};
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -54,22 +54,35 @@ sub get_vnet {
|
||||
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 ($vnet, $hostname, $ipversion) = @_;
|
||||
my ($vnetid, $hostname, $ipversion) = @_;
|
||||
|
||||
$ipversion = 4 if !$ipversion;
|
||||
my $subnets_cfg = PVE::Network::SDN::Subnets::config();
|
||||
my @subnets = PVE::Tools::split_list($vnet->{subnets}) if $vnet->{subnets};
|
||||
my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid);
|
||||
my $ip = undef;
|
||||
my $subnet = undef;
|
||||
my $subnetcount = 0;
|
||||
foreach my $s (@subnets) {
|
||||
my $subnetid = $s =~ s/\//-/r;
|
||||
|
||||
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++;
|
||||
$subnet = $subnets_cfg->{ids}->{$subnetid};
|
||||
if ($subnet && $subnet->{ipam}) {
|
||||
if ($subnet->{ipam}) {
|
||||
eval {
|
||||
$ip = PVE::Network::SDN::Subnets::next_free_ip($subnetid, $subnet, $hostname);
|
||||
};
|
||||
@ -83,21 +96,23 @@ sub get_next_free_ip {
|
||||
}
|
||||
|
||||
sub add_ip {
|
||||
my ($vnet, $cidr, $hostname) = @_;
|
||||
my ($vnetid, $cidr, $hostname) = @_;
|
||||
|
||||
my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid);
|
||||
|
||||
my ($ip, $mask) = split(/\//, $cidr);
|
||||
my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $vnet->{subnets});
|
||||
return if !$subnet->{ipam};
|
||||
my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $subnets);
|
||||
|
||||
PVE::Network::SDN::Subnets::add_ip($subnetid, $subnet, $ip, $hostname);
|
||||
}
|
||||
|
||||
sub del_ip {
|
||||
my ($vnet, $cidr, $hostname) = @_;
|
||||
my ($vnetid, $cidr, $hostname) = @_;
|
||||
|
||||
my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid);
|
||||
|
||||
my ($ip, $mask) = split(/\//, $cidr);
|
||||
my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $vnet->{subnets});
|
||||
return if !$subnet->{ipam};
|
||||
my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $subnets);
|
||||
|
||||
PVE::Network::SDN::Subnets::del_ip($subnetid, $subnet, $ip, $hostname);
|
||||
}
|
||||
|
@ -76,10 +76,16 @@ sub generate_sdn_config {
|
||||
#vnet bridge
|
||||
@iface_config = ();
|
||||
|
||||
my @subnets = PVE::Tools::split_list($vnet->{subnets}) if $vnet->{subnets};
|
||||
foreach my $subnet (@subnets) {
|
||||
next if !defined($subnet_cfg->{ids}->{$subnet});
|
||||
push @iface_config, "address $subnet_cfg->{ids}->{$subnet}->{gateway}" if $subnet_cfg->{ids}->{$subnet}->{gateway};
|
||||
my $address = {};
|
||||
my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid);
|
||||
foreach my $subnetid (sort keys %{$subnets}) {
|
||||
my $subnet = $subnets->{$subnetid};
|
||||
my $cidr = $subnetid =~ s/-/\//r;
|
||||
my $gateway = $subnet->{gateway};
|
||||
if ($gateway) {
|
||||
push @iface_config, "address $gateway" if !defined($address->{$gateway});
|
||||
$address->{$gateway} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
push @iface_config, "hwaddress $mac" if $mac;
|
||||
|
@ -35,10 +35,19 @@ sub generate_sdn_config {
|
||||
# vnet bridge
|
||||
my @iface_config = ();
|
||||
|
||||
my @subnets = PVE::Tools::split_list($vnet->{subnets}) if $vnet->{subnets};
|
||||
foreach my $subnet (@subnets) {
|
||||
next if !defined($subnet_cfg->{ids}->{$subnet});
|
||||
push @iface_config, "address $subnet_cfg->{ids}->{$subnet}->{gateway}" if $subnet_cfg->{ids}->{$subnet}->{gateway};
|
||||
my $address = {};
|
||||
my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid);
|
||||
foreach my $subnetid (sort keys %{$subnets}) {
|
||||
my $subnet = $subnets->{$subnetid};
|
||||
my $cidr = $subnetid =~ s/-/\//r;
|
||||
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;
|
||||
}
|
||||
|
||||
push @iface_config, "hwaddress $mac" if $mac;
|
||||
|
@ -3,17 +3,18 @@ use warnings;
|
||||
use File::Copy;
|
||||
use PVE::Cluster qw(cfs_read_file);
|
||||
|
||||
use PVE::Network::SDN;
|
||||
use PVE::Network::SDN::Zones;
|
||||
use PVE::Network::SDN::Controllers;
|
||||
use Data::Dumper;
|
||||
|
||||
my $network_config = PVE::Network::SDN::Zones::generate_etc_network_config();
|
||||
|
||||
PVE::Network::SDN::Zones::write_etc_network_config($network_config);
|
||||
print "/etc/network/interfaces.d/sdn\n";
|
||||
print $network_config;
|
||||
print "\n";
|
||||
|
||||
|
||||
my $controller_config = PVE::Network::SDN::Controllers::generate_controller_config();
|
||||
if ($controller_config) {
|
||||
print Dumper($controller_config);
|
||||
|
Loading…
Reference in New Issue
Block a user