A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
epc-pgw-application.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 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 epc-sgw-pgw-application.cc)
19 */
20
21#include "epc-pgw-application.h"
22
23#include "epc-gtpu-header.h"
24
25#include "ns3/abort.h"
26#include "ns3/inet-socket-address.h"
27#include "ns3/ipv4-l3-protocol.h"
28#include "ns3/ipv4.h"
29#include "ns3/ipv6-header.h"
30#include "ns3/ipv6-l3-protocol.h"
31#include "ns3/ipv6.h"
32#include "ns3/log.h"
33#include "ns3/mac48-address.h"
34
35namespace ns3
36{
37
38NS_LOG_COMPONENT_DEFINE("EpcPgwApplication");
39
41// UeInfo
43
45{
46 NS_LOG_FUNCTION(this);
47}
48
49void
51{
52 NS_LOG_FUNCTION(this << (uint16_t)bearerId << teid << tft);
53 m_teidByBearerIdMap[bearerId] = teid;
54 return m_tftClassifier.Add(tft, teid);
55}
56
57void
59{
60 NS_LOG_FUNCTION(this << (uint16_t)bearerId);
61 std::map<uint8_t, uint32_t>::iterator it = m_teidByBearerIdMap.find(bearerId);
62 m_tftClassifier.Delete(it->second); // delete tft
63 m_teidByBearerIdMap.erase(bearerId);
64}
65
68{
69 NS_LOG_FUNCTION(this << p);
70 // we hardcode DOWNLINK direction since the PGW is expected to
71 // classify only downlink packets (uplink packets will go to the
72 // internet without any classification).
73 return m_tftClassifier.Classify(p, EpcTft::DOWNLINK, protocolNumber);
74}
75
78{
79 return m_sgwAddr;
80}
81
82void
84{
85 m_sgwAddr = sgwAddr;
86}
87
90{
91 return m_ueAddr;
92}
93
94void
96{
97 m_ueAddr = ueAddr;
98}
99
102{
103 return m_ueAddr6;
104}
105
106void
108{
109 m_ueAddr6 = ueAddr;
110}
111
113// EpcPgwApplication
115
116TypeId
118{
119 static TypeId tid =
120 TypeId("ns3::EpcPgwApplication")
121 .SetParent<Object>()
122 .SetGroupName("Lte")
123 .AddTraceSource("RxFromTun",
124 "Receive data packets from internet in Tunnel NetDevice",
126 "ns3::EpcPgwApplication::RxTracedCallback")
127 .AddTraceSource("RxFromS1u",
128 "Receive data packets from S5 Socket",
130 "ns3::EpcPgwApplication::RxTracedCallback");
131 return tid;
132}
133
134void
136{
137 NS_LOG_FUNCTION(this);
139 m_s5uSocket = nullptr;
141 m_s5cSocket = nullptr;
142}
143
145 Ipv4Address s5Addr,
146 const Ptr<Socket> s5uSocket,
147 const Ptr<Socket> s5cSocket)
148 : m_pgwS5Addr(s5Addr),
149 m_s5uSocket(s5uSocket),
150 m_s5cSocket(s5cSocket),
151 m_tunDevice(tunDevice),
152 m_gtpuUdpPort(2152), // fixed by the standard
153 m_gtpcUdpPort(2123) // fixed by the standard
154{
155 NS_LOG_FUNCTION(this << tunDevice << s5Addr << s5uSocket << s5cSocket);
158}
159
161{
162 NS_LOG_FUNCTION(this);
163}
164
165bool
167 const Address& source,
168 const Address& dest,
169 uint16_t protocolNumber)
170{
171 NS_LOG_FUNCTION(this << source << dest << protocolNumber << packet << packet->GetSize());
172 m_rxTunPktTrace(packet->Copy());
173
174 // get IP address of UE
175 if (protocolNumber == Ipv4L3Protocol::PROT_NUMBER)
176 {
177 Ipv4Header ipv4Header;
178 packet->PeekHeader(ipv4Header);
179 Ipv4Address ueAddr = ipv4Header.GetDestination();
180 NS_LOG_LOGIC("packet addressed to UE " << ueAddr);
181
182 // find corresponding UeInfo address
183 std::map<Ipv4Address, Ptr<UeInfo>>::iterator it = m_ueInfoByAddrMap.find(ueAddr);
184 if (it == m_ueInfoByAddrMap.end())
185 {
186 NS_LOG_WARN("unknown UE address " << ueAddr);
187 }
188 else
189 {
190 Ipv4Address sgwAddr = it->second->GetSgwAddr();
191 uint32_t teid = it->second->Classify(packet, protocolNumber);
192 if (teid == 0)
193 {
194 NS_LOG_WARN("no matching bearer for this packet");
195 }
196 else
197 {
198 SendToS5uSocket(packet, sgwAddr, teid);
199 }
200 }
201 }
202 else if (protocolNumber == Ipv6L3Protocol::PROT_NUMBER)
203 {
204 Ipv6Header ipv6Header;
205 packet->PeekHeader(ipv6Header);
206 Ipv6Address ueAddr = ipv6Header.GetDestination();
207 NS_LOG_LOGIC("packet addressed to UE " << ueAddr);
208
209 // find corresponding UeInfo address
210 std::map<Ipv6Address, Ptr<UeInfo>>::iterator it = m_ueInfoByAddrMap6.find(ueAddr);
211 if (it == m_ueInfoByAddrMap6.end())
212 {
213 NS_LOG_WARN("unknown UE address " << ueAddr);
214 }
215 else
216 {
217 Ipv4Address sgwAddr = it->second->GetSgwAddr();
218 uint32_t teid = it->second->Classify(packet, protocolNumber);
219 if (teid == 0)
220 {
221 NS_LOG_WARN("no matching bearer for this packet");
222 }
223 else
224 {
225 SendToS5uSocket(packet, sgwAddr, teid);
226 }
227 }
228 }
229 else
230 {
231 NS_ABORT_MSG("Unknown IP type");
232 }
233
234 // there is no reason why we should notify the TUN
235 // VirtualNetDevice that he failed to send the packet: if we receive
236 // any bogus packet, it will just be silently discarded.
237 const bool succeeded = true;
238 return succeeded;
239}
240
241void
243{
244 NS_LOG_FUNCTION(this << socket);
245 NS_ASSERT(socket == m_s5uSocket);
246 Ptr<Packet> packet = socket->Recv();
247 m_rxS5PktTrace(packet->Copy());
248
249 GtpuHeader gtpu;
250 packet->RemoveHeader(gtpu);
251 uint32_t teid = gtpu.GetTeid();
252
253 SendToTunDevice(packet, teid);
254}
255
256void
258{
259 NS_LOG_FUNCTION(this << socket);
260 NS_ASSERT(socket == m_s5cSocket);
261 Ptr<Packet> packet = socket->Recv();
262 GtpcHeader header;
263 packet->PeekHeader(header);
264 uint16_t msgType = header.GetMessageType();
265
266 switch (msgType)
267 {
270 break;
271
274 break;
275
278 break;
279
282 break;
283
284 default:
285 NS_FATAL_ERROR("GTP-C message not supported");
286 break;
287 }
288}
289
290void
292{
293 NS_LOG_FUNCTION(this);
294
296 packet->RemoveHeader(msg);
297 uint64_t imsi = msg.GetImsi();
298 uint16_t cellId = msg.GetUliEcgi();
299 NS_LOG_DEBUG("cellId " << cellId << " IMSI " << imsi);
300
301 std::map<uint64_t, Ptr<UeInfo>>::iterator ueit = m_ueInfoByImsiMap.find(imsi);
302 NS_ASSERT_MSG(ueit != m_ueInfoByImsiMap.end(), "unknown IMSI " << imsi);
303 ueit->second->SetSgwAddr(m_sgwS5Addr);
304
305 GtpcHeader::Fteid_t sgwS5cFteid = msg.GetSenderCpFteid();
306 NS_ASSERT_MSG(sgwS5cFteid.interfaceType == GtpcHeader::S5_SGW_GTPC, "Wrong interface type");
307
309 msgOut.SetTeid(sgwS5cFteid.teid);
311
312 GtpcHeader::Fteid_t pgwS5cFteid;
314 pgwS5cFteid.teid = sgwS5cFteid.teid;
315 pgwS5cFteid.addr = m_pgwS5Addr;
316 msgOut.SetSenderCpFteid(pgwS5cFteid);
317
318 std::list<GtpcCreateSessionRequestMessage::BearerContextToBeCreated> bearerContexts =
320 NS_LOG_DEBUG("BearerContextsToBeCreated size = " << bearerContexts.size());
321
322 std::list<GtpcCreateSessionResponseMessage::BearerContextCreated> bearerContextsCreated;
323 for (auto& bearerContext : bearerContexts)
324 {
325 uint32_t teid = bearerContext.sgwS5uFteid.teid;
326 NS_LOG_DEBUG("bearerId " << (uint16_t)bearerContext.epsBearerId << " SGW "
327 << bearerContext.sgwS5uFteid.addr << " TEID " << teid);
328
329 ueit->second->AddBearer(bearerContext.epsBearerId, teid, bearerContext.tft);
330
333 bearerContextOut.fteid.teid = teid;
334 bearerContextOut.fteid.addr = m_pgwS5Addr;
335 bearerContextOut.epsBearerId = bearerContext.epsBearerId;
336 bearerContextOut.bearerLevelQos = bearerContext.bearerLevelQos;
337 bearerContextOut.tft = bearerContext.tft;
338 bearerContextsCreated.push_back(bearerContextOut);
339 }
340
341 NS_LOG_DEBUG("BearerContextsCreated size = " << bearerContextsCreated.size());
342 msgOut.SetBearerContextsCreated(bearerContextsCreated);
343 msgOut.SetTeid(sgwS5cFteid.teid);
344 msgOut.ComputeMessageLength();
345
346 Ptr<Packet> packetOut = Create<Packet>();
347 packetOut->AddHeader(msgOut);
348 NS_LOG_DEBUG("Send CreateSessionResponse to SGW " << sgwS5cFteid.addr);
349 m_s5cSocket->SendTo(packetOut, 0, InetSocketAddress(sgwS5cFteid.addr, m_gtpcUdpPort));
350}
351
352void
354{
355 NS_LOG_FUNCTION(this);
356
358 packet->RemoveHeader(msg);
359 uint64_t imsi = msg.GetImsi();
360 uint16_t cellId = msg.GetUliEcgi();
361 NS_LOG_DEBUG("cellId " << cellId << " IMSI " << imsi);
362
363 std::map<uint64_t, Ptr<UeInfo>>::iterator ueit = m_ueInfoByImsiMap.find(imsi);
364 NS_ASSERT_MSG(ueit != m_ueInfoByImsiMap.end(), "unknown IMSI " << imsi);
365 ueit->second->SetSgwAddr(m_sgwS5Addr);
366
367 std::list<GtpcModifyBearerRequestMessage::BearerContextToBeModified> bearerContexts =
369 NS_LOG_DEBUG("BearerContextsToBeModified size = " << bearerContexts.size());
370
371 for (auto& bearerContext : bearerContexts)
372 {
373 Ipv4Address sgwAddr = bearerContext.fteid.addr;
374 uint32_t teid = bearerContext.fteid.teid;
375 NS_LOG_DEBUG("bearerId " << (uint16_t)bearerContext.epsBearerId << " SGW " << sgwAddr
376 << " TEID " << teid);
377 }
378
381 msgOut.SetTeid(imsi);
382 msgOut.ComputeMessageLength();
383
384 Ptr<Packet> packetOut = Create<Packet>();
385 packetOut->AddHeader(msgOut);
386 NS_LOG_DEBUG("Send ModifyBearerResponse to SGW " << m_sgwS5Addr);
388}
389
390void
392{
393 NS_LOG_FUNCTION(this);
394
396 packet->RemoveHeader(msg);
397
398 std::list<uint8_t> epsBearerIds;
399 for (auto& bearerContext : msg.GetBearerContexts())
400 {
401 NS_LOG_DEBUG("ebid " << (uint16_t)bearerContext.m_epsBearerId);
402 epsBearerIds.push_back(bearerContext.m_epsBearerId);
403 }
404
406 msgOut.SetEpsBearerIds(epsBearerIds);
407 msgOut.SetTeid(msg.GetTeid());
408 msgOut.ComputeMessageLength();
409
410 Ptr<Packet> packetOut = Create<Packet>();
411 packetOut->AddHeader(msgOut);
412 NS_LOG_DEBUG("Send DeleteBearerRequest to SGW " << m_sgwS5Addr);
414}
415
416void
418{
419 NS_LOG_FUNCTION(this);
420
422 packet->RemoveHeader(msg);
423
424 uint64_t imsi = msg.GetTeid();
425 std::map<uint64_t, Ptr<UeInfo>>::iterator ueit = m_ueInfoByImsiMap.find(imsi);
426 NS_ASSERT_MSG(ueit != m_ueInfoByImsiMap.end(), "unknown IMSI " << imsi);
427
428 for (auto& epsBearerId : msg.GetEpsBearerIds())
429 {
430 // Remove de-activated bearer contexts from PGW side
431 NS_LOG_INFO("PGW removing bearer " << (uint16_t)epsBearerId << " of IMSI " << imsi);
432 ueit->second->RemoveBearer(epsBearerId);
433 }
434}
435
436void
438{
439 NS_LOG_FUNCTION(this << packet << teid);
440 NS_LOG_LOGIC("packet size: " << packet->GetSize() << " bytes");
441
442 uint8_t ipType;
443 packet->CopyData(&ipType, 1);
444 ipType = (ipType >> 4) & 0x0f;
445
446 uint16_t protocol = 0;
447 if (ipType == 0x04)
448 {
449 protocol = 0x0800;
450 }
451 else if (ipType == 0x06)
452 {
453 protocol = 0x86DD;
454 }
455 else
456 {
457 NS_ABORT_MSG("Unknown IP type");
458 }
459
460 m_tunDevice->Receive(packet,
461 protocol,
465}
466
467void
469{
470 NS_LOG_FUNCTION(this << packet << sgwAddr << teid);
471
472 GtpuHeader gtpu;
473 gtpu.SetTeid(teid);
474 // From 3GPP TS 29.281 v10.0.0 Section 5.1
475 // Length of the payload + the non obligatory GTP-U header
476 gtpu.SetLength(packet->GetSize() + gtpu.GetSerializedSize() - 8);
477 packet->AddHeader(gtpu);
478 uint32_t flags = 0;
479 m_s5uSocket->SendTo(packet, flags, InetSocketAddress(sgwAddr, m_gtpuUdpPort));
480}
481
482void
484{
485 NS_LOG_FUNCTION(this << sgwS5Addr);
486 m_sgwS5Addr = sgwS5Addr;
487}
488
489void
491{
492 NS_LOG_FUNCTION(this << imsi);
493 Ptr<UeInfo> ueInfo = Create<UeInfo>();
494 m_ueInfoByImsiMap[imsi] = ueInfo;
495}
496
497void
499{
500 NS_LOG_FUNCTION(this << imsi << ueAddr);
501 std::map<uint64_t, Ptr<UeInfo>>::iterator ueit = m_ueInfoByImsiMap.find(imsi);
502 NS_ASSERT_MSG(ueit != m_ueInfoByImsiMap.end(), "unknown IMSI" << imsi);
503 ueit->second->SetUeAddr(ueAddr);
504 m_ueInfoByAddrMap[ueAddr] = ueit->second;
505}
506
507void
509{
510 NS_LOG_FUNCTION(this << imsi << ueAddr);
511 std::map<uint64_t, Ptr<UeInfo>>::iterator ueit = m_ueInfoByImsiMap.find(imsi);
512 NS_ASSERT_MSG(ueit != m_ueInfoByImsiMap.end(), "unknown IMSI " << imsi);
513 m_ueInfoByAddrMap6[ueAddr] = ueit->second;
514 ueit->second->SetUeAddr6(ueAddr);
515}
516
517} // namespace ns3
a polymophic address class
Definition: address.h:100
Ipv6Address GetUeAddr6()
Get the IPv6 address of the UE.
uint32_t Classify(Ptr< Packet > p, uint16_t protocolNumber)
Classify the packet according to TFTs of this UE.
void SetUeAddr(Ipv4Address addr)
Set the IPv4 address of the UE.
Ipv4Address GetSgwAddr()
Get the address of the SGW to which the UE is connected.
void RemoveBearer(uint8_t bearerId)
Delete context of bearer for this UE on PGW side.
Ipv4Address GetUeAddr()
Get the IPv4 address of the UE.
void SetUeAddr6(Ipv6Address addr)
Set the IPv6 address of the UE.
void SetSgwAddr(Ipv4Address addr)
Set the address of the eNB to which the UE is connected.
void AddBearer(uint8_t bearerId, uint32_t teid, Ptr< EpcTft > tft)
Add a bearer for this UE on PGW side.
EpcPgwApplication(const Ptr< VirtualNetDevice > tunDevice, Ipv4Address s5Addr, const Ptr< Socket > s5uSocket, const Ptr< Socket > s5cSocket)
Constructor that binds the tap device to the callback methods.
void SendToS5uSocket(Ptr< Packet > packet, Ipv4Address sgwS5uAddress, uint32_t teid)
Send a data packet to the SGW via the S5-U interface.
void SetUeAddress6(uint64_t imsi, Ipv6Address ueAddr)
set the address of a previously added UE
void SendToTunDevice(Ptr< Packet > packet, uint32_t teid)
Send a data packet to the internet via the SGi interface of the PGW.
void AddSgw(Ipv4Address sgwS5Addr)
Let the PGW be aware of a new SGW.
TracedCallback< Ptr< Packet > > m_rxTunPktTrace
Callback to trace received data packets at Tun NetDevice from internet.
TracedCallback< Ptr< Packet > > m_rxS5PktTrace
Callback to trace received data packets from S5 socket.
std::map< Ipv6Address, Ptr< UeInfo > > m_ueInfoByAddrMap6
UeInfo stored by UE IPv6 address.
void RecvFromS5uSocket(Ptr< Socket > socket)
Method to be assigned to the receiver callback of the S5-U socket.
void DoRecvDeleteBearerResponse(Ptr< Packet > packet)
Process Delete Bearer Response message.
void RecvFromS5cSocket(Ptr< Socket > socket)
Method to be assigned to the receiver callback of the S5-C socket.
void DoRecvDeleteBearerCommand(Ptr< Packet > packet)
Process Delete Bearer Command message.
void AddUe(uint64_t imsi)
Let the PGW be aware of a new UE.
Ptr< Socket > m_s5uSocket
UDP socket to send/receive GTP-U packets to/from the S5 interface.
void DoDispose() override
Destructor implementation.
uint16_t m_gtpuUdpPort
UDP port to be used for GTP-U.
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.
std::map< uint64_t, Ptr< UeInfo > > m_ueInfoByImsiMap
UeInfo stored by IMSI.
Ipv4Address m_pgwS5Addr
PGW address of the S5 interface.
Ipv4Address m_sgwS5Addr
SGW address of the S5 interface.
~EpcPgwApplication() override
Destructor.
Ptr< VirtualNetDevice > m_tunDevice
TUN VirtualNetDevice used for tunneling/detunneling IP packets from/to the internet over GTP-U/UDP/IP...
void DoRecvModifyBearerRequest(Ptr< Packet > packet)
Process Modify Bearer Request message.
void DoRecvCreateSessionRequest(Ptr< Packet > packet)
Process Create Session Request message.
uint16_t m_gtpcUdpPort
UDP port to be used for GTPv2-C.
static TypeId GetTypeId()
Get the type ID.
Ptr< Socket > m_s5cSocket
UDP socket to send/receive GTPv2-C packets to/from the S5 interface.
std::map< Ipv4Address, Ptr< UeInfo > > m_ueInfoByAddrMap
UeInfo stored by UE IPv4 address.
void SetUeAddress(uint64_t imsi, Ipv4Address ueAddr)
Set the address of a previously added UE.
@ DOWNLINK
Definition: epc-tft.h:52
GTP-C Create Session Request Message.
uint64_t GetImsi() const
Get the IMSI.
GtpcHeader::Fteid_t GetSenderCpFteid() const
Get the Sender CpFteid.
uint32_t GetUliEcgi() const
Get the UliEcgi.
std::list< BearerContextToBeCreated > GetBearerContextsToBeCreated() const
Get the Bearer Contexts.
GTP-C Create Session Response Message.
void SetCause(Cause_t cause)
Set the Cause.
void SetBearerContextsCreated(std::list< BearerContextCreated > bearerContexts)
Set the Bearer Contexts.
void SetSenderCpFteid(GtpcHeader::Fteid_t fteid)
Set the Sender CpFteid.
GTP-C Delete Bearer Command Message.
std::list< BearerContext > GetBearerContexts() const
Get the Bearer contexts.
GTP-C Delete Bearer Request Message.
void SetEpsBearerIds(std::list< uint8_t > epsBearerIds)
Set the Bearers IDs.
GTP-C Delete Bearer Response Message.
std::list< uint8_t > GetEpsBearerIds() const
Get the Bearers IDs.
Header of the GTPv2-C protocol.
uint8_t GetMessageType() const
Get message type.
void ComputeMessageLength()
Compute the message length according to the message type.
void SetTeid(uint32_t teid)
Set TEID.
uint32_t GetTeid() const
Get TEID.
GTP-C Modify Bearer Request Message.
uint64_t GetImsi() const
Get the IMSI.
uint32_t GetUliEcgi() const
Get the UliEcgi.
std::list< BearerContextToBeModified > GetBearerContextsToBeModified() const
Get the Bearer Contexts.
GTP-C Modify Bearer Response Message.
void SetCause(Cause_t cause)
Set the Cause.
Implementation of the GPRS Tunnelling Protocol header according to GTPv1-U Release 10 as per 3Gpp TS ...
void SetTeid(uint32_t teid)
Set TEID function.
uint32_t GetSerializedSize() const override
uint32_t GetTeid() const
Get a tunnel endpoint identificator (TEID)
void SetLength(uint16_t length)
Set the length in octets of the payload.
an Inet address class
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
Packet header for IPv4.
Definition: ipv4-header.h:34
Ipv4Address GetDestination() const
Definition: ipv4-header.cc:316
static const uint16_t PROT_NUMBER
Protocol number (0x0800)
Describes an IPv6 address.
Definition: ipv6-address.h:49
Packet header for IPv6.
Definition: ipv6-header.h:35
Ipv6Address GetDestination() const
Get the "Destination address" field.
Definition: ipv6-header.cc:124
static const uint16_t PROT_NUMBER
The protocol number for IPv6 (0x86DD).
@ PACKET_HOST
Packet addressed to us.
Definition: net-device.h:301
A base class which provides memory management and object aggregation.
Definition: object.h:89
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:126
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
Address GetAddress() const override
bool Receive(Ptr< Packet > packet, uint16_t protocol, const Address &source, const Address &destination, PacketType packetType)
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
Callback< R, Args... > MakeNullCallback()
Definition: callback.h:745
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#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(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
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
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
Ptr< EpcTft > tft
Bearer traffic flow template.
Ipv4Address addr
IPv4 address.
InterfaceType_t interfaceType
Interface type.