}
my $warned_about_reload;
-# improve me : move status code inside plugins ?
+
sub status {
my $err_config = undef;
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};
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);
}
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;
}
}
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;
}
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;