blob: 9901b774c006b12d2b66a6d5494ac5a0a5bb7d9b [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
Syed Obaid3313a372014-07-01 01:31:33 -050077FaceEntry*
Vince12e49462014-06-09 13:29:32 -050078Rib::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
Syed Obaid3313a372014-07-01 01:31:33 -050087 RibEntry::iterator faceIt = std::find_if(entry->begin(), entry->end(),
Vince12e49462014-06-09 13:29:32 -050088 bind(&compareFaceIdAndOrigin, _1, face));
89
90 if (faceIt != entry->end())
91 {
Syed Obaid3313a372014-07-01 01:31:33 -050092 return &((*faceIt));
Vince12e49462014-06-09 13:29:32 -050093 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070094 }
Syed Obaid3313a372014-07-01 01:31:33 -050095 return 0;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070096}
97
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070098void
Vince12e49462014-06-09 13:29:32 -050099Rib::insert(const Name& prefix, const FaceEntry& face)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700100{
Vince12e49462014-06-09 13:29:32 -0500101 RibTable::iterator ribIt = m_rib.find(prefix);
102
103 // Name prefix exists
104 if (ribIt != m_rib.end())
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700105 {
Vince12e49462014-06-09 13:29:32 -0500106 shared_ptr<RibEntry> entry(ribIt->second);
107
108 RibEntry::iterator faceIt = std::find_if(entry->getFaces().begin(),
109 entry->getFaces().end(),
110 bind(&compareFaceIdAndOrigin, _1, face));
111
112 if (faceIt == entry->end())
113 {
Vince Lehman4387e782014-06-19 16:57:45 -0500114 // Will the new face change the namespace's capture flag?
115 bool captureWasTurnedOn = (entry->hasCapture() == false && isCaptureFlagSet(face.flags));
116
Vince12e49462014-06-09 13:29:32 -0500117 // New face
118 entry->insertFace(face);
119 m_nItems++;
120
121 // Register with face lookup table
122 m_faceMap[face.faceId].push_back(entry);
Vince Lehman4387e782014-06-19 16:57:45 -0500123
124 createFibUpdatesForNewFaceEntry(*entry, face, captureWasTurnedOn);
Vince12e49462014-06-09 13:29:32 -0500125 }
Vince Lehman4387e782014-06-19 16:57:45 -0500126 else // Entry exists, update fields
Vince12e49462014-06-09 13:29:32 -0500127 {
Syed Obaid3313a372014-07-01 01:31:33 -0500128 // First cancel old scheduled event, if any, then set the EventId to new one
129 if (static_cast<bool>(faceIt->getExpirationEvent()))
130 scheduler::cancel(faceIt->getExpirationEvent());
131
132 // No checks are required here as the iterator needs to be updated in all cases.
133 faceIt->setExpirationEvent(face.getExpirationEvent());
134
Vince Lehman4387e782014-06-19 16:57:45 -0500135 // Save flags for update processing
136 uint64_t previousFlags = faceIt->flags;
137
138 // If the entry's cost didn't change and child inherit is not set,
139 // no need to traverse subtree.
140 uint64_t previousCost = faceIt->cost;
141
Vince12e49462014-06-09 13:29:32 -0500142 faceIt->flags = face.flags;
143 faceIt->cost = face.cost;
144 faceIt->expires = face.expires;
Vince Lehman4387e782014-06-19 16:57:45 -0500145
146 createFibUpdatesForUpdatedEntry(*entry, face, previousFlags, previousCost);
Vince12e49462014-06-09 13:29:32 -0500147 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700148 }
Vince12e49462014-06-09 13:29:32 -0500149 else // New name prefix
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700150 {
Vince12e49462014-06-09 13:29:32 -0500151 shared_ptr<RibEntry> entry(make_shared<RibEntry>(RibEntry()));
152
153 m_rib[prefix] = entry;
154 m_nItems++;
155
156 entry->setName(prefix);
157 entry->insertFace(face);
158
159 // Find prefix's parent
160 shared_ptr<RibEntry> parent = findParent(prefix);
161
162 // Add self to parent's children
163 if (static_cast<bool>(parent))
164 {
165 parent->addChild(entry);
166 }
167
168 RibEntryList children = findDescendants(prefix);
169
170 for (std::list<shared_ptr<RibEntry> >::iterator child = children.begin();
171 child != children.end(); ++child)
172 {
173 if ((*child)->getParent() == parent)
174 {
175 // Remove child from parent and inherit parent's child
176 if (static_cast<bool>(parent))
177 {
178 parent->removeChild((*child));
179 }
Vince12e49462014-06-09 13:29:32 -0500180 entry->addChild((*child));
181 }
182 }
183
184 // Register with face lookup table
185 m_faceMap[face.faceId].push_back(entry);
Vince Lehman4387e782014-06-19 16:57:45 -0500186
187 createFibUpdatesForNewRibEntry(*entry, face);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700188 }
189}
190
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700191void
Vince12e49462014-06-09 13:29:32 -0500192Rib::erase(const Name& prefix, const FaceEntry& face)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700193{
Vince12e49462014-06-09 13:29:32 -0500194 RibTable::iterator ribIt = m_rib.find(prefix);
195
196 // Name prefix exists
197 if (ribIt != m_rib.end())
198 {
199 shared_ptr<RibEntry> entry(ribIt->second);
200
Vince Lehman4387e782014-06-19 16:57:45 -0500201 const bool hadCapture = entry->hasCapture();
202
203 // Need to copy face to do FIB updates with correct cost and flags since nfdc does not
204 // pass flags or cost
205 RibEntry::iterator faceIt = entry->findFace(face);
Vince Lehman4387e782014-06-19 16:57:45 -0500206
207 if (faceIt != entry->end())
Vince12e49462014-06-09 13:29:32 -0500208 {
Syed Obaid3313a372014-07-01 01:31:33 -0500209 FaceEntry faceToErase = *faceIt;
210 faceToErase.flags = faceIt->flags;
211 faceToErase.cost = faceIt->cost;
212
Vince Lehman4387e782014-06-19 16:57:45 -0500213 entry->eraseFace(faceIt);
Vince12e49462014-06-09 13:29:32 -0500214 m_nItems--;
215
Vince Lehman4387e782014-06-19 16:57:45 -0500216 const bool captureWasTurnedOff = (hadCapture && !entry->hasCapture());
217
218 createFibUpdatesForErasedFaceEntry(*entry, faceToErase, captureWasTurnedOff);
219
Vince12e49462014-06-09 13:29:32 -0500220 // If this RibEntry no longer has this faceId, unregister from face lookup table
221 if (!entry->hasFaceId(face.faceId))
222 {
223 m_faceMap[face.faceId].remove(entry);
224 }
Vince Lehman4387e782014-06-19 16:57:45 -0500225 else
226 {
227 // The RibEntry still has the face ID; need to update FIB
228 // with lowest cost for the same face instead of removing the face from the FIB
229 shared_ptr<FaceEntry> lowCostFace = entry->getFaceWithLowestCostByFaceId(face.faceId);
230
231 BOOST_ASSERT(static_cast<bool>(lowCostFace));
232
233 createFibUpdatesForNewFaceEntry(*entry, *lowCostFace, false);
234 }
Vince12e49462014-06-09 13:29:32 -0500235
236 // If a RibEntry's facelist is empty, remove it from the tree
237 if (entry->getFaces().size() == 0)
238 {
239 eraseEntry(ribIt);
240 }
241 }
242 }
243}
244
245void
246Rib::erase(const uint64_t faceId)
247{
248 FaceLookupTable::iterator lookupIt = m_faceMap.find(faceId);
249
250 // No RIB entries have this face
251 if (lookupIt == m_faceMap.end())
252 {
253 return;
254 }
255
256 RibEntryList& ribEntries = lookupIt->second;
257
258 // For each RIB entry that has faceId, remove the face from the entry
259 for (RibEntryList::iterator entryIt = ribEntries.begin(); entryIt != ribEntries.end(); ++entryIt)
260 {
261 shared_ptr<RibEntry> entry = *entryIt;
262
Vince Lehman4387e782014-06-19 16:57:45 -0500263 const bool hadCapture = entry->hasCapture();
264
Vince12e49462014-06-09 13:29:32 -0500265 // Find the faces in the entry
266 for (RibEntry::iterator faceIt = entry->begin(); faceIt != entry->end(); ++faceIt)
267 {
268 if (faceIt->faceId == faceId)
269 {
Vince Lehman4387e782014-06-19 16:57:45 -0500270 FaceEntry copy = *faceIt;
271
Vince12e49462014-06-09 13:29:32 -0500272 faceIt = entry->eraseFace(faceIt);
Vince Lehman4387e782014-06-19 16:57:45 -0500273
274 const bool captureWasTurnedOff = (hadCapture && !entry->hasCapture());
275 createFibUpdatesForErasedFaceEntry(*entry, copy, captureWasTurnedOff);
Vince12e49462014-06-09 13:29:32 -0500276 }
277 }
278
279 // If a RibEntry's facelist is empty, remove it from the tree
280 if (entry->getFaces().size() == 0)
281 {
282 eraseEntry(m_rib.find(entry->getName()));
283 }
284 }
285
286 // Face no longer exists, remove from face lookup table
287 FaceLookupTable::iterator entryToDelete = m_faceMap.find(faceId);
288
289 if (entryToDelete != m_faceMap.end())
290 {
291 m_faceMap.erase(entryToDelete);
292 }
293}
294
295shared_ptr<RibEntry>
296Rib::findParent(const Name& prefix) const
297{
298 for (int i = prefix.size() - 1; i >= 0; i--)
299 {
300 RibTable::const_iterator it = m_rib.find(prefix.getPrefix(i));
301 if (it != m_rib.end())
302 {
303 return (it->second);
304 }
305 }
306
307 return shared_ptr<RibEntry>();
308}
309
310std::list<shared_ptr<RibEntry> >
311Rib::findDescendants(const Name& prefix) const
312{
313 std::list<shared_ptr<RibEntry> > children;
314
315 RibTable::const_iterator it = m_rib.find(prefix);
316
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700317 if (it != m_rib.end())
318 {
Vince12e49462014-06-09 13:29:32 -0500319 ++it;
320 for (; it != m_rib.end(); ++it)
321 {
322 if (prefix.isPrefixOf(it->first))
323 {
324 children.push_back((it->second));
325 }
326 else
327 {
328 break;
329 }
330 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700331 }
Vince12e49462014-06-09 13:29:32 -0500332
333 return children;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700334}
335
Vince12e49462014-06-09 13:29:32 -0500336Rib::RibTable::iterator
337Rib::eraseEntry(RibTable::iterator it)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700338{
Vince12e49462014-06-09 13:29:32 -0500339 // Entry does not exist
340 if (it == m_rib.end())
341 {
342 return m_rib.end();
343 }
344
345 shared_ptr<RibEntry> entry(it->second);
346
Vince Lehman4387e782014-06-19 16:57:45 -0500347 // Remove inherited routes from namespace
348 createFibUpdatesForErasedRibEntry(*entry);
349
Vince12e49462014-06-09 13:29:32 -0500350 shared_ptr<RibEntry> parent = entry->getParent();
351
352 // Remove self from parent's children
353 if (static_cast<bool>(parent))
354 {
355 parent->removeChild(entry);
356 }
357
358 std::list<shared_ptr<RibEntry> > children = entry->getChildren();
359
360 for (RibEntryList::iterator child = children.begin(); child != children.end(); ++child)
361 {
362 // Remove children from self
363 entry->removeChild(*child);
364
365 // Update parent's children
366 if (static_cast<bool>(parent))
367 {
368 parent->addChild(*child);
369 }
370 }
371
372 // Must save and advance iterator to return a valid iterator
373 RibTable::iterator nextIt = it;
374 nextIt++;
375
376 m_rib.erase(it);
377
378 return nextIt;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700379}
380
Vince Lehman4387e782014-06-19 16:57:45 -0500381bool
382compareFibUpdates(const shared_ptr<const FibUpdate> lhs, const shared_ptr<const FibUpdate> rhs)
383{
384 return ((lhs->name == rhs->name) &&
385 (lhs->faceId == rhs->faceId));
386}
387
388void
389Rib::insertFibUpdate(shared_ptr<FibUpdate> update)
390{
391 // If an update with the same name and face already exists,
392 // replace it
393 FibUpdateList::iterator it = std::find_if(m_fibUpdateList.begin(), m_fibUpdateList.end(),
394 bind(&compareFibUpdates, _1, update));
395
396 if (it != m_fibUpdateList.end())
397 {
398 // Get rid of the const to alter the action, prevents copying or removal and
399 // insertion
400 FibUpdate& entry = const_cast<FibUpdate&>(*(*it));
401 entry.action = update->action;
402 entry.cost = update->cost;
403 }
404 else
405 {
406 m_fibUpdateList.push_back(update);
407 }
408}
409
410void
411Rib::createFibUpdatesForNewRibEntry(RibEntry& entry, const FaceEntry& face)
412{
413 // Create FIB update for new entry
414 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), face.faceId, face.cost));
415
416 // No flags are set
417 if (!isAnyFlagSet(face.flags))
418 {
419 // Add ancestor faces to self
420 addInheritedFacesToEntry(entry, getAncestorFaces(entry));
421 }
422 else if (areBothFlagsSet(face.flags))
423 {
424 // Add face to children
425 FaceSet facesToAdd;
426 facesToAdd.insert(face);
427
428 // Remove faces blocked by capture and add self to children
429 modifyChildrensInheritedFaces(entry, facesToAdd, getAncestorFaces(entry));
430 }
431 else if (isChildInheritFlagSet(face.flags))
432 {
433 FaceSet ancestorFaces = getAncestorFaces(entry);
434
435 // Add ancestor faces to self
436 addInheritedFacesToEntry(entry, ancestorFaces);
437
438 // If there is an ancestor face which is the same as the new face, replace it
439 // with the new face
440 FaceSet::iterator it = ancestorFaces.find(face);
441
442 // There is a face that needs to be overwritten, erase and then replace
443 if (it != ancestorFaces.end())
444 {
445 ancestorFaces.erase(it);
446 }
447
448 // Add new face to ancestor list so it can be added to children
449 ancestorFaces.insert(face);
450
451 // Add ancestor faces to children
452 modifyChildrensInheritedFaces(entry, ancestorFaces, FaceSet());
453 }
454 else if (isCaptureFlagSet(face.flags))
455 {
456 // Remove faces blocked by capture
457 modifyChildrensInheritedFaces(entry, FaceSet(), getAncestorFaces(entry));
458 }
459}
460
461void
462Rib::createFibUpdatesForNewFaceEntry(RibEntry& entry, const FaceEntry& face,
463 bool captureWasTurnedOn)
464{
465 // Only update if the new face has a lower cost than a previously installed face
466 shared_ptr<FaceEntry> prevFace = entry.getFaceWithLowestCostAndChildInheritByFaceId(face.faceId);
467
468 FaceSet facesToAdd;
469 if (isChildInheritFlagSet(face.flags))
470 {
471 // Add to children if this new face doesn't override a previous lower cost, or
472 // add to children if this new is lower cost than a previous face.
473 // Less than equal, since entry may find this face
474 if (!static_cast<bool>(prevFace) || face.cost <= prevFace->cost)
475 {
476 // Add self to children
477 facesToAdd.insert(face);
478 }
479 }
480
481 FaceSet facesToRemove;
482 if (captureWasTurnedOn)
483 {
484 // Capture flag on
485 facesToRemove = getAncestorFaces(entry);
486
487 // Remove ancestor faces from self
488 removeInheritedFacesFromEntry(entry, facesToRemove);
489 }
490
491 modifyChildrensInheritedFaces(entry, facesToAdd, facesToRemove);
492
493 // If another face with same faceId and lower cost, don't update.
494 // Must be done last so that add updates replace removal updates
495 // Create FIB update for new entry
496 if (face.cost <= entry.getFaceWithLowestCostByFaceId(face.faceId)->cost)
497 {
498 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), face.faceId, face.cost));
499 }
500}
501
502void
503Rib::createFibUpdatesForUpdatedEntry(RibEntry& entry, const FaceEntry& face,
504 const uint64_t previousFlags, const uint64_t previousCost)
505{
506 const bool costDidChange = (face.cost != previousCost);
507
508 // Look for an installed face with the lowest cost and child inherit set
509 shared_ptr<FaceEntry> prevFace = entry.getFaceWithLowestCostAndChildInheritByFaceId(face.faceId);
510
511 // No flags changed and cost didn't change, no change in FIB
512 if (face.flags == previousFlags && !costDidChange)
513 {
514 return;
515 }
516
517 // Cost changed so create update for the entry itself
518 if (costDidChange)
519 {
520 // Create update if this face's cost is lower than other faces
521 if (face.cost <= entry.getFaceWithLowestCostByFaceId(face.faceId)->cost)
522 {
523 // Create FIB update for the updated entry
524 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), face.faceId, face.cost));
525 }
526 else if (previousCost < entry.getFaceWithLowestCostByFaceId(face.faceId)->cost)
527 {
528 // Create update if this face used to be the lowest face but is no longer
529 // the lowest cost face.
530 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), prevFace->faceId,
531 prevFace->cost));
532 }
533
534 // If another face with same faceId and lower cost and ChildInherit exists,
535 // don't update children.
536 if (!static_cast<bool>(prevFace) || face.cost <= prevFace->cost)
537 {
538 // If no flags changed but child inheritance is set, need to update children
539 // with new cost
540 if ((face.flags == previousFlags) && isChildInheritFlagSet(face.flags))
541 {
542 // Add self to children
543 FaceSet facesToAdd;
544 facesToAdd.insert(face);
545 modifyChildrensInheritedFaces(entry, facesToAdd, FaceSet());
546
547 return;
548 }
549 }
550 }
551
552 // Child inherit was turned on
553 if (!isChildInheritFlagSet(previousFlags) && isChildInheritFlagSet(face.flags))
554 {
555 // If another face with same faceId and lower cost and ChildInherit exists,
556 // don't update children.
557 if (!static_cast<bool>(prevFace) || face.cost <= prevFace->cost)
558 {
559 // Add self to children
560 FaceSet facesToAdd;
561 facesToAdd.insert(face);
562 modifyChildrensInheritedFaces(entry, facesToAdd, FaceSet());
563 }
564
565 } // Child inherit was turned off
566 else if (isChildInheritFlagSet(previousFlags) && !isChildInheritFlagSet(face.flags))
567 {
568 // Remove self from children
569 FaceSet facesToRemove;
570 facesToRemove.insert(face);
571
572 FaceSet facesToAdd;
573 // If another face with same faceId and ChildInherit exists, update children with this face.
574 if (static_cast<bool>(prevFace))
575 {
576 facesToAdd.insert(*prevFace);
577 }
578 else
579 {
580 // Look for an ancestor that was blocked previously
581 const FaceSet ancestorFaces = getAncestorFaces(entry);
582 FaceSet::iterator it = ancestorFaces.find(face);
583
584 // If an ancestor is found, add it to children
585 if (it != ancestorFaces.end())
586 {
587 facesToAdd.insert(*it);
588 }
589 }
590
591 modifyChildrensInheritedFaces(entry, facesToAdd, facesToRemove);
592 }
593
594 // Capture was turned on
595 if (!isCaptureFlagSet(previousFlags) && isCaptureFlagSet(face.flags))
596 {
597 FaceSet ancestorFaces = getAncestorFaces(entry);
598
599 // Remove ancestor faces from self
600 removeInheritedFacesFromEntry(entry, ancestorFaces);
601
602 // Remove ancestor faces from children
603 modifyChildrensInheritedFaces(entry, FaceSet(), ancestorFaces);
604 } // Capture was turned off
605 else if (isCaptureFlagSet(previousFlags) && !isCaptureFlagSet(face.flags))
606 {
607 FaceSet ancestorFaces = getAncestorFaces(entry);
608
609 // Add ancestor faces to self
610 addInheritedFacesToEntry(entry, ancestorFaces);
611
612 // Add ancestor faces to children
613 modifyChildrensInheritedFaces(entry, ancestorFaces, FaceSet());
614 }
615}
616
617void
618Rib::createFibUpdatesForErasedFaceEntry(RibEntry& entry, const FaceEntry& face,
619 const bool captureWasTurnedOff)
620{
621 insertFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), face.faceId));
622
623 if (areBothFlagsSet(face.flags))
624 {
625 // Remove self from children
626 FaceSet facesToRemove;
627 facesToRemove.insert(face);
628
629 // If capture is turned off for the route, need to add ancestors
630 // to self and children
631 FaceSet facesToAdd;
632 if (captureWasTurnedOff)
633 {
634 // Look for an ancestors that were blocked previously
635 facesToAdd = getAncestorFaces(entry);
636
637 // Add ancestor faces to self
638 addInheritedFacesToEntry(entry, facesToAdd);
639 }
640
641 modifyChildrensInheritedFaces(entry, facesToAdd, facesToRemove);
642 }
643 else if (isChildInheritFlagSet(face.flags))
644 {
645 // If not blocked by capture, add inherited routes to children
646 FaceSet facesToAdd;
647 if (!entry.hasCapture())
648 {
649 facesToAdd = getAncestorFaces(entry);
650 }
651
652 FaceSet facesToRemove;
653 facesToRemove.insert(face);
654
655 // Add ancestor faces to children
656 modifyChildrensInheritedFaces(entry, facesToAdd, facesToRemove);
657 }
658 else if (isCaptureFlagSet(face.flags))
659 {
660 // If capture is turned off for the route, need to add ancestors
661 // to self and children
662 FaceSet facesToAdd;
663 if (captureWasTurnedOff)
664 {
665 // Look for an ancestors that were blocked previously
666 facesToAdd = getAncestorFaces(entry);
667
668 // Add ancestor faces to self
669 addInheritedFacesToEntry(entry, facesToAdd);
670 }
671
672 modifyChildrensInheritedFaces(entry, facesToAdd, FaceSet());
673 }
674
675 // Need to check if the removed face was blocking an inherited route
676 FaceSet ancestorFaces = getAncestorFaces(entry);
677
678 if (!entry.hasCapture())
679 {
680 // If there is an ancestor face which is the same as the erased face, add that face
681 // to the current entry
682 FaceSet::iterator it = ancestorFaces.find(face);
683
684 if (it != ancestorFaces.end())
685 {
686 entry.addInheritedFace(*it);
687 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), it->faceId, it->cost));
688 }
689 }
690}
691
692void
693Rib::createFibUpdatesForErasedRibEntry(RibEntry& entry)
694{
695 for (RibEntry::FaceList::iterator it = entry.getInheritedFaces().begin();
696 it != entry.getInheritedFaces().end(); ++it)
697 {
698 insertFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), it->faceId));
699 }
700}
701
702Rib::FaceSet
703Rib::getAncestorFaces(const RibEntry& entry) const
704{
705 FaceSet ancestorFaces(&sortFace);
706
707 shared_ptr<RibEntry> parent = entry.getParent();
708
709 while (static_cast<bool>(parent))
710 {
711 for (RibEntry::iterator it = parent->getFaces().begin();
712 it != parent->getFaces().end(); ++it)
713 {
714 if (isChildInheritFlagSet(it->flags))
715 {
716 ancestorFaces.insert(*it);
717 }
718 }
719
720 if (parent->hasCapture())
721 {
722 break;
723 }
724
725 parent = parent->getParent();
726 }
727
728 return ancestorFaces;
729}
730
731void
732Rib::addInheritedFacesToEntry(RibEntry& entry, const Rib::FaceSet& facesToAdd)
733{
734 for (FaceSet::const_iterator it = facesToAdd.begin(); it != facesToAdd.end(); ++it)
735 {
736 // Don't add an ancestor faceId if the namespace has an entry for that faceId
737 if (!entry.hasFaceId(it->faceId))
738 {
739 entry.addInheritedFace(*it);
740 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), it->faceId, it->cost));
741 }
742 }
743}
744
745void
746Rib::removeInheritedFacesFromEntry(RibEntry& entry, const Rib::FaceSet& facesToRemove)
747{
748 for (FaceSet::const_iterator it = facesToRemove.begin(); it != facesToRemove.end(); ++it)
749 {
750 // Only remove if the face has been inherited
751 if (entry.hasInheritedFace(*it))
752 {
753 entry.removeInheritedFace(*it);
754 insertFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), it->faceId));
755 }
756 }
757}
758
759void
760Rib::modifyChildrensInheritedFaces(RibEntry& entry, const Rib::FaceSet& facesToAdd,
761 const Rib::FaceSet& facesToRemove)
762{
763 RibEntryList children = entry.getChildren();
764
765 for (RibEntryList::iterator child = children.begin(); child != children.end(); ++child)
766 {
767 traverseSubTree(*(*child), facesToAdd, facesToRemove);
768 }
769}
770
771void
772Rib::traverseSubTree(RibEntry& entry, Rib::FaceSet facesToAdd,
773 Rib::FaceSet facesToRemove)
774{
775 // If a route on the namespace has the capture flag set, ignore self and children
776 if (entry.hasCapture())
777 {
778 return;
779 }
780
781 // Remove inherited faces from current namespace
782 for (Rib::FaceSet::const_iterator removeIt = facesToRemove.begin();
783 removeIt != facesToRemove.end(); )
784 {
785 // If a route on the namespace has the same face and child inheritance set, ignore this face
786 if (entry.hasChildInheritOnFaceId(removeIt->faceId))
787 {
788 facesToRemove.erase(removeIt++);
789 continue;
790 }
791
792 // Only remove face if it removes an existing inherited route
793 if (entry.hasInheritedFace(*removeIt))
794 {
795 entry.removeInheritedFace(*removeIt);
796 insertFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), removeIt->faceId));
797 }
798
799 ++removeIt;
800 }
801
802 // Add inherited faces to current namespace
803 for (Rib::FaceSet::const_iterator addIt = facesToAdd.begin();
804 addIt != facesToAdd.end(); )
805 {
806 // If a route on the namespace has the same face and child inherit set, ignore this face
807 if (entry.hasChildInheritOnFaceId(addIt->faceId))
808 {
809 facesToAdd.erase(addIt++);
810 continue;
811 }
812
813 // Only add face if it does not override an existing route
814 if (!entry.hasFaceId(addIt->faceId))
815 {
816 RibEntry::FaceList::iterator faceIt = entry.findInheritedFace(*addIt);
817
818 // If the entry already has the inherited face, just update the face
819 if (faceIt != entry.getInheritedFaces().end())
820 {
821 faceIt->cost = addIt->cost;
822 }
823 else // Otherwise, this is a newly inherited face
824 {
825 entry.addInheritedFace(*addIt);
826 }
827
828 insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), addIt->faceId, addIt->cost));
829 }
830
831 ++addIt;
832 }
833
834 Rib::RibEntryList children = entry.getChildren();
835
836 // Apply face operations to current namespace's children
837 for (Rib::RibEntryList::iterator child = children.begin(); child != children.end(); ++child)
838 {
839 traverseSubTree(*(*child), facesToAdd, facesToRemove);
840 }
841}
842
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700843std::ostream&
Vince12e49462014-06-09 13:29:32 -0500844operator<<(std::ostream& os, const Rib& rib)
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700845{
Vince12e49462014-06-09 13:29:32 -0500846 for (Rib::RibTable::const_iterator it = rib.begin(); it != rib.end(); ++it)
847 {
848 os << *(it->second) << "\n";
849 }
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700850
851 return os;
852}
853
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700854} // namespace rib
855} // namespace nfd