Skip to content

Commit 26b12bf

Browse files
committed
[FDB] [202012] Fix fbdorch to properly handle syncd FDB FLUSH Notif (sonic-net#2401)
* [FDB] Fix fbdorch to properly handle syncd FDB FLUSH Notif (sonic-net#2254) Vlan delete couldn't be handled by OA when there is fdb learnt on the member and when the member is deleted This inability of handling APPL_DB notif is affecting warm-restart. FDB Entry from State DB is not removed. OA doesn't have the logic to handle consolidate flush notif coming from syncd FdbOrch doesn't have logic to clear internal cache and decrement corresponding fdb counters during a flush notification Signed-off-by: Vivek Reddy Karri <[email protected]>
1 parent e84a901 commit 26b12bf

File tree

7 files changed

+565
-102
lines changed

7 files changed

+565
-102
lines changed

orchagent/fdborch.cpp

+116-102
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
extern sai_fdb_api_t *sai_fdb_api;
1818

1919
extern sai_object_id_t gSwitchId;
20-
extern PortsOrch* gPortsOrch;
2120
extern CrmOrch * gCrmOrch;
2221
extern Directory<Orch*> gDirectory;
2322

@@ -151,6 +150,104 @@ bool FdbOrch::storeFdbEntryState(const FdbUpdate& update)
151150
}
152151
}
153152

153+
/*
154+
clears stateDb and decrements corresponding internal fdb counters
155+
*/
156+
void FdbOrch::clearFdbEntry(const FdbEntry& entry)
157+
{
158+
FdbUpdate update;
159+
update.entry = entry;
160+
update.add = false;
161+
162+
/* Fetch Vlan and decrement the counter */
163+
Port temp_vlan;
164+
if (m_portsOrch->getPort(entry.bv_id, temp_vlan))
165+
{
166+
m_portsOrch->decrFdbCount(temp_vlan.m_alias, 1);
167+
}
168+
169+
/* Decrement port fdb_counter */
170+
m_portsOrch->decrFdbCount(entry.port_name, 1);
171+
172+
/* Remove the FdbEntry from the internal cache, update state DB and CRM counter */
173+
storeFdbEntryState(update);
174+
notify(SUBJECT_TYPE_FDB_CHANGE, &update);
175+
176+
SWSS_LOG_INFO("FdbEntry removed from internal cache, MAC: %s , port: %s, BVID: 0x%" PRIx64,
177+
update.entry.mac.to_string().c_str(), update.entry.port_name.c_str(), update.entry.bv_id);
178+
}
179+
180+
/*
181+
Handles the SAI_FDB_EVENT_FLUSHED notification recieved from syncd
182+
*/
183+
void FdbOrch::handleSyncdFlushNotif(const sai_object_id_t& bv_id,
184+
const sai_object_id_t& bridge_port_id,
185+
const MacAddress& mac)
186+
{
187+
// Consolidated flush will have a zero mac
188+
MacAddress flush_mac("00:00:00:00:00:00");
189+
190+
/* TODO: Read the SAI_FDB_FLUSH_ATTR_ENTRY_TYPE attr from the flush notif
191+
and clear the entries accordingly, currently only non-static entries are flushed
192+
*/
193+
if (bridge_port_id == SAI_NULL_OBJECT_ID && bv_id == SAI_NULL_OBJECT_ID)
194+
{
195+
for (auto itr = m_entries.begin(); itr != m_entries.end();)
196+
{
197+
auto curr = itr++;
198+
if (curr->second.type != "static" && (curr->first.mac == mac || mac == flush_mac))
199+
{
200+
clearFdbEntry(curr->first);
201+
}
202+
}
203+
}
204+
else if (bv_id == SAI_NULL_OBJECT_ID)
205+
{
206+
/* FLUSH based on PORT */
207+
for (auto itr = m_entries.begin(); itr != m_entries.end();)
208+
{
209+
auto curr = itr++;
210+
if (curr->second.bridge_port_id == bridge_port_id)
211+
{
212+
if (curr->second.type != "static" && (curr->first.mac == mac || mac == flush_mac))
213+
{
214+
clearFdbEntry(curr->first);
215+
}
216+
}
217+
}
218+
}
219+
else if (bridge_port_id == SAI_NULL_OBJECT_ID)
220+
{
221+
/* FLUSH based on BV_ID */
222+
for (auto itr = m_entries.begin(); itr != m_entries.end();)
223+
{
224+
auto curr = itr++;
225+
if (curr->first.bv_id == bv_id)
226+
{
227+
if (curr->second.type != "static" && (curr->first.mac == mac || mac == flush_mac))
228+
{
229+
clearFdbEntry(curr->first);
230+
}
231+
}
232+
}
233+
}
234+
else
235+
{
236+
/* FLUSH based on port and VLAN */
237+
for (auto itr = m_entries.begin(); itr != m_entries.end();)
238+
{
239+
auto curr = itr++;
240+
if (curr->first.bv_id == bv_id && curr->second.bridge_port_id == bridge_port_id)
241+
{
242+
if (curr->second.type != "static" && (curr->first.mac == mac || mac == flush_mac))
243+
{
244+
clearFdbEntry(curr->first);
245+
}
246+
}
247+
}
248+
}
249+
}
250+
154251
void FdbOrch::update(sai_fdb_event_t type,
155252
const sai_fdb_entry_t* entry,
156253
sai_object_id_t bridge_port_id)
@@ -168,24 +265,29 @@ void FdbOrch::update(sai_fdb_event_t type,
168265
type, update.entry.mac.to_string().c_str(),
169266
entry->bv_id, bridge_port_id);
170267

171-
172268
if (bridge_port_id &&
173269
!m_portsOrch->getPortByBridgePortId(bridge_port_id, update.port))
174270
{
175271
if (type == SAI_FDB_EVENT_FLUSHED)
176272
{
177-
/* In case of flush - can be ignored due to a race.
178-
There are notifications about FDB FLUSH (syncd/sai_redis) on port,
179-
which was already removed by orchagent as a result of
180-
removeVlanMember action (removeBridgePort) */
273+
/* There are notifications about FDB FLUSH (syncd/sai_redis) on port,
274+
which was already removed by orchagent as a result of removeVlanMember
275+
action (removeBridgePort). But the internal cleanup of statedb and
276+
internal counters is yet to be performed, thus continue
277+
*/
181278
SWSS_LOG_INFO("Flush event: Failed to get port by bridge port ID 0x%" PRIx64 ".",
182279
bridge_port_id);
183-
184280
} else {
185281
SWSS_LOG_ERROR("Failed to get port by bridge port ID 0x%" PRIx64 ".",
186282
bridge_port_id);
187-
283+
return;
188284
}
285+
}
286+
287+
if (entry->bv_id &&
288+
!m_portsOrch->getPort(entry->bv_id, vlan))
289+
{
290+
SWSS_LOG_NOTICE("FdbOrch notification type %d: Failed to locate vlan port from bv_id 0x%" PRIx64, type, entry->bv_id);
189291
return;
190292
}
191293

@@ -195,12 +297,6 @@ void FdbOrch::update(sai_fdb_event_t type,
195297
{
196298
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);
197299

198-
if (!m_portsOrch->getPort(entry->bv_id, vlan))
199-
{
200-
SWSS_LOG_ERROR("FdbOrch LEARN notification: Failed to locate vlan port from bv_id 0x%" PRIx64, entry->bv_id);
201-
return;
202-
}
203-
204300
// we already have such entries
205301
auto existing_entry = m_entries.find(update.entry);
206302
if (existing_entry != m_entries.end())
@@ -229,11 +325,6 @@ void FdbOrch::update(sai_fdb_event_t type,
229325
SWSS_LOG_INFO("Received AGE event for bvid=0x%" PRIx64 " mac=%s port=0x%" PRIx64,
230326
entry->bv_id, update.entry.mac.to_string().c_str(), bridge_port_id);
231327

232-
if (!m_portsOrch->getPort(entry->bv_id, vlan))
233-
{
234-
SWSS_LOG_NOTICE("FdbOrch AGE notification: Failed to locate vlan port from bv_id 0x%" PRIx64, entry->bv_id);
235-
}
236-
237328
auto existing_entry = m_entries.find(update.entry);
238329
// we don't have such entries
239330
if (existing_entry == m_entries.end())
@@ -326,12 +417,6 @@ void FdbOrch::update(sai_fdb_event_t type,
326417
SWSS_LOG_INFO("Received MOVE event for bvid=0x%" PRIx64 " mac=%s port=0x%" PRIx64,
327418
entry->bv_id, update.entry.mac.to_string().c_str(), bridge_port_id);
328419

329-
if (!m_portsOrch->getPort(entry->bv_id, vlan))
330-
{
331-
SWSS_LOG_ERROR("FdbOrch MOVE notification: Failed to locate vlan port from bv_id 0x%" PRIx64, entry->bv_id);
332-
return;
333-
}
334-
335420
// We should already have such entry
336421
if (existing_entry == m_entries.end())
337422
{
@@ -369,86 +454,15 @@ void FdbOrch::update(sai_fdb_event_t type,
369454
bridge_port_id);
370455

371456
string vlanName = "-";
372-
if (entry->bv_id) {
373-
Port vlan;
374-
375-
if (!m_portsOrch->getPort(entry->bv_id, vlan))
376-
{
377-
SWSS_LOG_NOTICE("FdbOrch notification: Failed to locate vlan\
378-
port from bv_id 0x%" PRIx64, entry->bv_id);
379-
return;
380-
}
457+
if (!vlan.m_alias.empty()) {
381458
vlanName = "Vlan" + to_string(vlan.m_vlan_info.vlan_id);
382459
}
383460

461+
SWSS_LOG_INFO("FDB Flush: [ %s , %s ] = { port: %s }", update.entry.mac.to_string().c_str(),
462+
vlanName.c_str(), update.port.m_alias.c_str());
384463

385-
if (bridge_port_id == SAI_NULL_OBJECT_ID &&
386-
entry->bv_id == SAI_NULL_OBJECT_ID)
387-
{
388-
SWSS_LOG_INFO("FDB Flush: [ %s , %s ] = { port: - }",
389-
update.entry.mac.to_string().c_str(), vlanName.c_str());
390-
for (auto itr = m_entries.begin(); itr != m_entries.end();)
391-
{
392-
/*
393-
TODO: here should only delete the dynamic fdb entries,
394-
but unfortunately in structure FdbEntry currently have
395-
no member to indicate the fdb entry type,
396-
if there is static mac added, here will have issue.
397-
*/
398-
update.entry.mac = itr->first.mac;
399-
update.entry.bv_id = itr->first.bv_id;
400-
update.add = false;
401-
itr++;
402-
403-
storeFdbEntryState(update);
404-
405-
for (auto observer: m_observers)
406-
{
407-
observer->update(SUBJECT_TYPE_FDB_CHANGE, &update);
408-
}
409-
}
410-
}
411-
else if (entry->bv_id == SAI_NULL_OBJECT_ID)
412-
{
413-
/* FLUSH based on port */
414-
SWSS_LOG_INFO("FDB Flush: [ %s , %s ] = { port: %s }",
415-
update.entry.mac.to_string().c_str(),
416-
vlanName.c_str(), update.port.m_alias.c_str());
417-
418-
for (auto itr = m_entries.begin(); itr != m_entries.end();)
419-
{
420-
auto next_item = std::next(itr);
421-
if (itr->first.port_name == update.port.m_alias)
422-
{
423-
update.entry.mac = itr->first.mac;
424-
update.entry.bv_id = itr->first.bv_id;
425-
update.add = false;
426-
427-
storeFdbEntryState(update);
464+
handleSyncdFlushNotif(entry->bv_id, bridge_port_id, update.entry.mac);
428465

429-
for (auto observer: m_observers)
430-
{
431-
observer->update(SUBJECT_TYPE_FDB_CHANGE, &update);
432-
}
433-
}
434-
itr = next_item;
435-
}
436-
}
437-
else if (bridge_port_id == SAI_NULL_OBJECT_ID)
438-
{
439-
/* FLUSH based on VLAN - unsupported */
440-
SWSS_LOG_ERROR("Unsupported FDB Flush: [ %s , %s ] = { port: - }",
441-
update.entry.mac.to_string().c_str(),
442-
vlanName.c_str());
443-
444-
}
445-
else
446-
{
447-
/* FLUSH based on port and VLAN - unsupported */
448-
SWSS_LOG_ERROR("Unsupported FDB Flush: [ %s , %s ] = { port: %s }",
449-
update.entry.mac.to_string().c_str(),
450-
vlanName.c_str(), update.port.m_alias.c_str());
451-
}
452466
break;
453467
}
454468

@@ -524,7 +538,7 @@ void FdbOrch::doTask(Consumer& consumer)
524538
{
525539
SWSS_LOG_ENTER();
526540

527-
if (!gPortsOrch->allPortsReady())
541+
if (!m_portsOrch->allPortsReady())
528542
{
529543
return;
530544
}
@@ -681,7 +695,7 @@ void FdbOrch::doTask(NotificationConsumer& consumer)
681695
{
682696
SWSS_LOG_ENTER();
683697

684-
if (!gPortsOrch->allPortsReady())
698+
if (!m_portsOrch->allPortsReady())
685699
{
686700
return;
687701
}

orchagent/fdborch.h

+3
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ class FdbOrch: public Orch, public Subject, public Observer
119119

120120
bool storeFdbEntryState(const FdbUpdate& update);
121121
void notifyTunnelOrch(Port& port);
122+
123+
void clearFdbEntry(const FdbEntry&);
124+
void handleSyncdFlushNotif(const sai_object_id_t&, const sai_object_id_t&, const MacAddress& );
122125
};
123126

124127
#endif /* SWSS_FDBORCH_H */

orchagent/portsorch.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -5355,3 +5355,17 @@ std::unordered_set<std::string> PortsOrch::generateCounterStats(const string& ty
53555355
}
53565356
return counter_stats;
53575357
}
5358+
5359+
bool PortsOrch::decrFdbCount(const std::string& alias, int count)
5360+
{
5361+
auto itr = m_portList.find(alias);
5362+
if (itr == m_portList.end())
5363+
{
5364+
return false;
5365+
}
5366+
else
5367+
{
5368+
itr->second.m_fdb_count -= count;
5369+
}
5370+
return true;
5371+
}

orchagent/portsorch.h

+1
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ class PortsOrch : public Orch, public Subject
147147
bool removeVlanMember(Port &vlan, Port &port);
148148
bool isVlanMember(Port &vlan, Port &port);
149149

150+
bool decrFdbCount(const string& alias, int count);
150151
private:
151152
unique_ptr<Table> m_counterTable;
152153
unique_ptr<Table> m_counterLagTable;

tests/mock_tests/Makefile.am

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ LDADD_GTEST = -L/usr/src/gtest
2222

2323
tests_SOURCES = aclorch_ut.cpp \
2424
portsorch_ut.cpp \
25+
fdborch/flush_syncd_notif_ut.cpp \
2526
saispy_ut.cpp \
2627
consumer_ut.cpp \
2728
ut_saihelper.cpp \

0 commit comments

Comments
 (0)