A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ipv6-radvd-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2021 Universita' di Firenze, Italy
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Tommaso Pecorella <tommaso.pecorella@unifi.it>
7 *
8 */
9
10#include "ns3/data-rate.h"
11#include "ns3/internet-stack-helper.h"
12#include "ns3/ipv6-address-helper.h"
13#include "ns3/ipv6-route.h"
14#include "ns3/ipv6-routing-helper.h"
15#include "ns3/ipv6-routing-protocol.h"
16#include "ns3/radvd-helper.h"
17#include "ns3/simple-net-device-helper.h"
18#include "ns3/simple-net-device.h"
19#include "ns3/test.h"
20
21using namespace ns3;
22
23/**
24 * \ingroup radvd
25 * \defgroup radvd-test radvd tests
26 */
27
28/**
29 * \ingroup radvd-test
30 * \ingroup tests
31 *
32 * \brief radvd basic tests
33 */
34class RadvdTestCase : public TestCase
35{
36 public:
38 ~RadvdTestCase() override;
39
40 private:
41 void DoRun() override;
42
43 /**
44 * Checks the addresses on the selected NetDevices.
45 * \param n0Dev node 0 device
46 * \param r0Dev router device toward node 0
47 * \param r1Dev router device toward node 1
48 * \param n1Dev node 1 device
49 */
51 Ptr<NetDevice> r0Dev,
52 Ptr<NetDevice> r1Dev,
53 Ptr<NetDevice> n1Dev);
54 /**
55 * Checks the routing between the selected NetDevices.
56 * \param n0Dev node 0 device
57 * \param r0Dev router device toward node 0
58 * \param r1Dev router device toward node 1
59 * \param n1Dev node 1 device
60 */
62 Ptr<NetDevice> r0Dev,
63 Ptr<NetDevice> r1Dev,
64 Ptr<NetDevice> n1Dev);
65
66 std::vector<Ipv6Address> m_addresses; //!< Addresses on the nodes
67 std::vector<Socket::SocketErrno> m_routingResults; //!< Routing call return values
68 std::vector<Ptr<Ipv6Route>> m_routes; //!< Routing call results
69};
70
72 : TestCase("Radvd test case ")
73{
74}
75
79
80void
82 Ptr<NetDevice> r0Dev,
83 Ptr<NetDevice> r1Dev,
84 Ptr<NetDevice> n1Dev)
85{
87
88 ipv6 = n0Dev->GetNode()->GetObject<Ipv6L3Protocol>();
89 m_addresses.push_back(ipv6->GetAddress(ipv6->GetInterfaceForDevice(n0Dev), 1).GetAddress());
90
91 ipv6 = r0Dev->GetNode()->GetObject<Ipv6L3Protocol>();
92 m_addresses.push_back(ipv6->GetAddress(ipv6->GetInterfaceForDevice(r0Dev), 1).GetAddress());
93
94 ipv6 = r1Dev->GetNode()->GetObject<Ipv6L3Protocol>();
95 m_addresses.push_back(ipv6->GetAddress(ipv6->GetInterfaceForDevice(r1Dev), 1).GetAddress());
96
97 ipv6 = n1Dev->GetNode()->GetObject<Ipv6L3Protocol>();
98 m_addresses.push_back(ipv6->GetAddress(ipv6->GetInterfaceForDevice(n1Dev), 1).GetAddress());
99}
100
101void
103 Ptr<NetDevice> r0Dev,
104 Ptr<NetDevice> r1Dev,
105 Ptr<NetDevice> n1Dev)
106{
109 Ipv6Header ipHdr;
110 Socket::SocketErrno sockerr;
111 Ptr<Ipv6Route> route;
112
113 ipv6 = n0Dev->GetNode()->GetObject<Ipv6L3Protocol>();
114 ipHdr.SetSource(m_addresses[0]);
115 ipHdr.SetDestination(m_addresses[1]);
116 route = ipv6->GetRoutingProtocol()->RouteOutput(p, ipHdr, n0Dev, sockerr);
117 m_routingResults.push_back(sockerr);
118 m_routes.push_back(route);
119
120 ipv6 = r0Dev->GetNode()->GetObject<Ipv6L3Protocol>();
121 ipHdr.SetSource(m_addresses[1]);
122 ipHdr.SetDestination(m_addresses[0]);
123 route = ipv6->GetRoutingProtocol()->RouteOutput(p, ipHdr, r0Dev, sockerr);
124 m_routingResults.push_back(sockerr);
125 m_routes.push_back(route);
126
127 ipv6 = r1Dev->GetNode()->GetObject<Ipv6L3Protocol>();
128 ipHdr.SetSource(m_addresses[2]);
129 ipHdr.SetDestination(m_addresses[3]);
130 route = ipv6->GetRoutingProtocol()->RouteOutput(p, ipHdr, r1Dev, sockerr);
131 m_routingResults.push_back(sockerr);
132 m_routes.push_back(route);
133
134 ipv6 = n1Dev->GetNode()->GetObject<Ipv6L3Protocol>();
135 ipHdr.SetSource(m_addresses[3]);
136 ipHdr.SetDestination(m_addresses[2]);
137 route = ipv6->GetRoutingProtocol()->RouteOutput(p, ipHdr, n1Dev, sockerr);
138 m_routingResults.push_back(sockerr);
139 m_routes.push_back(route);
140}
141
142void
144{
145 // Create nodes
149
150 NodeContainer net1(n0, r);
151 NodeContainer net2(r, n1);
152 NodeContainer all(n0, r, n1);
153
154 // Create IPv6 Internet Stack
155 InternetStackHelper internetv6;
156 internetv6.Install(all);
157
158 // Create channels
159 SimpleNetDeviceHelper simpleNetDevice;
160 simpleNetDevice.SetChannelAttribute("Delay", TimeValue(MilliSeconds(2)));
161 simpleNetDevice.SetDeviceAttribute("DataRate", DataRateValue(DataRate("5Mbps")));
162
163 NetDeviceContainer d1 = simpleNetDevice.Install(net1); /* n0 - R */
164 NetDeviceContainer d2 = simpleNetDevice.Install(net2); /* R - n1 */
165
166 // Create networks and assign IPv6 Addresses
168
169 /* first subnet */
170 ipv6.SetBase(Ipv6Address("2001:1::"), Ipv6Prefix(64));
172 tmp.Add(d1.Get(0)); /* n0 */
173 Ipv6InterfaceContainer iic1 = ipv6.AssignWithoutAddress(tmp); /* n0 interface */
174
176 tmp2.Add(d1.Get(1)); /* R */
178 tmp2); /* R interface to the first subnet is just statically assigned */
179 iicr1.SetForwarding(0, true);
180 iic1.Add(iicr1);
181
182 /* second subnet R - n1 */
183 ipv6.SetBase(Ipv6Address("2001:2::"), Ipv6Prefix(64));
185 tmp3.Add(d2.Get(0)); /* R */
186 Ipv6InterfaceContainer iicr2 = ipv6.Assign(tmp3); /* R interface */
187 iicr2.SetForwarding(0, true);
188
190 tmp4.Add(d2.Get(1)); /* n1 */
192 iic2.Add(iicr2);
193
194 /* radvd configuration */
195 RadvdHelper radvdHelper;
196
197 /* R interface (n0 - R) */
198 /* n0 will receive unsolicited (periodic) RA */
199 radvdHelper.AddAnnouncedPrefix(iic1.GetInterfaceIndex(1), Ipv6Address("2001:1::0"), 64);
200 Ptr<RadvdPrefix> prefix =
201 *(radvdHelper.GetRadvdInterface(iic1.GetInterfaceIndex(1))->GetPrefixes().begin());
202 prefix->SetOnLinkFlag(false);
203
204 /* R interface (R - n1) */
205 /* n1 will have to use RS, as RA are not sent automatically */
206 radvdHelper.AddAnnouncedPrefix(iic2.GetInterfaceIndex(1), Ipv6Address("2001:2::0"), 64);
207 radvdHelper.GetRadvdInterface(iic2.GetInterfaceIndex(1))->SetSendAdvert(false);
208
209 ApplicationContainer radvdApps = radvdHelper.Install(r);
210 radvdApps.Start(Seconds(1.0));
211 radvdApps.Stop(Seconds(10.0));
212
215 this,
216 d1.Get(0),
217 d1.Get(1),
218 d2.Get(0),
219 d2.Get(1));
222 this,
223 d1.Get(0),
224 d1.Get(1),
225 d2.Get(0),
226 d2.Get(1));
227
229
231
232 // Address assignment checks
234 Ipv6Address("2001:1::200:ff:fe00:1"),
235 m_addresses[0] << " instead of "
236 << "2001:1::200:ff:fe00:1");
237
239 Ipv6Address("2001:1::200:ff:fe00:2"),
240 m_addresses[1] << " instead of "
241 << "2001:1::200:ff:fe00:2");
242
244 Ipv6Address("2001:2::200:ff:fe00:3"),
245 m_addresses[2] << " instead of "
246 << "2001:2::200:ff:fe00:3");
247
249 Ipv6Address("2001:2::200:ff:fe00:4"),
250 m_addresses[3] << " instead of "
251 << "2001:2::200:ff:fe00:4");
252
253 // Routes checks
256 (int)m_routingResults[0] << " instead of Socket::ERROR_NOTERROR");
257
258 NS_TEST_ASSERT_MSG_EQ(m_routes[0]->GetGateway(),
259 Ipv6Address("fe80::200:ff:fe00:2"),
260 m_routes[0]->GetGateway() << " instead of "
261 << "fe80::200:ff:fe00:2");
262
265 (int)m_routingResults[1] << " instead of Socket::ERROR_NOROUTETOHOST");
266
269 (int)m_routingResults[2] << " instead of Socket::ERROR_NOTERROR");
270
271 NS_TEST_ASSERT_MSG_EQ(m_routes[2]->GetGateway(),
272 Ipv6Address("::"),
273 m_routes[2]->GetGateway() << " instead of "
274 << "::");
275
278 (int)m_routingResults[3] << " instead of Socket::ERROR_NOTERROR");
279
280 NS_TEST_ASSERT_MSG_EQ(m_routes[3]->GetGateway(),
281 Ipv6Address("::"),
282 m_routes[3]->GetGateway() << " instead of "
283 << "::");
284
286}
287
288/**
289 * \ingroup radvd-test
290 * \ingroup tests
291 *
292 * \brief radvd TestSuite
293 */
295{
296 public:
298};
299
301 : TestSuite("radvd", Type::UNIT)
302{
303 AddTestCase(new RadvdTestCase, TestCase::Duration::QUICK);
304}
305
306static RadvdTestSuite radvdTestSuite; //!< Static variable for test initialization
radvd basic tests
void CheckRouting(Ptr< NetDevice > n0Dev, Ptr< NetDevice > r0Dev, Ptr< NetDevice > r1Dev, Ptr< NetDevice > n1Dev)
Checks the routing between the selected NetDevices.
std::vector< Ipv6Address > m_addresses
Addresses on the nodes.
std::vector< Socket::SocketErrno > m_routingResults
Routing call return values.
void DoRun() override
Implementation to actually run this TestCase.
void CheckAddresses(Ptr< NetDevice > n0Dev, Ptr< NetDevice > r0Dev, Ptr< NetDevice > r1Dev, Ptr< NetDevice > n1Dev)
Checks the addresses on the selected NetDevices.
~RadvdTestCase() override
std::vector< Ptr< Ipv6Route > > m_routes
Routing call results.
radvd TestSuite
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
ApplicationContainer Install(NodeContainer c)
Install an application on each node of the input container configured with all the attributes set wit...
Class for representing data rates.
Definition data-rate.h:78
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...
Helper class to auto-assign global IPv6 unicast addresses.
Ipv6InterfaceContainer AssignWithoutAddress(const NetDeviceContainer &c)
Allocate an Ipv6InterfaceContainer but do not assign any IPv6 addresses.
void SetBase(Ipv6Address network, Ipv6Prefix prefix, Ipv6Address base=Ipv6Address("::1"))
Set the base network number, network prefix, and base interface ID.
Ipv6InterfaceContainer AssignWithoutOnLink(const NetDeviceContainer &c)
Allocate an Ipv6InterfaceContainer with auto-assigned addresses, but do not set the on-link property ...
Ipv6InterfaceContainer Assign(const NetDeviceContainer &c)
Allocate an Ipv6InterfaceContainer with auto-assigned addresses.
Describes an IPv6 address.
Packet header for IPv6.
Definition ipv6-header.h:24
void SetDestination(Ipv6Address dst)
Set the "Destination address" field.
void SetSource(Ipv6Address src)
Set the "Source address" field.
Keep track of a set of IPv6 interfaces.
void SetForwarding(uint32_t i, bool state)
Set the state of the stack (act as a router or as an host) for the specified index.
uint32_t GetInterfaceIndex(uint32_t i) const
Get the interface index for the specified node index.
void Add(Ptr< Ipv6 > ipv6, uint32_t interface)
Add a couple IPv6/interface.
IPv6 layer implementation.
Describes an IPv6 prefix.
holds a vector of ns3::NetDevice pointers
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
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.
Radvd application helper.
void AddAnnouncedPrefix(uint32_t interface, const Ipv6Address &prefix, uint32_t prefixLength)
Add a new prefix to be announced through an interface.
Ptr< RadvdInterface > GetRadvdInterface(uint32_t interface)
Get the low-level RadvdInterface specification for an interface.
RadvdPrefixList GetPrefixes() const
Get list of prefixes advertised for this interface.
build a set of SimpleNetDevice objects
void SetChannelAttribute(std::string n1, const AttributeValue &v1)
void SetDeviceAttribute(std::string n1, const AttributeValue &v1)
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 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
@ ERROR_NOROUTETOHOST
Definition socket.h:84
@ ERROR_NOTERROR
Definition socket.h:74
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
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: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
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1320
static RadvdTestSuite radvdTestSuite
Static variable for test initialization.
Every class exported by the ns3 library is enclosed in the ns3 namespace.