8#include "nr-epc-pgw-application.h"
10#include "nr-epc-gtpu-header.h"
13#include "ns3/inet-socket-address.h"
14#include "ns3/ipv4-l3-protocol.h"
16#include "ns3/ipv6-header.h"
17#include "ns3/ipv6-l3-protocol.h"
20#include "ns3/mac48-address.h"
25NS_LOG_COMPONENT_DEFINE(
"NrEpcPgwApplication");
31NrEpcPgwApplication::NrUeInfo::NrUeInfo()
33 NS_LOG_FUNCTION(
this);
37NrEpcPgwApplication::NrUeInfo::AddBearer(uint8_t bearerId, uint32_t teid, Ptr<NrEpcTft> tft)
39 NS_LOG_FUNCTION(
this << (uint16_t)bearerId << teid << tft);
40 m_teidByBearerIdMap[bearerId] = teid;
41 return m_tftClassifier.Add(tft, teid);
45NrEpcPgwApplication::NrUeInfo::RemoveBearer(uint8_t bearerId)
47 NS_LOG_FUNCTION(
this << (uint16_t)bearerId);
48 auto it = m_teidByBearerIdMap.find(bearerId);
49 m_tftClassifier.Delete(it->second);
50 m_teidByBearerIdMap.erase(bearerId);
54NrEpcPgwApplication::NrUeInfo::Classify(Ptr<Packet> p, uint16_t protocolNumber)
56 NS_LOG_FUNCTION(
this << p);
60 return m_tftClassifier.Classify(p, NrEpcTft::DOWNLINK, protocolNumber);
64NrEpcPgwApplication::NrUeInfo::GetSgwAddr()
70NrEpcPgwApplication::NrUeInfo::SetSgwAddr(Ipv4Address sgwAddr)
76NrEpcPgwApplication::NrUeInfo::GetUeAddr()
82NrEpcPgwApplication::NrUeInfo::SetUeAddr(Ipv4Address ueAddr)
88NrEpcPgwApplication::NrUeInfo::GetUeAddr6()
94NrEpcPgwApplication::NrUeInfo::SetUeAddr6(Ipv6Address ueAddr)
107 TypeId(
"ns3::NrEpcPgwApplication")
110 .AddTraceSource(
"RxFromTun",
111 "Receive data packets from internet in Tunnel NetDevice",
112 MakeTraceSourceAccessor(&NrEpcPgwApplication::m_rxTunPktTrace),
113 "ns3::NrEpcPgwApplication::RxTracedCallback")
114 .AddTraceSource(
"RxFromS1u",
115 "Receive data packets from S5 Socket",
116 MakeTraceSourceAccessor(&NrEpcPgwApplication::m_rxS5PktTrace),
117 "ns3::NrEpcPgwApplication::RxTracedCallback");
122NrEpcPgwApplication::DoDispose()
124 NS_LOG_FUNCTION(
this);
125 m_s5uSocket->SetRecvCallback(MakeNullCallback<
void, Ptr<Socket>>());
126 m_s5uSocket =
nullptr;
127 m_s5cSocket->SetRecvCallback(MakeNullCallback<
void, Ptr<Socket>>());
128 m_s5cSocket =
nullptr;
133 const Ptr<Socket> s5uSocket,
134 const Ptr<Socket> s5cSocket)
135 : m_pgwS5Addr(s5Addr),
136 m_s5uSocket(s5uSocket),
137 m_s5cSocket(s5cSocket),
138 m_tunDevice(tunDevice),
142 NS_LOG_FUNCTION(
this << tunDevice << s5Addr << s5uSocket << s5cSocket);
149 NS_LOG_FUNCTION(
this);
154 const Address& source,
156 uint16_t protocolNumber)
158 NS_LOG_FUNCTION(
this << source << dest << protocolNumber << packet << packet->GetSize());
159 m_rxTunPktTrace(packet->Copy());
162 if (protocolNumber == Ipv4L3Protocol::PROT_NUMBER)
164 Ipv4Header ipv4Header;
165 packet->PeekHeader(ipv4Header);
166 Ipv4Address ueAddr = ipv4Header.GetDestination();
167 NS_LOG_LOGIC(
"packet addressed to UE " << ueAddr);
170 auto it = m_ueInfoByAddrMap.find(ueAddr);
171 if (it == m_ueInfoByAddrMap.end())
173 NS_LOG_WARN(
"unknown UE address " << ueAddr);
177 Ipv4Address sgwAddr = it->second->GetSgwAddr();
178 uint32_t teid = it->second->Classify(packet, protocolNumber);
181 NS_LOG_WARN(
"no matching bearer for this packet");
189 else if (protocolNumber == Ipv6L3Protocol::PROT_NUMBER)
191 Ipv6Header ipv6Header;
192 packet->PeekHeader(ipv6Header);
193 Ipv6Address ueAddr = ipv6Header.GetDestination();
194 NS_LOG_LOGIC(
"packet addressed to UE " << ueAddr);
197 auto it = m_ueInfoByAddrMap6.find(ueAddr);
198 if (it == m_ueInfoByAddrMap6.end())
200 NS_LOG_WARN(
"unknown UE address " << ueAddr);
204 Ipv4Address sgwAddr = it->second->GetSgwAddr();
205 uint32_t teid = it->second->Classify(packet, protocolNumber);
208 NS_LOG_WARN(
"no matching bearer for this packet");
218 NS_ABORT_MSG(
"Unknown IP type");
224 const bool succeeded =
true;
231 NS_LOG_FUNCTION(
this << socket);
232 NS_ASSERT(socket == m_s5uSocket);
233 Ptr<Packet> packet = socket->Recv();
234 m_rxS5PktTrace(packet->Copy());
237 packet->RemoveHeader(gtpu);
238 uint32_t teid = gtpu.
GetTeid();
246 NS_LOG_FUNCTION(
this << socket);
247 NS_ASSERT(socket == m_s5cSocket);
248 Ptr<Packet> packet = socket->Recv();
250 packet->PeekHeader(header);
255 case NrGtpcHeader::CreateSessionRequest:
256 DoRecvCreateSessionRequest(packet);
259 case NrGtpcHeader::ModifyBearerRequest:
260 DoRecvModifyBearerRequest(packet);
263 case NrGtpcHeader::DeleteBearerCommand:
264 DoRecvDeleteBearerCommand(packet);
267 case NrGtpcHeader::DeleteBearerResponse:
268 DoRecvDeleteBearerResponse(packet);
272 NS_FATAL_ERROR(
"GTP-C message not supported");
278NrEpcPgwApplication::DoRecvCreateSessionRequest(Ptr<Packet> packet)
280 NS_LOG_FUNCTION(
this);
283 packet->RemoveHeader(msg);
286 NS_LOG_DEBUG(
"cellId " << cellId <<
" IMSI " << imsi);
288 auto ueit = m_ueInfoByImsiMap.find(imsi);
289 NS_ASSERT_MSG(ueit != m_ueInfoByImsiMap.end(),
"unknown IMSI " << imsi);
290 ueit->second->SetSgwAddr(m_sgwS5Addr);
293 NS_ASSERT_MSG(sgwS5cFteid.
interfaceType == NrGtpcHeader::S5_SGW_GTPC,
"Wrong interface type");
297 msgOut.
SetCause(NrGtpcCreateSessionResponseMessage::REQUEST_ACCEPTED);
301 pgwS5cFteid.
teid = sgwS5cFteid.
teid;
302 pgwS5cFteid.
addr = m_pgwS5Addr;
305 std::list<NrGtpcCreateSessionRequestMessage::BearerContextToBeCreated> bearerContexts =
307 NS_LOG_DEBUG(
"BearerContextsToBeCreated size = " << bearerContexts.size());
309 std::list<NrGtpcCreateSessionResponseMessage::BearerContextCreated> bearerContextsCreated;
310 for (
auto& bearerContext : bearerContexts)
312 uint32_t teid = bearerContext.sgwS5uFteid.teid;
313 NS_LOG_DEBUG(
"bearerId " << (uint16_t)bearerContext.epsBearerId <<
" SGW "
314 << bearerContext.sgwS5uFteid.addr <<
" TEID " << teid);
316 ueit->second->AddBearer(bearerContext.epsBearerId, teid, bearerContext.tft);
321 bearerContextOut.
fteid.
addr = m_pgwS5Addr;
322 bearerContextOut.
epsBearerId = bearerContext.epsBearerId;
324 bearerContextOut.
tft = bearerContext.tft;
325 bearerContextsCreated.push_back(bearerContextOut);
328 NS_LOG_DEBUG(
"BearerContextsCreated size = " << bearerContextsCreated.size());
333 Ptr<Packet> packetOut = Create<Packet>();
334 packetOut->AddHeader(msgOut);
335 NS_LOG_DEBUG(
"Send CreateSessionResponse to SGW " << sgwS5cFteid.
addr);
336 m_s5cSocket->SendTo(packetOut, 0, InetSocketAddress(sgwS5cFteid.
addr, m_gtpcUdpPort));
340NrEpcPgwApplication::DoRecvModifyBearerRequest(Ptr<Packet> packet)
342 NS_LOG_FUNCTION(
this);
344 NrGtpcModifyBearerRequestMessage msg;
345 packet->RemoveHeader(msg);
347 uint16_t cellId = msg.GetUliEcgi();
348 NS_LOG_DEBUG(
"cellId " << cellId <<
" IMSI " << imsi);
350 auto ueit = m_ueInfoByImsiMap.find(imsi);
351 NS_ASSERT_MSG(ueit != m_ueInfoByImsiMap.end(),
"unknown IMSI " << imsi);
352 ueit->second->SetSgwAddr(m_sgwS5Addr);
354 std::list<NrGtpcModifyBearerRequestMessage::BearerContextToBeModified> bearerContexts =
355 msg.GetBearerContextsToBeModified();
356 NS_LOG_DEBUG(
"BearerContextsToBeModified size = " << bearerContexts.size());
358 for (
auto& bearerContext : bearerContexts)
360 Ipv4Address sgwAddr = bearerContext.fteid.addr;
361 uint32_t teid = bearerContext.fteid.teid;
362 NS_LOG_DEBUG(
"bearerId " << (uint16_t)bearerContext.epsBearerId <<
" SGW " << sgwAddr
363 <<
" TEID " << teid);
366 NrGtpcModifyBearerResponseMessage msgOut;
367 msgOut.
SetCause(NrGtpcIes::REQUEST_ACCEPTED);
368 msgOut.SetTeid(imsi);
369 msgOut.ComputeMessageLength();
371 Ptr<Packet> packetOut = Create<Packet>();
372 packetOut->AddHeader(msgOut);
373 NS_LOG_DEBUG(
"Send ModifyBearerResponse to SGW " << m_sgwS5Addr);
374 m_s5cSocket->SendTo(packetOut, 0, InetSocketAddress(m_sgwS5Addr, m_gtpcUdpPort));
378NrEpcPgwApplication::DoRecvDeleteBearerCommand(Ptr<Packet> packet)
380 NS_LOG_FUNCTION(
this);
382 NrGtpcDeleteBearerCommandMessage msg;
383 packet->RemoveHeader(msg);
385 std::list<uint8_t> epsBearerIds;
386 for (
auto& bearerContext : msg.GetBearerContexts())
388 NS_LOG_DEBUG(
"ebid " << (uint16_t)bearerContext.m_epsBearerId);
389 epsBearerIds.push_back(bearerContext.m_epsBearerId);
392 NrGtpcDeleteBearerRequestMessage msgOut;
393 msgOut.SetEpsBearerIds(epsBearerIds);
394 msgOut.SetTeid(msg.GetTeid());
395 msgOut.ComputeMessageLength();
397 Ptr<Packet> packetOut = Create<Packet>();
398 packetOut->AddHeader(msgOut);
399 NS_LOG_DEBUG(
"Send DeleteBearerRequest to SGW " << m_sgwS5Addr);
400 m_s5cSocket->SendTo(packetOut, 0, InetSocketAddress(m_sgwS5Addr, m_gtpcUdpPort));
404NrEpcPgwApplication::DoRecvDeleteBearerResponse(Ptr<Packet> packet)
406 NS_LOG_FUNCTION(
this);
408 NrGtpcDeleteBearerResponseMessage msg;
409 packet->RemoveHeader(msg);
411 uint64_t imsi = msg.GetTeid();
412 auto ueit = m_ueInfoByImsiMap.find(imsi);
413 NS_ASSERT_MSG(ueit != m_ueInfoByImsiMap.end(),
"unknown IMSI " << imsi);
415 for (
auto& epsBearerId : msg.GetEpsBearerIds())
418 NS_LOG_INFO(
"PGW removing bearer " << (uint16_t)epsBearerId <<
" of IMSI " << imsi);
419 ueit->second->RemoveBearer(epsBearerId);
426 NS_LOG_FUNCTION(
this << packet << teid);
427 NS_LOG_LOGIC(
"packet size: " << packet->GetSize() <<
" bytes");
430 packet->CopyData(&ipType, 1);
431 ipType = (ipType >> 4) & 0x0f;
433 uint16_t protocol = 0;
438 else if (ipType == 0x06)
444 NS_ABORT_MSG(
"Unknown IP type");
447 m_tunDevice->Receive(packet,
449 m_tunDevice->GetAddress(),
450 m_tunDevice->GetAddress(),
451 NetDevice::PACKET_HOST);
457 NS_LOG_FUNCTION(
this << packet << sgwAddr << teid);
463 gtpu.
SetLength(packet->GetSize() + gtpu.GetSerializedSize() - 8);
464 packet->AddHeader(gtpu);
466 m_s5uSocket->SendTo(packet, flags, InetSocketAddress(sgwAddr, m_gtpuUdpPort));
472 NS_LOG_FUNCTION(
this << sgwS5Addr);
473 m_sgwS5Addr = sgwS5Addr;
479 NS_LOG_FUNCTION(
this << imsi);
480 Ptr<NrUeInfo> ueInfo = Create<NrUeInfo>();
481 m_ueInfoByImsiMap[imsi] = ueInfo;
487 NS_LOG_FUNCTION(
this << imsi << ueAddr);
488 auto ueit = m_ueInfoByImsiMap.find(imsi);
489 NS_ASSERT_MSG(ueit != m_ueInfoByImsiMap.end(),
"unknown IMSI" << imsi);
490 ueit->second->SetUeAddr(ueAddr);
491 m_ueInfoByAddrMap[ueAddr] = ueit->second;
497 NS_LOG_FUNCTION(
this << imsi << ueAddr);
498 auto ueit = m_ueInfoByImsiMap.find(imsi);
499 NS_ASSERT_MSG(ueit != m_ueInfoByImsiMap.end(),
"unknown IMSI " << imsi);
500 m_ueInfoByAddrMap6[ueAddr] = ueit->second;
501 ueit->second->SetUeAddr6(ueAddr);
void AddUe(uint64_t imsi)
static TypeId GetTypeId()
Get the type ID.
void RecvFromS5cSocket(Ptr< Socket > socket)
bool RecvFromTunDevice(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
void SetUeAddress(uint64_t imsi, Ipv4Address ueAddr)
~NrEpcPgwApplication() override
void SendToTunDevice(Ptr< Packet > packet, uint32_t teid)
void AddSgw(Ipv4Address sgwS5Addr)
NrEpcPgwApplication(const Ptr< VirtualNetDevice > tunDevice, Ipv4Address s5Addr, const Ptr< Socket > s5uSocket, const Ptr< Socket > s5cSocket)
void SetUeAddress6(uint64_t imsi, Ipv6Address ueAddr)
void RecvFromS5uSocket(Ptr< Socket > socket)
void SendToS5uSocket(Ptr< Packet > packet, Ipv4Address sgwS5uAddress, uint32_t teid)
NrGtpcHeader::Fteid_t GetSenderCpFteid() const
std::list< BearerContextToBeCreated > GetBearerContextsToBeCreated() const
uint32_t GetUliEcgi() const
void SetCause(Cause_t cause)
void SetBearerContextsCreated(std::list< BearerContextCreated > bearerContexts)
void SetSenderCpFteid(NrGtpcHeader::Fteid_t fteid)
uint8_t epsBearerId
EPS bearer ID.
Ptr< NrEpcTft > tft
Bearer traffic flow template.
NrGtpcHeader::Fteid_t fteid
FTEID.
NrEpsBearer bearerLevelQos
Bearer QOS level.