mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-11-03 21:02:34 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			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;
 |