diff --git a/src/DbInterface.cpp b/src/DbInterface.cpp index 75e8031b..621904b2 100644 --- a/src/DbInterface.cpp +++ b/src/DbInterface.cpp @@ -132,6 +132,23 @@ void DbInterface::probeMuxState(const std::string &portName) ))); } +// +// ---> probeForwardingState(const std::string &portName) +// +// trigger tranceiver daemon to read Fowarding state using gRPC +// +void DbInterface::probeForwardingState(const std::string &portName) +{ + MUXLOGDEBUG(portName); + + boost::asio::io_service &ioService = mStrand.context(); + ioService.post(mStrand.wrap(boost::bind( + &DbInterface::handleProbeForwardingState, + this, + portName + ))); +} + // // ---> setMuxLinkmgrState(const std::string &portName, link_manager::ActiveStandbyStateMachine::Label label); // @@ -251,11 +268,14 @@ void DbInterface::initialize() mAppDbMuxTablePtr = std::make_shared ( mAppDbPtr.get(), APP_MUX_CABLE_TABLE_NAME ); + mAppDbPeerMuxTablePtr = std::make_shared ( + mAppDbPtr.get(), APP_PEER_HW_FORWARDING_STATE_TABLE_NAME + ); mAppDbMuxCommandTablePtr = std::make_shared ( mAppDbPtr.get(), APP_MUX_CABLE_COMMAND_TABLE_NAME ); - mAppDbPeerMuxCommandTablePtr = std::make_shared ( - mAppDbPtr.get(), PEER_FORWARDING_STATE_COMMAND_TABLE + mAppDbForwardingCommandTablePtr = std::make_shared ( + mAppDbPtr.get(), APP_FORWARDING_STATE_COMMAND_TABLE_NAME ); mStateDbMuxLinkmgrTablePtr = std::make_shared ( mStateDbPtr.get(), STATE_MUX_LINKMGR_TABLE_NAME @@ -352,7 +372,7 @@ void DbInterface::handleSetPeerMuxState(const std::string portName, mux_state::M std::vector values = { {"state", mMuxState[label]}, }; - mAppDbPeerMuxCommandTablePtr->set(portName, values); + mAppDbPeerMuxTablePtr->set(portName, values); } } @@ -368,6 +388,18 @@ void DbInterface::handleProbeMuxState(const std::string portName) mAppDbMuxCommandTablePtr->hset(portName, "command", "probe"); } +// +// ---> handleProbeForwardingState(const std::string portName) +// +// trigger xcvrd to read forwarding state using gRPC +// +void DbInterface::handleProbeForwardingState(const std::string portName) +{ + MUXLOGDEBUG(portName); + + mAppDbForwardingCommandTablePtr->hset(portName, "command", "probe"); +} + // // ---> handleSetMuxLinkmgrState(const std::string portName, link_manager::ActiveStandbyStateMachine::Label label); // @@ -988,6 +1020,56 @@ void DbInterface::processMuxResponseNotifiction(std::deque processForwardingResponseNotification(std::deque &entries); +// +// process forwarding response (from xcvrd probing) notification +// +void DbInterface::processForwardingResponseNotification(std::deque &entries) +{ + for (auto &entry: entries) { + std::string port = kfvKey(entry); + std::string oprtation = kfvOp(entry); + std::vector fieldValues = kfvFieldsValues(entry); + + std::vector::const_iterator cit_self = std::find_if( + fieldValues.cbegin(), + fieldValues.cend(), + [] (const swss::FieldValueTuple &fv) {return fvField(fv) == "response";} + ); + if (cit_self != fieldValues.cend()) { + const std::string f = cit_self->first; + const std::string v = cit_self->second; + + MUXLOGDEBUG(boost::format("port: %s, operation: %s, f: %s, v: %s") % + port % + oprtation % + f % + v + ); + mMuxManagerPtr->processProbeMuxState(port, v); + } + + std::vector::const_iterator cit_peer = std::find_if( + fieldValues.cbegin(), + fieldValues.cend(), + [] (const swss::FieldValueTuple &fv) {return fvField(fv) == "response_peer";} + ); + if (cit_peer != fieldValues.cend()) { + const std::string f = cit_peer->first; + const std::string v = cit_peer->second; + + MUXLOGDEBUG(boost::format("port: %s, operation: %s, f: %s, v: %s") % + port % + oprtation % + f % + v + ); + mMuxManagerPtr->processPeerMuxState(port, v); + } + } +} + // // ---> handleMuxResponseNotifiction(swss::SubscriberStateTable &appdbPortTable); // @@ -1001,12 +1083,26 @@ void DbInterface::handleMuxResponseNotifiction(swss::SubscriberStateTable &appdb processMuxResponseNotifiction(entries); } +// +// ---> handleForwardingResponseNotification(swss::SubscriberStateTable &appdbForwardingResponseTable) +// +// handle fowarding response (from xcvrd) notification +// +void DbInterface::handleForwardingResponseNotification(swss::SubscriberStateTable &appdbForwardingResponseTable) +{ + std::deque entries; + + appdbForwardingResponseTable.pops(entries); + processForwardingResponseNotification(entries); +} + + // // ---> processPeerMuxResponseNotification(std::deque &entries); // -// process peer MUX response (from xcvrd) notification +// process peer MUX state (from xcvrd) notification // -void DbInterface::processPeerMuxResponseNotification(std::deque &entries) +void DbInterface::processPeerMuxNotification(std::deque &entries) { for (auto &entry: entries) { std::string port = kfvKey(entry); @@ -1034,16 +1130,16 @@ void DbInterface::processPeerMuxResponseNotification(std::deque handlePeerMuxResponseNotification(swss::SubscriberStateTable &stateDbPeerMuxResponseTable); +// ---> handlePeerMuxStateNotification(swss::SubscriberStateTable &stateDbPeerMuxTable); // -// handles peer MUX response (from xcvrd) notification +// handles peer MUX notification (from xcvrd) // -void DbInterface::handlePeerMuxResponseNotification(swss::SubscriberStateTable &stateDbPeerMuxResponseTable) +void DbInterface::handlePeerMuxStateNotification(swss::SubscriberStateTable &stateDbPeerMuxTable) { std::deque entries; - stateDbPeerMuxResponseTable.pops(entries); - processPeerMuxResponseNotification(entries); + stateDbPeerMuxTable.pops(entries); + processPeerMuxNotification(entries); } // @@ -1164,6 +1260,8 @@ void DbInterface::handleSwssNotification() swss::SubscriberStateTable appDbPortTable(appDbPtr.get(), APP_PORT_TABLE_NAME); // for command responses from the driver swss::SubscriberStateTable appDbMuxResponseTable(appDbPtr.get(), APP_MUX_CABLE_RESPONSE_TABLE_NAME); + // for command response of forwarding state probing from driver + swss::SubscriberStateTable appDbForwardingResponseTable(appDbPtr.get(), APP_FORWARDING_STATE_RESPONSE_TABLE_NAME); // for getting state db MUX state when orchagent updates it swss::SubscriberStateTable stateDbPortTable(stateDbPtr.get(), STATE_MUX_CABLE_TABLE_NAME); // for getting state db default route state @@ -1171,7 +1269,7 @@ void DbInterface::handleSwssNotification() // for getting peer's link status swss::SubscriberStateTable stateDbMuxInfoTable(stateDbPtr.get(), MUX_CABLE_INFO_TABLE); // for getting peer's admin forwarding state - swss::SubscriberStateTable stateDbPeerMuxResponseTable(stateDbPtr.get(), PEER_FORWARDING_STATE_RESPONSE_TABLE); + swss::SubscriberStateTable stateDbPeerMuxTable(stateDbPtr.get(), STATE_PEER_HW_FORWARDING_STATE_TABLE_NAME); getTorMacAddress(configDbPtr); getLoopback2InterfaceInfo(configDbPtr); @@ -1192,10 +1290,11 @@ void DbInterface::handleSwssNotification() swssSelect.addSelectable(&configDbMuxTable); swssSelect.addSelectable(&appDbPortTable); swssSelect.addSelectable(&appDbMuxResponseTable); + swssSelect.addSelectable(&appDbForwardingResponseTable); swssSelect.addSelectable(&stateDbPortTable); swssSelect.addSelectable(&stateDbRouteTable); swssSelect.addSelectable(&stateDbMuxInfoTable); - swssSelect.addSelectable(&stateDbPeerMuxResponseTable); + swssSelect.addSelectable(&stateDbPeerMuxTable); swssSelect.addSelectable(&netlinkNeighbor); while (mPollSwssNotifcation) { @@ -1220,14 +1319,16 @@ void DbInterface::handleSwssNotification() handleLinkStateNotifiction(appDbPortTable); } else if (selectable == static_cast (&appDbMuxResponseTable)) { handleMuxResponseNotifiction(appDbMuxResponseTable); + } else if (selectable == static_cast (&appDbForwardingResponseTable)) { + handleForwardingResponseNotification(appDbForwardingResponseTable); } else if (selectable == static_cast (&stateDbPortTable)) { handleMuxStateNotifiction(stateDbPortTable); } else if (selectable == static_cast (&stateDbRouteTable)) { handleDefaultRouteStateNotification(stateDbRouteTable); } else if (selectable == static_cast (&stateDbMuxInfoTable)) { handlePeerLinkStateNotification(stateDbMuxInfoTable); - } else if (selectable == static_cast (&stateDbPeerMuxResponseTable)) { - handlePeerMuxResponseNotification(stateDbPeerMuxResponseTable); + } else if (selectable == static_cast (&stateDbPeerMuxTable)) { + handlePeerMuxStateNotification(stateDbPeerMuxTable); } else if (selectable == static_cast (&netlinkNeighbor)) { continue; } else { diff --git a/src/DbInterface.h b/src/DbInterface.h index 0e54fa32..cfad446b 100644 --- a/src/DbInterface.h +++ b/src/DbInterface.h @@ -46,8 +46,12 @@ namespace mux { #define MUX_CABLE_INFO_TABLE "MUX_CABLE_INFO" #define LINK_PROBE_STATS_TABLE_NAME "LINK_PROBE_STATS" -#define PEER_FORWARDING_STATE_COMMAND_TABLE "HW_FORWARDING_STATE_PEER" -#define PEER_FORWARDING_STATE_RESPONSE_TABLE "HW_MUX_CABLE_TABLE_PEER" + +#define APP_FORWARDING_STATE_COMMAND_TABLE_NAME "FORWARDING_STATE_COMMAND" +#define APP_FORWARDING_STATE_RESPONSE_TABLE_NAME "FORWARDING_STATE_RESPONSE" + +#define APP_PEER_HW_FORWARDING_STATE_TABLE_NAME "HW_FORWARDING_STATE_PEER" +#define STATE_PEER_HW_FORWARDING_STATE_TABLE_NAME "HW_MUX_CABLE_TABLE_PEER" class MuxManager; using ServerIpPortMap = std::map; @@ -158,6 +162,17 @@ class DbInterface */ virtual void probeMuxState(const std::string &portName); + /** + * @method probeForwardingState + * + * @brief trigger tranceiver daemon to read Fowarding state using gRPC + * + * @param portName (in) MUX/port name + * + * @return none + */ + virtual void probeForwardingState(const std::string &portName); + /** *@method setMuxLinkmgrState * @@ -308,6 +323,17 @@ class DbInterface */ void handleProbeMuxState(const std::string portName); + /** + * @method handleProbeForwardingState + * + * @brief trigger xcvrd to read forwarding state using gRPC + * + * @param portName (in) MUX/port name + * + * @return none + */ + void handleProbeForwardingState(const std::string portName); + /** *@method handleSetMuxLinkmgrState * @@ -582,6 +608,17 @@ class DbInterface */ inline void processMuxResponseNotifiction(std::deque &entries); + /** + * @method processForwardingResponseNotification + * + * @brief process forwarding response (from xcvrd probing) notification + * + * @param entries (in) reference to app db entries + * + * @return none + */ + inline void processForwardingResponseNotification(std::deque &entries); + /** *@method handleMuxResponseNotifiction * @@ -594,26 +631,33 @@ class DbInterface void handleMuxResponseNotifiction(swss::SubscriberStateTable &appdbPortTable); /** - *@method processPeerMuxResponseNotification + * @method handleForwardingResponseNotification + * + * @brief handle forwarding state response (from xcvrd probing) notification + */ + void handleForwardingResponseNotification(swss::SubscriberStateTable &appdbForwardingResponseTable); + + /** + *@method processPeerMuxNotification * - *@brief process peer MUX response (from xcvrd) notification + *@brief process peer MUX state (from xcvrd) notification * - *@param entries (in) reference to app db peer mux response table entries + *@param entries (in) reference to state db peer mux table entries * *@return none */ - inline void processPeerMuxResponseNotification(std::deque &entries); + inline void processPeerMuxNotification(std::deque &entries); /** - *@method handlePeerMuxResponseNotification + *@method handlePeerMuxStateNotification * - *@brief handles peer MUX response (from xcvrd) notification + *@brief handles peer MUX notification (from xcvrd) * - *@param appdbPortTable (in) reference to app db peer mux response table + *@param stateDbPeerMuxTable (in) reference to state db peer hw forwarding table * *@return none */ - void handlePeerMuxResponseNotification(swss::SubscriberStateTable &stateDbPeerMuxResponseTable); + void handlePeerMuxStateNotification(swss::SubscriberStateTable &stateDbPeerMuxTable); /** *@method processMuxStateNotifiction @@ -684,10 +728,12 @@ class DbInterface // for communicating with orchagent std::shared_ptr mAppDbMuxTablePtr; + // for communication with driver (setting peer's forwarding state) + std::shared_ptr mAppDbPeerMuxTablePtr; // for communicating with the driver (probing the mux) std::shared_ptr mAppDbMuxCommandTablePtr; - // for communicating with xcvrd to set peer mux state - std::shared_ptr mAppDbPeerMuxCommandTablePtr; + // for communication with the driver (probing forwarding state) + std::shared_ptr mAppDbForwardingCommandTablePtr; // for writing the current mux linkmgr health std::shared_ptr mStateDbMuxLinkmgrTablePtr; // for writing mux metrics diff --git a/src/MuxPort.cpp b/src/MuxPort.cpp index 1b2d2f11..f7e6bd00 100644 --- a/src/MuxPort.cpp +++ b/src/MuxPort.cpp @@ -364,4 +364,23 @@ void MuxPort::resetPckLossCount() ))); } +// +// ---> probeMuxState() +// +// trigger xcvrd to read MUX state using i2c +// +void MuxPort::probeMuxState() +{ + switch (mMuxPortConfig.getPortCableType()) { + case common::MuxPortConfig::PortCableType::ActiveActive: + mDbInterfacePtr->probeForwardingState(mMuxPortConfig.getPortName()); + break; + case common::MuxPortConfig::PortCableType::ActiveStandby: + mDbInterfacePtr->probeMuxState(mMuxPortConfig.getPortName()); + break; + default: + break; + } +} + } /* namespace mux */ diff --git a/src/MuxPort.h b/src/MuxPort.h index 4fd04e60..467d7fe6 100644 --- a/src/MuxPort.h +++ b/src/MuxPort.h @@ -145,7 +145,7 @@ class MuxPort: public std::enable_shared_from_this * *@return label of MUX state */ - inline void probeMuxState() {mDbInterfacePtr->probeMuxState(mMuxPortConfig.getPortName());}; + void probeMuxState(); /** *@method setMuxLinkmgrState diff --git a/test/FakeDbInterface.cpp b/test/FakeDbInterface.cpp index cf52fc9a..a02c4b9c 100644 --- a/test/FakeDbInterface.cpp +++ b/test/FakeDbInterface.cpp @@ -60,6 +60,11 @@ void FakeDbInterface::probeMuxState(const std::string &portName) mProbeMuxStateInvokeCount++; } +void FakeDbInterface::probeForwardingState(const std::string &portName) +{ + mProbeForwardingStateInvokeCount++; +} + void FakeDbInterface::setMuxLinkmgrState(const std::string &portName, link_manager::ActiveStandbyStateMachine::Label label) { mSetMuxLinkmgrStateInvokeCount++; diff --git a/test/FakeDbInterface.h b/test/FakeDbInterface.h index e1a4c662..b2381ae0 100644 --- a/test/FakeDbInterface.h +++ b/test/FakeDbInterface.h @@ -40,6 +40,7 @@ class FakeDbInterface: public mux::DbInterface virtual void setPeerMuxState(const std::string &portName, mux_state::MuxState::Label label) override; virtual void getMuxState(const std::string &portName) override; virtual void probeMuxState(const std::string &portName) override; + virtual void probeForwardingState(const std::string &portName) override; virtual void setMuxLinkmgrState( const std::string &portName, link_manager::ActiveStandbyStateMachine::Label label @@ -75,6 +76,7 @@ class FakeDbInterface: public mux::DbInterface uint32_t mSetPeerMuxStateInvokeCount = 0; uint32_t mGetMuxStateInvokeCount = 0; uint32_t mProbeMuxStateInvokeCount = 0; + uint32_t mProbeForwardingStateInvokeCount = 0; uint32_t mSetMuxLinkmgrStateInvokeCount = 0; uint32_t mPostMetricsInvokeCount = 0; uint32_t mPostLinkProberMetricsInvokeCount = 0;