blob: dee765bab5954334232719eae5136f431d6b8435 [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 DiBenedetto2c2b8892014-02-27 11:46:48 -070020const Name FibManager::COMMAND_PREFIX = "/localhost/nfd/fib";
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070021
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070022const size_t FibManager::COMMAND_UNSIGNED_NCOMPS =
23 FibManager::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 DiBenedetto2c2b8892014-02-27 11:46:48 -070027const size_t FibManager::COMMAND_SIGNED_NCOMPS =
28 FibManager::COMMAND_UNSIGNED_NCOMPS +
29 4; // (timestamp, nonce, signed info tlv, signature tlv)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070030
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070031const FibManager::VerbAndProcessor FibManager::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
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070048 VerbAndProcessor(
Alexander Afanasyevb78ec7d2014-02-09 12:17:25 -080049 Name::Component("remove-nexthop"),
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070050 &FibManager::removeNextHop
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070051 ),
52
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070053 };
54
55FibManager::FibManager(Fib& fib,
Steve DiBenedetto3970c892014-01-31 23:31:13 -070056 function<shared_ptr<Face>(FaceId)> getFace,
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070057 shared_ptr<InternalFace> face)
58 : ManagerBase(face, FIB_PRIVILEGE),
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070059 m_managedFib(fib),
60 m_getFace(getFace),
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070061 m_verbDispatch(COMMAND_VERBS,
62 COMMAND_VERBS +
63 (sizeof(COMMAND_VERBS) / sizeof(VerbAndProcessor)))
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070064{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070065 face->setInterestFilter("/localhost/nfd/fib",
66 bind(&FibManager::onFibRequest, this, _2));
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070067}
68
69void
70FibManager::onFibRequest(const Interest& request)
71{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070072 const Name& command = request.getName();
73 const size_t commandNComps = command.size();
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070074
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070075 if (COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
76 commandNComps < COMMAND_SIGNED_NCOMPS)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070077 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070078 NFD_LOG_INFO("command result: unsigned verb: " << command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -070079 sendResponse(command, 401, "Signature required");
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070080
81 return;
82 }
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070083 else if (commandNComps < COMMAND_SIGNED_NCOMPS ||
84 !COMMAND_PREFIX.isPrefixOf(command))
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070085 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070086 NFD_LOG_INFO("command result: malformed");
Steve DiBenedettobdedce92014-02-02 22:49:39 -070087 sendResponse(command, 400, "Malformed command");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070088 return;
89 }
90
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070091 validate(request,
92 bind(&FibManager::onValidatedFibRequest,
93 this, _1),
94 bind(&ManagerBase::onCommandValidationFailed,
95 this, _1, _2));
96}
97
98void
99FibManager::onValidatedFibRequest(const shared_ptr<const Interest>& request)
100{
101 const Name& command = request->getName();
102 const Name::Component& verb = command.get(COMMAND_PREFIX.size());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700103
104 VerbDispatchTable::const_iterator verbProcessor = m_verbDispatch.find (verb);
105 if (verbProcessor != m_verbDispatch.end())
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700106 {
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800107 FibManagementOptions options;
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700108 if (!extractOptions(*request, options))
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700109 {
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700110 NFD_LOG_INFO("command result: malformed verb: " << verb);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700111 sendResponse(command, 400, "Malformed command");
112 return;
113 }
114
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700115 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);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700118 sendResponse(command, response);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700119 }
120 else
121 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700122 NFD_LOG_INFO("command result: unsupported verb: " << verb);
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700123 sendResponse(command, 501, "Unsupported command");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700124 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700125}
126
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700127bool
128FibManager::extractOptions(const Interest& request,
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800129 FibManagementOptions& extractedOptions)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700130{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700131 const Name& command = request.getName();
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700132 const size_t optionCompIndex = COMMAND_PREFIX.size() + 1;
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700133
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700134 try
135 {
Alexander Afanasyevb78ec7d2014-02-09 12:17:25 -0800136 Block rawOptions = request.getName()[optionCompIndex].blockFromValue();
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700137 extractedOptions.wireDecode(rawOptions);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700138 }
139 catch (const ndn::Tlv::Error& e)
140 {
141 NFD_LOG_INFO("Bad command option parse: " << command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700142 return false;
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700143 }
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700144
145 if (extractedOptions.getFaceId() == 0)
146 {
147 extractedOptions.setFaceId(request.getIncomingFaceId());
148 }
149
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700150 NFD_LOG_DEBUG("Options parsed OK");
151 return true;
152}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700153
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700154void
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800155FibManager::insertEntry(const FibManagementOptions& options,
156 ControlResponse& response)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700157{
158 NFD_LOG_DEBUG("insert prefix: " << options.getName());
159 NFD_LOG_INFO("insert result: OK"
160 << " prefix: " << options.getName());
161 std::pair<shared_ptr<fib::Entry>, bool> insertResult = m_managedFib.insert(options.getName());
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700162 setResponse(response, 200, "Success", options.wireEncode());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700163}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700164
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700165void
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800166FibManager::deleteEntry(const FibManagementOptions& options,
167 ControlResponse& response)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700168{
169 NFD_LOG_DEBUG("delete prefix: " << options.getName());
170 NFD_LOG_INFO("delete result: OK"
171 << " prefix: " << options.getName());
172
HangZhangad4afd12014-03-01 11:03:08 +0800173 m_managedFib.erase(options.getName());
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700174 setResponse(response, 200, "Success", options.wireEncode());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700175}
176
177static inline bool
178nextHopEqPredicate(const fib::NextHop& target, const fib::NextHop& hop)
179{
180 return target.getFace()->getId() == hop.getFace()->getId();
181}
182
183void
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800184FibManager::addNextHop(const FibManagementOptions& options,
185 ControlResponse& response)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700186{
187 NFD_LOG_DEBUG("add-nexthop prefix: " << options.getName()
188 << " faceid: " << options.getFaceId()
189 << " cost: " << options.getCost());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700190
191 shared_ptr<Face> nextHopFace = m_getFace(options.getFaceId());
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700192 if (static_cast<bool>(nextHopFace))
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700193 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700194 shared_ptr<fib::Entry> entry = m_managedFib.findExactMatch(options.getName());
195 if (static_cast<bool>(entry))
196 {
197 entry->addNextHop(nextHopFace, options.getCost());
198
199 NFD_LOG_INFO("add-nexthop result: OK"
200 << " prefix:" << options.getName()
201 << " faceid: " << options.getFaceId()
202 << " cost: " << options.getCost());
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700203 setResponse(response, 200, "Success", options.wireEncode());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700204 }
205 else
206 {
207 NFD_LOG_INFO("add-nexthop result: FAIL reason: unknown-prefix: " << options.getName());
208 setResponse(response, 404, "Prefix not found");
209 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700210 }
211 else
212 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700213 NFD_LOG_INFO("add-nexthop result: FAIL reason: unknown-faceid: " << options.getFaceId());
214 setResponse(response, 404, "Face not found");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700215 }
216}
217
218void
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800219FibManager::removeNextHop(const FibManagementOptions& options,
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700220 ControlResponse& response)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700221{
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700222 NFD_LOG_DEBUG("remove-nexthop prefix: " << options.getName()
223 << " faceid: " << options.getFaceId());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700224
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700225 shared_ptr<Face> faceToRemove = m_getFace(options.getFaceId());
226 if (static_cast<bool>(faceToRemove))
227 {
228 shared_ptr<fib::Entry> entry = m_managedFib.findExactMatch(options.getName());
229 if (static_cast<bool>(entry))
230 {
231 entry->removeNextHop(faceToRemove);
232 NFD_LOG_INFO("remove-nexthop result: OK prefix: " << options.getName()
233 << " faceid: " << options.getFaceId());
234
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700235 setResponse(response, 200, "Success", options.wireEncode());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700236 }
237 else
238 {
239 NFD_LOG_INFO("remove-nexthop result: FAIL reason: unknown-prefix: "
240 << options.getName());
241 setResponse(response, 404, "Prefix not found");
242 }
243 }
244 else
245 {
246 NFD_LOG_INFO("remove-nexthop result: FAIL reason: unknown-faceid: "
247 << options.getFaceId());
248 setResponse(response, 404, "Face not found");
249 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700250}
251
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700252// void
253// FibManager::onConfig(ConfigFile::Node section, bool isDryRun)
254// {
255
256// }
257
258} // namespace nfd