Exemplo n.º 1
0
    def collect_routes(self):
        """
        Collects the routing table, filters out what we consider to be static
        routes worthy of storage in NAV, and ensure storage as prefixes.

        """
        mib = IpForwardMib(self.agent)
        ifmib = IfMib(self.agent)

        routes = yield mib.get_decoded_routes(protocols=WANTED_PROTOCOLS)
        filtered = [r for r in routes if self.is_wanted_route(r)]

        self._logger.debug(
            "%d of %d collected routes are static candidates",
            len(filtered),
            len(routes),
        )
        self._logger.debug(
            "collected destinations: %r", [r.destination for r in filtered]
        )

        for route in filtered:
            ifindex = yield mib.get_cidr_route_column('IfIndex', route.index)
            alias = None
            if ifindex:
                alias = yield ifmib.retrieve_column_by_index('ifAlias', (ifindex,))
            self.route_to_containers(route, descr=alias)

        Prefix.add_static_routes_sentinel(self.containers)
Exemplo n.º 2
0
 def _make_interface_lookup_dict(self):
     ifmib = IfMib(self.agent_proxy)
     ifnames = yield ifmib.get_ifnames()
     lookup = {}
     for ifindex, (ifname, ifdescr) in ifnames.items():
         lookup[ifdescr] = ifindex
         lookup[ifname] = ifindex
     returnValue(lookup)
Exemplo n.º 3
0
    def handle(self):
        if self.netbox.master:
            self._logger.debug("this is a virtual instance of %s, not polling",
                               self.netbox.master)
            returnValue(None)

        ifmib = IfMib(self.agent)
        result = yield ifmib.retrieve_columns(
            ['ifName', 'ifAdminStatus',
             'ifOperStatus']).addCallback(reduce_index)
        self._put_results(result)
Exemplo n.º 4
0
    def _get_stats(self):
        ifmib = IfMib(self.agent)
        ipmib = IpMib(self.agent)
        stats = yield ifmib.retrieve_columns(
            ("ifName", "ifDescr") + USED_COUNTERS).addCallback(reduce_index)
        ipv6stats = yield ipmib.get_ipv6_octet_counters()
        if ipv6stats:
            self._logger.debug("found ipv6 octet counters for %d interfaces",
                               len(ipv6stats))
        for ifindex, (in_octets, out_octets) in ipv6stats.items():
            if ifindex in stats:
                stats[ifindex][IF_IN_OCTETS_IPV6] = in_octets
                stats[ifindex][IF_OUT_OCTETS_IPV6] = out_octets

        defer.returnValue(stats)
Exemplo n.º 5
0
    def _get_stats(self):
        ifmib = IfMib(self.agent)
        ipmib = IpMib(self.agent)
        stats = yield ifmib.retrieve_columns(
            ("ifName", "ifDescr") + USED_COUNTERS).addCallback(reduce_index)
        ipv6stats = yield ipmib.get_ipv6_octet_counters()
        if ipv6stats:
            self._logger.debug("found ipv6 octet counters for %d interfaces",
                               len(ipv6stats))
        for ifindex, (in_octets, out_octets) in ipv6stats.items():
            if ifindex in stats:
                stats[ifindex][IF_IN_OCTETS_IPV6] = in_octets
                stats[ifindex][IF_OUT_OCTETS_IPV6] = out_octets

        defer.returnValue(stats)
Exemplo n.º 6
0
class LinkAggregate(Plugin):
    """Collects information about link aggregation"""
    def __init__(self, *args, **kwargs):
        super(LinkAggregate, self).__init__(*args, **kwargs)
        self.ifmib = IfMib(self.agent)
        self.lagmib = IEEE8023LagMib(self.agent)

    @inlineCallbacks
    def handle(self):
        self._logger.debug("Collecting link aggregations")
        result = yield self.lagmib.retrieve_aggregations_by_operational_key()
        aggregates = yield self._convert_to_interfaces(result)
        self._log_aggregates(aggregates)
        self._create_aggregate_containers(aggregates)

    @inlineCallbacks
    def _convert_to_interfaces(self, aggregatedict):
        result = []
        for aggregator_idx, aggregates in aggregatedict.items():
            aggregator = yield self._get_interface(aggregator_idx)
            for if_idx in aggregates:
                interface = yield self._get_interface(if_idx)
                result.append((interface, aggregator))
        returnValue(result)

    @inlineCallbacks
    def _get_interface(self, ifindex):
        ifc = self.containers.factory(ifindex,
                                      shadows.Interface,
                                      ifindex=ifindex)
        if not ifc.ifname:
            # In case no other plugins ran before us to collect this:
            self._logger.debug("retrieving ifName.%s", ifindex)
            ifc.ifname = yield self.ifmib.retrieve_column_by_index(
                'ifName', (ifindex, ))
        returnValue(ifc)

    def _log_aggregates(self, aggregates):
        self._logger.debug("%r", aggregates)
        if not self._logger.isEnabledFor(logging.DEBUG):
            return

        aggr = defaultdict(list)
        for ifc, aggregator in aggregates:
            aggr[aggregator.ifname].append(ifc.ifname)

        for aggregator, ports in aggr.items():
            self._logger.debug("%s aggregates these ports: %s", aggregator,
                               ', '.join(ports))

    def _create_aggregate_containers(self, aggregates):
        for interface, aggregator in aggregates:
            key = aggregator.ifindex, interface.ifindex
            aggregate = self.containers.factory(key,
                                                shadows.InterfaceAggregate)
            aggregate.aggregator = aggregator
            aggregate.interface = interface
Exemplo n.º 7
0
    def get_vlan_interfaces(self):
        """Get all virtual VLAN interfaces.

        Any interface whose ifName matches the VLAN_PATTERN regexp
        will be included in the result.

        Return value:

          A deferred whose result is a dictionary: { ifindex: vlan }

        """
        ifmib = IfMib(self.agent)
        df = ifmib.retrieve_column('ifName')
        df.addCallback(reduce_index)
        interfaces = yield df

        vlan_ifs = {}
        for ifindex, ifname in interfaces.items():
            match = VLAN_PATTERN.match(ifname)
            if match:
                vlan = int(match.group('vlan'))
                vlan_ifs[ifindex] = vlan

        defer.returnValue(vlan_ifs)
Exemplo n.º 8
0
    def get_vlan_interfaces(self):
        """Get all virtual VLAN interfaces.

        Any interface whose ifName matches the VLAN_PATTERN regexp
        will be included in the result.

        Return value:

          A deferred whose result is a dictionary: { ifindex: vlan }

        """
        ifmib = IfMib(self.agent)
        df = ifmib.retrieve_column('ifName')
        df.addCallback(reduce_index)
        interfaces = yield df

        vlan_ifs = {}
        for ifindex, ifname in interfaces.items():
            match = VLAN_PATTERN.match(ifname)
            if match:
                vlan = int(match.group('vlan'))
                vlan_ifs[ifindex] = vlan

        defer.returnValue(vlan_ifs)
Exemplo n.º 9
0
class LinkState(Plugin):
    def handle(self):
        self.ifmib = IfMib(self.agent)
        df = self.ifmib.retrieve_columns(['ifName', 'ifOperStatus'])
        df.addCallback(reduce_index)
        return df.addCallback(self._put_results)

    def _put_results(self, results):
        netbox = self.containers.factory(None, shadows.Netbox)
        for index, row in results.items():
            self._update_interface(netbox, index, row)

    def _update_interface(self, netbox, ifindex, row):
        ifc = self.containers.factory(ifindex, shadows.Interface)
        ifc.netbox = netbox
        ifc.ifindex = ifindex
        if row['ifName']:
            ifc.ifname = row['ifName']
        ifc.ifoperstatus = row['ifOperStatus']
Exemplo n.º 10
0
class LinkState(Plugin):

    def handle(self):
        self.ifmib = IfMib(self.agent)
        df = self.ifmib.retrieve_columns(['ifName', 'ifOperStatus'])
        df.addCallback(reduce_index)
        return df.addCallback(self._put_results)

    def _put_results(self, results):
        netbox = self.containers.factory(None, shadows.Netbox)
        for index, row in results.items():
            self._update_interface(netbox, index, row)

    def _update_interface(self, netbox, ifindex, row):
        ifc = self.containers.factory(ifindex, shadows.Interface)
        ifc.netbox = netbox
        ifc.ifindex = ifindex
        if row['ifName']:
            ifc.ifname = row['ifName']
        ifc.ifoperstatus = row['ifOperStatus']
Exemplo n.º 11
0
 def handle(self):
     self.ifmib = IfMib(self.agent)
     df = self.ifmib.retrieve_columns(['ifName', 'ifOperStatus'])
     df.addCallback(reduce_index)
     return df.addCallback(self._put_results)
Exemplo n.º 12
0
 def _get_ifindexes(self):
     ifmib = IfMib(self.agent)
     indexes = yield ifmib.get_ifindexes()
     defer.returnValue(set(indexes))
Exemplo n.º 13
0
 def __init__(self, *args, **kwargs):
     super(LinkAggregate, self).__init__(*args, **kwargs)
     self.ifmib = IfMib(self.agent)
     self.lagmib = IEEE8023LagMib(self.agent)
Exemplo n.º 14
0
 def _get_adminup_ifcs(self):
     ifmib = IfMib(self.agent)
     statuses = yield ifmib.get_admin_status()
     result = set(ifindex for ifindex, status in statuses.items()
                  if status == 'up')
     defer.returnValue(result)
Exemplo n.º 15
0
 def _get_adminup_ifcs(self):
     ifmib = IfMib(self.agent)
     statuses = yield ifmib.get_admin_status()
     result = set(ifindex for ifindex, status in statuses.items()
                  if status == 'up')
     defer.returnValue(result)
Exemplo n.º 16
0
 def _get_ifc_aliases(self):
     return IfMib(self.agent).get_ifaliases()
Exemplo n.º 17
0
 def __init__(self, *args, **kwargs):
     super(Interfaces, self).__init__(*args, **kwargs)
     self.ifmib = IfMib(self.agent)
     self.etherlikemib = EtherLikeMib(self.agent)
Exemplo n.º 18
0
class Interfaces(Plugin):
    "Collects comprehensive information about device's network interfaces"

    def __init__(self, *args, **kwargs):
        super(Interfaces, self).__init__(*args, **kwargs)
        self.ifmib = IfMib(self.agent)
        self.etherlikemib = EtherLikeMib(self.agent)

    @defer.inlineCallbacks
    def handle(self):
        self._logger.debug("Collecting interface data")
        df = self._get_iftable_columns()
        df.addCallback(self._retrieve_duplex)
        df.addCallback(self._process_interfaces)
        df.addCallback(self._get_stack_status)
        yield df
        shadows.Interface.add_sentinel(self.containers)

    def _get_iftable_columns(self):
        df = self.ifmib.retrieve_columns(
            [
                'ifDescr',
                'ifType',
                'ifSpeed',
                'ifPhysAddress',
                'ifAdminStatus',
                'ifOperStatus',
                'ifName',
                'ifHighSpeed',
                'ifConnectorPresent',
                'ifAlias',
            ]
        )
        return df.addCallback(reduce_index)

    def _process_interfaces(self, result):
        """Process the list of collected interfaces."""

        self._logger.debug("Found %d interfaces", len(result))

        # Now save stuff to containers and pass the list of containers
        # to the next callback
        netbox = self.containers.factory(None, shadows.Netbox)
        interfaces = [
            self._convert_row_to_container(netbox, ifindex, row)
            for ifindex, row in result.items()
            if isinstance(ifindex, int)
        ]
        return interfaces

    def _convert_row_to_container(self, netbox, ifindex, row):
        """Convert a collected ifTable/ifXTable row into a container object."""

        interface = self.containers.factory(ifindex, shadows.Interface)
        interface.ifindex = ifindex
        interface.ifdescr = row['ifDescr']
        interface.iftype = row['ifType']

        speed = self._extract_interface_speed(
            row["ifSpeed"],
            row["ifHighSpeed"],
            always_use_highspeed=self.config.getboolean(
                "interfaces", "always_use_ifhighspeed"
            ),
        )
        if speed is not None:
            interface.speed = speed

        interface.ifphysaddress = typesafe_binary_mac_to_hex(row['ifPhysAddress'])
        interface.ifadminstatus = row['ifAdminStatus']
        interface.ifoperstatus = row['ifOperStatus']

        interface.ifname = row['ifName'] or interface.baseport or row['ifDescr']
        interface.ifconnectorpresent = row['ifConnectorPresent'] == 1
        interface.ifalias = safestring(row['ifAlias'])

        # Set duplex if sucessfully retrieved
        if 'duplex' in row and row['duplex'] in DUPLEX_MAP:
            interface.duplex = DUPLEX_MAP[row['duplex']]

        interface.gone_since = None

        interface.netbox = netbox
        return interface

    @staticmethod
    def _extract_interface_speed(speed, highspeed, always_use_highspeed=False):
        """Determines the interface speed from a combination of ifSpeed and ifHighSpeed
        values.

        The IF-MIB spec says to use the ifHighSpeed value if the 32-bit unsigned
        ifSpeed value is maxed out. However, some devices, like Cisco SG350X-24T
        running 2.5.5.47 firmware, have an incorrect implementation that causes
        ifSpeed=ifHighSpeed.

        Yet other buggy implementations even have no discernable correlation between
        the two values, and only their ifHighSpeed value can be trusted.
        """
        if always_use_highspeed and isinstance(highspeed, int):
            return float(highspeed)

        if isinstance(speed, int):
            if 4294967295 > speed != highspeed:
                return speed / 1000000.0
            elif isinstance(highspeed, int):
                return float(highspeed)

    @defer.inlineCallbacks
    def _get_stack_status(self, interfaces):
        """Retrieves data from the ifStackTable and initiates a search for a
        proper ifAlias value for those interfaces that lack it.

        """

        def _stackify(stackstatus):
            ifindex_map = dict((ifc.ifindex, ifc) for ifc in interfaces)
            stack = [
                (ifindex_map[higher], ifindex_map[lower])
                for higher, lower in stackstatus
                if higher in ifindex_map and lower in ifindex_map
            ]
            return stack

        stack = yield self.ifmib.get_stack_status().addCallback(_stackify)
        self._get_ifalias_from_lower_layers(stack)
        self._create_stack_containers(stack)
        defer.returnValue(interfaces)

    def _get_ifalias_from_lower_layers(self, stack):
        """For each interface without an ifAlias value, attempts to find
        ifAlias from a lower layer interface.

        By popular convention, some devices are configured with virtual router
        ports that are conceptually a layer above the physical interface.  The
        virtual port may have no ifAlias value, but the physical interface may
        have.  We want an ifAlias value, since it tells us the netident of the
        router port's network.

        """
        for higher, lower in stack:
            if not higher.ifalias and lower.ifalias:
                higher.ifalias = lower.ifalias
                self._logger.debug(
                    "%s alias set from lower layer %s: %s",
                    higher.ifname,
                    lower.ifname,
                    higher.ifalias,
                )

    def _create_stack_containers(self, stacklist):
        for higher, lower in stacklist:
            key = higher.ifindex, lower.ifindex
            stack = self.containers.factory(key, shadows.InterfaceStack)
            stack.higher = higher
            stack.lower = lower

    def _retrieve_duplex(self, interfaces):
        """Get duplex from EtherLike-MIB and update the ifTable results."""

        def update_result(duplexes):
            self._logger.debug("Got duplex information: %r", duplexes)
            for index, duplex in duplexes.items():
                if index in interfaces:
                    interfaces[index]['duplex'] = duplex
            return interfaces

        deferred = self.etherlikemib.get_duplex()
        deferred.addCallback(update_result)
        return deferred
Exemplo n.º 19
0
 def handle(self):
     self.ifmib = IfMib(self.agent)
     df = self.ifmib.retrieve_columns(['ifName', 'ifOperStatus'])
     df.addCallback(reduce_index)
     return df.addCallback(self._put_results)