mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-05-25 21:22:05 +00:00
655 lines
23 KiB
Perl
Executable File
655 lines
23 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
package xCAT_plugin::vlan::BNTSwitch;
|
|
|
|
BEGIN
|
|
{
|
|
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
|
|
}
|
|
use lib "$::XCATROOT/lib/perl";
|
|
use strict;
|
|
use xCAT::MacMap;
|
|
use xCAT::Table;
|
|
use Data::Dumper;
|
|
use xCAT::SwitchHandler;
|
|
use SNMP;
|
|
|
|
my $sysDescr = '.1.3.6.1.2.1.1.1';
|
|
|
|
#BNT uses different OIDs for different switch module and versions. The following
|
|
#assumes that the FW versions are v6.x.
|
|
#G8100 is not supported yet because it uses different method. No hw to test.
|
|
my $BNTOID = {
|
|
'EN4093' => {
|
|
'vlanInfoId' => '.1.3.6.1.4.1.20301.2.5.2.3.5.1.1.1',
|
|
'vlanInfoPorts' => '.1.3.6.1.4.1.20301.2.5.2.3.5.1.1.7',
|
|
'portInfoPhyIfDescr' => '.1.3.6.1.4.1.20301.2.5.1.3.2.1.1.6',
|
|
'vlanNewCfgVlanName' => '.1.3.6.1.4.1.20301.2.5.2.1.1.3.1.2',
|
|
'vlanNewCfgState' => '.1.3.6.1.4.1.20301.2.5.2.1.1.3.1.4', #2:enable 3:disable
|
|
'vlanNewCfgAddPort' => '.1.3.6.1.4.1.20301.2.5.2.1.1.3.1.5',
|
|
'vlanNewCfgRemovePort' => '.1.3.6.1.4.1.20301.2.5.2.1.1.3.1.6',
|
|
'vlanNewCfgDelete' => '.1.3.6.1.4.1.20301.2.5.2.1.1.3.1.7', #1:other 2:delete
|
|
'agPortNewCfgVlanTag' => '.1.3.6.1.4.1.20301.2.5.1.1.2.3.1.3', #2:tagged 3:untagged
|
|
'agPortNewCfgBpduGuard' => '.1.3.6.1.4.1.20301.2.5.1.1.2.3.1.41', #1:enable 2:disable
|
|
'agPortNewCfgStpExtGuard' => '.1.3.6.1.4.1.20301.2.5.1.1.2.3.1.52', #1:loop, 2:root, 3:none, 0:default
|
|
'agApplyConfig' => '.1.3.6.1.4.1.20301.2.5.1.1.8.2',
|
|
'agSaveConfiguration' => '.1.3.6.1.4.1.20301.2.5.1.1.1.4', #saveActive(2), notSaveActive(3)
|
|
'arpInfoDestIp' => '.1.3.6.1.4.1.20301.2.5.3.3.2.1.1.1',
|
|
'arpInfoSrcPort' => '.1.3.6.1.4.1.20301.2.5.3.3.2.1.1.4',
|
|
},
|
|
|
|
'G8000' => {
|
|
'vlanInfoId' => '.1.3.6.1.4.1.26543.2.7.1.2.3.5.1.1.1',
|
|
'vlanInfoPorts' => '.1.3.6.1.4.1.26543.2.7.1.2.3.5.1.1.7',
|
|
'portInfoPhyIfDescr' => '.1.3.6.1.4.1.26543.2.7.1.1.3.2.1.1.6',
|
|
'vlanNewCfgVlanName' => '.1.3.6.1.4.1.26543.2.7.1.2.1.1.3.1.2',
|
|
'vlanNewCfgState' => '.1.3.6.1.4.1.26543.2.7.1.2.1.1.3.1.4', #2:enable 3:disable
|
|
'vlanNewCfgAddPort' => '.1.3.6.1.4.1.26543.2.7.1.2.1.1.3.1.5',
|
|
'vlanNewCfgRemovePort' => '.1.3.6.1.4.1.26543.2.7.1.2.1.1.3.1.6',
|
|
'vlanNewCfgDelete' => '.1.3.6.1.4.1.26543.2.7.1.2.1.1.3.1.7', #1:other 2:delete
|
|
'agPortNewCfgVlanTag' => '.1.3.6.1.4.1.26543.2.7.1.1.1.2.3.1.3', #2:tagged 3:untagged
|
|
'agPortNewCfgBpduGuard' => '.1.3.6.1.4.1.26543.2.7.1.1.1.2.3.1.41', #1:enable 2:disable
|
|
'agPortNewCfgStpExtGuard' => '.1.3.6.1.4.1.26543.2.7.1.1.1.2.3.1.52', #1:loop, 2:root, 3:none, 0:default
|
|
'agApplyConfig' => '.1.3.6.1.4.1.26543.2.7.1.1.1.8.2',
|
|
'agSaveConfiguration' => '.1.3.6.1.4.1.26543.2.7.1.1.1.1.4', #saveActive(2), notSaveActive(3)
|
|
'arpInfoDestIp' => '.1.3.6.1.4.1.26543.2.7.1.3.3.2.1.1.1',
|
|
'arpInfoSrcPort' => '.1.3.6.1.4.1.26543.2.7.1.3.3.2.1.1.4',
|
|
},
|
|
|
|
'G8052' => {
|
|
'vlanInfoId' => '.1.3.6.1.4.1.26543.2.7.7.2.3.5.1.1.1',
|
|
'vlanInfoPorts' => '.1.3.6.1.4.1.26543.2.7.7.2.3.5.1.1.7',
|
|
'portInfoPhyIfDescr' => '.1.3.6.1.4.1.26543.2.7.7.1.3.2.1.1.6',
|
|
'vlanNewCfgVlanName' => '.1.3.6.1.4.1.26543.2.7.7.2.1.1.3.1.2',
|
|
'vlanNewCfgState' => '.1.3.6.1.4.1.26543.2.7.7.2.1.1.3.1.4',
|
|
'vlanNewCfgAddPort' => '.1.3.6.1.4.1.26543.2.7.7.2.1.1.3.1.5',
|
|
'vlanNewCfgRemovePort' => '.1.3.6.1.4.1.26543.2.7.7.2.1.1.3.1.6',
|
|
'vlanNewCfgDelete' => '.1.3.6.1.4.1.26543.2.7.7.2.1.1.3.1.7',
|
|
'agPortNewCfgVlanTag' => '.1.3.6.1.4.1.26543.2.7.7.1.1.2.3.1.3',
|
|
'agPortNewCfgBpduGuard' => '.1.3.6.1.4.1.26543.2.7.7.1.1.2.3.1.41',
|
|
'agPortNewCfgStpExtGuard' => '.1.3.6.1.4.1.26543.2.7.7.1.1.2.3.1.52',
|
|
'agApplyConfig' => '.1.3.6.1.4.1.26543.2.7.7.1.1.8.2',
|
|
'agSaveConfiguration' => '.1.3.6.1.4.1.26543.2.7.7.1.1.1.4', #saveActive(2), notSaveActive(3)
|
|
'arpInfoDestIp' => '.1.3.6.1.4.1.26543.2.7.7.3.3.2.1.1.1',
|
|
'arpInfoSrcPort' => '.1.3.6.1.4.1.26543.2.7.7.3.3.2.1.1.4',
|
|
},
|
|
|
|
'G8124' => {
|
|
'vlanInfoId' => '.1.3.6.1.4.1.26543.2.7.4.2.3.5.1.1.1',
|
|
'vlanInfoPorts' => '.1.3.6.1.4.1.26543.2.7.4.2.3.5.1.1.7',
|
|
'portInfoPhyIfDescr' => '.1.3.6.1.4.1.26543.2.7.4.1.3.2.1.1.6',
|
|
'vlanNewCfgVlanName' => '.1.3.6.1.4.1.26543.2.7.4.2.1.1.3.1.2',
|
|
'vlanNewCfgState' => '.1.3.6.1.4.1.26543.2.7.4.2.1.1.3.1.4',
|
|
'vlanNewCfgAddPort' => '.1.3.6.1.4.1.26543.2.7.4.2.1.1.3.1.5',
|
|
'vlanNewCfgRemovePort' => '.1.3.6.1.4.1.26543.2.7.4.2.1.1.3.1.6',
|
|
'vlanNewCfgDelete' => '.1.3.6.1.4.1.26543.2.7.4.2.1.1.3.1.7',
|
|
'agPortNewCfgVlanTag' => '.1.3.6.1.4.1.26543.2.7.4.1.1.2.3.1.3',
|
|
'agPortNewCfgBpduGuard' => '.1.3.6.1.4.1.26543.2.7.4.1.1.2.3.1.41',
|
|
'agPortNewCfgStpExtGuard' => '.1.3.6.1.4.1.26543.2.7.4.1.1.2.3.1.52',
|
|
'agApplyConfig' => '.1.3.6.1.4.1.26543.2.7.4.1.1.8.2',
|
|
'agSaveConfiguration' => '.1.3.6.1.4.1.26543.2.7.4.1.1.1.4', #saveActive(2), notSaveActive(3)
|
|
'arpInfoDestIp' => '.1.3.6.1.4.1.26543.2.7.4.3.3.2.1.1.1',
|
|
'arpInfoSrcPort' => '.1.3.6.1.4.1.26543.2.7.4.3.3.2.1.1.4',
|
|
},
|
|
|
|
#this is for G8264 and 8264E
|
|
'G8264' => {
|
|
'vlanInfoId' => '.1.3.6.1.4.1.26543.2.7.6.2.3.5.1.1.1',
|
|
'vlanInfoPorts' => '.1.3.6.1.4.1.26543.2.7.6.2.3.5.1.1.7',
|
|
'portInfoPhyIfDescr' => '.1.3.6.1.4.1.26543.2.7.6.1.3.2.1.1.6',
|
|
'vlanNewCfgVlanName' => '.1.3.6.1.4.1.26543.2.7.6.2.1.1.3.1.2',
|
|
'vlanNewCfgState' => '.1.3.6.1.4.1.26543.2.7.6.2.1.1.3.1.4',
|
|
'vlanNewCfgAddPort' => '.1.3.6.1.4.1.26543.2.7.6.2.1.1.3.1.5',
|
|
'vlanNewCfgRemovePort' => '.1.3.6.1.4.1.26543.2.7.6.2.1.1.3.1.6',
|
|
'vlanNewCfgDelete' => '.1.3.6.1.4.1.26543.2.7.6.2.1.1.3.1.7',
|
|
'agPortNewCfgVlanTag' => '.1.3.6.1.4.1.26543.2.7.6.1.1.2.3.1.3',
|
|
'agPortNewCfgBpduGuard' => '.1.3.6.1.4.1.26543.2.7.6.1.1.2.3.1.41',
|
|
'agPortNewCfgStpExtGuard' => '.1.3.6.1.4.1.26543.2.7.6.1.1.2.3.1.52',
|
|
'agApplyConfig' => '.1.3.6.1.4.1.26543.2.7.6.1.1.8.2',
|
|
'agSaveConfiguration' => '.1.3.6.1.4.1.26543.2.7.6.1.1.1.4', #saveActive(2), notSaveActive(3)
|
|
'arpInfoDestIp' => '.1.3.6.1.4.1.26543.2.7.6.3.3.2.1.1.1',
|
|
'arpInfoSrcPort' => '.1.3.6.1.4.1.26543.2.7.6.3.3.2.1.1.4',
|
|
},
|
|
};
|
|
|
|
|
|
my %HexConv = (0 => 0x80, 1 => 0x40, 2 => 0x20, 3 => 0x10,
|
|
4 => 0x08, 5 => 0x04, 6 => 0x02, 7 => 0x01);
|
|
|
|
|
|
#--------------------------------------------------------------
|
|
|
|
=head3 filter_string
|
|
|
|
Every switch plugin must implement this subroutine.
|
|
|
|
The return value will be used comare against the string
|
|
from sysDescr value from snmpget. If the latter contains
|
|
this string, then this mudule will be used to handle the
|
|
requests for vlan configuration.
|
|
|
|
=cut
|
|
|
|
#-------------------------------------------------------------
|
|
sub filter_string {
|
|
return "BNT |Blade Network Technologies|IBM Networking Operating System|EN4093";
|
|
}
|
|
|
|
|
|
#--------------------------------------------------------------
|
|
|
|
=head3 get_vlan_ids
|
|
|
|
Every switch plugin must implement this subroutine.
|
|
|
|
It gets the existing vlan IDs for the switch.
|
|
Returns: an array containing all the vlan ids for the switch
|
|
=cut
|
|
|
|
#-------------------------------------------------------------
|
|
sub get_vlan_ids {
|
|
my $session = shift;
|
|
|
|
my $swmod = getSwitchModule($session);
|
|
if (!$swmod) { return (); }
|
|
|
|
my $vlanmap = xCAT::MacMap::walkoid($session, $BNTOID->{$swmod}->{vlanInfoId}, silentfail => 1);
|
|
|
|
my %vlanids = ();
|
|
foreach (keys(%$vlanmap)) {
|
|
$vlanids{$_} = 1;
|
|
}
|
|
|
|
my @ret = (sort keys(%vlanids));
|
|
print "ids=@ret\n";
|
|
return @ret;
|
|
}
|
|
|
|
#--------------------------------------------------------------
|
|
|
|
=head3 get_vlanids_for_ports
|
|
|
|
Every switch plugin must implement this subroutine.
|
|
|
|
It returns a hash pointer that contains the vlan id for each given port.
|
|
The kay is the port, the vlaue is a pointer to an array.
|
|
=cut
|
|
|
|
#-------------------------------------------------------------
|
|
sub get_vlanids_for_ports {
|
|
my $session = shift;
|
|
my @ports = @_;
|
|
|
|
my $swmod = getSwitchModule($session);
|
|
if (!$swmod) { return; }
|
|
|
|
|
|
my $namemap = xCAT::MacMap::walkoid($session, $BNTOID->{$swmod}->{portInfoPhyIfDescr});
|
|
if ($namemap) {
|
|
my $ifnamesupport = 0;
|
|
foreach (keys %{$namemap}) {
|
|
if ($namemap->{$_}) {
|
|
$ifnamesupport = 1;
|
|
last;
|
|
}
|
|
}
|
|
unless ($ifnamesupport) {
|
|
$namemap = 0;
|
|
}
|
|
}
|
|
unless ($namemap) {
|
|
return;
|
|
}
|
|
|
|
#print "namemap=" . Dumper($namemap) . "\n";
|
|
|
|
my $portsvlanmap = xCAT::MacMap::walkoid($session, $BNTOID->{$swmod}->{vlanInfoPorts}, silentfail => 1);
|
|
|
|
#print "portsvlanmap=" . Dumper($portsvlanmap) . "\n";
|
|
foreach my $vid (keys(%$portsvlanmap)) {
|
|
my $data = $portsvlanmap->{$vid};
|
|
my @a = split(//, $data);
|
|
foreach (@a) {
|
|
my $num = unpack("C*", $_);
|
|
$_ = sprintf("%02x", $num);
|
|
}
|
|
$portsvlanmap->{$vid} = \@a;
|
|
}
|
|
|
|
my %ret = ();
|
|
if (defined($portsvlanmap)) {
|
|
foreach my $portid (keys %{$namemap}) {
|
|
my $switchport = $namemap->{$portid};
|
|
foreach my $portname (@ports) {
|
|
unless (xCAT::MacMap::namesmatch($portname, $switchport)) {
|
|
next;
|
|
}
|
|
|
|
foreach my $vid (keys(%$portsvlanmap)) {
|
|
my $data = $portsvlanmap->{$vid};
|
|
my $index = int($portid / 8);
|
|
my $offset = $portid % 8;
|
|
my $num = hex($data->[$index]) & ($HexConv{$offset});
|
|
if ($num != 0) {
|
|
if (exists($ret{$portname})) {
|
|
my $pa = $ret{$portname};
|
|
push(@$pa, $vid);
|
|
} else {
|
|
$ret{$portname} = [$vid];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return \%ret;
|
|
}
|
|
|
|
|
|
#--------------------------------------------------------------
|
|
|
|
=head3 create_vlan
|
|
|
|
Every switch plugin must implement this subroutine.
|
|
|
|
Creates a new vlan on the switch
|
|
Returns an array. (erorcode, errormsg). When errorcode=0, means no error.
|
|
=cut
|
|
|
|
#-------------------------------------------------------------
|
|
sub create_vlan {
|
|
my $session = shift;
|
|
my $vlan_id = shift;
|
|
my $vlan_name = "xcat_vlan_" . $vlan_id;
|
|
|
|
my $swmod = getSwitchModule($session);
|
|
if (!$swmod) { return (1, "This BNT switch modeule is not supported."); }
|
|
|
|
print "BNT $swmod\n";
|
|
|
|
#name
|
|
my @ret = xCAT::SwitchHandler::setoid($session, $BNTOID->{$swmod}->{vlanNewCfgVlanName}, $vlan_id, $vlan_name, 'OCTET');
|
|
if ($ret[0] != 0) {
|
|
$ret[1] = "Set vlanNewCfgVlanName " . $BNTOID->{$swmod}->{vlanNewCfgVlanName} . ".$vlan_id to $vlan_name.\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
|
|
my $tmp = xCAT::MacMap::walkoid($session, $BNTOID->{$swmod}->{vlanNewCfgVlanName});
|
|
|
|
#print "tmp=" . Dumper($tmp) . "\n";
|
|
|
|
#change to enable state
|
|
my @ret = xCAT::SwitchHandler::setoid($session, $BNTOID->{$swmod}->{vlanNewCfgState}, $vlan_id, 2, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1] = "Set vlanNewCfgState " . $BNTOID->{$swmod}->{vlanNewCfgState} . ".$vlan_id to 2(enable).\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
|
|
@ret = apply_changes($session, $swmod);
|
|
|
|
|
|
return @ret;
|
|
}
|
|
|
|
#--------------------------------------------------------------
|
|
|
|
=head3 add_ports_to_vlan
|
|
|
|
Every switch plugin must implement this subroutine.
|
|
|
|
Adds the given ports to the existing vlan
|
|
Returns an array. (erorcode, errormsg). When errorcode=0, means no error.
|
|
=cut
|
|
|
|
#-------------------------------------------------------------
|
|
sub add_ports_to_vlan {
|
|
my $session = shift;
|
|
my $vlan_id = shift;
|
|
|
|
# If portmode is set, we'll set the switchport to untagged(access) mode.
|
|
my $portmode = shift;
|
|
my @ports1 = @_;
|
|
|
|
my $swmod = getSwitchModule($session);
|
|
if (!$swmod) { return (1, "This BNT switch modeule is not supported."); }
|
|
|
|
my $port_vlan_hash = get_vlanids_for_ports($session, @ports1);
|
|
|
|
#print "port_vlan_hash=" . Dumper($port_vlan_hash) . "\n";
|
|
my @ports = ();
|
|
foreach my $port (keys(%$port_vlan_hash)) {
|
|
my $val = $port_vlan_hash->{$port};
|
|
my $found = 0;
|
|
foreach my $tmp_vid (@$val) {
|
|
if ($tmp_vid == $vlan_id) {
|
|
$found = 1;
|
|
last;
|
|
}
|
|
}
|
|
if (!$found) {
|
|
push(@ports, $port);
|
|
}
|
|
}
|
|
|
|
if (@ports == 0) { return (0, ""); }
|
|
|
|
#print "vlan=$vlan_id, ports=@ports\n";
|
|
my $namemap = xCAT::MacMap::walkoid($session, $BNTOID->{$swmod}->{portInfoPhyIfDescr});
|
|
if ($namemap) {
|
|
my $ifnamesupport = 0;
|
|
foreach (keys %{$namemap}) {
|
|
if ($namemap->{$_}) {
|
|
$ifnamesupport = 1;
|
|
last;
|
|
}
|
|
}
|
|
unless ($ifnamesupport) {
|
|
$namemap = 0;
|
|
}
|
|
}
|
|
unless ($namemap) {
|
|
return;
|
|
}
|
|
|
|
#print "namemap=" . Dumper($namemap) . "\n";
|
|
|
|
|
|
foreach my $portid (keys %{$namemap}) {
|
|
my $switchport = $namemap->{$portid};
|
|
foreach my $portname (@ports) {
|
|
unless (xCAT::MacMap::namesmatch($portname, $switchport)) {
|
|
next;
|
|
}
|
|
|
|
print "portid=$portid, vlan_id=$vlan_id\n";
|
|
if ($portmode) {
|
|
|
|
#change this port to untagged
|
|
my @ret = xCAT::SwitchHandler::setoid($session, $BNTOID->{$swmod}->{agPortNewCfgVlanTag}, $portid, 3, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1] = "Set agPortNewCfgVlanTag " . $BNTOID->{$swmod}->{agPortNewCfgVlanTag} . ".$portid to 3(untagged).\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
} else {
|
|
|
|
#change this port to tagged
|
|
my @ret = xCAT::SwitchHandler::setoid($session, $BNTOID->{$swmod}->{agPortNewCfgVlanTag}, $portid, 2, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1] = "Set agPortNewCfgVlanTag " . $BNTOID->{$swmod}->{agPortNewCfgVlanTag} . ".$portid to 2(tagged).\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
}
|
|
|
|
#security feature:
|
|
if ($::XCATSITEVALS{vlansecurity} eq '1') {
|
|
|
|
#enable bpdu guard on this port
|
|
my @ret = xCAT::SwitchHandler::setoid($session, $BNTOID->{$swmod}->{agPortNewCfgBpduGuard}, $portid, 1, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1] = "Enable bpdu guard for port $portid. (Set " . $BNTOID->{$swmod}->{agPortNewCfgBpduGuard} . ".$portid to 1.)\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
|
|
#enable root guard on this port
|
|
my @ret = xCAT::SwitchHandler::setoid($session, $BNTOID->{$swmod}->{agPortNewCfgStpExtGuard}, $portid, 2, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1] = "Enable root guard for port $portid. (Set " . $BNTOID->{$swmod}->{agPortNewCfgStpExtGuard} . ".$portid to 2.\n" . $ret[1];
|
|
|
|
# return @ret; #do not return because it is not supported for some switches yet. A defect will be fixed in BNT.
|
|
}
|
|
}
|
|
|
|
#add port in one by one
|
|
my @ret = xCAT::SwitchHandler::setoid($session, $BNTOID->{$swmod}->{vlanNewCfgAddPort}, $vlan_id, $portid, 'GAUGE');
|
|
if ($ret[0] != 0) {
|
|
$ret[1] = "Set vlanNewCfgAddPort" . $BNTOID->{$swmod}->{vlanNewCfgAddPort} . ".$vlan_id to $portid.\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
}
|
|
}
|
|
|
|
my @ret = apply_changes($session, $swmod);
|
|
|
|
return @ret;
|
|
}
|
|
|
|
#-------------------------------------------------------
|
|
|
|
=head3 add_crossover_ports_to_vlan
|
|
It enables the vlan on the cross-over links.
|
|
Returns an array. (erorcode, errormsg). When errorcode=0, means no error.
|
|
=cut
|
|
|
|
#-------------------------------------------------------
|
|
sub add_crossover_ports_to_vlan {
|
|
my $session = shift;
|
|
my $vlan_id = shift;
|
|
my $switch = shift;
|
|
my @switches = @_;
|
|
my @ret = (0, "");
|
|
my $msg;
|
|
|
|
if (@switches == 0) { return (0, ""); }
|
|
|
|
# my $swmod=getSwitchModule($session);
|
|
# if (!$swmod) { return (1, "This BNT switch modeule is not supported.");}
|
|
|
|
#figure out the port numbers that are connecting to the given switches
|
|
# my @ips=();
|
|
#get the ip address for each switch
|
|
# foreach my $switch (@switches) {
|
|
# my $ip=xCAT::NetworkUtils->getipaddr($switch);
|
|
# if (!$ip) {
|
|
# $msg .= "Cannot resolve ip address for switch $switch\n";
|
|
# } else {
|
|
# push(@ips, $ip);
|
|
# }
|
|
# }
|
|
|
|
# my @ports=();
|
|
# my $tmp = xCAT::MacMap::walkoid($session, $BNTOID->{$swmod}->{arpInfoDestIp});
|
|
# my $tmp1 = xCAT::MacMap::walkoid($session, $BNTOID->{$swmod}->{arpInfoSrcPort});
|
|
# print Dumper($tmp);
|
|
# print Dumper($tmp1);
|
|
# foreach my $tmp_id (keys %{$tmp}) {
|
|
# my $tmp_ip=$tmp->{$tmp_id};
|
|
# if (grep /^$tmp_ip$/, @ips) {
|
|
# my $port=$tmp1->{$tmp_id};
|
|
# if ($port) { push(@ports, $port); }
|
|
# }
|
|
# }
|
|
|
|
#get the ports that are connects to the switches
|
|
my $switchestab = xCAT::Table->new('switches', -create => 0);
|
|
my $ent = $switchestab->getNodeAttribs($switch, [qw(switch linkports)]);
|
|
if ((!$ent) || (!$ent->{linkports})) { return (0, $msg); }
|
|
|
|
my %linkports = ();
|
|
foreach my $item (split(',', $ent->{linkports})) {
|
|
my @a = split(':', $item);
|
|
if (@a > 1) {
|
|
$linkports{ $a[1] } = $a[0];
|
|
}
|
|
}
|
|
|
|
#print Dumper(%linkports);
|
|
|
|
my @ports = ();
|
|
foreach my $sw (@switches) {
|
|
if (exists($linkports{$sw})) {
|
|
push(@ports, $linkports{$sw});
|
|
}
|
|
}
|
|
|
|
#print "ports=@ports\n";
|
|
|
|
#now add the ports to the vlan
|
|
if (@ports > 0) {
|
|
my ($code, $msg1) = add_ports_to_vlan($session, $vlan_id, @ports);
|
|
if ($msg) {
|
|
$msg1 = $msg . $msg1;
|
|
}
|
|
|
|
return ($code, $msg1);
|
|
}
|
|
|
|
return (0, $msg);
|
|
}
|
|
|
|
#--------------------------------------------------------------
|
|
|
|
=head3 remove_vlan
|
|
|
|
Every switch plugin must implement this subroutine.
|
|
|
|
Remove a vlan from the switch
|
|
Returns an array. (erorcode, errormsg). When errorcode=0, means no error.
|
|
=cut
|
|
|
|
#-------------------------------------------------------------
|
|
sub remove_vlan {
|
|
my $session = shift;
|
|
my $vlan_id = shift;
|
|
|
|
my $swmod = getSwitchModule($session);
|
|
if (!$swmod) { return (1, "This BNT switch modeule is not supported."); }
|
|
|
|
#set to delete state
|
|
my @ret = xCAT::SwitchHandler::setoid($session, $BNTOID->{$swmod}->{vlanNewCfgDelete}, $vlan_id, 2, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1] = "Set vlanNewCfgDelete " . $BNTOID->{$swmod}->{vlanNewCfgDelete} . ".$vlan_id to 2(delete).\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
|
|
@ret = apply_changes($session, $swmod);
|
|
|
|
return @ret;
|
|
}
|
|
|
|
|
|
#--------------------------------------------------------------
|
|
|
|
=head3 remove_ports_from_vlan
|
|
|
|
Every switch plugin must implement this subroutine.
|
|
|
|
Remove ports from a vlan
|
|
Returns an array. (erorcode, errormsg). When errorcode=0, means no error.
|
|
=cut
|
|
|
|
#-------------------------------------------------------------
|
|
sub remove_ports_from_vlan {
|
|
my $session = shift;
|
|
my $vlan_id = shift;
|
|
my @ports = @_;
|
|
|
|
my $swmod = getSwitchModule($session);
|
|
if (!$swmod) { return (1, "This BNT switch modeule is not supported."); }
|
|
|
|
#print "vlan=$vlan_id, ports=@ports\n";
|
|
my $namemap = xCAT::MacMap::walkoid($session, $BNTOID->{$swmod}->{portInfoPhyIfDescr});
|
|
if ($namemap) {
|
|
my $ifnamesupport = 0;
|
|
foreach (keys %{$namemap}) {
|
|
if ($namemap->{$_}) {
|
|
$ifnamesupport = 1;
|
|
last;
|
|
}
|
|
}
|
|
unless ($ifnamesupport) {
|
|
$namemap = 0;
|
|
}
|
|
}
|
|
unless ($namemap) {
|
|
return;
|
|
}
|
|
|
|
#print "namemap=" . Dumper($namemap) . "\n";
|
|
|
|
|
|
foreach my $portid (keys %{$namemap}) {
|
|
my $switchport = $namemap->{$portid};
|
|
foreach my $portname (@ports) {
|
|
unless (xCAT::MacMap::namesmatch($portname, $switchport)) {
|
|
next;
|
|
}
|
|
|
|
print "portid=$portid, vlan_id=$vlan_id\n";
|
|
|
|
#remove port in one by one
|
|
my @ret = xCAT::SwitchHandler::setoid($session, $BNTOID->{$swmod}->{vlanNewCfgRemovePort}, $vlan_id, $portid, 'GAUGE');
|
|
if ($ret[0] != 0) {
|
|
$ret[1] = "Set vlanNewCfgRemovePort " . $BNTOID->{$swmod}->{vlanNewCfgRemovePort} . ".$vlan_id to $portid.\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
}
|
|
}
|
|
|
|
my @ret = apply_changes($session, $swmod);
|
|
|
|
return @ret;
|
|
|
|
}
|
|
|
|
|
|
sub apply_changes {
|
|
my $session = shift;
|
|
my $swmod = shift;
|
|
|
|
#apply
|
|
my @ret = xCAT::SwitchHandler::setoid($session, $BNTOID->{$swmod}->{agApplyConfig}, 0, 1, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1] = "Set agApplyConfig " . $BNTOID->{$swmod}->{agApplyConfig} . ".0 to 1(apply).\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
|
|
my $state = 3;
|
|
while ($state == 3) {
|
|
my $tmp = xCAT::MacMap::walkoid($session, $BNTOID->{$swmod}->{agApplyConfig});
|
|
|
|
#print "tmp=" . Dumper($tmp) . "\n";
|
|
if ($tmp) {
|
|
$state = $tmp->{0};
|
|
}
|
|
sleep(3);
|
|
}
|
|
|
|
#set apply to idle state
|
|
my @ret = xCAT::SwitchHandler::setoid($session, $BNTOID->{$swmod}->{agApplyConfig}, 0, 2, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1] = "Set agApplyConfig " . $BNTOID->{$swmod}->{agApplyConfig} . ".0 to 2(idle).\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
|
|
if ($state == 5) {
|
|
return (1, "Apply configuration failed.\n");
|
|
}
|
|
|
|
#save configurations.
|
|
my @ret = xCAT::SwitchHandler::setoid($session, $BNTOID->{$swmod}->{agSaveConfiguration}, 0, 2, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1] = "Set agSaveConfiguration " . $BNTOID->{$swmod}->{agSaveConfiguration} . ".0 to 2(saveActive).\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
return @ret;
|
|
}
|
|
|
|
sub getSwitchModule {
|
|
my $session = shift;
|
|
|
|
#get the the switch brand name
|
|
my $tmp = xCAT::MacMap::walkoid($session, "$sysDescr", silentfail => 1);
|
|
my $swmod;
|
|
my $descr = $tmp->{0};
|
|
if ($descr) {
|
|
if ($descr =~ /G8000/) { return "G8000"; }
|
|
if ($descr =~ /G8052/) { return "G8052"; }
|
|
if ($descr =~ /G8124/) { return "G8124"; }
|
|
if ($descr =~ /G8264/) { return "G8264"; }
|
|
if ($descr =~ /EN4093/) { return "EN4093"; }
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
1;
|