21 #pragma clang diagnostic push
22 #pragma clang diagnostic ignored "-Wunused-variable"
23 #pragma clang diagnostic ignored "-Wunneeded-internal-declaration"
38 #include "ns3/object.h"
40 #include "ns3/node-container.h"
41 #include "ns3/net-device.h"
42 #include "ns3/channel.h"
44 #include "ns3/assert.h"
45 #include "ns3/names.h"
46 #include "ns3/node-list.h"
47 #include "ns3/channel-list.h"
48 #include "ns3/object-factory.h"
50 #include <boost/lexical_cast.hpp>
51 #include <boost/foreach.hpp>
52 #include <boost/concept/assert.hpp>
53 #include <boost/graph/dijkstra_shortest_paths.hpp>
55 #include <unordered_map>
61 NS_LOG_COMPONENT_DEFINE(
"ndn.GlobalRoutingHelper");
69 NS_LOG_LOGIC(
"Node: " << node->GetId());
72 NS_ASSERT_MSG(
ndn != 0,
"Cannot install GlobalRoutingHelper before Ndn is installed on a node");
76 NS_LOG_DEBUG(
"GlobalRouter is already installed: " << gr);
80 gr = CreateObject<GlobalRouter>();
81 node->AggregateObject(gr);
83 for (
auto& face :
ndn->getFaceTable()) {
85 if (transport ==
nullptr) {
86 NS_LOG_DEBUG(
"Skipping non ndnSIM-specific transport face");
90 Ptr<NetDevice> nd = transport->GetNetDevice();
92 NS_LOG_DEBUG(
"Not a NetDevice associated with an ndnSIM-specific transport instance");
96 Ptr<Channel> ch = nd->GetChannel();
99 NS_LOG_DEBUG(
"Channel is not associated with NetDevice");
103 if (ch->GetNDevices() == 2)
105 for (uint32_t deviceId = 0; deviceId < ch->GetNDevices(); deviceId++) {
106 Ptr<NetDevice> otherSide = ch->GetDevice(deviceId);
110 Ptr<Node> otherNode = otherSide->GetNode();
111 NS_ASSERT(otherNode != 0);
113 Ptr<GlobalRouter> otherGr = otherNode->GetObject<
GlobalRouter>();
118 NS_ASSERT(otherGr != 0);
119 gr->AddIncidency(face.shared_from_this(), otherGr);
123 Ptr<GlobalRouter> grChannel = ch->GetObject<
GlobalRouter>();
124 if (grChannel == 0) {
137 NS_LOG_LOGIC(
"Channel: " << channel->GetId());
139 Ptr<GlobalRouter> gr = channel->GetObject<
GlobalRouter>();
143 gr = CreateObject<GlobalRouter>();
144 channel->AggregateObject(gr);
146 for (uint32_t deviceId = 0; deviceId < channel->GetNDevices(); deviceId++) {
147 Ptr<NetDevice> dev = channel->GetDevice(deviceId);
149 Ptr<Node> node = dev->GetNode();
150 NS_ASSERT(node != 0);
152 Ptr<GlobalRouter> grOther = node->GetObject<
GlobalRouter>();
156 grOther = node->GetObject<GlobalRouter>();
157 NS_ASSERT(grOther != 0);
159 gr->AddIncidency(0, grOther);
166 for (NodeContainer::Iterator node = nodes.Begin(); node != nodes.End(); node++) {
174 Install(NodeContainer::GetGlobal());
181 NS_ASSERT_MSG(gr != 0,
"GlobalRouter is not installed on the node");
183 auto name = make_shared<Name>(prefix);
184 gr->AddLocalPrefix(
name);
190 for (NodeContainer::Iterator node = nodes.Begin(); node != nodes.End(); node++) {
198 Ptr<Node> node = Names::Find<Node>(nodeName);
199 NS_ASSERT_MSG(node != 0, nodeName <<
"is not a Node");
207 for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
208 Ptr<GlobalRouter> gr = (*node)->GetObject<
GlobalRouter>();
209 std::string
name = Names::FindName(*node);
211 if (gr != 0 && !
name.empty()) {
225 BOOST_CONCEPT_ASSERT((boost::VertexListGraphConcept<boost::NdnGlobalRouterGraph>));
226 BOOST_CONCEPT_ASSERT((boost::IncidenceGraphConcept<boost::NdnGlobalRouterGraph>));
228 boost::NdnGlobalRouterGraph graph;
235 for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
236 Ptr<GlobalRouter> source = (*node)->GetObject<
GlobalRouter>();
238 NS_LOG_DEBUG(
"Node " << (*node)->GetId() <<
" does not export GlobalRouter interface");
242 boost::DistancesMap distances;
244 dijkstra_shortest_paths(graph, source,
247 distance_map(boost::ref(distances))
248 .distance_inf(boost::WeightInf)
249 .distance_zero(boost::WeightZero)
250 .distance_compare(boost::WeightCompare())
251 .distance_combine(boost::WeightCombine()));
255 Ptr<L3Protocol> L3protocol = (*node)->GetObject<
L3Protocol>();
256 shared_ptr<nfd::Forwarder> forwarder = L3protocol->
getForwarder();
258 NS_LOG_DEBUG(
"Reachability from Node: " << source->GetObject<Node>()->GetId());
259 for (
const auto& dist : distances) {
260 if (dist.first == source)
264 if (std::get<0>(dist.second) == 0) {
268 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));
274 std::get<1>(dist.second));
290 BOOST_CONCEPT_ASSERT((boost::VertexListGraphConcept<boost::NdnGlobalRouterGraph>));
291 BOOST_CONCEPT_ASSERT((boost::IncidenceGraphConcept<boost::NdnGlobalRouterGraph>));
293 boost::NdnGlobalRouterGraph graph;
300 for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
301 Ptr<GlobalRouter> source = (*node)->GetObject<
GlobalRouter>();
303 NS_LOG_DEBUG(
"Node " << (*node)->GetId() <<
" does not export GlobalRouter interface");
307 Ptr<L3Protocol> L3protocol = (*node)->GetObject<
L3Protocol>();
308 shared_ptr<nfd::Forwarder> forwarder = L3protocol->
getForwarder();
310 NS_LOG_DEBUG(
"Reachability from Node: " << source->GetObject<Node>()->GetId() <<
" ("
311 << Names::FindName(source->GetObject<Node>()) <<
")");
313 Ptr<L3Protocol> l3 = source->GetObject<
L3Protocol>();
317 std::list<nfd::FaceId> faceIds;
318 std::unordered_map<nfd::FaceId, uint16_t> originalMetrics;
319 for (
auto&
nfdFace : l3->getFaceTable()) {
320 faceIds.push_back(
nfdFace.getId());
322 nfdFace.setMetric(std::numeric_limits<uint16_t>::max() - 1);
326 for (
auto& faceId : faceIds) {
327 auto* face = l3->getFaceTable().get(faceId);
328 NS_ASSERT(face !=
nullptr);
330 if (transport ==
nullptr) {
331 NS_LOG_DEBUG(
"Skipping non ndnSIM-specific transport face");
336 face->setMetric(originalMetrics[faceId]);
338 boost::DistancesMap distances;
340 NS_LOG_DEBUG(
"-----------");
342 dijkstra_shortest_paths(graph, source,
345 distance_map(boost::ref(distances))
346 .distance_inf(boost::WeightInf)
347 .distance_zero(boost::WeightZero)
348 .distance_compare(boost::WeightCompare())
349 .distance_combine(boost::WeightCombine()));
353 for (
const auto& dist : distances) {
354 if (dist.first == source)
358 if (std::get<0>(dist.second) == 0) {
362 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));
368 if (std::get<0>(dist.second)->getMetric() == std::numeric_limits<uint16_t>::max() - 1)
372 std::get<1>(dist.second));
379 face->setMetric(std::numeric_limits<uint16_t>::max() - 1);
383 for (
auto& i : originalMetrics) {
384 l3->getFaceTable().get(i.first)->setMetric(i.second);