NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.3: NDN, CCN, CCNx, content centric networks
API Documentation
fib-updater.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
26 #include "fib-updater.hpp"
27 
28 #include "core/logger.hpp"
29 
30 #include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
31 
32 namespace nfd {
33 namespace rib {
34 
36 
37 NFD_LOG_INIT("FibUpdater");
38 
39 const unsigned int FibUpdater::MAX_NUM_TIMEOUTS = 10;
40 const uint32_t FibUpdater::ERROR_FACE_NOT_FOUND = 410;
41 
43  : m_rib(rib)
44  , m_controller(controller)
45 {
46  rib.setFibUpdater(this);
47 }
48 
49 void
51  const FibUpdateSuccessCallback& onSuccess,
52  const FibUpdateFailureCallback& onFailure)
53 {
54  m_batchFaceId = batch.getFaceId();
55 
56  // Erase previously calculated inherited routes
57  m_inheritedRoutes.clear();
58 
59  // Erase previously calculated FIB updates
60  m_updatesForBatchFaceId.clear();
61  m_updatesForNonBatchFaceId.clear();
62 
63  computeUpdates(batch);
64 
65  sendUpdatesForBatchFaceId(onSuccess, onFailure);
66 }
67 
68 void
69 FibUpdater::computeUpdates(const RibUpdateBatch& batch)
70 {
71  NFD_LOG_DEBUG("Computing updates for batch with faceID: " << batch.getFaceId());
72 
73  // Compute updates and add to m_fibUpdates
74  for (const RibUpdate& update : batch)
75  {
76  switch(update.getAction()) {
78  computeUpdatesForRegistration(update);
79  break;
81  computeUpdatesForUnregistration(update);
82  break;
84  computeUpdatesForUnregistration(update);
85 
86  // Do not apply updates with the same face ID as the destroyed face
87  // since they will be rejected by the FIB
88  m_updatesForBatchFaceId.clear();
89  break;
90  }
91  }
92 }
93 
94 void
95 FibUpdater::computeUpdatesForRegistration(const RibUpdate& update)
96 {
97  const Name& prefix = update.getName();
98  const Route& route = update.getRoute();
99 
100  Rib::const_iterator it = m_rib.find(prefix);
101 
102  // Name prefix exists
103  if (it != m_rib.end()) {
104  shared_ptr<const RibEntry> entry(it->second);
105 
106  RibEntry::const_iterator existingRoute = entry->findRoute(route);
107 
108  // Route will be new
109  if (existingRoute == entry->end()) {
110  // Will the new route change the namespace's capture flag?
111  bool willCaptureBeTurnedOn = (entry->hasCapture() == false && route.isCapture());
112 
113  createFibUpdatesForNewRoute(*entry, route, willCaptureBeTurnedOn);
114  }
115  else {
116  // Route already exists
117  RibEntry entryCopy = *entry;
118 
119  Route& routeToUpdate = *(entryCopy.findRoute(route));
120 
121  routeToUpdate.flags = route.flags;
122  routeToUpdate.cost = route.cost;
123  routeToUpdate.expires = route.expires;
124 
125  createFibUpdatesForUpdatedRoute(entryCopy, route, *existingRoute);
126  }
127  }
128  else {
129  // New name in RIB
130  // Find prefix's parent
131  shared_ptr<RibEntry> parent = m_rib.findParent(prefix);
132 
133  Rib::RibEntryList descendants = m_rib.findDescendantsForNonInsertedName(prefix);
134  Rib::RibEntryList children;
135 
136  for (const auto& descendant : descendants) {
137  // If the child has the same parent as the new entry,
138  // the new entry must be the child's new parent
139  if (descendant->getParent() == parent) {
140  children.push_back(descendant);
141  }
142  }
143 
144  createFibUpdatesForNewRibEntry(prefix, route, children);
145  }
146 }
147 
148 void
149 FibUpdater::computeUpdatesForUnregistration(const RibUpdate& update)
150 {
151  const Name& prefix = update.getName();
152  const Route& route = update.getRoute();
153 
154  Rib::const_iterator ribIt = m_rib.find(prefix);
155 
156  // Name prefix exists
157  if (ribIt != m_rib.end()) {
158  shared_ptr<const RibEntry> entry(ribIt->second);
159 
160  const bool hadCapture = entry->hasCapture();
161 
162  RibEntry::const_iterator existing = entry->findRoute(route);
163 
164  if (existing != entry->end()) {
165  RibEntry temp = *entry;
166 
167  // Erase route in temp entry
168  temp.eraseRoute(route);
169 
170  const bool captureWasTurnedOff = (hadCapture && !temp.hasCapture());
171 
172  createFibUpdatesForErasedRoute(temp, *existing, captureWasTurnedOff);
173 
174  // The RibEntry still has the face ID; need to update FIB
175  // with lowest cost for the same face instead of removing the face from the FIB
176  const Route* next = entry->getRouteWithSecondLowestCostByFaceId(route.faceId);
177 
178  if (next != nullptr) {
179  createFibUpdatesForNewRoute(temp, *next, false);
180  }
181 
182  // The RibEntry will be empty after this removal
183  if (entry->getNRoutes() == 1) {
184  createFibUpdatesForErasedRibEntry(*entry);
185  }
186  }
187  }
188 }
189 
190 void
191 FibUpdater::sendUpdates(const FibUpdateList& updates,
192  const FibUpdateSuccessCallback& onSuccess,
193  const FibUpdateFailureCallback& onFailure)
194 {
195  std::string updateString = (updates.size() == 1) ? " update" : " updates";
196  NFD_LOG_DEBUG("Applying " << updates.size() << updateString << " to FIB");
197 
198  for (const FibUpdate& update : updates) {
199  NFD_LOG_DEBUG("Sending FIB update: " << update);
200 
201  if (update.action == FibUpdate::ADD_NEXTHOP) {
202  sendAddNextHopUpdate(update, onSuccess, onFailure);
203  }
204  else if (update.action == FibUpdate::REMOVE_NEXTHOP) {
205  sendRemoveNextHopUpdate(update, onSuccess, onFailure);
206  }
207  }
208 }
209 
210 void
211 FibUpdater::sendUpdatesForBatchFaceId(const FibUpdateSuccessCallback& onSuccess,
212  const FibUpdateFailureCallback& onFailure)
213 {
214  if (m_updatesForBatchFaceId.size() > 0) {
215  sendUpdates(m_updatesForBatchFaceId, onSuccess, onFailure);
216  }
217  else {
218  sendUpdatesForNonBatchFaceId(onSuccess, onFailure);
219  }
220 }
221 
222 void
223 FibUpdater::sendUpdatesForNonBatchFaceId(const FibUpdateSuccessCallback& onSuccess,
224  const FibUpdateFailureCallback& onFailure)
225 {
226  if (m_updatesForNonBatchFaceId.size() > 0) {
227  sendUpdates(m_updatesForNonBatchFaceId, onSuccess, onFailure);
228  }
229  else {
230  onSuccess(m_inheritedRoutes);
231  }
232 }
233 
234 void
235 FibUpdater::sendAddNextHopUpdate(const FibUpdate& update,
236  const FibUpdateSuccessCallback& onSuccess,
237  const FibUpdateFailureCallback& onFailure,
238  uint32_t nTimeouts)
239 {
242  .setName(update.name)
243  .setFaceId(update.faceId)
244  .setCost(update.cost),
245  bind(&FibUpdater::onUpdateSuccess, this, update, onSuccess, onFailure),
246  bind(&FibUpdater::onUpdateError, this, update, onSuccess, onFailure, _1, nTimeouts));
247 }
248 
249 void
250 FibUpdater::sendRemoveNextHopUpdate(const FibUpdate& update,
251  const FibUpdateSuccessCallback& onSuccess,
252  const FibUpdateFailureCallback& onFailure,
253  uint32_t nTimeouts)
254 {
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, nTimeouts));
261 }
262 
263 void
264 FibUpdater::onUpdateSuccess(const FibUpdate update,
265  const FibUpdateSuccessCallback& onSuccess,
266  const FibUpdateFailureCallback& onFailure)
267 {
268  if (update.faceId == m_batchFaceId) {
269  m_updatesForBatchFaceId.remove(update);
270 
271  if (m_updatesForBatchFaceId.size() == 0) {
272  sendUpdatesForNonBatchFaceId(onSuccess, onFailure);
273  }
274  }
275  else {
276  m_updatesForNonBatchFaceId.remove(update);
277 
278  if (m_updatesForNonBatchFaceId.size() == 0) {
279  onSuccess(m_inheritedRoutes);
280  }
281  }
282 }
283 
284 void
285 FibUpdater::onUpdateError(const FibUpdate update,
286  const FibUpdateSuccessCallback& onSuccess,
287  const FibUpdateFailureCallback& onFailure,
288  const ndn::nfd::ControlResponse& response, uint32_t nTimeouts)
289 {
290  uint32_t code = response.getCode();
291  NFD_LOG_DEBUG("Failed to apply " << update <<
292  " (code: " << code << ", error: " << response.getText() << ")");
293 
294  if (code == ndn::nfd::Controller::ERROR_TIMEOUT && nTimeouts < MAX_NUM_TIMEOUTS) {
295  sendAddNextHopUpdate(update, onSuccess, onFailure, ++nTimeouts);
296  }
297  else if (code == ERROR_FACE_NOT_FOUND) {
298  if (update.faceId == m_batchFaceId) {
299  onFailure(code, response.getText());
300  }
301  else {
302  m_updatesForNonBatchFaceId.remove(update);
303 
304  if (m_updatesForNonBatchFaceId.size() == 0) {
305  onSuccess(m_inheritedRoutes);
306  }
307  }
308  }
309  else {
310  BOOST_THROW_EXCEPTION(Error("Non-recoverable error: " + response.getText() +
311  " code: " + to_string(code)));
312  }
313 }
314 
315 void
316 FibUpdater::addFibUpdate(FibUpdate update)
317 {
318  FibUpdateList& updates = (update.faceId == m_batchFaceId) ? m_updatesForBatchFaceId :
319  m_updatesForNonBatchFaceId;
320 
321  // If an update with the same name and route already exists,
322  // replace it
323  FibUpdateList::iterator it = std::find_if(updates.begin(), updates.end(),
324  [&update] (const FibUpdate& other) {
325  return update.name == other.name && update.faceId == other.faceId;
326  });
327 
328  if (it != updates.end()) {
329  FibUpdate& existingUpdate = *it;
330  existingUpdate.action = update.action;
331  existingUpdate.cost = update.cost;
332  }
333  else {
334  updates.push_back(update);
335  }
336 }
337 
338 void
339 FibUpdater::addInheritedRoutes(const RibEntry& entry, const Rib::RouteSet& routesToAdd)
340 {
341  for (const Route& route : routesToAdd) {
342  // Don't add an ancestor faceId if the namespace has an entry for that faceId
343  if (!entry.hasFaceId(route.faceId)) {
344  // Create a record of the inherited route so it can be added to the RIB later
345  addInheritedRoute(entry.getName(), route);
346 
347  addFibUpdate(FibUpdate::createAddUpdate(entry.getName(), route.faceId, route.cost));
348  }
349  }
350 }
351 
352 void
353 FibUpdater::addInheritedRoutes(const Name& name, const Rib::RouteSet& routesToAdd,
354  const Route& ignore)
355 {
356  for (const Route& route : routesToAdd) {
357  if (route.faceId != ignore.faceId) {
358  // Create a record of the inherited route so it can be added to the RIB later
359  addInheritedRoute(name, route);
360 
361  addFibUpdate(FibUpdate::createAddUpdate(name, route.faceId, route.cost));
362  }
363  }
364 }
365 
366 void
367 FibUpdater::removeInheritedRoutes(const RibEntry& entry, const Rib::Rib::RouteSet& routesToRemove)
368 {
369  for (const Route& route : routesToRemove) {
370  // Only remove if the route has been inherited
371  if (entry.hasInheritedRoute(route)) {
372  removeInheritedRoute(entry.getName(), route);
373  addFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), route.faceId));
374  }
375  }
376 }
377 
378 void
379 FibUpdater::createFibUpdatesForNewRibEntry(const Name& name, const Route& route,
380  const Rib::RibEntryList& children)
381 {
382  // Create FIB update for new entry
383  addFibUpdate(FibUpdate::createAddUpdate(name, route.faceId, route.cost));
384 
385  // No flags are set
386  if (!route.isChildInherit() && !route.isCapture()) {
387  // Add ancestor routes to self
388  addInheritedRoutes(name, m_rib.getAncestorRoutes(name), route);
389  }
390  else if (route.isChildInherit() && route.isCapture()) {
391  // Add route to children
392  Rib::RouteSet routesToAdd;
393  routesToAdd.insert(route);
394 
395  // Remove routes blocked by capture and add self to children
396  modifyChildrensInheritedRoutes(children, routesToAdd, m_rib.getAncestorRoutes(name));
397  }
398  else if (route.isChildInherit()) {
399  Rib::RouteSet ancestorRoutes = m_rib.getAncestorRoutes(name);
400 
401  // Add ancestor routes to self
402  addInheritedRoutes(name, ancestorRoutes, route);
403 
404  // If there is an ancestor route which is the same as the new route, replace it
405  // with the new route
406  Rib::RouteSet::iterator it = ancestorRoutes.find(route);
407 
408  // There is a route that needs to be overwritten, erase and then replace
409  if (it != ancestorRoutes.end()) {
410  ancestorRoutes.erase(it);
411  }
412 
413  // Add new route to ancestor list so it can be added to children
414  ancestorRoutes.insert(route);
415 
416  // Add ancestor routes to children
417  modifyChildrensInheritedRoutes(children, ancestorRoutes, Rib::RouteSet());
418  }
419  else if (route.isCapture()) {
420  // Remove routes blocked by capture
421  modifyChildrensInheritedRoutes(children, Rib::RouteSet(), m_rib.getAncestorRoutes(name));
422  }
423 }
424 
425 void
426 FibUpdater::createFibUpdatesForNewRoute(const RibEntry& entry, const Route& route,
427  bool captureWasTurnedOn)
428 {
429  // Only update if the new route has a lower cost than a previously installed route
430  const Route* prevRoute = entry.getRouteWithLowestCostAndChildInheritByFaceId(route.faceId);
431 
432  Rib::RouteSet routesToAdd;
433  if (route.isChildInherit()) {
434  // Add to children if this new route doesn't override a previous lower cost, or
435  // add to children if this new route is lower cost than a previous route.
436  // Less than equal, since entry may find this route
437  if (prevRoute == nullptr || route.cost <= prevRoute->cost) {
438  // Add self to children
439  routesToAdd.insert(route);
440  }
441  }
442 
443  Rib::RouteSet routesToRemove;
444  if (captureWasTurnedOn) {
445  // Capture flag on
446  routesToRemove = m_rib.getAncestorRoutes(entry);
447 
448  // Remove ancestor routes from self
449  removeInheritedRoutes(entry, routesToRemove);
450  }
451 
452  modifyChildrensInheritedRoutes(entry.getChildren(), routesToAdd, routesToRemove);
453 
454  // If another route with same faceId and lower cost exists, don't update.
455  // Must be done last so that add updates replace removal updates
456  // Create FIB update for new entry
457  const Route* other = entry.getRouteWithLowestCostByFaceId(route.faceId);
458 
459  if (other == nullptr || route.cost <= other->cost) {
460  addFibUpdate(FibUpdate::createAddUpdate(entry.getName(), route.faceId, route.cost));
461  }
462 }
463 
464 void
465 FibUpdater::createFibUpdatesForUpdatedRoute(const RibEntry& entry, const Route& route,
466  const Route& existingRoute)
467 {
468  const bool costDidChange = (route.cost != existingRoute.cost);
469 
470  // Look for an installed route with the lowest cost and child inherit set
471  const Route* prevRoute = entry.getRouteWithLowestCostAndChildInheritByFaceId(route.faceId);
472 
473  // No flags changed and cost didn't change, no change in FIB
474  if (route.flags == existingRoute.flags && !costDidChange) {
475  return;
476  }
477 
478  // Cost changed so create update for the entry itself
479  if (costDidChange) {
480  // Create update if this route's cost is lower than other routes
481  if (route.cost <= entry.getRouteWithLowestCostByFaceId(route.faceId)->cost) {
482  // Create FIB update for the updated entry
483  addFibUpdate(FibUpdate::createAddUpdate(entry.getName(), route.faceId, route.cost));
484  }
485  else if (existingRoute.cost < entry.getRouteWithLowestCostByFaceId(route.faceId)->cost) {
486  // Create update if this route used to be the lowest route but is no longer
487  // the lowest cost route.
488  addFibUpdate(FibUpdate::createAddUpdate(entry.getName(), prevRoute->faceId, prevRoute->cost));
489  }
490 
491  // If another route with same faceId and lower cost and ChildInherit exists,
492  // don't update children.
493  if (prevRoute == nullptr || route.cost <= prevRoute->cost) {
494  // If no flags changed but child inheritance is set, need to update children
495  // with new cost
496  if ((route.flags == existingRoute.flags) && route.isChildInherit()) {
497  // Add self to children
498  Rib::RouteSet routesToAdd;
499  routesToAdd.insert(route);
500  modifyChildrensInheritedRoutes(entry.getChildren(), routesToAdd, Rib::RouteSet());
501 
502  return;
503  }
504  }
505  }
506 
507  // Child inherit was turned on
508  if (!existingRoute.isChildInherit() && route.isChildInherit()) {
509  // If another route with same faceId and lower cost and ChildInherit exists,
510  // don't update children.
511  if (prevRoute == nullptr || route.cost <= prevRoute->cost) {
512  // Add self to children
513  Rib::RouteSet routesToAdd;
514  routesToAdd.insert(route);
515  modifyChildrensInheritedRoutes(entry.getChildren(), routesToAdd, Rib::RouteSet());
516  }
517  } // Child inherit was turned off
518  else if (existingRoute.isChildInherit() && !route.isChildInherit()) {
519  // Remove self from children
520  Rib::RouteSet routesToRemove;
521  routesToRemove.insert(route);
522 
523  Rib::RouteSet routesToAdd;
524  // If another route with same faceId and ChildInherit exists, update children with this route.
525  if (prevRoute != nullptr) {
526  routesToAdd.insert(*prevRoute);
527  }
528  else {
529  // Look for an ancestor that was blocked previously
530  const Rib::RouteSet ancestorRoutes = m_rib.getAncestorRoutes(entry);
531  Rib::RouteSet::iterator it = ancestorRoutes.find(route);
532 
533  // If an ancestor is found, add it to children
534  if (it != ancestorRoutes.end()) {
535  routesToAdd.insert(*it);
536  }
537  }
538 
539  modifyChildrensInheritedRoutes(entry.getChildren(), routesToAdd, routesToRemove);
540  }
541 
542  // Capture was turned on
543  if (!existingRoute.isCapture() && route.isCapture()) {
544  Rib::RouteSet ancestorRoutes = m_rib.getAncestorRoutes(entry);
545 
546  // Remove ancestor routes from self
547  removeInheritedRoutes(entry, ancestorRoutes);
548 
549  // Remove ancestor routes from children
550  modifyChildrensInheritedRoutes(entry.getChildren(), Rib::RouteSet(), ancestorRoutes);
551  } // Capture was turned off
552  else if (existingRoute.isCapture() && !route.isCapture()) {
553  Rib::RouteSet ancestorRoutes = m_rib.getAncestorRoutes(entry);
554 
555  // Add ancestor routes to self
556  addInheritedRoutes(entry, ancestorRoutes);
557 
558  // Add ancestor routes to children
559  modifyChildrensInheritedRoutes(entry.getChildren(), ancestorRoutes, Rib::RouteSet());
560  }
561 }
562 
563 void
564 FibUpdater::createFibUpdatesForErasedRoute(const RibEntry& entry, const Route& route,
565  const bool captureWasTurnedOff)
566 {
567  addFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), route.faceId));
568 
569  if (route.isChildInherit() && route.isCapture()) {
570  // Remove self from children
571  Rib::RouteSet routesToRemove;
572  routesToRemove.insert(route);
573 
574  // If capture is turned off for the route and another route is installed in the RibEntry,
575  // add ancestors to self
576  Rib::RouteSet routesToAdd;
577  if (captureWasTurnedOff && entry.getNRoutes() != 0) {
578  // Look for an ancestors that were blocked previously
579  routesToAdd = m_rib.getAncestorRoutes(entry);
580 
581  // Add ancestor routes to self
582  addInheritedRoutes(entry, routesToAdd);
583  }
584 
585  modifyChildrensInheritedRoutes(entry.getChildren(), routesToAdd, routesToRemove);
586  }
587  else if (route.isChildInherit()) {
588  // If not blocked by capture, add inherited routes to children
589  Rib::RouteSet routesToAdd;
590  if (!entry.hasCapture()) {
591  routesToAdd = m_rib.getAncestorRoutes(entry);
592  }
593 
594  Rib::RouteSet routesToRemove;
595  routesToRemove.insert(route);
596 
597  // Add ancestor routes to children
598  modifyChildrensInheritedRoutes(entry.getChildren(), routesToAdd, routesToRemove);
599  }
600  else if (route.isCapture()) {
601  // If capture is turned off for the route and another route is installed in the RibEntry,
602  // add ancestors to self
603  Rib::RouteSet routesToAdd;
604  if (captureWasTurnedOff && entry.getNRoutes() != 0) {
605  // Look for an ancestors that were blocked previously
606  routesToAdd = m_rib.getAncestorRoutes(entry);
607 
608  // Add ancestor routes to self
609  addInheritedRoutes(entry, routesToAdd);
610  }
611 
612  modifyChildrensInheritedRoutes(entry.getChildren(), routesToAdd, Rib::RouteSet());
613  }
614 
615  // Need to check if the removed route was blocking an inherited route
616  Rib::RouteSet ancestorRoutes = m_rib.getAncestorRoutes(entry);
617 
618  // If the current entry has capture set or is pending removal, don't add inherited route
619  if (!entry.hasCapture() && entry.getNRoutes() != 0) {
620  // If there is an ancestor route which is the same as the erased route, add that route
621  // to the current entry
622  Rib::RouteSet::iterator it = ancestorRoutes.find(route);
623 
624  if (it != ancestorRoutes.end()) {
625  addInheritedRoute(entry.getName(), *it);
626  addFibUpdate(FibUpdate::createAddUpdate(entry.getName(), it->faceId, it->cost));
627  }
628  }
629 }
630 
631 void
632 FibUpdater::createFibUpdatesForErasedRibEntry(const RibEntry& entry)
633 {
634  for (const Route& route : entry.getInheritedRoutes()) {
635  addFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), route.faceId));
636  }
637 }
638 
639 void
640 FibUpdater::modifyChildrensInheritedRoutes(const Rib::RibEntryList& children,
641  const Rib::RouteSet& routesToAdd,
642  const Rib::RouteSet& routesToRemove)
643 {
644  for (const auto& child : children) {
645  traverseSubTree(*child, routesToAdd, routesToRemove);
646  }
647 }
648 
649 void
650 FibUpdater::traverseSubTree(const RibEntry& entry, Rib::Rib::RouteSet routesToAdd,
651  Rib::Rib::RouteSet routesToRemove)
652 {
653  // If a route on the namespace has the capture flag set, ignore self and children
654  if (entry.hasCapture()) {
655  return;
656  }
657 
658  // Remove inherited routes from current namespace
659  for (Rib::RouteSet::const_iterator removeIt = routesToRemove.begin();
660  removeIt != routesToRemove.end(); )
661  {
662  // If a route on the namespace has the same face ID and child inheritance set,
663  // ignore this route
664  if (entry.hasChildInheritOnFaceId(removeIt->faceId)) {
665  routesToRemove.erase(removeIt++);
666  continue;
667  }
668 
669  // Only remove route if it removes an existing inherited route
670  if (entry.hasInheritedRoute(*removeIt)) {
671  removeInheritedRoute(entry.getName(), *removeIt);
672  addFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), removeIt->faceId));
673  }
674 
675  ++removeIt;
676  }
677 
678  // Add inherited routes to current namespace
679  for (Rib::RouteSet::const_iterator addIt = routesToAdd.begin(); addIt != routesToAdd.end(); ) {
680 
681  // If a route on the namespace has the same face ID and child inherit set, ignore this face
682  if (entry.hasChildInheritOnFaceId(addIt->faceId)) {
683  routesToAdd.erase(addIt++);
684  continue;
685  }
686 
687  // Only add route if it does not override an existing route
688  if (!entry.hasFaceId(addIt->faceId)) {
689  addInheritedRoute(entry.getName(), *addIt);
690  addFibUpdate(FibUpdate::createAddUpdate(entry.getName(), addIt->faceId, addIt->cost));
691  }
692 
693  ++addIt;
694  }
695 
696  modifyChildrensInheritedRoutes(entry.getChildren(), routesToAdd, routesToRemove);
697 }
698 
699 void
700 FibUpdater::addInheritedRoute(const Name& name, const Route& route)
701 {
702  RibUpdate update;
704  .setName(name)
705  .setRoute(route);
706 
707  m_inheritedRoutes.push_back(update);
708 }
709 
710 void
711 FibUpdater::removeInheritedRoute(const Name& name, const Route& route)
712 {
713  RibUpdate update;
715  .setName(name)
716  .setRoute(route);
717 
718  m_inheritedRoutes.push_back(update);
719 }
720 
721 } // namespace rib
722 } // namespace nfd
RibUpdate & setRoute(const Route &route)
Definition: rib-update.hpp:107
void start(const ControlParameters &parameters, const CommandSucceedCallback &onSuccess, const CommandFailCallback &onFailure, const CommandOptions &options=CommandOptions())
start command execution
Definition: controller.hpp:75
const_iterator end() const
Definition: rib.hpp:272
FibUpdater(Rib &rib, ndn::nfd::Controller &controller)
Definition: fib-updater.cpp:42
represents the Routing Information Base
Definition: rib.hpp:56
represents a fib/add-nexthop command
const Route & getRoute() const
Definition: rib-update.hpp:114
function< void(RibUpdateList inheritedRoutes)> FibUpdateSuccessCallback
Definition: fib-updater.hpp:57
time::steady_clock::TimePoint expires
Definition: route.hpp:83
iterator findRoute(const Route &route)
Definition: rib-entry.cpp:38
bool hasFaceId(const uint64_t faceId) const
Definition: rib-entry.cpp:84
represents a collection of RibUpdates to be applied to a single FaceId
size_t getNRoutes() const
Definition: rib-entry.cpp:92
const_iterator find(const Name &prefix) const
Definition: rib.cpp:59
bool isChildInherit() const
Definition: route.hpp:67
std::list< FibUpdate > FibUpdateList
Definition: fib-updater.hpp:55
uint64_t cost
Definition: route.hpp:82
uint64_t faceId
Definition: route.hpp:79
#define NFD_LOG_DEBUG(expression)
Definition: logger.hpp:55
function< void(uint32_t code, const std::string &error)> FibUpdateFailureCallback
Definition: fib-updater.hpp:58
represents a fib/remove-nexthop command
const Name & getName() const
Definition: rib-entry.hpp:205
static const uint32_t ERROR_TIMEOUT
error code for timeout
Definition: controller.hpp:153
std::set< Route, RouteComparePredicate > RouteSet
Definition: rib.hpp:64
represents a FIB update
Definition: fib-update.hpp:37
Table::const_iterator iterator
Definition: cs-internal.hpp:41
std::list< shared_ptr< RibEntry > > RibEntryList
Definition: rib.hpp:59
const Name & getName() const
Definition: rib-update.hpp:101
static FibUpdate createRemoveUpdate(const Name &name, const uint64_t faceId)
Definition: fib-update.cpp:45
Copyright (c) 2011-2015 Regents of the University of California.
Definition: ndn-common.hpp:40
static FibUpdate createAddUpdate(const Name &name, const uint64_t faceId, const uint64_t cost)
Definition: fib-update.cpp:32
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...
Definition: rib-entry.cpp:225
RibUpdate & setAction(Action action)
Definition: rib-update.hpp:81
represents a RIB entry, which contains one or more Routes with the same prefix
Definition: rib-entry.hpp:36
represents a route for a name prefix
Definition: route.hpp:37
shared_ptr< RibEntry > findParent(const Name &prefix) const
Definition: rib.cpp:206
NFD Management protocol client.
Definition: controller.hpp:51
bool hasInheritedRoute(const Route &route) const
Determines if the entry has an inherited route with a matching face ID.
Definition: rib-entry.cpp:153
Name abstraction to represent an absolute name.
Definition: name.hpp:46
RibTable::const_iterator const_iterator
Definition: rib.hpp:61
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...
Definition: rib-entry.cpp:167
uint64_t flags
Definition: route.hpp:81
RibUpdate & setName(const Name &name)
Definition: rib-update.hpp:94
RouteList::const_iterator const_iterator
Definition: rib-entry.hpp:41
const RouteList & getInheritedRoutes() const
Returns the routes this namespace has inherited.
Definition: rib-entry.hpp:235
const std::string & getText() const
void eraseRoute(const Route &route)
erases a Route with the same faceId and origin
Definition: rib-entry.cpp:69
std::list< shared_ptr< RibEntry > > findDescendantsForNonInsertedName(const Name &prefix) const
finds namespaces under the passed prefix
Definition: rib.cpp:242
std::string to_string(const V &v)
Definition: backports.hpp:51
ControlCommand response.
bool hasCapture() const
Definition: rib-entry.cpp:161
An update triggered by a face destruction notification.
Definition: rib-update.hpp:51
void computeAndSendFibUpdates(const RibUpdateBatch &batch, const FibUpdateSuccessCallback &onSuccess, const FibUpdateFailureCallback &onFailure)
computes FibUpdates using the provided RibUpdateBatch and then sends the updates to NFD&#39;s FIB ...
Definition: fib-updater.cpp:50
#define NFD_LOG_INIT(name)
Definition: logger.hpp:34
const Route * getRouteWithLowestCostByFaceId(uint64_t faceId) const
Returns the route with the lowest cost that has the passed face ID.
Definition: rib-entry.cpp:179
bool isCapture() const
Definition: route.hpp:73
void setFibUpdater(FibUpdater *updater)
Definition: rib.cpp:53
const std::list< shared_ptr< RibEntry > > & getChildren() const
Definition: rib-entry.hpp:223