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