blob: 70554e68b8592f427dec7b285b25b9436aad2d0f [file] [log] [blame]
Alexander Afanasyev3ecec502014-04-16 13:42:44 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi9f5b01d2016-08-05 03:54:28 +00003 * Copyright (c) 2014-2016, 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
Nick Gordon89c4cca2016-11-02 15:42:32 +000041 /** \brief references a route
42 */
43struct RibRouteRef
44{
45 shared_ptr<RibEntry> entry;
46 RibEntry::const_iterator route;
47};
48
49/** \brief represents the Routing Information Base
50
51 The Routing Information Base contains a collection of Routes, each
52 represents a piece of static or dynamic routing information
53 registered by applications, operators, or NFD itself. Routes
54 associated with the same namespace are collected into a RIB entry.
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070055 */
Alexander Afanasyev20d31442014-04-19 17:00:53 -070056class Rib : noncopyable
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070057{
58public:
Vince Lehman218be0a2015-01-15 17:25:20 -060059 typedef std::list<shared_ptr<RibEntry>> RibEntryList;
60 typedef std::map<Name, shared_ptr<RibEntry>> RibTable;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070061 typedef RibTable::const_iterator const_iterator;
Vince Lehman218be0a2015-01-15 17:25:20 -060062 typedef std::map<uint64_t, std::list<shared_ptr<RibEntry>>> FaceLookupTable;
63 typedef bool (*RouteComparePredicate)(const Route&, const Route&);
64 typedef std::set<Route, RouteComparePredicate> RouteSet;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070065
66 Rib();
67
Vince Lehman76c751c2014-11-18 17:36:38 -060068 ~Rib();
69
70 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
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070079 const_iterator
80 begin() const;
81
82 const_iterator
83 end() const;
84
85 size_t
86 size() const;
87
Vince12e49462014-06-09 13:29:32 -050088 bool
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070089 empty() const;
90
Vince12e49462014-06-09 13:29:32 -050091 shared_ptr<RibEntry>
92 findParent(const Name& prefix) const;
93
94 /** \brief finds namespaces under the passed prefix
95 * \return{ a list of entries which are under the passed prefix }
96 */
Vince Lehman218be0a2015-01-15 17:25:20 -060097 std::list<shared_ptr<RibEntry>>
Vince12e49462014-06-09 13:29:32 -050098 findDescendants(const Name& prefix) const;
99
Vince Lehman76c751c2014-11-18 17:36:38 -0600100 /** \brief finds namespaces under the passed prefix
101 *
102 * \note Unlike findDescendants, needs to find where prefix would fit in tree
103 * before collecting list of descendant prefixes
104 *
105 * \return{ a list of entries which would be under the passed prefix if the prefix
106 * existed in the RIB }
107 */
108 std::list<shared_ptr<RibEntry>>
109 findDescendantsForNonInsertedName(const Name& prefix) const;
110
111public:
112 typedef function<void()> UpdateSuccessCallback;
113 typedef function<void(uint32_t code, const std::string& error)> UpdateFailureCallback;
114
115 /** \brief passes the provided RibUpdateBatch to FibUpdater to calculate and send FibUpdates.
116 *
117 * If the FIB is updated successfully, onFibUpdateSuccess() will be called, and the
118 * RIB will be updated
119 *
120 * If the FIB update fails, onFibUpdateFailure() will be called, and the RIB will not
121 * be updated.
122 */
123 void
124 beginApplyUpdate(const RibUpdate& update,
125 const UpdateSuccessCallback& onSuccess,
126 const UpdateFailureCallback& onFailure);
127
128 /** \brief starts the FIB update process when a face has been destroyed
129 */
130 void
131 beginRemoveFace(uint64_t faceId);
Vince Lehman4387e782014-06-19 16:57:45 -0500132
133 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600134 onFibUpdateSuccess(const RibUpdateBatch& batch,
135 const RibUpdateList& inheritedRoutes,
136 const Rib::UpdateSuccessCallback& onSuccess);
137
138 void
139 onFibUpdateFailure(const Rib::UpdateFailureCallback& onFailure,
140 uint32_t code, const std::string& error);
141
142 void
143 onRouteExpiration(const Name& prefix, const Route& route);
144
Junxiao Shi9f5b01d2016-08-05 03:54:28 +0000145 void
146 insert(const Name& prefix, const Route& route);
147
Vince Lehman76c751c2014-11-18 17:36:38 -0600148private:
149 /** \brief adds the passed update to a RibUpdateBatch and adds the batch to
150 * the end of the update queue.
151 *
152 * If an update is not in progress, the front update batch in the queue will be
153 * processed by the RIB.
154 *
155 * If an update is in progress, the added update will eventually be processed
156 * when it reaches the front of the queue; after other update batches are
157 * processed, the queue is advanced.
158 */
159 void
160 addUpdateToQueue(const RibUpdate& update,
161 const Rib::UpdateSuccessCallback& onSuccess,
162 const Rib::UpdateFailureCallback& onFailure);
163
164 /** \brief Attempts to send the front update batch in the queue.
165 *
166 * If an update is not in progress, the front update batch in the queue will be
167 * sent to the RIB for processing.
168 *
169 * If an update is in progress, nothing will be done.
170 */
171 void
172 sendBatchFromQueue();
173
174PUBLIC_WITH_TESTS_ELSE_PRIVATE:
175 // Used by RibManager unit-tests to get sent batch to simulate successful FIB update
176 function<void(RibUpdateBatch)> m_onSendBatchFromQueue;
177
Vince Lehman76c751c2014-11-18 17:36:38 -0600178 void
179 erase(const Name& prefix, const Route& route);
Vince Lehman4387e782014-06-19 16:57:45 -0500180
181private:
Vince12e49462014-06-09 13:29:32 -0500182 RibTable::iterator
183 eraseEntry(RibTable::iterator it);
184
185 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600186 updateRib(const RibUpdateBatch& batch);
Vince Lehman4387e782014-06-19 16:57:45 -0500187
Vince Lehman76c751c2014-11-18 17:36:38 -0600188 /** \brief returns routes inherited from the entry's ancestors
189 *
190 * \return{ a list of inherited routes }
191 */
Vince Lehman218be0a2015-01-15 17:25:20 -0600192 RouteSet
193 getAncestorRoutes(const RibEntry& entry) const;
Vince Lehman4387e782014-06-19 16:57:45 -0500194
Vince Lehman76c751c2014-11-18 17:36:38 -0600195 /** \brief returns routes inherited from the parent of the name and the parent's ancestors
196 *
197 * \note A parent is first found for the passed name before inherited routes are collected
198 *
199 * \return{ a list of inherited routes }
200 */
201 RouteSet
202 getAncestorRoutes(const Name& name) const;
Vince Lehman4387e782014-06-19 16:57:45 -0500203
Vince Lehman76c751c2014-11-18 17:36:38 -0600204 /** \brief applies the passed inheritedRoutes and their actions to the corresponding RibEntries'
205 * inheritedRoutes lists
Vince Lehman4387e782014-06-19 16:57:45 -0500206 */
207 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600208 modifyInheritedRoutes(const RibUpdateList& inheritedRoutes);
Vince Lehman4387e782014-06-19 16:57:45 -0500209
Vince Lehman76c751c2014-11-18 17:36:38 -0600210PUBLIC_WITH_TESTS_ELSE_PRIVATE:
211 typedef std::pair<const Name&,const Route&> NameAndRoute;
212
213 std::list<NameAndRoute>
214 findRoutesWithFaceId(uint64_t faceId);
Vince12e49462014-06-09 13:29:32 -0500215
Yanbiao Lic17de832014-11-21 17:51:45 -0800216public:
Nick Gordon89c4cca2016-11-02 15:42:32 +0000217 /** \brief signals after a RIB entry is inserted
218 *
219 * A RIB entry is inserted when the first route associated with a
220 * certain namespace is added.
221 */
Yanbiao Lib9d439d2014-12-11 16:12:32 -0800222 ndn::util::signal::Signal<Rib, Name> afterInsertEntry;
Nick Gordon89c4cca2016-11-02 15:42:32 +0000223
224 /** \brief signals after a RIB entry is erased
225 *
226 * A RIB entry is erased when the last route associated with a
227 * certain namespace is removed.
228 */
229
Yanbiao Lib9d439d2014-12-11 16:12:32 -0800230 ndn::util::signal::Signal<Rib, Name> afterEraseEntry;
Yanbiao Lic17de832014-11-21 17:51:45 -0800231
Nick Gordon89c4cca2016-11-02 15:42:32 +0000232 /** \brief signals after a Route is added
233 */
234 ndn::util::signal::Signal<Rib, RibRouteRef> afterAddRoute;
235
236 /** \brief signals before a route is removed
237 */
238 ndn::util::signal::Signal<Rib, RibRouteRef> beforeRemoveRoute;
239
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700240private:
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700241 RibTable m_rib;
Vince12e49462014-06-09 13:29:32 -0500242 FaceLookupTable m_faceMap;
Vince Lehman76c751c2014-11-18 17:36:38 -0600243 FibUpdater* m_fibUpdater;
Vince Lehman4387e782014-06-19 16:57:45 -0500244
Vince12e49462014-06-09 13:29:32 -0500245 size_t m_nItems;
Vince Lehman76c751c2014-11-18 17:36:38 -0600246
247 friend class FibUpdater;
248
249private:
250 struct UpdateQueueItem
251 {
252 RibUpdateBatch batch;
253 const Rib::UpdateSuccessCallback managerSuccessCallback;
254 const Rib::UpdateFailureCallback managerFailureCallback;
255 };
256
257PUBLIC_WITH_TESTS_ELSE_PRIVATE:
258 typedef std::list<UpdateQueueItem> UpdateQueue;
259 UpdateQueue m_updateBatches;
260
261private:
262 bool m_isUpdateInProgress;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700263};
264
265inline Rib::const_iterator
266Rib::begin() const
267{
268 return m_rib.begin();
269}
270
271inline Rib::const_iterator
272Rib::end() const
273{
274 return m_rib.end();
275}
276
277inline size_t
278Rib::size() const
279{
Vince12e49462014-06-09 13:29:32 -0500280 return m_nItems;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700281}
282
Vince12e49462014-06-09 13:29:32 -0500283inline bool
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700284Rib::empty() const
285{
286 return m_rib.empty();
287}
288
Vince12e49462014-06-09 13:29:32 -0500289std::ostream&
290operator<<(std::ostream& os, const Rib& rib);
291
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700292} // namespace rib
293} // namespace nfd
294
295#endif // NFD_RIB_RIB_HPP