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 * 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
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
41namespace ns3
42{
43
44NS_LOG_COMPONENT_DEFINE("NoBackhaulEpcHelper");
45
46NS_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>();
81 InternetStackHelper internet;
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
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
126 NetDeviceContainer pgwSgwDevices = p2ph.Install(m_pgw, m_sgw);
127 NS_LOG_LOGIC("IPv4 ifaces of the PGW after installing p2p dev: "
129 NS_LOG_LOGIC("IPv4 ifaces of the SGW after installing p2p dev: "
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: "
137 NS_LOG_LOGIC("IPv4 ifaces of the SGW after assigning Ipv4 addr to S5 dev: "
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;
193 NetDeviceContainer mmeSgwDevices = s11P2ph.Install(m_mme, m_sgw);
194 NS_LOG_LOGIC("MME's IPv4 ifaces after installing p2p dev: "
196 NS_LOG_LOGIC("SGW's IPv4 ifaces after installing p2p dev: "
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: "
204 NS_LOG_LOGIC("SGW's IPv4 ifaces after assigning Ipv4 addr to S11 dev: "
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
234TypeId
236{
238 static TypeId tid =
239 TypeId("ns3::NoBackhaulEpcHelper")
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)),
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)),
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)),
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
302TypeId
304{
305 return GetTypeId();
306}
307
308void
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
323void
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
334 InternetStackHelper internet;
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));
371 CreateObject<EpcEnbApplication>(enbLteSocket, enbLteSocket6, cellIds.at(0));
372 enb->AddApplication(enbApp);
373 NS_ASSERT(enb->GetNApplications() == 1);
374 NS_ASSERT_MSG(enb->GetApplication(0)->GetObject<EpcEnbApplication>(),
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
383void
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
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
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
425void
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
457void
459{
460 NS_LOG_FUNCTION(this << imsi << ueDevice);
461
462 m_mmeApp->AddUe(imsi);
463 m_pgwApp->AddUe(imsi);
464}
465
466uint8_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
509void
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
530{
531 return m_pgw;
532}
533
536{
537 return m_uePgwAddressHelper.Assign(ueDevices);
538}
539
542{
543 for (NetDeviceContainer::Iterator 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
567{
568 return m_sgw;
569}
570
571void
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
585 Ptr<EpcEnbApplication> enbApp = enb->GetApplication(0)->GetObject<EpcEnbApplication>();
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
599int64_t
601{
602 int64_t currentStream = stream;
603 NS_ABORT_MSG_UNLESS(m_pgw && m_sgw && m_mme, "Running AssignStreams on empty node pointers");
604 InternetStackHelper internet;
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:100
List of Attribute name, value and checker triples used to construct Objects.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Class for representing data rates.
Definition: data-rate.h:89
AttributeValue implementation for DataRate.
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:50
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:79
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.
static Mac48Address GetBroadcast()
static Mac48Address Allocate()
Allocate a new Mac48Address.
holds a vector of ns3::NetDevice pointers
std::vector< Ptr< NetDevice > >::const_iterator Iterator
NetDevice container iterator.
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 AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:169
void ConstructSelf(const AttributeConstructionList &attributes)
Complete construction of ObjectBase; invoked by derived classes.
Definition: object-base.cc:81
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:200
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
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:78
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:606
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
Hold variables of type string.
Definition: string.h:56
AttributeValue implementation for Time.
Definition: nstime.h:1423
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:840
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
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
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeChecker > MakeStringChecker()
Definition: string.cc:30
Ptr< const AttributeAccessor > MakeStringAccessor(T1 a1)
Definition: string.h:57
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1444
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1424
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
Callback< R, Args... > MakeNullCallback()
Definition: callback.h:745
#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
#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:1336
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:702