diff --git a/lib/inc/ServerSai.h b/lib/inc/ServerSai.h index 00d11e050311..37a4550767e9 100644 --- a/lib/inc/ServerSai.h +++ b/lib/inc/ServerSai.h @@ -337,6 +337,11 @@ namespace sairedis _In_ const sai_object_id_t* object_ids, _In_ const sai_status_t* statuses); + // NON QUAD API + + sai_status_t processFdbFlush( + _In_ const swss::KeyOpFieldsValuesTuple &kco); + // QUERY API sai_status_t processAttrCapabilityQuery( diff --git a/lib/src/ServerSai.cpp b/lib/src/ServerSai.cpp index f22e4f50e0aa..5feec62eb910 100644 --- a/lib/src/ServerSai.cpp +++ b/lib/src/ServerSai.cpp @@ -697,10 +697,10 @@ sai_status_t ServerSai::processSingleEvent( // // if (op == REDIS_ASIC_STATE_COMMAND_CLEAR_STATS) // return processClearStatsEvent(kco); -// -// if (op == REDIS_ASIC_STATE_COMMAND_FLUSH) -// return processFdbFlush(kco); -// + + if (op == REDIS_ASIC_STATE_COMMAND_FLUSH) + return processFdbFlush(kco); + if (op == REDIS_ASIC_STATE_COMMAND_ATTR_CAPABILITY_QUERY) return processAttrCapabilityQuery(kco); @@ -1707,3 +1707,33 @@ sai_status_t ServerSai::processObjectTypeGetAvailabilityQuery( return status; } + +sai_status_t ServerSai::processFdbFlush( + _In_ const swss::KeyOpFieldsValuesTuple &kco) +{ + SWSS_LOG_ENTER(); + + auto& key = kfvKey(kco); + auto strSwitchOid = key.substr(key.find(":") + 1); + + sai_object_id_t switchOid; + sai_deserialize_object_id(strSwitchOid, switchOid); + + auto& values = kfvFieldsValues(kco); + + for (const auto &v: values) + { + SWSS_LOG_DEBUG("attr: %s: %s", fvField(v).c_str(), fvValue(v).c_str()); + } + + SaiAttributeList list(SAI_OBJECT_TYPE_FDB_FLUSH, values, false); + + sai_attribute_t *attr_list = list.get_attr_list(); + uint32_t attr_count = list.get_attr_count(); + + sai_status_t status = m_sai->flushFdbEntries(switchOid, attr_count, attr_list); + + m_selectableChannel->set(sai_serialize_status(status), {} , REDIS_ASIC_STATE_COMMAND_FLUSHRESPONSE); + + return status; +} diff --git a/tests/testclient.cpp b/tests/testclient.cpp index 9d508ecf33ab..0ded4f57d357 100644 --- a/tests/testclient.cpp +++ b/tests/testclient.cpp @@ -25,6 +25,8 @@ class TestClient void test_query_api(); + void test_fdb_flush(); + private: int profileGetNextValue( @@ -411,6 +413,50 @@ void TestClient::test_query_api() ASSERT_SUCCESS(sai_api_uninitialize()); } +void TestClient::test_fdb_flush() +{ + SWSS_LOG_ENTER(); + + m_profileMap.clear(); + + m_profileMap[SAI_REDIS_KEY_ENABLE_CLIENT] = "true"; // act as a client + + m_profileIter = m_profileMap.begin(); + + m_smt.profileGetValue = std::bind(&TestClient::profileGetValue, this, _1, _2); + m_smt.profileGetNextValue = std::bind(&TestClient::profileGetNextValue, this, _1, _2, _3); + + m_test_services = m_smt.getServiceMethodTable(); + + ASSERT_SUCCESS(sai_api_initialize(0, &m_test_services)); + + sai_switch_api_t* switch_api; + + ASSERT_SUCCESS(sai_api_query(SAI_API_SWITCH, (void**)&switch_api)); + + sai_attribute_t attr; + + // connect to existing switch + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = false; + + sai_object_id_t switch_id = SAI_NULL_OBJECT_ID; + + ASSERT_SUCCESS(switch_api->create_switch(&switch_id, 1, &attr)); + + ASSERT_TRUE(switch_id != SAI_NULL_OBJECT_ID); + + SWSS_LOG_NOTICE("switchId: %s", sai_serialize_object_id(switch_id).c_str()); + + sai_fdb_api_t* fdb_api; + + ASSERT_SUCCESS(sai_api_query(SAI_API_FDB, (void**)&fdb_api)); + + ASSERT_SUCCESS(fdb_api->flush_fdb_entries(switch_id, 0, NULL)); + + ASSERT_SUCCESS(sai_api_uninitialize()); +} + int main() { swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_DEBUG); @@ -427,5 +473,7 @@ int main() tc.test_query_api(); + tc.test_fdb_flush(); + return EXIT_SUCCESS; }