blob: 7288c9ac6ed341874adfc868316253260d78aa81 [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 Pesaventoae430302023-05-11 01:42:46 -04003 * Copyright (c) 2014-2023, 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
Vince Lehman4387e782014-06-19 16:57:45 -050034static inline bool
Vince Lehman218be0a2015-01-15 17:25:20 -060035sortRoutes(const Route& lhs, const Route& rhs)
Vince Lehman4387e782014-06-19 16:57:45 -050036{
Vince Lehman218be0a2015-01-15 17:25:20 -060037 return lhs.faceId < rhs.faceId;
Vince Lehman4387e782014-06-19 16:57:45 -050038}
39
Vince Lehman76c751c2014-11-18 17:36:38 -060040void
41Rib::setFibUpdater(FibUpdater* updater)
42{
43 m_fibUpdater = updater;
44}
45
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070046Rib::const_iterator
Vince12e49462014-06-09 13:29:32 -050047Rib::find(const Name& prefix) const
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070048{
Vince12e49462014-06-09 13:29:32 -050049 return m_rib.find(prefix);
50}
51
Vince Lehman218be0a2015-01-15 17:25:20 -060052Route*
53Rib::find(const Name& prefix, const Route& route) const
Vince12e49462014-06-09 13:29:32 -050054{
Davide Pesaventoe4b22382018-06-10 14:37:24 -040055 auto ribIt = m_rib.find(prefix);
Vince12e49462014-06-09 13:29:32 -050056
57 // Name prefix exists
Vince Lehman76c751c2014-11-18 17:36:38 -060058 if (ribIt != m_rib.end()) {
59 shared_ptr<RibEntry> entry = ribIt->second;
Davide Pesaventoe4b22382018-06-10 14:37:24 -040060 auto routeIt = entry->findRoute(route);
Vince Lehman76c751c2014-11-18 17:36:38 -060061 if (routeIt != entry->end()) {
Davide Pesaventoe4b22382018-06-10 14:37:24 -040062 return &*routeIt;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070063 }
Vince Lehman76c751c2014-11-18 17:36:38 -060064 }
Vince Lehman218be0a2015-01-15 17:25:20 -060065
66 return nullptr;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070067}
68
Teng Lianga4e6ec32018-10-21 09:25:00 -070069Route*
70Rib::findLongestPrefix(const Name& prefix, const Route& route) const
71{
72 Route* existingRoute = find(prefix, route);
73 if (existingRoute == nullptr) {
74 auto parent = findParent(prefix);
75 if (parent) {
76 existingRoute = find(parent->getName(), route);
77 }
78 }
79
80 return existingRoute;
81}
82
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070083void
Vince Lehman218be0a2015-01-15 17:25:20 -060084Rib::insert(const Name& prefix, const Route& route)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070085{
Davide Pesaventoe4b22382018-06-10 14:37:24 -040086 auto ribIt = m_rib.find(prefix);
Vince12e49462014-06-09 13:29:32 -050087
88 // Name prefix exists
Vince Lehman76c751c2014-11-18 17:36:38 -060089 if (ribIt != m_rib.end()) {
90 shared_ptr<RibEntry> entry(ribIt->second);
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -040091 auto [entryIt, didInsert] = entry->insertRoute(route);
Vince12e49462014-06-09 13:29:32 -050092
Nick Gordon89c4cca2016-11-02 15:42:32 +000093 if (didInsert) {
94 // The route was new and we successfully inserted it.
Vince Lehman76c751c2014-11-18 17:36:38 -060095 m_nItems++;
Vince12e49462014-06-09 13:29:32 -050096
Nick Gordon89c4cca2016-11-02 15:42:32 +000097 afterAddRoute(RibRouteRef{entry, entryIt});
98
Vince12e49462014-06-09 13:29:32 -050099 // Register with face lookup table
Junxiao Shi17a70012019-06-25 10:50:32 +0000100 m_faceEntries.emplace(route.faceId, entry);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700101 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600102 else {
103 // Route exists, update fields
104 // First cancel old scheduled event, if any, then set the EventId to new one
Davide Pesaventoe1bdc082018-10-11 21:20:23 -0400105 if (entryIt->getExpirationEvent()) {
106 NFD_LOG_TRACE("Cancelling expiration event for " << entry->getName() << " " << *entryIt);
107 entryIt->cancelExpirationEvent();
Vince Lehman76c751c2014-11-18 17:36:38 -0600108 }
109
Junxiao Shid47cd632018-09-11 03:10:00 +0000110 *entryIt = route;
Vince Lehman76c751c2014-11-18 17:36:38 -0600111 }
112 }
113 else {
114 // New name prefix
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400115 auto entry = make_shared<RibEntry>();
Vince Lehman76c751c2014-11-18 17:36:38 -0600116
117 m_rib[prefix] = entry;
118 m_nItems++;
119
120 entry->setName(prefix);
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400121 auto routeIt = entry->insertRoute(route).first;
Vince Lehman76c751c2014-11-18 17:36:38 -0600122
123 // Find prefix's parent
124 shared_ptr<RibEntry> parent = findParent(prefix);
125
126 // Add self to parent's children
127 if (parent != nullptr) {
128 parent->addChild(entry);
129 }
130
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400131 auto children = findDescendants(prefix);
Vince Lehman76c751c2014-11-18 17:36:38 -0600132 for (const auto& child : children) {
133 if (child->getParent() == parent) {
134 // Remove child from parent and inherit parent's child
135 if (parent != nullptr) {
136 parent->removeChild(child);
137 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600138 entry->addChild(child);
139 }
140 }
141
142 // Register with face lookup table
Junxiao Shi17a70012019-06-25 10:50:32 +0000143 m_faceEntries.emplace(route.faceId, entry);
Vince Lehman76c751c2014-11-18 17:36:38 -0600144
145 // do something after inserting an entry
146 afterInsertEntry(prefix);
Nick Gordon89c4cca2016-11-02 15:42:32 +0000147 afterAddRoute(RibRouteRef{entry, routeIt});
Vince Lehman76c751c2014-11-18 17:36:38 -0600148 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700149}
150
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700151void
Vince Lehman218be0a2015-01-15 17:25:20 -0600152Rib::erase(const Name& prefix, const Route& route)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700153{
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400154 auto ribIt = m_rib.find(prefix);
Junxiao Shi17a70012019-06-25 10:50:32 +0000155 if (ribIt == m_rib.end()) {
156 // Name prefix does not exist
157 return;
158 }
Vince12e49462014-06-09 13:29:32 -0500159
Junxiao Shi17a70012019-06-25 10:50:32 +0000160 shared_ptr<RibEntry> entry = ribIt->second;
161 auto routeIt = entry->findRoute(route);
Vince Lehman4387e782014-06-19 16:57:45 -0500162
Junxiao Shi17a70012019-06-25 10:50:32 +0000163 if (routeIt != entry->end()) {
164 beforeRemoveRoute(RibRouteRef{entry, routeIt});
Nick Gordon89c4cca2016-11-02 15:42:32 +0000165
Junxiao Shi17a70012019-06-25 10:50:32 +0000166 auto faceId = route.faceId;
167 entry->eraseRoute(routeIt);
168 m_nItems--;
Vince Lehman4387e782014-06-19 16:57:45 -0500169
Junxiao Shi17a70012019-06-25 10:50:32 +0000170 // If this RibEntry no longer has this faceId, unregister from face lookup table
171 if (!entry->hasFaceId(faceId)) {
172 auto range = m_faceEntries.equal_range(faceId);
173 for (auto it = range.first; it != range.second; ++it) {
174 if (it->second == entry) {
175 m_faceEntries.erase(it);
176 break;
177 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600178 }
Junxiao Shi17a70012019-06-25 10:50:32 +0000179 }
Syed Obaid3313a372014-07-01 01:31:33 -0500180
Junxiao Shi17a70012019-06-25 10:50:32 +0000181 // If a RibEntry's route list is empty, remove it from the tree
182 if (entry->getRoutes().empty()) {
183 eraseEntry(ribIt);
Vince12e49462014-06-09 13:29:32 -0500184 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600185 }
Vince12e49462014-06-09 13:29:32 -0500186}
187
188void
Vince Lehman76c751c2014-11-18 17:36:38 -0600189Rib::onRouteExpiration(const Name& prefix, const Route& route)
Vince12e49462014-06-09 13:29:32 -0500190{
Vince Lehman76c751c2014-11-18 17:36:38 -0600191 NFD_LOG_DEBUG(route << " for " << prefix << " has expired");
Vince12e49462014-06-09 13:29:32 -0500192
Vince Lehman76c751c2014-11-18 17:36:38 -0600193 RibUpdate update;
194 update.setAction(RibUpdate::UNREGISTER)
195 .setName(prefix)
196 .setRoute(route);
Vince12e49462014-06-09 13:29:32 -0500197
Vince Lehman76c751c2014-11-18 17:36:38 -0600198 beginApplyUpdate(update, nullptr, nullptr);
Vince12e49462014-06-09 13:29:32 -0500199}
200
201shared_ptr<RibEntry>
202Rib::findParent(const Name& prefix) const
203{
Vince Lehman76c751c2014-11-18 17:36:38 -0600204 for (int i = prefix.size() - 1; i >= 0; i--) {
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400205 auto it = m_rib.find(prefix.getPrefix(i));
Vince Lehman76c751c2014-11-18 17:36:38 -0600206 if (it != m_rib.end()) {
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400207 return it->second;
Vince12e49462014-06-09 13:29:32 -0500208 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600209 }
Vince12e49462014-06-09 13:29:32 -0500210
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400211 return nullptr;
Vince12e49462014-06-09 13:29:32 -0500212}
213
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400214std::list<shared_ptr<RibEntry>>
Vince12e49462014-06-09 13:29:32 -0500215Rib::findDescendants(const Name& prefix) const
216{
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400217 std::list<shared_ptr<RibEntry>> children;
Vince12e49462014-06-09 13:29:32 -0500218
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400219 auto it = m_rib.find(prefix);
Vince Lehman76c751c2014-11-18 17:36:38 -0600220 if (it != m_rib.end()) {
221 ++it;
222 for (; it != m_rib.end(); ++it) {
223 if (prefix.isPrefixOf(it->first)) {
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400224 children.push_back(it->second);
Vince Lehman76c751c2014-11-18 17:36:38 -0600225 }
226 else {
227 break;
228 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700229 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600230 }
231
232 return children;
233}
234
235std::list<shared_ptr<RibEntry>>
236Rib::findDescendantsForNonInsertedName(const Name& prefix) const
237{
238 std::list<shared_ptr<RibEntry>> children;
239
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400240 for (const auto& [name, ribEntry] : m_rib) {
241 if (prefix.isPrefixOf(name)) {
242 children.push_back(ribEntry);
Vince Lehman76c751c2014-11-18 17:36:38 -0600243 }
244 }
Vince12e49462014-06-09 13:29:32 -0500245
246 return children;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700247}
248
Vince12e49462014-06-09 13:29:32 -0500249Rib::RibTable::iterator
250Rib::eraseEntry(RibTable::iterator it)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700251{
Vince12e49462014-06-09 13:29:32 -0500252 // Entry does not exist
Vince Lehman76c751c2014-11-18 17:36:38 -0600253 if (it == m_rib.end()) {
254 return m_rib.end();
255 }
Vince12e49462014-06-09 13:29:32 -0500256
257 shared_ptr<RibEntry> entry(it->second);
Vince12e49462014-06-09 13:29:32 -0500258 shared_ptr<RibEntry> parent = entry->getParent();
259
260 // Remove self from parent's children
Vince Lehman76c751c2014-11-18 17:36:38 -0600261 if (parent != nullptr) {
262 parent->removeChild(entry);
263 }
264
265 for (auto childIt = entry->getChildren().begin(); childIt != entry->getChildren().end(); ) {
266 shared_ptr<RibEntry> child = *childIt;
267
268 // Advance iterator so it is not invalidated by removal
269 ++childIt;
270
271 // Remove children from self
272 entry->removeChild(child);
273
274 // Update parent's children
275 if (parent != nullptr) {
276 parent->addChild(child);
Vince12e49462014-06-09 13:29:32 -0500277 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600278 }
Vince12e49462014-06-09 13:29:32 -0500279
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400280 auto nextIt = m_rib.erase(it);
Vince12e49462014-06-09 13:29:32 -0500281
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400282 // do something after erasing an entry
Yanbiao Lic17de832014-11-21 17:51:45 -0800283 afterEraseEntry(entry->getName());
284
Vince12e49462014-06-09 13:29:32 -0500285 return nextIt;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700286}
287
Vince Lehman218be0a2015-01-15 17:25:20 -0600288Rib::RouteSet
289Rib::getAncestorRoutes(const RibEntry& entry) const
Vince Lehman4387e782014-06-19 16:57:45 -0500290{
Vince Lehman218be0a2015-01-15 17:25:20 -0600291 RouteSet ancestorRoutes(&sortRoutes);
Vince Lehman4387e782014-06-19 16:57:45 -0500292
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400293 auto parent = entry.getParent();
Vince Lehman76c751c2014-11-18 17:36:38 -0600294 while (parent != nullptr) {
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400295 for (const auto& route : parent->getRoutes()) {
Vince Lehman76c751c2014-11-18 17:36:38 -0600296 if (route.isChildInherit()) {
297 ancestorRoutes.insert(route);
Vince Lehman4387e782014-06-19 16:57:45 -0500298 }
Vince Lehman4387e782014-06-19 16:57:45 -0500299 }
300
Vince Lehman76c751c2014-11-18 17:36:38 -0600301 if (parent->hasCapture()) {
302 break;
Vince Lehman4387e782014-06-19 16:57:45 -0500303 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600304
305 parent = parent->getParent();
306 }
307
308 return ancestorRoutes;
309}
310
311Rib::RouteSet
312Rib::getAncestorRoutes(const Name& name) const
313{
314 RouteSet ancestorRoutes(&sortRoutes);
315
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400316 auto parent = findParent(name);
Vince Lehman76c751c2014-11-18 17:36:38 -0600317 while (parent != nullptr) {
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400318 for (const auto& route : parent->getRoutes()) {
Vince Lehman76c751c2014-11-18 17:36:38 -0600319 if (route.isChildInherit()) {
320 ancestorRoutes.insert(route);
321 }
322 }
323
324 if (parent->hasCapture()) {
325 break;
326 }
327
328 parent = parent->getParent();
329 }
330
331 return ancestorRoutes;
332}
333
334void
335Rib::beginApplyUpdate(const RibUpdate& update,
336 const Rib::UpdateSuccessCallback& onSuccess,
337 const Rib::UpdateFailureCallback& onFailure)
338{
339 BOOST_ASSERT(m_fibUpdater != nullptr);
Vince Lehman76c751c2014-11-18 17:36:38 -0600340 addUpdateToQueue(update, onSuccess, onFailure);
Vince Lehman76c751c2014-11-18 17:36:38 -0600341 sendBatchFromQueue();
342}
343
344void
345Rib::beginRemoveFace(uint64_t faceId)
346{
Junxiao Shi17a70012019-06-25 10:50:32 +0000347 auto range = m_faceEntries.equal_range(faceId);
348 for (auto it = range.first; it != range.second; ++it) {
349 enqueueRemoveFace(*it->second, faceId);
350 }
351 sendBatchFromQueue();
352}
353
354void
355Rib::beginRemoveFailedFaces(const std::set<uint64_t>& activeFaceIds)
356{
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400357 for (const auto& [faceId, ribEntry] : m_faceEntries) {
358 if (activeFaceIds.count(faceId) > 0) {
Junxiao Shi17a70012019-06-25 10:50:32 +0000359 continue;
360 }
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400361 enqueueRemoveFace(*ribEntry, faceId);
Junxiao Shi17a70012019-06-25 10:50:32 +0000362 }
363 sendBatchFromQueue();
364}
365
366void
367Rib::enqueueRemoveFace(const RibEntry& entry, uint64_t faceId)
368{
369 for (const Route& route : entry) {
370 if (route.faceId != faceId) {
371 continue;
372 }
373
Vince Lehman76c751c2014-11-18 17:36:38 -0600374 RibUpdate update;
375 update.setAction(RibUpdate::REMOVE_FACE)
Junxiao Shi17a70012019-06-25 10:50:32 +0000376 .setName(entry.getName())
377 .setRoute(route);
Vince Lehman76c751c2014-11-18 17:36:38 -0600378 addUpdateToQueue(update, nullptr, nullptr);
379 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600380}
381
382void
383Rib::addUpdateToQueue(const RibUpdate& update,
384 const Rib::UpdateSuccessCallback& onSuccess,
385 const Rib::UpdateFailureCallback& onFailure)
386{
387 RibUpdateBatch batch(update.getRoute().faceId);
388 batch.add(update);
389
390 UpdateQueueItem item{batch, onSuccess, onFailure};
391 m_updateBatches.push_back(std::move(item));
392}
393
394void
395Rib::sendBatchFromQueue()
396{
397 if (m_updateBatches.empty() || m_isUpdateInProgress) {
398 return;
399 }
400
401 m_isUpdateInProgress = true;
402
403 UpdateQueueItem item = std::move(m_updateBatches.front());
404 m_updateBatches.pop_front();
405
Vince Lehman76c751c2014-11-18 17:36:38 -0600406 // Until task #1698, each RibUpdateBatch contains exactly one RIB update
Davide Pesaventoae430302023-05-11 01:42:46 -0400407 BOOST_ASSERT(item.batch.size() == 1);
Vince Lehman76c751c2014-11-18 17:36:38 -0600408
Davide Pesaventoae430302023-05-11 01:42:46 -0400409 m_fibUpdater->computeAndSendFibUpdates(item.batch,
410 [this, batch = item.batch, successCb = item.managerSuccessCallback] (const auto& routes) {
411 onFibUpdateSuccess(batch, routes, successCb);
412 },
413 [this, failureCb = item.managerFailureCallback] (const auto& code, const auto& error) {
414 onFibUpdateFailure(failureCb, code, error);
415 });
Vince Lehman76c751c2014-11-18 17:36:38 -0600416}
417
418void
419Rib::onFibUpdateSuccess(const RibUpdateBatch& batch,
420 const RibUpdateList& inheritedRoutes,
421 const Rib::UpdateSuccessCallback& onSuccess)
422{
423 for (const RibUpdate& update : batch) {
424 switch (update.getAction()) {
425 case RibUpdate::REGISTER:
426 insert(update.getName(), update.getRoute());
427 break;
428 case RibUpdate::UNREGISTER:
429 case RibUpdate::REMOVE_FACE:
430 erase(update.getName(), update.getRoute());
431 break;
432 }
433 }
434
435 // Add and remove precalculated inherited routes to RibEntries
436 modifyInheritedRoutes(inheritedRoutes);
437
438 m_isUpdateInProgress = false;
439
440 if (onSuccess != nullptr) {
441 onSuccess();
442 }
443
444 // Try to advance the batch queue
445 sendBatchFromQueue();
446}
447
448void
449Rib::onFibUpdateFailure(const Rib::UpdateFailureCallback& onFailure,
450 uint32_t code, const std::string& error)
451{
452 m_isUpdateInProgress = false;
453
454 if (onFailure != nullptr) {
455 onFailure(code, error);
456 }
457
458 // Try to advance the batch queue
459 sendBatchFromQueue();
460}
461
462void
463Rib::modifyInheritedRoutes(const RibUpdateList& inheritedRoutes)
464{
465 for (const RibUpdate& update : inheritedRoutes) {
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400466 auto ribIt = m_rib.find(update.getName());
Vince Lehman76c751c2014-11-18 17:36:38 -0600467 BOOST_ASSERT(ribIt != m_rib.end());
468 shared_ptr<RibEntry> entry(ribIt->second);
469
470 switch (update.getAction()) {
471 case RibUpdate::REGISTER:
472 entry->addInheritedRoute(update.getRoute());
473 break;
474 case RibUpdate::UNREGISTER:
475 entry->removeInheritedRoute(update.getRoute());
476 break;
477 case RibUpdate::REMOVE_FACE:
478 break;
479 }
480 }
481}
482
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700483std::ostream&
Vince12e49462014-06-09 13:29:32 -0500484operator<<(std::ostream& os, const Rib& rib)
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700485{
Vince Lehman76c751c2014-11-18 17:36:38 -0600486 for (const auto& item : rib) {
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700487 os << *item.second << "\n";
Vince Lehman76c751c2014-11-18 17:36:38 -0600488 }
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700489
490 return os;
491}
492
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400493} // namespace nfd::rib