A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
global-route-manager-impl-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright 2007 University of Washington
3 * Copyright (C) 1999, 2000 Kunihiro Ishiguro, Toshiaki Takada
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 * Authors: Tom Henderson (tomhend@u.washington.edu)
8 *
9 * Modified By: Shashwat Patni (shashwatpatni25@gmail.com)
10 *
11 * Kunihiro Ishigura, Toshiaki Takada (GNU Zebra) are attributed authors
12 * of the quagga 0.99.7/src/ospfd/ospf_spf.c code which was ported here
13 */
14
15#include "ns3/candidate-queue.h"
16#include "ns3/config.h"
17#include "ns3/global-route-manager-impl.h"
18#include "ns3/internet-module.h"
19#include "ns3/internet-stack-helper.h"
20#include "ns3/ipv4-global-routing-helper.h"
21#include "ns3/ipv4-global-routing.h"
22#include "ns3/network-module.h"
23#include "ns3/node-container.h"
24#include "ns3/rng-seed-manager.h"
25#include "ns3/simple-net-device-helper.h"
26#include "ns3/simulator.h"
27#include "ns3/test.h"
28
29#include <cstdlib> // for rand()
30using namespace ns3;
31
32NS_LOG_COMPONENT_DEFINE("GlobalRouteManagerImplTestSuite");
33
34//
35// This test suite is designed to check the Working of the GlobalRouteManagerImpl
36// For that reason, the tests in this suite manually build LSAs for each topology
37// we manually call DebugSPFCalculate() to fill routing tables of the node we are interested in.
38//
39// TestCase 1: LinkRoutesTestCase
40// This test case tests that:
41// - GLobalRouteManagerLSDB stores the LSAs with key as the correct link state ID
42// - GlobalRouteManagerImpl checks for stubnodes and computes default routes for them
43// - HostRoutes are computed correctly for point-to-point links
44//
45// TestCase 2: LanRoutesTestCase
46// This test case tests that:
47// - Network LSAs are handled by the GlobalRouteManagerImpl
48// - GlobalRouteManagerImpl computes the routes correctly for a LAN topology
49//
50// TestCase 3: RandomEcmpRoutesTestCase
51// This test case tests that:
52// - GlobalRouteManagerImpl computes ECMP routes correctly.
53// - Those random routes are in fact used by the GlobalRouting protocol
54//
55
56/**
57 * @ingroup internet
58 * @ingroup tests
59 * @defgroup internet-test internet module tests
60 */
61
62/**
63 * @ingroup internet-test
64 *
65 * @brief Global Route Manager Test
66 */
68{
69 public:
71 void DoSetup() override;
72 void DoRun() override;
73
74 private:
75 /**
76 *@brief Builds the LSAs for the topology. These LSAs are manually created and inserted into the
77 * GlobalRouteManagerLSDB.Each node exports a router LSA.
78 */
79 void BuildLsa();
80
81 /**
82 * @brief Checks the Routing Table Entries for the expected output.
83 * @param globalroutingprotocol The routing protocol for the node whose routing table is to be
84 * checked.
85 * @param dests The expected destinations.
86 * @param gws The expected gateways.
87 */
88 void CheckRoutes(Ptr<Ipv4GlobalRouting>& globalroutingprotocol,
89 std::vector<Ipv4Address>& dests,
90 std::vector<Ipv4Address>& gws);
91
92 NodeContainer nodes; //!< NodeContainer to hold the nodes in the topology
93 std::vector<GlobalRoutingLSA*> m_lsas; //!< The LSAs for the topology
94};
95
97 : TestCase("LinkRoutesTestCase")
98{
99}
100
101void
103 std::vector<Ipv4Address>& dests,
104 std::vector<Ipv4Address>& gws)
105{
106 // check each individual Routing Table Entry for its destination and gateway
107 for (uint32_t i = 0; i < globalroutingprotocol->GetNRoutes(); i++)
108 {
109 Ipv4RoutingTableEntry* route = globalroutingprotocol->GetRoute(i);
110 NS_LOG_DEBUG("dest " << route->GetDest() << " gw " << route->GetGateway());
111 NS_TEST_ASSERT_MSG_EQ(route->GetDest(), dests[i], "Error-- wrong destination");
112 NS_TEST_ASSERT_MSG_EQ(route->GetGateway(), gws[i], "Error-- wrong gateway");
113 }
114}
115
116void
118{
119 // Simple p2p links. n0,n1 and n3 are stub nodes
120 //
121 //
122 // n0
123 // \ link 0
124 // \ link 2
125 // n2 -------------------------n3
126 // /
127 // / link 1
128 // n1
129 //
130 // link0: n0->10.1.1.1/30, n2-> 10.1.1.2/30
131 // link1: n1-> 10.1.2.1/30, n2->10.1.2.2/30
132 // link2: n2->10.1.3.1/30, n3-> 10.1.3.2/30
133 //
134 //
135 //
136
137 nodes.Create(4);
138
139 Ipv4GlobalRoutingHelper globalhelper;
141 stack.SetRoutingHelper(globalhelper);
142 stack.Install(nodes);
143
144 SimpleNetDeviceHelper devHelper;
145 devHelper.SetNetDevicePointToPointMode(true);
147 NetDeviceContainer d02 = devHelper.Install(nodes.Get(0), channel1);
148 d02.Add(devHelper.Install(nodes.Get(2), channel1));
150 NetDeviceContainer d12 = devHelper.Install(nodes.Get(1), channel2);
151 d12.Add(devHelper.Install(nodes.Get(2), channel2));
153 NetDeviceContainer d23 = devHelper.Install(nodes.Get(2), channel3);
154 d23.Add(devHelper.Install(nodes.Get(3), channel3));
155
156 // Assign IP addresses to the devices
157 Ipv4AddressHelper address;
158 address.SetBase("10.1.1.0", "255.255.255.252");
159 Ipv4InterfaceContainer i02 = address.Assign(d02);
160 address.SetBase("10.1.2.0", "255.255.255.252");
161 Ipv4InterfaceContainer i12 = address.Assign(d12);
162 address.SetBase("10.1.3.0", "255.255.255.252");
163 Ipv4InterfaceContainer i23 = address.Assign(d23);
164}
165
166void
168{
169 // Manually build the link state database; four routers (0-3), 3 point-to-point
170 // links
171
172 // Router 0
174 "0.0.0.2", // link id -> router ID 0.0.0.2
175 "10.1.1.1", // link data -> Local IP address of router 0
176 1); // metric
177
179 "10.1.1.2", // link id ->adjacent neighbor's IP address
180 "255.255.255.252",
181 1);
182
183 auto lsa0 = new GlobalRoutingLSA();
184 lsa0->SetLSType(GlobalRoutingLSA::RouterLSA);
185 lsa0->SetLinkStateId("0.0.0.0");
186 lsa0->SetAdvertisingRouter("0.0.0.0");
187 lsa0->SetNode(nodes.Get(0));
188 lsa0->AddLinkRecord(lr0);
189 lsa0->AddLinkRecord(lr1);
190 m_lsas.push_back(lsa0);
191
192 // Router 1
194 "0.0.0.2",
195 "10.1.2.1",
196 1);
197
199 "10.1.2.2",
200 "255.255.255.252",
201 1);
202
203 auto lsa1 = new GlobalRoutingLSA();
204 lsa1->SetLSType(GlobalRoutingLSA::RouterLSA);
205 lsa1->SetLinkStateId("0.0.0.1");
206 lsa1->SetAdvertisingRouter("0.0.0.1");
207 lsa1->AddLinkRecord(lr2);
208 lsa1->AddLinkRecord(lr3);
209 lsa1->SetNode(nodes.Get(1));
210 m_lsas.push_back(lsa1);
211
212 // Router 2
214 "0.0.0.0",
215 "10.1.1.2",
216 1);
217
219 "10.1.1.1",
220 "255.255.255.252",
221 1);
222
224 "0.0.0.1",
225 "10.1.2.2",
226 1);
227
229 "10.1.2.2",
230 "255.255.255.252",
231 1);
232
234 "0.0.0.3",
235 "10.1.3.1",
236 1);
237
239 "10.1.3.2",
240 "255.255.255.252",
241 1);
242
243 auto lsa2 = new GlobalRoutingLSA();
244 lsa2->SetLSType(GlobalRoutingLSA::RouterLSA);
245 lsa2->SetLinkStateId("0.0.0.2");
246 lsa2->SetAdvertisingRouter("0.0.0.2");
247 lsa2->AddLinkRecord(lr4);
248 lsa2->AddLinkRecord(lr5);
249 lsa2->AddLinkRecord(lr6);
250 lsa2->AddLinkRecord(lr7);
251 lsa2->AddLinkRecord(lr8);
252 lsa2->AddLinkRecord(lr9);
253 lsa2->SetNode(nodes.Get(2));
254 m_lsas.push_back(lsa2);
255
256 // Router 3
258 "0.0.0.2",
259 "10.1.3.2",
260 1);
261
263 "10.1.3.1",
264 "255.255.255.252",
265 1);
266
267 auto lsa3 = new GlobalRoutingLSA();
268 lsa3->SetLSType(GlobalRoutingLSA::RouterLSA);
269 lsa3->SetLinkStateId("0.0.0.3");
270 lsa3->SetAdvertisingRouter("0.0.0.3");
271 lsa3->AddLinkRecord(lr10);
272 lsa3->AddLinkRecord(lr11);
273 lsa3->SetNode(nodes.Get(3));
274 m_lsas.push_back(lsa3);
275}
276
277void
279{
280 // This test is for checking the individual working of GlobalRouteManagerImpl
281 // and GlobalRouteManagerLSDB, so we will not use the GlobalRoutingHelper
282 // to create the routing tables, but instead we will manually create the LSAs
283 // and insert them into the GlobalRouteManagerLSDB, and then use the
284 // GlobalRouteManagerImpl to calculate the routes based on the LSDB.
285 // This is a manual setup of the LSAs, which would normally be done by the
286 // GlobalRoutingHelper.
287
288 BuildLsa();
289
290 // Test the database
291 auto srmlsdb = new GlobalRouteManagerLSDB();
292 srmlsdb->Insert(m_lsas[0]->GetLinkStateId(), m_lsas[0]);
293 srmlsdb->Insert(m_lsas[1]->GetLinkStateId(), m_lsas[1]);
294 srmlsdb->Insert(m_lsas[2]->GetLinkStateId(), m_lsas[2]);
295 srmlsdb->Insert(m_lsas[3]->GetLinkStateId(), m_lsas[3]);
296
298 m_lsas[2],
299 srmlsdb->GetLSA(m_lsas[2]->GetLinkStateId()),
300 "The Ipv4Address is not stored as the link state ID"); // LSAs are mapped by router id as
301 // key here we check that they are
302 // indeed getting the right lsa for
303 // the right key
304
305 // next, calculate routes based on the manually created LSDB
306 auto srm = new GlobalRouteManagerImpl();
307 srm->DebugUseLsdb(srmlsdb); // manually add in an LSDB
308
309 srm->DebugSPFCalculate(m_lsas[0]->GetLinkStateId()); // fill routing table for node n0
310
311 srm->DebugSPFCalculate(m_lsas[1]->GetLinkStateId()); // fill routing table for node n1
312
313 srm->DebugSPFCalculate(m_lsas[2]->GetLinkStateId()); // fill routing table for node n2
314
315 srm->DebugSPFCalculate(m_lsas[3]->GetLinkStateId()); // fill routing table for node n3
316
318
319 //-----------------Now the tests------------------
320 // Test 1: Check if the SPF calculate Sets default routes for Stub nodes
322 NS_TEST_ASSERT_MSG_NE(ip0, nullptr, "Error-- no Ipv4 object at node 0");
323 Ptr<Ipv4RoutingProtocol> routing0 = ip0->GetRoutingProtocol();
324 NS_TEST_ASSERT_MSG_NE(routing0, nullptr, "Error-- no Ipv4 routing protocol object at node 0");
325 Ptr<Ipv4GlobalRouting> globalRouting0 = routing0->GetObject<Ipv4GlobalRouting>();
326 NS_TEST_ASSERT_MSG_NE(globalRouting0, nullptr, "Error-- no Ipv4GlobalRouting object at node 0");
327
328 // Check that the right number of entries are in the routing table
329 uint32_t nRoutes0 = globalRouting0->GetNRoutes();
330 NS_TEST_ASSERT_MSG_EQ(nRoutes0, 1, "Error-- default route not found for stub node");
331
332 Ipv4RoutingTableEntry* route = nullptr;
333 route = globalRouting0->GetRoute(0);
334 // the only route is the default route on this node
336 Ipv4Address("0.0.0.0"),
337 "Error-- wrong destination for default route");
338 NS_TEST_ASSERT_MSG_EQ(route->GetGateway(), Ipv4Address("10.1.1.2"), "Error-- wrong gateway");
339
340 // Test 2: Check if SPFCalculate sets the correct routes for node 2
342 NS_TEST_ASSERT_MSG_NE(ip2, nullptr, "Error-- no Ipv4 object at node 2");
343 Ptr<Ipv4RoutingProtocol> routing2 = ip2->GetRoutingProtocol();
344 NS_TEST_ASSERT_MSG_NE(routing2, nullptr, "Error-- no Ipv4 routing protocol object at node 2");
345 Ptr<Ipv4GlobalRouting> globalRouting2 = routing2->GetObject<Ipv4GlobalRouting>();
346 NS_TEST_ASSERT_MSG_NE(globalRouting2, nullptr, "Error-- no Ipv4GlobalRouting object at node 2");
347
348 // check that the correct number of routes were built
349 uint32_t nRoutes2 = globalRouting2->GetNRoutes();
350 NS_LOG_DEBUG("LinkRoutesTest nRoutes2 " << nRoutes2);
351 NS_TEST_ASSERT_MSG_EQ(nRoutes2, 6, "Error--- Incorrect number of routes found on node 2");
352
353 // check that all the routes in the routing table are correct for node 2
354 std::vector<Ipv4Address> expecteddests;
355 std::vector<Ipv4Address> expectedgws;
356 expecteddests.emplace_back("10.1.1.1");
357 expecteddests.emplace_back("10.1.2.1");
358 expecteddests.emplace_back("10.1.3.2");
359 expecteddests.emplace_back("10.1.1.0");
360 expecteddests.emplace_back("10.1.2.0");
361 expecteddests.emplace_back("10.1.3.0");
362
363 expectedgws.emplace_back("10.1.1.1");
364 expectedgws.emplace_back("10.1.2.1");
365 expectedgws.emplace_back("10.1.3.2");
366 expectedgws.emplace_back("10.1.1.1");
367 expectedgws.emplace_back("10.1.2.1");
368 expectedgws.emplace_back("10.1.3.2");
369
370 CheckRoutes(globalRouting2, expecteddests, expectedgws);
371
373
376
377 // This delete clears the srm, which deletes the LSDB, which clears
378 // all of the LSAs, which each destroys the attached LinkRecords.
379 delete srm;
380 // reset the router ID counter to zero so that it does not affect other tests
381 // that may run after this one in the same program run.
383}
384
385/**
386 * @ingroup internet-test
387 *
388 * @brief This test case is to check if NetworkRoutes are being built correctly, i.e if route
389 * computation works for a LAN Topology.
390 */
392{
393 public:
395 void DoSetup() override;
396 void DoRun() override;
397
398 private:
399 /**
400 *@brief Builds the LSAs for the topology. These LSAs are manually created and inserted into the
401 * GlobalRouteManagerLSDB.Each node exports a router LSA. In addition,the designated router
402 * also Exports the Network LSA.
403 */
404 void BuildLsa();
405
406 NodeContainer nodes; //!< NodeContainer to hold the nodes in the topology
407 std::vector<GlobalRoutingLSA*> m_lsas; //!< The LSAs for the topology
408};
409
411 : TestCase("LanRoutesTestCase")
412{
413}
414
415void
417{
418 // Simple Csma Network with three nodes
419 //
420 // n0 n1
421 // | (shared csma/cd) |
422 // -------------------------
423 // |
424 // n2
425 //
426 // n0:10.1.1.1/29
427 // n1:10.1.1.2/29
428 // n2:10.1.1.3/29
429 nodes.Create(3);
430 Ipv4GlobalRoutingHelper globalhelper;
432 stack.SetRoutingHelper(globalhelper);
433 stack.Install(nodes);
434 SimpleNetDeviceHelper devHelper;
436 NetDeviceContainer d012 = devHelper.Install(nodes.Get(0), channel);
437 d012.Add(devHelper.Install(nodes.Get(1), channel));
438 d012.Add(devHelper.Install(nodes.Get(2), channel));
439
440 // assign IP addresses to the devices
441 Ipv4AddressHelper address;
442 address.SetBase("10.1.1.0", "255.255.255.248");
443 Ipv4InterfaceContainer i012 = address.Assign(d012);
444}
445
446void
448{
449 // we manually create the link state database, we could have used BuildRoutingTables() but this
450 // way testing the GlobalRouteManagerImpl without the involvement of GLobalRouter makes it
451 // easier to debug each individually
452
453 // router 0
455 "10.1.1.1",
456 "10.1.1.1",
457 1);
458 auto lsa0 = new GlobalRoutingLSA();
459 lsa0->SetLSType(GlobalRoutingLSA::RouterLSA);
460 lsa0->AddLinkRecord(lr0);
461 lsa0->SetLinkStateId("0.0.0.0");
462 lsa0->SetAdvertisingRouter("0.0.0.0");
463 lsa0->SetNode(nodes.Get(0));
464 m_lsas.push_back(lsa0);
465
466 // router 1
468 "10.1.1.1",
469 "10.1.1.2",
470 1);
471 auto lsa1 = new GlobalRoutingLSA();
472 lsa1->SetLSType(GlobalRoutingLSA::RouterLSA);
473 lsa1->AddLinkRecord(lr1);
474 lsa1->SetLinkStateId("0.0.0.1");
475 lsa1->SetAdvertisingRouter("0.0.0.1");
476 lsa1->SetNode(nodes.Get(1));
477 m_lsas.push_back(lsa1);
478
479 // router 2
481 "10.1.1.1",
482 "10.1.1.3",
483 1);
484 auto lsa2 = new GlobalRoutingLSA();
485 lsa2->SetLSType(GlobalRoutingLSA::RouterLSA);
486 lsa2->AddLinkRecord(lr2);
487 lsa2->SetLinkStateId("0.0.0.2");
488 lsa2->SetAdvertisingRouter("0.0.0.2");
489 lsa2->SetNode(nodes.Get(2));
490 m_lsas.push_back(lsa2);
491
492 // router0 is the designated router for the LAN. it also exports the network LSA
493 auto lsa0network = new GlobalRoutingLSA();
494 lsa0network->SetLSType(GlobalRoutingLSA::NetworkLSA);
495 lsa0network->SetLinkStateId("10.1.1.1");
496 lsa0network->SetAdvertisingRouter("0.0.0.0");
497 lsa0network->AddAttachedRouter("10.1.1.1");
498 lsa0network->AddAttachedRouter("10.1.1.2");
499 lsa0network->AddAttachedRouter("10.1.1.3");
500 lsa0network->SetNetworkLSANetworkMask("255.255.255.248");
501 m_lsas.push_back(lsa0network); // note the index of the network lsa
502}
503
504void
506{
507 BuildLsa();
508 // insert the LSAs into the GlobalRouteManagerLSDB
509 auto srmlsdb = new GlobalRouteManagerLSDB();
510
511 srmlsdb->Insert(m_lsas[0]->GetLinkStateId(), m_lsas[0]);
512 srmlsdb->Insert(m_lsas[1]->GetLinkStateId(), m_lsas[1]);
513 srmlsdb->Insert(m_lsas[2]->GetLinkStateId(), m_lsas[2]);
514 srmlsdb->Insert(m_lsas[3]->GetLinkStateId(), m_lsas[3]);
515
516 // create the GlobalRouteManagerImpl
517 auto srm = new GlobalRouteManagerImpl();
518 srm->DebugUseLsdb(srmlsdb);
519
520 srm->DebugSPFCalculate(m_lsas[0]->GetLinkStateId()); // fill the routing table for node 0
521
522 // now the tests-----------------------
523
525 NS_TEST_ASSERT_MSG_NE(ip0, nullptr, "Error-- no Ipv4 object at node 0");
526 Ptr<Ipv4RoutingProtocol> routing0 = ip0->GetRoutingProtocol();
527 NS_TEST_ASSERT_MSG_NE(routing0, nullptr, "Error-- no Ipv4 routing protocol object at node 0");
528 Ptr<Ipv4GlobalRouting> globalRouting0 = routing0->GetObject<Ipv4GlobalRouting>();
529 NS_TEST_ASSERT_MSG_NE(globalRouting0, nullptr, "Error-- no Ipv4GlobalRouting object at node 0");
530
531 // The only route to check is the network route
532 uint32_t nRoutes0 = globalRouting0->GetNRoutes();
533 NS_TEST_ASSERT_MSG_EQ(nRoutes0, 1, "Error-- Network route not found for node 0");
534 Ipv4RoutingTableEntry* route = globalRouting0->GetRoute(0);
536 Ipv4Address("10.1.1.0"),
537 "Error-- wrong destination for network route");
539 Ipv4Address("0.0.0.0"),
540 "Error-- wrong gateway for network route");
541
543
546 // This delete clears the srm, which deletes the LSDB, which clears
547 // all of the LSAs, which each destroys the attached LinkRecords.
548 delete srm;
550}
551
552/**
553 * @ingroup internet-test
554 *
555 * @brief The purpose of this test is to check if Equal Cost MultiPath (ECMP) Routes are being built
556 * and used correctly.
557 */
559{
560 public:
562
563 void DoSetup() override;
564 void DoRun() override;
565
566 private:
567 /**
568 *@brief Builds the LSAs for the topology. These LSAs are manually created and inserted into the
569 * GlobalRouteManagerLSDB.Each node exports a router LSA.
570 */
571 void BuildLsa();
572
573 /**
574 * @brief Helper function that checks the output of the routing path
575 * and increments the corresponding route counter.
576 * @param route The routing path to check
577 */
578 void IncrementCount(Ptr<Ipv4Route>& route);
579 /**
580 * @brief function that checks the routing table entries for the expected output.
581 * @param globalroutingprotocol The routing protocol for the node whose routing table is to be
582 * checked.
583 * @param dests The expected destinations.
584 * @param gws The expected gateways.
585 */
586 void CheckRoutes(Ptr<Ipv4GlobalRouting>& globalroutingprotocol,
587 std::vector<Ipv4Address>& dests,
588 std::vector<Ipv4Address>& gws);
589 uint32_t route1 = 0; //!< Counter to keep track of the number of times route1 is used
590 uint32_t route2 = 0; //!< Counter to keep track of the number of times route2 is used
591 NodeContainer nodes; //!< NodeContainer to hold the nodes in the topology
592 std::vector<GlobalRoutingLSA*> m_lsas; //!< The LSAs for the topology
593};
594
596 : TestCase("RandomEcmpTestCase")
597{
598}
599
600void
602{
603 Config::SetDefault("ns3::Ipv4GlobalRouting::RandomEcmpRouting", BooleanValue(true));
604 /*
605 // Creating a Simple topology with 4 nodes and 3 links
606 //
607 //
608 //
609 // ------n1------
610 // / \
611 // / \
612 // n0 n3
613 // \ /
614 // \ /
615 // ------n2------
616 //
617 // Link n0-n1: 10.1.1.1/30,10.1.1.2/30
618 // Link n0-n2: 10.1.2.1/30,10.1.2.2/30
619 // Link n1-n3: 10.1.3.1/30,10.1.3.2/30
620 // Link n2-n3: 10.1.4.1/30,10.1.4.2/30
621 */
622 nodes.Create(4);
623
624 Ipv4GlobalRoutingHelper globalhelper;
626 stack.SetRoutingHelper(globalhelper);
627 stack.Install(nodes);
628 SimpleNetDeviceHelper devHelper;
629 devHelper.SetNetDevicePointToPointMode(true);
631 NetDeviceContainer d01 = devHelper.Install(nodes.Get(0), channel1);
632 d01.Add(devHelper.Install(nodes.Get(1), channel1));
634 NetDeviceContainer d23 = devHelper.Install(nodes.Get(2), channel2);
635 d23.Add(devHelper.Install(nodes.Get(3), channel2));
637 NetDeviceContainer d02 = devHelper.Install(nodes.Get(0), channel3);
638 d02.Add(devHelper.Install(nodes.Get(2), channel3));
640 NetDeviceContainer d13 = devHelper.Install(nodes.Get(1), channel4);
641 d13.Add(devHelper.Install(nodes.Get(3), channel4));
642
643 // Assign IP addresses to the devices
644 Ipv4AddressHelper address;
645 address.SetBase("10.1.1.0", "255.255.255.252");
646 Ipv4InterfaceContainer i01 = address.Assign(d01);
647
648 address.SetBase("10.1.2.0", "255.255.255.252");
649 Ipv4InterfaceContainer i02 = address.Assign(d02);
650
651 address.SetBase("10.1.3.0", "255.255.255.252");
652 Ipv4InterfaceContainer i13 = address.Assign(d13);
653
654 address.SetBase("10.1.4.0", "255.255.255.252");
655 Ipv4InterfaceContainer i23 = address.Assign(d23);
656}
657
658void
660 std::vector<Ipv4Address>& dests,
661 std::vector<Ipv4Address>& gws)
662{
663 // check each individual routes destination and gateway
664 for (uint32_t i = 0; i < globalroutingprotocol->GetNRoutes(); i++)
665 {
666 Ipv4RoutingTableEntry* route = globalroutingprotocol->GetRoute(i);
667 NS_LOG_DEBUG("dest " << route->GetDest() << " gw " << route->GetGateway());
668 NS_TEST_ASSERT_MSG_EQ(route->GetDest(), dests[i], "Error-- wrong destination");
669 NS_TEST_ASSERT_MSG_EQ(route->GetGateway(), gws[i], "Error-- wrong gateway");
670 }
671}
672
673void
675{
676 if (route->GetGateway() == Ipv4Address("10.1.1.2"))
677 {
678 route1++;
679 }
680 else if (route->GetGateway() == Ipv4Address("10.1.2.2"))
681 {
682 route2++;
683 }
684}
685
686void
688{
689 // we manually create the link state database, we could have used BuildRoutingTables() but this
690 // way testing the GlobalRouteManagerImpl without the involvement of GLobalRouter makes it
691 // easier to debug each individually
692
693 // router 0
695 "0.0.0.1",
696 "10.1.1.1",
697 1);
699 "10.1.1.2",
700 "255.255.255.252",
701 1);
702
704 "0.0.0.2",
705 "10.1.2.1",
706 1);
708 "10.1.2.2",
709 "255.255.255.252",
710 1);
711
712 auto lsa0 = new GlobalRoutingLSA();
713 lsa0->SetLSType(GlobalRoutingLSA::RouterLSA);
715 lsa0->SetLinkStateId("0.0.0.0");
716 lsa0->SetAdvertisingRouter("0.0.0.0");
717 lsa0->SetNode(nodes.Get(0));
718 lsa0->AddLinkRecord(lr0);
719 lsa0->AddLinkRecord(lr1);
720 lsa0->AddLinkRecord(lr2);
721 lsa0->AddLinkRecord(lr3);
722 m_lsas.push_back(lsa0);
723
724 // router 1
726 "0.0.0.0",
727 "10.1.1.2",
728 1);
730 "10.1.1.1",
731 "255.255.255.252",
732 1);
733
735 "0.0.0.3",
736 "10.1.3.1",
737 1);
739 "10.1.3.2",
740 "255.255.255.252",
741 1);
742
743 auto lsa1 = new GlobalRoutingLSA();
744 lsa1->SetLSType(GlobalRoutingLSA::RouterLSA);
746 lsa1->SetLinkStateId("0.0.0.1");
747 lsa1->SetAdvertisingRouter("0.0.0.1");
748 lsa1->SetNode(nodes.Get(1));
749 lsa1->AddLinkRecord(lr4);
750 lsa1->AddLinkRecord(lr5);
751 lsa1->AddLinkRecord(lr6);
752 lsa1->AddLinkRecord(lr7);
753 m_lsas.push_back(lsa1);
754
755 // router 2
757 "0.0.0.0",
758 "10.1.2.2",
759 1);
761 "10.1.2.1",
762 "255.255.255.252",
763 1);
765 "0.0.0.3",
766 "10.1.4.1",
767 1);
769 "10.1.4.2",
770 "255.255.255.252",
771 1);
772
773 auto lsa2 = new GlobalRoutingLSA();
774 lsa2->SetLSType(GlobalRoutingLSA::RouterLSA);
776 lsa2->SetLinkStateId("0.0.0.2");
777 lsa2->SetAdvertisingRouter("0.0.0.2");
778 lsa2->SetNode(nodes.Get(2));
779 lsa2->AddLinkRecord(lr8);
780 lsa2->AddLinkRecord(lr9);
781 lsa2->AddLinkRecord(lr10);
782 lsa2->AddLinkRecord(lr11);
783 m_lsas.push_back(lsa2);
784
785 // router 3
787 "0.0.0.1",
788 "10.1.3.2",
789 1);
791 "10.1.3.1",
792 "255.255.255.252",
793 1);
795 "0.0.0.2",
796 "10.1.4.2",
797 1);
799 "10.1.4.1",
800 "255.255.255.252",
801 1);
802
803 auto lsa3 = new GlobalRoutingLSA();
804 lsa3->SetLSType(GlobalRoutingLSA::RouterLSA);
806 lsa3->SetLinkStateId("0.0.0.3");
807 lsa3->SetAdvertisingRouter("0.0.0.3");
808 lsa3->SetNode(nodes.Get(3));
809 lsa3->AddLinkRecord(lr12);
810 lsa3->AddLinkRecord(lr13);
811 lsa3->AddLinkRecord(lr14);
812 lsa3->AddLinkRecord(lr15);
813 m_lsas.push_back(lsa3);
814}
815
816void
818{
819 // We need a deterministic output to pass the test. So we set a fixed seed and run for our
820 // UniformRandomVariable
825
826 BuildLsa();
827
828 // insert the LSAs into the GlobalRouteManagerLSDB
829 auto srmlsdb = new GlobalRouteManagerLSDB();
830 srmlsdb->Insert(m_lsas[0]->GetLinkStateId(), m_lsas[0]);
831 srmlsdb->Insert(m_lsas[1]->GetLinkStateId(), m_lsas[1]);
832 srmlsdb->Insert(m_lsas[2]->GetLinkStateId(), m_lsas[2]);
833 srmlsdb->Insert(m_lsas[3]->GetLinkStateId(), m_lsas[3]);
834
835 // create the GlobalRouteManagerImpl
836 auto srm = new GlobalRouteManagerImpl();
837 srm->DebugUseLsdb(srmlsdb);
838
839 // we manually call the DebugSPFCalculate to fill the routing tables for node 0
840 srm->DebugSPFCalculate(m_lsas[0]->GetLinkStateId());
841
842 // now the tests-----------------------
843
845 NS_TEST_ASSERT_MSG_NE(ip0, nullptr, "Error-- no Ipv4 object at node 0");
846 Ptr<Ipv4RoutingProtocol> routing0 = ip0->GetRoutingProtocol();
847 NS_TEST_ASSERT_MSG_NE(routing0, nullptr, "Error-- no Ipv4 routing protocol object at node 0");
848 Ptr<Ipv4GlobalRouting> globalRouting0 = routing0->GetObject<Ipv4GlobalRouting>();
849 NS_TEST_ASSERT_MSG_NE(globalRouting0, nullptr, "Error-- no Ipv4GlobalRouting object at node 0");
850
851 // assign streams to the UniformRandomVariable
852 globalRouting0->AssignStreams(0);
853 // check that the correct number of routes were built
854 uint32_t nRoutes0 = globalRouting0->GetNRoutes();
855 NS_TEST_ASSERT_MSG_EQ(nRoutes0, 14, "Error-- incorrect number of routes found on node 0");
856
857 // check that the routes are correct
858 std::vector<Ipv4Address> expectedDests;
859 std::vector<Ipv4Address> expectedNextHops;
860
861 // add all the expected destinations and gateways. This is pretty verbose
862 // Please Note: The order of the following line is important because we check the routing table
863 // entries in order. The test will fail if we reorder the vector entries.
864
865 // For Routing table of Node 0 we check the following Destinations and Gateways
866 expectedDests.emplace_back("10.1.1.2");
867 expectedDests.emplace_back("10.1.3.1");
868 expectedDests.emplace_back("10.1.2.2");
869 expectedDests.emplace_back("10.1.4.1");
870 expectedDests.emplace_back("10.1.3.2");
871 expectedDests.emplace_back("10.1.3.2");
872 expectedDests.emplace_back("10.1.4.2");
873 expectedDests.emplace_back("10.1.4.2");
874 expectedDests.emplace_back("10.1.1.0");
875 expectedDests.emplace_back("10.1.3.0");
876 expectedDests.emplace_back("10.1.3.0");
877 expectedDests.emplace_back("10.1.4.0");
878 expectedDests.emplace_back("10.1.4.0");
879 expectedDests.emplace_back("10.1.2.0");
880
881 expectedNextHops.emplace_back("10.1.1.2");
882 expectedNextHops.emplace_back("10.1.1.2");
883 expectedNextHops.emplace_back("10.1.2.2");
884 expectedNextHops.emplace_back("10.1.2.2");
885 expectedNextHops.emplace_back("10.1.1.2");
886 expectedNextHops.emplace_back("10.1.2.2");
887 expectedNextHops.emplace_back("10.1.1.2");
888 expectedNextHops.emplace_back("10.1.2.2");
889 expectedNextHops.emplace_back("10.1.1.2");
890 expectedNextHops.emplace_back("10.1.1.2");
891 expectedNextHops.emplace_back("10.1.2.2");
892 expectedNextHops.emplace_back("10.1.1.2");
893 expectedNextHops.emplace_back("10.1.2.2");
894 expectedNextHops.emplace_back("10.1.2.2");
895
896 // Test 1: Check the Routing Table of Node 0
897 CheckRoutes(globalRouting0, expectedDests, expectedNextHops);
898
899 // Test 2: Check that the equal cost routes are being used at least once.
900 // we need to call RouteOutput() at node 0 and check the output
901 // route from the table. The thing to check here is that different equal cost routes are
902 // returned across different calls to this method.
903
904 Socket::SocketErrno errno_;
905 Ptr<NetDevice> oif(nullptr);
906 Ptr<Packet> packet = Create<Packet>();
907 Ipv4Header ipHeader;
908 ipHeader.SetSource(Ipv4Address("10.1.1.1"));
909 ipHeader.SetDestination(Ipv4Address("10.1.4.2"));
910
911 for (uint32_t i = 0; i < 10; i++)
912 {
913 Ptr<Ipv4Route> route = globalRouting0->RouteOutput(packet, ipHeader, oif, errno_);
914 IncrementCount(route);
915 }
916
918
920 route1,
921 1,
922 "The routing path for node 0 to node 3 does not match the expected output, "
923 "Equal Cost MultiPath (ECMP) routes are not being used correctly");
925 route2,
926 1,
927 "The routing path for node 0 to node 3 does not match the expected output, "
928 "Equal Cost MultiPath (ECMP) routes are not being used correctly");
929
930 // end of test--------------------
931
933
935
938 // This delete clears the srm, which deletes the LSDB, which clears
939 // all of the LSAs, which each destroys the attached LinkRecords.
940 delete srm;
941}
942
943/**
944 * @ingroup internet-test
945 *
946 * @brief Global Route Manager TestSuite
947 */
949{
950 public:
952
953 private:
954};
955
957 : TestSuite("global-route-manager-impl", Type::UNIT)
958{
959 AddTestCase(new LinkRoutesTestCase(), TestCase::Duration::QUICK);
960 AddTestCase(new LanRoutesTestCase(), TestCase::Duration::QUICK);
961 AddTestCase(new RandomEcmpTestCase(), TestCase::Duration::QUICK);
962}
963
965 g_globalRoutingManagerImplTestSuite; //!< Static variable for test initialization
This test case is to check if NetworkRoutes are being built correctly, i.e if route computation works...
void DoRun() override
Implementation to actually run this TestCase.
NodeContainer nodes
NodeContainer to hold the nodes in the topology.
void BuildLsa()
Builds the LSAs for the topology.
std::vector< GlobalRoutingLSA * > m_lsas
The LSAs for the topology.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
The purpose of this test is to check if Equal Cost MultiPath (ECMP) Routes are being built and used c...
void DoSetup() override
Implementation to do any local setup required for this TestCase.
uint32_t route1
Counter to keep track of the number of times route1 is used.
std::vector< GlobalRoutingLSA * > m_lsas
The LSAs for the topology.
void CheckRoutes(Ptr< Ipv4GlobalRouting > &globalroutingprotocol, std::vector< Ipv4Address > &dests, std::vector< Ipv4Address > &gws)
function that checks the routing table entries for the expected output.
NodeContainer nodes
NodeContainer to hold the nodes in the topology.
void BuildLsa()
Builds the LSAs for the topology.
void DoRun() override
Implementation to actually run this TestCase.
uint32_t route2
Counter to keep track of the number of times route2 is used.
void IncrementCount(Ptr< Ipv4Route > &route)
Helper function that checks the output of the routing path and increments the corresponding route cou...
AttributeValue implementation for Boolean.
Definition boolean.h:26
static void ResetRouterId()
Reset the router ID counter to zero.
A global router implementation.
The Link State DataBase (LSDB) of the Global Route Manager.
a Link State Advertisement (LSA) for a router, used in global routing.
@ LSA_SPF_NOT_EXPLORED
New vertex not yet considered.
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
Ipv4 addresses are stored in host order in this class.
Helper class that adds ns3::Ipv4GlobalRouting objects.
Global routing protocol for IPv4 stacks.
Packet header for IPv4.
Definition ipv4-header.h:23
void SetDestination(Ipv4Address destination)
void SetSource(Ipv4Address source)
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Implement the IPv4 layer.
A record of an IPv4 routing table entry for Ipv4GlobalRouting and Ipv4StaticRouting.
Ipv4Address GetDest() const
Ipv4Address GetGateway() const
holds a vector of ns3::NetDevice pointers
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
Smart pointer class similar to boost::intrusive_ptr.
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static uint64_t GetRun()
Get the current run number.
static uint32_t GetSeed()
Get the current seed value which will be used by all subsequently instantiated RandomVariableStream o...
build a set of SimpleNetDevice objects
void SetNetDevicePointToPointMode(bool pointToPointMode)
SimpleNetDevice is Broadcast capable and ARP needing.
NetDeviceContainer Install(Ptr< Node > node) const
This method creates an ns3::SimpleChannel with the attributes configured by SimpleNetDeviceHelper::Se...
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition socket.h:73
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
static GlobalRouteManagerImplTestSuite g_globalRoutingManagerImplTestSuite
Static variable for test initialization.
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:886
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:439
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition test.h:134
#define NS_TEST_ASSERT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report and abort if not.
Definition test.h:554
#define NS_TEST_ASSERT_MSG_GT_OR_EQ(actual, limit, msg)
Test that an actual value is greater than or equal to a limit and report and abort if not.
Definition test.h:905
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1369
Every class exported by the ns3 library is enclosed in the ns3 namespace.