blob: 7be00015e2835a533fdb58e34e2050aef0db7090 [file] [log] [blame]
akmhoque3d06e792014-05-27 16:23:20 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyev67758b12018-03-06 18:36:44 -05002/*
awlane834ffb12025-01-24 20:11:51 -06003 * Copyright (c) 2014-2025, The University of Memphis,
Junxiao Shi3e5120c2016-09-10 16:58:34 +00004 * Regents of the University of California,
5 * Arizona Board of Regents.
akmhoque3d06e792014-05-27 16:23:20 -05006 *
7 * This file is part of NLSR (Named-data Link State Routing).
8 * See AUTHORS.md for complete list of NLSR authors and contributors.
9 *
10 * NLSR is free software: you can redistribute it and/or modify it under the terms
11 * of the GNU General Public License as published by the Free Software Foundation,
12 * either version 3 of the License, or (at your option) any later version.
13 *
14 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Alexander Afanasyev67758b12018-03-06 18:36:44 -050020 */
akmhoque53353462014-04-22 08:43:45 -050021
Muktadir Chowdhury3be64662015-05-01 14:50:53 -050022#ifndef NLSR_ROUTE_FIB_HPP
23#define NLSR_ROUTE_FIB_HPP
Nick Gordonb7168472016-09-21 13:57:17 -050024
Vince Lehman942eb7b2014-10-02 10:09:27 -050025#include "test-access-control.hpp"
Ashlesh Gawande7a231c02020-06-12 20:06:44 -070026#include "nexthop-list.hpp"
akmhoque53353462014-04-22 08:43:45 -050027
Nick Gordon21088082017-05-24 10:57:06 -050028#include <ndn-cxx/mgmt/nfd/controller.hpp>
Ashlesh Gawande7a231c02020-06-12 20:06:44 -070029#include <ndn-cxx/util/scheduler.hpp>
Muktadir Chowdhury3be64662015-05-01 14:50:53 -050030#include <ndn-cxx/util/time.hpp>
31
akmhoque53353462014-04-22 08:43:45 -050032namespace nlsr {
33
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -040034using NextHopsUriSortedSet = NexthopListT<NextHopUriSortedComparator>;
Ashlesh Gawande6f0f35d2021-08-21 23:52:14 -070035
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -040036struct FibEntry
37{
Ashlesh Gawande7a231c02020-06-12 20:06:44 -070038 ndn::Name name;
39 ndn::scheduler::ScopedEventId refreshEventId;
40 int32_t seqNo = 1;
Ashlesh Gawande6f0f35d2021-08-21 23:52:14 -070041 NextHopsUriSortedSet nexthopSet;
Ashlesh Gawande7a231c02020-06-12 20:06:44 -070042};
43
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -040044using AfterRefreshCallback = std::function<void(FibEntry&)>;
akmhoquec04e7272014-07-02 11:00:14 -050045
Vince Lehman942eb7b2014-10-02 10:09:27 -050046class AdjacencyList;
47class ConfParameter;
akmhoque53353462014-04-22 08:43:45 -050048
Nick Gordond0a7df32017-05-30 16:44:34 -050049/*! \brief Maps names to lists of next hops, and exports this information to NFD.
50 *
51 * The FIB (Forwarding Information Base) is the "authoritative" source
52 * of how to route Interests on this router to other nodes running
53 * NLSR. In essence, the FIB is a map that takes name prefixes to a
54 * list of next-hops out of this router. This class also contains
55 * methods to inform NFD about these relationships. The FIB has its
56 * entries populated by the NamePrefixTable
57 *
58 * \sa nlsr::NamePrefixTable
59 * \sa nlsr::NamePrefixTable::addEntry
60 * \sa nlsr::NamePrefixTable::updateWithNewRoute
61 */
akmhoque53353462014-04-22 08:43:45 -050062class Fib
63{
64public:
Ashlesh Gawandee5002b32018-12-20 21:07:31 -060065 Fib(ndn::Face& face, ndn::Scheduler& scheduler, AdjacencyList& adjacencyList,
Alexander Afanasyev0ad01f32020-06-03 14:12:58 -040066 ConfParameter& conf, ndn::security::KeyChain& keyChain);
Vince Lehman942eb7b2014-10-02 10:09:27 -050067
Nick Gordond0a7df32017-05-30 16:44:34 -050068 /*! \brief Completely remove a name prefix from the FIB.
69 *
70 * If a name prefix is found to no longer be reachable from this
71 * router, it will be removed from the FIB and all of its next-hops
72 * will be unregistered from NFD.
73 *
74 * \sa nlsr::NamePrefixTable::removeEntry
75 */
Ashlesh Gawande744e4812018-08-22 16:26:24 -050076 void
akmhoque31d1d4b2014-05-05 22:08:14 -050077 remove(const ndn::Name& name);
akmhoque53353462014-04-22 08:43:45 -050078
Nick Gordond0a7df32017-05-30 16:44:34 -050079 /*! \brief Set the nexthop list of a name.
80 *
81 * This method is the entry for others to add next-hop information
82 * to the FIB. Formally put, this method registers in NFD all
83 * next-hops in allHops, and unregisters the set difference of
84 * newHops - oldHops. This method also schedules the regular refresh
85 * of those next hops.
86 *
87 * \param name The name prefix that the next-hops apply to
88 * \param allHops A complete list of next-hops to associate with name.
89 */
Ashlesh Gawande744e4812018-08-22 16:26:24 -050090 void
Ashlesh Gawandee8d8bd52018-08-09 17:18:51 -050091 update(const ndn::Name& name, const NexthopList& allHops);
Nick Gordon4d2c6c02017-01-20 13:18:46 -060092
akmhoque53353462014-04-22 08:43:45 -050093 void
akmhoquefdbddb12014-05-02 18:35:19 -050094 setEntryRefreshTime(int32_t fert)
akmhoque53353462014-04-22 08:43:45 -050095 {
96 m_refreshTime = fert;
97 }
98
Nick Gordond0a7df32017-05-30 16:44:34 -050099 /*! \brief Inform NFD of a next-hop
100 *
101 * This method informs NFD of a next-hop for some name prefix. This
102 * method actually submits the information to NFD's RIB, which then
103 * aggregates its own best hops and updates NFD's (the actual)
104 * FIB. Typically, NLSR's FIB and NFD's FIB will be almost the
105 * same. However, this is not necessarily the case and there may be
106 * cases when other sources of information provide better next-hops
107 * to NFD that NLSR doesn't know about. For example, an operator
108 * could set up a direct link to a node that isn't running NLSR.
109 *
110 * \param namePrefix The name prefix to register a next-hop for
111 * \param faceUri The faceUri of the adjacent that this prefix can be reached through
112 * \param faceCost The cost to reach namePrefix through faceUri
113 * \param timeout How long this registration should last
114 * \param flags Route inheritance flags (CAPTURE, CHILD_INHERIT)
115 * \param times How many times we have failed to register this prefix since the last success.
116 *
117 * \sa Fib::registerPrefixInNfd
118 */
akmhoque53353462014-04-22 08:43:45 -0500119 void
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500120 registerPrefix(const ndn::Name& namePrefix,
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500121 const ndn::FaceUri& faceUri,
akmhoquebf11c5f2014-07-21 14:49:47 -0500122 uint64_t faceCost,
akmhoque060d3022014-08-12 13:35:06 -0500123 const ndn::time::milliseconds& timeout,
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500124 uint64_t flags,
125 uint8_t times);
akmhoquefdbddb12014-05-02 18:35:19 -0500126
127 void
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -0400128 setStrategy(const ndn::Name& name, const ndn::Name& strategy, uint32_t count);
akmhoque157b0a42014-05-13 00:26:37 -0500129
akmhoque674b0b12014-05-20 14:33:28 -0500130 void
131 writeLog();
132
akmhoque157b0a42014-05-13 00:26:37 -0500133private:
Nick Gordond0a7df32017-05-30 16:44:34 -0500134 /*! \brief Indicates whether a prefix is a direct neighbor or not.
135 *
136 * \return Whether the name is NOT associated with a direct neighbor
137 */
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500138 bool
Ashlesh Gawandee5002b32018-12-20 21:07:31 -0600139 isNotNeighbor(const ndn::Name& name);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500140
Nick Gordond0a7df32017-05-30 16:44:34 -0500141 /*! \brief Does one half of the updating of a FibEntry with new next-hops.
142 *
143 * Adds nexthops to a FibEntry and registers them in NFD.
144 * \sa Fib::update
145 * \sa Fib::removeOldNextHopsFromFibEntryAndNfd
146 */
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500147 void
Ashlesh Gawande6f0f35d2021-08-21 23:52:14 -0700148 addNextHopsToFibEntryAndNfd(FibEntry& entry, const NextHopsUriSortedSet& hopsToAdd);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500149
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500150 unsigned int
Ashlesh Gawandee8d8bd52018-08-09 17:18:51 -0500151 getNumberOfFacesForName(const NexthopList& nextHopList);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500152
Nick Gordond0a7df32017-05-30 16:44:34 -0500153 /*! \brief Unregisters a prefix from NFD's RIB.
154 *
155 */
akmhoque157b0a42014-05-13 00:26:37 -0500156 void
Junxiao Shi6593a432023-08-21 10:50:28 +0000157 unregisterPrefix(const ndn::Name& namePrefix, const ndn::FaceUri& faceUri);
akmhoque157b0a42014-05-13 00:26:37 -0500158
Nick Gordond0a7df32017-05-30 16:44:34 -0500159 /*! \brief Log registration success, and update the Face ID associated with a URI.
160 */
akmhoque157b0a42014-05-13 00:26:37 -0500161 void
Ashlesh Gawande6b388fc2019-09-30 10:14:41 -0500162 onRegistrationSuccess(const ndn::nfd::ControlParameters& param,
163 const ndn::FaceUri& faceUri);
akmhoquefdbddb12014-05-02 18:35:19 -0500164
Nick Gordond0a7df32017-05-30 16:44:34 -0500165 /*! \brief Retry a prefix (next-hop) registration up to three (3) times.
166 */
akmhoquefdbddb12014-05-02 18:35:19 -0500167 void
Junxiao Shi63bd0342016-08-17 16:57:14 +0000168 onRegistrationFailure(const ndn::nfd::ControlResponse& response,
akmhoque060d3022014-08-12 13:35:06 -0500169 const ndn::nfd::ControlParameters& parameters,
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500170 const ndn::FaceUri& faceUri,
akmhoque102aea42014-08-04 10:22:12 -0500171 uint8_t times);
172
Nick Gordond0a7df32017-05-30 16:44:34 -0500173 /*! \brief Log a successful strategy setting.
174 */
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500175 void
Davide Pesaventoaf7a2112019-03-19 14:55:20 -0400176 onSetStrategySuccess(const ndn::nfd::ControlParameters& commandSuccessResult);
akmhoque393d4ff2014-07-16 14:27:03 -0500177
Nick Gordond0a7df32017-05-30 16:44:34 -0500178 /*! \brief Retry a strategy setting up to three (3) times.
179 */
akmhoque393d4ff2014-07-16 14:27:03 -0500180 void
Junxiao Shi63bd0342016-08-17 16:57:14 +0000181 onSetStrategyFailure(const ndn::nfd::ControlResponse& response,
akmhoque393d4ff2014-07-16 14:27:03 -0500182 const ndn::nfd::ControlParameters& parameters,
Davide Pesaventoaf7a2112019-03-19 14:55:20 -0400183 uint32_t count);
akmhoque393d4ff2014-07-16 14:27:03 -0500184
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500185PUBLIC_WITH_TESTS_ELSE_PRIVATE:
Nick Gordond0a7df32017-05-30 16:44:34 -0500186 /*! \brief Schedule a refresh event for an entry.
187 *
188 * Schedules a refresh event for an entry. In order to form a
189 * perpetual loop, refreshCallback needs to call
190 * Fib::scheduleEntryRefresh in some way, with refreshCallback being
191 * the same each time. In the current implementation, this is
192 * accomplished by having a separate function, Fib::scheduleLoop,
193 * that does this work.
194 * \sa Fib::scheduleLoop
195 */
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500196 void
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -0400197 scheduleEntryRefresh(FibEntry& entry, const AfterRefreshCallback& refreshCb);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500198
199private:
Nick Gordond0a7df32017-05-30 16:44:34 -0500200 /*! \brief Continue the entry refresh cycle.
201 */
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500202 void
203 scheduleLoop(FibEntry& entry);
204
Nick Gordond0a7df32017-05-30 16:44:34 -0500205 /*! \brief Refreshes an entry in NFD.
206 */
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500207 void
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -0400208 refreshEntry(const ndn::Name& name, AfterRefreshCallback refreshCb);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500209
Ashlesh Gawande08bce9c2019-04-05 11:08:07 -0500210public:
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -0400211 static inline const ndn::Name MULTICAST_STRATEGY{"/localhost/nfd/strategy/multicast"};
212 static inline const ndn::Name BEST_ROUTE_STRATEGY{"/localhost/nfd/strategy/best-route"};
213
Junxiao Shi43f37a02023-08-09 00:09:00 +0000214 ndn::signal::Signal<Fib, ndn::Name> onPrefixRegistrationSuccess;
Ashlesh Gawande08bce9c2019-04-05 11:08:07 -0500215
akmhoque53353462014-04-22 08:43:45 -0500216private:
Vince Lehman7c603292014-09-11 17:48:16 -0500217 ndn::Scheduler& m_scheduler;
akmhoquefdbddb12014-05-02 18:35:19 -0500218 int32_t m_refreshTime;
219 ndn::nfd::Controller m_controller;
Vince Lehman942eb7b2014-10-02 10:09:27 -0500220
221PUBLIC_WITH_TESTS_ELSE_PRIVATE:
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500222 std::map<ndn::Name, FibEntry> m_table;
akmhoque393d4ff2014-07-16 14:27:03 -0500223
Vince Lehman942eb7b2014-10-02 10:09:27 -0500224private:
225 AdjacencyList& m_adjacencyList;
226 ConfParameter& m_confParameter;
227
Nick Gordond0a7df32017-05-30 16:44:34 -0500228 /*! GRACE_PERIOD A "window" we append to the timeout time to
229 * allow for things like stuttering prefix registrations and
230 * processing time when refreshing events.
231 */
Ashlesh Gawande7a231c02020-06-12 20:06:44 -0700232 static constexpr uint64_t GRACE_PERIOD = 10;
akmhoque53353462014-04-22 08:43:45 -0500233};
234
Nick Gordonfad8e252016-08-11 14:21:38 -0500235} // namespace nlsr
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500236
237#endif // NLSR_ROUTE_FIB_HPP