blob: 0d33f24b18f1bb3d1aee30ca94113a6d5ce1c692 [file] [log] [blame]
Alexander Afanasyev3ecec502014-04-16 13:42:44 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Vince12e49462014-06-09 13:29:32 -05003 * Copyright (c) 2014, 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
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070010 *
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/>.
Vince12e49462014-06-09 13:29:32 -050024 */
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070025
26#include "rib.hpp"
27
Vince Lehman281ded72014-08-21 12:17:08 -050028#include "core/logger.hpp"
29
30NFD_LOG_INIT("Rib");
31
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070032namespace nfd {
33namespace rib {
34
Vince Lehman4387e782014-06-19 16:57:45 -050035static inline bool
36sortFace(const FaceEntry& entry1, const FaceEntry& entry2)
37{
38 return entry1.faceId < entry2.faceId;
39}
40
41static inline bool
42isChildInheritFlagSet(uint64_t flags)
43{
44 return flags & ndn::nfd::ROUTE_FLAG_CHILD_INHERIT;
45}
46
47static inline bool
48isCaptureFlagSet(uint64_t flags)
49{
50 return flags & ndn::nfd::ROUTE_FLAG_CAPTURE;
51}
52
53static inline bool
54isAnyFlagSet(uint64_t flags)
55{
56 return isChildInheritFlagSet(flags) || isCaptureFlagSet(flags);
57}
58
59static inline bool
60areBothFlagsSet(uint64_t flags)
61{
62 return isChildInheritFlagSet(flags) && isCaptureFlagSet(flags);
63}
64
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070065Rib::Rib()
Vince12e49462014-06-09 13:29:32 -050066 : m_nItems(0)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070067{
68}
69
70
71Rib::~Rib()
72{
73}
74
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070075Rib::const_iterator
Vince12e49462014-06-09 13:29:32 -050076Rib::find(const Name& prefix) const
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070077{
Vince12e49462014-06-09 13:29:32 -050078 return m_rib.find(prefix);
79}
80
Syed Obaid3313a372014-07-01 01:31:33 -050081FaceEntry*
Vince12e49462014-06-09 13:29:32 -050082Rib::find(const Name& prefix, const FaceEntry& face) const
83{
84 RibTable::const_iterator ribIt = m_rib.find(prefix);
85
86 // Name prefix exists
87 if (ribIt != m_rib.end())
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070088 {
Vince12e49462014-06-09 13:29:32 -050089 shared_ptr<RibEntry> entry(ribIt->second);
90
Syed Obaid3313a372014-07-01 01:31:33 -050091 RibEntry::iterator faceIt = std::find_if(entry->begin(), entry->end(),
Vince12e49462014-06-09 13:29:32 -050092 bind(&compareFaceIdAndOrigin, _1, face));
93
94 if (faceIt != entry->end())
95 {
Syed Obaid3313a372014-07-01 01:31:33 -050096 return &((*faceIt));
Vince12e49462014-06-09 13:29:32 -050097 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070098 }
Syed Obaid3313a372014-07-01 01:31:33 -050099 return 0;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700100}
101
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700102void
Vince12e49462014-06-09 13:29:32 -0500103Rib::insert(const Name& prefix, const FaceEntry& face)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700104{
Vince12e49462014-06-09 13:29:32 -0500105 RibTable::iterator ribIt = m_rib.find(prefix);
106
107 // Name prefix exists
108 if (ribIt != m_rib.end())
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700109 {
Vince12e49462014-06-09 13:29:32 -0500110 shared_ptr<RibEntry> entry(ribIt->second);
111
112 RibEntry::iterator faceIt = std::find_if(entry->getFaces().begin(),
113 entry->getFaces().end(),
114 bind(&compareFaceIdAndOrigin, _1, face));
115
116 if (faceIt == entry->end())
117 {
Vince Lehman4387e782014-06-19 16:57:45 -0500118 // Will the new face change the namespace's capture flag?
119 bool captureWasTurnedOn = (entry->hasCapture() == false && isCaptureFlagSet(face.flags));
120
Vince12e49462014-06-09 13:29:32 -0500121 // New face
122 entry->insertFace(face);
123 m_nItems++;
124
125 // Register with face lookup table
126 m_faceMap[face.faceId].push_back(entry);
Vince Lehman4387e782014-06-19 16:57:45 -0500127
128 createFibUpdatesForNewFaceEntry(*entry, face, captureWasTurnedOn);
Vince12e49462014-06-09 13:29:32 -0500129 }
Vince Lehman4387e782014-06-19 16:57:45 -0500130 else // Entry exists, update fields
Vince12e49462014-06-09 13:29:32 -0500131 {
Syed Obaid3313a372014-07-01 01:31:33 -0500132 // First cancel old scheduled event, if any, then set the EventId to new one
133 if (static_cast<bool>(faceIt->getExpirationEvent()))
Vince Lehman281ded72014-08-21 12:17:08 -0500134 {
135 NFD_LOG_TRACE("Cancelling expiration event for " << entry->getName() << " "
136 << *faceIt);
Syed Obaid3313a372014-07-01 01:31:33 -0500137 scheduler::cancel(faceIt->getExpirationEvent());
Vince Lehman281ded72014-08-21 12:17:08 -0500138 }
Syed Obaid3313a372014-07-01 01:31:33 -0500139
140 // No checks are required here as the iterator needs to be updated in all cases.
141 faceIt->setExpirationEvent(face.getExpirationEvent());
142
Vince Lehman4387e782014-06-19 16:57:45 -0500143 // Save flags for update processing
144 uint64_t previousFlags = faceIt->flags;
145
146 // If the entry's cost didn't change and child inherit is not set,
147 // no need to traverse subtree.
148 uint64_t previousCost = faceIt->cost;
149
Vince12e49462014-06-09 13:29:32 -0500150 faceIt->flags = face.flags;
151 faceIt->cost = face.cost;
152 faceIt->expires = face.expires;
Vince Lehman4387e782014-06-19 16:57:45 -0500153
154 createFibUpdatesForUpdatedEntry(*entry, face, previousFlags, previousCost);
Vince12e49462014-06-09 13:29:32 -0500155 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700156 }
Vince12e49462014-06-09 13:29:32 -0500157 else // New name prefix
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700158 {
Vince12e49462014-06-09 13:29:32 -0500159 shared_ptr<RibEntry> entry(make_shared<RibEntry>(RibEntry()));
160
161 m_rib[prefix] = entry;
162 m_nItems++;
163
164 entry->setName(prefix);
165 entry->insertFace(face);
166
167 // Find prefix's parent
168 shared_ptr<RibEntry> parent = findParent(prefix);
169
170 // Add self to parent's children
171 if (static_cast<bool>(parent))
172 {
173 parent->addChild(entry);
174 }
175
176 RibEntryList children = findDescendants(prefix);
177
178 for (std::list<shared_ptr<RibEntry> >::iterator child = children.begin();
179 child != children.end(); ++child)
180 {
181 if ((*child)->getParent() == parent)
182 {
183 // Remove child from parent and inherit parent's child
184 if (static_cast<bool>(parent))
185 {
186 parent->removeChild((*child));
187 }
Vince12e49462014-06-09 13:29:32 -0500188 entry->addChild((*child));
189 }
190 }
191
192 // Register with face lookup table
193 m_faceMap[face.faceId].push_back(entry);
Vince Lehman4387e782014-06-19 16:57:45 -0500194
195 createFibUpdatesForNewRibEntry(*entry, face);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700196 }
197}
198
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700199void
Vince12e49462014-06-09 13:29:32 -0500200Rib::erase(const Name& prefix, const FaceEntry& face)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700201{
Vince12e49462014-06-09 13:29:32 -0500202 RibTable::iterator ribIt = m_rib.find(prefix);
203
204 // Name prefix exists
205 if (ribIt != m_rib.end())
206 {
207 shared_ptr<RibEntry> entry(ribIt->second);
208
Vince Lehman4387e782014-06-19 16:57:45 -0500209 const bool hadCapture = entry->hasCapture();
210
211 // Need to copy face to do FIB updates with correct cost and flags since nfdc does not
212 // pass flags or cost
213 RibEntry::iterator faceIt = entry->findFace(face);
Vince Lehman4387e782014-06-19 16:57:45 -0500214
215 if (faceIt != entry->end())
Vince12e49462014-06-09 13:29:32 -0500216 {
Syed Obaid3313a372014-07-01 01:31:33 -0500217 FaceEntry faceToErase = *faceIt;
218 faceToErase.flags = faceIt->flags;
219 faceToErase.cost = faceIt->cost;
220
Vince Lehman4387e782014-06-19 16:57:45 -0500221 entry->eraseFace(faceIt);
Vince Lehman281ded72014-08-21 12:17:08 -0500222
Vince12e49462014-06-09 13:29:32 -0500223 m_nItems--;
224
Vince Lehman4387e782014-06-19 16:57:45 -0500225 const bool captureWasTurnedOff = (hadCapture && !entry->hasCapture());
226
227 createFibUpdatesForErasedFaceEntry(*entry, faceToErase, captureWasTurnedOff);
228
Vince12e49462014-06-09 13:29:32 -0500229 // If this RibEntry no longer has this faceId, unregister from face lookup table
230 if (!entry->hasFaceId(face.faceId))
231 {
232 m_faceMap[face.faceId].remove(entry);
233 }
Vince Lehman4387e782014-06-19 16:57:45 -0500234 else
235 {
236 // The RibEntry still has the face ID; need to update FIB
237 // with lowest cost for the same face instead of removing the face from the FIB
238 shared_ptr<FaceEntry> lowCostFace = entry->getFaceWithLowestCostByFaceId(face.faceId);
239
240 BOOST_ASSERT(static_cast<bool>(lowCostFace));
241
242 createFibUpdatesForNewFaceEntry(*entry, *lowCostFace, false);
243 }
Vince12e49462014-06-09 13:29:32 -0500244
245 // If a RibEntry's facelist is empty, remove it from the tree
246 if (entry->getFaces().size() == 0)
247 {
248 eraseEntry(ribIt);
249 }
250 }
251 }
252}
253
254void
255Rib::erase(const uint64_t faceId)
256{
257 FaceLookupTable::iterator lookupIt = m_faceMap.find(faceId);
258
259 // No RIB entries have this face
260 if (lookupIt == m_faceMap.end())
261 {
262 return;
263 }
264
265 RibEntryList& ribEntries = lookupIt->second;
266
267 // For each RIB entry that has faceId, remove the face from the entry
268 for (RibEntryList::iterator entryIt = ribEntries.begin(); entryIt != ribEntries.end(); ++entryIt)
269 {
270 shared_ptr<RibEntry> entry = *entryIt;
271
Vince Lehman4387e782014-06-19 16:57:45 -0500272 const bool hadCapture = entry->hasCapture();
273
Vince12e49462014-06-09 13:29:32 -0500274 // Find the faces in the entry
275 for (RibEntry::iterator faceIt = entry->begin(); faceIt != entry->end(); ++faceIt)
276 {
277 if (faceIt->faceId == faceId)
278 {
Vince Lehman4387e782014-06-19 16:57:45 -0500279 FaceEntry copy = *faceIt;
280
Vince12e49462014-06-09 13:29:32 -0500281 faceIt = entry->eraseFace(faceIt);
Vince Lehman26b215c2014-08-17 15:00:41 -0500282 m_nItems--;
Vince Lehman4387e782014-06-19 16:57:45 -0500283
284 const bool captureWasTurnedOff = (hadCapture && !entry->hasCapture());
285 createFibUpdatesForErasedFaceEntry(*entry, copy, captureWasTurnedOff);
Vince12e49462014-06-09 13:29:32 -0500286 }
287 }
288
289 // If a RibEntry's facelist is empty, remove it from the tree
290 if (entry->getFaces().size() == 0)
291 {
292 eraseEntry(m_rib.find(entry->getName()));
293 }
294 }
295
296 // Face no longer exists, remove from face lookup table
297 FaceLookupTable::iterator entryToDelete = m_faceMap.find(faceId);
298
299 if (entryToDelete != m_faceMap.end())
300 {
301 m_faceMap.erase(entryToDelete);
302 }
303}
304
305shared_ptr<RibEntry>
306Rib::findParent(const Name& prefix) const
307{
308 for (int i = prefix.size() - 1; i >= 0; i--)
309 {
310 RibTable::const_iterator it = m_rib.find(prefix.getPrefix(i));
311 if (it != m_rib.end())
312 {
313 return (it->second);
314 }
315 }
316
317 return shared_ptr<RibEntry>();
318}
319
320std::list<shared_ptr<RibEntry> >
321Rib::findDescendants(const Name& prefix) const
322{
323 std::list<shared_ptr<RibEntry> > children;
324
325 RibTable::const_iterator it = m_rib.find(prefix);
326
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700327 if (it != m_rib.end())
328 {
Vince12e49462014-06-09 13:29:32 -0500329 ++it;
330 for (; it != m_rib.end(); ++it)
331 {
332 if (prefix.isPrefixOf(it->first))
333 {
334 children.push_back((it->second));
335 }
336 else
337 {
338 break;
339 }
340 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700341 }
Vince12e49462014-06-09 13:29:32 -0500342
343 return children;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700344}
345
Vince12e49462014-06-09 13:29:32 -0500346Rib::RibTable::iterator
347Rib::eraseEntry(RibTable::iterator it)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700348{
Vince12e49462014-06-09 13:29:32 -0500349 // Entry does not exist
350 if (it == m_rib.end())
351 {
352 return m_rib.end();
353 }
354
355 shared_ptr<RibEntry> entry(it->second);
356
Vince Lehman4387e782014-06-19 16:57:45 -0500357 // Remove inherited routes from namespace
358 createFibUpdatesForErasedRibEntry(*entry);
359
Vince12e49462014-06-09 13:29:32 -0500360 shared_ptr<RibEntry> parent = entry->getParent();
361
362 // Remove self from parent's children
363 if (static_cast<bool>(parent))
364 {
365 parent->removeChild(entry);
366 }
367
368 std::list<shared_ptr<RibEntry> > children = entry->getChildren();
369
370 for (RibEntryList::iterator child = children.begin(); child != children.end(); ++child)
371 {
372 // Remove children from self
373 entry->removeChild(*child);
374
375 // Update parent's children
376 if (static_cast<bool>(parent))
377 {
378 parent->addChild(*child);
379 }
380 }
381
382 // Must save and advance iterator to return a valid iterator
383 RibTable::iterator nextIt = it;
384 nextIt++;
385
386 m_rib.erase(it);
387
388 return nextIt;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700389}
390
Vince Lehman4387e782014-06-19 16:57:45 -0500391bool
392compareFibUpdates(const shared_ptr<const FibUpdate> lhs, const shared_ptr<const FibUpdate> rhs)
393{
394 return ((lhs->name == rhs->name) &&
395 (lhs->faceId == rhs->faceId));
396}
397
398void
399Rib::insertFibUpdate(shared_ptr<FibUpdate> update)
400{
401 // If an update with the same name and face already exists,
402 // replace it
403 FibUpdateList::iterator it = std::find_if(m_fibUpdateList.begin(), m_fibUpdateList.end(),
404 bind(&compareFibUpdates, _1, update));
405
406 if (it != m_fibUpdateList.end())
407 {
408 // Get rid of the const to alter the action, prevents copying or removal and
409 // insertion
410 FibUpdate& entry = const_cast<FibUpdate&>(*(*it));
411 entry.action = update->action;
412 entry.cost = update->cost;
413 }
414 else
415 {
416 m_fibUpdateList.push_back(update);
417 }
418}
419
420void
421Rib::createFibUpdatesForNewRibEntry(RibEntry& entry, const FaceEntry& face)
422{
423 // Create FIB update for new entry
424 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), face.faceId, face.cost));
425
426 // No flags are set
427 if (!isAnyFlagSet(face.flags))
428 {
429 // Add ancestor faces to self
430 addInheritedFacesToEntry(entry, getAncestorFaces(entry));
431 }
432 else if (areBothFlagsSet(face.flags))
433 {
434 // Add face to children
435 FaceSet facesToAdd;
436 facesToAdd.insert(face);
437
438 // Remove faces blocked by capture and add self to children
439 modifyChildrensInheritedFaces(entry, facesToAdd, getAncestorFaces(entry));
440 }
441 else if (isChildInheritFlagSet(face.flags))
442 {
443 FaceSet ancestorFaces = getAncestorFaces(entry);
444
445 // Add ancestor faces to self
446 addInheritedFacesToEntry(entry, ancestorFaces);
447
448 // If there is an ancestor face which is the same as the new face, replace it
449 // with the new face
450 FaceSet::iterator it = ancestorFaces.find(face);
451
452 // There is a face that needs to be overwritten, erase and then replace
453 if (it != ancestorFaces.end())
454 {
455 ancestorFaces.erase(it);
456 }
457
458 // Add new face to ancestor list so it can be added to children
459 ancestorFaces.insert(face);
460
461 // Add ancestor faces to children
462 modifyChildrensInheritedFaces(entry, ancestorFaces, FaceSet());
463 }
464 else if (isCaptureFlagSet(face.flags))
465 {
466 // Remove faces blocked by capture
467 modifyChildrensInheritedFaces(entry, FaceSet(), getAncestorFaces(entry));
468 }
469}
470
471void
472Rib::createFibUpdatesForNewFaceEntry(RibEntry& entry, const FaceEntry& face,
473 bool captureWasTurnedOn)
474{
475 // Only update if the new face has a lower cost than a previously installed face
476 shared_ptr<FaceEntry> prevFace = entry.getFaceWithLowestCostAndChildInheritByFaceId(face.faceId);
477
478 FaceSet facesToAdd;
479 if (isChildInheritFlagSet(face.flags))
480 {
481 // Add to children if this new face doesn't override a previous lower cost, or
482 // add to children if this new is lower cost than a previous face.
483 // Less than equal, since entry may find this face
484 if (!static_cast<bool>(prevFace) || face.cost <= prevFace->cost)
485 {
486 // Add self to children
487 facesToAdd.insert(face);
488 }
489 }
490
491 FaceSet facesToRemove;
492 if (captureWasTurnedOn)
493 {
494 // Capture flag on
495 facesToRemove = getAncestorFaces(entry);
496
497 // Remove ancestor faces from self
498 removeInheritedFacesFromEntry(entry, facesToRemove);
499 }
500
501 modifyChildrensInheritedFaces(entry, facesToAdd, facesToRemove);
502
503 // If another face with same faceId and lower cost, don't update.
504 // Must be done last so that add updates replace removal updates
505 // Create FIB update for new entry
506 if (face.cost <= entry.getFaceWithLowestCostByFaceId(face.faceId)->cost)
507 {
508 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), face.faceId, face.cost));
509 }
510}
511
512void
513Rib::createFibUpdatesForUpdatedEntry(RibEntry& entry, const FaceEntry& face,
514 const uint64_t previousFlags, const uint64_t previousCost)
515{
516 const bool costDidChange = (face.cost != previousCost);
517
518 // Look for an installed face with the lowest cost and child inherit set
519 shared_ptr<FaceEntry> prevFace = entry.getFaceWithLowestCostAndChildInheritByFaceId(face.faceId);
520
521 // No flags changed and cost didn't change, no change in FIB
522 if (face.flags == previousFlags && !costDidChange)
523 {
524 return;
525 }
526
527 // Cost changed so create update for the entry itself
528 if (costDidChange)
529 {
530 // Create update if this face's cost is lower than other faces
531 if (face.cost <= entry.getFaceWithLowestCostByFaceId(face.faceId)->cost)
532 {
533 // Create FIB update for the updated entry
534 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), face.faceId, face.cost));
535 }
536 else if (previousCost < entry.getFaceWithLowestCostByFaceId(face.faceId)->cost)
537 {
538 // Create update if this face used to be the lowest face but is no longer
539 // the lowest cost face.
540 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), prevFace->faceId,
541 prevFace->cost));
542 }
543
544 // If another face with same faceId and lower cost and ChildInherit exists,
545 // don't update children.
546 if (!static_cast<bool>(prevFace) || face.cost <= prevFace->cost)
547 {
548 // If no flags changed but child inheritance is set, need to update children
549 // with new cost
550 if ((face.flags == previousFlags) && isChildInheritFlagSet(face.flags))
551 {
552 // Add self to children
553 FaceSet facesToAdd;
554 facesToAdd.insert(face);
555 modifyChildrensInheritedFaces(entry, facesToAdd, FaceSet());
556
557 return;
558 }
559 }
560 }
561
562 // Child inherit was turned on
563 if (!isChildInheritFlagSet(previousFlags) && isChildInheritFlagSet(face.flags))
564 {
565 // If another face with same faceId and lower cost and ChildInherit exists,
566 // don't update children.
567 if (!static_cast<bool>(prevFace) || face.cost <= prevFace->cost)
568 {
569 // Add self to children
570 FaceSet facesToAdd;
571 facesToAdd.insert(face);
572 modifyChildrensInheritedFaces(entry, facesToAdd, FaceSet());
573 }
574
575 } // Child inherit was turned off
576 else if (isChildInheritFlagSet(previousFlags) && !isChildInheritFlagSet(face.flags))
577 {
578 // Remove self from children
579 FaceSet facesToRemove;
580 facesToRemove.insert(face);
581
582 FaceSet facesToAdd;
583 // If another face with same faceId and ChildInherit exists, update children with this face.
584 if (static_cast<bool>(prevFace))
585 {
586 facesToAdd.insert(*prevFace);
587 }
588 else
589 {
590 // Look for an ancestor that was blocked previously
591 const FaceSet ancestorFaces = getAncestorFaces(entry);
592 FaceSet::iterator it = ancestorFaces.find(face);
593
594 // If an ancestor is found, add it to children
595 if (it != ancestorFaces.end())
596 {
597 facesToAdd.insert(*it);
598 }
599 }
600
601 modifyChildrensInheritedFaces(entry, facesToAdd, facesToRemove);
602 }
603
604 // Capture was turned on
605 if (!isCaptureFlagSet(previousFlags) && isCaptureFlagSet(face.flags))
606 {
607 FaceSet ancestorFaces = getAncestorFaces(entry);
608
609 // Remove ancestor faces from self
610 removeInheritedFacesFromEntry(entry, ancestorFaces);
611
612 // Remove ancestor faces from children
613 modifyChildrensInheritedFaces(entry, FaceSet(), ancestorFaces);
614 } // Capture was turned off
615 else if (isCaptureFlagSet(previousFlags) && !isCaptureFlagSet(face.flags))
616 {
617 FaceSet ancestorFaces = getAncestorFaces(entry);
618
619 // Add ancestor faces to self
620 addInheritedFacesToEntry(entry, ancestorFaces);
621
622 // Add ancestor faces to children
623 modifyChildrensInheritedFaces(entry, ancestorFaces, FaceSet());
624 }
625}
626
627void
628Rib::createFibUpdatesForErasedFaceEntry(RibEntry& entry, const FaceEntry& face,
629 const bool captureWasTurnedOff)
630{
631 insertFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), face.faceId));
632
633 if (areBothFlagsSet(face.flags))
634 {
635 // Remove self from children
636 FaceSet facesToRemove;
637 facesToRemove.insert(face);
638
639 // If capture is turned off for the route, need to add ancestors
640 // to self and children
641 FaceSet facesToAdd;
642 if (captureWasTurnedOff)
643 {
644 // Look for an ancestors that were blocked previously
645 facesToAdd = getAncestorFaces(entry);
646
647 // Add ancestor faces to self
648 addInheritedFacesToEntry(entry, facesToAdd);
649 }
650
651 modifyChildrensInheritedFaces(entry, facesToAdd, facesToRemove);
652 }
653 else if (isChildInheritFlagSet(face.flags))
654 {
655 // If not blocked by capture, add inherited routes to children
656 FaceSet facesToAdd;
657 if (!entry.hasCapture())
658 {
659 facesToAdd = getAncestorFaces(entry);
660 }
661
662 FaceSet facesToRemove;
663 facesToRemove.insert(face);
664
665 // Add ancestor faces to children
666 modifyChildrensInheritedFaces(entry, facesToAdd, facesToRemove);
667 }
668 else if (isCaptureFlagSet(face.flags))
669 {
670 // If capture is turned off for the route, need to add ancestors
671 // to self and children
672 FaceSet facesToAdd;
673 if (captureWasTurnedOff)
674 {
675 // Look for an ancestors that were blocked previously
676 facesToAdd = getAncestorFaces(entry);
677
678 // Add ancestor faces to self
679 addInheritedFacesToEntry(entry, facesToAdd);
680 }
681
682 modifyChildrensInheritedFaces(entry, facesToAdd, FaceSet());
683 }
684
685 // Need to check if the removed face was blocking an inherited route
686 FaceSet ancestorFaces = getAncestorFaces(entry);
687
688 if (!entry.hasCapture())
689 {
690 // If there is an ancestor face which is the same as the erased face, add that face
691 // to the current entry
692 FaceSet::iterator it = ancestorFaces.find(face);
693
694 if (it != ancestorFaces.end())
695 {
696 entry.addInheritedFace(*it);
697 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), it->faceId, it->cost));
698 }
699 }
700}
701
702void
703Rib::createFibUpdatesForErasedRibEntry(RibEntry& entry)
704{
705 for (RibEntry::FaceList::iterator it = entry.getInheritedFaces().begin();
706 it != entry.getInheritedFaces().end(); ++it)
707 {
708 insertFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), it->faceId));
709 }
710}
711
712Rib::FaceSet
713Rib::getAncestorFaces(const RibEntry& entry) const
714{
715 FaceSet ancestorFaces(&sortFace);
716
717 shared_ptr<RibEntry> parent = entry.getParent();
718
719 while (static_cast<bool>(parent))
720 {
721 for (RibEntry::iterator it = parent->getFaces().begin();
722 it != parent->getFaces().end(); ++it)
723 {
724 if (isChildInheritFlagSet(it->flags))
725 {
726 ancestorFaces.insert(*it);
727 }
728 }
729
730 if (parent->hasCapture())
731 {
732 break;
733 }
734
735 parent = parent->getParent();
736 }
737
738 return ancestorFaces;
739}
740
741void
742Rib::addInheritedFacesToEntry(RibEntry& entry, const Rib::FaceSet& facesToAdd)
743{
744 for (FaceSet::const_iterator it = facesToAdd.begin(); it != facesToAdd.end(); ++it)
745 {
746 // Don't add an ancestor faceId if the namespace has an entry for that faceId
747 if (!entry.hasFaceId(it->faceId))
748 {
749 entry.addInheritedFace(*it);
750 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), it->faceId, it->cost));
751 }
752 }
753}
754
755void
756Rib::removeInheritedFacesFromEntry(RibEntry& entry, const Rib::FaceSet& facesToRemove)
757{
758 for (FaceSet::const_iterator it = facesToRemove.begin(); it != facesToRemove.end(); ++it)
759 {
760 // Only remove if the face has been inherited
761 if (entry.hasInheritedFace(*it))
762 {
763 entry.removeInheritedFace(*it);
764 insertFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), it->faceId));
765 }
766 }
767}
768
769void
770Rib::modifyChildrensInheritedFaces(RibEntry& entry, const Rib::FaceSet& facesToAdd,
771 const Rib::FaceSet& facesToRemove)
772{
773 RibEntryList children = entry.getChildren();
774
775 for (RibEntryList::iterator child = children.begin(); child != children.end(); ++child)
776 {
777 traverseSubTree(*(*child), facesToAdd, facesToRemove);
778 }
779}
780
781void
782Rib::traverseSubTree(RibEntry& entry, Rib::FaceSet facesToAdd,
783 Rib::FaceSet facesToRemove)
784{
785 // If a route on the namespace has the capture flag set, ignore self and children
786 if (entry.hasCapture())
787 {
788 return;
789 }
790
791 // Remove inherited faces from current namespace
792 for (Rib::FaceSet::const_iterator removeIt = facesToRemove.begin();
793 removeIt != facesToRemove.end(); )
794 {
795 // If a route on the namespace has the same face and child inheritance set, ignore this face
796 if (entry.hasChildInheritOnFaceId(removeIt->faceId))
797 {
798 facesToRemove.erase(removeIt++);
799 continue;
800 }
801
802 // Only remove face if it removes an existing inherited route
803 if (entry.hasInheritedFace(*removeIt))
804 {
805 entry.removeInheritedFace(*removeIt);
806 insertFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), removeIt->faceId));
807 }
808
809 ++removeIt;
810 }
811
812 // Add inherited faces to current namespace
813 for (Rib::FaceSet::const_iterator addIt = facesToAdd.begin();
814 addIt != facesToAdd.end(); )
815 {
816 // If a route on the namespace has the same face and child inherit set, ignore this face
817 if (entry.hasChildInheritOnFaceId(addIt->faceId))
818 {
819 facesToAdd.erase(addIt++);
820 continue;
821 }
822
823 // Only add face if it does not override an existing route
824 if (!entry.hasFaceId(addIt->faceId))
825 {
826 RibEntry::FaceList::iterator faceIt = entry.findInheritedFace(*addIt);
827
828 // If the entry already has the inherited face, just update the face
829 if (faceIt != entry.getInheritedFaces().end())
830 {
831 faceIt->cost = addIt->cost;
832 }
833 else // Otherwise, this is a newly inherited face
834 {
835 entry.addInheritedFace(*addIt);
836 }
837
838 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), addIt->faceId, addIt->cost));
839 }
840
841 ++addIt;
842 }
843
844 Rib::RibEntryList children = entry.getChildren();
845
846 // Apply face operations to current namespace's children
847 for (Rib::RibEntryList::iterator child = children.begin(); child != children.end(); ++child)
848 {
849 traverseSubTree(*(*child), facesToAdd, facesToRemove);
850 }
851}
852
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700853std::ostream&
Vince12e49462014-06-09 13:29:32 -0500854operator<<(std::ostream& os, const Rib& rib)
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700855{
Vince12e49462014-06-09 13:29:32 -0500856 for (Rib::RibTable::const_iterator it = rib.begin(); it != rib.end(); ++it)
857 {
858 os << *(it->second) << "\n";
859 }
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700860
861 return os;
862}
863
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700864} // namespace rib
865} // namespace nfd