blob: 04b08eaa0b2a9c3e7a2b9a6f1ce8cee81f1db2ae [file] [log] [blame]
Vince Lehman942eb7b2014-10-02 10:09:27 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
dmcoomescf8d0ed2017-02-21 11:39:01 -06003 * Copyright (c) 2014-2018, 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"
Vince Lehman942eb7b2014-10-02 10:09:27 -050023#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))
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 fib->m_faceMap.update(router1FaceUri, router1FaceId);
57 fib->m_faceMap.update(router2FaceUri, router2FaceId);
58 fib->m_faceMap.update(router3FaceUri, router3FaceId);
59 }
60
61public:
dmcoomes9f936662017-03-02 10:33:09 -060062 std::shared_ptr<ndn::util::DummyClientFace> face;
dmcoomes9f936662017-03-02 10:33:09 -060063 std::shared_ptr<Fib> fib;
Vince Lehman942eb7b2014-10-02 10:09:27 -050064
65 AdjacencyList adjacencies;
66 ConfParameter conf;
67 std::vector<ndn::Interest>& interests;
68
69 static const ndn::Name router1Name;
70 static const ndn::Name router2Name;
71 static const ndn::Name router3Name;
72
73 static const std::string router1FaceUri;
74 static const std::string router2FaceUri;
75 static const std::string router3FaceUri;
76
77 static const uint32_t router1FaceId;
78 static const uint32_t router2FaceId;
79 static const uint32_t router3FaceId;
80};
81
82const ndn::Name FibFixture::router1Name = "/ndn/router1";
83const ndn::Name FibFixture::router2Name = "/ndn/router2";
84const ndn::Name FibFixture::router3Name = "/ndn/router3";
85
Nick Gordone9733ed2017-04-26 10:48:39 -050086const std::string FibFixture::router1FaceUri = "udp4://10.0.0.1";
87const std::string FibFixture::router2FaceUri = "udp4://10.0.0.2";
88const std::string FibFixture::router3FaceUri = "udp4://10.0.0.3";
Vince Lehman942eb7b2014-10-02 10:09:27 -050089
90const uint32_t FibFixture::router1FaceId = 1;
91const uint32_t FibFixture::router2FaceId = 2;
92const uint32_t FibFixture::router3FaceId = 3;
93
94BOOST_FIXTURE_TEST_SUITE(TestFib, FibFixture)
95
96BOOST_AUTO_TEST_CASE(NextHopsAdd)
97{
98 NextHop hop1(router1FaceUri, 10);
99 NextHop hop2(router2FaceUri, 20);
100
101 NexthopList hops;
102 hops.addNextHop(hop1);
103 hops.addNextHop(hop2);
104
Nick Gordon5867b522017-09-06 17:41:37 -0500105 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500106 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500107
108 // Should register faces 1 and 2 for /ndn/name
109 BOOST_REQUIRE_EQUAL(interests.size(), 2);
110
111 ndn::nfd::ControlParameters extractedParameters;
112 ndn::Name::Component verb;
113 std::vector<ndn::Interest>::iterator it = interests.begin();
114
115 extractRibCommandParameters(*it, verb, extractedParameters);
116
117 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
118 extractedParameters.getFaceId() == router1FaceId &&
119 verb == ndn::Name::Component("register"));
120
121 ++it;
122 extractRibCommandParameters(*it, verb, extractedParameters);
123
124 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
125 extractedParameters.getFaceId() == router2FaceId &&
126 verb == ndn::Name::Component("register"));
127}
128
129
130BOOST_AUTO_TEST_CASE(NextHopsNoChange)
131{
132 NextHop hop1(router1FaceUri, 10);
133 NextHop hop2(router2FaceUri, 20);
134
135 NexthopList oldHops;
136 oldHops.addNextHop(hop1);
137 oldHops.addNextHop(hop2);
138
Nick Gordon5867b522017-09-06 17:41:37 -0500139 fib->update("/ndn/name", oldHops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500140 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500141
142 BOOST_REQUIRE_EQUAL(interests.size(), 2);
143 interests.clear();
144
Nick Gordon5867b522017-09-06 17:41:37 -0500145 fib->update("/ndn/name", oldHops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500146 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500147
148 // Should register face 1 and 2 for /ndn/name
149 BOOST_REQUIRE_EQUAL(interests.size(), 2);
150
151 ndn::nfd::ControlParameters extractedParameters;
152 ndn::Name::Component verb;
153 std::vector<ndn::Interest>::iterator it = interests.begin();
154
155 extractRibCommandParameters(*it, verb, extractedParameters);
156
157 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
158 extractedParameters.getFaceId() == router1FaceId &&
159 verb == ndn::Name::Component("register"));
160
161 ++it;
162 extractRibCommandParameters(*it, verb, extractedParameters);
163
164 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
165 extractedParameters.getFaceId() == router2FaceId &&
166 verb == ndn::Name::Component("register"));
167}
168
169BOOST_AUTO_TEST_CASE(NextHopsRemoveAll)
170{
171 NextHop hop1(router1FaceUri, 10);
172 NextHop hop2(router2FaceUri, 20);
173
174 NexthopList oldHops;
175 oldHops.addNextHop(hop1);
176 oldHops.addNextHop(hop2);
177
Nick Gordon5867b522017-09-06 17:41:37 -0500178 fib->update("/ndn/name", oldHops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500179 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500180
181 BOOST_REQUIRE_EQUAL(interests.size(), 2);
182 interests.clear();
183
184 NexthopList empty;
185
Nick Gordon5867b522017-09-06 17:41:37 -0500186 fib->update("/ndn/name", empty);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500187 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500188
189 // Should unregister faces 1 and 2 for /ndn/name
190 BOOST_CHECK_EQUAL(interests.size(), 2);
191
192 ndn::nfd::ControlParameters extractedParameters;
193 ndn::Name::Component verb;
194 std::vector<ndn::Interest>::iterator it = interests.begin();
195
196 extractRibCommandParameters(*it, verb, extractedParameters);
197
198 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
199 extractedParameters.getFaceId() == router1FaceId &&
200 verb == ndn::Name::Component("unregister"));
201
202 ++it;
203 extractRibCommandParameters(*it, verb, extractedParameters);
204
205 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
206 extractedParameters.getFaceId() == router2FaceId &&
207 verb == ndn::Name::Component("unregister"));
208}
209
210BOOST_AUTO_TEST_CASE(NextHopsMaxPrefixes)
211{
212 NextHop hop1(router1FaceUri, 10);
213 NextHop hop2(router2FaceUri, 20);
214 NextHop hop3(router3FaceUri, 30);
215
216 NexthopList hops;
217 hops.addNextHop(hop1);
218 hops.addNextHop(hop2);
219 hops.addNextHop(hop3);
220
Nick Gordon5867b522017-09-06 17:41:37 -0500221 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500222 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500223
224 // Should only register faces 1 and 2 for /ndn/name
225 BOOST_CHECK_EQUAL(interests.size(), 2);
226
227 ndn::nfd::ControlParameters extractedParameters;
228 ndn::Name::Component verb;
229 std::vector<ndn::Interest>::iterator it = interests.begin();
230
231 extractRibCommandParameters(*it, verb, extractedParameters);
232
233 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
234 extractedParameters.getFaceId() == router1FaceId &&
235 verb == ndn::Name::Component("register"));
236
237 ++it;
238 extractRibCommandParameters(*it, verb, extractedParameters);
239
240 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
241 extractedParameters.getFaceId() == router2FaceId &&
242 verb == ndn::Name::Component("register"));
243}
244
245BOOST_AUTO_TEST_CASE(NextHopsMaxPrefixesAfterRecalculation)
246{
247 NextHop hop1(router1FaceUri, 10);
248 NextHop hop2(router2FaceUri, 20);
249
250 NexthopList hops;
251 hops.addNextHop(hop1);
252 hops.addNextHop(hop2);
253
Nick Gordon5867b522017-09-06 17:41:37 -0500254 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500255 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500256
257 // FIB
258 // Name NextHops
259 // /ndn/name (faceId=1, cost=10), (faceId=2, cost=20)
260 BOOST_REQUIRE_EQUAL(interests.size(), 2);
261 interests.clear();
262
263 // Routing table is recalculated; a new more optimal path is found
264 NextHop hop3(router3FaceUri, 5);
265 hops.addNextHop(hop3);
266
Nick Gordon5867b522017-09-06 17:41:37 -0500267 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500268 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500269
270 // To maintain a max 2 face requirement, face 3 should be registered and face 2 should be
271 // unregistered. Face 1 will also be re-registered.
272 //
273 // FIB
274 // Name NextHops
275 // /ndn/name (faceId=3, cost=5), (faceId=1, cost=10)
276
277 BOOST_CHECK_EQUAL(interests.size(), 3);
278
279 ndn::nfd::ControlParameters extractedParameters;
280 ndn::Name::Component verb;
281 std::vector<ndn::Interest>::iterator it = interests.begin();
282
283 extractRibCommandParameters(*it, verb, extractedParameters);
284
285 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
286 extractedParameters.getFaceId() == router3FaceId &&
287 verb == ndn::Name::Component("register"));
288
289 ++it;
290 extractRibCommandParameters(*it, verb, extractedParameters);
291
292 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
293 extractedParameters.getFaceId() == router1FaceId &&
294 verb == ndn::Name::Component("register"));
295
296 ++it;
297 extractRibCommandParameters(*it, verb, extractedParameters);
298
299 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
300 extractedParameters.getFaceId() == router2FaceId &&
301 verb == ndn::Name::Component("unregister"));
302}
303
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500304BOOST_FIXTURE_TEST_CASE(ScheduleFibEntryRefresh, FibFixture)
305{
306 ndn::Name name1("/name/1");
307 FibEntry fe(name1);
308 fib->m_table.emplace(name1, fe);
309 int origSeqNo = fe.getSeqNo();
310
311 fib->scheduleEntryRefresh(fe,
Ashlesh Gawandee6ba9152018-03-30 01:15:00 -0500312 [&] (FibEntry& entry) {
313 BOOST_CHECK_EQUAL(origSeqNo + 1, entry.getSeqNo());
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500314 });
315 this->advanceClocks(ndn::time::milliseconds(10), 1);
316}
317
Ashlesh Gawandee5002b32018-12-20 21:07:31 -0600318BOOST_AUTO_TEST_CASE(ShouldNotRefreshNeighborRoute) // #4799
319{
320 NextHop hop1;
321 hop1.setConnectingFaceUri(router1FaceUri);
322
323 NexthopList hops;
324 hops.addNextHop(hop1);
325
326 // Simulate update for this neighbor from name prefix table
327 fib->update(router1Name, hops);
328 this->advanceClocks(ndn::time::seconds(1));
329
330 // Should not send the register interest
331 BOOST_CHECK_EQUAL(face->sentInterests.size(), 0);
332}
333
Vince Lehman942eb7b2014-10-02 10:09:27 -0500334BOOST_AUTO_TEST_SUITE_END()
335
Nick Gordonfad8e252016-08-11 14:21:38 -0500336} // namespace test
337} // namespace nlsr