blob: 0ffe333299e7ba25fc85b56a6239998b39cd885e [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 DiBenedetto042bfe92014-01-30 15:05:08 -070033
34 VerbAndProcessor(
Alexander Afanasyevb78ec7d2014-02-09 12:17:25 -080035 Name::Component("add-nexthop"),
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070036 &FibManager::addNextHop
37 ),
38
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070039 VerbAndProcessor(
Alexander Afanasyevb78ec7d2014-02-09 12:17:25 -080040 Name::Component("remove-nexthop"),
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070041 &FibManager::removeNextHop
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070042 ),
43
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070044 };
45
46FibManager::FibManager(Fib& fib,
Steve DiBenedetto3970c892014-01-31 23:31:13 -070047 function<shared_ptr<Face>(FaceId)> getFace,
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070048 shared_ptr<InternalFace> face)
49 : ManagerBase(face, FIB_PRIVILEGE),
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070050 m_managedFib(fib),
51 m_getFace(getFace),
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070052 m_verbDispatch(COMMAND_VERBS,
53 COMMAND_VERBS +
54 (sizeof(COMMAND_VERBS) / sizeof(VerbAndProcessor)))
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070055{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070056 face->setInterestFilter("/localhost/nfd/fib",
57 bind(&FibManager::onFibRequest, this, _2));
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070058}
59
Steve DiBenedettod030cfc2014-03-10 20:04:47 -060060FibManager::~FibManager()
61{
62
63}
64
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070065void
66FibManager::onFibRequest(const Interest& request)
67{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070068 const Name& command = request.getName();
69 const size_t commandNComps = command.size();
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070070
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070071 if (COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
72 commandNComps < COMMAND_SIGNED_NCOMPS)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070073 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070074 NFD_LOG_INFO("command result: unsigned verb: " << command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -070075 sendResponse(command, 401, "Signature required");
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070076
77 return;
78 }
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070079 else if (commandNComps < COMMAND_SIGNED_NCOMPS ||
80 !COMMAND_PREFIX.isPrefixOf(command))
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070081 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070082 NFD_LOG_INFO("command result: malformed");
Steve DiBenedettobdedce92014-02-02 22:49:39 -070083 sendResponse(command, 400, "Malformed command");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070084 return;
85 }
86
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070087 validate(request,
88 bind(&FibManager::onValidatedFibRequest,
89 this, _1),
90 bind(&ManagerBase::onCommandValidationFailed,
91 this, _1, _2));
92}
93
94void
95FibManager::onValidatedFibRequest(const shared_ptr<const Interest>& request)
96{
97 const Name& command = request->getName();
98 const Name::Component& verb = command.get(COMMAND_PREFIX.size());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070099
100 VerbDispatchTable::const_iterator verbProcessor = m_verbDispatch.find (verb);
101 if (verbProcessor != m_verbDispatch.end())
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700102 {
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800103 FibManagementOptions options;
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700104 if (!extractOptions(*request, options))
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700105 {
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700106 NFD_LOG_INFO("command result: malformed verb: " << verb);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700107 sendResponse(command, 400, "Malformed command");
108 return;
109 }
110
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700111 NFD_LOG_INFO("command result: processing verb: " << verb);
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800112 ControlResponse response;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700113 (verbProcessor->second)(this, options, response);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700114 sendResponse(command, response);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700115 }
116 else
117 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700118 NFD_LOG_INFO("command result: unsupported verb: " << verb);
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700119 sendResponse(command, 501, "Unsupported command");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700120 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700121}
122
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700123bool
124FibManager::extractOptions(const Interest& request,
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800125 FibManagementOptions& extractedOptions)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700126{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700127 const Name& command = request.getName();
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700128 const size_t optionCompIndex = COMMAND_PREFIX.size() + 1;
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700129
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700130 try
131 {
Alexander Afanasyevb78ec7d2014-02-09 12:17:25 -0800132 Block rawOptions = request.getName()[optionCompIndex].blockFromValue();
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700133 extractedOptions.wireDecode(rawOptions);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700134 }
135 catch (const ndn::Tlv::Error& e)
136 {
137 NFD_LOG_INFO("Bad command option parse: " << command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700138 return false;
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700139 }
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700140
141 if (extractedOptions.getFaceId() == 0)
142 {
143 extractedOptions.setFaceId(request.getIncomingFaceId());
144 }
145
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700146 NFD_LOG_DEBUG("Options parsed OK");
147 return true;
148}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700149
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700150void
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800151FibManager::addNextHop(const FibManagementOptions& options,
152 ControlResponse& response)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700153{
154 NFD_LOG_DEBUG("add-nexthop prefix: " << options.getName()
155 << " faceid: " << options.getFaceId()
156 << " cost: " << options.getCost());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700157
158 shared_ptr<Face> nextHopFace = m_getFace(options.getFaceId());
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700159 if (static_cast<bool>(nextHopFace))
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700160 {
Steve DiBenedettod030cfc2014-03-10 20:04:47 -0600161 shared_ptr<fib::Entry> entry = m_managedFib.insert(options.getName()).first;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700162
Steve DiBenedettod030cfc2014-03-10 20:04:47 -0600163 entry->addNextHop(nextHopFace, options.getCost());
164
165 NFD_LOG_INFO("add-nexthop result: OK"
166 << " prefix:" << options.getName()
167 << " faceid: " << options.getFaceId()
168 << " cost: " << options.getCost());
169 setResponse(response, 200, "Success", options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700170 }
171 else
172 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700173 NFD_LOG_INFO("add-nexthop result: FAIL reason: unknown-faceid: " << options.getFaceId());
174 setResponse(response, 404, "Face not found");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700175 }
176}
177
178void
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800179FibManager::removeNextHop(const FibManagementOptions& options,
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700180 ControlResponse& response)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700181{
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700182 NFD_LOG_DEBUG("remove-nexthop prefix: " << options.getName()
183 << " faceid: " << options.getFaceId());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700184
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700185 shared_ptr<Face> faceToRemove = m_getFace(options.getFaceId());
186 if (static_cast<bool>(faceToRemove))
187 {
188 shared_ptr<fib::Entry> entry = m_managedFib.findExactMatch(options.getName());
189 if (static_cast<bool>(entry))
190 {
191 entry->removeNextHop(faceToRemove);
192 NFD_LOG_INFO("remove-nexthop result: OK prefix: " << options.getName()
193 << " faceid: " << options.getFaceId());
194
Steve DiBenedettod030cfc2014-03-10 20:04:47 -0600195 if (!entry->hasNextHops())
196 {
197 m_managedFib.erase(*entry);
198 }
199
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700200 setResponse(response, 200, "Success", options.wireEncode());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700201 }
202 else
203 {
204 NFD_LOG_INFO("remove-nexthop result: FAIL reason: unknown-prefix: "
205 << options.getName());
206 setResponse(response, 404, "Prefix not found");
207 }
208 }
209 else
210 {
211 NFD_LOG_INFO("remove-nexthop result: FAIL reason: unknown-faceid: "
212 << options.getFaceId());
213 setResponse(response, 404, "Face not found");
214 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700215}
216
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700217} // namespace nfd