From 8cb4cf054b85a629544e80a6e9fbd4b769aeac35 Mon Sep 17 00:00:00 2001 From: Vijaya Kumar Abbaraju Date: Tue, 8 Oct 2024 04:34:03 +0530 Subject: [PATCH] MAB mgr changes for PAC (#18623) --- src/sonic-pac/mabmgr/Makefile.am | 16 + src/sonic-pac/mabmgr/mabmgr.cpp | 549 +++++++++++++++++++++++++++ src/sonic-pac/mabmgr/mabmgr.h | 97 +++++ src/sonic-pac/mabmgr/mabmgr_main.cpp | 101 +++++ 4 files changed, 763 insertions(+) create mode 100644 src/sonic-pac/mabmgr/Makefile.am create mode 100644 src/sonic-pac/mabmgr/mabmgr.cpp create mode 100644 src/sonic-pac/mabmgr/mabmgr.h create mode 100644 src/sonic-pac/mabmgr/mabmgr_main.cpp diff --git a/src/sonic-pac/mabmgr/Makefile.am b/src/sonic-pac/mabmgr/Makefile.am new file mode 100644 index 0000000000000..019ef7986b453 --- /dev/null +++ b/src/sonic-pac/mabmgr/Makefile.am @@ -0,0 +1,16 @@ +INCLUDES = -I $(top_srcdir)/mab -I $(top_srcdir)/mab/common -I $(top_srcdir)/mab/mapping/include -I $(top_srcdir)/fpinfra/inc -I $(top_srcdir)/mab/mapping/mab_sid -I $(top_srcdir)/mab/protocol/include -I $(top_srcdir)/authmgr/common -I $(top_srcdir)/../wpasupplicant/sonic-wpa-supplicant/src/radius + +bin_PROGRAMS = mabd + +if DEBUG +DBGFLAGS = -ggdb -DDEBUG +else +DBGFLAGS = -g -DNDEBUG +endif + +mabd_SOURCES = $(top_srcdir)/mabmgr/mabmgr_main.cpp $(top_srcdir)/mabmgr/mabmgr.cpp + +mabd_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(SONIC_COMMON_CFLAGS) + +AM_LDFLAGS = -L$(top_srcdir)/fpinfra/ -lfpinfra +AM_LDFLAGS += -lswsscommon -lnl-3 -lnl-route-3 -lhiredis -L$(top_srcdir)/mab/ -lmab $(SONIC_COMMON_LDFLAGS) diff --git a/src/sonic-pac/mabmgr/mabmgr.cpp b/src/sonic-pac/mabmgr/mabmgr.cpp new file mode 100644 index 0000000000000..8ec30672bab3b --- /dev/null +++ b/src/sonic-pac/mabmgr/mabmgr.cpp @@ -0,0 +1,549 @@ +/* + * Copyright 2019 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "mabmgr.h" +#include "mab_api.h" +#include "mab_exports.h" +#include "mab_include.h" +#include "datatypes.h" +#include "nimapi.h" +#include +#include +#include "fpSonicUtils.h" + +#define MABD_CMD_BUFFSZ 2048 +MabMgr *mab; + +const string INTFS_PREFIX = "E"; + +MabMgr::MabMgr(DBConnector *configDb, DBConnector *stateDb, DBConnector *appDb) : + m_confMabPortTbl(configDb, "MAB_PORT_CONFIG_TABLE"), + m_confRadiusServerTable(configDb, "RADIUS_SERVER"), + m_confRadiusGlobalTable(configDb, "RADIUS") { + + Logger::linkToDbNative("mabmgr"); + mab = this; +} + +std::vector MabMgr::getSelectables() { + vector selectables{ &m_confMabPortTbl, &m_confRadiusServerTable, &m_confRadiusGlobalTable }; + return selectables; +} + + +bool MabMgr::processDbEvent(Selectable *tbl) { + + SWSS_LOG_DEBUG("Received a MAB Database event"); + + //check the source table and accordingly invoke the appropriate handlers + + if (tbl == ((Selectable *) & m_confMabPortTbl)) { + return processMabConfigPortTblEvent(tbl); + } + + if (tbl == ((Selectable *) & m_confRadiusServerTable)) { + return processRadiusServerTblEvent(tbl); + } + + if (tbl == ((Selectable *) & m_confRadiusGlobalTable)) { + return processRadiusGlobalTblEvent(tbl); + } + + SWSS_LOG_DEBUG("Received event UNKNOWN to MAB, ignoring "); + return false; +} + +//Process the config db table events + +bool MabMgr::processMabConfigPortTblEvent(Selectable *tbl) +{ + SWSS_LOG_ENTER(); + SWSS_LOG_DEBUG("Received a table config event on MAB_PORT_CONFIG_TABLE table"); + + std::deque entries; + m_confMabPortTbl.pops(entries); + + SWSS_LOG_DEBUG("Received %d entries", (int) entries.size()); + + /* Nothing popped */ + if (entries.empty()) + { + return false; + } + + // Check through all the data + for (auto entry : entries) + { + std::string key = kfvKey(entry); + std::string op = kfvOp(entry); + bool task_result = false; + uint32 intIfNum; + + SWSS_LOG_DEBUG("Received %s as key and %s as OP", key.c_str(), op.c_str()); + + if(key.find(INTFS_PREFIX) == string::npos) + { + SWSS_LOG_NOTICE("Invalid key format. No 'E' prefix: %s", key.c_str()); + continue; + } + + if(fpGetIntIfNumFromHostIfName(key.c_str(), &intIfNum) != SUCCESS) + { + SWSS_LOG_NOTICE("Unable to get the internal interface number for %s.", key.c_str()); + continue; + } + + if (op == SET_COMMAND) + { + task_result = doMabPortTableSetTask(entry, intIfNum); + } + else if (op == DEL_COMMAND) + { + task_result = doMabPortTableDeleteTask(entry, intIfNum); + } + if (!task_result) + return false; + } + return true; +} + +bool MabMgr::doMabPortTableSetTask(const KeyOpFieldsValuesTuple & t, uint32 & intIfNum) +{ + SWSS_LOG_ENTER(); + const std::string & key = kfvKey(t); + + // Update mabPortConfigCache cache with incoming table data + mabPortConfigCacheParams_t mabPortConfigCache; + mabPortConfigCache.mab_enable = MABMGR_MAB_PORT_ENABLE_DEF; + mabPortConfigCache.mab_auth_type = MABMGR_MAB_PORT_AUTH_TYPE_DEF; + + for (auto item = kfvFieldsValues(t).begin(); item != kfvFieldsValues(t).end(); item++) + { + const std::string & field = fvField(*item); + const std::string & value = fvValue(*item); + + if (field == "mab_enable") + { + if (value == "true") + mabPortConfigCache.mab_enable = ENABLE; + else if (value == "false") + mabPortConfigCache.mab_enable = DISABLE; + else { + SWSS_LOG_WARN("Invalid configuration option received for mab enable: %s", value.c_str()); + continue; + } + } + if (field == "mab_auth_type") + { + if (value == "pap") + mabPortConfigCache.mab_auth_type= AUTHMGR_PORT_MAB_AUTH_TYPE_PAP; + else if (value == "chap") + mabPortConfigCache.mab_auth_type = AUTHMGR_PORT_MAB_AUTH_TYPE_CHAP; + else if (value == "eap-md5") + mabPortConfigCache.mab_auth_type = AUTHMGR_PORT_MAB_AUTH_TYPE_EAP_MD5; + else { + SWSS_LOG_WARN("Invalid configuration option received for mab auth type: %s", value.c_str()); + continue; + } + } + } + + mabPortConfigTableMap::iterator iter = m_mabPortConfigMap.find(key); + if(iter == m_mabPortConfigMap.end()) + { + m_mabPortConfigMap.insert(pair(key, mabPortConfigCache)); + mabPortConfigTableMap::iterator iter = m_mabPortConfigMap.find(key); + + if(mabPortConfigCache.mab_enable != MABMGR_MAB_PORT_ENABLE_DEF) + { + if ( SUCCESS != mabPortMABEnableSet(intIfNum, mabPortConfigCache.mab_enable)) + { + iter->second.mab_enable = MABMGR_MAB_PORT_ENABLE_DEF; + SWSS_LOG_ERROR("Unable to enable MAB operationally."); + } + } + if(mabPortConfigCache.mab_auth_type != MABMGR_MAB_PORT_AUTH_TYPE_DEF) + { + if ( SUCCESS != mabPortMABAuthTypeSet(intIfNum, mabPortConfigCache.mab_auth_type)) + { + iter->second.mab_auth_type = MABMGR_MAB_PORT_AUTH_TYPE_DEF; + SWSS_LOG_ERROR("Unable to set MAB authentication type operationally."); + } + } + } + else //Interface entry already exists in local cache, check for any parameter change for Add/Update/Delete + { + // mab_enable + if (((iter->second.mab_enable == MABMGR_MAB_PORT_ENABLE_DEF) && + (mabPortConfigCache.mab_enable != MABMGR_MAB_PORT_ENABLE_DEF)) || + ((iter->second.mab_enable != MABMGR_MAB_PORT_ENABLE_DEF) && + (mabPortConfigCache.mab_enable != iter->second.mab_enable))) + { + if ( SUCCESS == mabPortMABEnableSet(intIfNum, mabPortConfigCache.mab_enable)) + { + iter->second.mab_enable = mabPortConfigCache.mab_enable; + } + else + { + SWSS_LOG_ERROR("Unable to enable/disable MAB operationally."); + return false; + } + } + // mab_auth_type + if (((iter->second.mab_auth_type == MABMGR_MAB_PORT_AUTH_TYPE_DEF) && + (mabPortConfigCache.mab_auth_type != MABMGR_MAB_PORT_AUTH_TYPE_DEF)) || + ((iter->second.mab_auth_type != MABMGR_MAB_PORT_AUTH_TYPE_DEF) && + (mabPortConfigCache.mab_auth_type != iter->second.mab_auth_type))) + { + if ( SUCCESS == mabPortMABAuthTypeSet(intIfNum, mabPortConfigCache.mab_auth_type)) + { + iter->second.mab_auth_type = mabPortConfigCache.mab_auth_type; + } + else + { + SWSS_LOG_ERROR("Unable to set MAB authentication type operationally."); + return false; + } + } + } + return true; +} + +bool MabMgr::doMabPortTableDeleteTask(const KeyOpFieldsValuesTuple & t, uint32 & intIfNum) +{ + SWSS_LOG_ENTER(); + const std::string & key = kfvKey(t); + mabPortConfigTableMap::iterator iter = m_mabPortConfigMap.find(key); + if(iter != m_mabPortConfigMap.end()) + { + if (iter->second.mab_enable != MABMGR_MAB_PORT_ENABLE_DEF) + { + if ( SUCCESS == mabPortMABEnableSet(intIfNum, MABMGR_MAB_PORT_ENABLE_DEF)) + { + iter->second.mab_enable = MABMGR_MAB_PORT_ENABLE_DEF; + } + else + { + SWSS_LOG_ERROR("Unable to set MAB enable with default."); + return false; + } + } + if (iter->second.mab_auth_type != MABMGR_MAB_PORT_AUTH_TYPE_DEF) + { + if ( SUCCESS == mabPortMABAuthTypeSet(intIfNum, MABMGR_MAB_PORT_AUTH_TYPE_DEF)) + { + iter->second.mab_auth_type = MABMGR_MAB_PORT_AUTH_TYPE_DEF; + } + else + { + SWSS_LOG_ERROR("Unable to set MAB authentication type with default."); + return false; + } + } + } + return true; +} + +void MabMgr::updateRadiusServerGlobalKey(string newKey, string oldKey) { + + SWSS_LOG_ENTER(); + bool update = false; + RC_t rc = FAILURE; + + if (0 == newKey.compare(oldKey)) + { + return; + } + + for (auto& item: m_radius_info.radius_auth_server_list) + { + /* server specific is configured */ + if (0 != item.second.server_key.size()) + { + continue; + } + + /* Check and update Radius server if using Global key */ + if (0 != newKey.size()) + { + item.second.server_update = true; + update = true; + } + else + { + rc = mabRadiusServerUpdate(RADIUS_MAB_SERVER_DELETE, "auth", + item.second.server_ip.c_str(), + item.second.server_priority.c_str(), + oldKey.c_str(), + item.second.server_port.c_str()); + if ( SUCCESS != rc) + { + SWSS_LOG_ERROR("Unable to update radius server details for MAB ip = %s, port = %s, priority = %s", + item.second.server_ip.c_str(), + item.second.server_port.c_str(), + item.second.server_priority.c_str()); + } + } + } + + /* Due to global key change update server needed */ + if (true == update) + { + updateRadiusServer(); + } +} + +void MabMgr::updateRadiusServer() { + + SWSS_LOG_ENTER(); + RC_t rc = FAILURE; + struct addrinfo* result; + char ip[INET6_ADDRSTRLEN+1]; + void * src = NULL; + + SWSS_LOG_NOTICE("Deriving new RADIUS Servers for MAB"); + + for (auto& item: m_radius_info.radius_auth_server_list) + { + if (false == item.second.server_update) + { + SWSS_LOG_INFO("skipped %s as update not needed.", item.first.c_str()); + continue; + } + + if (getaddrinfo(item.first.c_str(), NULL, NULL, &result) || result == NULL) + { + SWSS_LOG_WARN("skipped %s as it could not resolve.", item.first.c_str()); + item.second.dns_ok = false; + continue; + } + + if(result->ai_family == AF_INET) + src = &((struct sockaddr_in*)result->ai_addr)->sin_addr; + else + src = &((struct sockaddr_in6*)result->ai_addr)->sin6_addr; + + inet_ntop(result->ai_family, src, ip, INET6_ADDRSTRLEN+1); + freeaddrinfo(result); + + //Check if radius server has key configured. If not, + // pick global key. If key does not exist, skip to next server. + if ((item.second.server_key == "") && (m_radius_info.m_radiusGlobalKey == "")) + { + SWSS_LOG_WARN("skipped %s as no key is configured.", item.first.c_str()); + continue; + } + + string newKey = m_radius_info.m_radiusGlobalKey; + if (item.second.server_key != "") + { + newKey = item.second.server_key; + } + + string radiusIp(ip); + item.second.server_ip = radiusIp; + + rc = mabRadiusServerUpdate(RADIUS_MAB_SERVER_ADD, "auth", item.second.server_ip.c_str(), + item.second.server_priority.c_str(), + newKey.c_str(), + item.second.server_port.c_str()); + if ( SUCCESS != rc) + { + SWSS_LOG_ERROR("Radius server update - Unable to update radius server details for MAB."); + return; + } + SWSS_LOG_NOTICE("Updating radius details for MAB ip = %s, port = %s, priority = %s", + item.second.server_ip.c_str(), + item.second.server_port.c_str(), + item.second.server_priority.c_str()); + item.second.server_update = false; + item.second.dns_ok = true; + } + return; +} + +void MabMgr::reloadRadiusServers() +{ + SWSS_LOG_ENTER(); + RC_t rc = FAILURE; + bool server_update = false; + + SWSS_LOG_NOTICE("Reloading RADIUS Servers for MAB"); + + /*Check for servers that failed DNS resolution */ + for (auto& item: m_radius_info.radius_auth_server_list) + { + if (false == item.second.dns_ok) + { + item.second.server_update = true; + server_update = true; + } + } + + if (true == server_update) + { + SWSS_LOG_NOTICE("Reloading DNS failed RADIUS Servers for MAB"); + updateRadiusServer(); + } + + rc = mabRadiusServerUpdate(RADIUS_MAB_SERVERS_RELOAD, "auth", + NULL, NULL, NULL, NULL); + + if ( SUCCESS != rc) + { + SWSS_LOG_ERROR("RADIUS Servers reload - Unable to reload."); + } + + return; +} + +bool MabMgr::processRadiusServerTblEvent(Selectable *tbl) +{ + SWSS_LOG_ENTER(); + SWSS_LOG_NOTICE("Received a RADIUS_SERVER event"); + + deque entries; + m_confRadiusServerTable.pops(entries); + + SWSS_LOG_NOTICE("Received %d entries", (int) entries.size()); + + /* Nothing popped */ + if (entries.empty()) + { + return false; + } + + // Check through all the data + for (auto entry : entries) + { + string key = kfvKey(entry); + string val = kfvOp(entry); + string cmd(""); + + SWSS_LOG_NOTICE("Received %s as key and %s as OP", key.c_str(), val.c_str()); + + if (val == SET_COMMAND) + { + SWSS_LOG_NOTICE("SET operation on RADIUS_SERVER table"); + + m_radius_info.radius_auth_server_list[key].server_port = ""; + m_radius_info.radius_auth_server_list[key].server_key = ""; + m_radius_info.radius_auth_server_list[key].server_priority = ""; + m_radius_info.radius_auth_server_list[key].server_update = true; + m_radius_info.radius_auth_server_list[key].dns_ok = true; + + // Look at the data that is sent for this key + + for (auto i : kfvFieldsValues(entry)) + { + string a = fvField(i); + string b = fvValue(i); + + SWSS_LOG_DEBUG("Received %s as field and %s as value", a.c_str(), b.c_str()); + + if (a == "passkey") + { + m_radius_info.radius_auth_server_list[key].server_key = b; + } + else if (a == "auth_port") + { + m_radius_info.radius_auth_server_list[key].server_port = b; + } + else if (a == "priority") + { + m_radius_info.radius_auth_server_list[key].server_priority = b; + } + } + updateRadiusServer(); + } + else if (val == DEL_COMMAND) + { + RC_t rc = FAILURE; + SWSS_LOG_INFO("Delete Radius server for MAB %s ", + m_radius_info.radius_auth_server_list[key].server_ip.c_str()); + // server deleted + rc = mabRadiusServerUpdate(RADIUS_MAB_SERVER_DELETE, "auth", + m_radius_info.radius_auth_server_list[key].server_ip.c_str(), + m_radius_info.radius_auth_server_list[key].server_priority.c_str(), + m_radius_info.radius_auth_server_list[key].server_key.c_str(), + m_radius_info.radius_auth_server_list[key].server_port.c_str()); + if (rc != SUCCESS) + { + SWSS_LOG_ERROR("Radius server delete - Unable to delete radius server details for MAB."); + } + m_radius_info.radius_auth_server_list.erase(key); + } + } + + return true; +} + +bool MabMgr::processRadiusGlobalTblEvent(Selectable *tbl) +{ + SWSS_LOG_ENTER(); + SWSS_LOG_NOTICE("Received a RADIUS event"); + string tmp_radiusGlobalKey(m_radius_info.m_radiusGlobalKey); + + deque entries; + m_confRadiusGlobalTable.pops(entries); + + SWSS_LOG_NOTICE("Received %d entries", (int) entries.size()); + + /* Nothing popped */ + if (entries.empty()) + { + return false; + } + + // Check through all the data + for (auto entry : entries) + { + string key = kfvKey(entry); + string val = kfvOp(entry); + string cmd(""); + + SWSS_LOG_NOTICE("Received %s as key and %s as OP", key.c_str(), val.c_str()); + + if (val == SET_COMMAND) + { + SWSS_LOG_NOTICE("SET operation on RADIUS table"); + + // Look at the data that is sent for this key + for (auto i : kfvFieldsValues(entry)) + { + string a = fvField(i); + string b = fvValue(i); + + SWSS_LOG_DEBUG("Received %s as field and %s as value", a.c_str(), b.c_str()); + + if (a == "passkey") + { + m_radius_info.m_radiusGlobalKey = b; + } + } + } + else if (val == DEL_COMMAND) + { + m_radius_info.m_radiusGlobalKey = ""; + } + } + + updateRadiusServerGlobalKey(m_radius_info.m_radiusGlobalKey, tmp_radiusGlobalKey); + + return true; +} diff --git a/src/sonic-pac/mabmgr/mabmgr.h b/src/sonic-pac/mabmgr/mabmgr.h new file mode 100644 index 0000000000000..17bbc4a226f38 --- /dev/null +++ b/src/sonic-pac/mabmgr/mabmgr.h @@ -0,0 +1,97 @@ +/* + * Copyright 2019 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _MABMGR_H_ +#define _MABMGR_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "redisapi.h" +#include "auth_mgr_exports.h" +#include "mab_exports.h" + +typedef struct radius_server_info_s { + std::string server_port; + std::string server_key; + std::string server_ip; + std::string server_priority; + bool server_update; + bool dns_ok; +}radius_server_info_t; + +typedef std::map radius_server_info_map_t; + +typedef struct radius_info_s { + std::string m_radiusGlobalKey; + radius_server_info_map_t radius_auth_server_list; +}radius_info_t; + +#define MABMGR_MAB_PORT_ENABLE_DEF DISABLE +#define MABMGR_MAB_PORT_AUTH_TYPE_DEF AUTHMGR_PORT_MAB_AUTH_TYPE_EAP_MD5 + +/* MAB port config table param cache Info */ +typedef struct mabPortConfigCacheParams_t { + bool mab_enable; + AUTHMGR_PORT_MAB_AUTH_TYPE_t mab_auth_type; +} mabPortConfigCacheParams_t; + +/* MAP to store MAB port config table params, + * Key is "interface-id" (Eg. Ethernet0) + * Value is "mabPortConfigCacheParams_t" + */ +typedef std::map mabPortConfigTableMap; + +using namespace swss; +using namespace std; + +class MabMgr +{ +public: + MabMgr(DBConnector *configDb, DBConnector *stateDb, DBConnector *appDb); + std::vector getSelectables(); + bool processDbEvent(Selectable *source); + +private: + //tables this component listens to + SubscriberStateTable m_confMabPortTbl; + SubscriberStateTable m_confRadiusServerTable; + SubscriberStateTable m_confRadiusGlobalTable; + + radius_info_t m_radius_info; + mabPortConfigTableMap m_mabPortConfigMap; + + // DB Event handler functions + bool processMabConfigPortTblEvent(Selectable *tbl); + bool processRadiusServerTblEvent(Selectable *tbl); + bool processRadiusGlobalTblEvent(Selectable *tbl); + bool doMabPortTableSetTask(const KeyOpFieldsValuesTuple & t, uint32 & intIfNum); + bool doMabPortTableDeleteTask(const KeyOpFieldsValuesTuple & t, uint32 & intIfNum); + + void updateRadiusServer(); + void updateRadiusServerGlobalKey(std::string newKey, std::string oldKey); + void reloadRadiusServers() ; +}; + +#endif // _MABMGR_H_ diff --git a/src/sonic-pac/mabmgr/mabmgr_main.cpp b/src/sonic-pac/mabmgr/mabmgr_main.cpp new file mode 100644 index 0000000000000..4172eaf9d8752 --- /dev/null +++ b/src/sonic-pac/mabmgr/mabmgr_main.cpp @@ -0,0 +1,101 @@ +/* + * Copyright 2019 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include "datatypes.h" +#include "osapi.h" +#include "mabmgr.h" +#include "mab_include.h" +#include +#include "fpinfra.h" + +int main(int argc, char *argv[]) +{ + cout<<"Invoking fpinfraInit" << endl; + fpinfraInit(); + + if (mabInit () != SUCCESS) + cout<<"Fail" << endl; + else + cout<<"Success linked" << endl; + + if (osapiWaitForTaskInit ( MAB_DB_TASK_SYNC, WAIT_FOREVER) != + SUCCESS) + { + return -1; + } + + cout<<"DB_TASK_SYNC Success" << endl; + + /* Set log level MSG_DEBUG to get hostapd logs for debugging purposes + * Use the below values from wpa_debug.h + * enum { MSG_EXCESSIVE, MSG_MSGDUMP, MSG_DEBUG, MSG_INFO, MSG_WARNING, MSG_ERROR }; + */ + // mab_radius_server_debug_level_set(2 /*MSG_DEBUG*/); + + try + { + SWSS_LOG_NOTICE("-----Starting MabMgr-----"); + sleep(20); + swss::DBConnector stateDb("STATE_DB", 0); + swss::DBConnector configDb("CONFIG_DB", 0); + swss::DBConnector appDb("APPL_DB", 0); + + MabMgr mab(&configDb, &stateDb, &appDb); + +#if 0 + // App Marking closest UP status + Table feat_tbl(&stateDb, STATE_FEATURE_TABLE_NAME); + std::vector attrs; + FieldValueTuple up_ready_status("UP_STATUS", "True"); + FieldValueTuple fail_reason("FAIL_REASON", ""); + char buffer[100]; + std::time_t rawtime; + struct tm *timeinfo; + time(&rawtime); + timeinfo = gmtime(&rawtime); + strftime(buffer, 100, "%Y-%m-%d %H:%M:%S", timeinfo); + FieldValueTuple time("TIME", string(buffer)); + attrs.push_back(up_ready_status); + attrs.push_back(fail_reason); + attrs.push_back(time); + feat_tbl.set("mabd", attrs); + SWSS_LOG_NOTICE("mabd marked its UP Status to True"); +#endif + //register for the table events + swss::Select s; + s.addSelectables(mab.getSelectables()); + + //wait for the events and process them + while (true) + { + SWSS_LOG_NOTICE("Waiting for MAB Table Events"); + + swss::Selectable *sel = NULL; + s.select(&sel); + + //Pass on the processing to the Mab Manager + mab.processDbEvent(sel); + } + + } + catch (const exception &e) + { + SWSS_LOG_ERROR("Runtime error: %s", e.what()); + } + return -1; +}