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());
71 Ptr<L3Protocol> ndn = node->GetObject<
L3Protocol>();
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& i : ndn->getForwarder()->getFaceTable()) {
84 shared_ptr<NetDeviceFace> face = std::dynamic_pointer_cast<
NetDeviceFace>(i);
86 NS_LOG_DEBUG(
"Skipping non-netdevice face");
90 Ptr<NetDevice> nd = face->GetNetDevice();
92 NS_LOG_DEBUG(
"Not a NetDevice associated with NetDeviceFace");
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, 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& i : l3->getForwarder()->getFaceTable()) {
320 shared_ptr<Face> nfdFace = std::dynamic_pointer_cast<
Face>(i);
321 faceIds.push_back(nfdFace->getId());
322 originalMetrics[nfdFace->getId()] = nfdFace->getMetric();
323 nfdFace->setMetric(std::numeric_limits<uint16_t>::max() - 1);
327 for (
auto& faceId : faceIds) {
328 shared_ptr<Face> k = l3->getForwarder()->getFaceTable().get(faceId);
329 shared_ptr<NetDeviceFace> face = std::dynamic_pointer_cast<
NetDeviceFace>(k);
331 NS_LOG_DEBUG(
"Skipping non-netdevice 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->getForwarder()->getFaceTable().get(i.first)->setMetric(i.second);
shared_ptr< nfd::Forwarder > getForwarder()
Get smart pointer to nfd::Forwarder installed on the node.
Class representing global router interface for ndnSIM.
void AddOriginsForAll()
Add origin to each node based on the node's name (using Names class)
Implementation of layer-2 (Ethernet) Ndn face.
void AddOrigins(const std::string &prefix, const NodeContainer &nodes)
Add `prefix' as origin on all `nodes'.
void InstallAll()
Install GlobalRouter interface on all nodes.
static void CalculateAllPossibleRoutes()
Calculate all possible next-hop independent alternative routes.
void AddIncidency(shared_ptr< Face > face, Ptr< GlobalRouter > ndn)
Add edge to the node.
static void CalculateRoutes()
Calculate for every node shortest path trees and install routes to all prefix origins.
void AddOrigin(const std::string &prefix, Ptr< Node > node)
Add `prefix' as origin on `node'.
Implementation network-layer of NDN stack.
void Install(Ptr< Node > node)
Install GlobalRouter interface on a node.
static void AddRoute(const std::string &nodeName, const Name &prefix, uint32_t faceId, int32_t metric)
Add forwarding entry to FIB.