Skip to content

Commit

Permalink
Adding Connection UVE for ToR connection
Browse files Browse the repository at this point in the history
This will help reporting connection state for ToR.

Change-Id: I5d9f0d80eba5305309e9a01eb0b792c3a1763a16
Closes-Bug: 1430745
  • Loading branch information
Prabhjot Singh Sethi committed May 11, 2015
1 parent 081ca34 commit 3468494
Show file tree
Hide file tree
Showing 17 changed files with 311 additions and 22 deletions.
4 changes: 3 additions & 1 deletion src/base/sandesh/process_info.sandesh
Expand Up @@ -14,6 +14,7 @@ enum ConnectionType {
ZOOKEEPER,
DISCOVERY,
APISERVER,
TOR,
}

const map<ConnectionType, string> ConnectionTypeNames = {
Expand All @@ -25,7 +26,8 @@ const map<ConnectionType, string> ConnectionTypeNames = {
ConnectionType.REDIS : "Redis",
ConnectionType.ZOOKEEPER : "Zookeeper",
ConnectionType.DISCOVERY : "Discovery",
ConnectionType.APISERVER : "ApiServer"
ConnectionType.APISERVER : "ApiServer",
ConnectionType.TOR : "ToR"
}

enum ConnectionStatus {
Expand Down
1 change: 1 addition & 0 deletions src/vnsw/agent/ovs_tor_agent/ovsdb_client/SConscript
Expand Up @@ -25,6 +25,7 @@ libovsdbclient = env.Library('ovsdbclient',
'logical_switch_ovsdb.cc',
'multicast_mac_local_ovsdb.cc',
'ovsdb_client.cc',
'ovsdb_client_connection_state.cc',
'ovsdb_client_idl.cc',
'ovsdb_client_session.cc',
'ovsdb_client_ssl.cc',
Expand Down
10 changes: 10 additions & 0 deletions src/vnsw/agent/ovs_tor_agent/ovsdb_client/ovsdb_client.cc
Expand Up @@ -8,10 +8,12 @@
#include <ovsdb_client.h>
#include <ovsdb_client_ssl.h>
#include <ovsdb_client_tcp.h>
#include <ovsdb_client_connection_state.h>
#include <ovs_tor_agent/tor_agent_init.h>
#include <ovs_tor_agent/tor_agent_param.h>

using OVSDB::OvsdbClient;
using OVSDB::ConnectionStateTable;

OvsdbClient::OvsdbClient(OvsPeerManager *manager, int keepalive_interval) :
peer_manager_(manager), ksync_obj_manager_(KSyncObjectManager::Init()),
Expand All @@ -21,6 +23,14 @@ OvsdbClient::OvsdbClient(OvsPeerManager *manager, int keepalive_interval) :
OvsdbClient::~OvsdbClient() {
}

void OvsdbClient::RegisterConnectionTable(Agent *agent) {
connection_table_.reset(new ConnectionStateTable(agent));
}

ConnectionStateTable *OvsdbClient::connection_table() {
return connection_table_.get();
}

KSyncObjectManager *OvsdbClient::ksync_obj_manager() {
return ksync_obj_manager_;
}
Expand Down
4 changes: 4 additions & 0 deletions src/vnsw/agent/ovs_tor_agent/ovsdb_client/ovsdb_client.h
Expand Up @@ -13,6 +13,7 @@ class KSyncObjectManager;

namespace OVSDB {
class OvsdbClientSession;
class ConnectionStateTable;
class OvsdbClient {
public:
OvsdbClient(OvsPeerManager *manager, int keepalive_interval);
Expand All @@ -33,6 +34,8 @@ class OvsdbClient {
virtual void AddSessionInfo(SandeshOvsdbClient &client) = 0;
virtual void shutdown() = 0;

void RegisterConnectionTable(Agent *agent);
ConnectionStateTable *connection_table();
KSyncObjectManager *ksync_obj_manager();
int keepalive_interval() const;
void Init();
Expand All @@ -42,6 +45,7 @@ class OvsdbClient {
protected:
OvsPeerManager *peer_manager_;
private:
boost::scoped_ptr<ConnectionStateTable> connection_table_;
KSyncObjectManager *ksync_obj_manager_;
int keepalive_interval_;
DISALLOW_COPY_AND_ASSIGN(OvsdbClient);
Expand Down
@@ -0,0 +1,130 @@
/*
* Copyright (c) 2015 Juniper Networks, Inc. All rights reserved.
*/

#include <base/string_util.h>
#include "ovsdb_client_connection_state.h"

using namespace OVSDB;
using namespace process;
using namespace std;

ConnectionStateEntry::ConnectionStateEntry(const std::string &device_name) :
device_name_(device_name), device_entry_(NULL) {
}

ConnectionStateEntry::~ConnectionStateEntry() {
}

ConnectionStateTable::ConnectionStateTable(Agent *agent)
: agent_(agent), table_(agent->physical_device_table()) {
id_ = table_->Register(
boost::bind(&ConnectionStateTable::PhysicalDeviceNotify,
this, _1, _2));
}

ConnectionStateTable::~ConnectionStateTable() {
table_->Unregister(id_);
}

void ConnectionStateTable::AddIdlToConnectionState(const std::string &dev_name,
OvsdbClientIdl *idl) {
ConnectionStateEntry *state = new ConnectionStateEntry(dev_name);
pair<EntryMap::iterator, bool> ret;
ret = entry_map_.insert(pair<string, ConnectionStateEntry*>(dev_name,
state));
if (ret.second == false) {
// entry already existed, delete allocated memory
delete state;
}
ret.first->second->idl_list_.insert(idl);
UpdateConnectionInfo(ret.first->second, false);
}

void ConnectionStateTable::DelIdlToConnectionState(const std::string &dev_name,
OvsdbClientIdl *idl) {
EntryMap::iterator it = entry_map_.find(dev_name);
if (it == entry_map_.end()) {
return;
}
it->second->idl_list_.erase(idl);
if (it->second->idl_list_.empty()) {
if (it->second->device_entry_ == NULL) {
UpdateConnectionInfo(it->second, true);
delete it->second;
entry_map_.erase(it);
} else {
UpdateConnectionInfo(it->second, false);
}
}
}

void ConnectionStateTable::PhysicalDeviceNotify(DBTablePartBase *part,
DBEntryBase *e) {
PhysicalDevice *dev = static_cast<PhysicalDevice *>(e);
ConnectionStateEntry *state =
static_cast<ConnectionStateEntry *>(dev->GetState(table_, id_));
if (dev->IsDeleted()) {
if (state) {
state->device_entry_ = NULL;
if (state->idl_list_.empty()) {
UpdateConnectionInfo(state, true);
entry_map_.erase(state->device_name_);
delete state;
} else {
UpdateConnectionInfo(state, false);
}
dev->ClearState(table_, id_);
}
return;
}
if (!state) {
state = new ConnectionStateEntry(dev->name());
pair<EntryMap::iterator, bool> ret;
ret = entry_map_.insert(pair<string, ConnectionStateEntry*>(dev->name(),
state));
if (ret.second == false) {
// entry already existed, delete allocated memory
delete state;
}
ret.first->second->device_entry_ = dev;
dev->SetState(table_, id_, ret.first->second);
UpdateConnectionInfo(ret.first->second, false);
}
}

void ConnectionStateTable::UpdateConnectionInfo(ConnectionStateEntry *entry,
bool deleted) {
if (agent_->connection_state() == NULL)
return;

if (deleted) {
agent_->connection_state()->Delete(ConnectionType::TOR,
entry->device_name_);
} else {
ConnectionStatus::type status = ConnectionStatus::UP;
string message;
boost::asio::ip::tcp::endpoint ep;
if (!entry->idl_list_.empty()) {
ConnectionStateEntry::IdlList::iterator it =
entry->idl_list_.begin();
ep.address((*it)->remote_ip());
ep.port((*it)->remote_port());
}

if (entry->device_entry_ == NULL) {
status = ConnectionStatus::DOWN;
message = "Config Not Available";
} else if (entry->idl_list_.empty()) {
status = ConnectionStatus::DOWN;
message = "ToR Not Available";
} else {
message = "Active sessions = " +
integerToString(entry->idl_list_.size());
}
agent_->connection_state()->Update(ConnectionType::TOR,
entry->device_name_, status,
ep, message);
}
}

@@ -0,0 +1,70 @@
/*
* Copyright (c) 2015 Juniper Networks, Inc. All rights reserved.
*/

#ifndef SRC_VNSW_AGENT_OVS_TOR_AGENT_OVSDB_CLIENT_CONNECTION_STATE_H_
#define SRC_VNSW_AGENT_OVS_TOR_AGENT_OVSDB_CLIENT_CONNECTION_STATE_H_

#include <tbb/atomic.h>
#include <base/connection_info.h>
#include <db/db.h>
#include <db/db_entry.h>
#include <db/db_table.h>
#include <db/db_table_partition.h>

#include <cmn/agent.h>
#include <oper/physical_device.h>

#include "ovsdb_client_idl.h"

namespace OVSDB {
class ConnectionStateEntry;

// Table to maintain Connection State for Physical Switches/Devices
class ConnectionStateTable {
public:
typedef std::map<std::string, ConnectionStateEntry *> EntryMap;
explicit ConnectionStateTable(Agent *agent);
virtual ~ConnectionStateTable();

// Adding first IDL to ConnectionState Entry marks session Up
void AddIdlToConnectionState(const std::string &device_name,
OvsdbClientIdl *idl);

// Deleting last IDL from ConnectionState Entry marks session Down
void DelIdlToConnectionState(const std::string &device_name,
OvsdbClientIdl *idl);

private:
void PhysicalDeviceNotify(DBTablePartBase *part, DBEntryBase *e);

// API to update connection info state
void UpdateConnectionInfo(ConnectionStateEntry *entry, bool deleted);

Agent *agent_;
DBTableBase *table_;
DBTableBase::ListenerId id_;
EntryMap entry_map_;
DISALLOW_COPY_AND_ASSIGN(ConnectionStateTable);
};

// Connection State Entry represent a physical router, reports connection
// state Up as long as config and idl for Physical Switch exists
class ConnectionStateEntry : public DBState {
public:
typedef std::set<OvsdbClientIdl *> IdlList;
explicit ConnectionStateEntry(const std::string &device_name);
virtual ~ConnectionStateEntry();

private:
friend class ConnectionStateTable;
std::string device_name_;
PhysicalDevice *device_entry_;
IdlList idl_list_;
DISALLOW_COPY_AND_ASSIGN(ConnectionStateEntry);
};

};

#endif //SRC_VNSW_AGENT_OVS_TOR_AGENT_OVSDB_CLIENT_CONNECTION_STATE_H_

14 changes: 14 additions & 0 deletions src/vnsw/agent/ovs_tor_agent/ovsdb_client/ovsdb_client_idl.cc
Expand Up @@ -12,6 +12,7 @@ extern "C" {
};
#include <oper/agent_sandesh.h>
#include <ovsdb_types.h>
#include <ovsdb_client_connection_state.h>
#include <ovsdb_client_idl.h>
#include <ovsdb_client_session.h>
#include <ovsdb_route_peer.h>
Expand Down Expand Up @@ -48,6 +49,7 @@ using OVSDB::UnicastMacLocalOvsdb;
using OVSDB::MulticastMacLocalOvsdb;
using OVSDB::VrfOvsdbObject;
using OVSDB::VnOvsdbObject;
using OVSDB::ConnectionStateTable;

namespace OVSDB {
void ovsdb_wrapper_idl_callback(void *idl_base, int op,
Expand Down Expand Up @@ -282,6 +284,18 @@ void OvsdbClientIdl::MessageProcess(struct jsonrpc_msg *msg) {
receive_queue_->Enqueue(ovs_msg);
}

Ip4Address OvsdbClientIdl::remote_ip() const {
return session_->remote_ip();
}

uint16_t OvsdbClientIdl::remote_port() const {
return session_->remote_port();
}

ConnectionStateTable *OvsdbClientIdl::connection_table() {
return session_->connection_table();
}

KSyncObjectManager *OvsdbClientIdl::ksync_obj_manager() {
return session_->ksync_obj_manager();
}
Expand Down
5 changes: 5 additions & 0 deletions src/vnsw/agent/ovs_tor_agent/ovsdb_client/ovsdb_client_idl.h
Expand Up @@ -46,6 +46,7 @@ class MulticastMacLocalOvsdb;
class VrfOvsdbObject;
class VnOvsdbObject;
class OvsdbEntryBase;
class ConnectionStateTable;

class OvsdbClientIdl;
typedef boost::intrusive_ptr<OvsdbClientIdl> OvsdbClientIdlPtr;
Expand Down Expand Up @@ -130,6 +131,10 @@ class OvsdbClientIdl {
// Process jsonrpc_msg for IDL, takes ownership of jsonrpc_msg
void MessageProcess(struct jsonrpc_msg *msg);

Ip4Address remote_ip() const;
uint16_t remote_port() const;

ConnectionStateTable *connection_table();
KSyncObjectManager *ksync_obj_manager();
OvsPeer *route_peer();
bool deleted() { return deleted_; }
Expand Down
Expand Up @@ -10,6 +10,7 @@ extern "C" {

#include <cmn/agent.h>
#include <ovsdb_types.h>
#include <ovsdb_client_connection_state.h>
#include <ovsdb_client_idl.h>
#include <ovsdb_client_session.h>
#include <ovsdb_route_peer.h>
Expand All @@ -18,6 +19,7 @@ extern "C" {

using OVSDB::OvsdbClientIdl;
using OVSDB::OvsdbClientSession;
using OVSDB::ConnectionStateTable;

int OvsdbClientSession::ovsdb_io_task_id_ = -1;

Expand Down
Expand Up @@ -35,8 +35,10 @@ class OvsdbClientSession {

virtual int keepalive_interval() = 0;

virtual ConnectionStateTable *connection_table() = 0;
virtual KSyncObjectManager *ksync_obj_manager() = 0;
virtual Ip4Address remote_ip() { return Ip4Address(); }
virtual Ip4Address remote_ip() const { return Ip4Address(); }
virtual uint16_t remote_port() const { return 0; }
virtual Ip4Address tsn_ip() = 0;
virtual void SendMsg(u_int8_t *buf, std::size_t len) = 0;
void MessageProcess(const u_int8_t *buf, std::size_t len);
Expand Down

0 comments on commit 3468494

Please sign in to comment.