blob: fd68e80f4c21ca8fdf6979865fdc882a3971297b [file] [log] [blame]
Vince Lehman942eb7b2014-10-02 10:09:27 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Ashlesh Gawande7a231c02020-06-12 20:06:44 -07002/*
Saurab Dulal427e0122019-11-28 11:58:02 -06003 * Copyright (c) 2014-2020, The University of Memphis,
Nick Gordonf8b5bcd2016-08-11 15:06:50 -05004 * Regents of the University of California
Vince Lehman942eb7b2014-10-02 10:09:27 -05005 *
6 * This file is part of NLSR (Named-data Link State Routing).
7 * See AUTHORS.md for complete list of NLSR authors and contributors.
8 *
9 * NLSR is free software: you can redistribute it and/or modify it under the terms
10 * of the GNU General Public License as published by the Free Software Foundation,
11 * either version 3 of the License, or (at your option) any later version.
12 *
13 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
14 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Ashlesh Gawande7a231c02020-06-12 20:06:44 -070019 */
Vince Lehman942eb7b2014-10-02 10:09:27 -050020
Nick Gordon5867b522017-09-06 17:41:37 -050021#include "route/fib.hpp"
Ashlesh Gawande85998a12017-12-07 22:22:13 -060022#include "../test-common.hpp"
23#include "../control-commands.hpp"
Vince Lehman942eb7b2014-10-02 10:09:27 -050024#include "adjacency-list.hpp"
25#include "conf-parameter.hpp"
26
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -060027#include <ndn-cxx/util/dummy-client-face.hpp>
28
Vince Lehman942eb7b2014-10-02 10:09:27 -050029namespace nlsr {
30namespace test {
31
dmcoomes9f936662017-03-02 10:33:09 -060032using std::shared_ptr;
Vince Lehman942eb7b2014-10-02 10:09:27 -050033
Muktadir Chowdhury3be64662015-05-01 14:50:53 -050034class FibFixture : public UnitTestTimeFixture
Vince Lehman942eb7b2014-10-02 10:09:27 -050035{
36public:
37 FibFixture()
Ashlesh Gawandee5002b32018-12-20 21:07:31 -060038 : face(std::make_shared<ndn::util::DummyClientFace>(m_ioService, m_keyChain))
Saurab Dulal427e0122019-11-28 11:58:02 -060039 , conf(*face, m_keyChain)
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -060040 , interests(face->sentInterests)
Vince Lehman942eb7b2014-10-02 10:09:27 -050041 {
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050042 Adjacent neighbor1(router1Name, ndn::FaceUri(router1FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router1FaceId);
Vince Lehman942eb7b2014-10-02 10:09:27 -050043 adjacencies.insert(neighbor1);
44
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050045 Adjacent neighbor2(router2Name, ndn::FaceUri(router2FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router2FaceId);
Vince Lehman942eb7b2014-10-02 10:09:27 -050046 adjacencies.insert(neighbor2);
47
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050048 Adjacent neighbor3(router3Name, ndn::FaceUri(router3FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router3FaceId);
Vince Lehman942eb7b2014-10-02 10:09:27 -050049 adjacencies.insert(neighbor3);
50
51 conf.setMaxFacesPerPrefix(2);
52
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050053 fib = std::make_shared<Fib>(*face, m_scheduler, adjacencies, conf, m_keyChain);
Ashlesh Gawandee5002b32018-12-20 21:07:31 -060054 fib->setEntryRefreshTime(1);
Vince Lehman942eb7b2014-10-02 10:09:27 -050055 }
56
57public:
dmcoomes9f936662017-03-02 10:33:09 -060058 std::shared_ptr<ndn::util::DummyClientFace> face;
dmcoomes9f936662017-03-02 10:33:09 -060059 std::shared_ptr<Fib> fib;
Vince Lehman942eb7b2014-10-02 10:09:27 -050060
61 AdjacencyList adjacencies;
62 ConfParameter conf;
63 std::vector<ndn::Interest>& interests;
64
65 static const ndn::Name router1Name;
66 static const ndn::Name router2Name;
67 static const ndn::Name router3Name;
68
69 static const std::string router1FaceUri;
70 static const std::string router2FaceUri;
71 static const std::string router3FaceUri;
72
73 static const uint32_t router1FaceId;
74 static const uint32_t router2FaceId;
75 static const uint32_t router3FaceId;
76};
77
78const ndn::Name FibFixture::router1Name = "/ndn/router1";
79const ndn::Name FibFixture::router2Name = "/ndn/router2";
80const ndn::Name FibFixture::router3Name = "/ndn/router3";
81
Nick Gordone9733ed2017-04-26 10:48:39 -050082const std::string FibFixture::router1FaceUri = "udp4://10.0.0.1";
83const std::string FibFixture::router2FaceUri = "udp4://10.0.0.2";
84const std::string FibFixture::router3FaceUri = "udp4://10.0.0.3";
Vince Lehman942eb7b2014-10-02 10:09:27 -050085
86const uint32_t FibFixture::router1FaceId = 1;
87const uint32_t FibFixture::router2FaceId = 2;
88const uint32_t FibFixture::router3FaceId = 3;
89
90BOOST_FIXTURE_TEST_SUITE(TestFib, FibFixture)
91
92BOOST_AUTO_TEST_CASE(NextHopsAdd)
93{
94 NextHop hop1(router1FaceUri, 10);
95 NextHop hop2(router2FaceUri, 20);
96
97 NexthopList hops;
98 hops.addNextHop(hop1);
99 hops.addNextHop(hop2);
100
Nick Gordon5867b522017-09-06 17:41:37 -0500101 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500102 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500103
104 // Should register faces 1 and 2 for /ndn/name
105 BOOST_REQUIRE_EQUAL(interests.size(), 2);
106
107 ndn::nfd::ControlParameters extractedParameters;
108 ndn::Name::Component verb;
109 std::vector<ndn::Interest>::iterator it = interests.begin();
110
111 extractRibCommandParameters(*it, verb, extractedParameters);
112
113 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
114 extractedParameters.getFaceId() == router1FaceId &&
115 verb == ndn::Name::Component("register"));
116
117 ++it;
118 extractRibCommandParameters(*it, verb, extractedParameters);
119
120 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
121 extractedParameters.getFaceId() == router2FaceId &&
122 verb == ndn::Name::Component("register"));
123}
124
125
126BOOST_AUTO_TEST_CASE(NextHopsNoChange)
127{
128 NextHop hop1(router1FaceUri, 10);
129 NextHop hop2(router2FaceUri, 20);
130
131 NexthopList oldHops;
132 oldHops.addNextHop(hop1);
133 oldHops.addNextHop(hop2);
134
Nick Gordon5867b522017-09-06 17:41:37 -0500135 fib->update("/ndn/name", oldHops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500136 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500137
138 BOOST_REQUIRE_EQUAL(interests.size(), 2);
139 interests.clear();
140
Nick Gordon5867b522017-09-06 17:41:37 -0500141 fib->update("/ndn/name", oldHops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500142 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500143
144 // Should register face 1 and 2 for /ndn/name
145 BOOST_REQUIRE_EQUAL(interests.size(), 2);
146
147 ndn::nfd::ControlParameters extractedParameters;
148 ndn::Name::Component verb;
149 std::vector<ndn::Interest>::iterator it = interests.begin();
150
151 extractRibCommandParameters(*it, verb, extractedParameters);
152
153 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
154 extractedParameters.getFaceId() == router1FaceId &&
155 verb == ndn::Name::Component("register"));
156
157 ++it;
158 extractRibCommandParameters(*it, verb, extractedParameters);
159
160 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
161 extractedParameters.getFaceId() == router2FaceId &&
162 verb == ndn::Name::Component("register"));
163}
164
165BOOST_AUTO_TEST_CASE(NextHopsRemoveAll)
166{
167 NextHop hop1(router1FaceUri, 10);
168 NextHop hop2(router2FaceUri, 20);
169
170 NexthopList oldHops;
171 oldHops.addNextHop(hop1);
172 oldHops.addNextHop(hop2);
173
Nick Gordon5867b522017-09-06 17:41:37 -0500174 fib->update("/ndn/name", oldHops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500175 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500176
177 BOOST_REQUIRE_EQUAL(interests.size(), 2);
178 interests.clear();
179
180 NexthopList empty;
181
Nick Gordon5867b522017-09-06 17:41:37 -0500182 fib->update("/ndn/name", empty);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500183 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500184
185 // Should unregister faces 1 and 2 for /ndn/name
186 BOOST_CHECK_EQUAL(interests.size(), 2);
187
188 ndn::nfd::ControlParameters extractedParameters;
189 ndn::Name::Component verb;
190 std::vector<ndn::Interest>::iterator it = interests.begin();
191
192 extractRibCommandParameters(*it, verb, extractedParameters);
193
194 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
195 extractedParameters.getFaceId() == router1FaceId &&
196 verb == ndn::Name::Component("unregister"));
197
198 ++it;
199 extractRibCommandParameters(*it, verb, extractedParameters);
200
201 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
202 extractedParameters.getFaceId() == router2FaceId &&
203 verb == ndn::Name::Component("unregister"));
204}
205
206BOOST_AUTO_TEST_CASE(NextHopsMaxPrefixes)
207{
208 NextHop hop1(router1FaceUri, 10);
209 NextHop hop2(router2FaceUri, 20);
210 NextHop hop3(router3FaceUri, 30);
211
212 NexthopList hops;
213 hops.addNextHop(hop1);
214 hops.addNextHop(hop2);
215 hops.addNextHop(hop3);
216
Nick Gordon5867b522017-09-06 17:41:37 -0500217 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500218 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500219
220 // Should only register faces 1 and 2 for /ndn/name
221 BOOST_CHECK_EQUAL(interests.size(), 2);
222
223 ndn::nfd::ControlParameters extractedParameters;
224 ndn::Name::Component verb;
225 std::vector<ndn::Interest>::iterator it = interests.begin();
226
227 extractRibCommandParameters(*it, verb, extractedParameters);
228
229 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
230 extractedParameters.getFaceId() == router1FaceId &&
231 verb == ndn::Name::Component("register"));
232
233 ++it;
234 extractRibCommandParameters(*it, verb, extractedParameters);
235
236 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
237 extractedParameters.getFaceId() == router2FaceId &&
238 verb == ndn::Name::Component("register"));
239}
240
241BOOST_AUTO_TEST_CASE(NextHopsMaxPrefixesAfterRecalculation)
242{
243 NextHop hop1(router1FaceUri, 10);
244 NextHop hop2(router2FaceUri, 20);
245
246 NexthopList hops;
247 hops.addNextHop(hop1);
248 hops.addNextHop(hop2);
249
Nick Gordon5867b522017-09-06 17:41:37 -0500250 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500251 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500252
253 // FIB
254 // Name NextHops
255 // /ndn/name (faceId=1, cost=10), (faceId=2, cost=20)
256 BOOST_REQUIRE_EQUAL(interests.size(), 2);
257 interests.clear();
258
259 // Routing table is recalculated; a new more optimal path is found
260 NextHop hop3(router3FaceUri, 5);
261 hops.addNextHop(hop3);
262
Nick Gordon5867b522017-09-06 17:41:37 -0500263 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500264 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500265
266 // To maintain a max 2 face requirement, face 3 should be registered and face 2 should be
267 // unregistered. Face 1 will also be re-registered.
268 //
269 // FIB
270 // Name NextHops
271 // /ndn/name (faceId=3, cost=5), (faceId=1, cost=10)
272
273 BOOST_CHECK_EQUAL(interests.size(), 3);
274
275 ndn::nfd::ControlParameters extractedParameters;
276 ndn::Name::Component verb;
277 std::vector<ndn::Interest>::iterator it = interests.begin();
278
279 extractRibCommandParameters(*it, verb, extractedParameters);
280
281 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
282 extractedParameters.getFaceId() == router3FaceId &&
283 verb == ndn::Name::Component("register"));
284
285 ++it;
286 extractRibCommandParameters(*it, verb, extractedParameters);
287
288 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
289 extractedParameters.getFaceId() == router1FaceId &&
290 verb == ndn::Name::Component("register"));
291
292 ++it;
293 extractRibCommandParameters(*it, verb, extractedParameters);
294
295 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
296 extractedParameters.getFaceId() == router2FaceId &&
297 verb == ndn::Name::Component("unregister"));
298}
299
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500300BOOST_FIXTURE_TEST_CASE(ScheduleFibEntryRefresh, FibFixture)
301{
302 ndn::Name name1("/name/1");
Ashlesh Gawande7a231c02020-06-12 20:06:44 -0700303 FibEntry fe;
304 fe.name = name1;
305 int origSeqNo = fe.seqNo;
306 fib->m_table.emplace(name1, std::move(fe));
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500307
308 fib->scheduleEntryRefresh(fe,
Ashlesh Gawandee6ba9152018-03-30 01:15:00 -0500309 [&] (FibEntry& entry) {
Ashlesh Gawande7a231c02020-06-12 20:06:44 -0700310 BOOST_CHECK_EQUAL(origSeqNo + 1, entry.seqNo);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500311 });
312 this->advanceClocks(ndn::time::milliseconds(10), 1);
313}
314
Ashlesh Gawandee5002b32018-12-20 21:07:31 -0600315BOOST_AUTO_TEST_CASE(ShouldNotRefreshNeighborRoute) // #4799
316{
317 NextHop hop1;
318 hop1.setConnectingFaceUri(router1FaceUri);
319
320 NexthopList hops;
321 hops.addNextHop(hop1);
322
323 // Simulate update for this neighbor from name prefix table
324 fib->update(router1Name, hops);
325 this->advanceClocks(ndn::time::seconds(1));
326
327 // Should not send the register interest
328 BOOST_CHECK_EQUAL(face->sentInterests.size(), 0);
329}
330
Vince Lehman942eb7b2014-10-02 10:09:27 -0500331BOOST_AUTO_TEST_SUITE_END()
332
Nick Gordonfad8e252016-08-11 14:21:38 -0500333} // namespace test
334} // namespace nlsr