blob: 5d2d27e126ab3817deda423359b8912823e90009 [file] [log] [blame]
Vince Lehman942eb7b2014-10-02 10:09:27 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
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/>.
19 *
20 **/
21
Nick Gordon5867b522017-09-06 17:41:37 -050022#include "route/fib.hpp"
Ashlesh Gawande85998a12017-12-07 22:22:13 -060023#include "../test-common.hpp"
24#include "../control-commands.hpp"
Vince Lehman942eb7b2014-10-02 10:09:27 -050025#include "adjacency-list.hpp"
26#include "conf-parameter.hpp"
27
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -060028#include <ndn-cxx/util/dummy-client-face.hpp>
29
Vince Lehman942eb7b2014-10-02 10:09:27 -050030namespace nlsr {
31namespace test {
32
dmcoomes9f936662017-03-02 10:33:09 -060033using std::shared_ptr;
Vince Lehman942eb7b2014-10-02 10:09:27 -050034
Muktadir Chowdhury3be64662015-05-01 14:50:53 -050035class FibFixture : public UnitTestTimeFixture
Vince Lehman942eb7b2014-10-02 10:09:27 -050036{
37public:
38 FibFixture()
Ashlesh Gawandee5002b32018-12-20 21:07:31 -060039 : face(std::make_shared<ndn::util::DummyClientFace>(m_ioService, m_keyChain))
Saurab Dulal427e0122019-11-28 11:58:02 -060040 , conf(*face, m_keyChain)
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -060041 , interests(face->sentInterests)
Vince Lehman942eb7b2014-10-02 10:09:27 -050042 {
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050043 Adjacent neighbor1(router1Name, ndn::FaceUri(router1FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router1FaceId);
Vince Lehman942eb7b2014-10-02 10:09:27 -050044 adjacencies.insert(neighbor1);
45
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050046 Adjacent neighbor2(router2Name, ndn::FaceUri(router2FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router2FaceId);
Vince Lehman942eb7b2014-10-02 10:09:27 -050047 adjacencies.insert(neighbor2);
48
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050049 Adjacent neighbor3(router3Name, ndn::FaceUri(router3FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router3FaceId);
Vince Lehman942eb7b2014-10-02 10:09:27 -050050 adjacencies.insert(neighbor3);
51
52 conf.setMaxFacesPerPrefix(2);
53
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050054 fib = std::make_shared<Fib>(*face, m_scheduler, adjacencies, conf, m_keyChain);
Ashlesh Gawandee5002b32018-12-20 21:07:31 -060055 fib->setEntryRefreshTime(1);
Vince Lehman942eb7b2014-10-02 10:09:27 -050056 }
57
58public:
dmcoomes9f936662017-03-02 10:33:09 -060059 std::shared_ptr<ndn::util::DummyClientFace> face;
dmcoomes9f936662017-03-02 10:33:09 -060060 std::shared_ptr<Fib> fib;
Vince Lehman942eb7b2014-10-02 10:09:27 -050061
62 AdjacencyList adjacencies;
63 ConfParameter conf;
64 std::vector<ndn::Interest>& interests;
65
66 static const ndn::Name router1Name;
67 static const ndn::Name router2Name;
68 static const ndn::Name router3Name;
69
70 static const std::string router1FaceUri;
71 static const std::string router2FaceUri;
72 static const std::string router3FaceUri;
73
74 static const uint32_t router1FaceId;
75 static const uint32_t router2FaceId;
76 static const uint32_t router3FaceId;
77};
78
79const ndn::Name FibFixture::router1Name = "/ndn/router1";
80const ndn::Name FibFixture::router2Name = "/ndn/router2";
81const ndn::Name FibFixture::router3Name = "/ndn/router3";
82
Nick Gordone9733ed2017-04-26 10:48:39 -050083const std::string FibFixture::router1FaceUri = "udp4://10.0.0.1";
84const std::string FibFixture::router2FaceUri = "udp4://10.0.0.2";
85const std::string FibFixture::router3FaceUri = "udp4://10.0.0.3";
Vince Lehman942eb7b2014-10-02 10:09:27 -050086
87const uint32_t FibFixture::router1FaceId = 1;
88const uint32_t FibFixture::router2FaceId = 2;
89const uint32_t FibFixture::router3FaceId = 3;
90
91BOOST_FIXTURE_TEST_SUITE(TestFib, FibFixture)
92
93BOOST_AUTO_TEST_CASE(NextHopsAdd)
94{
95 NextHop hop1(router1FaceUri, 10);
96 NextHop hop2(router2FaceUri, 20);
97
98 NexthopList hops;
99 hops.addNextHop(hop1);
100 hops.addNextHop(hop2);
101
Nick Gordon5867b522017-09-06 17:41:37 -0500102 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500103 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500104
105 // Should register faces 1 and 2 for /ndn/name
106 BOOST_REQUIRE_EQUAL(interests.size(), 2);
107
108 ndn::nfd::ControlParameters extractedParameters;
109 ndn::Name::Component verb;
110 std::vector<ndn::Interest>::iterator it = interests.begin();
111
112 extractRibCommandParameters(*it, verb, extractedParameters);
113
114 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
115 extractedParameters.getFaceId() == router1FaceId &&
116 verb == ndn::Name::Component("register"));
117
118 ++it;
119 extractRibCommandParameters(*it, verb, extractedParameters);
120
121 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
122 extractedParameters.getFaceId() == router2FaceId &&
123 verb == ndn::Name::Component("register"));
124}
125
126
127BOOST_AUTO_TEST_CASE(NextHopsNoChange)
128{
129 NextHop hop1(router1FaceUri, 10);
130 NextHop hop2(router2FaceUri, 20);
131
132 NexthopList oldHops;
133 oldHops.addNextHop(hop1);
134 oldHops.addNextHop(hop2);
135
Nick Gordon5867b522017-09-06 17:41:37 -0500136 fib->update("/ndn/name", oldHops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500137 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500138
139 BOOST_REQUIRE_EQUAL(interests.size(), 2);
140 interests.clear();
141
Nick Gordon5867b522017-09-06 17:41:37 -0500142 fib->update("/ndn/name", oldHops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500143 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500144
145 // Should register face 1 and 2 for /ndn/name
146 BOOST_REQUIRE_EQUAL(interests.size(), 2);
147
148 ndn::nfd::ControlParameters extractedParameters;
149 ndn::Name::Component verb;
150 std::vector<ndn::Interest>::iterator it = interests.begin();
151
152 extractRibCommandParameters(*it, verb, extractedParameters);
153
154 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
155 extractedParameters.getFaceId() == router1FaceId &&
156 verb == ndn::Name::Component("register"));
157
158 ++it;
159 extractRibCommandParameters(*it, verb, extractedParameters);
160
161 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
162 extractedParameters.getFaceId() == router2FaceId &&
163 verb == ndn::Name::Component("register"));
164}
165
166BOOST_AUTO_TEST_CASE(NextHopsRemoveAll)
167{
168 NextHop hop1(router1FaceUri, 10);
169 NextHop hop2(router2FaceUri, 20);
170
171 NexthopList oldHops;
172 oldHops.addNextHop(hop1);
173 oldHops.addNextHop(hop2);
174
Nick Gordon5867b522017-09-06 17:41:37 -0500175 fib->update("/ndn/name", oldHops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500176 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500177
178 BOOST_REQUIRE_EQUAL(interests.size(), 2);
179 interests.clear();
180
181 NexthopList empty;
182
Nick Gordon5867b522017-09-06 17:41:37 -0500183 fib->update("/ndn/name", empty);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500184 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500185
186 // Should unregister faces 1 and 2 for /ndn/name
187 BOOST_CHECK_EQUAL(interests.size(), 2);
188
189 ndn::nfd::ControlParameters extractedParameters;
190 ndn::Name::Component verb;
191 std::vector<ndn::Interest>::iterator it = interests.begin();
192
193 extractRibCommandParameters(*it, verb, extractedParameters);
194
195 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
196 extractedParameters.getFaceId() == router1FaceId &&
197 verb == ndn::Name::Component("unregister"));
198
199 ++it;
200 extractRibCommandParameters(*it, verb, extractedParameters);
201
202 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
203 extractedParameters.getFaceId() == router2FaceId &&
204 verb == ndn::Name::Component("unregister"));
205}
206
207BOOST_AUTO_TEST_CASE(NextHopsMaxPrefixes)
208{
209 NextHop hop1(router1FaceUri, 10);
210 NextHop hop2(router2FaceUri, 20);
211 NextHop hop3(router3FaceUri, 30);
212
213 NexthopList hops;
214 hops.addNextHop(hop1);
215 hops.addNextHop(hop2);
216 hops.addNextHop(hop3);
217
Nick Gordon5867b522017-09-06 17:41:37 -0500218 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500219 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500220
221 // Should only register faces 1 and 2 for /ndn/name
222 BOOST_CHECK_EQUAL(interests.size(), 2);
223
224 ndn::nfd::ControlParameters extractedParameters;
225 ndn::Name::Component verb;
226 std::vector<ndn::Interest>::iterator it = interests.begin();
227
228 extractRibCommandParameters(*it, verb, extractedParameters);
229
230 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
231 extractedParameters.getFaceId() == router1FaceId &&
232 verb == ndn::Name::Component("register"));
233
234 ++it;
235 extractRibCommandParameters(*it, verb, extractedParameters);
236
237 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
238 extractedParameters.getFaceId() == router2FaceId &&
239 verb == ndn::Name::Component("register"));
240}
241
242BOOST_AUTO_TEST_CASE(NextHopsMaxPrefixesAfterRecalculation)
243{
244 NextHop hop1(router1FaceUri, 10);
245 NextHop hop2(router2FaceUri, 20);
246
247 NexthopList hops;
248 hops.addNextHop(hop1);
249 hops.addNextHop(hop2);
250
Nick Gordon5867b522017-09-06 17:41:37 -0500251 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500252 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500253
254 // FIB
255 // Name NextHops
256 // /ndn/name (faceId=1, cost=10), (faceId=2, cost=20)
257 BOOST_REQUIRE_EQUAL(interests.size(), 2);
258 interests.clear();
259
260 // Routing table is recalculated; a new more optimal path is found
261 NextHop hop3(router3FaceUri, 5);
262 hops.addNextHop(hop3);
263
Nick Gordon5867b522017-09-06 17:41:37 -0500264 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500265 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500266
267 // To maintain a max 2 face requirement, face 3 should be registered and face 2 should be
268 // unregistered. Face 1 will also be re-registered.
269 //
270 // FIB
271 // Name NextHops
272 // /ndn/name (faceId=3, cost=5), (faceId=1, cost=10)
273
274 BOOST_CHECK_EQUAL(interests.size(), 3);
275
276 ndn::nfd::ControlParameters extractedParameters;
277 ndn::Name::Component verb;
278 std::vector<ndn::Interest>::iterator it = interests.begin();
279
280 extractRibCommandParameters(*it, verb, extractedParameters);
281
282 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
283 extractedParameters.getFaceId() == router3FaceId &&
284 verb == ndn::Name::Component("register"));
285
286 ++it;
287 extractRibCommandParameters(*it, verb, extractedParameters);
288
289 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
290 extractedParameters.getFaceId() == router1FaceId &&
291 verb == ndn::Name::Component("register"));
292
293 ++it;
294 extractRibCommandParameters(*it, verb, extractedParameters);
295
296 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
297 extractedParameters.getFaceId() == router2FaceId &&
298 verb == ndn::Name::Component("unregister"));
299}
300
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500301BOOST_FIXTURE_TEST_CASE(ScheduleFibEntryRefresh, FibFixture)
302{
303 ndn::Name name1("/name/1");
304 FibEntry fe(name1);
305 fib->m_table.emplace(name1, fe);
306 int origSeqNo = fe.getSeqNo();
307
308 fib->scheduleEntryRefresh(fe,
Ashlesh Gawandee6ba9152018-03-30 01:15:00 -0500309 [&] (FibEntry& entry) {
310 BOOST_CHECK_EQUAL(origSeqNo + 1, entry.getSeqNo());
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