blob: 8e27114012d555c19e95270f78c8e1020843057b [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
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070055 };
56
57FibManager::FibManager(Fib& fib,
Steve DiBenedetto3970c892014-01-31 23:31:13 -070058 function<shared_ptr<Face>(FaceId)> getFace,
59 shared_ptr<AppFace> face)
60 : ManagerBase(face),
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070061 m_managedFib(fib),
62 m_getFace(getFace),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070063 m_verbDispatch(FIB_MANAGER_COMMAND_VERBS,
64 FIB_MANAGER_COMMAND_VERBS +
65 (sizeof(FIB_MANAGER_COMMAND_VERBS) / sizeof(VerbAndProcessor)))
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070066{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070067 face->setInterestFilter("/localhost/nfd/fib",
68 bind(&FibManager::onFibRequest, this, _2));
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070069}
70
71void
72FibManager::onFibRequest(const Interest& request)
73{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070074 const Name& command = request.getName();
75 const size_t commandNComps = command.size();
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070076
Steve DiBenedetto2693db92014-02-10 15:58:36 -070077
78
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070079 if (FIB_MANAGER_COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
80 commandNComps < FIB_MANAGER_COMMAND_SIGNED_NCOMPS)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070081 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070082 NFD_LOG_INFO("command result: unsigned verb: " << command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -070083 sendResponse(command, 401, "Signature required");
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070084
85 return;
86 }
87 else if (commandNComps < FIB_MANAGER_COMMAND_SIGNED_NCOMPS ||
88 !FIB_MANAGER_COMMAND_PREFIX.isPrefixOf(command))
89 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070090 NFD_LOG_INFO("command result: malformed");
Steve DiBenedettobdedce92014-02-02 22:49:39 -070091 sendResponse(command, 400, "Malformed command");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070092 return;
93 }
94
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070095 const Name::Component& verb = command.get(FIB_MANAGER_COMMAND_PREFIX.size());
96
97 VerbDispatchTable::const_iterator verbProcessor = m_verbDispatch.find (verb);
98 if (verbProcessor != m_verbDispatch.end())
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070099 {
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800100 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700101 if (!extractOptions(request, options))
102 {
103 sendResponse(command, 400, "Malformed command");
104 return;
105 }
106
107 /// \todo authorize command
108 if (false)
109 {
110 NFD_LOG_INFO("command result: unauthorized verb: " << command);
111 sendResponse(request.getName(), 403, "Unauthorized command");
112 return;
113 }
114
115 NFD_LOG_INFO("command result: processing verb: " << verb);
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800116 ControlResponse response;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700117 (verbProcessor->second)(this, options, response);
118
119 sendResponse(command, response);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700120 }
121 else
122 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700123 NFD_LOG_INFO("command result: unsupported verb: " << verb);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700124 sendResponse(request.getName(), 501, "Unsupported command");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700125 }
126
127}
128
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700129bool
130FibManager::extractOptions(const Interest& request,
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800131 FibManagementOptions& extractedOptions)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700132{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700133 const Name& command = request.getName();
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700134 const size_t optionCompIndex =
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700135 FIB_MANAGER_COMMAND_PREFIX.size() + 1;
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700136
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700137 try
138 {
Alexander Afanasyevb78ec7d2014-02-09 12:17:25 -0800139 Block rawOptions = request.getName()[optionCompIndex].blockFromValue();
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700140 extractedOptions.wireDecode(rawOptions);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700141 }
142 catch (const ndn::Tlv::Error& e)
143 {
144 NFD_LOG_INFO("Bad command option parse: " << command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700145 return false;
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700146 }
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700147
148 if (extractedOptions.getFaceId() == 0)
149 {
150 extractedOptions.setFaceId(request.getIncomingFaceId());
151 }
152
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700153 NFD_LOG_DEBUG("Options parsed OK");
154 return true;
155}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700156
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700157void
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800158FibManager::insertEntry(const FibManagementOptions& options,
159 ControlResponse& response)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700160{
161 NFD_LOG_DEBUG("insert prefix: " << options.getName());
162 NFD_LOG_INFO("insert result: OK"
163 << " prefix: " << options.getName());
164 std::pair<shared_ptr<fib::Entry>, bool> insertResult = m_managedFib.insert(options.getName());
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700165 setResponse(response, 200, "Success", options.wireEncode());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700166}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700167
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700168void
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800169FibManager::deleteEntry(const FibManagementOptions& options,
170 ControlResponse& response)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700171{
172 NFD_LOG_DEBUG("delete prefix: " << options.getName());
173 NFD_LOG_INFO("delete result: OK"
174 << " prefix: " << options.getName());
175
HangZhangad4afd12014-03-01 11:03:08 +0800176 m_managedFib.erase(options.getName());
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700177 setResponse(response, 200, "Success", options.wireEncode());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700178}
179
180static inline bool
181nextHopEqPredicate(const fib::NextHop& target, const fib::NextHop& hop)
182{
183 return target.getFace()->getId() == hop.getFace()->getId();
184}
185
186void
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800187FibManager::addNextHop(const FibManagementOptions& options,
188 ControlResponse& response)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700189{
190 NFD_LOG_DEBUG("add-nexthop prefix: " << options.getName()
191 << " faceid: " << options.getFaceId()
192 << " cost: " << options.getCost());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700193
194 shared_ptr<Face> nextHopFace = m_getFace(options.getFaceId());
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700195 if (static_cast<bool>(nextHopFace))
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700196 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700197 shared_ptr<fib::Entry> entry = m_managedFib.findExactMatch(options.getName());
198 if (static_cast<bool>(entry))
199 {
200 entry->addNextHop(nextHopFace, options.getCost());
201
202 NFD_LOG_INFO("add-nexthop result: OK"
203 << " prefix:" << options.getName()
204 << " faceid: " << options.getFaceId()
205 << " cost: " << options.getCost());
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700206 setResponse(response, 200, "Success", options.wireEncode());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700207 }
208 else
209 {
210 NFD_LOG_INFO("add-nexthop result: FAIL reason: unknown-prefix: " << options.getName());
211 setResponse(response, 404, "Prefix not found");
212 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700213 }
214 else
215 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700216 NFD_LOG_INFO("add-nexthop result: FAIL reason: unknown-faceid: " << options.getFaceId());
217 setResponse(response, 404, "Face not found");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700218 }
219}
220
221void
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800222FibManager::removeNextHop(const FibManagementOptions& options,
223 ControlResponse &response)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700224{
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700225 NFD_LOG_DEBUG("remove-nexthop prefix: " << options.getName()
226 << " faceid: " << options.getFaceId());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700227
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700228 shared_ptr<Face> faceToRemove = m_getFace(options.getFaceId());
229 if (static_cast<bool>(faceToRemove))
230 {
231 shared_ptr<fib::Entry> entry = m_managedFib.findExactMatch(options.getName());
232 if (static_cast<bool>(entry))
233 {
234 entry->removeNextHop(faceToRemove);
235 NFD_LOG_INFO("remove-nexthop result: OK prefix: " << options.getName()
236 << " faceid: " << options.getFaceId());
237
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700238 setResponse(response, 200, "Success", options.wireEncode());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700239 }
240 else
241 {
242 NFD_LOG_INFO("remove-nexthop result: FAIL reason: unknown-prefix: "
243 << options.getName());
244 setResponse(response, 404, "Prefix not found");
245 }
246 }
247 else
248 {
249 NFD_LOG_INFO("remove-nexthop result: FAIL reason: unknown-faceid: "
250 << options.getFaceId());
251 setResponse(response, 404, "Face not found");
252 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700253}
254
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700255// void
256// FibManager::onConfig(ConfigFile::Node section, bool isDryRun)
257// {
258
259// }
260
261} // namespace nfd