mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-11-04 05:12:30 +00:00 
			
		
		
		
	Support Vlan info of Cumulus Switch for switch_macmap command (#4050)
* Support Vlan info of Cumulus Switch for switch_macmap command * merge the code from PR #4022 * fill in mac info via ssh instead of snmp command
This commit is contained in:
		@@ -546,11 +546,11 @@ sub refresh_table {
 | 
			
		||||
 | 
			
		||||
        $children++;
 | 
			
		||||
        my $cpid = xCAT::Utils->xfork;
 | 
			
		||||
        unless (defined $cpid) { 
 | 
			
		||||
        unless (defined $cpid) {
 | 
			
		||||
            $children--;
 | 
			
		||||
            close($child);
 | 
			
		||||
            close($parent);
 | 
			
		||||
            xCAT::MsgUtils->message("S", "refresh_table: failed to fork refresh_switch process for $entry->{switch},skip..."); 
 | 
			
		||||
            xCAT::MsgUtils->message("S", "refresh_table: failed to fork refresh_switch process for $entry->{switch},skip...");
 | 
			
		||||
            next;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -564,7 +564,6 @@ sub refresh_table {
 | 
			
		||||
            xCAT::MsgUtils->message("S", "refresh_switch $entry->{switch} ElapsedTime:$diffduration sec");
 | 
			
		||||
            exit(0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        close($parent);
 | 
			
		||||
        $inputs->add($child);
 | 
			
		||||
    }
 | 
			
		||||
@@ -718,50 +717,55 @@ sub refresh_switch {
 | 
			
		||||
    my $output    = shift;
 | 
			
		||||
    my $community = shift;
 | 
			
		||||
    my $switch    = shift;
 | 
			
		||||
    my %index_to_vlan = ();
 | 
			
		||||
    my %index_to_mac = ();
 | 
			
		||||
 | 
			
		||||
    unless($self->{collect_mac_info})
 | 
			
		||||
    {
 | 
			
		||||
        if($self->{switchparmhash}->{$switch}->{switchtype} eq 'onie'){
 | 
			
		||||
            #for cumulus switch, the MAC table can be retrieved with ssh
 | 
			
		||||
            #which is much faster than snmp 
 | 
			
		||||
            my $mymac;
 | 
			
		||||
            my $myport;
 | 
			
		||||
    if($self->{switchparmhash}->{$switch}->{switchtype} eq 'onie'){
 | 
			
		||||
        #for cumulus switch, the MAC table can be retrieved with ssh
 | 
			
		||||
        #which is much faster than snmp 
 | 
			
		||||
        my $mymac;
 | 
			
		||||
        my $myport;
 | 
			
		||||
 | 
			
		||||
            my @res=xCAT::Utils->runcmd("ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no $switch 'bridge fdb show|grep -i -v permanent|tr A-Z a-z  2>/dev/null' 2>/dev/null",-1);
 | 
			
		||||
            if ($::RUNCMD_RC) {
 | 
			
		||||
                xCAT::MsgUtils->message("S", "Failed to get mac table with ssh to $switch, fall back to snmp! To obtain mac table with ssh, please make sure the passwordless root ssh to $switch is available");
 | 
			
		||||
            }else{
 | 
			
		||||
                foreach (@res){
 | 
			
		||||
                    if($_ =~ m/^([0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}) dev swp([0-9]+) .*/){
 | 
			
		||||
                        $mymac=$1;
 | 
			
		||||
                        $myport=$2;         
 | 
			
		||||
                        $myport=sprintf("%d",$myport);
 | 
			
		||||
                        
 | 
			
		||||
                        #try all the possible port number formats
 | 
			
		||||
                        #e.g, "5","swp5","05","swp05"
 | 
			
		||||
                        unless(exists $self->{switches}->{$switch}->{$myport}){
 | 
			
		||||
                            if(exists $self->{switches}->{$switch}->{"swp".$myport}){
 | 
			
		||||
                                $myport="swp".$myport;
 | 
			
		||||
                            }else{
 | 
			
		||||
                                $myport=sprintf("%02d",$myport);
 | 
			
		||||
                                unless(exists $self->{switches}->{$switch}->{$myport}){
 | 
			
		||||
                                    if(exists $self->{switches}->{$switch}->{"swp".$myport}){
 | 
			
		||||
                                        $myport="swp".$myport;
 | 
			
		||||
                                    }else{
 | 
			
		||||
                                        $myport="";
 | 
			
		||||
                                    }
 | 
			
		||||
        my @res=xCAT::Utils->runcmd("ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no $switch 'bridge fdb show|grep -i -v permanent|tr A-Z a-z  2>/dev/null' 2>/dev/null",-1);
 | 
			
		||||
        if ($::RUNCMD_RC) {
 | 
			
		||||
            xCAT::MsgUtils->message("S", "Failed to get mac table with ssh to $switch, fall back to snmp! To obtain mac table with ssh, please make sure the passwordless root ssh to $switch is available");
 | 
			
		||||
        }else{
 | 
			
		||||
            foreach (@res){
 | 
			
		||||
                if($_ =~ m/^([0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}) dev swp([0-9]+) vlan ([0-9]+) .*/){
 | 
			
		||||
                    $mymac=$1;
 | 
			
		||||
                    $myport=$2;         
 | 
			
		||||
                    $myport=sprintf("%d",$myport);
 | 
			
		||||
                    my $macport=$2;
 | 
			
		||||
                    my $macvlan=$3;
 | 
			
		||||
 
 | 
			
		||||
                    #try all the possible port number formats
 | 
			
		||||
                    #e.g, "5","swp5","05","swp05"
 | 
			
		||||
                    unless(exists $self->{switches}->{$switch}->{$myport}){
 | 
			
		||||
                        if(exists $self->{switches}->{$switch}->{"swp".$myport}){
 | 
			
		||||
                            $myport="swp".$myport;
 | 
			
		||||
                        }else{
 | 
			
		||||
                            $myport=sprintf("%02d",$myport);
 | 
			
		||||
                            unless(exists $self->{switches}->{$switch}->{$myport}){
 | 
			
		||||
                                if(exists $self->{switches}->{$switch}->{"swp".$myport}){
 | 
			
		||||
                                    $myport="swp".$myport;
 | 
			
		||||
                                }else{
 | 
			
		||||
                                    $myport="";
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if($myport){
 | 
			
		||||
                            if($output){
 | 
			
		||||
                                printf $output "$mymac|%s\n", $self->{switches}->{$switch}->{$myport};
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if($myport){
 | 
			
		||||
                        if($output){
 | 
			
		||||
                            printf $output "$mymac|%s\n", $self->{switches}->{$switch}->{$myport};
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    push @{ $index_to_vlan{$macport} }, $macvlan;
 | 
			
		||||
                    push @{ $index_to_mac{$macport} }, $mymac;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            unless($self->{collect_mac_info}) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -812,6 +816,38 @@ sub refresh_switch {
 | 
			
		||||
        xCAT::MsgUtils->message("I", "MTU information is not availabe for this switch $switch");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    my $iscisco = 0;
 | 
			
		||||
    if ($self->{switchparmhash}->{$switch}->{switchtype} eq 'onie'){
 | 
			
		||||
        my $bridgetoifmap = walkoid($session, '.1.3.6.1.2.1.17.1.4.1.2', ciscowarn => $iscisco, verbose => $self->{show_verbose_info}, switch => $switch, callback => $self->{callback}); # Good for all switches
 | 
			
		||||
        if (not ref $bridgetoifmap or !keys %{$bridgetoifmap}) {
 | 
			
		||||
            xCAT::MsgUtils->message("S", "Error communicating with " . $session->{DestHost} . ": failed to get a valid response to BRIDGE-MIB request");
 | 
			
		||||
            $self->{macinfo}->{$switch}->{ErrorStr} = "Failed to get a valid response to BRIDGE-MIB request";
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        foreach my $boid (keys %$bridgetoifmap) {
 | 
			
		||||
            my $port_index = $boid;
 | 
			
		||||
            my $port_name  = $namemap->{ $bridgetoifmap->{$port_index} };
 | 
			
		||||
            my $mtu  = $iftomtumap->{ $bridgetoifmap->{$port_index} };
 | 
			
		||||
            if (defined($index_to_mac{$port_index})) {
 | 
			
		||||
                push @{ $self->{macinfo}->{$switch}->{$port_name} }, @{ $index_to_mac{$port_index} };
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                $self->{macinfo}->{$switch}->{$port_name}->[0] = '';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (defined($index_to_vlan{$port_index})) {
 | 
			
		||||
                push @{ $self->{vlaninfo}->{$switch}->{$port_name} }, @{ $index_to_vlan{$port_index} };
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                $self->{vlaninfo}->{$switch}->{$port_name}->[0] = '';
 | 
			
		||||
            }
 | 
			
		||||
            push @{ $self->{mtuinfo}->{$switch}->{$port_name} } , $mtu;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    # get port state
 | 
			
		||||
    my $mactostate = walkoid($session, '.1.3.6.1.2.1.17.7.1.2.2.1.3', silentfail => 1, verbose => $self->{show_verbose_info}, switch => $switch, callback => $self->{callback});
 | 
			
		||||
 | 
			
		||||
@@ -853,7 +889,6 @@ sub refresh_switch {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    my $vlan;
 | 
			
		||||
    my $iscisco = 0;
 | 
			
		||||
    foreach $vlan (sort keys %vlans_to_check) { #Sort, because if numbers, we want 1 first, because that vlan should not get communiy string indexed query
 | 
			
		||||
        unless (not $vlan or $vlan eq 'NA' or $vlan eq '1') { #don't subject users to the context pain unless needed
 | 
			
		||||
            $iscisco = 1;
 | 
			
		||||
@@ -903,8 +938,6 @@ sub refresh_switch {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (defined($self->{collect_mac_info})) {
 | 
			
		||||
            my %index_to_mac = ();
 | 
			
		||||
            my %index_to_vlan = ();
 | 
			
		||||
            foreach (keys %$mactoindexmap) {
 | 
			
		||||
                my $index     = $mactoindexmap->{$_};
 | 
			
		||||
                my @tmp       = split /\./, $_;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user