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