5G-LENA nr-v3.3-67-g8257369a
The 5G/NR module for the ns-3 simulator
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
nr-test-ipv6-routing.cc
1/*
2 * Copyright (c) 2017 Jadavpur University, India
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Manoj Kumar Rana <manoj24.rana@gmail.com>
7 */
8
9#include "ns3/config-store.h"
10#include "ns3/core-module.h"
11#include "ns3/internet-module.h"
12#include "ns3/ipv4-global-routing-helper.h"
13#include "ns3/ipv6-static-routing.h"
14#include "ns3/mobility-module.h"
15#include "ns3/network-module.h"
16#include "ns3/nr-epc-helper.h"
17#include "ns3/nr-helper.h"
18#include "ns3/nr-module.h"
19#include "ns3/point-to-point-helper.h"
20#include "ns3/udp-echo-helper.h"
21
22#include <algorithm>
23
24/* *
25 * Scenario: 3 UEs, 2 ENBs, 1 Remote Host, UE0<-->gNB0, UE1<-->gNB0, UE2<-->gNB1
26 Servers: UE1, UE2, Remote Host
27 Client: UE0 (3 clients)
28 UDP Echo Packets transmitted between client and server
29
30 * Pass criteria: 1) Every UDP Echo Request and Reply messages sent and received respectively
31 at UE0 must be matched by their UID, source address, destination address,
32 source port and destination port
33 2) Every request reply must follow proper route (e.g. In case of UE0->UE1,
34 packet must travel this route:
35UE0->gNB0->PGW->gNB1->UE1->gNB1->PGW->gNB0->UE0) 3) The above check also ensures no redundancy of
36the followed route for a packet
37* */
38
39using namespace ns3;
40
46class NrIpv6RoutingTestCase : public TestCase
47{
48 public:
49 NrIpv6RoutingTestCase();
50 ~NrIpv6RoutingTestCase() override;
51
55 void Checker();
56
63 void SentAtClient(Ptr<const Packet> p, Ptr<Ipv6> ipv6, uint32_t interface);
64
71 void ReceivedAtClient(Ptr<const Packet> p, Ptr<Ipv6> ipv6, uint32_t interface);
72
77 void GnbToPgw(Ptr<Packet> p);
78
83 void TunToPgw(Ptr<Packet> p);
84
85 private:
86 void DoRun() override;
87 Ipv6InterfaceContainer m_ueIpIface;
88 Ipv6Address m_remoteHostAddr;
89 std::list<uint64_t> m_pgwUidRxFrmGnb;
90 std::list<uint64_t>
91 m_pgwUidRxFrmTun;
92
93 std::list<Ptr<Packet>> m_clientTxPkts;
94 std::list<Ptr<Packet>> m_clientRxPkts;
95};
96
97NrIpv6RoutingTestCase::NrIpv6RoutingTestCase()
98 : TestCase("Test IPv6 Routing at LTE")
99{
100}
101
102NrIpv6RoutingTestCase::~NrIpv6RoutingTestCase()
103{
104}
105
106void
107NrIpv6RoutingTestCase::SentAtClient(Ptr<const Packet> p, Ptr<Ipv6> ipv6, uint32_t interface)
108{
109 Ipv6Header ipv6Header;
110 p->PeekHeader(ipv6Header);
111 if (ipv6Header.GetNextHeader() == UdpL4Protocol::PROT_NUMBER)
112 {
113 m_clientTxPkts.push_back(p->Copy());
114 }
115}
116
117void
118NrIpv6RoutingTestCase::ReceivedAtClient(Ptr<const Packet> p, Ptr<Ipv6> ipv6, uint32_t interface)
119{
120 Ipv6Header ipv6Header;
121 p->PeekHeader(ipv6Header);
122 if (ipv6Header.GetNextHeader() == UdpL4Protocol::PROT_NUMBER)
123 {
124 m_clientRxPkts.push_back(p->Copy());
125 }
126}
127
128void
129NrIpv6RoutingTestCase::GnbToPgw(Ptr<Packet> p)
130{
131 Ipv6Header ipv6Header;
132 p->PeekHeader(ipv6Header);
133 if (ipv6Header.GetNextHeader() == UdpL4Protocol::PROT_NUMBER)
134 {
135 m_pgwUidRxFrmGnb.push_back(p->GetUid());
136 }
137}
138
139void
140NrIpv6RoutingTestCase::TunToPgw(Ptr<Packet> p)
141{
142 Ipv6Header ipv6Header;
143 p->PeekHeader(ipv6Header);
144 if (ipv6Header.GetNextHeader() == UdpL4Protocol::PROT_NUMBER)
145 {
146 m_pgwUidRxFrmTun.push_back(p->GetUid());
147 }
148}
149
150void
151NrIpv6RoutingTestCase::Checker()
152{
153 bool b = false;
154 bool check = true;
155 // Extract each received reply packet of the client
156 for (auto it1 = m_clientRxPkts.begin(); it1 != m_clientRxPkts.end(); it1++)
157 {
158 Ipv6Header ipv6header1;
159 UdpHeader udpHeader1;
160 Ptr<Packet> p1 = (*it1)->Copy();
161 p1->RemoveHeader(ipv6header1);
162 uint64_t uid = p1->GetUid();
163 p1->RemoveHeader(udpHeader1);
164 // Search each packet in list of sent request packet of the client
165 for (auto it2 = m_clientTxPkts.begin(); it2 != m_clientTxPkts.end(); it2++)
166 {
167 Ptr<Packet> p2 = (*it2)->Copy();
168 Ipv6Header ipv6header2;
169 p2->RemoveHeader(ipv6header2);
170 Ipv6Address sourceAddress = ipv6header2.GetSource();
171 Ipv6Address destinationAddress = ipv6header2.GetDestination();
172 UdpHeader udpHeader2;
173 p2->RemoveHeader(udpHeader2);
174 uint16_t sourcePort;
175 uint16_t destinationPort;
176 sourcePort = udpHeader2.GetSourcePort();
177 destinationPort = udpHeader2.GetDestinationPort();
178 // Check whether the uids, addresses and ports match
179 if ((p2->GetUid() == p1->GetUid()) && sourceAddress == ipv6header1.GetDestination() &&
180 destinationAddress == ipv6header1.GetSource() &&
181 sourcePort == udpHeader1.GetDestinationPort() &&
182 destinationPort == udpHeader1.GetSourcePort())
183 {
184 b = true;
185 break;
186 }
187 }
188 check &= b;
189 if (std::find(m_pgwUidRxFrmGnb.begin(), m_pgwUidRxFrmGnb.end(), uid) !=
190 m_pgwUidRxFrmGnb.end())
191 {
192 check &= true;
193 m_pgwUidRxFrmGnb.remove(uid);
194 }
195 if (std::find(m_pgwUidRxFrmTun.begin(), m_pgwUidRxFrmTun.end(), uid) !=
196 m_pgwUidRxFrmTun.end())
197 {
198 check &= true;
199 m_pgwUidRxFrmTun.remove(uid);
200 }
201 b = false;
202 }
203
204 NS_TEST_ASSERT_MSG_EQ(check, true, "Failure Happens IPv6 routing of LENA");
205 NS_TEST_ASSERT_MSG_EQ(m_clientTxPkts.size(),
206 m_clientRxPkts.size(),
207 "No. of Request and Reply messages mismatch");
208 NS_TEST_ASSERT_MSG_EQ(m_pgwUidRxFrmGnb.size(), 0, "Route is not Redundant in Nr IPv6 test");
209 NS_TEST_ASSERT_MSG_EQ(m_pgwUidRxFrmTun.size(), 0, "Route is not Redundant in Nr IPv6 test");
210}
211
212void
213NrIpv6RoutingTestCase::DoRun()
214{
215 double distance = 60.0;
216
217 Ptr<NrHelper> nrHelper = CreateObject<NrHelper>();
218 Ptr<NrPointToPointEpcHelper> nrEpcHelper = CreateObject<NrPointToPointEpcHelper>();
219 nrHelper->SetEpcHelper(nrEpcHelper);
220
221 ConfigStore inputConfig;
222 inputConfig.ConfigureDefaults();
223
224 Ptr<Node> pgw = nrEpcHelper->GetPgwNode();
225
226 // Create a single RemoteHost
227 NodeContainer remoteHostContainer;
228 remoteHostContainer.Create(1);
229 Ptr<Node> remoteHost = remoteHostContainer.Get(0);
230 InternetStackHelper internet;
231 internet.Install(remoteHostContainer);
232
233 // Create the Internet
234 PointToPointHelper p2ph;
235 p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s")));
236 p2ph.SetDeviceAttribute("Mtu", UintegerValue(1500));
237 p2ph.SetChannelAttribute("Delay", TimeValue(Seconds(0.010)));
238 NetDeviceContainer internetDevices = p2ph.Install(pgw, remoteHost);
239
240 NodeContainer ueNodes;
241 NodeContainer gnbNodes;
242 gnbNodes.Create(2);
243 ueNodes.Create(3);
244
245 // Install Mobility Model
246 Ptr<ListPositionAllocator> positionAlloc1 = CreateObject<ListPositionAllocator>();
247 Ptr<ListPositionAllocator> positionAlloc2 = CreateObject<ListPositionAllocator>();
248
249 positionAlloc1->Add(Vector(distance * 0, 0, 0));
250 positionAlloc1->Add(Vector(distance * 0 + 5, 0, 0));
251 positionAlloc1->Add(Vector(distance * 1, 0, 0));
252
253 positionAlloc2->Add(Vector(distance * 0, 0.1, 0));
254 positionAlloc2->Add(Vector(distance * 1, 0.1, 0));
255
256 MobilityHelper mobility;
257 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
258 mobility.SetPositionAllocator(positionAlloc1);
259 mobility.Install(ueNodes);
260
261 mobility.SetPositionAllocator(positionAlloc2);
262 mobility.Install(gnbNodes);
263
264 // Install the IP stack on the UEs
265 internet.Install(ueNodes);
266
267 // Create bandwidth part
268 auto bandwidthAndBWPPair = nrHelper->CreateBandwidthParts({{2.8e9, 5e6, 1}}, "UMa");
269
270 // Install NR Devices to the nodes
271 NetDeviceContainer nrGnbDevs = nrHelper->InstallGnbDevice(gnbNodes, bandwidthAndBWPPair.second);
272 NetDeviceContainer ueNrDevs = nrHelper->InstallUeDevice(ueNodes, bandwidthAndBWPPair.second);
273
274 // Assign IP address to UEs, and install applications
275 m_ueIpIface = nrEpcHelper->AssignUeIpv6Address(NetDeviceContainer(ueNrDevs));
276
277 Ipv6StaticRoutingHelper ipv6RoutingHelper;
278
279 for (uint32_t u = 0; u < ueNodes.GetN(); ++u)
280 {
281 Ptr<Node> ueNode = ueNodes.Get(u);
282 // Set the default gateway for the UE
283 Ptr<Ipv6StaticRouting> ueStaticRouting =
284 ipv6RoutingHelper.GetStaticRouting(ueNode->GetObject<Ipv6>());
285 ueStaticRouting->SetDefaultRoute(nrEpcHelper->GetUeDefaultGatewayAddress6(), 1);
286 }
287
288 // Attach two UEs at first eNodeB and one UE at second eNodeB
289 nrHelper->AttachToGnb(ueNrDevs.Get(0), nrGnbDevs.Get(0));
290 nrHelper->AttachToGnb(ueNrDevs.Get(1), nrGnbDevs.Get(0));
291 nrHelper->AttachToGnb(ueNrDevs.Get(2), nrGnbDevs.Get(1));
292
293 Ipv6AddressHelper ipv6h;
294 ipv6h.SetBase(Ipv6Address("6001:db80::"), Ipv6Prefix(64));
295 Ipv6InterfaceContainer internetIpIfaces = ipv6h.Assign(internetDevices);
296
297 internetIpIfaces.SetForwarding(0, true);
298 internetIpIfaces.SetDefaultRouteInAllNodes(0);
299
300 Ptr<Ipv6StaticRouting> remoteHostStaticRouting =
301 ipv6RoutingHelper.GetStaticRouting(remoteHost->GetObject<Ipv6>());
302 remoteHostStaticRouting
303 ->AddNetworkRouteTo("7777:f00d::", Ipv6Prefix(64), internetIpIfaces.GetAddress(0, 1), 1, 0);
304
305 // interface 0 is localhost, 1 is the p2p device
306 m_remoteHostAddr = internetIpIfaces.GetAddress(1, 1);
307
308 // Install and start applications on UEs and remote host
309 UdpEchoServerHelper echoServer1(10);
310 UdpEchoServerHelper echoServer2(11);
311 UdpEchoServerHelper echoServer3(12);
312
313 ApplicationContainer serverApps = echoServer1.Install(remoteHost);
314 serverApps.Add(echoServer2.Install(ueNodes.Get(1)));
315 serverApps.Add(echoServer3.Install(ueNodes.Get(2)));
316
317 serverApps.Start(Seconds(4.0));
318 serverApps.Stop(Seconds(12.0));
319
320 UdpEchoClientHelper echoClient1(m_remoteHostAddr, 10);
321 UdpEchoClientHelper echoClient2(m_ueIpIface.GetAddress(1, 1), 11);
322 UdpEchoClientHelper echoClient3(m_ueIpIface.GetAddress(2, 1), 12);
323
324 echoClient1.SetAttribute("MaxPackets", UintegerValue(1000));
325 echoClient1.SetAttribute("Interval", TimeValue(Seconds(0.2)));
326 echoClient1.SetAttribute("PacketSize", UintegerValue(1024));
327
328 echoClient2.SetAttribute("MaxPackets", UintegerValue(1000));
329 echoClient2.SetAttribute("Interval", TimeValue(Seconds(0.2)));
330 echoClient2.SetAttribute("PacketSize", UintegerValue(1024));
331
332 echoClient3.SetAttribute("MaxPackets", UintegerValue(1000));
333 echoClient3.SetAttribute("Interval", TimeValue(Seconds(0.2)));
334 echoClient3.SetAttribute("PacketSize", UintegerValue(1024));
335
336 ApplicationContainer clientApps1 = echoClient1.Install(ueNodes.Get(0));
337 ApplicationContainer clientApps2 = echoClient2.Install(ueNodes.Get(0));
338 ApplicationContainer clientApps3 = echoClient3.Install(ueNodes.Get(0));
339
340 clientApps1.Start(Seconds(4.0));
341 clientApps1.Stop(Seconds(6.0));
342
343 clientApps2.Start(Seconds(6.1));
344 clientApps2.Stop(Seconds(8.0));
345
346 clientApps3.Start(Seconds(8.1));
347 clientApps3.Stop(Seconds(10.0));
348
349 // Set Cllback for Client Sent and Received packets
350 Ptr<Ipv6L3Protocol> ipL3 = (ueNodes.Get(0))->GetObject<Ipv6L3Protocol>();
351 ipL3->TraceConnectWithoutContext("Tx",
352 MakeCallback(&NrIpv6RoutingTestCase::SentAtClient, this));
353 ipL3->TraceConnectWithoutContext("Rx",
354 MakeCallback(&NrIpv6RoutingTestCase::ReceivedAtClient, this));
355
356 // Set Callback at SgwPgWApplication of epc to get the packets from gnb and from tunnel net
357 // device
358 Ptr<Application> appPgw = pgw->GetApplication(0);
359 appPgw->TraceConnectWithoutContext("RxFromS1u",
360 MakeCallback(&NrIpv6RoutingTestCase::GnbToPgw, this));
361 appPgw->TraceConnectWithoutContext("RxFromTun",
362 MakeCallback(&NrIpv6RoutingTestCase::TunToPgw, this));
363
364 Simulator::Schedule(Time(Seconds(12.0)), &NrIpv6RoutingTestCase::Checker, this);
365
366 Simulator::Stop(Seconds(14));
367 Simulator::Run();
368
369 Simulator::Destroy();
370}
371
375class NrIpv6RoutingTestSuite : public TestSuite
376{
377 public:
378 NrIpv6RoutingTestSuite();
379};
380
381NrIpv6RoutingTestSuite::NrIpv6RoutingTestSuite()
382 : TestSuite("nr-ipv6-routing-test", Type::UNIT)
383{
384 AddTestCase(new NrIpv6RoutingTestCase, TestCase::Duration::QUICK);
385}
386
391static NrIpv6RoutingTestSuite g_nripv6testsuite;
static NrIpv6RoutingTestSuite g_nripv6testsuite