Esempio n. 1
0
    def reinit_data(self):
        """
        Subclass update interface information
        """
        self.if_name_map, \
        self.if_alias_map, \
        self.if_id_map, \
        self.oid_sai_map, \
        self.oid_name_map = mibs.init_sync_d_interface_tables(self.db_conn)

        self.mgmt_oid_name_map, \
        self.mgmt_alias_map = mibs.init_mgmt_interface_tables(self.db_conn)

        # merge dataplane and mgmt ports
        self.oid_name_map.update(self.mgmt_oid_name_map)
        self.if_alias_map.update(self.mgmt_alias_map)

        self.if_range = []
        # get local port kvs from APP_BD's PORT_TABLE
        self.loc_port_data = {}
        for if_oid, if_name in self.oid_name_map.items():
            self.update_interface_data(if_name)
            self.if_range.append((if_oid, ))
        self.if_range.sort()
        if not self.loc_port_data:
            logger.warning("0 - b'PORT_TABLE' is empty. No local port information could be retrieved.")
Esempio n. 2
0
    def update_rem_if_mgmt(self, if_oid, if_name):
        lldp_kvs = self.db_conn.get_all(mibs.APPL_DB, mibs.lldp_entry_table(if_name))
        if not lldp_kvs or b'lldp_rem_man_addr' not in lldp_kvs:
            # this interfaces doesn't have remote lldp data, or the peer doesn't advertise his mgmt address
            return
        try:
            mgmt_ip_str = lldp_kvs[b'lldp_rem_man_addr'].decode()
            time_mark = int(lldp_kvs[b'lldp_rem_time_mark'])
            remote_index = int(lldp_kvs[b'lldp_rem_index'])
            subtype = self.get_subtype(mgmt_ip_str)
            ip_hex = self.get_ip_hex(mgmt_ip_str, subtype)
            if subtype == ManAddrConst.man_addr_subtype_ipv4:
                addr_subtype_sub_oid = 4
                mgmt_ip_sub_oid = (addr_subtype_sub_oid, *[int(i) for i in mgmt_ip_str.split('.')])
            elif subtype == ManAddrConst.man_addr_subtype_ipv6:
                addr_subtype_sub_oid = 6
                mgmt_ip_sub_oid = (addr_subtype_sub_oid, *[int(i, 16) if i else 0 for i in mgmt_ip_str.split(':')])
            else:
                logger.warning("Invalid management IP {}".format(mgmt_ip_str))
                return
            self.if_range.append((time_mark,
                                  if_oid,
                                  remote_index,
                                  subtype,
                                  *mgmt_ip_sub_oid))

            self.mgmt_ips.update({if_name: {"ip_str": mgmt_ip_str,
                                            "addr_subtype": subtype,
                                            "addr_hex": ip_hex}})
        except (KeyError, AttributeError) as e:
            logger.warning("Error updating remote mgmt addr: {}".format(e))
            return
        self.if_range.sort()
Esempio n. 3
0
 def table_lookup(self, table_name):
     try:
         _table_name = bytes(getattr(table_name, 'name', table_name), 'utf-8')
         return self.loc_chassis_data[_table_name]
     except KeyError as e:
         logger.warning(" 0 - b'LOC_CHASSIS' missing attribute '{}'.".format(e))
         return None
Esempio n. 4
0
    def update_data(self):
        """
        Subclass update data routine. Updates available LLDP counters.
        """
        # establish connection to application database.

        self.if_range = []
        self.lldp_counters = {}
        for if_oid, if_name in self.oid_name_map.items():
            lldp_kvs = Namespace.dbs_get_all(self.db_conn, mibs.APPL_DB,
                                             mibs.lldp_entry_table(if_name))
            if not lldp_kvs:
                continue
            try:
                # OID index for this MIB consists of remote time mark, if_oid, remote_index.
                # For multi-asic platform, it can happen that same interface index result
                # is seen in SNMP walk, with a different remote time mark.
                # To avoid repeating the data of same interface index with different remote
                # time mark, remote time mark is made as 0 in the OID indexing.
                time_mark = 0
                remote_index = int(lldp_kvs['lldp_rem_index'])
                self.if_range.append((time_mark, if_oid, remote_index))
                lldp_kvs['lldp_rem_sys_cap_supported'] = parse_sys_capability(
                    lldp_kvs['lldp_rem_sys_cap_supported'])
                lldp_kvs['lldp_rem_sys_cap_enabled'] = parse_sys_capability(
                    lldp_kvs['lldp_rem_sys_cap_enabled'])
                self.lldp_counters.update({if_name: lldp_kvs})
            except (KeyError, AttributeError) as e:
                logger.warning(
                    "Exception when updating lldpRemTable: {}".format(e))
                continue

        self.if_range.sort()
Esempio n. 5
0
 def update_rem_if_mgmt(self, if_oid, if_name):
     lldp_kvs = Namespace.dbs_get_all(self.db_conn, mibs.APPL_DB,
                                      mibs.lldp_entry_table(if_name))
     if not lldp_kvs or 'lldp_rem_man_addr' not in lldp_kvs:
         # this interfaces doesn't have remote lldp data, or the peer doesn't advertise his mgmt address
         return
     try:
         mgmt_ip_str = lldp_kvs['lldp_rem_man_addr']
         mgmt_ip_str = mgmt_ip_str.strip()
         if len(mgmt_ip_str) == 0:
             # the peer advertise an emtpy mgmt address
             return
         mgmt_ip_set = set()
         for mgmt_ip in mgmt_ip_str.split(','):
             time_mark = int(lldp_kvs['lldp_rem_time_mark'])
             remote_index = int(lldp_kvs['lldp_rem_index'])
             subtype = self.get_subtype(mgmt_ip)
             if not subtype:
                 logger.warning("Invalid management IP {}".format(mgmt_ip))
                 continue
             mgmt_ip_tuple = ip2byte_tuple(mgmt_ip)
             if mgmt_ip_tuple in mgmt_ip_set:
                 continue
             elif subtype == ManAddrConst.man_addr_subtype_ipv4:
                 addr_subtype_sub_oid = 4
             else:
                 addr_subtype_sub_oid = 16
             mgmt_ip_set.add(mgmt_ip_tuple)
             mgmt_ip_sub_oid = (addr_subtype_sub_oid, *mgmt_ip_tuple)
             self.if_range.append((time_mark, if_oid, remote_index, subtype,
                                   *mgmt_ip_sub_oid))
     except (KeyError, AttributeError) as e:
         logger.warning("Error updating remote mgmt addr: {}".format(e))
         return
     self.if_range.sort()
Esempio n. 6
0
def init_mgmt_interface_tables(db_conn):
    """
    Initializes interface maps for mgmt ports
    :param db_conn: db connector
    :return: tuple of mgmt name to oid map and mgmt name to alias map
    """

    db_conn.connect(CONFIG_DB)
    db_conn.connect(STATE_DB)

    mgmt_ports_keys = db_conn.keys(CONFIG_DB, mgmt_if_entry_table(b'*'))

    if not mgmt_ports_keys:
        logger.warning('No managment ports found in {}'.format(mgmt_if_entry_table(b'')))
        return {}, {}

    mgmt_ports = [key.split(mgmt_if_entry_table(b''))[-1] for key in mgmt_ports_keys]
    oid_name_map = {get_index(mgmt_name): mgmt_name for mgmt_name in mgmt_ports}
    logger.debug('Managment port map:\n' + pprint.pformat(oid_name_map, indent=2))

    if_alias_map = dict()

    for if_name in oid_name_map.values():
        if_entry = db_conn.get_all(CONFIG_DB, mgmt_if_entry_table(if_name), blocking=True)
        if_alias_map[if_name] = if_entry.get(b'alias', if_name)

    logger.debug("Management alias map:\n" + pprint.pformat(if_alias_map, indent=2))

    return oid_name_map, if_alias_map
Esempio n. 7
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)

        self.mgmt_oid_name_map, \
        self.mgmt_alias_map = mibs.init_mgmt_interface_tables(self.db_conn[0])

        # merge dataplane and mgmt ports
        self.oid_name_map.update(self.mgmt_oid_name_map)
        self.if_alias_map.update(self.mgmt_alias_map)

        self.if_range = []
        # get local port kvs from APP_BD's PORT_TABLE
        self.loc_port_data = {}
        for if_oid, if_name in self.oid_name_map.items():
            self.update_interface_data(if_name)
            self.if_range.append((if_oid, ))
        self.if_range.sort()
        if not self.loc_port_data:
            logger.warning(
                "0 - b'PORT_TABLE' is empty. No local port information could be retrieved."
            )
 def table_lookup(self, table_name):
     try:
         _table_name = bytes(getattr(table_name, 'name', table_name), 'utf-8')
         return self.loc_chassis_data[_table_name]
     except KeyError as e:
         logger.warning(" 0 - b'LOC_CHASSIS' missing attribute '{}'.".format(e))
         return None
Esempio n. 9
0
    def update_data(self):
        """
        Subclass update data routine. Updates available LLDP counters.
        """
        # establish connection to application database.
        self.db_conn.connect(mibs.APPL_DB)

        self.if_range = []
        self.lldp_counters = {}
        for if_oid, if_name in self.oid_name_map.items():
            lldp_kvs = self.db_conn.get_all(mibs.APPL_DB,
                                            mibs.lldp_entry_table(if_name))
            if not lldp_kvs:
                continue
            try:
                time_mark = int(lldp_kvs[b'lldp_rem_time_mark'])
                remote_index = int(lldp_kvs[b'lldp_rem_index'])
                self.if_range.append((time_mark, if_oid, remote_index))

                self.lldp_counters.update({if_name: lldp_kvs})
            except (KeyError, AttributeError) as e:
                logger.warning(
                    "Exception when updating lldpRemTable: {}".format(e))
                continue

        self.if_range.sort()
Esempio n. 10
0
    def reinit_data(self):
        """
        Subclass update data routine.
        """
        self.man_addr_list = []
        self.mgmt_ip_str = None

        # establish connection to application database.
        self.db_conn.connect(mibs.APPL_DB)
        mgmt_ip_bytes = self.db_conn.get(mibs.APPL_DB, mibs.LOC_CHASSIS_TABLE,
                                         b'lldp_loc_man_addr')

        if not mgmt_ip_bytes:
            logger.warning("Missing lldp_loc_man_addr from APPL DB")
            return

        self.mgmt_ip_str = mgmt_ip_bytes.decode()
        logger.debug("Got mgmt ip from db : {}".format(self.mgmt_ip_str))
        try:
            addr_subtype_sub_oid = 4
            mgmt_ip_sub_oid = None
            for mgmt_ip in self.mgmt_ip_str.split(','):
                if '.' in mgmt_ip:
                    mgmt_ip_sub_oid = (addr_subtype_sub_oid,
                                       *[int(i) for i in mgmt_ip.split('.')])
                    break
        except ValueError:
            logger.error("Invalid local mgmt IP {}".format(self.mgmt_ip_str))
            return

        sub_oid = (ManAddrConst.man_addr_subtype_ipv4, *mgmt_ip_sub_oid)
        self.man_addr_list.append(sub_oid)
Esempio n. 11
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:
                for port_counter_name, rif_counter_name in mibs.RIF_DROPS_AGGR_MAP.items(
                ):
                    self.if_counters[port_sai_id][port_counter_name] = \
                    int(self.if_counters[port_sai_id][port_counter_name]) + \
                    int(self.rif_counters[rif_sai_id][rif_counter_name])

        for vlan_sai_id in self.vlan_name_map:
            for port_counter_name, rif_counter_name in mibs.RIF_COUNTERS_AGGR_MAP.items(
            ):
                try:
                    self.if_counters.setdefault(vlan_sai_id, {})
                    self.if_counters[vlan_sai_id][port_counter_name] = \
                    int(self.rif_counters[vlan_sai_id][rif_counter_name])
                except KeyError as e:
                    logger.warning(
                        "Not able to aggregate counters for {}: {}\n {}".
                        format(vlan_sai_id, rif_counter_name, e))
Esempio n. 12
0
    def _get_counter(self, oid, table_name):
        """
        :param sub_id: The interface OID.
        :param table_name: the redis table (either IntEnum or string literal) to query.
        :return: the counter for the respective sub_id/table.
        """
        sai_id = ''
        if oid in self.oid_sai_map:
            sai_id = self.oid_sai_map[oid]
        elif oid in self.vlan_oid_sai_map:
            sai_id = self.vlan_oid_sai_map[oid]
        else:
            logger.warning("Unexpected oid {}".format(oid))
        # Enum.name or table_name = 'name_of_the_table'
        _table_name = bytes(getattr(table_name, 'name', table_name), 'utf-8')

        try:
            counter_value = self.if_counters[sai_id][_table_name]
            # truncate to 32-bit counter (database implements 64-bit counters)
            counter_value = int(counter_value) & 0x00000000ffffffff
            # done!
            return counter_value
        except KeyError as e:
            mibs.logger.warning(
                "SyncD 'COUNTERS_DB' missing attribute '{}'.".format(e))
            return None
Esempio n. 13
0
    def update_data(self):
        """
        Subclass update data routine. Updates available LLDP counters.
        """
        # establish connection to application database.
        self.db_conn.connect(mibs.APPL_DB)

        self.if_range = []
        self.lldp_counters = {}
        for if_oid, if_name in self.oid_name_map.items():
            lldp_kvs = self.db_conn.get_all(mibs.APPL_DB, mibs.lldp_entry_table(if_name))
            if not lldp_kvs:
                continue
            try:
                time_mark = int(lldp_kvs[b'lldp_rem_time_mark'])
                remote_index = int(lldp_kvs[b'lldp_rem_index'])
                self.if_range.append((time_mark,
                                      if_oid,
                                      remote_index))

                self.lldp_counters.update({if_name: lldp_kvs})
            except (KeyError, AttributeError) as e:
                logger.warning("Exception when updating lldpRemTable: {}".format(e))
                continue

        self.if_range.sort()
def poll_lldp_entry_updates(pubsub):
    ret = None, None, None
    msg = pubsub.get_message()
    if not msg:
        return ret

    try:
        interface = msg["channel"].split(b":")[-1].decode()
        data = msg['data']
    except (KeyError, AttributeError) as e:
        logger.error("Invalid msg when polling for lldp updates: {}\n"
                     "The error seems to be: {}".format(msg, e))
        return ret

    if interface == 'eth0':
        return ret

    # get interface from interface name
    if_index = port_util.get_index_from_str(interface)

    if if_index is None:
        # interface name invalid, skip this entry
        logger.warning(
            "Invalid interface name in {} in APP_DB, skipping".format(
                interface))
        return ret
    return data, interface, if_index
Esempio n. 15
0
def init_sync_d_interface_tables(db_conn):
    """
    Initializes interface maps for SyncD-connected MIB(s).
    :return: tuple(if_name_map, if_id_map, oid_map, if_alias_map)
    """

    # { if_name (SONiC) -> sai_id }
    # ex: { "Ethernet76" : "1000000000023" }
    if_name_map, if_id_map = port_util.get_interface_oid_map(db_conn)
    if_name_map = {if_name: sai_id for if_name, sai_id in if_name_map.items() if \
                   (re.match(port_util.SONIC_ETHERNET_RE_PATTERN, if_name.decode()) or \
                    re.match(port_util.SONIC_ETHERNET_BP_RE_PATTERN, if_name.decode()))}
    # As sai_id is not unique in multi-asic platform, concatenate it with
    # namespace to get a unique key. Assuming that ':' is not present in namespace
    # string or in sai id.
    # sai_id_key = namespace : sai_id
    if_id_map = {get_sai_id_key(db_conn.namespace, sai_id): if_name for sai_id, if_name in if_id_map.items() if \
                 (re.match(port_util.SONIC_ETHERNET_RE_PATTERN, if_name.decode()) or \
                  re.match(port_util.SONIC_ETHERNET_BP_RE_PATTERN, if_name.decode()))}
    logger.debug("Port name map:\n" + pprint.pformat(if_name_map, indent=2))
    logger.debug("Interface name map:\n" + pprint.pformat(if_id_map, indent=2))

    # { OID -> sai_id }
    oid_sai_map = {get_index(if_name): sai_id for if_name, sai_id in if_name_map.items()
                   # only map the interface if it's a style understood to be a SONiC interface.
                   if get_index(if_name) is not None}
    logger.debug("OID sai map:\n" + pprint.pformat(oid_sai_map, indent=2))

    # { OID -> if_name (SONiC) }
    oid_name_map = {get_index(if_name): if_name for if_name in if_name_map
                    # only map the interface if it's a style understood to be a SONiC interface.
                    if get_index(if_name) is not None}

    logger.debug("OID name map:\n" + pprint.pformat(oid_name_map, indent=2))

    # SyncD consistency checks.
    if not oid_sai_map:
        # In the event no interface exists that follows the SONiC pattern, no OIDs are able to be registered.
        # A RuntimeError here will prevent the 'main' module from loading. (This is desirable.)
        message = "No interfaces found matching pattern '{}'. SyncD database is incoherent." \
            .format(port_util.SONIC_ETHERNET_RE_PATTERN)
        logger.error(message)
        raise RuntimeError(message)
    elif len(if_id_map) < len(if_name_map) or len(oid_sai_map) < len(if_name_map):
        # a length mismatch indicates a bad interface name
        logger.warning("SyncD database contains incoherent interface names. Interfaces must match pattern '{}'"
                       .format(port_util.SONIC_ETHERNET_RE_PATTERN))
        logger.warning("Port name map:\n" + pprint.pformat(if_name_map, indent=2))


    if_alias_map = dict()

    for if_name in if_name_map:
        if_entry = db_conn.get_all(APPL_DB, if_entry_table(if_name), blocking=True)
        if_alias_map[if_name] = if_entry.get(b'alias', if_name)

    logger.debug("Chassis name map:\n" + pprint.pformat(if_alias_map, indent=2))

    return if_name_map, if_alias_map, if_id_map, oid_sai_map, oid_name_map
Esempio n. 16
0
def init_sync_d_interface_tables(db_conn):
    """
    Initializes interface maps for SyncD-connected MIB(s).
    :return: tuple(if_name_map, if_id_map, oid_map, if_alias_map)
    """

    # Make sure we're connected to COUNTERS_DB
    db_conn.connect(COUNTERS_DB)

    # { if_name (SONiC) -> sai_id }
    # ex: { "Ethernet76" : "1000000000023" }
    if_name_map, if_id_map = port_util.get_interface_oid_map(db_conn)
    logger.debug("Port name map:\n" + pprint.pformat(if_name_map, indent=2))
    logger.debug("Interface name map:\n" + pprint.pformat(if_id_map, indent=2))

    # { OID -> sai_id }
    oid_sai_map = {get_index(if_name): sai_id for if_name, sai_id in if_name_map.items()
                   # only map the interface if it's a style understood to be a SONiC interface.
                   if get_index(if_name) is not None}
    logger.debug("OID sai map:\n" + pprint.pformat(oid_sai_map, indent=2))

    # { OID -> if_name (SONiC) }
    oid_name_map = {get_index(if_name): if_name for if_name in if_name_map
                    # only map the interface if it's a style understood to be a SONiC interface.
                    if get_index(if_name) is not None}

    logger.debug("OID name map:\n" + pprint.pformat(oid_name_map, indent=2))

    # SyncD consistency checks.
    if not oid_sai_map:
        # In the event no interface exists that follows the SONiC pattern, no OIDs are able to be registered.
        # A RuntimeError here will prevent the 'main' module from loading. (This is desirable.)
        message = "No interfaces found matching pattern '{}'. SyncD database is incoherent." \
            .format(port_util.SONIC_ETHERNET_RE_PATTERN)
        logger.error(message)
        raise RuntimeError(message)
    elif len(if_id_map) < len(if_name_map) or len(oid_sai_map) < len(if_name_map):
        # a length mismatch indicates a bad interface name
        logger.warning("SyncD database contains incoherent interface names. Interfaces must match pattern '{}'"
                       .format(port_util.SONIC_ETHERNET_RE_PATTERN))
        logger.warning("Port name map:\n" + pprint.pformat(if_name_map, indent=2))

    db_conn.connect(APPL_DB)

    if_alias_map = dict()

    for if_name in if_name_map:
        if_entry = db_conn.get_all(APPL_DB, if_entry_table(if_name), blocking=True)
        if_alias_map[if_name] = if_entry.get(b'alias', if_name)

    logger.debug("Chassis name map:\n" + pprint.pformat(if_alias_map, indent=2))

    return if_name_map, if_alias_map, if_id_map, oid_sai_map, oid_name_map
Esempio n. 17
0
 def get_subtype(self, ip_str):
     try:
         ipaddress.IPv4Address(ip_str)
         return ManAddrConst.man_addr_subtype_ipv4
     except ipaddress.AddressValueError:
         # not a valid IPv4
         pass
     try:
         ipaddress.IPv6Address(ip_str)
         return ManAddrConst.man_addr_subtype_ipv6
     except ipaddress.AddressValueError:
         # not a valid IPv6
         logger.warning("Invalid mgmt IP {}".format(ip_str))
     return None
Esempio n. 18
0
 def get_subtype(self, ip_str):
     try:
         ipaddress.IPv4Address(ip_str)
         return ManAddrConst.man_addr_subtype_ipv4
     except ipaddress.AddressValueError:
         # not a valid IPv4
         pass
     try:
         ipaddress.IPv6Address(ip_str)
         return ManAddrConst.man_addr_subtype_ipv6
     except ipaddress.AddressValueError:
         # not a valid IPv6
         logger.warning("Invalid mgmt IP {}".format(ip_str))
     return None
Esempio n. 19
0
 def update_data(self):
     """
     Subclass update data routine. Updates available sai_ids and LLDP counters.
     """
     self.lldp_counters = {}
     for if_name in self.if_name_map:
         lldp_kvs = self.db_conn.get_all(mibs.APPL_DB,
                                         mibs.lldp_entry_table(if_name))
         if not lldp_kvs:
             continue
         self.lldp_counters.update({if_name: lldp_kvs})
     if not self.lldp_counters:
         logger.warning(
             "0 - b'LLDP_ENTRY_TABLE' is empty. No LLDP information could be retrieved."
         )
 def lldp_table_lookup(self, sub_id, table_name):
     if len(sub_id) == 0:
         return None
     sub_id = sub_id[1]
     if sub_id not in self.oid_name_map:
         return None
     if_name = self.oid_name_map[sub_id]
     if if_name not in self.lldp_counters:
         # no LLDP data for this interface
         return None
     counters = self.lldp_counters[if_name]
     _table_name = bytes(getattr(table_name, 'name', table_name), 'utf-8')
     try:
         return counters[_table_name]
     except KeyError as e:
         logger.warning(" 0 - b'LLDP_ENTRY_TABLE' missing attribute '{}'.".format(e))
         return None
Esempio n. 21
0
 def lldp_table_lookup(self, sub_id, table_name):
     if len(sub_id) == 0:
         return None
     sub_id = sub_id[1]
     if sub_id not in self.oid_name_map:
         return None
     if_name = self.oid_name_map[sub_id]
     if if_name not in self.lldp_counters:
         # no LLDP data for this interface
         return None
     counters = self.lldp_counters[if_name]
     _table_name = bytes(getattr(table_name, 'name', table_name), 'utf-8')
     try:
         return counters[_table_name]
     except KeyError as e:
         logger.warning(" 0 - b'LLDP_ENTRY_TABLE' missing attribute '{}'.".format(e))
         return None
Esempio n. 22
0
    def update_rem_if_mgmt(self, if_oid, if_name):
        lldp_kvs = Namespace.dbs_get_all(self.db_conn, mibs.APPL_DB,
                                         mibs.lldp_entry_table(if_name))
        if not lldp_kvs or b'lldp_rem_man_addr' not in lldp_kvs:
            # this interfaces doesn't have remote lldp data, or the peer doesn't advertise his mgmt address
            return
        try:
            mgmt_ip_str = lldp_kvs[b'lldp_rem_man_addr'].decode()
            mgmt_ip_str = mgmt_ip_str.strip()
            if len(mgmt_ip_str) == 0:
                # the peer advertise an emtpy mgmt address
                return
            time_mark = int(lldp_kvs[b'lldp_rem_time_mark'])
            remote_index = int(lldp_kvs[b'lldp_rem_index'])
            subtype = self.get_subtype(mgmt_ip_str)
            ip_hex = self.get_ip_hex(mgmt_ip_str, subtype)
            if subtype == ManAddrConst.man_addr_subtype_ipv4:
                addr_subtype_sub_oid = 4
                mgmt_ip_sub_oid = (addr_subtype_sub_oid,
                                   *[int(i) for i in mgmt_ip_str.split('.')])
            elif subtype == ManAddrConst.man_addr_subtype_ipv6:
                addr_subtype_sub_oid = 6
                mgmt_ip_sub_oid = (
                    addr_subtype_sub_oid,
                    *[int(i, 16) if i else 0 for i in mgmt_ip_str.split(':')])
            else:
                logger.warning("Invalid management IP {}".format(mgmt_ip_str))
                return
            self.if_range.append(
                (time_mark, if_oid, remote_index, subtype, *mgmt_ip_sub_oid))

            self.mgmt_ips.update({
                if_name: {
                    "ip_str": mgmt_ip_str,
                    "addr_subtype": subtype,
                    "addr_hex": ip_hex
                }
            })
        except (KeyError, AttributeError) as e:
            logger.warning("Error updating remote mgmt addr: {}".format(e))
            return
        self.if_range.sort()
Esempio n. 23
0
def init_sync_d_interface_tables(db_conn):
    """
    Initializes interface maps for SyncD-connected MIB(s).
    :return: tuple(if_name_map, if_id_map, oid_map, if_alias_map)
    """

    # Make sure we're connected to COUNTERS_DB
    db_conn.connect(COUNTERS_DB)

    # { if_name (SONiC) -> sai_id }
    # ex: { "Ethernet76" : "1000000000023" }
    if_name_map, if_id_map = port_util.get_interface_oid_map(db_conn)
    logger.debug("Port name map:\n" + pprint.pformat(if_name_map, indent=2))
    logger.debug("Interface name map:\n" + pprint.pformat(if_id_map, indent=2))

    # { OID -> sai_id }
    oid_sai_map = {
        get_index(if_name): sai_id
        for if_name, sai_id in if_name_map.items()
        # only map the interface if it's a style understood to be a SONiC interface.
        if get_index(if_name) is not None
    }
    logger.debug("OID sai map:\n" + pprint.pformat(oid_sai_map, indent=2))

    # { OID -> if_name (SONiC) }
    oid_name_map = {
        get_index(if_name): if_name
        for if_name in if_name_map
        # only map the interface if it's a style understood to be a SONiC interface.
        if get_index(if_name) is not None
    }

    logger.debug("OID name map:\n" + pprint.pformat(oid_name_map, indent=2))

    # SyncD consistency checks.
    if not oid_sai_map:
        # In the event no interface exists that follows the SONiC pattern, no OIDs are able to be registered.
        # A RuntimeError here will prevent the 'main' module from loading. (This is desirable.)
        message = "No interfaces found matching pattern '{}'. SyncD database is incoherent." \
            .format(port_util.SONIC_ETHERNET_RE_PATTERN)
        logger.error(message)
        raise RuntimeError(message)
    elif len(if_id_map) < len(if_name_map) or len(oid_sai_map) < len(
            if_name_map):
        # a length mismatch indicates a bad interface name
        logger.warning(
            "SyncD database contains incoherent interface names. Interfaces must match pattern '{}'"
            .format(port_util.SONIC_ETHERNET_RE_PATTERN))
        logger.warning("Port name map:\n" +
                       pprint.pformat(if_name_map, indent=2))

    # { SONiC name -> optional rename }
    if_alias_map = _if_alias_map
    logger.debug("Chassis name map:\n" +
                 pprint.pformat(if_alias_map, indent=2))
    if if_alias_map is None or len(if_alias_map) == 0:
        logger.warning("No alias map found--port names will use SONiC names.")
        if_alias_map = dict(zip(if_name_map.keys(), if_name_map.keys()))

    return if_name_map, if_alias_map, if_id_map, oid_sai_map, oid_name_map
Esempio n. 24
0
    def update_data(self):
        """
        Subclass update data routine. Updates available LLDP counters.
        """

        # establish connection to application database.
        self.db_conn.connect(mibs.APPL_DB)

        self.if_range = []
        self.lldp_counters = {}
        for if_oid, if_name in self.oid_name_map.items():
            lldp_kvs = self.db_conn.get_all(mibs.APPL_DB,
                                            mibs.lldp_entry_table(if_name))
            if not lldp_kvs:
                continue
            self.if_range.append((if_oid, ))
            self.lldp_counters.update({if_name: lldp_kvs})
        if not self.lldp_counters:
            logger.warning(
                "0 - b'LLDP_ENTRY_TABLE' is empty. No LLDP information could be retrieved."
            )
        self.if_range.sort()
Esempio n. 25
0
def init_mgmt_interface_tables(db_conn):
    """
    Initializes interface maps for mgmt ports
    :param db_conn: db connector
    :return: tuple of mgmt name to oid map and mgmt name to alias map
    """

    db_conn.connect(CONFIG_DB)
    db_conn.connect(STATE_DB)

    mgmt_ports_keys = db_conn.keys(CONFIG_DB, mgmt_if_entry_table(b'*'))

    if not mgmt_ports_keys:
        logger.warning('No managment ports found in {}'.format(
            mgmt_if_entry_table(b'')))
        return {}, {}

    mgmt_ports = [
        key.split(mgmt_if_entry_table(b''))[-1] for key in mgmt_ports_keys
    ]
    oid_name_map = {
        get_index(mgmt_name): mgmt_name
        for mgmt_name in mgmt_ports
    }
    logger.debug('Managment port map:\n' +
                 pprint.pformat(oid_name_map, indent=2))

    if_alias_map = dict()

    for if_name in oid_name_map.values():
        if_entry = db_conn.get_all(CONFIG_DB,
                                   mgmt_if_entry_table(if_name),
                                   blocking=True)
        if_alias_map[if_name] = if_entry.get(b'alias', if_name)

    logger.debug("Management alias map:\n" +
                 pprint.pformat(if_alias_map, indent=2))

    return oid_name_map, if_alias_map
Esempio n. 26
0
def poll_lldp_entry_updates(pubsub):
    ret = None, None, None
    msg = pubsub.get_message()
    if not msg:
        return ret

    try:
        interface = msg["channel"].split(b":")[-1].decode()
        data = msg['data']
    except (KeyError, AttributeError) as e:
        logger.error("Invalid msg when polling for lldp updates: {}\n"
                     "The error seems to be: {}".format(msg, e))
        return ret

    # get interface from interface name
    if_index = port_util.get_index_from_str(interface)

    if if_index is None:
        # interface name invalid, skip this entry
        logger.warning("Invalid interface name in {} in APP_DB, skipping"
                       .format(interface))
        return ret
    return data, interface, if_index
Esempio n. 27
0
def init_sync_d_interface_tables():
    """
    DRY helper method. Connects to and initializes interface maps for SyncD-connected MIB(s).
    :return: tuple(db_conn, if_name_map, if_id_map, oid_map, if_alias_map)
    """
    # SyncD database connector. THIS MUST BE INITIALIZED ON A PER-THREAD BASIS.
    # Redis PubSub objects (such as those within swsssdk) are NOT thread-safe.
    db_conn = SonicV2Connector(**redis_kwargs)
    db_conn.connect(COUNTERS_DB)

    # { if_name (SONiC) -> sai_id }
    # ex: { "Ethernet76" : "1000000000023" }
    if_name_map = db_conn.get_all(COUNTERS_DB, COUNTERS_PORT_NAME_MAP, blocking=True)
    logger.debug("Port name map:\n" + pprint.pformat(if_name_map, indent=2))

    # { sai_id -> if_name (SONiC) }
    if_id_map = {sai_id: if_name for if_name, sai_id in if_name_map.items()
                 # only map the interface if it's a style understood to be a SONiC interface.
                 if get_index(if_name) is not None}
    logger.debug("Interface name map:\n" + pprint.pformat(if_id_map, indent=2))

    # { OID -> sai_id }
    oid_sai_map = {get_index(if_name): sai_id for if_name, sai_id in if_name_map.items()
                   # only map the interface if it's a style understood to be a SONiC interface.
                   if get_index(if_name) is not None}
    logger.debug("OID sai map:\n" + pprint.pformat(oid_sai_map, indent=2))

    # { OID -> if_name (SONiC) }
    oid_name_map = {get_index(if_name): if_name for if_name in if_name_map
                    # only map the interface if it's a style understood to be a SONiC interface.
                    if get_index(if_name) is not None}

    logger.debug("OID name map:\n" + pprint.pformat(oid_name_map, indent=2))

    # SyncD consistency checks.
    if not oid_sai_map:
        # In the event no interface exists that follows the SONiC pattern, no OIDs are able to be registered.
        # A RuntimeError here will prevent the 'main' module from loading. (This is desirable.)
        message = "No interfaces found matching pattern '{}'. SyncD database is incoherent." \
            .format(SONIC_ETHERNET_RE_PATTERN)
        logger.error(message)
        raise RuntimeError(message)
    elif len(if_id_map) < len(if_name_map) or len(oid_sai_map) < len(if_name_map):
        # a length mismatch indicates a bad interface name
        logger.warning("SyncD database contains incoherent interface names. Interfaces must match pattern '{}'"
                       .format(SONIC_ETHERNET_RE_PATTERN))
        logger.warning("Port name map:\n" + pprint.pformat(if_name_map, indent=2))

    # { SONiC name -> optional rename }
    if_alias_map = _if_alias_map
    logger.debug("Chassis name map:\n" + pprint.pformat(if_alias_map, indent=2))
    if if_alias_map is None or len(if_alias_map) == 0:
        logger.warning("No alias map found--port names will use SONiC names.")
        if_alias_map = dict(zip(if_name_map.keys(), if_name_map.keys()))

    return db_conn, if_name_map, if_alias_map, if_id_map, oid_sai_map, oid_name_map