A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
nix-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2021 NITK Surathkal
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Ameya Deshpande <ameyanrd@outlook.com>
7 */
8
9#include "ns3/icmpv4-l4-protocol.h"
10#include "ns3/icmpv6-l4-protocol.h"
11#include "ns3/internet-stack-helper.h"
12#include "ns3/ipv4-address-helper.h"
13#include "ns3/ipv4-l3-protocol.h"
14#include "ns3/ipv6-address-helper.h"
15#include "ns3/ipv6-l3-protocol.h"
16#include "ns3/nix-vector-helper.h"
17#include "ns3/simple-net-device-helper.h"
18#include "ns3/simulator.h"
19#include "ns3/socket-factory.h"
20#include "ns3/socket.h"
21#include "ns3/test.h"
22#include "ns3/udp-l4-protocol.h"
23#include "ns3/udp-socket-factory.h"
24
25using namespace ns3;
26
27/**
28 * \defgroup nix-vector-routing-test Nix-Vector Routing Tests
29 */
30
31/**
32 * \ingroup nix-vector-routing-test
33 * \ingroup tests
34 *
35 * The topology is of the form:
36 * \verbatim
37 __________
38 / \
39 nSrc -- nA -- nB -- nC -- nDst
40 \endverbatim
41 *
42 * Following are the tests in this test case:
43 * - Test the routing from nSrc to nDst.
44 * - Test if the path taken is the shortest path.
45 * (Set down the interface of nA on nA-nC channel.)
46 * - Test if the NixCache and Ipv4RouteCache are empty.
47 * - Test the routing from nSrc to nDst again.
48 * - Test if the new shortest path is taken.
49 * (Set down the interface of nC on nB-nC channel.)
50 * - Test that routing is not possible from nSrc to nDst.
51 *
52 * \brief IPv4 Nix-Vector Routing Test
53 */
55{
56 Ptr<Packet> m_receivedPacket; //!< Received packet
57
58 /**
59 * \brief Send data immediately after being called.
60 * \param socket The sending socket.
61 * \param to IPv4 Destination address.
62 */
63 void DoSendDatav4(Ptr<Socket> socket, Ipv4Address to);
64
65 /**
66 * \brief Send data immediately after being called.
67 * \param socket The sending socket.
68 * \param to IPv6 Destination address.
69 */
70 void DoSendDatav6(Ptr<Socket> socket, Ipv6Address to);
71
72 /**
73 * \brief Schedules the DoSendData () function to send the data.
74 * \param delay The scheduled time to send data.
75 * \param socket The sending socket.
76 * \param to IPv4 Destination address.
77 */
78 void SendData(Time delay, Ptr<Socket> socket, Ipv4Address to);
79
80 /**
81 * \brief Schedules the DoSendData () function to send the data.
82 * \param delay The scheduled time to send data.
83 * \param socket The sending socket.
84 * \param to IPv6 Destination address.
85 */
86 void SendData(Time delay, Ptr<Socket> socket, Ipv6Address to);
87
88 public:
89 void DoRun() override;
91
92 /**
93 * \brief Receive data.
94 * \param socket The receiving socket.
95 */
96 void ReceivePkt(Ptr<Socket> socket);
97
98 std::vector<uint32_t> m_receivedPacketSizes; //!< Received packet sizes
99};
100
102 : TestCase("three router, two path test")
103{
104}
105
106void
108{
109 uint32_t availableData [[maybe_unused]] = socket->GetRxAvailable();
110 m_receivedPacket = socket->Recv(std::numeric_limits<uint32_t>::max(), 0);
111 NS_TEST_ASSERT_MSG_EQ(availableData,
113 "availableData should be equal to the size of packet received.");
115}
116
117void
119{
120 Address realTo = InetSocketAddress(to, 1234);
121 socket->SendTo(Create<Packet>(123), 0, realTo);
122}
123
124void
126{
127 Address realTo = Inet6SocketAddress(to, 1234);
128 socket->SendTo(Create<Packet>(123), 0, realTo);
129}
130
131void
133{
135 Simulator::ScheduleWithContext(socket->GetNode()->GetId(),
136 delay,
138 this,
139 socket,
140 to);
141}
142
143void
145{
147 Simulator::ScheduleWithContext(socket->GetNode()->GetId(),
148 delay,
150 this,
151 socket,
152 to);
153}
154
155void
157{
158 // Create topology
159 NodeContainer nSrcnA;
160 NodeContainer nAnB;
161 NodeContainer nBnC;
162 NodeContainer nCnDst;
163 NodeContainer nAnC;
164
165 nSrcnA.Create(2);
166
167 nAnB.Add(nSrcnA.Get(1));
168 nAnB.Create(1);
169
170 nBnC.Add(nAnB.Get(1));
171 nBnC.Create(1);
172
173 nCnDst.Add(nBnC.Get(1));
174 nCnDst.Create(1);
175
176 nAnC.Add(nAnB.Get(0));
177 nAnC.Add(nCnDst.Get(0));
178
179 SimpleNetDeviceHelper devHelper;
180 devHelper.SetNetDevicePointToPointMode(true);
181
182 NodeContainer allNodes = NodeContainer(nSrcnA, nBnC, nCnDst.Get(1));
183
184 std::ostringstream stringStream1v4;
185 Ptr<OutputStreamWrapper> routingStream1v4 = Create<OutputStreamWrapper>(&stringStream1v4);
186 std::ostringstream stringStream1v6;
187 Ptr<OutputStreamWrapper> routingStream1v6 = Create<OutputStreamWrapper>(&stringStream1v6);
188 std::ostringstream stringStream2v4;
189 Ptr<OutputStreamWrapper> cacheStreamv4 = Create<OutputStreamWrapper>(&stringStream2v4);
190 std::ostringstream stringStream2v6;
191 Ptr<OutputStreamWrapper> cacheStreamv6 = Create<OutputStreamWrapper>(&stringStream2v6);
192 std::ostringstream stringStream3v4;
193 Ptr<OutputStreamWrapper> routingStream3v4 = Create<OutputStreamWrapper>(&stringStream3v4);
194 std::ostringstream stringStream3v6;
195 Ptr<OutputStreamWrapper> routingStream3v6 = Create<OutputStreamWrapper>(&stringStream3v6);
196
197 // NixHelper to install nix-vector routing on all nodes
198 Ipv4NixVectorHelper ipv4NixRouting;
199 Ipv6NixVectorHelper ipv6NixRouting;
201 stack.SetRoutingHelper(ipv4NixRouting); // has effect on the next Install ()
202 stack.SetRoutingHelper(ipv6NixRouting); // has effect on the next Install ()
203 stack.Install(allNodes);
204
205 NetDeviceContainer dSrcdA;
208 NetDeviceContainer dCdDst;
210 dSrcdA = devHelper.Install(nSrcnA);
211 dAdB = devHelper.Install(nAnB);
212 dBdC = devHelper.Install(nBnC);
213 dCdDst = devHelper.Install(nCnDst);
214 dAdC = devHelper.Install(nAnC);
215
216 Ipv4AddressHelper aSrcaAv4;
217 aSrcaAv4.SetBase("10.1.0.0", "255.255.255.0");
218 Ipv4AddressHelper aAaBv4;
219 aAaBv4.SetBase("10.1.1.0", "255.255.255.0");
220 Ipv4AddressHelper aBaCv4;
221 aBaCv4.SetBase("10.1.2.0", "255.255.255.0");
222 Ipv4AddressHelper aCaDstv4;
223 aCaDstv4.SetBase("10.1.3.0", "255.255.255.0");
224 Ipv4AddressHelper aAaCv4;
225 aAaCv4.SetBase("10.1.4.0", "255.255.255.0");
226
227 Ipv6AddressHelper aSrcaAv6;
228 aSrcaAv6.SetBase(Ipv6Address("2001:0::"), Ipv6Prefix(64));
229 Ipv6AddressHelper aAaBv6;
230 aAaBv6.SetBase(Ipv6Address("2001:1::"), Ipv6Prefix(64));
231 Ipv6AddressHelper aBaCv6;
232 aBaCv6.SetBase(Ipv6Address("2001:2::"), Ipv6Prefix(64));
233 Ipv6AddressHelper aCaDstv6;
234 aCaDstv6.SetBase(Ipv6Address("2001:3::"), Ipv6Prefix(64));
235 Ipv6AddressHelper aAaCv6;
236 aAaCv6.SetBase(Ipv6Address("2001:4::"), Ipv6Prefix(64));
237
238 aSrcaAv4.Assign(dSrcdA);
239 aAaBv4.Assign(dAdB);
240 aBaCv4.Assign(dBdC);
241 Ipv4InterfaceContainer iCiDstv4 = aCaDstv4.Assign(dCdDst);
242 Ipv4InterfaceContainer iAiCv4 = aAaCv4.Assign(dAdC);
243
244 aSrcaAv6.Assign(dSrcdA);
245 aAaBv6.Assign(dAdB);
246 aBaCv6.Assign(dBdC);
247 Ipv6InterfaceContainer iCiDstv6 = aCaDstv6.Assign(dCdDst);
248 Ipv6InterfaceContainer iAiCv6 = aAaCv6.Assign(dAdC);
249
250 // Create the UDP sockets
251 Ptr<SocketFactory> rxSocketFactory = nCnDst.Get(1)->GetObject<UdpSocketFactory>();
252 Ptr<Socket> rxSocketv4 = rxSocketFactory->CreateSocket();
253 Ptr<Socket> rxSocketv6 = rxSocketFactory->CreateSocket();
254 NS_TEST_EXPECT_MSG_EQ(rxSocketv4->Bind(InetSocketAddress(iCiDstv4.GetAddress(1), 1234)),
255 0,
256 "trivial");
257 NS_TEST_EXPECT_MSG_EQ(rxSocketv6->Bind(Inet6SocketAddress(iCiDstv6.GetAddress(1, 1), 1234)),
258 0,
259 "trivial");
260 rxSocketv4->SetRecvCallback(MakeCallback(&NixVectorRoutingTest::ReceivePkt, this));
261 rxSocketv6->SetRecvCallback(MakeCallback(&NixVectorRoutingTest::ReceivePkt, this));
262
263 Ptr<SocketFactory> txSocketFactory = nSrcnA.Get(0)->GetObject<UdpSocketFactory>();
264 Ptr<Socket> txSocket = txSocketFactory->CreateSocket();
265 txSocket->SetAllowBroadcast(true);
266
267 SendData(Seconds(2), txSocket, Ipv4Address("10.1.3.2"));
268 SendData(Seconds(2), txSocket, Ipv6Address("2001:3::200:ff:fe00:8"));
269
270 ipv4NixRouting.PrintRoutingPathAt(Seconds(3),
271 nSrcnA.Get(0),
272 iCiDstv4.GetAddress(1),
273 routingStream1v4);
274 ipv6NixRouting.PrintRoutingPathAt(Seconds(3),
275 nSrcnA.Get(0),
276 iCiDstv6.GetAddress(1, 1),
277 routingStream1v6);
278
279 // Set the IPv4 nA interface on nA - nC channel down.
280 Ptr<Ipv4> ipv4 = nAnC.Get(0)->GetObject<Ipv4>();
281 int32_t ifIndex = ipv4->GetInterfaceForDevice(dAdC.Get(0));
282 Simulator::Schedule(Seconds(5), &Ipv4::SetDown, ipv4, ifIndex);
283
284 // Set the IPv6 nA interface on nA - nC channel down.
285 Ptr<Ipv6> ipv6 = nAnC.Get(0)->GetObject<Ipv6>();
286 ifIndex = ipv6->GetInterfaceForDevice(dAdC.Get(0));
287 Simulator::Schedule(Seconds(5), &Ipv6::SetDown, ipv6, ifIndex);
288
289 Ipv4NixVectorHelper::PrintRoutingTableAllAt(Seconds(7), cacheStreamv4);
290 Ipv6NixVectorHelper::PrintRoutingTableAllAt(Seconds(7), cacheStreamv6);
291
292 SendData(Seconds(8), txSocket, Ipv4Address("10.1.3.2"));
293 SendData(Seconds(8), txSocket, Ipv6Address("2001:3::200:ff:fe00:8"));
294
295 ipv4NixRouting.PrintRoutingPathAt(Seconds(9),
296 nSrcnA.Get(0),
297 iCiDstv4.GetAddress(1),
298 routingStream3v4);
299 ipv6NixRouting.PrintRoutingPathAt(Seconds(9),
300 nSrcnA.Get(0),
301 iCiDstv6.GetAddress(1, 1),
302 routingStream3v6);
303
304 // Set the IPv4 nC interface on nB - nC channel down.
305 ipv4 = nBnC.Get(1)->GetObject<Ipv4>();
306 ifIndex = ipv4->GetInterfaceForDevice(dBdC.Get(1));
307 Simulator::Schedule(Seconds(10), &Ipv4::SetDown, ipv4, ifIndex);
308
309 // Set the IPv6 nC interface on nB - nC channel down.
310 ipv6 = nBnC.Get(1)->GetObject<Ipv6>();
311 ifIndex = ipv6->GetInterfaceForDevice(dBdC.Get(1));
312 Simulator::Schedule(Seconds(10), &Ipv6::SetDown, ipv6, ifIndex);
313
314 SendData(Seconds(11), txSocket, Ipv4Address("10.1.3.2"));
315 SendData(Seconds(11), txSocket, Ipv6Address("2001:3::200:ff:fe00:8"));
316
319
320 // ------ Now the tests ------------
321
322 // Test the Routing
323 NS_TEST_EXPECT_MSG_EQ(m_receivedPacketSizes[0], 123, "IPv4 Nix-Vector Routing should work.");
324 NS_TEST_EXPECT_MSG_EQ(m_receivedPacketSizes[1], 123, "IPv6 Nix-Vector Routing should work.");
326 4,
327 "IPv4 and IPv6 Nix-Vector Routing should have received only 1 packet.");
328
329 // Test the Path
330 const std::string p_nSrcnAnCnDstv4 =
331 "Time: +3s, Nix Routing\n"
332 "Route path from Node 0 to Node 4, Nix Vector: 01001 (5 bits left)\n"
333 "10.1.0.1 (Node 0) ----> 10.1.0.2 (Node 1)\n"
334 "10.1.4.1 (Node 1) ----> 10.1.4.2 (Node 3)\n"
335 "10.1.3.1 (Node 3) ----> 10.1.3.2 (Node 4)\n\n";
336 NS_TEST_EXPECT_MSG_EQ(stringStream1v4.str(), p_nSrcnAnCnDstv4, "Routing Path is incorrect.");
337
338 const std::string p_nSrcnAnCnDstv6 =
339 "Time: +3s, Nix Routing\n"
340 "Route path from Node 0 to Node 4, Nix Vector: 01001 (5 bits left)\n"
341 "2001::200:ff:fe00:1 (Node 0) ----> fe80::200:ff:fe00:2 (Node 1)\n"
342 "fe80::200:ff:fe00:9 (Node 1) ----> fe80::200:ff:fe00:a (Node 3)\n"
343 "fe80::200:ff:fe00:7 (Node 3) ----> 2001:3::200:ff:fe00:8 (Node 4)\n\n";
344 NS_TEST_EXPECT_MSG_EQ(stringStream1v6.str(), p_nSrcnAnCnDstv6, "Routing Path is incorrect.");
345
346 const std::string p_nSrcnAnBnCnDstv4 =
347 "Time: +9s, Nix Routing\n"
348 "Route path from Node 0 to Node 4, Nix Vector: 0111 (4 bits left)\n"
349 "10.1.0.1 (Node 0) ----> 10.1.0.2 (Node 1)\n"
350 "10.1.1.1 (Node 1) ----> 10.1.1.2 (Node 2)\n"
351 "10.1.2.1 (Node 2) ----> 10.1.2.2 (Node 3)\n"
352 "10.1.3.1 (Node 3) ----> 10.1.3.2 (Node 4)\n\n";
353 NS_TEST_EXPECT_MSG_EQ(stringStream3v4.str(), p_nSrcnAnBnCnDstv4, "Routing Path is incorrect.");
354
355 const std::string p_nSrcnAnBnCnDstv6 =
356 "Time: +9s, Nix Routing\n"
357 "Route path from Node 0 to Node 4, Nix Vector: 0111 (4 bits left)\n"
358 "2001::200:ff:fe00:1 (Node 0) ----> fe80::200:ff:fe00:2 (Node 1)\n"
359 "fe80::200:ff:fe00:3 (Node 1) ----> fe80::200:ff:fe00:4 (Node 2)\n"
360 "fe80::200:ff:fe00:5 (Node 2) ----> fe80::200:ff:fe00:6 (Node 3)\n"
361 "fe80::200:ff:fe00:7 (Node 3) ----> 2001:3::200:ff:fe00:8 (Node 4)\n\n";
362 NS_TEST_EXPECT_MSG_EQ(stringStream3v6.str(), p_nSrcnAnBnCnDstv6, "Routing Path is incorrect.");
363
364 const std::string emptyCaches = "Node: 0, Time: +7s, Local time: +7s, Nix Routing\n"
365 "NixCache:\n"
366 "IpRouteCache:\n\n"
367 "Node: 1, Time: +7s, Local time: +7s, Nix Routing\n"
368 "NixCache:\n"
369 "IpRouteCache:\n\n"
370 "Node: 2, Time: +7s, Local time: +7s, Nix Routing\n"
371 "NixCache:\n"
372 "IpRouteCache:\n\n"
373 "Node: 3, Time: +7s, Local time: +7s, Nix Routing\n"
374 "NixCache:\n"
375 "IpRouteCache:\n\n"
376 "Node: 4, Time: +7s, Local time: +7s, Nix Routing\n"
377 "NixCache:\n"
378 "IpRouteCache:\n\n";
379 NS_TEST_EXPECT_MSG_EQ(stringStream2v4.str(), emptyCaches, "The caches should have been empty.");
380 NS_TEST_EXPECT_MSG_EQ(stringStream2v6.str(), emptyCaches, "The caches should have been empty.");
381
383}
384
385/**
386 * \ingroup nix-vector-routing-test
387 * \ingroup tests
388 *
389 * \brief IPv4 Nix-Vector Routing TestSuite
390 */
392{
393 public:
395 : TestSuite("nix-vector-routing", Type::UNIT)
396 {
397 AddTestCase(new NixVectorRoutingTest(), TestCase::Duration::QUICK);
398 }
399};
400
401/// Static variable for test initialization
The topology is of the form:
Definition nix-test.cc:55
void DoSendDatav4(Ptr< Socket > socket, Ipv4Address to)
Send data immediately after being called.
Definition nix-test.cc:118
void DoRun() override
Implementation to actually run this TestCase.
Definition nix-test.cc:156
std::vector< uint32_t > m_receivedPacketSizes
Received packet sizes.
Definition nix-test.cc:98
Ptr< Packet > m_receivedPacket
Received packet.
Definition nix-test.cc:56
void ReceivePkt(Ptr< Socket > socket)
Receive data.
Definition nix-test.cc:107
void DoSendDatav6(Ptr< Socket > socket, Ipv6Address to)
Send data immediately after being called.
Definition nix-test.cc:125
void SendData(Time delay, Ptr< Socket > socket, Ipv4Address to)
Schedules the DoSendData () function to send the data.
Definition nix-test.cc:132
IPv4 Nix-Vector Routing TestSuite.
Definition nix-test.cc:392
a polymophic address class
Definition address.h:90
An Inet6 address class.
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
Ipv4 addresses are stored in host order in this class.
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition ipv4.h:69
virtual void SetDown(uint32_t interface)=0
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
Helper class to auto-assign global IPv6 unicast addresses.
void SetBase(Ipv6Address network, Ipv6Prefix prefix, Ipv6Address base=Ipv6Address("::1"))
Set the base network number, network prefix, and base interface ID.
Ipv6InterfaceContainer Assign(const NetDeviceContainer &c)
Allocate an Ipv6InterfaceContainer with auto-assigned addresses.
Describes an IPv6 address.
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition ipv6.h:71
virtual void SetDown(uint32_t interface)=0
Set the interface into the "down" state.
Keep track of a set of IPv6 interfaces.
Ipv6Address GetAddress(uint32_t i, uint32_t j) const
Get the address for the specified index.
Describes an IPv6 prefix.
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.
Helper class that adds Nix-vector routing to nodes.
void PrintRoutingPathAt(Time printTime, Ptr< Node > source, IpAddress dest, Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S)
prints the routing path for a source and destination at a particular time.
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.
void Add(const NodeContainer &nc)
Append the contents of another NodeContainer to the end of this container.
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
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition packet.h:850
Smart pointer class similar to boost::intrusive_ptr.
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 EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static void ScheduleWithContext(uint32_t context, const Time &delay, FUNC f, Ts &&... args)
Schedule an event with the given context.
Definition simulator.h:577
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
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 constexpr auto UNIT
Definition test.h:1291
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
API to create UDP socket instances.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
#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_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition test.h:241
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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:684
static NixVectorRoutingTestSuite g_nixVectorRoutingTestSuite
Static variable for test initialization.
Definition nix-test.cc:402