blob: 2d7761ae652df4a582cc6406769d867302077390 [file] [log] [blame]
Vince Lehman76c751c2014-11-18 17:36:38 -06001/* -*- 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,
Vince Lehman76c751c2014-11-18 17:36:38 -06004 * 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.
10 *
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/>.
24 */
25
26#ifndef NFD_RIB_FIB_UPDATER_HPP
27#define NFD_RIB_FIB_UPDATER_HPP
28
Junxiao Shi9f5b01d2016-08-05 03:54:28 +000029#include "core/common.hpp"
Vince Lehman76c751c2014-11-18 17:36:38 -060030#include "fib-update.hpp"
31#include "rib.hpp"
32#include "rib-update-batch.hpp"
33
34#include <ndn-cxx/management/nfd-controller.hpp>
35
36namespace nfd {
37namespace rib {
38
39/** \brief computes FibUpdates based on updates to the RIB and sends them to NFD
40 */
41class FibUpdater : noncopyable
42{
43public:
44 class Error : public std::runtime_error
45 {
46 public:
47 explicit
48 Error(const std::string& what)
49 : std::runtime_error(what)
50 {
51 }
52 };
53
54public:
55 typedef std::list<FibUpdate> FibUpdateList;
56
57 typedef function<void(RibUpdateList inheritedRoutes)> FibUpdateSuccessCallback;
58 typedef function<void(uint32_t code, const std::string& error)> FibUpdateFailureCallback;
59
60 FibUpdater(Rib& rib, ndn::nfd::Controller& controller);
61
62 /** \brief computes FibUpdates using the provided RibUpdateBatch and then sends the
63 * updates to NFD's FIB
64 *
65 * \note Caller must guarantee that the previous batch has either succeeded or failed
66 * before calling this method
67 */
68 void
69 computeAndSendFibUpdates(const RibUpdateBatch& batch,
70 const FibUpdateSuccessCallback& onSuccess,
71 const FibUpdateFailureCallback& onFailure);
72
73PUBLIC_WITH_TESTS_ELSE_PRIVATE:
74 /** \brief determines the type of action that will be performed on the RIB and calls the
75 * corresponding computation method
76 */
77 void
78 computeUpdates(const RibUpdateBatch& batch);
79
80 /** \brief sends the passed updates to NFD
81 *
82 * onSuccess or onFailure will be called based on the results in
83 * onUpdateSuccess or onUpdateFailure
84 *
85 * \see FibUpdater::onUpdateSuccess
86 * \see FibUpdater::onUpdateFailure
87 */
88 void
89 sendUpdates(const FibUpdateList& updates,
90 const FibUpdateSuccessCallback& onSuccess,
91 const FibUpdateFailureCallback& onFailure);
92
93 /** \brief sends the updates in m_updatesForBatchFaceId to NFD if any exist,
94 * otherwise calls FibUpdater::sendUpdatesForNonBatchFaceId.
95 */
96 void
97 sendUpdatesForBatchFaceId(const FibUpdateSuccessCallback& onSuccess,
98 const FibUpdateFailureCallback& onFailure);
99
100 /** \brief sends the updates in m_updatesForNonBatchFaceId to NFD if any exist,
101 * otherwise calls onSuccess.
102 */
103 void
104 sendUpdatesForNonBatchFaceId(const FibUpdateSuccessCallback& onSuccess,
105 const FibUpdateFailureCallback& onFailure);
106
107 /** \brief sends a FibAddNextHopCommand to NFD using the parameters supplied by
108 * the passed update
109 *
110 * \param nTimeouts the number of times this FibUpdate has failed due to timeout
111 */
112 void
113 sendAddNextHopUpdate(const FibUpdate& update,
114 const FibUpdateSuccessCallback& onSuccess,
115 const FibUpdateFailureCallback& onFailure,
116 uint32_t nTimeouts = 0);
117
118 /** \brief sends a FibRemoveNextHopCommand to NFD using the parameters supplied by
119 * the passed update
120 *
121 * \param nTimeouts the number of times this FibUpdate has failed due to timeout
122 */
123 void
124 sendRemoveNextHopUpdate(const FibUpdate& update,
125 const FibUpdateSuccessCallback& onSuccess,
126 const FibUpdateFailureCallback& onFailure,
127 uint32_t nTimeouts = 0);
128
129private:
130 /** \brief calculates the FibUpdates generated by a RIB registration
131 */
132 void
133 computeUpdatesForRegistration(const RibUpdate& update);
134
135 /** \brief calculates the FibUpdates generated by a RIB unregistration
136 */
137 void
138 computeUpdatesForUnregistration(const RibUpdate& update);
139
140PUBLIC_WITH_TESTS_ELSE_PRIVATE:
141 /** \brief callback used by NfdController when a FibAddNextHopCommand or FibRemoveNextHopCommand
142 * is successful.
143 *
144 * If the update has the same Face ID as the batch being processed, the update is
145 * removed from m_updatesForBatchFaceId. If m_updatesForBatchFaceId becomes empty,
146 * the updates with a different Face ID than the batch are sent to NFD.
147 *
148 * If the update has a different Face ID than the batch being processed, the update is
149 * removed from m_updatesForBatchNonFaceId. If m_updatesForBatchNonFaceId becomes empty,
150 * the FIB update process is considered a success.
151 */
152 void
153 onUpdateSuccess(const FibUpdate update,
154 const FibUpdateSuccessCallback& onSuccess,
155 const FibUpdateFailureCallback& onFailure);
156
157 /** \brief callback used by NfdController when a FibAddNextHopCommand or FibRemoveNextHopCommand
158 * is successful.
159 *
160 * If the update has not reached the max number of timeouts allowed, the update
161 * is retried.
162 *
163 * If the update failed due to a non-existent face and the update has the same Face ID
164 * as the update batch, the FIB update process fails.
165 *
166 * If the update failed due to a non-existent face and the update has a different
167 * face than the update batch, the update is not retried and the error is
168 * ignored.
169 *
170 * Otherwise, a non-recoverable error has occurred and an exception is thrown.
171 */
172 void
173 onUpdateError(const FibUpdate update,
174 const FibUpdateSuccessCallback& onSuccess,
175 const FibUpdateFailureCallback& onFailure,
176 uint32_t code, const std::string& error, uint32_t nTimeouts);
177
178private:
179 /** \brief adds the update to an update list based on its Face ID
180 *
181 * If the update has the same Face ID as the update batch, the update is added
182 * to m_updatesForBatchFaceId.
183 *
184 * Otherwise, the update is added to m_updatesForBatchNonFaceId.
185 */
186 void
187 addFibUpdate(const FibUpdate update);
188
189 /** \brief creates records of the passed routes added to the entry and creates FIB updates
190 */
191 void
192 addInheritedRoutes(const RibEntry& entry, const Rib::RouteSet& routesToAdd);
193
194 /** \brief creates records of the passed routes added to the name and creates FIB updates.
195 * Routes in routesToAdd with the same Face ID as ignore will be not be considered.
196 */
197 void
198 addInheritedRoutes(const Name& name, const Rib::RouteSet& routesToAdd, const Route& ignore);
199
200 /** \brief creates records of the passed routes removed from the entry and creates FIB updates
201 */
202 void
203 removeInheritedRoutes(const RibEntry& entry, const Rib::RouteSet& routesToRemove);
204
205 /** \brief calculates updates for a name that will create a new RIB entry
206 */
207 void
208 createFibUpdatesForNewRibEntry(const Name& name, const Route& route,
209 const Rib::RibEntryList& children);
210
211 /** \brief calculates updates for a new route added to a RIB entry
212 */
213 void
214 createFibUpdatesForNewRoute(const RibEntry& entry, const Route& route,
215 const bool captureWasTurnedOn);
216
217 /** \brief calculates updates for changes to an existing route for a RIB entry
218 */
219 void
220 createFibUpdatesForUpdatedRoute(const RibEntry& entry, const Route& route,
221 const Route& existingRoute);
222
223 /** \brief calculates updates for a an existing route removed from a RIB entry
224 */
225 void
226 createFibUpdatesForErasedRoute(const RibEntry& entry, const Route& route,
227 const bool captureWasTurnedOff);
228
229 /** \brief calculates updates for an entry that will be removed from the RIB
230 */
231 void
232 createFibUpdatesForErasedRibEntry(const RibEntry& entry);
233
234 /** \brief adds and removes passed routes to children's inherited routes
235 */
236 void
237 modifyChildrensInheritedRoutes(const Rib::RibEntryList& children,
238 const Rib::RouteSet& routesToAdd,
239 const Rib::RouteSet& routesToRemove);
240
241 /** \brief traverses the entry's children adding and removing the passed routes
242 */
243 void
244 traverseSubTree(const RibEntry& entry, Rib::RouteSet routesToAdd, Rib::RouteSet routesToRemove);
245
246private:
247 /** \brief creates a record of a calculated inherited route that should be added to the entry
248 */
249 void
250 addInheritedRoute(const Name& name, const Route& route);
251
252 /** \brief creates a record of an existing inherited route that should be removed from the entry
253 */
254 void
255 removeInheritedRoute(const Name& name, const Route& route);
256
257private:
258 const Rib& m_rib;
259 ndn::nfd::Controller& m_controller;
260 uint64_t m_batchFaceId;
261
262PUBLIC_WITH_TESTS_ELSE_PRIVATE:
263 FibUpdateList m_updatesForBatchFaceId;
264 FibUpdateList m_updatesForNonBatchFaceId;
265
266 /** \brief list of inherited routes generated during FIB update calculation;
267 * passed to the RIB when updates are completed successfully
268 */
269 RibUpdateList m_inheritedRoutes;
270
271private:
272 static const unsigned int MAX_NUM_TIMEOUTS;
273 static const uint32_t ERROR_FACE_NOT_FOUND;
274};
275
276} // namespace rib
277} // namespace nfd
278
279#endif // NFD_RIB_FIB_UPDATER_HPP