blob: 7d4cff8c5eaca410d537e23b0ecd61b3439d54a3 [file] [log] [blame]
Vince12e49462014-06-09 13:29:32 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Vince Lehman4310d502016-03-04 11:58:59 -06003 * Copyright (c) 2014-2016, 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.
Vince12e49462014-06-09 13:29:32 -050010 *
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/>.
24 */
25
26#include "rib-entry.hpp"
27
Vince Lehman281ded72014-08-21 12:17:08 -050028#include "core/logger.hpp"
29
Junxiao Shi25c6ce42016-09-09 13:49:59 +000030#include <ndn-cxx/mgmt/nfd/control-command.hpp>
Vince12e49462014-06-09 13:29:32 -050031
Vince Lehman281ded72014-08-21 12:17:08 -050032NFD_LOG_INIT("RibEntry");
33
Vince12e49462014-06-09 13:29:32 -050034namespace nfd {
35namespace rib {
36
Vince Lehman218be0a2015-01-15 17:25:20 -060037RibEntry::RouteList::iterator
38RibEntry::findRoute(const Route& route)
Vince12e49462014-06-09 13:29:32 -050039{
Vince Lehman218be0a2015-01-15 17:25:20 -060040 return std::find_if(begin(), end(), bind(&compareFaceIdAndOrigin, _1, route));
Vince12e49462014-06-09 13:29:32 -050041}
42
Vince Lehman76c751c2014-11-18 17:36:38 -060043RibEntry::RouteList::const_iterator
44RibEntry::findRoute(const Route& route) const
45{
46 return std::find_if(begin(), end(), bind(&compareFaceIdAndOrigin, _1, route));
47}
48
Vince12e49462014-06-09 13:29:32 -050049bool
Vince Lehman218be0a2015-01-15 17:25:20 -060050RibEntry::insertRoute(const Route& route)
Vince12e49462014-06-09 13:29:32 -050051{
Vince Lehman218be0a2015-01-15 17:25:20 -060052 iterator it = findRoute(route);
Vince12e49462014-06-09 13:29:32 -050053
Vince Lehman76c751c2014-11-18 17:36:38 -060054 if (it == end()) {
55 if (route.flags & ndn::nfd::ROUTE_FLAG_CAPTURE) {
56 m_nRoutesWithCaptureSet++;
57 }
Vince Lehman4387e782014-06-19 16:57:45 -050058
Vince Lehman76c751c2014-11-18 17:36:38 -060059 m_routes.push_back(route);
60
61 return true;
62 }
63 else {
64 return false;
65 }
Vince12e49462014-06-09 13:29:32 -050066}
67
Vince Lehman281ded72014-08-21 12:17:08 -050068void
Vince Lehman218be0a2015-01-15 17:25:20 -060069RibEntry::eraseRoute(const Route& route)
Vince12e49462014-06-09 13:29:32 -050070{
Vince Lehman218be0a2015-01-15 17:25:20 -060071 RibEntry::iterator it = findRoute(route);
72 eraseRoute(it);
Vince12e49462014-06-09 13:29:32 -050073}
74
75bool
Vince Lehman218be0a2015-01-15 17:25:20 -060076RibEntry::hasRoute(const Route& route)
Vince Lehman4387e782014-06-19 16:57:45 -050077{
Vince Lehman218be0a2015-01-15 17:25:20 -060078 RibEntry::const_iterator it = findRoute(route);
Vince Lehman4387e782014-06-19 16:57:45 -050079
Vince Lehman218be0a2015-01-15 17:25:20 -060080 return it != end();
Vince Lehman4387e782014-06-19 16:57:45 -050081}
82
83bool
Vince12e49462014-06-09 13:29:32 -050084RibEntry::hasFaceId(const uint64_t faceId) const
85{
Vince Lehman218be0a2015-01-15 17:25:20 -060086 RibEntry::const_iterator it = std::find_if(begin(), end(), bind(&compareFaceId, _1, faceId));
Vince12e49462014-06-09 13:29:32 -050087
Vince Lehman218be0a2015-01-15 17:25:20 -060088 return it != end();
Vince12e49462014-06-09 13:29:32 -050089}
90
Vince Lehman76c751c2014-11-18 17:36:38 -060091size_t
92RibEntry::getNRoutes() const
93{
94 return m_routes.size();
95}
96
Vince12e49462014-06-09 13:29:32 -050097void
98RibEntry::addChild(shared_ptr<RibEntry> child)
99{
100 BOOST_ASSERT(!static_cast<bool>(child->getParent()));
101 child->setParent(this->shared_from_this());
102 m_children.push_back(child);
103}
104
105void
106RibEntry::removeChild(shared_ptr<RibEntry> child)
107{
108 BOOST_ASSERT(child->getParent().get() == this);
109 child->setParent(shared_ptr<RibEntry>());
110 m_children.remove(child);
111}
112
Vince Lehman218be0a2015-01-15 17:25:20 -0600113RibEntry::RouteList::iterator
114RibEntry::eraseRoute(RouteList::iterator route)
Vince12e49462014-06-09 13:29:32 -0500115{
Vince Lehman76c751c2014-11-18 17:36:38 -0600116 if (route != m_routes.end()) {
117 if (route->flags & ndn::nfd::ROUTE_FLAG_CAPTURE) {
118 m_nRoutesWithCaptureSet--;
Vince Lehman4387e782014-06-19 16:57:45 -0500119 }
120
Vince Lehman76c751c2014-11-18 17:36:38 -0600121 // Cancel any scheduled event
122 NFD_LOG_TRACE("Cancelling expiration eventId: " << route->getExpirationEvent());
123 scheduler::cancel(route->getExpirationEvent());
124
125 return m_routes.erase(route);
126 }
127
Vince Lehman218be0a2015-01-15 17:25:20 -0600128 return m_routes.end();
Vince Lehman4387e782014-06-19 16:57:45 -0500129}
130
131void
Vince Lehman218be0a2015-01-15 17:25:20 -0600132RibEntry::addInheritedRoute(const Route& route)
Vince Lehman4387e782014-06-19 16:57:45 -0500133{
Vince Lehman218be0a2015-01-15 17:25:20 -0600134 m_inheritedRoutes.push_back(route);
Vince Lehman4387e782014-06-19 16:57:45 -0500135}
136
137void
Vince Lehman218be0a2015-01-15 17:25:20 -0600138RibEntry::removeInheritedRoute(const Route& route)
Vince Lehman4387e782014-06-19 16:57:45 -0500139{
Vince Lehman76c751c2014-11-18 17:36:38 -0600140 RouteList::iterator it = std::find_if(m_inheritedRoutes.begin(), m_inheritedRoutes.end(),
141 bind(&compareFaceId, _1, route.faceId));
Vince Lehman218be0a2015-01-15 17:25:20 -0600142 m_inheritedRoutes.erase(it);
Vince Lehman4387e782014-06-19 16:57:45 -0500143}
144
Vince Lehman76c751c2014-11-18 17:36:38 -0600145RibEntry::RouteList::const_iterator
146RibEntry::findInheritedRoute(const Route& route) const
Vince Lehman4387e782014-06-19 16:57:45 -0500147{
Vince Lehman218be0a2015-01-15 17:25:20 -0600148 return std::find_if(m_inheritedRoutes.begin(), m_inheritedRoutes.end(),
149 bind(&compareFaceId, _1, route.faceId));
Vince Lehman4387e782014-06-19 16:57:45 -0500150}
151
152bool
Vince Lehman76c751c2014-11-18 17:36:38 -0600153RibEntry::hasInheritedRoute(const Route& route) const
Vince Lehman4387e782014-06-19 16:57:45 -0500154{
Vince Lehman218be0a2015-01-15 17:25:20 -0600155 RouteList::const_iterator it = findInheritedRoute(route);
Vince Lehman4387e782014-06-19 16:57:45 -0500156
Vince Lehman218be0a2015-01-15 17:25:20 -0600157 return (it != m_inheritedRoutes.end());
Vince Lehman4387e782014-06-19 16:57:45 -0500158}
159
160bool
161RibEntry::hasCapture() const
162{
Vince Lehman218be0a2015-01-15 17:25:20 -0600163 return m_nRoutesWithCaptureSet > 0;
Vince Lehman4387e782014-06-19 16:57:45 -0500164}
165
166bool
167RibEntry::hasChildInheritOnFaceId(uint64_t faceId) const
168{
Vince Lehman76c751c2014-11-18 17:36:38 -0600169 for (const Route& route : m_routes) {
170 if (route.faceId == faceId && (route.flags & ndn::nfd::ROUTE_FLAG_CHILD_INHERIT)) {
171 return true;
Vince Lehman4387e782014-06-19 16:57:45 -0500172 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600173 }
Vince Lehman4387e782014-06-19 16:57:45 -0500174
175 return false;
176}
177
Vince Lehman9dcfc402015-03-26 03:18:54 -0500178const Route*
Vince Lehman76c751c2014-11-18 17:36:38 -0600179RibEntry::getRouteWithLowestCostByFaceId(uint64_t faceId) const
Vince Lehman4387e782014-06-19 16:57:45 -0500180{
Vince Lehman9dcfc402015-03-26 03:18:54 -0500181 const Route* candidate = nullptr;
Vince Lehman4387e782014-06-19 16:57:45 -0500182
Vince Lehman76c751c2014-11-18 17:36:38 -0600183 for (const Route& route : m_routes) {
184 // Matching face ID
185 if (route.faceId == faceId) {
186 // If this is the first route with this Face ID found
187 if (candidate == nullptr) {
Vince Lehman9dcfc402015-03-26 03:18:54 -0500188 candidate = &route;
Vince Lehman76c751c2014-11-18 17:36:38 -0600189 }
190 else if (route.cost < candidate->cost) {
191 // Found a route with a lower cost
Vince Lehman9dcfc402015-03-26 03:18:54 -0500192 candidate = &route;
Vince Lehman76c751c2014-11-18 17:36:38 -0600193 }
Vince Lehman4387e782014-06-19 16:57:45 -0500194 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600195 }
Vince Lehman4387e782014-06-19 16:57:45 -0500196
Vince Lehman218be0a2015-01-15 17:25:20 -0600197 return candidate;
Vince Lehman4387e782014-06-19 16:57:45 -0500198}
199
Vince Lehman76c751c2014-11-18 17:36:38 -0600200const Route*
201RibEntry::getRouteWithSecondLowestCostByFaceId(uint64_t faceId) const
202{
Vince Lehman4310d502016-03-04 11:58:59 -0600203 std::vector<const Route*> matches;
Vince Lehman76c751c2014-11-18 17:36:38 -0600204
205 // Copy routes which have faceId
Vince Lehman4310d502016-03-04 11:58:59 -0600206 for (const Route& route : m_routes) {
207 if (route.faceId == faceId) {
208 matches.push_back(&route);
209 }
210 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600211
Vince Lehman4310d502016-03-04 11:58:59 -0600212 // If there are less than 2 routes, there is no second lowest
Vince Lehman76c751c2014-11-18 17:36:38 -0600213 if (matches.size() < 2) {
214 return nullptr;
215 }
216
217 // Get second lowest cost
218 std::nth_element(matches.begin(), matches.begin() + 1, matches.end(),
Vince Lehman4310d502016-03-04 11:58:59 -0600219 [] (const Route* lhs, const Route* rhs) { return lhs->cost < rhs->cost; });
Vince Lehman76c751c2014-11-18 17:36:38 -0600220
Vince Lehman4310d502016-03-04 11:58:59 -0600221 return matches.at(1);
Vince Lehman76c751c2014-11-18 17:36:38 -0600222}
223
Vince Lehman9dcfc402015-03-26 03:18:54 -0500224const Route*
Vince Lehman76c751c2014-11-18 17:36:38 -0600225RibEntry::getRouteWithLowestCostAndChildInheritByFaceId(uint64_t faceId) const
Vince Lehman4387e782014-06-19 16:57:45 -0500226{
Vince Lehman9dcfc402015-03-26 03:18:54 -0500227 const Route* candidate = nullptr;
Vince Lehman4387e782014-06-19 16:57:45 -0500228
Vince Lehman76c751c2014-11-18 17:36:38 -0600229 for (const Route& route : m_routes) {
230 // Correct face ID and Child Inherit flag set
231 if (route.faceId == faceId &&
232 (route.flags & ndn::nfd::ROUTE_FLAG_CHILD_INHERIT) == ndn::nfd::ROUTE_FLAG_CHILD_INHERIT)
Vince Lehman4387e782014-06-19 16:57:45 -0500233 {
Vince Lehman76c751c2014-11-18 17:36:38 -0600234 // If this is the first route with this Face ID found
235 if (candidate == nullptr) {
Vince Lehman9dcfc402015-03-26 03:18:54 -0500236 candidate = &route;
Vince Lehman76c751c2014-11-18 17:36:38 -0600237 }
238 else if (route.cost < candidate->cost) {
239 // Found a route with a lower cost
Vince Lehman9dcfc402015-03-26 03:18:54 -0500240 candidate = &route;
Vince Lehman76c751c2014-11-18 17:36:38 -0600241 }
Vince Lehman4387e782014-06-19 16:57:45 -0500242 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600243 }
Vince Lehman4387e782014-06-19 16:57:45 -0500244
Vince Lehman218be0a2015-01-15 17:25:20 -0600245 return candidate;
Vince12e49462014-06-09 13:29:32 -0500246}
247
248std::ostream&
Vince12e49462014-06-09 13:29:32 -0500249operator<<(std::ostream& os, const RibEntry& entry)
250{
Syed Obaid3313a372014-07-01 01:31:33 -0500251 os << "RibEntry {\n";
252 os << "\tName: " << entry.getName() << "\n";
Vince12e49462014-06-09 13:29:32 -0500253
Vince Lehman76c751c2014-11-18 17:36:38 -0600254 for (const Route& route : entry) {
255 os << "\t" << route << "\n";
256 }
Vince12e49462014-06-09 13:29:32 -0500257
258 os << "}";
259
260 return os;
261}
262
263} // namespace rib
264} // namespace nfd