blob: 36d5e41277c2ab72e60fc2aaad01bc0df2888850 [file] [log] [blame]
Alexander Afanasyev3ecec502014-04-16 13:42:44 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento87fc0f82018-04-11 23:43:51 -04002/*
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -04003 * Copyright (c) 2014-2022, 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
Davide Pesavento1b077f62019-02-19 19:19:44 -050026#ifndef NFD_DAEMON_RIB_RIB_HPP
27#define NFD_DAEMON_RIB_RIB_HPP
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070028
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
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040034namespace nfd::rib {
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070035
Vince Lehman76c751c2014-11-18 17:36:38 -060036using ndn::nfd::ControlParameters;
37
38class FibUpdater;
39
Davide Pesaventoe1bdc082018-10-11 21:20:23 -040040/** \brief references a route
41 */
Nick Gordon89c4cca2016-11-02 15:42:32 +000042struct RibRouteRef
43{
44 shared_ptr<RibEntry> entry;
45 RibEntry::const_iterator route;
46};
47
Junxiao Shi89c0ea02017-03-06 19:52:05 +000048bool
49operator<(const RibRouteRef& lhs, const RibRouteRef& rhs);
50
Nick Gordon89c4cca2016-11-02 15:42:32 +000051/** \brief represents the Routing Information Base
52
53 The Routing Information Base contains a collection of Routes, each
54 represents a piece of static or dynamic routing information
55 registered by applications, operators, or NFD itself. Routes
56 associated with the same namespace are collected into a RIB entry.
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070057 */
Alexander Afanasyev20d31442014-04-19 17:00:53 -070058class Rib : noncopyable
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070059{
60public:
Junxiao Shidf1dc652019-08-30 19:03:19 +000061 using RibEntryList = std::list<shared_ptr<RibEntry>>;
62 using RibTable = std::map<Name, shared_ptr<RibEntry>>;
63 using const_iterator = RibTable::const_iterator;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070064
Vince Lehman76c751c2014-11-18 17:36:38 -060065 void
66 setFibUpdater(FibUpdater* updater);
67
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070068 const_iterator
Vince12e49462014-06-09 13:29:32 -050069 find(const Name& prefix) const;
70
Vince Lehman218be0a2015-01-15 17:25:20 -060071 Route*
72 find(const Name& prefix, const Route& route) const;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070073
Teng Lianga4e6ec32018-10-21 09:25:00 -070074 Route*
75 findLongestPrefix(const Name& prefix, const Route& route) const;
76
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070077 const_iterator
Junxiao Shidf1dc652019-08-30 19:03:19 +000078 begin() const
79 {
80 return m_rib.begin();
81 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070082
83 const_iterator
Junxiao Shidf1dc652019-08-30 19:03:19 +000084 end() const
85 {
86 return m_rib.end();
87 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070088
89 size_t
Junxiao Shidf1dc652019-08-30 19:03:19 +000090 size() const
91 {
92 return m_nItems;
93 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070094
Vince12e49462014-06-09 13:29:32 -050095 bool
Junxiao Shidf1dc652019-08-30 19:03:19 +000096 empty() const
97 {
98 return m_rib.empty();
99 }
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700100
Vince12e49462014-06-09 13:29:32 -0500101 shared_ptr<RibEntry>
102 findParent(const Name& prefix) const;
103
Vince Lehman76c751c2014-11-18 17:36:38 -0600104public:
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400105 using UpdateSuccessCallback = std::function<void()>;
106 using UpdateFailureCallback = std::function<void(uint32_t code, const std::string& error)>;
Vince Lehman76c751c2014-11-18 17:36:38 -0600107
108 /** \brief passes the provided RibUpdateBatch to FibUpdater to calculate and send FibUpdates.
109 *
110 * If the FIB is updated successfully, onFibUpdateSuccess() will be called, and the
111 * RIB will be updated
112 *
113 * If the FIB update fails, onFibUpdateFailure() will be called, and the RIB will not
114 * be updated.
115 */
116 void
117 beginApplyUpdate(const RibUpdate& update,
118 const UpdateSuccessCallback& onSuccess,
119 const UpdateFailureCallback& onFailure);
120
121 /** \brief starts the FIB update process when a face has been destroyed
122 */
123 void
124 beginRemoveFace(uint64_t faceId);
Vince Lehman4387e782014-06-19 16:57:45 -0500125
126 void
Junxiao Shi17a70012019-06-25 10:50:32 +0000127 beginRemoveFailedFaces(const std::set<uint64_t>& activeFaceIds);
128
129 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600130 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:
Junxiao Shi17a70012019-06-25 10:50:32 +0000136 void
137 enqueueRemoveFace(const RibEntry& entry, uint64_t faceId);
138
Junxiao Shi51533382019-07-19 13:50:26 +0000139 /** \brief Append the RIB update to the update queue.
140 *
141 * To start updates, invoke sendBatchFromQueue() .
142 */
Vince Lehman76c751c2014-11-18 17:36:38 -0600143 void
144 addUpdateToQueue(const RibUpdate& update,
145 const Rib::UpdateSuccessCallback& onSuccess,
146 const Rib::UpdateFailureCallback& onFailure);
147
Junxiao Shi51533382019-07-19 13:50:26 +0000148 /** \brief Send the first update batch in the queue, if no other update is in progress.
149 */
Vince Lehman76c751c2014-11-18 17:36:38 -0600150 void
151 sendBatchFromQueue();
152
Junxiao Shi51533382019-07-19 13:50:26 +0000153 void
154 onFibUpdateSuccess(const RibUpdateBatch& batch,
155 const RibUpdateList& inheritedRoutes,
156 const Rib::UpdateSuccessCallback& onSuccess);
157
158 void
159 onFibUpdateFailure(const Rib::UpdateFailureCallback& onFailure,
160 uint32_t code, const std::string& error);
161
Davide Pesavento264af772021-02-09 21:48:24 -0500162NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
Vince Lehman76c751c2014-11-18 17:36:38 -0600163 void
164 erase(const Name& prefix, const Route& route);
Vince Lehman4387e782014-06-19 16:57:45 -0500165
166private:
Junxiao Shidf1dc652019-08-30 19:03:19 +0000167 using RouteComparePredicate = bool (*)(const Route&, const Route&);
168 using RouteSet = std::set<Route, RouteComparePredicate>;
169
Junxiao Shi51533382019-07-19 13:50:26 +0000170 /** \brief find entries under \p prefix
171 * \pre a RIB entry exists at \p prefix
172 */
173 std::list<shared_ptr<RibEntry>>
174 findDescendants(const Name& prefix) const;
175
176 /** \brief find entries under \p prefix
177 * \pre a RIB entry does not exist at \p prefix
178 */
179 std::list<shared_ptr<RibEntry>>
180 findDescendantsForNonInsertedName(const Name& prefix) const;
181
Vince12e49462014-06-09 13:29:32 -0500182 RibTable::iterator
183 eraseEntry(RibTable::iterator it);
184
185 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600186 updateRib(const RibUpdateBatch& batch);
Vince Lehman4387e782014-06-19 16:57:45 -0500187
Vince Lehman76c751c2014-11-18 17:36:38 -0600188 /** \brief returns routes inherited from the entry's ancestors
189 *
190 * \return{ a list of inherited routes }
191 */
Vince Lehman218be0a2015-01-15 17:25:20 -0600192 RouteSet
193 getAncestorRoutes(const RibEntry& entry) const;
Vince Lehman4387e782014-06-19 16:57:45 -0500194
Vince Lehman76c751c2014-11-18 17:36:38 -0600195 /** \brief returns routes inherited from the parent of the name and the parent's ancestors
196 *
197 * \note A parent is first found for the passed name before inherited routes are collected
198 *
199 * \return{ a list of inherited routes }
200 */
201 RouteSet
202 getAncestorRoutes(const Name& name) const;
Vince Lehman4387e782014-06-19 16:57:45 -0500203
Vince Lehman76c751c2014-11-18 17:36:38 -0600204 /** \brief applies the passed inheritedRoutes and their actions to the corresponding RibEntries'
205 * inheritedRoutes lists
Vince Lehman4387e782014-06-19 16:57:45 -0500206 */
207 void
Vince Lehman76c751c2014-11-18 17:36:38 -0600208 modifyInheritedRoutes(const RibUpdateList& inheritedRoutes);
Vince Lehman4387e782014-06-19 16:57:45 -0500209
Yanbiao Lic17de832014-11-21 17:51:45 -0800210public:
Nick Gordon89c4cca2016-11-02 15:42:32 +0000211 /** \brief signals after a RIB entry is inserted
212 *
213 * A RIB entry is inserted when the first route associated with a
214 * certain namespace is added.
215 */
Junxiao Shidf1dc652019-08-30 19:03:19 +0000216 signal::Signal<Rib, Name> afterInsertEntry;
Nick Gordon89c4cca2016-11-02 15:42:32 +0000217
218 /** \brief signals after a RIB entry is erased
219 *
220 * A RIB entry is erased when the last route associated with a
221 * certain namespace is removed.
222 */
Junxiao Shidf1dc652019-08-30 19:03:19 +0000223 signal::Signal<Rib, Name> afterEraseEntry;
Yanbiao Lic17de832014-11-21 17:51:45 -0800224
Nick Gordon89c4cca2016-11-02 15:42:32 +0000225 /** \brief signals after a Route is added
226 */
Junxiao Shidf1dc652019-08-30 19:03:19 +0000227 signal::Signal<Rib, RibRouteRef> afterAddRoute;
Nick Gordon89c4cca2016-11-02 15:42:32 +0000228
229 /** \brief signals before a route is removed
230 */
Junxiao Shidf1dc652019-08-30 19:03:19 +0000231 signal::Signal<Rib, RibRouteRef> beforeRemoveRoute;
Nick Gordon89c4cca2016-11-02 15:42:32 +0000232
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700233private:
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700234 RibTable m_rib;
Junxiao Shi17a70012019-06-25 10:50:32 +0000235 std::multimap<uint64_t, shared_ptr<RibEntry>> m_faceEntries; ///< FaceId => Entry with Route on this face
Junxiao Shidf1dc652019-08-30 19:03:19 +0000236 size_t m_nItems = 0;
237 FibUpdater* m_fibUpdater = nullptr;
Vince Lehman4387e782014-06-19 16:57:45 -0500238
Vince Lehman76c751c2014-11-18 17:36:38 -0600239 struct UpdateQueueItem
240 {
241 RibUpdateBatch batch;
242 const Rib::UpdateSuccessCallback managerSuccessCallback;
243 const Rib::UpdateFailureCallback managerFailureCallback;
244 };
245
Junxiao Shidf1dc652019-08-30 19:03:19 +0000246 using UpdateQueue = std::list<UpdateQueueItem>;
Vince Lehman76c751c2014-11-18 17:36:38 -0600247 UpdateQueue m_updateBatches;
Junxiao Shidf1dc652019-08-30 19:03:19 +0000248 bool m_isUpdateInProgress = false;
Vince Lehman76c751c2014-11-18 17:36:38 -0600249
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400250 friend FibUpdater;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700251};
252
Vince12e49462014-06-09 13:29:32 -0500253std::ostream&
254operator<<(std::ostream& os, const Rib& rib);
255
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400256} // namespace nfd::rib
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700257
Davide Pesavento1b077f62019-02-19 19:19:44 -0500258#endif // NFD_DAEMON_RIB_RIB_HPP