blob: aca25d51cade02652e7026092f80d4f5c027d0f9 [file] [log] [blame]
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2011-2015 Regents of the University of California.
Alexander Afanasyevad3757f2012-04-17 10:27:59 -07004 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08005 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
6 * contributors.
Alexander Afanasyevad3757f2012-04-17 10:27:59 -07007 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08008 * ndnSIM is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070011 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -080012 * ndnSIM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070015 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -080016 * You should have received a copy of the GNU General Public License along with
17 * ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 **/
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070019
Alexander Afanasyev3898e1b2013-07-27 12:03:17 -070020#if __clang__
21#pragma clang diagnostic push
22#pragma clang diagnostic ignored "-Wunused-variable"
23#pragma clang diagnostic ignored "-Wunneeded-internal-declaration"
24#endif
25
Alexander Afanasyev0c395372014-12-20 15:54:02 -080026#include "ndn-global-routing-helper.hpp"
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070027
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -080028#include "model/ndn-l3-protocol.hpp"
29#include "helper/ndn-fib-helper.hpp"
Alexander Afanasyevca3c67e2016-09-08 15:48:23 -070030#include "model/ndn-net-device-link-service.hpp"
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -080031#include "model/ndn-global-router.hpp"
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070032
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -080033#include "daemon/table/fib.hpp"
34#include "daemon/fw/forwarder.hpp"
35#include "daemon/table/fib-entry.hpp"
36#include "daemon/table/fib-nexthop.hpp"
37
38#include "ns3/object.h"
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070039#include "ns3/node.h"
Alexander Afanasyevce810142012-04-17 15:50:36 -070040#include "ns3/node-container.h"
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070041#include "ns3/net-device.h"
42#include "ns3/channel.h"
43#include "ns3/log.h"
44#include "ns3/assert.h"
45#include "ns3/names.h"
46#include "ns3/node-list.h"
47#include "ns3/channel-list.h"
Alexander Afanasyevf5c07742012-10-31 13:13:05 -070048#include "ns3/object-factory.h"
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070049
50#include <boost/lexical_cast.hpp>
Alexander Afanasyev8e2f1122012-04-17 15:01:11 -070051#include <boost/foreach.hpp>
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -070052#include <boost/concept/assert.hpp>
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -070053#include <boost/graph/dijkstra_shortest_paths.hpp>
54
Christian Kreuzberger8a56e8d2015-02-18 08:45:01 -080055#include <unordered_map>
56
Alexander Afanasyev0c395372014-12-20 15:54:02 -080057#include "boost-graph-ndn-global-routing-helper.hpp"
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070058
Alexander Afanasyev73532512012-11-27 00:42:35 -080059#include <math.h>
60
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080061NS_LOG_COMPONENT_DEFINE("ndn.GlobalRoutingHelper");
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070062
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070063namespace ns3 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070064namespace ndn {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070065
66void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080067GlobalRoutingHelper::Install(Ptr<Node> node)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070068{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080069 NS_LOG_LOGIC("Node: " << node->GetId());
Alexander Afanasyev49165862013-01-31 00:38:20 -080070
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080071 Ptr<L3Protocol> ndn = node->GetObject<L3Protocol>();
72 NS_ASSERT_MSG(ndn != 0, "Cannot install GlobalRoutingHelper before Ndn is installed on a node");
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070073
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080074 Ptr<GlobalRouter> gr = node->GetObject<GlobalRouter>();
75 if (gr != 0) {
76 NS_LOG_DEBUG("GlobalRouter is already installed: " << gr);
77 return; // already installed
78 }
79
80 gr = CreateObject<GlobalRouter>();
81 node->AggregateObject(gr);
82
Alexander Afanasyevca3c67e2016-09-08 15:48:23 -070083 for (auto& face : ndn->getForwarder()->getFaceTable()) {
84 auto linkService = dynamic_cast<NetDeviceLinkService*>(face->getLinkService());
85 if (linkService == nullptr) {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080086 NS_LOG_DEBUG("Skipping non-netdevice face");
87 continue;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070088 }
Alexander Afanasyev49165862013-01-31 00:38:20 -080089
Alexander Afanasyevca3c67e2016-09-08 15:48:23 -070090 Ptr<NetDevice> nd = linkService->GetNetDevice();
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080091 if (nd == 0) {
92 NS_LOG_DEBUG("Not a NetDevice associated with NetDeviceFace");
93 continue;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070094 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080095
96 Ptr<Channel> ch = nd->GetChannel();
97
98 if (ch == 0) {
99 NS_LOG_DEBUG("Channel is not associated with NetDevice");
100 continue;
101 }
102
103 if (ch->GetNDevices() == 2) // e.g., point-to-point channel
104 {
105 for (uint32_t deviceId = 0; deviceId < ch->GetNDevices(); deviceId++) {
106 Ptr<NetDevice> otherSide = ch->GetDevice(deviceId);
107 if (nd == otherSide)
108 continue;
109
110 Ptr<Node> otherNode = otherSide->GetNode();
111 NS_ASSERT(otherNode != 0);
112
113 Ptr<GlobalRouter> otherGr = otherNode->GetObject<GlobalRouter>();
114 if (otherGr == 0) {
115 Install(otherNode);
116 }
117 otherGr = otherNode->GetObject<GlobalRouter>();
118 NS_ASSERT(otherGr != 0);
119 gr->AddIncidency(face, otherGr);
120 }
121 }
122 else {
123 Ptr<GlobalRouter> grChannel = ch->GetObject<GlobalRouter>();
124 if (grChannel == 0) {
125 Install(ch);
126 }
127 grChannel = ch->GetObject<GlobalRouter>();
128
129 gr->AddIncidency(face, grChannel);
130 }
131 }
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700132}
133
134void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800135GlobalRoutingHelper::Install(Ptr<Channel> channel)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700136{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800137 NS_LOG_LOGIC("Channel: " << channel->GetId());
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700138
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800139 Ptr<GlobalRouter> gr = channel->GetObject<GlobalRouter>();
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700140 if (gr != 0)
141 return;
142
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800143 gr = CreateObject<GlobalRouter>();
144 channel->AggregateObject(gr);
Alexander Afanasyev49165862013-01-31 00:38:20 -0800145
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800146 for (uint32_t deviceId = 0; deviceId < channel->GetNDevices(); deviceId++) {
147 Ptr<NetDevice> dev = channel->GetDevice(deviceId);
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700148
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800149 Ptr<Node> node = dev->GetNode();
150 NS_ASSERT(node != 0);
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700151
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800152 Ptr<GlobalRouter> grOther = node->GetObject<GlobalRouter>();
153 if (grOther == 0) {
154 Install(node);
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700155 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800156 grOther = node->GetObject<GlobalRouter>();
157 NS_ASSERT(grOther != 0);
158
159 gr->AddIncidency(0, grOther);
160 }
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700161}
162
163void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800164GlobalRoutingHelper::Install(const NodeContainer& nodes)
Alexander Afanasyevce810142012-04-17 15:50:36 -0700165{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800166 for (NodeContainer::Iterator node = nodes.Begin(); node != nodes.End(); node++) {
167 Install(*node);
168 }
169}
170
171void
172GlobalRoutingHelper::InstallAll()
173{
174 Install(NodeContainer::GetGlobal());
175}
176
177void
178GlobalRoutingHelper::AddOrigin(const std::string& prefix, Ptr<Node> node)
179{
180 Ptr<GlobalRouter> gr = node->GetObject<GlobalRouter>();
181 NS_ASSERT_MSG(gr != 0, "GlobalRouter is not installed on the node");
182
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700183 auto name = make_shared<Name>(prefix);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800184 gr->AddLocalPrefix(name);
185}
186
187void
188GlobalRoutingHelper::AddOrigins(const std::string& prefix, const NodeContainer& nodes)
189{
190 for (NodeContainer::Iterator node = nodes.Begin(); node != nodes.End(); node++) {
191 AddOrigin(prefix, *node);
192 }
193}
194
195void
196GlobalRoutingHelper::AddOrigin(const std::string& prefix, const std::string& nodeName)
197{
198 Ptr<Node> node = Names::Find<Node>(nodeName);
199 NS_ASSERT_MSG(node != 0, nodeName << "is not a Node");
200
201 AddOrigin(prefix, node);
202}
203
204void
205GlobalRoutingHelper::AddOriginsForAll()
206{
207 for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
208 Ptr<GlobalRouter> gr = (*node)->GetObject<GlobalRouter>();
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800209 std::string name = Names::FindName(*node);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800210
211 if (gr != 0 && !name.empty()) {
212 AddOrigin("/" + name, *node);
Alexander Afanasyevce810142012-04-17 15:50:36 -0700213 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800214 }
Alexander Afanasyevce810142012-04-17 15:50:36 -0700215}
216
217void
Alexander Afanasyev8e60bcd2015-01-15 20:55:40 +0000218GlobalRoutingHelper::CalculateRoutes()
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700219{
Alexander Afanasyev8e2f1122012-04-17 15:01:11 -0700220 /**
221 * Implementation of route calculation is heavily based on Boost Graph Library
222 * See http://www.boost.org/doc/libs/1_49_0/libs/graph/doc/table_of_contents.html for more details
223 */
Alexander Afanasyev49165862013-01-31 00:38:20 -0800224
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800225 BOOST_CONCEPT_ASSERT((boost::VertexListGraphConcept<boost::NdnGlobalRouterGraph>));
226 BOOST_CONCEPT_ASSERT((boost::IncidenceGraphConcept<boost::NdnGlobalRouterGraph>));
Alexander Afanasyev49165862013-01-31 00:38:20 -0800227
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800228 boost::NdnGlobalRouterGraph graph;
Zongyi Zhaoc8372632014-04-28 15:36:49 -0700229 // typedef graph_traits < NdnGlobalRouterGraph >::vertex_descriptor vertex_descriptor;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700230
Alexander Afanasyev8e2f1122012-04-17 15:01:11 -0700231 // For now we doing Dijkstra for every node. Can be replaced with Bellman-Ford or Floyd-Warshall.
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800232 // Other algorithms should be faster, but they need additional EdgeListGraph concept provided by
233 // the graph, which
Alexander Afanasyev8e2f1122012-04-17 15:01:11 -0700234 // is not obviously how implement in an efficient manner
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800235 for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
236 Ptr<GlobalRouter> source = (*node)->GetObject<GlobalRouter>();
237 if (source == 0) {
238 NS_LOG_DEBUG("Node " << (*node)->GetId() << " does not export GlobalRouter interface");
239 continue;
240 }
Alexander Afanasyev49165862013-01-31 00:38:20 -0800241
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800242 boost::DistancesMap distances;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700243
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800244 dijkstra_shortest_paths(graph, source,
245 // predecessor_map (boost::ref(predecessors))
246 // .
247 distance_map(boost::ref(distances))
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800248 .distance_inf(boost::WeightInf)
249 .distance_zero(boost::WeightZero)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800250 .distance_compare(boost::WeightCompare())
251 .distance_combine(boost::WeightCombine()));
252
253 // NS_LOG_DEBUG (predecessors.size () << ", " << distances.size ());
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800254
255 Ptr<L3Protocol> L3protocol = (*node)->GetObject<L3Protocol>();
256 shared_ptr<nfd::Forwarder> forwarder = L3protocol->getForwarder();
257
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800258 NS_LOG_DEBUG("Reachability from Node: " << source->GetObject<Node>()->GetId());
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800259 for (const auto& dist : distances) {
260 if (dist.first == source)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800261 continue;
262 else {
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800263 // cout << " Node " << dist.first->GetObject<Node> ()->GetId ();
264 if (std::get<0>(dist.second) == 0) {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800265 // cout << " is unreachable" << endl;
266 }
267 else {
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800268 for (const auto& prefix : dist.first->GetLocalPrefixes()) {
269 NS_LOG_DEBUG(" prefix " << prefix << " reachable via face " << *std::get<0>(dist.second)
270 << " with distance " << std::get<1>(dist.second) << " with delay "
271 << std::get<2>(dist.second));
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800272
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800273 FibHelper::AddRoute(*node, *prefix, std::get<0>(dist.second),
274 std::get<1>(dist.second));
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800275 }
276 }
277 }
278 }
279 }
280}
281
282void
Alexander Afanasyev8e60bcd2015-01-15 20:55:40 +0000283GlobalRoutingHelper::CalculateAllPossibleRoutes()
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800284{
285 /**
286 * Implementation of route calculation is heavily based on Boost Graph Library
287 * See http://www.boost.org/doc/libs/1_49_0/libs/graph/doc/table_of_contents.html for more details
288 */
289
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800290 BOOST_CONCEPT_ASSERT((boost::VertexListGraphConcept<boost::NdnGlobalRouterGraph>));
291 BOOST_CONCEPT_ASSERT((boost::IncidenceGraphConcept<boost::NdnGlobalRouterGraph>));
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800292
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800293 boost::NdnGlobalRouterGraph graph;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800294 // typedef graph_traits < NdnGlobalRouterGraph >::vertex_descriptor vertex_descriptor;
295
296 // For now we doing Dijkstra for every node. Can be replaced with Bellman-Ford or Floyd-Warshall.
297 // Other algorithms should be faster, but they need additional EdgeListGraph concept provided by
298 // the graph, which
299 // is not obviously how implement in an efficient manner
300 for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
301 Ptr<GlobalRouter> source = (*node)->GetObject<GlobalRouter>();
302 if (source == 0) {
303 NS_LOG_DEBUG("Node " << (*node)->GetId() << " does not export GlobalRouter interface");
304 continue;
305 }
306
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800307 Ptr<L3Protocol> L3protocol = (*node)->GetObject<L3Protocol>();
308 shared_ptr<nfd::Forwarder> forwarder = L3protocol->getForwarder();
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800309
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800310 NS_LOG_DEBUG("Reachability from Node: " << source->GetObject<Node>()->GetId() << " ("
311 << Names::FindName(source->GetObject<Node>()) << ")");
312
313 Ptr<L3Protocol> l3 = source->GetObject<L3Protocol>();
314 NS_ASSERT(l3 != 0);
315
316 // remember interface statuses
Christian Kreuzberger8a56e8d2015-02-18 08:45:01 -0800317 std::list<nfd::FaceId> faceIds;
318 std::unordered_map<nfd::FaceId, uint16_t> originalMetrics;
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800319 for (auto& i : l3->getForwarder()->getFaceTable()) {
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800320 shared_ptr<Face> nfdFace = std::dynamic_pointer_cast<Face>(i);
Christian Kreuzberger8a56e8d2015-02-18 08:45:01 -0800321 faceIds.push_back(nfdFace->getId());
322 originalMetrics[nfdFace->getId()] = nfdFace->getMetric();
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800323 nfdFace->setMetric(std::numeric_limits<uint16_t>::max() - 1);
324 // value std::numeric_limits<uint16_t>::max () MUST NOT be used (reserved)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800325 }
326
Christian Kreuzberger8a56e8d2015-02-18 08:45:01 -0800327 for (auto& faceId : faceIds) {
Alexander Afanasyevca3c67e2016-09-08 15:48:23 -0700328 shared_ptr<Face> face = l3->getForwarder()->getFaceTable().get(faceId);
329 auto linkService = dynamic_cast<NetDeviceLinkService*>(face->getLinkService());
330 if (linkService == nullptr) {
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800331 NS_LOG_DEBUG("Skipping non-netdevice face");
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800332 continue;
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800333 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800334
335 // enabling only faceId
Christian Kreuzberger8a56e8d2015-02-18 08:45:01 -0800336 face->setMetric(originalMetrics[faceId]);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800337
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800338 boost::DistancesMap distances;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800339
340 NS_LOG_DEBUG("-----------");
341
342 dijkstra_shortest_paths(graph, source,
343 // predecessor_map (boost::ref(predecessors))
344 // .
345 distance_map(boost::ref(distances))
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800346 .distance_inf(boost::WeightInf)
347 .distance_zero(boost::WeightZero)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800348 .distance_compare(boost::WeightCompare())
349 .distance_combine(boost::WeightCombine()));
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700350
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700351 // NS_LOG_DEBUG (predecessors.size () << ", " << distances.size ());
Alexander Afanasyev8e2f1122012-04-17 15:01:11 -0700352
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800353 for (const auto& dist : distances) {
354 if (dist.first == source)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800355 continue;
356 else {
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800357 // cout << " Node " << dist.first->GetObject<Node> ()->GetId ();
358 if (std::get<0>(dist.second) == 0) {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800359 // cout << " is unreachable" << endl;
360 }
361 else {
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800362 for (const auto& prefix : dist.first->GetLocalPrefixes()) {
363 NS_LOG_DEBUG(" prefix " << *prefix << " reachable via face "
364 << *std::get<0>(dist.second)
365 << " with distance " << std::get<1>(dist.second)
366 << " with delay " << std::get<2>(dist.second));
Alexander Afanasyev49165862013-01-31 00:38:20 -0800367
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800368 if (std::get<0>(dist.second)->getMetric() == std::numeric_limits<uint16_t>::max() - 1)
Alexander Afanasyevf484fb92013-03-04 10:37:27 -0800369 continue;
Alexander Afanasyevf484fb92013-03-04 10:37:27 -0800370
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800371 FibHelper::AddRoute(*node, *prefix, std::get<0>(dist.second),
372 std::get<1>(dist.second));
Alexander Afanasyevf484fb92013-03-04 10:37:27 -0800373 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800374 }
Alexander Afanasyevf484fb92013-03-04 10:37:27 -0800375 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800376 }
Alexander Afanasyevf484fb92013-03-04 10:37:27 -0800377
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800378 // disabling the face again
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800379 face->setMetric(std::numeric_limits<uint16_t>::max() - 1);
Alexander Afanasyevf484fb92013-03-04 10:37:27 -0800380 }
Alexander Afanasyevf484fb92013-03-04 10:37:27 -0800381
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800382 // recover original interface statuses
Christian Kreuzberger8a56e8d2015-02-18 08:45:01 -0800383 for (auto& i : originalMetrics) {
384 l3->getForwarder()->getFaceTable().get(i.first)->setMetric(i.second);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800385 }
386 }
387}
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700388
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700389} // namespace ndn
390} // namespace ns3