From 166c221efc5a30329cf6e3b7a2698ac16765a782 Mon Sep 17 00:00:00 2001 From: SuvarnaMeenakshi <50386592+SuvarnaMeenakshi@users.noreply.github.com> Date: Wed, 22 Jul 2020 07:44:36 -0700 Subject: [PATCH] [Namespace]: Fix interface counters in RFC 1213 (#145) * [Namespace]: Fix interface counters in RFC 1213 for multi-asic platforms. In multi-asic platform, SAI OID is not unique for the whole device. Fix implementation to make sure that interfaces counters is keyed based on interface index. Signed-off-by: SuvarnaMeenakshi --- src/sonic_ax_impl/mibs/__init__.py | 22 ++++++++++++++-------- src/sonic_ax_impl/mibs/ietf/rfc1213.py | 14 ++++++++------ src/sonic_ax_impl/mibs/ietf/rfc2863.py | 3 +-- src/sonic_ax_impl/mibs/ietf/rfc4363.py | 2 +- tests/namespace/test_interfaces.py | 2 -- 5 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/sonic_ax_impl/mibs/__init__.py b/src/sonic_ax_impl/mibs/__init__.py index 35d29693e811..de76ab988644 100644 --- a/src/sonic_ax_impl/mibs/__init__.py +++ b/src/sonic_ax_impl/mibs/__init__.py @@ -148,7 +148,7 @@ def get_sai_id_key(namespace, sai_id): Return value: namespace:sai id or sai id """ if namespace != '': - return namespace.encode() + b':' + sai_id + return namespace.encode() + b':' + sai_id else: return sai_id @@ -213,20 +213,26 @@ 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_id_map = {} + if_name_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()))} + if_name_map_util, if_id_map_util = port_util.get_interface_oid_map(db_conn) + for if_name, sai_id in if_name_map_util.items(): + if_name_str = if_name.decode() + if (re.match(port_util.SONIC_ETHERNET_RE_PATTERN, if_name_str) or \ + re.match(port_util.SONIC_ETHERNET_BP_RE_PATTERN, if_name_str)): + if_name_map[if_name] = sai_id # 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()))} + for sai_id, if_name in if_id_map_util.items(): + if_name = if_name.decode() + if (re.match(port_util.SONIC_ETHERNET_RE_PATTERN, if_name) or \ + re.match(port_util.SONIC_ETHERNET_BP_RE_PATTERN, if_name)): + if_id_map[get_sai_id_key(db_conn.namespace, sai_id)] = if_name 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)) diff --git a/src/sonic_ax_impl/mibs/ietf/rfc1213.py b/src/sonic_ax_impl/mibs/ietf/rfc1213.py index c7dc2848fb6f..4e7b5465d594 100644 --- a/src/sonic_ax_impl/mibs/ietf/rfc1213.py +++ b/src/sonic_ax_impl/mibs/ietf/rfc1213.py @@ -152,7 +152,7 @@ class InterfacesUpdater(MIBUpdater): def __init__(self): super().__init__() - self.db_conn = Namespace.init_namespace_dbs() + self.db_conn = Namespace.init_namespace_dbs() self.lag_name_if_name_map = {} self.if_name_lag_name_map = {} @@ -168,6 +168,7 @@ def __init__(self): self.if_id_map = {} self.oid_sai_map = {} self.oid_name_map = {} + self.namespace_db_map = Namespace.get_namespace_db_map(self.db_conn) def reinit_data(self): """ @@ -191,9 +192,11 @@ def update_data(self): Update redis (caches config) Pulls the table references for each interface. """ - self.if_counters = \ - {sai_id: Namespace.dbs_get_all(self.db_conn, mibs.COUNTERS_DB, mibs.counter_table(sai_id), blocking=True) - for sai_id in self.if_id_map} + 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, \ @@ -254,12 +257,11 @@ def _get_counter(self, oid, table_name): :param table_name: the redis table (either IntEnum or string literal) to query. :return: the counter for the respective sub_id/table. """ - sai_id = self.oid_sai_map[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] + counter_value = self.if_counters[oid][_table_name] # truncate to 32-bit counter (database implements 64-bit counters) counter_value = int(counter_value) & 0x00000000ffffffff # done! diff --git a/src/sonic_ax_impl/mibs/ietf/rfc2863.py b/src/sonic_ax_impl/mibs/ietf/rfc2863.py index 6e7e1619fb6d..8a756bde7c98 100644 --- a/src/sonic_ax_impl/mibs/ietf/rfc2863.py +++ b/src/sonic_ax_impl/mibs/ietf/rfc2863.py @@ -4,7 +4,6 @@ from sonic_ax_impl import mibs from ax_interface.mib import MIBMeta, MIBUpdater, ValueType, SubtreeMIBEntry, OverlayAdpaterMIBEntry, OidMIBEntry from sonic_ax_impl.mibs import Namespace -from swsssdk.port_util import get_index_from_str @unique class DbTables32(int, Enum): @@ -103,7 +102,7 @@ def update_data(self): """ for sai_id_key in self.if_id_map: namespace, sai_id = mibs.split_sai_id_key(sai_id_key) - if_idx = get_index_from_str(self.if_id_map[sai_id_key].decode()) + 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) diff --git a/src/sonic_ax_impl/mibs/ietf/rfc4363.py b/src/sonic_ax_impl/mibs/ietf/rfc4363.py index e9aa46af65b2..3caa89547151 100644 --- a/src/sonic_ax_impl/mibs/ietf/rfc4363.py +++ b/src/sonic_ax_impl/mibs/ietf/rfc4363.py @@ -74,7 +74,7 @@ def update_data(self): port_id = self.if_bpid_map[bridge_port_id] vlanmac = self.fdb_vlanmac(fdb) - self.vlanmac_ifindex_map[vlanmac] = mibs.get_index(self.if_id_map[port_id]) + self.vlanmac_ifindex_map[vlanmac] = mibs.get_index_from_str(self.if_id_map[port_id]) self.vlanmac_ifindex_list.append(vlanmac) self.vlanmac_ifindex_list.sort() diff --git a/tests/namespace/test_interfaces.py b/tests/namespace/test_interfaces.py index 784a324eac89..ea51339f8e34 100644 --- a/tests/namespace/test_interfaces.py +++ b/tests/namespace/test_interfaces.py @@ -22,8 +22,6 @@ class TestGetNextPDU(TestCase): @classmethod def setUpClass(cls): - cls.skipTest(cls, "TODO: Need to update corresponding MIB implementation \ - in the Snmp Agent for multiple namespaces/multi-asic") tests.mock_tables.dbconnector.load_namespace_config() importlib.reload(rfc1213) cls.lut = MIBTable(rfc1213.InterfacesMIB)