diff --git a/src/sonic_ax_impl/mibs/__init__.py b/src/sonic_ax_impl/mibs/__init__.py index 2c4006a61..582bd6041 100644 --- a/src/sonic_ax_impl/mibs/__init__.py +++ b/src/sonic_ax_impl/mibs/__init__.py @@ -95,6 +95,9 @@ def queue_table(sai_id): def queue_key(port_index, queue_index): return str(port_index) + ':' + str(queue_index) +def get_port_index_from_queue_key(queue_key): + return int(queue_key.split(':')[0]) + def transceiver_info_table(port_name): """ :param: port_name: port name @@ -469,7 +472,7 @@ class RedisOidTreeUpdater(MIBUpdater): def __init__(self, prefix_str): super().__init__() - self.db_conn = Namespace.init_namespace_dbs() + self.db_conn = Namespace.init_namespace_dbs() if prefix_str.startswith('.'): prefix_str = prefix_str[1:] self.prefix_str = prefix_str @@ -495,16 +498,18 @@ def update_data(self): self.oid_list = [] self.oid_map = {} - keys = Namespace.dbs_keys(self.db_conn, SNMP_OVERLAY_DB, self.prefix_str + '*') + Namespace.connect_all_dbs(self.db_conn, SNMP_OVERLAY_DB) + keys = Namespace.dbs_keys_namespace(self.db_conn, SNMP_OVERLAY_DB, self.prefix_str + '*') # TODO: fix db_conn.keys to return empty list instead of None if there is no match if keys is None: - keys = [] + keys = {} for key in keys: + db_index = keys[key] key = key.decode() oid = oid2tuple(key, dot_prefix=False) self.oid_list.append(oid) - value = Namespace.dbs_get_all(self.db_conn, SNMP_OVERLAY_DB, key) + value = self.db_conn[db_index].get_all(SNMP_OVERLAY_DB, key) if value[b'type'] in [b'COUNTER_32', b'COUNTER_64']: self.oid_map[oid] = int(value[b'data']) else: @@ -520,7 +525,7 @@ def get_oidvalue(self, oid): class Namespace: @staticmethod def init_namespace_dbs(): - db_conn= [] + db_conn = [] SonicDBConfig.load_sonic_global_db_config() for namespace in SonicDBConfig.get_ns_list(): db = SonicV2Connector(use_unix_socket_path=True, namespace=namespace) @@ -538,7 +543,7 @@ def dbs_keys(dbs, db_name, pattern='*'): """ db keys function execute on global and all namespace DBs. """ - result_keys=[] + result_keys = [] for db_conn in dbs: db_conn.connect(db_name) keys = db_conn.keys(db_name, pattern) @@ -547,33 +552,35 @@ def dbs_keys(dbs, db_name, pattern='*'): return result_keys @staticmethod - def dbs_get_all(dbs, db_name, _hash, *args, **kwargs): + def dbs_keys_namespace(dbs, db_name, pattern='*'): """ - db get_all function executed on global and all namespace DBs. + dbs_keys_namespace function execute on global + and all namespace DBs. Provides a map of keys + and namespace(db index). """ - result = {} - for db_conn in dbs: - db_conn.connect(db_name) - if(db_conn.exists(db_name, _hash)): - ns_result = db_conn.get_all(db_name, _hash, *args, **kwargs) - if ns_result is not None: - result.update(ns_result) - return result + result_keys = {} + for db_index in range(len(dbs)): + keys = dbs[db_index].keys(db_name, pattern) + if keys is not None: + keys_ns = dict.fromkeys(keys, db_index) + result_keys.update(keys_ns) + return result_keys @staticmethod - def get_non_host_dbs(dbs): + def get_non_host_db_indexes(dbs): """ From the list of all dbs, return the list of dbs which will have interface related tables. For single namespace db, return the single db. - For multiple namespace dbs, return all dbs except the - host namespace db which is the first db in the list. + For multiple namespace dbs, return db index ofall dbs + except the host namespace db which is the first db + in the list. """ if len(dbs) == 1: - return dbs + start_index = 0 else: - return dbs[1:] - + start_index = 1 + return range(start_index, len(dbs)) @staticmethod def init_namespace_sync_d_interface_tables(dbs): @@ -582,6 +589,7 @@ def init_namespace_sync_d_interface_tables(dbs): if_id_map = {} oid_sai_map = {} oid_name_map = {} + if_oid_namespace = {} """ all_ns_db - will have db_conn to all namespace DBs and @@ -589,19 +597,21 @@ def init_namespace_sync_d_interface_tables(dbs): Ignore first global db to get interface tables if there are multiple namespaces. """ - for db_conn in Namespace.get_non_host_dbs(dbs): + for db_index in Namespace.get_non_host_db_indexes(dbs): if_name_map_ns, \ if_alias_map_ns, \ if_id_map_ns, \ oid_sai_map_ns, \ - oid_name_map_ns = init_sync_d_interface_tables(db_conn) + oid_name_map_ns = init_sync_d_interface_tables(dbs[db_index]) if_name_map.update(if_name_map_ns) if_alias_map.update(if_alias_map_ns) if_id_map.update(if_id_map_ns) oid_sai_map.update(oid_sai_map_ns) oid_name_map.update(oid_name_map_ns) + if_oid_namespace_ns = dict.fromkeys(oid_name_map_ns.keys(), db_index) + if_oid_namespace.update(if_oid_namespace_ns) - return if_name_map, if_alias_map, if_id_map, oid_sai_map, oid_name_map + return if_name_map, if_alias_map, if_id_map, oid_sai_map, oid_name_map, if_oid_namespace @staticmethod def init_namespace_sync_d_lag_tables(dbs): @@ -610,6 +620,7 @@ def init_namespace_sync_d_lag_tables(dbs): if_name_lag_name_map = {} oid_lag_name_map = {} lag_sai_map = {} + oid_lag_namespace = {} """ all_ns_db - will have db_conn to all namespace DBs and @@ -617,46 +628,54 @@ def init_namespace_sync_d_lag_tables(dbs): Ignore first global db to get lag tables if there are multiple namespaces. """ - for db_conn in Namespace.get_non_host_dbs(dbs): + for db_index in Namespace.get_non_host_db_indexes(dbs): lag_name_if_name_map_ns, \ if_name_lag_name_map_ns, \ oid_lag_name_map_ns, \ - lag_sai_map_ns = init_sync_d_lag_tables(db_conn) + lag_sai_map_ns = init_sync_d_lag_tables(dbs[db_index]) lag_name_if_name_map.update(lag_name_if_name_map_ns) if_name_lag_name_map.update(if_name_lag_name_map_ns) oid_lag_name_map.update(oid_lag_name_map_ns) + oid_lag_namespace_ns = dict.fromkeys(oid_lag_name_map_ns.keys(), db_index) + oid_lag_namespace.update(oid_lag_namespace_ns) lag_sai_map.update(lag_sai_map_ns) - return lag_name_if_name_map, if_name_lag_name_map, oid_lag_name_map, lag_sai_map + return lag_name_if_name_map, if_name_lag_name_map, oid_lag_name_map, lag_sai_map, oid_lag_namespace @staticmethod def init_namespace_sync_d_rif_tables(dbs): rif_port_map = {} port_rif_map = {} + port_namespace = {} - for db_conn in Namespace.get_non_host_dbs(dbs): + for db_index in Namespace.get_non_host_db_indexes(dbs): rif_port_map_ns, \ - port_rif_map_ns = init_sync_d_rif_tables(db_conn) + port_rif_map_ns = init_sync_d_rif_tables(dbs[db_index]) rif_port_map.update(rif_port_map_ns) port_rif_map.update(port_rif_map_ns) + port_namespace_ns = dict.fromkeys(rif_port_map_ns.keys(), db_index) + port_namespace.update(port_namespace_ns) - return rif_port_map, port_rif_map + return rif_port_map, port_rif_map, port_namespace @staticmethod def init_namespace_sync_d_vlan_tables(dbs): vlan_name_map = {} oid_sai_map = {} oid_name_map = {} + vlan_oid_namespace = {} - for db_conn in Namespace.get_non_host_dbs(dbs): + for db_index in Namespace.get_non_host_db_indexes(dbs): vlan_name_map_ns, \ oid_sai_map_ns, \ - oid_name_map_ns = init_sync_d_vlan_tables(db_conn) + oid_name_map_ns = init_sync_d_vlan_tables(dbs[db_index]) vlan_name_map.update(vlan_name_map_ns) oid_sai_map.update(oid_sai_map_ns) oid_name_map.update(oid_name_map_ns) + vlan_oid_namespace_ns = dict.fromkeys(oid_name_map.keys(), db_index) + vlan_oid_namespace.update(vlan_oid_namespace_ns) - return vlan_name_map, oid_sai_map, oid_name_map + return vlan_name_map, oid_sai_map, oid_name_map, vlan_oid_namespace @staticmethod def init_namespace_sync_d_queue_tables(dbs): @@ -670,10 +689,10 @@ def init_namespace_sync_d_queue_tables(dbs): Ignore first global db to get queue tables if there are multiple namespaces. """ - for db_conn in Namespace.get_non_host_dbs(dbs): + for db_index in Namespace.get_non_host_db_indexes(dbs): port_queues_map_ns, \ queue_stat_map_ns, \ - port_queue_list_map_ns = init_sync_d_queue_tables(db_conn) + port_queue_list_map_ns = init_sync_d_queue_tables(dbs[db_index]) port_queues_map.update(port_queues_map_ns) queue_stat_map.update(queue_stat_map_ns) port_queue_list_map.update(port_queue_list_map_ns) @@ -686,15 +705,15 @@ def dbs_get_bridge_port_map(dbs, db_name): get_bridge_port_map from all namespace DBs """ if_br_oid_map = {} - for db_conn in Namespace.get_non_host_dbs(dbs): - if_br_oid_map_ns = port_util.get_bridge_port_map(db_conn) + for db_index in Namespace.get_non_host_db_indexes(dbs): + if_br_oid_map_ns = port_util.get_bridge_port_map(dbs[db_index]) if_br_oid_map.update(if_br_oid_map_ns) return if_br_oid_map @staticmethod def dbs_get_vlan_id_from_bvid(dbs, bvid): - for db_conn in Namespace.get_non_host_dbs(dbs): - db_conn.connect('ASIC_DB') - vlan_obj = db_conn.keys('ASIC_DB', "ASIC_STATE:SAI_OBJECT_TYPE_VLAN:" + bvid) + for db_index in Namespace.get_non_host_db_indexes(dbs): + dbs[db_index].connect('ASIC_DB') + vlan_obj = dbs[db_index].keys('ASIC_DB', "ASIC_STATE:SAI_OBJECT_TYPE_VLAN:" + bvid) if vlan_obj is not None: - return port_util.get_vlan_id_from_bvid(db_conn, bvid) + return port_util.get_vlan_id_from_bvid(dbs[db_index], bvid) diff --git a/src/sonic_ax_impl/mibs/ieee802_1ab.py b/src/sonic_ax_impl/mibs/ieee802_1ab.py index 6b36ff866..942043f36 100644 --- a/src/sonic_ax_impl/mibs/ieee802_1ab.py +++ b/src/sonic_ax_impl/mibs/ieee802_1ab.py @@ -111,7 +111,10 @@ def reinit_data(self): """ # establish connection to application database. Namespace.connect_all_dbs(self.db_conn, mibs.APPL_DB) - self.loc_chassis_data = Namespace.dbs_get_all(self.db_conn, mibs.APPL_DB, mibs.LOC_CHASSIS_TABLE) + for db in self.db_conn: + loc_chassis_data_ns = db.get_all(mibs.APPL_DB, mibs.LOC_CHASSIS_TABLE) + if loc_chassis_data_ns is not None: + self.loc_chassis_data.update(loc_chassis_data_ns) self.loc_chassis_data[b'lldp_loc_sys_cap_supported'] = parse_sys_capability(self.loc_chassis_data[b'lldp_loc_sys_cap_supported']) self.loc_chassis_data[b'lldp_loc_sys_cap_enabled'] = parse_sys_capability(self.loc_chassis_data[b'lldp_loc_sys_cap_enabled']) def update_data(self): @@ -158,6 +161,9 @@ def __init__(self): self.loc_port_data = {} self.pubsub = [None] * len(self.db_conn) + # map of if_idx/oid and db index + self.if_oid_namespace = {} + def reinit_data(self): """ Subclass update interface information @@ -166,7 +172,8 @@ def reinit_data(self): self.if_alias_map, \ self.if_id_map, \ self.oid_sai_map, \ - self.oid_name_map = Namespace.init_namespace_sync_d_interface_tables(self.db_conn) + self.oid_name_map, \ + self.if_oid_namespace = Namespace.init_namespace_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]) @@ -174,18 +181,22 @@ def reinit_data(self): # merge dataplane and mgmt ports self.oid_name_map.update(self.mgmt_oid_name_map) self.if_alias_map.update(self.mgmt_alias_map) + """ + mgmt interface idx will be mapped to host db or the first db index. + """ + self.if_oid_namespace.update(dict.fromkeys(self.mgmt_oid_name_map.keys(), 0)) 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.update_interface_data(if_name, self.if_oid_namespace[if_oid]) 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 _get_if_entry(self, if_name): + def _get_if_entry(self, if_name, db_index): if_table = "" # Once PORT_TABLE will be moved to CONFIG DB @@ -195,18 +206,19 @@ def _get_if_entry(self, if_name): if_table = mibs.if_entry_table(if_name) elif if_name in self.mgmt_oid_name_map.values(): if_table = mibs.mgmt_if_entry_table(if_name) + db_index = 0 db = mibs.CONFIG_DB else: return None - return Namespace.dbs_get_all(self.db_conn, db, if_table, blocking=True) + return self.db_conn[db_index].get_all(db, if_table, blocking=True) - def update_interface_data(self, if_name): + def update_interface_data(self, if_name, db_index): """ Update data from the DB for a single interface """ - loc_port_kvs = self._get_if_entry(if_name) + loc_port_kvs = self._get_if_entry(if_name, db_index) if not loc_port_kvs: return self.loc_port_data.update({if_name: loc_port_kvs}) @@ -221,7 +233,7 @@ def get_next(self, sub_id): return None return self.if_range[right] - def _update_per_namespace_data(self, pubsub): + def _update_per_namespace_data(self, pubsub, db_index): """ Listen to updates in APP DB, update local cache """ @@ -232,14 +244,14 @@ def _update_per_namespace_data(self, pubsub): break if b"set" in data: - self.update_interface_data(interface.encode()) + self.update_interface_data(interface.encode(), db_index) def update_data(self): for i in range(len(self.db_conn)): if not self.pubsub[i]: pattern = mibs.lldp_entry_table(b'*') self.pubsub[i] = mibs.get_redis_pubsub(self.db_conn[i], self.db_conn[i].APPL_DB, pattern) - self._update_per_namespace_data(self.pubsub[i]) + self._update_per_namespace_data(self.pubsub[i], i) def local_port_num(self, sub_id): if len(sub_id) == 0: @@ -393,6 +405,9 @@ def __init__(self): # { sai_id -> { 'counter': 'value' } } self.lldp_counters = {} + # map of if_idx/oid and db index + self.if_oid_namespace = {} + def reinit_data(self): """ Subclass update interface information @@ -401,9 +416,14 @@ def reinit_data(self): self.if_alias_map, \ self.if_id_map, \ self.oid_sai_map, \ - self.oid_name_map = Namespace.init_namespace_sync_d_interface_tables(self.db_conn) + self.oid_name_map, \ + self.if_oid_namespace = Namespace.init_namespace_sync_d_interface_tables(self.db_conn) self.mgmt_oid_name_map, _ = mibs.init_mgmt_interface_tables(self.db_conn[0]) + """ + mgmt interface idx will be mapped to host db or the first db index. + """ + self.if_oid_namespace.update(dict.fromkeys(self.mgmt_oid_name_map.keys(), 0)) self.oid_name_map.update(self.mgmt_oid_name_map) @@ -422,11 +442,13 @@ def update_data(self): Subclass update data routine. Updates available LLDP counters. """ # establish connection to application database. + Namespace.connect_all_dbs(self.db_conn, mibs.APPL_DB) 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)) + db_index = self.if_oid_namespace[if_oid] + lldp_kvs = self.db_conn[db_index].get_all(mibs.APPL_DB, mibs.lldp_entry_table(if_name)) if not lldp_kvs: continue try: @@ -494,8 +516,12 @@ def __init__(self): self.mgmt_ip_str = None self.pubsub = [None] * len(self.db_conn) + # map of if_idx/oid and db index + self.if_oid_namespace = {} + 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)) + db_index = self.if_oid_namespace[if_oid] + lldp_kvs = self.db_conn[db_index].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 @@ -561,11 +587,15 @@ def reinit_data(self): """ Subclass reinit data routine. """ - _, _, _, _, self.oid_name_map = Namespace.init_namespace_sync_d_interface_tables(self.db_conn) + _, _, _, _, self.oid_name_map, self.if_oid_namespace = Namespace.init_namespace_sync_d_interface_tables(self.db_conn) self.mgmt_oid_name_map, _ = mibs.init_mgmt_interface_tables(self.db_conn[0]) self.oid_name_map.update(self.mgmt_oid_name_map) + """ + mgmt interface idx will be mapped to host db or the first db index. + """ + self.if_oid_namespace.update(dict.fromkeys(self.mgmt_oid_name_map.keys(), 0)) # establish connection to application database. Namespace.connect_all_dbs(self.db_conn, mibs.APPL_DB) diff --git a/src/sonic_ax_impl/mibs/ietf/rfc1213.py b/src/sonic_ax_impl/mibs/ietf/rfc1213.py index 6333b966e..3e99a974a 100644 --- a/src/sonic_ax_impl/mibs/ietf/rfc1213.py +++ b/src/sonic_ax_impl/mibs/ietf/rfc1213.py @@ -108,7 +108,8 @@ def update_data(self): self.nexthop_map = {} self.route_list = [] - route_entries = Namespace.dbs_keys(self.db_conn, mibs.APPL_DB, "ROUTE_TABLE:*") + Namespace.connect_all_dbs(self.db_conn, mibs.APPL_DB) + route_entries = Namespace.dbs_keys_namespace(self.db_conn, mibs.APPL_DB, "ROUTE_TABLE:*") if not route_entries: return @@ -117,7 +118,8 @@ def update_data(self): ipnstr = routestr[len("ROUTE_TABLE:"):] if ipnstr == "0.0.0.0/0": ipn = ipaddress.ip_network(ipnstr) - ent = Namespace.dbs_get_all(self.db_conn, mibs.APPL_DB, routestr, blocking=True) + db_index = route_entries[route_entry] + ent = self.db_conn[db_index].get_all(mibs.APPL_DB, routestr, blocking=True) nexthops = ent[b"nexthop"].decode() for nh in nexthops.split(','): # TODO: if ipn contains IP range, create more sub_id here @@ -154,7 +156,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 = {} @@ -177,6 +179,12 @@ def __init__(self): self.oid_name_map = {} self.rif_counters = {} + # map of if_idx/oid and db instance + self.if_oid_namespace = {} + self.oid_lag_namespace = {} + self.vlan_oid_namespace = {} + self.port_namespace = {} + def reinit_data(self): """ Subclass update interface information @@ -185,7 +193,8 @@ def reinit_data(self): self.if_alias_map, \ self.if_id_map, \ self.oid_sai_map, \ - self.oid_name_map = Namespace.init_namespace_sync_d_interface_tables(self.db_conn) + self.oid_name_map, \ + self.if_oid_namespace = Namespace.init_namespace_sync_d_interface_tables(self.db_conn) """ db_conn - will have db_conn to all namespace DBs and global db. First db in the list is global db. @@ -193,13 +202,19 @@ def reinit_data(self): """ self.mgmt_oid_name_map, \ self.mgmt_alias_map = mibs.init_mgmt_interface_tables(self.db_conn[0]) + """ + mgmt interface idx will be mapped to host db or the first db instance. + """ + self.if_oid_namespace.update(dict.fromkeys(self.mgmt_oid_name_map.keys(), 0)) self.vlan_name_map, \ self.vlan_oid_sai_map, \ - self.vlan_oid_name_map = Namespace.init_namespace_sync_d_vlan_tables(self.db_conn) + self.vlan_oid_name_map, \ + self.vlan_oid_namespace = Namespace.init_namespace_sync_d_vlan_tables(self.db_conn) self.rif_port_map, \ - self.port_rif_map = Namespace.init_namespace_sync_d_rif_tables(self.db_conn) + self.port_rif_map, \ + self.port_namespace = Namespace.init_namespace_sync_d_rif_tables(self.db_conn) def update_data(self): """ @@ -207,22 +222,26 @@ def update_data(self): 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} + {self.oid_sai_map[if_idx]: self.db_conn[self.if_oid_namespace[if_idx]].get_all(mibs.COUNTERS_DB, mibs.counter_table(self.oid_sai_map[if_idx]), blocking=True) + for if_idx in self.oid_sai_map} - rif_sai_ids = list(self.rif_port_map) + list(self.vlan_name_map) + for sai_id in self.rif_port_map: + db_index = self.port_namespace[sai_id] + self.rif_counters[sai_id] = self.db_conn[db_index].get_all(mibs.COUNTERS_DB, mibs.counter_table(sai_id), blocking=True) - self.rif_counters = \ - {sai_id: Namespace.dbs_get_all(self.db_conn, mibs.COUNTERS_DB, mibs.counter_table(sai_id), blocking=True) - for sai_id in rif_sai_ids} + for vlan_oid in self.vlan_oid_namespace: + db_index = self.vlan_oid_namespace[vlan_oid] + sai_id = self.vlan_oid_sai_map[vlan_oid] + self.rif_counters[sai_id] = self.db_conn[db_index].get_all(mibs.COUNTERS_DB, mibs.counter_table(sai_id), blocking=True) - if self.rif_counters: + if self.rif_counters: self.aggregate_counters() self.lag_name_if_name_map, \ self.if_name_lag_name_map, \ self.oid_lag_name_map, \ - self.lag_sai_map = Namespace.init_namespace_sync_d_lag_tables(self.db_conn) + self.lag_sai_map, \ + self.oid_lag_namespace = Namespace.init_namespace_sync_d_lag_tables(self.db_conn) self.if_range = sorted(list(self.oid_sai_map.keys()) + list(self.oid_lag_name_map.keys()) + @@ -377,17 +396,20 @@ def _get_if_entry(self, sub_id): db = mibs.APPL_DB if oid in self.oid_lag_name_map: if_table = mibs.lag_entry_table(self.oid_lag_name_map[oid]) + db_index = self.oid_lag_namespace[oid] elif oid in self.mgmt_oid_name_map: if_table = mibs.mgmt_if_entry_table(self.mgmt_oid_name_map[oid]) + db_index = 0 db = mibs.CONFIG_DB elif oid in self.vlan_oid_name_map: if_table = mibs.vlan_entry_table(self.vlan_oid_name_map[oid]) elif oid in self.oid_name_map: if_table = mibs.if_entry_table(self.oid_name_map[oid]) + db_index = self.if_oid_namespace[oid] else: return None - return Namespace.dbs_get_all(self.db_conn, db, if_table, blocking=True) + return self.db_conn[db_index].get_all(db, if_table, blocking=True) def _get_if_entry_state_db(self, sub_id): """ @@ -406,7 +428,7 @@ def _get_if_entry_state_db(self, sub_id): else: return None - return Namespace.dbs_get_all(self.db_conn, db, if_table, blocking=False) + return self.db_conn[0].get_all(db, if_table, blocking=False) def _get_status(self, sub_id, key): """ diff --git a/src/sonic_ax_impl/mibs/ietf/rfc2737.py b/src/sonic_ax_impl/mibs/ietf/rfc2737.py index b503967d1..1cc2466f6 100644 --- a/src/sonic_ax_impl/mibs/ietf/rfc2737.py +++ b/src/sonic_ax_impl/mibs/ietf/rfc2737.py @@ -152,7 +152,7 @@ def reinit_data(self): self.physical_model_name_map = {} # update interface maps - _, self.if_alias_map, _, _, _ = \ + _, self.if_alias_map, _, _, _, _ = \ Namespace.init_namespace_sync_d_interface_tables(Namespace.init_namespace_dbs()) device_metadata = mibs.get_device_metadata(self.statedb[0]) @@ -168,20 +168,20 @@ def reinit_data(self): self.physical_serial_number_map[chassis_sub_id] = chassis_serial_number # retrieve the initial list of transceivers that are present in the system - transceiver_info = Namespace.dbs_keys(self.statedb, mibs.STATE_DB, self.TRANSCEIVER_KEY_PATTERN) + transceiver_info = Namespace.dbs_keys_namespace(self.statedb, mibs.STATE_DB, self.TRANSCEIVER_KEY_PATTERN) if transceiver_info: - self.transceiver_entries = [entry.decode() \ + self.transceiver_entries = [(entry.decode(), transceiver_info[entry]) \ for entry in transceiver_info] else: - self.transceiver_entries = [] + self.transceiver_entries = {} # update cache with initial data - for transceiver_entry in self.transceiver_entries: + for transceiver_entry, namespace in self.transceiver_entries: # extract interface name interface = transceiver_entry.split(mibs.TABLE_NAME_SEPARATOR_VBAR)[-1] - self._update_transceiver_cache(interface) + self._update_transceiver_cache(interface, namespace) - def _update_per_namespace_data(self, pubsub): + def _update_per_namespace_data(self, pubsub, db_index): """ Update cache. Here we listen to changes in STATE_DB TRANSCEIVER_INFO table @@ -213,7 +213,7 @@ def _update_per_namespace_data(self, pubsub): continue if b"set" in data: - self._update_transceiver_cache(interface) + self._update_transceiver_cache(interface, db_index) elif b"del" in data: # remove deleted transceiver remove_sub_ids = [mibs.get_transceiver_sub_id(ifindex)] @@ -233,9 +233,9 @@ def update_data(self): if not self.pubsub[i]: pattern = self.TRANSCEIVER_KEY_PATTERN self.pubsub[i] = mibs.get_redis_pubsub(self.statedb[i], self.statedb[i].STATE_DB, pattern) - self._update_per_namespace_data(self.pubsub[i]) + self._update_per_namespace_data(self.pubsub[i], i) - def _update_transceiver_cache(self, interface): + def _update_transceiver_cache(self, interface, db_index): """ Update data for single transceiver :param: interface: Interface name associated with transceiver @@ -252,7 +252,7 @@ def _update_transceiver_cache(self, interface): insort_right(self.physical_entities, sub_id) # get transceiver information from transceiver info entry in STATE DB - transceiver_info = Namespace.dbs_get_all(self.statedb, mibs.STATE_DB, + transceiver_info = self.statedb[db_index].get_all(mibs.STATE_DB, mibs.transceiver_info_table(interface)) if not transceiver_info: @@ -274,9 +274,9 @@ def _update_transceiver_cache(self, interface): self.physical_description_map[sub_id] = get_transceiver_description(sfp_type, ifalias) # update transceiver sensor cache - self._update_transceiver_sensor_cache(interface) + self._update_transceiver_sensor_cache(interface, db_index) - def _update_transceiver_sensor_cache(self, interface): + def _update_transceiver_sensor_cache(self, interface, db_index): """ Update sensor data for single transceiver :param: interface: Interface name associated with transceiver @@ -286,7 +286,7 @@ def _update_transceiver_sensor_cache(self, interface): ifindex = port_util.get_index_from_str(interface) # get transceiver sensors from transceiver dom entry in STATE DB - transceiver_dom_entry = Namespace.dbs_get_all(self.statedb, mibs.STATE_DB, + transceiver_dom_entry = self.statedb[db_index].get_all(mibs.STATE_DB, mibs.transceiver_dom_table(interface)) if not transceiver_dom_entry: diff --git a/src/sonic_ax_impl/mibs/ietf/rfc2863.py b/src/sonic_ax_impl/mibs/ietf/rfc2863.py index 6bec4cbdf..741295be2 100644 --- a/src/sonic_ax_impl/mibs/ietf/rfc2863.py +++ b/src/sonic_ax_impl/mibs/ietf/rfc2863.py @@ -67,6 +67,10 @@ def __init__(self): self.if_name_lag_name_map = {} self.oid_lag_name_map = {} + # map of if_idx/oid and db instance + self.if_oid_namespace = {} + self.oid_lag_namespace = {} + def reinit_data(self): """ Subclass update interface information @@ -75,11 +79,13 @@ def reinit_data(self): self.if_alias_map, \ self.if_id_map, \ self.oid_sai_map, \ - self.oid_name_map = Namespace.init_namespace_sync_d_interface_tables(self.db_conn) + self.oid_name_map, \ + self.if_oid_namespace = Namespace.init_namespace_sync_d_interface_tables(self.db_conn) self.lag_name_if_name_map, \ self.if_name_lag_name_map, \ - self.oid_lag_name_map, _ = Namespace.init_namespace_sync_d_lag_tables(self.db_conn) + self.oid_lag_name_map, _,\ + self.oid_lag_namespace = Namespace.init_namespace_sync_d_lag_tables(self.db_conn) """ db_conn - will have db_conn to all namespace DBs and global db. First db in the list is global db. @@ -87,6 +93,11 @@ def reinit_data(self): """ self.mgmt_oid_name_map, \ self.mgmt_alias_map = mibs.init_mgmt_interface_tables(self.db_conn[0]) + """ + mgmt interface idx will be mapped to host db or the first db instance. + """ + self.if_oid_namespace.update(dict.fromkeys(self.mgmt_oid_name_map.keys(), 0)) + self.if_range = sorted(list(self.oid_sai_map.keys()) + list(self.oid_lag_name_map.keys()) + @@ -98,10 +109,9 @@ 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} - + self.if_counters = \ + {self.oid_sai_map[if_idx]: self.db_conn[self.if_oid_namespace[if_idx]].get_all(mibs.COUNTERS_DB, mibs.counter_table(self.oid_sai_map[if_idx]), blocking=True) + for if_idx in self.oid_sai_map} def get_next(self, sub_id): """ @@ -214,15 +224,18 @@ def _get_if_entry(self, sub_id): db = mibs.APPL_DB if oid in self.oid_lag_name_map: if_table = mibs.lag_entry_table(self.oid_lag_name_map[oid]) + db_index = self.oid_lag_namespace[oid] elif oid in self.mgmt_oid_name_map: if_table = mibs.mgmt_if_entry_table(self.mgmt_oid_name_map[oid]) + db_index = 0 db = mibs.CONFIG_DB elif oid in self.oid_name_map: if_table = mibs.if_entry_table(self.oid_name_map[oid]) + db_index = self.if_oid_namespace[oid] else: return None - return Namespace.dbs_get_all(self.db_conn, db, if_table, blocking=True) + return self.db_conn[db_index].get_all(db, if_table, blocking=True) def get_high_speed(self, sub_id): """ diff --git a/src/sonic_ax_impl/mibs/ietf/rfc3433.py b/src/sonic_ax_impl/mibs/ietf/rfc3433.py index 4e97b2bab..4576d36ae 100644 --- a/src/sonic_ax_impl/mibs/ietf/rfc3433.py +++ b/src/sonic_ax_impl/mibs/ietf/rfc3433.py @@ -277,10 +277,10 @@ def reinit_data(self): self.ent_phy_sensor_value_map = {} self.ent_phy_sensor_oper_state_map = {} - transceiver_dom_encoded = Namespace.dbs_keys(self.statedb, mibs.STATE_DB, + transceiver_dom_encoded = Namespace.dbs_keys_namespace(self.statedb, mibs.STATE_DB, self.TRANSCEIVER_DOM_KEY_PATTERN) if transceiver_dom_encoded: - self.transceiver_dom = [entry.decode() for entry in transceiver_dom_encoded] + self.transceiver_dom = [(entry.decode(), transceiver_dom_encoded[entry]) for entry in transceiver_dom_encoded] def update_data(self): """ @@ -293,7 +293,7 @@ def update_data(self): return # update transceiver sensors cache - for transceiver_dom_entry in self.transceiver_dom: + for transceiver_dom_entry, db_index in self.transceiver_dom: # extract interface name interface = transceiver_dom_entry.split(mibs.TABLE_NAME_SEPARATOR_VBAR)[-1] ifindex = port_util.get_index_from_str(interface) @@ -305,7 +305,7 @@ def update_data(self): continue # get transceiver sensors from transceiver dom entry in STATE DB - transceiver_dom_entry_data = Namespace.dbs_get_all(self.statedb, mibs.STATE_DB, + transceiver_dom_entry_data = self.statedb[db_index].get_all(mibs.STATE_DB, transceiver_dom_entry) if not transceiver_dom_entry_data: diff --git a/src/sonic_ax_impl/mibs/ietf/rfc4292.py b/src/sonic_ax_impl/mibs/ietf/rfc4292.py index c004338bb..ba8b6b66c 100644 --- a/src/sonic_ax_impl/mibs/ietf/rfc4292.py +++ b/src/sonic_ax_impl/mibs/ietf/rfc4292.py @@ -49,7 +49,8 @@ def update_data(self): self.route_dest_list.append(sub_id) self.route_dest_map[sub_id] = self.loips[loip].packed - route_entries = Namespace.dbs_keys(self.db_conn, mibs.APPL_DB, "ROUTE_TABLE:*") + Namespace.connect_all_dbs(self.db_conn, mibs.APPL_DB) + route_entries = Namespace.dbs_keys_namespace(self.db_conn, mibs.APPL_DB, "ROUTE_TABLE:*") if not route_entries: return @@ -58,7 +59,8 @@ def update_data(self): ipnstr = routestr[len("ROUTE_TABLE:"):] if ipnstr == "0.0.0.0/0": ipn = ipaddress.ip_network(ipnstr) - ent = Namespace.dbs_get_all(self.db_conn, mibs.APPL_DB, routestr, blocking=True) + namespace = route_entries[route_entry] + ent = self.db_conn[namespace].get_all(mibs.APPL_DB, routestr, blocking=True) nexthops = ent[b"nexthop"].decode() ifnames = ent[b"ifname"].decode() for nh, ifn in zip(nexthops.split(','), ifnames.split(',')): diff --git a/src/sonic_ax_impl/mibs/ietf/rfc4363.py b/src/sonic_ax_impl/mibs/ietf/rfc4363.py index e9aa46af6..f831feecf 100644 --- a/src/sonic_ax_impl/mibs/ietf/rfc4363.py +++ b/src/sonic_ax_impl/mibs/ietf/rfc4363.py @@ -32,7 +32,7 @@ def fdb_vlanmac(self, fdb): vlan_id = Namespace.dbs_get_vlan_id_from_bvid(self.db_conn, fdb["bvid"]) self.bvid_vlan_map[fdb["bvid"]] = vlan_id return (int(vlan_id),) + mac_decimals(fdb["mac"]) - + def reinit_data(self): """ Subclass update interface information @@ -41,7 +41,7 @@ def reinit_data(self): self.if_alias_map, \ self.if_id_map, \ self.oid_sai_map, \ - self.oid_name_map = Namespace.init_namespace_sync_d_interface_tables(self.db_conn) + self.oid_name_map, _ = Namespace.init_namespace_sync_d_interface_tables(self.db_conn) self.if_bpid_map = Namespace.dbs_get_bridge_port_map(self.db_conn, mibs.ASIC_DB) self.bvid_vlan_map.clear() @@ -54,7 +54,8 @@ def update_data(self): 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:*") + Namespace.connect_all_dbs(self.db_conn, mibs.ASIC_DB) + fdb_strings = Namespace.dbs_keys_namespace(self.db_conn, mibs.ASIC_DB, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:*") if not fdb_strings: return @@ -66,7 +67,8 @@ def update_data(self): mibs.logger.error("SyncD 'ASIC_DB' includes invalid FDB_ENTRY '{}': {}.".format(fdb_str, e)) break - ent = Namespace.dbs_get_all(self.db_conn, mibs.ASIC_DB, s, blocking=True) + db_index = fdb_strings[s] + ent = self.db_conn[db_index].get_all(mibs.ASIC_DB, s, blocking=True) # Example output: oid:0x3a000000000608 bridge_port_id = ent[b"SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID"][6:] if bridge_port_id not in self.if_bpid_map: diff --git a/src/sonic_ax_impl/mibs/vendor/cisco/ciscoPfcExtMIB.py b/src/sonic_ax_impl/mibs/vendor/cisco/ciscoPfcExtMIB.py index e46ae902d..585629b50 100644 --- a/src/sonic_ax_impl/mibs/vendor/cisco/ciscoPfcExtMIB.py +++ b/src/sonic_ax_impl/mibs/vendor/cisco/ciscoPfcExtMIB.py @@ -28,6 +28,9 @@ def __init__(self): self.if_counters = {} self.if_range = [] + self.if_oid_namespace = {} + self.oid_lag_namespace = {} + def reinit_data(self): """ Subclass update interface information @@ -36,7 +39,8 @@ def reinit_data(self): self.if_alias_map, \ self.if_id_map, \ self.oid_sai_map, \ - self.oid_name_map = Namespace.init_namespace_sync_d_interface_tables(self.db_conn) + self.oid_name_map, \ + self.if_oid_namespace = Namespace.init_namespace_sync_d_interface_tables(self.db_conn) self.update_data() @@ -46,12 +50,13 @@ def update_data(self): 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} + {self.oid_sai_map[if_idx]: self.db_conn[self.if_oid_namespace[if_idx]].get_all(mibs.COUNTERS_DB, mibs.counter_table(self.oid_sai_map[if_idx]), blocking=True) + for if_idx in self.oid_sai_map} self.lag_name_if_name_map, \ self.if_name_lag_name_map, \ - self.oid_lag_name_map, _ = Namespace.init_namespace_sync_d_lag_tables(self.db_conn) + self.oid_lag_name_map, _, \ + self.oid_lag_namespace = Namespace.init_namespace_sync_d_lag_tables(self.db_conn) self.if_range = sorted(list(self.oid_sai_map.keys()) + list(self.oid_lag_name_map.keys())) self.if_range = [(i,) for i in self.if_range] diff --git a/src/sonic_ax_impl/mibs/vendor/cisco/ciscoSwitchQosMIB.py b/src/sonic_ax_impl/mibs/vendor/cisco/ciscoSwitchQosMIB.py index 274b71695..370ea96f2 100644 --- a/src/sonic_ax_impl/mibs/vendor/cisco/ciscoSwitchQosMIB.py +++ b/src/sonic_ax_impl/mibs/vendor/cisco/ciscoSwitchQosMIB.py @@ -66,6 +66,9 @@ def __init__(self): self.queue_type_map = {} + self.queue_type_map = {} + self.if_oid_namespace = {} + def reinit_data(self): """ Subclass update interface information @@ -74,12 +77,17 @@ def reinit_data(self): self.if_alias_map, \ self.if_id_map, \ self.oid_sai_map, \ - self.oid_name_map = Namespace.init_namespace_sync_d_interface_tables(self.db_conn) + self.oid_name_map, \ + self.if_oid_namespace = Namespace.init_namespace_sync_d_interface_tables(self.db_conn) + self.port_queues_map, self.queue_stat_map, self.port_queue_list_map = \ Namespace.init_namespace_sync_d_queue_tables(self.db_conn) - self.queue_type_map = Namespace.dbs_get_all(self.db_conn, mibs.COUNTERS_DB, "COUNTERS_QUEUE_TYPE_MAP", blocking=False) + for db_index in Namespace.get_non_host_db_indexes(self.db_conn): + queue_type_map_ns = self.db_conn[db_index].get_all(mibs.COUNTERS_DB, "COUNTERS_QUEUE_TYPE_MAP", blocking=False) + if queue_type_map_ns is not None: + self.queue_type_map.update(queue_type_map_ns) self.update_data() @@ -90,7 +98,9 @@ def update_data(self): """ for queue_key, sai_id in self.port_queues_map.items(): queue_stat_name = mibs.queue_table(sai_id) - queue_stat = Namespace.dbs_get_all(self.db_conn, mibs.COUNTERS_DB, queue_stat_name, blocking=False) + if_idx = mibs.get_port_index_from_queue_key(queue_key) + db_index = self.if_oid_namespace[if_idx] + queue_stat = self.db_conn[db_index].get_all(mibs.COUNTERS_DB, queue_stat_name, blocking=False) if queue_stat is not None: self.queue_stat_map[queue_stat_name] = queue_stat diff --git a/tests/namespace/test_mibs.py b/tests/namespace/test_mibs.py index bf94fb4d6..0b4868cfb 100644 --- a/tests/namespace/test_mibs.py +++ b/tests/namespace/test_mibs.py @@ -21,7 +21,8 @@ def test_init_namespace_sync_d_lag_tables(self): lag_name_if_name_map, \ if_name_lag_name_map, \ oid_lag_name_map, \ - lag_sai_map = Namespace.init_namespace_sync_d_lag_tables(dbs) + lag_sai_map, \ + self.oid_lag_namespace = Namespace.init_namespace_sync_d_lag_tables(dbs) #PortChannel in asic0 Namespace self.assertTrue(b"PortChannel01" in lag_name_if_name_map) self.assertTrue(b"Ethernet-BP0" in lag_name_if_name_map[b"PortChannel01"])