check all plumbing interfaces needed for vnets Signed-off-by: Alexandre Derumier <aderum...@odiso.com> --- PVE/Network/SDN/Zones.pm | 29 +++++++++++++--- PVE/Network/SDN/Zones/Plugin.pm | 35 ++++++++------------ PVE/Network/SDN/Zones/QinQPlugin.pm | 51 +++++++++++++++++++++-------- PVE/Network/SDN/Zones/VlanPlugin.pm | 47 ++++++++++++++++++-------- 4 files changed, 109 insertions(+), 53 deletions(-)
diff --git a/PVE/Network/SDN/Zones.pm b/PVE/Network/SDN/Zones.pm index 4fd4a14..df4c0da 100644 --- a/PVE/Network/SDN/Zones.pm +++ b/PVE/Network/SDN/Zones.pm @@ -178,7 +178,7 @@ sub ifquery_check { } my $warned_about_reload; -# improve me : move status code inside plugins ? + sub status { my $err_config = undef; @@ -210,10 +210,17 @@ sub status { my $zone_cfg = PVE::Cluster::cfs_read_file('sdn/zones.cfg'); my $nodename = PVE::INotify::nodename(); - - my $vnet_status = {}; + my $vnet_status = {}; my $zone_status = {}; + foreach my $id (sort keys %{$zone_cfg->{ids}}) { + $zone_status->{$id}->{status} = 'available'; + if($err_config) { + $zone_status->{$id}->{status} = 'pending'; + next; + } + } + foreach my $id (sort keys %{$vnet_cfg->{ids}}) { my $vnet = $vnet_cfg->{ids}->{$id}; my $zone = $vnet->{zone}; @@ -222,8 +229,22 @@ sub status { my $plugin_config = $zone_cfg->{ids}->{$zone}; next if defined($plugin_config->{nodes}) && !$plugin_config->{nodes}->{$nodename}; + $vnet_status->{$id}->{zone} = $zone; + $vnet_status->{$id}->{status} = 'available'; + + if($err_config) { + $vnet_status->{$id}->{status} = 'pending'; + $vnet_status->{$id}->{statusmsg} = $err_config; + next; + } + my $plugin = PVE::Network::SDN::Zones::Plugin->lookup($plugin_config->{type}); - $plugin->status($plugin_config, $zone, $id, $vnet, $err_config, $status, $vnet_status, $zone_status); + my $err_msg = $plugin->status($plugin_config, $zone, $id, $vnet, $status); + if (@{$err_msg} > 0) { + $vnet_status->{$id}->{status} = 'error'; + $vnet_status->{$id}->{statusmsg} = join(',', @{$err_msg}); + $zone_status->{$id}->{status} = 'error'; + } } return($zone_status, $vnet_status); diff --git a/PVE/Network/SDN/Zones/Plugin.pm b/PVE/Network/SDN/Zones/Plugin.pm index 0633b78..190a153 100644 --- a/PVE/Network/SDN/Zones/Plugin.pm +++ b/PVE/Network/SDN/Zones/Plugin.pm @@ -178,30 +178,21 @@ sub parse_tag_number_or_range { } sub status { - my ($class, $plugin_config, $zone, $id, $vnet, $err_config, $status, $vnet_status, $zone_status) = @_; - - $vnet_status->{$id}->{zone} = $zone; - $zone_status->{$zone}->{status} = 'available' if !defined($zone_status->{$zone}->{status}); - - if($err_config) { - $vnet_status->{$id}->{status} = 'pending'; - $vnet_status->{$id}->{statusmsg} = $err_config; - $zone_status->{$zone}->{status} = 'pending'; - } elsif ($status->{$id}->{status} && $status->{$id}->{status} eq 'pass') { - $vnet_status->{$id}->{status} = 'available'; - my $bridgeport = $status->{$id}->{config}->{'bridge-ports'}; - - if ($bridgeport && $status->{$bridgeport}->{status} && $status->{$bridgeport}->{status} ne 'pass') { - $vnet_status->{$id}->{status} = 'error'; - $vnet_status->{$id}->{statusmsg} = 'configuration not fully applied'; - $zone_status->{$zone}->{status} = 'error'; - } + my ($class, $plugin_config, $zone, $vnetid, $vnet, $status) = @_; + + my $err_msg = []; - } else { - $vnet_status->{$id}->{status} = 'error'; - $vnet_status->{$id}->{statusmsg} = 'missing'; - $zone_status->{$zone}->{status} = 'error'; + # ifaces to check + my $ifaces = [ $vnetid ]; + + foreach my $iface (@{$ifaces}) { + if (!$status->{$iface}->{status}) { + push @$err_msg, "missing $iface"; + } elsif ($status->{$iface}->{status} ne 'pass') { + push @$err_msg, "error $iface"; + } } + return $err_msg; } diff --git a/PVE/Network/SDN/Zones/QinQPlugin.pm b/PVE/Network/SDN/Zones/QinQPlugin.pm index 73c2e84..f1c3222 100644 --- a/PVE/Network/SDN/Zones/QinQPlugin.pm +++ b/PVE/Network/SDN/Zones/QinQPlugin.pm @@ -166,23 +166,48 @@ sub generate_sdn_config { } sub status { - my ($class, $plugin_config, $zone, $id, $vnet, $err_config, $status, $vnet_status, $zone_status) = @_; + my ($class, $plugin_config, $zone, $vnetid, $vnet, $status) = @_; my $bridge = $plugin_config->{bridge}; - $vnet_status->{$id}->{zone} = $zone; - $zone_status->{$zone}->{status} = 'available' if !defined($zone_status->{$zone}->{status}); - - if($err_config) { - $vnet_status->{$id}->{status} = 'pending'; - $vnet_status->{$id}->{statusmsg} = $err_config; - $zone_status->{$zone}->{status} = 'pending'; - } elsif ($status->{$bridge}->{status} && $status->{$bridge}->{status} eq 'pass') { - $vnet_status->{$id}->{status} = 'available'; + my $err_msg = []; + + if (!-d "/sys/class/net/$bridge") { + push @$err_msg, "missing $bridge"; + return $err_msg; + } + + my $vlan_aware = PVE::Tools::file_read_firstline("/sys/class/net/$bridge/bridge/vlan_filtering"); + my $is_ovs = 1 if !-d "/sys/class/net/$bridge/brif"; + + my $tag = $vnet->{tag}; + my $vnet_uplink = "ln_".$vnetid; + my $vnet_uplinkpeer = "pr_".$vnetid; + + # ifaces to check + my $ifaces = [ $vnetid, $bridge ]; + if($is_ovs) { + my $svlan_iface = "sv_".$zone; + my $zonebridge = "z_$zone"; + push @$ifaces, $svlan_iface; + push @$ifaces, $zonebridge; + } elsif ($vlan_aware) { + my $zonebridge = "z_$zone"; + push @$ifaces, $zonebridge; } else { - $vnet_status->{$id}->{status} = 'error'; - $vnet_status->{$id}->{statusmsg} = 'missing bridge'; - $zone_status->{$zone}->{status} = 'error'; + my $svlan_iface = "sv_$vnetid"; + my $cvlan_iface = "cv_$vnetid"; + push @$ifaces, $svlan_iface; + push @$ifaces, $cvlan_iface; + } + + foreach my $iface (@{$ifaces}) { + if (!$status->{$iface}->{status}) { + push @$err_msg, "missing $iface"; + } elsif ($status->{$iface}->{status} ne 'pass') { + push @$err_msg, "error $iface"; + } } + return $err_msg; } 1; diff --git a/PVE/Network/SDN/Zones/VlanPlugin.pm b/PVE/Network/SDN/Zones/VlanPlugin.pm index edb132c..8721287 100644 --- a/PVE/Network/SDN/Zones/VlanPlugin.pm +++ b/PVE/Network/SDN/Zones/VlanPlugin.pm @@ -131,23 +131,42 @@ sub generate_sdn_config { } sub status { - my ($class, $plugin_config, $zone, $id, $vnet, $err_config, $status, $vnet_status, $zone_status) = @_; + my ($class, $plugin_config, $zone, $vnetid, $vnet, $status) = @_; my $bridge = $plugin_config->{bridge}; - $vnet_status->{$id}->{zone} = $zone; - $zone_status->{$zone}->{status} = 'available' if !defined($zone_status->{$zone}->{status}); - - if($err_config) { - $vnet_status->{$id}->{status} = 'pending'; - $vnet_status->{$id}->{statusmsg} = $err_config; - $zone_status->{$zone}->{status} = 'pending'; - } elsif ($status->{$bridge}->{status} && $status->{$bridge}->{status} eq 'pass') { - $vnet_status->{$id}->{status} = 'available'; - } else { - $vnet_status->{$id}->{status} = 'error'; - $vnet_status->{$id}->{statusmsg} = 'missing bridge'; - $zone_status->{$zone}->{status} = 'error'; + + my $err_msg = []; + if (!-d "/sys/class/net/$bridge") { + push @$err_msg, "missing $bridge"; + return $err_msg; } + + my $vlan_aware = PVE::Tools::file_read_firstline("/sys/class/net/$bridge/bridge/vlan_filtering"); + my $is_ovs = 1 if !-d "/sys/class/net/$bridge/brif"; + + my $tag = $vnet->{tag}; + my $vnet_uplink = "ln_".$vnetid; + my $vnet_uplinkpeer = "pr_".$vnetid; + + # ifaces to check + my $ifaces = [ $vnetid, $bridge ]; + if($is_ovs) { + push @$ifaces, $vnet_uplink; + } elsif (!$vlan_aware) { + my $bridgevlan = $bridge."v".$tag; + push @$ifaces, $bridgevlan; + push @$ifaces, $vnet_uplink; + push @$ifaces, $vnet_uplinkpeer; + } + + foreach my $iface (@{$ifaces}) { + if (!$status->{$iface}->{status}) { + push @$err_msg, "missing $iface"; + } elsif ($status->{$iface}->{status} ne 'pass') { + push @$err_msg, "error iface $iface"; + } + } + return $err_msg; } 1; -- 2.20.1 _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel