17
17
extern sai_fdb_api_t *sai_fdb_api;
18
18
19
19
extern sai_object_id_t gSwitchId ;
20
- extern PortsOrch* gPortsOrch ;
21
20
extern CrmOrch * gCrmOrch ;
22
21
extern Directory<Orch*> gDirectory ;
23
22
@@ -151,6 +150,104 @@ bool FdbOrch::storeFdbEntryState(const FdbUpdate& update)
151
150
}
152
151
}
153
152
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
+
154
251
void FdbOrch::update (sai_fdb_event_t type,
155
252
const sai_fdb_entry_t * entry,
156
253
sai_object_id_t bridge_port_id)
@@ -168,24 +265,29 @@ void FdbOrch::update(sai_fdb_event_t type,
168
265
type, update.entry .mac .to_string ().c_str (),
169
266
entry->bv_id , bridge_port_id);
170
267
171
-
172
268
if (bridge_port_id &&
173
269
!m_portsOrch->getPortByBridgePortId (bridge_port_id, update.port ))
174
270
{
175
271
if (type == SAI_FDB_EVENT_FLUSHED)
176
272
{
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
+ */
181
278
SWSS_LOG_INFO (" Flush event: Failed to get port by bridge port ID 0x%" PRIx64 " ." ,
182
279
bridge_port_id);
183
-
184
280
} else {
185
281
SWSS_LOG_ERROR (" Failed to get port by bridge port ID 0x%" PRIx64 " ." ,
186
282
bridge_port_id);
187
-
283
+ return ;
188
284
}
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 );
189
291
return ;
190
292
}
191
293
@@ -195,12 +297,6 @@ void FdbOrch::update(sai_fdb_event_t type,
195
297
{
196
298
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);
197
299
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
-
204
300
// we already have such entries
205
301
auto existing_entry = m_entries.find (update.entry );
206
302
if (existing_entry != m_entries.end ())
@@ -229,11 +325,6 @@ void FdbOrch::update(sai_fdb_event_t type,
229
325
SWSS_LOG_INFO (" Received AGE event for bvid=0x%" PRIx64 " mac=%s port=0x%" PRIx64,
230
326
entry->bv_id , update.entry .mac .to_string ().c_str (), bridge_port_id);
231
327
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
-
237
328
auto existing_entry = m_entries.find (update.entry );
238
329
// we don't have such entries
239
330
if (existing_entry == m_entries.end ())
@@ -326,12 +417,6 @@ void FdbOrch::update(sai_fdb_event_t type,
326
417
SWSS_LOG_INFO (" Received MOVE event for bvid=0x%" PRIx64 " mac=%s port=0x%" PRIx64,
327
418
entry->bv_id , update.entry .mac .to_string ().c_str (), bridge_port_id);
328
419
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
-
335
420
// We should already have such entry
336
421
if (existing_entry == m_entries.end ())
337
422
{
@@ -369,86 +454,15 @@ void FdbOrch::update(sai_fdb_event_t type,
369
454
bridge_port_id);
370
455
371
456
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 ()) {
381
458
vlanName = " Vlan" + to_string (vlan.m_vlan_info .vlan_id );
382
459
}
383
460
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 ());
384
463
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 );
428
465
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
- }
452
466
break ;
453
467
}
454
468
@@ -524,7 +538,7 @@ void FdbOrch::doTask(Consumer& consumer)
524
538
{
525
539
SWSS_LOG_ENTER ();
526
540
527
- if (!gPortsOrch ->allPortsReady ())
541
+ if (!m_portsOrch ->allPortsReady ())
528
542
{
529
543
return ;
530
544
}
@@ -681,7 +695,7 @@ void FdbOrch::doTask(NotificationConsumer& consumer)
681
695
{
682
696
SWSS_LOG_ENTER ();
683
697
684
- if (!gPortsOrch ->allPortsReady ())
698
+ if (!m_portsOrch ->allPortsReady ())
685
699
{
686
700
return ;
687
701
}
0 commit comments