diff --git a/src/sonic_ax_impl/mibs/ietf/rfc1213.py b/src/sonic_ax_impl/mibs/ietf/rfc1213.py index 75238b054..baa609d76 100644 --- a/src/sonic_ax_impl/mibs/ietf/rfc1213.py +++ b/src/sonic_ax_impl/mibs/ietf/rfc1213.py @@ -3,6 +3,7 @@ import socket from enum import unique, Enum from bisect import bisect_right +import os from sonic_ax_impl import mibs from sonic_ax_impl.mibs import Namespace @@ -184,6 +185,7 @@ class IpMib(metaclass=MIBMeta, prefix='.1.3.6.1.2.1.4'): class InterfacesUpdater(MIBUpdater): RFC1213_MAX_SPEED = 4294967295 + if_operstate_file = "/sys/class/net/{}/operstate" def __init__(self): super().__init__() @@ -203,6 +205,7 @@ def __init__(self): self.if_id_map = {} self.oid_name_map = {} self.namespace_db_map = Namespace.get_namespace_db_map(self.db_conn) + self.mgmt_oper_status = {} def reinit_data(self): """ @@ -239,6 +242,14 @@ def update_data(self): list(self.oid_lag_name_map.keys()) + list(self.mgmt_oid_name_map.keys())) self.if_range = [(i,) for i in self.if_range] + """ + For multi-asic platform, operstatus of + management iface is not stored in state db, + Retrieve oper status from sys/class/net + """ + if len(self.db_conn) > 1: + for mgmt_oid,if_name in self.mgmt_oid_name_map.items(): + self.mgmt_oper_status[mgmt_oid] = self._get_mgmt_oper_status(if_name) def get_next(self, sub_id): """ @@ -359,6 +370,20 @@ def _get_if_entry(self, sub_id): return Namespace.dbs_get_all(self.db_conn, db, if_table, blocking=True) + + def _get_mgmt_oper_status(self, if_name): + """ + :param if_name: mgmt interface name + :return: operation status string + """ + status = "unknown" + if_operstate_file = self.if_operstate_file.format(if_name) + if os.path.exists(if_operstate_file): + file = open(if_operstate_file, "r") + if file is not None: + status = file.readline().strip() + return status + def _get_if_entry_state_db(self, sub_id): """ :param oid: The 1-based sub-identifier query. @@ -372,7 +397,19 @@ def _get_if_entry_state_db(self, sub_id): db = mibs.STATE_DB if oid in self.mgmt_oid_name_map: mgmt_if_name = self.mgmt_oid_name_map[oid] - if_table = mibs.mgmt_if_entry_table_state_db(mgmt_if_name) + """ + For multi-asic platform, operstatus of + management iface is not stored in state db, + Retrieve oper status from sys/class/net + """ + if len(self.db_conn) > 1: + if oid in self.mgmt_oper_status: + state = self.mgmt_oper_status[oid] + return {"oper_status":state} + else: + return None + else: + if_table = mibs.mgmt_if_entry_table_state_db(mgmt_if_name) else: return None diff --git a/tests/mock_tables/eth1 b/tests/mock_tables/eth1 new file mode 100644 index 000000000..e31ee94e1 --- /dev/null +++ b/tests/mock_tables/eth1 @@ -0,0 +1 @@ +up diff --git a/tests/namespace/test_interfaces.py b/tests/namespace/test_interfaces.py index ea51339f8..2583ff9f7 100644 --- a/tests/namespace/test_interfaces.py +++ b/tests/namespace/test_interfaces.py @@ -1,12 +1,14 @@ import os import sys import importlib +import mock # noinspection PyUnresolvedReferences import tests.mock_tables.dbconnector modules_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.join(modules_path, 'src')) +mgmt_iface_status = modules_path + "/mock_tables/{}" from unittest import TestCase @@ -18,6 +20,7 @@ from ax_interface.mib import MIBTable from sonic_ax_impl.mibs.ietf import rfc1213 from sonic_ax_impl import mibs +from mock import patch class TestGetNextPDU(TestCase): @classmethod @@ -25,10 +28,11 @@ def setUpClass(cls): tests.mock_tables.dbconnector.load_namespace_config() importlib.reload(rfc1213) cls.lut = MIBTable(rfc1213.InterfacesMIB) - for updater in cls.lut.updater_instances: - updater.update_data() - updater.reinit_data() - updater.update_data() + with mock.patch('sonic_ax_impl.mibs.ietf.rfc1213.InterfacesUpdater.if_operstate_file', mgmt_iface_status): + for updater in cls.lut.updater_instances: + updater.update_data() + updater.reinit_data() + updater.update_data() def test_getnextpdu_noneifindex(self): # oid.include = 1 @@ -236,6 +240,101 @@ def test_if_type_portchannel(self): self.assertEqual(str(value0.name), str(ObjectIdentifier(11, 0, 1, 0, (1, 3, 6, 1, 2, 1, 2, 2, 1, 3, 1001)))) self.assertEqual(value0.data, 161) + def test_mgmt_iface(self): + """ + Test that mgmt port is present in the MIB + """ + oid = ObjectIdentifier(11, 0, 0, 0, (1, 3, 6, 1, 2, 1, 2, 2, 1, 1, 10000)) + get_pdu = GetNextPDU( + header=PDUHeader(1, PduTypes.GET, 16, 0, 42, 0, 0, 0), + oids=[oid] + ) + + encoded = get_pdu.encode() + response = get_pdu.make_response(self.lut) + print(response) + + value0 = response.values[0] + self.assertEqual(value0.type_, ValueType.INTEGER) + self.assertEqual(str(value0.name), str(ObjectIdentifier(11, 0, 1, 0, (1, 3, 6, 1, 2, 1, 2, 2, 1, 1, 10001)))) + self.assertEqual(value0.data, 10000) + + def test_mgmt_iface_description(self): + """ + Test mgmt port description (which is simply an alias) + """ + oid = ObjectIdentifier(11, 0, 0, 0, (1, 3, 6, 1, 2, 1, 2, 2, 1, 2, 10001)) + get_pdu = GetPDU( + header=PDUHeader(1, PduTypes.GET, 16, 0, 42, 0, 0, 0), + oids=[oid] + ) + + encoded = get_pdu.encode() + response = get_pdu.make_response(self.lut) + print(response) + + value0 = response.values[0] + self.assertEqual(value0.type_, ValueType.OCTET_STRING) + self.assertEqual(str(value0.name), str(ObjectIdentifier(11, 0, 1, 0, (1, 3, 6, 1, 2, 1, 2, 2, 1, 2, 10001)))) + self.assertEqual(str(value0.data), 'mgmt1') + + def test_mgmt_iface_oper_status(self): + """ + Test mgmt port operative status + """ + oid = ObjectIdentifier(11, 0, 0, 0, (1, 3, 6, 1, 2, 1, 2, 2, 1, 8, 10001)) + get_pdu = GetPDU( + header=PDUHeader(1, PduTypes.GET, 16, 0, 42, 0, 0, 0), + oids=[oid] + ) + + encoded = get_pdu.encode() + response = get_pdu.make_response(self.lut) + print(response) + + value0 = response.values[0] + self.assertEqual(value0.type_, ValueType.INTEGER) + self.assertEqual(str(value0.name), str(ObjectIdentifier(11, 0, 1, 0, (1, 3, 6, 1, 2, 1, 2, 2, 1, 8, 10001)))) + self.assertEqual(value0.data, 1) + + def test_mgmt_iface_oper_status_unknown(self): + """ + Test mgmt port operative status + """ + oid = ObjectIdentifier(11, 0, 0, 0, (1, 3, 6, 1, 2, 1, 2, 2, 1, 8, 10002)) + get_pdu = GetPDU( + header=PDUHeader(1, PduTypes.GET, 16, 0, 42, 0, 0, 0), + oids=[oid] + ) + + encoded = get_pdu.encode() + response = get_pdu.make_response(self.lut) + print(response) + + value0 = response.values[0] + self.assertEqual(value0.type_, ValueType.INTEGER) + self.assertEqual(str(value0.name), str(ObjectIdentifier(11, 0, 1, 0, (1, 3, 6, 1, 2, 1, 2, 2, 1, 8, 10002)))) + self.assertEqual(value0.data, 4) + + def test_mgmt_iface_admin_status(self): + """ + Test mgmt port admin status + """ + oid = ObjectIdentifier(11, 0, 0, 0, (1, 3, 6, 1, 2, 1, 2, 2, 1, 7, 10001)) + get_pdu = GetPDU( + header=PDUHeader(1, PduTypes.GET, 16, 0, 42, 0, 0, 0), + oids=[oid] + ) + + encoded = get_pdu.encode() + response = get_pdu.make_response(self.lut) + print(response) + + value0 = response.values[0] + self.assertEqual(value0.type_, ValueType.INTEGER) + self.assertEqual(str(value0.name), str(ObjectIdentifier(11, 0, 1, 0, (1, 3, 6, 1, 2, 1, 2, 2, 1, 7, 10001)))) + self.assertEqual(value0.data, 1) + def test_getnextpdu_first_bp_ifindex(self): oid = ObjectIdentifier(11, 0, 0, 0, (1, 3, 6, 1, 2, 1, 2, 2, 1, 1,1004)) get_pdu = GetNextPDU(