blob: 4c9e6088ecd3594effd00ef068bebb788285dc7b [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
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070041/** \brief represents the RIB
42 */
Alexander Afanasyev20d31442014-04-19 17:00:53 -070043class Rib : noncopyable
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070044{
45public:
Vince Lehman218be0a2015-01-15 17:25:20 -060046 typedef std::list<shared_ptr<RibEntry>> RibEntryList;
47 typedef std::map<Name, shared_ptr<RibEntry>> RibTable;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070048 typedef RibTable::const_iterator const_iterator;
Vince Lehman218be0a2015-01-15 17:25:20 -060049 typedef std::map<uint64_t, std::list<shared_ptr<RibEntry>>> FaceLookupTable;
50 typedef bool (*RouteComparePredicate)(const Route&, const Route&);
51 typedef std::set<Route, RouteComparePredicate> RouteSet;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070052
53 Rib();
54
Vince Lehman76c751c2014-11-18 17:36:38 -060055 ~Rib();
56
57 void
58 setFibUpdater(FibUpdater* updater);
59
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070060 const_iterator
Vince12e49462014-06-09 13:29:32 -050061 find(const Name& prefix) const;
62
Vince Lehman218be0a2015-01-15 17:25:20 -060063 Route*
64 find(const Name& prefix, const Route& route) const;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070065
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070066 const_iterator
67 begin() const;
68
69 const_iterator
70 end() const;
71
72 size_t
73 size() const;
74
Vince12e49462014-06-09 13:29:32 -050075 bool
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070076 empty() const;
77
Vince12e49462014-06-09 13:29:32 -050078 shared_ptr<RibEntry>
79 findParent(const Name& prefix) const;
80
81 /** \brief finds namespaces under the passed prefix
82 * \return{ a list of entries which are under the passed prefix }
83 */
Vince Lehman218be0a2015-01-15 17:25:20 -060084 std::list<shared_ptr<RibEntry>>
Vince12e49462014-06-09 13:29:32 -050085 findDescendants(const Name& prefix) const;
86
Vince Lehman76c751c2014-11-18 17:36:38 -060087 /** \brief finds namespaces under the passed prefix
88 *
89 * \note Unlike findDescendants, needs to find where prefix would fit in tree
90 * before collecting list of descendant prefixes
91 *
92 * \return{ a list of entries which would be under the passed prefix if the prefix
93 * existed in the RIB }
94 */
95 std::list<shared_ptr<RibEntry>>
96 findDescendantsForNonInsertedName(const Name& prefix) const;
97
98public:
99 typedef function<void()> UpdateSuccessCallback;
100 typedef function<void(uint32_t code, const std::string& error)> UpdateFailureCallback;
101
102 /** \brief passes the provided RibUpdateBatch to FibUpdater to calculate and send FibUpdates.
103 *
104 * If the FIB is updated successfully, onFibUpdateSuccess() will be called, and the
105 * RIB will be updated
106 *
107 * If the FIB update fails, onFibUpdateFailure() will be called, and the RIB will not
108 * be updated.
109 */
110 void
111 beginApplyUpdate(const RibUpdate& update,
112 const UpdateSuccessCallback& onSuccess,
113 const UpdateFailureCallback& onFailure);
114
115 /** \brief starts the FIB update process when a face has been destroyed
116 */
117 void
118 beginRemoveFace(uint64_t faceId);
Vince Lehman4387e782014-06-19 16:57:45 -0500119
120 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600121 onFibUpdateSuccess(const RibUpdateBatch& batch,
122 const RibUpdateList& inheritedRoutes,
123 const Rib::UpdateSuccessCallback& onSuccess);
124
125 void
126 onFibUpdateFailure(const Rib::UpdateFailureCallback& onFailure,
127 uint32_t code, const std::string& error);
128
129 void
130 onRouteExpiration(const Name& prefix, const Route& route);
131
Junxiao Shi9f5b01d2016-08-05 03:54:28 +0000132 void
133 insert(const Name& prefix, const Route& route);
134
Vince Lehman76c751c2014-11-18 17:36:38 -0600135private:
136 /** \brief adds the passed update to a RibUpdateBatch and adds the batch to
137 * the end of the update queue.
138 *
139 * If an update is not in progress, the front update batch in the queue will be
140 * processed by the RIB.
141 *
142 * If an update is in progress, the added update will eventually be processed
143 * when it reaches the front of the queue; after other update batches are
144 * processed, the queue is advanced.
145 */
146 void
147 addUpdateToQueue(const RibUpdate& update,
148 const Rib::UpdateSuccessCallback& onSuccess,
149 const Rib::UpdateFailureCallback& onFailure);
150
151 /** \brief Attempts to send the front update batch in the queue.
152 *
153 * If an update is not in progress, the front update batch in the queue will be
154 * sent to the RIB for processing.
155 *
156 * If an update is in progress, nothing will be done.
157 */
158 void
159 sendBatchFromQueue();
160
161PUBLIC_WITH_TESTS_ELSE_PRIVATE:
162 // Used by RibManager unit-tests to get sent batch to simulate successful FIB update
163 function<void(RibUpdateBatch)> m_onSendBatchFromQueue;
164
Vince Lehman76c751c2014-11-18 17:36:38 -0600165 void
166 erase(const Name& prefix, const Route& route);
Vince Lehman4387e782014-06-19 16:57:45 -0500167
168private:
Vince12e49462014-06-09 13:29:32 -0500169 RibTable::iterator
170 eraseEntry(RibTable::iterator it);
171
172 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600173 updateRib(const RibUpdateBatch& batch);
Vince Lehman4387e782014-06-19 16:57:45 -0500174
Vince Lehman76c751c2014-11-18 17:36:38 -0600175 /** \brief returns routes inherited from the entry's ancestors
176 *
177 * \return{ a list of inherited routes }
178 */
Vince Lehman218be0a2015-01-15 17:25:20 -0600179 RouteSet
180 getAncestorRoutes(const RibEntry& entry) const;
Vince Lehman4387e782014-06-19 16:57:45 -0500181
Vince Lehman76c751c2014-11-18 17:36:38 -0600182 /** \brief returns routes inherited from the parent of the name and the parent's ancestors
183 *
184 * \note A parent is first found for the passed name before inherited routes are collected
185 *
186 * \return{ a list of inherited routes }
187 */
188 RouteSet
189 getAncestorRoutes(const Name& name) const;
Vince Lehman4387e782014-06-19 16:57:45 -0500190
Vince Lehman76c751c2014-11-18 17:36:38 -0600191 /** \brief applies the passed inheritedRoutes and their actions to the corresponding RibEntries'
192 * inheritedRoutes lists
Vince Lehman4387e782014-06-19 16:57:45 -0500193 */
194 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600195 modifyInheritedRoutes(const RibUpdateList& inheritedRoutes);
Vince Lehman4387e782014-06-19 16:57:45 -0500196
Vince Lehman76c751c2014-11-18 17:36:38 -0600197PUBLIC_WITH_TESTS_ELSE_PRIVATE:
198 typedef std::pair<const Name&,const Route&> NameAndRoute;
199
200 std::list<NameAndRoute>
201 findRoutesWithFaceId(uint64_t faceId);
Vince12e49462014-06-09 13:29:32 -0500202
Yanbiao Lic17de832014-11-21 17:51:45 -0800203public:
Yanbiao Lib9d439d2014-12-11 16:12:32 -0800204 ndn::util::signal::Signal<Rib, Name> afterInsertEntry;
205 ndn::util::signal::Signal<Rib, Name> afterEraseEntry;
Yanbiao Lic17de832014-11-21 17:51:45 -0800206
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700207private:
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700208 RibTable m_rib;
Vince12e49462014-06-09 13:29:32 -0500209 FaceLookupTable m_faceMap;
Vince Lehman76c751c2014-11-18 17:36:38 -0600210 FibUpdater* m_fibUpdater;
Vince Lehman4387e782014-06-19 16:57:45 -0500211
Vince12e49462014-06-09 13:29:32 -0500212 size_t m_nItems;
Vince Lehman76c751c2014-11-18 17:36:38 -0600213
214 friend class FibUpdater;
215
216private:
217 struct UpdateQueueItem
218 {
219 RibUpdateBatch batch;
220 const Rib::UpdateSuccessCallback managerSuccessCallback;
221 const Rib::UpdateFailureCallback managerFailureCallback;
222 };
223
224PUBLIC_WITH_TESTS_ELSE_PRIVATE:
225 typedef std::list<UpdateQueueItem> UpdateQueue;
226 UpdateQueue m_updateBatches;
227
228private:
229 bool m_isUpdateInProgress;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700230};
231
232inline Rib::const_iterator
233Rib::begin() const
234{
235 return m_rib.begin();
236}
237
238inline Rib::const_iterator
239Rib::end() const
240{
241 return m_rib.end();
242}
243
244inline size_t
245Rib::size() const
246{
Vince12e49462014-06-09 13:29:32 -0500247 return m_nItems;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700248}
249
Vince12e49462014-06-09 13:29:32 -0500250inline bool
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700251Rib::empty() const
252{
253 return m_rib.empty();
254}
255
Vince12e49462014-06-09 13:29:32 -0500256std::ostream&
257operator<<(std::ostream& os, const Rib& rib);
258
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700259} // namespace rib
260} // namespace nfd
261
262#endif // NFD_RIB_RIB_HPP