mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 03:12:30 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			621 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			621 lines
		
	
	
		
			20 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;
 |