blob: 26c3c2e4e2c9051fe3903fa2ccc20c115c1b9f88 [file] [log] [blame]
Steve DiBenedetto042bfe92014-01-30 15:05:08 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -07003 * Copyright (c) 2014 Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology
9 *
10 * This file is part of NFD (Named Data Networking Forwarding Daemon).
11 * See AUTHORS.md for complete list of NFD authors and contributors.
12 *
13 * NFD is free software: you can redistribute it and/or modify it under the terms
14 * of the GNU General Public License as published by the Free Software Foundation,
15 * either version 3 of the License, or (at your option) any later version.
16 *
17 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
18 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
19 * PURPOSE. See the GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along with
22 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
23 **/
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070024
25#include "fib-manager.hpp"
26
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -060027#include "core/logger.hpp"
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070028#include "table/fib.hpp"
29#include "fw/forwarder.hpp"
30#include "mgmt/internal-face.hpp"
31#include "mgmt/app-face.hpp"
32
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070033#include <ndn-cpp-dev/encoding/tlv.hpp>
34
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070035namespace nfd {
36
37NFD_LOG_INIT("FibManager");
38
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070039const Name FibManager::COMMAND_PREFIX = "/localhost/nfd/fib";
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070040
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070041const size_t FibManager::COMMAND_UNSIGNED_NCOMPS =
42 FibManager::COMMAND_PREFIX.size() +
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070043 1 + // verb
Steve DiBenedetto7564d972014-03-24 14:28:46 -060044 1; // verb parameters
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070045
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070046const size_t FibManager::COMMAND_SIGNED_NCOMPS =
47 FibManager::COMMAND_UNSIGNED_NCOMPS +
48 4; // (timestamp, nonce, signed info tlv, signature tlv)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070049
Steve DiBenedetto6214e562014-03-15 16:27:04 -060050const FibManager::SignedVerbAndProcessor FibManager::SIGNED_COMMAND_VERBS[] =
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070051 {
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070052
Steve DiBenedetto6214e562014-03-15 16:27:04 -060053 SignedVerbAndProcessor(
54 Name::Component("add-nexthop"),
55 &FibManager::addNextHop
56 ),
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070057
Steve DiBenedetto6214e562014-03-15 16:27:04 -060058 SignedVerbAndProcessor(
59 Name::Component("remove-nexthop"),
60 &FibManager::removeNextHop
61 ),
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070062
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070063 };
64
Steve DiBenedetto6214e562014-03-15 16:27:04 -060065const FibManager::UnsignedVerbAndProcessor FibManager::UNSIGNED_COMMAND_VERBS[] =
66 {
67 UnsignedVerbAndProcessor(
68 Name::Component("list"),
69 &FibManager::listEntries
70 ),
71 };
72
73const Name FibManager::LIST_COMMAND_PREFIX("/localhost/nfd/fib/list");
74const size_t FibManager::LIST_COMMAND_NCOMPS = LIST_COMMAND_PREFIX.size();
75
76
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070077FibManager::FibManager(Fib& fib,
Steve DiBenedetto3970c892014-01-31 23:31:13 -070078 function<shared_ptr<Face>(FaceId)> getFace,
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070079 shared_ptr<InternalFace> face)
Steve DiBenedetto6214e562014-03-15 16:27:04 -060080 : ManagerBase(face, FIB_PRIVILEGE)
81 , m_managedFib(fib)
82 , m_getFace(getFace)
83 , m_fibEnumerationPublisher(fib, face, LIST_COMMAND_PREFIX)
84 , m_signedVerbDispatch(SIGNED_COMMAND_VERBS,
85 SIGNED_COMMAND_VERBS +
86 (sizeof(SIGNED_COMMAND_VERBS) / sizeof(SignedVerbAndProcessor)))
87 , m_unsignedVerbDispatch(UNSIGNED_COMMAND_VERBS,
88 UNSIGNED_COMMAND_VERBS +
89 (sizeof(UNSIGNED_COMMAND_VERBS) / sizeof(UnsignedVerbAndProcessor)))
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070090{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070091 face->setInterestFilter("/localhost/nfd/fib",
92 bind(&FibManager::onFibRequest, this, _2));
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070093}
94
Steve DiBenedettod030cfc2014-03-10 20:04:47 -060095FibManager::~FibManager()
96{
97
98}
99
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700100void
101FibManager::onFibRequest(const Interest& request)
102{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700103 const Name& command = request.getName();
104 const size_t commandNComps = command.size();
Steve DiBenedetto6214e562014-03-15 16:27:04 -0600105 const Name::Component& verb = command.get(COMMAND_PREFIX.size());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700106
Steve DiBenedetto6214e562014-03-15 16:27:04 -0600107 UnsignedVerbDispatchTable::const_iterator unsignedVerbProcessor = m_unsignedVerbDispatch.find(verb);
108 if (unsignedVerbProcessor != m_unsignedVerbDispatch.end())
109 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700110 NFD_LOG_DEBUG("command result: processing verb: " << verb);
Steve DiBenedetto6214e562014-03-15 16:27:04 -0600111 (unsignedVerbProcessor->second)(this, boost::cref(request));
112 }
113 else if (COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600114 commandNComps < COMMAND_SIGNED_NCOMPS)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700115 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700116 NFD_LOG_DEBUG("command result: unsigned verb: " << command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700117 sendResponse(command, 401, "Signature required");
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700118 }
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700119 else if (commandNComps < COMMAND_SIGNED_NCOMPS ||
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600120 !COMMAND_PREFIX.isPrefixOf(command))
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700121 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700122 NFD_LOG_DEBUG("command result: malformed");
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700123 sendResponse(command, 400, "Malformed command");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700124 }
Steve DiBenedetto6214e562014-03-15 16:27:04 -0600125 else
126 {
127 validate(request,
128 bind(&FibManager::onValidatedFibRequest, this, _1),
129 bind(&ManagerBase::onCommandValidationFailed, this, _1, _2));
130 }
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700131}
132
133void
134FibManager::onValidatedFibRequest(const shared_ptr<const Interest>& request)
135{
136 const Name& command = request->getName();
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600137 const Name::Component& verb = command[COMMAND_PREFIX.size()];
138 const Name::Component& parameterComponent = command[COMMAND_PREFIX.size() + 1];
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700139
Steve DiBenedetto6214e562014-03-15 16:27:04 -0600140 SignedVerbDispatchTable::const_iterator signedVerbProcessor = m_signedVerbDispatch.find (verb);
141 if (signedVerbProcessor != m_signedVerbDispatch.end())
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700142 {
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600143 ControlParameters parameters;
Steve DiBenedetto51d242a2014-03-31 13:46:43 -0600144 if (!extractParameters(parameterComponent, parameters) || !parameters.hasFaceId())
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700145 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700146 NFD_LOG_DEBUG("command result: malformed verb: " << verb);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700147 sendResponse(command, 400, "Malformed command");
148 return;
149 }
150
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600151 if (parameters.getFaceId() == 0)
152 {
153 parameters.setFaceId(request->getIncomingFaceId());
154 }
155
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700156 NFD_LOG_DEBUG("command result: processing verb: " << verb);
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800157 ControlResponse response;
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600158 (signedVerbProcessor->second)(this, parameters, response);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700159 sendResponse(command, response);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700160 }
161 else
162 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700163 NFD_LOG_DEBUG("command result: unsupported verb: " << verb);
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700164 sendResponse(command, 501, "Unsupported command");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700165 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700166}
167
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700168void
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600169FibManager::addNextHop(ControlParameters& parameters,
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800170 ControlResponse& response)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700171{
Steve DiBenedetto51d242a2014-03-31 13:46:43 -0600172 ndn::nfd::FibAddNextHopCommand command;
173
174 if (!validateParameters(command, parameters))
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600175 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700176 NFD_LOG_DEBUG("add-nexthop result: FAIL reason: malformed");
Steve DiBenedetto51d242a2014-03-31 13:46:43 -0600177 setResponse(response, 400, "Malformed command");
178 return;
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600179 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700180
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600181 const Name& prefix = parameters.getName();
182 FaceId faceId = parameters.getFaceId();
183 uint64_t cost = parameters.getCost();
184
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700185 NFD_LOG_TRACE("add-nexthop prefix: " << prefix
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600186 << " faceid: " << faceId
187 << " cost: " << cost);
188
189 shared_ptr<Face> nextHopFace = m_getFace(faceId);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700190 if (static_cast<bool>(nextHopFace))
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700191 {
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600192 shared_ptr<fib::Entry> entry = m_managedFib.insert(prefix).first;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700193
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600194 entry->addNextHop(nextHopFace, cost);
Steve DiBenedettod030cfc2014-03-10 20:04:47 -0600195
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700196 NFD_LOG_DEBUG("add-nexthop result: OK"
197 << " prefix:" << prefix
198 << " faceid: " << faceId
199 << " cost: " << cost);
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600200
201 setResponse(response, 200, "Success", parameters.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700202 }
203 else
204 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700205 NFD_LOG_DEBUG("add-nexthop result: FAIL reason: unknown-faceid: " << faceId);
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600206 setResponse(response, 410, "Face not found");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700207 }
208}
209
210void
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600211FibManager::removeNextHop(ControlParameters& parameters,
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700212 ControlResponse& response)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700213{
Steve DiBenedetto51d242a2014-03-31 13:46:43 -0600214 ndn::nfd::FibRemoveNextHopCommand command;
215 if (!validateParameters(command, parameters))
216 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700217 NFD_LOG_DEBUG("remove-nexthop result: FAIL reason: malformed");
Steve DiBenedetto51d242a2014-03-31 13:46:43 -0600218 setResponse(response, 400, "Malformed command");
219 return;
220 }
221
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700222 NFD_LOG_TRACE("remove-nexthop prefix: " << parameters.getName()
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600223 << " faceid: " << parameters.getFaceId());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700224
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600225 shared_ptr<Face> faceToRemove = m_getFace(parameters.getFaceId());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700226 if (static_cast<bool>(faceToRemove))
227 {
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600228 shared_ptr<fib::Entry> entry = m_managedFib.findExactMatch(parameters.getName());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700229 if (static_cast<bool>(entry))
230 {
231 entry->removeNextHop(faceToRemove);
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700232 NFD_LOG_DEBUG("remove-nexthop result: OK prefix: " << parameters.getName()
233 << " faceid: " << parameters.getFaceId());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700234
Steve DiBenedettod030cfc2014-03-10 20:04:47 -0600235 if (!entry->hasNextHops())
236 {
237 m_managedFib.erase(*entry);
238 }
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700239 }
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700240 else
241 {
242 NFD_LOG_DEBUG("remove-nexthop result: OK, but entry for face id "
243 << parameters.getFaceId() << " not found");
244 }
245 }
246 else
247 {
248 NFD_LOG_DEBUG("remove-nexthop result: OK, but face id "
249 << parameters.getFaceId() << " not found");
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700250 }
Steve DiBenedetto51d242a2014-03-31 13:46:43 -0600251
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600252 setResponse(response, 200, "Success", parameters.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700253}
254
Steve DiBenedetto6214e562014-03-15 16:27:04 -0600255void
256FibManager::listEntries(const Interest& request)
257{
258 const Name& command = request.getName();
259 const size_t commandNComps = command.size();
260
261 if (commandNComps < LIST_COMMAND_NCOMPS ||
262 !LIST_COMMAND_PREFIX.isPrefixOf(command))
263 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700264 NFD_LOG_DEBUG("command result: malformed");
Steve DiBenedetto6214e562014-03-15 16:27:04 -0600265 sendResponse(command, 400, "Malformed command");
266 return;
267 }
268
269 m_fibEnumerationPublisher.publish();
270}
271
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700272} // namespace nfd