A Discrete-Event Network Simulator
API
lte-test-ipv6-routing.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Jadavpur University, India
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  * Author: Manoj Kumar Rana <manoj24.rana@gmail.com>
18  */
19 
20 #include "ns3/config-store.h"
21 #include "ns3/core-module.h"
22 #include "ns3/epc-helper.h"
23 #include "ns3/internet-module.h"
24 #include "ns3/ipv4-global-routing-helper.h"
25 #include "ns3/ipv6-static-routing.h"
26 #include "ns3/lte-helper.h"
27 #include "ns3/lte-module.h"
28 #include "ns3/mobility-module.h"
29 #include "ns3/network-module.h"
30 #include "ns3/point-to-point-helper.h"
31 #include "ns3/udp-echo-helper.h"
32 
33 #include <algorithm>
34 
35 /* *
36  * Scenario: 3 UEs, 2 ENBs, 1 Remote Host, UE0<-->ENB0, UE1<-->ENB0, UE2<-->ENB1
37  Servers: UE1, UE2, Remote Host
38  Client: UE0 (3 clients)
39  UDP Echo Packets transmitted between client and server
40 
41  * Pass criteria: 1) Every UDP Echo Request and Reply messages sent and received respectively
42  at UE0 must be matched by their UID, source address, destination address,
43  source port and destination port
44  2) Every request reply must follow proper route (e.g. In case of UE0->UE1,
45  packet must travel this route:
46 UE0->ENB0->PGW->ENB1->UE1->ENB1->PGW->ENB0->UE0) 3) The above check also ensures no redundancy of
47 the followed route for a packet
48 * */
49 
50 using namespace ns3;
51 
58 {
59  public:
61  ~LteIpv6RoutingTestCase() override;
62 
66  void Checker();
67 
74  void SentAtClient(Ptr<const Packet> p, Ptr<Ipv6> ipv6, uint32_t interface);
75 
82  void ReceivedAtClient(Ptr<const Packet> p, Ptr<Ipv6> ipv6, uint32_t interface);
83 
88  void EnbToPgw(Ptr<Packet> p);
89 
94  void TunToPgw(Ptr<Packet> p);
95 
96  private:
97  void DoRun() override;
100  std::list<uint64_t> m_pgwUidRxFrmEnb;
101  std::list<uint64_t>
103 
104  std::list<Ptr<Packet>> m_clientTxPkts;
105  std::list<Ptr<Packet>> m_clientRxPkts;
106 };
107 
109  : TestCase("Test IPv6 Routing at LTE")
110 {
111 }
112 
114 {
115 }
116 
117 void
119 {
120  Ipv6Header ipv6Header;
121  p->PeekHeader(ipv6Header);
122  if (ipv6Header.GetNextHeader() == UdpL4Protocol::PROT_NUMBER)
123  {
124  m_clientTxPkts.push_back(p->Copy());
125  }
126 }
127 
128 void
130 {
131  Ipv6Header ipv6Header;
132  p->PeekHeader(ipv6Header);
133  if (ipv6Header.GetNextHeader() == UdpL4Protocol::PROT_NUMBER)
134  {
135  m_clientRxPkts.push_back(p->Copy());
136  }
137 }
138 
139 void
141 {
142  Ipv6Header ipv6Header;
143  p->PeekHeader(ipv6Header);
144  if (ipv6Header.GetNextHeader() == UdpL4Protocol::PROT_NUMBER)
145  {
146  m_pgwUidRxFrmEnb.push_back(p->GetUid());
147  }
148 }
149 
150 void
152 {
153  Ipv6Header ipv6Header;
154  p->PeekHeader(ipv6Header);
155  if (ipv6Header.GetNextHeader() == UdpL4Protocol::PROT_NUMBER)
156  {
157  m_pgwUidRxFrmTun.push_back(p->GetUid());
158  }
159 }
160 
161 void
163 {
164  bool b = false;
165  bool check = true;
166  // Extract each received reply packet of the client
167  for (auto it1 = m_clientRxPkts.begin(); it1 != m_clientRxPkts.end(); it1++)
168  {
169  Ipv6Header ipv6header1;
170  UdpHeader udpHeader1;
171  Ptr<Packet> p1 = (*it1)->Copy();
172  p1->RemoveHeader(ipv6header1);
173  uint64_t uid = p1->GetUid();
174  p1->RemoveHeader(udpHeader1);
175  // Search each packet in list of sent request packet of the client
176  for (auto it2 = m_clientTxPkts.begin(); it2 != m_clientTxPkts.end(); it2++)
177  {
178  Ptr<Packet> p2 = (*it2)->Copy();
179  Ipv6Header ipv6header2;
180  p2->RemoveHeader(ipv6header2);
181  Ipv6Address sourceAddress = ipv6header2.GetSource();
182  Ipv6Address destinationAddress = ipv6header2.GetDestination();
183  UdpHeader udpHeader2;
184  p2->RemoveHeader(udpHeader2);
185  uint16_t sourcePort;
186  uint16_t destinationPort;
187  sourcePort = udpHeader2.GetSourcePort();
188  destinationPort = udpHeader2.GetDestinationPort();
189  // Check whether the uids, addresses and ports match
190  if ((p2->GetUid() == p1->GetUid()) && sourceAddress == ipv6header1.GetDestination() &&
191  destinationAddress == ipv6header1.GetSource() &&
192  sourcePort == udpHeader1.GetDestinationPort() &&
193  destinationPort == udpHeader1.GetSourcePort())
194  {
195  b = true;
196  break;
197  }
198  }
199  check &= b;
200  if (std::find(m_pgwUidRxFrmEnb.begin(), m_pgwUidRxFrmEnb.end(), uid) !=
201  m_pgwUidRxFrmEnb.end())
202  {
203  check &= true;
204  m_pgwUidRxFrmEnb.remove(uid);
205  }
206  if (std::find(m_pgwUidRxFrmTun.begin(), m_pgwUidRxFrmTun.end(), uid) !=
207  m_pgwUidRxFrmTun.end())
208  {
209  check &= true;
210  m_pgwUidRxFrmTun.remove(uid);
211  }
212  b = false;
213  }
214 
215  NS_TEST_ASSERT_MSG_EQ(check, true, "Failure Happens IPv6 routing of LENA");
217  m_clientRxPkts.size(),
218  "No. of Request and Reply messages mismatch");
219  NS_TEST_ASSERT_MSG_EQ(m_pgwUidRxFrmEnb.size(), 0, "Route is not Redundant in Lte IPv6 test");
220  NS_TEST_ASSERT_MSG_EQ(m_pgwUidRxFrmTun.size(), 0, "Route is not Redundant in Lte IPv6 test");
221 }
222 
223 void
225 {
226  double distance = 60.0;
227 
228  Ptr<LteHelper> lteHelper = CreateObject<LteHelper>();
229  Ptr<PointToPointEpcHelper> epcHelper = CreateObject<PointToPointEpcHelper>();
230  lteHelper->SetEpcHelper(epcHelper);
231 
232  ConfigStore inputConfig;
233  inputConfig.ConfigureDefaults();
234 
235  Ptr<Node> pgw = epcHelper->GetPgwNode();
236 
237  // Create a single RemoteHost
238  NodeContainer remoteHostContainer;
239  remoteHostContainer.Create(1);
240  Ptr<Node> remoteHost = remoteHostContainer.Get(0);
242  internet.Install(remoteHostContainer);
243 
244  // Create the Internet
245  PointToPointHelper p2ph;
246  p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s")));
247  p2ph.SetDeviceAttribute("Mtu", UintegerValue(1500));
248  p2ph.SetChannelAttribute("Delay", TimeValue(Seconds(0.010)));
249  NetDeviceContainer internetDevices = p2ph.Install(pgw, remoteHost);
250 
251  NodeContainer ueNodes;
252  NodeContainer enbNodes;
253  enbNodes.Create(2);
254  ueNodes.Create(3);
255 
256  // Install Mobility Model
257  Ptr<ListPositionAllocator> positionAlloc1 = CreateObject<ListPositionAllocator>();
258  Ptr<ListPositionAllocator> positionAlloc2 = CreateObject<ListPositionAllocator>();
259 
260  positionAlloc1->Add(Vector(distance * 0, 0, 0));
261  positionAlloc1->Add(Vector(distance * 0 + 5, 0, 0));
262  positionAlloc1->Add(Vector(distance * 1, 0, 0));
263 
264  positionAlloc2->Add(Vector(distance * 0, 0, 0));
265  positionAlloc2->Add(Vector(distance * 1, 0, 0));
266 
268  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
269  mobility.SetPositionAllocator(positionAlloc1);
270  mobility.Install(ueNodes);
271 
272  mobility.SetPositionAllocator(positionAlloc2);
273  mobility.Install(enbNodes);
274 
275  // Install the IP stack on the UEs
276  internet.Install(ueNodes);
277 
278  // Install LTE Devices to the nodes
279  NetDeviceContainer enbLteDevs = lteHelper->InstallEnbDevice(enbNodes);
280  NetDeviceContainer ueLteDevs = lteHelper->InstallUeDevice(ueNodes);
281 
282  // Assign IP address to UEs, and install applications
283  m_ueIpIface = epcHelper->AssignUeIpv6Address(NetDeviceContainer(ueLteDevs));
284 
285  Ipv6StaticRoutingHelper ipv6RoutingHelper;
286 
287  for (uint32_t u = 0; u < ueNodes.GetN(); ++u)
288  {
289  Ptr<Node> ueNode = ueNodes.Get(u);
290  // Set the default gateway for the UE
291  Ptr<Ipv6StaticRouting> ueStaticRouting =
292  ipv6RoutingHelper.GetStaticRouting(ueNode->GetObject<Ipv6>());
293  ueStaticRouting->SetDefaultRoute(epcHelper->GetUeDefaultGatewayAddress6(), 1);
294  }
295 
296  // Attach two UEs at first eNodeB and one UE at second eNodeB
297  lteHelper->Attach(ueLteDevs.Get(0), enbLteDevs.Get(0));
298  lteHelper->Attach(ueLteDevs.Get(1), enbLteDevs.Get(0));
299  lteHelper->Attach(ueLteDevs.Get(2), enbLteDevs.Get(1));
300 
301  Ipv6AddressHelper ipv6h;
302  ipv6h.SetBase(Ipv6Address("6001:db80::"), Ipv6Prefix(64));
303  Ipv6InterfaceContainer internetIpIfaces = ipv6h.Assign(internetDevices);
304 
305  internetIpIfaces.SetForwarding(0, true);
306  internetIpIfaces.SetDefaultRouteInAllNodes(0);
307 
308  Ptr<Ipv6StaticRouting> remoteHostStaticRouting =
309  ipv6RoutingHelper.GetStaticRouting(remoteHost->GetObject<Ipv6>());
310  remoteHostStaticRouting
311  ->AddNetworkRouteTo("7777:f00d::", Ipv6Prefix(64), internetIpIfaces.GetAddress(0, 1), 1, 0);
312 
313  // interface 0 is localhost, 1 is the p2p device
314  m_remoteHostAddr = internetIpIfaces.GetAddress(1, 1);
315 
316  // Install and start applications on UEs and remote host
317  UdpEchoServerHelper echoServer1(10);
318  UdpEchoServerHelper echoServer2(11);
319  UdpEchoServerHelper echoServer3(12);
320 
321  ApplicationContainer serverApps = echoServer1.Install(remoteHost);
322  serverApps.Add(echoServer2.Install(ueNodes.Get(1)));
323  serverApps.Add(echoServer3.Install(ueNodes.Get(2)));
324 
325  serverApps.Start(Seconds(4.0));
326  serverApps.Stop(Seconds(12.0));
327 
328  UdpEchoClientHelper echoClient1(m_remoteHostAddr, 10);
329  UdpEchoClientHelper echoClient2(m_ueIpIface.GetAddress(1, 1), 11);
330  UdpEchoClientHelper echoClient3(m_ueIpIface.GetAddress(2, 1), 12);
331 
332  echoClient1.SetAttribute("MaxPackets", UintegerValue(1000));
333  echoClient1.SetAttribute("Interval", TimeValue(Seconds(0.2)));
334  echoClient1.SetAttribute("PacketSize", UintegerValue(1024));
335 
336  echoClient2.SetAttribute("MaxPackets", UintegerValue(1000));
337  echoClient2.SetAttribute("Interval", TimeValue(Seconds(0.2)));
338  echoClient2.SetAttribute("PacketSize", UintegerValue(1024));
339 
340  echoClient3.SetAttribute("MaxPackets", UintegerValue(1000));
341  echoClient3.SetAttribute("Interval", TimeValue(Seconds(0.2)));
342  echoClient3.SetAttribute("PacketSize", UintegerValue(1024));
343 
344  ApplicationContainer clientApps1 = echoClient1.Install(ueNodes.Get(0));
345  ApplicationContainer clientApps2 = echoClient2.Install(ueNodes.Get(0));
346  ApplicationContainer clientApps3 = echoClient3.Install(ueNodes.Get(0));
347 
348  clientApps1.Start(Seconds(4.0));
349  clientApps1.Stop(Seconds(6.0));
350 
351  clientApps2.Start(Seconds(6.1));
352  clientApps2.Stop(Seconds(8.0));
353 
354  clientApps3.Start(Seconds(8.1));
355  clientApps3.Stop(Seconds(10.0));
356 
357  // Set Cllback for Client Sent and Received packets
358  Ptr<Ipv6L3Protocol> ipL3 = (ueNodes.Get(0))->GetObject<Ipv6L3Protocol>();
359  ipL3->TraceConnectWithoutContext("Tx",
361  ipL3->TraceConnectWithoutContext("Rx",
363 
364  // Set Callback at SgwPgWApplication of epc to get the packets from enb and from tunnel net
365  // device
366  Ptr<Application> appPgw = pgw->GetApplication(0);
367  appPgw->TraceConnectWithoutContext("RxFromS1u",
369  appPgw->TraceConnectWithoutContext("RxFromTun",
371 
372  Simulator::Schedule(Time(Seconds(12.0)), &LteIpv6RoutingTestCase::Checker, this);
373 
374  Simulator::Stop(Seconds(14));
375  Simulator::Run();
376 
377  Simulator::Destroy();
378 }
379 
384 {
385  public:
387 };
388 
390  : TestSuite("lte-ipv6-routing-test", UNIT)
391 {
392  AddTestCase(new LteIpv6RoutingTestCase, TestCase::QUICK);
393 }
394 
Lte Ipv6 routing test case.
Ipv6InterfaceContainer m_ueIpIface
IPv6 interface container for ue.
void TunToPgw(Ptr< Packet > p)
Received Packet at pgw from enb.
Ipv6Address m_remoteHostAddr
remote host address
void ReceivedAtClient(Ptr< const Packet > p, Ptr< Ipv6 > ipv6, uint32_t interface)
Received Packets at client's IPv6 interface.
std::list< Ptr< Packet > > m_clientTxPkts
list of sent packets from client
std::list< uint64_t > m_pgwUidRxFrmTun
list of uids of packets received at pgw from tunnel net device
void EnbToPgw(Ptr< Packet > p)
Received Packet at pgw from enb.
void Checker()
Initialize testing parameters.
std::list< Ptr< Packet > > m_clientRxPkts
list of received packets at client
void SentAtClient(Ptr< const Packet > p, Ptr< Ipv6 > ipv6, uint32_t interface)
sent Packets from client's IPv6 interface.
std::list< uint64_t > m_pgwUidRxFrmEnb
list of uids of packets received at pgw from enb
void DoRun() override
Implementation to actually run this TestCase.
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.
void ConfigureDefaults()
Configure the default values.
aggregate IP/TCP/UDP functionality to existing Nodes.
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.
Definition: ipv6-address.h:49
Packet header for IPv6.
Definition: ipv6-header.h:35
uint8_t GetNextHeader() const
Get the next header.
Definition: ipv6-header.cc:88
Ipv6Address GetDestination() const
Get the "Destination address" field.
Definition: ipv6-header.cc:124
Ipv6Address GetSource() const
Get the "Source address" field.
Definition: ipv6-header.cc:112
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition: ipv6.h:82
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.
void SetDefaultRouteInAllNodes(uint32_t router)
Set the default route for all the devices (except the router itself).
Ipv6Address GetAddress(uint32_t i, uint32_t j) const
Get the address for the specified index.
Describes an IPv6 prefix.
Definition: ipv6-address.h:455
Helper class that adds ns3::Ipv6StaticRouting objects.
Ptr< Ipv6StaticRouting > GetStaticRouting(Ptr< Ipv6 > ipv6) const
Get Ipv6StaticRouting pointer from IPv6 stack.
void SetEpcHelper(Ptr< EpcHelper > h)
Set the EpcHelper to be used to setup the EPC network in conjunction with the setup of the LTE radio ...
Definition: lte-helper.cc:285
NetDeviceContainer InstallEnbDevice(NodeContainer c)
Create a set of eNodeB devices.
Definition: lte-helper.cc:485
void Attach(NetDeviceContainer ueDevices)
Enables automatic attachment of a set of UE devices to a suitable cell using Idle mode initial cell s...
Definition: lte-helper.cc:1039
NetDeviceContainer InstallUeDevice(NodeContainer c)
Create a set of UE devices.
Definition: lte-helper.cc:500
Helper class used to assign positions and mobility models to nodes.
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.
Ipv6Address GetUeDefaultGatewayAddress6() override
Ptr< Node > GetPgwNode() const override
Get the PGW node.
Ipv6InterfaceContainer AssignUeIpv6Address(NetDeviceContainer ueDevices) override
Assign IPv6 addresses to UE devices.
keep track of a set of node pointers.
uint32_t GetN() const
Get the number of Ptr<Node> stored in this container.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
Ptr< Application > GetApplication(uint32_t index) const
Retrieve the index-th Application associated to this node.
Definition: node.cc:180
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:315
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:305
uint64_t GetUid() const
Returns the packet's Uid.
Definition: packet.cc:412
Build a set of PointToPointNetDevice objects.
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
NetDeviceContainer Install(NodeContainer c)
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
Create an application which sends a UDP packet and waits for an echo of this packet.
void SetAttribute(std::string name, const AttributeValue &value)
Record an attribute to be set in each Application after it is is created.
ApplicationContainer Install(Ptr< Node > node) const
Create a udp echo client application on the specified node.
Create a server application which waits for input UDP packets and sends them back to the original sen...
ApplicationContainer Install(Ptr< Node > node) const
Create a UdpEchoServerApplication on the specified Node.
Packet header for UDP packets.
Definition: udp-header.h:41
uint16_t GetDestinationPort() const
Definition: udp-header.cc:54
uint16_t GetSourcePort() const
Definition: udp-header.cc:48
Hold an unsigned integer type.
Definition: uinteger.h:45
static LteIpv6RoutingTestSuite g_lteipv6testsuite
Static variable for test initialization.
void(* DataRate)(DataRate oldValue, DataRate newValue)
TracedValue callback signature for DataRate.
Definition: data-rate.h:327
#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:144
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
serverApps
Definition: first.py:54
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:839
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:704
mobility
Definition: third.py:105