NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.0: 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/forwarder-status-manager.hpp"
46 // #include "ns3/ndnSIM/NFD/daemon/mgmt/general-config-section.hpp"
47 #include "ns3/ndnSIM/NFD/daemon/mgmt/tables-config-section.hpp"
48 #include "ns3/ndnSIM/NFD/daemon/mgmt/command-validator.hpp"
49 
50 #include "ns3/ndnSIM/NFD/rib/rib-manager.hpp"
51 
52 #include "ns3/ndnSIM/NFD/daemon/face/null-face.hpp"
53 #include "ns3/ndnSIM/NFD/daemon/face/internal-face.hpp"
54 
55 #include "ns3/ndnSIM/NFD/core/config-file.hpp"
56 
57 #include <ndn-cxx/mgmt/dispatcher.hpp>
58 
59 NS_LOG_COMPONENT_DEFINE("ndn.L3Protocol");
60 
61 namespace ns3 {
62 namespace ndn {
63 
64 const uint16_t L3Protocol::ETHERNET_FRAME_TYPE = 0x7777;
65 const uint16_t L3Protocol::IP_STACK_PORT = 9695;
66 
68 
69 TypeId
71 {
72  static TypeId tid =
73  TypeId("ns3::ndn::L3Protocol")
74  .SetGroupName("ndn")
75  .SetParent<Object>()
76  .AddConstructor<L3Protocol>()
77 
78  .AddTraceSource("OutInterests", "OutInterests",
79  MakeTraceSourceAccessor(&L3Protocol::m_outInterests),
80  "ns3::ndn::L3Protocol::InterestTraceCallback")
81  .AddTraceSource("InInterests", "InInterests",
82  MakeTraceSourceAccessor(&L3Protocol::m_inInterests),
83  "ns3::ndn::L3Protocol::InterestTraceCallback")
84 
86 
87  .AddTraceSource("OutData", "OutData", MakeTraceSourceAccessor(&L3Protocol::m_outData),
88  "ns3::ndn::L3Protocol::DataTraceCallback")
89  .AddTraceSource("InData", "InData", MakeTraceSourceAccessor(&L3Protocol::m_inData),
90  "ns3::ndn::L3Protocol::DataTraceCallback")
91 
93 
94  .AddTraceSource("SatisfiedInterests", "SatisfiedInterests",
95  MakeTraceSourceAccessor(&L3Protocol::m_satisfiedInterests),
96  "ns3::ndn::L3Protocol::SatisfiedInterestsCallback")
97  .AddTraceSource("TimedOutInterests", "TimedOutInterests",
98  MakeTraceSourceAccessor(&L3Protocol::m_timedOutInterests),
99  "ns3::ndn::L3Protocol::TimedOutInterestsCallback")
100  ;
101  return tid;
102 }
103 
105 private:
106  Impl()
107  {
108  // Do not modify initial config file. Use helpers to set specific NFD parameters
109  std::string initialConfig =
110  "general\n"
111  "{\n"
112  "}\n"
113  "\n"
114  "tables\n"
115  "{\n"
116  " cs_max_packets 100\n"
117  "\n"
118  " strategy_choice\n"
119  " {\n"
120  " / /localhost/nfd/strategy/best-route\n"
121  " /localhost /localhost/nfd/strategy/multicast\n"
122  " /localhost/nfd /localhost/nfd/strategy/best-route\n"
123  " /ndn/multicast /localhost/nfd/strategy/multicast\n"
124  " }\n"
125  "}\n"
126  "\n"
127  // "face_system\n"
128  // "{\n"
129  // "}\n"
130  "\n"
131  "authorizations\n"
132  "{\n"
133  " authorize\n"
134  " {\n"
135  " certfile any\n"
136  " privileges\n"
137  " {\n"
138  " faces\n"
139  " fib\n"
140  " strategy-choice\n"
141  " }\n"
142  " }\n"
143  "}\n"
144  "\n"
145  "rib\n"
146  "{\n"
147  " localhost_security\n"
148  " {\n"
149  " trust-anchor\n"
150  " {\n"
151  " type any\n"
152  " }\n"
153  " }\n"
154  "}\n"
155  "\n";
156 
157  std::istringstream input(initialConfig);
158  boost::property_tree::read_info(input, m_config);
159  }
160 
161  friend class L3Protocol;
162 
163  std::shared_ptr<nfd::Forwarder> m_forwarder;
164 
165  std::shared_ptr<nfd::Face> m_internalFace;
166  std::shared_ptr<::ndn::Face> m_internalClientFace;
167  std::unique_ptr<nfd::CommandValidator> m_validator;
168 
169  std::shared_ptr<nfd::Face> m_internalRibFace;
170  std::shared_ptr<::ndn::Face> m_internalRibClientFace;
171 
172  std::unique_ptr<::ndn::mgmt::Dispatcher> m_dispatcher;
173  std::shared_ptr<nfd::FibManager> m_fibManager;
174  std::shared_ptr<nfd::FaceManager> m_faceManager;
175  std::shared_ptr<nfd::StrategyChoiceManager> m_strategyChoiceManager;
176  std::shared_ptr<nfd::ForwarderStatusManager> m_forwarderStatusManager;
177  std::shared_ptr<nfd::rib::RibManager> m_ribManager;
178 
179  nfd::ConfigSection m_config;
180 
181  Ptr<ContentStore> m_csFromNdnSim;
182  PolicyCreationCallback m_policy;
183 };
184 
186  : m_impl(new Impl())
187 {
188  NS_LOG_FUNCTION(this);
189 }
190 
192 {
193  NS_LOG_FUNCTION(this);
194 }
195 
196 void
197 L3Protocol::initialize()
198 {
199  m_impl->m_forwarder = make_shared<nfd::Forwarder>();
200 
201  initializeManagement();
202 
203  nfd::FaceTable& faceTable = m_impl->m_forwarder->getFaceTable();
205  faceTable.addReserved(nfd::face::makeNullFace(FaceUri("contentstore://")), nfd::face::FACEID_CONTENT_STORE);
206 
207  if (!this->getConfig().get<bool>("ndnSIM.disable_rib_manager", false)) {
208  Simulator::ScheduleWithContext(m_node->GetId(), Seconds(0), &L3Protocol::initializeRibManager, this);
209  }
210 
211  m_impl->m_forwarder->beforeSatisfyInterest.connect(std::ref(m_satisfiedInterests));
212  m_impl->m_forwarder->beforeExpirePendingInterest.connect(std::ref(m_timedOutInterests));
213 }
214 
216 {
217 public:
218  IgnoreSections(const std::vector<std::string>& ignored)
219  : m_ignored(ignored)
220  {
221  }
222 
223  void
224  operator()(const std::string& filename, const std::string& sectionName,
225  const nfd::ConfigSection& section, bool isDryRun)
226 
227  {
228  if (std::find(m_ignored.begin(), m_ignored.end(), sectionName) == m_ignored.end()) {
229  nfd::ConfigFile::throwErrorOnUnknownSection(filename, sectionName, section, isDryRun);
230  }
231  }
232 private:
233  std::vector<std::string> m_ignored;
234 };
235 
236 void
238 {
239  m_impl->m_internalFace->sendInterest(interest);
240 }
241 
242 void
244 {
245  m_impl->m_policy = policy;
246 }
247 
248 void
249 L3Protocol::initializeManagement()
250 {
251  auto& forwarder = m_impl->m_forwarder;
252  using namespace nfd;
253 
254  std::tie(m_impl->m_internalFace, m_impl->m_internalClientFace) = face::makeInternalFace(StackHelper::getKeyChain());
255  forwarder->getFaceTable().addReserved(m_impl->m_internalFace, face::FACEID_INTERNAL_FACE);
256  m_impl->m_dispatcher.reset(new ::ndn::mgmt::Dispatcher(*m_impl->m_internalClientFace, StackHelper::getKeyChain()));
257 
258  m_impl->m_validator.reset(new CommandValidator());
259 
260  m_impl->m_fibManager.reset(new FibManager(forwarder->getFib(),
261  bind(&Forwarder::getFace, forwarder.get(), _1),
262  *m_impl->m_dispatcher,
263  *m_impl->m_validator));
264 
265  // Cannot be disabled for now
266  // if (!this->getConfig().get<bool>("ndnSIM.disable_face_manager", false)) {
267  m_impl->m_faceManager.reset(new FaceManager(forwarder->getFaceTable(),
268  *m_impl->m_dispatcher,
269  *m_impl->m_validator));
270  // }
271  // else {
272  // this->getConfig().get_child("authorizations").get_child("authorize").get_child("privileges").erase("faces");
273  // }
274 
275  if (!this->getConfig().get<bool>("ndnSIM.disable_strategy_choice_manager", false)) {
276  m_impl->m_strategyChoiceManager.reset(new StrategyChoiceManager(forwarder->getStrategyChoice(),
277  *m_impl->m_dispatcher,
278  *m_impl->m_validator));
279  }
280  else {
281  this->getConfig().get_child("authorizations").get_child("authorize").get_child("privileges").erase("strategy-choice");
282  }
283 
284  if (!this->getConfig().get<bool>("ndnSIM.disable_forwarder_status_manager", false)) {
285  m_impl->m_forwarderStatusManager.reset(new ForwarderStatusManager(*forwarder, *m_impl->m_dispatcher));
286  }
287 
288  ConfigFile config(&ConfigFile::ignoreUnknownSection);
289 
290  // if we use NFD's CS, we have to specify a replacement policy
291  m_impl->m_csFromNdnSim = GetObject<ContentStore>();
292  if (m_impl->m_csFromNdnSim == nullptr) {
293  forwarder->getCs().setPolicy(m_impl->m_policy());
294  }
295 
296  TablesConfigSection tablesConfig(forwarder->getCs(),
297  forwarder->getPit(),
298  forwarder->getFib(),
299  forwarder->getStrategyChoice(),
300  forwarder->getMeasurements(),
301  forwarder->getNetworkRegionTable());
302  tablesConfig.setConfigFile(config);
303 
304  m_impl->m_validator->setConfigFile(config);
305 
306  // if (!this->getConfig().get<bool>("ndnSIM.disable_face_manager", false)) {
307  m_impl->m_faceManager->setConfigFile(config);
308  // }
309 
310  // apply config
311  config.parse(m_impl->m_config, false, "ndnSIM.conf");
312 
313  tablesConfig.ensureTablesAreConfigured();
314 
315  // add FIB entry for NFD Management Protocol
316  Name topPrefix("/localhost/nfd");
317  auto entry = forwarder->getFib().insert(topPrefix).first;
318  entry->addNextHop(m_impl->m_internalFace, 0);
319  m_impl->m_dispatcher->addTopPrefix(topPrefix, false);
320 }
321 
322 void
323 L3Protocol::initializeRibManager()
324 {
325  using namespace nfd;
326 
327  std::tie(m_impl->m_internalRibFace, m_impl->m_internalRibClientFace) = face::makeInternalFace(StackHelper::getKeyChain());
328  m_impl->m_forwarder->getFaceTable().add(m_impl->m_internalRibFace);
329  m_impl->m_ribManager = make_shared<rib::RibManager>(*(m_impl->m_internalRibClientFace),
331 
332  ConfigFile config([] (const std::string& filename, const std::string& sectionName,
333  const ConfigSection& section, bool isDryRun) {
334  // Ignore "log" and sections belonging to NFD,
335  // but raise an error if we're missing a handler for a "rib" section.
336  if (sectionName != "rib" || sectionName == "log") {
337  // do nothing
338  }
339  else {
340  // missing RIB section
341  ConfigFile::throwErrorOnUnknownSection(filename, sectionName, section, isDryRun);
342  }
343  });
344 
345  m_impl->m_ribManager->setConfigFile(config);
346 
347  // apply config
348  config.parse(m_impl->m_config, false, "ndnSIM.conf");
349 
350  m_impl->m_ribManager->registerWithNfd();
351 
352  m_impl->m_ribManager->enableLocalControlHeader();
353 }
354 
355 shared_ptr<nfd::Forwarder>
357 {
358  return m_impl->m_forwarder;
359 }
360 
361 shared_ptr<nfd::FibManager>
363 {
364  return m_impl->m_fibManager;
365 }
366 
367 shared_ptr<nfd::StrategyChoiceManager>
369 {
370  return m_impl->m_strategyChoiceManager;
371 }
372 
375 {
376  return m_impl->m_config;
377 }
378 
379 /*
380  * This method is called by AddAgregate and completes the aggregation
381  * by setting the node in the ndn stack
382  */
383 void
385 {
386  if (m_node == nullptr) {
387  m_node = GetObject<Node>();
388  if (m_node != nullptr) {
389  initialize();
390 
391  NS_ASSERT(m_impl->m_forwarder != nullptr);
392  m_impl->m_csFromNdnSim = GetObject<ContentStore>();
393  if (m_impl->m_csFromNdnSim != nullptr) {
394  m_impl->m_forwarder->setCsFromNdnSim(m_impl->m_csFromNdnSim);
395  }
396  }
397  }
398 
399  Object::NotifyNewAggregate();
400 }
401 
402 void
404 {
405  NS_LOG_FUNCTION(this);
406 
407  // MUST HAPPEN BEFORE Simulator IS DESTROYED
408  m_impl.reset();
409 
410  nfd::scheduler::getGlobalScheduler().cancelAllEvents();
411 
412  m_node = 0;
413 
414  Object::DoDispose();
415 }
416 
418 L3Protocol::addFace(shared_ptr<Face> face)
419 {
420  NS_LOG_FUNCTION(this << face.get());
421 
422  m_impl->m_forwarder->addFace(face);
423 
424  std::weak_ptr<Face> weakFace = face;
425 
426  // // Connect Signals to TraceSource
427  face->afterReceiveInterest.connect([this, weakFace](const Interest& interest) {
428  shared_ptr<Face> face = weakFace.lock();
429  if (face != nullptr) {
430  this->m_inInterests(interest, *face);
431  }
432  });
433 
434  face->afterReceiveData.connect([this, weakFace](const Data& data) {
435  shared_ptr<Face> face = weakFace.lock();
436  if (face != nullptr) {
437  this->m_inData(data, *face);
438  }
439  });
440  // TODO Add nack signals
441 
442  auto tracingLink = face->getLinkService();
443  NS_LOG_LOGIC("Adding trace sources for afterSendInterest and afterSendData");
444  tracingLink->afterSendInterest.connect([this, weakFace](const Interest& interest) {
445  shared_ptr<Face> face = weakFace.lock();
446  if (face != nullptr) {
447  this->m_outInterests(interest, *face);
448  }
449  });
450 
451  tracingLink->afterSendData.connect([this, weakFace](const Data& data) {
452  shared_ptr<Face> face = weakFace.lock();
453  if (face != nullptr) {
454  this->m_outData(data, *face);
455  }
456  });
457 
458  // TODO Add nack signals
459 
460  return face->getId();
461 }
462 
463 shared_ptr<Face>
465 {
466  return m_impl->m_forwarder->getFaceTable().get(id);
467 }
468 
469 shared_ptr<Face>
470 L3Protocol::getFaceByNetDevice(Ptr<NetDevice> netDevice) const
471 {
472  for (const auto& i : m_impl->m_forwarder->getFaceTable()) {
473  auto linkService = dynamic_cast<NetDeviceLinkService*>(i->getLinkService());
474  if (linkService == nullptr)
475  continue;
476 
477  if (linkService->GetNetDevice() == netDevice)
478  return i;
479  }
480  return nullptr;
481 }
482 
483 Ptr<L3Protocol>
484 L3Protocol::getL3Protocol(Ptr<Object> node)
485 {
486  Ptr<L3Protocol> retval = node->GetObject<L3Protocol>();
487  NS_ASSERT_MSG(retval != nullptr, "L3Protocol is not aggregated on this object");
488  return retval;
489 }
490 
491 } // namespace ndn
492 } // namespace ns3
Implementation of layer-2 (Ethernet) LinkService (current hack, to be changed eventually) ...
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.
NS_OBJECT_ENSURE_REGISTERED(ContentStore)
nfd::ConfigSection & getConfig()
Get NFD config (boost::property_tree)
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
implement the Forwarder Status of NFD Management Protocol.
shared_ptr< nfd::FibManager > getFibManager()
Get smart pointer to nfd::FibManager, used by node&#39;s NFD.
virtual void NotifyNewAggregate()
This function will notify other components connected to the node that a new stack member is now conne...
FibManager
Definition: fib-manager.cpp:31
shared_ptr< Face > getFaceByNetDevice(Ptr< NetDevice > netDevice) const
Remove face from ndn stack (remove callbacks)
static TypeId GetTypeId()
Interface ID.
container of all Faces
Definition: face-table.hpp:38
void setCsReplacementPolicy(const PolicyCreationCallback &policy)
Set the replacement policy of NFD&#39;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.
boost::property_tree::ptree ConfigSection
L3Protocol()
Default constructor.
ndn L3Protocol
Copyright (c) 2011-2015 Regents of the University of California.
shared_ptr< nfd::StrategyChoiceManager > getStrategyChoiceManager()
Get smart pointer to nfd::StrategyChoiceManager, used by node&#39;s NFD.
Implementation network-layer of NDN stack.
static Ptr< L3Protocol > getL3Protocol(Ptr< Object > node)
Provides parsing for tables configuration file section.
virtual void DoDispose(void)
Do cleanup.
void injectInterest(const Interest &interest)
Inject interest through internal Face.
void addReserved(shared_ptr< Face > face, FaceId faceId)
add a special Face with a reserved FaceId
Definition: face-table.cpp:74
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
void parse(const std::string &filename, bool isDryRun)
Definition: config-file.cpp:86
void setConfigFile(ConfigFile &configFile)
const FaceId FACEID_CONTENT_STORE
identifies a packet comes from the ContentStore
Definition: face.hpp:46
shared_ptr< Face > getFaceById(nfd::FaceId face) const
Get face by face ID.
Scheduler & getGlobalScheduler()
Definition: scheduler.cpp:37