diff --git a/orchagent/fdborch.cpp b/orchagent/fdborch.cpp index b79e589af4f2..7498eb7e055a 100644 --- a/orchagent/fdborch.cpp +++ b/orchagent/fdborch.cpp @@ -57,12 +57,18 @@ bool FdbOrch::storeFdbEntryState(const FdbUpdate& update) { const FdbEntry& entry = update.entry; const Port& port = update.port; - sai_vlan_id_t vlan_id = port.m_port_vlan_id; const MacAddress& mac = entry.mac; string portName = port.m_alias; + Port vlan; + + if (!m_portsOrch->getPort(entry.bv_id, vlan)) + { + SWSS_LOG_NOTICE("FdbOrch notification: Failed to locate vlan port from bv_id 0x%lx", entry.bv_id); + return false; + } // ref: https://github.com/Azure/sonic-swss/blob/master/doc/swss-schema.md#fdb_table - string key = "Vlan" + to_string(vlan_id) + ":" + mac.to_string(); + string key = "Vlan" + to_string(vlan.m_vlan_info.vlan_id) + ":" + mac.to_string(); if (update.add) { diff --git a/tests/conftest.py b/tests/conftest.py index 70ca0b1f9648..893ab489a1a9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -668,6 +668,12 @@ def create_vlan_member(self, vlan, interface): tbl.set("Vlan" + vlan + "|" + interface, fvs) time.sleep(1) + def create_vlan_member_tagged(self, vlan, interface): + tbl = swsscommon.Table(self.cdb, "VLAN_MEMBER") + fvs = swsscommon.FieldValuePairs([("tagging_mode", "tagged")]) + tbl.set("Vlan" + vlan + "|" + interface, fvs) + time.sleep(1) + def set_interface_status(self, interface, admin_status): if interface.startswith("PortChannel"): tbl_name = "PORTCHANNEL" diff --git a/tests/test_fdb_warm.py b/tests/test_fdb_warm.py index 492fe781e57d..a6d741d983a3 100644 --- a/tests/test_fdb_warm.py +++ b/tests/test_fdb_warm.py @@ -40,6 +40,17 @@ def test_fdb_notifications(dvs, testlog): dvs.create_vlan_member("6", "Ethernet64") dvs.create_vlan_member("6", "Ethernet68") + # Put Ethernet72 and Ethernet76 into vlan 7 in untagged mode, they will have pvid of 7 + # and into vlan8 in tagged mode + dvs.create_vlan("7") + dvs.create_vlan_member("7", "Ethernet72") + dvs.create_vlan_member("7", "Ethernet76") + + dvs.create_vlan("8") + dvs.create_vlan_member_tagged("8", "Ethernet72") + dvs.create_vlan_member_tagged("8", "Ethernet76") + + # Get mapping between interface name and its bridge port_id time.sleep(2) iface_2_bridge_port_id = dvs.get_map_iface_bridge_port_id(dvs.adb) @@ -54,6 +65,16 @@ def test_fdb_notifications(dvs, testlog): [("SAI_BRIDGE_PORT_ATTR_FDB_LEARNING_MODE", "SAI_BRIDGE_PORT_FDB_LEARNING_MODE_HW")]) assert ok, str(extra) + ok, extra = dvs.is_table_entry_exists(dvs.adb, 'ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT', + iface_2_bridge_port_id["Ethernet72"], + [("SAI_BRIDGE_PORT_ATTR_FDB_LEARNING_MODE", "SAI_BRIDGE_PORT_FDB_LEARNING_MODE_HW")]) + assert ok, str(extra) + + ok, extra = dvs.is_table_entry_exists(dvs.adb, 'ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT', + iface_2_bridge_port_id["Ethernet76"], + [("SAI_BRIDGE_PORT_ATTR_FDB_LEARNING_MODE", "SAI_BRIDGE_PORT_FDB_LEARNING_MODE_HW")]) + assert ok, str(extra) + # check fdb aging attr ok, extra = dvs.all_table_entry_has_no(dvs.adb, 'ASIC_STATE:SAI_OBJECT_TYPE_SWITCH', ".*", @@ -62,13 +83,24 @@ def test_fdb_notifications(dvs, testlog): # bring up vlan and member dvs.set_interface_status("Vlan6", "up") dvs.add_ip_address("Vlan6", "6.6.6.1/24") + dvs.add_ip_address("Vlan8", "8.8.8.1/24") dvs.set_interface_status("Ethernet64", "up") dvs.set_interface_status("Ethernet68", "up") + dvs.set_interface_status("Ethernet72", "up") + dvs.set_interface_status("Ethernet76", "up") dvs.servers[16].runcmd("ifconfig eth0 6.6.6.6/24 up") dvs.servers[16].runcmd("ip route add default via 6.6.6.1") dvs.servers[17].runcmd("ifconfig eth0 6.6.6.7/24 up") dvs.servers[17].runcmd("ip route add default via 6.6.6.1") + dvs.servers[18].runcmd("vconfig add eth0 8") + dvs.servers[18].runcmd("ifconfig eth0.8 8.8.8.6/24 up") + dvs.servers[18].runcmd("ip route add default via 8.8.8.1") + + dvs.servers[19].runcmd("vconfig add eth0 8") + dvs.servers[19].runcmd("ifconfig eth0.8 8.8.8.7/24 up") + dvs.servers[19].runcmd("ip route add default via 8.8.8.1") + # get neighbor and arp entry time.sleep(2) rc = dvs.servers[16].runcmd("ping -c 1 6.6.6.7") @@ -76,6 +108,13 @@ def test_fdb_notifications(dvs, testlog): rc = dvs.servers[17].runcmd("ping -c 1 6.6.6.6") assert rc == 0 + # get neighbor and arp entry + time.sleep(2) + rc = dvs.servers[18].runcmd("ping -c 1 8.8.8.7") + assert rc == 0 + rc = dvs.servers[19].runcmd("ping -c 1 8.8.8.6") + assert rc == 0 + # check that the FDB entries were inserted into ASIC DB ok, extra = dvs.is_fdb_entry_exists(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY", @@ -93,9 +132,24 @@ def test_fdb_notifications(dvs, testlog): ) assert ok, str(extra) + ok, extra = dvs.is_fdb_entry_exists(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY", + [], + [("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_DYNAMIC"), + ("SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID", iface_2_bridge_port_id["Ethernet72"]), + ] + ) + assert ok, str(extra) + ok, extra = dvs.is_fdb_entry_exists(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY", + [], + [("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_DYNAMIC"), + ("SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID", iface_2_bridge_port_id["Ethernet76"]), + ] + ) + assert ok, str(extra) + time.sleep(2) counter_inserted = dvs.getCrmCounterValue('STATS', 'crm_stats_fdb_entry_used') - assert counter_inserted - counter_before == 2 + assert counter_inserted - counter_before == 4 # check that the FDB entries were inserted into State DB ok, extra = dvs.is_table_entry_exists(dvs.sdb, "FDB_TABLE", @@ -113,6 +167,22 @@ def test_fdb_notifications(dvs, testlog): ) assert ok, str(extra) + # check that the FDB entries were inserted into State DB, Vlan8 while not Vlan7(untagged) in the key + ok, extra = dvs.is_table_entry_exists(dvs.sdb, "FDB_TABLE", + "Vlan8:.*", + [("port", "Ethernet72"), + ("type", "dynamic"), + ] + ) + assert ok, str(extra) + ok, extra = dvs.is_table_entry_exists(dvs.sdb, "FDB_TABLE", + "Vlan8:*", + [("port", "Ethernet76"), + ("type", "dynamic"), + ] + ) + assert ok, str(extra) + # enable warm restart (exitcode, result) = dvs.runcmd("config warm_restart enable swss") assert exitcode == 0 @@ -160,6 +230,22 @@ def test_fdb_notifications(dvs, testlog): ) assert ok, str(extra) + # check that the FDB entries were inserted into ASIC DB + ok, extra = dvs.is_fdb_entry_exists(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY", + [], + [("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_DYNAMIC"), + ("SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID", iface_2_bridge_port_id["Ethernet72"]), + ] + ) + assert ok, str(extra) + ok, extra = dvs.is_fdb_entry_exists(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY", + [], + [("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_DYNAMIC"), + ("SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID", iface_2_bridge_port_id["Ethernet76"]), + ] + ) + assert ok, str(extra) + # check FDB learning mode ok, extra = dvs.is_table_entry_exists(dvs.adb, 'ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT', iface_2_bridge_port_id["Ethernet64"], @@ -170,6 +256,15 @@ def test_fdb_notifications(dvs, testlog): [("SAI_BRIDGE_PORT_ATTR_FDB_LEARNING_MODE", "SAI_BRIDGE_PORT_FDB_LEARNING_MODE_HW")]) assert ok, str(extra) + ok, extra = dvs.is_table_entry_exists(dvs.adb, 'ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT', + iface_2_bridge_port_id["Ethernet72"], + [("SAI_BRIDGE_PORT_ATTR_FDB_LEARNING_MODE", "SAI_BRIDGE_PORT_FDB_LEARNING_MODE_HW")]) + assert ok, str(extra) + ok, extra = dvs.is_table_entry_exists(dvs.adb, 'ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT', + iface_2_bridge_port_id["Ethernet76"], + [("SAI_BRIDGE_PORT_ATTR_FDB_LEARNING_MODE", "SAI_BRIDGE_PORT_FDB_LEARNING_MODE_HW")]) + assert ok, str(extra) + time.sleep(2) counter_restarted = dvs.getCrmCounterValue('STATS', 'crm_stats_fdb_entry_used') assert counter_inserted == counter_restarted