Skip to content

Commit

Permalink
Remove per table prefix counts from BgpNeighborListResp
Browse files Browse the repository at this point in the history
The back end implementation for this functionality was not scalable
since it synchronously traversed all tables partitions for an index.
To boot, it ended up returning 0 prefix counts due to other bugs.

Change-Id: Ie87d4e5cae0d926cb2b151d435111e7cb27a789b
Closes-Bug: 1399137
  • Loading branch information
Nischal Sheth committed Jul 6, 2015
1 parent a8e812d commit 8a7a373
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 149 deletions.
3 changes: 0 additions & 3 deletions src/bgp/bgp_peer.sandesh
Expand Up @@ -37,9 +37,6 @@ struct BgpNeighborRoutingTable {
2: string current_state;
3: string current_request;
4: string pending_request;
5: u32 active_prefixes;
6: u32 received_prefixes;
7: u32 accepted_prefixes;
}

struct BgpNeighborResp {
Expand Down
163 changes: 17 additions & 146 deletions src/bgp/bgp_sandesh.cc
Expand Up @@ -384,66 +384,11 @@ void ShowRouteSummaryReq::HandleRequest() const {

class ShowNeighborHandler {
public:
struct ShowNeighborData : public RequestPipeline::InstData {
vector<BgpNeighborResp> nbr_list;
};
struct ShowNeighborDataS2Key {
string peer;
string table;
bool operator<(const ShowNeighborDataS2Key&rhs) const {
if (peer != rhs.peer) return (peer < rhs.peer);
return (table < rhs.table);
}
};
struct ShowNeighborDataS2 : public RequestPipeline::InstData {
typedef map<ShowNeighborDataS2Key, BgpNeighborRoutingTable> Map;
Map peers;
};
static RequestPipeline::InstData *CreateData(int stage) {
switch (stage) {
case 0:
case 2:
return static_cast<RequestPipeline::InstData *>(new ShowNeighborData);
case 1:
return static_cast<RequestPipeline::InstData *>(new ShowNeighborDataS2);
default:
return NULL;
}
}
static void FillNeighborStats(ShowNeighborDataS2 *data, BgpTable *table, int inst_id) {
DBTablePartition *partition =
static_cast<DBTablePartition *>(table->GetTablePartition(inst_id));
BgpRoute *route = static_cast<BgpRoute *>(partition->GetFirst());
ShowNeighborDataS2Key key;
key.table = table->name();
for (; route; route = static_cast<BgpRoute *>(partition->GetNext(route))) {
Route::PathList &plist = route->GetPathList();
Route::PathList::iterator it = plist.begin();
for (; it != plist.end(); it++) {
BgpPath *path = static_cast<BgpPath *>(it.operator->());
// If paths are added with Peer as NULL(e.g. aggregate route)
if (path->GetPeer() == NULL) continue;
key.peer = path->GetPeer()->ToString();
BgpNeighborRoutingTable &nt = data->peers[key];
nt.received_prefixes++;
if (path->IsFeasible()) nt.accepted_prefixes++;
if (route->BestPath()->GetPeer() == path->GetPeer()) nt.active_prefixes++;
}
}
}
static void FillXmppNeighborInfo(vector<BgpNeighborResp> *, BgpServer *, BgpXmppChannel *);
static bool CallbackS1(const Sandesh *sr,
const RequestPipeline::PipeSpec ps,
int stage, int instNum,
RequestPipeline::InstData *data);
static bool CallbackS2(const Sandesh *sr,
const RequestPipeline::PipeSpec ps,
int stage, int instNum,
RequestPipeline::InstData *data);
static bool CallbackS3(const Sandesh *sr,
const RequestPipeline::PipeSpec ps,
int stage, int instNum,
RequestPipeline::InstData *data);
};

void ShowNeighborHandler::FillXmppNeighborInfo(
Expand Down Expand Up @@ -475,81 +420,28 @@ bool ShowNeighborHandler::CallbackS1(const Sandesh *sr,
const RequestPipeline::PipeSpec ps,
int stage, int instNum,
RequestPipeline::InstData * data) {
ShowNeighborData* mydata = static_cast<ShowNeighborData*>(data);
vector<BgpNeighborResp> nbr_list;
const BgpNeighborReq *req = static_cast<const BgpNeighborReq *>(ps.snhRequest_.get());
BgpSandeshContext *bsc = static_cast<BgpSandeshContext *>(req->client_context());
RoutingInstanceMgr *rim = bsc->bgp_server->routing_instance_mgr();
if (req->get_domain() != "") {
RoutingInstance *ri = rim->GetRoutingInstance(req->get_domain());
if (ri)
ri->peer_manager()->FillBgpNeighborInfo(mydata->nbr_list,
ri->peer_manager()->FillBgpNeighborInfo(nbr_list,
req->get_ip_address());
} else {
RoutingInstanceMgr::RoutingInstanceIterator it = rim->begin();
for (;it != rim->end(); it++) {
it->peer_manager()->FillBgpNeighborInfo(mydata->nbr_list,
it->peer_manager()->FillBgpNeighborInfo(nbr_list,
req->get_ip_address());
}
}

bsc->xmpp_peer_manager->VisitChannels(boost::bind(FillXmppNeighborInfo,
&mydata->nbr_list, bsc->bgp_server, _1));

return true;
}

bool ShowNeighborHandler::CallbackS2(const Sandesh *sr,
const RequestPipeline::PipeSpec ps,
int stage, int instNum,
RequestPipeline::InstData *data) {
ShowNeighborDataS2* mydata = static_cast<ShowNeighborDataS2*>(data);
int inst_id = ps.stages_[stage].instances_[instNum];
const BgpNeighborReq *req = static_cast<const BgpNeighborReq *>(ps.snhRequest_.get());
BgpSandeshContext *bsc = static_cast<BgpSandeshContext *>(req->client_context());
RoutingInstanceMgr *rim = bsc->bgp_server->routing_instance_mgr();
RoutingInstanceMgr::NameIterator i = rim->name_begin();
for (;i != rim->name_end(); i++) {
RoutingInstance::RouteTableList::const_iterator j =
i->second->GetTables().begin();
for (;j != i->second->GetTables().end(); j++) {
FillNeighborStats(mydata, j->second, inst_id);
}
}
return true;
}

bool ShowNeighborHandler::CallbackS3(const Sandesh *sr,
const RequestPipeline::PipeSpec ps,
int stage, int instNum,
RequestPipeline::InstData *data) {
const BgpNeighborReq *req = static_cast<const BgpNeighborReq *>(ps.snhRequest_.get());
const RequestPipeline::StageData *sd[2] = { ps.GetStageData(0), ps.GetStageData(1) };
const ShowNeighborData &nbrs = static_cast<const ShowNeighborData &>(sd[0]->at(0));

vector<BgpNeighborResp> nbr_list = nbrs.nbr_list;

for (size_t i = 0; i < nbrs.nbr_list.size(); i++) {
ShowNeighborDataS2Key key;
key.peer = nbrs.nbr_list[i].peer;
for (size_t j = 0; j < nbrs.nbr_list[i].routing_tables.size(); j++) {
key.table = nbrs.nbr_list[i].routing_tables[j].name;
for (size_t k = 0; k < sd[1]->size(); k++) {
const ShowNeighborDataS2 &stats_data =
static_cast<const ShowNeighborDataS2 &>(sd[1]->at(k));
ShowNeighborDataS2::Map::const_iterator it = stats_data.peers.find(key);
if (it == stats_data.peers.end()) continue;
nbr_list[i].routing_tables[j].active_prefixes +=
it->second.active_prefixes;
nbr_list[i].routing_tables[j].received_prefixes +=
it->second.received_prefixes;
nbr_list[i].routing_tables[j].accepted_prefixes +=
it->second.accepted_prefixes;
}
}
}
&nbr_list, bsc->bgp_server, _1));

BgpNeighborListResp *resp = new BgpNeighborListResp;
resp->set_neighbors(nbrs.nbr_list);
resp->set_neighbors(nbr_list);
resp->set_context(req->context());
resp->Response();
return true;
Expand All @@ -567,6 +459,18 @@ class ShowNeighborStatisticsHandler {
BgpServer *bgp_server);
};

// handler for 'show bgp neighbor'
void BgpNeighborReq::HandleRequest() const {
RequestPipeline::PipeSpec ps(this);
RequestPipeline::StageSpec s1;
TaskScheduler *scheduler = TaskScheduler::GetInstance();
s1.taskId_ = scheduler->GetTaskId("bgp::PeerMembership");
s1.cbFn_ = ShowNeighborHandler::CallbackS1;
s1.instances_.push_back(0);
ps.stages_= list_of(s1);
RequestPipeline rp(ps);
}

void ShowNeighborStatisticsHandler::FillXmppNeighborStatistics(
size_t *count, BgpServer *bgp_server, string domain,
string up_or_down, BgpXmppChannel *channel) {
Expand Down Expand Up @@ -666,39 +570,6 @@ void ShowNeighborStatisticsReq::HandleRequest() const {
RequestPipeline rp(ps);
}

// handler for 'show bgp neighbor'
void BgpNeighborReq::HandleRequest() const {
RequestPipeline::PipeSpec ps(this);
BgpSandeshContext *bsc = static_cast<BgpSandeshContext *>(client_context());

// Request pipeline has 3 stages:
// First stage to collect neighbor info
// Second stage to collect stats
// Third stage to collate all data and respond to the request
RequestPipeline::StageSpec s1, s2, s3;
TaskScheduler *scheduler = TaskScheduler::GetInstance();
s1.taskId_ = scheduler->GetTaskId("bgp::PeerMembership");
s1.allocFn_ = ShowNeighborHandler::CreateData;
s1.cbFn_ = ShowNeighborHandler::CallbackS1;
s1.instances_.push_back(
PeerRibMembershipManager::kMembershipTaskInstanceId);

s2.taskId_ = scheduler->GetTaskId("db::DBTable");
s2.allocFn_ = ShowNeighborHandler::CreateData;
s2.cbFn_ = ShowNeighborHandler::CallbackS2;
for (int i = 0; i < bsc->bgp_server->database()->PartitionCount(); i++) {
s2.instances_.push_back(i);
}

s3.taskId_ = scheduler->GetTaskId("bgp::ShowCommand");
s3.allocFn_ = ShowNeighborHandler::CreateData;
s3.cbFn_ = ShowNeighborHandler::CallbackS3;
s3.instances_.push_back(0);
ps.stages_= list_of(s1)(s2)(s3);
RequestPipeline rp(ps);

}

class ClearBgpNeighborHandler {
public:
static bool CallbackS1(const Sandesh *sr,
Expand Down

0 comments on commit 8a7a373

Please sign in to comment.