Commit 39e5017b authored by Keith Sklower's avatar Keith Sklower

Add the backend method removeSomePortsFromVlan.

Clean up a couple of minor inconsistancies in the modules concerning
printing ports not in the wires table and make sure utterances like
"wap snmpit -i Nortel10 4/4" work properly.
parent 7c13765f
......@@ -2,9 +2,8 @@
#
# EMULAB-LGPL
# Copyright (c) 2004, Regents, University of California.
# Modified from an Netbed/Emulab module, Copyright (c) 2000-2003, University of
# Utah
# Copyright (c) 2000-2009 University of Utah and the Flux Group.
# Copyright (c) 2004-2009, Regents, University of California.
#
#
......@@ -134,7 +133,7 @@ sub new($$$;$) {
warn ("Opening SNMP session to $self->{NAME}...") if ($self->{DEBUG});
$self->{SESS} = new SNMP::Session(DestHost => $self->{NAME},
Community => $self->{COMMUNITY});
Community => $self->{COMMUNITY}, Version => "2c");
if (!$self->{SESS}) {
#
......@@ -184,7 +183,7 @@ sub hammer($$$;$) {
sub get1($$$) {
my ($self, $obj, $instance) = @_;
my $id = "nortel::snmpitGetOnePersistently of $obj, $instance";
my $id = $self->{NAME}."::snmpitGetOnePersistently of $obj, $instance";
my $closure = sub () {
my $RetVal = snmpitGet($self->{SESS}, [$obj, $instance], 1);
if (!defined($RetVal)) { sleep 2;}
......@@ -215,9 +214,6 @@ sub portControl ($$@) {
$self->debug("portControl: $cmd -> (@ports)\n");
my @p = map { portnum($_) } @ports;
#
# Find the command in the %cmdOIDs hash (defined at the top of this file).
# Some commands involve multiple SNMP commands, so we need to make sure
# we get all of them
......@@ -654,6 +650,61 @@ sub removePortsFromVlan($@) {
return $errors;
}
#
# Removes and disables some ports in a given VLAN. The VLAN is given as a VLAN
# 802.1Q tag value. Ports are known to be regular ports and not trunked.
#
# usage: removeSomePortsFromVlan(self,vlan,@ports)
# returns 0 on sucess.
# returns the number of failed ports on failure.
#
sub removeSomePortsFromVlan($$@) {
my ($self, $vlan_number, @ports) = @_;
my ($errors, $id, %hports) = (0,$self->{NAME}."::removeSomePortsFromVlan");
$self->debug("$id $vlan_number @ports\n");
@ports = $self->convertPortFormat($PORT_FORMAT_IFINDEX,@ports);
@hports{@ports} = @ports;
my $field = ["snVLanByPortMemberVLanId"];
my ($rows) = snmpitBulkwalkFatal($self->{SESS}, $field);
foreach my $rowref (@$rows) {
my ($name,$index,$value) = @$rowref;
$self->debug("removeSomePortsFromVlan: Got $name $index $value\n",2);
if ($value == $vlan_number) {
#
# This table is indexed by vlan.port
#
$index =~ /(\d+)\.(\d+)/;
my ($vlan,$ifIndex) = ($1,$2);
if ($vlan != $vlan_number)
{ die "Something seriously hosed on $self->{NAME}\n"; }
next unless ($hports{$ifIndex});
my $portIndex = $self->{PORTINDEX}{$ifIndex};
my $modport = $self->{IFINDEX}{$ifIndex};
#
# disable this port, unless it is tagged.
#
$value = $self->{SESS}->get(["snSwPortInfoTagMode",$portIndex]);
$self->debug("disabling $modport ( $portIndex ) "
. "from vlan $vlan ( $value )\n" );
if (defined($value) && ($value eq "untagged")) {
$value = $self->{SESS}->set
(["ifAdminStatus",$ifIndex,"down","INTEGER"]);
}
$value = $self->{SESS}->set
(["snVLanByPortMemberRowStatus",$index,"delete","INTEGER"]);
if (!$value) {
$errors++;
print STDERR "couldn't add/remove port $modport" .
"on vlan $vlan_number\n";
}
}
};
return $errors;
}
#
# Remove the given VLANs from this switch. Removes all ports from the VLAN,
# so it's not necessary to call removePortsFromVlan() first. The VLAN is
......@@ -709,7 +760,7 @@ sub UpdateField($$$@) {
# switch:module.port form, or we may have to convert them to it with
# portnum
#
if ($portname =~ /:(\d+)\.(\d+)/) {
if ($portname =~ /\.(\d+)\/(\d+)/) {
$module = $1; $port = $2;
} else {
$portname = portnum($portname);
......@@ -834,10 +885,11 @@ sub listVlans($) {
my $node = portnum($portname);
if (defined($node)) {
$self->debug("portnum returns $node for $portname\n",2);
push @{$Members{$index}}, $node;
} else {
$node = $prefix . '.' . $slot . "/" . $port ;
$self->debug("no portnum for $portname in $vlan_name\n");
}
push @{$Members{$index}}, $node;
}
#@memberlist = $Members{$index};
#$self->debug("constructed list @memberlist\n",2);
......@@ -1076,6 +1128,9 @@ sub getChannelIfIndex($@) {
foreach my $port (@ifIndexes) {
if ($port) { $ifindex = $port; last; }
}
if (! defined ($ifindex)) {
print "Foundry::getChannelIfIndex failed on @ports , @ifIndexes\n";
}
return $ifindex;
}
......@@ -1115,19 +1170,30 @@ sub setVlansOnTrunk($$$$) {
}
}
foreach my $vlan_number (@vlan_numbers) {
my $oid = "snVLanByPortMemberRowStatus.$vlan_number.$ifIndex";
my $action = ($value == 1) ? "create" : "delete" ;
my $readable = ($value == 1) ? "add" : "remove" ;
if ($vlan_number == 1) { next ; }
$RetVal = $self->{SESS}->set(
"snVLanByPortMemberRowStatus.$vlan_number.$ifIndex",$action);
$RetVal = $self->{SESS}->set($oid,$action);
if (!$RetVal) {
$RetVal = $self->{SESS}->get($oid);
if (defined($RetVal) && ($RetVal eq "valid")) {
# Foundry9604's won't let you add
# a vlan when it's already there
if ($value == 1) { next;}
}
# next happens when asked to delete a non-existant vlan
if (($value == 0) && !$RetVal) { next; }
# otherwise, something really did go wrong.
$errors++;
print STDERR "couldn't add/remove port $modport" .
"on vlan $vlan_number\n";
print STDERR "couldn't $readable port $modport " .
"on vlan $vlan_number (ifIndex $ifIndex)\n";
next;
}
#
# If this is a new vlan, need to set name and turn off STP.
#
$self->newNameNoStp($vlan_number, \$errors);
if ($value == 1) { $self->newNameNoStp($vlan_number, \$errors); }
}
return !$errors;
}
......
......@@ -2,8 +2,8 @@
#
# EMULAB-LGPL
# Copyright (c) 2000-2008 University of Utah and the Flux Group.
# Copyright (c) 2004-2008 Regents, University of California.
# Copyright (c) 2000-2009 University of Utah and the Flux Group.
# Copyright (c) 2004-2009 Regents, University of California.
# All rights reserved.
#
......@@ -966,6 +966,49 @@ sub removePortsFromVlan($@) {
return $errors;
}
#
# Removes and disables some ports in a given VLAN. The VLAN is given as a VLAN
# 802.1Q tag value. Ports are known to be regular ports and not trunked.
#
# usage: removeSomePortsFromVlan(self,vlan,@ports)
# returns 0 on sucess.
# returns the number of failed ports on failure.
#
sub removeSomePortsFromVlan($$@) {
my ($self, $vlan_number, @ports) = @_;
my ($errors, $changes, $id, %porthash) =
(0, 0, $self->{NAME} . "::removeSomePortsFromVlan");
@ports = $self->convertPortFormat($PORT_FORMAT_IFINDEX,@ports);
@porthash{@ports} = @ports;
$self->lock();
my $defaultLists = $self->getVlanLists(1);
my $vLists = $self->getVlanLists($vlan_number);
my @portlist = bitSetToList(@$vLists[2]);
$self->debug("$id $vlan_number: @portlist\n",2);
foreach my $portIndex (@portlist) {
next unless $porthash{$portIndex};
if (@{@$vLists[1]}[$portIndex - 1]) {
# otherwise, port is tagged, or dual; maybe should complain.
@{@$defaultLists[1]}[$portIndex - 1] = 1;
@{@$defaultLists[2]}[$portIndex - 1] = 1;
$self->debug("disabling port $portIndex "
. "from vlan $vlan_number \n" );
$self->set(["ifAdminStatus",$portIndex,"down","INTEGER"],$id);
}
@{@$vLists[1]}[$portIndex - 1] = 0;
@{@$vLists[2]}[$portIndex - 1] = 0;
$changes++;
}
$errors += $self->setVlanLists($vlan_number, $vLists, 1, $defaultLists)
if ($changes > 0);
$self->unlock();
return $errors;
}
#
# Remove the given VLANs from this switch. Removes all ports from the VLAN,
# It's necessary to call removePortsFromVlan() first on HP's. The VLAN is
......
......@@ -3,7 +3,7 @@
#
# EMULAB-LGPL
# Copyright (c) 2000-2003 University of Utah and the Flux Group.
# Copyright (c) 2004-2008 Regents, University of California.
# Copyright (c) 2004-2009 Regents, University of California.
# All rights reserved.
#
......@@ -290,8 +290,6 @@ sub portControl ($$@) {
$self->debug("portControl: $cmd -> (@ports)\n");
my @p = map { portnum($_) } @ports;
#
# Find the command in the %cmdOIDs hash (defined at the top of this file).
# Some commands involve multiple SNMP commands, so we need to make sure
......@@ -839,6 +837,30 @@ sub removePortsFromVlan($@) {
return $errors;
}
#
# Removes and disables some ports in a given VLAN. The VLAN is given as a VLAN
# 802.1Q tag value. Ports are known to be regular ports and not trunked.
#
# usage: removeSomePortsFromVlan(self,vlan,@ports)
# returns 0 on sucess.
# returns the number of failed ports on failure.
#
sub removeSomePortsFromVlan($$@) {
my ($self, $vlan_number, @ports) = @_;
my ($errors, $id, %hports) = (0,$self->{NAME}."::removeSomePortsFromVlan");
@ports = $self->convertPortFormat($PORT_FORMAT_IFINDEX,@ports);
my $value = $self->get1("rcVlanPortMembers",$vlan_number);
return 1 if (!$value);
@hports{@ports} = @ports;
@ports = grep { $hports{$_};} $self->portSetToList($value);
$errors += $self->delPortVlan($vlan_number,@ports);
$errors += $self->portControl("disable",@ports);
return $errors;
}
#
# Remove the given VLANs from this switch. Removes all ports from the VLAN,
# so it's not necessary to call removePortsFromVlan() first. The VLAN is
......@@ -896,26 +918,7 @@ sub UpdateField($$$@) {
foreach my $portname (@ports) {
#
# Check the input format - the ports might already be in
# switch:module.port form, or we may have to convert them to it with
# portnum
#
if ($portname =~ /:(\d+)\.(\d+)/) {
$module = $1; $port = $2;
} else {
$portname = portnum($portname);
if (!$portname) { next; }
$portname =~ /:(\d+)\.(\d+)/;
$module = $1; $port = $2;
}
$modport = "$module.$port";
$self->debug("port $portname ( $modport ), " );
if ($OID =~ /^ifAdmin/) {
$row = $self->{IFINDEX}{$modport};
} else {
$row = $self->{PORTINDEX}{$modport};
}
my ($row) = $self->convertPortFormat($PORT_FORMAT_IFINDEX,$portname);
$self->debug("checking row $row for $val ...\n");
$Status = $self->{SESS}->get([$OID,$row]);
if (!defined $Status) {
......@@ -999,11 +1002,12 @@ sub listVlans($) {
if (!$node) {
($modport) = $self->convertPortFormat
($PORT_FORMAT_MODPORT,$ifIndex);
$node = $self->{NAME} . ":$modport";
$modport =~ s/\./\//;
$node = $self->{NAME} . ".$modport";
}
push @{$Members{$vlan_number}}, $node;
if (!$Names{$vlan_number}) {
$self->debug("listVlans: WARNING: port $self->{NAME}.$modport in non-existant " .
$self->debug("listVlans: WARNING: port $node in non-existant " .
"VLAN $vlan_number\n");
}
}
......@@ -1398,6 +1402,9 @@ sub disablePortTrunking($$) {
# IfIndex rather than the module.port style. Fills out the objects IFINDEX
# members,
#
# Unlike Foundry's, Nortel's use same indexes for private port functions
# and IETF standard ifIndex-ed mibs.
#
# usage: readifIndex(self)
# returns nothing but sets instance variables IFINDEX and PORTINDEX
#
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment