Skip to content

Commit

Permalink
CLI interface to see only dry run routes
Browse files Browse the repository at this point in the history
Summary:
A way to see only routes in dry run mode. At fib level we can only see non-dry run routes, by having ability to see uninstallabe/dryrun routes alone, we can quickly compare with bgp route table and expected behavior. This command routes will not intermix bgp and openr during dry run verification so easy to compare.
Let me know what you guys think.

Reviewed By: jstrizich

Differential Revision: D15701821

fbshipit-source-id: 96e0326a88fb2355cf14b85df9850c6dc4f27294
  • Loading branch information
Nanda Kishore Salem authored and facebook-github-bot committed Jun 7, 2019
1 parent 790d866 commit d36d872
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 0 deletions.
19 changes: 19 additions & 0 deletions openr/ctrl-server/OpenrCtrlHandler.cpp
Expand Up @@ -432,6 +432,25 @@ OpenrCtrlHandler::semifuture_getRouteDb() {
return p.getSemiFuture();
}

folly::SemiFuture<std::unique_ptr<thrift::RouteDatabase>>
OpenrCtrlHandler::semifuture_getRouteDbUnInstallable() {
folly::Promise<std::unique_ptr<thrift::RouteDatabase>> p;

thrift::FibRequest request;
request.cmd = thrift::FibCommand::ROUTE_DB_UNINSTALLABLE_GET;

auto reply = requestReplyThrift<thrift::RouteDatabase>(
thrift::OpenrModuleType::FIB, std::move(request));
if (reply.hasError()) {
p.setException(thrift::OpenrError(reply.error().errString));
} else {
p.setValue(
std::make_unique<thrift::RouteDatabase>(std::move(reply.value())));
}

return p.getSemiFuture();
}

folly::SemiFuture<std::unique_ptr<thrift::RouteDatabase>>
OpenrCtrlHandler::semifuture_getRouteDbComputed(
std::unique_ptr<std::string> nodeName) {
Expand Down
3 changes: 3 additions & 0 deletions openr/ctrl-server/OpenrCtrlHandler.h
Expand Up @@ -95,6 +95,9 @@ class OpenrCtrlHandler final : public thrift::OpenrCtrlCppSvIf,
folly::SemiFuture<std::unique_ptr<thrift::RouteDatabase>>
semifuture_getRouteDbComputed(std::unique_ptr<std::string> nodeName) override;

folly::SemiFuture<std::unique_ptr<thrift::RouteDatabase>>
semifuture_getRouteDbUnInstallable() override;

//
// Performance stats APIs
//
Expand Down
10 changes: 10 additions & 0 deletions openr/fib/Fib.cpp
Expand Up @@ -219,6 +219,11 @@ Fib::processRequestMsg(fbzmq::Message&& request) {
// send the thrift::PerfDatabase
return fbzmq::Message::fromThriftObj(dumpPerfDb(), serializer_);
break;
case thrift::FibCommand::ROUTE_DB_UNINSTALLABLE_GET:
VLOG(2) << "Fib: Do not install RouteDb requested";
// send the thrift::RouteDatabase
return fbzmq::Message::fromThriftObj(doNotInstallRouteDb_, serializer_);
break;
default:
LOG(ERROR) << "Unknown command received";
return folly::makeUnexpected(fbzmq::Error());
Expand All @@ -227,6 +232,8 @@ Fib::processRequestMsg(fbzmq::Message&& request) {

void
Fib::processRouteDb(thrift::RouteDatabase&& newRouteDb) {
thrift::RouteDatabase doNotInstallRouteDb;

VLOG(2) << "Processing new routes from Decision. "
<< newRouteDb.unicastRoutes.size() << " unicast routes and "
<< newRouteDb.mplsRoutes.size() << " mpls routes";
Expand All @@ -242,6 +249,8 @@ Fib::processRouteDb(thrift::RouteDatabase&& newRouteDb) {
auto rIter = newRouteDb.unicastRoutes.begin();
while (rIter != newRouteDb.unicastRoutes.end()) {
if (rIter->doNotInstall) {
doNotInstallRouteDb.unicastRoutes.emplace_back(
*std::make_move_iterator(rIter));
rIter = newRouteDb.unicastRoutes.erase(rIter);
} else {
++rIter;
Expand All @@ -252,6 +261,7 @@ Fib::processRouteDb(thrift::RouteDatabase&& newRouteDb) {
auto const routeDelta = findDeltaRoutes(newRouteDb, routeDb_);
// update new routeDb_
routeDb_ = std::move(newRouteDb);
doNotInstallRouteDb_ = std::move(doNotInstallRouteDb);
// Add some counters
tData_.addStatValue("fib.process_route_db", 1, fbzmq::COUNT);
// Send request to agent
Expand Down
2 changes: 2 additions & 0 deletions openr/fib/Fib.h
Expand Up @@ -139,6 +139,8 @@ class Fib final : public OpenrEventLoop {
// received route-db if provided.
folly::Optional<thrift::PerfEvents> maybePerfEvents_;
thrift::RouteDatabase routeDb_;
// Route DB containing only dry run or not installed routes
thrift::RouteDatabase doNotInstallRouteDb_;
std::deque<thrift::PerfEvents> perfDb_;

// Flag to indicate the result of previous route programming attempt.
Expand Down
1 change: 1 addition & 0 deletions openr/if/Fib.thrift
Expand Up @@ -37,6 +37,7 @@ struct PerfDatabase {
enum FibCommand {
ROUTE_DB_GET = 1,
PERF_DB_GET = 2,
ROUTE_DB_UNINSTALLABLE_GET = 3,
}

struct FibRequest {
Expand Down
6 changes: 6 additions & 0 deletions openr/if/OpenrCtrl.thrift
Expand Up @@ -113,6 +113,12 @@ service OpenrCtrl extends fb303.FacebookService {
Fib.RouteDatabase getRouteDbComputed(1: string nodeName)
throws (1: OpenrError error)

/**
* Get route database of the current node which are not installable.
*/
Fib.RouteDatabase getRouteDbUnInstallable()
throws (1: OpenrError error)

//
// Performance stats APIs
//
Expand Down
27 changes: 27 additions & 0 deletions openr/py/openr/cli/clis/fib.py
Expand Up @@ -22,6 +22,9 @@ class FibCli(object):
def __init__(self):
self.fib.add_command(FibRoutesComputedCli().routes, name="routes-computed")
self.fib.add_command(FibRoutesInstalledCli().routes, name="routes-installed")
self.fib.add_command(
FibRoutesUnInstallableCli().routes, name="routes-uninstallable"
)

# NOTE: keeping alias `list` and `routes`
# for backward compatibility. Deprecated.
Expand Down Expand Up @@ -109,6 +112,30 @@ def routes(cli_opts, prefixes, labels, json): # noqa: B902
fib.FibRoutesComputedCmd(cli_opts).run(prefixes, labels, json)


class FibRoutesUnInstallableCli(object):
@click.command()
@click.option(
"--prefixes",
"-p",
default="",
multiple=True,
help="Get route for specific IPs or Prefixes.",
)
@click.option(
"--labels",
"-l",
type=click.INT,
multiple=True,
help="Get route for specific labels.",
)
@click.option("--json/--no-json", default=False, help="Dump in JSON format")
@click.pass_obj
def routes(cli_opts, prefixes, labels, json): # noqa: B902
""" Request un installable routing table of the current host """

fib.FibRoutesUnInstallableCmd(cli_opts).run(prefixes, labels, json)


class FibAddRoutesCli(object):
@click.command()
@click.argument("prefixes") # Comma separated list of prefixes
Expand Down
12 changes: 12 additions & 0 deletions openr/py/openr/cli/commands/fib.py
Expand Up @@ -52,6 +52,18 @@ def _run(
utils.print_route_db(route_db, prefixes, labels)


class FibRoutesUnInstallableCmd(OpenrCtrlCmd):
def _run(
self, client: OpenrCtrl.Client, prefixes: Any, labels: Any, json: bool
) -> None:
route_db = client.getRouteDbUnInstallable()
if json:
route_db_dict = {route_db.thisNodeName: utils.route_db_to_dict(route_db)}
utils.print_routes_json(route_db_dict, prefixes, labels)
else:
utils.print_route_db(route_db, prefixes, labels)


class FibCountersCmd(FibAgentCmd):
def run(self, json_opt):
try:
Expand Down

0 comments on commit d36d872

Please sign in to comment.