blob: 54b032b4e77d2d33b26dd36d93d7196b7519546e [file] [log] [blame]
Alexander Afanasyevad3757f2012-04-17 10:27:59 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2011 UCLA
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19 */
20
Alexander Afanasyev3898e1b2013-07-27 12:03:17 -070021#if __clang__
22#pragma clang diagnostic push
23#pragma clang diagnostic ignored "-Wunused-variable"
24#pragma clang diagnostic ignored "-Wunneeded-internal-declaration"
25#endif
26
Alexander Afanasyev0c395372014-12-20 15:54:02 -080027#include "ndn-global-routing-helper.hpp"
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070028
Alexander Afanasyev0c395372014-12-20 15:54:02 -080029#include "ns3/ndn-l3-protocol.hpp"
30#include "../model/ndn-net-device-face.hpp"
31#include "../model/ndn-global-router.hpp"
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070032
33#include "ns3/node.h"
Alexander Afanasyevce810142012-04-17 15:50:36 -070034#include "ns3/node-container.h"
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070035#include "ns3/net-device.h"
36#include "ns3/channel.h"
37#include "ns3/log.h"
38#include "ns3/assert.h"
39#include "ns3/names.h"
40#include "ns3/node-list.h"
41#include "ns3/channel-list.h"
Alexander Afanasyevf5c07742012-10-31 13:13:05 -070042#include "ns3/object-factory.h"
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070043
44#include <boost/lexical_cast.hpp>
Alexander Afanasyev8e2f1122012-04-17 15:01:11 -070045#include <boost/foreach.hpp>
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -070046#include <boost/concept/assert.hpp>
47// #include <boost/graph/graph_concepts.hpp>
48// #include <boost/graph/adjacency_list.hpp>
49#include <boost/graph/dijkstra_shortest_paths.hpp>
50
Alexander Afanasyev0c395372014-12-20 15:54:02 -080051#include "boost-graph-ndn-global-routing-helper.hpp"
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070052
Alexander Afanasyev73532512012-11-27 00:42:35 -080053#include <math.h>
54
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080055NS_LOG_COMPONENT_DEFINE("ndn.GlobalRoutingHelper");
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070056
57using namespace std;
58using namespace boost;
59
60namespace ns3 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070061namespace ndn {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070062
63void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080064GlobalRoutingHelper::Install(Ptr<Node> node)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070065{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080066 NS_LOG_LOGIC("Node: " << node->GetId());
Alexander Afanasyev49165862013-01-31 00:38:20 -080067
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080068 Ptr<L3Protocol> ndn = node->GetObject<L3Protocol>();
69 NS_ASSERT_MSG(ndn != 0, "Cannot install GlobalRoutingHelper before Ndn is installed on a node");
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070070
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080071 Ptr<GlobalRouter> gr = node->GetObject<GlobalRouter>();
72 if (gr != 0) {
73 NS_LOG_DEBUG("GlobalRouter is already installed: " << gr);
74 return; // already installed
75 }
76
77 gr = CreateObject<GlobalRouter>();
78 node->AggregateObject(gr);
79
80 for (uint32_t faceId = 0; faceId < ndn->GetNFaces(); faceId++) {
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -070081 shared_ptr<NetDeviceFace> face = DynamicCast<NetDeviceFace>(ndn->GetFace(faceId));
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080082 if (face == 0) {
83 NS_LOG_DEBUG("Skipping non-netdevice face");
84 continue;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070085 }
Alexander Afanasyev49165862013-01-31 00:38:20 -080086
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080087 Ptr<NetDevice> nd = face->GetNetDevice();
88 if (nd == 0) {
89 NS_LOG_DEBUG("Not a NetDevice associated with NetDeviceFace");
90 continue;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070091 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080092
93 Ptr<Channel> ch = nd->GetChannel();
94
95 if (ch == 0) {
96 NS_LOG_DEBUG("Channel is not associated with NetDevice");
97 continue;
98 }
99
100 if (ch->GetNDevices() == 2) // e.g., point-to-point channel
101 {
102 for (uint32_t deviceId = 0; deviceId < ch->GetNDevices(); deviceId++) {
103 Ptr<NetDevice> otherSide = ch->GetDevice(deviceId);
104 if (nd == otherSide)
105 continue;
106
107 Ptr<Node> otherNode = otherSide->GetNode();
108 NS_ASSERT(otherNode != 0);
109
110 Ptr<GlobalRouter> otherGr = otherNode->GetObject<GlobalRouter>();
111 if (otherGr == 0) {
112 Install(otherNode);
113 }
114 otherGr = otherNode->GetObject<GlobalRouter>();
115 NS_ASSERT(otherGr != 0);
116 gr->AddIncidency(face, otherGr);
117 }
118 }
119 else {
120 Ptr<GlobalRouter> grChannel = ch->GetObject<GlobalRouter>();
121 if (grChannel == 0) {
122 Install(ch);
123 }
124 grChannel = ch->GetObject<GlobalRouter>();
125
126 gr->AddIncidency(face, grChannel);
127 }
128 }
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700129}
130
131void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800132GlobalRoutingHelper::Install(Ptr<Channel> channel)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700133{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800134 NS_LOG_LOGIC("Channel: " << channel->GetId());
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700135
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800136 Ptr<GlobalRouter> gr = channel->GetObject<GlobalRouter>();
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700137 if (gr != 0)
138 return;
139
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800140 gr = CreateObject<GlobalRouter>();
141 channel->AggregateObject(gr);
Alexander Afanasyev49165862013-01-31 00:38:20 -0800142
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800143 for (uint32_t deviceId = 0; deviceId < channel->GetNDevices(); deviceId++) {
144 Ptr<NetDevice> dev = channel->GetDevice(deviceId);
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700145
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800146 Ptr<Node> node = dev->GetNode();
147 NS_ASSERT(node != 0);
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700148
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800149 Ptr<GlobalRouter> grOther = node->GetObject<GlobalRouter>();
150 if (grOther == 0) {
151 Install(node);
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700152 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800153 grOther = node->GetObject<GlobalRouter>();
154 NS_ASSERT(grOther != 0);
155
156 gr->AddIncidency(0, grOther);
157 }
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700158}
159
160void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800161GlobalRoutingHelper::Install(const NodeContainer& nodes)
Alexander Afanasyevce810142012-04-17 15:50:36 -0700162{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800163 for (NodeContainer::Iterator node = nodes.Begin(); node != nodes.End(); node++) {
164 Install(*node);
165 }
166}
167
168void
169GlobalRoutingHelper::InstallAll()
170{
171 Install(NodeContainer::GetGlobal());
172}
173
174void
175GlobalRoutingHelper::AddOrigin(const std::string& prefix, Ptr<Node> node)
176{
177 Ptr<GlobalRouter> gr = node->GetObject<GlobalRouter>();
178 NS_ASSERT_MSG(gr != 0, "GlobalRouter is not installed on the node");
179
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700180 auto name = make_shared<Name>(prefix);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800181 gr->AddLocalPrefix(name);
182}
183
184void
185GlobalRoutingHelper::AddOrigins(const std::string& prefix, const NodeContainer& nodes)
186{
187 for (NodeContainer::Iterator node = nodes.Begin(); node != nodes.End(); node++) {
188 AddOrigin(prefix, *node);
189 }
190}
191
192void
193GlobalRoutingHelper::AddOrigin(const std::string& prefix, const std::string& nodeName)
194{
195 Ptr<Node> node = Names::Find<Node>(nodeName);
196 NS_ASSERT_MSG(node != 0, nodeName << "is not a Node");
197
198 AddOrigin(prefix, node);
199}
200
201void
202GlobalRoutingHelper::AddOriginsForAll()
203{
204 for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
205 Ptr<GlobalRouter> gr = (*node)->GetObject<GlobalRouter>();
206 string name = Names::FindName(*node);
207
208 if (gr != 0 && !name.empty()) {
209 AddOrigin("/" + name, *node);
Alexander Afanasyevce810142012-04-17 15:50:36 -0700210 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800211 }
Alexander Afanasyevce810142012-04-17 15:50:36 -0700212}
213
214void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800215GlobalRoutingHelper::CalculateRoutes(bool invalidatedRoutes /* = true*/)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700216{
Alexander Afanasyev8e2f1122012-04-17 15:01:11 -0700217 /**
218 * Implementation of route calculation is heavily based on Boost Graph Library
219 * See http://www.boost.org/doc/libs/1_49_0/libs/graph/doc/table_of_contents.html for more details
220 */
Alexander Afanasyev49165862013-01-31 00:38:20 -0800221
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800222 BOOST_CONCEPT_ASSERT((VertexListGraphConcept<NdnGlobalRouterGraph>));
223 BOOST_CONCEPT_ASSERT((IncidenceGraphConcept<NdnGlobalRouterGraph>));
Alexander Afanasyev49165862013-01-31 00:38:20 -0800224
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700225 NdnGlobalRouterGraph graph;
Zongyi Zhaoc8372632014-04-28 15:36:49 -0700226 // typedef graph_traits < NdnGlobalRouterGraph >::vertex_descriptor vertex_descriptor;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700227
Alexander Afanasyev8e2f1122012-04-17 15:01:11 -0700228 // For now we doing Dijkstra for every node. Can be replaced with Bellman-Ford or Floyd-Warshall.
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800229 // Other algorithms should be faster, but they need additional EdgeListGraph concept provided by
230 // the graph, which
Alexander Afanasyev8e2f1122012-04-17 15:01:11 -0700231 // is not obviously how implement in an efficient manner
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800232 for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
233 Ptr<GlobalRouter> source = (*node)->GetObject<GlobalRouter>();
234 if (source == 0) {
235 NS_LOG_DEBUG("Node " << (*node)->GetId() << " does not export GlobalRouter interface");
236 continue;
237 }
Alexander Afanasyev49165862013-01-31 00:38:20 -0800238
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800239 DistancesMap distances;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700240
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800241 dijkstra_shortest_paths(graph, source,
242 // predecessor_map (boost::ref(predecessors))
243 // .
244 distance_map(boost::ref(distances))
245 .distance_inf(WeightInf)
246 .distance_zero(WeightZero)
247 .distance_compare(boost::WeightCompare())
248 .distance_combine(boost::WeightCombine()));
249
250 // NS_LOG_DEBUG (predecessors.size () << ", " << distances.size ());
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700251 /*
252 Ptr<Fib> fib = source->GetObject<Fib> ();
253 if (invalidatedRoutes)
254 {
255 fib->InvalidateAll ();
256 }
257 NS_ASSERT (fib != 0);
258*/
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800259 NS_LOG_DEBUG("Reachability from Node: " << source->GetObject<Node>()->GetId());
260 for (DistancesMap::iterator i = distances.begin(); i != distances.end(); i++) {
261 if (i->first == source)
262 continue;
263 else {
264 // cout << " Node " << i->first->GetObject<Node> ()->GetId ();
265 if (i->second.get<0>() == 0) {
266 // cout << " is unreachable" << endl;
267 }
268 else {
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700269 BOOST_FOREACH (const std::shared_ptr<const Name>& prefix, i->first->GetLocalPrefixes()) {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800270 NS_LOG_DEBUG(" prefix " << prefix << " reachable via face " << *i->second.get<0>()
271 << " with distance " << i->second.get<1>() << " with delay "
272 << i->second.get<2>());
273
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700274 // Ptr<fib::Entry> entry = fib->Add (prefix, i->second.get<0> (), i->second.get<1> ());
275 // entry->SetRealDelayToProducer (i->second.get<0> (), Seconds (i->second.get<2> ()));
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800276
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700277 // Ptr<Limits> faceLimits = i->second.get<0> ()->GetObject<Limits> ();
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800278
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700279 // Ptr<Limits> fibLimits = entry->GetObject<Limits> ();
280 // if (fibLimits != 0)
281 //{
282 // if it was created by the forwarding strategy via DidAddFibEntry event
283 // fibLimits->SetLimits (faceLimits->GetMaxRate (), 2 * i->second.get<2> () /*exact
284 // RTT*/);
285 // NS_LOG_DEBUG ("Set limit for prefix " << *prefix << " " << faceLimits->GetMaxRate ()
286 // << " / " << 2*i->second.get<2> () << "s (" << faceLimits->GetMaxRate () * 2 *
287 // i->second.get<2> () << ")");
288 //}
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800289 }
290 }
291 }
292 }
293 }
294}
295
296void
297GlobalRoutingHelper::CalculateAllPossibleRoutes(bool invalidatedRoutes /* = true*/)
298{
299 /**
300 * Implementation of route calculation is heavily based on Boost Graph Library
301 * See http://www.boost.org/doc/libs/1_49_0/libs/graph/doc/table_of_contents.html for more details
302 */
303
304 BOOST_CONCEPT_ASSERT((VertexListGraphConcept<NdnGlobalRouterGraph>));
305 BOOST_CONCEPT_ASSERT((IncidenceGraphConcept<NdnGlobalRouterGraph>));
306
307 NdnGlobalRouterGraph graph;
308 // typedef graph_traits < NdnGlobalRouterGraph >::vertex_descriptor vertex_descriptor;
309
310 // For now we doing Dijkstra for every node. Can be replaced with Bellman-Ford or Floyd-Warshall.
311 // Other algorithms should be faster, but they need additional EdgeListGraph concept provided by
312 // the graph, which
313 // is not obviously how implement in an efficient manner
314 for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
315 Ptr<GlobalRouter> source = (*node)->GetObject<GlobalRouter>();
316 if (source == 0) {
317 NS_LOG_DEBUG("Node " << (*node)->GetId() << " does not export GlobalRouter interface");
318 continue;
319 }
320
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700321 // Ptr<Fib> fib = source->GetObject<Fib> ();
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800322 if (invalidatedRoutes) {
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700323 // fib->InvalidateAll ();
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800324 }
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700325 // NS_ASSERT (fib != 0);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800326
327 NS_LOG_DEBUG("===========");
328 NS_LOG_DEBUG("Reachability from Node: " << source->GetObject<Node>()->GetId() << " ("
329 << Names::FindName(source->GetObject<Node>()) << ")");
330
331 Ptr<L3Protocol> l3 = source->GetObject<L3Protocol>();
332 NS_ASSERT(l3 != 0);
333
334 // remember interface statuses
335 std::vector<uint16_t> originalMetric(l3->GetNFaces());
336 for (uint32_t faceId = 0; faceId < l3->GetNFaces(); faceId++) {
337 originalMetric[faceId] = l3->GetFace(faceId)->GetMetric();
338 l3->GetFace(faceId)
339 ->SetMetric(std::numeric_limits<uint16_t>::max()
340 - 1); // value std::numeric_limits<uint16_t>::max () MUST NOT be used (reserved)
341 }
342
343 for (uint32_t enabledFaceId = 0; enabledFaceId < l3->GetNFaces(); enabledFaceId++) {
344 if (DynamicCast<ndn::NetDeviceFace>(l3->GetFace(enabledFaceId)) == 0)
345 continue;
346
347 // enabling only faceId
348 l3->GetFace(enabledFaceId)->SetMetric(originalMetric[enabledFaceId]);
349
350 DistancesMap distances;
351
352 NS_LOG_DEBUG("-----------");
353
354 dijkstra_shortest_paths(graph, source,
355 // predecessor_map (boost::ref(predecessors))
356 // .
357 distance_map(boost::ref(distances))
358 .distance_inf(WeightInf)
359 .distance_zero(WeightZero)
360 .distance_compare(boost::WeightCompare())
361 .distance_combine(boost::WeightCombine()));
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700362
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700363 // NS_LOG_DEBUG (predecessors.size () << ", " << distances.size ());
Alexander Afanasyev8e2f1122012-04-17 15:01:11 -0700364
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800365 for (DistancesMap::iterator i = distances.begin(); i != distances.end(); i++) {
366 if (i->first == source)
367 continue;
368 else {
369 // cout << " Node " << i->first->GetObject<Node> ()->GetId ();
370 if (i->second.get<0>() == 0) {
371 // cout << " is unreachable" << endl;
372 }
373 else {
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700374 BOOST_FOREACH (const std::shared_ptr<const Name>& prefix,
375 i->first->GetLocalPrefixes()) {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800376 NS_LOG_DEBUG(" prefix " << *prefix << " reachable via face " << *i->second.get<0>()
377 << " with distance " << i->second.get<1>() << " with delay "
378 << i->second.get<2>());
Alexander Afanasyev49165862013-01-31 00:38:20 -0800379
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800380 if (i->second.get<0>()->GetMetric() == std::numeric_limits<uint16_t>::max() - 1)
Alexander Afanasyevf484fb92013-03-04 10:37:27 -0800381 continue;
Alexander Afanasyevf484fb92013-03-04 10:37:27 -0800382
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700383 // Ptr<fib::Entry> entry = fib->Add (prefix, i->second.get<0> (), i->second.get<1>
384 // ());
385 // entry->SetRealDelayToProducer (i->second.get<0> (), Seconds (i->second.get<2> ()));
Alexander Afanasyevf484fb92013-03-04 10:37:27 -0800386
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700387 // Ptr<Limits> faceLimits = i->second.get<0> ()->GetObject<Limits> ();
Alexander Afanasyevf484fb92013-03-04 10:37:27 -0800388
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700389 // Ptr<Limits> fibLimits = entry->GetObject<Limits> ();
390 // if (fibLimits != 0)
391 //{
392 // if it was created by the forwarding strategy via DidAddFibEntry event
393 // fibLimits->SetLimits (faceLimits->GetMaxRate (), 2 * i->second.get<2> () /*exact
394 // RTT*/);
395 // NS_LOG_DEBUG ("Set limit for prefix " << *prefix << " " << faceLimits->GetMaxRate
396 // () << " / " << 2*i->second.get<2> () << "s (" << faceLimits->GetMaxRate () * 2 *
397 // i->second.get<2> () << ")");
398 //}
Alexander Afanasyevf484fb92013-03-04 10:37:27 -0800399 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800400 }
Alexander Afanasyevf484fb92013-03-04 10:37:27 -0800401 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800402 }
Alexander Afanasyevf484fb92013-03-04 10:37:27 -0800403
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800404 // disabling the face again
405 l3->GetFace(enabledFaceId)->SetMetric(std::numeric_limits<uint16_t>::max() - 1);
Alexander Afanasyevf484fb92013-03-04 10:37:27 -0800406 }
Alexander Afanasyevf484fb92013-03-04 10:37:27 -0800407
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800408 // recover original interface statuses
409 for (uint32_t faceId = 0; faceId < l3->GetNFaces(); faceId++) {
410 l3->GetFace(faceId)->SetMetric(originalMetric[faceId]);
411 }
412 }
413}
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700414
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700415} // namespace ndn
416} // namespace ns3