blob: 1d002a11947622e559a9d29f5d75351c0e45eec4 [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
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040030namespace nfd::rib {
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070031
Davide Pesaventoa3148082018-04-12 18:21:54 -040032NFD_LOG_INIT(Rib);
33
Junxiao Shi89c0ea02017-03-06 19:52:05 +000034bool
35operator<(const RibRouteRef& lhs, const RibRouteRef& rhs)
36{
37 return std::tie(lhs.entry->getName(), lhs.route->faceId, lhs.route->origin) <
38 std::tie(rhs.entry->getName(), rhs.route->faceId, rhs.route->origin);
39}
40
Vince Lehman4387e782014-06-19 16:57:45 -050041static inline bool
Vince Lehman218be0a2015-01-15 17:25:20 -060042sortRoutes(const Route& lhs, const Route& rhs)
Vince Lehman4387e782014-06-19 16:57:45 -050043{
Vince Lehman218be0a2015-01-15 17:25:20 -060044 return lhs.faceId < rhs.faceId;
Vince Lehman4387e782014-06-19 16:57:45 -050045}
46
Vince Lehman76c751c2014-11-18 17:36:38 -060047void
48Rib::setFibUpdater(FibUpdater* updater)
49{
50 m_fibUpdater = updater;
51}
52
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070053Rib::const_iterator
Vince12e49462014-06-09 13:29:32 -050054Rib::find(const Name& prefix) const
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070055{
Vince12e49462014-06-09 13:29:32 -050056 return m_rib.find(prefix);
57}
58
Vince Lehman218be0a2015-01-15 17:25:20 -060059Route*
60Rib::find(const Name& prefix, const Route& route) const
Vince12e49462014-06-09 13:29:32 -050061{
Davide Pesaventoe4b22382018-06-10 14:37:24 -040062 auto ribIt = m_rib.find(prefix);
Vince12e49462014-06-09 13:29:32 -050063
64 // Name prefix exists
Vince Lehman76c751c2014-11-18 17:36:38 -060065 if (ribIt != m_rib.end()) {
66 shared_ptr<RibEntry> entry = ribIt->second;
Davide Pesaventoe4b22382018-06-10 14:37:24 -040067 auto routeIt = entry->findRoute(route);
Vince Lehman76c751c2014-11-18 17:36:38 -060068 if (routeIt != entry->end()) {
Davide Pesaventoe4b22382018-06-10 14:37:24 -040069 return &*routeIt;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070070 }
Vince Lehman76c751c2014-11-18 17:36:38 -060071 }
Vince Lehman218be0a2015-01-15 17:25:20 -060072
73 return nullptr;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070074}
75
Teng Lianga4e6ec32018-10-21 09:25:00 -070076Route*
77Rib::findLongestPrefix(const Name& prefix, const Route& route) const
78{
79 Route* existingRoute = find(prefix, route);
80 if (existingRoute == nullptr) {
81 auto parent = findParent(prefix);
82 if (parent) {
83 existingRoute = find(parent->getName(), route);
84 }
85 }
86
87 return existingRoute;
88}
89
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070090void
Vince Lehman218be0a2015-01-15 17:25:20 -060091Rib::insert(const Name& prefix, const Route& route)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070092{
Davide Pesaventoe4b22382018-06-10 14:37:24 -040093 auto ribIt = m_rib.find(prefix);
Vince12e49462014-06-09 13:29:32 -050094
95 // Name prefix exists
Vince Lehman76c751c2014-11-18 17:36:38 -060096 if (ribIt != m_rib.end()) {
97 shared_ptr<RibEntry> entry(ribIt->second);
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -040098 auto [entryIt, didInsert] = entry->insertRoute(route);
Vince12e49462014-06-09 13:29:32 -050099
Nick Gordon89c4cca2016-11-02 15:42:32 +0000100 if (didInsert) {
101 // The route was new and we successfully inserted it.
Vince Lehman76c751c2014-11-18 17:36:38 -0600102 m_nItems++;
Vince12e49462014-06-09 13:29:32 -0500103
Nick Gordon89c4cca2016-11-02 15:42:32 +0000104 afterAddRoute(RibRouteRef{entry, entryIt});
105
Vince12e49462014-06-09 13:29:32 -0500106 // Register with face lookup table
Junxiao Shi17a70012019-06-25 10:50:32 +0000107 m_faceEntries.emplace(route.faceId, entry);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700108 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600109 else {
110 // Route exists, update fields
111 // First cancel old scheduled event, if any, then set the EventId to new one
Davide Pesaventoe1bdc082018-10-11 21:20:23 -0400112 if (entryIt->getExpirationEvent()) {
113 NFD_LOG_TRACE("Cancelling expiration event for " << entry->getName() << " " << *entryIt);
114 entryIt->cancelExpirationEvent();
Vince Lehman76c751c2014-11-18 17:36:38 -0600115 }
116
Junxiao Shid47cd632018-09-11 03:10:00 +0000117 *entryIt = route;
Vince Lehman76c751c2014-11-18 17:36:38 -0600118 }
119 }
120 else {
121 // New name prefix
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400122 auto entry = make_shared<RibEntry>();
Vince Lehman76c751c2014-11-18 17:36:38 -0600123
124 m_rib[prefix] = entry;
125 m_nItems++;
126
127 entry->setName(prefix);
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400128 auto routeIt = entry->insertRoute(route).first;
Vince Lehman76c751c2014-11-18 17:36:38 -0600129
130 // Find prefix's parent
131 shared_ptr<RibEntry> parent = findParent(prefix);
132
133 // Add self to parent's children
134 if (parent != nullptr) {
135 parent->addChild(entry);
136 }
137
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400138 auto children = findDescendants(prefix);
Vince Lehman76c751c2014-11-18 17:36:38 -0600139 for (const auto& child : children) {
140 if (child->getParent() == parent) {
141 // Remove child from parent and inherit parent's child
142 if (parent != nullptr) {
143 parent->removeChild(child);
144 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600145 entry->addChild(child);
146 }
147 }
148
149 // Register with face lookup table
Junxiao Shi17a70012019-06-25 10:50:32 +0000150 m_faceEntries.emplace(route.faceId, entry);
Vince Lehman76c751c2014-11-18 17:36:38 -0600151
152 // do something after inserting an entry
153 afterInsertEntry(prefix);
Nick Gordon89c4cca2016-11-02 15:42:32 +0000154 afterAddRoute(RibRouteRef{entry, routeIt});
Vince Lehman76c751c2014-11-18 17:36:38 -0600155 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700156}
157
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700158void
Vince Lehman218be0a2015-01-15 17:25:20 -0600159Rib::erase(const Name& prefix, const Route& route)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700160{
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400161 auto ribIt = m_rib.find(prefix);
Junxiao Shi17a70012019-06-25 10:50:32 +0000162 if (ribIt == m_rib.end()) {
163 // Name prefix does not exist
164 return;
165 }
Vince12e49462014-06-09 13:29:32 -0500166
Junxiao Shi17a70012019-06-25 10:50:32 +0000167 shared_ptr<RibEntry> entry = ribIt->second;
168 auto routeIt = entry->findRoute(route);
Vince Lehman4387e782014-06-19 16:57:45 -0500169
Junxiao Shi17a70012019-06-25 10:50:32 +0000170 if (routeIt != entry->end()) {
171 beforeRemoveRoute(RibRouteRef{entry, routeIt});
Nick Gordon89c4cca2016-11-02 15:42:32 +0000172
Junxiao Shi17a70012019-06-25 10:50:32 +0000173 auto faceId = route.faceId;
174 entry->eraseRoute(routeIt);
175 m_nItems--;
Vince Lehman4387e782014-06-19 16:57:45 -0500176
Junxiao Shi17a70012019-06-25 10:50:32 +0000177 // If this RibEntry no longer has this faceId, unregister from face lookup table
178 if (!entry->hasFaceId(faceId)) {
179 auto range = m_faceEntries.equal_range(faceId);
180 for (auto it = range.first; it != range.second; ++it) {
181 if (it->second == entry) {
182 m_faceEntries.erase(it);
183 break;
184 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600185 }
Junxiao Shi17a70012019-06-25 10:50:32 +0000186 }
Syed Obaid3313a372014-07-01 01:31:33 -0500187
Junxiao Shi17a70012019-06-25 10:50:32 +0000188 // If a RibEntry's route list is empty, remove it from the tree
189 if (entry->getRoutes().empty()) {
190 eraseEntry(ribIt);
Vince12e49462014-06-09 13:29:32 -0500191 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600192 }
Vince12e49462014-06-09 13:29:32 -0500193}
194
195void
Vince Lehman76c751c2014-11-18 17:36:38 -0600196Rib::onRouteExpiration(const Name& prefix, const Route& route)
Vince12e49462014-06-09 13:29:32 -0500197{
Vince Lehman76c751c2014-11-18 17:36:38 -0600198 NFD_LOG_DEBUG(route << " for " << prefix << " has expired");
Vince12e49462014-06-09 13:29:32 -0500199
Vince Lehman76c751c2014-11-18 17:36:38 -0600200 RibUpdate update;
201 update.setAction(RibUpdate::UNREGISTER)
202 .setName(prefix)
203 .setRoute(route);
Vince12e49462014-06-09 13:29:32 -0500204
Vince Lehman76c751c2014-11-18 17:36:38 -0600205 beginApplyUpdate(update, nullptr, nullptr);
Vince12e49462014-06-09 13:29:32 -0500206}
207
208shared_ptr<RibEntry>
209Rib::findParent(const Name& prefix) const
210{
Vince Lehman76c751c2014-11-18 17:36:38 -0600211 for (int i = prefix.size() - 1; i >= 0; i--) {
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400212 auto it = m_rib.find(prefix.getPrefix(i));
Vince Lehman76c751c2014-11-18 17:36:38 -0600213 if (it != m_rib.end()) {
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400214 return it->second;
Vince12e49462014-06-09 13:29:32 -0500215 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600216 }
Vince12e49462014-06-09 13:29:32 -0500217
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400218 return nullptr;
Vince12e49462014-06-09 13:29:32 -0500219}
220
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400221std::list<shared_ptr<RibEntry>>
Vince12e49462014-06-09 13:29:32 -0500222Rib::findDescendants(const Name& prefix) const
223{
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400224 std::list<shared_ptr<RibEntry>> children;
Vince12e49462014-06-09 13:29:32 -0500225
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400226 auto it = m_rib.find(prefix);
Vince Lehman76c751c2014-11-18 17:36:38 -0600227 if (it != m_rib.end()) {
228 ++it;
229 for (; it != m_rib.end(); ++it) {
230 if (prefix.isPrefixOf(it->first)) {
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400231 children.push_back(it->second);
Vince Lehman76c751c2014-11-18 17:36:38 -0600232 }
233 else {
234 break;
235 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700236 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600237 }
238
239 return children;
240}
241
242std::list<shared_ptr<RibEntry>>
243Rib::findDescendantsForNonInsertedName(const Name& prefix) const
244{
245 std::list<shared_ptr<RibEntry>> children;
246
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400247 for (const auto& [name, ribEntry] : m_rib) {
248 if (prefix.isPrefixOf(name)) {
249 children.push_back(ribEntry);
Vince Lehman76c751c2014-11-18 17:36:38 -0600250 }
251 }
Vince12e49462014-06-09 13:29:32 -0500252
253 return children;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700254}
255
Vince12e49462014-06-09 13:29:32 -0500256Rib::RibTable::iterator
257Rib::eraseEntry(RibTable::iterator it)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700258{
Vince12e49462014-06-09 13:29:32 -0500259 // Entry does not exist
Vince Lehman76c751c2014-11-18 17:36:38 -0600260 if (it == m_rib.end()) {
261 return m_rib.end();
262 }
Vince12e49462014-06-09 13:29:32 -0500263
264 shared_ptr<RibEntry> entry(it->second);
Vince12e49462014-06-09 13:29:32 -0500265 shared_ptr<RibEntry> parent = entry->getParent();
266
267 // Remove self from parent's children
Vince Lehman76c751c2014-11-18 17:36:38 -0600268 if (parent != nullptr) {
269 parent->removeChild(entry);
270 }
271
272 for (auto childIt = entry->getChildren().begin(); childIt != entry->getChildren().end(); ) {
273 shared_ptr<RibEntry> child = *childIt;
274
275 // Advance iterator so it is not invalidated by removal
276 ++childIt;
277
278 // Remove children from self
279 entry->removeChild(child);
280
281 // Update parent's children
282 if (parent != nullptr) {
283 parent->addChild(child);
Vince12e49462014-06-09 13:29:32 -0500284 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600285 }
Vince12e49462014-06-09 13:29:32 -0500286
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400287 auto nextIt = m_rib.erase(it);
Vince12e49462014-06-09 13:29:32 -0500288
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400289 // do something after erasing an entry
Yanbiao Lic17de832014-11-21 17:51:45 -0800290 afterEraseEntry(entry->getName());
291
Vince12e49462014-06-09 13:29:32 -0500292 return nextIt;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700293}
294
Vince Lehman218be0a2015-01-15 17:25:20 -0600295Rib::RouteSet
296Rib::getAncestorRoutes(const RibEntry& entry) const
Vince Lehman4387e782014-06-19 16:57:45 -0500297{
Vince Lehman218be0a2015-01-15 17:25:20 -0600298 RouteSet ancestorRoutes(&sortRoutes);
Vince Lehman4387e782014-06-19 16:57:45 -0500299
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400300 auto parent = entry.getParent();
Vince Lehman76c751c2014-11-18 17:36:38 -0600301 while (parent != nullptr) {
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400302 for (const auto& route : parent->getRoutes()) {
Vince Lehman76c751c2014-11-18 17:36:38 -0600303 if (route.isChildInherit()) {
304 ancestorRoutes.insert(route);
Vince Lehman4387e782014-06-19 16:57:45 -0500305 }
Vince Lehman4387e782014-06-19 16:57:45 -0500306 }
307
Vince Lehman76c751c2014-11-18 17:36:38 -0600308 if (parent->hasCapture()) {
309 break;
Vince Lehman4387e782014-06-19 16:57:45 -0500310 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600311
312 parent = parent->getParent();
313 }
314
315 return ancestorRoutes;
316}
317
318Rib::RouteSet
319Rib::getAncestorRoutes(const Name& name) const
320{
321 RouteSet ancestorRoutes(&sortRoutes);
322
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400323 auto parent = findParent(name);
Vince Lehman76c751c2014-11-18 17:36:38 -0600324 while (parent != nullptr) {
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400325 for (const auto& route : parent->getRoutes()) {
Vince Lehman76c751c2014-11-18 17:36:38 -0600326 if (route.isChildInherit()) {
327 ancestorRoutes.insert(route);
328 }
329 }
330
331 if (parent->hasCapture()) {
332 break;
333 }
334
335 parent = parent->getParent();
336 }
337
338 return ancestorRoutes;
339}
340
341void
342Rib::beginApplyUpdate(const RibUpdate& update,
343 const Rib::UpdateSuccessCallback& onSuccess,
344 const Rib::UpdateFailureCallback& onFailure)
345{
346 BOOST_ASSERT(m_fibUpdater != nullptr);
Vince Lehman76c751c2014-11-18 17:36:38 -0600347 addUpdateToQueue(update, onSuccess, onFailure);
Vince Lehman76c751c2014-11-18 17:36:38 -0600348 sendBatchFromQueue();
349}
350
351void
352Rib::beginRemoveFace(uint64_t faceId)
353{
Junxiao Shi17a70012019-06-25 10:50:32 +0000354 auto range = m_faceEntries.equal_range(faceId);
355 for (auto it = range.first; it != range.second; ++it) {
356 enqueueRemoveFace(*it->second, faceId);
357 }
358 sendBatchFromQueue();
359}
360
361void
362Rib::beginRemoveFailedFaces(const std::set<uint64_t>& activeFaceIds)
363{
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400364 for (const auto& [faceId, ribEntry] : m_faceEntries) {
365 if (activeFaceIds.count(faceId) > 0) {
Junxiao Shi17a70012019-06-25 10:50:32 +0000366 continue;
367 }
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400368 enqueueRemoveFace(*ribEntry, faceId);
Junxiao Shi17a70012019-06-25 10:50:32 +0000369 }
370 sendBatchFromQueue();
371}
372
373void
374Rib::enqueueRemoveFace(const RibEntry& entry, uint64_t faceId)
375{
376 for (const Route& route : entry) {
377 if (route.faceId != faceId) {
378 continue;
379 }
380
Vince Lehman76c751c2014-11-18 17:36:38 -0600381 RibUpdate update;
382 update.setAction(RibUpdate::REMOVE_FACE)
Junxiao Shi17a70012019-06-25 10:50:32 +0000383 .setName(entry.getName())
384 .setRoute(route);
Vince Lehman76c751c2014-11-18 17:36:38 -0600385 addUpdateToQueue(update, nullptr, nullptr);
386 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600387}
388
389void
390Rib::addUpdateToQueue(const RibUpdate& update,
391 const Rib::UpdateSuccessCallback& onSuccess,
392 const Rib::UpdateFailureCallback& onFailure)
393{
394 RibUpdateBatch batch(update.getRoute().faceId);
395 batch.add(update);
396
397 UpdateQueueItem item{batch, onSuccess, onFailure};
398 m_updateBatches.push_back(std::move(item));
399}
400
401void
402Rib::sendBatchFromQueue()
403{
404 if (m_updateBatches.empty() || m_isUpdateInProgress) {
405 return;
406 }
407
408 m_isUpdateInProgress = true;
409
410 UpdateQueueItem item = std::move(m_updateBatches.front());
411 m_updateBatches.pop_front();
412
413 RibUpdateBatch& batch = item.batch;
414
415 // Until task #1698, each RibUpdateBatch contains exactly one RIB update
416 BOOST_ASSERT(batch.size() == 1);
417
Davide Pesavento412c9822021-07-02 00:21:05 -0400418 auto fibSuccessCb = std::bind(&Rib::onFibUpdateSuccess, this, batch, _1, item.managerSuccessCallback);
419 auto fibFailureCb = std::bind(&Rib::onFibUpdateFailure, this, item.managerFailureCallback, _1, _2);
Junxiao Shi52009042018-09-10 12:33:56 +0000420 m_fibUpdater->computeAndSendFibUpdates(batch, fibSuccessCb, fibFailureCb);
Vince Lehman76c751c2014-11-18 17:36:38 -0600421}
422
423void
424Rib::onFibUpdateSuccess(const RibUpdateBatch& batch,
425 const RibUpdateList& inheritedRoutes,
426 const Rib::UpdateSuccessCallback& onSuccess)
427{
428 for (const RibUpdate& update : batch) {
429 switch (update.getAction()) {
430 case RibUpdate::REGISTER:
431 insert(update.getName(), update.getRoute());
432 break;
433 case RibUpdate::UNREGISTER:
434 case RibUpdate::REMOVE_FACE:
435 erase(update.getName(), update.getRoute());
436 break;
437 }
438 }
439
440 // Add and remove precalculated inherited routes to RibEntries
441 modifyInheritedRoutes(inheritedRoutes);
442
443 m_isUpdateInProgress = false;
444
445 if (onSuccess != nullptr) {
446 onSuccess();
447 }
448
449 // Try to advance the batch queue
450 sendBatchFromQueue();
451}
452
453void
454Rib::onFibUpdateFailure(const Rib::UpdateFailureCallback& onFailure,
455 uint32_t code, const std::string& error)
456{
457 m_isUpdateInProgress = false;
458
459 if (onFailure != nullptr) {
460 onFailure(code, error);
461 }
462
463 // Try to advance the batch queue
464 sendBatchFromQueue();
465}
466
467void
468Rib::modifyInheritedRoutes(const RibUpdateList& inheritedRoutes)
469{
470 for (const RibUpdate& update : inheritedRoutes) {
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400471 auto ribIt = m_rib.find(update.getName());
Vince Lehman76c751c2014-11-18 17:36:38 -0600472 BOOST_ASSERT(ribIt != m_rib.end());
473 shared_ptr<RibEntry> entry(ribIt->second);
474
475 switch (update.getAction()) {
476 case RibUpdate::REGISTER:
477 entry->addInheritedRoute(update.getRoute());
478 break;
479 case RibUpdate::UNREGISTER:
480 entry->removeInheritedRoute(update.getRoute());
481 break;
482 case RibUpdate::REMOVE_FACE:
483 break;
484 }
485 }
486}
487
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700488std::ostream&
Vince12e49462014-06-09 13:29:32 -0500489operator<<(std::ostream& os, const Rib& rib)
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700490{
Vince Lehman76c751c2014-11-18 17:36:38 -0600491 for (const auto& item : rib) {
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700492 os << *item.second << "\n";
Vince Lehman76c751c2014-11-18 17:36:38 -0600493 }
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700494
495 return os;
496}
497
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400498} // namespace nfd::rib