From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 6BC2E68EBE for ; Fri, 28 Aug 2020 14:37:57 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 8A86421311 for ; Fri, 28 Aug 2020 14:37:26 +0200 (CEST) Received: from mailpro.odiso.net (mailpro.odiso.net [89.248.211.110]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 83ACB20E50 for ; Fri, 28 Aug 2020 14:37:01 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mailpro.odiso.net (Postfix) with ESMTP id 4D20415F9D41; Fri, 28 Aug 2020 14:36:58 +0200 (CEST) Received: from mailpro.odiso.net ([127.0.0.1]) by localhost (mailpro.odiso.net [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id xi6bg6NaRdGd; Fri, 28 Aug 2020 14:36:58 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mailpro.odiso.net (Postfix) with ESMTP id 3497915F9E1A; Fri, 28 Aug 2020 14:36:58 +0200 (CEST) X-Virus-Scanned: amavisd-new at mailpro.odiso.com Received: from mailpro.odiso.net ([127.0.0.1]) by localhost (mailpro.odiso.net [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id Pt_R_liAwv5l; Fri, 28 Aug 2020 14:36:58 +0200 (CEST) Received: from pve.fritz.box (unknown [213.211.148.86]) by mailpro.odiso.net (Postfix) with ESMTPSA id 0348415F9E16; Fri, 28 Aug 2020 14:36:57 +0200 (CEST) From: Alexandre Derumier To: pve-devel@lists.proxmox.com Date: Fri, 28 Aug 2020 14:36:46 +0200 Message-Id: <20200828123649.11125-19-aderumier@odiso.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200828123649.11125-1-aderumier@odiso.com> References: <20200828123649.11125-1-aderumier@odiso.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SPAM-LEVEL: Spam detection results: 0 AWL 0.000 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_DNSWL_NONE -0.0001 Sender listed at https://www.dnswl.org/, no trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [vnetplugin.pm, vnets.pm, evpnplugin.pm, subnets.pm, simpleplugin.pm, subnetplugin.pm] Subject: [pve-devel] [PATCH v7 pve-network 18/21] add vnet to subnets && remove subnetlist from vnet X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 28 Aug 2020 12:37:57 -0000 --- PVE/API2/Network/SDN/Subnets.pm | 31 +------------- PVE/Network/SDN/SubnetPlugin.pm | 59 ++++++++++++++++++++------- PVE/Network/SDN/Subnets.pm | 34 +++++++++------ PVE/Network/SDN/VnetPlugin.pm | 23 ++++------- PVE/Network/SDN/Vnets.pm | 43 ++++++++++++------- PVE/Network/SDN/Zones/EvpnPlugin.pm | 10 ++--- PVE/Network/SDN/Zones/SimplePlugin.pm | 16 ++++---- 7 files changed, 117 insertions(+), 99 deletions(-) diff --git a/PVE/API2/Network/SDN/Subnets.pm b/PVE/API2/Network/SDN/Subne= ts.pm index 094401c..728b939 100644 --- a/PVE/API2/Network/SDN/Subnets.pm +++ b/PVE/API2/Network/SDN/Subnets.pm @@ -135,17 +135,7 @@ __PACKAGE__->register_method ({ } =20 $cfg->{ids}->{$id} =3D $opts; - PVE::Network::SDN::SubnetPlugin->on_update_hook($id, $cfg); - - my $ipam_cfg =3D PVE::Network::SDN::Ipams::config(); - my $ipam =3D $cfg->{ids}->{$id}->{ipam}; - if ($ipam) { - raise_param_exc({ ipam =3D> "$ipam not existing"}) if !$ipam_cfg->= {ids}->{$ipam}; - my $plugin_config =3D $ipam_cfg->{ids}->{$ipam}; - my $plugin =3D PVE::Network::SDN::Ipams::Plugin->lookup($plugin_co= nfig->{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); =20 PVE::Network::SDN::Subnets::write_config($cfg); =20 @@ -182,24 +172,7 @@ __PACKAGE__->register_method ({ my $opts =3D PVE::Network::SDN::SubnetPlugin->check_config($id, $pa= ram, 0, 1); $cfg->{ids}->{$id} =3D $opts; =20 - PVE::Network::SDN::SubnetPlugin->on_update_hook($id, $cfg); - - my $ipam_cfg =3D PVE::Network::SDN::Ipams::config(); - my $ipam =3D $cfg->{ids}->{$id}->{ipam}; - if ($ipam) { - raise_param_exc({ ipam =3D> "$ipam not existing"}) if !$ipam_cfg->{ids= }->{$ipam}; - my $plugin_config =3D $ipam_cfg->{ids}->{$ipam}; - my $plugin =3D 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}); - }=20 - $plugin->add_ip($plugin_config, $id, $opts->{gateway}, 1) if $opts->{g= ateway}; - } + PVE::Network::SDN::SubnetPlugin->on_update_hook($id, $opts, $scfg); =20 PVE::Network::SDN::Subnets::write_config($cfg); =20 diff --git a/PVE/Network/SDN/SubnetPlugin.pm b/PVE/Network/SDN/SubnetPlug= in.pm index bc66b82..84303d1 100644 --- a/PVE/Network/SDN/SubnetPlugin.pm +++ b/PVE/Network/SDN/SubnetPlugin.pm @@ -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; =20 PVE::Cluster::cfs_register_file('sdn/subnets.cfg', sub { __PACKAGE__->parse_config(@_); }, @@ -52,6 +54,10 @@ sub private { =20 sub properties { return { + vnet =3D> { + type =3D> 'string', + description =3D> "associated vnet", + }, gateway =3D> { type =3D> 'string', format =3D> 'ip', description =3D> "Subnet Gateway: Will be assign on vnet for= layer3 zones", @@ -94,6 +100,7 @@ sub properties { =20 sub options { return { + vnet =3D> { optional =3D> 1 }, gateway =3D> { optional =3D> 1 }, routes =3D> { optional =3D> 1 }, snat =3D> { optional =3D> 1 }, @@ -107,44 +114,66 @@ sub options { } =20 sub on_update_hook { - my ($class, $subnetid, $subnet_cfg) =3D @_; + my ($class, $subnetid, $subnet, $old_subnet) =3D @_; =20 my $cidr =3D $subnetid =3D~ s/-/\//r; my $subnet_matcher =3D subnet_matcher($cidr); =20 - my $subnet =3D $subnet_cfg->{ids}->{$subnetid}; - + my $vnetid =3D $subnet->{vnet}; my $gateway =3D $subnet->{gateway}; + my $ipam =3D $subnet->{ipam}; my $dns =3D $subnet->{dns}; my $dnszone =3D $subnet->{dnszone}; my $reversedns =3D $subnet->{reversedns}; my $reversednszone =3D $subnet->{reversednszone}; =20 - my ($ip, $mask) =3D split(/\//, $cidr); + my $old_gateway =3D $old_subnet->{gateway} if $old_subnet; =20 + if($vnetid) { + my $vnet =3D PVE::Network::SDN::Vnets::get_vnet($vnetid); + raise_param_exc({ vnet =3D> "$vnetid don't exist"}) if !$vnet; + } + + my ($ip, $mask) =3D split(/\//, $cidr); #for /32 pointopoint, we allow gateway outside the subnet - raise_param_exc({ gateway =3D> "$gateway is not in subnet $subnet"})= if $gateway && !$subnet_matcher->($gateway) && $mask !=3D 32; + raise_param_exc({ gateway =3D> "$gateway is not in subnet $subnetid"= }) if $gateway && !$subnet_matcher->($gateway) && $mask !=3D 32; =20 raise_param_exc({ dns =3D> "missing dns provider"}) if $dnszone && != $dns; raise_param_exc({ dnszone =3D> "missing dns zone"}) if $dns && !$dns= zone; raise_param_exc({ reversedns =3D> "missing dns provider"}) if $rever= sednszone && !$reversedns; raise_param_exc({ reversednszone =3D> "missing dns zone"}) if $rever= sedns && !$reversednszone; =20 + if ($ipam) { + my $ipam_cfg =3D PVE::Network::SDN::Ipams::config(); + my $plugin_config =3D $ipam_cfg->{ids}->{$ipam}; + raise_param_exc({ ipam =3D> "$ipam not existing"}) if !$plugin_config; + my $plugin =3D 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_gatewa= y); + }; + 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_gatewa= y); + }; + warn if $@; + } + } } =20 sub on_delete_hook { my ($class, $subnetid, $subnet_cfg, $vnet_cfg) =3D @_; =20 - #verify if vnets have subnet - foreach my $vnetid (keys %{$vnet_cfg->{ids}}) { - my $vnet =3D $vnet_cfg->{ids}->{$vnetid}; - my @subnets =3D PVE::Tools::split_list($vnet->{subnets}) if $vnet->{sub= nets}; - foreach my $subnet (@subnets) { - my $id =3D $subnet =3D~ s/\//-/r; - raise_param_exc({ subnet =3D> "$subnet is attached to vnet $vnetid"= }) if $id eq $subnetid; - } - } - return; } =20 diff --git a/PVE/Network/SDN/Subnets.pm b/PVE/Network/SDN/Subnets.pm index 4e8353e..d20af9e 100644 --- a/PVE/Network/SDN/Subnets.pm +++ b/PVE/Network/SDN/Subnets.pm @@ -57,20 +57,18 @@ sub get_subnet { } =20 sub find_ip_subnet { - my ($ip, $subnetslist) =3D @_; - - my $subnets_cfg =3D PVE::Network::SDN::Subnets::config(); - my @subnets =3D PVE::Tools::split_list($subnetslist) if $subnetslist= ; + my ($ip, $subnets) =3D @_; =20 my $subnet =3D undef; my $subnetid =3D undef; =20 - foreach my $s (@subnets) { - my $subnet_matcher =3D subnet_matcher($s); - next if !$subnet_matcher->($ip); - $subnetid =3D $s =3D~ s/\//-/r; - $subnet =3D $subnets_cfg->{ids}->{$subnetid}; - last; + foreach my $id (sort keys %{$subnets}) { + my $cidr =3D $id =3D~ s/-/\//r; + my $subnet_matcher =3D subnet_matcher($cidr); + next if !$subnet_matcher->($ip); + $subnet =3D $subnets->{$id}; + $subnetid =3D $id; + last; } die "can't find any subnet for ip $ip" if !$subnet; =20 @@ -143,8 +141,11 @@ sub next_free_ip { my $ipam_cfg =3D PVE::Network::SDN::Ipams::config(); my $plugin_config =3D $ipam_cfg->{ids}->{$ipamid}; my $plugin =3D PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config-= >{type}); - $cidr =3D $plugin->add_next_freeip($plugin_config, $subnetid, $subnet); - ($ip, undef) =3D split(/\//, $cidr); + eval { + $cidr =3D $plugin->add_next_freeip($plugin_config, $subnetid, $subn= et); + ($ip, undef) =3D split(/\//, $cidr); + }; + die $@ if $@; } =20 eval { @@ -167,6 +168,8 @@ sub next_free_ip { sub add_ip { my ($subnetid, $subnet, $ip, $hostname) =3D @_; =20 + return if !$subnet; + my $ipamid =3D $subnet->{ipam}; my $dns =3D $subnet->{dns}; my $dnszone =3D $subnet->{dnszone}; @@ -182,7 +185,10 @@ sub add_ip { my $ipam_cfg =3D PVE::Network::SDN::Ipams::config(); my $plugin_config =3D $ipam_cfg->{ids}->{$ipamid}; my $plugin =3D 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 $@; } =20 eval { @@ -204,6 +210,8 @@ sub add_ip { sub del_ip { my ($subnetid, $subnet, $ip, $hostname) =3D @_; =20 + return if !$subnet; + my $ipamid =3D $subnet->{ipam}; my $dns =3D $subnet->{dns}; my $dnszone =3D $subnet->{dnszone}; diff --git a/PVE/Network/SDN/VnetPlugin.pm b/PVE/Network/SDN/VnetPlugin.p= m index 6b2bcc8..47fd4d4 100644 --- a/PVE/Network/SDN/VnetPlugin.pm +++ b/PVE/Network/SDN/VnetPlugin.pm @@ -68,11 +68,6 @@ sub properties { description =3D> "alias name of the vnet", optional =3D> 1, }, - subnets =3D> { - type =3D> 'string', - description =3D> "Subnets list", - optional =3D> 1, - }, mac =3D> { type =3D> 'string', description =3D> "Anycast router mac address", @@ -86,16 +81,21 @@ sub options { zone =3D> { optional =3D> 0}, tag =3D> { optional =3D> 1}, alias =3D> { optional =3D> 1 }, - subnets =3D> { optional =3D> 1 }, mac =3D> { optional =3D> 1 }, vlanaware =3D> { optional =3D> 1 }, }; } =20 sub on_delete_hook { - my ($class, $sdnid, $vnet_cfg) =3D @_; + my ($class, $vnetid, $vnet_cfg) =3D @_; =20 - return; + #verify if subnets are associated + my $subnets =3D PVE::Network::SDN::Vnets::get_subnets($vnetid); + my @subnetlist =3D (); + foreach my $subnetid (sort keys %{$subnets}) { + push @subnetlist, $subnetid; + } + raise_param_exc({ vnet =3D> "Vnet is attached to following subnets:"= . join(',', @subnetlist)}) if @subnetlist > 0; } =20 sub on_update_hook { @@ -111,13 +111,6 @@ sub on_update_hook { } } } - - #verify subnet - my @subnets =3D PVE::Tools::split_list($vnet_cfg->{ids}->{$vnetid}->= {subnets}) if $vnet_cfg->{ids}->{$vnetid}->{subnets}; - foreach my $subnet (@subnets) { - my $id =3D $subnet =3D~ s/\//-/r; - raise_param_exc({ subnet =3D> "$subnet not existing"}) if !$subnet_cfg-= >{ids}->{$id}; - } } =20 1; diff --git a/PVE/Network/SDN/Vnets.pm b/PVE/Network/SDN/Vnets.pm index c9916b1..7cec418 100644 --- a/PVE/Network/SDN/Vnets.pm +++ b/PVE/Network/SDN/Vnets.pm @@ -54,22 +54,35 @@ sub get_vnet { return $vnet; } =20 +sub get_subnets { + my ($vnetid) =3D @_; + + my $subnets =3D {}; + my $subnets_cfg =3D PVE::Network::SDN::Subnets::config(); + foreach my $subnetid (sort keys %{$subnets_cfg->{ids}}) { + my $subnet =3D $subnets_cfg->{ids}->{$subnetid}; + next if !$subnet->{vnet} || $subnet->{vnet} ne $vnetid; + $subnets->{$subnetid} =3D $subnet; + } + return $subnets; + +} + sub get_next_free_ip { - my ($vnet, $hostname, $ipversion) =3D @_; + my ($vnetid, $hostname, $ipversion) =3D @_; =20 $ipversion =3D 4 if !$ipversion; - my $subnets_cfg =3D PVE::Network::SDN::Subnets::config(); - my @subnets =3D PVE::Tools::split_list($vnet->{subnets}) if $vnet->{= subnets}; + my $subnets =3D PVE::Network::SDN::Vnets::get_subnets($vnetid); my $ip =3D undef; - my $subnet =3D undef; my $subnetcount =3D 0; - foreach my $s (@subnets) { - my $subnetid =3D $s =3D~ s/\//-/r; + + foreach my $subnetid (sort keys %{$subnets}) { + my $subnet =3D $subnets->{$subnetid}; my ($network, $mask) =3D split(/-/, $subnetid); + next if $ipversion !=3D Net::IP::ip_get_version($network); $subnetcount++; - $subnet =3D $subnets_cfg->{ids}->{$subnetid}; - if ($subnet && $subnet->{ipam}) { + if ($subnet->{ipam}) { eval { $ip =3D PVE::Network::SDN::Subnets::next_free_ip($subnetid, $subnet, $= hostname); }; @@ -83,21 +96,23 @@ sub get_next_free_ip { } =20 sub add_ip { - my ($vnet, $cidr, $hostname) =3D @_; + my ($vnetid, $cidr, $hostname) =3D @_; + + my $subnets =3D PVE::Network::SDN::Vnets::get_subnets($vnetid); =20 my ($ip, $mask) =3D split(/\//, $cidr); - my ($subnetid, $subnet) =3D PVE::Network::SDN::Subnets::find_ip_subn= et($ip, $vnet->{subnets}); - return if !$subnet->{ipam}; + my ($subnetid, $subnet) =3D PVE::Network::SDN::Subnets::find_ip_subn= et($ip, $subnets); =20 PVE::Network::SDN::Subnets::add_ip($subnetid, $subnet, $ip, $hostnam= e); } =20 sub del_ip { - my ($vnet, $cidr, $hostname) =3D @_; + my ($vnetid, $cidr, $hostname) =3D @_; + + my $subnets =3D PVE::Network::SDN::Vnets::get_subnets($vnetid); =20 my ($ip, $mask) =3D split(/\//, $cidr); - my ($subnetid, $subnet) =3D PVE::Network::SDN::Subnets::find_ip_subn= et($ip, $vnet->{subnets}); - return if !$subnet->{ipam}; + my ($subnetid, $subnet) =3D PVE::Network::SDN::Subnets::find_ip_subn= et($ip, $subnets); =20 PVE::Network::SDN::Subnets::del_ip($subnetid, $subnet, $ip, $hostnam= e); } diff --git a/PVE/Network/SDN/Zones/EvpnPlugin.pm b/PVE/Network/SDN/Zones/= EvpnPlugin.pm index 17c9262..ff25f12 100644 --- a/PVE/Network/SDN/Zones/EvpnPlugin.pm +++ b/PVE/Network/SDN/Zones/EvpnPlugin.pm @@ -76,12 +76,12 @@ sub generate_sdn_config { #vnet bridge @iface_config =3D (); =20 - my @subnets =3D PVE::Tools::split_list($vnet->{subnets}) if $vnet->{= subnets}; my $address =3D {}; - foreach my $subnet (@subnets) { - my $subnetid =3D $subnet =3D~ s/\//-/r; - next if !defined($subnet_cfg->{ids}->{$subnetid}); - my $gateway =3D $subnet_cfg->{ids}->{$subnetid}->{gateway}; + my $subnets =3D PVE::Network::SDN::Vnets::get_subnets($vnetid); + foreach my $subnetid (sort keys %{$subnets}) { + my $subnet =3D $subnets->{$subnetid}; + my $cidr =3D $subnetid =3D~ s/-/\//r; + my $gateway =3D $subnet->{gateway}; if ($gateway) { push @iface_config, "address $gateway" if !defined($address->{$gate= way}); $address->{$gateway} =3D 1; diff --git a/PVE/Network/SDN/Zones/SimplePlugin.pm b/PVE/Network/SDN/Zone= s/SimplePlugin.pm index a1733d5..a4299dd 100644 --- a/PVE/Network/SDN/Zones/SimplePlugin.pm +++ b/PVE/Network/SDN/Zones/SimplePlugin.pm @@ -35,19 +35,19 @@ sub generate_sdn_config { # vnet bridge my @iface_config =3D (); =20 - my @subnets =3D PVE::Tools::split_list($vnet->{subnets}) if $vnet->{= subnets}; my $address =3D {}; - foreach my $subnet (@subnets) { - my $subnetid =3D $subnet =3D~ s/\//-/r; - next if !defined($subnet_cfg->{ids}->{$subnetid}); - my $gateway =3D $subnet_cfg->{ids}->{$subnetid}->{gateway}; - if ($gateway) { + my $subnets =3D PVE::Network::SDN::Vnets::get_subnets($vnetid); + foreach my $subnetid (sort keys %{$subnets}) { + my $subnet =3D $subnets->{$subnetid}; + my $cidr =3D $subnetid =3D~ s/-/\//r;=20 + my $gateway =3D $subnet->{gateway}; + if ($gateway) { push @iface_config, "address $gateway" if !defined($address->{$gate= way}); $address->{$gateway} =3D 1; } #add route for /32 pointtopoint - my ($ip, $mask) =3D split(/\//, $subnet); - push @iface_config, "up ip route add $subnet dev $vnetid" if $mask =3D=3D= 32; + my ($ip, $mask) =3D split(/\//, $cidr); + push @iface_config, "up ip route add $cidr dev $vnetid" if $mask =3D=3D= 32; } =20 push @iface_config, "hwaddress $mac" if $mac; --=20 2.20.1