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"
39 
40 #include <limits>
41 #include <map>
42 #include <boost/lexical_cast.hpp>
43 
44 #include "ns3/ndnSIM/NFD/daemon/face/generic-link-service.hpp"
45 #include "ns3/ndnSIM/NFD/daemon/table/cs-policy-priority-fifo.hpp"
46 #include "ns3/ndnSIM/NFD/daemon/table/cs-policy-lru.hpp"
47 
48 NS_LOG_COMPONENT_DEFINE("ndn.StackHelper");
49 
50 namespace ns3 {
51 namespace ndn {
52 
54  : m_isForwarderStatusManagerDisabled(false)
55  , m_isStrategyChoiceManagerDisabled(false)
56  , m_needSetDefaultRoutes(false)
57  , m_maxCsSize(100)
58 {
60 
61  m_csPolicies.insert({"nfd::cs::lru", [] { return make_unique<nfd::cs::LruPolicy>(); }});
62  m_csPolicies.insert({"nfd::cs::priority_fifo", [] () { return make_unique<nfd::cs::PriorityFifoPolicy>(); }});
63 
64  m_csPolicyCreationFunc = m_csPolicies["nfd::cs::lru"];
65 
66  m_ndnFactory.SetTypeId("ns3::ndn::L3Protocol");
67  m_contentStoreFactory.SetTypeId("ns3::ndn::cs::Lru");
68 
69  m_netDeviceCallbacks.push_back(
70  std::make_pair(PointToPointNetDevice::GetTypeId(),
71  MakeCallback(&StackHelper::PointToPointNetDeviceCallback, this)));
72  // default callback will be fired if non of others callbacks fit or did the job
73 }
74 
76 {
77 }
78 
79 KeyChain&
81 {
82  static ::ndn::KeyChain keyChain("pib-dummy", "tpm-dummy");
83  return keyChain;
84 }
85 
86 void
88 {
89  ::ndn::time::setCustomClocks(make_shared<ns3::ndn::time::CustomSteadyClock>(),
90  make_shared<ns3::ndn::time::CustomSystemClock>());
91 }
92 
93 void
95 {
96  NS_LOG_FUNCTION(this << needSet);
97  m_needSetDefaultRoutes = needSet;
98 }
99 
100 void
101 StackHelper::SetStackAttributes(const std::string& attr1, const std::string& value1,
102  const std::string& attr2, const std::string& value2,
103  const std::string& attr3, const std::string& value3,
104  const std::string& attr4, const std::string& value4)
105 {
106  if (attr1 != "")
107  m_ndnFactory.Set(attr1, StringValue(value1));
108  if (attr2 != "")
109  m_ndnFactory.Set(attr2, StringValue(value2));
110  if (attr3 != "")
111  m_ndnFactory.Set(attr3, StringValue(value3));
112  if (attr4 != "")
113  m_ndnFactory.Set(attr4, StringValue(value4));
114 }
115 
116 void
117 StackHelper::SetOldContentStore(const std::string& contentStore, const std::string& attr1,
118  const std::string& value1, const std::string& attr2,
119  const std::string& value2, const std::string& attr3,
120  const std::string& value3, const std::string& attr4,
121  const std::string& value4)
122 {
123  m_maxCsSize = 0;
124 
125  m_contentStoreFactory.SetTypeId(contentStore);
126  if (attr1 != "")
127  m_contentStoreFactory.Set(attr1, StringValue(value1));
128  if (attr2 != "")
129  m_contentStoreFactory.Set(attr2, StringValue(value2));
130  if (attr3 != "")
131  m_contentStoreFactory.Set(attr3, StringValue(value3));
132  if (attr4 != "")
133  m_contentStoreFactory.Set(attr4, StringValue(value4));
134 }
135 
136 void
137 StackHelper::setCsSize(size_t maxSize)
138 {
139  m_maxCsSize = maxSize;
140 }
141 
142 void
143 StackHelper::setPolicy(const std::string& policy)
144 {
145  auto found = m_csPolicies.find(policy);
146  if (found != m_csPolicies.end()) {
147  m_csPolicyCreationFunc = found->second;
148  }
149  else {
150  NS_FATAL_ERROR("Cache replacement policy " << policy << " not found");
151  NS_LOG_DEBUG("Available cache replacement policies: ");
152  for (auto it = m_csPolicies.begin(); it != m_csPolicies.end(); it++) {
153  NS_LOG_DEBUG(" " << it->first);
154  }
155  }
156 }
157 
158 void
159 StackHelper::Install(const NodeContainer& c) const
160 {
161  for (NodeContainer::Iterator i = c.Begin(); i != c.End(); ++i) {
162  Install(*i);
163  }
164 }
165 
166 void
168 {
169  Install(NodeContainer::GetGlobal());
170 }
171 
172 void
173 StackHelper::Install(Ptr<Node> node) const
174 {
175  if (node->GetObject<L3Protocol>() != 0) {
176  NS_FATAL_ERROR("Cannot re-install NDN stack on node "
177  << node->GetId());
178  return;
179  }
180  Simulator::ScheduleWithContext(node->GetId(), Seconds(0), &StackHelper::doInstall, this, node);
182 }
183 
184 void
185 StackHelper::doInstall(Ptr<Node> node) const
186 {
187  // async install to ensure proper context
188  Ptr<L3Protocol> ndn = m_ndnFactory.Create<L3Protocol>();
189 
190  if (m_isForwarderStatusManagerDisabled) {
191  ndn->getConfig().put("ndnSIM.disable_forwarder_status_manager", true);
192  }
193 
194  if (m_isStrategyChoiceManagerDisabled) {
195  ndn->getConfig().put("ndnSIM.disable_strategy_choice_manager", true);
196  }
197 
198  ndn->getConfig().put("tables.cs_max_packets", (m_maxCsSize == 0) ? 1 : m_maxCsSize);
199 
200  // Create and aggregate content store if NFD's contest store has been disabled
201  if (m_maxCsSize == 0) {
202  ndn->AggregateObject(m_contentStoreFactory.Create<ContentStore>());
203  }
204  // if NFD's CS is enabled, check if a replacement policy has been specified
205  else {
206  ndn->setCsReplacementPolicy(m_csPolicyCreationFunc);
207  }
208 
209  // Aggregate L3Protocol on node (must be after setting ndnSIM CS)
210  node->AggregateObject(ndn);
211 
212  for (uint32_t index = 0; index < node->GetNDevices(); index++) {
213  Ptr<NetDevice> device = node->GetDevice(index);
214  // This check does not make sense: LoopbackNetDevice is installed only if IP stack is installed,
215  // Normally, ndnSIM works without IP stack, so no reason to check
216  // if (DynamicCast<LoopbackNetDevice> (device) != 0)
217  // continue; // don't create face for a LoopbackNetDevice
218 
219  this->createAndRegisterFace(node, ndn, device);
220  }
221 }
222 
223 void
226 {
227  m_netDeviceCallbacks.push_back(std::make_pair(netDeviceType, callback));
228 }
229 
230 void
232  FaceCreateCallback callback)
233 {
234  for (auto& i : m_netDeviceCallbacks) {
235  if (i.first == netDeviceType) {
236  i.second = callback;
237  return;
238  }
239  }
240 }
241 
242 void
244  FaceCreateCallback callback)
245 {
246  m_netDeviceCallbacks.remove_if([&] (const std::pair<TypeId, FaceCreateCallback>& i) {
247  return (i.first == netDeviceType);
248  });
249 }
250 
251 std::string
252 constructFaceUri(Ptr<NetDevice> netDevice)
253 {
254  std::string uri = "netdev://";
255  Address address = netDevice->GetAddress();
256  if (Mac48Address::IsMatchingType(address)) {
257  uri += "[" + boost::lexical_cast<std::string>(Mac48Address::ConvertFrom(address)) + "]";
258  }
259 
260  return uri;
261 }
262 
263 
264 shared_ptr<Face>
265 StackHelper::DefaultNetDeviceCallback(Ptr<Node> node, Ptr<L3Protocol> ndn,
266  Ptr<NetDevice> netDevice) const
267 {
268  NS_LOG_DEBUG("Creating default Face on node " << node->GetId());
269 
270  // Create an ndnSIM-specific transport instance
272  opts.allowFragmentation = true;
273  opts.allowReassembly = true;
274  opts.allowCongestionMarking = true;
275 
276  auto linkService = make_unique<::nfd::face::GenericLinkService>(opts);
277 
278  auto transport = make_unique<NetDeviceTransport>(node, netDevice,
279  constructFaceUri(netDevice),
280  "netdev://[ff:ff:ff:ff:ff:ff]");
281 
282  auto face = std::make_shared<Face>(std::move(linkService), std::move(transport));
283  face->setMetric(1);
284 
285  ndn->addFace(face);
286  NS_LOG_LOGIC("Node " << node->GetId() << ": added Face as face #"
287  << face->getLocalUri());
288 
289  return face;
290 }
291 
292 shared_ptr<Face>
293 StackHelper::PointToPointNetDeviceCallback(Ptr<Node> node, Ptr<L3Protocol> ndn,
294  Ptr<NetDevice> device) const
295 {
296  NS_LOG_DEBUG("Creating point-to-point Face on node " << node->GetId());
297 
298  Ptr<PointToPointNetDevice> netDevice = DynamicCast<PointToPointNetDevice>(device);
299  NS_ASSERT(netDevice != nullptr);
300 
301  // access the other end of the link
302  Ptr<PointToPointChannel> channel = DynamicCast<PointToPointChannel>(netDevice->GetChannel());
303  NS_ASSERT(channel != nullptr);
304 
305  Ptr<NetDevice> remoteNetDevice = channel->GetDevice(0);
306  if (remoteNetDevice->GetNode() == node)
307  remoteNetDevice = channel->GetDevice(1);
308 
309  // Create an ndnSIM-specific transport instance
311  opts.allowFragmentation = true;
312  opts.allowReassembly = true;
313  opts.allowCongestionMarking = true;
314 
315  auto linkService = make_unique<::nfd::face::GenericLinkService>(opts);
316 
317  auto transport = make_unique<NetDeviceTransport>(node, netDevice,
318  constructFaceUri(netDevice),
319  constructFaceUri(remoteNetDevice));
320 
321  auto face = std::make_shared<Face>(std::move(linkService), std::move(transport));
322  face->setMetric(1);
323 
324  ndn->addFace(face);
325  NS_LOG_LOGIC("Node " << node->GetId() << ": added Face as face #"
326  << face->getLocalUri());
327 
328  return face;
329 }
330 
331 void
332 StackHelper::Install(const std::string& nodeName) const
333 {
334  Ptr<Node> node = Names::Find<Node>(nodeName);
335  Install(node);
336 }
337 
338 void
339 StackHelper::Update(Ptr<Node> node)
340 {
341  if (node->GetObject<L3Protocol>() == 0) {
342  Install(node);
343  return;
344  }
345 
346  Ptr<L3Protocol> ndn = node->GetObject<L3Protocol>();
347 
348  for (uint32_t index = 0; index < node->GetNDevices(); index++) {
349 
350  Ptr<NetDevice> device = node->GetDevice(index);
351 
352  if (ndn->getFaceByNetDevice(device) == nullptr) {
353  this->createAndRegisterFace(node, ndn, device);
354  }
355  }
356 }
357 
358 void
359 StackHelper::Update(const NodeContainer& c)
360 {
361  for (NodeContainer::Iterator i = c.Begin(); i != c.End(); ++i) {
362  Update(*i);
363  }
364 }
365 
366 void
367 StackHelper::Update(const std::string& nodeName)
368 {
369  Ptr<Node> node = Names::Find<Node>(nodeName);
370  Update(node);
371 }
372 
373 void
375 {
376  Update(NodeContainer::GetGlobal());
377 }
378 
379 shared_ptr<Face>
380 StackHelper::createAndRegisterFace(Ptr<Node> node, Ptr<L3Protocol> ndn, Ptr<NetDevice> device) const
381 {
382  shared_ptr<Face> face;
383 
384  for (const auto& item : m_netDeviceCallbacks) {
385  if (device->GetInstanceTypeId() == item.first ||
386  device->GetInstanceTypeId().IsChildOf(item.first)) {
387  face = item.second(node, ndn, device);
388  if (face != 0)
389  break;
390  }
391  }
392 
393  if (face == 0) {
394  face = DefaultNetDeviceCallback(node, ndn, device);
395  }
396 
397  if (m_needSetDefaultRoutes) {
398  // default route with lowest priority possible
399  FibHelper::AddRoute(node, "/", face, std::numeric_limits<int32_t>::max());
400  }
401  return face;
402 }
403 
404 void
406 {
407  m_isStrategyChoiceManagerDisabled = true;
408 }
409 
410 void
412 {
413  m_isForwarderStatusManagerDisabled = true;
414 }
415 
416 void
418 {
419  for (uint32_t i = 0; i < NodeList::GetNNodes(); ++i) {
420  auto ndn = NodeList::GetNode(i)->GetObject<L3Protocol>();
421  if (ndn == nullptr)
422  continue;
423 
424  for (auto& face : ndn->getForwarder()->getFaceTable()) {
425  auto transport = dynamic_cast<NetDeviceTransport*>(face.getTransport());
426  if (transport == nullptr)
427  continue;
428  auto p2p = dynamic_cast<PointToPointChannel*>(&(*(transport->GetNetDevice()->GetChannel())));
429  TimeValue currentDelay;
430  p2p->GetAttribute("Delay", currentDelay);
431  face.setMetric((currentDelay.Get().ToDouble(Time::S)) * 1000);
432 
433  std::cout << "Node " << i << ": Face " << face.getId()
434  << " with metric " << face.getMetric() << "\n";
435  }
436  }
437 }
438 
439 void
441 {
442  Simulator::Stop(Seconds(0));
443 #if HAVE_NS3_VISUALIZER
444  auto impl = DynamicCast<VisualSimulatorImpl>(Simulator::GetImplementation());
445  if (impl != nullptr) {
446  impl->RunRealSimulator();
447  }
448  else {
449  Simulator::Run();
450  }
451 #else
452  Simulator::Run();
453 #endif // HAVE_NS3_VISUALIZER
454 }
455 
456 
457 } // namespace ndn
458 } // 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'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's Content Store (in number of packets)
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.
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)
bool allowCongestionMarking
enables send queue congestion detection and marking
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...
void SetOldContentStore(const std::string &contentStoreClass, 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 ndnSIM 1.0 content store implementation and its attributes.
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
Options that control the behavior of GenericLinkService.
ndn cs ContentStore
Copyright (c) 2011-2015 Regents of the University of California.
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)
ndn security v2 KeyChain
Definition: key-chain.cpp:69
void disableStrategyChoiceManager()
Disable Strategy Choice Manager.