Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 1 | /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
| 2 | /** |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 3 | * 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 Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 10 | * |
| 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/>. |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 24 | */ |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 25 | |
| 26 | #include "rib.hpp" |
| 27 | |
Vince Lehman | 281ded7 | 2014-08-21 12:17:08 -0500 | [diff] [blame] | 28 | #include "core/logger.hpp" |
| 29 | |
| 30 | NFD_LOG_INIT("Rib"); |
| 31 | |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 32 | namespace nfd { |
| 33 | namespace rib { |
| 34 | |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 35 | static inline bool |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 36 | sortRoutes(const Route& lhs, const Route& rhs) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 37 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 38 | return lhs.faceId < rhs.faceId; |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 39 | } |
| 40 | |
| 41 | static inline bool |
| 42 | isChildInheritFlagSet(uint64_t flags) |
| 43 | { |
| 44 | return flags & ndn::nfd::ROUTE_FLAG_CHILD_INHERIT; |
| 45 | } |
| 46 | |
| 47 | static inline bool |
| 48 | isCaptureFlagSet(uint64_t flags) |
| 49 | { |
| 50 | return flags & ndn::nfd::ROUTE_FLAG_CAPTURE; |
| 51 | } |
| 52 | |
| 53 | static inline bool |
| 54 | isAnyFlagSet(uint64_t flags) |
| 55 | { |
| 56 | return isChildInheritFlagSet(flags) || isCaptureFlagSet(flags); |
| 57 | } |
| 58 | |
| 59 | static inline bool |
| 60 | areBothFlagsSet(uint64_t flags) |
| 61 | { |
| 62 | return isChildInheritFlagSet(flags) && isCaptureFlagSet(flags); |
| 63 | } |
| 64 | |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 65 | Rib::Rib() |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 66 | : m_nItems(0) |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 67 | { |
| 68 | } |
| 69 | |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 70 | Rib::const_iterator |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 71 | Rib::find(const Name& prefix) const |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 72 | { |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 73 | return m_rib.find(prefix); |
| 74 | } |
| 75 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 76 | Route* |
| 77 | Rib::find(const Name& prefix, const Route& route) const |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 78 | { |
| 79 | RibTable::const_iterator ribIt = m_rib.find(prefix); |
| 80 | |
| 81 | // Name prefix exists |
| 82 | if (ribIt != m_rib.end()) |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 83 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 84 | shared_ptr<RibEntry> entry = ribIt->second; |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 85 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 86 | RibEntry::iterator routeIt = entry->findRoute(route); |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 87 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 88 | if (routeIt != entry->end()) |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 89 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 90 | return &((*routeIt)); |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 91 | } |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 92 | } |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 93 | |
| 94 | return nullptr; |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 95 | } |
| 96 | |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 97 | void |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 98 | Rib::insert(const Name& prefix, const Route& route) |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 99 | { |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 100 | RibTable::iterator ribIt = m_rib.find(prefix); |
| 101 | |
| 102 | // Name prefix exists |
| 103 | if (ribIt != m_rib.end()) |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 104 | { |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 105 | shared_ptr<RibEntry> entry(ribIt->second); |
| 106 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 107 | RibEntry::iterator routeIt = entry->findRoute(route); |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 108 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 109 | if (routeIt == entry->end()) |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 110 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 111 | // Will the new route change the namespace's capture flag? |
| 112 | bool captureWasTurnedOn = (entry->hasCapture() == false && isCaptureFlagSet(route.flags)); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 113 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 114 | // New route |
| 115 | entry->insertRoute(route); |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 116 | m_nItems++; |
| 117 | |
| 118 | // Register with face lookup table |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 119 | m_faceMap[route.faceId].push_back(entry); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 120 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 121 | createFibUpdatesForNewRoute(*entry, route, captureWasTurnedOn); |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 122 | } |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 123 | else // Route exists, update fields |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 124 | { |
Syed Obaid | 3313a37 | 2014-07-01 01:31:33 -0500 | [diff] [blame] | 125 | // First cancel old scheduled event, if any, then set the EventId to new one |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 126 | if (static_cast<bool>(routeIt->getExpirationEvent())) |
Vince Lehman | 281ded7 | 2014-08-21 12:17:08 -0500 | [diff] [blame] | 127 | { |
| 128 | NFD_LOG_TRACE("Cancelling expiration event for " << entry->getName() << " " |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 129 | << *routeIt); |
| 130 | scheduler::cancel(routeIt->getExpirationEvent()); |
Vince Lehman | 281ded7 | 2014-08-21 12:17:08 -0500 | [diff] [blame] | 131 | } |
Syed Obaid | 3313a37 | 2014-07-01 01:31:33 -0500 | [diff] [blame] | 132 | |
| 133 | // No checks are required here as the iterator needs to be updated in all cases. |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 134 | routeIt->setExpirationEvent(route.getExpirationEvent()); |
Syed Obaid | 3313a37 | 2014-07-01 01:31:33 -0500 | [diff] [blame] | 135 | |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 136 | // Save flags for update processing |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 137 | uint64_t previousFlags = routeIt->flags; |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 138 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 139 | // If the route's cost didn't change and child inherit is not set, |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 140 | // no need to traverse subtree. |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 141 | uint64_t previousCost = routeIt->cost; |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 142 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 143 | routeIt->flags = route.flags; |
| 144 | routeIt->cost = route.cost; |
| 145 | routeIt->expires = route.expires; |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 146 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 147 | createFibUpdatesForUpdatedRoute(*entry, route, previousFlags, previousCost); |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 148 | } |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 149 | } |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 150 | else // New name prefix |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 151 | { |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 152 | shared_ptr<RibEntry> entry(make_shared<RibEntry>(RibEntry())); |
| 153 | |
| 154 | m_rib[prefix] = entry; |
| 155 | m_nItems++; |
| 156 | |
| 157 | entry->setName(prefix); |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 158 | entry->insertRoute(route); |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 159 | |
| 160 | // Find prefix's parent |
| 161 | shared_ptr<RibEntry> parent = findParent(prefix); |
| 162 | |
| 163 | // Add self to parent's children |
| 164 | if (static_cast<bool>(parent)) |
| 165 | { |
| 166 | parent->addChild(entry); |
| 167 | } |
| 168 | |
| 169 | RibEntryList children = findDescendants(prefix); |
| 170 | |
| 171 | for (std::list<shared_ptr<RibEntry> >::iterator child = children.begin(); |
| 172 | child != children.end(); ++child) |
| 173 | { |
| 174 | if ((*child)->getParent() == parent) |
| 175 | { |
| 176 | // Remove child from parent and inherit parent's child |
| 177 | if (static_cast<bool>(parent)) |
| 178 | { |
| 179 | parent->removeChild((*child)); |
| 180 | } |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 181 | entry->addChild((*child)); |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | // Register with face lookup table |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 186 | m_faceMap[route.faceId].push_back(entry); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 187 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 188 | createFibUpdatesForNewRibEntry(*entry, route); |
Yanbiao Li | c17de83 | 2014-11-21 17:51:45 -0800 | [diff] [blame] | 189 | |
| 190 | // do something after inserting an entry |
| 191 | afterInsertEntry(prefix); |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 192 | } |
| 193 | } |
| 194 | |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 195 | void |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 196 | Rib::erase(const Name& prefix, const Route& route) |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 197 | { |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 198 | RibTable::iterator ribIt = m_rib.find(prefix); |
| 199 | |
| 200 | // Name prefix exists |
| 201 | if (ribIt != m_rib.end()) |
| 202 | { |
| 203 | shared_ptr<RibEntry> entry(ribIt->second); |
| 204 | |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 205 | const bool hadCapture = entry->hasCapture(); |
| 206 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 207 | // Need to copy route to do FIB updates with correct cost and flags since nfdc does not |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 208 | // pass flags or cost |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 209 | RibEntry::iterator routeIt = entry->findRoute(route); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 210 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 211 | if (routeIt != entry->end()) |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 212 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 213 | Route routeToErase = *routeIt; |
| 214 | routeToErase.flags = routeIt->flags; |
| 215 | routeToErase.cost = routeIt->cost; |
Syed Obaid | 3313a37 | 2014-07-01 01:31:33 -0500 | [diff] [blame] | 216 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 217 | entry->eraseRoute(routeIt); |
Vince Lehman | 281ded7 | 2014-08-21 12:17:08 -0500 | [diff] [blame] | 218 | |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 219 | m_nItems--; |
| 220 | |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 221 | const bool captureWasTurnedOff = (hadCapture && !entry->hasCapture()); |
| 222 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 223 | createFibUpdatesForErasedRoute(*entry, routeToErase, captureWasTurnedOff); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 224 | |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 225 | // If this RibEntry no longer has this faceId, unregister from face lookup table |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 226 | if (!entry->hasFaceId(route.faceId)) |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 227 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 228 | m_faceMap[route.faceId].remove(entry); |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 229 | } |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 230 | else |
| 231 | { |
| 232 | // The RibEntry still has the face ID; need to update FIB |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 233 | // with lowest cost for the same route instead of removing the route from the FIB |
| 234 | shared_ptr<Route> lowCostRoute = entry->getRouteWithLowestCostByFaceId(route.faceId); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 235 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 236 | BOOST_ASSERT(static_cast<bool>(lowCostRoute)); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 237 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 238 | createFibUpdatesForNewRoute(*entry, *lowCostRoute, false); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 239 | } |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 240 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 241 | // If a RibEntry's route list is empty, remove it from the tree |
| 242 | if (entry->getRoutes().size() == 0) |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 243 | { |
| 244 | eraseEntry(ribIt); |
| 245 | } |
| 246 | } |
| 247 | } |
| 248 | } |
| 249 | |
| 250 | void |
| 251 | Rib::erase(const uint64_t faceId) |
| 252 | { |
| 253 | FaceLookupTable::iterator lookupIt = m_faceMap.find(faceId); |
| 254 | |
| 255 | // No RIB entries have this face |
| 256 | if (lookupIt == m_faceMap.end()) |
| 257 | { |
| 258 | return; |
| 259 | } |
| 260 | |
| 261 | RibEntryList& ribEntries = lookupIt->second; |
| 262 | |
| 263 | // For each RIB entry that has faceId, remove the face from the entry |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 264 | for (shared_ptr<RibEntry>& entry : ribEntries) |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 265 | { |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 266 | const bool hadCapture = entry->hasCapture(); |
| 267 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 268 | // Find the routes in the entry |
| 269 | for (RibEntry::iterator routeIt = entry->begin(); routeIt != entry->end(); ++routeIt) |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 270 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 271 | if (routeIt->faceId == faceId) |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 272 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 273 | Route copy = *routeIt; |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 274 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 275 | routeIt = entry->eraseRoute(routeIt); |
Vince Lehman | 26b215c | 2014-08-17 15:00:41 -0500 | [diff] [blame] | 276 | m_nItems--; |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 277 | |
| 278 | const bool captureWasTurnedOff = (hadCapture && !entry->hasCapture()); |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 279 | createFibUpdatesForErasedRoute(*entry, copy, captureWasTurnedOff); |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 280 | } |
| 281 | } |
| 282 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 283 | // If a RibEntry's route list is empty, remove it from the tree |
| 284 | if (entry->getRoutes().size() == 0) |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 285 | { |
| 286 | eraseEntry(m_rib.find(entry->getName())); |
| 287 | } |
| 288 | } |
| 289 | |
| 290 | // Face no longer exists, remove from face lookup table |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 291 | m_faceMap.erase(lookupIt); |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 292 | } |
| 293 | |
| 294 | shared_ptr<RibEntry> |
| 295 | Rib::findParent(const Name& prefix) const |
| 296 | { |
| 297 | for (int i = prefix.size() - 1; i >= 0; i--) |
| 298 | { |
| 299 | RibTable::const_iterator it = m_rib.find(prefix.getPrefix(i)); |
| 300 | if (it != m_rib.end()) |
| 301 | { |
| 302 | return (it->second); |
| 303 | } |
| 304 | } |
| 305 | |
| 306 | return shared_ptr<RibEntry>(); |
| 307 | } |
| 308 | |
| 309 | std::list<shared_ptr<RibEntry> > |
| 310 | Rib::findDescendants(const Name& prefix) const |
| 311 | { |
| 312 | std::list<shared_ptr<RibEntry> > children; |
| 313 | |
| 314 | RibTable::const_iterator it = m_rib.find(prefix); |
| 315 | |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 316 | if (it != m_rib.end()) |
| 317 | { |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 318 | ++it; |
| 319 | for (; it != m_rib.end(); ++it) |
| 320 | { |
| 321 | if (prefix.isPrefixOf(it->first)) |
| 322 | { |
| 323 | children.push_back((it->second)); |
| 324 | } |
| 325 | else |
| 326 | { |
| 327 | break; |
| 328 | } |
| 329 | } |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 330 | } |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 331 | |
| 332 | return children; |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 333 | } |
| 334 | |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 335 | Rib::RibTable::iterator |
| 336 | Rib::eraseEntry(RibTable::iterator it) |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 337 | { |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 338 | // Entry does not exist |
| 339 | if (it == m_rib.end()) |
| 340 | { |
| 341 | return m_rib.end(); |
| 342 | } |
| 343 | |
| 344 | shared_ptr<RibEntry> entry(it->second); |
| 345 | |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 346 | // Remove inherited routes from namespace |
| 347 | createFibUpdatesForErasedRibEntry(*entry); |
| 348 | |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 349 | shared_ptr<RibEntry> parent = entry->getParent(); |
| 350 | |
| 351 | // Remove self from parent's children |
| 352 | if (static_cast<bool>(parent)) |
| 353 | { |
| 354 | parent->removeChild(entry); |
| 355 | } |
| 356 | |
| 357 | std::list<shared_ptr<RibEntry> > children = entry->getChildren(); |
| 358 | |
| 359 | for (RibEntryList::iterator child = children.begin(); child != children.end(); ++child) |
| 360 | { |
| 361 | // Remove children from self |
| 362 | entry->removeChild(*child); |
| 363 | |
| 364 | // Update parent's children |
| 365 | if (static_cast<bool>(parent)) |
| 366 | { |
| 367 | parent->addChild(*child); |
| 368 | } |
| 369 | } |
| 370 | |
| 371 | // Must save and advance iterator to return a valid iterator |
| 372 | RibTable::iterator nextIt = it; |
| 373 | nextIt++; |
| 374 | |
| 375 | m_rib.erase(it); |
| 376 | |
Yanbiao Li | c17de83 | 2014-11-21 17:51:45 -0800 | [diff] [blame] | 377 | // do something after erasing an entry. |
| 378 | afterEraseEntry(entry->getName()); |
| 379 | |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 380 | return nextIt; |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 381 | } |
| 382 | |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 383 | bool |
| 384 | compareFibUpdates(const shared_ptr<const FibUpdate> lhs, const shared_ptr<const FibUpdate> rhs) |
| 385 | { |
| 386 | return ((lhs->name == rhs->name) && |
| 387 | (lhs->faceId == rhs->faceId)); |
| 388 | } |
| 389 | |
| 390 | void |
| 391 | Rib::insertFibUpdate(shared_ptr<FibUpdate> update) |
| 392 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 393 | // If an update with the same name and Face ID already exists, replace it |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 394 | FibUpdateList::iterator it = std::find_if(m_fibUpdateList.begin(), m_fibUpdateList.end(), |
| 395 | bind(&compareFibUpdates, _1, update)); |
| 396 | |
| 397 | if (it != m_fibUpdateList.end()) |
| 398 | { |
| 399 | // Get rid of the const to alter the action, prevents copying or removal and |
| 400 | // insertion |
| 401 | FibUpdate& entry = const_cast<FibUpdate&>(*(*it)); |
| 402 | entry.action = update->action; |
| 403 | entry.cost = update->cost; |
| 404 | } |
| 405 | else |
| 406 | { |
| 407 | m_fibUpdateList.push_back(update); |
| 408 | } |
| 409 | } |
| 410 | |
| 411 | void |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 412 | Rib::createFibUpdatesForNewRibEntry(RibEntry& entry, const Route& route) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 413 | { |
| 414 | // Create FIB update for new entry |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 415 | insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), route.faceId, route.cost)); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 416 | |
| 417 | // No flags are set |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 418 | if (!isAnyFlagSet(route.flags)) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 419 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 420 | // Add ancestor routes to self |
| 421 | addInheritedRoutesToEntry(entry, getAncestorRoutes(entry)); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 422 | } |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 423 | else if (areBothFlagsSet(route.flags)) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 424 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 425 | // Add route to children |
| 426 | RouteSet routesToAdd; |
| 427 | routesToAdd.insert(route); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 428 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 429 | // Remove routes blocked by capture and add self to children |
| 430 | modifyChildrensInheritedRoutes(entry, routesToAdd, getAncestorRoutes(entry)); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 431 | } |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 432 | else if (isChildInheritFlagSet(route.flags)) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 433 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 434 | RouteSet ancestorRoutes = getAncestorRoutes(entry); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 435 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 436 | // Add ancestor routes to self |
| 437 | addInheritedRoutesToEntry(entry, ancestorRoutes); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 438 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 439 | // If there is an ancestor route with the same Face ID as the new route, replace it |
| 440 | // with the new route |
| 441 | RouteSet::iterator it = ancestorRoutes.find(route); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 442 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 443 | // There is a route that needs to be overwritten, erase and then replace |
| 444 | if (it != ancestorRoutes.end()) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 445 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 446 | ancestorRoutes.erase(it); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 447 | } |
| 448 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 449 | // Add new route to ancestor list so it can be added to children |
| 450 | ancestorRoutes.insert(route); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 451 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 452 | // Add ancestor routes to children |
| 453 | modifyChildrensInheritedRoutes(entry, ancestorRoutes, RouteSet()); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 454 | } |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 455 | else if (isCaptureFlagSet(route.flags)) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 456 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 457 | // Remove routes blocked by capture |
| 458 | modifyChildrensInheritedRoutes(entry, RouteSet(), getAncestorRoutes(entry)); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 459 | } |
| 460 | } |
| 461 | |
| 462 | void |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 463 | Rib::createFibUpdatesForNewRoute(RibEntry& entry, const Route& route, bool captureWasTurnedOn) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 464 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 465 | // Only update if the new route has a lower cost than a previously installed route |
| 466 | shared_ptr<Route> prevRoute = entry.getRouteWithLowestCostAndChildInheritByFaceId(route.faceId); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 467 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 468 | RouteSet routesToAdd; |
| 469 | if (isChildInheritFlagSet(route.flags)) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 470 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 471 | // Add to children if this new route doesn't override a previous lower cost, or |
| 472 | // add to children if this new route is lower cost than a previous route. |
| 473 | // Less than equal, since entry may find this route |
| 474 | if (prevRoute == nullptr || route.cost <= prevRoute->cost) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 475 | { |
| 476 | // Add self to children |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 477 | routesToAdd.insert(route); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 478 | } |
| 479 | } |
| 480 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 481 | RouteSet routesToRemove; |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 482 | if (captureWasTurnedOn) |
| 483 | { |
| 484 | // Capture flag on |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 485 | routesToRemove = getAncestorRoutes(entry); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 486 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 487 | // Remove ancestor routes from self |
| 488 | removeInheritedRoutesFromEntry(entry, routesToRemove); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 489 | } |
| 490 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 491 | modifyChildrensInheritedRoutes(entry, routesToAdd, routesToRemove); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 492 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 493 | // If another route with same faceId and lower cost, don't update. |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 494 | // Must be done last so that add updates replace removal updates |
| 495 | // Create FIB update for new entry |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 496 | if (route.cost <= entry.getRouteWithLowestCostByFaceId(route.faceId)->cost) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 497 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 498 | insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), route.faceId, route.cost)); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 499 | } |
| 500 | } |
| 501 | |
| 502 | void |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 503 | Rib::createFibUpdatesForUpdatedRoute(RibEntry& entry, const Route& route, |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 504 | const uint64_t previousFlags, const uint64_t previousCost) |
| 505 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 506 | const bool costDidChange = (route.cost != previousCost); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 507 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 508 | // Look for the installed route with the lowest cost and child inherit set |
| 509 | shared_ptr<Route> prevRoute = entry.getRouteWithLowestCostAndChildInheritByFaceId(route.faceId); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 510 | |
| 511 | // No flags changed and cost didn't change, no change in FIB |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 512 | if (route.flags == previousFlags && !costDidChange) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 513 | { |
| 514 | return; |
| 515 | } |
| 516 | |
| 517 | // Cost changed so create update for the entry itself |
| 518 | if (costDidChange) |
| 519 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 520 | // Create update if this route's cost is lower than other routes |
| 521 | if (route.cost <= entry.getRouteWithLowestCostByFaceId(route.faceId)->cost) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 522 | { |
| 523 | // Create FIB update for the updated entry |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 524 | insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), route.faceId, route.cost)); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 525 | } |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 526 | else if (previousCost < entry.getRouteWithLowestCostByFaceId(route.faceId)->cost) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 527 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 528 | // Create update if this route used to be the lowest cost route but is no longer |
| 529 | // the lowest cost route. |
| 530 | insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), prevRoute->faceId, |
| 531 | prevRoute->cost)); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 532 | } |
| 533 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 534 | // If another route with same faceId and lower cost and ChildInherit exists, |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 535 | // don't update children. |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 536 | if (prevRoute == nullptr || route.cost <= prevRoute->cost) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 537 | { |
| 538 | // If no flags changed but child inheritance is set, need to update children |
| 539 | // with new cost |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 540 | if ((route.flags == previousFlags) && isChildInheritFlagSet(route.flags)) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 541 | { |
| 542 | // Add self to children |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 543 | RouteSet routesToAdd; |
| 544 | routesToAdd.insert(route); |
| 545 | modifyChildrensInheritedRoutes(entry, routesToAdd, RouteSet()); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 546 | |
| 547 | return; |
| 548 | } |
| 549 | } |
| 550 | } |
| 551 | |
| 552 | // Child inherit was turned on |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 553 | if (!isChildInheritFlagSet(previousFlags) && isChildInheritFlagSet(route.flags)) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 554 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 555 | // If another route with same faceId and lower cost and ChildInherit exists, |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 556 | // don't update children. |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 557 | if (prevRoute == nullptr || route.cost <= prevRoute->cost) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 558 | { |
| 559 | // Add self to children |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 560 | RouteSet routesToAdd; |
| 561 | routesToAdd.insert(route); |
| 562 | modifyChildrensInheritedRoutes(entry, routesToAdd, RouteSet()); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 563 | } |
| 564 | |
| 565 | } // Child inherit was turned off |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 566 | else if (isChildInheritFlagSet(previousFlags) && !isChildInheritFlagSet(route.flags)) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 567 | { |
| 568 | // Remove self from children |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 569 | RouteSet routesToRemove; |
| 570 | routesToRemove.insert(route); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 571 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 572 | RouteSet routesToAdd; |
| 573 | // If another route with same faceId and ChildInherit exists, update children with this route. |
| 574 | if (prevRoute != nullptr) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 575 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 576 | routesToAdd.insert(*prevRoute); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 577 | } |
| 578 | else |
| 579 | { |
| 580 | // Look for an ancestor that was blocked previously |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 581 | const RouteSet ancestorRoutes = getAncestorRoutes(entry); |
| 582 | RouteSet::iterator it = ancestorRoutes.find(route); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 583 | |
| 584 | // If an ancestor is found, add it to children |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 585 | if (it != ancestorRoutes.end()) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 586 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 587 | routesToAdd.insert(*it); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 588 | } |
| 589 | } |
| 590 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 591 | modifyChildrensInheritedRoutes(entry, routesToAdd, routesToRemove); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 592 | } |
| 593 | |
| 594 | // Capture was turned on |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 595 | if (!isCaptureFlagSet(previousFlags) && isCaptureFlagSet(route.flags)) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 596 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 597 | RouteSet ancestorRoutes = getAncestorRoutes(entry); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 598 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 599 | // Remove ancestor routes from self |
| 600 | removeInheritedRoutesFromEntry(entry, ancestorRoutes); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 601 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 602 | // Remove ancestor routes from children |
| 603 | modifyChildrensInheritedRoutes(entry, RouteSet(), ancestorRoutes); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 604 | } // Capture was turned off |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 605 | else if (isCaptureFlagSet(previousFlags) && !isCaptureFlagSet(route.flags)) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 606 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 607 | RouteSet ancestorRoutes = getAncestorRoutes(entry); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 608 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 609 | // Add ancestor routes to self |
| 610 | addInheritedRoutesToEntry(entry, ancestorRoutes); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 611 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 612 | // Add ancestor routes to children |
| 613 | modifyChildrensInheritedRoutes(entry, ancestorRoutes, RouteSet()); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 614 | } |
| 615 | } |
| 616 | |
| 617 | void |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 618 | Rib::createFibUpdatesForErasedRoute(RibEntry& entry, const Route& route, |
| 619 | const bool captureWasTurnedOff) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 620 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 621 | insertFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), route.faceId)); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 622 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 623 | if (areBothFlagsSet(route.flags)) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 624 | { |
| 625 | // Remove self from children |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 626 | RouteSet routesToRemove; |
| 627 | routesToRemove.insert(route); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 628 | |
| 629 | // If capture is turned off for the route, need to add ancestors |
| 630 | // to self and children |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 631 | RouteSet routesToAdd; |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 632 | if (captureWasTurnedOff) |
| 633 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 634 | // Look for ancestors that were blocked previously |
| 635 | routesToAdd = getAncestorRoutes(entry); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 636 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 637 | // Add ancestor routes to self |
| 638 | addInheritedRoutesToEntry(entry, routesToAdd); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 639 | } |
| 640 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 641 | modifyChildrensInheritedRoutes(entry, routesToAdd, routesToRemove); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 642 | } |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 643 | else if (isChildInheritFlagSet(route.flags)) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 644 | { |
| 645 | // If not blocked by capture, add inherited routes to children |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 646 | RouteSet routesToAdd; |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 647 | if (!entry.hasCapture()) |
| 648 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 649 | routesToAdd = getAncestorRoutes(entry); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 650 | } |
| 651 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 652 | RouteSet routesToRemove; |
| 653 | routesToRemove.insert(route); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 654 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 655 | // Add ancestor routes to children |
| 656 | modifyChildrensInheritedRoutes(entry, routesToAdd, routesToRemove); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 657 | } |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 658 | else if (isCaptureFlagSet(route.flags)) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 659 | { |
| 660 | // If capture is turned off for the route, need to add ancestors |
| 661 | // to self and children |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 662 | RouteSet routesToAdd; |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 663 | if (captureWasTurnedOff) |
| 664 | { |
| 665 | // Look for an ancestors that were blocked previously |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 666 | routesToAdd = getAncestorRoutes(entry); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 667 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 668 | // Add ancestor routes to self |
| 669 | addInheritedRoutesToEntry(entry, routesToAdd); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 670 | } |
| 671 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 672 | modifyChildrensInheritedRoutes(entry, routesToAdd, RouteSet()); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 673 | } |
| 674 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 675 | // Need to check if the removed route was blocking an inherited route |
| 676 | RouteSet ancestorRoutes = getAncestorRoutes(entry); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 677 | |
| 678 | if (!entry.hasCapture()) |
| 679 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 680 | // If there is an ancestor route with the same Face ID as the erased route, add that route |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 681 | // to the current entry |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 682 | RouteSet::iterator it = ancestorRoutes.find(route); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 683 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 684 | if (it != ancestorRoutes.end()) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 685 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 686 | entry.addInheritedRoute(*it); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 687 | insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), it->faceId, it->cost)); |
| 688 | } |
| 689 | } |
| 690 | } |
| 691 | |
| 692 | void |
| 693 | Rib::createFibUpdatesForErasedRibEntry(RibEntry& entry) |
| 694 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 695 | for (RibEntry::RouteList::iterator it = entry.getInheritedRoutes().begin(); |
| 696 | it != entry.getInheritedRoutes().end(); ++it) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 697 | { |
| 698 | insertFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), it->faceId)); |
| 699 | } |
| 700 | } |
| 701 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 702 | Rib::RouteSet |
| 703 | Rib::getAncestorRoutes(const RibEntry& entry) const |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 704 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 705 | RouteSet ancestorRoutes(&sortRoutes); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 706 | |
| 707 | shared_ptr<RibEntry> parent = entry.getParent(); |
| 708 | |
| 709 | while (static_cast<bool>(parent)) |
| 710 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 711 | for (RibEntry::iterator it = parent->getRoutes().begin(); |
| 712 | it != parent->getRoutes().end(); ++it) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 713 | { |
| 714 | if (isChildInheritFlagSet(it->flags)) |
| 715 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 716 | ancestorRoutes.insert(*it); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 717 | } |
| 718 | } |
| 719 | |
| 720 | if (parent->hasCapture()) |
| 721 | { |
| 722 | break; |
| 723 | } |
| 724 | |
| 725 | parent = parent->getParent(); |
| 726 | } |
| 727 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 728 | return ancestorRoutes; |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 729 | } |
| 730 | |
| 731 | void |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 732 | Rib::addInheritedRoutesToEntry(RibEntry& entry, const Rib::RouteSet& routesToAdd) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 733 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 734 | for (RouteSet::const_iterator it = routesToAdd.begin(); it != routesToAdd.end(); ++it) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 735 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 736 | // Don't add an ancestor route if the namespace has a route with that Face ID |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 737 | if (!entry.hasFaceId(it->faceId)) |
| 738 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 739 | entry.addInheritedRoute(*it); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 740 | insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), it->faceId, it->cost)); |
| 741 | } |
| 742 | } |
| 743 | } |
| 744 | |
| 745 | void |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 746 | Rib::removeInheritedRoutesFromEntry(RibEntry& entry, const Rib::RouteSet& routesToRemove) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 747 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 748 | for (RouteSet::const_iterator it = routesToRemove.begin(); it != routesToRemove.end(); ++it) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 749 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 750 | // Only remove if the route has been inherited |
| 751 | if (entry.hasInheritedRoute(*it)) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 752 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 753 | entry.removeInheritedRoute(*it); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 754 | insertFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), it->faceId)); |
| 755 | } |
| 756 | } |
| 757 | } |
| 758 | |
| 759 | void |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 760 | Rib::modifyChildrensInheritedRoutes(RibEntry& entry, const Rib::RouteSet& routesToAdd, |
| 761 | const Rib::RouteSet& routesToRemove) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 762 | { |
| 763 | RibEntryList children = entry.getChildren(); |
| 764 | |
| 765 | for (RibEntryList::iterator child = children.begin(); child != children.end(); ++child) |
| 766 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 767 | traverseSubTree(*(*child), routesToAdd, routesToRemove); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 768 | } |
| 769 | } |
| 770 | |
| 771 | void |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 772 | Rib::traverseSubTree(RibEntry& entry, Rib::RouteSet routesToAdd, Rib::RouteSet routesToRemove) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 773 | { |
| 774 | // If a route on the namespace has the capture flag set, ignore self and children |
| 775 | if (entry.hasCapture()) |
| 776 | { |
| 777 | return; |
| 778 | } |
| 779 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 780 | // Remove inherited routes from current namespace |
| 781 | for (Rib::RouteSet::const_iterator removeIt = routesToRemove.begin(); |
| 782 | removeIt != routesToRemove.end(); ) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 783 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 784 | // If a route on the namespace has the same face and child inheritance set, ignore this route |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 785 | if (entry.hasChildInheritOnFaceId(removeIt->faceId)) |
| 786 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 787 | routesToRemove.erase(removeIt++); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 788 | continue; |
| 789 | } |
| 790 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 791 | // Only remove route if it removes an existing inherited route |
| 792 | if (entry.hasInheritedRoute(*removeIt)) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 793 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 794 | entry.removeInheritedRoute(*removeIt); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 795 | insertFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), removeIt->faceId)); |
| 796 | } |
| 797 | |
| 798 | ++removeIt; |
| 799 | } |
| 800 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 801 | // Add inherited routes to current namespace |
| 802 | for (Rib::RouteSet::const_iterator addIt = routesToAdd.begin(); addIt != routesToAdd.end(); ) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 803 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 804 | // If a route on the namespace has the same face and child inherit set, ignore this route |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 805 | if (entry.hasChildInheritOnFaceId(addIt->faceId)) |
| 806 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 807 | routesToAdd.erase(addIt++); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 808 | continue; |
| 809 | } |
| 810 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 811 | // Only add route if it does not override an existing route |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 812 | if (!entry.hasFaceId(addIt->faceId)) |
| 813 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 814 | RibEntry::RouteList::iterator routeIt = entry.findInheritedRoute(*addIt); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 815 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 816 | // If the entry already has the inherited route, just update the route |
| 817 | if (routeIt != entry.getInheritedRoutes().end()) |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 818 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 819 | routeIt->cost = addIt->cost; |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 820 | } |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 821 | else // Otherwise, this is a newly inherited route |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 822 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 823 | entry.addInheritedRoute(*addIt); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 824 | } |
| 825 | |
| 826 | insertFibUpdate(FibUpdate::createAddUpdate(entry.getName(), addIt->faceId, addIt->cost)); |
| 827 | } |
| 828 | |
| 829 | ++addIt; |
| 830 | } |
| 831 | |
| 832 | Rib::RibEntryList children = entry.getChildren(); |
| 833 | |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 834 | // Apply route operations to current namespace's children |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 835 | for (Rib::RibEntryList::iterator child = children.begin(); child != children.end(); ++child) |
| 836 | { |
Vince Lehman | 218be0a | 2015-01-15 17:25:20 -0600 | [diff] [blame] | 837 | traverseSubTree(*(*child), routesToAdd, routesToRemove); |
Vince Lehman | 4387e78 | 2014-06-19 16:57:45 -0500 | [diff] [blame] | 838 | } |
| 839 | } |
| 840 | |
Alexander Afanasyev | 20d3144 | 2014-04-19 17:00:53 -0700 | [diff] [blame] | 841 | std::ostream& |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 842 | operator<<(std::ostream& os, const Rib& rib) |
Alexander Afanasyev | 20d3144 | 2014-04-19 17:00:53 -0700 | [diff] [blame] | 843 | { |
Vince | 12e4946 | 2014-06-09 13:29:32 -0500 | [diff] [blame] | 844 | for (Rib::RibTable::const_iterator it = rib.begin(); it != rib.end(); ++it) |
| 845 | { |
| 846 | os << *(it->second) << "\n"; |
| 847 | } |
Alexander Afanasyev | 20d3144 | 2014-04-19 17:00:53 -0700 | [diff] [blame] | 848 | |
| 849 | return os; |
| 850 | } |
| 851 | |
Alexander Afanasyev | 3ecec50 | 2014-04-16 13:42:44 -0700 | [diff] [blame] | 852 | } // namespace rib |
| 853 | } // namespace nfd |