Skip to content

Commit

Permalink
Merge "Implement introspect for evpn information" into R2.20
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Aug 15, 2015
2 parents 462c670 + 7069594 commit 35b130f
Show file tree
Hide file tree
Showing 10 changed files with 509 additions and 97 deletions.
1 change: 1 addition & 0 deletions src/bgp/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ libbgp = env.Library('bgp',
'bgp_session_manager.cc',
'bgp_session.cc',
'bgp_show_config.cc',
'bgp_show_evpn_table.cc',
'bgp_show_neighbor.cc',
'bgp_show_route_summary.cc',
'bgp_show_routing_instance.cc',
Expand Down
29 changes: 29 additions & 0 deletions src/bgp/bgp_peer.sandesh
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,35 @@ request sandesh ShowRoutingInstanceSummaryReq {
1: string search_string;
}

struct ShowEvpnTable {
1: string name (link="ShowRouteReq");
2: u64 mac_routes;
3: u64 unique_mac_routes;
4: u64 im_routes;
5: bool deleted;
6: string deleted_at;
}

response sandesh ShowEvpnTableResp {
1: list<ShowEvpnTable> tables;
2: optional string next_batch (link="ShowEvpnTableReqIterate",
link_title="next_batch");
}

request sandesh ShowEvpnTableReq {
1: string search_string;
}

response sandesh ShowEvpnTableSummaryResp {
1: list<ShowEvpnTable> tables;
2: optional string next_batch (link="ShowEvpnTableSummaryReqIterate",
link_title="next_batch");
}

request sandesh ShowEvpnTableSummaryReq {
1: string search_string;
}

struct ShowMulticastManager {
1: string name (link="ShowMulticastManagerDetailReq");
2: u32 total_trees;
Expand Down
8 changes: 8 additions & 0 deletions src/bgp/bgp_peer_internal.sandesh
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ request sandesh ShowRoutingInstanceSummaryReqIterate {
1: string iterate_info;
}

request sandesh ShowEvpnTableReqIterate {
1: string iterate_info;
}

request sandesh ShowEvpnTableSummaryReqIterate {
1: string iterate_info;
}

response sandesh ShowMulticastManagerDetailResp {
1: list<bgp_peer.ShowMulticastTree> trees;
}
Expand Down
230 changes: 230 additions & 0 deletions src/bgp/bgp_show_evpn_table.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
/*
* Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
*/

#include "bgp/bgp_show_handler.h"

#include <boost/bind.hpp>
#include <boost/foreach.hpp>

#include "base/time_util.h"
#include "bgp/bgp_peer_internal_types.h"
#include "bgp/bgp_server.h"
#include "bgp/bgp_table.h"
#include "bgp/evpn/evpn_table.h"
#include "bgp/routing-instance/routing_instance.h"

using std::string;
using std::vector;

//
// Fill in information for an evpn table.
//
static void FillEvpnTableInfo(ShowEvpnTable *sevt,
const BgpSandeshContext *bsc, const EvpnTable *table, bool summary) {
sevt->set_name(table->name());
sevt->set_deleted(table->IsDeleted());
sevt->set_deleted_at(
UTCUsecToString(table->deleter()->delete_time_stamp_usecs()));
sevt->set_mac_routes(table->mac_route_count());
sevt->set_unique_mac_routes(table->unique_mac_route_count());
sevt->set_im_routes(table->im_route_count());

if (table->IsVpnTable() || summary)
return;
}

//
// Fill in information for list of evpn tables.
//
// Allows regular and summary introspect to share code.
//
static bool FillEvpnTableInfoList(const BgpSandeshContext *bsc,
bool summary, uint32_t page_limit, uint32_t iter_limit,
const string &start_instance, const string &search_string,
vector<ShowEvpnTable> *sevt_list, string *next_instance) {
RoutingInstanceMgr *rim = bsc->bgp_server->routing_instance_mgr();
RoutingInstanceMgr::const_name_iterator it =
rim->name_clower_bound(start_instance);
for (uint32_t iter_count = 0; it != rim->name_cend(); ++it, ++iter_count) {
const RoutingInstance *rtinstance = it->second;
const EvpnTable *table =
static_cast<const EvpnTable *>(rtinstance->GetTable(Address::EVPN));
if (!table)
continue;
if (!search_string.empty() &&
(table->name().find(search_string) == string::npos) &&
(search_string != "deleted" || !table->IsDeleted())) {
continue;
}
ShowEvpnTable sevt;
FillEvpnTableInfo(&sevt, bsc, table, summary);
sevt_list->push_back(sevt);
if (sevt_list->size() >= page_limit)
break;
if (iter_count >= iter_limit)
break;
}

// All done if we've looked at all instances.
if (it == rim->name_cend() || ++it == rim->name_end())
return true;

// Return true if we've reached the page limit, false if we've reached the
// iteration limit.
bool done = sevt_list->size() >= page_limit;
*next_instance = it->second->name();
return done;
}

//
// Specialization of BgpShowHandler<>::CallbackCommon for regular introspect.
//
template <>
bool BgpShowHandler<ShowEvpnTableReq, ShowEvpnTableReqIterate,
ShowEvpnTableResp, ShowEvpnTable>::CallbackCommon(
const BgpSandeshContext *bsc, Data *data) {
uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit;
uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit;
string next_instance;
bool done = FillEvpnTableInfoList(bsc, false, page_limit, iter_limit,
data->next_entry, data->search_string, &data->show_list,
&next_instance);
if (!next_instance.empty())
SaveContextToData(next_instance, done, data);
return done;
}

//
// Specialization of BgpShowHandler<>::FillShowList for regular introspect.
//
template <>
void BgpShowHandler<ShowEvpnTableReq, ShowEvpnTableReqIterate,
ShowEvpnTableResp, ShowEvpnTable>::FillShowList(
ShowEvpnTableResp *resp, const vector<ShowEvpnTable> &show_list) {
resp->set_tables(show_list);
}

//
// Specialization of BgpShowHandler<>::CallbackCommon for summary introspect.
//
template <>
bool BgpShowHandler<ShowEvpnTableSummaryReq, ShowEvpnTableSummaryReqIterate,
ShowEvpnTableSummaryResp, ShowEvpnTable>::CallbackCommon(
const BgpSandeshContext *bsc, Data *data) {
uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit;
uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit;
string next_instance;
bool done = FillEvpnTableInfoList(bsc, true, page_limit, iter_limit,
data->next_entry, data->search_string, &data->show_list,
&next_instance);
if (!next_instance.empty())
SaveContextToData(next_instance, done, data);
return done;
}

//
// Specialization of BgpShowHandler<>::FillShowList for summary introspect.
//
template <>
void BgpShowHandler<ShowEvpnTableSummaryReq, ShowEvpnTableSummaryReqIterate,
ShowEvpnTableSummaryResp, ShowEvpnTable>::FillShowList(
ShowEvpnTableSummaryResp *resp, const vector<ShowEvpnTable> &show_list) {
resp->set_tables(show_list);
}

//
// Handler for ShowEvpnTableReq.
//
void ShowEvpnTableReq::HandleRequest() const {
RequestPipeline::PipeSpec ps(this);
RequestPipeline::StageSpec s1;
TaskScheduler *scheduler = TaskScheduler::GetInstance();

s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand");
s1.cbFn_ = boost::bind(&BgpShowHandler<
ShowEvpnTableReq,
ShowEvpnTableReqIterate,
ShowEvpnTableResp,
ShowEvpnTable>::Callback, _1, _2, _3, _4, _5);
s1.allocFn_ = BgpShowHandler<
ShowEvpnTableReq,
ShowEvpnTableReqIterate,
ShowEvpnTableResp,
ShowEvpnTable>::CreateData;
s1.instances_.push_back(0);
ps.stages_.push_back(s1);
RequestPipeline rp(ps);
}

//
// Handler for ShowEvpnTableReqIterate.
//
void ShowEvpnTableReqIterate::HandleRequest() const {
RequestPipeline::PipeSpec ps(this);
RequestPipeline::StageSpec s1;
TaskScheduler *scheduler = TaskScheduler::GetInstance();

s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand");
s1.cbFn_ = boost::bind(&BgpShowHandler<
ShowEvpnTableReq,
ShowEvpnTableReqIterate,
ShowEvpnTableResp,
ShowEvpnTable>::CallbackIterate, _1, _2, _3, _4, _5);
s1.allocFn_ = BgpShowHandler<
ShowEvpnTableReq,
ShowEvpnTableReqIterate,
ShowEvpnTableResp,
ShowEvpnTable>::CreateData;
s1.instances_.push_back(0);
ps.stages_.push_back(s1);
RequestPipeline rp(ps);
}

//
// Handler for ShowEvpnTableSummaryReq.
//
void ShowEvpnTableSummaryReq::HandleRequest() const {
RequestPipeline::PipeSpec ps(this);
RequestPipeline::StageSpec s1;
TaskScheduler *scheduler = TaskScheduler::GetInstance();

s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand");
s1.cbFn_ = boost::bind(&BgpShowHandler<
ShowEvpnTableSummaryReq,
ShowEvpnTableSummaryReqIterate,
ShowEvpnTableSummaryResp,
ShowEvpnTable>::Callback, _1, _2, _3, _4, _5);
s1.allocFn_ = BgpShowHandler<
ShowEvpnTableSummaryReq,
ShowEvpnTableSummaryReqIterate,
ShowEvpnTableSummaryResp,
ShowEvpnTable>::CreateData;
s1.instances_.push_back(0);
ps.stages_.push_back(s1);
RequestPipeline rp(ps);
}

//
// Handler for ShowEvpnTableSummaryReqIterate.
//
void ShowEvpnTableSummaryReqIterate::HandleRequest() const {
RequestPipeline::PipeSpec ps(this);
RequestPipeline::StageSpec s1;
TaskScheduler *scheduler = TaskScheduler::GetInstance();

s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand");
s1.cbFn_ = boost::bind(&BgpShowHandler<
ShowEvpnTableSummaryReq,
ShowEvpnTableSummaryReqIterate,
ShowEvpnTableSummaryResp,
ShowEvpnTable>::CallbackIterate, _1, _2, _3, _4, _5);
s1.allocFn_ = BgpShowHandler<
ShowEvpnTableSummaryReq,
ShowEvpnTableSummaryReqIterate,
ShowEvpnTableSummaryResp,
ShowEvpnTable>::CreateData;
s1.instances_.push_back(0);
ps.stages_.push_back(s1);
RequestPipeline rp(ps);
}
4 changes: 2 additions & 2 deletions src/bgp/bgp_table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -303,11 +303,11 @@ void BgpTable::InputCommon(DBTablePartBase *root, BgpRoute *rt, BgpPath *path,
// Remove the Path from the route
rt->RemovePath(BgpPath::BGP_XMPP, peer, path_id);

// Delete the route only if all paths are gone.
if (rt->front() == NULL) {
// Delete the route only if all paths are gone
root->Delete(rt);
} else {
root->Notify(rt);
root->Notify(rt);
}
}
break;
Expand Down
44 changes: 44 additions & 0 deletions src/bgp/evpn/evpn_table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ size_t EvpnTable::HashFunction(const EvpnPrefix &prefix) {

EvpnTable::EvpnTable(DB *db, const string &name)
: BgpTable(db, name), evpn_manager_(NULL) {
mac_route_count_ = 0;
unique_mac_route_count_ = 0;
im_route_count_ = 0;
}

auto_ptr<DBEntry> EvpnTable::AllocEntry(
Expand All @@ -50,6 +53,47 @@ auto_ptr<DBEntry> EvpnTable::AllocEntryStr(
return auto_ptr<DBEntry> (new EvpnRoute(prefix));
}

void EvpnTable::AddRemoveCallback(const DBEntryBase *entry, bool add) const {
if (IsVpnTable())
return;
const EvpnRoute *evpn_rt = static_cast<const EvpnRoute *>(entry);
const EvpnPrefix &evpn_prefix = evpn_rt->GetPrefix();
switch (evpn_prefix.type()) {
case EvpnPrefix::MacAdvertisementRoute:
// Ignore Broadcast MAC routes.
if (evpn_prefix.mac_addr().IsBroadcast())
break;

if (add) {
mac_route_count_++;
} else {
mac_route_count_--;
}

// Ignore MAC routes with IP addresses.
if (evpn_prefix.family() != Address::UNSPEC)
break;

if (add) {
unique_mac_route_count_++;
} else {
unique_mac_route_count_--;
}
break;

case EvpnPrefix::InclusiveMulticastRoute:
if (add) {
im_route_count_++;
} else {
im_route_count_--;
}
break;

default:
break;
}
}

size_t EvpnTable::Hash(const DBRequestKey *key) const {
const RequestKey *rkey = static_cast<const RequestKey *>(key);
size_t value = HashFunction(rkey->prefix);
Expand Down
8 changes: 8 additions & 0 deletions src/bgp/evpn/evpn_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class EvpnTable : public BgpTable {

virtual std::auto_ptr<DBEntry> AllocEntry(const DBRequestKey *key) const;
virtual std::auto_ptr<DBEntry> AllocEntryStr(const std::string &key) const;
virtual void AddRemoveCallback(const DBEntryBase *entry, bool add) const;

virtual Address::Family family() const { return Address::EVPN; }
bool IsDefault() const;
Expand All @@ -51,10 +52,17 @@ class EvpnTable : public BgpTable {
EvpnManager *GetEvpnManager();
virtual void set_routing_instance(RoutingInstance *rtinstance);

uint64_t mac_route_count() const { return mac_route_count_; }
uint64_t unique_mac_route_count() const { return unique_mac_route_count_; }
uint64_t im_route_count() const { return im_route_count_; }

private:
virtual BgpRoute *TableFind(DBTablePartition *rtp,
const DBRequestKey *prefix);
EvpnManager *evpn_manager_;
mutable tbb::atomic<uint64_t> mac_route_count_;
mutable tbb::atomic<uint64_t> unique_mac_route_count_;
mutable tbb::atomic<uint64_t> im_route_count_;

DISALLOW_COPY_AND_ASSIGN(EvpnTable);
};
Expand Down

0 comments on commit 35b130f

Please sign in to comment.