@@ -113,8 +113,8 @@ bool FdbOrch::storeFdbEntryState(const FdbUpdate& update)
113113 }
114114}
115115
116- void FdbOrch::update (sai_fdb_event_t type,
117- const sai_fdb_entry_t * entry,
116+ void FdbOrch::update (sai_fdb_event_t type,
117+ const sai_fdb_entry_t * entry,
118118 sai_object_id_t bridge_port_id)
119119{
120120 SWSS_LOG_ENTER ();
@@ -124,11 +124,11 @@ void FdbOrch::update(sai_fdb_event_t type,
124124 update.entry .bv_id = entry->bv_id ;
125125
126126 SWSS_LOG_INFO (" FDB event:%d, MAC: %s , BVID: 0x%" PRIx64 " , \
127- bridge port ID: 0x%" PRIx64 " ." ,
128- type, update.entry .mac .to_string ().c_str (),
127+ bridge port ID: 0x%" PRIx64 " ." ,
128+ type, update.entry .mac .to_string ().c_str (),
129129 entry->bv_id , bridge_port_id);
130130
131- if (bridge_port_id &&
131+ if (bridge_port_id &&
132132 !m_portsOrch->getPortByBridgePortId (bridge_port_id, update.port ))
133133 {
134134 SWSS_LOG_ERROR (" Failed to get port by bridge port ID 0x%" PRIx64 " ." ,
@@ -199,7 +199,7 @@ void FdbOrch::update(sai_fdb_event_t type,
199199 }
200200
201201
202- if (bridge_port_id == SAI_NULL_OBJECT_ID &&
202+ if (bridge_port_id == SAI_NULL_OBJECT_ID &&
203203 entry->bv_id == SAI_NULL_OBJECT_ID)
204204 {
205205 SWSS_LOG_INFO (" FDB Flush: [ %s , %s ] = { port: - }" ,
@@ -491,6 +491,18 @@ void FdbOrch::doTask(NotificationConsumer& consumer)
491491 }
492492}
493493
494+ /*
495+ * Name: flushFDBEntries
496+ * Params:
497+ * bridge_port_oid - SAI object ID of bridge port associated with the port
498+ * vlan_oid - SAI object ID of the VLAN
499+ * Description:
500+ * Flushes FDB entries based on bridge_port_oid, or vlan_oid or both.
501+ * This function is called in three cases.
502+ * 1. Port is reoved from VLAN (via SUBJECT_TYPE_VLAN_MEMBER_CHANGE)
503+ * 2. Bridge port OID is removed (Direct call)
504+ * 3. Port is shut down (via SUBJECT_TYPE_
505+ */
494506void FdbOrch::flushFDBEntries (sai_object_id_t bridge_port_oid,
495507 sai_object_id_t vlan_oid)
496508{
@@ -531,13 +543,56 @@ void FdbOrch::flushFDBEntries(sai_object_id_t bridge_port_oid,
531543 }
532544}
533545
546+ void FdbOrch::notifyObserversFDBFlush (Port &port, sai_object_id_t & bvid)
547+ {
548+ FdbFlushUpdate flushUpdate;
549+ flushUpdate.port = port;
550+
551+ for (auto itr = m_entries.begin (); itr != m_entries.end (); ++itr)
552+ {
553+ if ((itr->port_name == port.m_alias ) &&
554+ (itr->bv_id == bvid))
555+ {
556+ SWSS_LOG_INFO (" Adding MAC learnt on [ port:%s , bvid:0x%" PRIx64 " ]\
557+ to ARP flush" , port.m_alias .c_str (), bvid);
558+ FdbEntry entry;
559+ entry.mac = itr->mac ;
560+ entry.bv_id = itr->bv_id ;
561+ flushUpdate.entries .push_back (entry);
562+ }
563+ }
564+
565+ if (!flushUpdate.entries .empty ())
566+ {
567+ for (auto observer: m_observers)
568+ {
569+ observer->update (SUBJECT_TYPE_FDB_FLUSH_CHANGE, &flushUpdate);
570+ }
571+ }
572+ }
573+
534574void FdbOrch::updatePortOperState (const PortOperStateUpdate& update)
535575{
536576 SWSS_LOG_ENTER ();
537577 if (update.operStatus == SAI_PORT_OPER_STATUS_DOWN)
538578 {
539579 swss::Port p = update.port ;
540580 flushFDBEntries (p.m_bridge_port_id , SAI_NULL_OBJECT_ID);
581+
582+ // Get BVID of each VLAN that this port is a member of
583+ // and call notifyObserversFDBFlush
584+ for (const auto & vlan_member: p.m_vlan_members )
585+ {
586+ swss::Port vlan;
587+ string vlan_alias = VLAN_PREFIX + to_string (vlan_member.first );
588+ if (!m_portsOrch->getPort (vlan_alias, vlan))
589+ {
590+ SWSS_LOG_INFO (" Failed to locate VLAN %s" , vlan_alias.c_str ());
591+ continue ;
592+ }
593+ notifyObserversFDBFlush (p, vlan.m_vlan_info .vlan_oid );
594+ }
595+
541596 }
542597 return ;
543598}
@@ -551,6 +606,7 @@ void FdbOrch::updateVlanMember(const VlanMemberUpdate& update)
551606 swss::Port vlan = update.vlan ;
552607 swss::Port port = update.member ;
553608 flushFDBEntries (port.m_bridge_port_id , vlan.m_vlan_info .vlan_oid );
609+ notifyObserversFDBFlush (port, vlan.m_vlan_info .vlan_oid );
554610 return ;
555611 }
556612
@@ -580,7 +636,7 @@ bool FdbOrch::addFdbEntry(const FdbEntry& entry, const string& type)
580636 if (!m_portsOrch->getPort (entry.port_name , port))
581637 {
582638 SWSS_LOG_DEBUG (" Saving a fdb entry until port %s becomes active" ,
583- entry. port_name.c_str ());
639+ entry.port_name .c_str ());
584640 saved_fdb_entries[entry.port_name ].push_back ({entry, type});
585641
586642 return true ;
@@ -589,7 +645,7 @@ bool FdbOrch::addFdbEntry(const FdbEntry& entry, const string& type)
589645 /* Retry until port is added to the VLAN */
590646 if (!port.m_bridge_port_id )
591647 {
592- SWSS_LOG_DEBUG (" Saving a fdb entry until port %s has got a bridge port ID" ,
648+ SWSS_LOG_DEBUG (" Saving a fdb entry until port %s has got a bridge port ID" ,
593649 entry.port_name .c_str ());
594650 saved_fdb_entries[entry.port_name ].push_back ({entry, type});
595651
0 commit comments