From dddecaab7f4dcb788c62a46d2f35c39ebe33f86e Mon Sep 17 00:00:00 2001 From: Madhu Challa Date: Tue, 3 Sep 2024 12:18:34 -0700 Subject: [PATCH] Reset all peers during vmotion interval Use outOfBandConfigUpdated and outOfBandConfigDeleted to figure out interval and during this period if a disconnect happens we will reset both peers and fallback to configured list This avoids issues where we miss the platformConfigDelete event during vmotion. This basically does the same thing as what the reset.conf fix would do in case we miss that event. Signed-off-by: Madhu Challa --- agent-ovs/lib/ExtraConfigManager.cpp | 2 ++ libopflex/engine/OpflexClientConnection.cpp | 32 ++++++++++++------- libopflex/engine/OpflexPool.cpp | 1 + .../engine/internal/OpflexClientConnection.h | 1 + .../opflex/engine/internal/OpflexPool.h | 9 ++++++ libopflex/include/opflex/ofcore/OFFramework.h | 14 ++++++++ libopflex/ofcore/OFFramework.cpp | 10 ++++++ 7 files changed, 58 insertions(+), 11 deletions(-) diff --git a/agent-ovs/lib/ExtraConfigManager.cpp b/agent-ovs/lib/ExtraConfigManager.cpp index fb691d89..fd24890b 100644 --- a/agent-ovs/lib/ExtraConfigManager.cpp +++ b/agent-ovs/lib/ExtraConfigManager.cpp @@ -123,6 +123,7 @@ void ExtraConfigManager::outOfBandConfigUpdated(const OutOfBandConfigSpec &outOf mutator.commit(); shared_ptr oobSptr(new OutOfBandConfigSpec(outOfBandCfg.tunnelEpAdvInterval)); notifyOutOfBandConfigListeners(oobSptr); + framework.setResetAllPeers(true); } void ExtraConfigManager::outOfBandConfigDeleted() { @@ -138,6 +139,7 @@ void ExtraConfigManager::outOfBandConfigDeleted() { mutator.commit(); shared_ptr oobSptr; notifyOutOfBandConfigListeners(oobSptr); + framework.setResetAllPeers(false); } void ExtraConfigManager::packetDropLogConfigUpdated(PacketDropLogConfig &dropCfg) { diff --git a/libopflex/engine/OpflexClientConnection.cpp b/libopflex/engine/OpflexClientConnection.cpp index 322c43d6..23a33678 100644 --- a/libopflex/engine/OpflexClientConnection.cpp +++ b/libopflex/engine/OpflexClientConnection.cpp @@ -160,17 +160,21 @@ void OpflexClientConnection::on_state_change(Peer * p, void * data, case yajr::StateChange::DISCONNECT: LOG(INFO) << "[" << conn->getRemotePeer() << "] " << "Disconnected"; - - uv_timer_stop(conn->handshake_timer); - conn->active = false; - conn->ready = false; - conn->handler->disconnected(); - conn->cleanup(); - - if (!conn->closing) - conn->pool->updatePeerStatus(conn->hostname, conn->port, - PeerStatusListener::CONNECTING); - break; + if (conn->pool->getResetAllPeers() && + !conn->pool->isConfiguredPeer(conn->hostname, conn->port)) { + conn->resetAllUnconfiguredPeers(); + } else { + uv_timer_stop(conn->handshake_timer); + conn->active = false; + conn->ready = false; + conn->handler->disconnected(); + conn->cleanup(); + + if (!conn->closing) + conn->pool->updatePeerStatus(conn->hostname, conn->port, + PeerStatusListener::CONNECTING); + } + break; case yajr::StateChange::TRANSPORT_FAILURE: { char buf[120]; @@ -210,6 +214,12 @@ void OpflexClientConnection::connectionFailure() { } } +void OpflexClientConnection::resetAllUnconfiguredPeers() { + LOG(WARNING) << "Disconnect from existing peers and fallback to configured list"; + pool->resetAllUnconfiguredPeers(); + pool->addConfiguredPeers(); +} + void OpflexClientConnection::messagesReady() { pool->messagesReady(); } diff --git a/libopflex/engine/OpflexPool.cpp b/libopflex/engine/OpflexPool.cpp index a417d679..24b1b7ce 100644 --- a/libopflex/engine/OpflexPool.cpp +++ b/libopflex/engine/OpflexPool.cpp @@ -34,6 +34,7 @@ OpflexPool::OpflexPool(HandlerFactory& factory_, util::ThreadManager& threadManager_) : factory(factory_), threadManager(threadManager_), active(false), + reset_all_peers(false), client_mode(OFConstants::OpflexElementMode::STITCHED_MODE), transport_state(OFConstants::OpflexTransportModeState::SEEKING_PROXIES), ipv4_proxy(0), ipv6_proxy(0), diff --git a/libopflex/engine/include/opflex/engine/internal/OpflexClientConnection.h b/libopflex/engine/include/opflex/engine/internal/OpflexClientConnection.h index 8a91e1bd..878a69b4 100644 --- a/libopflex/engine/include/opflex/engine/internal/OpflexClientConnection.h +++ b/libopflex/engine/include/opflex/engine/internal/OpflexClientConnection.h @@ -131,6 +131,7 @@ class OpflexClientConnection : public OpflexConnection { yajr::StateChange::To stateChange, int error); void connectionFailure(); + void resetAllUnconfiguredPeers(); }; diff --git a/libopflex/engine/include/opflex/engine/internal/OpflexPool.h b/libopflex/engine/include/opflex/engine/internal/OpflexPool.h index 7c0d23c4..3f84413f 100644 --- a/libopflex/engine/include/opflex/engine/internal/OpflexPool.h +++ b/libopflex/engine/include/opflex/engine/internal/OpflexPool.h @@ -379,6 +379,14 @@ class OpflexPool : private boost::noncopyable { return tunnelMac; } + void setResetAllPeers(bool value) { + reset_all_peers = value; + } + + bool getResetAllPeers() { + return reset_all_peers; + } + /** * Retrieve OpFlex client stats for each available peer * @@ -422,6 +430,7 @@ class OpflexPool : private boost::noncopyable { conn_map_t connections; role_map_t roles; boost::atomic active; + boost::atomic reset_all_peers; opflex::ofcore::OFConstants::OpflexElementMode client_mode; opflex::ofcore::OFConstants::OpflexTransportModeState transport_state; diff --git a/libopflex/include/opflex/ofcore/OFFramework.h b/libopflex/include/opflex/ofcore/OFFramework.h index 50835e37..07a3c45a 100644 --- a/libopflex/include/opflex/ofcore/OFFramework.h +++ b/libopflex/include/opflex/ofcore/OFFramework.h @@ -793,6 +793,20 @@ class OFFramework : private boost::noncopyable { */ void deleteMOs(opflex::modb::mointernal::StoreClient::notif_t& notifs); + /** + * Enable or Disable reset_all_peers bool in OpflexPool + * when enabled any peer disconnect will result in all non configured peers + * to disconnect. + * @param value bool current intended reset behavior + */ + void setResetAllPeers(bool value); + + /** + * return current value of reset_all_peers bool in OpflexPool + * @return bool current intended reset behavior + */ + bool getResetAllPeers(); + /** * Start the framework. This will start all the framework threads * and attempt to connect to configured OpFlex peers. diff --git a/libopflex/ofcore/OFFramework.cpp b/libopflex/ofcore/OFFramework.cpp index b18edacb..60e075a8 100644 --- a/libopflex/ofcore/OFFramework.cpp +++ b/libopflex/ofcore/OFFramework.cpp @@ -256,6 +256,16 @@ void OFFramework::getMacProxy(boost::asio::ip::address_v4 &macProxyAddress ) { macProxyAddress = pool.getMacProxy(); } +void OFFramework::setResetAllPeers(bool value) { + engine::internal::OpflexPool& pool = pimpl->processor.getPool(); + pool.setResetAllPeers(value); +} + +bool OFFramework::getResetAllPeers() { + engine::internal::OpflexPool& pool = pimpl->processor.getPool(); + return pool.getResetAllPeers(); +} + void MockOFFramework::setV4Proxy(const boost::asio::ip::address_v4& v4ProxyAddress ) { engine::internal::OpflexPool& pool = pimpl->processor.getPool(); pool.setV4Proxy(v4ProxyAddress);