blob: fe4db0b67612c9de9051136b9842aed2a3a9b093 [file] [log] [blame]
Alexander Afanasyev3ecec502014-04-16 13:42:44 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesaventoa3148082018-04-12 18:21:54 -04002/*
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -04003 * Copyright (c) 2014-2022, Regents of the University of California,
Alexander Afanasyev7c10b3b2015-01-20 12:24:27 -08004 * 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"
Vince Lehman76c751c2014-11-18 17:36:38 -060027#include "fib-updater.hpp"
Davide Pesavento2cae8ca2019-04-18 20:48:05 -040028#include "common/logger.hpp"
Vince Lehman281ded72014-08-21 12:17:08 -050029
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070030namespace nfd {
31namespace rib {
32
Davide Pesaventoa3148082018-04-12 18:21:54 -040033NFD_LOG_INIT(Rib);
34
Junxiao Shi89c0ea02017-03-06 19:52:05 +000035bool
36operator<(const RibRouteRef& lhs, const RibRouteRef& rhs)
37{
38 return std::tie(lhs.entry->getName(), lhs.route->faceId, lhs.route->origin) <
39 std::tie(rhs.entry->getName(), rhs.route->faceId, rhs.route->origin);
40}
41
Vince Lehman4387e782014-06-19 16:57:45 -050042static inline bool
Vince Lehman218be0a2015-01-15 17:25:20 -060043sortRoutes(const Route& lhs, const Route& rhs)
Vince Lehman4387e782014-06-19 16:57:45 -050044{
Vince Lehman218be0a2015-01-15 17:25:20 -060045 return lhs.faceId < rhs.faceId;
Vince Lehman4387e782014-06-19 16:57:45 -050046}
47
Vince Lehman76c751c2014-11-18 17:36:38 -060048void
49Rib::setFibUpdater(FibUpdater* updater)
50{
51 m_fibUpdater = updater;
52}
53
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070054Rib::const_iterator
Vince12e49462014-06-09 13:29:32 -050055Rib::find(const Name& prefix) const
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070056{
Vince12e49462014-06-09 13:29:32 -050057 return m_rib.find(prefix);
58}
59
Vince Lehman218be0a2015-01-15 17:25:20 -060060Route*
61Rib::find(const Name& prefix, const Route& route) const
Vince12e49462014-06-09 13:29:32 -050062{
Davide Pesaventoe4b22382018-06-10 14:37:24 -040063 auto ribIt = m_rib.find(prefix);
Vince12e49462014-06-09 13:29:32 -050064
65 // Name prefix exists
Vince Lehman76c751c2014-11-18 17:36:38 -060066 if (ribIt != m_rib.end()) {
67 shared_ptr<RibEntry> entry = ribIt->second;
Davide Pesaventoe4b22382018-06-10 14:37:24 -040068 auto routeIt = entry->findRoute(route);
Vince Lehman76c751c2014-11-18 17:36:38 -060069 if (routeIt != entry->end()) {
Davide Pesaventoe4b22382018-06-10 14:37:24 -040070 return &*routeIt;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070071 }
Vince Lehman76c751c2014-11-18 17:36:38 -060072 }
Vince Lehman218be0a2015-01-15 17:25:20 -060073
74 return nullptr;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070075}
76
Teng Lianga4e6ec32018-10-21 09:25:00 -070077Route*
78Rib::findLongestPrefix(const Name& prefix, const Route& route) const
79{
80 Route* existingRoute = find(prefix, route);
81 if (existingRoute == nullptr) {
82 auto parent = findParent(prefix);
83 if (parent) {
84 existingRoute = find(parent->getName(), route);
85 }
86 }
87
88 return existingRoute;
89}
90
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070091void
Vince Lehman218be0a2015-01-15 17:25:20 -060092Rib::insert(const Name& prefix, const Route& route)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070093{
Davide Pesaventoe4b22382018-06-10 14:37:24 -040094 auto ribIt = m_rib.find(prefix);
Vince12e49462014-06-09 13:29:32 -050095
96 // Name prefix exists
Vince Lehman76c751c2014-11-18 17:36:38 -060097 if (ribIt != m_rib.end()) {
98 shared_ptr<RibEntry> entry(ribIt->second);
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -040099 auto [entryIt, didInsert] = entry->insertRoute(route);
Vince12e49462014-06-09 13:29:32 -0500100
Nick Gordon89c4cca2016-11-02 15:42:32 +0000101 if (didInsert) {
102 // The route was new and we successfully inserted it.
Vince Lehman76c751c2014-11-18 17:36:38 -0600103 m_nItems++;
Vince12e49462014-06-09 13:29:32 -0500104
Nick Gordon89c4cca2016-11-02 15:42:32 +0000105 afterAddRoute(RibRouteRef{entry, entryIt});
106
Vince12e49462014-06-09 13:29:32 -0500107 // Register with face lookup table
Junxiao Shi17a70012019-06-25 10:50:32 +0000108 m_faceEntries.emplace(route.faceId, entry);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700109 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600110 else {
111 // Route exists, update fields
112 // First cancel old scheduled event, if any, then set the EventId to new one
Davide Pesaventoe1bdc082018-10-11 21:20:23 -0400113 if (entryIt->getExpirationEvent()) {
114 NFD_LOG_TRACE("Cancelling expiration event for " << entry->getName() << " " << *entryIt);
115 entryIt->cancelExpirationEvent();
Vince Lehman76c751c2014-11-18 17:36:38 -0600116 }
117
Junxiao Shid47cd632018-09-11 03:10:00 +0000118 *entryIt = route;
Vince Lehman76c751c2014-11-18 17:36:38 -0600119 }
120 }
121 else {
122 // New name prefix
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400123 auto entry = make_shared<RibEntry>();
Vince Lehman76c751c2014-11-18 17:36:38 -0600124
125 m_rib[prefix] = entry;
126 m_nItems++;
127
128 entry->setName(prefix);
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400129 auto routeIt = entry->insertRoute(route).first;
Vince Lehman76c751c2014-11-18 17:36:38 -0600130
131 // Find prefix's parent
132 shared_ptr<RibEntry> parent = findParent(prefix);
133
134 // Add self to parent's children
135 if (parent != nullptr) {
136 parent->addChild(entry);
137 }
138
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400139 auto children = findDescendants(prefix);
Vince Lehman76c751c2014-11-18 17:36:38 -0600140 for (const auto& child : children) {
141 if (child->getParent() == parent) {
142 // Remove child from parent and inherit parent's child
143 if (parent != nullptr) {
144 parent->removeChild(child);
145 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600146 entry->addChild(child);
147 }
148 }
149
150 // Register with face lookup table
Junxiao Shi17a70012019-06-25 10:50:32 +0000151 m_faceEntries.emplace(route.faceId, entry);
Vince Lehman76c751c2014-11-18 17:36:38 -0600152
153 // do something after inserting an entry
154 afterInsertEntry(prefix);
Nick Gordon89c4cca2016-11-02 15:42:32 +0000155 afterAddRoute(RibRouteRef{entry, routeIt});
Vince Lehman76c751c2014-11-18 17:36:38 -0600156 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700157}
158
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700159void
Vince Lehman218be0a2015-01-15 17:25:20 -0600160Rib::erase(const Name& prefix, const Route& route)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700161{
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400162 auto ribIt = m_rib.find(prefix);
Junxiao Shi17a70012019-06-25 10:50:32 +0000163 if (ribIt == m_rib.end()) {
164 // Name prefix does not exist
165 return;
166 }
Vince12e49462014-06-09 13:29:32 -0500167
Junxiao Shi17a70012019-06-25 10:50:32 +0000168 shared_ptr<RibEntry> entry = ribIt->second;
169 auto routeIt = entry->findRoute(route);
Vince Lehman4387e782014-06-19 16:57:45 -0500170
Junxiao Shi17a70012019-06-25 10:50:32 +0000171 if (routeIt != entry->end()) {
172 beforeRemoveRoute(RibRouteRef{entry, routeIt});
Nick Gordon89c4cca2016-11-02 15:42:32 +0000173
Junxiao Shi17a70012019-06-25 10:50:32 +0000174 auto faceId = route.faceId;
175 entry->eraseRoute(routeIt);
176 m_nItems--;
Vince Lehman4387e782014-06-19 16:57:45 -0500177
Junxiao Shi17a70012019-06-25 10:50:32 +0000178 // If this RibEntry no longer has this faceId, unregister from face lookup table
179 if (!entry->hasFaceId(faceId)) {
180 auto range = m_faceEntries.equal_range(faceId);
181 for (auto it = range.first; it != range.second; ++it) {
182 if (it->second == entry) {
183 m_faceEntries.erase(it);
184 break;
185 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600186 }
Junxiao Shi17a70012019-06-25 10:50:32 +0000187 }
Syed Obaid3313a372014-07-01 01:31:33 -0500188
Junxiao Shi17a70012019-06-25 10:50:32 +0000189 // If a RibEntry's route list is empty, remove it from the tree
190 if (entry->getRoutes().empty()) {
191 eraseEntry(ribIt);
Vince12e49462014-06-09 13:29:32 -0500192 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600193 }
Vince12e49462014-06-09 13:29:32 -0500194}
195
196void
Vince Lehman76c751c2014-11-18 17:36:38 -0600197Rib::onRouteExpiration(const Name& prefix, const Route& route)
Vince12e49462014-06-09 13:29:32 -0500198{
Vince Lehman76c751c2014-11-18 17:36:38 -0600199 NFD_LOG_DEBUG(route << " for " << prefix << " has expired");
Vince12e49462014-06-09 13:29:32 -0500200
Vince Lehman76c751c2014-11-18 17:36:38 -0600201 RibUpdate update;
202 update.setAction(RibUpdate::UNREGISTER)
203 .setName(prefix)
204 .setRoute(route);
Vince12e49462014-06-09 13:29:32 -0500205
Vince Lehman76c751c2014-11-18 17:36:38 -0600206 beginApplyUpdate(update, nullptr, nullptr);
Vince12e49462014-06-09 13:29:32 -0500207}
208
209shared_ptr<RibEntry>
210Rib::findParent(const Name& prefix) const
211{
Vince Lehman76c751c2014-11-18 17:36:38 -0600212 for (int i = prefix.size() - 1; i >= 0; i--) {
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400213 auto it = m_rib.find(prefix.getPrefix(i));
Vince Lehman76c751c2014-11-18 17:36:38 -0600214 if (it != m_rib.end()) {
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400215 return it->second;
Vince12e49462014-06-09 13:29:32 -0500216 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600217 }
Vince12e49462014-06-09 13:29:32 -0500218
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400219 return nullptr;
Vince12e49462014-06-09 13:29:32 -0500220}
221
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400222std::list<shared_ptr<RibEntry>>
Vince12e49462014-06-09 13:29:32 -0500223Rib::findDescendants(const Name& prefix) const
224{
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400225 std::list<shared_ptr<RibEntry>> children;
Vince12e49462014-06-09 13:29:32 -0500226
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400227 auto it = m_rib.find(prefix);
Vince Lehman76c751c2014-11-18 17:36:38 -0600228 if (it != m_rib.end()) {
229 ++it;
230 for (; it != m_rib.end(); ++it) {
231 if (prefix.isPrefixOf(it->first)) {
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400232 children.push_back(it->second);
Vince Lehman76c751c2014-11-18 17:36:38 -0600233 }
234 else {
235 break;
236 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700237 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600238 }
239
240 return children;
241}
242
243std::list<shared_ptr<RibEntry>>
244Rib::findDescendantsForNonInsertedName(const Name& prefix) const
245{
246 std::list<shared_ptr<RibEntry>> children;
247
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400248 for (const auto& [name, ribEntry] : m_rib) {
249 if (prefix.isPrefixOf(name)) {
250 children.push_back(ribEntry);
Vince Lehman76c751c2014-11-18 17:36:38 -0600251 }
252 }
Vince12e49462014-06-09 13:29:32 -0500253
254 return children;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700255}
256
Vince12e49462014-06-09 13:29:32 -0500257Rib::RibTable::iterator
258Rib::eraseEntry(RibTable::iterator it)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700259{
Vince12e49462014-06-09 13:29:32 -0500260 // Entry does not exist
Vince Lehman76c751c2014-11-18 17:36:38 -0600261 if (it == m_rib.end()) {
262 return m_rib.end();
263 }
Vince12e49462014-06-09 13:29:32 -0500264
265 shared_ptr<RibEntry> entry(it->second);
Vince12e49462014-06-09 13:29:32 -0500266 shared_ptr<RibEntry> parent = entry->getParent();
267
268 // Remove self from parent's children
Vince Lehman76c751c2014-11-18 17:36:38 -0600269 if (parent != nullptr) {
270 parent->removeChild(entry);
271 }
272
273 for (auto childIt = entry->getChildren().begin(); childIt != entry->getChildren().end(); ) {
274 shared_ptr<RibEntry> child = *childIt;
275
276 // Advance iterator so it is not invalidated by removal
277 ++childIt;
278
279 // Remove children from self
280 entry->removeChild(child);
281
282 // Update parent's children
283 if (parent != nullptr) {
284 parent->addChild(child);
Vince12e49462014-06-09 13:29:32 -0500285 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600286 }
Vince12e49462014-06-09 13:29:32 -0500287
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400288 auto nextIt = m_rib.erase(it);
Vince12e49462014-06-09 13:29:32 -0500289
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400290 // do something after erasing an entry
Yanbiao Lic17de832014-11-21 17:51:45 -0800291 afterEraseEntry(entry->getName());
292
Vince12e49462014-06-09 13:29:32 -0500293 return nextIt;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700294}
295
Vince Lehman218be0a2015-01-15 17:25:20 -0600296Rib::RouteSet
297Rib::getAncestorRoutes(const RibEntry& entry) const
Vince Lehman4387e782014-06-19 16:57:45 -0500298{
Vince Lehman218be0a2015-01-15 17:25:20 -0600299 RouteSet ancestorRoutes(&sortRoutes);
Vince Lehman4387e782014-06-19 16:57:45 -0500300
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400301 auto parent = entry.getParent();
Vince Lehman76c751c2014-11-18 17:36:38 -0600302 while (parent != nullptr) {
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400303 for (const auto& route : parent->getRoutes()) {
Vince Lehman76c751c2014-11-18 17:36:38 -0600304 if (route.isChildInherit()) {
305 ancestorRoutes.insert(route);
Vince Lehman4387e782014-06-19 16:57:45 -0500306 }
Vince Lehman4387e782014-06-19 16:57:45 -0500307 }
308
Vince Lehman76c751c2014-11-18 17:36:38 -0600309 if (parent->hasCapture()) {
310 break;
Vince Lehman4387e782014-06-19 16:57:45 -0500311 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600312
313 parent = parent->getParent();
314 }
315
316 return ancestorRoutes;
317}
318
319Rib::RouteSet
320Rib::getAncestorRoutes(const Name& name) const
321{
322 RouteSet ancestorRoutes(&sortRoutes);
323
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400324 auto parent = findParent(name);
Vince Lehman76c751c2014-11-18 17:36:38 -0600325 while (parent != nullptr) {
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400326 for (const auto& route : parent->getRoutes()) {
Vince Lehman76c751c2014-11-18 17:36:38 -0600327 if (route.isChildInherit()) {
328 ancestorRoutes.insert(route);
329 }
330 }
331
332 if (parent->hasCapture()) {
333 break;
334 }
335
336 parent = parent->getParent();
337 }
338
339 return ancestorRoutes;
340}
341
342void
343Rib::beginApplyUpdate(const RibUpdate& update,
344 const Rib::UpdateSuccessCallback& onSuccess,
345 const Rib::UpdateFailureCallback& onFailure)
346{
347 BOOST_ASSERT(m_fibUpdater != nullptr);
Vince Lehman76c751c2014-11-18 17:36:38 -0600348 addUpdateToQueue(update, onSuccess, onFailure);
Vince Lehman76c751c2014-11-18 17:36:38 -0600349 sendBatchFromQueue();
350}
351
352void
353Rib::beginRemoveFace(uint64_t faceId)
354{
Junxiao Shi17a70012019-06-25 10:50:32 +0000355 auto range = m_faceEntries.equal_range(faceId);
356 for (auto it = range.first; it != range.second; ++it) {
357 enqueueRemoveFace(*it->second, faceId);
358 }
359 sendBatchFromQueue();
360}
361
362void
363Rib::beginRemoveFailedFaces(const std::set<uint64_t>& activeFaceIds)
364{
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400365 for (const auto& [faceId, ribEntry] : m_faceEntries) {
366 if (activeFaceIds.count(faceId) > 0) {
Junxiao Shi17a70012019-06-25 10:50:32 +0000367 continue;
368 }
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400369 enqueueRemoveFace(*ribEntry, faceId);
Junxiao Shi17a70012019-06-25 10:50:32 +0000370 }
371 sendBatchFromQueue();
372}
373
374void
375Rib::enqueueRemoveFace(const RibEntry& entry, uint64_t faceId)
376{
377 for (const Route& route : entry) {
378 if (route.faceId != faceId) {
379 continue;
380 }
381
Vince Lehman76c751c2014-11-18 17:36:38 -0600382 RibUpdate update;
383 update.setAction(RibUpdate::REMOVE_FACE)
Junxiao Shi17a70012019-06-25 10:50:32 +0000384 .setName(entry.getName())
385 .setRoute(route);
Vince Lehman76c751c2014-11-18 17:36:38 -0600386 addUpdateToQueue(update, nullptr, nullptr);
387 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600388}
389
390void
391Rib::addUpdateToQueue(const RibUpdate& update,
392 const Rib::UpdateSuccessCallback& onSuccess,
393 const Rib::UpdateFailureCallback& onFailure)
394{
395 RibUpdateBatch batch(update.getRoute().faceId);
396 batch.add(update);
397
398 UpdateQueueItem item{batch, onSuccess, onFailure};
399 m_updateBatches.push_back(std::move(item));
400}
401
402void
403Rib::sendBatchFromQueue()
404{
405 if (m_updateBatches.empty() || m_isUpdateInProgress) {
406 return;
407 }
408
409 m_isUpdateInProgress = true;
410
411 UpdateQueueItem item = std::move(m_updateBatches.front());
412 m_updateBatches.pop_front();
413
414 RibUpdateBatch& batch = item.batch;
415
416 // Until task #1698, each RibUpdateBatch contains exactly one RIB update
417 BOOST_ASSERT(batch.size() == 1);
418
Davide Pesavento412c9822021-07-02 00:21:05 -0400419 auto fibSuccessCb = std::bind(&Rib::onFibUpdateSuccess, this, batch, _1, item.managerSuccessCallback);
420 auto fibFailureCb = std::bind(&Rib::onFibUpdateFailure, this, item.managerFailureCallback, _1, _2);
Junxiao Shi52009042018-09-10 12:33:56 +0000421 m_fibUpdater->computeAndSendFibUpdates(batch, fibSuccessCb, fibFailureCb);
Vince Lehman76c751c2014-11-18 17:36:38 -0600422}
423
424void
425Rib::onFibUpdateSuccess(const RibUpdateBatch& batch,
426 const RibUpdateList& inheritedRoutes,
427 const Rib::UpdateSuccessCallback& onSuccess)
428{
429 for (const RibUpdate& update : batch) {
430 switch (update.getAction()) {
431 case RibUpdate::REGISTER:
432 insert(update.getName(), update.getRoute());
433 break;
434 case RibUpdate::UNREGISTER:
435 case RibUpdate::REMOVE_FACE:
436 erase(update.getName(), update.getRoute());
437 break;
438 }
439 }
440
441 // Add and remove precalculated inherited routes to RibEntries
442 modifyInheritedRoutes(inheritedRoutes);
443
444 m_isUpdateInProgress = false;
445
446 if (onSuccess != nullptr) {
447 onSuccess();
448 }
449
450 // Try to advance the batch queue
451 sendBatchFromQueue();
452}
453
454void
455Rib::onFibUpdateFailure(const Rib::UpdateFailureCallback& onFailure,
456 uint32_t code, const std::string& error)
457{
458 m_isUpdateInProgress = false;
459
460 if (onFailure != nullptr) {
461 onFailure(code, error);
462 }
463
464 // Try to advance the batch queue
465 sendBatchFromQueue();
466}
467
468void
469Rib::modifyInheritedRoutes(const RibUpdateList& inheritedRoutes)
470{
471 for (const RibUpdate& update : inheritedRoutes) {
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400472 auto ribIt = m_rib.find(update.getName());
Vince Lehman76c751c2014-11-18 17:36:38 -0600473 BOOST_ASSERT(ribIt != m_rib.end());
474 shared_ptr<RibEntry> entry(ribIt->second);
475
476 switch (update.getAction()) {
477 case RibUpdate::REGISTER:
478 entry->addInheritedRoute(update.getRoute());
479 break;
480 case RibUpdate::UNREGISTER:
481 entry->removeInheritedRoute(update.getRoute());
482 break;
483 case RibUpdate::REMOVE_FACE:
484 break;
485 }
486 }
487}
488
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700489std::ostream&
Vince12e49462014-06-09 13:29:32 -0500490operator<<(std::ostream& os, const Rib& rib)
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700491{
Vince Lehman76c751c2014-11-18 17:36:38 -0600492 for (const auto& item : rib) {
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700493 os << *item.second << "\n";
Vince Lehman76c751c2014-11-18 17:36:38 -0600494 }
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700495
496 return os;
497}
498
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700499} // namespace rib
500} // namespace nfd