snmpit_intel_stack.pm 4.76 KB
Newer Older
1
#!/usr/bin/perl -w
Leigh Stoller's avatar
Leigh Stoller committed
2 3

#
4
# EMULAB-LGPL
5
# Copyright (c) 2000-2003 University of Utah and the Flux Group.
Leigh Stoller's avatar
Leigh Stoller committed
6 7 8
# All rights reserved.
#

9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
#
# snmpit module for Intel EtherExpress 510T switches. This module is largely
# just a wrapper around snmpit_intel, but is here just in case we ever need to
# contact multiple switches (which may happen if we move to port-based (instead
# of MAC-based) VLANs.) For now, though, pretty much everything just calls
# $self->{LEADER}->foo()
#

package snmpit_intel_stack;
use strict;

$| = 1;				# Turn off line buffering on output

use English;
use SNMP;
use snmpit_lib;

use libdb;

#
# Creates a new object. A list of devices that will be operated on is given
# so that the object knows which to connect to. A future version may not 
# require the device list, and dynamically connect to devices as appropriate
#
# For an Intel stack, the stack_id happens to also be the name of the stack
# leader.
#
# usage: new(string name, string stack_id, int debuglevel list of devicenames)
# returns a new object blessed into the snmpit_intel_stack class
#

40
sub new($$$@) {
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72

    # The next two lines are some voodoo taken from perltoot(1)
    my $proto = shift;
    my $class = ref($proto) || $proto;

    my $stack_id = shift;
    my $debuglevel = shift;
    my @devicenames = @_; # Devicenames are not presently needed for Intel
			  # stacks


    #
    # Create the actual object
    #
    my $self = {};

    #
    # Set up some defaults
    #
    if (defined $debuglevel) {
	$self->{DEBUG} = $debuglevel;
    } else {
	$self->{DEBUG} = 0;
    }

    #
    # The stackid just happens to also be leader of the stack
    # 
    $self->{STACKID} = $stack_id;

    #
    # We only need to create 1 snmpit_intel object, since we only have to
73 74 75
    # talk to one (for now) to do all the setup we need. We fall back on the
    # old behavior of using the stack name as the leader if the leader is not
    # set
76
    #
77 78 79 80 81 82
    my $leader_name = getStackLeader($stack_id);
    if (!$leader_name) {
        $leader_name = $stack_id;
    }
    $self->{LEADERNAME} = $leader_name;

83
    use snmpit_intel;
84 85 86 87 88 89 90 91 92 93 94 95
    $self->{LEADER} = new snmpit_intel($leader_name,$self->{DEBUG});

    #
    # Check for failed object creation
    #
    if (!$self->{LEADER}) {
        #
        # The snmpit_intel object has already printed an error message,
        # so we'll just return an error
        #
        return undef;
    }
96

97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
    bless($self,$class);
    return $self;
}

#
# NOTE: See snmpit_cisco_stack for descriptions of these functions.
# XXX: Document these functions
#

sub listVlans($) {
    my $self = shift;

    return $self->{LEADER}->listVlans();
}

sub listPorts($) {
    my $self = shift;

    return $self->{LEADER}->listPorts();
}

sub setPortVlan($$@) {
    my $self = shift;
    my $vlan_id = shift;
    my @ports = @_;

    return $self->{LEADER}->setPortVlan($vlan_id,@ports);
}

126
sub createVlan($$$;@) {
127 128
    my $self = shift;
    my $vlan_id = shift;
129 130 131 132
    my @ports = @{shift()};
    #
    # We ignore other args for now, since Intels don't support private VLANs
    #
133

134
    return $self->{LEADER}->createVlan($vlan_id,@ports);
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156

}

sub addDevicesToVlan($$@) {
    my $self = shift;
    my $vlan_id = shift;
    my @devicenames = @_; # Note: This is not used for Intel switches

    #
    # This function is not needed on Intel stacks, but it may be someday
    #
    if (!$self->vlanExists($vlan_id)) {
	return 1;
    }

    return 0;
}

sub vlanExists($$) {
    my $self = shift;
    my $vlan_id = shift;

157
    if ($self->{LEADER}->findVlan($vlan_id,1)) {
158 159 160 161 162 163
	return 1;
    } else {
	return 0;
    }
}

164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
#
# Return a list of which VLANs from the input set exist on this stack
#
# usage: existantVlans(self, vlan identifiers)
#
# returns: a list containing the VLANs from the input set that exist on this
# 	stack
#
sub existantVlans($@) {
    my $self = shift;
    my @vlan_ids = @_;

    #
    # The leader holds the list of which VLANs exist
    #
    my %mapping = $self->{LEADER}->findVlans(@vlan_ids);

    my @existant = ();
    foreach my $vlan_id (@vlan_ids) {
	if (defined $mapping{$vlan_id}) {
	    push @existant, $vlan_id;
	}
    }

    return @existant;

}
191

192
sub removeVlan($@) {
193
    my $self = shift; 
194
    my @vlan_ids = @_;
195
		    
196 197 198 199 200 201 202 203 204 205 206 207 208 209
    my $errors = 0;
    foreach my $vlan_id (@vlan_ids) {
	#
	# First, make sure that the VLAN really does exist
	#
	my $vlan_number = $self->{LEADER}->findVlan($vlan_id);
	if (!$vlan_number) {
	    warn "ERROR: VLAN $vlan_id not found on switch!";
	    $errors++;
	}
	my $ok = $self->{LEADER}->removeVlan($vlan_id);
	if (!$ok) {
	    $errors++;
	}
210 211
    }

212
    return ($errors == 0);
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
}       

sub portControl ($$@) { 
    my $self = shift;
    my $cmd = shift;
    my @ports = @_;

    return $self->{LEADER}->portControl($cmd,@ports);
}

sub getStats($) {
    my $self = shift;

    return $self->{LEADER}->getStats();
}