blob: e2313417896c115d070f81bb5cc1b19314bb5bfa [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 Pesaventoe422f9e2022-06-03 01:30:23 -04003 * Copyright (c) 2014-2022, 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
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040036namespace nfd::rib {
Vince Lehman76c751c2014-11-18 17:36:38 -060037
38/** \brief computes FibUpdates based on updates to the RIB and sends them to NFD
39 */
40class FibUpdater : noncopyable
41{
42public:
43 class Error : public std::runtime_error
44 {
45 public:
Davide Pesavento1b077f62019-02-19 19:19:44 -050046 using std::runtime_error::runtime_error;
Vince Lehman76c751c2014-11-18 17:36:38 -060047 };
48
49public:
Junxiao Shidf1dc652019-08-30 19:03:19 +000050 using FibUpdateList = std::list<FibUpdate>;
51 using FibUpdateSuccessCallback = std::function<void(RibUpdateList inheritedRoutes)>;
52 using FibUpdateFailureCallback = std::function<void(uint32_t code, const std::string& error)>;
Vince Lehman76c751c2014-11-18 17:36:38 -060053
54 FibUpdater(Rib& rib, ndn::nfd::Controller& controller);
55
Davide Pesavento264af772021-02-09 21:48:24 -050056 NFD_VIRTUAL_WITH_TESTS
Junxiao Shidf1dc652019-08-30 19:03:19 +000057 ~FibUpdater() = default;
58
Vince Lehman76c751c2014-11-18 17:36:38 -060059 /** \brief computes FibUpdates using the provided RibUpdateBatch and then sends the
60 * updates to NFD's FIB
61 *
62 * \note Caller must guarantee that the previous batch has either succeeded or failed
63 * before calling this method
64 */
65 void
66 computeAndSendFibUpdates(const RibUpdateBatch& batch,
67 const FibUpdateSuccessCallback& onSuccess,
68 const FibUpdateFailureCallback& onFailure);
69
Junxiao Shidf1dc652019-08-30 19:03:19 +000070private:
Vince Lehman76c751c2014-11-18 17:36:38 -060071 /** \brief determines the type of action that will be performed on the RIB and calls the
72 * corresponding computation method
73 */
74 void
75 computeUpdates(const RibUpdateBatch& batch);
76
77 /** \brief sends the passed updates to NFD
78 *
79 * onSuccess or onFailure will be called based on the results in
80 * onUpdateSuccess or onUpdateFailure
81 *
82 * \see FibUpdater::onUpdateSuccess
83 * \see FibUpdater::onUpdateFailure
84 */
85 void
86 sendUpdates(const FibUpdateList& updates,
87 const FibUpdateSuccessCallback& onSuccess,
88 const FibUpdateFailureCallback& onFailure);
89
90 /** \brief sends the updates in m_updatesForBatchFaceId to NFD if any exist,
91 * otherwise calls FibUpdater::sendUpdatesForNonBatchFaceId.
92 */
93 void
94 sendUpdatesForBatchFaceId(const FibUpdateSuccessCallback& onSuccess,
95 const FibUpdateFailureCallback& onFailure);
96
97 /** \brief sends the updates in m_updatesForNonBatchFaceId to NFD if any exist,
98 * otherwise calls onSuccess.
99 */
100 void
101 sendUpdatesForNonBatchFaceId(const FibUpdateSuccessCallback& onSuccess,
102 const FibUpdateFailureCallback& onFailure);
103
Davide Pesavento264af772021-02-09 21:48:24 -0500104NFD_PROTECTED_WITH_TESTS_ELSE_PRIVATE:
Vince Lehman76c751c2014-11-18 17:36:38 -0600105 /** \brief sends a FibAddNextHopCommand to NFD using the parameters supplied by
106 * the passed update
107 *
108 * \param nTimeouts the number of times this FibUpdate has failed due to timeout
109 */
Davide Pesavento264af772021-02-09 21:48:24 -0500110 NFD_VIRTUAL_WITH_TESTS void
Vince Lehman76c751c2014-11-18 17:36:38 -0600111 sendAddNextHopUpdate(const FibUpdate& update,
112 const FibUpdateSuccessCallback& onSuccess,
113 const FibUpdateFailureCallback& onFailure,
114 uint32_t nTimeouts = 0);
115
116 /** \brief sends a FibRemoveNextHopCommand to NFD using the parameters supplied by
117 * the passed update
118 *
119 * \param nTimeouts the number of times this FibUpdate has failed due to timeout
120 */
Davide Pesavento264af772021-02-09 21:48:24 -0500121 NFD_VIRTUAL_WITH_TESTS void
Vince Lehman76c751c2014-11-18 17:36:38 -0600122 sendRemoveNextHopUpdate(const FibUpdate& update,
123 const FibUpdateSuccessCallback& onSuccess,
124 const FibUpdateFailureCallback& onFailure,
125 uint32_t nTimeouts = 0);
126
127private:
128 /** \brief calculates the FibUpdates generated by a RIB registration
129 */
130 void
131 computeUpdatesForRegistration(const RibUpdate& update);
132
133 /** \brief calculates the FibUpdates generated by a RIB unregistration
134 */
135 void
136 computeUpdatesForUnregistration(const RibUpdate& update);
137
Davide Pesavento264af772021-02-09 21:48:24 -0500138NFD_PROTECTED_WITH_TESTS_ELSE_PRIVATE:
Vince Lehman76c751c2014-11-18 17:36:38 -0600139 /** \brief callback used by NfdController when a FibAddNextHopCommand or FibRemoveNextHopCommand
140 * is successful.
141 *
142 * If the update has the same Face ID as the batch being processed, the update is
143 * removed from m_updatesForBatchFaceId. If m_updatesForBatchFaceId becomes empty,
144 * the updates with a different Face ID than the batch are sent to NFD.
145 *
146 * If the update has a different Face ID than the batch being processed, the update is
147 * removed from m_updatesForBatchNonFaceId. If m_updatesForBatchNonFaceId becomes empty,
148 * the FIB update process is considered a success.
149 */
150 void
Davide Pesavento412c9822021-07-02 00:21:05 -0400151 onUpdateSuccess(const FibUpdate& update,
Vince Lehman76c751c2014-11-18 17:36:38 -0600152 const FibUpdateSuccessCallback& onSuccess,
153 const FibUpdateFailureCallback& onFailure);
154
155 /** \brief callback used by NfdController when a FibAddNextHopCommand or FibRemoveNextHopCommand
156 * is successful.
157 *
158 * If the update has not reached the max number of timeouts allowed, the update
159 * is retried.
160 *
161 * If the update failed due to a non-existent face and the update has the same Face ID
162 * as the update batch, the FIB update process fails.
163 *
164 * If the update failed due to a non-existent face and the update has a different
165 * face than the update batch, the update is not retried and the error is
166 * ignored.
167 *
168 * Otherwise, a non-recoverable error has occurred and an exception is thrown.
169 */
170 void
Davide Pesavento412c9822021-07-02 00:21:05 -0400171 onUpdateError(const FibUpdate& update,
Vince Lehman76c751c2014-11-18 17:36:38 -0600172 const FibUpdateSuccessCallback& onSuccess,
173 const FibUpdateFailureCallback& onFailure,
Junxiao Shi29b41282016-08-22 03:47:02 +0000174 const ndn::nfd::ControlResponse& response, uint32_t nTimeouts);
Vince Lehman76c751c2014-11-18 17:36:38 -0600175
176private:
177 /** \brief adds the update to an update list based on its Face ID
178 *
179 * If the update has the same Face ID as the update batch, the update is added
180 * to m_updatesForBatchFaceId.
181 *
182 * Otherwise, the update is added to m_updatesForBatchNonFaceId.
183 */
184 void
Davide Pesavento412c9822021-07-02 00:21:05 -0400185 addFibUpdate(const FibUpdate& update);
Vince Lehman76c751c2014-11-18 17:36:38 -0600186
187 /** \brief creates records of the passed routes added to the entry and creates FIB updates
188 */
189 void
190 addInheritedRoutes(const RibEntry& entry, const Rib::RouteSet& routesToAdd);
191
192 /** \brief creates records of the passed routes added to the name and creates FIB updates.
193 * Routes in routesToAdd with the same Face ID as ignore will be not be considered.
194 */
195 void
196 addInheritedRoutes(const Name& name, const Rib::RouteSet& routesToAdd, const Route& ignore);
197
198 /** \brief creates records of the passed routes removed from the entry and creates FIB updates
199 */
200 void
201 removeInheritedRoutes(const RibEntry& entry, const Rib::RouteSet& routesToRemove);
202
203 /** \brief calculates updates for a name that will create a new RIB entry
204 */
205 void
206 createFibUpdatesForNewRibEntry(const Name& name, const Route& route,
207 const Rib::RibEntryList& children);
208
209 /** \brief calculates updates for a new route added to a RIB entry
210 */
211 void
212 createFibUpdatesForNewRoute(const RibEntry& entry, const Route& route,
213 const bool captureWasTurnedOn);
214
215 /** \brief calculates updates for changes to an existing route for a RIB entry
216 */
217 void
218 createFibUpdatesForUpdatedRoute(const RibEntry& entry, const Route& route,
219 const Route& existingRoute);
220
221 /** \brief calculates updates for a an existing route removed from a RIB entry
222 */
223 void
224 createFibUpdatesForErasedRoute(const RibEntry& entry, const Route& route,
225 const bool captureWasTurnedOff);
226
227 /** \brief calculates updates for an entry that will be removed from the RIB
228 */
229 void
230 createFibUpdatesForErasedRibEntry(const RibEntry& entry);
231
232 /** \brief adds and removes passed routes to children's inherited routes
233 */
234 void
235 modifyChildrensInheritedRoutes(const Rib::RibEntryList& children,
236 const Rib::RouteSet& routesToAdd,
237 const Rib::RouteSet& routesToRemove);
238
239 /** \brief traverses the entry's children adding and removing the passed routes
240 */
241 void
242 traverseSubTree(const RibEntry& entry, Rib::RouteSet routesToAdd, Rib::RouteSet routesToRemove);
243
Vince Lehman76c751c2014-11-18 17:36:38 -0600244 /** \brief creates a record of a calculated inherited route that should be added to the entry
245 */
246 void
247 addInheritedRoute(const Name& name, const Route& route);
248
249 /** \brief creates a record of an existing inherited route that should be removed from the entry
250 */
251 void
252 removeInheritedRoute(const Name& name, const Route& route);
253
254private:
255 const Rib& m_rib;
256 ndn::nfd::Controller& m_controller;
257 uint64_t m_batchFaceId;
258
Davide Pesavento264af772021-02-09 21:48:24 -0500259NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
Vince Lehman76c751c2014-11-18 17:36:38 -0600260 FibUpdateList m_updatesForBatchFaceId;
261 FibUpdateList m_updatesForNonBatchFaceId;
262
263 /** \brief list of inherited routes generated during FIB update calculation;
264 * passed to the RIB when updates are completed successfully
265 */
266 RibUpdateList m_inheritedRoutes;
Vince Lehman76c751c2014-11-18 17:36:38 -0600267};
268
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400269} // namespace nfd::rib
Vince Lehman76c751c2014-11-18 17:36:38 -0600270
Davide Pesavento1b077f62019-02-19 19:19:44 -0500271#endif // NFD_DAEMON_RIB_FIB_UPDATER_HPP