A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Manuel Requena <manuel.requena@cttc.es>
7 * (based on the original point-to-point-epc-helper.cc)
8 */
9
11
12#include "ns3/boolean.h"
13#include "ns3/epc-enb-application.h"
14#include "ns3/epc-mme-application.h"
15#include "ns3/epc-pgw-application.h"
16#include "ns3/epc-sgw-application.h"
17#include "ns3/epc-ue-nas.h"
18#include "ns3/epc-x2.h"
19#include "ns3/icmpv6-l4-protocol.h"
20#include "ns3/internet-stack-helper.h"
21#include "ns3/ipv6-static-routing-helper.h"
22#include "ns3/log.h"
23#include "ns3/lte-enb-net-device.h"
24#include "ns3/lte-enb-rrc.h"
25#include "ns3/lte-ue-net-device.h"
26#include "ns3/packet-socket-address.h"
27#include "ns3/point-to-point-helper.h"
28#include "ns3/string.h"
29
30namespace ns3
31{
32
33NS_LOG_COMPONENT_DEFINE("NoBackhaulEpcHelper");
34
35NS_OBJECT_ENSURE_REGISTERED(NoBackhaulEpcHelper);
36
38 : m_gtpuUdpPort(2152), // fixed by the standard
39 m_s11LinkDataRate(DataRate("10Gb/s")),
40 m_s11LinkDelay(),
41 m_s11LinkMtu(3000),
42 m_gtpcUdpPort(2123), // fixed by the standard
43 m_s5LinkDataRate(DataRate("10Gb/s")),
44 m_s5LinkDelay(),
45 m_s5LinkMtu(3000)
46{
47 NS_LOG_FUNCTION(this);
48 // To access the attribute value within the constructor
50
51 int retval;
52
53 // since we use point-to-point links for links between the core network nodes,
54 // we use a /30 subnet which can hold exactly two addresses
55 // (remember that net broadcast and null address are not valid)
56 m_x2Ipv4AddressHelper.SetBase("12.0.0.0", "255.255.255.252");
57 m_s11Ipv4AddressHelper.SetBase("13.0.0.0", "255.255.255.252");
58 m_s5Ipv4AddressHelper.SetBase("14.0.0.0", "255.255.255.252");
59
60 // we use a /8 net for all UEs
61 m_uePgwAddressHelper.SetBase("7.0.0.0", "255.0.0.0");
62
63 // we use a /64 IPv6 net all UEs
64 m_uePgwAddressHelper6.SetBase("7777:f00d::", Ipv6Prefix(64));
65
66 // Create PGW, SGW and MME nodes
70 InternetStackHelper internet;
71 internet.Install(m_pgw);
72 internet.Install(m_sgw);
73 internet.Install(m_mme);
74
75 // The Tun device resides in different 64 bit subnet.
76 // We must create an unique route to tun device for all the packets destined
77 // to all 64 bit IPv6 prefixes of UEs, based by the unique 48 bit network prefix of this EPC
78 // network
79 Ipv6StaticRoutingHelper ipv6RoutingHelper;
80 Ptr<Ipv6StaticRouting> pgwStaticRouting =
81 ipv6RoutingHelper.GetStaticRouting(m_pgw->GetObject<Ipv6>());
82 pgwStaticRouting->AddNetworkRouteTo("7777:f00d::", Ipv6Prefix(64), Ipv6Address("::"), 1, 0);
83
84 // create TUN device implementing tunneling of user data over GTP-U/UDP/IP in the PGW
86
87 // allow jumbo packets
88 m_tunDevice->SetAttribute("Mtu", UintegerValue(30000));
89
90 // yes we need this
92
94 NetDeviceContainer tunDeviceContainer;
95 tunDeviceContainer.Add(m_tunDevice);
96 // the TUN device is on the same subnet as the UEs, so when a packet
97 // addressed to an UE arrives at the internet to the WAN interface of
98 // the PGW it will be forwarded to the TUN device.
99 Ipv4InterfaceContainer tunDeviceIpv4IfContainer = AssignUeIpv4Address(tunDeviceContainer);
100
101 // the TUN device for IPv6 address is on the different subnet as the
102 // UEs, it will forward the UE packets as we have inserted the route
103 // for all UEs at the time of assigning UE addresses
104 Ipv6InterfaceContainer tunDeviceIpv6IfContainer = AssignUeIpv6Address(tunDeviceContainer);
105
106 // Set Forwarding of the IPv6 interface
107 tunDeviceIpv6IfContainer.SetForwarding(0, true);
108 tunDeviceIpv6IfContainer.SetDefaultRouteInAllNodes(0);
109
110 // Create S5 link between PGW and SGW
115 NetDeviceContainer pgwSgwDevices = p2ph.Install(m_pgw, m_sgw);
116 NS_LOG_LOGIC("IPv4 ifaces of the PGW after installing p2p dev: "
118 NS_LOG_LOGIC("IPv4 ifaces of the SGW after installing p2p dev: "
120 Ptr<NetDevice> pgwDev = pgwSgwDevices.Get(0);
121 Ptr<NetDevice> sgwDev = pgwSgwDevices.Get(1);
123 Ipv4InterfaceContainer pgwSgwIpIfaces = m_s5Ipv4AddressHelper.Assign(pgwSgwDevices);
124 NS_LOG_LOGIC("IPv4 ifaces of the PGW after assigning Ipv4 addr to S5 dev: "
126 NS_LOG_LOGIC("IPv4 ifaces of the SGW after assigning Ipv4 addr to S5 dev: "
128
129 Ipv4Address pgwS5Address = pgwSgwIpIfaces.GetAddress(0);
130 Ipv4Address sgwS5Address = pgwSgwIpIfaces.GetAddress(1);
131
132 // Create S5-U socket in the PGW
133 Ptr<Socket> pgwS5uSocket =
134 Socket::CreateSocket(m_pgw, TypeId::LookupByName("ns3::UdpSocketFactory"));
135 retval = pgwS5uSocket->Bind(InetSocketAddress(pgwS5Address, m_gtpuUdpPort));
136 NS_ASSERT(retval == 0);
137
138 // Create S5-C socket in the PGW
139 Ptr<Socket> pgwS5cSocket =
140 Socket::CreateSocket(m_pgw, TypeId::LookupByName("ns3::UdpSocketFactory"));
141 retval = pgwS5cSocket->Bind(InetSocketAddress(pgwS5Address, m_gtpcUdpPort));
142 NS_ASSERT(retval == 0);
143
144 // Create EpcPgwApplication
145 m_pgwApp =
146 CreateObject<EpcPgwApplication>(m_tunDevice, pgwS5Address, pgwS5uSocket, pgwS5cSocket);
148
149 // Connect EpcPgwApplication and virtual net device for tunneling
151
152 // Create S5-U socket in the SGW
153 Ptr<Socket> sgwS5uSocket =
154 Socket::CreateSocket(m_sgw, TypeId::LookupByName("ns3::UdpSocketFactory"));
155 retval = sgwS5uSocket->Bind(InetSocketAddress(sgwS5Address, m_gtpuUdpPort));
156 NS_ASSERT(retval == 0);
157
158 // Create S5-C socket in the SGW
159 Ptr<Socket> sgwS5cSocket =
160 Socket::CreateSocket(m_sgw, TypeId::LookupByName("ns3::UdpSocketFactory"));
161 retval = sgwS5cSocket->Bind(InetSocketAddress(sgwS5Address, m_gtpcUdpPort));
162 NS_ASSERT(retval == 0);
163
164 // Create S1-U socket in the SGW
165 Ptr<Socket> sgwS1uSocket =
166 Socket::CreateSocket(m_sgw, TypeId::LookupByName("ns3::UdpSocketFactory"));
167 retval = sgwS1uSocket->Bind(InetSocketAddress(Ipv4Address::GetAny(), m_gtpuUdpPort));
168 NS_ASSERT(retval == 0);
169
170 // Create EpcSgwApplication
171 m_sgwApp =
172 CreateObject<EpcSgwApplication>(sgwS1uSocket, sgwS5Address, sgwS5uSocket, sgwS5cSocket);
174 m_sgwApp->AddPgw(pgwS5Address);
175 m_pgwApp->AddSgw(sgwS5Address);
176
177 // Create S11 link between MME and SGW
178 PointToPointHelper s11P2ph;
182 NetDeviceContainer mmeSgwDevices = s11P2ph.Install(m_mme, m_sgw);
183 NS_LOG_LOGIC("MME's IPv4 ifaces after installing p2p dev: "
185 NS_LOG_LOGIC("SGW's IPv4 ifaces after installing p2p dev: "
187 Ptr<NetDevice> mmeDev = mmeSgwDevices.Get(0);
188 Ptr<NetDevice> sgwS11Dev = mmeSgwDevices.Get(1);
190 Ipv4InterfaceContainer mmeSgwIpIfaces = m_s11Ipv4AddressHelper.Assign(mmeSgwDevices);
191 NS_LOG_LOGIC("MME's IPv4 ifaces after assigning Ipv4 addr to S11 dev: "
193 NS_LOG_LOGIC("SGW's IPv4 ifaces after assigning Ipv4 addr to S11 dev: "
195
196 Ipv4Address mmeS11Address = mmeSgwIpIfaces.GetAddress(0);
197 Ipv4Address sgwS11Address = mmeSgwIpIfaces.GetAddress(1);
198
199 // Create S11 socket in the MME
200 Ptr<Socket> mmeS11Socket =
201 Socket::CreateSocket(m_mme, TypeId::LookupByName("ns3::UdpSocketFactory"));
202 retval = mmeS11Socket->Bind(InetSocketAddress(mmeS11Address, m_gtpcUdpPort));
203 NS_ASSERT(retval == 0);
204
205 // Create S11 socket in the SGW
206 Ptr<Socket> sgwS11Socket =
207 Socket::CreateSocket(m_sgw, TypeId::LookupByName("ns3::UdpSocketFactory"));
208 retval = sgwS11Socket->Bind(InetSocketAddress(sgwS11Address, m_gtpcUdpPort));
209 NS_ASSERT(retval == 0);
210
211 // Create MME Application and connect with SGW via S11 interface
214 m_mmeApp->AddSgw(sgwS11Address, mmeS11Address, mmeS11Socket);
215 m_sgwApp->AddMme(mmeS11Address, sgwS11Socket);
216}
217
222
223TypeId
225{
227 static TypeId tid =
228 TypeId("ns3::NoBackhaulEpcHelper")
230 .SetGroupName("Lte")
231 .AddConstructor<NoBackhaulEpcHelper>()
232 .AddAttribute("S5LinkDataRate",
233 "The data rate to be used for the next S5 link to be created",
234 DataRateValue(DataRate("10Gb/s")),
237 .AddAttribute("S5LinkDelay",
238 "The delay to be used for the next S5 link to be created",
239 TimeValue(Seconds(0)),
242 .AddAttribute("S5LinkMtu",
243 "The MTU of the next S5 link to be created",
244 UintegerValue(2000),
247 .AddAttribute("S11LinkDataRate",
248 "The data rate to be used for the next S11 link to be created",
249 DataRateValue(DataRate("10Gb/s")),
252 .AddAttribute("S11LinkDelay",
253 "The delay to be used for the next S11 link to be created",
254 TimeValue(Seconds(0)),
257 .AddAttribute("S11LinkMtu",
258 "The MTU of the next S11 link to be created.",
259 UintegerValue(2000),
262 .AddAttribute("X2LinkDataRate",
263 "The data rate to be used for the next X2 link to be created",
264 DataRateValue(DataRate("10Gb/s")),
267 .AddAttribute("X2LinkDelay",
268 "The delay to be used for the next X2 link to be created",
269 TimeValue(Seconds(0)),
272 .AddAttribute("X2LinkMtu",
273 "The MTU of the next X2 link to be created. Note that, because of some "
274 "big X2 messages, you need a big MTU.",
275 UintegerValue(3000),
278 .AddAttribute("X2LinkPcapPrefix",
279 "Prefix for Pcap generated by X2 link",
280 StringValue("x2"),
283 .AddAttribute("X2LinkEnablePcap",
284 "Enable Pcap for X2 link",
285 BooleanValue(false),
288 return tid;
289}
290
291void
293{
294 NS_LOG_FUNCTION(this);
295 m_tunDevice->SetSendCallback(
296 MakeNullCallback<bool, Ptr<Packet>, const Address&, const Address&, uint16_t>());
297 m_tunDevice = nullptr;
298 m_sgwApp = nullptr;
299 m_sgw->Dispose();
300 m_pgwApp = nullptr;
301 m_pgw->Dispose();
302 m_mmeApp = nullptr;
303 m_mme->Dispose();
304}
305
306void
308 Ptr<NetDevice> lteEnbNetDevice,
309 std::vector<uint16_t> cellIds)
310{
311 NS_LOG_FUNCTION(this << enb << lteEnbNetDevice << cellIds.size());
312 NS_ASSERT(enb == lteEnbNetDevice->GetNode());
313
314 int retval;
315
316 // add an IPv4 stack to the previously created eNB
317 InternetStackHelper internet;
318 internet.Install(enb);
319 NS_LOG_LOGIC("number of Ipv4 ifaces of the eNB after node creation: "
320 << enb->GetObject<Ipv4>()->GetNInterfaces());
321
322 // create LTE socket for the ENB
323 Ptr<Socket> enbLteSocket =
324 Socket::CreateSocket(enb, TypeId::LookupByName("ns3::PacketSocketFactory"));
325 PacketSocketAddress enbLteSocketBindAddress;
326 enbLteSocketBindAddress.SetSingleDevice(lteEnbNetDevice->GetIfIndex());
327 enbLteSocketBindAddress.SetProtocol(Ipv4L3Protocol::PROT_NUMBER);
328 retval = enbLteSocket->Bind(enbLteSocketBindAddress);
329 NS_ASSERT(retval == 0);
330 PacketSocketAddress enbLteSocketConnectAddress;
331 enbLteSocketConnectAddress.SetPhysicalAddress(Mac48Address::GetBroadcast());
332 enbLteSocketConnectAddress.SetSingleDevice(lteEnbNetDevice->GetIfIndex());
333 enbLteSocketConnectAddress.SetProtocol(Ipv4L3Protocol::PROT_NUMBER);
334 retval = enbLteSocket->Connect(enbLteSocketConnectAddress);
335 NS_ASSERT(retval == 0);
336
337 // create LTE socket for the ENB
338 Ptr<Socket> enbLteSocket6 =
339 Socket::CreateSocket(enb, TypeId::LookupByName("ns3::PacketSocketFactory"));
340 PacketSocketAddress enbLteSocketBindAddress6;
341 enbLteSocketBindAddress6.SetSingleDevice(lteEnbNetDevice->GetIfIndex());
342 enbLteSocketBindAddress6.SetProtocol(Ipv6L3Protocol::PROT_NUMBER);
343 retval = enbLteSocket6->Bind(enbLteSocketBindAddress6);
344 NS_ASSERT(retval == 0);
345 PacketSocketAddress enbLteSocketConnectAddress6;
346 enbLteSocketConnectAddress6.SetPhysicalAddress(Mac48Address::GetBroadcast());
347 enbLteSocketConnectAddress6.SetSingleDevice(lteEnbNetDevice->GetIfIndex());
348 enbLteSocketConnectAddress6.SetProtocol(Ipv6L3Protocol::PROT_NUMBER);
349 retval = enbLteSocket6->Connect(enbLteSocketConnectAddress6);
350 NS_ASSERT(retval == 0);
351
352 NS_LOG_INFO("Create EpcEnbApplication for cell ID " << cellIds.at(0));
354 CreateObject<EpcEnbApplication>(enbLteSocket, enbLteSocket6, cellIds.at(0));
355 enb->AddApplication(enbApp);
356 NS_ASSERT(enb->GetNApplications() == 1);
357 NS_ASSERT_MSG(enb->GetApplication(0)->GetObject<EpcEnbApplication>(),
358 "cannot retrieve EpcEnbApplication");
359 NS_LOG_LOGIC("enb: " << enb << ", enb->GetApplication (0): " << enb->GetApplication(0));
360
361 NS_LOG_INFO("Create EpcX2 entity");
363 enb->AggregateObject(x2);
364}
365
366void
368{
369 NS_LOG_FUNCTION(this << enb1 << enb2);
370
371 // Create a point to point link between the two eNBs with
372 // the corresponding new NetDevices on each side
377 NetDeviceContainer enbDevices = p2ph.Install(enb1, enb2);
378 NS_LOG_LOGIC("number of Ipv4 ifaces of the eNB #1 after installing p2p dev: "
379 << enb1->GetObject<Ipv4>()->GetNInterfaces());
380 NS_LOG_LOGIC("number of Ipv4 ifaces of the eNB #2 after installing p2p dev: "
381 << enb2->GetObject<Ipv4>()->GetNInterfaces());
382
384 {
386 }
387
389 Ipv4InterfaceContainer enbIpIfaces = m_x2Ipv4AddressHelper.Assign(enbDevices);
390 NS_LOG_LOGIC("number of Ipv4 ifaces of the eNB #1 after assigning Ipv4 addr to X2 dev: "
391 << enb1->GetObject<Ipv4>()->GetNInterfaces());
392 NS_LOG_LOGIC("number of Ipv4 ifaces of the eNB #2 after assigning Ipv4 addr to X2 dev: "
393 << enb2->GetObject<Ipv4>()->GetNInterfaces());
394
395 Ipv4Address enb1X2Address = enbIpIfaces.GetAddress(0);
396 Ipv4Address enb2X2Address = enbIpIfaces.GetAddress(1);
397
398 // Add X2 interface to both eNBs' X2 entities
399 Ptr<EpcX2> enb1X2 = enb1->GetObject<EpcX2>();
400 Ptr<EpcX2> enb2X2 = enb2->GetObject<EpcX2>();
401
402 Ptr<NetDevice> enb1LteDev = enb1->GetDevice(0);
403 Ptr<NetDevice> enb2LteDev = enb2->GetDevice(0);
404
405 DoAddX2Interface(enb1X2, enb1LteDev, enb1X2Address, enb2X2, enb2LteDev, enb2X2Address);
406}
407
408void
410 const Ptr<NetDevice>& enb1LteDev,
411 const Ipv4Address& enb1X2Address,
412 const Ptr<EpcX2>& enb2X2,
413 const Ptr<NetDevice>& enb2LteDev,
414 const Ipv4Address& enb2X2Address) const
415{
416 NS_LOG_FUNCTION(this);
417
418 Ptr<LteEnbNetDevice> enb1LteDevice = enb1LteDev->GetObject<LteEnbNetDevice>();
419 Ptr<LteEnbNetDevice> enb2LteDevice = enb2LteDev->GetObject<LteEnbNetDevice>();
420
421 NS_ABORT_MSG_IF(!enb1LteDevice, "Unable to find LteEnbNetDevice for the first eNB");
422 NS_ABORT_MSG_IF(!enb2LteDevice, "Unable to find LteEnbNetDevice for the second eNB");
423
424 std::vector<uint16_t> enb1CellIds = enb1LteDevice->GetCellIds();
425 std::vector<uint16_t> enb2CellIds = enb2LteDevice->GetCellIds();
426
427 uint16_t enb1CellId = enb1CellIds.at(0);
428 uint16_t enb2CellId = enb2CellIds.at(0);
429
430 NS_LOG_LOGIC("LteEnbNetDevice #1 = " << enb1LteDev << " - CellId = " << enb1CellId);
431 NS_LOG_LOGIC("LteEnbNetDevice #2 = " << enb2LteDev << " - CellId = " << enb2CellId);
432
433 enb1X2->AddX2Interface(enb1CellId, enb1X2Address, enb2CellIds, enb2X2Address);
434 enb2X2->AddX2Interface(enb2CellId, enb2X2Address, enb1CellIds, enb1X2Address);
435
436 enb1LteDevice->GetRrc()->AddX2Neighbour(enb2CellId);
437 enb2LteDevice->GetRrc()->AddX2Neighbour(enb1CellId);
438}
439
440void
442{
443 NS_LOG_FUNCTION(this << imsi << ueDevice);
444
445 m_mmeApp->AddUe(imsi);
446 m_pgwApp->AddUe(imsi);
447}
448
449uint8_t
451 uint64_t imsi,
452 Ptr<EpcTft> tft,
453 EpsBearer bearer)
454{
455 NS_LOG_FUNCTION(this << ueDevice << imsi);
456
457 // we now retrieve the IPv4/IPv6 address of the UE and notify it to the SGW;
458 // we couldn't do it before since address assignment is triggered by
459 // the user simulation program, rather than done by the EPC
460 Ptr<Node> ueNode = ueDevice->GetNode();
461 Ptr<Ipv4> ueIpv4 = ueNode->GetObject<Ipv4>();
462 Ptr<Ipv6> ueIpv6 = ueNode->GetObject<Ipv6>();
463 NS_ASSERT_MSG(ueIpv4 || ueIpv6,
464 "UEs need to have IPv4/IPv6 installed before EPS bearers can be activated");
465
466 if (ueIpv4)
467 {
468 int32_t interface = ueIpv4->GetInterfaceForDevice(ueDevice);
469 if (interface >= 0 && ueIpv4->GetNAddresses(interface) == 1)
470 {
471 Ipv4Address ueAddr = ueIpv4->GetAddress(interface, 0).GetLocal();
472 NS_LOG_LOGIC(" UE IPv4 address: " << ueAddr);
473 m_pgwApp->SetUeAddress(imsi, ueAddr);
474 }
475 }
476 if (ueIpv6)
477 {
478 int32_t interface6 = ueIpv6->GetInterfaceForDevice(ueDevice);
479 if (interface6 >= 0 && ueIpv6->GetNAddresses(interface6) == 2)
480 {
481 Ipv6Address ueAddr6 = ueIpv6->GetAddress(interface6, 1).GetAddress();
482 NS_LOG_LOGIC(" UE IPv6 address: " << ueAddr6);
483 m_pgwApp->SetUeAddress6(imsi, ueAddr6);
484 }
485 }
486 uint8_t bearerId = m_mmeApp->AddBearer(imsi, tft, bearer);
487 DoActivateEpsBearerForUe(ueDevice, tft, bearer);
488
489 return bearerId;
490}
491
492void
494 const Ptr<EpcTft>& tft,
495 const EpsBearer& bearer) const
496{
497 NS_LOG_FUNCTION(this);
498 Ptr<LteUeNetDevice> ueLteDevice = DynamicCast<LteUeNetDevice>(ueDevice);
499 if (!ueLteDevice)
500 {
501 // You may wonder why this is not an assert. Well, take a look in epc-test-s1u-downlink
502 // and -uplink: we are using CSMA to simulate UEs.
503 NS_LOG_WARN("Unable to find LteUeNetDevice while activating the EPS bearer");
504 }
505 else
506 {
507 Simulator::ScheduleNow(&EpcUeNas::ActivateEpsBearer, ueLteDevice->GetNas(), bearer, tft);
508 }
509}
510
513{
514 return m_pgw;
515}
516
522
525{
526 for (auto iter = ueDevices.Begin(); iter != ueDevices.End(); iter++)
527 {
528 Ptr<Icmpv6L4Protocol> icmpv6 = (*iter)->GetNode()->GetObject<Icmpv6L4Protocol>();
529 icmpv6->SetAttribute("DAD", BooleanValue(false));
530 }
531 return m_uePgwAddressHelper6.Assign(ueDevices);
532}
533
536{
537 // return the address of the tun device
538 return m_pgw->GetObject<Ipv4>()->GetAddress(1, 0).GetLocal();
539}
540
543{
544 // return the address of the tun device
545 return m_pgw->GetObject<Ipv6>()->GetAddress(1, 1).GetAddress();
546}
547
550{
551 return m_sgw;
552}
553
554void
556 Ipv4Address enbAddress,
557 Ipv4Address sgwAddress,
558 std::vector<uint16_t> cellIds)
559{
560 NS_LOG_FUNCTION(this << enb << enbAddress << sgwAddress << cellIds.size());
561
562 // create S1-U socket for the ENB
563 Ptr<Socket> enbS1uSocket =
564 Socket::CreateSocket(enb, TypeId::LookupByName("ns3::UdpSocketFactory"));
565 int retval = enbS1uSocket->Bind(InetSocketAddress(enbAddress, m_gtpuUdpPort));
566 NS_ASSERT(retval == 0);
567
568 Ptr<EpcEnbApplication> enbApp = enb->GetApplication(0)->GetObject<EpcEnbApplication>();
569 NS_ASSERT_MSG(enbApp, "EpcEnbApplication not available");
570 enbApp->AddS1Interface(enbS1uSocket, enbAddress, sgwAddress);
571
572 NS_LOG_INFO("Connect S1-AP interface");
573 for (uint16_t cellId : cellIds)
574 {
575 NS_LOG_DEBUG("Adding MME and SGW for cell ID " << cellId);
576 m_mmeApp->AddEnb(cellId, enbAddress, enbApp->GetS1apSapEnb());
577 m_sgwApp->AddEnb(cellId, enbAddress, sgwAddress);
578 }
579 enbApp->SetS1apSapMme(m_mmeApp->GetS1apSapMme());
580}
581
582int64_t
584{
585 int64_t currentStream = stream;
586 NS_ABORT_MSG_UNLESS(m_pgw && m_sgw && m_mme, "Running AssignStreams on empty node pointers");
587 InternetStackHelper internet;
588 NodeContainer nc;
589 nc.Add(m_pgw);
590 nc.Add(m_sgw);
591 nc.Add(m_mme);
592 currentStream += internet.AssignStreams(nc, currentStream);
593 return (currentStream - stream);
594}
595
596} // namespace ns3
a polymophic address class
Definition address.h:90
List of Attribute name, value and checker triples used to construct Objects.
AttributeValue implementation for Boolean.
Definition boolean.h:26
Class for representing data rates.
Definition data-rate.h:78
AttributeValue implementation for DataRate.
Definition data-rate.h:285
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:40
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.
This entity is installed inside an eNB and provides the functionality for the X2 interface.
Definition epc-x2.h:88
This class contains the specification of EPS Bearers.
Definition eps-bearer.h:80
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.
static Ipv4Address GetAny()
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition ipv4.h:69
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 constexpr uint16_t PROT_NUMBER
Protocol number.
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.
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition ipv6.h:71
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 constexpr uint16_t PROT_NUMBER
The protocol number for IPv6 (0x86DD).
Describes an IPv6 prefix.
Helper class that adds ns3::Ipv6StaticRouting objects.
Ptr< Ipv6StaticRouting > GetStaticRouting(Ptr< Ipv6 > ipv6) const
Get Ipv6StaticRouting pointer from IPv6 stack.
The eNodeB device implementation.
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.
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:124
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition node.cc:153
void ConstructSelf(const AttributeConstructionList &attributes)
Complete construction of ObjectBase; invoked by derived classes.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
void Dispose()
Dispose of this Object.
Definition object.cc:247
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.
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:595
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:61
Hold variables of type string.
Definition string.h:45
AttributeValue implementation for Time.
Definition nstime.h:1432
a unique identifier for an interface.
Definition type-id.h:49
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition type-id.cc:872
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Hold an unsigned integer type.
Definition uinteger.h:34
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#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:75
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:113
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:70
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:285
Ptr< const AttributeChecker > MakeDataRateChecker()
Definition data-rate.cc:20
Ptr< const AttributeChecker > MakeStringChecker()
Definition string.cc:19
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:46
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:1433
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1453
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
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:35
Callback< R, Args... > MakeNullCallback()
Definition callback.h:727
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition abort.h:133
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#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:250
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1345
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:684
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580