Exemple #1
0
    def aggregate_counters(self):
        """
        For ports with l3 router interfaces l3 drops may be counted separately (RIF counters)
        add l3 drops to l2 drop counters cache according to mapping

        For l3vlan map l3 counters to l2 counters
        """
        for rif_sai_id, port_sai_id in self.rif_port_map.items():
            if port_sai_id in self.if_id_map:
                port_idx = mibs.get_index_from_str(self.if_id_map[port_sai_id])
                for port_counter_name, rif_counter_name in mibs.RIF_DROPS_AGGR_MAP.items(
                ):
                    self.if_counters[port_idx][port_counter_name] = \
                    self.if_counters[port_idx][port_counter_name] + \
                    self.rif_counters[rif_sai_id][rif_counter_name]

        for vlan_sai_id, vlan_name in self.vlan_name_map.items():
            for port_counter_name, rif_counter_name in mibs.RIF_COUNTERS_AGGR_MAP.items(
            ):
                vlan_idx = mibs.get_index_from_str(vlan_name)
                vlan_rif_counters = self.rif_counters[vlan_sai_id]
                if rif_counter_name in vlan_rif_counters:
                    self.if_counters.setdefault(vlan_idx, {})
                    self.if_counters[vlan_idx][port_counter_name] = \
                        vlan_rif_counters[rif_counter_name]
    def update_data(self):
        """
        Update redis (caches config)
        Pulls the table references for each interface.
        """
        self.vlanmac_ifindex_map = {}
        self.vlanmac_ifindex_list = []

        fdb_strings = Namespace.dbs_keys(
            self.db_conn, mibs.ASIC_DB,
            "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:*")
        if not fdb_strings:
            return

        for s in fdb_strings:
            fdb_str = s
            try:
                fdb = json.loads(fdb_str.split(":", maxsplit=2)[-1])
            except ValueError as e:  # includes simplejson.decoder.JSONDecodeError
                mibs.logger.error(
                    "SyncD 'ASIC_DB' includes invalid FDB_ENTRY '{}': {}.".
                    format(fdb_str, e))
                continue

            ent = Namespace.dbs_get_all(self.db_conn,
                                        mibs.ASIC_DB,
                                        s,
                                        blocking=True)
            # Example output: oid:0x3a000000000608
            bridge_port_id = ent["SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID"][6:]
            if bridge_port_id not in self.if_bpid_map:
                continue
            port_id = self.if_bpid_map[bridge_port_id]
            if port_id in self.if_id_map:
                port_name = self.if_id_map[port_id]
                port_index = mibs.get_index_from_str(port_name)
            elif port_id in self.sai_lag_map:
                port_name = self.sai_lag_map[port_id]
                port_index = mibs.get_index_from_str(port_name)
            else:
                continue

            vlanmac = self.fdb_vlanmac(fdb)
            if not vlanmac:
                mibs.logger.error(
                    "SyncD 'ASIC_DB' includes invalid FDB_ENTRY '{}': failed in fdb_vlanmac()."
                    .format(fdb_str))
                continue
            self.vlanmac_ifindex_map[vlanmac] = port_index
            self.vlanmac_ifindex_list.append(vlanmac)
        self.vlanmac_ifindex_list.sort()
    def get_counter(self, sub_id, table_name):
        """
        :param sub_id: The 1-based sub-identifier query.
        :param table_name: the redis table (either IntEnum or string literal) to query.
        :return: the counter for the respective sub_id/table.
        """

        oid = self.get_oid(sub_id)
        if not oid:
            return

        if oid in self.mgmt_oid_name_map:
            # TODO: mgmt counters not available through SNMP right now
            # COUNTERS DB does not have support for generic linux (mgmt) interface counters
            return 0
        elif oid in self.oid_lag_name_map:
            counter_value = 0
            for lag_member in self.lag_name_if_name_map[
                    self.oid_lag_name_map[oid]]:
                counter_value += self._get_counter(
                    mibs.get_index_from_str(lag_member), table_name)

            # truncate to 32-bit counter
            return counter_value & 0x00000000ffffffff
        else:
            return self._get_counter(oid, table_name)
Exemple #4
0
    def indications_per_priority(self, sub_id):
        """
        :param sub_id: The 0-based sub-identifier query.
        :return: the counter for the respective sub_id/table.
        """
        port_oid = ''
        queue_index = ''
        try:
            if not sub_id:
                return None

            port_oid = self.get_oid((sub_id[0],))
            queue_index = self.queue_index(sub_id)
            if port_oid is None or queue_index is None:
                return None
        except IndexError:
            mibs.logger.warning("indicationsPerPriority: incorrect sub_id = {}".format(str(sub_id)))
            return None

        counter_name = 'SAI_PORT_STAT_PFC_' + str(queue_index) + '_RX_PKTS'

        if port_oid in self.oid_lag_name_map:
            counter_value = 0
            for lag_member in self.lag_name_if_name_map[self.oid_lag_name_map[port_oid]]:
                counter_value += self._get_counter(mibs.get_index_from_str(lag_member), counter_name)

            return counter_value
        else:
            return self._get_counter(port_oid, counter_name)
    def _get_counter(self, oid, table_name, mask):
        """
        :param oid: The 1-based sub-identifier query.
        :param table_name: the redis table (either IntEnum or string literal) to query.
        :param mask: mask to apply to counter
        :return: the counter for the respective sub_id/table.
        """

        if oid in self.mgmt_oid_name_map:
            # TODO: mgmt counters not available through SNMP right now
            # COUNTERS DB does not have support for generic linux (mgmt) interface counters
            return 0

        if oid in self.oid_lag_name_map:
            counter_value = 0
            for lag_member in self.lag_name_if_name_map[
                    self.oid_lag_name_map[oid]]:
                counter_value += self._get_counter(
                    mibs.get_index_from_str(lag_member), table_name, mask)

            return counter_value & mask

        # Enum.name or table_name = 'name_of_the_table'
        _table_name = getattr(table_name, 'name', table_name)
        try:
            counter_value = self.if_counters[oid][_table_name]
            # truncate to 32-bit counter (database implements 64-bit counters)
            counter_value = int(counter_value) & mask
            # done!
            return counter_value
        except KeyError as e:
            mibs.logger.warning(
                "SyncD 'COUNTERS_DB' missing attribute '{}'.".format(e))
            return None
Exemple #6
0
    def get_counter(self, sub_id, table_name):
        """
        :param sub_id: The 1-based sub-identifier query.
        :param table_name: the redis table (either IntEnum or string literal) to query.
        :return: the counter for the respective sub_id/table.
        """

        oid = self.get_oid(sub_id)
        if not oid:
            return

        if oid in self.mgmt_oid_name_map:
            # TODO: mgmt counters not available through SNMP right now
            # COUNTERS DB does not have support for generic linux (mgmt) interface counters
            return 0
        elif oid in self.oid_lag_name_map:
            counter_value = 0
            for lag_member in self.lag_name_if_name_map[self.oid_lag_name_map[oid]]:
                counter_value += self._get_counter(mibs.get_index_from_str(lag_member), table_name)
            sai_lag_id = self.lag_sai_map[self.oid_lag_name_map[oid]]
            sai_lag_rif_id = self.port_rif_map[sai_lag_id]
            if sai_lag_rif_id in self.rif_port_map:
                table_name = getattr(table_name, 'name', table_name)
                if table_name in mibs.RIF_DROPS_AGGR_MAP:
                    rif_table_name = mibs.RIF_DROPS_AGGR_MAP[table_name]
                    counter_value += int(self.rif_counters[sai_lag_rif_id].get(rif_table_name, 0))
            # truncate to 32-bit counter
            return counter_value & 0x00000000ffffffff
        else:
            return self._get_counter(oid, table_name)
Exemple #7
0
    def get_counter(self, sub_id, table_name):
        """
        :param sub_id: The 1-based sub-identifier query.
        :param table_name: the redis table (either IntEnum or string literal) to query.
        :return: the counter for the respective sub_id/table.
        """

        oid = self.get_oid(sub_id)
        if not oid:
            return

        if oid in self.mgmt_oid_name_map:
            # TODO: mgmt counters not available through SNMP right now
            # COUNTERS DB does not have support for generic linux (mgmt) interface counters
            return 0
        elif oid in self.oid_lag_name_map:
            counter_value = 0
            # Sum the values of this counter for all ports in the LAG.
            # Example:
            # table_name = <DbTables.SAI_PORT_STAT_IF_OUT_ERRORS: 20>
            # oid = 1001
            # self.oid_lag_name_map = {1001: 'PortChannel01', 1002: 'PortChannel02', 1003: 'PortChannel03'}
            # self.oid_lag_name_map[oid] = 'PortChannel01'
            # self.lag_name_if_name_map = {'PortChannel01': ['Ethernet112'], 'PortChannel02': ['Ethernet116'], 'PortChannel03': ['Ethernet120']}
            # self.lag_name_if_name_map['PortChannel01'] = ['Ethernet112']
            # mibs.get_index_from_str('Ethernet112') = 113 (because Ethernet N = N + 1)
            # self._get_counter retrieves the counter per oid and table.
            for lag_member in self.lag_name_if_name_map[
                    self.oid_lag_name_map[oid]]:
                counter_value += self._get_counter(
                    mibs.get_index_from_str(lag_member), table_name)
            # Check if we need to add a router interface count.
            # Example:
            # self.lag_sai_map = {'PortChannel01': '2000000000006', 'PortChannel02': '2000000000005', 'PortChannel03': '2000000000004'}
            # self.port_rif_map = {'2000000000006': '6000000000006', '2000000000005': '6000000000005', '2000000000004': '6000000000004'}
            # self.rif_port_map = {'6000000000006': '2000000000006', '6000000000005': '2000000000005', '6000000000004': '2000000000004'}
            # self.lag_sai_map['PortChannel01'] = '2000000000006'
            # self.port_rif_map['2000000000006'] = '6000000000006'
            sai_lag_id = self.lag_sai_map[self.oid_lag_name_map[oid]]
            sai_lag_rif_id = self.port_rif_map[sai_lag_id]
            if sai_lag_rif_id in self.rif_port_map:
                # Extract the 'name' part of 'table_name'.
                # Example:
                # table_name = <DbTables.SAI_PORT_STAT_IF_OUT_ERRORS: 20>
                # _table_name = 'SAI_PORT_STAT_IF_OUT_ERRORS'
                table_name = getattr(table_name, 'name', table_name)
                # Find rif counter table if applicable and add the count for this table.
                # Example:
                # mibs.RIF_DROPS_AGGR_MAP = {'SAI_PORT_STAT_IF_IN_ERRORS': 'SAI_ROUTER_INTERFACE_STAT_IN_ERROR_PACKETS', 'SAI_PORT_STAT_IF_OUT_ERRORS': 'SAI_ROUTER_INTERFACE_STAT_OUT_ERROR_PACKETS'}
                # self.rif_counters['6000000000006'] = {'SAI_ROUTER_INTERFACE_STAT_IN_PACKETS': 6, ... 'SAI_ROUTER_INTERFACE_STAT_OUT_ERROR_PACKETS': 6, ...}
                if table_name in mibs.RIF_DROPS_AGGR_MAP:
                    rif_table_name = mibs.RIF_DROPS_AGGR_MAP[table_name]
                    counter_value += self.rif_counters[sai_lag_rif_id].get(
                        rif_table_name, 0)
            # truncate to 32-bit counter
            return counter_value & 0x00000000ffffffff
        else:
            return self._get_counter(oid, table_name)
Exemple #8
0
 def update_if_counters(self):
     for sai_id_key in self.if_id_map:
         namespace, sai_id = mibs.split_sai_id_key(sai_id_key)
         if_idx = mibs.get_index_from_str(self.if_id_map[sai_id_key])
         counters_db_data = self.namespace_db_map[namespace].get_all(
             mibs.COUNTERS_DB, mibs.counter_table(sai_id), blocking=True)
         self.if_counters[if_idx] = {
             counter: int(value)
             for counter, value in counters_db_data.items()
         }
 def update_data(self):
     """
     Update redis (caches config)
     Pulls the table references for each interface.
     """
     for sai_id_key in self.if_id_map:
         namespace, sai_id = mibs.split_sai_id_key(sai_id_key)
         if_idx = mibs.get_index_from_str(self.if_id_map[sai_id_key])
         self.if_counters[if_idx] = self.namespace_db_map[namespace].get_all(mibs.COUNTERS_DB, \
                 mibs.counter_table(sai_id), blocking=True)
    def _update_arp_info(self, dev, mac, ip):
        if_index = mibs.get_index_from_str(dev)
        if if_index is None: return

        mactuple = mac_decimals(mac)
        machex = ''.join(chr(b) for b in mactuple)
        # if MAC is all zero
        #if not any(mac): continue

        iptuple = ip2tuple_v4(ip)

        subid = (if_index, ) + iptuple
        self.arp_dest_map[subid] = machex
        self.arp_dest_list.append(subid)
Exemple #11
0
    def update_data(self):
        """
        Update redis (caches config)
        Pulls the table references for each interface.
        """
        for sai_id_key in self.if_id_map:
            namespace, sai_id = mibs.split_sai_id_key(sai_id_key)
            if_idx = mibs.get_index_from_str(self.if_id_map[sai_id_key])
            self.if_counters[if_idx] = self.namespace_db_map[namespace].get_all(mibs.COUNTERS_DB, \
                    mibs.counter_table(sai_id), blocking=True)

        self.lag_name_if_name_map, \
        self.if_name_lag_name_map, \
        self.oid_lag_name_map, _ = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_lag_tables, self.db_conn)

        self.if_range = sorted(list(self.oid_name_map.keys()) + list(self.oid_lag_name_map.keys()))
        self.if_range = [(i,) for i in self.if_range]
Exemple #12
0
    def reinit_data(self):
        """
        Subclass update interface information
        """
        self.if_name_map, \
        self.if_alias_map, \
        self.if_id_map, \
        self.oid_name_map = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_interface_tables, self.db_conn)

        for sai_id_key in self.if_id_map:
            namespace, sai_id = mibs.split_sai_id_key(sai_id_key)
            if_idx = mibs.get_index_from_str(self.if_id_map[sai_id_key])
            self.port_index_namespace[if_idx] = namespace

        self.port_queues_map, self.queue_stat_map, self.port_queue_list_map = \
            Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_queue_tables, self.db_conn)

        for db_conn in Namespace.get_non_host_dbs(self.db_conn):
            self.queue_type_map[db_conn.namespace] = db_conn.get_all(mibs.COUNTERS_DB, "COUNTERS_QUEUE_TYPE_MAP", blocking=False)
Exemple #13
0
    def cpfc_if_indications(self, sub_id):
        """
        :param sub_id: The 1-based sub-identifier query.
        :return: the counter for the respective sub_id/table.
        """
        oid = self.get_oid(sub_id)
        if oid is None:
            return None

        # BUG: need the sum of all the priorities
        counter_name = 'SAI_PORT_STAT_PFC_3_RX_PKTS'

        if oid in self.oid_lag_name_map:
            counter_value = 0
            for lag_member in self.lag_name_if_name_map[self.oid_lag_name_map[oid]]:
                counter_value += self._get_counter(mibs.get_index_from_str(lag_member), counter_name)

            return counter_value
        else:
            return self._get_counter(oid, counter_name)
Exemple #14
0
    def update_data(self):
        self.arp_dest_map = {}
        self.arp_dest_list = []
        for entry in python_arptable.get_arp_table():
            dev = entry['Device']
            mac = entry['HW address']
            ip = entry['IP address']

            if_index = mibs.get_index_from_str(dev)
            if if_index is None: continue

            mactuple = mac_decimals(mac)
            machex = ''.join(chr(b) for b in mactuple)
            # if MAC is all zero
            #if not any(mac): continue

            iptuple = ip2tuple_v4(ip)

            subid = (if_index, ) + iptuple
            self.arp_dest_map[subid] = machex
            self.arp_dest_list.append(subid)
        self.arp_dest_list.sort()
Exemple #15
0
    def update_data(self):
        self.arp_dest_map = {}
        self.arp_dest_list = []
        for entry in python_arptable.get_arp_table():
            dev = entry['Device']
            mac = entry['HW address']
            ip = entry['IP address']

            if_index = mibs.get_index_from_str(dev)
            if if_index is None: continue

            mactuple = mac_decimals(mac)
            machex = ''.join(chr(b) for b in mactuple)
            # if MAC is all zero
            #if not any(mac): continue

            iptuple = ip2tuple_v4(ip)

            subid = (if_index,) + iptuple
            self.arp_dest_map[subid] = machex
            self.arp_dest_list.append(subid)
        self.arp_dest_list.sort()
Exemple #16
0
 def update_if_counters(self):
     for sai_id_key in self.if_id_map:
         namespace, sai_id = mibs.split_sai_id_key(sai_id_key)
         if_idx = mibs.get_index_from_str(self.if_id_map[sai_id_key])
         self.if_counters[if_idx] = self.namespace_db_map[namespace].get_all(mibs.COUNTERS_DB, \
                 mibs.counter_table(sai_id), blocking=True)