revised TEID generation and TFT classification at SGW
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include "ns3/ipv4.h"
|
||||
#include "ns3/inet-socket-address.h"
|
||||
#include "ns3/epc-gtpu-header.h"
|
||||
#include "ns3/abort.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -33,25 +34,24 @@ NS_LOG_COMPONENT_DEFINE ("EpcSgwPgwApplication");
|
||||
|
||||
|
||||
/////////////////////////
|
||||
// EnbInfo
|
||||
// UeInfo
|
||||
/////////////////////////
|
||||
|
||||
|
||||
EpcSgwPgwApplication::EnbInfo::EnbInfo ()
|
||||
: m_teidCounter (0)
|
||||
EpcSgwPgwApplication::UeInfo::UeInfo ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
EpcSgwPgwApplication::EnbInfo::AddBearer (Ptr<LteTft> tft)
|
||||
void
|
||||
EpcSgwPgwApplication::UeInfo::AddBearer (Ptr<LteTft> tft, uint32_t teid)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << tft);
|
||||
return m_tftClassifier.Add (tft);
|
||||
NS_LOG_FUNCTION (this << tft << teid);
|
||||
return m_tftClassifier.Add (tft, teid);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
EpcSgwPgwApplication::EnbInfo::Classify (Ptr<Packet> p)
|
||||
EpcSgwPgwApplication::UeInfo::Classify (Ptr<Packet> p)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << p);
|
||||
// we hardcode DOWNLINK direction since the PGW is espected to
|
||||
@@ -60,6 +60,17 @@ EpcSgwPgwApplication::EnbInfo::Classify (Ptr<Packet> p)
|
||||
return m_tftClassifier.Classify (p, LteTft::DOWNLINK);
|
||||
}
|
||||
|
||||
Ipv4Address
|
||||
EpcSgwPgwApplication::UeInfo::GetEnbAddr ()
|
||||
{
|
||||
return m_enbAddr;
|
||||
}
|
||||
|
||||
void
|
||||
EpcSgwPgwApplication::UeInfo::SetEnbAddr (Ipv4Address enbAddr)
|
||||
{
|
||||
m_enbAddr = enbAddr;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// EpcSgwPgwApplication
|
||||
@@ -79,7 +90,8 @@ EpcSgwPgwApplication::GetTypeId (void)
|
||||
EpcSgwPgwApplication::EpcSgwPgwApplication (const Ptr<VirtualNetDevice> tunDevice, const Ptr<Socket> s1uSocket)
|
||||
: m_s1uSocket (s1uSocket),
|
||||
m_tunDevice (tunDevice),
|
||||
m_gtpuUdpPort (2152) // fixed by the standard
|
||||
m_gtpuUdpPort (2152), // fixed by the standard
|
||||
m_teidCount (0)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << tunDevice << s1uSocket);
|
||||
m_s1uSocket->SetRecvCallback (MakeCallback (&EpcSgwPgwApplication::RecvFromS1uSocket, this));
|
||||
@@ -96,11 +108,24 @@ uint32_t
|
||||
EpcSgwPgwApplication::ActivateS1Bearer (Ipv4Address ueAddr, Ipv4Address enbAddr, Ptr<LteTft> tft)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << ueAddr << enbAddr << tft);
|
||||
// side effect: add entry if not exists
|
||||
m_ueAddrEnbAddrMap[ueAddr] = enbAddr;
|
||||
|
||||
// side effect: create new EnbInfo if it does not exist
|
||||
uint32_t teid = m_enbInfoMap[enbAddr].AddBearer (tft);
|
||||
// simple sanity check. If you ever need more than 4M teids
|
||||
// throughout your simulation, you'll need to implement a smarter teid
|
||||
// management algorithm.
|
||||
NS_ABORT_IF (m_teidCount == 0xFFFFFFFF);
|
||||
uint32_t teid = ++m_teidCount;
|
||||
|
||||
std::map<Ipv4Address, UeInfo>::iterator it = m_ueInfoMap.find (ueAddr);
|
||||
if (it == m_ueInfoMap.end ())
|
||||
{
|
||||
// UE unknown, creating new entry
|
||||
std::pair<std::map<Ipv4Address, UeInfo>::iterator, bool> ret;
|
||||
ret = m_ueInfoMap.insert (std::pair <Ipv4Address, UeInfo> (ueAddr, UeInfo ()));
|
||||
it = ret.first;
|
||||
it->second.SetEnbAddr (enbAddr);
|
||||
}
|
||||
|
||||
it->second.AddBearer (tft, teid);
|
||||
return teid;
|
||||
}
|
||||
|
||||
@@ -116,30 +141,28 @@ EpcSgwPgwApplication::RecvFromTunDevice (Ptr<Packet> packet, const Address& sour
|
||||
Ipv4Address ueAddr = ipv4Header.GetDestination ();
|
||||
NS_LOG_LOGIC ("packet addressed to UE " << ueAddr);
|
||||
|
||||
// find corresponding eNB address
|
||||
std::map<Ipv4Address, Ipv4Address>::iterator it1 = m_ueAddrEnbAddrMap.find (ueAddr);
|
||||
if (it1 == m_ueAddrEnbAddrMap.end ())
|
||||
// find corresponding UeInfo address
|
||||
std::map<Ipv4Address, UeInfo>::iterator it = m_ueInfoMap.find (ueAddr);
|
||||
if (it == m_ueInfoMap.end ())
|
||||
{
|
||||
NS_LOG_WARN ("could not find corresponding eNB for UE address " << ueAddr) ;
|
||||
NS_LOG_WARN ("unknown UE address " << ueAddr) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
Ipv4Address enbAddr = it1->second;
|
||||
// lookup into TFT classifier for that eNB
|
||||
std::map<Ipv4Address, EnbInfo>::iterator it2 = m_enbInfoMap.find (enbAddr);
|
||||
NS_ASSERT (it2 != m_enbInfoMap.end ());
|
||||
uint32_t teid = it2->second.Classify (packet);
|
||||
Ipv4Address enbAddr = it->second.GetEnbAddr ();
|
||||
uint32_t teid = it->second.Classify (packet);
|
||||
if (teid == 0)
|
||||
{
|
||||
NS_LOG_WARN ("no matching TEID for this packet");
|
||||
NS_LOG_WARN ("no matching bearer for this packet");
|
||||
}
|
||||
else
|
||||
{
|
||||
SendToS1uSocket (packet, enbAddr, teid);
|
||||
}
|
||||
}
|
||||
// there is no reason why we should notify the Gi TUN
|
||||
// VirtualNetDevice that he failed to send the packet
|
||||
// there is no reason why we should notify the TUN
|
||||
// VirtualNetDevice that he failed to send the packet: if we receive
|
||||
// any bogus packet, it will just be silently discarded.
|
||||
const bool succeeded = true;
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
@@ -130,36 +130,47 @@ private:
|
||||
|
||||
|
||||
/**
|
||||
* store info for each eNB connected to this SGW
|
||||
*
|
||||
* store info for each UE connected to this SGW
|
||||
*/
|
||||
class EnbInfo
|
||||
class UeInfo
|
||||
{
|
||||
public:
|
||||
EnbInfo ();
|
||||
UeInfo ();
|
||||
|
||||
/**
|
||||
*
|
||||
* \param tft the Traffic Flow Template of the new bearer to be added
|
||||
*
|
||||
* \return the TEID of the newly added bearer
|
||||
* \param teid the TEID of the new bearer
|
||||
*/
|
||||
uint32_t AddBearer (Ptr<LteTft> tft);
|
||||
|
||||
void AddBearer (Ptr<LteTft> tft, uint32_t teid);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* \param p the IP packet from the internet to be classified
|
||||
*
|
||||
* \return the corresponding TEID > 0 if matched, or 0 if no match
|
||||
* \return the corresponding bearer ID > 0 identifying the bearer
|
||||
* among all the bearers of this UE; returns 0 if no bearers
|
||||
* matches with the previously declared TFTs
|
||||
*/
|
||||
uint32_t Classify (Ptr<Packet> p);
|
||||
|
||||
/**
|
||||
* \return the address of the eNB to which the UE is connected
|
||||
*/
|
||||
Ipv4Address GetEnbAddr ();
|
||||
|
||||
/**
|
||||
* set the address of the eNB to which the UE is connected
|
||||
*
|
||||
* \param addr the address of the eNB
|
||||
*/
|
||||
void SetEnbAddr (Ipv4Address addr);
|
||||
|
||||
|
||||
private:
|
||||
uint32_t m_teidCounter;
|
||||
EpsTftClassifier m_tftClassifier;
|
||||
Ipv4Address m_enbAddr;
|
||||
};
|
||||
|
||||
|
||||
@@ -175,21 +186,17 @@ private:
|
||||
Ptr<VirtualNetDevice> m_tunDevice;
|
||||
|
||||
/**
|
||||
* Map telling for each UE address what is the corresponding eNB address
|
||||
* Map telling for each UE address the corresponding UE info
|
||||
*/
|
||||
std::map<Ipv4Address, Ipv4Address> m_ueAddrEnbAddrMap;
|
||||
|
||||
/**
|
||||
* Map telling for each eNB address the corresponding eNB info (TFT
|
||||
* classifier, etc.)
|
||||
*/
|
||||
std::map<Ipv4Address, EnbInfo> m_enbInfoMap;
|
||||
std::map<Ipv4Address, UeInfo> m_ueInfoMap;
|
||||
|
||||
/**
|
||||
* UDP port to be used for GTP
|
||||
*/
|
||||
uint16_t m_gtpuUdpPort;
|
||||
|
||||
uint32_t m_teidCount;
|
||||
|
||||
};
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
#include "eps-tft-classifier.h"
|
||||
#include "lte-tft.h"
|
||||
#include "ns3/abort.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/ipv4-header.h"
|
||||
@@ -42,20 +41,19 @@ NS_LOG_COMPONENT_DEFINE ("EpsTftClassifier");
|
||||
namespace ns3 {
|
||||
|
||||
EpsTftClassifier::EpsTftClassifier ()
|
||||
: m_tftCount (0)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
EpsTftClassifier::Add (Ptr<LteTft> tft)
|
||||
void
|
||||
EpsTftClassifier::Add (Ptr<LteTft> tft, uint32_t id)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << tft);
|
||||
// simple sanity check. If you ever need more than 4M TFTs within a same classifiers, you'll need to implement a smarter id management algorithm.
|
||||
NS_ABORT_IF (m_tftCount == 0xFFFFFFFF);
|
||||
++m_tftCount;
|
||||
m_tftMap[m_tftCount] = tft;
|
||||
return m_tftCount;
|
||||
|
||||
m_tftMap[id] = tft;
|
||||
|
||||
// simple sanity check: there shouldn't be more than 16 bearers (hence TFTs) per UE
|
||||
NS_ASSERT (m_tftMap.size () <= 16);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -51,9 +51,8 @@ public:
|
||||
*
|
||||
* \param tft the TFT to be added
|
||||
*
|
||||
* \return the unique identifier of the added TFT within this Classifier instance
|
||||
*/
|
||||
uint32_t Add (Ptr<LteTft> tft);
|
||||
void Add (Ptr<LteTft> tft, uint32_t id);
|
||||
|
||||
/**
|
||||
* delete an existing TFT from the classifier
|
||||
@@ -75,7 +74,6 @@ public:
|
||||
protected:
|
||||
|
||||
std::map <uint32_t, Ptr<LteTft> > m_tftMap;
|
||||
uint32_t m_tftCount;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ EpsTftClassifierTestSuite::EpsTftClassifierTestSuite ()
|
||||
pf1_1_2.localMask.Set (0xFFFFFF00);
|
||||
tft1_1->Add (pf1_1_2);
|
||||
|
||||
c1->Add (tft1_1);
|
||||
c1->Add (tft1_1, 1);
|
||||
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ EpsTftClassifierTestSuite::EpsTftClassifierTestSuite ()
|
||||
pf1_2_2.localPortEnd = 3489;
|
||||
tft1_2->Add (pf1_2_2);
|
||||
|
||||
c1->Add (tft1_2);
|
||||
c1->Add (tft1_2, 2);
|
||||
|
||||
// ------------------------------------classifier---direction--------------src address---------------dst address---src port--dst port--ToS--TFT id
|
||||
|
||||
@@ -211,7 +211,7 @@ EpsTftClassifierTestSuite::EpsTftClassifierTestSuite ()
|
||||
///////////////////////////
|
||||
|
||||
Ptr<EpsTftClassifier> c2 = Create<EpsTftClassifier> ();
|
||||
c2->Add (LteTft::Default ());
|
||||
c2->Add (LteTft::Default (), 1);
|
||||
|
||||
// ------------------------------------classifier---direction--------------src address---------------dst address---src port--dst port--ToS--TFT id
|
||||
|
||||
@@ -247,9 +247,9 @@ EpsTftClassifierTestSuite::EpsTftClassifierTestSuite ()
|
||||
///////////////////////////////////////////
|
||||
|
||||
Ptr<EpsTftClassifier> c3 = Create<EpsTftClassifier> ();
|
||||
c3->Add (LteTft::Default ());
|
||||
c3->Add (tft1_1);
|
||||
c3->Add (tft1_2);
|
||||
c3->Add (LteTft::Default (), 1);
|
||||
c3->Add (tft1_1, 2);
|
||||
c3->Add (tft1_2, 3);
|
||||
|
||||
// ------------------------------------classifier---direction--------------src address---------------dst address---src port--dst port--ToS--TFT id
|
||||
|
||||
|
||||
Reference in New Issue
Block a user