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
36
38 : m_gtpuUdpPort(2152), // fixed by the standard
39 m_s11LinkDataRate(DataRate("10Gb/s")),
41 m_s11LinkMtu(3000),
42 m_gtpcUdpPort(2123), // fixed by the standard
43 m_s5LinkDataRate(DataRate("10Gb/s")),
45 m_s5LinkMtu(3000)
46{
47 NS_LOG_FUNCTION(this);
48}
49
50void
52{
54
55 int retval;
56
57 // since we use point-to-point links for links between the core network nodes,
58 // we use a /30 subnet which can hold exactly two addresses
59 // (remember that net broadcast and null address are not valid)
60 m_x2Ipv4AddressHelper.SetBase("12.0.0.0", "255.255.255.252");
61 m_s11Ipv4AddressHelper.SetBase("13.0.0.0", "255.255.255.252");
62 m_s5Ipv4AddressHelper.SetBase("14.0.0.0", "255.255.255.252");
63
64 // we use a /8 net for all UEs
65 m_uePgwAddressHelper.SetBase("7.0.0.0", "255.0.0.0");
66
67 // we use a /64 IPv6 net all UEs
68 m_uePgwAddressHelper6.SetBase("7777:f00d::", Ipv6Prefix(64));
69
70 // Create PGW, SGW and MME nodes
74 InternetStackHelper internet;
75 internet.Install(m_pgw);
76 internet.Install(m_sgw);
77 internet.Install(m_mme);
78
79 // The Tun device resides in different 64 bit subnet.
80 // We must create an unique route to tun device for all the packets destined
81 // to all 64 bit IPv6 prefixes of UEs, based by the unique 48 bit network prefix of this EPC
82 // network
83 Ipv6StaticRoutingHelper ipv6RoutingHelper;
84 Ptr<Ipv6StaticRouting> pgwStaticRouting =
85 ipv6RoutingHelper.GetStaticRouting(m_pgw->GetObject<Ipv6>());
86 pgwStaticRouting->AddNetworkRouteTo("7777:f00d::", Ipv6Prefix(64), Ipv6Address("::"), 1, 0);
87
88 // create TUN device implementing tunneling of user data over GTP-U/UDP/IP in the PGW
90
91 // allow jumbo packets
92 m_tunDevice->SetAttribute("Mtu", UintegerValue(30000));
93
94 // yes we need this
96
97 m_pgw->AddDevice(m_tunDevice);
98 NetDeviceContainer tunDeviceContainer;
99 tunDeviceContainer.Add(m_tunDevice);
100 // the TUN device is on the same subnet as the UEs, so when a packet
101 // addressed to an UE arrives at the internet to the WAN interface of
102 // the PGW it will be forwarded to the TUN device.
103 Ipv4InterfaceContainer tunDeviceIpv4IfContainer = AssignUeIpv4Address(tunDeviceContainer);
104
105 // the TUN device for IPv6 address is on the different subnet as the
106 // UEs, it will forward the UE packets as we have inserted the route
107 // for all UEs at the time of assigning UE addresses
108 Ipv6InterfaceContainer tunDeviceIpv6IfContainer = AssignUeIpv6Address(tunDeviceContainer);
109
110 // Set Forwarding of the IPv6 interface
111 tunDeviceIpv6IfContainer.SetForwarding(0, true);
112 tunDeviceIpv6IfContainer.SetDefaultRouteInAllNodes(0);
113
114 // Create S5 link between PGW and SGW
119 NetDeviceContainer pgwSgwDevices = p2ph.Install(m_pgw, m_sgw);
120 NS_LOG_LOGIC("IPv4 ifaces of the PGW after installing p2p dev: "
121 << m_pgw->GetObject<Ipv4>()->GetNInterfaces());
122 NS_LOG_LOGIC("IPv4 ifaces of the SGW after installing p2p dev: "
123 << m_sgw->GetObject<Ipv4>()->GetNInterfaces());
124 Ptr<NetDevice> pgwDev = pgwSgwDevices.Get(0);
125 Ptr<NetDevice> sgwDev = pgwSgwDevices.Get(1);
126 m_s5Ipv4AddressHelper.NewNetwork();
127 Ipv4InterfaceContainer pgwSgwIpIfaces = m_s5Ipv4AddressHelper.Assign(pgwSgwDevices);
128 NS_LOG_LOGIC("IPv4 ifaces of the PGW after assigning Ipv4 addr to S5 dev: "
129 << m_pgw->GetObject<Ipv4>()->GetNInterfaces());
130 NS_LOG_LOGIC("IPv4 ifaces of the SGW after assigning Ipv4 addr to S5 dev: "
131 << m_sgw->GetObject<Ipv4>()->GetNInterfaces());
132
133 Ipv4Address pgwS5Address = pgwSgwIpIfaces.GetAddress(0);
134 Ipv4Address sgwS5Address = pgwSgwIpIfaces.GetAddress(1);
135
136 // Create S5-U socket in the PGW
137 Ptr<Socket> pgwS5uSocket =
138 Socket::CreateSocket(m_pgw, TypeId::LookupByName("ns3::UdpSocketFactory"));
139 retval = pgwS5uSocket->Bind(InetSocketAddress(pgwS5Address, m_gtpuUdpPort));
140 NS_ASSERT(retval == 0);
141
142 // Create S5-C socket in the PGW
143 Ptr<Socket> pgwS5cSocket =
144 Socket::CreateSocket(m_pgw, TypeId::LookupByName("ns3::UdpSocketFactory"));
145 retval = pgwS5cSocket->Bind(InetSocketAddress(pgwS5Address, m_gtpcUdpPort));
146 NS_ASSERT(retval == 0);
147
148 // Create EpcPgwApplication
149 m_pgwApp =
150 CreateObject<EpcPgwApplication>(m_tunDevice, pgwS5Address, pgwS5uSocket, pgwS5cSocket);
151 m_pgw->AddApplication(m_pgwApp);
152
153 // Connect EpcPgwApplication and virtual net device for tunneling
155
156 // Create S5-U socket in the SGW
157 Ptr<Socket> sgwS5uSocket =
158 Socket::CreateSocket(m_sgw, TypeId::LookupByName("ns3::UdpSocketFactory"));
159 retval = sgwS5uSocket->Bind(InetSocketAddress(sgwS5Address, m_gtpuUdpPort));
160 NS_ASSERT(retval == 0);
161
162 // Create S5-C socket in the SGW
163 Ptr<Socket> sgwS5cSocket =
164 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 =
170 Socket::CreateSocket(m_sgw, TypeId::LookupByName("ns3::UdpSocketFactory"));
171 retval = sgwS1uSocket->Bind(InetSocketAddress(Ipv4Address::GetAny(), m_gtpuUdpPort));
172 NS_ASSERT(retval == 0);
173
174 // Create EpcSgwApplication
175 m_sgwApp =
176 CreateObject<EpcSgwApplication>(sgwS1uSocket, sgwS5Address, sgwS5uSocket, sgwS5cSocket);
177 m_sgw->AddApplication(m_sgwApp);
178 m_sgwApp->AddPgw(pgwS5Address);
179 m_pgwApp->AddSgw(sgwS5Address);
180
181 // Create S11 link between MME and SGW
182 PointToPointHelper s11P2ph;
186 NetDeviceContainer mmeSgwDevices = s11P2ph.Install(m_mme, m_sgw);
187 NS_LOG_LOGIC("MME's IPv4 ifaces after installing p2p dev: "
188 << m_mme->GetObject<Ipv4>()->GetNInterfaces());
189 NS_LOG_LOGIC("SGW's IPv4 ifaces after installing p2p dev: "
190 << m_sgw->GetObject<Ipv4>()->GetNInterfaces());
191 Ptr<NetDevice> mmeDev = mmeSgwDevices.Get(0);
192 Ptr<NetDevice> sgwS11Dev = mmeSgwDevices.Get(1);
193 m_s11Ipv4AddressHelper.NewNetwork();
194 Ipv4InterfaceContainer mmeSgwIpIfaces = m_s11Ipv4AddressHelper.Assign(mmeSgwDevices);
195 NS_LOG_LOGIC("MME's IPv4 ifaces after assigning Ipv4 addr to S11 dev: "
196 << m_mme->GetObject<Ipv4>()->GetNInterfaces());
197 NS_LOG_LOGIC("SGW's IPv4 ifaces after assigning Ipv4 addr to S11 dev: "
198 << m_sgw->GetObject<Ipv4>()->GetNInterfaces());
199
200 Ipv4Address mmeS11Address = mmeSgwIpIfaces.GetAddress(0);
201 Ipv4Address sgwS11Address = mmeSgwIpIfaces.GetAddress(1);
202
203 // Create S11 socket in the MME
204 Ptr<Socket> mmeS11Socket =
205 Socket::CreateSocket(m_mme, TypeId::LookupByName("ns3::UdpSocketFactory"));
206 retval = mmeS11Socket->Bind(InetSocketAddress(mmeS11Address, m_gtpcUdpPort));
207 NS_ASSERT(retval == 0);
208
209 // Create S11 socket in the SGW
210 Ptr<Socket> sgwS11Socket =
211 Socket::CreateSocket(m_sgw, TypeId::LookupByName("ns3::UdpSocketFactory"));
212 retval = sgwS11Socket->Bind(InetSocketAddress(sgwS11Address, m_gtpcUdpPort));
213 NS_ASSERT(retval == 0);
214
215 // Create MME Application and connect with SGW via S11 interface
217 m_mme->AddApplication(m_mmeApp);
218 m_mmeApp->AddSgw(sgwS11Address, mmeS11Address, mmeS11Socket);
219 m_sgwApp->AddMme(mmeS11Address, sgwS11Socket);
220}
221
226
227TypeId
229{
231 static TypeId tid =
232 TypeId("ns3::NoBackhaulEpcHelper")
234 .SetGroupName("Lte")
235 .AddConstructor<NoBackhaulEpcHelper>()
236 .AddAttribute("S5LinkDataRate",
237 "The data rate to be used for the next S5 link to be created",
238 DataRateValue(DataRate("10Gb/s")),
241 .AddAttribute("S5LinkDelay",
242 "The delay to be used for the next S5 link to be created",
243 TimeValue(Seconds(0)),
246 .AddAttribute("S5LinkMtu",
247 "The MTU of the next S5 link to be created",
248 UintegerValue(2000),
251 .AddAttribute("S11LinkDataRate",
252 "The data rate to be used for the next S11 link to be created",
253 DataRateValue(DataRate("10Gb/s")),
256 .AddAttribute("S11LinkDelay",
257 "The delay to be used for the next S11 link to be created",
258 TimeValue(Seconds(0)),
261 .AddAttribute("S11LinkMtu",
262 "The MTU of the next S11 link to be created.",
263 UintegerValue(2000),
266 .AddAttribute("X2LinkDataRate",
267 "The data rate to be used for the next X2 link to be created",
268 DataRateValue(DataRate("10Gb/s")),
271 .AddAttribute("X2LinkDelay",
272 "The delay to be used for the next X2 link to be created",
273 TimeValue(Seconds(0)),
276 .AddAttribute("X2LinkMtu",
277 "The MTU of the next X2 link to be created. Note that, because of some "
278 "big X2 messages, you need a big MTU.",
279 UintegerValue(3000),
282 .AddAttribute("X2LinkPcapPrefix",
283 "Prefix for Pcap generated by X2 link",
284 StringValue("x2"),
287 .AddAttribute("X2LinkEnablePcap",
288 "Enable Pcap for X2 link",
289 BooleanValue(false),
292 return tid;
293}
294
295void
297{
298 NS_LOG_FUNCTION(this);
299 m_tunDevice->SetSendCallback(
300 MakeNullCallback<bool, Ptr<Packet>, const Address&, const Address&, uint16_t>());
301 m_tunDevice = nullptr;
302 m_sgwApp = nullptr;
303 m_sgw->Dispose();
304 m_pgwApp = nullptr;
305 m_pgw->Dispose();
306 m_mmeApp = nullptr;
307 m_mme->Dispose();
308}
309
310void
312 Ptr<NetDevice> lteEnbNetDevice,
313 std::vector<uint16_t> cellIds)
314{
315 NS_LOG_FUNCTION(this << enb << lteEnbNetDevice << cellIds.size());
316 NS_ASSERT(enb == lteEnbNetDevice->GetNode());
317
318 int retval;
319
320 // add an IPv4 stack to the previously created eNB
321 InternetStackHelper internet;
322 internet.Install(enb);
323 NS_LOG_LOGIC("number of Ipv4 ifaces of the eNB after node creation: "
324 << enb->GetObject<Ipv4>()->GetNInterfaces());
325
326 // create LTE socket for the ENB
327 Ptr<Socket> enbLteSocket =
328 Socket::CreateSocket(enb, TypeId::LookupByName("ns3::PacketSocketFactory"));
329 PacketSocketAddress enbLteSocketBindAddress;
330 enbLteSocketBindAddress.SetSingleDevice(lteEnbNetDevice->GetIfIndex());
331 enbLteSocketBindAddress.SetProtocol(Ipv4L3Protocol::PROT_NUMBER);
332 retval = enbLteSocket->Bind(enbLteSocketBindAddress);
333 NS_ASSERT(retval == 0);
334 PacketSocketAddress enbLteSocketConnectAddress;
335 enbLteSocketConnectAddress.SetPhysicalAddress(Mac48Address::GetBroadcast());
336 enbLteSocketConnectAddress.SetSingleDevice(lteEnbNetDevice->GetIfIndex());
337 enbLteSocketConnectAddress.SetProtocol(Ipv4L3Protocol::PROT_NUMBER);
338 retval = enbLteSocket->Connect(enbLteSocketConnectAddress);
339 NS_ASSERT(retval == 0);
340
341 // create LTE socket for the ENB
342 Ptr<Socket> enbLteSocket6 =
343 Socket::CreateSocket(enb, TypeId::LookupByName("ns3::PacketSocketFactory"));
344 PacketSocketAddress enbLteSocketBindAddress6;
345 enbLteSocketBindAddress6.SetSingleDevice(lteEnbNetDevice->GetIfIndex());
346 enbLteSocketBindAddress6.SetProtocol(Ipv6L3Protocol::PROT_NUMBER);
347 retval = enbLteSocket6->Bind(enbLteSocketBindAddress6);
348 NS_ASSERT(retval == 0);
349 PacketSocketAddress enbLteSocketConnectAddress6;
350 enbLteSocketConnectAddress6.SetPhysicalAddress(Mac48Address::GetBroadcast());
351 enbLteSocketConnectAddress6.SetSingleDevice(lteEnbNetDevice->GetIfIndex());
352 enbLteSocketConnectAddress6.SetProtocol(Ipv6L3Protocol::PROT_NUMBER);
353 retval = enbLteSocket6->Connect(enbLteSocketConnectAddress6);
354 NS_ASSERT(retval == 0);
355
356 NS_LOG_INFO("Create EpcEnbApplication for cell ID " << cellIds.at(0));
358 CreateObject<EpcEnbApplication>(enbLteSocket, enbLteSocket6, cellIds.at(0));
359 enb->AddApplication(enbApp);
360 NS_ASSERT(enb->GetNApplications() == 1);
361 NS_ASSERT_MSG(enb->GetApplication(0)->GetObject<EpcEnbApplication>(),
362 "cannot retrieve EpcEnbApplication");
363 NS_LOG_LOGIC("enb: " << enb << ", enb->GetApplication (0): " << enb->GetApplication(0));
364
365 NS_LOG_INFO("Create EpcX2 entity");
367 enb->AggregateObject(x2);
368}
369
370void
372{
373 NS_LOG_FUNCTION(this << enb1 << enb2);
374
375 // Create a point to point link between the two eNBs with
376 // the corresponding new NetDevices on each side
381 NetDeviceContainer enbDevices = p2ph.Install(enb1, enb2);
382 NS_LOG_LOGIC("number of Ipv4 ifaces of the eNB #1 after installing p2p dev: "
383 << enb1->GetObject<Ipv4>()->GetNInterfaces());
384 NS_LOG_LOGIC("number of Ipv4 ifaces of the eNB #2 after installing p2p dev: "
385 << enb2->GetObject<Ipv4>()->GetNInterfaces());
386
388 {
390 }
391
392 m_x2Ipv4AddressHelper.NewNetwork();
393 Ipv4InterfaceContainer enbIpIfaces = m_x2Ipv4AddressHelper.Assign(enbDevices);
394 NS_LOG_LOGIC("number of Ipv4 ifaces of the eNB #1 after assigning Ipv4 addr to X2 dev: "
395 << enb1->GetObject<Ipv4>()->GetNInterfaces());
396 NS_LOG_LOGIC("number of Ipv4 ifaces of the eNB #2 after assigning Ipv4 addr to X2 dev: "
397 << enb2->GetObject<Ipv4>()->GetNInterfaces());
398
399 Ipv4Address enb1X2Address = enbIpIfaces.GetAddress(0);
400 Ipv4Address enb2X2Address = enbIpIfaces.GetAddress(1);
401
402 // Add X2 interface to both eNBs' X2 entities
403 Ptr<EpcX2> enb1X2 = enb1->GetObject<EpcX2>();
404 Ptr<EpcX2> enb2X2 = enb2->GetObject<EpcX2>();
405
406 Ptr<NetDevice> enb1LteDev = enb1->GetDevice(0);
407 Ptr<NetDevice> enb2LteDev = enb2->GetDevice(0);
408
409 DoAddX2Interface(enb1X2, enb1LteDev, enb1X2Address, enb2X2, enb2LteDev, enb2X2Address);
410}
411
412void
414 const Ptr<NetDevice>& enb1LteDev,
415 const Ipv4Address& enb1X2Address,
416 const Ptr<EpcX2>& enb2X2,
417 const Ptr<NetDevice>& enb2LteDev,
418 const Ipv4Address& enb2X2Address) const
419{
420 NS_LOG_FUNCTION(this);
421
422 Ptr<LteEnbNetDevice> enb1LteDevice = enb1LteDev->GetObject<LteEnbNetDevice>();
423 Ptr<LteEnbNetDevice> enb2LteDevice = enb2LteDev->GetObject<LteEnbNetDevice>();
424
425 NS_ABORT_MSG_IF(!enb1LteDevice, "Unable to find LteEnbNetDevice for the first eNB");
426 NS_ABORT_MSG_IF(!enb2LteDevice, "Unable to find LteEnbNetDevice for the second eNB");
427
428 std::vector<uint16_t> enb1CellIds = enb1LteDevice->GetCellIds();
429 std::vector<uint16_t> enb2CellIds = enb2LteDevice->GetCellIds();
430
431 uint16_t enb1CellId = enb1CellIds.at(0);
432 uint16_t enb2CellId = enb2CellIds.at(0);
433
434 NS_LOG_LOGIC("LteEnbNetDevice #1 = " << enb1LteDev << " - CellId = " << enb1CellId);
435 NS_LOG_LOGIC("LteEnbNetDevice #2 = " << enb2LteDev << " - CellId = " << enb2CellId);
436
437 enb1X2->AddX2Interface(enb1CellId, enb1X2Address, enb2CellIds, enb2X2Address);
438 enb2X2->AddX2Interface(enb2CellId, enb2X2Address, enb1CellIds, enb1X2Address);
439
440 enb1LteDevice->GetRrc()->AddX2Neighbour(enb2CellId);
441 enb2LteDevice->GetRrc()->AddX2Neighbour(enb1CellId);
442}
443
444void
446{
447 NS_LOG_FUNCTION(this << imsi << ueDevice);
448
449 m_mmeApp->AddUe(imsi);
450 m_pgwApp->AddUe(imsi);
451}
452
453uint8_t
455 uint64_t imsi,
456 Ptr<EpcTft> tft,
457 EpsBearer bearer)
458{
459 NS_LOG_FUNCTION(this << ueDevice << imsi);
460
461 // we now retrieve the IPv4/IPv6 address of the UE and notify it to the SGW;
462 // we couldn't do it before since address assignment is triggered by
463 // the user simulation program, rather than done by the EPC
464 Ptr<Node> ueNode = ueDevice->GetNode();
465 Ptr<Ipv4> ueIpv4 = ueNode->GetObject<Ipv4>();
466 Ptr<Ipv6> ueIpv6 = ueNode->GetObject<Ipv6>();
467 NS_ASSERT_MSG(ueIpv4 || ueIpv6,
468 "UEs need to have IPv4/IPv6 installed before EPS bearers can be activated");
469
470 if (ueIpv4)
471 {
472 int32_t interface = ueIpv4->GetInterfaceForDevice(ueDevice);
473 if (interface >= 0 && ueIpv4->GetNAddresses(interface) == 1)
474 {
475 Ipv4Address ueAddr = ueIpv4->GetAddress(interface, 0).GetLocal();
476 NS_LOG_LOGIC(" UE IPv4 address: " << ueAddr);
477 m_pgwApp->SetUeAddress(imsi, ueAddr);
478 }
479 }
480 if (ueIpv6)
481 {
482 int32_t interface6 = ueIpv6->GetInterfaceForDevice(ueDevice);
483 if (interface6 >= 0 && ueIpv6->GetNAddresses(interface6) == 2)
484 {
485 Ipv6Address ueAddr6 = ueIpv6->GetAddress(interface6, 1).GetAddress();
486 NS_LOG_LOGIC(" UE IPv6 address: " << ueAddr6);
487 m_pgwApp->SetUeAddress6(imsi, ueAddr6);
488 }
489 }
490 uint8_t bearerId = m_mmeApp->AddBearer(imsi, tft, bearer);
491 DoActivateEpsBearerForUe(ueDevice, tft, bearer);
492
493 return bearerId;
494}
495
496void
498 const Ptr<EpcTft>& tft,
499 const EpsBearer& bearer) const
500{
501 NS_LOG_FUNCTION(this);
502 Ptr<LteUeNetDevice> ueLteDevice = DynamicCast<LteUeNetDevice>(ueDevice);
503 if (!ueLteDevice)
504 {
505 // You may wonder why this is not an assert. Well, take a look in epc-test-s1u-downlink
506 // and -uplink: we are using CSMA to simulate UEs.
507 NS_LOG_WARN("Unable to find LteUeNetDevice while activating the EPS bearer");
508 }
509 else
510 {
511 Simulator::ScheduleNow(&EpcUeNas::ActivateEpsBearer, ueLteDevice->GetNas(), bearer, tft);
512 }
513}
514
517{
518 return m_pgw;
519}
520
526
529{
530 for (auto iter = ueDevices.Begin(); iter != ueDevices.End(); iter++)
531 {
532 Ptr<Icmpv6L4Protocol> icmpv6 = (*iter)->GetNode()->GetObject<Icmpv6L4Protocol>();
533 icmpv6->SetAttribute("DAD", BooleanValue(false));
534 }
535 return m_uePgwAddressHelper6.Assign(ueDevices);
536}
537
540{
541 // return the address of the tun device
542 return m_pgw->GetObject<Ipv4>()->GetAddress(1, 0).GetLocal();
543}
544
547{
548 // return the address of the tun device
549 return m_pgw->GetObject<Ipv6>()->GetAddress(1, 1).GetAddress();
550}
551
554{
555 return m_sgw;
556}
557
558void
560 Ipv4Address enbAddress,
561 Ipv4Address sgwAddress,
562 std::vector<uint16_t> cellIds)
563{
564 NS_LOG_FUNCTION(this << enb << enbAddress << sgwAddress << cellIds.size());
565
566 // create S1-U socket for the ENB
567 Ptr<Socket> enbS1uSocket =
568 Socket::CreateSocket(enb, TypeId::LookupByName("ns3::UdpSocketFactory"));
569 int retval = enbS1uSocket->Bind(InetSocketAddress(enbAddress, m_gtpuUdpPort));
570 NS_ASSERT(retval == 0);
571
572 Ptr<EpcEnbApplication> enbApp = enb->GetApplication(0)->GetObject<EpcEnbApplication>();
573 NS_ASSERT_MSG(enbApp, "EpcEnbApplication not available");
574 enbApp->AddS1Interface(enbS1uSocket, enbAddress, sgwAddress);
575
576 NS_LOG_INFO("Connect S1-AP interface");
577 for (uint16_t cellId : cellIds)
578 {
579 NS_LOG_DEBUG("Adding MME and SGW for cell ID " << cellId);
580 m_mmeApp->AddEnb(cellId, enbAddress, enbApp->GetS1apSapEnb());
581 m_sgwApp->AddEnb(cellId, enbAddress, sgwAddress);
582 }
583 enbApp->SetS1apSapMme(m_mmeApp->GetS1apSapMme());
584}
585
586int64_t
588{
589 int64_t currentStream = stream;
590 NS_ABORT_MSG_UNLESS(m_pgw && m_sgw && m_mme, "Running AssignStreams on empty node pointers");
591 InternetStackHelper internet;
592 NodeContainer nc;
593 nc.Add(m_pgw);
594 nc.Add(m_sgw);
595 nc.Add(m_mme);
596 currentStream += internet.AssignStreams(nc, currentStream);
597 return (currentStream - stream);
598}
599
600} // namespace ns3
a polymophic address class
Definition address.h:90
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...
EpcHelper()
Constructor.
Definition epc-helper.cc:26
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.
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.
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.
void NotifyConstructionCompleted() override
Notifier called once the ObjectBase is fully constructed.
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.
virtual void NotifyConstructionCompleted()
Notifier called once the ObjectBase is fully constructed.
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:67
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:1456
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:1457
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1477
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:1369
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:585