33 #include <ndn-cxx/lp/tags.hpp> 34 #include <ndn-cxx/mgmt/nfd/face-status.hpp> 35 #include <ndn-cxx/mgmt/nfd/rib-entry.hpp> 51 ndn::nfd::Controller& nfdController, Dispatcher& dispatcher)
54 , m_keyChain(keyChain)
55 , m_nfdController(nfdController)
56 , m_dispatcher(dispatcher)
58 , m_localhostValidator(face)
59 , m_localhopValidator(face)
60 , m_isLocalhopEnabled(false)
62 registerCommandHandler<ndn::nfd::RibRegisterCommand>(
"register",
63 bind(&RibManager::registerEntry,
this, _2, _3, _4, _5));
64 registerCommandHandler<ndn::nfd::RibUnregisterCommand>(
"unregister",
65 bind(&RibManager::unregisterEntry,
this, _2, _3, _4, _5));
73 m_localhostValidator.load(section, filename);
79 m_localhopValidator.load(section, filename);
80 m_isLocalhopEnabled =
true;
86 m_isLocalhopEnabled =
false;
92 registerTopPrefix(LOCALHOST_TOP_PREFIX);
94 if (m_isLocalhopEnabled) {
98 NFD_LOG_INFO(
"Start monitoring face create/destroy events");
99 m_faceMonitor.onNotification.connect(bind(&RibManager::onNotification,
this, _1));
100 m_faceMonitor.start();
102 scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
108 m_nfdController.start<ndn::nfd::FaceUpdateCommand>(
109 ControlParameters().setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
true),
110 [] (
const ControlParameters&) {
113 [] (
const ControlResponse& res) {
114 NDN_THROW(
Error(
"Couldn't enable local fields (" + to_string(res.getCode()) +
115 " " + res.getText() +
")"));
120 RibManager::beginAddRoute(
const Name& name, Route route, optional<time::nanoseconds> expires,
121 const std::function<
void(RibUpdateResult)>& done)
124 route.expires = time::steady_clock::now() + *expires;
126 else if (route.expires) {
127 expires = *route.expires - time::steady_clock::now();
130 if (expires && *expires <= 0_s) {
132 return done(RibUpdateResult::EXPIRED);
135 NFD_LOG_INFO(
"Adding route " << name <<
" nexthop=" << route.faceId <<
136 " origin=" << route.origin <<
" cost=" << route.cost);
140 route.setExpirationEvent(event);
141 NFD_LOG_TRACE(
"Scheduled unregistration at: " << *route.expires);
144 m_registeredFaces.insert(route.faceId);
147 update.setAction(RibUpdate::REGISTER)
150 beginRibUpdate(update, done);
154 RibManager::beginRemoveRoute(
const Name& name,
const Route& route,
155 const std::function<
void(RibUpdateResult)>& done)
157 NFD_LOG_INFO(
"Removing route " << name <<
" nexthop=" << route.faceId <<
158 " origin=" << route.origin);
161 update.setAction(RibUpdate::UNREGISTER)
164 beginRibUpdate(update, done);
168 RibManager::beginRibUpdate(
const RibUpdate& update,
169 const std::function<
void(RibUpdateResult)>& done)
174 done(RibUpdateResult::OK);
176 [=] (uint32_t code,
const std::string& error) {
177 NFD_LOG_DEBUG(
"RIB update failed for " << update <<
" (" << code <<
" " << error <<
")");
180 scheduleActiveFaceFetch(1_s);
182 done(RibUpdateResult::ERROR);
187 RibManager::registerTopPrefix(
const Name& topPrefix)
190 m_nfdController.start<ndn::nfd::FibAddNextHopCommand>(
191 ControlParameters().setName(Name(topPrefix).append(MGMT_MODULE_NAME))
193 [=] (
const ControlParameters& res) {
194 NFD_LOG_DEBUG(
"Successfully registered " << topPrefix <<
" with NFD");
198 route.faceId = res.getFaceId();
199 route.origin = ndn::nfd::ROUTE_ORIGIN_APP;
200 route.flags = ndn::nfd::ROUTE_FLAG_CHILD_INHERIT;
202 m_rib.
insert(topPrefix, route);
204 m_registeredFaces.insert(route.faceId);
206 [=] (
const ControlResponse& res) {
207 NDN_THROW(
Error(
"Cannot add FIB entry " + topPrefix.toUri() +
" (" +
208 to_string(res.getCode()) +
" " + res.getText() +
")"));
212 m_dispatcher.addTopPrefix(topPrefix,
false);
216 RibManager::registerEntry(
const Name& topPrefix,
const Interest& interest,
217 ControlParameters parameters,
218 const ndn::mgmt::CommandContinuation& done)
220 if (parameters.getName().size() > Fib::getMaxDepth()) {
221 done(ControlResponse(414,
"Route prefix cannot exceed " + to_string(Fib::getMaxDepth()) +
226 setFaceForSelfRegistration(interest, parameters);
229 done(ControlResponse(200,
"Success").setBody(parameters.wireEncode()));
232 route.faceId = parameters.getFaceId();
233 route.origin = parameters.getOrigin();
234 route.cost = parameters.getCost();
235 route.flags = parameters.getFlags();
237 optional<time::nanoseconds> expires;
238 if (parameters.hasExpirationPeriod() &&
239 parameters.getExpirationPeriod() != time::milliseconds::max()) {
240 expires = time::duration_cast<time::nanoseconds>(parameters.getExpirationPeriod());
243 beginAddRoute(parameters.getName(), std::move(route), expires, [] (RibUpdateResult) {});
247 RibManager::unregisterEntry(
const Name& topPrefix,
const Interest& interest,
248 ControlParameters parameters,
249 const ndn::mgmt::CommandContinuation& done)
251 setFaceForSelfRegistration(interest, parameters);
254 done(ControlResponse(200,
"Success").setBody(parameters.wireEncode()));
257 route.faceId = parameters.getFaceId();
258 route.origin = parameters.getOrigin();
260 beginRemoveRoute(parameters.getName(), route, [] (RibUpdateResult) {});
264 RibManager::listEntries(
const Name& topPrefix,
const Interest& interest,
265 ndn::mgmt::StatusDatasetContext& context)
267 auto now = time::steady_clock::now();
268 for (
const auto& kv : m_rib) {
270 ndn::nfd::RibEntry item;
272 for (
const Route& route : entry.
getRoutes()) {
274 r.setFaceId(route.faceId);
275 r.setOrigin(route.origin);
276 r.setCost(route.cost);
277 r.setFlags(route.flags);
279 r.setExpirationPeriod(time::duration_cast<time::milliseconds>(*route.expires - now));
283 context.append(item.wireEncode());
289 RibManager::setFaceForSelfRegistration(
const Interest& request, ControlParameters& parameters)
291 bool isSelfRegistration = (parameters.getFaceId() == 0);
292 if (isSelfRegistration) {
293 shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = request.getTag<lp::IncomingFaceIdTag>();
297 BOOST_ASSERT(incomingFaceIdTag !=
nullptr);
298 parameters.setFaceId(*incomingFaceIdTag);
302 ndn::mgmt::Authorization
303 RibManager::makeAuthorization(
const std::string& verb)
305 return [
this] (
const Name& prefix,
const Interest& interest,
306 const ndn::mgmt::ControlParameters* params,
307 const ndn::mgmt::AcceptContinuation& accept,
308 const ndn::mgmt::RejectContinuation& reject) {
309 BOOST_ASSERT(params !=
nullptr);
310 BOOST_ASSERT(
typeid(*params) ==
typeid(ndn::nfd::ControlParameters));
313 ndn::ValidatorConfig& validator = prefix == LOCALHOST_TOP_PREFIX ?
314 m_localhostValidator : m_localhopValidator;
315 validator.validate(interest,
317 bind([reject] { reject(ndn::mgmt::RejectReply::STATUS403); }));
328 return os <<
"ERROR";
330 return os <<
"VALIDATION_FAILURE";
332 return os <<
"EXPIRED";
334 return os <<
"NOT_FOUND";
336 BOOST_ASSERT_MSG(
false,
"bad SlAnnounceResult");
341 RibManager::getSlAnnounceResultFromRibUpdateResult(RibUpdateResult r)
344 case RibUpdateResult::OK:
346 case RibUpdateResult::ERROR:
348 case RibUpdateResult::EXPIRED:
360 BOOST_ASSERT(pa.getData());
362 if (!m_isLocalhopEnabled) {
363 NFD_LOG_INFO(
"slAnnounce " << pa.getAnnouncedName() <<
" " << faceId <<
364 ": localhop_security unconfigured");
369 m_localhopValidator.validate(*pa.getData(),
371 Route route(pa, faceId);
372 route.expires = std::min(route.annExpires, time::steady_clock::now() + maxLifetime);
373 beginAddRoute(pa.getAnnouncedName(), route, nullopt,
374 [=] (RibUpdateResult ribRes) {
375 auto res = getSlAnnounceResultFromRibUpdateResult(ribRes);
376 NFD_LOG_INFO(
"slAnnounce " << pa.getAnnouncedName() <<
" " << faceId <<
": " << res);
380 [=] (
const Data&, ndn::security::v2::ValidationError err) {
381 NFD_LOG_INFO(
"slAnnounce " << pa.getAnnouncedName() <<
" " << faceId <<
382 " validation error: " << err);
393 routeQuery.faceId = faceId;
394 routeQuery.origin = ndn::nfd::ROUTE_ORIGIN_PREFIXANN;
397 if (oldRoute ==
nullptr || !oldRoute->announcement) {
398 NFD_LOG_DEBUG(
"slRenew " << name <<
" " << faceId <<
": not found");
401 Name routeName = oldRoute->announcement->getAnnouncedName();
403 Route route = *oldRoute;
404 route.expires = std::min(route.annExpires, time::steady_clock::now() + maxLifetime);
405 beginAddRoute(routeName, route, nullopt,
406 [=] (RibUpdateResult ribRes) {
407 auto res = getSlAnnounceResultFromRibUpdateResult(ribRes);
408 NFD_LOG_INFO(
"slRenew " << name <<
" " << faceId <<
": " << res <<
" " << routeName);
416 shared_ptr<rib::RibEntry> entry;
417 auto exactMatch = m_rib.
find(name);
418 if (exactMatch != m_rib.
end()) {
419 entry = exactMatch->second;
424 if (entry ==
nullptr) {
428 auto pa = entry->getPrefixAnnouncement();
429 pa.toData(m_keyChain);
434 RibManager::fetchActiveFaces()
438 m_nfdController.fetch<ndn::nfd::FaceDataset>(
439 bind(&RibManager::removeInvalidFaces,
this, _1),
440 bind(&RibManager::onFetchActiveFacesFailure,
this, _1, _2),
441 ndn::nfd::CommandOptions());
445 RibManager::onFetchActiveFacesFailure(uint32_t code,
const std::string& reason)
447 NFD_LOG_DEBUG(
"Face Status Dataset request failure " << code <<
" " << reason);
448 scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
452 RibManager::onFaceDestroyedEvent(uint64_t faceId)
455 m_registeredFaces.erase(faceId);
459 RibManager::scheduleActiveFaceFetch(
const time::seconds& timeToWait)
461 m_activeFaceFetchEvent =
getScheduler().schedule(timeToWait, [
this] { fetchActiveFaces(); });
465 RibManager::removeInvalidFaces(
const std::vector<ndn::nfd::FaceStatus>& activeFaces)
469 FaceIdSet activeFaceIds;
470 for (
const auto& faceStatus : activeFaces) {
471 activeFaceIds.insert(faceStatus.getFaceId());
476 for (
auto faceId : m_registeredFaces) {
477 if (activeFaceIds.count(faceId) == 0) {
484 scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
488 RibManager::onNotification(
const ndn::nfd::FaceEventNotification& notification)
492 if (notification.getKind() == ndn::nfd::FACE_EVENT_DESTROYED) {
493 NFD_LOG_DEBUG(
"Received notification for destroyed FaceId " << notification.getFaceId());
494 getGlobalIoService().post([
this,
id = notification.getFaceId()] { onFaceDestroyedEvent(
id); });
void registerStatusDatasetHandler(const std::string &verb, const ndn::mgmt::StatusDatasetHandler &handler)
represents the Routing Information Base
void disableLocalhop()
Disallow accepting commands on /localhop/nfd/rib prefix.
std::function< void(SlAnnounceResult res)> SlAnnounceCallback
void slAnnounce(const ndn::PrefixAnnouncement &pa, uint64_t faceId, time::milliseconds maxLifetime, const SlAnnounceCallback &cb)
Insert a route by prefix announcement from self-learning strategy.
void enableLocalhop(const ConfigSection §ion, const std::string &filename)
Apply localhop_security configuration and allow accepting commands on /localhop/nfd/rib prefix...
const_iterator find(const Name &prefix) const
void setName(const Name &prefix)
RibManager(rib::Rib &rib, ndn::Face &face, ndn::KeyChain &keyChain, ndn::nfd::Controller &nfdController, Dispatcher &dispatcher)
std::function< void(optional< ndn::PrefixAnnouncement >)> SlFindAnnCallback
void slRenew(const Name &name, uint64_t faceId, time::milliseconds maxLifetime, const SlAnnounceCallback &cb)
Renew a route created by prefix announcement from self-learning strategy.
the announcement cannot be verified against the trust schema
void applyLocalhostConfig(const ConfigSection §ion, const std::string &filename)
Apply localhost_security configuration.
const_iterator end() const
Scheduler & getScheduler()
Returns the global Scheduler instance for the calling thread.
A collection of common functions shared by all NFD managers, such as communicating with the dispatche...
void registerWithNfd()
Start accepting commands and dataset requests.
boost::property_tree::ptree ConfigSection
a config file section
std::ostream & operator<<(std::ostream &os, const Network &network)
Copyright (c) 2014-2015, Regents of the University of California, Arizona Board of Regents...
static const std::string MGMT_MODULE_NAME
const Name & getName() const
const RouteList & getRoutes() const
void insert(const Name &prefix, const Route &route)
Route * findLongestPrefix(const Name &prefix, const Route &route) const
static const time::seconds ACTIVE_FACE_FETCH_INTERVAL
void extractRequester(const Interest &interest, ndn::mgmt::AcceptContinuation accept)
Extracts the requester from a ControlCommand request.
static const Name LOCALHOP_TOP_PREFIX
void slFindAnn(const Name &name, const SlFindAnnCallback &cb) const
Retrieve an outgoing prefix announcement for self-learning strategy.
#define NFD_LOG_INIT(name)
Represents a RIB entry, which contains one or more Routes with the same prefix.
void beginRemoveFace(uint64_t faceId)
starts the FIB update process when a face has been destroyed
void enableLocalFields()
Enable NDNLP IncomingFaceId field in order to support self-registration commands. ...
RIB and FIB have been updated.
the announcement has expired
void onRouteExpiration(const Name &prefix, const Route &route)
void beginApplyUpdate(const RibUpdate &update, const UpdateSuccessCallback &onSuccess, const UpdateFailureCallback &onFailure)
passes the provided RibUpdateBatch to FibUpdater to calculate and send FibUpdates.
static const Name LOCALHOST_TOP_PREFIX
route does not exist (slRenew only)
shared_ptr< RibEntry > findParent(const Name &prefix) const
boost::asio::io_service & getGlobalIoService()
Returns the global io_service instance for the calling thread.