Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Multi-asic]: Namespace support for LLDP and Sensor tables #131

Merged
merged 5 commits into from
May 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/sonic_ax_impl/mibs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,3 +571,22 @@ def init_namespace_sync_d_queue_tables(dbs):
port_queue_list_map.update(port_queue_list_map_ns)

return port_queues_map, queue_stat_map, port_queue_list_map

@staticmethod
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)
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.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)
81 changes: 45 additions & 36 deletions src/sonic_ax_impl/mibs/ieee802_1ab.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from swsssdk import port_util
from sonic_ax_impl import mibs, logger
from sonic_ax_impl.mibs import Namespace
from ax_interface import MIBMeta, SubtreeMIBEntry, MIBEntry, MIBUpdater, ValueType


Expand Down Expand Up @@ -102,16 +103,16 @@ class LLDPLocalSystemDataUpdater(MIBUpdater):
def __init__(self):
super().__init__()

self.db_conn = mibs.init_db()
self.db_conn = Namespace.init_namespace_dbs()
self.loc_chassis_data = {}

def reinit_data(self):
"""
Subclass update data routine.
"""
# establish connection to application database.
self.db_conn.connect(mibs.APPL_DB)
self.loc_chassis_data = self.db_conn.get_all(mibs.APPL_DB, mibs.LOC_CHASSIS_TABLE)
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)
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):
Expand Down Expand Up @@ -139,9 +140,9 @@ class LocPortUpdater(MIBUpdater):
def __init__(self):
super().__init__()

self.db_conn = mibs.init_db()
self.db_conn = Namespace.init_namespace_dbs()
# establish connection to application database.
self.db_conn.connect(mibs.APPL_DB)
Namespace.connect_all_dbs(self.db_conn, mibs.APPL_DB)
self.if_name_map = {}
self.if_alias_map = {}
self.if_id_map = {}
Expand All @@ -156,7 +157,7 @@ def __init__(self):
# cache of port data
# { if_name -> { 'key': 'value' } }
self.loc_port_data = {}
self.pubsub = None
self.pubsub = [None] * len(self.db_conn)

def reinit_data(self):
"""
Expand All @@ -166,10 +167,10 @@ def reinit_data(self):
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.oid_name_map = 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)
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)
Expand Down Expand Up @@ -199,7 +200,7 @@ def _get_if_entry(self, if_name):
else:
return None

return self.db_conn.get_all(db, if_table, blocking=True)
return Namespace.dbs_get_all(self.db_conn, db, if_table, blocking=True)

def update_interface_data(self, if_name):
"""
Expand All @@ -221,25 +222,29 @@ def get_next(self, sub_id):
return None
return self.if_range[right]

def update_data(self):
def _update_per_namespace_data(self, db_conn, pubsub):
"""
Listen to updates in APP DB, update local cache
"""
if not self.pubsub:
redis_client = self.db_conn.get_redis_client(self.db_conn.APPL_DB)
db = self.db_conn.get_dbid(self.db_conn.APPL_DB)
self.pubsub = redis_client.pubsub()
self.pubsub.psubscribe("__keyspace@{}__:{}".format(db, mibs.lldp_entry_table(b'*')))
if not pubsub:
redis_client = db_conn.get_redis_client(db_conn.APPL_DB)
db = db_conn.get_dbid(db_conn.APPL_DB)
pubsub = redis_client.pubsub()
pubsub.psubscribe("__keyspace@{}__:{}".format(db, mibs.lldp_entry_table(b'*')))

while True:
data, interface, if_id = poll_lldp_entry_updates(self.pubsub)
data, interface, if_id = poll_lldp_entry_updates(pubsub)

if not data:
break

if b"set" in data:
self.update_interface_data(interface.encode())

def update_data(self):
for i in range(len(self.db_conn)):
self._update_per_namespace_data(self.db_conn[i], self.pubsub[i])

def local_port_num(self, sub_id):
if len(sub_id) == 0:
return None
Expand Down Expand Up @@ -302,7 +307,7 @@ def reinit_data(self):
self.mgmt_ip_str = None

# establish connection to application database.
self.db_conn.connect(mibs.APPL_DB)
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:
Expand Down Expand Up @@ -377,7 +382,7 @@ class LLDPRemTableUpdater(MIBUpdater):
def __init__(self):
super().__init__()

self.db_conn = mibs.init_db()
self.db_conn = Namespace.init_namespace_dbs()
self.if_name_map = {}
self.if_alias_map = {}
self.if_id_map = {}
Expand All @@ -400,9 +405,9 @@ def reinit_data(self):
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.oid_name_map = Namespace.init_namespace_sync_d_interface_tables(self.db_conn)

self.mgmt_oid_name_map, _ = mibs.init_mgmt_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)

Expand All @@ -421,12 +426,11 @@ 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))
lldp_kvs = Namespace.dbs_get_all(self.db_conn, mibs.APPL_DB, mibs.lldp_entry_table(if_name))
if not lldp_kvs:
continue
try:
Expand Down Expand Up @@ -484,18 +488,18 @@ class LLDPRemManAddrUpdater(MIBUpdater):
def __init__(self):
super().__init__()

self.db_conn = mibs.init_db()
self.db_conn = Namespace.init_namespace_dbs()
# establish connection to application database.
self.db_conn.connect(self.db_conn.APPL_DB)
Namespace.connect_all_dbs(self.db_conn, mibs.APPL_DB)
self.if_range = []
self.mgmt_ips = {}
self.oid_name_map = {}
self.mgmt_oid_name_map = {}
self.mgmt_ip_str = None
self.pubsub = None
self.pubsub = [None] * len(self.db_conn)

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))
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
Expand Down Expand Up @@ -532,18 +536,18 @@ def update_rem_if_mgmt(self, if_oid, if_name):
return
self.if_range.sort()

def update_data(self):
def _update_per_namespace_data(self, db_conn, pubsub):
"""
Listen to updates in APP DB, update local cache
"""
if not self.pubsub:
redis_client = self.db_conn.get_redis_client(self.db_conn.APPL_DB)
db = self.db_conn.get_dbid(self.db_conn.APPL_DB)
self.pubsub = redis_client.pubsub()
self.pubsub.psubscribe("__keyspace@{}__:{}".format(db, mibs.lldp_entry_table(b'*')))
if not pubsub:
redis_client = db_conn.get_redis_client(db_conn.APPL_DB)
db = db_conn.get_dbid(db_conn.APPL_DB)
pubsub = redis_client.pubsub()
pubsub.psubscribe("__keyspace@{}__:{}".format(db, mibs.lldp_entry_table(b'*')))

while True:
data, interface, if_index = poll_lldp_entry_updates(self.pubsub)
data, interface, if_index = poll_lldp_entry_updates(pubsub)

if not data:
break
Expand All @@ -555,18 +559,23 @@ def update_data(self):
self.if_range = [sub_oid for sub_oid in self.if_range if sub_oid[0] != if_index]
self.update_rem_if_mgmt(if_index, interface.encode())

def update_data(self):
for i in range(len(self.db_conn)):
self._update_per_namespace_data(self.db_conn[i], self.pubsub[i])


def reinit_data(self):
"""
Subclass reinit data routine.
"""
_, _, _, _, self.oid_name_map = mibs.init_sync_d_interface_tables(self.db_conn)
_, _, _, _, self.oid_name_map = Namespace.init_namespace_sync_d_interface_tables(self.db_conn)

self.mgmt_oid_name_map, _ = mibs.init_mgmt_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)

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

self.if_range = []
self.mgmt_ips = {}
Expand Down
38 changes: 21 additions & 17 deletions src/sonic_ax_impl/mibs/ietf/rfc2737.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
from enum import Enum, unique
from bisect import bisect_right, insort_right

from swsssdk import SonicV2Connector, port_util
from swsssdk import port_util
from ax_interface import MIBMeta, MIBUpdater, ValueType, SubtreeMIBEntry

from sonic_ax_impl import mibs

from sonic_ax_impl.mibs import Namespace

@unique
class PhysicalClass(int, Enum):
Expand Down Expand Up @@ -120,8 +120,8 @@ class PhysicalTableMIBUpdater(MIBUpdater):
def __init__(self):
super().__init__()

self.statedb = SonicV2Connector()
self.statedb.connect(self.statedb.STATE_DB)
self.statedb = Namespace.init_namespace_dbs()
Namespace.connect_all_dbs(self.statedb, mibs.STATE_DB)

self.if_alias_map = {}

Expand All @@ -136,7 +136,7 @@ def __init__(self):
self.physical_mfg_name_map = {}
self.physical_model_name_map = {}

self.pubsub = None
self.pubsub = [None] * len(self.statedb)

def reinit_data(self):
"""
Expand All @@ -153,9 +153,9 @@ def reinit_data(self):

# update interface maps
_, self.if_alias_map, _, _, _ = \
mibs.init_sync_d_interface_tables(SonicV2Connector())
Namespace.init_namespace_sync_d_interface_tables(Namespace.init_namespace_dbs())

device_metadata = mibs.get_device_metadata(self.statedb)
device_metadata = mibs.get_device_metadata(self.statedb[0])
chassis_sub_id = (self.CHASSIS_ID, )
self.physical_entities = [chassis_sub_id]

Expand All @@ -168,7 +168,7 @@ 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 = self.statedb.keys(self.statedb.STATE_DB, self.TRANSCEIVER_KEY_PATTERN)
transceiver_info = Namespace.dbs_keys(self.statedb, mibs.STATE_DB, self.TRANSCEIVER_KEY_PATTERN)
if transceiver_info:
self.transceiver_entries = [entry.decode() \
for entry in transceiver_info]
Expand All @@ -181,7 +181,7 @@ def reinit_data(self):
interface = transceiver_entry.split(mibs.TABLE_NAME_SEPARATOR_VBAR)[-1]
self._update_transceiver_cache(interface)

def update_data(self):
def _update_per_namespace_data(self, statedb, pubsub):
"""
Update cache.
Here we listen to changes in STATE_DB TRANSCEIVER_INFO table
Expand All @@ -190,14 +190,14 @@ def update_data(self):

# This code is not executed in unit test, since mockredis
# does not support pubsub
if not self.pubsub:
redis_client = self.statedb.get_redis_client(self.statedb.STATE_DB)
db = self.statedb.get_dbid(self.statedb.STATE_DB)
self.pubsub = redis_client.pubsub()
self.pubsub.psubscribe("__keyspace@{}__:{}".format(db, self.TRANSCEIVER_KEY_PATTERN))
if not pubsub:
redis_client = statedb.get_redis_client(statedb.STATE_DB)
db = statedb.get_dbid(statedb.STATE_DB)
pubsub = redis_client.pubsub()
pubsub.psubscribe("__keyspace@{}__:{}".format(db, self.TRANSCEIVER_KEY_PATTERN))

while True:
msg = self.pubsub.get_message()
msg = pubsub.get_message()

if not msg:
break
Expand Down Expand Up @@ -232,6 +232,10 @@ def update_data(self):
if sub_id and sub_id in self.physical_entities:
self.physical_entities.remove(sub_id)

def update_data(self):
for i in range(len(self.statedb)):
self._update_per_namespace_data(self.statedb[i], self.pubsub[i])

def _update_transceiver_cache(self, interface):
"""
Update data for single transceiver
Expand All @@ -249,7 +253,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 = self.statedb.get_all(self.statedb.STATE_DB,
transceiver_info = Namespace.dbs_get_all(self.statedb, mibs.STATE_DB,
mibs.transceiver_info_table(interface))

if not transceiver_info:
Expand Down Expand Up @@ -283,7 +287,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 = self.statedb.get_all(self.statedb.STATE_DB,
transceiver_dom_entry = Namespace.dbs_get_all(self.statedb, mibs.STATE_DB,
mibs.transceiver_dom_table(interface))

if not transceiver_dom_entry:
Expand Down
Loading