35 #include <ndn-cxx/lp/tags.hpp> 36 #include <ndn-cxx/mgmt/nfd/control-command.hpp> 37 #include <ndn-cxx/mgmt/nfd/control-parameters.hpp> 38 #include <ndn-cxx/mgmt/nfd/control-response.hpp> 39 #include <ndn-cxx/mgmt/nfd/face-status.hpp> 40 #include <ndn-cxx/mgmt/nfd/rib-entry.hpp> 47 const Name RibManager::LOCAL_HOST_TOP_PREFIX =
"/localhost/nfd";
48 const Name RibManager::LOCAL_HOP_TOP_PREFIX =
"/localhop/nfd";
49 const std::string RibManager::MGMT_MODULE_NAME =
"rib";
50 const Name RibManager::FACES_LIST_DATASET_PREFIX =
"/localhost/nfd/faces/list";
51 const time::seconds RibManager::ACTIVE_FACE_FETCH_INTERVAL = time::seconds(300);
52 const Name RibManager::READVERTISE_NLSR_PREFIX =
"/localhost/nlsr";
56 ndn::KeyChain& keyChain)
59 , m_keyChain(keyChain)
60 , m_nfdController(m_face, m_keyChain)
61 , m_faceMonitor(m_face)
62 , m_localhostValidator(m_face)
63 , m_localhopValidator(m_face)
64 , m_isLocalhopEnabled(false)
65 , m_prefixPropagator(m_nfdController, m_keyChain, m_rib)
66 , m_fibUpdater(m_rib, m_nfdController)
67 , m_addTopPrefix([&dispatcher] (const Name& topPrefix) {
68 dispatcher.addTopPrefix(topPrefix,
false);
71 registerCommandHandler<ndn::nfd::RibRegisterCommand>(
"register",
72 bind(&RibManager::registerEntry,
this, _2, _3, _4, _5));
73 registerCommandHandler<ndn::nfd::RibUnregisterCommand>(
"unregister",
74 bind(&RibManager::unregisterEntry,
this, _2, _3, _4, _5));
84 registerTopPrefix(LOCAL_HOST_TOP_PREFIX);
86 if (m_isLocalhopEnabled) {
87 registerTopPrefix(LOCAL_HOP_TOP_PREFIX);
90 NFD_LOG_INFO(
"Start monitoring face create/destroy events");
91 m_faceMonitor.onNotification.connect(bind(&RibManager::onNotification,
this, _1));
92 m_faceMonitor.start();
94 scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
100 m_nfdController.start<ndn::nfd::FaceUpdateCommand>(
102 .setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
true),
103 bind(&RibManager::onEnableLocalFieldsSuccess,
this),
104 bind(&RibManager::onEnableLocalFieldsError,
this, _1));
111 bind(&RibManager::onConfig,
this, _1, _2, _3));
123 NFD_LOG_DEBUG(
"RIB update failed for " << update <<
" (code: " << code
124 <<
", error: " << error <<
")");
127 scheduleActiveFaceFetch(time::seconds(1));
133 const std::string& filename)
135 bool isAutoPrefixPropagatorEnabled =
false;
136 bool wantReadvertiseToNlsr =
false;
138 for (
const auto& item : configSection) {
139 if (item.first ==
"localhost_security") {
140 m_localhostValidator.load(item.second, filename);
142 else if (item.first ==
"localhop_security") {
143 m_localhopValidator.load(item.second, filename);
144 m_isLocalhopEnabled =
true;
146 else if (item.first ==
"auto_prefix_propagate") {
148 isAutoPrefixPropagatorEnabled =
true;
155 m_prefixPropagator.
enable();
157 else if (item.first ==
"readvertise_nlsr") {
161 BOOST_THROW_EXCEPTION(
Error(
"Unrecognized rib property: " + item.first));
165 if (!isAutoPrefixPropagatorEnabled) {
169 if (wantReadvertiseToNlsr && m_readvertiseNlsr ==
nullptr) {
173 make_unique<ClientToNlsrReadvertisePolicy>(),
174 make_unique<NfdRibReadvertiseDestination>(m_nfdController, READVERTISE_NLSR_PREFIX, m_rib)));
176 else if (!wantReadvertiseToNlsr && m_readvertiseNlsr !=
nullptr) {
178 m_readvertiseNlsr.reset();
183 RibManager::registerTopPrefix(
const Name& topPrefix)
186 m_nfdController.start<ndn::nfd::FibAddNextHopCommand>(
188 .setName(Name(topPrefix).append(MGMT_MODULE_NAME))
190 bind(&RibManager::onCommandPrefixAddNextHopSuccess,
this, cref(topPrefix), _1),
191 bind(&RibManager::onCommandPrefixAddNextHopError,
this, cref(topPrefix), _1));
194 m_addTopPrefix(topPrefix);
198 RibManager::registerEntry(
const Name& topPrefix,
const Interest& interest,
199 ControlParameters parameters,
200 const ndn::mgmt::CommandContinuation& done)
203 done(ControlResponse(414,
"Route prefix cannot exceed " + ndn::to_string(
FIB_MAX_DEPTH) +
208 setFaceForSelfRegistration(interest, parameters);
211 done(ControlResponse(200,
"Success").setBody(parameters.wireEncode()));
214 route.
faceId = parameters.getFaceId();
215 route.
origin = parameters.getOrigin();
216 route.
cost = parameters.getCost();
217 route.
flags = parameters.getFlags();
219 if (parameters.hasExpirationPeriod() &&
220 parameters.getExpirationPeriod() != time::milliseconds::max()) {
221 route.
expires = time::steady_clock::now() + parameters.getExpirationPeriod();
228 " with EventId: " << eventId);
238 <<
" origin=" << route.
origin 239 <<
" cost=" << route.
cost);
250 m_registeredFaces.insert(route.
faceId);
254 RibManager::unregisterEntry(
const Name& topPrefix,
const Interest& interest,
255 ControlParameters parameters,
256 const ndn::mgmt::CommandContinuation& done)
258 setFaceForSelfRegistration(interest, parameters);
261 done(ControlResponse(200,
"Success").setBody(parameters.wireEncode()));
264 route.
faceId = parameters.getFaceId();
265 route.
origin = parameters.getOrigin();
268 <<
" origin=" << route.
origin);
281 RibManager::listEntries(
const Name& topPrefix,
const Interest& interest,
282 ndn::mgmt::StatusDatasetContext& context)
284 auto now = time::steady_clock::now();
285 for (
const auto& kv : m_rib) {
287 ndn::nfd::RibEntry item;
291 r.setFaceId(route.faceId);
292 r.setOrigin(route.origin);
293 r.setCost(route.cost);
294 r.setFlags(route.flags);
296 r.setExpirationPeriod(time::duration_cast<time::milliseconds>(*route.expires - now));
300 context.append(item.wireEncode());
306 RibManager::setFaceForSelfRegistration(
const Interest& request, ControlParameters& parameters)
308 bool isSelfRegistration = (parameters.getFaceId() == 0);
309 if (isSelfRegistration) {
310 shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = request.getTag<lp::IncomingFaceIdTag>();
314 BOOST_ASSERT(incomingFaceIdTag !=
nullptr);
315 parameters.setFaceId(*incomingFaceIdTag);
319 ndn::mgmt::Authorization
320 RibManager::makeAuthorization(
const std::string& verb)
322 return [
this] (
const Name& prefix,
const Interest& interest,
323 const ndn::mgmt::ControlParameters* params,
324 const ndn::mgmt::AcceptContinuation& accept,
325 const ndn::mgmt::RejectContinuation& reject) {
326 BOOST_ASSERT(params !=
nullptr);
327 BOOST_ASSERT(
typeid(*params) ==
typeid(ndn::nfd::ControlParameters));
328 BOOST_ASSERT(prefix == LOCAL_HOST_TOP_PREFIX || prefix == LOCAL_HOP_TOP_PREFIX);
330 ndn::ValidatorConfig& validator = prefix == LOCAL_HOST_TOP_PREFIX ?
331 m_localhostValidator : m_localhopValidator;
332 validator.validate(interest,
334 bind([reject] { reject(ndn::mgmt::RejectReply::STATUS403); }));
339 RibManager::fetchActiveFaces()
343 m_nfdController.fetch<ndn::nfd::FaceDataset>(
344 bind(&RibManager::removeInvalidFaces,
this, _1),
345 bind(&RibManager::onFetchActiveFacesFailure,
this, _1, _2),
346 ndn::nfd::CommandOptions());
350 RibManager::onFetchActiveFacesFailure(uint32_t code,
const std::string& reason)
352 NFD_LOG_DEBUG(
"Face Status Dataset request failure " << code <<
" " << reason);
353 scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
357 RibManager::onFaceDestroyedEvent(uint64_t faceId)
360 m_registeredFaces.erase(faceId);
364 RibManager::scheduleActiveFaceFetch(
const time::seconds& timeToWait)
366 m_activeFaceFetchEvent =
scheduler::schedule(timeToWait, [
this] { this->fetchActiveFaces(); });
370 RibManager::removeInvalidFaces(
const std::vector<ndn::nfd::FaceStatus>& activeFaces)
374 FaceIdSet activeFaceIds;
375 for (
const auto& faceStatus : activeFaces) {
376 activeFaceIds.insert(faceStatus.getFaceId());
381 for (
auto faceId : m_registeredFaces) {
382 if (activeFaceIds.count(faceId) == 0) {
384 scheduler::schedule(time::seconds(0), [
this, faceId] { this->onFaceDestroyedEvent(faceId); });
389 scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
393 RibManager::onNotification(
const ndn::nfd::FaceEventNotification& notification)
397 if (notification.getKind() == ndn::nfd::FACE_EVENT_DESTROYED) {
398 NFD_LOG_DEBUG(
"Received notification for destroyed faceId: " << notification.getFaceId());
401 bind(&RibManager::onFaceDestroyedEvent,
this, notification.getFaceId()));
406 RibManager::onCommandPrefixAddNextHopSuccess(
const Name& prefix,
407 const ndn::nfd::ControlParameters& result)
409 NFD_LOG_DEBUG(
"Successfully registered " + prefix.toUri() +
" with NFD");
413 route.
faceId = result.getFaceId();
414 route.origin = ndn::nfd::ROUTE_ORIGIN_APP;
415 route.expires = ndn::nullopt;
416 route.flags = ndn::nfd::ROUTE_FLAG_CHILD_INHERIT;
418 m_rib.
insert(prefix, route);
420 m_registeredFaces.insert(route.faceId);
424 RibManager::onCommandPrefixAddNextHopError(
const Name& name,
425 const ndn::nfd::ControlResponse& response)
427 BOOST_THROW_EXCEPTION(
Error(
"Error in setting interest filter (" + name.toUri() +
428 "): " + response.getText()));
432 RibManager::onEnableLocalFieldsSuccess()
438 RibManager::onEnableLocalFieldsError(
const ndn::nfd::ControlResponse& response)
440 BOOST_THROW_EXCEPTION(
Error(
"Couldn't enable local fields (code: " +
441 to_string(response.getCode()) +
", info: " + response.getText() +
void registerStatusDatasetHandler(const std::string &verb, const ndn::mgmt::StatusDatasetHandler &handler)
void addSectionHandler(const std::string §ionName, ConfigSectionHandler subscriber)
setup notification of configuration file sections
#define NFD_LOG_DEBUG(expression)
configuration file parsing utility
void disable()
disable automatic prefix propagation
void enable()
enable automatic prefix propagation
RibUpdate & setAction(Action action)
void setName(const Name &prefix)
static bool parseYesNo(const ConfigSection &node, const std::string &key, const std::string §ionName)
parse a config option that can be either "yes" or "no"
RibUpdate & setName(const Name &name)
a collection of common functions shared by all NFD managers and RIB manager, such as communicating wi...
#define NFD_LOG_INFO(expression)
Copyright (c) 2014-2015, Regents of the University of California, Arizona Board of Regents...
const Name & getName() const
void onRibUpdateFailure(const RibUpdate &update, uint32_t code, const std::string &error)
const RouteList & getRoutes() const
ndn::nfd::RouteOrigin origin
void loadConfig(const ConfigSection &configSection)
load the "auto_prefix_propagate" section from config file
void insert(const Name &prefix, const Route &route)
void setExpirationEvent(const scheduler::EventId eid)
boost::property_tree::ptree ConfigSection
a config file section
represents a route for a name prefix
void extractRequester(const Interest &interest, ndn::mgmt::AcceptContinuation accept)
extract a requester from a ControlCommand request
void setConfigFile(ConfigFile &configFile)
static const int FIB_MAX_DEPTH
Maximum number of components in a FIB entry prefix.
#define NFD_LOG_INIT(name)
ndn::optional< time::steady_clock::TimePoint > expires
#define NFD_LOG_TRACE(expression)
EventId schedule(time::nanoseconds after, const EventCallback &event)
schedule an event
readvertise a subset of routes to a destination according to a policy
represents a RIB entry, which contains one or more Routes with the same prefix
void onRibUpdateSuccess(const RibUpdate &update)
void beginRemoveFace(uint64_t faceId)
starts the FIB update process when a face has been destroyed
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.
RibManager(Dispatcher &dispatcher, ndn::Face &face, ndn::KeyChain &keyChain)
std::underlying_type< ndn::nfd::RouteFlags >::type flags