blob: 529350c46c91a77ba3afb6543461c9e460c66623 [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 Pesavento1b077f62019-02-19 19:19:44 -05003 * Copyright (c) 2014-2019, 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
34namespace nfd {
35namespace rib {
36
Vince Lehman76c751c2014-11-18 17:36:38 -060037using ndn::nfd::ControlParameters;
38
39class FibUpdater;
40
Davide Pesaventoe1bdc082018-10-11 21:20:23 -040041/** \brief references a route
42 */
Nick Gordon89c4cca2016-11-02 15:42:32 +000043struct RibRouteRef
44{
45 shared_ptr<RibEntry> entry;
46 RibEntry::const_iterator route;
47};
48
Junxiao Shi89c0ea02017-03-06 19:52:05 +000049bool
50operator<(const RibRouteRef& lhs, const RibRouteRef& rhs);
51
Nick Gordon89c4cca2016-11-02 15:42:32 +000052/** \brief represents the Routing Information Base
53
54 The Routing Information Base contains a collection of Routes, each
55 represents a piece of static or dynamic routing information
56 registered by applications, operators, or NFD itself. Routes
57 associated with the same namespace are collected into a RIB entry.
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070058 */
Alexander Afanasyev20d31442014-04-19 17:00:53 -070059class Rib : noncopyable
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070060{
61public:
Vince Lehman218be0a2015-01-15 17:25:20 -060062 typedef std::list<shared_ptr<RibEntry>> RibEntryList;
63 typedef std::map<Name, shared_ptr<RibEntry>> RibTable;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070064 typedef RibTable::const_iterator const_iterator;
Vince Lehman218be0a2015-01-15 17:25:20 -060065 typedef bool (*RouteComparePredicate)(const Route&, const Route&);
66 typedef std::set<Route, RouteComparePredicate> RouteSet;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070067
68 Rib();
69
Vince Lehman76c751c2014-11-18 17:36:38 -060070 void
71 setFibUpdater(FibUpdater* updater);
72
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070073 const_iterator
Vince12e49462014-06-09 13:29:32 -050074 find(const Name& prefix) const;
75
Vince Lehman218be0a2015-01-15 17:25:20 -060076 Route*
77 find(const Name& prefix, const Route& route) const;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070078
Teng Lianga4e6ec32018-10-21 09:25:00 -070079 Route*
80 findLongestPrefix(const Name& prefix, const Route& route) const;
81
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070082 const_iterator
83 begin() const;
84
85 const_iterator
86 end() const;
87
88 size_t
89 size() const;
90
Vince12e49462014-06-09 13:29:32 -050091 bool
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070092 empty() const;
93
Vince12e49462014-06-09 13:29:32 -050094 shared_ptr<RibEntry>
95 findParent(const Name& prefix) const;
96
Vince Lehman76c751c2014-11-18 17:36:38 -060097public:
Davide Pesavento87fc0f82018-04-11 23:43:51 -040098 using UpdateSuccessCallback = std::function<void()>;
99 using UpdateFailureCallback = std::function<void(uint32_t code, const std::string& error)>;
Vince Lehman76c751c2014-11-18 17:36:38 -0600100
101 /** \brief passes the provided RibUpdateBatch to FibUpdater to calculate and send FibUpdates.
102 *
103 * If the FIB is updated successfully, onFibUpdateSuccess() will be called, and the
104 * RIB will be updated
105 *
106 * If the FIB update fails, onFibUpdateFailure() will be called, and the RIB will not
107 * be updated.
108 */
109 void
110 beginApplyUpdate(const RibUpdate& update,
111 const UpdateSuccessCallback& onSuccess,
112 const UpdateFailureCallback& onFailure);
113
114 /** \brief starts the FIB update process when a face has been destroyed
115 */
116 void
117 beginRemoveFace(uint64_t faceId);
Vince Lehman4387e782014-06-19 16:57:45 -0500118
119 void
Junxiao Shi17a70012019-06-25 10:50:32 +0000120 beginRemoveFailedFaces(const std::set<uint64_t>& activeFaceIds);
121
122 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600123 onRouteExpiration(const Name& prefix, const Route& route);
124
Junxiao Shi9f5b01d2016-08-05 03:54:28 +0000125 void
126 insert(const Name& prefix, const Route& route);
127
Vince Lehman76c751c2014-11-18 17:36:38 -0600128private:
Junxiao Shi17a70012019-06-25 10:50:32 +0000129 void
130 enqueueRemoveFace(const RibEntry& entry, uint64_t faceId);
131
Junxiao Shi51533382019-07-19 13:50:26 +0000132 /** \brief Append the RIB update to the update queue.
133 *
134 * To start updates, invoke sendBatchFromQueue() .
135 */
Vince Lehman76c751c2014-11-18 17:36:38 -0600136 void
137 addUpdateToQueue(const RibUpdate& update,
138 const Rib::UpdateSuccessCallback& onSuccess,
139 const Rib::UpdateFailureCallback& onFailure);
140
Junxiao Shi51533382019-07-19 13:50:26 +0000141 /** \brief Send the first update batch in the queue, if no other update is in progress.
142 */
Vince Lehman76c751c2014-11-18 17:36:38 -0600143 void
144 sendBatchFromQueue();
145
Junxiao Shi51533382019-07-19 13:50:26 +0000146 void
147 onFibUpdateSuccess(const RibUpdateBatch& batch,
148 const RibUpdateList& inheritedRoutes,
149 const Rib::UpdateSuccessCallback& onSuccess);
150
151 void
152 onFibUpdateFailure(const Rib::UpdateFailureCallback& onFailure,
153 uint32_t code, const std::string& error);
154
Vince Lehman76c751c2014-11-18 17:36:38 -0600155PUBLIC_WITH_TESTS_ELSE_PRIVATE:
Junxiao Shi52009042018-09-10 12:33:56 +0000156#ifdef WITH_TESTS
157 /** \brief In unit tests, mock FIB update result.
158 *
159 * If the callback is not nullptr, sendBatchFromQueue() immediately succeeds or fails according
160 * to the return value of callback function.
161 */
162 std::function<bool(const RibUpdateBatch&)> mockFibResponse;
163
164 bool wantMockFibResponseOnce = false; ///< if true, mockFibResponse is cleared after every use.
165#endif
Vince Lehman76c751c2014-11-18 17:36:38 -0600166
Vince Lehman76c751c2014-11-18 17:36:38 -0600167 void
168 erase(const Name& prefix, const Route& route);
Vince Lehman4387e782014-06-19 16:57:45 -0500169
170private:
Junxiao Shi51533382019-07-19 13:50:26 +0000171 /** \brief find entries under \p prefix
172 * \pre a RIB entry exists at \p prefix
173 */
174 std::list<shared_ptr<RibEntry>>
175 findDescendants(const Name& prefix) const;
176
177 /** \brief find entries under \p prefix
178 * \pre a RIB entry does not exist at \p prefix
179 */
180 std::list<shared_ptr<RibEntry>>
181 findDescendantsForNonInsertedName(const Name& prefix) const;
182
Vince12e49462014-06-09 13:29:32 -0500183 RibTable::iterator
184 eraseEntry(RibTable::iterator it);
185
186 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600187 updateRib(const RibUpdateBatch& batch);
Vince Lehman4387e782014-06-19 16:57:45 -0500188
Vince Lehman76c751c2014-11-18 17:36:38 -0600189 /** \brief returns routes inherited from the entry's ancestors
190 *
191 * \return{ a list of inherited routes }
192 */
Vince Lehman218be0a2015-01-15 17:25:20 -0600193 RouteSet
194 getAncestorRoutes(const RibEntry& entry) const;
Vince Lehman4387e782014-06-19 16:57:45 -0500195
Vince Lehman76c751c2014-11-18 17:36:38 -0600196 /** \brief returns routes inherited from the parent of the name and the parent's ancestors
197 *
198 * \note A parent is first found for the passed name before inherited routes are collected
199 *
200 * \return{ a list of inherited routes }
201 */
202 RouteSet
203 getAncestorRoutes(const Name& name) const;
Vince Lehman4387e782014-06-19 16:57:45 -0500204
Vince Lehman76c751c2014-11-18 17:36:38 -0600205 /** \brief applies the passed inheritedRoutes and their actions to the corresponding RibEntries'
206 * inheritedRoutes lists
Vince Lehman4387e782014-06-19 16:57:45 -0500207 */
208 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600209 modifyInheritedRoutes(const RibUpdateList& inheritedRoutes);
Vince Lehman4387e782014-06-19 16:57:45 -0500210
Yanbiao Lic17de832014-11-21 17:51:45 -0800211public:
Nick Gordon89c4cca2016-11-02 15:42:32 +0000212 /** \brief signals after a RIB entry is inserted
213 *
214 * A RIB entry is inserted when the first route associated with a
215 * certain namespace is added.
216 */
Yanbiao Lib9d439d2014-12-11 16:12:32 -0800217 ndn::util::signal::Signal<Rib, Name> afterInsertEntry;
Nick Gordon89c4cca2016-11-02 15:42:32 +0000218
219 /** \brief signals after a RIB entry is erased
220 *
221 * A RIB entry is erased when the last route associated with a
222 * certain namespace is removed.
223 */
224
Yanbiao Lib9d439d2014-12-11 16:12:32 -0800225 ndn::util::signal::Signal<Rib, Name> afterEraseEntry;
Yanbiao Lic17de832014-11-21 17:51:45 -0800226
Nick Gordon89c4cca2016-11-02 15:42:32 +0000227 /** \brief signals after a Route is added
228 */
229 ndn::util::signal::Signal<Rib, RibRouteRef> afterAddRoute;
230
231 /** \brief signals before a route is removed
232 */
233 ndn::util::signal::Signal<Rib, RibRouteRef> beforeRemoveRoute;
234
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700235private:
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700236 RibTable m_rib;
Junxiao Shi17a70012019-06-25 10:50:32 +0000237 std::multimap<uint64_t, shared_ptr<RibEntry>> m_faceEntries; ///< FaceId => Entry with Route on this face
Vince Lehman76c751c2014-11-18 17:36:38 -0600238 FibUpdater* m_fibUpdater;
Vince Lehman4387e782014-06-19 16:57:45 -0500239
Vince12e49462014-06-09 13:29:32 -0500240 size_t m_nItems;
Vince Lehman76c751c2014-11-18 17:36:38 -0600241
242 friend class FibUpdater;
243
244private:
245 struct UpdateQueueItem
246 {
247 RibUpdateBatch batch;
248 const Rib::UpdateSuccessCallback managerSuccessCallback;
249 const Rib::UpdateFailureCallback managerFailureCallback;
250 };
251
252PUBLIC_WITH_TESTS_ELSE_PRIVATE:
253 typedef std::list<UpdateQueueItem> UpdateQueue;
254 UpdateQueue m_updateBatches;
255
256private:
257 bool m_isUpdateInProgress;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700258};
259
260inline Rib::const_iterator
261Rib::begin() const
262{
263 return m_rib.begin();
264}
265
266inline Rib::const_iterator
267Rib::end() const
268{
269 return m_rib.end();
270}
271
272inline size_t
273Rib::size() const
274{
Vince12e49462014-06-09 13:29:32 -0500275 return m_nItems;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700276}
277
Vince12e49462014-06-09 13:29:32 -0500278inline bool
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700279Rib::empty() const
280{
281 return m_rib.empty();
282}
283
Vince12e49462014-06-09 13:29:32 -0500284std::ostream&
285operator<<(std::ostream& os, const Rib& rib);
286
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700287} // namespace rib
288} // namespace nfd
289
Davide Pesavento1b077f62019-02-19 19:19:44 -0500290#endif // NFD_DAEMON_RIB_RIB_HPP