Skip to content

Commit

Permalink
[Namespace]: Fix interface counters in RFC 1213 for
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
SuvarnaMeenakshi committed Jul 13, 2020
1 parent bbde44c commit 8ed0978
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 30 deletions.
28 changes: 20 additions & 8 deletions src/sonic_ax_impl/mibs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,11 +300,17 @@ def init_sync_d_rif_tables(db_conn):

if not rif_port_map:
return {}, {}
port_rif_map = {port: rif for rif, port in rif_port_map.items()}
logger.debug("Rif port map:\n" + pprint.pformat(rif_port_map, indent=2))
rif_port_map_updated = {}
port_rif_map = {}
for rif, port in rif_port_map.items():
rif_key = get_sai_id_key(db_conn.namespace, rif)
port_key = get_sai_id_key(db_conn.namespace, port)
rif_port_map_updated[rif_key] = port_key
port_rif_map[port_key] = rif_key

return rif_port_map, port_rif_map
logger.debug("Rif port map:\n" + pprint.pformat(rif_port_map, indent=2))

return rif_port_map_updated, port_rif_map

def init_sync_d_vlan_tables(db_conn):
"""
Expand All @@ -314,22 +320,28 @@ def init_sync_d_vlan_tables(db_conn):

vlan_name_map = port_util.get_vlan_interface_oid_map(db_conn)

vlan_name_map_updated = {}

for sai_id in vlan_name_map:
sai_id_key = get_sai_id_key(db_conn.namespace, sai_id)
vlan_name_map_updated[sai_id_key] = vlan_name_map[sai_id]

logger.debug("Vlan oid map:\n" + pprint.pformat(vlan_name_map, indent=2))

# { OID -> sai_id }
oid_sai_map = {get_index(if_name): sai_id for sai_id, if_name in vlan_name_map.items()
oid_sai_map = {get_index(if_name): sai_id for sai_id, if_name in vlan_name_map_updated.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 sai_id, if_name in vlan_name_map.items()
oid_name_map = {get_index(if_name): if_name for sai_id, if_name in vlan_name_map_updated.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 name map:\n" + pprint.pformat(oid_name_map, indent=2))

return vlan_name_map, oid_sai_map, oid_name_map
return vlan_name_map_updated, oid_sai_map, oid_name_map


def init_sync_d_lag_tables(db_conn):
Expand All @@ -346,7 +358,7 @@ def init_sync_d_lag_tables(db_conn):
if_name_lag_name_map = {}
# { OID -> lag_name (SONiC) }
oid_lag_name_map = {}
# { lag_name (SONiC) -> lag_oid (SAI) }
# { lag_name (SONiC) -> namespace: lag_oid (SAI) }
lag_sai_map = {}

lag_entries = db_conn.keys(APPL_DB, b"LAG_TABLE:*")
Expand All @@ -355,7 +367,7 @@ def init_sync_d_lag_tables(db_conn):
return lag_name_if_name_map, if_name_lag_name_map, oid_lag_name_map, lag_sai_map

lag_sai_map = db_conn.get_all(COUNTERS_DB, b"COUNTERS_LAG_NAME_MAP")
lag_sai_map = {name: sai_id.lstrip(b"oid:0x") for name, sai_id in lag_sai_map.items()}
lag_sai_map = {name: get_sai_id_key(db_conn.namespace, sai_id.lstrip(b"oid:0x")) for name, sai_id in lag_sai_map.items()}

for lag_entry in lag_entries:
lag_name = lag_entry[len(b"LAG_TABLE:"):]
Expand Down
39 changes: 19 additions & 20 deletions src/sonic_ax_impl/mibs/ietf/rfc1213.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from ax_interface.mib import MIBMeta, ValueType, MIBUpdater, MIBEntry, SubtreeMIBEntry, OverlayAdpaterMIBEntry, OidMIBEntry
from ax_interface.encodings import ObjectIdentifier
from ax_interface.util import mac_decimals, ip2tuple_v4
from swsssdk.port_util import get_index_from_str

@unique
class DbTables(int, Enum):
Expand Down Expand Up @@ -154,7 +155,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 @@ -176,6 +177,7 @@ def __init__(self):
self.oid_sai_map = {}
self.oid_name_map = {}
self.rif_counters = {}
self.namespace_db_map = Namespace.get_namespace_db_map(self.db_conn)

def reinit_data(self):
"""
Expand Down Expand Up @@ -206,17 +208,19 @@ 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 = get_index_from_str(self.if_id_map[sai_id_key].decode())
self.if_counters[if_idx] = self.namespace_db_map[namespace].get_all(mibs.COUNTERS_DB, \
mibs.counter_table(sai_id), blocking=True)

rif_sai_ids = list(self.rif_port_map) + list(self.vlan_name_map)

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 sai_id_key in rif_sai_ids:
namespace, sai_id = mibs.split_sai_id_key(sai_id_key)
self.rif_counters[sai_id_key] = self.namespace_db_map[namespace].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, \
Expand Down Expand Up @@ -282,18 +286,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 = ''
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]
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 All @@ -311,16 +308,18 @@ def aggregate_counters(self):
"""
for rif_sai_id, port_sai_id in self.rif_port_map.items():
if port_sai_id in self.if_id_map:
if_idx = get_index_from_str(self.if_id_map[port_sai_id].decode())
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]) + \
self.if_counters[if_idx][port_counter_name] = \
int(self.if_counters[if_idx][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] = \
if_idx = get_index_from_str(self.vlan_name_map[vlan_sai_id].decode())
self.if_counters.setdefault(if_idx, {})
self.if_counters[if_idx][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))
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 8ed0978

Please sign in to comment.