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 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Authors: Tommaso Pecorella <tommaso.pecorella@unifi.it>
18 *
19 */
20
21#include "ns3/data-rate.h"
22#include "ns3/internet-stack-helper.h"
23#include "ns3/ipv6-address-helper.h"
24#include "ns3/ipv6-route.h"
25#include "ns3/ipv6-routing-helper.h"
26#include "ns3/ipv6-routing-protocol.h"
27#include "ns3/radvd-helper.h"
28#include "ns3/simple-net-device-helper.h"
29#include "ns3/simple-net-device.h"
30#include "ns3/test.h"
31
32using namespace ns3;
33
34/**
35 * \ingroup radvd
36 * \defgroup radvd-test radvd tests
37 */
38
39/**
40 * \ingroup radvd-test
41 * \ingroup tests
42 *
43 * \brief radvd basic tests
44 */
45class RadvdTestCase : public TestCase
46{
47 public:
49 ~RadvdTestCase() override;
50
51 private:
52 void DoRun() override;
53
54 /**
55 * Checks the addresses on 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 * Checks the routing between the selected NetDevices.
67 * \param n0Dev node 0 device
68 * \param r0Dev router device toward node 0
69 * \param r1Dev router device toward node 1
70 * \param n1Dev node 1 device
71 */
73 Ptr<NetDevice> r0Dev,
74 Ptr<NetDevice> r1Dev,
75 Ptr<NetDevice> n1Dev);
76
77 std::vector<Ipv6Address> m_addresses; //!< Addresses on the nodes
78 std::vector<Socket::SocketErrno> m_routingResults; //!< Routing call return values
79 std::vector<Ptr<Ipv6Route>> m_routes; //!< Routing call results
80};
81
83 : TestCase("Radvd test case ")
84{
85}
86
88{
89}
90
91void
93 Ptr<NetDevice> r0Dev,
94 Ptr<NetDevice> r1Dev,
95 Ptr<NetDevice> n1Dev)
96{
98
99 ipv6 = n0Dev->GetNode()->GetObject<Ipv6L3Protocol>();
100 m_addresses.push_back(ipv6->GetAddress(ipv6->GetInterfaceForDevice(n0Dev), 1).GetAddress());
101
102 ipv6 = r0Dev->GetNode()->GetObject<Ipv6L3Protocol>();
103 m_addresses.push_back(ipv6->GetAddress(ipv6->GetInterfaceForDevice(r0Dev), 1).GetAddress());
104
105 ipv6 = r1Dev->GetNode()->GetObject<Ipv6L3Protocol>();
106 m_addresses.push_back(ipv6->GetAddress(ipv6->GetInterfaceForDevice(r1Dev), 1).GetAddress());
107
108 ipv6 = n1Dev->GetNode()->GetObject<Ipv6L3Protocol>();
109 m_addresses.push_back(ipv6->GetAddress(ipv6->GetInterfaceForDevice(n1Dev), 1).GetAddress());
110}
111
112void
114 Ptr<NetDevice> r0Dev,
115 Ptr<NetDevice> r1Dev,
116 Ptr<NetDevice> n1Dev)
117{
119 Ptr<Packet> p = Create<Packet>();
120 Ipv6Header ipHdr;
121 Socket::SocketErrno sockerr;
122 Ptr<Ipv6Route> route;
123
124 ipv6 = n0Dev->GetNode()->GetObject<Ipv6L3Protocol>();
125 ipHdr.SetSource(m_addresses[0]);
126 ipHdr.SetDestination(m_addresses[1]);
127 route = ipv6->GetRoutingProtocol()->RouteOutput(p, ipHdr, n0Dev, sockerr);
128 m_routingResults.push_back(sockerr);
129 m_routes.push_back(route);
130
131 ipv6 = r0Dev->GetNode()->GetObject<Ipv6L3Protocol>();
132 ipHdr.SetSource(m_addresses[1]);
133 ipHdr.SetDestination(m_addresses[0]);
134 route = ipv6->GetRoutingProtocol()->RouteOutput(p, ipHdr, r0Dev, sockerr);
135 m_routingResults.push_back(sockerr);
136 m_routes.push_back(route);
137
138 ipv6 = r1Dev->GetNode()->GetObject<Ipv6L3Protocol>();
139 ipHdr.SetSource(m_addresses[2]);
140 ipHdr.SetDestination(m_addresses[3]);
141 route = ipv6->GetRoutingProtocol()->RouteOutput(p, ipHdr, r1Dev, sockerr);
142 m_routingResults.push_back(sockerr);
143 m_routes.push_back(route);
144
145 ipv6 = n1Dev->GetNode()->GetObject<Ipv6L3Protocol>();
146 ipHdr.SetSource(m_addresses[3]);
147 ipHdr.SetDestination(m_addresses[2]);
148 route = ipv6->GetRoutingProtocol()->RouteOutput(p, ipHdr, n1Dev, sockerr);
149 m_routingResults.push_back(sockerr);
150 m_routes.push_back(route);
151}
152
153void
155{
156 // Create nodes
157 Ptr<Node> n0 = CreateObject<Node>();
158 Ptr<Node> r = CreateObject<Node>();
159 Ptr<Node> n1 = CreateObject<Node>();
160
161 NodeContainer net1(n0, r);
162 NodeContainer net2(r, n1);
163 NodeContainer all(n0, r, n1);
164
165 // Create IPv6 Internet Stack
166 InternetStackHelper internetv6;
167 internetv6.Install(all);
168
169 // Create channels
170 SimpleNetDeviceHelper simpleNetDevice;
171 simpleNetDevice.SetChannelAttribute("Delay", TimeValue(MilliSeconds(2)));
172 simpleNetDevice.SetDeviceAttribute("DataRate", DataRateValue(DataRate("5Mbps")));
173
174 NetDeviceContainer d1 = simpleNetDevice.Install(net1); /* n0 - R */
175 NetDeviceContainer d2 = simpleNetDevice.Install(net2); /* R - n1 */
176
177 // Create networks and assign IPv6 Addresses
179
180 /* first subnet */
181 ipv6.SetBase(Ipv6Address("2001:1::"), Ipv6Prefix(64));
183 tmp.Add(d1.Get(0)); /* n0 */
184 Ipv6InterfaceContainer iic1 = ipv6.AssignWithoutAddress(tmp); /* n0 interface */
185
187 tmp2.Add(d1.Get(1)); /* R */
189 tmp2); /* R interface to the first subnet is just statically assigned */
190 iicr1.SetForwarding(0, true);
191 iic1.Add(iicr1);
192
193 /* second subnet R - n1 */
194 ipv6.SetBase(Ipv6Address("2001:2::"), Ipv6Prefix(64));
196 tmp3.Add(d2.Get(0)); /* R */
197 Ipv6InterfaceContainer iicr2 = ipv6.Assign(tmp3); /* R interface */
198 iicr2.SetForwarding(0, true);
199
201 tmp4.Add(d2.Get(1)); /* n1 */
203 iic2.Add(iicr2);
204
205 /* radvd configuration */
206 RadvdHelper radvdHelper;
207
208 /* R interface (n0 - R) */
209 /* n0 will receive unsolicited (periodic) RA */
210 radvdHelper.AddAnnouncedPrefix(iic1.GetInterfaceIndex(1), Ipv6Address("2001:1::0"), 64);
211 Ptr<RadvdPrefix> prefix =
212 *(radvdHelper.GetRadvdInterface(iic1.GetInterfaceIndex(1))->GetPrefixes().begin());
213 prefix->SetOnLinkFlag(false);
214
215 /* R interface (R - n1) */
216 /* n1 will have to use RS, as RA are not sent automatically */
217 radvdHelper.AddAnnouncedPrefix(iic2.GetInterfaceIndex(1), Ipv6Address("2001:2::0"), 64);
218 radvdHelper.GetRadvdInterface(iic2.GetInterfaceIndex(1))->SetSendAdvert(false);
219
220 ApplicationContainer radvdApps = radvdHelper.Install(r);
221 radvdApps.Start(Seconds(1.0));
222 radvdApps.Stop(Seconds(10.0));
223
226 this,
227 d1.Get(0),
228 d1.Get(1),
229 d2.Get(0),
230 d2.Get(1));
233 this,
234 d1.Get(0),
235 d1.Get(1),
236 d2.Get(0),
237 d2.Get(1));
238
240
242
243 // Address assignment checks
245 Ipv6Address("2001:1::200:ff:fe00:1"),
246 m_addresses[0] << " instead of "
247 << "2001:1::200:ff:fe00:1");
248
250 Ipv6Address("2001:1::200:ff:fe00:2"),
251 m_addresses[1] << " instead of "
252 << "2001:1::200:ff:fe00:2");
253
255 Ipv6Address("2001:2::200:ff:fe00:3"),
256 m_addresses[2] << " instead of "
257 << "2001:2::200:ff:fe00:3");
258
260 Ipv6Address("2001:2::200:ff:fe00:4"),
261 m_addresses[3] << " instead of "
262 << "2001:2::200:ff:fe00:4");
263
264 // Routes checks
267 (int)m_routingResults[0] << " instead of Socket::ERROR_NOTERROR");
268
269 NS_TEST_ASSERT_MSG_EQ(m_routes[0]->GetGateway(),
270 Ipv6Address("fe80::200:ff:fe00:2"),
271 m_routes[0]->GetGateway() << " instead of "
272 << "fe80::200:ff:fe00:2");
273
276 (int)m_routingResults[1] << " instead of Socket::ERROR_NOROUTETOHOST");
277
280 (int)m_routingResults[2] << " instead of Socket::ERROR_NOTERROR");
281
282 NS_TEST_ASSERT_MSG_EQ(m_routes[2]->GetGateway(),
283 Ipv6Address("::"),
284 m_routes[2]->GetGateway() << " instead of "
285 << "::");
286
289 (int)m_routingResults[3] << " instead of Socket::ERROR_NOTERROR");
290
291 NS_TEST_ASSERT_MSG_EQ(m_routes[3]->GetGateway(),
292 Ipv6Address("::"),
293 m_routes[3]->GetGateway() << " instead of "
294 << "::");
295
297}
298
299/**
300 * \ingroup radvd-test
301 * \ingroup tests
302 *
303 * \brief radvd TestSuite
304 */
306{
307 public:
309};
310
312 : TestSuite("radvd", Type::UNIT)
313{
314 AddTestCase(new RadvdTestCase, TestCase::Duration::QUICK);
315}
316
317static 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:89
AttributeValue implementation for DataRate.
Definition: data-rate.h:296
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.
Definition: ipv6-address.h:49
Packet header for IPv6.
Definition: ipv6-header.h:35
void SetDestination(Ipv6Address dst)
Set the "Destination address" field.
Definition: ipv6-header.cc:118
void SetSource(Ipv6Address src)
Set the "Source address" field.
Definition: ipv6-header.cc:106
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.
Definition: ipv6-address.h:455
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.
Definition: ptr.h:77
Radvd application helper.
Definition: radvd-helper.h:37
void AddAnnouncedPrefix(uint32_t interface, const Ipv6Address &prefix, uint32_t prefixLength)
Add a new prefix to be announced through an interface.
Definition: radvd-helper.cc:39
Ptr< RadvdInterface > GetRadvdInterface(uint32_t interface)
Get the low-level RadvdInterface specification for an interface.
Definition: radvd-helper.cc:99
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:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:84
@ ERROR_NOROUTETOHOST
Definition: socket.h:95
@ ERROR_NOTERROR
Definition: socket.h:85
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
AttributeValue implementation for Time.
Definition: nstime.h:1413
#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:145
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
static RadvdTestSuite radvdTestSuite
Static variable for test initialization.
Every class exported by the ns3 library is enclosed in the ns3 namespace.