A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
sixlowpan-nd-reg-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2025
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Boh Jie Qi <jieqiboh5836@gmail.com>
7 */
8
10
11#include "ns3/core-module.h"
12#include "ns3/internet-module.h"
13#include "ns3/internet-stack-helper.h"
14#include "ns3/simple-net-device-helper.h"
15#include "ns3/simple-net-device.h"
16#include "ns3/sixlowpan-module.h"
17#include "ns3/sixlowpan-nd-protocol.h"
18#include "ns3/test.h"
19
20#include <fstream>
21#include <limits>
22#include <regex>
23#include <string>
24
25namespace ns3
26{
27
28/**
29 * @ingroup sixlowpan-nd-reg-tests
30 *
31 * @brief Test successful registration of varying numbers of 6LNs with 1 6LBR
32 */
34{
35 public:
37 : TestCase("Registration of 1 6LN with 1 6LBR")
38 {
39 }
40
41 void DoRun() override
42 {
43 // 6LBR - node 0
44 // LLaddr: fe80::200:ff:fe00:1
45 // Link-layer address: 02:00:00:00:00:01
46 // Gaddr: 2001::200:ff:fe00:1
47
48 // 6LN - node 1
49 // LLaddr: fe80::200:ff:fe00:2
50 // Link-layer address: 02:00:00:00:00:02
51 // Gaddr: 2001::200:ff:fe00:2 (Needs reg first)
52
53 // Basic Exchange, then assert NC, 6LNC and RT contents of 6LN and 6LBR
54 // Create nodes
56 nodes.Create(2);
57 Ptr<Node> lbrNode = nodes.Get(0);
58 Ptr<Node> lnNode = nodes.Get(1);
59
60 // Install SimpleNetDevice on nodes
61 SimpleNetDeviceHelper simpleNetDeviceHelper;
62 NetDeviceContainer simpleNetDevices = simpleNetDeviceHelper.Install(nodes);
63
64 // Install Internet stack
65 InternetStackHelper internetv6;
66 internetv6.Install(nodes);
67
68 // Install 6LoWPAN on top of SimpleNetDevice
69 SixLowPanHelper sixlowpan;
70 NetDeviceContainer devices = sixlowpan.Install(simpleNetDevices);
71
72 // Configure 6LoWPAN ND
73 // Node 0 = 6LBR
74 sixlowpan.InstallSixLowPanNdBorderRouter(devices.Get(0), "2001::");
75 sixlowpan.SetAdvertisedPrefix(devices.Get(0), Ipv6Prefix("2001::", 64));
76 // Node 1 = 6LN
77 sixlowpan.InstallSixLowPanNdNode(devices.Get(1));
78
79 std::ostringstream ndiscStream;
80 Ptr<OutputStreamWrapper> outputNdiscStream = Create<OutputStreamWrapper>(&ndiscStream);
81 std::ostringstream routingTableStream;
82 Ptr<OutputStreamWrapper> outputRoutingTableStream =
83 Create<OutputStreamWrapper>(&routingTableStream);
84 std::ostringstream bindingTableStream;
85 Ptr<OutputStreamWrapper> outputBindingTableStream =
86 Create<OutputStreamWrapper>(&bindingTableStream);
87
89 Ipv6RoutingHelper::PrintRoutingTableAllAt(Seconds(5), outputRoutingTableStream);
90 SixLowPanHelper::PrintBindingTableAllAt(Seconds(5), outputBindingTableStream);
91
92 Ptr<SixLowPanNdProtocol> nd = lnNode->GetObject<SixLowPanNdProtocol>();
93 nd->TraceConnectWithoutContext(
94 "AddressRegistrationResult",
96
100
101 constexpr auto expectedNdiscStream =
102 "NDISC Cache of node 0 at time +5s\n"
103 "2001::200:ff:fe00:2 dev 2 lladdr 03-06-00:00:00:00:00:02 REACHABLE\n"
104 "fe80::200:ff:fe00:2 dev 2 lladdr 03-06-00:00:00:00:00:02 REACHABLE\n"
105 "NDISC Cache of node 1 at time +5s\n"
106 "fe80::200:ff:fe00:1 dev 2 lladdr 03-06-00:00:00:00:00:01 REACHABLE\n";
107 NS_TEST_EXPECT_MSG_EQ(ndiscStream.str(), expectedNdiscStream, "NdiscCache is incorrect.");
108
109 constexpr auto expectedRoutingTableStream =
110 "Node: 0, Time: +5s, Local time: +5s, Ipv6ListRouting table\n"
111 " Priority: 0 Protocol: ns3::Ipv6StaticRouting\n"
112 "Node: 0, Time: +5s, Local time: +5s, Ipv6StaticRouting table\n"
113 "Destination Next Hop Flag Met Ref Use If\n"
114 "::1/128 :: UH 0 - - 0\n"
115 "fe80::/64 :: U 0 - - 1\n"
116 "2001::200:ff:fe00:2/128 fe80::200:ff:fe00:2 UH 0 - - 1\n\n"
117 " Priority: -10 Protocol: ns3::Ipv6GlobalRouting\n"
118 "Node: 0, Time: +5s, Local time: +5s, Ipv6GlobalRouting table\n"
119 "Destination Next Hop Flag Met Ref Use Iface\n\n"
120 "Node: 1, Time: +5s, Local time: +5s, Ipv6ListRouting table\n"
121 " Priority: 0 Protocol: ns3::Ipv6StaticRouting\n"
122 "Node: 1, Time: +5s, Local time: +5s, Ipv6StaticRouting table\n"
123 "Destination Next Hop Flag Met Ref Use If\n"
124 "::1/128 :: UH 0 - - 0\n"
125 "fe80::/64 :: U 0 - - 1\n"
126 "::/0 fe80::200:ff:fe00:1 UG 0 - - 1\n\n"
127 " Priority: -10 Protocol: ns3::Ipv6GlobalRouting\n"
128 "Node: 1, Time: +5s, Local time: +5s, Ipv6GlobalRouting table\n"
129 "Destination Next Hop Flag Met Ref Use Iface\n\n";
130 NS_TEST_EXPECT_MSG_EQ(routingTableStream.str(),
131 expectedRoutingTableStream,
132 "Routing table does not match expected.");
133
135 Ipv6Address("2001::200:ff:fe00:2"),
136 "Registered address does not match expected value.");
137
138 // Validate binding table output for Node 0 and Node 1
139 NS_TEST_ASSERT_MSG_EQ((bindingTableStream.str()),
141 "BindingTable does not match expected output.");
142 }
143
144 private:
145 Ipv6Address registeredAddress; //!< Address that was successfully registered during the test
146
147 /**
148 * @brief Callback sink for address registration result trace events
149 * @param address IPv6 address that was being registered
150 * @param success Whether the registration was successful
151 * @param status Registration status code
152 */
153 void RegistrationResultSink(Ipv6Address address, bool success, uint8_t status)
154 {
155 if (success)
156 {
157 registeredAddress = address;
158 }
159 }
160};
161
162/**
163 * @ingroup sixlowpan-nd-reg-tests
164 *
165 * @brief Test successful registration of 5 6LNs with 1 6LBR
166 */
168{
169 public:
171 : TestCase("Registration of 5 6LNs with 1 6LBR")
172 {
173 }
174
175 void DoRun() override
176 {
177 Time duration = Time("50s");
178
179 constexpr uint32_t numLns = 5;
180
182 nodes.Create(1 + numLns); // 1 LBR + 5 LNs
183 Ptr<Node> lbrNode = nodes.Get(0);
184
185 SimpleNetDeviceHelper simpleNetDeviceHelper;
186
187 NetDeviceContainer simpleNetDevices;
188 simpleNetDevices = simpleNetDeviceHelper.Install(nodes);
189
190 InternetStackHelper internetv6;
191 internetv6.Install(nodes);
192
193 SixLowPanHelper sixlowpan;
194 NetDeviceContainer devices = sixlowpan.Install(simpleNetDevices);
195
196 sixlowpan.InstallSixLowPanNdBorderRouter(devices.Get(0), "2001::");
197 sixlowpan.SetAdvertisedPrefix(devices.Get(0), Ipv6Prefix("2001::", 64));
198
199 for (uint32_t i = 1; i <= numLns; ++i)
200 {
201 sixlowpan.InstallSixLowPanNdNode(devices.Get(i));
202 }
203
204 std::ostringstream ndiscStream;
205 Ptr<OutputStreamWrapper> outputNdiscStream = Create<OutputStreamWrapper>(&ndiscStream);
206 std::ostringstream routingTableStream;
207 Ptr<OutputStreamWrapper> outputRoutingTableStream =
208 Create<OutputStreamWrapper>(&routingTableStream);
209 std::ostringstream bindingTableStream;
210 Ptr<OutputStreamWrapper> outputBindingTableStream =
211 Create<OutputStreamWrapper>(&bindingTableStream);
212
213 Ipv6RoutingHelper::PrintNeighborCacheAllAt(duration, outputNdiscStream);
214 Ipv6RoutingHelper::PrintRoutingTableAllAt(duration, outputRoutingTableStream);
215 SixLowPanHelper::PrintBindingTableAllAt(duration, outputBindingTableStream);
216
217 Simulator::Stop(duration);
220
222 GenerateNdiscCacheOutput(numLns + 1, duration),
223 "NdiscCache does not match expected output.");
224
225 NS_TEST_ASSERT_MSG_EQ(SortRoutingTableString(routingTableStream.str()),
226 GenerateRoutingTableOutput(numLns + 1, duration),
227 "RoutingTable does not match expected output.");
228
229 NS_TEST_ASSERT_MSG_EQ((bindingTableStream.str()),
230 GenerateBindingTableOutput(numLns + 1, duration),
231 "BindingTable does not match expected output.");
232 }
233};
234
235/**
236 * @ingroup sixlowpan-nd-reg-tests
237 *
238 * @brief Test successful registration of 15 6LNs with 1 6LBR
239 */
241{
242 public:
244 : TestCase("Registration of 15 6LNs with 1 6LBR")
245 {
246 }
247
248 void DoRun() override
249 {
250 Time duration = Time("300s");
251 constexpr uint32_t numLns = 15;
252
254 nodes.Create(1 + numLns); // 1 LBR + 15 LNs
255 Ptr<Node> lbrNode = nodes.Get(0);
256
257 // Use SimpleNetDevice instead of LrWpan
258 SimpleNetDeviceHelper simpleNetDeviceHelper;
259 NetDeviceContainer simpleNetDevices = simpleNetDeviceHelper.Install(nodes);
260
261 InternetStackHelper internetv6;
262 internetv6.Install(nodes);
263
264 SixLowPanHelper sixlowpan;
265 NetDeviceContainer devices = sixlowpan.Install(simpleNetDevices);
266
267 // Configure 6LoWPAN ND
268 sixlowpan.InstallSixLowPanNdBorderRouter(devices.Get(0), "2001::");
269 sixlowpan.SetAdvertisedPrefix(devices.Get(0), Ipv6Prefix("2001::", 64));
270
271 for (uint32_t i = 1; i <= numLns; ++i)
272 {
273 sixlowpan.InstallSixLowPanNdNode(devices.Get(i));
274 }
275
276 std::ostringstream ndiscStream;
277 Ptr<OutputStreamWrapper> outputNdiscStream = Create<OutputStreamWrapper>(&ndiscStream);
278 std::ostringstream routingTableStream;
279 Ptr<OutputStreamWrapper> outputRoutingTableStream =
280 Create<OutputStreamWrapper>(&routingTableStream);
281 std::ostringstream bindingTableStream;
282 Ptr<OutputStreamWrapper> outputBindingTableStream =
283 Create<OutputStreamWrapper>(&bindingTableStream);
284
285 Ipv6RoutingHelper::PrintNeighborCacheAllAt(duration, outputNdiscStream);
286 Ipv6RoutingHelper::PrintRoutingTableAllAt(duration, outputRoutingTableStream);
287 SixLowPanHelper::PrintBindingTableAllAt(duration, outputBindingTableStream);
288
289 Simulator::Stop(duration);
292
294 GenerateNdiscCacheOutput(numLns + 1, duration),
295 "NdiscCache does not match expected output.");
296
297 NS_TEST_ASSERT_MSG_EQ(SortRoutingTableString(routingTableStream.str()),
298 GenerateRoutingTableOutput(numLns + 1, duration),
299 "RoutingTable does not match expected output.");
300
301 NS_TEST_ASSERT_MSG_EQ((bindingTableStream.str()),
302 GenerateBindingTableOutput(numLns + 1, duration),
303 "BindingTable does not match expected output.");
304 }
305};
306
307/**
308 * @ingroup sixlowpan-nd-reg-tests
309 *
310 * @brief Test successful registration of 20 6LNs with 1 6LBR
311 */
313{
314 public:
316 : TestCase("Registration of 20 6LNs with 1 6LBR")
317 {
318 }
319
320 void DoRun() override
321 {
322 Time duration = Time("300s");
323 constexpr uint32_t numLns = 20;
324
326 nodes.Create(1 + numLns); // 1 LBR + 20 LNs
327 Ptr<Node> lbrNode = nodes.Get(0);
328
329 // Use SimpleNetDevice instead of LrWpan
330 SimpleNetDeviceHelper simpleNetDeviceHelper;
331 NetDeviceContainer simpleNetDevices = simpleNetDeviceHelper.Install(nodes);
332
333 InternetStackHelper internetv6;
334 internetv6.Install(nodes);
335
336 SixLowPanHelper sixlowpan;
337 NetDeviceContainer devices = sixlowpan.Install(simpleNetDevices);
338
339 // Configure 6LoWPAN ND
340 sixlowpan.InstallSixLowPanNdBorderRouter(devices.Get(0), "2001::");
341 sixlowpan.SetAdvertisedPrefix(devices.Get(0), Ipv6Prefix("2001::", 64));
342
343 for (uint32_t i = 1; i <= numLns; ++i)
344 {
345 sixlowpan.InstallSixLowPanNdNode(devices.Get(i));
346 }
347
348 std::ostringstream ndiscStream;
349 Ptr<OutputStreamWrapper> outputNdiscStream = Create<OutputStreamWrapper>(&ndiscStream);
350 std::ostringstream routingTableStream;
351 Ptr<OutputStreamWrapper> outputRoutingTableStream =
352 Create<OutputStreamWrapper>(&routingTableStream);
353 std::ostringstream bindingTableStream;
354 Ptr<OutputStreamWrapper> outputBindingTableStream =
355 Create<OutputStreamWrapper>(&bindingTableStream);
356
357 Ipv6RoutingHelper::PrintNeighborCacheAllAt(duration, outputNdiscStream);
358 Ipv6RoutingHelper::PrintRoutingTableAllAt(duration, outputRoutingTableStream);
359 SixLowPanHelper::PrintBindingTableAllAt(duration, outputBindingTableStream);
360
361 Simulator::Stop(duration);
364
366 GenerateNdiscCacheOutput(numLns + 1, duration),
367 "NdiscCache does not match expected output.");
368
369 NS_TEST_ASSERT_MSG_EQ(SortRoutingTableString(routingTableStream.str()),
370 GenerateRoutingTableOutput(numLns + 1, duration),
371 "RoutingTable does not match expected output.");
372
373 NS_TEST_ASSERT_MSG_EQ((bindingTableStream.str()),
374 GenerateBindingTableOutput(numLns + 1, duration),
375 "BindingTable does not match expected output.");
376 }
377};
378
379/**
380 * @ingroup sixlowpan-nd-reg-tests
381 *
382 * @brief Test 6LN multicast RS timeout behavior when no RA is received
383 */
385{
386 public:
388 : TestCase("6LN sends multicast RS but receives no RA, test timeout behavior")
389 {
390 }
391
392 void DoRun() override
393 {
395 nodes.Create(1);
396 Ptr<Node> lnNode = nodes.Get(0);
397
398 // Use SimpleNetDevice instead of LrWpan
399 SimpleNetDeviceHelper simpleNetDeviceHelper;
400 NetDeviceContainer simpleNetDevices = simpleNetDeviceHelper.Install(nodes);
401
402 // Install Internet stack
403 InternetStackHelper internetv6;
404 internetv6.Install(nodes);
405
406 // Install 6LoWPAN device on top of SimpleNetDevice
407 SixLowPanHelper sixlowpan;
408 NetDeviceContainer sixDevices = sixlowpan.Install(simpleNetDevices);
409
410 // Install ND only as a node (no BR) - this means no RA responses
411 sixlowpan.InstallSixLowPanNdNode(sixDevices.Get(0));
412
413 // Set up trace to capture multicast RS events
414 Ptr<SixLowPanNdProtocol> nd = lnNode->GetObject<SixLowPanNdProtocol>();
415 NS_ASSERT_MSG(nd, "Failed to get SixLowPanNdProtocol");
416 nd->TraceConnectWithoutContext(
417 "MulticastRS",
419
420 // Simulation time should be long enough to see RS timeout
421 // Keep same duration to maintain test behavior
425
426 // Verify we got the expected number of multicast RS events
428 7,
429 "Expected 7 multicast RS events, but got " +
430 std::to_string(m_multicastRsEvents.size()));
431 }
432
433 private:
434 std::vector<Ipv6Address>
435 m_multicastRsEvents; //!< Container for multicast RS events captured during test
436
437 /**
438 * @brief Callback sink for multicast RS trace events
439 * @param src Source address of the multicast RS
440 */
442 {
443 m_multicastRsEvents.push_back(src);
444 }
445};
446
447/**
448 * @ingroup sixlowpan-nd-reg-tests
449 *
450 * @brief 6LoWPAN-ND TestSuite
451 */
465
466static SixLowPanNdRegTestSuite
467 g_sixlowpanndregTestSuite; //!< Static variable for test initialization
468} // namespace ns3
aggregate IP/TCP/UDP functionality to existing Nodes.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
Describes an IPv6 address.
Describes an IPv6 prefix.
static void PrintRoutingTableAllAt(Time printTime, Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S)
prints the routing tables of all nodes at a particular time.
static void PrintNeighborCacheAllAt(Time printTime, Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S)
prints the neighbor cache of all nodes at a particular time.
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
keep track of a set of node pointers.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
build a set of SimpleNetDevice objects
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:125
static void Run()
Run the simulation.
Definition simulator.cc:161
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:169
Setup a sixlowpan stack to be used as a shim between IPv6 and a generic NetDevice.
Ipv6InterfaceContainer InstallSixLowPanNdNode(NetDeviceContainer c)
Install the SixLoWPAN-ND stack, associate it with a NetDevice, and set it as a 6LN.
NetDeviceContainer Install(NetDeviceContainer c)
Install the SixLoWPAN stack on top of an existing NetDevice.
static void PrintBindingTableAllAt(Time printTime, Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S)
Print the binding table of all nodes at a specific time.
void SetAdvertisedPrefix(const Ptr< NetDevice > nd, Ipv6Prefix prefix)
Add a new prefix to be advertised by 6LoWPAN-ND.
Ipv6InterfaceContainer InstallSixLowPanNdBorderRouter(NetDeviceContainer c, Ipv6Address baseAddr)
Install the SixLoWPAN-ND stack, associate it with a NetDevice, and set it as a 6LBR.
Test successful registration of 15 6LNs with 1 6LBR.
void DoRun() override
Implementation to actually run this TestCase.
Test successful registration of 5 6LNs with 1 6LBR.
void DoRun() override
Implementation to actually run this TestCase.
Test 6LN multicast RS timeout behavior when no RA is received.
std::vector< Ipv6Address > m_multicastRsEvents
Container for multicast RS events captured during test.
void MulticastRsSink(Ipv6Address src)
Callback sink for multicast RS trace events.
void DoRun() override
Implementation to actually run this TestCase.
Test successful registration of varying numbers of 6LNs with 1 6LBR.
void RegistrationResultSink(Ipv6Address address, bool success, uint8_t status)
Callback sink for address registration result trace events.
void DoRun() override
Implementation to actually run this TestCase.
Ipv6Address registeredAddress
Address that was successfully registered during the test.
An optimization of the ND protocol for 6LoWPANs.
Test successful registration of 20 6LNs with 1 6LBR.
void DoRun() override
Implementation to actually run this TestCase.
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:296
@ QUICK
Fast test.
Definition test.h:1057
TestCase(const TestCase &)=delete
Caller graph was not generated because of its size.
Type
Type of test.
Definition test.h:1271
@ UNIT
This test suite implements a Unit Test.
Definition test.h:1273
TestSuite(std::string name, Type type=Type::UNIT)
Construct a new test suite.
Definition test.cc:494
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:690
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:454
#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:133
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition test.h:240
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1273
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::string SortRoutingTableString(std::string routingTable)
Sort the host-route entries in node 0's routing table block numerically.
std::string GenerateNdiscCacheOutput(uint32_t numNodes, Time time)
Generate expected NDisc cache output for a star topology.
std::string GenerateBindingTableOutput(uint32_t numNodes, Time time)
Generate expected binding table output for a star topology.
std::string NormalizeNdiscCacheStates(const std::string &ndiscOutput)
Replace STALE with REACHABLE in an NDisc cache output string.
std::string GenerateRoutingTableOutput(uint32_t numNodes, Time time)
Generate expected routing table output for a star topology.
static SixLowPanNdRegTestSuite g_sixlowpanndregTestSuite
Static variable for test initialization.