blob: a9278de91211224c565b69624c8fe9d142992f84 [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/*
3 * Copyright (c) 2014-2018, 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
26#ifndef NFD_RIB_RIB_HPP
27#define NFD_RIB_RIB_HPP
28
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 std::map<uint64_t, std::list<shared_ptr<RibEntry>>> FaceLookupTable;
66 typedef bool (*RouteComparePredicate)(const Route&, const Route&);
67 typedef std::set<Route, RouteComparePredicate> RouteSet;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070068
69 Rib();
70
Vince Lehman76c751c2014-11-18 17:36:38 -060071 void
72 setFibUpdater(FibUpdater* updater);
73
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070074 const_iterator
Vince12e49462014-06-09 13:29:32 -050075 find(const Name& prefix) const;
76
Vince Lehman218be0a2015-01-15 17:25:20 -060077 Route*
78 find(const Name& prefix, const Route& route) const;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070079
Teng Lianga4e6ec32018-10-21 09:25:00 -070080 Route*
81 findLongestPrefix(const Name& prefix, const Route& route) const;
82
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070083 const_iterator
84 begin() const;
85
86 const_iterator
87 end() const;
88
89 size_t
90 size() const;
91
Vince12e49462014-06-09 13:29:32 -050092 bool
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070093 empty() const;
94
Vince12e49462014-06-09 13:29:32 -050095 shared_ptr<RibEntry>
96 findParent(const Name& prefix) const;
97
98 /** \brief finds namespaces under the passed prefix
99 * \return{ a list of entries which are under the passed prefix }
100 */
Vince Lehman218be0a2015-01-15 17:25:20 -0600101 std::list<shared_ptr<RibEntry>>
Vince12e49462014-06-09 13:29:32 -0500102 findDescendants(const Name& prefix) const;
103
Vince Lehman76c751c2014-11-18 17:36:38 -0600104 /** \brief finds namespaces under the passed prefix
105 *
106 * \note Unlike findDescendants, needs to find where prefix would fit in tree
107 * before collecting list of descendant prefixes
108 *
109 * \return{ a list of entries which would be under the passed prefix if the prefix
110 * existed in the RIB }
111 */
112 std::list<shared_ptr<RibEntry>>
113 findDescendantsForNonInsertedName(const Name& prefix) const;
114
115public:
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
119 /** \brief passes the provided RibUpdateBatch to FibUpdater to calculate and send FibUpdates.
120 *
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
132 /** \brief starts the FIB update process when a face has been destroyed
133 */
134 void
135 beginRemoveFace(uint64_t faceId);
Vince Lehman4387e782014-06-19 16:57:45 -0500136
137 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600138 onFibUpdateSuccess(const RibUpdateBatch& batch,
139 const RibUpdateList& inheritedRoutes,
140 const Rib::UpdateSuccessCallback& onSuccess);
141
142 void
143 onFibUpdateFailure(const Rib::UpdateFailureCallback& onFailure,
144 uint32_t code, const std::string& error);
145
146 void
147 onRouteExpiration(const Name& prefix, const Route& route);
148
Junxiao Shi9f5b01d2016-08-05 03:54:28 +0000149 void
150 insert(const Name& prefix, const Route& route);
151
Vince Lehman76c751c2014-11-18 17:36:38 -0600152private:
153 /** \brief adds the passed update to a RibUpdateBatch and adds the batch to
154 * the end of the update queue.
155 *
156 * If an update is not in progress, the front update batch in the queue will be
157 * processed by the RIB.
158 *
159 * If an update is in progress, the added update will eventually be processed
160 * when it reaches the front of the queue; after other update batches are
161 * processed, the queue is advanced.
162 */
163 void
164 addUpdateToQueue(const RibUpdate& update,
165 const Rib::UpdateSuccessCallback& onSuccess,
166 const Rib::UpdateFailureCallback& onFailure);
167
168 /** \brief Attempts to send the front update batch in the queue.
169 *
170 * If an update is not in progress, the front update batch in the queue will be
171 * sent to the RIB for processing.
172 *
173 * If an update is in progress, nothing will be done.
174 */
175 void
176 sendBatchFromQueue();
177
178PUBLIC_WITH_TESTS_ELSE_PRIVATE:
Junxiao Shi52009042018-09-10 12:33:56 +0000179#ifdef WITH_TESTS
180 /** \brief In unit tests, mock FIB update result.
181 *
182 * If the callback is not nullptr, sendBatchFromQueue() immediately succeeds or fails according
183 * to the return value of callback function.
184 */
185 std::function<bool(const RibUpdateBatch&)> mockFibResponse;
186
187 bool wantMockFibResponseOnce = false; ///< if true, mockFibResponse is cleared after every use.
188#endif
Vince Lehman76c751c2014-11-18 17:36:38 -0600189
Vince Lehman76c751c2014-11-18 17:36:38 -0600190 void
191 erase(const Name& prefix, const Route& route);
Vince Lehman4387e782014-06-19 16:57:45 -0500192
193private:
Vince12e49462014-06-09 13:29:32 -0500194 RibTable::iterator
195 eraseEntry(RibTable::iterator it);
196
197 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600198 updateRib(const RibUpdateBatch& batch);
Vince Lehman4387e782014-06-19 16:57:45 -0500199
Vince Lehman76c751c2014-11-18 17:36:38 -0600200 /** \brief returns routes inherited from the entry's ancestors
201 *
202 * \return{ a list of inherited routes }
203 */
Vince Lehman218be0a2015-01-15 17:25:20 -0600204 RouteSet
205 getAncestorRoutes(const RibEntry& entry) const;
Vince Lehman4387e782014-06-19 16:57:45 -0500206
Vince Lehman76c751c2014-11-18 17:36:38 -0600207 /** \brief returns routes inherited from the parent of the name and the parent's ancestors
208 *
209 * \note A parent is first found for the passed name before inherited routes are collected
210 *
211 * \return{ a list of inherited routes }
212 */
213 RouteSet
214 getAncestorRoutes(const Name& name) const;
Vince Lehman4387e782014-06-19 16:57:45 -0500215
Vince Lehman76c751c2014-11-18 17:36:38 -0600216 /** \brief applies the passed inheritedRoutes and their actions to the corresponding RibEntries'
217 * inheritedRoutes lists
Vince Lehman4387e782014-06-19 16:57:45 -0500218 */
219 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600220 modifyInheritedRoutes(const RibUpdateList& inheritedRoutes);
Vince Lehman4387e782014-06-19 16:57:45 -0500221
Vince Lehman76c751c2014-11-18 17:36:38 -0600222PUBLIC_WITH_TESTS_ELSE_PRIVATE:
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400223 using NameAndRoute = std::pair<const Name&, const Route&>;
Vince Lehman76c751c2014-11-18 17:36:38 -0600224
225 std::list<NameAndRoute>
226 findRoutesWithFaceId(uint64_t faceId);
Vince12e49462014-06-09 13:29:32 -0500227
Yanbiao Lic17de832014-11-21 17:51:45 -0800228public:
Nick Gordon89c4cca2016-11-02 15:42:32 +0000229 /** \brief signals after a RIB entry is inserted
230 *
231 * A RIB entry is inserted when the first route associated with a
232 * certain namespace is added.
233 */
Yanbiao Lib9d439d2014-12-11 16:12:32 -0800234 ndn::util::signal::Signal<Rib, Name> afterInsertEntry;
Nick Gordon89c4cca2016-11-02 15:42:32 +0000235
236 /** \brief signals after a RIB entry is erased
237 *
238 * A RIB entry is erased when the last route associated with a
239 * certain namespace is removed.
240 */
241
Yanbiao Lib9d439d2014-12-11 16:12:32 -0800242 ndn::util::signal::Signal<Rib, Name> afterEraseEntry;
Yanbiao Lic17de832014-11-21 17:51:45 -0800243
Nick Gordon89c4cca2016-11-02 15:42:32 +0000244 /** \brief signals after a Route is added
245 */
246 ndn::util::signal::Signal<Rib, RibRouteRef> afterAddRoute;
247
248 /** \brief signals before a route is removed
249 */
250 ndn::util::signal::Signal<Rib, RibRouteRef> beforeRemoveRoute;
251
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700252private:
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700253 RibTable m_rib;
Vince12e49462014-06-09 13:29:32 -0500254 FaceLookupTable m_faceMap;
Vince Lehman76c751c2014-11-18 17:36:38 -0600255 FibUpdater* m_fibUpdater;
Vince Lehman4387e782014-06-19 16:57:45 -0500256
Vince12e49462014-06-09 13:29:32 -0500257 size_t m_nItems;
Vince Lehman76c751c2014-11-18 17:36:38 -0600258
259 friend class FibUpdater;
260
261private:
262 struct UpdateQueueItem
263 {
264 RibUpdateBatch batch;
265 const Rib::UpdateSuccessCallback managerSuccessCallback;
266 const Rib::UpdateFailureCallback managerFailureCallback;
267 };
268
269PUBLIC_WITH_TESTS_ELSE_PRIVATE:
270 typedef std::list<UpdateQueueItem> UpdateQueue;
271 UpdateQueue m_updateBatches;
272
273private:
274 bool m_isUpdateInProgress;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700275};
276
277inline Rib::const_iterator
278Rib::begin() const
279{
280 return m_rib.begin();
281}
282
283inline Rib::const_iterator
284Rib::end() const
285{
286 return m_rib.end();
287}
288
289inline size_t
290Rib::size() const
291{
Vince12e49462014-06-09 13:29:32 -0500292 return m_nItems;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700293}
294
Vince12e49462014-06-09 13:29:32 -0500295inline bool
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700296Rib::empty() const
297{
298 return m_rib.empty();
299}
300
Vince12e49462014-06-09 13:29:32 -0500301std::ostream&
302operator<<(std::ostream& os, const Rib& rib);
303
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700304} // namespace rib
305} // namespace nfd
306
307#endif // NFD_RIB_RIB_HPP