Skip to content

Commit

Permalink
Update BGP and XMPP UVEs
Browse files Browse the repository at this point in the history
o Add UVEs for BgpTables (total,  primary, secondary and infeasible path counts)
o Add total_path_count and primary_path_count to bgp and xmpp peer UVEs
o Send UVEs periodically off a new bgp::Uve task. This runs mutually
  exclusively with (only) bgp::Config task
o Convert all counters in IPeerDebygStats to tbb::atomic, as they can now be
  changed and read at the same from different threads
o Cleanup stats collection in control-node/main.c by moving code into
  respective modules BgpServer, BgpXmppChannelManager and IFMapServer

TODO: Integrate UVEs (selectively) with KPIs

Change-Id: Ia53e766956bb2590d417a1f4ce71e5df570cf040
Partial-Bug: #1576437
  • Loading branch information
ananth-at-camphor-networks committed May 30, 2016
1 parent 172d46d commit a82a822
Show file tree
Hide file tree
Showing 64 changed files with 731 additions and 503 deletions.
15 changes: 15 additions & 0 deletions src/analytics/viz.sandesh
Expand Up @@ -391,6 +391,7 @@ const map<string, string> UVE_MAP = {
"vrouter" : VROUTER_TABLE,
"control-node" : BGP_ROUTER_TABLE,
"bgp-peer" : BGP_PEER_TABLE,
"routing-instance" : ROUTING_INSTANCE_TABLE,
"xmpp-peer" : XMPP_PEER_INFO_TABLE,
"analytics-node" : COLLECTOR_INFO_TABLE,
"database-node" : DATABASE_INFO_TABLE,
Expand Down Expand Up @@ -2052,6 +2053,20 @@ const list<stat_table> _STAT_TABLES = [
{ 'name' : 'phy_if_band.out_bandwidth_usage', 'datatype' : 'int', 'index' : false }
]
},
{
'display_name' : 'Routung Instance Information',
'stat_type' : 'RoutingInstanceStatsData',
'stat_attr' : 'table_stats',
'obj_table' : ROUTING_INSTANCE_TABLE,
'attributes': [
{ 'name' : 'table_stats.address_family', 'datatype' : 'string', 'index' : true},
{ 'name' : 'table_stats.prefixes', 'datatype' : 'int', 'index' : false},
{ 'name' : 'table_stats.primary_paths', 'datatype' : 'int', 'index' : false},
{ 'name' : 'table_stats.secondary_paths', 'datatype' : 'int', 'index' : false},
{ 'name' : 'table_stats.infeasible_paths', 'datatype' : 'int', 'index' : false},
{ 'name' : 'table_stats.total_paths', 'datatype' : 'int', 'index' : false},
]
},

#ifdef BROADVIEW_RECEIVER_SUPPORT
{
Expand Down
12 changes: 12 additions & 0 deletions src/bgp/SConscript
Expand Up @@ -18,17 +18,28 @@ SandeshGenFiles += env.SandeshGenOnlyCpp('bgp_peer_internal.sandesh')
SandeshGenFiles += env.SandeshGenCpp('bgp_log.sandesh')
SandeshGenFiles += env.SandeshGenCpp('virtual_network.sandesh')
SandeshGenFiles += env.SandeshGenCpp('vrouter.sandesh')
SandeshGenFiles += env.SandeshGenCpp('bgp_table.sandesh')
SandeshGenSrcs = env.ExtractCpp(SandeshGenFiles)

env.Append(CPPPATH = env['TOP'])
env.Append(CPPPATH = [env['TOP'] + '/bgp'])
env.Append(CPPPATH = [env['TOP'] + '/io'])
env.Append(CPPPATH = [env['TOP'] + '/db'])
env.Append(CPPPATH = [env['TOP'] + '/ifmap'])
env.Append(CPPPATH = [env['TOP'] + '/base/sandesh'])

SandeshPeerFiles = env.SandeshGenCpp('peer_info.sandesh')
SandeshPeerGenSrcs = env.ExtractCpp(SandeshPeerFiles)
libpeer_sandesh = env.Library('peer_sandesh', SandeshPeerGenSrcs);

SandeshTableFiles = env.SandeshGenCpp('table_info.sandesh')
SandeshTableGenSrcs = env.ExtractCpp(SandeshTableFiles)
libtable_sandesh = env.Library('table_sandesh', SandeshTableGenSrcs);

SandeshTableFiles = env.SandeshGenCpp('sandesh_info.sandesh')
SandeshTableGenSrcs = env.ExtractCpp(SandeshTableFiles)
libsandesh_sandesh = env.Library('sandesh_sandesh', SandeshTableGenSrcs);

libbgp = env.Library('bgp',
SandeshGenSrcs +
['bgp_aspath.cc',
Expand Down Expand Up @@ -75,6 +86,7 @@ libbgp = env.Library('bgp',
'bgp_update_queue.cc',
'community.cc',
'message_builder.cc',
'peer_stats.cc',
'scheduling_group.cc',
'state_machine.cc',
])
Expand Down
2 changes: 1 addition & 1 deletion src/bgp/bgp_path.cc
Expand Up @@ -140,7 +140,7 @@ bool BgpPath::PathSameNeighborAs(const BgpPath &rhs) const {
void BgpPath::UpdatePeerRefCount(int count) const {
if (!peer_)
return;
peer_->UpdateRefCount(count);
peer_->UpdateTotalPathCount(count);
if (source_ != BGP_XMPP || IsReplicated())
return;
peer_->UpdatePrimaryPathCount(count);
Expand Down
9 changes: 7 additions & 2 deletions src/bgp/bgp_peer.cc
Expand Up @@ -280,6 +280,11 @@ class BgpPeer::PeerStats : public IPeerDebugStats {
virtual void GetRxErrorStats(RxErrorStats *stats) const {
}

virtual void GetRxRouteStats(RxRouteStats *stats) const {
stats->total_path_count = peer_->GetTotalPathCount();
stats->primary_path_count = peer_->GetPrimaryPathCount();
}

private:
friend class BgpPeer;

Expand Down Expand Up @@ -496,7 +501,7 @@ BgpPeer::BgpPeer(BgpServer *server, RoutingInstance *instance,
peer_basename_ = peer_name_;
}

refcount_ = 0;
total_path_count_ = 0;
primary_path_count_ = 0;

ProcessEndpointConfig(config);
Expand All @@ -522,7 +527,7 @@ BgpPeer::BgpPeer(BgpServer *server, RoutingInstance *instance,
}

BgpPeer::~BgpPeer() {
assert(GetRefCount() == 0);
assert(GetTotalPathCount() == 0);
STLDeleteValues(&family_attributes_list_);
ClearListenSocketAuthKey();
BgpPeerInfoData peer_info;
Expand Down
12 changes: 6 additions & 6 deletions src/bgp/bgp_peer.h
Expand Up @@ -270,14 +270,14 @@ class BgpPeer : public IPeer {
bool ResumeClose();
void MembershipRequestCallback(IPeer *ipeer, BgpTable *table);

virtual void UpdateRefCount(int count) const { refcount_ += count; }
virtual tbb::atomic<int> GetRefCount() const { return refcount_; }
virtual void UpdateTotalPathCount(int count) const {
total_path_count_ += count;
}
virtual int GetTotalPathCount() const { return total_path_count_; }
virtual void UpdatePrimaryPathCount(int count) const {
primary_path_count_ += count;
}
virtual int GetPrimaryPathCount() const {
return primary_path_count_;
}
virtual int GetPrimaryPathCount() const { return primary_path_count_; }

void RegisterToVpnTables();

Expand Down Expand Up @@ -447,7 +447,7 @@ class BgpPeer : public IPeer {
boost::scoped_ptr<PeerStats> peer_stats_;
boost::scoped_ptr<DeleteActor> deleter_;
LifetimeRef<BgpPeer> instance_delete_ref_;
mutable tbb::atomic<int> refcount_;
mutable tbb::atomic<int> total_path_count_;
mutable tbb::atomic<int> primary_path_count_;
uint64_t flap_count_;
uint64_t last_flap_;
Expand Down
198 changes: 196 additions & 2 deletions src/bgp/bgp_server.cc
Expand Up @@ -16,6 +16,8 @@
#include "bgp/bgp_peer.h"
#include "bgp/bgp_peer_membership.h"
#include "bgp/bgp_session_manager.h"
#include "bgp/bgp_table_types.h"
#include "bgp/peer_stats.h"
#include "bgp/scheduling_group.h"
#include "bgp/routing-instance/iservice_chain_mgr.h"
#include "bgp/routing-instance/istatic_route_mgr.h"
Expand All @@ -25,6 +27,9 @@
#include "bgp/routing-instance/rtarget_group_mgr.h"
#include "bgp/routing-policy/routing_policy.h"

#include "sandesh/sandesh.h"
#include "control-node/sandesh/control_node_types.h"

using boost::system::error_code;
using boost::tie;
using process::ConnectionState;
Expand Down Expand Up @@ -705,7 +710,7 @@ void BgpServer::NotifyAllStaticRoutes() {
}

uint32_t BgpServer::GetStaticRouteCount() const {
CHECK_CONCURRENCY("bgp::Config");
CHECK_CONCURRENCY("bgp::Uve");
uint32_t count = 0;
for (StaticRouteMgrList::iterator it = srt_manager_list_.begin();
it != srt_manager_list_.end(); ++it) {
Expand All @@ -716,7 +721,7 @@ uint32_t BgpServer::GetStaticRouteCount() const {
}

uint32_t BgpServer::GetDownStaticRouteCount() const {
CHECK_CONCURRENCY("bgp::Config");
CHECK_CONCURRENCY("bgp::Uve");
uint32_t count = 0;
for (StaticRouteMgrList::iterator it = srt_manager_list_.begin();
it != srt_manager_list_.end(); ++it) {
Expand All @@ -725,3 +730,192 @@ uint32_t BgpServer::GetDownStaticRouteCount() const {
}
return count;
}

uint32_t BgpServer::SendTableStatsUve(bool first) const {
uint32_t out_q_depth = 0;
for (RoutingInstanceMgr::RoutingInstanceIterator rit = inst_mgr_->begin();
rit != inst_mgr_->end(); ++rit) {
RoutingInstanceStatsData instance_info;
RoutingInstance::RouteTableList const rt_list = rit->GetTables();
std::vector<BgpTableStats> tables_stats;

for (RoutingInstance::RouteTableList::const_iterator it =
rt_list.begin(); it != rt_list.end(); ++it) {
BgpTable *table = it->second;

size_t markers;
out_q_depth += table->GetPendingRiboutsCount(&markers);
string family = Address::FamilyToString(table->family());

bool changed = false;
if (first || table->stats()->get_address_family() != family) {
changed = true;
table->stats()->set_address_family(family);
}

if (first || table->stats()->get_prefixes() != table->Size()) {
changed = true;
table->stats()->set_prefixes(table->Size());
}

if (first || table->stats()->get_primary_paths() !=
table->GetPrimaryPathCount()) {
changed = true;
table->stats()->set_primary_paths(table->GetPrimaryPathCount());
}

if (first || table->stats()->get_secondary_paths() !=
table->GetSecondaryPathCount()) {
changed = true;
table->stats()->set_secondary_paths(
table->GetSecondaryPathCount());
}

uint64_t total_paths = table->stats()->get_primary_paths() +
table->stats()->get_secondary_paths() +
table->stats()->get_infeasible_paths();
if (first || table->stats()->get_total_paths() != total_paths) {
changed = true;
table->stats()->set_total_paths(total_paths);
}

if (changed) {
tables_stats.push_back(*table->stats());

// Reset changed flags in the uve structure.
memset(&(table->stats()->__isset), 0,
sizeof(table->stats()->__isset));
}
}

// Set the key and send out the uve.
if (!tables_stats.empty()) {
instance_info.set_name(rit->name());
instance_info.set_table_stats(tables_stats);
RoutingInstanceStats::Send(instance_info);
}
}

return out_q_depth;
}

void BgpServer::FillPeerStats(const BgpPeer *peer) const {
PeerStatsInfo stats;
PeerStats::FillPeerDebugStats(peer->peer_stats(), &stats);

BgpPeerInfoData peer_info;
peer_info.set_name(peer->ToUVEKey());
peer_info.set_peer_stats_info(stats);
BGPPeerInfo::Send(peer_info);
}

bool BgpServer::CollectStats(BgpRouterState *state, bool first) const {
CHECK_CONCURRENCY("bgp::Uve");

VisitBgpPeers(boost::bind(&BgpServer::FillPeerStats, this, _1));
bool change = false;
uint32_t is_admin_down = admin_down();
if (first || is_admin_down != state->get_admin_down()) {
state->set_admin_down(is_admin_down);
change = true;
}

string router_id = bgp_identifier_string();
if (first || router_id != state->get_router_id()) {
state->set_router_id(router_id);
change = true;
}

uint32_t local_asn = local_autonomous_system();
if (first || local_asn != state->get_local_asn()) {
state->set_local_asn(local_asn);
change = true;
}

uint32_t global_asn = autonomous_system();
if (first || global_asn != state->get_global_asn()) {
state->set_global_asn(global_asn);
change = true;
}

uint32_t num_bgp = num_bgp_peer();
if (first || num_bgp != state->get_num_bgp_peer()) {
state->set_num_bgp_peer(num_bgp);
change = true;
}

uint32_t num_up_bgp_peer = NumUpPeer();
if (first || num_up_bgp_peer != state->get_num_up_bgp_peer()) {
state->set_num_up_bgp_peer(num_up_bgp_peer);
change = true;
}

uint32_t deleting_bgp_peer = num_deleting_bgp_peer();
if (first || deleting_bgp_peer != state->get_num_deleting_bgp_peer()) {
state->set_num_deleting_bgp_peer(deleting_bgp_peer);
change = true;
}

uint32_t num_bgpaas = num_bgpaas_peer();
if (first || num_bgpaas != state->get_num_bgpaas_peer()) {
state->set_num_bgpaas_peer(num_bgpaas);
change = true;
}

uint32_t num_up_bgpaas_peer = NumUpBgpaasPeer();
if (first || num_up_bgpaas_peer != state->get_num_up_bgpaas_peer()) {
state->set_num_up_bgpaas_peer(num_up_bgpaas_peer);
change = true;
}

uint32_t deleting_bgpaas_peer = num_deleting_bgpaas_peer();
if (first || deleting_bgpaas_peer !=
state->get_num_deleting_bgpaas_peer()) {
state->set_num_deleting_bgpaas_peer(deleting_bgpaas_peer);
change = true;
}

uint32_t num_ri = num_routing_instance();
if (first || num_ri != state->get_num_routing_instance()) {
state->set_num_routing_instance(num_ri);
change = true;
}

uint32_t num_deleted_ri = num_deleted_routing_instance();
if (first || num_deleted_ri != state->get_num_deleted_routing_instance()) {
state->set_num_deleted_routing_instance(num_deleted_ri);
change = true;
}

uint32_t service_chains = num_service_chains();
if (first || service_chains != state->get_num_service_chains()) {
state->set_num_service_chains(service_chains);
change = true;
}

uint32_t down_service_chains = num_down_service_chains();
if (first || down_service_chains != state->get_num_down_service_chains()) {
state->set_num_down_service_chains(down_service_chains);
change = true;
}

uint32_t static_routes = num_static_routes();
if (first || static_routes != state->get_num_static_routes()) {
state->set_num_static_routes(static_routes);
change = true;
}

uint32_t down_static_routes = num_down_static_routes();
if (first || down_static_routes != state->get_num_down_static_routes()) {
state->set_num_down_static_routes(down_static_routes);
change = true;
}

uint32_t out_load = SendTableStatsUve(first);
if (first || out_load != state->get_output_queue_depth()) {
state->set_output_queue_depth(out_load);
change = true;
}

return change;
}
4 changes: 4 additions & 0 deletions src/bgp/bgp_server.h
Expand Up @@ -28,6 +28,7 @@ class BgpConfigManager;
class BgpMembershipManager;
class BgpOListDB;
class BgpPeer;
class BgpRouterState;
class BgpSessionManager;
class ClusterListDB;
class CommunityDB;
Expand Down Expand Up @@ -242,6 +243,7 @@ class BgpServer {
void NotifyAllStaticRoutes();
uint32_t GetStaticRouteCount() const;
uint32_t GetDownStaticRouteCount() const;
bool CollectStats(BgpRouterState *state, bool first) const;

private:
class ConfigUpdater;
Expand All @@ -255,6 +257,8 @@ class BgpServer {
typedef std::map<TcpSession::Endpoint, BgpPeer *> EndpointToBgpPeerList;

void RoutingInstanceMgrDeletionComplete(RoutingInstanceMgr *mgr);
uint32_t SendTableStatsUve(bool first) const;
void FillPeerStats(const BgpPeer *peer) const;

// base config variables
tbb::spin_rw_mutex rw_mutex_;
Expand Down

0 comments on commit a82a822

Please sign in to comment.