42 parser.
addAlias(
"route",
"list",
"");
46 .
setTitle(
"show routes toward a prefix")
74 auto nexthopIt = ctx.
args.find(
"nexthop");
75 std::set<uint64_t> nexthops;
78 if (nexthopIt != ctx.
args.end()) {
82 ctx.
exitCode =
static_cast<int>(res);
92 BOOST_ASSERT_MSG(
false,
"unexpected FindFace result");
99 listRoutesImpl(ctx, [&] (
const RibEntry&,
const Route& route) {
100 return (nexthops.empty() || nexthops.count(route.getFaceId()) > 0) &&
101 (!origin || route.getOrigin() == *origin);
108 auto prefix = ctx.
args.
get<Name>(
"prefix");
110 listRoutesImpl(ctx, [&] (
const RibEntry& entry,
const Route&) {
111 return entry.getName() == prefix;
116 RibModule::listRoutesImpl(
ExecuteContext& ctx,
const RoutePredicate& filter)
119 [&] (
const auto& dataset) {
120 bool hasRoute =
false;
121 for (
const RibEntry& entry : dataset) {
122 for (
const Route& route : entry.getRoutes()) {
123 if (filter(entry, route)) {
125 formatRouteText(ctx.
out, entry, route,
true);
133 ctx.
err <<
"Route not found\n";
139 ctx.
face.processEvents();
145 auto prefix = ctx.
args.
get<Name>(
"prefix");
146 auto nexthop = ctx.
args.at(
"nexthop");
147 auto origin = ctx.
args.
get<RouteOrigin>(
"origin", ndn::nfd::ROUTE_ORIGIN_STATIC);
148 auto cost = ctx.
args.
get<uint64_t>(
"cost", 0);
149 bool wantChildInherit = !ctx.
args.
get<
bool>(
"no-inherit",
false);
150 bool wantCapture = ctx.
args.
get<
bool>(
"capture",
false);
153 auto registerRoute = [&] (uint64_t faceId) {
154 ControlParameters registerParams;
160 .setFlags((wantChildInherit ? ndn::nfd::ROUTE_FLAG_CHILD_INHERIT : ndn::nfd::ROUTE_FLAGS_NONE) |
161 (wantCapture ? ndn::nfd::ROUTE_FLAG_CAPTURE : ndn::nfd::ROUTE_FLAGS_NONE));
163 registerParams.setExpirationPeriod(time::milliseconds(*expiresMillis));
166 ctx.
controller.start<ndn::nfd::RibRegisterCommand>(
168 [&] (
const ControlParameters& resp) {
170 ctx.
out <<
"route-add-accepted ";
172 ctx.
out << ia(
"prefix") << resp.getName()
173 << ia(
"nexthop") << resp.getFaceId()
174 << ia(
"origin") << resp.getOrigin()
175 << ia(
"cost") << resp.getCost()
176 << ia(
"flags") <<
static_cast<ndn::nfd::RouteFlags
>(resp.getFlags());
177 if (resp.hasExpirationPeriod()) {
178 ctx.
out << ia(
"expires") << text::formatDuration<time::milliseconds>(resp.getExpirationPeriod()) <<
"\n";
181 ctx.
out<< ia(
"expires") <<
"never\n";
188 auto handleFaceNotFound = [&] {
189 const FaceUri* faceUri = std::any_cast<FaceUri>(&nexthop);
190 if (faceUri ==
nullptr) {
191 ctx.
err <<
"Face not found\n";
195 if (faceUri->getScheme() ==
"ether") {
198 ctx.
err <<
"Unable to implicitly create Ethernet faces\n";
199 ctx.
err <<
"Please create the face with 'nfdc face create' before adding the route\n";
203 auto [canonized, error] =
canonize(ctx, *faceUri);
207 ctx.
exitCode =
static_cast<int>(canonizationError.first);
208 ctx.
err << canonizationError.second <<
'\n';
212 ControlParameters faceCreateParams;
213 faceCreateParams.setUri(canonized->toString());
215 ctx.
controller.start<ndn::nfd::FaceCreateCommand>(
217 [&] (
const ControlParameters& resp) {
219 registerRoute(resp.getFaceId());
228 ctx.
exitCode =
static_cast<int>(res);
239 handleFaceNotFound();
242 ctx.
err <<
"Multiple faces match specified remote FaceUri. Re-run the command with a FaceId:";
247 BOOST_ASSERT_MSG(
false,
"unexpected FindFace result");
251 ctx.
face.processEvents();
257 auto prefix = ctx.
args.
get<Name>(
"prefix");
258 auto nexthop = ctx.
args.at(
"nexthop");
259 auto origin = ctx.
args.
get<RouteOrigin>(
"origin", ndn::nfd::ROUTE_ORIGIN_STATIC);
264 ctx.
exitCode =
static_cast<int>(res);
271 ctx.
err << findFace.getErrorReason() <<
'\n';
274 BOOST_ASSERT_MSG(
false,
"unexpected FindFace result");
278 for (uint64_t faceId : findFace.getFaceIds()) {
279 ControlParameters unregisterParams;
285 ctx.
controller.start<ndn::nfd::RibUnregisterCommand>(
287 [&] (
const ControlParameters& resp) {
288 ctx.
out <<
"route-removed ";
290 ctx.
out << ia(
"prefix") << resp.getName()
291 << ia(
"nexthop") << resp.getFaceId()
292 << ia(
"origin") << resp.getOrigin()
299 ctx.
face.processEvents();
304 const std::function<
void()>& onSuccess,
305 const Controller::DatasetFailCallback& onFailure,
306 const CommandOptions& options)
308 controller.fetch<ndn::nfd::RibDataset>(
309 [
this, onSuccess] (
const auto& result) {
320 for (
const RibEntry& item : m_status) {
321 this->formatItemXml(os, item);
327 RibModule::formatItemXml(std::ostream& os,
const RibEntry& item)
const
331 os <<
"<prefix>" <<
xml::Text{item.getName().toUri()} <<
"</prefix>";
334 for (
const Route& route : item.getRoutes()) {
336 <<
"<faceId>" << route.getFaceId() <<
"</faceId>"
337 <<
"<origin>" << route.getOrigin() <<
"</origin>"
338 <<
"<cost>" << route.getCost() <<
"</cost>";
339 if (route.getFlags() == ndn::nfd::ROUTE_FLAGS_NONE) {
344 if (route.isChildInherit()) {
345 os <<
"<childInherit/>";
347 if (route.isRibCapture()) {
348 os <<
"<ribCapture/>";
352 if (route.hasExpirationPeriod()) {
353 os <<
"<expirationPeriod>"
355 <<
"</expirationPeriod>";
368 for (
const RibEntry& item : m_status) {
370 formatEntryText(os, item);
376 RibModule::formatEntryText(std::ostream& os,
const RibEntry& entry)
378 os << entry.getName() <<
" routes={";
381 for (
const Route& route : entry.getRoutes()) {
383 formatRouteText(os, entry, route,
false);
390 RibModule::formatRouteText(std::ostream& os,
const RibEntry& entry,
const Route& route,
393 text::ItemAttributes ia;
396 os << ia(
"prefix") << entry.getName();
398 os << ia(
"nexthop") << route.getFaceId();
399 os << ia(
"origin") << route.getOrigin();
400 os << ia(
"cost") << route.getCost();
401 os << ia(
"flags") <<
static_cast<ndn::nfd::RouteFlags
>(route.
getFlags());
402 if (route.hasExpirationPeriod()) {
403 os << ia(
"expires") << text::formatDuration<time::seconds>(route.getExpirationPeriod());
406 os << ia(
"expires") <<
"never";
Represents a route for a name prefix.
std::underlying_type_t< ndn::nfd::RouteFlags > getFlags() const
Context for command execution.
std::ostream & out
output stream
Controller::DatasetFailCallback makeDatasetFailureHandler(const std::string &datasetName)
const CommandArguments & args
int exitCode
program exit code
Controller::CommandFailCallback makeCommandFailureHandler(const std::string &commandName)
ndn::nfd::CommandOptions makeCommandOptions() const
std::ostream & err
error stream
Print attributes of an item.
Print different string on first and subsequent usage.