Exemple #1
0
 def __init__(self, *args, **kwargs):
     super(ExtremeVlan, self).__init__(*args, **kwargs)
     self.extremevlan = ExtremeVlanMib(self.agent)
     self.bridge = BridgeMib(self.agent)
     self.baseport_ifindex = {}
Exemple #2
0
class ExtremeVlan(Plugin):
    """Collects 802.1q info from EXTREME-VLAN-MIB and BRIDGE-MIB"""

    def __init__(self, *args, **kwargs):
        super(ExtremeVlan, self).__init__(*args, **kwargs)
        self.extremevlan = ExtremeVlanMib(self.agent)
        self.bridge = BridgeMib(self.agent)
        self.baseport_ifindex = {}

    @classmethod
    def can_handle(cls, netbox):
        daddy_says_ok = super(ExtremeVlan, cls).can_handle(netbox)
        if netbox.type:
            vendor_id = netbox.type.get_enterprise_id()
            if vendor_id != VENDORID_EXTREMENETWORKS:
                return False
        return daddy_says_ok

    def handle(self):
        self._logger.debug(
            "Collecting Extreme Networks proprietary 802.1q VLAN information")
        return self._get_vlan_data()

    @inlineCallbacks
    def _get_vlan_data(self):
        vlan_ports = yield self.extremevlan.get_vlan_ports()
        if not vlan_ports:
            # Doesn't appear to have VLAN data in EXTREME MIBs, get out now.
            returnValue(None)
        ifindex_vlan = yield self.extremevlan.get_ifindex_vlan_map()
        self.baseport_ifindex = yield self.bridge.get_baseport_ifindex_map()

        vlan_config = self._consolidate_vlan_config(vlan_ports, ifindex_vlan)

        self._store_access_ports(vlan_config)
        self._store_trunk_ports(vlan_config)

    def _consolidate_vlan_config(self, vlan_ports, ifindex_vlan):
        config = {}
        for vlan_ifindex, (tagged, untagged) in vlan_ports.items():
            vlanid = ifindex_vlan.get(vlan_ifindex, None)
            if not vlanid:
                continue
            tagged_indexes = self._portnums_to_ifindexes(tagged)
            untagged_indexes = self._portnums_to_ifindexes(untagged)
            config[vlanid] = (tagged_indexes, untagged_indexes)

        return config

    def _portnums_to_ifindexes(self, portnums):
        return [self.baseport_ifindex[portnum]
                for portnum in portnums
                if portnum in self.baseport_ifindex]

    def _store_access_ports(self, vlan_config):
        """Store vlan memberships for all ports."""
        for vlanid, (_tagged, untagged) in vlan_config.items():
            for ifindex in untagged:
                interface = self.containers.factory(ifindex, shadows.Interface)
                interface.trunk = False
                interface.vlan = vlanid

    def _store_trunk_ports(self, vlan_config):
        """Store the set of enabled vlans for each trunk port."""
        ifindex_vlans = {}
        for vlanid, (tagged, _untagged) in vlan_config.items():
            for ifindex in tagged:
                if ifindex not in ifindex_vlans:
                    ifindex_vlans[ifindex] = set()
                ifindex_vlans[ifindex].add(vlanid)

        for ifindex, vlans in ifindex_vlans.items():
            interface = self.containers.factory(ifindex, shadows.Interface)
            interface.trunk = True
            interface.vlan = None

            allowed = self.containers.factory(ifindex,
                                              shadows.SwPortAllowedVlan)
            allowed.interface = interface
            allowed.hex_string = vlan_list_to_hex(vlans)
Exemple #3
0
 def __init__(self, *args, **kwargs):
     super(Dot1q, self).__init__(*args, **kwargs)
     self.bridgemib = BridgeMib(self.agent)
     self.qbridgemib = QBridgeMib(self.agent)
Exemple #4
0
class Dot1q(Plugin):
    """Collect 802.1q info from BRIDGE and Q-BRIDGE MIBs."""
    baseports = {}
    pvids = {}

    def __init__(self, *args, **kwargs):
        super(Dot1q, self).__init__(*args, **kwargs)
        self.bridgemib = BridgeMib(self.agent)
        self.qbridgemib = QBridgeMib(self.agent)

    def _remap_vlan(self, vlan_ident):
        """Hook-in for subclasses to remap VLAN numbers if necessary"""
        return vlan_ident

    @inlineCallbacks
    def handle(self):
        """Collects VLAN configuration using Q-BRIDGE-MIB.

        If no PVID information can be found in Q-BRIDGE, the plugin assumes
        the device either doesn't support Q-BRIDGE or doesn't support 802.1q
        and exits.

        """
        self._logger.debug("Collecting 802.1q VLAN information")

        self.baseports = yield self.bridgemib.get_baseport_ifindex_map()
        self.pvids = yield self.qbridgemib.get_baseport_pvid_map()
        if self.pvids:
            self._process_pvids()
        else:
            return

        yield self._get_vlan_names()
        yield self._get_tagging_info()

    def _process_pvids(self):
        """Process the list of collected port/PVID mappings.

        If no PVID data was found, it is assumed that this bridge
        either does not support Q-BRIDGE-MIB or does not support
        802.1q, and the plugin exits.

        """
        self._logger.debug("PVID mapping: %r", self.pvids)

        for port, pvid in self.pvids.items():
            self._set_port_pvid(port, pvid)

    def _set_port_pvid(self, port, pvid):
        if port in self.baseports:
            ifindex = self.baseports[port]
            interface = self.containers.factory(ifindex, shadows.Interface)
            interface.vlan = pvid
            interface.trunk = False  # default all ports to non-tagging at first
        else:
            self._logger.debug("saw reference to non-existant baseport %s",
                               port)

    @inlineCallbacks
    def _get_tagging_info(self):
        """Retrieves and processes information about VLAN egress ports and
        tagging.

        The set of untagged ports is subtracted from the total set of
        egress ports for each vlan, resulting in a set of ports that
        transmit and receive tagged frames for this vlan (i.e. trunk
        ports).

        """
        egress, untagged = yield self._retrieve_vlan_ports()
        trunkports = self._find_trunkports(egress, untagged)
        self._logger.debug("trunkports: %r", trunkports)

        self._store_trunkports(trunkports)

    @inlineCallbacks
    def _retrieve_vlan_ports(self):
        query = self.qbridgemib
        egress = yield query.get_vlan_current_egress_ports()
        untagged = yield query.get_vlan_current_untagged_ports()

        if not egress and not untagged:
            egress = yield query.get_vlan_static_egress_ports()
            untagged = yield query.get_vlan_static_untagged_ports()

        returnValue((egress, untagged))

    def _find_trunkports(self, egress, untagged):
        trunkports = defaultdict(list)
        for vlan, (egress, untagged) in mergedicts(egress, untagged).items():
            try:
                tagged = egress - untagged
            except ValueError:
                self._logger.error(
                    "vlan %s subtraction mismatch between "
                    "EgressPorts and UntaggedPorts", vlan)
            else:
                for port in tagged:
                    trunkports[port].append(vlan)
            finally:
                self._logger.debug("vlan: %s egress: %r untagged: %r", vlan,
                                   egress, untagged)

        return trunkports

    def _store_trunkports(self, trunkports):
        for port, vlans in trunkports.items():
            self._set_trunkport(port, vlans)

    def _set_trunkport(self, port, vlans):
        if port not in self.baseports:
            self._logger.debug("saw reference to non-existant baseport %s",
                               port)
            return

        # Mark as trunk
        ifindex = self.baseports[port]
        interface = self.containers.factory(ifindex, shadows.Interface)
        interface.trunk = True

        # Store a hex string representation of enabled VLANs
        # in swportallowedvlan
        allowed = self.containers.factory(ifindex, shadows.SwPortAllowedVlan)
        allowed.interface = interface
        allowed.hex_string = vlan_list_to_hex(vlans)

    @inlineCallbacks
    def _get_vlan_names(self):
        names = yield self.qbridgemib.get_vlan_static_names()
        if names:
            for vlannum, name in names.items():
                vlannum = self._remap_vlan(vlannum)
                suffix = '+{}'.format(vlannum)
                if name.endswith(suffix):
                    name = name[:-len(suffix)]
                vlan = self.containers.factory(name, shadows.Vlan)
                vlan.net_type = shadows.NetType.get('lan')
                vlan.vlan = vlannum
                vlan.net_ident = name
                vlan.netbox = self.netbox
                self._logger.debug("Found vlan {}: {}".format(vlannum, name))
Exemple #5
0
 def __init__(self, *args, **kwargs):
     super(Dot1q, self).__init__(*args, **kwargs)
     self.bridgemib = BridgeMib(self.agent)
     self.qbridgemib = QBridgeMib(self.agent)
Exemple #6
0
class Dot1q(Plugin):
    """Collect 802.1q info from BRIDGE and Q-BRIDGE MIBs."""
    baseports = {}
    pvids = {}

    def __init__(self, *args, **kwargs):
        super(Dot1q, self).__init__(*args, **kwargs)
        self.bridgemib = BridgeMib(self.agent)
        self.qbridgemib = QBridgeMib(self.agent)

    @inlineCallbacks
    def handle(self):
        """Collects VLAN configuration using Q-BRIDGE-MIB.

        If no PVID information can be found in Q-BRIDGE, the plugin assumes
        the device either doesn't support Q-BRIDGE or doesn't support 802.1q
        and exits.

        """
        self._logger.debug("Collecting 802.1q VLAN information")

        self.baseports = yield self.bridgemib.get_baseport_ifindex_map()
        self.pvids = yield self.qbridgemib.get_baseport_pvid_map()
        if self.pvids:
            self._process_pvids()
        else:
            return

        yield self._get_tagging_info()

    def _process_pvids(self):
        """Process the list of collected port/PVID mappings.

        If no PVID data was found, it is assumed that this bridge
        either does not support Q-BRIDGE-MIB or does not support
        802.1q, and the plugin exits.

        """
        self._logger.debug("PVID mapping: %r", self.pvids)

        for port, pvid in self.pvids.items():
            self._set_port_pvid(port, pvid)

    def _set_port_pvid(self, port, pvid):
        if port in self.baseports:
            ifindex = self.baseports[port]
            interface = self.containers.factory(ifindex,
                                                shadows.Interface)
            interface.vlan = pvid
        else:
            self._logger.debug("saw reference to non-existant baseport %s",
                               port)

    @inlineCallbacks
    def _get_tagging_info(self):
        """Retrieves and processes information about VLAN egress ports and
        tagging.

        The set of untagged ports is subtracted from the total set of
        egress ports for each vlan, resulting in a set of ports that
        transmit and receive tagged frames for this vlan (i.e. trunk
        ports).

        """
        egress, untagged = yield self._retrieve_vlan_ports()
        trunkports = self._find_trunkports(egress, untagged)
        self._logger.debug("trunkports: %r", trunkports)

        self._store_trunkports(trunkports)

    @inlineCallbacks
    def _retrieve_vlan_ports(self):
        query = self.qbridgemib
        egress = yield query.get_vlan_current_egress_ports()
        untagged = yield query.get_vlan_current_untagged_ports()

        if not egress or not untagged:
            egress = yield query.get_vlan_static_egress_ports()
            untagged = yield query.get_vlan_static_untagged_ports()

        returnValue((egress, untagged))

    def _find_trunkports(self, egress, untagged):
        trunkports = {}
        for vlan, (egress, untagged) in mergedicts(egress, untagged).items():
            try:
                tagged = egress - untagged
            except ValueError:
                self._logger.error("vlan %s subtraction mismatch between "
                                   "EgressPorts and UntaggedPorts", vlan)
            else:
                for port in tagged.get_ports():
                    if port not in trunkports:
                        trunkports[port] = [vlan]
                    else:
                        trunkports[port].append(vlan)
            finally:
                self._logger.debug("vlan: %s egress: %r untagged: %r",
                   vlan, egress.get_ports(), untagged.get_ports())

        return trunkports


    def _store_trunkports(self, trunkports):
        for port, vlans in trunkports.items():
            self._set_trunkport(port, vlans)

    def _set_trunkport(self, port, vlans):
        if port not in self.baseports:
            self._logger.debug("saw reference to non-existant baseport %s",
                               port)
            return

        # Mark as trunk
        ifindex = self.baseports[port]
        interface = self.containers.factory(ifindex, shadows.Interface)
        interface.trunk = True

        # Store a hex string representation of enabled VLANs
        # in swportallowedvlan
        allowed = self.containers.factory(ifindex, shadows.SwPortAllowedVlan)
        allowed.interface = interface
        allowed.hex_string = vlan_list_to_hex(vlans)