tools: create face during nfdc route add
refs #4332
Change-Id: I1a30bf87abd57bab08a2c027870e779392de0104
diff --git a/tools/nfdc/rib-module.cpp b/tools/nfdc/rib-module.cpp
index b41d33a..544da6e 100644
--- a/tools/nfdc/rib-module.cpp
+++ b/tools/nfdc/rib-module.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2018, Regents of the University of California,
+ * Copyright (c) 2014-2020, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -24,6 +24,8 @@
*/
#include "rib-module.hpp"
+#include "canonizer.hpp"
+#include "face-module.hpp"
#include "find-face.hpp"
#include "format-helpers.hpp"
@@ -151,18 +153,96 @@
bool wantCapture = ctx.args.get<bool>("capture", false);
auto expiresMillis = ctx.args.getOptional<uint64_t>("expires");
+ auto registerRoute = [&] (uint64_t faceId) {
+ ControlParameters registerParams;
+ registerParams
+ .setName(prefix)
+ .setFaceId(faceId)
+ .setOrigin(origin)
+ .setCost(cost)
+ .setFlags((wantChildInherit ? ndn::nfd::ROUTE_FLAG_CHILD_INHERIT : ndn::nfd::ROUTE_FLAGS_NONE) |
+ (wantCapture ? ndn::nfd::ROUTE_FLAG_CAPTURE : ndn::nfd::ROUTE_FLAGS_NONE));
+ if (expiresMillis) {
+ registerParams.setExpirationPeriod(time::milliseconds(*expiresMillis));
+ }
+
+ ctx.controller.start<ndn::nfd::RibRegisterCommand>(
+ registerParams,
+ [&] (const ControlParameters& resp) {
+ ctx.exitCode = static_cast<int>(FindFace::Code::OK);
+ ctx.out << "route-add-accepted ";
+ text::ItemAttributes ia;
+ ctx.out << ia("prefix") << resp.getName()
+ << ia("nexthop") << resp.getFaceId()
+ << ia("origin") << resp.getOrigin()
+ << ia("cost") << resp.getCost()
+ << ia("flags") << static_cast<ndn::nfd::RouteFlags>(resp.getFlags());
+ if (resp.hasExpirationPeriod()) {
+ ctx.out << ia("expires") << text::formatDuration<time::milliseconds>(resp.getExpirationPeriod()) << "\n";
+ }
+ else {
+ ctx.out<< ia("expires") << "never\n";
+ }
+ },
+ ctx.makeCommandFailureHandler("adding route"),
+ ctx.makeCommandOptions());
+ };
+
+ auto handleFaceNotFound = [&] {
+ const FaceUri* faceUri = ndn::any_cast<FaceUri>(&nexthop);
+ if (faceUri == nullptr) {
+ ctx.err << "Face not found\n";
+ return;
+ }
+
+ if (faceUri->getScheme() == "ether") {
+ // Unicast Ethernet faces require a LocalUri, which hasn't been provided
+ // Multicast Ethernet faces cannot be created via management (already exist on each interface)
+ ctx.err << "Unable to implicitly create Ethernet faces\n";
+ ctx.err << "Please create the face with 'nfdc face create' before adding the route\n";
+ return;
+ }
+
+ optional<FaceUri> canonized;
+ std::string error;
+ std::tie(canonized, error) = canonize(ctx, *faceUri);
+ if (!canonized) {
+ // Canonization failed
+ auto canonizationError = canonizeErrorHelper(*faceUri, error);
+ ctx.exitCode = static_cast<int>(canonizationError.first);
+ ctx.err << canonizationError.second << '\n';
+ return;
+ }
+
+ ControlParameters faceCreateParams;
+ faceCreateParams.setUri(canonized->toString());
+
+ ctx.controller.start<ndn::nfd::FaceCreateCommand>(
+ faceCreateParams,
+ [&] (const ControlParameters& resp) {
+ FaceModule::printSuccess(ctx.out, "face-created", resp);
+ registerRoute(resp.getFaceId());
+ },
+ ctx.makeCommandFailureHandler("implicitly creating face"),
+ ctx.makeCommandOptions());
+ };
+
FindFace findFace(ctx);
FindFace::Code res = findFace.execute(nexthop);
ctx.exitCode = static_cast<int>(res);
switch (res) {
case FindFace::Code::OK:
+ registerRoute(findFace.getFaceId());
break;
case FindFace::Code::ERROR:
case FindFace::Code::CANONIZE_ERROR:
- case FindFace::Code::NOT_FOUND:
ctx.err << findFace.getErrorReason() << '\n';
return;
+ case FindFace::Code::NOT_FOUND:
+ // Attempt to create face if it doesn't exist
+ handleFaceNotFound();
+ break;
case FindFace::Code::AMBIGUOUS:
ctx.err << "Multiple faces match specified remote FaceUri. Re-run the command with a FaceId:";
findFace.printDisambiguation(ctx.err, FindFace::DisambiguationStyle::LOCAL_URI);
@@ -173,38 +253,6 @@
return;
}
- ControlParameters registerParams;
- registerParams
- .setName(prefix)
- .setFaceId(findFace.getFaceId())
- .setOrigin(origin)
- .setCost(cost)
- .setFlags((wantChildInherit ? ndn::nfd::ROUTE_FLAG_CHILD_INHERIT : ndn::nfd::ROUTE_FLAGS_NONE) |
- (wantCapture ? ndn::nfd::ROUTE_FLAG_CAPTURE : ndn::nfd::ROUTE_FLAGS_NONE));
- if (expiresMillis) {
- registerParams.setExpirationPeriod(time::milliseconds(*expiresMillis));
- }
-
- ctx.controller.start<ndn::nfd::RibRegisterCommand>(
- registerParams,
- [&] (const ControlParameters& resp) {
- ctx.out << "route-add-accepted ";
- text::ItemAttributes ia;
- ctx.out << ia("prefix") << resp.getName()
- << ia("nexthop") << resp.getFaceId()
- << ia("origin") << resp.getOrigin()
- << ia("cost") << resp.getCost()
- << ia("flags") << static_cast<ndn::nfd::RouteFlags>(resp.getFlags());
- if (resp.hasExpirationPeriod()) {
- ctx.out << ia("expires") << text::formatDuration<time::milliseconds>(resp.getExpirationPeriod()) << "\n";
- }
- else {
- ctx.out<< ia("expires") << "never\n";
- }
- },
- ctx.makeCommandFailureHandler("adding route"),
- ctx.makeCommandOptions());
-
ctx.face.processEvents();
}