624 lines
21 KiB
Perl
Executable File
624 lines
21 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
package xCAT_plugin::vlan::CiscoSwitch;
|
|
BEGIN
|
|
{
|
|
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
|
|
}
|
|
use lib "$::XCATROOT/lib/perl";
|
|
use strict;
|
|
use xCAT::MacMap;
|
|
use Data::Dumper;
|
|
use xCAT::SwitchHandler;
|
|
use SNMP;
|
|
|
|
#IF-MIB
|
|
my $ifName='.1.3.6.1.2.1.31.1.1.1.1';
|
|
my $ifDescr='.1.3.6.1.2.1.2.2.1.2';
|
|
my $ifOperStatus='.1.3.6.1.2.1.2.2.1.8';
|
|
|
|
#CISCO-VTP-MIB
|
|
my $vtpVlanEditTable='.1.3.6.1.4.1.9.9.46.1.4.2';
|
|
my $vtpVlanEditOperation='.1.3.6.1.4.1.9.9.46.1.4.1.1.1';
|
|
my $vtpVlanEditBufferOwner='.1.3.6.1.4.1.9.9.46.1.4.1.1.3';
|
|
my $vtpVlanEditRowStatus='.1.3.6.1.4.1.9.9.46.1.4.2.1.11.1';
|
|
my $vtpVlanEditType='.1.3.6.1.4.1.9.9.46.1.4.2.1.3.1';
|
|
my $vtpVlanEditName='.1.3.6.1.4.1.9.9.46.1.4.2.1.4.1';
|
|
my $vtpVlanEditDot10Said='.1.3.6.1.4.1.9.9.46.1.4.2.1.6.1';
|
|
my $vtpVlanState='.1.3.6.1.4.1.9.9.46.1.3.1.1.2';
|
|
my $vlanTrunkPortDynamicStatus='.1.3.6.1.4.1.9.9.46.1.6.1.1.14';
|
|
my $vlanTrunkPortDynamicState='.1.3.6.1.4.1.9.9.46.1.6.1.1.13';
|
|
my $vlanTrunkPortNativeVlan= '.1.3.6.1.4.1.9.9.46.1.6.1.1.5';
|
|
my $vlanTrunkPortVlansEnabled='.1.3.6.1.4.1.9.9.46.1.6.1.1.4';
|
|
my $vlanTrunkPortEncapsulationType='.1.3.6.1.4.1.9.9.46.1.6.1.1.3';
|
|
|
|
#CISCO-VLAN-MEMBERSHIP-MIB
|
|
my $vmVlan='.1.3.6.1.4.1.9.9.68.1.2.2.1.2';
|
|
my $vmVlanType='.1.3.6.1.4.1.9.9.68.1.2.2.1.1'; #1:static 2:dynamic 3:trunk
|
|
|
|
#CISCI-STP-EXTENSION-MIB
|
|
my $stpxRootGuardConfigEnabled='1.3.6.1.4.1.9.9.82.1.5.1.1.2'; #1:enable 2:disable
|
|
my $stpxFastStartPortBpduGuardMode='1.3.6.1.4.1.9.9.82.1.9.3.1.4'; #1:enable 2:disable 3:default
|
|
|
|
|
|
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 "Cisco ";
|
|
}
|
|
|
|
#--------------------------------------------------------------
|
|
=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 $vlanmap = xCAT::MacMap::walkoid($session, "$vtpVlanState.1", 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 ids 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 $namemap = xCAT::MacMap::walkoid($session, $ifName);
|
|
#namemap is the mapping of ifIndex->(human readable name)
|
|
if ($namemap) {
|
|
my $ifnamesupport=0;
|
|
foreach (keys %{$namemap}) {
|
|
if ($namemap->{$_}) {
|
|
$ifnamesupport=1;
|
|
last;
|
|
}
|
|
}
|
|
unless ($ifnamesupport) {
|
|
$namemap=0;
|
|
}
|
|
}
|
|
unless ($namemap) { #Failback to ifDescr. ifDescr is close, but not perfect on some switches
|
|
$namemap = xCAT::MacMap::walkoid($session,$ifDescr);
|
|
}
|
|
unless ($namemap) {
|
|
return;
|
|
}
|
|
#print "namemap=" . Dumper($namemap) . "\n";
|
|
|
|
my $iftovlanmap = xCAT::MacMap::walkoid($session, $vmVlan, silentfail=>1);
|
|
#print "iftovlanmap=" . Dumper($iftovlanmap) . "\n";
|
|
|
|
my $trunktovlanmap = xCAT::MacMap::walkoid($session, $vlanTrunkPortNativeVlan, silentfail=>1); #for trunk ports, we are interested in the native vlan
|
|
#print "trunktovlanmap=" . Dumper($trunktovlanmap) . "\n";
|
|
|
|
my %ret=();
|
|
if (defined($iftovlanmap) or defined($trunktovlanmap)) {
|
|
foreach my $portid (keys %{$namemap}) {
|
|
my $switchport = $namemap->{$portid};
|
|
foreach my $portname (@ports) {
|
|
unless (xCAT::MacMap::namesmatch($portname,$switchport)) {
|
|
next;
|
|
}
|
|
|
|
if (defined $iftovlanmap->{$portid}) {
|
|
$ret{$portname}=[$iftovlanmap->{$portid}];
|
|
} elsif (defined $trunktovlanmap->{$portid}){
|
|
$ret{$portname}=[$trunktovlanmap->{$portid}];
|
|
} else {
|
|
$ret{$portname}=['NA'];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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;
|
|
|
|
print "Cisco\n";
|
|
#Verify if the edition is in use by another NMS station or device.
|
|
#The edition is not in use if you see this message: no MIB objects contained under subtree:
|
|
my $tmp = xCAT::MacMap::walkoid($session,$vtpVlanEditTable);
|
|
#print "tmp=" . Dumper($tmp) . "\n";
|
|
|
|
#Set the vtpVlanEditOperation to the copy state(2). This allows to create the VLAN.
|
|
my @ret= xCAT::SwitchHandler::setoid($session, $vtpVlanEditOperation, 1, 2, 'INTEGER');
|
|
#if ($ret[0] != 0) { return @ret; }
|
|
|
|
#set vtpVlanEditBufferOwner in order to makethe current owner of the edit permission visible
|
|
my $username="xcat";
|
|
my @ret=xCAT::SwitchHandler::setoid($session,$vtpVlanEditBufferOwner, 1, $username, 'OCTET');
|
|
if ($ret[0] != 0) {
|
|
$ret[1]="Set vtpVlanEditBufferOwner $vtpVlanEditBufferOwner.1 to $username.\n" .$ret[1];
|
|
return @ret;
|
|
}
|
|
|
|
#my $tmp = xCAT::MacMap::walkoid($session, $vtpVlanEditOperation);
|
|
#print "tmp=" . Dumper($tmp) . "\n";
|
|
|
|
#my $tmp = xCAT::MacMap::walkoid($session, $vtpVlanEditBufferOwner);
|
|
#print "tmp=" . Dumper($tmp) . "\n";
|
|
|
|
#set vtpVlanEditRowStatus to createAndGo(4)
|
|
my @ret= xCAT::SwitchHandler::setoid($session, $vtpVlanEditRowStatus, $vlan_id, 4, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1]="Set vtpVlanEditRowStatus $vtpVlanEditRowStatus.$vlan_id to 4.\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
|
|
#set vtpVlanEditType to ethernet (1)
|
|
my @ret= xCAT::SwitchHandler::setoid($session,$vtpVlanEditType, $vlan_id, 1, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1]="Set vtpVlanEditType $vtpVlanEditType.$vlan_id to 1.\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
|
|
#set vtpVlanEditName to xcat_vlan_#
|
|
my @ret= xCAT::SwitchHandler::setoid($session,$vtpVlanEditName, $vlan_id, $vlan_name, 'OCTET');
|
|
if ($ret[0] != 0) {
|
|
$ret[1]="Set vtpVlanEditName $vtpVlanEditName.$vlan_id to $vlan_name.\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
|
|
#Set the vtpVlanEditDot10Said. This is the VLAN number + 100000 translated to hexadecimal.
|
|
my $num=100000 + $vlan_id;
|
|
my $hex_num=sprintf("%x", $num);
|
|
my @ret= xCAT::SwitchHandler::setoid($session,$vtpVlanEditDot10Said, $vlan_id, $hex_num, 'OCTETHEX');
|
|
#if ($ret[0] != 0) {
|
|
# $ret[1]="Set vtpVlanEditDot10Said $vtpVlanEditDot10Said.$vlan_id to $hex_num.\n" . $ret[1];
|
|
#return @ret;
|
|
#}
|
|
|
|
#apply the changes, set vtpVlanEditOperation.1 to apply (3)
|
|
my @ret= xCAT::SwitchHandler::setoid($session, $vtpVlanEditOperation, 1, 3, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1]="Set vtpVlanEditOperation $vtpVlanEditOperation.1 to 3.\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
|
|
#release the edition buffer, set vtpVlanEditOperation.1 to release (4)
|
|
my @ret= xCAT::SwitchHandler::setoid($session, $vtpVlanEditOperation, 1, 4, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1]="Set vtpVlanEditOperation $vtpVlanEditOperation.1 to 4.\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
|
|
|
|
return (0, "");
|
|
}
|
|
|
|
#--------------------------------------------------------------
|
|
=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 @ports=@_;
|
|
|
|
#print "Add ports @ports to vla $vlan_id.\n";
|
|
|
|
#add ports to the vlan.
|
|
if (@ports > 0) {
|
|
my $namemap = xCAT::MacMap::walkoid($session,$ifName);
|
|
#namemap is the mapping of ifIndex->(human readable name)
|
|
if ($namemap) {
|
|
my $ifnamesupport=0; #Assume broken ifnamesupport until proven good... (Nortel switch)
|
|
foreach (keys %{$namemap}) {
|
|
if ($namemap->{$_}) {
|
|
$ifnamesupport=1;
|
|
last;
|
|
}
|
|
}
|
|
unless ($ifnamesupport) {
|
|
$namemap=0;
|
|
}
|
|
}
|
|
unless ($namemap) { #Failback to ifDescr. ifDescr is close, but not perfect on some switches
|
|
$namemap = xCAT::MacMap::walkoid($session, $ifDescr);
|
|
}
|
|
unless ($namemap) {
|
|
return;
|
|
}
|
|
#print "namemap=" . Dumper($namemap) . "\n";
|
|
|
|
my $trunkportstate = xCAT::MacMap::walkoid($session,$vlanTrunkPortDynamicState);
|
|
#print "trunkportstate=" . Dumper($trunkportstate) . "\n";
|
|
|
|
my $iftovlanmap = xCAT::MacMap::walkoid($session, $vmVlan, silentfail=>1);
|
|
#print "iftovlanmap=" . Dumper($iftovlanmap) . "\n";
|
|
my $trunktovlanmap = xCAT::MacMap::walkoid($session, $vlanTrunkPortNativeVlan, silentfail=>1);
|
|
#print "trunktovlanmap=" . Dumper($trunktovlanmap) . "\n";
|
|
|
|
#get current vlan type (static, dynamic or trunk)
|
|
my $vlantypemap = xCAT::MacMap::walkoid($session, $vmVlanType, silentfail=>1);
|
|
#print "vlantypemap=" . Dumper($vlantypemap) . "\n";
|
|
|
|
|
|
foreach my $portid (keys %{$namemap}) {
|
|
my $switchport = $namemap->{$portid};
|
|
foreach my $portname (@ports) {
|
|
unless (xCAT::MacMap::namesmatch($portname,$switchport)) {
|
|
next;
|
|
}
|
|
|
|
|
|
### set the port to trunk mode
|
|
print "portid=$portid\n";
|
|
# TODO: need testing in cisco's env for how to set a port as access mode through snmpset?
|
|
# Can setting vlanTrunkPortDot1qTunnel or cltcDot1qTunnelMode helps?
|
|
if ($trunkportstate->{$portid} != 1) {
|
|
my @ret = xCAT::SwitchHandler::setoid($session, $vlanTrunkPortEncapsulationType, $portid, 4, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1]="Set vlanTrunkPortEncapsulationType $vlanTrunkPortEncapsulationType.$portid to 4(dot1Q).\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
my @ret = xCAT::SwitchHandler::setoid($session, $vlanTrunkPortDynamicState, $portid, 1, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1]="Set vlanTrunkPortDynamicState $vlanTrunkPortDynamicState.$portid to 1.\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
}
|
|
|
|
### set trunk native vlan id
|
|
my $native_vlanid=1;
|
|
if ((exists($vlantypemap->{$portid})) && ($vlantypemap->{$portid} < 3)) { #the port was set to access mode before
|
|
if ((exists($iftovlanmap->{$portid})) && ($iftovlanmap->{$portid} > 0)) {
|
|
$native_vlanid=$iftovlanmap->{$portid};
|
|
}
|
|
} else { #the port is originally set to trunk mode
|
|
if ((exists($trunktovlanmap->{$portid})) && ($trunktovlanmap->{$portid} > 0)) {
|
|
$native_vlanid=$trunktovlanmap->{$portid};
|
|
} elsif ((exists($iftovlanmap->{$portid})) && ($iftovlanmap->{$portid} > 0)) {
|
|
$native_vlanid=$iftovlanmap->{$portid};
|
|
}
|
|
}
|
|
print "*** native_vlanid=$native_vlanid\n";
|
|
my @ret = xCAT::SwitchHandler::setoid($session, $vlanTrunkPortNativeVlan, $portid, $native_vlanid, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1]="Set native vlan for port $portid to $native_vlanid ($vlanTrunkPortNativeVlan.$portid to $native_vlanid).\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
|
|
|
|
### allow this vlan on the port
|
|
my $data = $session->get([$vlanTrunkPortVlansEnabled, $portid]);
|
|
my @a = split(//, $data);
|
|
foreach (@a) {
|
|
my $num=unpack("C*", $_);
|
|
$_= sprintf ("%02x",$num);
|
|
}
|
|
if ((exists($vlantypemap->{$portid})) && ($vlantypemap->{$portid} < 3)) {
|
|
#if originally this port was in access or dynamic mode, only enable original vlan and this tagged vlan
|
|
#reset the matrix
|
|
#print "***was access mode\n";
|
|
foreach (@a) {
|
|
$_="00";
|
|
}
|
|
#add native vlan id in the matrix
|
|
my $index = int($native_vlanid / 8);
|
|
my $offset = $native_vlanid % 8;
|
|
my $num = hex($a[$index]) | $HexConv{$offset};
|
|
$a[$index] = sprintf("%02x", $num);
|
|
#print "index=$index, offset=$offset\n";
|
|
|
|
#add current vlan id in the matrix
|
|
$index = int($vlan_id / 8);
|
|
$offset = $vlan_id % 8;
|
|
$num = hex($a[$index]) | $HexConv{$offset};
|
|
$a[$index] = sprintf("%02x", $num);
|
|
} else {
|
|
#if this port was trunk mode before, add this tagged vlan in the matrix
|
|
# print "***was trunk mode\n";
|
|
my $index = int($vlan_id / 8);
|
|
my $offset = $vlan_id % 8;
|
|
my $num = hex($a[$index]) | $HexConv{$offset};
|
|
$a[$index] = sprintf("%02x", $num);
|
|
}
|
|
#print "a=@a\n";
|
|
foreach (@a) {
|
|
$_=hex($_);
|
|
$_=pack("C*", $_);
|
|
}
|
|
my $s = join(//, @a);
|
|
my @ret = xCAT::SwitchHandler::setoid($session, $vlanTrunkPortVlansEnabled, $portid, $s, 'OCTET');
|
|
#print "**** ret=@ret\n";
|
|
if ($ret[0] != 0) {
|
|
$ret[1]="Allow vlan on port $portid ($vlanTrunkPortVlansEnabled.$portid=$s).\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
|
|
|
|
### security feature
|
|
if ($::XCATSITEVALS{vlansecurity} eq '1') {
|
|
#set root guard on the port
|
|
my @ret = xCAT::SwitchHandler::setoid($session, $stpxRootGuardConfigEnabled, $portname, 1, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1]="Set root guard for port $portname to enable ($stpxRootGuardConfigEnabled.$portname=1).\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
#set bpdu guard on the port
|
|
my @ret = xCAT::SwitchHandler::setoid($session, $stpxFastStartPortBpduGuardMode, $portname, 1, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1]="Set bpdu guard for port $portname to enalbe ($stpxFastStartPortBpduGuardMode.$portname=1).\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
}
|
|
last;
|
|
}
|
|
}
|
|
}
|
|
|
|
return (0, "");
|
|
}
|
|
|
|
#-------------------------------------------------------
|
|
=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, ""); }
|
|
#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;
|
|
|
|
#Verify if the edition is in use by another NMS station or device.
|
|
#The edition is not in use if you see this message: no MIB objects contained under subtree:
|
|
my $tmp = xCAT::MacMap::walkoid($session,$vtpVlanEditTable);
|
|
#print "tmp=" . Dumper($tmp) . "\n";
|
|
|
|
#Set the vtpVlanEditOperation to the copy state(2). This allows to delete the VLAN.
|
|
my @ret= xCAT::SwitchHandler::setoid($session, $vtpVlanEditOperation, 1, 2, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1]="Set vtpVlanEditOperation $vtpVlanEditOperation.1 to 3 (copy state).\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
|
|
#set vtpVlanEditBufferOwner in order to makethe current owner of the edit permission visible
|
|
my $username="xcat";
|
|
my @ret=xCAT::SwitchHandler::setoid($session,$vtpVlanEditBufferOwner, 1, $username, 'OCTET');
|
|
if ($ret[0] != 0) {
|
|
$ret[1]="Set vtpVlanEditBufferOwner $vtpVlanEditBufferOwner.1 to $username.\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
|
|
#set vtpVlanEditRowStatus to destroy(6)
|
|
my @ret= xCAT::SwitchHandler::setoid($session, $vtpVlanEditRowStatus, $vlan_id, 6, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1]="Set vtpVlanEditRowStatus $vtpVlanEditRowStatus.$vlan_id to 6 (destroy).\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
|
|
#apply the changes, set vtpVlanEditOperation.1 to apply (3)
|
|
my @ret= xCAT::SwitchHandler::setoid($session, $vtpVlanEditOperation, 1, 3, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1]="Set $vtpVlanEditOperation.1 to 3 (apply).\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
|
|
#release the edition buffer, set vtpVlanEditOperation.1 to release (4)
|
|
my @ret= xCAT::SwitchHandler::setoid($session, $vtpVlanEditOperation, 1, 4, 'INTEGER');
|
|
if ($ret[0] != 0) {
|
|
$ret[1]="Set vtpVlanEditOperation $vtpVlanEditOperation.1 to 4 (release).\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
|
|
#my $iftovlanmap = xCAT::MacMap::walkoid($session, $vmVlan, silentfail=>1);
|
|
#print "iftovlanmap=" . Dumper($iftovlanmap) . "\n";
|
|
#foreach (keys(%$iftovlanmap)) {
|
|
# if($iftovlanmap->{$_} == $vlan_id) {
|
|
#my @ret= xCAT::SwitchHandler::setoid($session, $vmVlan, $_, 1, 'INTEGER');
|
|
#if ($ret[0] != 0) {
|
|
# $ret[1]="Set $vmVlan.$_ to 1.\n" . $ret[1];
|
|
# return @ret;
|
|
#}
|
|
# }
|
|
#}
|
|
#my $trunktovlanmap = xCAT::MacMap::walkoid($session, $vlanTrunkPortNativeVlan, silentfail=>1); #for trunk ports, we are interested in the native vlan
|
|
#print "trunktovlanmap=" . Dumper($trunktovlanmap) . "\n";
|
|
#foreach (keys(%$trunktovlanmap)) {
|
|
# if($trunktovlanmap->{$_} == $vlan_id) {
|
|
# my @ret= xCAT::SwitchHandler::setoid($session, $vlanTrunkPortNativeVlan, $_, 1, 'INTEGER');
|
|
# if ($ret[0] != 0) {
|
|
# $ret[1]="Set $vlanTrunkPortNativeVlan.$_ to 1.\n" . $ret[1];
|
|
# return @ret;
|
|
# }
|
|
# }
|
|
#}
|
|
|
|
|
|
return (0, "");;
|
|
}
|
|
|
|
|
|
#--------------------------------------------------------------
|
|
=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 = @_;
|
|
|
|
|
|
if (@ports > 0) {
|
|
my $namemap = xCAT::MacMap::walkoid($session,$ifName);
|
|
#namemap is the mapping of ifIndex->(human readable name)
|
|
if ($namemap) {
|
|
my $ifnamesupport=0;
|
|
foreach (keys %{$namemap}) {
|
|
if ($namemap->{$_}) {
|
|
$ifnamesupport=1;
|
|
last;
|
|
}
|
|
}
|
|
unless ($ifnamesupport) {
|
|
$namemap=0;
|
|
}
|
|
}
|
|
unless ($namemap) { #Failback to ifDescr. ifDescr is close, but not perfect on some switches
|
|
$namemap = xCAT::MacMap::walkoid($session, $ifDescr);
|
|
}
|
|
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;
|
|
}
|
|
|
|
#remove the vlan id from the vlanTrunkPortVlansEnabled.port matrix
|
|
my $data = $session->get([$vlanTrunkPortVlansEnabled, $portid]);
|
|
my @a = split(//, $data);
|
|
foreach (@a) {
|
|
my $num=unpack("C*", $_);
|
|
$_= sprintf ("%02x",$num);
|
|
}
|
|
#print "a=@a\n";
|
|
my $index = int($vlan_id / 8);
|
|
my $offset = $vlan_id % 8;
|
|
my $num = hex($a[$index]) & (~$HexConv{$offset});
|
|
$a[$index] = sprintf("%02x", $num);
|
|
|
|
#print "a=@a\n";
|
|
|
|
foreach (@a) {
|
|
$_=hex($_);
|
|
$_=pack("C*", $_);
|
|
}
|
|
|
|
my $s = join(//, @a);
|
|
my @ret = xCAT::SwitchHandler::setoid($session, $vlanTrunkPortVlansEnabled, $portid, $s, 'OCTET');
|
|
if ($ret[0] != 0) {
|
|
$ret[1]="Set vlanTrunkPortVlansEnabled $vlanTrunkPortVlansEnabled.$portid to $s.\n" . $ret[1];
|
|
return @ret;
|
|
}
|
|
|
|
last;
|
|
}
|
|
}
|
|
}
|
|
|
|
return (0, "");;
|
|
}
|
|
|
|
|
|
|
|
1;
|