blob: 206ecc0169505e1d0857025c0ecf1801290ed67a [file] [log] [blame]
Alexander Afanasyev3ecec502014-04-16 13:42:44 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento9f8b10e2018-08-22 08:45:37 +00002/*
Davide Pesavento40641272023-03-16 13:31:12 -04003 * Copyright (c) 2014-2023, Regents of the University of California,
Junxiao Shi1e46be32015-01-08 20:18:05 -07004 * 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 * The University of Memphis.
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070010 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Vince12e49462014-06-09 13:29:32 -050024 */
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070025
Davide Pesavento8a05c7f2019-02-28 02:26:19 -050026#ifndef NFD_DAEMON_MGMT_RIB_MANAGER_HPP
27#define NFD_DAEMON_MGMT_RIB_MANAGER_HPP
Nick Gordon9fcf1232017-03-10 22:30:20 +000028
Davide Pesavento78ddcab2019-02-28 22:00:03 -050029#include "manager-base.hpp"
Davide Pesavento78ddcab2019-02-28 22:00:03 -050030#include "rib/route.hpp"
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070031
Junxiao Shi25c6ce42016-09-09 13:49:59 +000032#include <ndn-cxx/mgmt/nfd/controller.hpp>
Nick Gordon9fcf1232017-03-10 22:30:20 +000033#include <ndn-cxx/mgmt/nfd/face-event-notification.hpp>
34#include <ndn-cxx/mgmt/nfd/face-monitor.hpp>
Davide Pesavento40641272023-03-16 13:31:12 -040035#include <ndn-cxx/mgmt/nfd/face-status.hpp>
Davide Pesavento8a05c7f2019-02-28 02:26:19 -050036#include <ndn-cxx/security/validator-config.hpp>
Junxiao Shifeddc3c2019-01-17 19:06:00 +000037#include <ndn-cxx/util/scheduler.hpp>
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070038
39namespace nfd {
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070040
Davide Pesavento78ddcab2019-02-28 22:00:03 -050041namespace rib {
42class Rib;
43class RibUpdate;
44} // namespace rib
45
Junxiao Shif4cfed12018-08-22 23:26:29 +000046/**
Davide Pesavento78ddcab2019-02-28 22:00:03 -050047 * @brief Implements the RIB Management of NFD Management Protocol.
Davide Pesavento8a05c7f2019-02-28 02:26:19 -050048 * @sa https://redmine.named-data.net/projects/nfd/wiki/RibMgmt
Junxiao Shif4cfed12018-08-22 23:26:29 +000049 */
Davide Pesavento3db98072021-03-09 23:03:27 -050050class RibManager final : public ManagerBase
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070051{
52public:
Davide Pesavento8a05c7f2019-02-28 02:26:19 -050053 RibManager(rib::Rib& rib, ndn::Face& face, ndn::KeyChain& keyChain,
Davide Pesavento0a71dd32019-03-17 20:36:18 -040054 ndn::nfd::Controller& nfdController, Dispatcher& dispatcher);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070055
Junxiao Shif4cfed12018-08-22 23:26:29 +000056 /**
57 * @brief Apply localhost_security configuration.
58 */
59 void
60 applyLocalhostConfig(const ConfigSection& section, const std::string& filename);
Vince Lehman26b215c2014-08-17 15:00:41 -050061
Junxiao Shif4cfed12018-08-22 23:26:29 +000062 /**
63 * @brief Apply localhop_security configuration and allow accepting commands on
64 * /localhop/nfd/rib prefix.
65 */
66 void
67 enableLocalhop(const ConfigSection& section, const std::string& filename);
68
69 /**
70 * @brief Disallow accepting commands on /localhop/nfd/rib prefix.
71 */
72 void
73 disableLocalhop();
74
75 /**
Teng Liang18c2b292019-10-18 14:31:04 -070076 * @brief Apply prefix_announcement_validation configuration.
77 */
78 void
79 applyPaConfig(const ConfigSection& section, const std::string& filename);
80
81 /**
Junxiao Shif4cfed12018-08-22 23:26:29 +000082 * @brief Start accepting commands and dataset requests.
83 */
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070084 void
85 registerWithNfd();
86
Junxiao Shif4cfed12018-08-22 23:26:29 +000087 /**
88 * @brief Enable NDNLP IncomingFaceId field in order to support self-registration commands.
89 */
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070090 void
Eric Newberryecc45cb2016-11-08 19:57:12 +000091 enableLocalFields();
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070092
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000093public: // self-learning support
94 enum class SlAnnounceResult {
95 OK, ///< RIB and FIB have been updated
96 ERROR, ///< unspecified error
97 VALIDATION_FAILURE, ///< the announcement cannot be verified against the trust schema
98 EXPIRED, ///< the announcement has expired
99 NOT_FOUND, ///< route does not exist (slRenew only)
100 };
101
102 using SlAnnounceCallback = std::function<void(SlAnnounceResult res)>;
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400103 using SlFindAnnCallback = std::function<void(std::optional<ndn::PrefixAnnouncement>)>;
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000104
105 /** \brief Insert a route by prefix announcement from self-learning strategy.
106 * \param pa A prefix announcement. It must contain the Data.
107 * \param faceId Face on which the announcement arrives.
108 * \param maxLifetime Maximum route lifetime as imposed by self-learning strategy.
109 * \param cb Callback to receive the operation result.
110 *
111 * If \p pa passes validation and is unexpired, inserts or replaces a route for the announced
112 * name and faceId whose lifetime is set to the earlier of now+maxLifetime or prefix
113 * announcement expiration time, updates FIB, and invokes \p cb with SlAnnounceResult::OK.
114 * In case \p pa expires when validation completes, invokes \p cb with SlAnnounceResult::EXPIRED.
115 * If \p pa cannot be verified by the trust schema given in rib.localhop_security config key,
116 * or the relevant config has not been loaded via \c enableLocalHop, invokes \p cb with
117 * SlAnnounceResult::VALIDATION_FAILURE.
118 *
119 * Self-learning strategy invokes this method after receiving a Data carrying a prefix
120 * announcement.
121 */
122 void
123 slAnnounce(const ndn::PrefixAnnouncement& pa, uint64_t faceId, time::milliseconds maxLifetime,
124 const SlAnnounceCallback& cb);
125
126 /** \brief Renew a route created by prefix announcement from self-learning strategy.
127 * \param name Data name, for finding RIB entry by longest-prefix-match.
128 * \param faceId Nexthop face.
129 * \param maxLifetime Maximum route lifetime as imposed by self-learning strategy.
130 * \param cb Callback to receive the operation result.
131 *
132 * If the specified route exists, prolongs its lifetime to the earlier of now+maxLifetime or
133 * prefix announcement expiration time, and invokes \p cb with SlAnnounceResult::OK.
134 * If the prefix announcement has expired, invokes \p cb with SlAnnounceResult::EXPIRED.
135 * If the route is not found, invokes \p cb with SlAnnounceResult::NOT_FOUND.
136 *
137 * Self-learning strategy invokes this method after an Interest forwarded via a learned route
138 * is satisfied.
139 *
140 * \bug In current implementation, if an slAnnounce operation is in progress to create a Route
141 * or replace a prefix announcement, slRenew could fail because Route does not exist in
142 * existing RIB, or overwrite the new prefix announcement with an old one.
143 */
144 void
145 slRenew(const Name& name, uint64_t faceId, time::milliseconds maxLifetime,
146 const SlAnnounceCallback& cb);
147
148 /** \brief Retrieve an outgoing prefix announcement for self-learning strategy.
149 * \param name Data name.
150 * \param cb Callback to receive a prefix announcement that announces a prefix of \p name, or
151 * nullopt if no RIB entry is found by longest-prefix-match of \p name.
152 *
153 * Self-learning strategy invokes this method before sending a Data in reply to a discovery
154 * Interest, so as to attach a prefix announcement onto that Data.
155 *
156 * \bug In current implementation, if an slAnnounce operation is in progress, slFindAnn does not
157 * wait for that operation to complete and its result reflects the prior RIB state.
158 */
159 void
160 slFindAnn(const Name& name, const SlFindAnnCallback& cb) const;
161
Junxiao Shi52009042018-09-10 12:33:56 +0000162private: // RIB and FibUpdater actions
163 enum class RibUpdateResult
164 {
165 OK,
166 ERROR,
167 EXPIRED,
168 };
169
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000170 static SlAnnounceResult
171 getSlAnnounceResultFromRibUpdateResult(RibUpdateResult r);
172
Junxiao Shi52009042018-09-10 12:33:56 +0000173 /** \brief Start adding a route to RIB and FIB.
174 * \param name route name
175 * \param route route parameters; may contain absolute expiration time
176 * \param expires relative expiration time; if specified, overwrites \c route.expires
177 * \param done completion callback
178 */
Vince Lehman76c751c2014-11-18 17:36:38 -0600179 void
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400180 beginAddRoute(const Name& name, rib::Route route, std::optional<time::nanoseconds> expires,
Junxiao Shi52009042018-09-10 12:33:56 +0000181 const std::function<void(RibUpdateResult)>& done);
182
183 /** \brief Start removing a route from RIB and FIB.
184 * \param name route name
185 * \param route route parameters
186 * \param done completion callback
187 */
188 void
Davide Pesavento8a05c7f2019-02-28 02:26:19 -0500189 beginRemoveRoute(const Name& name, const rib::Route& route,
Junxiao Shi52009042018-09-10 12:33:56 +0000190 const std::function<void(RibUpdateResult)>& done);
Vince Lehman4387e782014-06-19 16:57:45 -0500191
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700192 void
Davide Pesavento8a05c7f2019-02-28 02:26:19 -0500193 beginRibUpdate(const rib::RibUpdate& update,
194 const std::function<void(RibUpdateResult)>& done);
Vince Lehman76c751c2014-11-18 17:36:38 -0600195
Junxiao Shi52009042018-09-10 12:33:56 +0000196private: // management Dispatcher related
Vince Lehman76c751c2014-11-18 17:36:38 -0600197 void
Yanbiao Licf0db022016-01-29 00:54:25 -0800198 registerTopPrefix(const Name& topPrefix);
199
Junxiao Shi52009042018-09-10 12:33:56 +0000200 /** \brief Serve rib/register command.
201 */
Yanbiao Licf0db022016-01-29 00:54:25 -0800202 void
203 registerEntry(const Name& topPrefix, const Interest& interest,
204 ControlParameters parameters,
205 const ndn::mgmt::CommandContinuation& done);
Junxiao Shia3295742014-05-16 22:40:10 -0700206
Junxiao Shi52009042018-09-10 12:33:56 +0000207 /** \brief Serve rib/unregister command.
208 */
Junxiao Shia3295742014-05-16 22:40:10 -0700209 void
Yanbiao Licf0db022016-01-29 00:54:25 -0800210 unregisterEntry(const Name& topPrefix, const Interest& interest,
211 ControlParameters parameters,
212 const ndn::mgmt::CommandContinuation& done);
Yingdi Yue5224e92014-04-29 18:04:02 -0700213
Junxiao Shi52009042018-09-10 12:33:56 +0000214 /** \brief Serve rib/list dataset.
215 */
Yingdi Yue5224e92014-04-29 18:04:02 -0700216 void
Yanbiao Licf0db022016-01-29 00:54:25 -0800217 listEntries(const Name& topPrefix, const Interest& interest,
218 ndn::mgmt::StatusDatasetContext& context);
Yingdi Yue5224e92014-04-29 18:04:02 -0700219
220 void
Yanbiao Licf0db022016-01-29 00:54:25 -0800221 setFaceForSelfRegistration(const Interest& request, ControlParameters& parameters);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700222
Nick Gordon9fcf1232017-03-10 22:30:20 +0000223 ndn::mgmt::Authorization
Davide Pesavento3db98072021-03-09 23:03:27 -0500224 makeAuthorization(const std::string& verb) final;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700225
Yanbiao Licf0db022016-01-29 00:54:25 -0800226private: // Face monitor
Vince Lehman26b215c2014-08-17 15:00:41 -0500227 void
Vince Lehmancd613c52014-07-30 14:34:49 -0500228 fetchActiveFaces();
229
230 void
Weiwei Liu6e21cdb2016-09-29 15:16:23 -0700231 onFetchActiveFacesFailure(uint32_t code, const std::string& reason);
Vince Lehmancd613c52014-07-30 14:34:49 -0500232
Davide Pesavento264af772021-02-09 21:48:24 -0500233NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
Yanbiao Licf0db022016-01-29 00:54:25 -0800234 void
235 scheduleActiveFaceFetch(const time::seconds& timeToWait);
236
Vince Lehman26b215c2014-08-17 15:00:41 -0500237 void
Weiwei Liu6e21cdb2016-09-29 15:16:23 -0700238 removeInvalidFaces(const std::vector<ndn::nfd::FaceStatus>& activeFaces);
Vince Lehman26b215c2014-08-17 15:00:41 -0500239
Yanbiao Licf0db022016-01-29 00:54:25 -0800240 void
Nick Gordon9fcf1232017-03-10 22:30:20 +0000241 onNotification(const ndn::nfd::FaceEventNotification& notification);
Yanbiao Licf0db022016-01-29 00:54:25 -0800242
Yanbiao Lif48d0802018-06-01 03:00:02 -0700243public:
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400244 static inline const Name LOCALHOP_TOP_PREFIX{"/localhop/nfd"};
Yanbiao Lif48d0802018-06-01 03:00:02 -0700245
Yanbiao Licf0db022016-01-29 00:54:25 -0800246private:
Davide Pesavento8a05c7f2019-02-28 02:26:19 -0500247 rib::Rib& m_rib;
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000248 ndn::KeyChain& m_keyChain;
Davide Pesavento9f8b10e2018-08-22 08:45:37 +0000249 ndn::nfd::Controller& m_nfdController;
Junxiao Shif4cfed12018-08-22 23:26:29 +0000250 Dispatcher& m_dispatcher;
251
Yanbiao Licf0db022016-01-29 00:54:25 -0800252 ndn::nfd::FaceMonitor m_faceMonitor;
Yingdi Yue5224e92014-04-29 18:04:02 -0700253 ndn::ValidatorConfig m_localhostValidator;
254 ndn::ValidatorConfig m_localhopValidator;
Teng Liang18c2b292019-10-18 14:31:04 -0700255 ndn::ValidatorConfig m_paValidator;
Junxiao Shif4cfed12018-08-22 23:26:29 +0000256 bool m_isLocalhopEnabled;
Vince Lehman4387e782014-06-19 16:57:45 -0500257
Davide Pesavento3dade002019-03-19 11:29:56 -0600258 scheduler::ScopedEventId m_activeFaceFetchEvent;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700259};
260
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000261std::ostream&
262operator<<(std::ostream& os, RibManager::SlAnnounceResult res);
263
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700264} // namespace nfd
265
Davide Pesavento8a05c7f2019-02-28 02:26:19 -0500266#endif // NFD_DAEMON_MGMT_RIB_MANAGER_HPP