A Discrete-Event Network Simulator
API
no-backhaul-epc-helper.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2019 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Manuel Requena <manuel.requena@cttc.es>
19  * (based on the original point-to-point-epc-helper.cc)
20  */
21 
22 #include "ns3/boolean.h"
23 #include "ns3/string.h"
24 #include "ns3/log.h"
25 #include "ns3/packet-socket-address.h"
26 #include "ns3/point-to-point-helper.h"
27 #include "ns3/internet-stack-helper.h"
28 #include "ns3/ipv6-static-routing-helper.h"
29 #include "ns3/icmpv6-l4-protocol.h"
30 #include "ns3/epc-enb-application.h"
31 #include "ns3/epc-pgw-application.h"
32 #include "ns3/epc-sgw-application.h"
33 #include "ns3/epc-mme-application.h"
34 #include "ns3/epc-x2.h"
35 #include "ns3/lte-enb-rrc.h"
36 #include "ns3/epc-ue-nas.h"
37 #include "ns3/lte-enb-net-device.h"
38 #include "ns3/lte-ue-net-device.h"
39 
40 #include "ns3/no-backhaul-epc-helper.h"
41 
42 namespace ns3 {
43 
44 NS_LOG_COMPONENT_DEFINE ("NoBackhaulEpcHelper");
45 
46 NS_OBJECT_ENSURE_REGISTERED (NoBackhaulEpcHelper);
47 
48 
50  : m_gtpuUdpPort (2152), // fixed by the standard
51  m_s11LinkDataRate (DataRate ("10Gb/s")),
52  m_s11LinkDelay (Seconds (0)),
53  m_s11LinkMtu (3000),
54  m_gtpcUdpPort (2123), // fixed by the standard
55  m_s5LinkDataRate (DataRate ("10Gb/s")),
56  m_s5LinkDelay (Seconds (0)),
57  m_s5LinkMtu (3000)
58 {
59  NS_LOG_FUNCTION (this);
60  // To access the attribute value within the constructor
62 
63  int retval;
64 
65  // since we use point-to-point links for links between the core network nodes,
66  // we use a /30 subnet which can hold exactly two addresses
67  // (remember that net broadcast and null address are not valid)
68  m_x2Ipv4AddressHelper.SetBase ("12.0.0.0", "255.255.255.252");
69  m_s11Ipv4AddressHelper.SetBase ("13.0.0.0", "255.255.255.252");
70  m_s5Ipv4AddressHelper.SetBase ("14.0.0.0", "255.255.255.252");
71 
72  // we use a /8 net for all UEs
73  m_uePgwAddressHelper.SetBase ("7.0.0.0", "255.0.0.0");
74 
75  // we use a /64 IPv6 net all UEs
76  m_uePgwAddressHelper6.SetBase ("7777:f00d::", Ipv6Prefix (64));
77 
78  // Create PGW, SGW and MME nodes
79  m_pgw = CreateObject<Node> ();
80  m_sgw = CreateObject<Node> ();
81  m_mme = CreateObject<Node> ();
82  InternetStackHelper internet;
83  internet.Install (m_pgw);
84  internet.Install (m_sgw);
85  internet.Install (m_mme);
86 
87  // The Tun device resides in different 64 bit subnet.
88  // We must create an unique route to tun device for all the packets destined
89  // to all 64 bit IPv6 prefixes of UEs, based by the unique 48 bit network prefix of this EPC network
90  Ipv6StaticRoutingHelper ipv6RoutingHelper;
91  Ptr<Ipv6StaticRouting> pgwStaticRouting = ipv6RoutingHelper.GetStaticRouting (m_pgw->GetObject<Ipv6> ());
92  pgwStaticRouting->AddNetworkRouteTo ("7777:f00d::", Ipv6Prefix (64), Ipv6Address ("::"), 1, 0);
93 
94  // create TUN device implementing tunneling of user data over GTP-U/UDP/IP in the PGW
95  m_tunDevice = CreateObject<VirtualNetDevice> ();
96 
97  // allow jumbo packets
98  m_tunDevice->SetAttribute ("Mtu", UintegerValue (30000));
99 
100  // yes we need this
102 
104  NetDeviceContainer tunDeviceContainer;
105  tunDeviceContainer.Add (m_tunDevice);
106  // the TUN device is on the same subnet as the UEs, so when a packet
107  // addressed to an UE arrives at the intenet to the WAN interface of
108  // the PGW it will be forwarded to the TUN device.
109  Ipv4InterfaceContainer tunDeviceIpv4IfContainer = AssignUeIpv4Address (tunDeviceContainer);
110 
111 
112  // the TUN device for IPv6 address is on the different subnet as the
113  // UEs, it will forward the UE packets as we have inserted the route
114  // for all UEs at the time of assigning UE addresses
115  Ipv6InterfaceContainer tunDeviceIpv6IfContainer = AssignUeIpv6Address (tunDeviceContainer);
116 
117 
118  //Set Forwarding of the IPv6 interface
119  tunDeviceIpv6IfContainer.SetForwarding (0,true);
120  tunDeviceIpv6IfContainer.SetDefaultRouteInAllNodes (0);
121 
122  // Create S5 link between PGW and SGW
123  PointToPointHelper p2ph;
126  p2ph.SetChannelAttribute ("Delay", TimeValue (m_s5LinkDelay));
127  NetDeviceContainer pgwSgwDevices = p2ph.Install (m_pgw, m_sgw);
128  NS_LOG_LOGIC ("IPv4 ifaces of the PGW after installing p2p dev: " << m_pgw->GetObject<Ipv4> ()->GetNInterfaces ());
129  NS_LOG_LOGIC ("IPv4 ifaces of the SGW after installing p2p dev: " << m_sgw->GetObject<Ipv4> ()->GetNInterfaces ());
130  Ptr<NetDevice> pgwDev = pgwSgwDevices.Get (0);
131  Ptr<NetDevice> sgwDev = pgwSgwDevices.Get (1);
133  Ipv4InterfaceContainer pgwSgwIpIfaces = m_s5Ipv4AddressHelper.Assign (pgwSgwDevices);
134  NS_LOG_LOGIC ("IPv4 ifaces of the PGW after assigning Ipv4 addr to S5 dev: " << m_pgw->GetObject<Ipv4> ()->GetNInterfaces ());
135  NS_LOG_LOGIC ("IPv4 ifaces of the SGW after assigning Ipv4 addr to S5 dev: " << m_sgw->GetObject<Ipv4> ()->GetNInterfaces ());
136 
137  Ipv4Address pgwS5Address = pgwSgwIpIfaces.GetAddress (0);
138  Ipv4Address sgwS5Address = pgwSgwIpIfaces.GetAddress (1);
139 
140  // Create S5-U socket in the PGW
141  Ptr<Socket> pgwS5uSocket = Socket::CreateSocket (m_pgw, TypeId::LookupByName ("ns3::UdpSocketFactory"));
142  retval = pgwS5uSocket->Bind (InetSocketAddress (pgwS5Address, m_gtpuUdpPort));
143  NS_ASSERT (retval == 0);
144 
145  // Create S5-C socket in the PGW
146  Ptr<Socket> pgwS5cSocket = Socket::CreateSocket (m_pgw, TypeId::LookupByName ("ns3::UdpSocketFactory"));
147  retval = pgwS5cSocket->Bind (InetSocketAddress (pgwS5Address, m_gtpcUdpPort));
148  NS_ASSERT (retval == 0);
149 
150  // Create EpcPgwApplication
151  m_pgwApp = CreateObject<EpcPgwApplication> (m_tunDevice, pgwS5Address, pgwS5uSocket, pgwS5cSocket);
153 
154  // Connect EpcPgwApplication and virtual net device for tunneling
156 
157 
158  // Create S5-U socket in the SGW
159  Ptr<Socket> sgwS5uSocket = Socket::CreateSocket (m_sgw, TypeId::LookupByName ("ns3::UdpSocketFactory"));
160  retval = sgwS5uSocket->Bind (InetSocketAddress (sgwS5Address, m_gtpuUdpPort));
161  NS_ASSERT (retval == 0);
162 
163  // Create S5-C socket in the SGW
164  Ptr<Socket> sgwS5cSocket = Socket::CreateSocket (m_sgw, TypeId::LookupByName ("ns3::UdpSocketFactory"));
165  retval = sgwS5cSocket->Bind (InetSocketAddress (sgwS5Address, m_gtpcUdpPort));
166  NS_ASSERT (retval == 0);
167 
168  // Create S1-U socket in the SGW
169  Ptr<Socket> sgwS1uSocket = Socket::CreateSocket (m_sgw, TypeId::LookupByName ("ns3::UdpSocketFactory"));
170  retval = sgwS1uSocket->Bind (InetSocketAddress (Ipv4Address::GetAny (), m_gtpuUdpPort));
171  NS_ASSERT (retval == 0);
172 
173  // Create EpcSgwApplication
174  m_sgwApp = CreateObject<EpcSgwApplication> (sgwS1uSocket, sgwS5Address, sgwS5uSocket, sgwS5cSocket);
176  m_sgwApp->AddPgw (pgwS5Address);
177  m_pgwApp->AddSgw (sgwS5Address);
178 
179 
180  // Create S11 link between MME and SGW
181  PointToPointHelper s11P2ph;
182  s11P2ph.SetDeviceAttribute ("DataRate", DataRateValue (m_s11LinkDataRate));
183  s11P2ph.SetDeviceAttribute ("Mtu", UintegerValue (m_s11LinkMtu));
184  s11P2ph.SetChannelAttribute ("Delay", TimeValue (m_s11LinkDelay));
185  NetDeviceContainer mmeSgwDevices = s11P2ph.Install (m_mme, m_sgw);
186  NS_LOG_LOGIC ("MME's IPv4 ifaces after installing p2p dev: " << m_mme->GetObject<Ipv4> ()->GetNInterfaces ());
187  NS_LOG_LOGIC ("SGW's IPv4 ifaces after installing p2p dev: " << m_sgw->GetObject<Ipv4> ()->GetNInterfaces ());
188  Ptr<NetDevice> mmeDev = mmeSgwDevices.Get (0);
189  Ptr<NetDevice> sgwS11Dev = mmeSgwDevices.Get (1);
191  Ipv4InterfaceContainer mmeSgwIpIfaces = m_s11Ipv4AddressHelper.Assign (mmeSgwDevices);
192  NS_LOG_LOGIC ("MME's IPv4 ifaces after assigning Ipv4 addr to S11 dev: " << m_mme->GetObject<Ipv4> ()->GetNInterfaces ());
193  NS_LOG_LOGIC ("SGW's IPv4 ifaces after assigning Ipv4 addr to S11 dev: " << m_sgw->GetObject<Ipv4> ()->GetNInterfaces ());
194 
195  Ipv4Address mmeS11Address = mmeSgwIpIfaces.GetAddress (0);
196  Ipv4Address sgwS11Address = mmeSgwIpIfaces.GetAddress (1);
197 
198  // Create S11 socket in the MME
199  Ptr<Socket> mmeS11Socket = Socket::CreateSocket (m_mme, TypeId::LookupByName ("ns3::UdpSocketFactory"));
200  retval = mmeS11Socket->Bind (InetSocketAddress (mmeS11Address, m_gtpcUdpPort));
201  NS_ASSERT (retval == 0);
202 
203  // Create S11 socket in the SGW
204  Ptr<Socket> sgwS11Socket = Socket::CreateSocket (m_sgw, TypeId::LookupByName ("ns3::UdpSocketFactory"));
205  retval = sgwS11Socket->Bind (InetSocketAddress (sgwS11Address, m_gtpcUdpPort));
206  NS_ASSERT (retval == 0);
207 
208 
209  // Create MME Application and connect with SGW via S11 interface
210  m_mmeApp = CreateObject<EpcMmeApplication> ();
212  m_mmeApp->AddSgw (sgwS11Address, mmeS11Address, mmeS11Socket);
213  m_sgwApp->AddMme (mmeS11Address, sgwS11Socket);
214 }
215 
217 {
218  NS_LOG_FUNCTION (this);
219 }
220 
221 TypeId
223 {
225  static TypeId tid = TypeId ("ns3::NoBackhaulEpcHelper")
226  .SetParent<EpcHelper> ()
227  .SetGroupName("Lte")
228  .AddConstructor<NoBackhaulEpcHelper> ()
229  .AddAttribute ("S5LinkDataRate",
230  "The data rate to be used for the next S5 link to be created",
231  DataRateValue (DataRate ("10Gb/s")),
234  .AddAttribute ("S5LinkDelay",
235  "The delay to be used for the next S5 link to be created",
236  TimeValue (Seconds (0)),
238  MakeTimeChecker ())
239  .AddAttribute ("S5LinkMtu",
240  "The MTU of the next S5 link to be created",
241  UintegerValue (2000),
243  MakeUintegerChecker<uint16_t> ())
244  .AddAttribute ("S11LinkDataRate",
245  "The data rate to be used for the next S11 link to be created",
246  DataRateValue (DataRate ("10Gb/s")),
249  .AddAttribute ("S11LinkDelay",
250  "The delay to be used for the next S11 link to be created",
251  TimeValue (Seconds (0)),
253  MakeTimeChecker ())
254  .AddAttribute ("S11LinkMtu",
255  "The MTU of the next S11 link to be created.",
256  UintegerValue (2000),
258  MakeUintegerChecker<uint16_t> ())
259  .AddAttribute ("X2LinkDataRate",
260  "The data rate to be used for the next X2 link to be created",
261  DataRateValue (DataRate ("10Gb/s")),
264  .AddAttribute ("X2LinkDelay",
265  "The delay to be used for the next X2 link to be created",
266  TimeValue (Seconds (0)),
268  MakeTimeChecker ())
269  .AddAttribute ("X2LinkMtu",
270  "The MTU of the next X2 link to be created. Note that, because of some big X2 messages, you need a big MTU.",
271  UintegerValue (3000),
273  MakeUintegerChecker<uint16_t> ())
274  .AddAttribute ("X2LinkPcapPrefix",
275  "Prefix for Pcap generated by X2 link",
276  StringValue ("x2"),
279  .AddAttribute ("X2LinkEnablePcap",
280  "Enable Pcap for X2 link",
281  BooleanValue (false),
284  ;
285  return tid;
286 }
287 
288 TypeId
290 {
291  return GetTypeId ();
292 }
293 
294 void
296 {
297  NS_LOG_FUNCTION (this);
298  m_tunDevice->SetSendCallback (MakeNullCallback<bool, Ptr<Packet>, const Address&, const Address&, uint16_t> ());
299  m_tunDevice = 0;
300  m_sgwApp = 0;
301  m_sgw->Dispose ();
302  m_pgwApp = 0;
303  m_pgw->Dispose ();
304  m_mmeApp = 0;
305  m_mme->Dispose ();
306 }
307 
308 
309 void
310 NoBackhaulEpcHelper::AddEnb (Ptr<Node> enb, Ptr<NetDevice> lteEnbNetDevice, uint16_t cellId)
311 {
312  NS_LOG_FUNCTION (this << enb << lteEnbNetDevice << cellId);
313  NS_ASSERT (enb == lteEnbNetDevice->GetNode ());
314 
315  int retval;
316 
317  // add an IPv4 stack to the previously created eNB
318  InternetStackHelper internet;
319  internet.Install (enb);
320  NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB after node creation: " << enb->GetObject<Ipv4> ()->GetNInterfaces ());
321 
322  // create LTE socket for the ENB
323  Ptr<Socket> enbLteSocket = Socket::CreateSocket (enb, TypeId::LookupByName ("ns3::PacketSocketFactory"));
324  PacketSocketAddress enbLteSocketBindAddress;
325  enbLteSocketBindAddress.SetSingleDevice (lteEnbNetDevice->GetIfIndex ());
326  enbLteSocketBindAddress.SetProtocol (Ipv4L3Protocol::PROT_NUMBER);
327  retval = enbLteSocket->Bind (enbLteSocketBindAddress);
328  NS_ASSERT (retval == 0);
329  PacketSocketAddress enbLteSocketConnectAddress;
330  enbLteSocketConnectAddress.SetPhysicalAddress (Mac48Address::GetBroadcast ());
331  enbLteSocketConnectAddress.SetSingleDevice (lteEnbNetDevice->GetIfIndex ());
332  enbLteSocketConnectAddress.SetProtocol (Ipv4L3Protocol::PROT_NUMBER);
333  retval = enbLteSocket->Connect (enbLteSocketConnectAddress);
334  NS_ASSERT (retval == 0);
335 
336  // create LTE socket for the ENB
337  Ptr<Socket> enbLteSocket6 = Socket::CreateSocket (enb, TypeId::LookupByName ("ns3::PacketSocketFactory"));
338  PacketSocketAddress enbLteSocketBindAddress6;
339  enbLteSocketBindAddress6.SetSingleDevice (lteEnbNetDevice->GetIfIndex ());
340  enbLteSocketBindAddress6.SetProtocol (Ipv6L3Protocol::PROT_NUMBER);
341  retval = enbLteSocket6->Bind (enbLteSocketBindAddress6);
342  NS_ASSERT (retval == 0);
343  PacketSocketAddress enbLteSocketConnectAddress6;
344  enbLteSocketConnectAddress6.SetPhysicalAddress (Mac48Address::GetBroadcast ());
345  enbLteSocketConnectAddress6.SetSingleDevice (lteEnbNetDevice->GetIfIndex ());
346  enbLteSocketConnectAddress6.SetProtocol (Ipv6L3Protocol::PROT_NUMBER);
347  retval = enbLteSocket6->Connect (enbLteSocketConnectAddress6);
348  NS_ASSERT (retval == 0);
349 
350  NS_LOG_INFO ("Create EpcEnbApplication");
351  Ptr<EpcEnbApplication> enbApp = CreateObject<EpcEnbApplication> (enbLteSocket, enbLteSocket6, cellId);
352  enb->AddApplication (enbApp);
353  NS_ASSERT (enb->GetNApplications () == 1);
354  NS_ASSERT_MSG (enb->GetApplication (0)->GetObject<EpcEnbApplication> () != 0, "cannot retrieve EpcEnbApplication");
355  NS_LOG_LOGIC ("enb: " << enb << ", enb->GetApplication (0): " << enb->GetApplication (0));
356 
357  NS_LOG_INFO ("Create EpcX2 entity");
358  Ptr<EpcX2> x2 = CreateObject<EpcX2> ();
359  enb->AggregateObject (x2);
360 }
361 
362 
363 void
365 {
366  NS_LOG_FUNCTION (this << enb1 << enb2);
367 
368  // Create a point to point link between the two eNBs with
369  // the corresponding new NetDevices on each side
370  PointToPointHelper p2ph;
373  p2ph.SetChannelAttribute ("Delay", TimeValue (m_x2LinkDelay));
374  NetDeviceContainer enbDevices = p2ph.Install (enb1, enb2);
375  NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #1 after installing p2p dev: " << enb1->GetObject<Ipv4> ()->GetNInterfaces ());
376  NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #2 after installing p2p dev: " << enb2->GetObject<Ipv4> ()->GetNInterfaces ());
377 
378  if (m_x2LinkEnablePcap)
379  {
381  }
382 
384  Ipv4InterfaceContainer enbIpIfaces = m_x2Ipv4AddressHelper.Assign (enbDevices);
385  NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #1 after assigning Ipv4 addr to X2 dev: " << enb1->GetObject<Ipv4> ()->GetNInterfaces ());
386  NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #2 after assigning Ipv4 addr to X2 dev: " << enb2->GetObject<Ipv4> ()->GetNInterfaces ());
387 
388  Ipv4Address enb1X2Address = enbIpIfaces.GetAddress (0);
389  Ipv4Address enb2X2Address = enbIpIfaces.GetAddress (1);
390 
391  // Add X2 interface to both eNBs' X2 entities
392  Ptr<EpcX2> enb1X2 = enb1->GetObject<EpcX2> ();
393  Ptr<EpcX2> enb2X2 = enb2->GetObject<EpcX2> ();
394 
395  Ptr<NetDevice> enb1LteDev = enb1->GetDevice (0);
396  Ptr<NetDevice> enb2LteDev = enb2->GetDevice (0);
397 
398  DoAddX2Interface (enb1X2, enb1LteDev, enb1X2Address, enb2X2, enb2LteDev, enb2X2Address);
399 }
400 
401 void
403  const Ipv4Address &enb1X2Address,
404  const Ptr<EpcX2> &enb2X2, const Ptr<NetDevice> &enb2LteDev,
405  const Ipv4Address &enb2X2Address) const
406 {
407  NS_LOG_FUNCTION (this);
408 
409  Ptr<LteEnbNetDevice> enb1LteDevice = enb1LteDev->GetObject<LteEnbNetDevice> ();
410  Ptr<LteEnbNetDevice> enb2LteDevice = enb2LteDev->GetObject<LteEnbNetDevice> ();
411 
412  NS_ABORT_MSG_IF (enb1LteDevice == nullptr , "Unable to find LteEnbNetDevice for the first eNB");
413  NS_ABORT_MSG_IF (enb2LteDevice == nullptr , "Unable to find LteEnbNetDevice for the second eNB");
414 
415  uint16_t enb1CellId = enb1LteDevice->GetCellId ();
416  uint16_t enb2CellId = enb2LteDevice->GetCellId ();
417 
418  NS_LOG_LOGIC ("LteEnbNetDevice #1 = " << enb1LteDev << " - CellId = " << enb1CellId);
419  NS_LOG_LOGIC ("LteEnbNetDevice #2 = " << enb2LteDev << " - CellId = " << enb2CellId);
420 
421  enb1X2->AddX2Interface (enb1CellId, enb1X2Address, enb2CellId, enb2X2Address);
422  enb2X2->AddX2Interface (enb2CellId, enb2X2Address, enb1CellId, enb1X2Address);
423 
424  enb1LteDevice->GetRrc ()->AddX2Neighbour (enb2CellId);
425  enb2LteDevice->GetRrc ()->AddX2Neighbour (enb1CellId);
426 }
427 
428 
429 void
431 {
432  NS_LOG_FUNCTION (this << imsi << ueDevice);
433 
434  m_mmeApp->AddUe (imsi);
435  m_pgwApp->AddUe (imsi);
436 }
437 
438 uint8_t
440  Ptr<EpcTft> tft, EpsBearer bearer)
441 {
442  NS_LOG_FUNCTION (this << ueDevice << imsi);
443 
444  // we now retrieve the IPv4/IPv6 address of the UE and notify it to the SGW;
445  // we couldn't do it before since address assignment is triggered by
446  // the user simulation program, rather than done by the EPC
447  Ptr<Node> ueNode = ueDevice->GetNode ();
448  Ptr<Ipv4> ueIpv4 = ueNode->GetObject<Ipv4> ();
449  Ptr<Ipv6> ueIpv6 = ueNode->GetObject<Ipv6> ();
450  NS_ASSERT_MSG (ueIpv4 != 0 || ueIpv6 != 0, "UEs need to have IPv4/IPv6 installed before EPS bearers can be activated");
451 
452  if (ueIpv4)
453  {
454  int32_t interface = ueIpv4->GetInterfaceForDevice (ueDevice);
455  if (interface >= 0 && ueIpv4->GetNAddresses (interface) == 1)
456  {
457  Ipv4Address ueAddr = ueIpv4->GetAddress (interface, 0).GetLocal ();
458  NS_LOG_LOGIC (" UE IPv4 address: " << ueAddr);
459  m_pgwApp->SetUeAddress (imsi, ueAddr);
460  }
461  }
462  if (ueIpv6)
463  {
464  int32_t interface6 = ueIpv6->GetInterfaceForDevice (ueDevice);
465  if (interface6 >= 0 && ueIpv6->GetNAddresses (interface6) == 2)
466  {
467  Ipv6Address ueAddr6 = ueIpv6->GetAddress (interface6, 1).GetAddress ();
468  NS_LOG_LOGIC (" UE IPv6 address: " << ueAddr6);
469  m_pgwApp->SetUeAddress6 (imsi, ueAddr6);
470  }
471  }
472  uint8_t bearerId = m_mmeApp->AddBearer (imsi, tft, bearer);
473  DoActivateEpsBearerForUe (ueDevice, tft, bearer);
474 
475  return bearerId;
476 }
477 
478 void
480  const Ptr<EpcTft> &tft,
481  const EpsBearer &bearer) const
482 {
483  NS_LOG_FUNCTION (this);
484  Ptr<LteUeNetDevice> ueLteDevice = DynamicCast<LteUeNetDevice> (ueDevice);
485  if (ueLteDevice == nullptr)
486  {
487  // You may wonder why this is not an assert. Well, take a look in epc-test-s1u-downlink
488  // and -uplink: we are using CSMA to simulate UEs.
489  NS_LOG_WARN ("Unable to find LteUeNetDevice while activating the EPS bearer");
490  }
491  else
492  {
493  Simulator::ScheduleNow (&EpcUeNas::ActivateEpsBearer, ueLteDevice->GetNas (), bearer, tft);
494  }
495 }
496 
497 Ptr<Node>
499 {
500  return m_pgw;
501 }
502 
505 {
506  return m_uePgwAddressHelper.Assign (ueDevices);
507 }
508 
511 {
512  for (NetDeviceContainer::Iterator iter = ueDevices.Begin ();
513  iter != ueDevices.End ();
514  iter ++)
515  {
516  Ptr<Icmpv6L4Protocol> icmpv6 = (*iter)->GetNode ()->GetObject<Icmpv6L4Protocol> ();
517  icmpv6->SetAttribute ("DAD", BooleanValue (false));
518  }
519  return m_uePgwAddressHelper6.Assign (ueDevices);
520 }
521 
524 {
525  // return the address of the tun device
526  return m_pgw->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal ();
527 }
528 
531 {
532  // return the address of the tun device
533  return m_pgw->GetObject<Ipv6> ()->GetAddress (1, 1).GetAddress ();
534 }
535 
536 
537 Ptr<Node>
539 {
540  return m_sgw;
541 }
542 
543 
544 void
545 NoBackhaulEpcHelper::AddS1Interface (Ptr<Node> enb, Ipv4Address enbAddress, Ipv4Address sgwAddress, uint16_t cellId)
546 {
547  NS_LOG_FUNCTION (this << enb << enbAddress << sgwAddress << cellId);
548 
549  // create S1-U socket for the ENB
550  Ptr<Socket> enbS1uSocket = Socket::CreateSocket (enb, TypeId::LookupByName ("ns3::UdpSocketFactory"));
551  int retval = enbS1uSocket->Bind (InetSocketAddress (enbAddress, m_gtpuUdpPort));
552  NS_ASSERT (retval == 0);
553 
555  NS_ASSERT_MSG (enbApp != 0, "EpcEnbApplication not available");
556  enbApp->AddS1Interface (enbS1uSocket, enbAddress, sgwAddress);
557 
558  NS_LOG_INFO ("Connect S1-AP interface");
559  if (cellId == 0)
560  {
561  Ptr<LteEnbNetDevice> enbLteDev = enb->GetDevice (0)->GetObject<LteEnbNetDevice> ();
562  NS_ASSERT_MSG (enbLteDev, "LteEnbNetDevice is missing");
563  cellId = enbLteDev->GetCellId ();
564  }
565  m_mmeApp->AddEnb (cellId, enbAddress, enbApp->GetS1apSapEnb ());
566  m_sgwApp->AddEnb (cellId, enbAddress, sgwAddress);
567  enbApp->SetS1apSapMme (m_mmeApp->GetS1apSapMme ());
568 }
569 
570 } // namespace ns3
void Dispose(void)
Dispose of this Object.
Definition: object.cc:214
Ptr< const AttributeChecker > MakeStringChecker(void)
Definition: string.cc:30
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:157
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
void ActivateEpsBearer(EpsBearer bearer, Ptr< EpcTft > tft)
Activate an EPS bearer.
Definition: epc-ue-nas.cc:187
an Inet address class
static Ipv4Address GetAny(void)
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Ipv6AddressHelper m_uePgwAddressHelper6
helper to assign IPv6 addresses to UE devices as well as to the TUN device of the SGW/PGW ...
virtual ~NoBackhaulEpcHelper()
Destructor.
AttributeValue implementation for Boolean.
Definition: boolean.h:36
virtual void AddEnb(Ptr< Node > enbNode, Ptr< NetDevice > lteEnbNetDevice, uint16_t cellId)
Add an eNB to the EPC.
Ipv4AddressHelper m_x2Ipv4AddressHelper
helper to assign addresses to X2 NetDevices
Keep track of a set of IPv6 interfaces.
holds a vector of std::pair of Ptr<Ipv4> and interface index.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Iterator End(void) const
Get an iterator which indicates past-the-last NetDevice in the container.
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition: ipv6.h:81
Hold variables of type string.
Definition: string.h:41
void SetDefaultRouteInAllNodes(uint32_t router)
Set the default route for all the devices (except the router itself).
NetDeviceContainer Install(NodeContainer c)
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:142
uint16_t m_gtpcUdpPort
UDP port where the GTPv2-C Socket is bound, fixed by the standard as 2123.
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:84
Ptr< EpcMmeApplication > m_mmeApp
MME application.
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:252
Ptr< EpcSgwApplication > m_sgwApp
SGW application.
an address for a packet socket
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
virtual Ipv6Address GetUeDefaultGatewayAddress6()
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:204
aggregate IP/TCP/UDP functionality to existing Nodes.
void SetBase(Ipv6Address network, Ipv6Prefix prefix, Ipv6Address base=Ipv6Address("::1"))
Set the base network number, network prefix, and base interface ID.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:280
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Callback< R > MakeNullCallback(void)
Definition: callback.h:1635
Build a set of PointToPointNetDevice objects.
static TypeId GetTypeId(void)
Register this type.
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
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.
a polymophic address class
Definition: address.h:90
Ptr< const AttributeChecker > MakeDataRateChecker(void)
Definition: data-rate.cc:30
Time m_x2LinkDelay
The delay to be used for the next X2 link to be created.
DataRate m_x2LinkDataRate
The data rate to be used for the next X2 link to be created.
Ipv6InterfaceContainer Assign(const NetDeviceContainer &c)
Allocate an Ipv6InterfaceContainer with auto-assigned addresses.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
std::string m_x2LinkPcapPrefix
Prefix for the PCAP file for the X2 link.
Class for representing data rates.
Definition: data-rate.h:88
virtual Ipv4InterfaceContainer AssignUeIpv4Address(NetDeviceContainer ueDevices)
Assign IPv4 addresses to UE devices.
void EnablePcapAll(std::string prefix, bool promiscuous=false)
Enable pcap output on each device (which is of the appropriate type) in the set of all nodes created ...
static Mac48Address Allocate(void)
Allocate a new Mac48Address.
Ptr< Node > m_mme
MME network element.
Ipv4AddressHelper m_s5Ipv4AddressHelper
S5 interfaces.
AttributeValue implementation for Time.
Definition: nstime.h:1124
virtual Ipv6InterfaceAddress GetAddress(uint32_t interface, uint32_t addressIndex) const =0
Get IPv6 address on specified IPv6 interface.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
uint16_t GetCellId() const
Iterator Begin(void) const
Get an iterator which refers to the first NetDevice in the container.
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
Ptr< VirtualNetDevice > m_tunDevice
TUN device implementing tunneling of user data over GTP-U/UDP/IP.
Hold an unsigned integer type.
Definition: uinteger.h:44
virtual void SetAddress(Address address)
Set the address of this interface.
virtual uint8_t ActivateEpsBearer(Ptr< NetDevice > ueLteDevice, uint64_t imsi, Ptr< EpcTft > tft, EpsBearer bearer)
Activate an EPS bearer, setting up the corresponding S1-U tunnel.
Ptr< Application > GetApplication(uint32_t index) const
Retrieve the index-th Application associated to this node.
Definition: node.cc:168
virtual Ipv6InterfaceContainer AssignUeIpv6Address(NetDeviceContainer ueDevices)
Assign IPv6 addresses to UE devices.
Time m_s11LinkDelay
The delay to be used for the next S11 link to be created.
List of Attribute name, value and checker triples used to construct Objects.
holds a vector of ns3::NetDevice pointers
uint16_t m_gtpuUdpPort
UDP port where the GTP-U Socket is bound, fixed by the standard as 2152.
DataRate m_s5LinkDataRate
The data rate to be used for the next S5 link to be created.
virtual void AddS1Interface(Ptr< Node > enb, Ipv4Address enbAddress, Ipv4Address sgwAddress, uint16_t cellId=0)
Add an S1 interface between an eNB and a SGW.
uint16_t m_x2LinkMtu
The MTU of the next X2 link to be created.
static Mac48Address GetBroadcast(void)
An implementation of the ICMPv6 protocol.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:71
Ptr< const AttributeAccessor > MakeDataRateAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: data-rate.h:242
Ptr< Node > m_sgw
SGW network element.
bool RecvFromTunDevice(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
Method to be assigned to the callback of the SGi TUN VirtualNetDevice.
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:76
Ptr< Ipv6StaticRouting > GetStaticRouting(Ptr< Ipv6 > ipv6) const
Get Ipv6StaticRouting pointer from IPv6 stack.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:459
Create an EPC network with PointToPoint links between the core network nodes.
DataRate m_s11LinkDataRate
The data rate to be used for the next S11 link to be created.
Base helper class to handle the creation of the EPC entities.
Definition: epc-helper.h:49
virtual void DoDispose()
Destructor implementation.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SetPhysicalAddress(const Address address)
Set the destination address.
This entity is installed inside an eNB and provides the functionality for the X2 interface.
Definition: epc-x2.h:99
Ptr< Node > m_pgw
PGW network element.
Helper class that adds ns3::Ipv6StaticRouting objects.
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
bool m_x2LinkEnablePcap
Enable PCAP generation for X2 link.
void ConstructSelf(const AttributeConstructionList &attributes)
Complete construction of ObjectBase; invoked by derived classes.
Definition: object-base.cc:80
This class contains the specification of EPS Bearers.
Definition: eps-bearer.h:91
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Schedule an event to expire Now.
Definition: simulator.h:1578
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:1125
Time m_s5LinkDelay
The delay to be used for the next S5 link to be created.
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
virtual void DoActivateEpsBearerForUe(const Ptr< NetDevice > &ueDevice, const Ptr< EpcTft > &tft, const EpsBearer &bearer) const
DoActivateEpsBearerForUe: Schedule ActivateEpsBearer on the UE.
virtual void AddUe(Ptr< NetDevice > ueLteDevice, uint64_t imsi)
Notify the EPC of the existence of a new UE which might attach at a later time.
Describes an IPv6 address.
Definition: ipv6-address.h:49
Ipv4AddressHelper m_s11Ipv4AddressHelper
Helper to assign addresses to S11 NetDevices.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
This application is installed inside eNBs and provides the bridge functionality for user data plane p...
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:128
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:264
AttributeValue implementation for DataRate.
Definition: data-rate.h:242
virtual Ptr< Node > GetPgwNode() const
Get the PGW node.
std::vector< Ptr< NetDevice > >::const_iterator Iterator
NetDevice container iterator.
uint16_t m_s5LinkMtu
The MTU of the next S5 link to be created.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1062
TypeId GetInstanceTypeId() const
Get the most derived TypeId for this Object.
void SetProtocol(uint16_t protocol)
Set the protocol.
uint16_t m_s11LinkMtu
The MTU of the next S11 link to be created.
uint32_t GetNApplications(void) const
Definition: node.cc:176
Describes an IPv6 prefix.
Definition: ipv6-address.h:449
Ipv4Address NewNetwork(void)
Increment the network number and reset the IP address counter to the base value provided in the SetBa...
virtual void AddX2Interface(Ptr< Node > enbNode1, Ptr< Node > enbNode2)
Add an X2 interface between two eNB.
Ptr< const AttributeAccessor > MakeStringAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: string.h:42
virtual void DoAddX2Interface(const Ptr< EpcX2 > &enb1X2, const Ptr< NetDevice > &enb1LteDev, const Ipv4Address &enb1X2Address, const Ptr< EpcX2 > &enb2X2, const Ptr< NetDevice > &enb2LteDev, const Ipv4Address &enb2X2Address) const
DoAddX2Interface: Call AddX2Interface on top of the Enb device pointers.
void SetSendCallback(SendCallback transmitCb)
Set the user callback to be called when a L2 packet is to be transmitted.
virtual Ptr< Node > GetSgwNode() const
Get the SGW node.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
The eNodeB device implementation.
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: uinteger.h:45
a unique identifier for an interface.
Definition: type-id.h:58
Ptr< LteEnbRrc > GetRrc() const
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:915
static const uint16_t PROT_NUMBER
The protocol number for IPv6 (0x86DD).
virtual uint32_t GetNInterfaces(void) const =0
virtual Ipv4Address GetUeDefaultGatewayAddress()
Ptr< EpcPgwApplication > m_pgwApp
PGW application.
static const uint16_t PROT_NUMBER
Protocol number (0x0800)
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4AddressHelper m_uePgwAddressHelper
helper to assign IPv4 addresses to UE devices as well as to the TUN device of the SGW/PGW ...
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:824