1818extern sai_fdb_api_t *sai_fdb_api;
1919
2020extern sai_object_id_t gSwitchId ;
21- extern PortsOrch* gPortsOrch ;
2221extern CrmOrch * gCrmOrch ;
2322extern MlagOrch* gMlagOrch ;
2423extern Directory<Orch*> gDirectory ;
@@ -175,6 +174,107 @@ bool FdbOrch::storeFdbEntryState(const FdbUpdate& update)
175174 }
176175}
177176
177+ /*
178+ clears stateDb and decrements corresponding internal fdb counters
179+ */
180+ void FdbOrch::clearFdbEntry (const MacAddress& mac,
181+ const sai_object_id_t & bv_id,
182+ const string& port_alias)
183+ {
184+ FdbUpdate update;
185+ update.entry .mac = mac;
186+ update.entry .bv_id = bv_id;
187+ update.add = false ;
188+
189+ /* Fetch Vlan and decrement the counter */
190+ Port temp_vlan;
191+ if (m_portsOrch->getPort (bv_id, temp_vlan))
192+ {
193+ m_portsOrch->decrFdbCount (temp_vlan.m_alias , 1 );
194+ }
195+
196+ /* Decrement port fdb_counter */
197+ m_portsOrch->decrFdbCount (port_alias, 1 );
198+
199+ /* Remove the FdbEntry from the internal cache, update state DB and CRM counter */
200+ storeFdbEntryState (update);
201+ notify (SUBJECT_TYPE_FDB_CHANGE , &update);
202+
203+ SWSS_LOG_INFO (" FdbEntry removed from internal cache, MAC: %s , port: %s, BVID: 0x%" PRIx64,
204+ mac.to_string ().c_str (), port_alias.c_str (), bv_id);
205+ }
206+
207+ /*
208+ Handles the SAI_FDB_EVENT_FLUSHED notification recieved from syncd
209+ */
210+ void FdbOrch::handleSyncdFlushNotif (const sai_object_id_t & bv_id,
211+ const sai_object_id_t & bridge_port_id,
212+ const MacAddress& mac)
213+ {
214+ // Consolidated flush will have a zero mac
215+ MacAddress flush_mac (" 00:00:00:00:00:00" );
216+
217+ /* TODO: Read the SAI_FDB_FLUSH_ATTR_ENTRY_TYPE attr from the flush notif
218+ and clear the entries accordingly, currently only non-static entries are flushed
219+ */
220+ if (bridge_port_id == SAI_NULL_OBJECT_ID && bv_id == SAI_NULL_OBJECT_ID )
221+ {
222+ for (auto itr = m_entries.begin (); itr != m_entries.end ();)
223+ {
224+ auto curr = itr++;
225+ if (curr->second .type != " static" && (curr->first .mac == mac || mac == flush_mac))
226+ {
227+ clearFdbEntry (curr->first .mac , curr->first .bv_id , curr->first .port_name );
228+ }
229+ }
230+ }
231+ else if (bv_id == SAI_NULL_OBJECT_ID )
232+ {
233+ /* FLUSH based on PORT */
234+ for (auto itr = m_entries.begin (); itr != m_entries.end ();)
235+ {
236+ auto curr = itr++;
237+ if (curr->second .bridge_port_id == bridge_port_id)
238+ {
239+ if (curr->second .type != " static" && (curr->first .mac == mac || mac == flush_mac))
240+ {
241+ clearFdbEntry (curr->first .mac , curr->first .bv_id , curr->first .port_name );
242+ }
243+ }
244+ }
245+ }
246+ else if (bridge_port_id == SAI_NULL_OBJECT_ID )
247+ {
248+ /* FLUSH based on BV_ID */
249+ for (auto itr = m_entries.begin (); itr != m_entries.end ();)
250+ {
251+ auto curr = itr++;
252+ if (curr->first .bv_id == bv_id)
253+ {
254+ if (curr->second .type != " static" && (curr->first .mac == mac || mac == flush_mac))
255+ {
256+ clearFdbEntry (curr->first .mac , curr->first .bv_id , curr->first .port_name );
257+ }
258+ }
259+ }
260+ }
261+ else
262+ {
263+ /* FLUSH based on port and VLAN */
264+ for (auto itr = m_entries.begin (); itr != m_entries.end ();)
265+ {
266+ auto curr = itr++;
267+ if (curr->first .bv_id == bv_id && curr->second .bridge_port_id == bridge_port_id)
268+ {
269+ if (curr->second .type != " static" && (curr->first .mac == mac || mac == flush_mac))
270+ {
271+ clearFdbEntry (curr->first .mac , curr->first .bv_id , curr->first .port_name );
272+ }
273+ }
274+ }
275+ }
276+ }
277+
178278void FdbOrch::update (sai_fdb_event_t type,
179279 const sai_fdb_entry_t * entry,
180280 sai_object_id_t bridge_port_id)
@@ -192,24 +292,29 @@ void FdbOrch::update(sai_fdb_event_t type,
192292 type, update.entry .mac .to_string ().c_str (),
193293 entry->bv_id , bridge_port_id);
194294
195-
196295 if (bridge_port_id &&
197296 !m_portsOrch->getPortByBridgePortId (bridge_port_id, update.port ))
198297 {
199298 if (type == SAI_FDB_EVENT_FLUSHED )
200299 {
201- /* In case of flush - can be ignored due to a race.
202- There are notifications about FDB FLUSH (syncd/sai_redis) on port,
203- which was already removed by orchagent as a result of
204- removeVlanMember action (removeBridgePort) */
300+ /* There are notifications about FDB FLUSH (syncd/sai_redis) on port,
301+ which was already removed by orchagent as a result of removeVlanMember
302+ action (removeBridgePort). But the internal cleanup of statedb and
303+ internal counters is yet to be performed, thus continue
304+ */
205305 SWSS_LOG_INFO (" Flush event: Failed to get port by bridge port ID 0x%" PRIx64 " ." ,
206306 bridge_port_id);
207-
208307 } else {
209308 SWSS_LOG_ERROR (" Failed to get port by bridge port ID 0x%" PRIx64 " ." ,
210309 bridge_port_id);
211-
310+ return ;
212311 }
312+ }
313+
314+ if (entry->bv_id &&
315+ !m_portsOrch->getPort (entry->bv_id , vlan))
316+ {
317+ SWSS_LOG_NOTICE (" FdbOrch notification type %d: Failed to locate vlan port from bv_id 0x%" PRIx64, type, entry->bv_id );
213318 return ;
214319 }
215320
@@ -219,12 +324,6 @@ void FdbOrch::update(sai_fdb_event_t type,
219324 {
220325 SWSS_LOG_INFO (" Received LEARN event for bvid=0x%" PRIx64 " mac=%s port=0x%" PRIx64, entry->bv_id , update.entry .mac .to_string ().c_str (), bridge_port_id);
221326
222- if (!m_portsOrch->getPort (entry->bv_id , vlan))
223- {
224- SWSS_LOG_ERROR (" FdbOrch LEARN notification: Failed to locate vlan port from bv_id 0x%" PRIx64, entry->bv_id );
225- return ;
226- }
227-
228327 // we already have such entries
229328 auto existing_entry = m_entries.find (update.entry );
230329 if (existing_entry != m_entries.end ())
@@ -319,11 +418,6 @@ void FdbOrch::update(sai_fdb_event_t type,
319418 SWSS_LOG_INFO (" Received AGE event for bvid=0x%" PRIx64 " mac=%s port=0x%" PRIx64,
320419 entry->bv_id , update.entry .mac .to_string ().c_str (), bridge_port_id);
321420
322- if (!m_portsOrch->getPort (entry->bv_id , vlan))
323- {
324- SWSS_LOG_NOTICE (" FdbOrch AGE notification: Failed to locate vlan port from bv_id 0x%" PRIx64, entry->bv_id );
325- }
326-
327421 auto existing_entry = m_entries.find (update.entry );
328422 // we don't have such entries
329423 if (existing_entry == m_entries.end ())
@@ -457,12 +551,6 @@ void FdbOrch::update(sai_fdb_event_t type,
457551 SWSS_LOG_INFO (" Received MOVE event for bvid=0x%" PRIx64 " mac=%s port=0x%" PRIx64,
458552 entry->bv_id , update.entry .mac .to_string ().c_str (), bridge_port_id);
459553
460- if (!m_portsOrch->getPort (entry->bv_id , vlan))
461- {
462- SWSS_LOG_ERROR (" FdbOrch MOVE notification: Failed to locate vlan port from bv_id 0x%" PRIx64, entry->bv_id );
463- return ;
464- }
465-
466554 // We should already have such entry
467555 if (existing_entry == m_entries.end ())
468556 {
@@ -500,80 +588,15 @@ void FdbOrch::update(sai_fdb_event_t type,
500588 bridge_port_id);
501589
502590 string vlanName = " -" ;
503- if (entry->bv_id ) {
504- Port vlan;
505-
506- if (!m_portsOrch->getPort (entry->bv_id , vlan))
507- {
508- SWSS_LOG_NOTICE (" FdbOrch notification: Failed to locate vlan\
509- port from bv_id 0x%" PRIx64, entry->bv_id );
510- return ;
511- }
591+ if (!vlan.m_alias .empty ()) {
512592 vlanName = " Vlan" + to_string (vlan.m_vlan_info .vlan_id );
513593 }
514594
595+ SWSS_LOG_INFO (" FDB Flush: [ %s , %s ] = { port: %s }" , update.entry .mac .to_string ().c_str (),
596+ vlanName.c_str (), update.port .m_alias .c_str ());
515597
516- if (bridge_port_id == SAI_NULL_OBJECT_ID &&
517- entry->bv_id == SAI_NULL_OBJECT_ID )
518- {
519- SWSS_LOG_INFO (" FDB Flush: [ %s , %s ] = { port: - }" ,
520- update.entry .mac .to_string ().c_str (), vlanName.c_str ());
521- for (auto itr = m_entries.begin (); itr != m_entries.end ();)
522- {
523- /*
524- TODO: here should only delete the dynamic fdb entries,
525- but unfortunately in structure FdbEntry currently have
526- no member to indicate the fdb entry type,
527- if there is static mac added, here will have issue.
528- */
529- update.entry .mac = itr->first .mac ;
530- update.entry .bv_id = itr->first .bv_id ;
531- update.add = false ;
532- itr++;
533-
534- storeFdbEntryState (update);
535-
536- notify (SUBJECT_TYPE_FDB_CHANGE , &update);
537-
538- }
539- }
540- else if (entry->bv_id == SAI_NULL_OBJECT_ID )
541- {
542- /* FLUSH based on port */
543- SWSS_LOG_INFO (" FDB Flush: [ %s , %s ] = { port: %s }" ,
544- update.entry .mac .to_string ().c_str (),
545- vlanName.c_str (), update.port .m_alias .c_str ());
546-
547- for (auto itr = m_entries.begin (); itr != m_entries.end ();)
548- {
549- auto next_item = std::next (itr);
550- if (itr->first .port_name == update.port .m_alias )
551- {
552- update.entry .mac = itr->first .mac ;
553- update.entry .bv_id = itr->first .bv_id ;
554- update.add = false ;
598+ handleSyncdFlushNotif (entry->bv_id , bridge_port_id, update.entry .mac );
555599
556- storeFdbEntryState (update);
557- notify (SUBJECT_TYPE_FDB_CHANGE , &update);
558- }
559- itr = next_item;
560- }
561- }
562- else if (bridge_port_id == SAI_NULL_OBJECT_ID )
563- {
564- /* FLUSH based on VLAN - unsupported */
565- SWSS_LOG_ERROR (" Unsupported FDB Flush: [ %s , %s ] = { port: - }" ,
566- update.entry .mac .to_string ().c_str (),
567- vlanName.c_str ());
568-
569- }
570- else
571- {
572- /* FLUSH based on port and VLAN - unsupported */
573- SWSS_LOG_ERROR (" Unsupported FDB Flush: [ %s , %s ] = { port: %s }" ,
574- update.entry .mac .to_string ().c_str (),
575- vlanName.c_str (), update.port .m_alias .c_str ());
576- }
577600 break ;
578601 }
579602
@@ -649,7 +672,7 @@ void FdbOrch::doTask(Consumer& consumer)
649672{
650673 SWSS_LOG_ENTER ();
651674
652- if (!gPortsOrch ->allPortsReady ())
675+ if (!m_portsOrch ->allPortsReady ())
653676 {
654677 return ;
655678 }
@@ -856,7 +879,7 @@ void FdbOrch::doTask(NotificationConsumer& consumer)
856879{
857880 SWSS_LOG_ENTER ();
858881
859- if (!gPortsOrch ->allPortsReady ())
882+ if (!m_portsOrch ->allPortsReady ())
860883 {
861884 return ;
862885 }
@@ -892,7 +915,7 @@ void FdbOrch::doTask(NotificationConsumer& consumer)
892915 SWSS_LOG_ERROR (" Receive wrong port to flush fdb!" );
893916 return ;
894917 }
895- if (!gPortsOrch ->getPort (alias, port))
918+ if (!m_portsOrch ->getPort (alias, port))
896919 {
897920 SWSS_LOG_ERROR (" Get Port from port(%s) failed!" , alias.c_str ());
898921 return ;
@@ -913,7 +936,7 @@ void FdbOrch::doTask(NotificationConsumer& consumer)
913936 SWSS_LOG_ERROR (" Receive wrong vlan to flush fdb!" );
914937 return ;
915938 }
916- if (!gPortsOrch ->getPort (vlan, vlanPort))
939+ if (!m_portsOrch ->getPort (vlan, vlanPort))
917940 {
918941 SWSS_LOG_ERROR (" Get Port from vlan(%s) failed!" , vlan.c_str ());
919942 return ;
@@ -939,12 +962,12 @@ void FdbOrch::doTask(NotificationConsumer& consumer)
939962 SWSS_LOG_ERROR (" Receive wrong port or vlan to flush fdb!" );
940963 return ;
941964 }
942- if (!gPortsOrch ->getPort (alias, port))
965+ if (!m_portsOrch ->getPort (alias, port))
943966 {
944967 SWSS_LOG_ERROR (" Get Port from port(%s) failed!" , alias.c_str ());
945968 return ;
946969 }
947- if (!gPortsOrch ->getPort (vlan, vlanPort))
970+ if (!m_portsOrch ->getPort (vlan, vlanPort))
948971 {
949972 SWSS_LOG_ERROR (" Get Port from vlan(%s) failed!" , vlan.c_str ());
950973 return ;
0 commit comments