Commit 5d2ca341 authored by Weibin Sun's avatar Weibin Sun
Browse files

apply changes in new_snmpit* to original snmpit*

parent 97edc6fb
......@@ -23,6 +23,7 @@ use libdb;
use libtestbed;
use Expect;
use Lan;
use Port;
# CLI constants
......@@ -183,7 +184,7 @@ sub new($$$;$) {
#
$self->{SESS} = undef;
$self->readTranslationTable();
#$self->readTranslationTable();
return $self;
}
......@@ -223,181 +224,37 @@ sub createExpectObject($)
return $exp;
}
#
# Convert port format between switch format and db format
# the original format is auto-detected.
# simply, a switch port starts with A-Z, or A-I on Apcon 2000 series
# while a db port is totally number: card.port.
#
sub convertPortFormat($$)
sub toApconPort($$)
{
my ($self, $srcport) = @_;
my $card = "";
my $port = "";
if ($srcport =~ /([A-Z])([0-9]{2})/) {
# froms switch to db
$card = ord($1) - ord('A') + 1;
$port = int($2);
my ($self, $p) = @_;
my $apcport = $p->getEndByNode($self->{NAME});
if (!defined($apcport)) {
return $p;
}
return "$card.$port";
} elsif ($srcport =~ /(\d+)\.(\d+)/) {
# from db to switch
$card = chr(ord('A') + $1 - 1);
$port = sprintf("%02d", $2);
my $card = chr(ord('A')+int($apcport->card()) - 1);
my $port = sprintf("%02d", int($apcport->port()));
return "$card"."$port";
} else {
# unknown format, return itself
return $srcport;
}
}
##############################################################################
my %Interfaces=();
# Interfaces maps pcX:Y<==>MAC
my %PortIface=();
# Maps pcX:Y<==>pcX:iface
my %Ports=();
# Ports maps pcX:Y.port<==>switch:port
my %OldPorts=();
# Ports maps pcX:Y<==>switch:port
my %MorePortIface=();
# Maps node:card.port <==> node:iface
#
# This function fills in %Interfaces and %Ports
# They hold pcX:Y<==>MAC and pcX:Y.port<==>switch:port respectively
#
# XXX: Temp workround for portnum
#
sub readTranslationTable($) {
my $self = shift;
my $name="";
my $mac="";
my $iface="";
my $switchport="";
print "FILLING %Interfaces\n" if $self->{DEBUG};
my $result =
DBQueryFatal("select node_id,card,port,mac,iface from interfaces");
while ( @_ = $result->fetchrow_array()) {
$name = "$_[0]:$_[1]";
$iface = "$_[0]:$_[4]";
if ($_[2] != 1) {$name .=$_[2]; }
$mac = "$_[3]";
$Interfaces{$name} = $mac;
$Interfaces{$mac} = $name;
$PortIface{$name} = $iface;
$PortIface{$iface} = $name;
$MorePortIface{"$_[0]:$_[1].$_[2]"} = $iface;
$MorePortIface{$iface} = "$_[0]:$_[1].$_[2]";
print "Interfaces: $mac <==> $name\n" if $self->{DEBUG} > 1;
}
print "FILLING %Ports\n" if $self->{DEBUG};
$result = DBQueryFatal("select node_id1,card1,port1,node_id2,card2,port2 ".
"from wires;");
while ( my @row = $result->fetchrow_array()) {
my ($node_id1, $card1, $port1, $node_id2, $card2, $port2) = @row;
my $oldname = "$node_id1:$card1";
$name = "$node_id1:$card1.$port1";
print "Name='$name'\t" if $self->{DEBUG} > 2;
print "Dev='$node_id2'\t" if $self->{DEBUG} > 2;
$switchport = "$node_id2:$card2.$port2";
print "switchport='$switchport'\n" if $self->{DEBUG} > 2;
$Ports{$name} = $switchport;
$Ports{$switchport} = $name;
sub fromApconPort($$)
{
my ($self, $ap) = @_;
if ($ap =~ /([A-Z])([0-9]{2})/) {
# froms switch to db
my $card = ord($1) - ord('A') + 1;
my $port = int($2);
if (exists($OldPorts{$oldname})) {
if ($OldPorts{$oldname} ne "") {
delete $OldPorts{$OldPorts{$oldname}};
}
$OldPorts{$oldname} = "";
} else {
$OldPorts{$oldname} = $switchport;
$OldPorts{$switchport} = $oldname;
return Port->LookupByTriple($self->{NAME}, $card, $port);
}
print "Ports: '$name' <==> '$switchport'\n" if $self->{DEBUG} > 1;
}
return $ap;
}
#
# More robust version of convertPortFromNode2Dev
#
sub getRealSwitchPortFromPCPort($$) {
my $self = shift;
my $port = shift;
my $realport = "";
$self->debug("get real port on switch from PC port: $port\n");
if (exists($OldPorts{$port})) {
$realport = $OldPorts{$port};
if ($realport ne "") {
return $realport;
}
}
if (exists($Ports{$port})) {
$realport = $Ports{$port};
return $realport;
}
my $fullport = $port.".1";
if (exists($Ports{$fullport})) {
return $Ports{$fullport};
}
return undef;
}
#
# Try to guess if the given ports contains switch ports
# and refine it to be full port format.
#
sub refineVlanPorts($$@) {
my ($self, $vlanid, @givenports) = @_;
my @ifaces = getVlanIfaces($vlanid);
# Now we have to guess...
if ($#givenports == $#ifaces) {
#
# seems like all ports are here
#
my @fullports = ();
foreach my $iface (@ifaces) {
if (exists($MorePortIface{$iface})) {
push @fullports, $MorePortIface{$iface};
} else {
#
# iface doesn't exist, may God bless the givenports
# be new... new enough to be not in DB.
#
$self->debug("refine failed: Iface $iface not found\n");
return @givenports;
}
}
return @fullports;
}
$self->debug("refine failed: ports numbers not equal @givenports, @ifaces\n");
return @givenports;
}
##############################################################################
......@@ -953,28 +810,6 @@ sub setPortRate($$$)
return 0;
}
#
# Internal
# convert port format from pcxx:card to [A-I][0-9]{2}
#
sub convertPortFromNode2Dev($$) {
my $self = shift;
my $pcport = shift;
my $modport;
if ($pcport =~ /(.+):(.+)\.(.+)/) {
$modport = $Ports{"$pcport"};
} else {
$modport = $Ports{"$pcport.1"};
}
if (defined($modport)) {
return $self->convertPortFormat($modport);
}
return $pcport;
}
#
# Set a variable associated with a port. The commands to execute are given
# in the apcon_clilib::portCMDs hash
......@@ -990,26 +825,13 @@ sub portControl ($$@) {
my $cmd = shift;
my @pcports = @_;
$self->debug("portControl: $cmd -> (@pcports)\n");
#my @fullports = $self->refineVlanPorts($vlan_id, @pcports);
#my @ports = map {$self->getRealSwitchPortFromPCPort($_)} @fullports;
my $errors = 0;
foreach my $port (@pcports) {
my $swport = $self->getRealSwitchPortFromPCPort($port);
if (!defined($swport)) {
if (isSwitchPort($port)) {
next;
} else {
$self->debug("No such port: $port\n");
$errors++;
next;
}
}
foreach my $port (@pcports) {
if (isSwitchPort($port) || ref($self->toApconPort($port->getSwitchPort()))) {
next;
}
$swport = $self->convertPortFormat($swport);
my $rt = $self->setPortRate($swport, $cmd);
my $rt = $self->setPortRate($self->toApconPort($port->getSwitchPort()), $cmd);
if ($rt) {
if ($rt =~ /^ERROR: port rate unsupported/) {
#
......@@ -1109,7 +931,7 @@ sub findVlan($$;$) {
if (@$ports) {
return $vlan_id;
} elsif (exists($emptyVlans{$vlan_id})) {
return $vlan_id; #return $emptyVlans{$vlan_id};
return $vlan_id;
}
return undef;
......@@ -1169,20 +991,14 @@ sub setPortVlan($$@) {
my $id = $self->{NAME} . "::setPortVlan";
$self->debug("$id: $vlan_id ");
$self->debug("ports: " . join(",",@pcports) . "\n");
$self->debug("ports: " . Port->toStrings(@pcports). "\n");
if (@pcports != 2) {
warn "$id: supports only two ports in one VLAN.\n";
return 1;
}
#my @ports = map {$self->convertPortFromNode2Dev($_)} @pcports;
my @fullports = $self->refineVlanPorts($vlan_id, @pcports);
my @swports = map {$self->getRealSwitchPortFromPCPort($_)} @fullports;
$self->debug("$id: set ports in vlan: ".join(", ",@swports)."\n");
my @ports = map {$self->convertPortFormat($_)} @swports;
my @ports = grep(!ref($_), map( $self->toApconPort($_->getSwitchPort()), @pcports));
$self->lock();
# Check if ports are free
......@@ -1248,15 +1064,9 @@ sub delPortVlan($$@) {
my @pcports = @_;
$self->debug($self->{NAME} . "::delPortVlan $vlan_id ");
$self->debug("ports: " . join(",",@pcports) . "\n");
#my @ports = map {$self->convertPortFromNode2Dev($_)} @pcports;
my @fullports = $self->refineVlanPorts($vlan_id, @pcports);
my @swports = map {$self->getRealSwitchPortFromPCPort($_)} @fullports;
$self->debug("snmpit_apcon:delPortVlan: set ports in vlan: ".join(", ",@swports)."\n");
$self->debug("ports: " . Port->toStrings(@pcports) . "\n");
my @ports = map {$self->convertPortFormat($_)} @swports;
my @ports = grep(!ref($_), map($self->toApconPort($_->getSwitchPort()), @pcports));
$self->lock();
......@@ -1413,22 +1223,6 @@ sub vlanHasPorts($$) {
}
#
# Internal
# Convert from switch device port to pc node port
#
sub convertPortFromDev2Node($$) {
my ($self, $devport) = @_;
my $pnum = $self->{NAME}.":".$self->convertPortFormat($devport);
if (!exists $Ports{$pnum}) {
return undef;
}
return $Ports{$pnum};
}
#
# List all VLANs on the device
#
......@@ -1442,17 +1236,10 @@ sub listVlans($) {
my $vlans = $self->getAllNamedPorts();
foreach my $vlan_id (keys %$vlans) {
my @swports = @{$vlans->{$vlan_id}};
my @pcports = ();
foreach my $p (@swports) {
my $pcp = $self->convertPortFromDev2Node($p);
if ($pcp) {
push @pcports, $pcp;
} else {
push @pcports, $p;
}
}
my @pcports = map($_->getPCPort(),
grep(ref($_),
map($self->fromApconPort($_), @swports)));
push @list, [$vlan_id, $vlan_id, \@pcports];
}
......@@ -1475,24 +1262,21 @@ sub listPorts($) {
my @arate = @$arateref;
my @strdrate = @{$portRates{$drate}};
my $pnum = $self->{NAME}.":".$self->convertPortFormat($port);
if (!exists $Ports{$pnum}) {
next;
}
my $finalport = $Ports{$pnum};
my $finalport = $self->fromApconPort($port);
if (!ref($finalport)) {
next;
}
#
# if port is actived, use actual rate, otherwise use desired rate
#
if ( $arate[0] eq "00" ) {
push @ports, [$finalport, "no", "down", $strdrate[2], $strdrate[1]];
push @ports, [$finalport->getPCPort(), "no", "down", $strdrate[2], $strdrate[1]];
} else {
#
# Not sure if it is OK to just ignore the desired rate
#
push @ports, [$finalport, "yes", "up", $arate[3], $arate[2]];
push @ports, [$finalport->getPCPort(), "yes", "up", $arate[3], $arate[2]];
}
}
......
......@@ -2,7 +2,7 @@
#
# EMULAB-LGPL
# Copyright (c) 2000-2009, 2011 University of Utah and the Flux Group.
# Copyright (c) 2000-2009 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -23,6 +23,8 @@ use SNMP;
use snmpit_lib;
use Socket;
use libtestbed;
use Port;
use Lan;
#
# These are the commands that can be passed to the portControl function
......@@ -55,6 +57,7 @@ my %cmdOIDs =
my $PORT_FORMAT_IFINDEX = 1;
my $PORT_FORMAT_MODPORT = 2;
my $PORT_FORMAT_NODEPORT = 3;
my $PORT_FORMAT_PORT = 4;
#
# used by vlanTrunkUtil()
......@@ -107,11 +110,7 @@ sub new($$$;$) {
$self->{MIN_VLAN} = $options->{'min_vlan'};
$self->{MAX_VLAN} = $options->{'max_vlan'};
#
# Temporary removal by Leigh.
#
if (0 &&
($self->{MAX_VLAN} > 1024) && ($self->{MIN_VLAN} < 1000)) {
if (($self->{MAX_VLAN} > 1024) && ($self->{MIN_VLAN} < 1000)) {
warn "ERROR: Some Cisco switches forbid creation of user vlans ".
"with 1000 < vlan number <= 1024\n";
return undef;
......@@ -282,7 +281,7 @@ sub portControl ($$@) {
my $cmd = shift;
my @ports = @_;
$self->debug("portControl: $cmd -> (@ports)\n");
$self->debug("portControl: $cmd -> (".Port->toStrings(@ports).")\n");
#
# Find the command in the %cmdOIDs hash (defined at the top of this file)
......@@ -375,6 +374,7 @@ sub convertPortFormat($$@) {
my $input;
SWITCH: for ($sample) {
(Port->isPort($sample)) && do { $input = $PORT_FORMAT_PORT; last; };
(/^\d+$/) && do { $input = $PORT_FORMAT_IFINDEX; last; };
(/^\d+\.\d+$/) && do { $input = $PORT_FORMAT_MODPORT; last; };
(/^$self->{NAME}\.\d+\/\d+$/) && do { $input = $PORT_FORMAT_MODPORT;
......@@ -391,29 +391,65 @@ sub convertPortFormat($$@) {
}
if ($input == $PORT_FORMAT_IFINDEX) {
my @mps = map $self->{IFINDEX}{$_}, @ports;
if ($output == $PORT_FORMAT_MODPORT) {
$self->debug("Converting ifindex to modport\n",2);
return map $self->{IFINDEX}{$_}, @ports;
} elsif ($output == $PORT_FORMAT_NODEPORT) {
$self->debug("Converting ifindex to nodeport\n",2);
return map portnum($self->{NAME}.":".$self->{IFINDEX}{$_}), @ports;
return @mps;
}
my @pos = map Port->LookupByStringForced($self->{NAME}.":".(defined($_)? $_:"")), @mps;
if ($output == $PORT_FORMAT_NODEPORT) {
$self->debug("Converting ifindex to nodeport\n",2);
return map $_->getPCPort()->toTripleString(), @pos;
} elsif ($output == $PORT_FORMAT_PORT) {
return @pos;
}
} elsif ($input == $PORT_FORMAT_MODPORT) {
if ($output == $PORT_FORMAT_IFINDEX) {
$self->debug("Converting modport to ifindex\n",2);
return map $self->{IFINDEX}{$_}, @ports;
} elsif ($output == $PORT_FORMAT_NODEPORT) {
$self->debug("Converting modport to nodeport\n",2);
return map portnum($self->{NAME} . ":$_"), @ports;
}
my @pos = map Port->LookupByStringForced($self->{NAME}.":".$_), @ports;
if ($output == $PORT_FORMAT_NODEPORT) {
$self->debug("Converting modport to nodeport\n",3);
return map $_->getPCPort()->toTripleString(), @pos;
} elsif ($output == $PORT_FORMAT_PORT) {
return @pos;
}
} elsif ($input == $PORT_FORMAT_NODEPORT) {
} elsif ($input == $PORT_FORMAT_NODEPORT) {
my @pos = map Port->LookupByStringForced($_)->getSwitchPort(), @ports;
if ($output == $PORT_FORMAT_IFINDEX) {
$self->debug("Converting nodeport to ifindex\n",2);
return map $self->{IFINDEX}{(split /:/,portnum($_))[1]}, @ports;
$self->debug("Converting nodeport to ifindex\n",3);
return map $self->{IFINDEX}{(split /:/, $_->toTripleString())[1]}, @pos;
} elsif ($output == $PORT_FORMAT_MODPORT) {
$self->debug("Converting nodeport to modport\n",2);
return map { (split /:/,portnum($_))[1] } @ports;
$self->debug("Converting nodeport to modport\n",3);
return map { (split /:/, $_->toTripleString())[1] } @pos;
} elsif ($output == $PORT_FORMAT_PORT) {
return @pos;
}
} elsif ($input == $PORT_FORMAT_PORT) {
if ($output == $PORT_FORMAT_IFINDEX) {
$self->debug("Converting port to ifindex\n",3);
return map $self->{IFINDEX}{(split /:/,
($_->node_id() eq $self->{NAME})?
$_->toTripleString():
$_->getOtherEndTripleString()
)[1]}, @ports;
} elsif ($output == $PORT_FORMAT_MODPORT) {
$self->debug("Converting port to modport\n",3);
return map { (split /:/,
($_->node_id() eq $self->{NAME})?
$_->toTripleString():
$_->getOtherEndTripleString()
)[1] } @ports;
} elsif ($output == $PORT_FORMAT_NODEPORT) {
$self->debug("Converting port to nodeport\n",3);
return map $_->getPCPort()->toTripleString(), @ports;
}
}
#
......@@ -1026,7 +1062,7 @@ sub opPortVlan($$$@) {
my %BumpedVlans = ();
foreach my $port (@ports) {
$self->debug("Putting port $port in VLAN $vlan_number\n");
$self->debug("Putting port ".Port->toStrings(($port))." in VLAN $vlan_number\n");
#
# Check to see if it's a trunk ....
#
......@@ -1049,9 +1085,7 @@ sub opPortVlan($$$@) {
# Make sure the port didn't get mangled in conversion
#
if (!defined $index) {
my $name = $self->{NAME};
print STDERR "Port ($port) not found on $name, skipping\n";
print STDERR "Port not found, skipping\n";
$errors++;
next;
}
......@@ -1093,16 +1127,16 @@ sub opPortVlan($$$@) {
# disable them. Otherwise, we need to make sure they get enabled.
#
if (($vlan_number == 1) || $remove) {
$self->debug("Disabling " . join(',',@okports) . "...");
$self->debug("Disabling " . Port->toStrings(@okports) . "...");
if ( my $rv = $self->portControl("disable",@okports) ) {
print STDERR "Port disable had $rv failures.\n";
$errors += $rv;
}
} else {
$self->debug("Enabling " . join(',',@okports) . "...");
$self->debug("Enabling " . Port->toStrings(@okports) . "...");
if ( my $rv = $self->portControl("enable",@okports) ) {
print STDERR "Port enable had $rv failures.\n";
$errors += $rv;
$errors += $rv;
}
}
......@@ -1139,6 +1173,8 @@ sub setPortVlan($$@) {
# returns 0 on sucess.
# returns the number of failed ports on failure.
#
# use old port format because all ports used here are from SNMP.
#
sub removePortsFromVlan($@) {
my $self = shift;
my @vlan_numbers = @_;
......@@ -1300,6 +1336,8 @@ sub removeVlan($@) {
#
# TODO: Cleanup
#
# ports passed must be either ifindex or modport
#
sub UpdateField($$$@) {
my $self = shift;
# returns 0 on success, # of failed ports on failure
......@@ -1518,7 +1556,7 @@ sub listVlans($) {
$modport =~ s/\./\//;
$node = $self->{NAME} . ".$modport";
}
push @{$Members{$vlan_number}}, $node;
push @{$Members{$vlan_number}}, Port->LookupByStringForced($node);
if (!$Names{$vlan_number}) {
$self->debug("listVlans: WARNING: port $self->{NAME}.$modport in non-existant " .
"VLAN $vlan_number\n");
......@@ -1537,19 +1575,13 @@ sub listVlans($) {
# XXX: This should really print out something more useful, like the
# other end of the trunk
my $node = $self->{NAME} . ".trunk$ifIndex";
#my ($node) = $self->convertPortFormat($PORT_FORMAT_NODEPORT,$ifIndex);
#if (!$node) {
# my ($modport) = $self->convertPortFormat($PORT_FORMAT_MODPORT,$ifIndex);
# $modport =~ s/\./\//;
# $node = $self->{NAME} . ".$modport";
#}
# Get the allowed VLANs on this trunk
my @trunklans = $self->vlanTrunkUtil($VOP_CHECK, $ifIndex, keys %Names);
foreach my $vlan_number (@trunklans) {
$self->debug("got vlan $vlan_number on trunk $node\n",3);
push @{$Members{$vlan_number}}, $node;
push @{$Members{$vlan_number}}, Port->LookupByStringForced($node);
}
}
......@@ -1615,9 +1647,10 @@ sub walkTableIfIndex($$$;$) {