blob: 3bcbb1a5c3cd59083a2ebc6d47faeb9e064718f2 [file] [log] [blame]
Steve DiBenedetto042bfe92014-01-30 15:05:08 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
7#include "fib-manager.hpp"
8
9#include "table/fib.hpp"
10#include "fw/forwarder.hpp"
11#include "mgmt/internal-face.hpp"
12#include "mgmt/app-face.hpp"
13
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070014#include <ndn-cpp-dev/management/fib-management-options.hpp>
15#include <ndn-cpp-dev/encoding/tlv.hpp>
16
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070017
18namespace nfd {
19
20NFD_LOG_INIT("FibManager");
21
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070022const Name FibManager::FIB_MANAGER_COMMAND_PREFIX = "/localhost/nfd/fib";
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070023
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070024const size_t FibManager::FIB_MANAGER_COMMAND_UNSIGNED_NCOMPS =
25 FibManager::FIB_MANAGER_COMMAND_PREFIX.size() +
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070026 1 + // verb
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070027 1; // verb options
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070028
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070029const size_t FibManager::FIB_MANAGER_COMMAND_SIGNED_NCOMPS =
30 FibManager::FIB_MANAGER_COMMAND_UNSIGNED_NCOMPS +
31 0; // No signed Interest support in mock, otherwise 3 (timestamp, signed info tlv, signature tlv)
32
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070033const FibManager::VerbAndProcessor FibManager::FIB_MANAGER_COMMAND_VERBS[] =
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070034 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070035 VerbAndProcessor(
36 "insert",
37 &FibManager::insertEntry
38 ),
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070039
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070040 VerbAndProcessor(
41 "delete",
42 &FibManager::deleteEntry
43 ),
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070044
45 VerbAndProcessor(
Steve DiBenedettobdedce92014-02-02 22:49:39 -070046 "add-nexthop",
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070047 &FibManager::addNextHop
48 ),
49
50
51
52 VerbAndProcessor(
53 "remove-nexthop",
54 &FibManager::removeNextHop
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070055 ),
56
57 // Unsupported
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070058 // VerbAndProcessor(
Steve DiBenedettobdedce92014-02-02 22:49:39 -070059 // "strategy",
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070060 // &FibManager::strategy
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070061 // )
62
63 };
64
65FibManager::FibManager(Fib& fib,
Steve DiBenedetto3970c892014-01-31 23:31:13 -070066 function<shared_ptr<Face>(FaceId)> getFace,
67 shared_ptr<AppFace> face)
68 : ManagerBase(face),
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070069 m_managedFib(fib),
70 m_getFace(getFace),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070071 m_verbDispatch(FIB_MANAGER_COMMAND_VERBS,
72 FIB_MANAGER_COMMAND_VERBS +
73 (sizeof(FIB_MANAGER_COMMAND_VERBS) / sizeof(VerbAndProcessor)))
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070074{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070075 face->setInterestFilter("/localhost/nfd/fib",
76 bind(&FibManager::onFibRequest, this, _2));
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070077}
78
79void
80FibManager::onFibRequest(const Interest& request)
81{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070082 const Name& command = request.getName();
83 const size_t commandNComps = command.size();
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070084
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070085 if (FIB_MANAGER_COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
86 commandNComps < FIB_MANAGER_COMMAND_SIGNED_NCOMPS)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070087 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070088 NFD_LOG_INFO("command result: unsigned verb: " << command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -070089 sendResponse(command, 401, "Signature required");
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070090
91 return;
92 }
93 else if (commandNComps < FIB_MANAGER_COMMAND_SIGNED_NCOMPS ||
94 !FIB_MANAGER_COMMAND_PREFIX.isPrefixOf(command))
95 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070096 NFD_LOG_INFO("command result: malformed");
Steve DiBenedettobdedce92014-02-02 22:49:39 -070097 sendResponse(command, 400, "Malformed command");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070098 return;
99 }
100
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700101 const Name::Component& verb = command.get(FIB_MANAGER_COMMAND_PREFIX.size());
102
103 VerbDispatchTable::const_iterator verbProcessor = m_verbDispatch.find (verb);
104 if (verbProcessor != m_verbDispatch.end())
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700105 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700106 ndn::FibManagementOptions options;
107 if (!extractOptions(request, options))
108 {
109 sendResponse(command, 400, "Malformed command");
110 return;
111 }
112
113 /// \todo authorize command
114 if (false)
115 {
116 NFD_LOG_INFO("command result: unauthorized verb: " << command);
117 sendResponse(request.getName(), 403, "Unauthorized command");
118 return;
119 }
120
121 NFD_LOG_INFO("command result: processing verb: " << verb);
122
123 ndn::ControlResponse response;
124 (verbProcessor->second)(this, options, response);
125
126 sendResponse(command, response);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700127 }
128 else
129 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700130 NFD_LOG_INFO("command result: unsupported verb: " << verb);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700131 sendResponse(request.getName(), 501, "Unsupported command");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700132 }
133
134}
135
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700136bool
137FibManager::extractOptions(const Interest& request,
138 ndn::FibManagementOptions& extractedOptions)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700139{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700140 const Name& command = request.getName();
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700141 const size_t optionCompIndex =
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700142 FIB_MANAGER_COMMAND_PREFIX.size() + 1;
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700143
Steve DiBenedetto3970c892014-01-31 23:31:13 -0700144 const ndn::Buffer& optionBuffer =
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700145 request.getName()[optionCompIndex].getValue();
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700146 shared_ptr<const ndn::Buffer> tmpOptionBuffer(make_shared<ndn::Buffer>(optionBuffer));
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700147
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700148 try
149 {
150 Block rawOptions(tmpOptionBuffer);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700151 extractedOptions.wireDecode(rawOptions);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700152 }
153 catch (const ndn::Tlv::Error& e)
154 {
155 NFD_LOG_INFO("Bad command option parse: " << command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700156 return false;
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700157 }
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700158 NFD_LOG_DEBUG("Options parsed OK");
159 return true;
160}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700161
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700162void
163FibManager::insertEntry(const ndn::FibManagementOptions& options,
164 ndn::ControlResponse& response)
165{
166 NFD_LOG_DEBUG("insert prefix: " << options.getName());
167 NFD_LOG_INFO("insert result: OK"
168 << " prefix: " << options.getName());
169 std::pair<shared_ptr<fib::Entry>, bool> insertResult = m_managedFib.insert(options.getName());
170 setResponse(response, 200, "OK");
171}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700172
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700173void
174FibManager::deleteEntry(const ndn::FibManagementOptions& options,
175 ndn::ControlResponse& response)
176{
177 NFD_LOG_DEBUG("delete prefix: " << options.getName());
178 NFD_LOG_INFO("delete result: OK"
179 << " prefix: " << options.getName());
180
181 m_managedFib.remove(options.getName());
182 setResponse(response, 200, "OK");
183}
184
185static inline bool
186nextHopEqPredicate(const fib::NextHop& target, const fib::NextHop& hop)
187{
188 return target.getFace()->getId() == hop.getFace()->getId();
189}
190
191void
192FibManager::addNextHop(const ndn::FibManagementOptions& options,
193 ndn::ControlResponse& response)
194{
195 NFD_LOG_DEBUG("add-nexthop prefix: " << options.getName()
196 << " faceid: " << options.getFaceId()
197 << " cost: " << options.getCost());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700198
199 shared_ptr<Face> nextHopFace = m_getFace(options.getFaceId());
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700200 if (static_cast<bool>(nextHopFace))
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700201 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700202 shared_ptr<fib::Entry> entry = m_managedFib.findExactMatch(options.getName());
203 if (static_cast<bool>(entry))
204 {
205 entry->addNextHop(nextHopFace, options.getCost());
206
207 NFD_LOG_INFO("add-nexthop result: OK"
208 << " prefix:" << options.getName()
209 << " faceid: " << options.getFaceId()
210 << " cost: " << options.getCost());
211 setResponse(response, 200, "OK");
212 }
213 else
214 {
215 NFD_LOG_INFO("add-nexthop result: FAIL reason: unknown-prefix: " << options.getName());
216 setResponse(response, 404, "Prefix not found");
217 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700218 }
219 else
220 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700221 NFD_LOG_INFO("add-nexthop result: FAIL reason: unknown-faceid: " << options.getFaceId());
222 setResponse(response, 404, "Face not found");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700223 }
224}
225
226void
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700227FibManager::removeNextHop(const ndn::FibManagementOptions& options,
228 ndn::ControlResponse &response)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700229{
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700230 NFD_LOG_DEBUG("remove-nexthop prefix: " << options.getName()
231 << " faceid: " << options.getFaceId());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700232
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700233 shared_ptr<Face> faceToRemove = m_getFace(options.getFaceId());
234 if (static_cast<bool>(faceToRemove))
235 {
236 shared_ptr<fib::Entry> entry = m_managedFib.findExactMatch(options.getName());
237 if (static_cast<bool>(entry))
238 {
239 entry->removeNextHop(faceToRemove);
240 NFD_LOG_INFO("remove-nexthop result: OK prefix: " << options.getName()
241 << " faceid: " << options.getFaceId());
242
243 setResponse(response, 200, "OK");
244 }
245 else
246 {
247 NFD_LOG_INFO("remove-nexthop result: FAIL reason: unknown-prefix: "
248 << options.getName());
249 setResponse(response, 404, "Prefix not found");
250 }
251 }
252 else
253 {
254 NFD_LOG_INFO("remove-nexthop result: FAIL reason: unknown-faceid: "
255 << options.getFaceId());
256 setResponse(response, 404, "Face not found");
257 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700258}
259
260void
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700261FibManager::strategy(const ndn::FibManagementOptions& options, ndn::ControlResponse& response)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700262{
263
264}
265
266// void
267// FibManager::onConfig(ConfigFile::Node section, bool isDryRun)
268// {
269
270// }
271
272} // namespace nfd