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