NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.5: NDN, CCN, CCNx, content centric networks
API Documentation
ndn-l3-protocol.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
20 #include "ndn-l3-protocol.hpp"
21 
22 #include "ns3/packet.h"
23 #include "ns3/node.h"
24 #include "ns3/log.h"
25 #include "ns3/callback.h"
26 #include "ns3/uinteger.h"
27 #include "ns3/trace-source-accessor.h"
28 #include "ns3/object-vector.h"
29 #include "ns3/pointer.h"
30 #include "ns3/simulator.h"
31 
33 
34 #include "../helper/ndn-stack-helper.hpp"
35 #include "cs/ndn-content-store.hpp"
36 
37 #include <boost/property_tree/info_parser.hpp>
38 
39 #include "ns3/ndnSIM/NFD/daemon/fw/forwarder.hpp"
40 #include "ns3/ndnSIM/NFD/daemon/face/internal-face.hpp"
41 #include "ns3/ndnSIM/NFD/daemon/face/internal-transport.hpp"
42 #include "ns3/ndnSIM/NFD/daemon/mgmt/fib-manager.hpp"
43 #include "ns3/ndnSIM/NFD/daemon/mgmt/face-manager.hpp"
44 #include "ns3/ndnSIM/NFD/daemon/mgmt/strategy-choice-manager.hpp"
45 #include "ns3/ndnSIM/NFD/daemon/mgmt/cs-manager.hpp"
46 #include "ns3/ndnSIM/NFD/daemon/mgmt/forwarder-status-manager.hpp"
47 // #include "ns3/ndnSIM/NFD/daemon/mgmt/general-config-section.hpp"
48 #include "ns3/ndnSIM/NFD/daemon/mgmt/tables-config-section.hpp"
49 #include "ns3/ndnSIM/NFD/daemon/mgmt/command-authenticator.hpp"
50 
51 #include "ns3/ndnSIM/NFD/rib/service.hpp"
52 
53 #include "ns3/ndnSIM/NFD/daemon/face/null-face.hpp"
54 #include "ns3/ndnSIM/NFD/daemon/face/internal-face.hpp"
55 
56 #include "ns3/ndnSIM/NFD/core/config-file.hpp"
57 
59 
60 NS_LOG_COMPONENT_DEFINE("ndn.L3Protocol");
61 
62 namespace ns3 {
63 namespace ndn {
64 
65 const uint16_t L3Protocol::ETHERNET_FRAME_TYPE = 0x7777;
66 const uint16_t L3Protocol::IP_STACK_PORT = 9695;
67 
69 
70 TypeId
72 {
73  static TypeId tid =
74  TypeId("ns3::ndn::L3Protocol")
75  .SetGroupName("ndn")
76  .SetParent<Object>()
77  .AddConstructor<L3Protocol>()
78 
79  .AddTraceSource("OutInterests", "OutInterests",
80  MakeTraceSourceAccessor(&L3Protocol::m_outInterests),
81  "ns3::ndn::L3Protocol::InterestTraceCallback")
82  .AddTraceSource("InInterests", "InInterests",
83  MakeTraceSourceAccessor(&L3Protocol::m_inInterests),
84  "ns3::ndn::L3Protocol::InterestTraceCallback")
85 
87 
88  .AddTraceSource("OutData", "OutData", MakeTraceSourceAccessor(&L3Protocol::m_outData),
89  "ns3::ndn::L3Protocol::DataTraceCallback")
90  .AddTraceSource("InData", "InData", MakeTraceSourceAccessor(&L3Protocol::m_inData),
91  "ns3::ndn::L3Protocol::DataTraceCallback")
92 
94 
95  .AddTraceSource("OutNack", "OutNack", MakeTraceSourceAccessor(&L3Protocol::m_outNack),
96  "ns3::ndn::L3Protocol::NackTraceCallback")
97  .AddTraceSource("InNack", "InNack", MakeTraceSourceAccessor(&L3Protocol::m_inNack),
98  "ns3::ndn::L3Protocol::NackTraceCallback")
99 
101 
102  .AddTraceSource("SatisfiedInterests", "SatisfiedInterests",
103  MakeTraceSourceAccessor(&L3Protocol::m_satisfiedInterests),
104  "ns3::ndn::L3Protocol::SatisfiedInterestsCallback")
105  .AddTraceSource("TimedOutInterests", "TimedOutInterests",
106  MakeTraceSourceAccessor(&L3Protocol::m_timedOutInterests),
107  "ns3::ndn::L3Protocol::TimedOutInterestsCallback")
108  ;
109  return tid;
110 }
111 
113 private:
114  Impl()
115  {
116  // Do not modify initial config file. Use helpers to set specific NFD parameters
117  std::string initialConfig =
118  "general\n"
119  "{\n"
120  "}\n"
121  "\n"
122  "tables\n"
123  "{\n"
124  " cs_max_packets 100\n"
125  "\n"
126  " strategy_choice\n"
127  " {\n"
128  " / /localhost/nfd/strategy/best-route\n"
129  " /localhost /localhost/nfd/strategy/multicast\n"
130  " /localhost/nfd /localhost/nfd/strategy/best-route\n"
131  " /ndn/multicast /localhost/nfd/strategy/multicast\n"
132  " }\n"
133  "}\n"
134  "\n"
135  // "face_system\n"
136  // "{\n"
137  // "}\n"
138  "\n"
139  "authorizations\n"
140  "{\n"
141  " authorize\n"
142  " {\n"
143  " certfile any\n"
144  " privileges\n"
145  " {\n"
146  " faces\n"
147  " fib\n"
148  " strategy-choice\n"
149  " }\n"
150  " }\n"
151  "}\n"
152  "\n"
153  "rib\n"
154  "{\n"
155  " localhost_security\n"
156  " {\n"
157  " trust-anchor\n"
158  " {\n"
159  " type any\n"
160  " }\n"
161  " }\n"
162  "}\n"
163  "\n";
164 
165  std::istringstream input(initialConfig);
166  boost::property_tree::read_info(input, m_config);
167  }
168 
169  friend class L3Protocol;
170 
171  // note that shared_ptr needed for Python bindings
172 
173  std::shared_ptr<::nfd::Forwarder> m_forwarder;
174  std::unique_ptr<::nfd::face::FaceSystem> m_faceSystem;
175 
176  std::shared_ptr<::nfd::face::Face> m_internalFace;
177  std::shared_ptr<::ndn::Face> m_internalClientFace;
178  std::unique_ptr<::ndn::mgmt::Dispatcher> m_dispatcher;
179  std::shared_ptr<::nfd::CommandAuthenticator> m_authenticator;
180  std::unique_ptr<::nfd::ForwarderStatusManager> m_forwarderStatusManager;
181  std::unique_ptr<::nfd::FaceManager> m_faceManager;
182  std::shared_ptr<::nfd::FibManager> m_fibManager;
183  std::unique_ptr<::nfd::CsManager> m_csManager;
184  std::unique_ptr<::nfd::StrategyChoiceManager> m_strategyChoiceManager;
185 
186  std::shared_ptr<::nfd::face::Face> m_internalFaceForInjects;
187  std::shared_ptr<::ndn::Face> m_internalClientFaceForInjects;
188 
189  std::shared_ptr<::nfd::Face> m_internalRibFace;
190  std::shared_ptr<::ndn::Face> m_internalRibClientFace;
191  std::unique_ptr<::nfd::rib::Service> m_ribService;
192 
193  nfd::ConfigSection m_config;
194 
195  Ptr<ContentStore> m_csFromNdnSim;
196  PolicyCreationCallback m_policy;
197 };
198 
200  : m_impl(new Impl())
201 {
202  NS_LOG_FUNCTION(this);
203 }
204 
206 {
207  NS_LOG_FUNCTION(this);
208 }
209 
210 void
211 L3Protocol::initialize()
212 {
213  m_impl->m_forwarder = make_shared<::nfd::Forwarder>();
214 
215  ::nfd::FaceTable& faceTable = m_impl->m_forwarder->getFaceTable();
217  // faceTable.addReserved(face::makeNullFace(FaceUri("contentstore://")), face::FACEID_CONTENT_STORE);
218  m_impl->m_faceSystem = make_unique<::nfd::face::FaceSystem>(faceTable, nullptr);
219 
220  initializeManagement();
221  initializeRibManager();
222 
223  m_impl->m_forwarder->beforeSatisfyInterest.connect(std::ref(m_satisfiedInterests));
224  m_impl->m_forwarder->beforeExpirePendingInterest.connect(std::ref(m_timedOutInterests));
225 }
226 
228 {
229 public:
230  IgnoreSections(const std::vector<std::string>& ignored)
231  : m_ignored(ignored)
232  {
233  }
234 
235  void
236  operator()(const std::string& filename, const std::string& sectionName,
237  const nfd::ConfigSection& section, bool isDryRun)
238 
239  {
240  if (std::find(m_ignored.begin(), m_ignored.end(), sectionName) == m_ignored.end()) {
241  nfd::ConfigFile::throwErrorOnUnknownSection(filename, sectionName, section, isDryRun);
242  }
243  }
244 private:
245  std::vector<std::string> m_ignored;
246 };
247 
248 void
250 {
251  m_impl->m_internalClientFaceForInjects->expressInterest(interest, nullptr, nullptr, nullptr);
252 }
253 
254 void
256 {
257  m_impl->m_policy = policy;
258 }
259 
260 void
261 L3Protocol::initializeManagement()
262 {
263  auto& forwarder = m_impl->m_forwarder;
264  using namespace nfd;
265 
266  std::tie(m_impl->m_internalFace, m_impl->m_internalClientFace) = face::makeInternalFace(StackHelper::getKeyChain());
267  forwarder->getFaceTable().addReserved(m_impl->m_internalFace, face::FACEID_INTERNAL_FACE);
268 
269  std::tie(m_impl->m_internalFaceForInjects, m_impl->m_internalClientFaceForInjects) = face::makeInternalFace(StackHelper::getKeyChain());
270  forwarder->getFaceTable().addReserved(m_impl->m_internalFaceForInjects, face::FACEID_INTERNAL_FACE + 1);
271 
272  m_impl->m_dispatcher = make_unique<::ndn::mgmt::Dispatcher>(*m_impl->m_internalClientFace, StackHelper::getKeyChain());
273  m_impl->m_authenticator = ::nfd::CommandAuthenticator::create();
274 
275  if (!this->getConfig().get<bool>("ndnSIM.disable_forwarder_status_manager", false)) {
276  m_impl->m_forwarderStatusManager = make_unique<::nfd::ForwarderStatusManager>(*m_impl->m_forwarder, *m_impl->m_dispatcher);
277  }
278  m_impl->m_faceManager = make_unique<::nfd::FaceManager>(*m_impl->m_faceSystem, *m_impl->m_dispatcher, *m_impl->m_authenticator);
279  m_impl->m_fibManager = make_shared<::nfd::FibManager>(m_impl->m_forwarder->getFib(), m_impl->m_forwarder->getFaceTable(),
280  *m_impl->m_dispatcher, *m_impl->m_authenticator);
281  m_impl->m_csManager = make_unique<::nfd::CsManager>(m_impl->m_forwarder->getCs(), m_impl->m_forwarder->getCounters(),
282  *m_impl->m_dispatcher, *m_impl->m_authenticator);
283  if (!this->getConfig().get<bool>("ndnSIM.disable_strategy_choice_manager", false)) {
284  m_impl->m_strategyChoiceManager = make_unique<::nfd::StrategyChoiceManager>(m_impl->m_forwarder->getStrategyChoice(),
285  *m_impl->m_dispatcher, *m_impl->m_authenticator);
286 
287  }
288  else {
289  this->getConfig().get_child("authorizations").get_child("authorize").get_child("privileges").erase("strategy-choice");
290  }
291 
292  ConfigFile config(&ConfigFile::ignoreUnknownSection);
293 
294  // if we use NFD's CS, we have to specify a replacement policy
295  m_impl->m_csFromNdnSim = GetObject<ContentStore>();
296  if (m_impl->m_csFromNdnSim == nullptr) {
297  forwarder->getCs().setPolicy(m_impl->m_policy());
298  }
299 
300  TablesConfigSection tablesConfig(*forwarder);
301  tablesConfig.setConfigFile(config);
302 
303  m_impl->m_authenticator->setConfigFile(config);
304 
305  // if (!this->getConfig().get<bool>("ndnSIM.disable_face_manager", false)) {
306  m_impl->m_faceSystem->setConfigFile(config);
307  // }
308 
309  // apply config
310  config.parse(m_impl->m_config, false, "ndnSIM.conf");
311 
312  tablesConfig.ensureConfigured();
313 
314  // add FIB entry for NFD Management Protocol
315  Name topPrefix("/localhost/nfd");
316  m_impl->m_forwarder->getFib().insert(topPrefix).first->addOrUpdateNextHop(*m_impl->m_internalFace, 0, 0);
317  m_impl->m_dispatcher->addTopPrefix(topPrefix, false);
318 }
319 
320 void
321 L3Protocol::initializeRibManager()
322 {
323  using namespace nfd;
324 
325  std::tie(m_impl->m_internalRibFace, m_impl->m_internalRibClientFace) = face::makeInternalFace(StackHelper::getKeyChain());
326  m_impl->m_forwarder->getFaceTable().add(m_impl->m_internalRibFace);
327 
328  m_impl->m_ribService = make_unique<rib::Service>(m_impl->m_config,
329  std::ref(*m_impl->m_internalRibClientFace),
330  std::ref(StackHelper::getKeyChain()));
331 }
332 
333 shared_ptr<nfd::Forwarder>
335 {
336  return m_impl->m_forwarder;
337 }
338 
339 shared_ptr<nfd::FibManager>
341 {
342  return m_impl->m_fibManager;
343 }
344 
347 {
348  return *m_impl->m_strategyChoiceManager;
349 }
350 
353 {
354  return *m_impl->m_ribService;
355 }
356 
359 {
360  return m_impl->m_config;
361 }
362 
363 /*
364  * This method is called by AddAgregate and completes the aggregation
365  * by setting the node in the ndn stack
366  */
367 void
369 {
370  if (m_node == nullptr) {
371  m_node = GetObject<Node>();
372  if (m_node != nullptr) {
373  initialize();
374 
375  NS_ASSERT(m_impl->m_forwarder != nullptr);
376  m_impl->m_csFromNdnSim = GetObject<ContentStore>();
377  if (m_impl->m_csFromNdnSim != nullptr) {
378  m_impl->m_forwarder->setCsFromNdnSim(m_impl->m_csFromNdnSim);
379  }
380  }
381  }
382 
383  Object::NotifyNewAggregate();
384 }
385 
386 void
388 {
389  NS_LOG_FUNCTION(this);
390 
391  // MUST HAPPEN BEFORE Simulator IS DESTROYED
392  m_impl.reset();
393 
395 
396  m_node = 0;
397 
398  Object::DoDispose();
399 }
400 
402 L3Protocol::addFace(shared_ptr<Face> face)
403 {
404  NS_LOG_FUNCTION(this << face.get());
405 
406  m_impl->m_forwarder->addFace(face);
407 
408  std::weak_ptr<Face> weakFace = face;
409 
410  // // Connect Signals to TraceSource
411  face->afterReceiveInterest.connect([this, weakFace](const Interest& interest) {
412  shared_ptr<Face> face = weakFace.lock();
413  if (face != nullptr) {
414  this->m_inInterests(interest, *face);
415  }
416  });
417 
418  face->afterReceiveData.connect([this, weakFace](const Data& data) {
419  shared_ptr<Face> face = weakFace.lock();
420  if (face != nullptr) {
421  this->m_inData(data, *face);
422  }
423  });
424 
425  face->afterReceiveNack.connect([this, weakFace](const lp::Nack& nack) {
426  shared_ptr<Face> face = weakFace.lock();
427  if (face != nullptr) {
428  this->m_inNack(nack, *face);
429  }
430  });
431 
432  auto tracingLink = face->getLinkService();
433  NS_LOG_LOGIC("Adding trace sources for afterSendInterest and afterSendData");
434  tracingLink->afterSendInterest.connect([this, weakFace](const Interest& interest) {
435  shared_ptr<Face> face = weakFace.lock();
436  if (face != nullptr) {
437  this->m_outInterests(interest, *face);
438  }
439  });
440 
441  tracingLink->afterSendData.connect([this, weakFace](const Data& data) {
442  shared_ptr<Face> face = weakFace.lock();
443  if (face != nullptr) {
444  this->m_outData(data, *face);
445  }
446  });
447 
448  tracingLink->afterSendNack.connect([this, weakFace](const lp::Nack& nack) {
449  shared_ptr<Face> face = weakFace.lock();
450  if (face != nullptr) {
451  this->m_outNack(nack, *face);
452  }
453  });
454 
455  return face->getId();
456 }
457 
458 shared_ptr<Face>
460 {
461  return m_impl->m_forwarder->getFaceTable().get(id)->shared_from_this();
462 }
463 
464 shared_ptr<Face>
465 L3Protocol::getFaceByNetDevice(Ptr<NetDevice> netDevice) const
466 {
467  for (auto& i : m_impl->m_forwarder->getFaceTable()) {
468  auto transport = dynamic_cast<NetDeviceTransport*>(i.getTransport());
469  if (transport == nullptr)
470  continue;
471 
472  if (transport->GetNetDevice() == netDevice)
473  return i.shared_from_this();
474  }
475  return nullptr;
476 }
477 
478 Ptr<L3Protocol>
479 L3Protocol::getL3Protocol(Ptr<Object> node)
480 {
481  Ptr<L3Protocol> retval = node->GetObject<L3Protocol>();
482  NS_ASSERT_MSG(retval != nullptr, "L3Protocol is not aggregated on this object");
483  return retval;
484 }
485 
486 } // namespace ndn
487 } // namespace ns3
static const uint16_t IP_STACK_PORT
TCP/UDP port for NDN stack.
Copyright (c) 2011-2015 Regents of the University of California.
shared_ptr< Face > makeNullFace(const FaceUri &uri)
Definition: null-face.cpp:37
std::tuple< shared_ptr< Face >, shared_ptr< ndn::Face > > makeInternalFace(ndn::KeyChain &clientKeyChain)
make a pair of forwarder-side face and client-side face that are connected with each other
shared_ptr< nfd::Forwarder > getForwarder()
Get smart pointer to nfd::Forwarder installed on the node.
static const uint16_t ETHERNET_FRAME_TYPE
Ethernet Frame Type of Ndn.
initializes and executes NFD-RIB service thread
Definition: service.hpp:51
NS_OBJECT_ENSURE_REGISTERED(ContentStore)
implement the Strategy Choice Management of NFD Management Protocol.
nfd::ConfigSection & getConfig()
Get NFD config (boost::property_tree)
configuration file parsing utility
Definition: config-file.hpp:57
const FaceId FACEID_INTERNAL_FACE
identifies the InternalFace used in management
Definition: face.hpp:44
void operator()(const std::string &filename, const std::string &sectionName, const nfd::ConfigSection &section, bool isDryRun)
std::function< std::unique_ptr< nfd::cs::Policy >)> PolicyCreationCallback
shared_ptr< nfd::FibManager > getFibManager()
Get smart pointer to nfd::FibManager, used by node's NFD.
virtual void NotifyNewAggregate()
This function will notify other components connected to the node that a new stack member is now conne...
shared_ptr< Face > getFaceByNetDevice(Ptr< NetDevice > netDevice) const
Remove face from ndn stack (remove callbacks)
represents a Network Nack
Definition: nack.hpp:38
static TypeId GetTypeId()
Interface ID.
::nfd::rib::Service & getRibService()
container of all faces
Definition: face-table.hpp:37
void setCsReplacementPolicy(const PolicyCreationCallback &policy)
Set the replacement policy of NFD's CS.
static void throwErrorOnUnknownSection(const std::string &filename, const std::string &sectionName, const ConfigSection &section, bool isDryRun)
Definition: config-file.cpp:40
Copyright (c) 2011-2015 Regents of the University of California.
Definition: ndn-common.hpp:40
nfd::FaceId addFace(shared_ptr< Face > face)
Add face to NDN stack.
Copyright (c) 2011-2015 Regents of the University of California.
void resetGlobalScheduler()
Definition: scheduler.cpp:54
boost::property_tree::ptree ConfigSection
a config file section
L3Protocol()
Default constructor.
ndn L3Protocol
Copyright (c) 2011-2015 Regents of the University of California.
Implementation network-layer of NDN stack.
static Ptr< L3Protocol > getL3Protocol(Ptr< Object > node)
handles 'tables' config section
virtual void DoDispose(void)
Do cleanup.
nfd::StrategyChoiceManager & getStrategyChoiceManager()
Get nfd::StrategyChoiceManager, used by node's NFD.
void injectInterest(const Interest &interest)
Inject interest through internal Face.
static shared_ptr< CommandAuthenticator > create()
void addReserved(shared_ptr< Face > face, FaceId faceId)
add a special face with a reserved FaceId
Definition: face-table.cpp:71
IgnoreSections(const std::vector< std::string > &ignored)
static KeyChain & getKeyChain()
const FaceId FACEID_NULL
identifies the NullFace that drops every packet
Definition: face.hpp:48
uint64_t FaceId
identifies a face
Definition: face.hpp:39
shared_ptr< Face > getFaceById(nfd::FaceId face) const
Get face by face ID.