blob: 2e13692e6bd12af1f8a71cfd9d5239d8002ca3b5 [file] [log] [blame]
Alexander Afanasyev3ecec502014-04-16 13:42:44 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev7c10b3b2015-01-20 12:24:27 -08003 * Copyright (c) 2014-2015, Regents of the University of California,
4 * 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
29#include "common.hpp"
Vince Lehman76c751c2014-11-18 17:36:38 -060030
31#include "rib-entry.hpp"
32#include "rib-update-batch.hpp"
33
34#include <ndn-cxx/management/nfd-control-parameters.hpp>
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070035
36namespace nfd {
37namespace rib {
38
Vince Lehman76c751c2014-11-18 17:36:38 -060039using ndn::nfd::ControlParameters;
40
41class FibUpdater;
42
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070043/** \brief represents the RIB
44 */
Alexander Afanasyev20d31442014-04-19 17:00:53 -070045class Rib : noncopyable
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070046{
47public:
Vince Lehman218be0a2015-01-15 17:25:20 -060048 typedef std::list<shared_ptr<RibEntry>> RibEntryList;
49 typedef std::map<Name, shared_ptr<RibEntry>> RibTable;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070050 typedef RibTable::const_iterator const_iterator;
Vince Lehman218be0a2015-01-15 17:25:20 -060051 typedef std::map<uint64_t, std::list<shared_ptr<RibEntry>>> FaceLookupTable;
52 typedef bool (*RouteComparePredicate)(const Route&, const Route&);
53 typedef std::set<Route, RouteComparePredicate> RouteSet;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070054
55 Rib();
56
Vince Lehman76c751c2014-11-18 17:36:38 -060057 ~Rib();
58
59 void
60 setFibUpdater(FibUpdater* updater);
61
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070062 const_iterator
Vince12e49462014-06-09 13:29:32 -050063 find(const Name& prefix) const;
64
Vince Lehman218be0a2015-01-15 17:25:20 -060065 Route*
66 find(const Name& prefix, const Route& route) const;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070067
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070068 const_iterator
69 begin() const;
70
71 const_iterator
72 end() const;
73
74 size_t
75 size() const;
76
Vince12e49462014-06-09 13:29:32 -050077 bool
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070078 empty() const;
79
Vince12e49462014-06-09 13:29:32 -050080 shared_ptr<RibEntry>
81 findParent(const Name& prefix) const;
82
83 /** \brief finds namespaces under the passed prefix
84 * \return{ a list of entries which are under the passed prefix }
85 */
Vince Lehman218be0a2015-01-15 17:25:20 -060086 std::list<shared_ptr<RibEntry>>
Vince12e49462014-06-09 13:29:32 -050087 findDescendants(const Name& prefix) const;
88
Vince Lehman76c751c2014-11-18 17:36:38 -060089 /** \brief finds namespaces under the passed prefix
90 *
91 * \note Unlike findDescendants, needs to find where prefix would fit in tree
92 * before collecting list of descendant prefixes
93 *
94 * \return{ a list of entries which would be under the passed prefix if the prefix
95 * existed in the RIB }
96 */
97 std::list<shared_ptr<RibEntry>>
98 findDescendantsForNonInsertedName(const Name& prefix) const;
99
100public:
101 typedef function<void()> UpdateSuccessCallback;
102 typedef function<void(uint32_t code, const std::string& error)> UpdateFailureCallback;
103
104 /** \brief passes the provided RibUpdateBatch to FibUpdater to calculate and send FibUpdates.
105 *
106 * If the FIB is updated successfully, onFibUpdateSuccess() will be called, and the
107 * RIB will be updated
108 *
109 * If the FIB update fails, onFibUpdateFailure() will be called, and the RIB will not
110 * be updated.
111 */
112 void
113 beginApplyUpdate(const RibUpdate& update,
114 const UpdateSuccessCallback& onSuccess,
115 const UpdateFailureCallback& onFailure);
116
117 /** \brief starts the FIB update process when a face has been destroyed
118 */
119 void
120 beginRemoveFace(uint64_t faceId);
Vince Lehman4387e782014-06-19 16:57:45 -0500121
122 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600123 onFibUpdateSuccess(const RibUpdateBatch& batch,
124 const RibUpdateList& inheritedRoutes,
125 const Rib::UpdateSuccessCallback& onSuccess);
126
127 void
128 onFibUpdateFailure(const Rib::UpdateFailureCallback& onFailure,
129 uint32_t code, const std::string& error);
130
131 void
132 onRouteExpiration(const Name& prefix, const Route& route);
133
134private:
135 /** \brief adds the passed update to a RibUpdateBatch and adds the batch to
136 * the end of the update queue.
137 *
138 * If an update is not in progress, the front update batch in the queue will be
139 * processed by the RIB.
140 *
141 * If an update is in progress, the added update will eventually be processed
142 * when it reaches the front of the queue; after other update batches are
143 * processed, the queue is advanced.
144 */
145 void
146 addUpdateToQueue(const RibUpdate& update,
147 const Rib::UpdateSuccessCallback& onSuccess,
148 const Rib::UpdateFailureCallback& onFailure);
149
150 /** \brief Attempts to send the front update batch in the queue.
151 *
152 * If an update is not in progress, the front update batch in the queue will be
153 * sent to the RIB for processing.
154 *
155 * If an update is in progress, nothing will be done.
156 */
157 void
158 sendBatchFromQueue();
159
160PUBLIC_WITH_TESTS_ELSE_PRIVATE:
161 // Used by RibManager unit-tests to get sent batch to simulate successful FIB update
162 function<void(RibUpdateBatch)> m_onSendBatchFromQueue;
163
164public:
165 void
166 insert(const Name& prefix, const Route& route);
167
168PUBLIC_WITH_TESTS_ELSE_PRIVATE:
169 void
170 erase(const Name& prefix, const Route& route);
Vince Lehman4387e782014-06-19 16:57:45 -0500171
172private:
Vince12e49462014-06-09 13:29:32 -0500173 RibTable::iterator
174 eraseEntry(RibTable::iterator it);
175
176 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600177 updateRib(const RibUpdateBatch& batch);
Vince Lehman4387e782014-06-19 16:57:45 -0500178
Vince Lehman76c751c2014-11-18 17:36:38 -0600179 /** \brief returns routes inherited from the entry's ancestors
180 *
181 * \return{ a list of inherited routes }
182 */
Vince Lehman218be0a2015-01-15 17:25:20 -0600183 RouteSet
184 getAncestorRoutes(const RibEntry& entry) const;
Vince Lehman4387e782014-06-19 16:57:45 -0500185
Vince Lehman76c751c2014-11-18 17:36:38 -0600186 /** \brief returns routes inherited from the parent of the name and the parent's ancestors
187 *
188 * \note A parent is first found for the passed name before inherited routes are collected
189 *
190 * \return{ a list of inherited routes }
191 */
192 RouteSet
193 getAncestorRoutes(const Name& name) const;
Vince Lehman4387e782014-06-19 16:57:45 -0500194
Vince Lehman76c751c2014-11-18 17:36:38 -0600195 /** \brief applies the passed inheritedRoutes and their actions to the corresponding RibEntries'
196 * inheritedRoutes lists
Vince Lehman4387e782014-06-19 16:57:45 -0500197 */
198 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600199 modifyInheritedRoutes(const RibUpdateList& inheritedRoutes);
Vince Lehman4387e782014-06-19 16:57:45 -0500200
Vince Lehman76c751c2014-11-18 17:36:38 -0600201PUBLIC_WITH_TESTS_ELSE_PRIVATE:
202 typedef std::pair<const Name&,const Route&> NameAndRoute;
203
204 std::list<NameAndRoute>
205 findRoutesWithFaceId(uint64_t faceId);
Vince12e49462014-06-09 13:29:32 -0500206
Yanbiao Lic17de832014-11-21 17:51:45 -0800207public:
Yanbiao Lib9d439d2014-12-11 16:12:32 -0800208 ndn::util::signal::Signal<Rib, Name> afterInsertEntry;
209 ndn::util::signal::Signal<Rib, Name> afterEraseEntry;
Yanbiao Lic17de832014-11-21 17:51:45 -0800210
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700211private:
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700212 RibTable m_rib;
Vince12e49462014-06-09 13:29:32 -0500213 FaceLookupTable m_faceMap;
Vince Lehman76c751c2014-11-18 17:36:38 -0600214 FibUpdater* m_fibUpdater;
Vince Lehman4387e782014-06-19 16:57:45 -0500215
Vince12e49462014-06-09 13:29:32 -0500216 size_t m_nItems;
Vince Lehman76c751c2014-11-18 17:36:38 -0600217
218 friend class FibUpdater;
219
220private:
221 struct UpdateQueueItem
222 {
223 RibUpdateBatch batch;
224 const Rib::UpdateSuccessCallback managerSuccessCallback;
225 const Rib::UpdateFailureCallback managerFailureCallback;
226 };
227
228PUBLIC_WITH_TESTS_ELSE_PRIVATE:
229 typedef std::list<UpdateQueueItem> UpdateQueue;
230 UpdateQueue m_updateBatches;
231
232private:
233 bool m_isUpdateInProgress;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700234};
235
236inline Rib::const_iterator
237Rib::begin() const
238{
239 return m_rib.begin();
240}
241
242inline Rib::const_iterator
243Rib::end() const
244{
245 return m_rib.end();
246}
247
248inline size_t
249Rib::size() const
250{
Vince12e49462014-06-09 13:29:32 -0500251 return m_nItems;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700252}
253
Vince12e49462014-06-09 13:29:32 -0500254inline bool
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700255Rib::empty() const
256{
257 return m_rib.empty();
258}
259
Vince12e49462014-06-09 13:29:32 -0500260std::ostream&
261operator<<(std::ostream& os, const Rib& rib);
262
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700263} // namespace rib
264} // namespace nfd
265
266#endif // NFD_RIB_RIB_HPP