blob: f99bf1e033ecd8b66d9419f59f2a55fda75bacea [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(
Alexander Afanasyevb78ec7d2014-02-09 12:17:25 -080036 Name::Component("insert"),
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070037 &FibManager::insertEntry
38 ),
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070039
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070040 VerbAndProcessor(
Alexander Afanasyevb78ec7d2014-02-09 12:17:25 -080041 Name::Component("delete"),
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070042 &FibManager::deleteEntry
43 ),
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070044
45 VerbAndProcessor(
Alexander Afanasyevb78ec7d2014-02-09 12:17:25 -080046 Name::Component("add-nexthop"),
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070047 &FibManager::addNextHop
48 ),
49
50
51
52 VerbAndProcessor(
Alexander Afanasyevb78ec7d2014-02-09 12:17:25 -080053 Name::Component("remove-nexthop"),
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070054 &FibManager::removeNextHop
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070055 ),
56
57 // Unsupported
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070058 // VerbAndProcessor(
Alexander Afanasyevb78ec7d2014-02-09 12:17:25 -080059 // Name::Component("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 DiBenedetto80ddc212014-02-01 22:23:56 -0700144 try
145 {
Alexander Afanasyevb78ec7d2014-02-09 12:17:25 -0800146 Block rawOptions = request.getName()[optionCompIndex].blockFromValue();
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700147 extractedOptions.wireDecode(rawOptions);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700148 }
149 catch (const ndn::Tlv::Error& e)
150 {
151 NFD_LOG_INFO("Bad command option parse: " << command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700152 return false;
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700153 }
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700154 NFD_LOG_DEBUG("Options parsed OK");
155 return true;
156}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700157
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700158void
159FibManager::insertEntry(const ndn::FibManagementOptions& options,
160 ndn::ControlResponse& response)
161{
162 NFD_LOG_DEBUG("insert prefix: " << options.getName());
163 NFD_LOG_INFO("insert result: OK"
164 << " prefix: " << options.getName());
165 std::pair<shared_ptr<fib::Entry>, bool> insertResult = m_managedFib.insert(options.getName());
166 setResponse(response, 200, "OK");
167}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700168
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700169void
170FibManager::deleteEntry(const ndn::FibManagementOptions& options,
171 ndn::ControlResponse& response)
172{
173 NFD_LOG_DEBUG("delete prefix: " << options.getName());
174 NFD_LOG_INFO("delete result: OK"
175 << " prefix: " << options.getName());
176
177 m_managedFib.remove(options.getName());
178 setResponse(response, 200, "OK");
179}
180
181static inline bool
182nextHopEqPredicate(const fib::NextHop& target, const fib::NextHop& hop)
183{
184 return target.getFace()->getId() == hop.getFace()->getId();
185}
186
187void
188FibManager::addNextHop(const ndn::FibManagementOptions& options,
189 ndn::ControlResponse& response)
190{
191 NFD_LOG_DEBUG("add-nexthop prefix: " << options.getName()
192 << " faceid: " << options.getFaceId()
193 << " cost: " << options.getCost());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700194
195 shared_ptr<Face> nextHopFace = m_getFace(options.getFaceId());
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700196 if (static_cast<bool>(nextHopFace))
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700197 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700198 shared_ptr<fib::Entry> entry = m_managedFib.findExactMatch(options.getName());
199 if (static_cast<bool>(entry))
200 {
201 entry->addNextHop(nextHopFace, options.getCost());
202
203 NFD_LOG_INFO("add-nexthop result: OK"
204 << " prefix:" << options.getName()
205 << " faceid: " << options.getFaceId()
206 << " cost: " << options.getCost());
207 setResponse(response, 200, "OK");
208 }
209 else
210 {
211 NFD_LOG_INFO("add-nexthop result: FAIL reason: unknown-prefix: " << options.getName());
212 setResponse(response, 404, "Prefix not found");
213 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700214 }
215 else
216 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700217 NFD_LOG_INFO("add-nexthop result: FAIL reason: unknown-faceid: " << options.getFaceId());
218 setResponse(response, 404, "Face not found");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700219 }
220}
221
222void
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700223FibManager::removeNextHop(const ndn::FibManagementOptions& options,
224 ndn::ControlResponse &response)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700225{
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700226 NFD_LOG_DEBUG("remove-nexthop prefix: " << options.getName()
227 << " faceid: " << options.getFaceId());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700228
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700229 shared_ptr<Face> faceToRemove = m_getFace(options.getFaceId());
230 if (static_cast<bool>(faceToRemove))
231 {
232 shared_ptr<fib::Entry> entry = m_managedFib.findExactMatch(options.getName());
233 if (static_cast<bool>(entry))
234 {
235 entry->removeNextHop(faceToRemove);
236 NFD_LOG_INFO("remove-nexthop result: OK prefix: " << options.getName()
237 << " faceid: " << options.getFaceId());
238
239 setResponse(response, 200, "OK");
240 }
241 else
242 {
243 NFD_LOG_INFO("remove-nexthop result: FAIL reason: unknown-prefix: "
244 << options.getName());
245 setResponse(response, 404, "Prefix not found");
246 }
247 }
248 else
249 {
250 NFD_LOG_INFO("remove-nexthop result: FAIL reason: unknown-faceid: "
251 << options.getFaceId());
252 setResponse(response, 404, "Face not found");
253 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700254}
255
256void
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700257FibManager::strategy(const ndn::FibManagementOptions& options, ndn::ControlResponse& response)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700258{
259
260}
261
262// void
263// FibManager::onConfig(ConfigFile::Node section, bool isDryRun)
264// {
265
266// }
267
268} // namespace nfd