Skip to content

Commit

Permalink
[Namespace]: Fix interface counters in RFC 1213 (sonic-net#145)
Browse files Browse the repository at this point in the history
* [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 <sumeenak@microsoft.com>
  • Loading branch information
SuvarnaMeenakshi authored Jul 22, 2020
1 parent c702a57 commit 166c221
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 19 deletions.
22 changes: 14 additions & 8 deletions src/sonic_ax_impl/mibs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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))

Expand Down
14 changes: 8 additions & 6 deletions src/sonic_ax_impl/mibs/ietf/rfc1213.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {}
Expand All @@ -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):
"""
Expand All @@ -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, \
Expand Down Expand Up @@ -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!
Expand Down
3 changes: 1 addition & 2 deletions src/sonic_ax_impl/mibs/ietf/rfc2863.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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)

Expand Down
2 changes: 1 addition & 1 deletion src/sonic_ax_impl/mibs/ietf/rfc4363.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
2 changes: 0 additions & 2 deletions tests/namespace/test_interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 166c221

Please sign in to comment.