blob: 9251a0d13709d48cb4b1d4af68f9c2a90c53a4a1 [file] [log] [blame]
Alexander Afanasyev3ecec502014-04-16 13:42:44 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento87fc0f82018-04-11 23:43:51 -04002/*
Davide Pesavento2c9d2ca2024-01-27 16:36:51 -05003 * Copyright (c) 2014-2024, Regents of the University of California,
Alexander Afanasyev7c10b3b2015-01-20 12:24:27 -08004 * 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 Pesavento1b077f62019-02-19 19:19:44 -050026#ifndef NFD_DAEMON_RIB_RIB_HPP
27#define NFD_DAEMON_RIB_RIB_HPP
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070028
Vince Lehman76c751c2014-11-18 17:36:38 -060029#include "rib-entry.hpp"
30#include "rib-update-batch.hpp"
31
Junxiao Shi25c6ce42016-09-09 13:49:59 +000032#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070033
Davide Pesavento2c9d2ca2024-01-27 16:36:51 -050034#include <functional>
35#include <map>
36
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040037namespace nfd::rib {
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070038
Vince Lehman76c751c2014-11-18 17:36:38 -060039using ndn::nfd::ControlParameters;
40
41class FibUpdater;
42
Davide Pesavento8f0b8b62023-08-29 21:04:08 -040043/**
44 * \brief References a route.
Davide Pesaventoe1bdc082018-10-11 21:20:23 -040045 */
Nick Gordon89c4cca2016-11-02 15:42:32 +000046struct RibRouteRef
47{
48 shared_ptr<RibEntry> entry;
49 RibEntry::const_iterator route;
Nick Gordon89c4cca2016-11-02 15:42:32 +000050
Davide Pesavento8f0b8b62023-08-29 21:04:08 -040051 friend bool
52 operator<(const RibRouteRef& lhs, const RibRouteRef& rhs) noexcept
53 {
54 return std::tie(lhs.entry->getName(), lhs.route->faceId, lhs.route->origin) <
55 std::tie(rhs.entry->getName(), rhs.route->faceId, rhs.route->origin);
56 }
57};
Junxiao Shi89c0ea02017-03-06 19:52:05 +000058
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040059/**
60 * \brief Represents the Routing Information Base.
61 *
62 * The Routing Information Base (RIB) contains a collection of Route objects,
63 * each representing a piece of static or dynamic routing information registered
64 * by applications, operators, or NFD itself. Routes associated with the same
65 * namespace are collected into a RIB entry.
66 *
67 * \sa RibEntry
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070068 */
Alexander Afanasyev20d31442014-04-19 17:00:53 -070069class Rib : noncopyable
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070070{
71public:
Junxiao Shidf1dc652019-08-30 19:03:19 +000072 using RibEntryList = std::list<shared_ptr<RibEntry>>;
73 using RibTable = std::map<Name, shared_ptr<RibEntry>>;
74 using const_iterator = RibTable::const_iterator;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070075
Vince Lehman76c751c2014-11-18 17:36:38 -060076 void
77 setFibUpdater(FibUpdater* updater);
78
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070079 const_iterator
Vince12e49462014-06-09 13:29:32 -050080 find(const Name& prefix) const;
81
Vince Lehman218be0a2015-01-15 17:25:20 -060082 Route*
83 find(const Name& prefix, const Route& route) const;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070084
Teng Lianga4e6ec32018-10-21 09:25:00 -070085 Route*
86 findLongestPrefix(const Name& prefix, const Route& route) const;
87
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070088 const_iterator
Junxiao Shidf1dc652019-08-30 19:03:19 +000089 begin() const
90 {
91 return m_rib.begin();
92 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070093
94 const_iterator
Junxiao Shidf1dc652019-08-30 19:03:19 +000095 end() const
96 {
97 return m_rib.end();
98 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070099
100 size_t
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400101 size() const noexcept
Junxiao Shidf1dc652019-08-30 19:03:19 +0000102 {
103 return m_nItems;
104 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700105
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400106 [[nodiscard]] bool
107 empty() const noexcept
Junxiao Shidf1dc652019-08-30 19:03:19 +0000108 {
109 return m_rib.empty();
110 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700111
Vince12e49462014-06-09 13:29:32 -0500112 shared_ptr<RibEntry>
113 findParent(const Name& prefix) const;
114
Vince Lehman76c751c2014-11-18 17:36:38 -0600115public:
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400116 using UpdateSuccessCallback = std::function<void()>;
117 using UpdateFailureCallback = std::function<void(uint32_t code, const std::string& error)>;
Vince Lehman76c751c2014-11-18 17:36:38 -0600118
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400119 /** \brief Passes the provided RibUpdateBatch to FibUpdater to calculate and send FibUpdates.
Vince Lehman76c751c2014-11-18 17:36:38 -0600120 *
121 * If the FIB is updated successfully, onFibUpdateSuccess() will be called, and the
122 * RIB will be updated
123 *
124 * If the FIB update fails, onFibUpdateFailure() will be called, and the RIB will not
125 * be updated.
126 */
127 void
128 beginApplyUpdate(const RibUpdate& update,
129 const UpdateSuccessCallback& onSuccess,
130 const UpdateFailureCallback& onFailure);
131
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400132 /** \brief Starts the FIB update process when a face has been destroyed.
Vince Lehman76c751c2014-11-18 17:36:38 -0600133 */
134 void
135 beginRemoveFace(uint64_t faceId);
Vince Lehman4387e782014-06-19 16:57:45 -0500136
137 void
Junxiao Shi17a70012019-06-25 10:50:32 +0000138 beginRemoveFailedFaces(const std::set<uint64_t>& activeFaceIds);
139
140 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600141 onRouteExpiration(const Name& prefix, const Route& route);
142
Junxiao Shi9f5b01d2016-08-05 03:54:28 +0000143 void
144 insert(const Name& prefix, const Route& route);
145
Vince Lehman76c751c2014-11-18 17:36:38 -0600146private:
Junxiao Shi17a70012019-06-25 10:50:32 +0000147 void
148 enqueueRemoveFace(const RibEntry& entry, uint64_t faceId);
149
Junxiao Shi51533382019-07-19 13:50:26 +0000150 /** \brief Append the RIB update to the update queue.
151 *
152 * To start updates, invoke sendBatchFromQueue() .
153 */
Vince Lehman76c751c2014-11-18 17:36:38 -0600154 void
155 addUpdateToQueue(const RibUpdate& update,
156 const Rib::UpdateSuccessCallback& onSuccess,
157 const Rib::UpdateFailureCallback& onFailure);
158
Junxiao Shi51533382019-07-19 13:50:26 +0000159 /** \brief Send the first update batch in the queue, if no other update is in progress.
160 */
Vince Lehman76c751c2014-11-18 17:36:38 -0600161 void
162 sendBatchFromQueue();
163
Junxiao Shi51533382019-07-19 13:50:26 +0000164 void
165 onFibUpdateSuccess(const RibUpdateBatch& batch,
166 const RibUpdateList& inheritedRoutes,
167 const Rib::UpdateSuccessCallback& onSuccess);
168
169 void
170 onFibUpdateFailure(const Rib::UpdateFailureCallback& onFailure,
171 uint32_t code, const std::string& error);
172
Davide Pesavento264af772021-02-09 21:48:24 -0500173NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
Vince Lehman76c751c2014-11-18 17:36:38 -0600174 void
175 erase(const Name& prefix, const Route& route);
Vince Lehman4387e782014-06-19 16:57:45 -0500176
177private:
Junxiao Shidf1dc652019-08-30 19:03:19 +0000178 using RouteComparePredicate = bool (*)(const Route&, const Route&);
179 using RouteSet = std::set<Route, RouteComparePredicate>;
180
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400181 /** \brief Find entries under \p prefix.
Junxiao Shi51533382019-07-19 13:50:26 +0000182 * \pre a RIB entry exists at \p prefix
183 */
184 std::list<shared_ptr<RibEntry>>
185 findDescendants(const Name& prefix) const;
186
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400187 /** \brief Find entries under \p prefix.
Junxiao Shi51533382019-07-19 13:50:26 +0000188 * \pre a RIB entry does not exist at \p prefix
189 */
190 std::list<shared_ptr<RibEntry>>
191 findDescendantsForNonInsertedName(const Name& prefix) const;
192
Vince12e49462014-06-09 13:29:32 -0500193 RibTable::iterator
194 eraseEntry(RibTable::iterator it);
195
196 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600197 updateRib(const RibUpdateBatch& batch);
Vince Lehman4387e782014-06-19 16:57:45 -0500198
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400199 /** \brief Returns routes inherited from the entry's ancestors.
200 * \return a list of inherited routes
Vince Lehman76c751c2014-11-18 17:36:38 -0600201 */
Vince Lehman218be0a2015-01-15 17:25:20 -0600202 RouteSet
203 getAncestorRoutes(const RibEntry& entry) const;
Vince Lehman4387e782014-06-19 16:57:45 -0500204
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400205 /** \brief Returns routes inherited from the parent of the name and the parent's ancestors.
Vince Lehman76c751c2014-11-18 17:36:38 -0600206 * \note A parent is first found for the passed name before inherited routes are collected
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400207 * \return a list of inherited routes
Vince Lehman76c751c2014-11-18 17:36:38 -0600208 */
209 RouteSet
210 getAncestorRoutes(const Name& name) const;
Vince Lehman4387e782014-06-19 16:57:45 -0500211
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400212 /** \brief Applies the passed \p inheritedRoutes and their actions to the corresponding
213 * RibEntries' inheritedRoutes lists.
Vince Lehman4387e782014-06-19 16:57:45 -0500214 */
215 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600216 modifyInheritedRoutes(const RibUpdateList& inheritedRoutes);
Vince Lehman4387e782014-06-19 16:57:45 -0500217
Yanbiao Lic17de832014-11-21 17:51:45 -0800218public:
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400219 /** \brief Signals after a RIB entry is inserted.
Nick Gordon89c4cca2016-11-02 15:42:32 +0000220 *
221 * A RIB entry is inserted when the first route associated with a
222 * certain namespace is added.
223 */
Junxiao Shidf1dc652019-08-30 19:03:19 +0000224 signal::Signal<Rib, Name> afterInsertEntry;
Nick Gordon89c4cca2016-11-02 15:42:32 +0000225
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400226 /** \brief Signals after a RIB entry is erased.
Nick Gordon89c4cca2016-11-02 15:42:32 +0000227 *
228 * A RIB entry is erased when the last route associated with a
229 * certain namespace is removed.
230 */
Junxiao Shidf1dc652019-08-30 19:03:19 +0000231 signal::Signal<Rib, Name> afterEraseEntry;
Yanbiao Lic17de832014-11-21 17:51:45 -0800232
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400233 /** \brief Signals after a Route is added.
Nick Gordon89c4cca2016-11-02 15:42:32 +0000234 */
Junxiao Shidf1dc652019-08-30 19:03:19 +0000235 signal::Signal<Rib, RibRouteRef> afterAddRoute;
Nick Gordon89c4cca2016-11-02 15:42:32 +0000236
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400237 /** \brief Signals before a route is removed.
Nick Gordon89c4cca2016-11-02 15:42:32 +0000238 */
Junxiao Shidf1dc652019-08-30 19:03:19 +0000239 signal::Signal<Rib, RibRouteRef> beforeRemoveRoute;
Nick Gordon89c4cca2016-11-02 15:42:32 +0000240
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700241private:
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700242 RibTable m_rib;
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400243 // FaceId => Entry with Route on this face
244 std::multimap<uint64_t, shared_ptr<RibEntry>> m_faceEntries;
Junxiao Shidf1dc652019-08-30 19:03:19 +0000245 size_t m_nItems = 0;
246 FibUpdater* m_fibUpdater = nullptr;
Vince Lehman4387e782014-06-19 16:57:45 -0500247
Vince Lehman76c751c2014-11-18 17:36:38 -0600248 struct UpdateQueueItem
249 {
250 RibUpdateBatch batch;
251 const Rib::UpdateSuccessCallback managerSuccessCallback;
252 const Rib::UpdateFailureCallback managerFailureCallback;
253 };
254
Junxiao Shidf1dc652019-08-30 19:03:19 +0000255 using UpdateQueue = std::list<UpdateQueueItem>;
Vince Lehman76c751c2014-11-18 17:36:38 -0600256 UpdateQueue m_updateBatches;
Junxiao Shidf1dc652019-08-30 19:03:19 +0000257 bool m_isUpdateInProgress = false;
Vince Lehman76c751c2014-11-18 17:36:38 -0600258
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400259 friend FibUpdater;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700260};
261
Vince12e49462014-06-09 13:29:32 -0500262std::ostream&
263operator<<(std::ostream& os, const Rib& rib);
264
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400265} // namespace nfd::rib
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700266
Davide Pesavento1b077f62019-02-19 19:19:44 -0500267#endif // NFD_DAEMON_RIB_RIB_HPP