NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.0: NDN, CCN, CCNx, content centric networks
API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
fib-manager.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
26 #include "fib-manager.hpp"
27 
28 #include "core/logger.hpp"
29 #include "table/fib.hpp"
30 #include "fw/forwarder.hpp"
31 #include "mgmt/internal-face.hpp"
32 #include "mgmt/app-face.hpp"
33 
34 #include <ndn-cxx/encoding/tlv.hpp>
35 
36 namespace nfd {
37 
38 NFD_LOG_INIT("FibManager");
39 
40 const Name FibManager::COMMAND_PREFIX = "/localhost/nfd/fib";
41 
42 const size_t FibManager::COMMAND_UNSIGNED_NCOMPS =
43  FibManager::COMMAND_PREFIX.size() +
44  1 + // verb
45  1; // verb parameters
46 
47 const size_t FibManager::COMMAND_SIGNED_NCOMPS =
48  FibManager::COMMAND_UNSIGNED_NCOMPS +
49  4; // (timestamp, nonce, signed info tlv, signature tlv)
50 
51 const FibManager::SignedVerbAndProcessor FibManager::SIGNED_COMMAND_VERBS[] =
52  {
53 
54  SignedVerbAndProcessor(
55  Name::Component("add-nexthop"),
56  &FibManager::addNextHop
57  ),
58 
59  SignedVerbAndProcessor(
60  Name::Component("remove-nexthop"),
61  &FibManager::removeNextHop
62  ),
63 
64  };
65 
66 const FibManager::UnsignedVerbAndProcessor FibManager::UNSIGNED_COMMAND_VERBS[] =
67  {
68  UnsignedVerbAndProcessor(
69  Name::Component("list"),
70  &FibManager::listEntries
71  ),
72  };
73 
74 const Name FibManager::LIST_COMMAND_PREFIX("/localhost/nfd/fib/list");
75 const size_t FibManager::LIST_COMMAND_NCOMPS = LIST_COMMAND_PREFIX.size();
76 
77 
79  function<shared_ptr<Face>(FaceId)> getFace,
80  shared_ptr<InternalFace> face,
81  ndn::KeyChain& keyChain)
82  : ManagerBase(face, FIB_PRIVILEGE, keyChain)
83  , m_managedFib(fib)
84  , m_getFace(getFace)
85  , m_fibEnumerationPublisher(fib, *face, LIST_COMMAND_PREFIX, keyChain)
86  , m_signedVerbDispatch(SIGNED_COMMAND_VERBS,
87  SIGNED_COMMAND_VERBS +
88  (sizeof(SIGNED_COMMAND_VERBS) / sizeof(SignedVerbAndProcessor)))
89  , m_unsignedVerbDispatch(UNSIGNED_COMMAND_VERBS,
90  UNSIGNED_COMMAND_VERBS +
91  (sizeof(UNSIGNED_COMMAND_VERBS) / sizeof(UnsignedVerbAndProcessor)))
92 {
93  face->setInterestFilter("/localhost/nfd/fib",
94  bind(&FibManager::onFibRequest, this, _2));
95 }
96 
98 {
99 
100 }
101 
102 void
103 FibManager::onFibRequest(const Interest& request)
104 {
105  const Name& command = request.getName();
106  const size_t commandNComps = command.size();
107 
108  if (commandNComps <= COMMAND_PREFIX.size())
109  {
110  // command is too short to have a verb
111  NFD_LOG_DEBUG("command result: malformed");
112  sendResponse(command, 400, "Malformed command");
113  return;
114  }
115 
116  const Name::Component& verb = command.at(COMMAND_PREFIX.size());
117 
118  const auto unsignedVerbProcessor = m_unsignedVerbDispatch.find(verb);
119  if (unsignedVerbProcessor != m_unsignedVerbDispatch.end())
120  {
121  NFD_LOG_DEBUG("command result: processing verb: " << verb);
122  (unsignedVerbProcessor->second)(this, request);
123  }
124  else if (COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
125  commandNComps < COMMAND_SIGNED_NCOMPS)
126  {
127  NFD_LOG_DEBUG("command result: unsigned verb: " << command);
128  sendResponse(command, 401, "Signature required");
129  }
130  else if (commandNComps < COMMAND_SIGNED_NCOMPS ||
131  !COMMAND_PREFIX.isPrefixOf(command))
132  {
133  NFD_LOG_DEBUG("command result: malformed");
134  sendResponse(command, 400, "Malformed command");
135  }
136  else
137  {
138  validate(request,
139  bind(&FibManager::onValidatedFibRequest, this, _1),
140  bind(&ManagerBase::onCommandValidationFailed, this, _1, _2));
141  }
142 }
143 
144 void
145 FibManager::onValidatedFibRequest(const shared_ptr<const Interest>& request)
146 {
147  const Name& command = request->getName();
148  const Name::Component& verb = command[COMMAND_PREFIX.size()];
149  const Name::Component& parameterComponent = command[COMMAND_PREFIX.size() + 1];
150 
151  SignedVerbDispatchTable::const_iterator verbProcessor = m_signedVerbDispatch.find(verb);
152  if (verbProcessor != m_signedVerbDispatch.end())
153  {
154  ControlParameters parameters;
155  if (!extractParameters(parameterComponent, parameters))
156  {
157  NFD_LOG_DEBUG("command result: malformed verb: " << verb);
158  sendResponse(command, 400, "Malformed command");
159  return;
160  }
161 
162  bool isSelfRegistration = (!parameters.hasFaceId() || parameters.getFaceId() == 0);
163  if (isSelfRegistration)
164  {
165  parameters.setFaceId(request->getIncomingFaceId());
166  }
167 
168  NFD_LOG_DEBUG("command result: processing verb: " << verb);
169  ControlResponse response;
170  (verbProcessor->second)(this, parameters, response);
171  sendResponse(command, response);
172  }
173  else
174  {
175  NFD_LOG_DEBUG("command result: unsupported verb: " << verb);
176  sendResponse(command, 501, "Unsupported command");
177  }
178 }
179 
180 void
181 FibManager::addNextHop(ControlParameters& parameters,
182  ControlResponse& response)
183 {
184  ndn::nfd::FibAddNextHopCommand command;
185 
186  if (!validateParameters(command, parameters))
187  {
188  NFD_LOG_DEBUG("add-nexthop result: FAIL reason: malformed");
189  setResponse(response, 400, "Malformed command");
190  return;
191  }
192 
193  const Name& prefix = parameters.getName();
194  FaceId faceId = parameters.getFaceId();
195  uint64_t cost = parameters.getCost();
196 
197  NFD_LOG_TRACE("add-nexthop prefix: " << prefix
198  << " faceid: " << faceId
199  << " cost: " << cost);
200 
201  shared_ptr<Face> nextHopFace = m_getFace(faceId);
202  if (static_cast<bool>(nextHopFace))
203  {
204  shared_ptr<fib::Entry> entry = m_managedFib.insert(prefix).first;
205 
206  entry->addNextHop(nextHopFace, cost);
207 
208  NFD_LOG_DEBUG("add-nexthop result: OK"
209  << " prefix:" << prefix
210  << " faceid: " << faceId
211  << " cost: " << cost);
212 
213  setResponse(response, 200, "Success", parameters.wireEncode());
214  }
215  else
216  {
217  NFD_LOG_DEBUG("add-nexthop result: FAIL reason: unknown-faceid: " << faceId);
218  setResponse(response, 410, "Face not found");
219  }
220 }
221 
222 void
223 FibManager::removeNextHop(ControlParameters& parameters,
224  ControlResponse& response)
225 {
226  ndn::nfd::FibRemoveNextHopCommand command;
227  if (!validateParameters(command, parameters))
228  {
229  NFD_LOG_DEBUG("remove-nexthop result: FAIL reason: malformed");
230  setResponse(response, 400, "Malformed command");
231  return;
232  }
233 
234  NFD_LOG_TRACE("remove-nexthop prefix: " << parameters.getName()
235  << " faceid: " << parameters.getFaceId());
236 
237  shared_ptr<Face> faceToRemove = m_getFace(parameters.getFaceId());
238  if (static_cast<bool>(faceToRemove))
239  {
240  shared_ptr<fib::Entry> entry = m_managedFib.findExactMatch(parameters.getName());
241  if (static_cast<bool>(entry))
242  {
243  entry->removeNextHop(faceToRemove);
244  NFD_LOG_DEBUG("remove-nexthop result: OK prefix: " << parameters.getName()
245  << " faceid: " << parameters.getFaceId());
246 
247  if (!entry->hasNextHops())
248  {
249  m_managedFib.erase(*entry);
250  }
251  }
252  else
253  {
254  NFD_LOG_DEBUG("remove-nexthop result: OK, but entry for face id "
255  << parameters.getFaceId() << " not found");
256  }
257  }
258  else
259  {
260  NFD_LOG_DEBUG("remove-nexthop result: OK, but face id "
261  << parameters.getFaceId() << " not found");
262  }
263 
264  setResponse(response, 200, "Success", parameters.wireEncode());
265 }
266 
267 void
268 FibManager::listEntries(const Interest& request)
269 {
270  const Name& command = request.getName();
271  const size_t commandNComps = command.size();
272 
273  if (commandNComps < LIST_COMMAND_NCOMPS ||
274  !LIST_COMMAND_PREFIX.isPrefixOf(command))
275  {
276  NFD_LOG_DEBUG("command result: malformed");
277  sendResponse(command, 400, "Malformed command");
278  return;
279  }
280 
281  m_fibEnumerationPublisher.publish();
282 }
283 
284 } // namespace nfd
#define NFD_LOG_DEBUG(expression)
Definition: logger.hpp:36
std::pair< shared_ptr< fib::Entry >, bool > insert(const Name &prefix)
inserts a FIB entry for prefix If an entry for exact same prefix exists, that entry is returned...
Definition: fib.cpp:120
void sendResponse(const Name &name, const ControlResponse &response)
represents the FIB
Definition: fib.hpp:44
virtual ~FibManager()
Definition: fib-manager.cpp:97
FibManager(Fib &fib, function< shared_ptr< Face >(FaceId)> getFace, shared_ptr< InternalFace > face, ndn::KeyChain &keyChain)
Definition: fib-manager.cpp:78
static bool extractParameters(const Name::Component &parameterComponent, ControlParameters &extractedParameters)
const std::string FIB_PRIVILEGE
Definition: fib-manager.hpp:39
void erase(const Name &prefix)
Definition: fib.cpp:141
shared_ptr< fib::Entry > findExactMatch(const Name &prefix) const
Definition: fib.cpp:111
void onCommandValidationFailed(const shared_ptr< const Interest > &command, const std::string &error)
identifies a face
void onFibRequest(const Interest &request)
#define NFD_LOG_INIT(name)
Definition: logger.hpp:33
#define NFD_LOG_TRACE(expression)
Definition: logger.hpp:35
void setResponse(ControlResponse &response, uint32_t code, const std::string &text)
virtual bool validateParameters(const ControlCommand &command, ControlParameters &parameters)
void validate(const Interest &interest, const ndn::OnInterestValidated &onValidated, const ndn::OnInterestValidationFailed &onValidationFailed)