blob: 8cf7aa4733d829f00045a383bbc708e45111791d [file] [log] [blame]
akmhoque3d06e792014-05-27 16:23:20 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Nick Gordonc6a85222017-01-03 16:54:34 -06003 * Copyright (c) 2014-2017, 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/>.
20 *
akmhoque3d06e792014-05-27 16:23:20 -050021 **/
akmhoque53353462014-04-22 08:43:45 -050022
Muktadir Chowdhury3be64662015-05-01 14:50:53 -050023#ifndef NLSR_ROUTE_FIB_HPP
24#define NLSR_ROUTE_FIB_HPP
Nick Gordonb7168472016-09-21 13:57:17 -050025
akmhoque157b0a42014-05-13 00:26:37 -050026#include "face-map.hpp"
akmhoque53353462014-04-22 08:43:45 -050027#include "fib-entry.hpp"
Vince Lehman942eb7b2014-10-02 10:09:27 -050028#include "test-access-control.hpp"
akmhoque53353462014-04-22 08:43:45 -050029
Nick Gordon21088082017-05-24 10:57:06 -050030#include <ndn-cxx/mgmt/nfd/controller.hpp>
Muktadir Chowdhury3be64662015-05-01 14:50:53 -050031#include <ndn-cxx/util/time.hpp>
32
akmhoque53353462014-04-22 08:43:45 -050033namespace nlsr {
34
Muktadir Chowdhury3be64662015-05-01 14:50:53 -050035typedef std::function<void(FibEntry&)> afterRefreshCallback;
akmhoquec04e7272014-07-02 11:00:14 -050036
Vince Lehman942eb7b2014-10-02 10:09:27 -050037class AdjacencyList;
38class ConfParameter;
Muktadir Chowdhury3be64662015-05-01 14:50:53 -050039class FibEntry;
akmhoque53353462014-04-22 08:43:45 -050040
Nick Gordond0a7df32017-05-30 16:44:34 -050041/*! \brief Maps names to lists of next hops, and exports this information to NFD.
42 *
43 * The FIB (Forwarding Information Base) is the "authoritative" source
44 * of how to route Interests on this router to other nodes running
45 * NLSR. In essence, the FIB is a map that takes name prefixes to a
46 * list of next-hops out of this router. This class also contains
47 * methods to inform NFD about these relationships. The FIB has its
48 * entries populated by the NamePrefixTable
49 *
50 * \sa nlsr::NamePrefixTable
51 * \sa nlsr::NamePrefixTable::addEntry
52 * \sa nlsr::NamePrefixTable::updateWithNewRoute
53 */
akmhoque53353462014-04-22 08:43:45 -050054class Fib
55{
56public:
Vince Lehmanb7079a12014-11-04 12:45:50 -060057 Fib(ndn::Face& face, ndn::Scheduler& scheduler, AdjacencyList& adjacencyList, ConfParameter& conf,
58 ndn::KeyChain& keyChain)
Vince Lehman942eb7b2014-10-02 10:09:27 -050059 : m_scheduler(scheduler)
akmhoque53353462014-04-22 08:43:45 -050060 , m_refreshTime(0)
Vince Lehmanb7079a12014-11-04 12:45:50 -060061 , m_controller(face, keyChain)
Vince Lehman942eb7b2014-10-02 10:09:27 -050062 , m_adjacencyList(adjacencyList)
63 , m_confParameter(conf)
akmhoquefdbddb12014-05-02 18:35:19 -050064 {
65 }
Vince Lehman942eb7b2014-10-02 10:09:27 -050066
Nick Gordond0a7df32017-05-30 16:44:34 -050067 /*! \brief Completely remove a name prefix from the FIB.
68 *
69 * If a name prefix is found to no longer be reachable from this
70 * router, it will be removed from the FIB and all of its next-hops
71 * will be unregistered from NFD.
72 *
73 * \sa nlsr::NamePrefixTable::removeEntry
74 */
Nick Gordon4d2c6c02017-01-20 13:18:46 -060075 VIRTUAL_WITH_TESTS void
akmhoque31d1d4b2014-05-05 22:08:14 -050076 remove(const ndn::Name& name);
akmhoque53353462014-04-22 08:43:45 -050077
Nick Gordond0a7df32017-05-30 16:44:34 -050078 /*! \brief Set the nexthop list of a name.
79 *
80 * This method is the entry for others to add next-hop information
81 * to the FIB. Formally put, this method registers in NFD all
82 * next-hops in allHops, and unregisters the set difference of
83 * newHops - oldHops. This method also schedules the regular refresh
84 * of those next hops.
85 *
86 * \param name The name prefix that the next-hops apply to
87 * \param allHops A complete list of next-hops to associate with name.
88 */
Nick Gordon4d2c6c02017-01-20 13:18:46 -060089 VIRTUAL_WITH_TESTS void
90 update(const ndn::Name& name, NexthopList& allHops);
91
Nick Gordond0a7df32017-05-30 16:44:34 -050092 /*! \brief Remove all entries from the FIB.
93 *
94 * This method is called before terminating NLSR to minimize the
95 * time NFD spends routing on now-invalid information. This is not
96 * strictly necessary, because eventually those prefix registrations
97 * will expire, but cleaning up after ourselves improves
98 * performance.
99 *
100 * \sa NlsrRunner::run
101 *
102 */
akmhoque53353462014-04-22 08:43:45 -0500103 void
akmhoque31d1d4b2014-05-05 22:08:14 -0500104 clean();
akmhoque53353462014-04-22 08:43:45 -0500105
106 void
akmhoquefdbddb12014-05-02 18:35:19 -0500107 setEntryRefreshTime(int32_t fert)
akmhoque53353462014-04-22 08:43:45 -0500108 {
109 m_refreshTime = fert;
110 }
111
Nick Gordond0a7df32017-05-30 16:44:34 -0500112 /*! \brief Inform NFD of a next-hop
113 *
114 * This method informs NFD of a next-hop for some name prefix. This
115 * method actually submits the information to NFD's RIB, which then
116 * aggregates its own best hops and updates NFD's (the actual)
117 * FIB. Typically, NLSR's FIB and NFD's FIB will be almost the
118 * same. However, this is not necessarily the case and there may be
119 * cases when other sources of information provide better next-hops
120 * to NFD that NLSR doesn't know about. For example, an operator
121 * could set up a direct link to a node that isn't running NLSR.
122 *
123 * \param namePrefix The name prefix to register a next-hop for
124 * \param faceUri The faceUri of the adjacent that this prefix can be reached through
125 * \param faceCost The cost to reach namePrefix through faceUri
126 * \param timeout How long this registration should last
127 * \param flags Route inheritance flags (CAPTURE, CHILD_INHERIT)
128 * \param times How many times we have failed to register this prefix since the last success.
129 *
130 * \sa Fib::registerPrefixInNfd
131 */
akmhoque53353462014-04-22 08:43:45 -0500132 void
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500133 registerPrefix(const ndn::Name& namePrefix,
Ashlesh Gawande793e8702017-08-01 15:59:26 -0500134 const ndn::util::FaceUri& faceUri,
akmhoquebf11c5f2014-07-21 14:49:47 -0500135 uint64_t faceCost,
akmhoque060d3022014-08-12 13:35:06 -0500136 const ndn::time::milliseconds& timeout,
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500137 uint64_t flags,
138 uint8_t times);
akmhoquefdbddb12014-05-02 18:35:19 -0500139
140 void
akmhoque393d4ff2014-07-16 14:27:03 -0500141 setStrategy(const ndn::Name& name, const std::string& strategy, uint32_t count);
akmhoque157b0a42014-05-13 00:26:37 -0500142
akmhoque674b0b12014-05-20 14:33:28 -0500143 void
144 writeLog();
145
akmhoque157b0a42014-05-13 00:26:37 -0500146private:
Nick Gordond0a7df32017-05-30 16:44:34 -0500147 /*! \brief Indicates whether a prefix is a direct neighbor or not.
148 *
149 * \return Whether the name is NOT associated with a direct neighbor
150 */
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500151 bool
152 isPrefixUpdatable(const ndn::Name& name);
153
Nick Gordond0a7df32017-05-30 16:44:34 -0500154 /*! \brief Does one half of the updating of a FibEntry with new next-hops.
155 *
156 * Adds nexthops to a FibEntry and registers them in NFD.
157 * \sa Fib::update
158 * \sa Fib::removeOldNextHopsFromFibEntryAndNfd
159 */
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500160 void
161 addNextHopsToFibEntryAndNfd(FibEntry& entry, NexthopList& hopsToAdd);
162
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500163 unsigned int
164 getNumberOfFacesForName(NexthopList& nextHopList);
165
Nick Gordond0a7df32017-05-30 16:44:34 -0500166 /*! \brief Unregisters a prefix from NFD's RIB.
167 *
168 */
akmhoque157b0a42014-05-13 00:26:37 -0500169 void
170 unregisterPrefix(const ndn::Name& namePrefix, const std::string& faceUri);
171
Nick Gordond0a7df32017-05-30 16:44:34 -0500172 /*! \brief Log registration success, and update the Face ID associated with a URI.
173 */
akmhoque157b0a42014-05-13 00:26:37 -0500174 void
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500175 onRegistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
Ashlesh Gawande793e8702017-08-01 15:59:26 -0500176 const std::string& message, const ndn::util::FaceUri& faceUri);
akmhoquefdbddb12014-05-02 18:35:19 -0500177
Nick Gordond0a7df32017-05-30 16:44:34 -0500178 /*! \brief Retry a prefix (next-hop) registration up to three (3) times.
179 */
akmhoquefdbddb12014-05-02 18:35:19 -0500180 void
Junxiao Shi63bd0342016-08-17 16:57:14 +0000181 onRegistrationFailure(const ndn::nfd::ControlResponse& response,
akmhoque102aea42014-08-04 10:22:12 -0500182 const std::string& message,
akmhoque060d3022014-08-12 13:35:06 -0500183 const ndn::nfd::ControlParameters& parameters,
Ashlesh Gawande793e8702017-08-01 15:59:26 -0500184 const ndn::util::FaceUri& faceUri,
akmhoque102aea42014-08-04 10:22:12 -0500185 uint8_t times);
186
Nick Gordond0a7df32017-05-30 16:44:34 -0500187 /*! \brief Log a successful unregistration.
188 */
akmhoque102aea42014-08-04 10:22:12 -0500189 void
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500190 onUnregistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
Junxiao Shi63bd0342016-08-17 16:57:14 +0000191 const std::string& message);
akmhoque53353462014-04-22 08:43:45 -0500192
Nick Gordond0a7df32017-05-30 16:44:34 -0500193 /*! \brief Log an unregistration failure. Does not retry.
194 */
akmhoque393d4ff2014-07-16 14:27:03 -0500195 void
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500196 onUnregistrationFailure(const ndn::nfd::ControlResponse& response,
197 const std::string& message);
198
Nick Gordond0a7df32017-05-30 16:44:34 -0500199 /*! \brief Log a successful strategy setting.
200 */
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500201 void
akmhoque393d4ff2014-07-16 14:27:03 -0500202 onSetStrategySuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
203 const std::string& message);
204
Nick Gordond0a7df32017-05-30 16:44:34 -0500205 /*! \brief Retry a strategy setting up to three (3) times.
206 */
akmhoque393d4ff2014-07-16 14:27:03 -0500207 void
Junxiao Shi63bd0342016-08-17 16:57:14 +0000208 onSetStrategyFailure(const ndn::nfd::ControlResponse& response,
akmhoque393d4ff2014-07-16 14:27:03 -0500209 const ndn::nfd::ControlParameters& parameters,
210 uint32_t count,
211 const std::string& message);
212
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500213PUBLIC_WITH_TESTS_ELSE_PRIVATE:
Nick Gordond0a7df32017-05-30 16:44:34 -0500214 /*! \brief Schedule a refresh event for an entry.
215 *
216 * Schedules a refresh event for an entry. In order to form a
217 * perpetual loop, refreshCallback needs to call
218 * Fib::scheduleEntryRefresh in some way, with refreshCallback being
219 * the same each time. In the current implementation, this is
220 * accomplished by having a separate function, Fib::scheduleLoop,
221 * that does this work.
222 * \sa Fib::scheduleLoop
223 */
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500224 void
225 scheduleEntryRefresh(FibEntry& entry, const afterRefreshCallback& refreshCb);
226
227private:
Nick Gordond0a7df32017-05-30 16:44:34 -0500228 /*! \brief Continue the entry refresh cycle.
229 */
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500230 void
231 scheduleLoop(FibEntry& entry);
232
Nick Gordond0a7df32017-05-30 16:44:34 -0500233 /*! \brief Cancel an entry's refresh event.
234 *
235 * Cancel an entry's refresh event. This only needs to be done when
236 * an entry is removed. Typically this happens when NLSR is
237 * terminated or crashes, and we don't want the scheduler to crash
238 * because it's referencing memory that has no valid function.
239 *
240 * \sa NlsrRunner::run
241 */
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500242 void
243 cancelEntryRefresh(const FibEntry& entry);
244
Nick Gordond0a7df32017-05-30 16:44:34 -0500245 /*! \brief Refreshes an entry in NFD.
246 */
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500247 void
248 refreshEntry(const ndn::Name& name, afterRefreshCallback refreshCb);
249
akmhoque53353462014-04-22 08:43:45 -0500250private:
Vince Lehman7c603292014-09-11 17:48:16 -0500251 ndn::Scheduler& m_scheduler;
akmhoquefdbddb12014-05-02 18:35:19 -0500252 int32_t m_refreshTime;
253 ndn::nfd::Controller m_controller;
Vince Lehman942eb7b2014-10-02 10:09:27 -0500254
255PUBLIC_WITH_TESTS_ELSE_PRIVATE:
akmhoque157b0a42014-05-13 00:26:37 -0500256 FaceMap m_faceMap;
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500257 std::map<ndn::Name, FibEntry> m_table;
akmhoque393d4ff2014-07-16 14:27:03 -0500258
Vince Lehman942eb7b2014-10-02 10:09:27 -0500259private:
260 AdjacencyList& m_adjacencyList;
261 ConfParameter& m_confParameter;
262
Nick Gordond0a7df32017-05-30 16:44:34 -0500263 /*! GRACE_PERIOD A "window" we append to the timeout time to
264 * allow for things like stuttering prefix registrations and
265 * processing time when refreshing events.
266 */
akmhoque393d4ff2014-07-16 14:27:03 -0500267 static const uint64_t GRACE_PERIOD;
akmhoque53353462014-04-22 08:43:45 -0500268};
269
Nick Gordonfad8e252016-08-11 14:21:38 -0500270} // namespace nlsr
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500271
272#endif // NLSR_ROUTE_FIB_HPP