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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Manuel Requena <manuel.requena@cttc.es>
7 * (based on epc-sgw-pgw-application.cc)
8 */
9
10#include "epc-pgw-application.h"
11
12#include "epc-gtpu-header.h"
13
14#include "ns3/abort.h"
15#include "ns3/inet-socket-address.h"
16#include "ns3/ipv4-l3-protocol.h"
17#include "ns3/ipv4.h"
18#include "ns3/ipv6-header.h"
19#include "ns3/ipv6-l3-protocol.h"
20#include "ns3/ipv6.h"
21#include "ns3/log.h"
22#include "ns3/mac48-address.h"
23
24namespace ns3
25{
26
27NS_LOG_COMPONENT_DEFINE("EpcPgwApplication");
28
29/////////////////////////
30// UeInfo
31/////////////////////////
32
37
38void
40{
41 NS_LOG_FUNCTION(this << (uint16_t)bearerId << teid << tft);
42 m_teidByBearerIdMap[bearerId] = teid;
43 return m_tftClassifier.Add(tft, teid);
44}
45
46void
48{
49 NS_LOG_FUNCTION(this << (uint16_t)bearerId);
50 auto it = m_teidByBearerIdMap.find(bearerId);
51 m_tftClassifier.Delete(it->second); // delete tft
52 m_teidByBearerIdMap.erase(bearerId);
53}
54
57{
58 NS_LOG_FUNCTION(this << p);
59 // we hardcode DOWNLINK direction since the PGW is expected to
60 // classify only downlink packets (uplink packets will go to the
61 // internet without any classification).
62 return m_tftClassifier.Classify(p, EpcTft::DOWNLINK, protocolNumber);
63}
64
67{
68 return m_sgwAddr;
69}
70
71void
73{
74 m_sgwAddr = sgwAddr;
75}
76
79{
80 return m_ueAddr;
81}
82
83void
85{
86 m_ueAddr = ueAddr;
87}
88
91{
92 return m_ueAddr6;
93}
94
95void
97{
98 m_ueAddr6 = ueAddr;
99}
100
101/////////////////////////
102// EpcPgwApplication
103/////////////////////////
104
105TypeId
107{
108 static TypeId tid =
109 TypeId("ns3::EpcPgwApplication")
110 .SetParent<Object>()
111 .SetGroupName("Lte")
112 .AddTraceSource("RxFromTun",
113 "Receive data packets from internet in Tunnel NetDevice",
115 "ns3::EpcPgwApplication::RxTracedCallback")
116 .AddTraceSource("RxFromS1u",
117 "Receive data packets from S5 Socket",
119 "ns3::EpcPgwApplication::RxTracedCallback");
120 return tid;
121}
122
123void
132
134 Ipv4Address s5Addr,
135 const Ptr<Socket> s5uSocket,
136 const Ptr<Socket> s5cSocket)
137 : m_pgwS5Addr(s5Addr),
138 m_s5uSocket(s5uSocket),
139 m_s5cSocket(s5cSocket),
140 m_tunDevice(tunDevice),
141 m_gtpuUdpPort(2152), // fixed by the standard
142 m_gtpcUdpPort(2123) // fixed by the standard
143{
144 NS_LOG_FUNCTION(this << tunDevice << s5Addr << s5uSocket << s5cSocket);
147}
148
153
154bool
156 const Address& source,
157 const Address& dest,
158 uint16_t protocolNumber)
159{
160 NS_LOG_FUNCTION(this << source << dest << protocolNumber << packet << packet->GetSize());
161 m_rxTunPktTrace(packet->Copy());
162
163 // get IP address of UE
164 if (protocolNumber == Ipv4L3Protocol::PROT_NUMBER)
165 {
166 Ipv4Header ipv4Header;
167 packet->PeekHeader(ipv4Header);
168 Ipv4Address ueAddr = ipv4Header.GetDestination();
169 NS_LOG_LOGIC("packet addressed to UE " << ueAddr);
170
171 // find corresponding UeInfo address
172 auto it = m_ueInfoByAddrMap.find(ueAddr);
173 if (it == m_ueInfoByAddrMap.end())
174 {
175 NS_LOG_WARN("unknown UE address " << ueAddr);
176 }
177 else
178 {
179 Ipv4Address sgwAddr = it->second->GetSgwAddr();
180 uint32_t teid = it->second->Classify(packet, protocolNumber);
181 if (teid == 0)
182 {
183 NS_LOG_WARN("no matching bearer for this packet");
184 }
185 else
186 {
187 SendToS5uSocket(packet, sgwAddr, teid);
188 }
189 }
190 }
191 else if (protocolNumber == Ipv6L3Protocol::PROT_NUMBER)
192 {
193 Ipv6Header ipv6Header;
194 packet->PeekHeader(ipv6Header);
195 Ipv6Address ueAddr = ipv6Header.GetDestination();
196 NS_LOG_LOGIC("packet addressed to UE " << ueAddr);
197
198 // find corresponding UeInfo address
199 auto it = m_ueInfoByAddrMap6.find(ueAddr);
200 if (it == m_ueInfoByAddrMap6.end())
201 {
202 NS_LOG_WARN("unknown UE address " << ueAddr);
203 }
204 else
205 {
206 Ipv4Address sgwAddr = it->second->GetSgwAddr();
207 uint32_t teid = it->second->Classify(packet, protocolNumber);
208 if (teid == 0)
209 {
210 NS_LOG_WARN("no matching bearer for this packet");
211 }
212 else
213 {
214 SendToS5uSocket(packet, sgwAddr, teid);
215 }
216 }
217 }
218 else
219 {
220 NS_ABORT_MSG("Unknown IP type");
221 }
222
223 // there is no reason why we should notify the TUN
224 // VirtualNetDevice that he failed to send the packet: if we receive
225 // any bogus packet, it will just be silently discarded.
226 const bool succeeded = true;
227 return succeeded;
228}
229
230void
232{
233 NS_LOG_FUNCTION(this << socket);
234 NS_ASSERT(socket == m_s5uSocket);
235 Ptr<Packet> packet = socket->Recv();
236 m_rxS5PktTrace(packet->Copy());
237
238 GtpuHeader gtpu;
239 packet->RemoveHeader(gtpu);
240 uint32_t teid = gtpu.GetTeid();
241
242 SendToTunDevice(packet, teid);
243}
244
245void
247{
248 NS_LOG_FUNCTION(this << socket);
249 NS_ASSERT(socket == m_s5cSocket);
250 Ptr<Packet> packet = socket->Recv();
251 GtpcHeader header;
252 packet->PeekHeader(header);
253 uint16_t msgType = header.GetMessageType();
254
255 switch (msgType)
256 {
259 break;
260
263 break;
264
267 break;
268
271 break;
272
273 default:
274 NS_FATAL_ERROR("GTP-C message not supported");
275 break;
276 }
277}
278
279void
281{
282 NS_LOG_FUNCTION(this);
283
285 packet->RemoveHeader(msg);
286 uint64_t imsi = msg.GetImsi();
287 uint16_t cellId = msg.GetUliEcgi();
288 NS_LOG_DEBUG("cellId " << cellId << " IMSI " << imsi);
289
290 auto ueit = m_ueInfoByImsiMap.find(imsi);
291 NS_ASSERT_MSG(ueit != m_ueInfoByImsiMap.end(), "unknown IMSI " << imsi);
292 ueit->second->SetSgwAddr(m_sgwS5Addr);
293
294 GtpcHeader::Fteid_t sgwS5cFteid = msg.GetSenderCpFteid();
295 NS_ASSERT_MSG(sgwS5cFteid.interfaceType == GtpcHeader::S5_SGW_GTPC, "Wrong interface type");
296
298 msgOut.SetTeid(sgwS5cFteid.teid);
300
301 GtpcHeader::Fteid_t pgwS5cFteid;
303 pgwS5cFteid.teid = sgwS5cFteid.teid;
304 pgwS5cFteid.addr = m_pgwS5Addr;
305 msgOut.SetSenderCpFteid(pgwS5cFteid);
306
307 std::list<GtpcCreateSessionRequestMessage::BearerContextToBeCreated> bearerContexts =
309 NS_LOG_DEBUG("BearerContextsToBeCreated size = " << bearerContexts.size());
310
311 std::list<GtpcCreateSessionResponseMessage::BearerContextCreated> bearerContextsCreated;
312 for (auto& bearerContext : bearerContexts)
313 {
314 uint32_t teid = bearerContext.sgwS5uFteid.teid;
315 NS_LOG_DEBUG("bearerId " << (uint16_t)bearerContext.epsBearerId << " SGW "
316 << bearerContext.sgwS5uFteid.addr << " TEID " << teid);
317
318 ueit->second->AddBearer(bearerContext.epsBearerId, teid, bearerContext.tft);
319
322 bearerContextOut.fteid.teid = teid;
323 bearerContextOut.fteid.addr = m_pgwS5Addr;
324 bearerContextOut.epsBearerId = bearerContext.epsBearerId;
325 bearerContextOut.bearerLevelQos = bearerContext.bearerLevelQos;
326 bearerContextOut.tft = bearerContext.tft;
327 bearerContextsCreated.push_back(bearerContextOut);
328 }
329
330 NS_LOG_DEBUG("BearerContextsCreated size = " << bearerContextsCreated.size());
331 msgOut.SetBearerContextsCreated(bearerContextsCreated);
332 msgOut.SetTeid(sgwS5cFteid.teid);
333 msgOut.ComputeMessageLength();
334
335 Ptr<Packet> packetOut = Create<Packet>();
336 packetOut->AddHeader(msgOut);
337 NS_LOG_DEBUG("Send CreateSessionResponse to SGW " << sgwS5cFteid.addr);
338 m_s5cSocket->SendTo(packetOut, 0, InetSocketAddress(sgwS5cFteid.addr, m_gtpcUdpPort));
339}
340
341void
343{
344 NS_LOG_FUNCTION(this);
345
347 packet->RemoveHeader(msg);
348 uint64_t imsi = msg.GetImsi();
349 uint16_t cellId = msg.GetUliEcgi();
350 NS_LOG_DEBUG("cellId " << cellId << " IMSI " << imsi);
351
352 auto ueit = m_ueInfoByImsiMap.find(imsi);
353 NS_ASSERT_MSG(ueit != m_ueInfoByImsiMap.end(), "unknown IMSI " << imsi);
354 ueit->second->SetSgwAddr(m_sgwS5Addr);
355
356 std::list<GtpcModifyBearerRequestMessage::BearerContextToBeModified> bearerContexts =
358 NS_LOG_DEBUG("BearerContextsToBeModified size = " << bearerContexts.size());
359
360 for (auto& bearerContext : bearerContexts)
361 {
362 Ipv4Address sgwAddr = bearerContext.fteid.addr;
363 uint32_t teid = bearerContext.fteid.teid;
364 NS_LOG_DEBUG("bearerId " << (uint16_t)bearerContext.epsBearerId << " SGW " << sgwAddr
365 << " TEID " << teid);
366 }
367
370 msgOut.SetTeid(imsi);
371 msgOut.ComputeMessageLength();
372
373 Ptr<Packet> packetOut = Create<Packet>();
374 packetOut->AddHeader(msgOut);
375 NS_LOG_DEBUG("Send ModifyBearerResponse to SGW " << m_sgwS5Addr);
377}
378
379void
381{
382 NS_LOG_FUNCTION(this);
383
385 packet->RemoveHeader(msg);
386
387 std::list<uint8_t> epsBearerIds;
388 for (auto& bearerContext : msg.GetBearerContexts())
389 {
390 NS_LOG_DEBUG("ebid " << (uint16_t)bearerContext.m_epsBearerId);
391 epsBearerIds.push_back(bearerContext.m_epsBearerId);
392 }
393
395 msgOut.SetEpsBearerIds(epsBearerIds);
396 msgOut.SetTeid(msg.GetTeid());
397 msgOut.ComputeMessageLength();
398
399 Ptr<Packet> packetOut = Create<Packet>();
400 packetOut->AddHeader(msgOut);
401 NS_LOG_DEBUG("Send DeleteBearerRequest to SGW " << m_sgwS5Addr);
403}
404
405void
407{
408 NS_LOG_FUNCTION(this);
409
411 packet->RemoveHeader(msg);
412
413 uint64_t imsi = msg.GetTeid();
414 auto ueit = m_ueInfoByImsiMap.find(imsi);
415 NS_ASSERT_MSG(ueit != m_ueInfoByImsiMap.end(), "unknown IMSI " << imsi);
416
417 for (auto& epsBearerId : msg.GetEpsBearerIds())
418 {
419 // Remove de-activated bearer contexts from PGW side
420 NS_LOG_INFO("PGW removing bearer " << (uint16_t)epsBearerId << " of IMSI " << imsi);
421 ueit->second->RemoveBearer(epsBearerId);
422 }
423}
424
425void
427{
428 NS_LOG_FUNCTION(this << packet << teid);
429 NS_LOG_LOGIC("packet size: " << packet->GetSize() << " bytes");
430
431 uint8_t ipType;
432 packet->CopyData(&ipType, 1);
433 ipType = (ipType >> 4) & 0x0f;
434
435 uint16_t protocol = 0;
436 if (ipType == 0x04)
437 {
438 protocol = 0x0800;
439 }
440 else if (ipType == 0x06)
441 {
442 protocol = 0x86DD;
443 }
444 else
445 {
446 NS_ABORT_MSG("Unknown IP type");
447 }
448
449 m_tunDevice->Receive(packet,
450 protocol,
451 m_tunDevice->GetAddress(),
452 m_tunDevice->GetAddress(),
454}
455
456void
458{
459 NS_LOG_FUNCTION(this << packet << sgwAddr << teid);
460
461 GtpuHeader gtpu;
462 gtpu.SetTeid(teid);
463 // From 3GPP TS 29.281 v10.0.0 Section 5.1
464 // Length of the payload + the non obligatory GTP-U header
465 gtpu.SetLength(packet->GetSize() + gtpu.GetSerializedSize() - 8);
466 packet->AddHeader(gtpu);
467 uint32_t flags = 0;
468 m_s5uSocket->SendTo(packet, flags, InetSocketAddress(sgwAddr, m_gtpuUdpPort));
469}
470
471void
473{
474 NS_LOG_FUNCTION(this << sgwS5Addr);
475 m_sgwS5Addr = sgwS5Addr;
476}
477
478void
480{
481 NS_LOG_FUNCTION(this << imsi);
482 Ptr<UeInfo> ueInfo = Create<UeInfo>();
483 m_ueInfoByImsiMap[imsi] = ueInfo;
484}
485
486void
488{
489 NS_LOG_FUNCTION(this << imsi << ueAddr);
490 auto ueit = m_ueInfoByImsiMap.find(imsi);
491 NS_ASSERT_MSG(ueit != m_ueInfoByImsiMap.end(), "unknown IMSI" << imsi);
492 ueit->second->SetUeAddr(ueAddr);
493 m_ueInfoByAddrMap[ueAddr] = ueit->second;
494}
495
496void
498{
499 NS_LOG_FUNCTION(this << imsi << ueAddr);
500 auto ueit = m_ueInfoByImsiMap.find(imsi);
501 NS_ASSERT_MSG(ueit != m_ueInfoByImsiMap.end(), "unknown IMSI " << imsi);
502 m_ueInfoByAddrMap6[ueAddr] = ueit->second;
503 ueit->second->SetUeAddr6(ueAddr);
504}
505
506} // namespace ns3
a polymophic address class
Definition address.h:90
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.
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.
Packet header for IPv4.
Definition ipv4-header.h:23
Ipv4Address GetDestination() const
static const uint16_t PROT_NUMBER
Protocol number (0x0800)
Describes an IPv6 address.
Packet header for IPv6.
Definition ipv6-header.h:24
Ipv6Address GetDestination() const
Get the "Destination address" field.
static const uint16_t PROT_NUMBER
The protocol number for IPv6 (0x86DD).
@ PACKET_HOST
Packet addressed to us.
Definition net-device.h:290
A base class which provides memory management and object aggregation.
Definition object.h:78
Smart pointer class similar to boost::intrusive_ptr.
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
Definition socket.cc:117
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:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
#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
Callback< R, Args... > MakeNullCallback()
Definition callback.h:727
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#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(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 > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
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:684
Ptr< EpcTft > tft
Bearer traffic flow template.
Ipv4Address addr
IPv4 address.
InterfaceType_t interfaceType
Interface type.