blob: 0b20c02432bc7ef2c6d16eb0f5ab3a88acc2c74e [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/encoding/tlv.hpp>
15
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070016namespace nfd {
17
18NFD_LOG_INIT("FibManager");
19
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070020const Name FibManager::FIB_MANAGER_COMMAND_PREFIX = "/localhost/nfd/fib";
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070021
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070022const size_t FibManager::FIB_MANAGER_COMMAND_UNSIGNED_NCOMPS =
23 FibManager::FIB_MANAGER_COMMAND_PREFIX.size() +
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070024 1 + // verb
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070025 1; // verb options
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070026
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070027const size_t FibManager::FIB_MANAGER_COMMAND_SIGNED_NCOMPS =
28 FibManager::FIB_MANAGER_COMMAND_UNSIGNED_NCOMPS +
29 0; // No signed Interest support in mock, otherwise 3 (timestamp, signed info tlv, signature tlv)
30
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070031const FibManager::VerbAndProcessor FibManager::FIB_MANAGER_COMMAND_VERBS[] =
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070032 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070033 VerbAndProcessor(
Alexander Afanasyevb78ec7d2014-02-09 12:17:25 -080034 Name::Component("insert"),
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070035 &FibManager::insertEntry
36 ),
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070037
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070038 VerbAndProcessor(
Alexander Afanasyevb78ec7d2014-02-09 12:17:25 -080039 Name::Component("delete"),
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070040 &FibManager::deleteEntry
41 ),
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070042
43 VerbAndProcessor(
Alexander Afanasyevb78ec7d2014-02-09 12:17:25 -080044 Name::Component("add-nexthop"),
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070045 &FibManager::addNextHop
46 ),
47
48
49
50 VerbAndProcessor(
Alexander Afanasyevb78ec7d2014-02-09 12:17:25 -080051 Name::Component("remove-nexthop"),
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070052 &FibManager::removeNextHop
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070053 ),
54
55 // Unsupported
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070056 // VerbAndProcessor(
Alexander Afanasyevb78ec7d2014-02-09 12:17:25 -080057 // Name::Component("strategy"),
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070058 // &FibManager::strategy
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070059 // )
60
61 };
62
63FibManager::FibManager(Fib& fib,
Steve DiBenedetto3970c892014-01-31 23:31:13 -070064 function<shared_ptr<Face>(FaceId)> getFace,
65 shared_ptr<AppFace> face)
66 : ManagerBase(face),
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070067 m_managedFib(fib),
68 m_getFace(getFace),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070069 m_verbDispatch(FIB_MANAGER_COMMAND_VERBS,
70 FIB_MANAGER_COMMAND_VERBS +
71 (sizeof(FIB_MANAGER_COMMAND_VERBS) / sizeof(VerbAndProcessor)))
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070072{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070073 face->setInterestFilter("/localhost/nfd/fib",
74 bind(&FibManager::onFibRequest, this, _2));
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070075}
76
77void
78FibManager::onFibRequest(const Interest& request)
79{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070080 const Name& command = request.getName();
81 const size_t commandNComps = command.size();
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070082
Steve DiBenedetto2693db92014-02-10 15:58:36 -070083
84
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 {
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800106 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700107 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);
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800122 ControlResponse response;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700123 (verbProcessor->second)(this, options, response);
124
125 sendResponse(command, response);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700126 }
127 else
128 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700129 NFD_LOG_INFO("command result: unsupported verb: " << verb);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700130 sendResponse(request.getName(), 501, "Unsupported command");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700131 }
132
133}
134
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700135bool
136FibManager::extractOptions(const Interest& request,
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800137 FibManagementOptions& extractedOptions)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700138{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700139 const Name& command = request.getName();
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700140 const size_t optionCompIndex =
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700141 FIB_MANAGER_COMMAND_PREFIX.size() + 1;
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700142
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700143 try
144 {
Alexander Afanasyevb78ec7d2014-02-09 12:17:25 -0800145 Block rawOptions = request.getName()[optionCompIndex].blockFromValue();
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700146 extractedOptions.wireDecode(rawOptions);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700147 }
148 catch (const ndn::Tlv::Error& e)
149 {
150 NFD_LOG_INFO("Bad command option parse: " << command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700151 return false;
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700152 }
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700153
154 if (extractedOptions.getFaceId() == 0)
155 {
156 extractedOptions.setFaceId(request.getIncomingFaceId());
157 }
158
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700159 NFD_LOG_DEBUG("Options parsed OK");
160 return true;
161}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700162
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700163void
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800164FibManager::insertEntry(const FibManagementOptions& options,
165 ControlResponse& response)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700166{
167 NFD_LOG_DEBUG("insert prefix: " << options.getName());
168 NFD_LOG_INFO("insert result: OK"
169 << " prefix: " << options.getName());
170 std::pair<shared_ptr<fib::Entry>, bool> insertResult = m_managedFib.insert(options.getName());
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700171 setResponse(response, 200, "Success", options.wireEncode());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700172}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700173
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700174void
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800175FibManager::deleteEntry(const FibManagementOptions& options,
176 ControlResponse& response)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700177{
178 NFD_LOG_DEBUG("delete prefix: " << options.getName());
179 NFD_LOG_INFO("delete result: OK"
180 << " prefix: " << options.getName());
181
182 m_managedFib.remove(options.getName());
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700183 setResponse(response, 200, "Success", options.wireEncode());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700184}
185
186static inline bool
187nextHopEqPredicate(const fib::NextHop& target, const fib::NextHop& hop)
188{
189 return target.getFace()->getId() == hop.getFace()->getId();
190}
191
192void
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800193FibManager::addNextHop(const FibManagementOptions& options,
194 ControlResponse& response)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700195{
196 NFD_LOG_DEBUG("add-nexthop prefix: " << options.getName()
197 << " faceid: " << options.getFaceId()
198 << " cost: " << options.getCost());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700199
200 shared_ptr<Face> nextHopFace = m_getFace(options.getFaceId());
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700201 if (static_cast<bool>(nextHopFace))
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700202 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700203 shared_ptr<fib::Entry> entry = m_managedFib.findExactMatch(options.getName());
204 if (static_cast<bool>(entry))
205 {
206 entry->addNextHop(nextHopFace, options.getCost());
207
208 NFD_LOG_INFO("add-nexthop result: OK"
209 << " prefix:" << options.getName()
210 << " faceid: " << options.getFaceId()
211 << " cost: " << options.getCost());
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700212 setResponse(response, 200, "Success", options.wireEncode());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700213 }
214 else
215 {
216 NFD_LOG_INFO("add-nexthop result: FAIL reason: unknown-prefix: " << options.getName());
217 setResponse(response, 404, "Prefix not found");
218 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700219 }
220 else
221 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700222 NFD_LOG_INFO("add-nexthop result: FAIL reason: unknown-faceid: " << options.getFaceId());
223 setResponse(response, 404, "Face not found");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700224 }
225}
226
227void
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800228FibManager::removeNextHop(const FibManagementOptions& options,
229 ControlResponse &response)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700230{
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700231 NFD_LOG_DEBUG("remove-nexthop prefix: " << options.getName()
232 << " faceid: " << options.getFaceId());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700233
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700234 shared_ptr<Face> faceToRemove = m_getFace(options.getFaceId());
235 if (static_cast<bool>(faceToRemove))
236 {
237 shared_ptr<fib::Entry> entry = m_managedFib.findExactMatch(options.getName());
238 if (static_cast<bool>(entry))
239 {
240 entry->removeNextHop(faceToRemove);
241 NFD_LOG_INFO("remove-nexthop result: OK prefix: " << options.getName()
242 << " faceid: " << options.getFaceId());
243
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700244 setResponse(response, 200, "Success", options.wireEncode());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700245 }
246 else
247 {
248 NFD_LOG_INFO("remove-nexthop result: FAIL reason: unknown-prefix: "
249 << options.getName());
250 setResponse(response, 404, "Prefix not found");
251 }
252 }
253 else
254 {
255 NFD_LOG_INFO("remove-nexthop result: FAIL reason: unknown-faceid: "
256 << options.getFaceId());
257 setResponse(response, 404, "Face not found");
258 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700259}
260
261void
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800262FibManager::strategy(const FibManagementOptions& options, ControlResponse& response)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700263{
264
265}
266
267// void
268// FibManager::onConfig(ConfigFile::Node section, bool isDryRun)
269// {
270
271// }
272
273} // namespace nfd