NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.5: NDN, CCN, CCNx, content centric networks
API Documentation
ndn-global-routing-helper-lfid.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
21 #include "ns3/ndnSIM/helper/ndn-global-routing-helper.hpp"
22 
23 #include <boost/graph/dijkstra_shortest_paths.hpp>
24 #include <boost/graph/graph_utility.hpp>
25 
26 #include "ns3/ndnSIM/helper/boost-graph-ndn-global-routing-helper.hpp"
27 #include "ns3/ndnSIM/helper/lfid/abstract-fib.hpp"
28 #include "ns3/ndnSIM/helper/lfid/remove-loops.hpp"
29 #include "ns3/ndnSIM/helper/ndn-fib-helper.hpp"
30 #include "ns3/ndnSIM/model/ndn-global-router.hpp"
31 
32 NS_LOG_COMPONENT_DEFINE("ndn.GlobalRoutingHelperLfid");
33 
34 namespace ns3 {
35 namespace ndn {
36 
37 using std::get;
38 using std::unordered_map;
39 
40 void
42 {
43  BOOST_CONCEPT_ASSERT((boost::VertexListGraphConcept<boost::NdnGlobalRouterGraph>));
44  BOOST_CONCEPT_ASSERT((boost::IncidenceGraphConcept<boost::NdnGlobalRouterGraph>));
45 
46  // Creates graph from nodeList:
47  boost::NdnGlobalRouterGraph graph{};
48 
49  AbstractFib::AllNodeFib allNodeFIB;
50 
51  // Store mapping nodeId -> faceId -> Ptr<Face>
52  unordered_map<int, unordered_map<nfd::FaceId, shared_ptr<Face>>> faceMap;
53 
54  // For all existing nodes:
55  for (auto node = NodeList::Begin(); node != NodeList::End(); node++) {
56 
57  int nodeId = static_cast<int>((*node)->GetId());
58  const Ptr<GlobalRouter>& source = (*node)->GetObject<GlobalRouter>();
59 
60  AbstractFib nodeFib = AbstractFib{source, static_cast<int>(NodeList::GetNNodes())};
61 
62  if (source == nullptr) {
63  NS_LOG_ERROR("Node " << (*node)->GetId() << " does not export GlobalRouter interface");
64  continue;
65  }
66 
67  // map: neighborId -> DistancesMap
68  unordered_map<int, boost::DistancesMap> nbSp;
69 
70  // map: Destination (GlobalRouter) -> Distance
71  boost::DistancesMap distMap;
72  unordered_map<int, boost::DistancesMap> neighborSpMap;
73 
74  dijkstra_shortest_paths(graph, source,
75  distance_map(boost::ref(distMap))
76  .distance_inf(boost::WeightInf)
77  .distance_zero(boost::WeightZero)
78  .distance_compare(boost::WeightCompare())
79  .distance_combine(boost::WeightCombine()));
80 
81  // 1. Get all neighbors of node.
82  unordered_map<nfd::FaceId, uint64_t> originalMetrics;
83  auto& originalFace = faceMap[nodeId];
84 
85  const GlobalRouter::IncidencyList& neighbors = source->GetIncidencies();
86  // Set link weight of all neighbors to infinity
87  for (const auto& neighbor : neighbors) {
88  int nbId = get<2>(neighbor)->GetObject<ns3::Node>()->GetId();
89  NS_ABORT_UNLESS(nbId != nodeId);
90 
91  auto& face = get<shared_ptr<Face>>(neighbor);
92  NS_ABORT_UNLESS(face != nullptr);
93 
94  originalMetrics[nbId] = face->getMetric();
95  originalFace[nbId] = face; // Is only a copy
96  face->setMetric(get<uint16_t>(boost::WeightInf));
97  }
98 
99  // 2. Calculate Dijkstra for neighbors
100  for (const auto& neighbor : neighbors) {
101  const auto& nSource = get<0>(neighbor);
102  const auto& target = get<2>(neighbor);
103 
104  int nbId = target->GetObject<ns3::Node>()->GetId();
105  Ptr<GlobalRouter> nbRouter = target;
106 
107  NS_ABORT_UNLESS(target != source && nbId != nodeId);
108  NS_ABORT_UNLESS(nSource == source);
109 
110  dijkstra_shortest_paths(graph, nbRouter,
111  distance_map(boost::ref(neighborSpMap[nbId]))
112  .distance_inf(boost::WeightInf)
113  .distance_zero(boost::WeightZero)
114  .distance_compare(boost::WeightCompare())
115  .distance_combine(boost::WeightCombine()));
116  }
117 
118  // 3. Reset link weights
119  for (const auto& neighbor : neighbors) {
120  int nbId = get<2>(neighbor)->GetObject<ns3::Node>()->GetId();
121  NS_ABORT_UNLESS(nbId != nodeId);
122 
123  const auto& face = get<shared_ptr<Face>>(neighbor);
124  NS_ABORT_UNLESS(face->getMetric() == get<uint16_t>(boost::WeightInf));
125  face->setMetric(originalMetrics.at(nbId));
126  }
127 
128  // 4. Fill Abstract FIB:
129  // For each destination:
130  for (const auto& dstEntry : distMap) {
131  Ptr<GlobalRouter> dstRouter = dstEntry.first;
132  int dstId = dstRouter->GetObject<ns3::Node>()->GetId();
133  if (dstRouter == source)
134  continue; // Skip destination == source.
135 
136  int spTotalCost = static_cast<int>(get<uint32_t>(dstEntry.second));
137 
138  // For each neighbor:
139  for (const auto& nb : neighborSpMap) {
140  int neighborId = nb.first;
141  const uint32_t nbDist{get<uint32_t>(nb.second.at(dstRouter))};
142 
143  int neighborCost = static_cast<int>(nbDist);
144  int neighborTotalCost = neighborCost + static_cast<int>(originalFace.at(neighborId)->getMetric());
145 
146  NS_ABORT_UNLESS(neighborTotalCost >= spTotalCost);
147 
148  // Skip routers that would loop back
149  if (neighborTotalCost >= static_cast<int>(get<uint16_t>(boost::WeightInf)))
150  continue;
151 
152  NextHopType nbType;
153  if (neighborCost < spTotalCost) {
154  nbType = NextHopType::DOWNWARD;
155  }
156  else {
157  nbType = NextHopType::UPWARD;
158  }
159 
160  int costDelta = neighborTotalCost - spTotalCost;
161  FibNextHop nh = {neighborTotalCost, neighborId, costDelta, nbType};
162  nodeFib.insert(dstId, nh);
163  }
164 
165  } // End for all dsts
166 
167  nodeFib.checkFib();
168  allNodeFIB.emplace(nodeId, nodeFib);
169  } // End for all nodes
170 
172  removeLoops(allNodeFIB, true);
173  removeDeadEnds(allNodeFIB, true);
174 
175  // 5. Insert from AbsFIB into real FIB!
176  // For each node in the AbsFIB: Insert into real fib.
177  for (const auto& nodeEntry : allNodeFIB) {
178  int nodeId = nodeEntry.first;
179  const auto& fib = nodeEntry.second;
180 
181  // For each destination:
182  for (const auto& dst : fib) {
183  int dstId = dst.first;
184  const auto& dstRouter = allNodeFIB.at(dstId).getGR();
185 
186  // Each fibNexthop
187  for (const auto& nh : dst.second) {
188  int neighborId = nh.getNexthopId();
189  int neighborTotalCost = nh.getCost();
190 
191  for (const auto& prefix : dstRouter->GetLocalPrefixes()) {
192  Ptr<Node> node = NodeList::GetNode(static_cast<uint32_t>(nodeId));
193  FibHelper::AddRoute(node, *prefix, faceMap.at(nodeId).at(neighborId), neighborTotalCost);
194  }
195  }
196  }
197  }
198 }
199 
200 } // namespace ndn
201 } // namespace ns3
Copyright (c) 2011-2015 Regents of the University of California.
Class representing global router interface for ndnSIM.
static void AddRoute(Ptr< Node > node, const Name &prefix, shared_ptr< Face > face, int32_t metric)
Add forwarding entry to FIB.
R & get(variant< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 > &v, nonstd_lite_in_place_type_t(R)=nonstd_lite_in_place_type(R))
static void CalculateLfidRoutes()
Calculates a set of loop-free multipath routes.
int removeLoops(AllNodeFib &allNodeFIB, bool printOutput)
An abstract, lightweight representation of the FIB.
int removeDeadEnds(AllNodeFib &allNodeFIB, bool printOutput)
std::unordered_map< int, AbstractFib > AllNodeFib
std::list< Incidency > IncidencyList
List of graph edges.
Copyright (c) 2011-2015 Regents of the University of California.