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