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