From c20bf604361c7a1ea47f0815897df6dbb2239a01 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Mon, 15 Mar 2021 14:28:31 -0700 Subject: [PATCH] Implement rfc4363 FdbUpdater for lag inside vlan (#203) **- What I did** Currently if there are lags in vlan, and FDB entries with lag will not visible in FdbUpdater. **- How I did it** Implement rfc4363 FdbUpdater for lag inside vlan **- How to verify it** Test in DUT, and add unit test. --- src/sonic_ax_impl/mibs/__init__.py | 16 ++++++++++++-- src/sonic_ax_impl/mibs/ietf/rfc1213.py | 2 +- src/sonic_ax_impl/mibs/ietf/rfc2863.py | 2 +- src/sonic_ax_impl/mibs/ietf/rfc4363.py | 18 +++++++++++++++- .../mibs/vendor/cisco/ciscoPfcExtMIB.py | 2 +- tests/mock_tables/asic_db.json | 20 ++++++++++++++++++ tests/mock_tables/counters_db.json | 3 ++- tests/namespace/test_mibs.py | 2 +- tests/test_fdb.py | 21 ++++++++++++++++++- tests/test_mibs.py | 2 +- 10 files changed, 78 insertions(+), 10 deletions(-) diff --git a/src/sonic_ax_impl/mibs/__init__.py b/src/sonic_ax_impl/mibs/__init__.py index dbe4d6f4f767..f3b0d17fa76a 100644 --- a/src/sonic_ax_impl/mibs/__init__.py +++ b/src/sonic_ax_impl/mibs/__init__.py @@ -304,13 +304,24 @@ 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_sai_map = {} + # { lag_oid (SAI) -> lag_name (SONiC) } + sai_lag_map = {} db_conn.connect(APPL_DB) lag_entries = db_conn.keys(APPL_DB, "LAG_TABLE:*") if not lag_entries: - return lag_name_if_name_map, if_name_lag_name_map, oid_lag_name_map + return lag_name_if_name_map, if_name_lag_name_map, oid_lag_name_map, lag_sai_map + + db_conn.connect(COUNTERS_DB) + lag_sai_map = db_conn.get_all(COUNTERS_DB, "COUNTERS_LAG_NAME_MAP") + for name, sai_id in lag_sai_map.items(): + sai_id_key = get_sai_id_key(db_conn.namespace, sai_id.lstrip("oid:0x")) + lag_sai_map[name] = sai_id_key + sai_lag_map[sai_id_key] = name for lag_entry in lag_entries: lag_name = lag_entry[len("LAG_TABLE:"):] @@ -332,7 +343,7 @@ def member_name_str(val, lag_name): if idx: oid_lag_name_map[idx] = if_name - return lag_name_if_name_map, if_name_lag_name_map, oid_lag_name_map + return lag_name_if_name_map, if_name_lag_name_map, oid_lag_name_map, sai_lag_map def init_sync_d_queue_tables(db_conn): """ @@ -588,3 +599,4 @@ def dbs_get_vlan_id_from_bvid(dbs, bvid): vlan_obj = db_conn.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 None diff --git a/src/sonic_ax_impl/mibs/ietf/rfc1213.py b/src/sonic_ax_impl/mibs/ietf/rfc1213.py index 35c6e1f0c2a7..0b8b69ff04cc 100644 --- a/src/sonic_ax_impl/mibs/ietf/rfc1213.py +++ b/src/sonic_ax_impl/mibs/ietf/rfc1213.py @@ -233,7 +233,7 @@ def update_data(self): self.lag_name_if_name_map, \ self.if_name_lag_name_map, \ - self.oid_lag_name_map = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_lag_tables, self.db_conn) + self.oid_lag_name_map, _ = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_lag_tables, self.db_conn) self.if_range = sorted(list(self.oid_name_map.keys()) + list(self.oid_lag_name_map.keys()) + diff --git a/src/sonic_ax_impl/mibs/ietf/rfc2863.py b/src/sonic_ax_impl/mibs/ietf/rfc2863.py index 931c560f8f85..1bfa4a588b9f 100644 --- a/src/sonic_ax_impl/mibs/ietf/rfc2863.py +++ b/src/sonic_ax_impl/mibs/ietf/rfc2863.py @@ -79,7 +79,7 @@ def reinit_data(self): self.lag_name_if_name_map, \ self.if_name_lag_name_map, \ - self.oid_lag_name_map = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_lag_tables, self.db_conn) + self.oid_lag_name_map, _ = Namespace.get_sync_d_from_all_namespace(mibs.init_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. diff --git a/src/sonic_ax_impl/mibs/ietf/rfc4363.py b/src/sonic_ax_impl/mibs/ietf/rfc4363.py index f2adf9f325f8..8dd5dead2811 100644 --- a/src/sonic_ax_impl/mibs/ietf/rfc4363.py +++ b/src/sonic_ax_impl/mibs/ietf/rfc4363.py @@ -15,6 +15,7 @@ def __init__(self): self.if_alias_map = {} self.if_id_map = {} self.oid_name_map = {} + self.sai_lag_map = {} self.vlanmac_ifindex_map = {} self.vlanmac_ifindex_list = [] self.if_bpid_map = {} @@ -28,6 +29,8 @@ def fdb_vlanmac(self, fdb): vlan_id = self.bvid_vlan_map[fdb["bvid"]] else: vlan_id = Namespace.dbs_get_vlan_id_from_bvid(self.db_conn, fdb["bvid"]) + if isinstance(vlan_id, bytes): + vlan_id = vlan_id.decode() self.bvid_vlan_map[fdb["bvid"]] = vlan_id else: return None @@ -48,6 +51,11 @@ def reinit_data(self): mibs.init_sync_d_interface_tables, self.db_conn ) + self.lag_name_if_name_map, \ + self.if_name_lag_name_map, \ + self.oid_lag_name_map, \ + self.sai_lag_map = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_lag_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() @@ -77,12 +85,20 @@ def update_data(self): if bridge_port_id not in self.if_bpid_map: continue port_id = self.if_bpid_map[bridge_port_id] + if port_id in self.if_id_map: + port_name = self.if_id_map[port_id] + port_index = mibs.get_index_from_str(port_name) + elif port_id in self.sai_lag_map: + port_name = self.sai_lag_map[port_id] + port_index = mibs.get_index_from_str(port_name) + else: + continue vlanmac = self.fdb_vlanmac(fdb) if not vlanmac: mibs.logger.error("SyncD 'ASIC_DB' includes invalid FDB_ENTRY '{}': failed in fdb_vlanmac().".format(fdb_str)) continue - self.vlanmac_ifindex_map[vlanmac] = mibs.get_index_from_str(self.if_id_map[port_id]) + self.vlanmac_ifindex_map[vlanmac] = port_index self.vlanmac_ifindex_list.append(vlanmac) self.vlanmac_ifindex_list.sort() diff --git a/src/sonic_ax_impl/mibs/vendor/cisco/ciscoPfcExtMIB.py b/src/sonic_ax_impl/mibs/vendor/cisco/ciscoPfcExtMIB.py index ca2516cd500f..3130de034bf3 100644 --- a/src/sonic_ax_impl/mibs/vendor/cisco/ciscoPfcExtMIB.py +++ b/src/sonic_ax_impl/mibs/vendor/cisco/ciscoPfcExtMIB.py @@ -52,7 +52,7 @@ def update_data(self): self.lag_name_if_name_map, \ self.if_name_lag_name_map, \ - self.oid_lag_name_map = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_lag_tables, self.db_conn) + self.oid_lag_name_map, _ = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_lag_tables, self.db_conn) self.if_range = sorted(list(self.oid_name_map.keys()) + list(self.oid_lag_name_map.keys())) self.if_range = [(i,) for i in self.if_range] diff --git a/tests/mock_tables/asic_db.json b/tests/mock_tables/asic_db.json index bdec0aeb5d93..4050ca3e8730 100644 --- a/tests/mock_tables/asic_db.json +++ b/tests/mock_tables/asic_db.json @@ -7,6 +7,15 @@ "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID": "oid:0x3a000000000608", "SAI_FDB_ENTRY_ATTR_TYPE": "SAI_FDB_ENTRY_TYPE_DYNAMIC" }, + "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"bridge_id\":\"oid:0x0\",\"bridge_type\":\"SAI_FDB_ENTRY_BRIDGE_TYPE_1Q\",\"mac\":\"7C:FE:90:80:9F:06\",\"switch_id\":\"oid:0x21000000000000\",\"bvid\":\"oid:0x26000000000a20\"}": { + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID": "oid:0x3a000000000a21", + "SAI_FDB_ENTRY_ATTR_TYPE": "SAI_FDB_ENTRY_TYPE_DYNAMIC" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"bvid\":\"oid:0x26000000000013\",\"mac\":\"7C:FE:90:5E:6B:BE\",\"switch_id\":\"oid:0x21000000000000\"}" : { + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID": "oid:0x3a000000000a21", + "SAI_FDB_ENTRY_ATTR_TYPE": "SAI_FDB_ENTRY_TYPE_DYNAMIC", + "SAI_FDB_ENTRY_ATTR_PACKET_ACTION": "SAI_PACKET_ACTION_FORWARD" + }, "ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT:oid:0x3a000000000616": { "SAI_BRIDGE_PORT_ATTR_TYPE": "SAI_BRIDGE_PORT_TYPE_PORT", "SAI_BRIDGE_PORT_ATTR_PORT_ID": "oid:0x1000000000006", @@ -16,5 +25,16 @@ "SAI_BRIDGE_PORT_ATTR_TYPE": "SAI_BRIDGE_PORT_TYPE_PORT", "SAI_BRIDGE_PORT_ATTR_PORT_ID": "oid:0x1000000000008", "SAI_BRIDGE_PORT_ATTR_ADMIN_STATE": "true" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT:oid:0x3a000000000a21": { + "SAI_BRIDGE_PORT_ATTR_TYPE": "SAI_BRIDGE_PORT_TYPE_PORT", + "SAI_BRIDGE_PORT_ATTR_PORT_ID": "oid:0x2000000000a14", + "SAI_BRIDGE_PORT_ATTR_ADMIN_STATE": "true" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_VLAN:oid:0x26000000000a20": { + "SAI_VLAN_ATTR_VLAN_ID": "102" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_VLAN:oid:0x26000000000013": { + "NULL": "NULL" } } diff --git a/tests/mock_tables/counters_db.json b/tests/mock_tables/counters_db.json index 0ec1fa1c7fe1..531fa4c15ebe 100644 --- a/tests/mock_tables/counters_db.json +++ b/tests/mock_tables/counters_db.json @@ -2278,7 +2278,8 @@ "Ethernet68": "oid:0x1000000000020" }, "COUNTERS_LAG_NAME_MAP": { - "PortChannel01": "oid:0x1000000000023" + "PortChannel01": "oid:0x1000000000023", + "PortChannel101": "oid:0x2000000000a14" }, "COUNTERS:oid:0x1000000000009": { "SAI_PORT_STAT_ETHER_STATS_TX_NO_ERRORS": "0", diff --git a/tests/namespace/test_mibs.py b/tests/namespace/test_mibs.py index 3e76485cd32f..109b0796d6d7 100644 --- a/tests/namespace/test_mibs.py +++ b/tests/namespace/test_mibs.py @@ -21,7 +21,7 @@ def test_init_namespace_sync_d_lag_tables(self): lag_name_if_name_map, \ if_name_lag_name_map, \ - oid_lag_name_map = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_lag_tables, dbs) + oid_lag_name_map, _ = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_lag_tables, dbs) #PortChannel in asic0 Namespace self.assertTrue("PortChannel01" in lag_name_if_name_map) self.assertTrue("Ethernet-BP0" in lag_name_if_name_map["PortChannel01"]) diff --git a/tests/test_fdb.py b/tests/test_fdb.py index 9d4111c764d6..dca9b10f0d74 100644 --- a/tests/test_fdb.py +++ b/tests/test_fdb.py @@ -17,11 +17,16 @@ from ax_interface.constants import PduTypes from sonic_ax_impl.mibs.ietf import rfc4363 from sonic_ax_impl.main import SonicMIB +from swsssdk.port_util import BaseIdx class TestSonicMIB(TestCase): @classmethod def setUpClass(cls): cls.lut = MIBTable(SonicMIB) + for updater in cls.lut.updater_instances: + updater.update_data() + updater.reinit_data() + updater.update_data() def test_getpdu(self): oid = ObjectIdentifier(20, 0, 0, 0, (1, 3, 6, 1, 2, 1, 17, 7, 1, 2, 2, 1, 2, 1000, 124, 254, 144, 128, 159, 4)) @@ -43,7 +48,7 @@ def test_getnextpdu(self): get_pdu = GetNextPDU( header=PDUHeader(1, PduTypes.GET, 16, 0, 42, 0, 0, 0), oids=( - ObjectIdentifier(20, 0, 0, 0, (1, 3, 6, 1, 2, 1, 17, 7, 1, 2, 2, 1, 2)), + ObjectIdentifier(20, 0, 0, 0, (1, 3, 6, 1, 2, 1, 17, 7, 1, 2, 2, 1, 2, 999)), ) ) @@ -56,6 +61,20 @@ def test_getnextpdu(self): self.assertEqual(value0.type_, ValueType.INTEGER) self.assertEqual(value0.data, 113) + def test_getnextpdu_lag(self): + get_pdu = GetNextPDU( + header=PDUHeader(1, PduTypes.GET, 16, 0, 42, 0, 0, 0), + oids=( + ObjectIdentifier(20, 0, 0, 0, (1, 3, 6, 1, 2, 1, 17, 7, 1, 2, 2, 1, 2, 101)), + ) + ) + + response = get_pdu.make_response(self.lut) + + value0 = response.values[0] + self.assertEqual(value0.type_, ValueType.INTEGER) + self.assertEqual(value0.data, BaseIdx.portchannel_base_idx + 101) + def test_getnextpdu_exactmatch(self): # oid.include = 1 oid = ObjectIdentifier(20, 0, 1, 0, (1, 3, 6, 1, 2, 1, 17, 7, 1, 2, 2, 1, 2, 1000, 124, 254, 144, 128, 159, 4)) diff --git a/tests/test_mibs.py b/tests/test_mibs.py index 6fb461760c04..87a5f3e861a0 100644 --- a/tests/test_mibs.py +++ b/tests/test_mibs.py @@ -21,7 +21,7 @@ def test_init_sync_d_lag_tables(self): lag_name_if_name_map, \ if_name_lag_name_map, \ - oid_lag_name_map = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_lag_tables, db_conn) + oid_lag_name_map, _ = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_lag_tables, db_conn) self.assertTrue("PortChannel04" in lag_name_if_name_map) self.assertTrue(lag_name_if_name_map["PortChannel04"] == ["Ethernet124"])