157 lines
4.9 KiB
C++
157 lines
4.9 KiB
C++
#include "psfp-flow-meter-instance.h"
|
|
|
|
#include "ns3/log.h"
|
|
#include "ns3/integer.h"
|
|
#include "ns3/uinteger.h"
|
|
#include "ns3/boolean.h"
|
|
#include "ns3/simulator.h"
|
|
|
|
#include "ns3/ethernet-header2.h"
|
|
#include "ns3/ethernet-trailer.h"
|
|
|
|
namespace ns3
|
|
{
|
|
|
|
NS_LOG_COMPONENT_DEFINE("FlowMeterInstance");
|
|
|
|
NS_OBJECT_ENSURE_REGISTERED(FlowMeterInstance);
|
|
|
|
TypeId
|
|
FlowMeterInstance::GetTypeId()
|
|
{
|
|
static TypeId tid =
|
|
TypeId("ns3::FlowMeterInstance")
|
|
.SetParent<Object>()
|
|
.SetGroupName("Tsn")
|
|
.AddConstructor<FlowMeterInstance>()
|
|
.AddAttribute("CIR",
|
|
"CIR parameter in bit/s",
|
|
DataRateValue(DataRate("0Gb/s")),
|
|
MakeDataRateAccessor(&FlowMeterInstance::m_cir),
|
|
MakeDataRateChecker())
|
|
.AddAttribute("CBS",
|
|
"CBS parameter in bit",
|
|
UintegerValue(0),
|
|
MakeUintegerAccessor(&FlowMeterInstance::m_cbs),
|
|
MakeUintegerChecker<uint32_t>())
|
|
.AddAttribute("EIR",
|
|
"EIR parameter in bit/s",
|
|
DataRateValue(DataRate("0Gb/s")),
|
|
MakeDataRateAccessor(&FlowMeterInstance::m_eir),
|
|
MakeDataRateChecker())
|
|
.AddAttribute("EBS",
|
|
"EBS parameter in bit",
|
|
UintegerValue(0),
|
|
MakeUintegerAccessor(&FlowMeterInstance::m_ebs),
|
|
MakeUintegerChecker<uint32_t>())
|
|
.AddAttribute("DropOnYellow",
|
|
"Drop on yellow function activation boolean",
|
|
BooleanValue(false),
|
|
MakeBooleanAccessor(&FlowMeterInstance::m_dropOnYellow),
|
|
MakeBooleanChecker())
|
|
.AddAttribute("CF",
|
|
"coupling flag boolean",
|
|
BooleanValue(false),
|
|
MakeBooleanAccessor(&FlowMeterInstance::m_cf),
|
|
MakeBooleanChecker())
|
|
.AddAttribute("MarkAllFramesRedEnable",
|
|
"MarkAllFramesRedEnable function activation boolean",
|
|
BooleanValue(false),
|
|
MakeBooleanAccessor(&FlowMeterInstance::m_markAllFramesRedEnable),
|
|
MakeBooleanChecker());
|
|
return tid;
|
|
}
|
|
|
|
FlowMeterInstance::FlowMeterInstance()
|
|
{
|
|
NS_LOG_FUNCTION(this);
|
|
m_lastTokenUpdateTime = Simulator::Now();
|
|
m_markAllFramesRed = false;
|
|
}
|
|
|
|
FlowMeterInstance::~FlowMeterInstance()
|
|
{
|
|
NS_LOG_FUNCTION(this);
|
|
}
|
|
|
|
bool
|
|
FlowMeterInstance::Test(Ptr<Packet> packet)
|
|
{
|
|
NS_LOG_FUNCTION(this);
|
|
updateTokenBuckets();
|
|
|
|
Ptr<Packet> payload = packet->Copy();
|
|
EthernetHeader2 ethHeader;
|
|
EthernetTrailer trailer;
|
|
payload->RemoveHeader(ethHeader);
|
|
payload->RemoveTrailer(trailer);
|
|
|
|
if (m_markAllFramesRed){
|
|
//Mark all frame = drop all
|
|
NS_LOG_INFO("[PSFP] Packet #" << payload->GetUid() << " dropped due to markAllFrameRed");
|
|
return true;
|
|
}
|
|
|
|
NS_LOG_INFO("pkt size = " << payload->GetSize());
|
|
//First token bucket test
|
|
if (payload->GetSize() <= m_committedToken) {
|
|
//Mark green
|
|
m_committedToken -= payload->GetSize();
|
|
NS_LOG_INFO("[PSFP] Packet #" << payload->GetUid() << " marked green");
|
|
return false;
|
|
}
|
|
|
|
//Second token bucket test
|
|
if (payload->GetSize() <= m_excessToken) {
|
|
//Mark yellow
|
|
m_excessToken -= payload->GetSize();
|
|
if(m_dropOnYellow){
|
|
NS_LOG_INFO("[PSFP] Packet #" << payload->GetUid() << " marked yellow and dropped");
|
|
return true;
|
|
}
|
|
else{
|
|
NS_LOG_INFO("[PSFP] Packet #" << payload->GetUid() << " marked yellow and passed");
|
|
return false;
|
|
}
|
|
}
|
|
else{
|
|
//Mark red
|
|
NS_LOG_INFO("[PSFP] Packet #" << payload->GetUid() << " marked red (committedToken=" << m_committedToken << ", need " << payload->GetSize() << " tokens to pass)");
|
|
if(m_markAllFramesRedEnable){
|
|
m_markAllFramesRed = true;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void
|
|
FlowMeterInstance::updateTokenBuckets()
|
|
{
|
|
NS_LOG_FUNCTION(this);
|
|
uint16_t tokenOverflow = 0;
|
|
Time sinceLastUpdate = Simulator::Now() - m_lastTokenUpdateTime;
|
|
|
|
m_committedToken = m_committedToken + (sinceLastUpdate.GetSeconds() * m_cir.GetBitRate())/8.;
|
|
if (m_committedToken > m_cbs){
|
|
if (m_cf){
|
|
tokenOverflow = m_committedToken - m_cbs;
|
|
}
|
|
m_committedToken = m_cbs;
|
|
}
|
|
|
|
m_excessToken = m_excessToken + (sinceLastUpdate.GetSeconds() * m_eir.GetBitRate())/8. + tokenOverflow;
|
|
if (m_excessToken>m_ebs){
|
|
m_excessToken = m_ebs;
|
|
}
|
|
|
|
m_lastTokenUpdateTime = Simulator::Now();
|
|
NS_LOG_INFO("m_committedToken = " << m_committedToken);
|
|
NS_LOG_INFO("m_excessToken = " << m_excessToken);
|
|
}
|
|
|
|
|
|
|
|
};
|