30 #include <ndn-cxx/management/nfd-control-parameters.hpp> 39 const unsigned int FibUpdater::MAX_NUM_TIMEOUTS = 10;
40 const uint32_t FibUpdater::ERROR_FACE_NOT_FOUND = 410;
44 , m_controller(controller)
57 m_inheritedRoutes.clear();
60 m_updatesForBatchFaceId.clear();
61 m_updatesForNonBatchFaceId.clear();
63 computeUpdates(batch);
65 sendUpdatesForBatchFaceId(onSuccess, onFailure);
76 switch(update.getAction()) {
78 computeUpdatesForRegistration(update);
81 computeUpdatesForUnregistration(update);
84 computeUpdatesForUnregistration(update);
88 m_updatesForBatchFaceId.clear();
95 FibUpdater::computeUpdatesForRegistration(
const RibUpdate& update)
103 if (it != m_rib.
end()) {
104 shared_ptr<const RibEntry> entry(it->second);
109 if (existingRoute == entry->end()) {
111 bool willCaptureBeTurnedOn = (entry->hasCapture() ==
false && route.
isCapture());
113 createFibUpdatesForNewRoute(*entry, route, willCaptureBeTurnedOn);
125 createFibUpdatesForUpdatedRoute(entryCopy, route, *existingRoute);
131 shared_ptr<RibEntry> parent = m_rib.
findParent(prefix);
136 for (
const auto& descendant : descendants) {
139 if (descendant->getParent() == parent) {
140 children.push_back(descendant);
144 createFibUpdatesForNewRibEntry(prefix, route, children);
149 FibUpdater::computeUpdatesForUnregistration(
const RibUpdate& update)
157 if (ribIt != m_rib.
end()) {
158 shared_ptr<const RibEntry> entry(ribIt->second);
160 const bool hadCapture = entry->hasCapture();
164 if (existing != entry->end()) {
170 const bool captureWasTurnedOff = (hadCapture && !temp.
hasCapture());
172 createFibUpdatesForErasedRoute(temp, *existing, captureWasTurnedOff);
176 const Route* next = entry->getRouteWithSecondLowestCostByFaceId(route.
faceId);
178 if (next !=
nullptr) {
179 createFibUpdatesForNewRoute(temp, *next,
false);
183 if (entry->getNRoutes() == 1) {
184 createFibUpdatesForErasedRibEntry(*entry);
195 std::string updateString = (updates.size() == 1) ?
" update" :
" updates";
196 NFD_LOG_DEBUG(
"Applying " << updates.size() << updateString <<
" to FIB");
198 for (
const FibUpdate& update : updates) {
202 sendAddNextHopUpdate(update, onSuccess, onFailure);
205 sendRemoveNextHopUpdate(update, onSuccess, onFailure);
214 if (m_updatesForBatchFaceId.size() > 0) {
215 sendUpdates(m_updatesForBatchFaceId, onSuccess, onFailure);
218 sendUpdatesForNonBatchFaceId(onSuccess, onFailure);
226 if (m_updatesForNonBatchFaceId.size() > 0) {
227 sendUpdates(m_updatesForNonBatchFaceId, onSuccess, onFailure);
230 onSuccess(m_inheritedRoutes);
235 FibUpdater::sendAddNextHopUpdate(
const FibUpdate& update,
242 .setName(update.
name)
244 .setCost(update.
cost),
245 bind(&FibUpdater::onUpdateSuccess,
this, update, onSuccess, onFailure),
246 bind(&FibUpdater::onUpdateError,
this, update, onSuccess, onFailure, _1, _2, nTimeouts));
250 FibUpdater::sendRemoveNextHopUpdate(
const FibUpdate& update,
257 .setName(update.
name)
258 .setFaceId(update.
faceId),
259 bind(&FibUpdater::onUpdateSuccess,
this, update, onSuccess, onFailure),
260 bind(&FibUpdater::onUpdateError,
this, update, onSuccess, onFailure, _1, _2, nTimeouts));
264 FibUpdater::onUpdateSuccess(
const FibUpdate update,
268 if (update.
faceId == m_batchFaceId) {
269 m_updatesForBatchFaceId.remove(update);
271 if (m_updatesForBatchFaceId.size() == 0) {
272 sendUpdatesForNonBatchFaceId(onSuccess, onFailure);
276 m_updatesForNonBatchFaceId.remove(update);
278 if (m_updatesForNonBatchFaceId.size() == 0) {
279 onSuccess(m_inheritedRoutes);
285 FibUpdater::onUpdateError(
const FibUpdate update,
288 uint32_t code,
const std::string& error, uint32_t nTimeouts)
290 NFD_LOG_DEBUG(
"Failed to apply " << update <<
" (code: " << code <<
", error: " << error <<
")");
293 sendAddNextHopUpdate(update, onSuccess, onFailure, ++nTimeouts);
295 else if (code == ERROR_FACE_NOT_FOUND) {
296 if (update.
faceId == m_batchFaceId) {
297 onFailure(code, error);
300 m_updatesForNonBatchFaceId.remove(update);
302 if (m_updatesForNonBatchFaceId.size() == 0) {
303 onSuccess(m_inheritedRoutes);
308 BOOST_THROW_EXCEPTION(
Error(
"Non-recoverable error: " + error +
" code: " +
309 std::to_string(code)));
314 FibUpdater::addFibUpdate(
FibUpdate update)
317 m_updatesForNonBatchFaceId;
323 return update.
name == other.name && update.
faceId == other.faceId;
326 if (it != updates.end()) {
332 updates.push_back(update);
337 FibUpdater::addInheritedRoutes(
const RibEntry& entry,
const Rib::Rib::RouteSet& routesToAdd)
339 for (
const Route& route : routesToAdd) {
343 addInheritedRoute(entry.
getName(), route);
351 FibUpdater::addInheritedRoutes(
const Name&
name,
const Rib::Rib::RouteSet& routesToAdd,
354 for (
const Route& route : routesToAdd) {
355 if (route.faceId != ignore.
faceId) {
357 addInheritedRoute(name, route);
365 FibUpdater::removeInheritedRoutes(
const RibEntry& entry,
const Rib::Rib::RouteSet& routesToRemove)
367 for (
const Route& route : routesToRemove) {
370 removeInheritedRoute(entry.
getName(), route);
377 FibUpdater::createFibUpdatesForNewRibEntry(
const Name& name,
const Route& route,
386 addInheritedRoutes(name, m_rib.getAncestorRoutes(name), route);
391 routesToAdd.insert(route);
394 modifyChildrensInheritedRoutes(children, routesToAdd, m_rib.getAncestorRoutes(name));
397 Rib::RouteSet ancestorRoutes = m_rib.getAncestorRoutes(name);
400 addInheritedRoutes(name, ancestorRoutes, route);
407 if (it != ancestorRoutes.end()) {
408 ancestorRoutes.erase(it);
412 ancestorRoutes.insert(route);
415 modifyChildrensInheritedRoutes(children, ancestorRoutes,
Rib::RouteSet());
419 modifyChildrensInheritedRoutes(children,
Rib::RouteSet(), m_rib.getAncestorRoutes(name));
424 FibUpdater::createFibUpdatesForNewRoute(
const RibEntry& entry,
const Route& route,
425 bool captureWasTurnedOn)
435 if (prevRoute ==
nullptr || route.
cost <= prevRoute->
cost) {
437 routesToAdd.insert(route);
442 if (captureWasTurnedOn) {
444 routesToRemove = m_rib.getAncestorRoutes(entry);
447 removeInheritedRoutes(entry, routesToRemove);
450 modifyChildrensInheritedRoutes(entry.
getChildren(), routesToAdd, routesToRemove);
457 if (other ==
nullptr || route.
cost <= other->cost) {
463 FibUpdater::createFibUpdatesForUpdatedRoute(
const RibEntry& entry,
const Route& route,
464 const Route& existingRoute)
466 const bool costDidChange = (route.
cost != existingRoute.
cost);
472 if (route.
flags == existingRoute.
flags && !costDidChange) {
491 if (prevRoute ==
nullptr || route.
cost <= prevRoute->
cost) {
497 routesToAdd.insert(route);
509 if (prevRoute ==
nullptr || route.
cost <= prevRoute->
cost) {
512 routesToAdd.insert(route);
519 routesToRemove.insert(route);
523 if (prevRoute !=
nullptr) {
524 routesToAdd.insert(*prevRoute);
528 const Rib::RouteSet ancestorRoutes = m_rib.getAncestorRoutes(entry);
532 if (it != ancestorRoutes.end()) {
533 routesToAdd.insert(*it);
537 modifyChildrensInheritedRoutes(entry.
getChildren(), routesToAdd, routesToRemove);
542 Rib::RouteSet ancestorRoutes = m_rib.getAncestorRoutes(entry);
545 removeInheritedRoutes(entry, ancestorRoutes);
551 Rib::RouteSet ancestorRoutes = m_rib.getAncestorRoutes(entry);
554 addInheritedRoutes(entry, ancestorRoutes);
562 FibUpdater::createFibUpdatesForErasedRoute(
const RibEntry& entry,
const Route& route,
563 const bool captureWasTurnedOff)
570 routesToRemove.insert(route);
575 if (captureWasTurnedOff) {
577 routesToAdd = m_rib.getAncestorRoutes(entry);
580 addInheritedRoutes(entry, routesToAdd);
583 modifyChildrensInheritedRoutes(entry.
getChildren(), routesToAdd, routesToRemove);
589 routesToAdd = m_rib.getAncestorRoutes(entry);
593 routesToRemove.insert(route);
596 modifyChildrensInheritedRoutes(entry.
getChildren(), routesToAdd, routesToRemove);
602 if (captureWasTurnedOff) {
604 routesToAdd = m_rib.getAncestorRoutes(entry);
607 addInheritedRoutes(entry, routesToAdd);
614 Rib::RouteSet ancestorRoutes = m_rib.getAncestorRoutes(entry);
622 if (it != ancestorRoutes.end()) {
623 addInheritedRoute(entry.
getName(), *it);
630 FibUpdater::createFibUpdatesForErasedRibEntry(
const RibEntry& entry)
642 for (
const auto& child : children) {
643 traverseSubTree(*child, routesToAdd, routesToRemove);
648 FibUpdater::traverseSubTree(
const RibEntry& entry, Rib::Rib::RouteSet routesToAdd,
649 Rib::Rib::RouteSet routesToRemove)
657 for (Rib::RouteSet::const_iterator removeIt = routesToRemove.begin();
658 removeIt != routesToRemove.end(); )
663 routesToRemove.erase(removeIt++);
669 removeInheritedRoute(entry.
getName(), *removeIt);
677 for (Rib::RouteSet::const_iterator addIt = routesToAdd.begin(); addIt != routesToAdd.end(); ) {
681 routesToAdd.erase(addIt++);
687 addInheritedRoute(entry.
getName(), *addIt);
694 modifyChildrensInheritedRoutes(entry.
getChildren(), routesToAdd, routesToRemove);
698 FibUpdater::addInheritedRoute(
const Name& name,
const Route& route)
705 m_inheritedRoutes.push_back(update);
709 FibUpdater::removeInheritedRoute(
const Name& name,
const Route& route)
716 m_inheritedRoutes.push_back(update);
RibUpdate & setRoute(const Route &route)
void start(const ControlParameters ¶meters, const CommandSucceedCallback &onSuccess, const CommandFailCallback &onFailure, const CommandOptions &options=CommandOptions())
start command execution
FibUpdater(Rib &rib, ndn::nfd::Controller &controller)
const Route & getRoute() const
#define NFD_LOG_DEBUG(expression)
represents a fib/add-nexthop command
function< void(RibUpdateList inheritedRoutes)> FibUpdateSuccessCallback
time::steady_clock::TimePoint expires
iterator findRoute(const Route &route)
const Route * getRouteWithLowestCostByFaceId(uint64_t faceId) const
Returns the route with the lowest cost that has the passed face ID.
represents a collection of RibUpdates to be applied to a single FaceId
std::list< FibUpdate > FibUpdateList
shared_ptr< RibEntry > findParent(const Name &prefix) const
function< void(uint32_t code, const std::string &error)> FibUpdateFailureCallback
represents a fib/remove-nexthop command
static const uint32_t ERROR_TIMEOUT
error code for timeout
uint64_t getFaceId() const
std::set< Route, RouteComparePredicate > RouteSet
Table::const_iterator iterator
std::list< shared_ptr< RibEntry > > RibEntryList
static FibUpdate createRemoveUpdate(const Name &name, const uint64_t faceId)
Copyright (c) 2011-2015 Regents of the University of California.
static FibUpdate createAddUpdate(const Name &name, const uint64_t faceId, const uint64_t cost)
RibUpdate & setAction(Action action)
represents a RIB entry, which contains one or more Routes with the same prefix
represents a route for a name prefix
NFD Management protocol - ControlCommand client.
const Name & getName() const
Name abstraction to represent an absolute name.
const std::list< shared_ptr< RibEntry > > & getChildren() const
RibTable::const_iterator const_iterator
const Name & getName() const
const RouteList & getInheritedRoutes() const
Returns the routes this namespace has inherited.
size_t getNRoutes() const
bool isChildInherit() const
const_iterator end() const
#define NFD_LOG_INIT(name)
RibUpdate & setName(const Name &name)
bool hasFaceId(const uint64_t faceId) const
RouteList::const_iterator const_iterator
const Route * getRouteWithLowestCostAndChildInheritByFaceId(uint64_t faceId) const
Returns the route with the lowest cost that has the passed face ID and its child inherit flag set...
const_iterator find(const Name &prefix) const
void eraseRoute(const Route &route)
erases a Route with the same faceId and origin
bool hasInheritedRoute(const Route &route) const
Determines if the entry has an inherited route with a matching face ID.
An update triggered by a face destruction notification.
bool hasChildInheritOnFaceId(uint64_t faceId) const
Determines if the entry has an inherited route with the passed face ID and its child inherit flag set...
void computeAndSendFibUpdates(const RibUpdateBatch &batch, const FibUpdateSuccessCallback &onSuccess, const FibUpdateFailureCallback &onFailure)
computes FibUpdates using the provided RibUpdateBatch and then sends the updates to NFD's FIB ...
std::list< shared_ptr< RibEntry > > findDescendantsForNonInsertedName(const Name &prefix) const
finds namespaces under the passed prefix
void setFibUpdater(FibUpdater *updater)