NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.5: NDN, CCN, CCNx, content centric networks
API Documentation
ndn-stack-helper.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
20 #include "ndn-stack-helper.hpp"
21 
22 #include "ns3/log.h"
23 #include "ns3/names.h"
24 #include "ns3/string.h"
25 #include "ns3/point-to-point-net-device.h"
26 #include "ns3/point-to-point-channel.h"
27 #include "ns3/node-list.h"
28 #include "ns3/simulator.h"
29 
30 #if HAVE_NS3_VISUALIZER
31 #include "../../visualizer/model/visual-simulator-impl.h"
32 #endif // HAVE_NS3_VISUALIZER
33 
36 #include "utils/ndn-time.hpp"
37 #include "utils/dummy-keychain.hpp"
38 
39 #include <limits>
40 #include <map>
41 #include <boost/lexical_cast.hpp>
42 
43 #include "ns3/ndnSIM/NFD/daemon/face/generic-link-service.hpp"
44 #include "ns3/ndnSIM/NFD/daemon/table/cs-policy-priority-fifo.hpp"
45 #include "ns3/ndnSIM/NFD/daemon/table/cs-policy-lru.hpp"
46 
47 NS_LOG_COMPONENT_DEFINE("ndn.StackHelper");
48 
49 namespace ns3 {
50 namespace ndn {
51 
53  : m_isForwarderStatusManagerDisabled(false)
54  , m_isStrategyChoiceManagerDisabled(false)
55  , m_needSetDefaultRoutes(false)
56 {
58 
59  m_csPolicies.insert({"nfd::cs::lru", [] { return make_unique<nfd::cs::LruPolicy>(); }});
60  m_csPolicies.insert({"nfd::cs::priority_fifo", [] () { return make_unique<nfd::cs::PriorityFifoPolicy>(); }});
61 
62  m_csPolicyCreationFunc = m_csPolicies["nfd::cs::lru"];
63 
64  m_ndnFactory.SetTypeId("ns3::ndn::L3Protocol");
65 
66  m_netDeviceCallbacks.push_back(
67  std::make_pair(PointToPointNetDevice::GetTypeId(),
68  MakeCallback(&StackHelper::PointToPointNetDeviceCallback, this)));
69  // default callback will be fired if non of others callbacks fit or did the job
70 }
71 
73 {
74 }
75 
76 KeyChain&
78 {
79  static ::ndn::KeyChain keyChain("pib-dummy", "tpm-dummy");
80  return keyChain;
81 }
82 
83 void
85 {
86  ::ndn::time::setCustomClocks(make_shared<ns3::ndn::time::CustomSteadyClock>(),
87  make_shared<ns3::ndn::time::CustomSystemClock>());
88 }
89 
90 void
92 {
93  NS_LOG_FUNCTION(this << needSet);
94  m_needSetDefaultRoutes = needSet;
95 }
96 
97 void
98 StackHelper::SetStackAttributes(const std::string& attr1, const std::string& value1,
99  const std::string& attr2, const std::string& value2,
100  const std::string& attr3, const std::string& value3,
101  const std::string& attr4, const std::string& value4)
102 {
103  if (attr1 != "")
104  m_ndnFactory.Set(attr1, StringValue(value1));
105  if (attr2 != "")
106  m_ndnFactory.Set(attr2, StringValue(value2));
107  if (attr3 != "")
108  m_ndnFactory.Set(attr3, StringValue(value3));
109  if (attr4 != "")
110  m_ndnFactory.Set(attr4, StringValue(value4));
111 }
112 
113 void
114 StackHelper::setCsSize(size_t maxSize)
115 {
116  m_maxCsSize = maxSize;
117 }
118 
119 void
120 StackHelper::setPolicy(const std::string& policy)
121 {
122  auto found = m_csPolicies.find(policy);
123  if (found != m_csPolicies.end()) {
124  m_csPolicyCreationFunc = found->second;
125  }
126  else {
127  NS_FATAL_ERROR("Cache replacement policy " << policy << " not found");
128  NS_LOG_DEBUG("Available cache replacement policies: ");
129  for (auto it = m_csPolicies.begin(); it != m_csPolicies.end(); it++) {
130  NS_LOG_DEBUG(" " << it->first);
131  }
132  }
133 }
134 
135 void
136 StackHelper::Install(const NodeContainer& c) const
137 {
138  for (NodeContainer::Iterator i = c.Begin(); i != c.End(); ++i) {
139  Install(*i);
140  }
141 }
142 
143 void
145 {
146  Install(NodeContainer::GetGlobal());
147 }
148 
149 void
150 StackHelper::Install(Ptr<Node> node) const
151 {
152  if (node->GetObject<L3Protocol>() != 0) {
153  NS_FATAL_ERROR("Cannot re-install NDN stack on node "
154  << node->GetId());
155  return;
156  }
157  Simulator::ScheduleWithContext(node->GetId(), Seconds(0), &StackHelper::doInstall, this, node);
159 }
160 
161 void
162 StackHelper::doInstall(Ptr<Node> node) const
163 {
164  // async install to ensure proper context
165  Ptr<L3Protocol> ndn = m_ndnFactory.Create<L3Protocol>();
166 
167  if (m_isForwarderStatusManagerDisabled) {
168  ndn->getConfig().put("ndnSIM.disable_forwarder_status_manager", true);
169  }
170 
171  if (m_isStrategyChoiceManagerDisabled) {
172  ndn->getConfig().put("ndnSIM.disable_strategy_choice_manager", true);
173  }
174 
175  ndn->getConfig().put("tables.cs_max_packets", m_maxCsSize);
176 
177  ndn->setCsReplacementPolicy(m_csPolicyCreationFunc);
178 
179  // Aggregate L3Protocol on node (must be after setting ndnSIM CS)
180  node->AggregateObject(ndn);
181 
182  for (uint32_t index = 0; index < node->GetNDevices(); index++) {
183  Ptr<NetDevice> device = node->GetDevice(index);
184  // This check does not make sense: LoopbackNetDevice is installed only if IP stack is installed,
185  // Normally, ndnSIM works without IP stack, so no reason to check
186  // if (DynamicCast<LoopbackNetDevice> (device) != 0)
187  // continue; // don't create face for a LoopbackNetDevice
188 
189  this->createAndRegisterFace(node, ndn, device);
190  }
191 }
192 
193 void
196 {
197  m_netDeviceCallbacks.push_back(std::make_pair(netDeviceType, callback));
198 }
199 
200 void
202  FaceCreateCallback callback)
203 {
204  for (auto& i : m_netDeviceCallbacks) {
205  if (i.first == netDeviceType) {
206  i.second = callback;
207  return;
208  }
209  }
210 }
211 
212 void
214  FaceCreateCallback callback)
215 {
216  m_netDeviceCallbacks.remove_if([&] (const std::pair<TypeId, FaceCreateCallback>& i) {
217  return (i.first == netDeviceType);
218  });
219 }
220 
221 std::string
222 constructFaceUri(Ptr<NetDevice> netDevice)
223 {
224  std::string uri = "netdev://";
225  Address address = netDevice->GetAddress();
226  if (Mac48Address::IsMatchingType(address)) {
227  uri += "[" + boost::lexical_cast<std::string>(Mac48Address::ConvertFrom(address)) + "]";
228  }
229 
230  return uri;
231 }
232 
233 
234 shared_ptr<Face>
235 StackHelper::DefaultNetDeviceCallback(Ptr<Node> node, Ptr<L3Protocol> ndn,
236  Ptr<NetDevice> netDevice) const
237 {
238  NS_LOG_DEBUG("Creating default Face on node " << node->GetId());
239 
240  // Create an ndnSIM-specific transport instance
241  ::nfd::face::GenericLinkService::Options opts;
242  opts.allowFragmentation = true;
243  opts.allowReassembly = true;
244  opts.allowCongestionMarking = true;
245 
246  auto linkService = make_unique<::nfd::face::GenericLinkService>(opts);
247 
248  auto transport = make_unique<NetDeviceTransport>(node, netDevice,
249  constructFaceUri(netDevice),
250  "netdev://[ff:ff:ff:ff:ff:ff]");
251 
252  auto face = std::make_shared<Face>(std::move(linkService), std::move(transport));
253  face->setMetric(1);
254 
255  ndn->addFace(face);
256  NS_LOG_LOGIC("Node " << node->GetId() << ": added Face as face #"
257  << face->getLocalUri());
258 
259  return face;
260 }
261 
262 shared_ptr<Face>
263 StackHelper::PointToPointNetDeviceCallback(Ptr<Node> node, Ptr<L3Protocol> ndn,
264  Ptr<NetDevice> device) const
265 {
266  NS_LOG_DEBUG("Creating point-to-point Face on node " << node->GetId());
267 
268  Ptr<PointToPointNetDevice> netDevice = DynamicCast<PointToPointNetDevice>(device);
269  NS_ASSERT(netDevice != nullptr);
270 
271  // access the other end of the link
272  Ptr<PointToPointChannel> channel = DynamicCast<PointToPointChannel>(netDevice->GetChannel());
273  NS_ASSERT(channel != nullptr);
274 
275  Ptr<NetDevice> remoteNetDevice = channel->GetDevice(0);
276  if (remoteNetDevice->GetNode() == node)
277  remoteNetDevice = channel->GetDevice(1);
278 
279  // Create an ndnSIM-specific transport instance
280  ::nfd::face::GenericLinkService::Options opts;
281  opts.allowFragmentation = true;
282  opts.allowReassembly = true;
283  opts.allowCongestionMarking = true;
284 
285  auto linkService = make_unique<::nfd::face::GenericLinkService>(opts);
286 
287  auto transport = make_unique<NetDeviceTransport>(node, netDevice,
288  constructFaceUri(netDevice),
289  constructFaceUri(remoteNetDevice));
290 
291  auto face = std::make_shared<Face>(std::move(linkService), std::move(transport));
292  face->setMetric(1);
293 
294  ndn->addFace(face);
295  NS_LOG_LOGIC("Node " << node->GetId() << ": added Face as face #"
296  << face->getLocalUri());
297 
298  return face;
299 }
300 
301 void
302 StackHelper::Install(const std::string& nodeName) const
303 {
304  Ptr<Node> node = Names::Find<Node>(nodeName);
305  Install(node);
306 }
307 
308 void
309 StackHelper::Update(Ptr<Node> node)
310 {
311  if (node->GetObject<L3Protocol>() == 0) {
312  Install(node);
313  return;
314  }
315 
316  Ptr<L3Protocol> ndn = node->GetObject<L3Protocol>();
317 
318  for (uint32_t index = 0; index < node->GetNDevices(); index++) {
319 
320  Ptr<NetDevice> device = node->GetDevice(index);
321 
322  if (ndn->getFaceByNetDevice(device) == nullptr) {
323  this->createAndRegisterFace(node, ndn, device);
324  }
325  }
326 }
327 
328 void
329 StackHelper::Update(const NodeContainer& c)
330 {
331  for (NodeContainer::Iterator i = c.Begin(); i != c.End(); ++i) {
332  Update(*i);
333  }
334 }
335 
336 void
337 StackHelper::Update(const std::string& nodeName)
338 {
339  Ptr<Node> node = Names::Find<Node>(nodeName);
340  Update(node);
341 }
342 
343 void
345 {
346  Update(NodeContainer::GetGlobal());
347 }
348 
349 shared_ptr<Face>
350 StackHelper::createAndRegisterFace(Ptr<Node> node, Ptr<L3Protocol> ndn, Ptr<NetDevice> device) const
351 {
352  shared_ptr<Face> face;
353 
354  for (const auto& item : m_netDeviceCallbacks) {
355  if (device->GetInstanceTypeId() == item.first ||
356  device->GetInstanceTypeId().IsChildOf(item.first)) {
357  face = item.second(node, ndn, device);
358  if (face != 0)
359  break;
360  }
361  }
362 
363  if (face == 0) {
364  face = DefaultNetDeviceCallback(node, ndn, device);
365  }
366 
367  if (m_needSetDefaultRoutes) {
368  // default route with lowest priority possible
369  FibHelper::AddRoute(node, "/", face, std::numeric_limits<int32_t>::max());
370  }
371  return face;
372 }
373 
374 void
376 {
377  m_isStrategyChoiceManagerDisabled = true;
378 }
379 
380 void
382 {
383  m_isForwarderStatusManagerDisabled = true;
384 }
385 
386 void
388 {
389  for (uint32_t i = 0; i < NodeList::GetNNodes(); ++i) {
390  auto ndn = NodeList::GetNode(i)->GetObject<L3Protocol>();
391  if (ndn == nullptr)
392  continue;
393 
394  for (auto& face : ndn->getFaceTable()) {
395  auto transport = dynamic_cast<NetDeviceTransport*>(face.getTransport());
396  if (transport == nullptr)
397  continue;
398  auto p2p = dynamic_cast<PointToPointChannel*>(&(*(transport->GetNetDevice()->GetChannel())));
399  TimeValue currentDelay;
400  p2p->GetAttribute("Delay", currentDelay);
401  face.setMetric((currentDelay.Get().ToDouble(Time::S)) * 1000);
402 
403  std::cout << "Node " << i << ": Face " << face.getId()
404  << " with metric " << face.getMetric() << "\n";
405  }
406  }
407 }
408 
409 void
411 {
412  Simulator::Stop(Seconds(0));
413 #if HAVE_NS3_VISUALIZER
414  auto impl = DynamicCast<VisualSimulatorImpl>(Simulator::GetImplementation());
415  if (impl != nullptr) {
416  impl->RunRealSimulator();
417  }
418  else {
419  Simulator::Run();
420  }
421 #else
422  Simulator::Run();
423 #endif // HAVE_NS3_VISUALIZER
424 }
425 
426 
427 } // namespace ndn
428 } // namespace ns3
virtual ~StackHelper()
Destroy the NdnStackHelper.
Copyright (c) 2011-2015 Regents of the University of California.
void setPolicy(const std::string &policy)
Set the cache replacement policy for NFD&#39;s Content Store.
StackHelper()
Create a new NdnStackHelper with a default NDN_FLOODING forwarding stategy.
static void ProcessWarmupEvents()
void RemoveFaceCreateCallback(TypeId netDeviceType, FaceCreateCallback callback)
Remove callback to create and configure instance of the face, based on supplied Ptr<Node> and Ptr<Net...
void setCsSize(size_t maxSize)
Set maximum size for NFD&#39;s Content Store (in number of packets)
ndn security KeyChain
Definition: key-chain.cpp:70
void SetDefaultRoutes(bool needSet)
Set flag indicating necessity to install default routes in FIB.
static void SetLinkDelayAsFaceMetric()
Set face metric of all faces connected through PointToPoint channel to channel latency.
nfd::ConfigSection & getConfig()
Get NFD config (boost::property_tree)
void SetStackAttributes(const std::string &attr1="", const std::string &value1="", const std::string &attr2="", const std::string &value2="", const std::string &attr3="", const std::string &value3="", const std::string &attr4="", const std::string &value4="")
Set parameters of NdnL3Protocol.
static void AddRoute(Ptr< Node > node, const Name &prefix, shared_ptr< Face > face, int32_t metric)
Add forwarding entry to FIB.
void InstallAll() const
Install Ndn stack on all nodes in the simulation.
void disableForwarderStatusManager()
Disable Forwarder Status Manager.
std::string constructFaceUri(Ptr< NetDevice > netDevice)
Callback< shared_ptr< Face >, Ptr< Node >, Ptr< L3Protocol >, Ptr< NetDevice > > FaceCreateCallback
void Install(const std::string &nodeName) const
Install Ndn stack on the node.
Copyright (c) 2011-2015 Regents of the University of California.
void AddFaceCreateCallback(TypeId netDeviceType, FaceCreateCallback callback)
Add callback to create and configure instance of the face, based on supplied Ptr<Node> and Ptr<NetDev...
Implementation network-layer of NDN stack.
void setCustomClocks(shared_ptr< CustomSteadyClock > steadyClock=nullptr, shared_ptr< CustomSystemClock > systemClock=nullptr)
Set custom system and steady clocks.
Definition: time.cpp:36
void UpdateAll()
Update Ndn stack on all the nodes (Add faces for new devices)
static KeyChain & getKeyChain()
void UpdateFaceCreateCallback(TypeId netDeviceType, FaceCreateCallback callback)
Update callback to create and configure instance of the face, based on supplied Ptr<Node> and Ptr<Net...
void Update(Ptr< Node > node)
Update Ndn stack on a given node (Add faces for new devices)
void disableStrategyChoiceManager()
Disable Strategy Choice Manager.