diff --git a/orchagent/fdborch.cpp b/orchagent/fdborch.cpp index 229dec0b15..cdc54fc26b 100644 --- a/orchagent/fdborch.cpp +++ b/orchagent/fdborch.cpp @@ -73,8 +73,8 @@ bool FdbOrch::storeFdbEntryState(const FdbUpdate& update) if (!m_portsOrch->getPort(entry.bv_id, vlan)) { - SWSS_LOG_NOTICE("FdbOrch notification: Failed to locate \ - vlan port from bv_id 0x%" PRIx64, entry.bv_id); + SWSS_LOG_NOTICE("FdbOrch notification: Failed to locate " + "vlan port from bv_id 0x%" PRIx64, entry.bv_id); return false; } @@ -163,8 +163,8 @@ void FdbOrch::update(sai_fdb_event_t type, update.type = "dynamic"; Port vlan; - SWSS_LOG_INFO("FDB event:%d, MAC: %s , BVID: 0x%" PRIx64 " , \ - bridge port ID: 0x%" PRIx64 ".", + SWSS_LOG_INFO("FDB event:%d, MAC: %s , BVID: 0x%" PRIx64 " , " + "bridge port ID: 0x%" PRIx64 ".", type, update.entry.mac.to_string().c_str(), entry->bv_id, bridge_port_id); @@ -362,8 +362,8 @@ void FdbOrch::update(sai_fdb_event_t type, } case SAI_FDB_EVENT_FLUSHED: - SWSS_LOG_INFO("FDB Flush event received: [ %s , 0x%" PRIx64 " ], \ - bridge port ID: 0x%" PRIx64 ".", + SWSS_LOG_INFO("FDB Flush event received: [ %s , 0x%" PRIx64 " ], " + "bridge port ID: 0x%" PRIx64 ".", update.entry.mac.to_string().c_str(), entry->bv_id, bridge_port_id); @@ -373,8 +373,8 @@ void FdbOrch::update(sai_fdb_event_t type, if (!m_portsOrch->getPort(entry->bv_id, vlan)) { - SWSS_LOG_NOTICE("FdbOrch notification: Failed to locate vlan\ - port from bv_id 0x%" PRIx64, entry->bv_id); + SWSS_LOG_NOTICE("FdbOrch notification: Failed to locate vlan " + "port from bv_id 0x%" PRIx64, entry->bv_id); return; } vlanName = "Vlan" + to_string(vlan.m_vlan_info.vlan_id); @@ -439,7 +439,6 @@ void FdbOrch::update(sai_fdb_event_t type, SWSS_LOG_ERROR("Unsupported FDB Flush: [ %s , %s ] = { port: - }", update.entry.mac.to_string().c_str(), vlanName.c_str()); - } else { @@ -647,6 +646,7 @@ void FdbOrch::doTask(Consumer& consumer) port = tunnel_orch->getTunnelPortName(remote_ip); } + entry.port_name = port; FdbData fdbData; fdbData.bridge_port_id = SAI_NULL_OBJECT_ID; @@ -666,7 +666,6 @@ void FdbOrch::doTask(Consumer& consumer) it = consumer.m_toSync.erase(it); else it++; - } else { @@ -881,8 +880,8 @@ void FdbOrch::notifyObserversFDBFlush(Port &port, sai_object_id_t& bvid) if ((itr->first.port_name == port.m_alias) && (itr->first.bv_id == bvid)) { - SWSS_LOG_INFO("Adding MAC learnt on [ port:%s , bvid:0x%" PRIx64 "]\ - to ARP flush", port.m_alias.c_str(), bvid); + SWSS_LOG_INFO("Adding MAC learnt on [ port:%s , bvid:0x%" PRIx64 "] " + "to ARP flush", port.m_alias.c_str(), bvid); FdbEntry entry; entry.mac = itr->first.mac; entry.bv_id = itr->first.bv_id; @@ -920,7 +919,6 @@ void FdbOrch::updatePortOperState(const PortOperStateUpdate& update) } notifyObserversFDBFlush(p, vlan.m_vlan_info.vlan_oid); } - } return; } diff --git a/orchagent/mirrororch.cpp b/orchagent/mirrororch.cpp index 37c2ef73df..4bb47e8a36 100644 --- a/orchagent/mirrororch.cpp +++ b/orchagent/mirrororch.cpp @@ -576,6 +576,7 @@ bool MirrorOrch::getNeighborInfo(const string& name, MirrorEntry& session) !m_neighOrch->getNeighborEntry(session.nexthopInfo.nexthop, session.neighborInfo.neighbor, session.neighborInfo.mac))) { + session.neighborInfo.mac = MacAddress(); return false; } diff --git a/tests/test_mirror.py b/tests/test_mirror.py index f74ff6fa0d..a50be97c22 100644 --- a/tests/test_mirror.py +++ b/tests/test_mirror.py @@ -14,6 +14,15 @@ def setup_db(self, dvs): self.cdb = swsscommon.DBConnector(4, dvs.redis_sock, 0) self.sdb = swsscommon.DBConnector(6, dvs.redis_sock, 0) + def set_port_oper_status(self, dvs, port_name, status): + if port_name.startswith("Ethernet"): + srv_idx = int(port_name[len("Ethernet"):]) // 4 + dvs.servers[srv_idx].runcmd("ip link set dev eth0 " + status) + elif port_name.startswith("PortChannel"): + dvs.runcmd("bash -c 'echo " + ("1" if status == "up" else "0") + \ + " > /sys/class/net/" + port_name + "/carrier'") + time.sleep(1) + def set_interface_status(self, dvs, interface, admin_status): if interface.startswith("PortChannel"): tbl_name = "PORTCHANNEL" @@ -26,11 +35,13 @@ def set_interface_status(self, dvs, interface, admin_status): tbl.set(interface, fvs) time.sleep(1) - # when using FRR, route cannot be inserted if the neighbor is not - # connected. thus it is mandatory to force the interface up manually if interface.startswith("PortChannel"): - dvs.runcmd("bash -c 'echo " + ("1" if admin_status == "up" else "0") +\ - " > /sys/class/net/" + interface + "/carrier'") + # when using FRR, route cannot be inserted if the neighbor is not + # connected. thus it is mandatory to force the interface up manually + self.set_port_oper_status(dvs, interface, admin_status) + elif interface.startswith("Ethernet"): + self.set_port_oper_status(dvs, interface, "down") + self.set_port_oper_status(dvs, interface, "up") def add_ip_address(self, interface, ip): if interface.startswith("PortChannel"): @@ -239,6 +250,11 @@ def remove_fdb(self, vlan, mac): tbl._del("Vlan" + vlan + ":" + mac) time.sleep(1) + def flush_fdb(self, op, data): + ntf = swsscommon.NotificationProducer(self.adb, "FLUSHFDBREQUEST") + fvs = swsscommon.FieldValuePairs() + ntf.send(op, data, fvs) + time.sleep(1) # Ignore testcase in Debian Jessie # TODO: Remove this skip if Jessie support is no longer needed @@ -328,6 +344,56 @@ def test_MirrorToVlanAddRemove(self, dvs, testlog): else: assert False + # test port oper status down that triggers fdb flush on port, which further triggers neighbor flush + self.set_port_oper_status(dvs, "Ethernet4", "down") + assert self.get_mirror_session_state(session)["status"] == "inactive" + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_MIRROR_SESSION") + assert len(tbl.getKeys()) == 0 + # Allow time for neighor flush to occur + time.sleep(1) + + # restore port oper status up + self.set_port_oper_status(dvs, "Ethernet4", "up") + + # restore fdb entry to ethernet 4 + self.create_fdb("6", "66-66-66-66-66-66", "Ethernet4") + assert self.get_mirror_session_state(session)["status"] == "inactive" + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_MIRROR_SESSION") + assert len(tbl.getKeys()) == 0 + + # restore neighbor to vlan 6 + self.add_neighbor("Vlan6", "6.6.6.6", "66:66:66:66:66:66") + assert self.get_mirror_session_state(session)["status"] == "active" + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_MIRROR_SESSION") + assert len(tbl.getKeys()) == 1 + + # test fdb flush all from appl db + self.flush_fdb("ALL", "ALL") + assert self.get_mirror_session_state(session)["status"] == "inactive" + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_MIRROR_SESSION") + assert len(tbl.getKeys()) == 0 + + # restore fdb entry to ethernet 4 + self.create_fdb("6", "66-66-66-66-66-66", "Ethernet4") + assert self.get_mirror_session_state(session)["status"] == "active" + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_MIRROR_SESSION") + assert len(tbl.getKeys()) == 1 + + # test fdb flush port from appl db + self.flush_fdb("PORT", "Ethernet4") + assert self.get_mirror_session_state(session)["status"] == "inactive" + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_MIRROR_SESSION") + assert len(tbl.getKeys()) == 0 + + # restore fdb entry to ethernet 4 + self.create_fdb("6", "66-66-66-66-66-66", "Ethernet4") + assert self.get_mirror_session_state(session)["status"] == "active" + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_MIRROR_SESSION") + assert len(tbl.getKeys()) == 1 + + # test fdb flush vlan from appl db, the corresponding flush event from asic db not yet handled + # test fdb flush {vlan, port} from appl db, the corresponding flush event from asic db not yet handled + # remove fdb entry self.remove_fdb("6", "66-66-66-66-66-66") assert self.get_mirror_session_state(session)["status"] == "inactive"