blob: c3fc399736f5a754e075a0d94c3410a78d9f845e [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
28namespace nfd {
29namespace rib {
30
Vince Lehman4387e782014-06-19 16:57:45 -050031static inline bool
32sortFace(const FaceEntry& entry1, const FaceEntry& entry2)
33{
34 return entry1.faceId < entry2.faceId;
35}
36
37static inline bool
38isChildInheritFlagSet(uint64_t flags)
39{
40 return flags & ndn::nfd::ROUTE_FLAG_CHILD_INHERIT;
41}
42
43static inline bool
44isCaptureFlagSet(uint64_t flags)
45{
46 return flags & ndn::nfd::ROUTE_FLAG_CAPTURE;
47}
48
49static inline bool
50isAnyFlagSet(uint64_t flags)
51{
52 return isChildInheritFlagSet(flags) || isCaptureFlagSet(flags);
53}
54
55static inline bool
56areBothFlagsSet(uint64_t flags)
57{
58 return isChildInheritFlagSet(flags) && isCaptureFlagSet(flags);
59}
60
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070061Rib::Rib()
Vince12e49462014-06-09 13:29:32 -050062 : m_nItems(0)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070063{
64}
65
66
67Rib::~Rib()
68{
69}
70
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070071Rib::const_iterator
Vince12e49462014-06-09 13:29:32 -050072Rib::find(const Name& prefix) const
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070073{
Vince12e49462014-06-09 13:29:32 -050074 return m_rib.find(prefix);
75}
76
77shared_ptr<FaceEntry>
78Rib::find(const Name& prefix, const FaceEntry& face) const
79{
80 RibTable::const_iterator ribIt = m_rib.find(prefix);
81
82 // Name prefix exists
83 if (ribIt != m_rib.end())
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070084 {
Vince12e49462014-06-09 13:29:32 -050085 shared_ptr<RibEntry> entry(ribIt->second);
86
87 RibEntry::const_iterator faceIt = std::find_if(entry->begin(), entry->end(),
88 bind(&compareFaceIdAndOrigin, _1, face));
89
90 if (faceIt != entry->end())
91 {
92 return make_shared<FaceEntry>(*faceIt);
93 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070094 }
Vince12e49462014-06-09 13:29:32 -050095
96 return shared_ptr<FaceEntry>();
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070097}
98
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070099void
Vince12e49462014-06-09 13:29:32 -0500100Rib::insert(const Name& prefix, const FaceEntry& face)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700101{
Vince12e49462014-06-09 13:29:32 -0500102 RibTable::iterator ribIt = m_rib.find(prefix);
103
104 // Name prefix exists
105 if (ribIt != m_rib.end())
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700106 {
Vince12e49462014-06-09 13:29:32 -0500107 shared_ptr<RibEntry> entry(ribIt->second);
108
109 RibEntry::iterator faceIt = std::find_if(entry->getFaces().begin(),
110 entry->getFaces().end(),
111 bind(&compareFaceIdAndOrigin, _1, face));
112
113 if (faceIt == entry->end())
114 {
Vince Lehman4387e782014-06-19 16:57:45 -0500115 // Will the new face change the namespace's capture flag?
116 bool captureWasTurnedOn = (entry->hasCapture() == false && isCaptureFlagSet(face.flags));
117
Vince12e49462014-06-09 13:29:32 -0500118 // New face
119 entry->insertFace(face);
120 m_nItems++;
121
122 // Register with face lookup table
123 m_faceMap[face.faceId].push_back(entry);
Vince Lehman4387e782014-06-19 16:57:45 -0500124
125 createFibUpdatesForNewFaceEntry(*entry, face, captureWasTurnedOn);
Vince12e49462014-06-09 13:29:32 -0500126 }
Vince Lehman4387e782014-06-19 16:57:45 -0500127 else // Entry exists, update fields
Vince12e49462014-06-09 13:29:32 -0500128 {
Vince Lehman4387e782014-06-19 16:57:45 -0500129 // Save flags for update processing
130 uint64_t previousFlags = faceIt->flags;
131
132 // If the entry's cost didn't change and child inherit is not set,
133 // no need to traverse subtree.
134 uint64_t previousCost = faceIt->cost;
135
Vince12e49462014-06-09 13:29:32 -0500136 faceIt->flags = face.flags;
137 faceIt->cost = face.cost;
138 faceIt->expires = face.expires;
Vince Lehman4387e782014-06-19 16:57:45 -0500139
140 createFibUpdatesForUpdatedEntry(*entry, face, previousFlags, previousCost);
Vince12e49462014-06-09 13:29:32 -0500141 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700142 }
Vince12e49462014-06-09 13:29:32 -0500143 else // New name prefix
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700144 {
Vince12e49462014-06-09 13:29:32 -0500145 shared_ptr<RibEntry> entry(make_shared<RibEntry>(RibEntry()));
146
147 m_rib[prefix] = entry;
148 m_nItems++;
149
150 entry->setName(prefix);
151 entry->insertFace(face);
152
153 // Find prefix's parent
154 shared_ptr<RibEntry> parent = findParent(prefix);
155
156 // Add self to parent's children
157 if (static_cast<bool>(parent))
158 {
159 parent->addChild(entry);
160 }
161
162 RibEntryList children = findDescendants(prefix);
163
164 for (std::list<shared_ptr<RibEntry> >::iterator child = children.begin();
165 child != children.end(); ++child)
166 {
167 if ((*child)->getParent() == parent)
168 {
169 // Remove child from parent and inherit parent's child
170 if (static_cast<bool>(parent))
171 {
172 parent->removeChild((*child));
173 }
174
175 entry->addChild((*child));
176 }
177 }
178
179 // Register with face lookup table
180 m_faceMap[face.faceId].push_back(entry);
Vince Lehman4387e782014-06-19 16:57:45 -0500181
182 createFibUpdatesForNewRibEntry(*entry, face);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700183 }
184}
185
186
187void
Vince12e49462014-06-09 13:29:32 -0500188Rib::erase(const Name& prefix, const FaceEntry& face)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700189{
Vince12e49462014-06-09 13:29:32 -0500190 RibTable::iterator ribIt = m_rib.find(prefix);
191
192 // Name prefix exists
193 if (ribIt != m_rib.end())
194 {
195 shared_ptr<RibEntry> entry(ribIt->second);
196
Vince Lehman4387e782014-06-19 16:57:45 -0500197 const bool hadCapture = entry->hasCapture();
198
199 // Need to copy face to do FIB updates with correct cost and flags since nfdc does not
200 // pass flags or cost
201 RibEntry::iterator faceIt = entry->findFace(face);
202 FaceEntry faceToErase = *faceIt;
203 faceToErase.flags = faceIt->flags;
204 faceToErase.cost = faceIt->cost;
205
206 if (faceIt != entry->end())
Vince12e49462014-06-09 13:29:32 -0500207 {
Vince Lehman4387e782014-06-19 16:57:45 -0500208 entry->eraseFace(faceIt);
Vince12e49462014-06-09 13:29:32 -0500209 m_nItems--;
210
Vince Lehman4387e782014-06-19 16:57:45 -0500211 const bool captureWasTurnedOff = (hadCapture && !entry->hasCapture());
212
213 createFibUpdatesForErasedFaceEntry(*entry, faceToErase, captureWasTurnedOff);
214
Vince12e49462014-06-09 13:29:32 -0500215 // If this RibEntry no longer has this faceId, unregister from face lookup table
216 if (!entry->hasFaceId(face.faceId))
217 {
218 m_faceMap[face.faceId].remove(entry);
219 }
Vince Lehman4387e782014-06-19 16:57:45 -0500220 else
221 {
222 // The RibEntry still has the face ID; need to update FIB
223 // with lowest cost for the same face instead of removing the face from the FIB
224 shared_ptr<FaceEntry> lowCostFace = entry->getFaceWithLowestCostByFaceId(face.faceId);
225
226 BOOST_ASSERT(static_cast<bool>(lowCostFace));
227
228 createFibUpdatesForNewFaceEntry(*entry, *lowCostFace, false);
229 }
Vince12e49462014-06-09 13:29:32 -0500230
231 // If a RibEntry's facelist is empty, remove it from the tree
232 if (entry->getFaces().size() == 0)
233 {
234 eraseEntry(ribIt);
235 }
236 }
237 }
238}
239
240void
241Rib::erase(const uint64_t faceId)
242{
243 FaceLookupTable::iterator lookupIt = m_faceMap.find(faceId);
244
245 // No RIB entries have this face
246 if (lookupIt == m_faceMap.end())
247 {
248 return;
249 }
250
251 RibEntryList& ribEntries = lookupIt->second;
252
253 // For each RIB entry that has faceId, remove the face from the entry
254 for (RibEntryList::iterator entryIt = ribEntries.begin(); entryIt != ribEntries.end(); ++entryIt)
255 {
256 shared_ptr<RibEntry> entry = *entryIt;
257
Vince Lehman4387e782014-06-19 16:57:45 -0500258 const bool hadCapture = entry->hasCapture();
259
Vince12e49462014-06-09 13:29:32 -0500260 // Find the faces in the entry
261 for (RibEntry::iterator faceIt = entry->begin(); faceIt != entry->end(); ++faceIt)
262 {
263 if (faceIt->faceId == faceId)
264 {
Vince Lehman4387e782014-06-19 16:57:45 -0500265 FaceEntry copy = *faceIt;
266
Vince12e49462014-06-09 13:29:32 -0500267 faceIt = entry->eraseFace(faceIt);
Vince Lehman4387e782014-06-19 16:57:45 -0500268
269 const bool captureWasTurnedOff = (hadCapture && !entry->hasCapture());
270 createFibUpdatesForErasedFaceEntry(*entry, copy, captureWasTurnedOff);
Vince12e49462014-06-09 13:29:32 -0500271 }
272 }
273
274 // If a RibEntry's facelist is empty, remove it from the tree
275 if (entry->getFaces().size() == 0)
276 {
277 eraseEntry(m_rib.find(entry->getName()));
278 }
279 }
280
281 // Face no longer exists, remove from face lookup table
282 FaceLookupTable::iterator entryToDelete = m_faceMap.find(faceId);
283
284 if (entryToDelete != m_faceMap.end())
285 {
286 m_faceMap.erase(entryToDelete);
287 }
288}
289
290shared_ptr<RibEntry>
291Rib::findParent(const Name& prefix) const
292{
293 for (int i = prefix.size() - 1; i >= 0; i--)
294 {
295 RibTable::const_iterator it = m_rib.find(prefix.getPrefix(i));
296 if (it != m_rib.end())
297 {
298 return (it->second);
299 }
300 }
301
302 return shared_ptr<RibEntry>();
303}
304
305std::list<shared_ptr<RibEntry> >
306Rib::findDescendants(const Name& prefix) const
307{
308 std::list<shared_ptr<RibEntry> > children;
309
310 RibTable::const_iterator it = m_rib.find(prefix);
311
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700312 if (it != m_rib.end())
313 {
Vince12e49462014-06-09 13:29:32 -0500314 ++it;
315 for (; it != m_rib.end(); ++it)
316 {
317 if (prefix.isPrefixOf(it->first))
318 {
319 children.push_back((it->second));
320 }
321 else
322 {
323 break;
324 }
325 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700326 }
Vince12e49462014-06-09 13:29:32 -0500327
328 return children;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700329}
330
Vince12e49462014-06-09 13:29:32 -0500331Rib::RibTable::iterator
332Rib::eraseEntry(RibTable::iterator it)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700333{
Vince12e49462014-06-09 13:29:32 -0500334 // Entry does not exist
335 if (it == m_rib.end())
336 {
337 return m_rib.end();
338 }
339
340 shared_ptr<RibEntry> entry(it->second);
341
Vince Lehman4387e782014-06-19 16:57:45 -0500342 // Remove inherited routes from namespace
343 createFibUpdatesForErasedRibEntry(*entry);
344
Vince12e49462014-06-09 13:29:32 -0500345 shared_ptr<RibEntry> parent = entry->getParent();
346
347 // Remove self from parent's children
348 if (static_cast<bool>(parent))
349 {
350 parent->removeChild(entry);
351 }
352
353 std::list<shared_ptr<RibEntry> > children = entry->getChildren();
354
355 for (RibEntryList::iterator child = children.begin(); child != children.end(); ++child)
356 {
357 // Remove children from self
358 entry->removeChild(*child);
359
360 // Update parent's children
361 if (static_cast<bool>(parent))
362 {
363 parent->addChild(*child);
364 }
365 }
366
367 // Must save and advance iterator to return a valid iterator
368 RibTable::iterator nextIt = it;
369 nextIt++;
370
371 m_rib.erase(it);
372
373 return nextIt;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700374}
375
Vince Lehman4387e782014-06-19 16:57:45 -0500376bool
377compareFibUpdates(const shared_ptr<const FibUpdate> lhs, const shared_ptr<const FibUpdate> rhs)
378{
379 return ((lhs->name == rhs->name) &&
380 (lhs->faceId == rhs->faceId));
381}
382
383void
384Rib::insertFibUpdate(shared_ptr<FibUpdate> update)
385{
386 // If an update with the same name and face already exists,
387 // replace it
388 FibUpdateList::iterator it = std::find_if(m_fibUpdateList.begin(), m_fibUpdateList.end(),
389 bind(&compareFibUpdates, _1, update));
390
391 if (it != m_fibUpdateList.end())
392 {
393 // Get rid of the const to alter the action, prevents copying or removal and
394 // insertion
395 FibUpdate& entry = const_cast<FibUpdate&>(*(*it));
396 entry.action = update->action;
397 entry.cost = update->cost;
398 }
399 else
400 {
401 m_fibUpdateList.push_back(update);
402 }
403}
404
405void
406Rib::createFibUpdatesForNewRibEntry(RibEntry& entry, const FaceEntry& face)
407{
408 // Create FIB update for new entry
409 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), face.faceId, face.cost));
410
411 // No flags are set
412 if (!isAnyFlagSet(face.flags))
413 {
414 // Add ancestor faces to self
415 addInheritedFacesToEntry(entry, getAncestorFaces(entry));
416 }
417 else if (areBothFlagsSet(face.flags))
418 {
419 // Add face to children
420 FaceSet facesToAdd;
421 facesToAdd.insert(face);
422
423 // Remove faces blocked by capture and add self to children
424 modifyChildrensInheritedFaces(entry, facesToAdd, getAncestorFaces(entry));
425 }
426 else if (isChildInheritFlagSet(face.flags))
427 {
428 FaceSet ancestorFaces = getAncestorFaces(entry);
429
430 // Add ancestor faces to self
431 addInheritedFacesToEntry(entry, ancestorFaces);
432
433 // If there is an ancestor face which is the same as the new face, replace it
434 // with the new face
435 FaceSet::iterator it = ancestorFaces.find(face);
436
437 // There is a face that needs to be overwritten, erase and then replace
438 if (it != ancestorFaces.end())
439 {
440 ancestorFaces.erase(it);
441 }
442
443 // Add new face to ancestor list so it can be added to children
444 ancestorFaces.insert(face);
445
446 // Add ancestor faces to children
447 modifyChildrensInheritedFaces(entry, ancestorFaces, FaceSet());
448 }
449 else if (isCaptureFlagSet(face.flags))
450 {
451 // Remove faces blocked by capture
452 modifyChildrensInheritedFaces(entry, FaceSet(), getAncestorFaces(entry));
453 }
454}
455
456void
457Rib::createFibUpdatesForNewFaceEntry(RibEntry& entry, const FaceEntry& face,
458 bool captureWasTurnedOn)
459{
460 // Only update if the new face has a lower cost than a previously installed face
461 shared_ptr<FaceEntry> prevFace = entry.getFaceWithLowestCostAndChildInheritByFaceId(face.faceId);
462
463 FaceSet facesToAdd;
464 if (isChildInheritFlagSet(face.flags))
465 {
466 // Add to children if this new face doesn't override a previous lower cost, or
467 // add to children if this new is lower cost than a previous face.
468 // Less than equal, since entry may find this face
469 if (!static_cast<bool>(prevFace) || face.cost <= prevFace->cost)
470 {
471 // Add self to children
472 facesToAdd.insert(face);
473 }
474 }
475
476 FaceSet facesToRemove;
477 if (captureWasTurnedOn)
478 {
479 // Capture flag on
480 facesToRemove = getAncestorFaces(entry);
481
482 // Remove ancestor faces from self
483 removeInheritedFacesFromEntry(entry, facesToRemove);
484 }
485
486 modifyChildrensInheritedFaces(entry, facesToAdd, facesToRemove);
487
488 // If another face with same faceId and lower cost, don't update.
489 // Must be done last so that add updates replace removal updates
490 // Create FIB update for new entry
491 if (face.cost <= entry.getFaceWithLowestCostByFaceId(face.faceId)->cost)
492 {
493 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), face.faceId, face.cost));
494 }
495}
496
497void
498Rib::createFibUpdatesForUpdatedEntry(RibEntry& entry, const FaceEntry& face,
499 const uint64_t previousFlags, const uint64_t previousCost)
500{
501 const bool costDidChange = (face.cost != previousCost);
502
503 // Look for an installed face with the lowest cost and child inherit set
504 shared_ptr<FaceEntry> prevFace = entry.getFaceWithLowestCostAndChildInheritByFaceId(face.faceId);
505
506 // No flags changed and cost didn't change, no change in FIB
507 if (face.flags == previousFlags && !costDidChange)
508 {
509 return;
510 }
511
512 // Cost changed so create update for the entry itself
513 if (costDidChange)
514 {
515 // Create update if this face's cost is lower than other faces
516 if (face.cost <= entry.getFaceWithLowestCostByFaceId(face.faceId)->cost)
517 {
518 // Create FIB update for the updated entry
519 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), face.faceId, face.cost));
520 }
521 else if (previousCost < entry.getFaceWithLowestCostByFaceId(face.faceId)->cost)
522 {
523 // Create update if this face used to be the lowest face but is no longer
524 // the lowest cost face.
525 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), prevFace->faceId,
526 prevFace->cost));
527 }
528
529 // If another face with same faceId and lower cost and ChildInherit exists,
530 // don't update children.
531 if (!static_cast<bool>(prevFace) || face.cost <= prevFace->cost)
532 {
533 // If no flags changed but child inheritance is set, need to update children
534 // with new cost
535 if ((face.flags == previousFlags) && isChildInheritFlagSet(face.flags))
536 {
537 // Add self to children
538 FaceSet facesToAdd;
539 facesToAdd.insert(face);
540 modifyChildrensInheritedFaces(entry, facesToAdd, FaceSet());
541
542 return;
543 }
544 }
545 }
546
547 // Child inherit was turned on
548 if (!isChildInheritFlagSet(previousFlags) && isChildInheritFlagSet(face.flags))
549 {
550 // If another face with same faceId and lower cost and ChildInherit exists,
551 // don't update children.
552 if (!static_cast<bool>(prevFace) || face.cost <= prevFace->cost)
553 {
554 // Add self to children
555 FaceSet facesToAdd;
556 facesToAdd.insert(face);
557 modifyChildrensInheritedFaces(entry, facesToAdd, FaceSet());
558 }
559
560 } // Child inherit was turned off
561 else if (isChildInheritFlagSet(previousFlags) && !isChildInheritFlagSet(face.flags))
562 {
563 // Remove self from children
564 FaceSet facesToRemove;
565 facesToRemove.insert(face);
566
567 FaceSet facesToAdd;
568 // If another face with same faceId and ChildInherit exists, update children with this face.
569 if (static_cast<bool>(prevFace))
570 {
571 facesToAdd.insert(*prevFace);
572 }
573 else
574 {
575 // Look for an ancestor that was blocked previously
576 const FaceSet ancestorFaces = getAncestorFaces(entry);
577 FaceSet::iterator it = ancestorFaces.find(face);
578
579 // If an ancestor is found, add it to children
580 if (it != ancestorFaces.end())
581 {
582 facesToAdd.insert(*it);
583 }
584 }
585
586 modifyChildrensInheritedFaces(entry, facesToAdd, facesToRemove);
587 }
588
589 // Capture was turned on
590 if (!isCaptureFlagSet(previousFlags) && isCaptureFlagSet(face.flags))
591 {
592 FaceSet ancestorFaces = getAncestorFaces(entry);
593
594 // Remove ancestor faces from self
595 removeInheritedFacesFromEntry(entry, ancestorFaces);
596
597 // Remove ancestor faces from children
598 modifyChildrensInheritedFaces(entry, FaceSet(), ancestorFaces);
599 } // Capture was turned off
600 else if (isCaptureFlagSet(previousFlags) && !isCaptureFlagSet(face.flags))
601 {
602 FaceSet ancestorFaces = getAncestorFaces(entry);
603
604 // Add ancestor faces to self
605 addInheritedFacesToEntry(entry, ancestorFaces);
606
607 // Add ancestor faces to children
608 modifyChildrensInheritedFaces(entry, ancestorFaces, FaceSet());
609 }
610}
611
612void
613Rib::createFibUpdatesForErasedFaceEntry(RibEntry& entry, const FaceEntry& face,
614 const bool captureWasTurnedOff)
615{
616 insertFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), face.faceId));
617
618 if (areBothFlagsSet(face.flags))
619 {
620 // Remove self from children
621 FaceSet facesToRemove;
622 facesToRemove.insert(face);
623
624 // If capture is turned off for the route, need to add ancestors
625 // to self and children
626 FaceSet facesToAdd;
627 if (captureWasTurnedOff)
628 {
629 // Look for an ancestors that were blocked previously
630 facesToAdd = getAncestorFaces(entry);
631
632 // Add ancestor faces to self
633 addInheritedFacesToEntry(entry, facesToAdd);
634 }
635
636 modifyChildrensInheritedFaces(entry, facesToAdd, facesToRemove);
637 }
638 else if (isChildInheritFlagSet(face.flags))
639 {
640 // If not blocked by capture, add inherited routes to children
641 FaceSet facesToAdd;
642 if (!entry.hasCapture())
643 {
644 facesToAdd = getAncestorFaces(entry);
645 }
646
647 FaceSet facesToRemove;
648 facesToRemove.insert(face);
649
650 // Add ancestor faces to children
651 modifyChildrensInheritedFaces(entry, facesToAdd, facesToRemove);
652 }
653 else if (isCaptureFlagSet(face.flags))
654 {
655 // If capture is turned off for the route, need to add ancestors
656 // to self and children
657 FaceSet facesToAdd;
658 if (captureWasTurnedOff)
659 {
660 // Look for an ancestors that were blocked previously
661 facesToAdd = getAncestorFaces(entry);
662
663 // Add ancestor faces to self
664 addInheritedFacesToEntry(entry, facesToAdd);
665 }
666
667 modifyChildrensInheritedFaces(entry, facesToAdd, FaceSet());
668 }
669
670 // Need to check if the removed face was blocking an inherited route
671 FaceSet ancestorFaces = getAncestorFaces(entry);
672
673 if (!entry.hasCapture())
674 {
675 // If there is an ancestor face which is the same as the erased face, add that face
676 // to the current entry
677 FaceSet::iterator it = ancestorFaces.find(face);
678
679 if (it != ancestorFaces.end())
680 {
681 entry.addInheritedFace(*it);
682 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), it->faceId, it->cost));
683 }
684 }
685}
686
687void
688Rib::createFibUpdatesForErasedRibEntry(RibEntry& entry)
689{
690 for (RibEntry::FaceList::iterator it = entry.getInheritedFaces().begin();
691 it != entry.getInheritedFaces().end(); ++it)
692 {
693 insertFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), it->faceId));
694 }
695}
696
697Rib::FaceSet
698Rib::getAncestorFaces(const RibEntry& entry) const
699{
700 FaceSet ancestorFaces(&sortFace);
701
702 shared_ptr<RibEntry> parent = entry.getParent();
703
704 while (static_cast<bool>(parent))
705 {
706 for (RibEntry::iterator it = parent->getFaces().begin();
707 it != parent->getFaces().end(); ++it)
708 {
709 if (isChildInheritFlagSet(it->flags))
710 {
711 ancestorFaces.insert(*it);
712 }
713 }
714
715 if (parent->hasCapture())
716 {
717 break;
718 }
719
720 parent = parent->getParent();
721 }
722
723 return ancestorFaces;
724}
725
726void
727Rib::addInheritedFacesToEntry(RibEntry& entry, const Rib::FaceSet& facesToAdd)
728{
729 for (FaceSet::const_iterator it = facesToAdd.begin(); it != facesToAdd.end(); ++it)
730 {
731 // Don't add an ancestor faceId if the namespace has an entry for that faceId
732 if (!entry.hasFaceId(it->faceId))
733 {
734 entry.addInheritedFace(*it);
735 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), it->faceId, it->cost));
736 }
737 }
738}
739
740void
741Rib::removeInheritedFacesFromEntry(RibEntry& entry, const Rib::FaceSet& facesToRemove)
742{
743 for (FaceSet::const_iterator it = facesToRemove.begin(); it != facesToRemove.end(); ++it)
744 {
745 // Only remove if the face has been inherited
746 if (entry.hasInheritedFace(*it))
747 {
748 entry.removeInheritedFace(*it);
749 insertFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), it->faceId));
750 }
751 }
752}
753
754void
755Rib::modifyChildrensInheritedFaces(RibEntry& entry, const Rib::FaceSet& facesToAdd,
756 const Rib::FaceSet& facesToRemove)
757{
758 RibEntryList children = entry.getChildren();
759
760 for (RibEntryList::iterator child = children.begin(); child != children.end(); ++child)
761 {
762 traverseSubTree(*(*child), facesToAdd, facesToRemove);
763 }
764}
765
766void
767Rib::traverseSubTree(RibEntry& entry, Rib::FaceSet facesToAdd,
768 Rib::FaceSet facesToRemove)
769{
770 // If a route on the namespace has the capture flag set, ignore self and children
771 if (entry.hasCapture())
772 {
773 return;
774 }
775
776 // Remove inherited faces from current namespace
777 for (Rib::FaceSet::const_iterator removeIt = facesToRemove.begin();
778 removeIt != facesToRemove.end(); )
779 {
780 // If a route on the namespace has the same face and child inheritance set, ignore this face
781 if (entry.hasChildInheritOnFaceId(removeIt->faceId))
782 {
783 facesToRemove.erase(removeIt++);
784 continue;
785 }
786
787 // Only remove face if it removes an existing inherited route
788 if (entry.hasInheritedFace(*removeIt))
789 {
790 entry.removeInheritedFace(*removeIt);
791 insertFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), removeIt->faceId));
792 }
793
794 ++removeIt;
795 }
796
797 // Add inherited faces to current namespace
798 for (Rib::FaceSet::const_iterator addIt = facesToAdd.begin();
799 addIt != facesToAdd.end(); )
800 {
801 // If a route on the namespace has the same face and child inherit set, ignore this face
802 if (entry.hasChildInheritOnFaceId(addIt->faceId))
803 {
804 facesToAdd.erase(addIt++);
805 continue;
806 }
807
808 // Only add face if it does not override an existing route
809 if (!entry.hasFaceId(addIt->faceId))
810 {
811 RibEntry::FaceList::iterator faceIt = entry.findInheritedFace(*addIt);
812
813 // If the entry already has the inherited face, just update the face
814 if (faceIt != entry.getInheritedFaces().end())
815 {
816 faceIt->cost = addIt->cost;
817 }
818 else // Otherwise, this is a newly inherited face
819 {
820 entry.addInheritedFace(*addIt);
821 }
822
823 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), addIt->faceId, addIt->cost));
824 }
825
826 ++addIt;
827 }
828
829 Rib::RibEntryList children = entry.getChildren();
830
831 // Apply face operations to current namespace's children
832 for (Rib::RibEntryList::iterator child = children.begin(); child != children.end(); ++child)
833 {
834 traverseSubTree(*(*child), facesToAdd, facesToRemove);
835 }
836}
837
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700838std::ostream&
Vince12e49462014-06-09 13:29:32 -0500839operator<<(std::ostream& os, const Rib& rib)
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700840{
Vince12e49462014-06-09 13:29:32 -0500841 for (Rib::RibTable::const_iterator it = rib.begin(); it != rib.end(); ++it)
842 {
843 os << *(it->second) << "\n";
844 }
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700845
846 return os;
847}
848
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700849} // namespace rib
850} // namespace nfd