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);