blob: 01e2cc8d58c7969e508fb9ffbbd7cfc3b3c5f89b [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 DiBenedetto80ddc212014-02-01 22:23:56 -070083 if (FIB_MANAGER_COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
84 commandNComps < FIB_MANAGER_COMMAND_SIGNED_NCOMPS)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070085 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070086 NFD_LOG_INFO("command result: unsigned verb: " << command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -070087 sendResponse(command, 401, "Signature required");
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070088
89 return;
90 }
91 else if (commandNComps < FIB_MANAGER_COMMAND_SIGNED_NCOMPS ||
92 !FIB_MANAGER_COMMAND_PREFIX.isPrefixOf(command))
93 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070094 NFD_LOG_INFO("command result: malformed");
Steve DiBenedettobdedce92014-02-02 22:49:39 -070095 sendResponse(command, 400, "Malformed command");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070096 return;
97 }
98
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070099 const Name::Component& verb = command.get(FIB_MANAGER_COMMAND_PREFIX.size());
100
101 VerbDispatchTable::const_iterator verbProcessor = m_verbDispatch.find (verb);
102 if (verbProcessor != m_verbDispatch.end())
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700103 {
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800104 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700105 if (!extractOptions(request, options))
106 {
107 sendResponse(command, 400, "Malformed command");
108 return;
109 }
110
111 /// \todo authorize command
112 if (false)
113 {
114 NFD_LOG_INFO("command result: unauthorized verb: " << command);
115 sendResponse(request.getName(), 403, "Unauthorized command");
116 return;
117 }
118
119 NFD_LOG_INFO("command result: processing verb: " << verb);
120
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800121 ControlResponse response;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700122 (verbProcessor->second)(this, options, response);
123
124 sendResponse(command, response);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700125 }
126 else
127 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700128 NFD_LOG_INFO("command result: unsupported verb: " << verb);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700129 sendResponse(request.getName(), 501, "Unsupported command");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700130 }
131
132}
133
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700134bool
135FibManager::extractOptions(const Interest& request,
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800136 FibManagementOptions& extractedOptions)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700137{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700138 const Name& command = request.getName();
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700139 const size_t optionCompIndex =
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700140 FIB_MANAGER_COMMAND_PREFIX.size() + 1;
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700141
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700142 try
143 {
Alexander Afanasyevb78ec7d2014-02-09 12:17:25 -0800144 Block rawOptions = request.getName()[optionCompIndex].blockFromValue();
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700145 extractedOptions.wireDecode(rawOptions);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700146 }
147 catch (const ndn::Tlv::Error& e)
148 {
149 NFD_LOG_INFO("Bad command option parse: " << command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700150 return false;
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700151 }
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700152 NFD_LOG_DEBUG("Options parsed OK");
153 return true;
154}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700155
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700156void
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800157FibManager::insertEntry(const FibManagementOptions& options,
158 ControlResponse& response)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700159{
160 NFD_LOG_DEBUG("insert prefix: " << options.getName());
161 NFD_LOG_INFO("insert result: OK"
162 << " prefix: " << options.getName());
163 std::pair<shared_ptr<fib::Entry>, bool> insertResult = m_managedFib.insert(options.getName());
164 setResponse(response, 200, "OK");
165}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700166
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700167void
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800168FibManager::deleteEntry(const FibManagementOptions& options,
169 ControlResponse& response)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700170{
171 NFD_LOG_DEBUG("delete prefix: " << options.getName());
172 NFD_LOG_INFO("delete result: OK"
173 << " prefix: " << options.getName());
174
175 m_managedFib.remove(options.getName());
176 setResponse(response, 200, "OK");
177}
178
179static inline bool
180nextHopEqPredicate(const fib::NextHop& target, const fib::NextHop& hop)
181{
182 return target.getFace()->getId() == hop.getFace()->getId();
183}
184
185void
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800186FibManager::addNextHop(const FibManagementOptions& options,
187 ControlResponse& response)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700188{
189 NFD_LOG_DEBUG("add-nexthop prefix: " << options.getName()
190 << " faceid: " << options.getFaceId()
191 << " cost: " << options.getCost());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700192
193 shared_ptr<Face> nextHopFace = m_getFace(options.getFaceId());
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700194 if (static_cast<bool>(nextHopFace))
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700195 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700196 shared_ptr<fib::Entry> entry = m_managedFib.findExactMatch(options.getName());
197 if (static_cast<bool>(entry))
198 {
199 entry->addNextHop(nextHopFace, options.getCost());
200
201 NFD_LOG_INFO("add-nexthop result: OK"
202 << " prefix:" << options.getName()
203 << " faceid: " << options.getFaceId()
204 << " cost: " << options.getCost());
205 setResponse(response, 200, "OK");
206 }
207 else
208 {
209 NFD_LOG_INFO("add-nexthop result: FAIL reason: unknown-prefix: " << options.getName());
210 setResponse(response, 404, "Prefix not found");
211 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700212 }
213 else
214 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700215 NFD_LOG_INFO("add-nexthop result: FAIL reason: unknown-faceid: " << options.getFaceId());
216 setResponse(response, 404, "Face not found");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700217 }
218}
219
220void
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800221FibManager::removeNextHop(const FibManagementOptions& options,
222 ControlResponse &response)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700223{
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700224 NFD_LOG_DEBUG("remove-nexthop prefix: " << options.getName()
225 << " faceid: " << options.getFaceId());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700226
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700227 shared_ptr<Face> faceToRemove = m_getFace(options.getFaceId());
228 if (static_cast<bool>(faceToRemove))
229 {
230 shared_ptr<fib::Entry> entry = m_managedFib.findExactMatch(options.getName());
231 if (static_cast<bool>(entry))
232 {
233 entry->removeNextHop(faceToRemove);
234 NFD_LOG_INFO("remove-nexthop result: OK prefix: " << options.getName()
235 << " faceid: " << options.getFaceId());
236
237 setResponse(response, 200, "OK");
238 }
239 else
240 {
241 NFD_LOG_INFO("remove-nexthop result: FAIL reason: unknown-prefix: "
242 << options.getName());
243 setResponse(response, 404, "Prefix not found");
244 }
245 }
246 else
247 {
248 NFD_LOG_INFO("remove-nexthop result: FAIL reason: unknown-faceid: "
249 << options.getFaceId());
250 setResponse(response, 404, "Face not found");
251 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700252}
253
254void
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800255FibManager::strategy(const FibManagementOptions& options, ControlResponse& response)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700256{
257
258}
259
260// void
261// FibManager::onConfig(ConfigFile::Node section, bool isDryRun)
262// {
263
264// }
265
266} // namespace nfd