flow-monitor: Keep track of the DSCP value of packets
This commit is contained in:
@@ -86,6 +86,10 @@ us a note on ns-developers mailing list.</p>
|
||||
optional and if not specified defaults to the previous behavior (Time::S).
|
||||
</li>
|
||||
<li><b>TxopTrace</b>: new trace source exported by EdcaTxopN.</li>
|
||||
<li>A <b>GetDscpCounts</b> method is added to <b>Ipv4FlowClassifier</b> and <b>Ipv6FlowClassifier</b>
|
||||
which returns a vector of pairs (dscp,count), each of which indicates how many packets with the
|
||||
associated dscp value have been classified for a given flow.
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Changes to existing API:</h2>
|
||||
<ul>
|
||||
|
||||
@@ -153,7 +153,9 @@ main (int argc, char *argv[])
|
||||
onoff.SetAttribute ("DataRate", StringValue ("50Mbps")); //bit/s
|
||||
ApplicationContainer apps;
|
||||
|
||||
AddressValue remoteAddress (InetSocketAddress (interfaces.GetAddress (0), port));
|
||||
InetSocketAddress rmt (interfaces.GetAddress (0), port);
|
||||
rmt.SetTos (0xb8);
|
||||
AddressValue remoteAddress (rmt);
|
||||
onoff.SetAttribute ("Remote", remoteAddress);
|
||||
apps.Add (onoff.Install (nodes.Get (1)));
|
||||
apps.Start (Seconds (1.0));
|
||||
@@ -194,6 +196,12 @@ main (int argc, char *argv[])
|
||||
std::cout << " Throughput: " << stats[1].rxBytes * 8.0 / (stats[1].timeLastRxPacket.GetSeconds () - stats[1].timeFirstRxPacket.GetSeconds ()) / 1000000 << " Mbps" << std::endl;
|
||||
std::cout << " Mean delay: " << stats[1].delaySum.GetSeconds () / stats[1].rxPackets << std::endl;
|
||||
std::cout << " Mean jitter: " << stats[1].jitterSum.GetSeconds () / (stats[1].rxPackets - 1) << std::endl;
|
||||
auto dscpVec = classifier->GetDscpCounts (1);
|
||||
for (auto p : dscpVec)
|
||||
{
|
||||
std::cout << " DSCP value: 0x" << std::hex << static_cast<uint32_t>(p.first) << std::dec
|
||||
<< " count: "<< p.second << std::endl;
|
||||
}
|
||||
|
||||
Simulator::Destroy ();
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "ipv4-flow-classifier.h"
|
||||
#include "ns3/udp-header.h"
|
||||
#include "ns3/tcp-header.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -156,12 +157,24 @@ Ipv4FlowClassifier::Classify (const Ipv4Header &ipHeader, Ptr<const Packet> ipPa
|
||||
FlowId newFlowId = GetNewFlowId ();
|
||||
insert.first->second = newFlowId;
|
||||
m_flowPktIdMap[newFlowId] = 0;
|
||||
m_flowDscpMap[newFlowId];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flowPktIdMap[insert.first->second] ++;
|
||||
}
|
||||
|
||||
// increment the counter of packets with the same DSCP value
|
||||
Ipv4Header::DscpType dscp = ipHeader.GetDscp ();
|
||||
std::pair<std::map<Ipv4Header::DscpType, uint32_t>::iterator, bool> dscpInserter
|
||||
= m_flowDscpMap[insert.first->second].insert (std::pair<Ipv4Header::DscpType, uint32_t> (dscp, 1));
|
||||
|
||||
// if the insertion did not succeed, we need to increment the counter
|
||||
if (!dscpInserter.second)
|
||||
{
|
||||
m_flowDscpMap[insert.first->second][dscp] ++;
|
||||
}
|
||||
|
||||
*out_flowId = insert.first->second;
|
||||
*out_packetId = m_flowPktIdMap[*out_flowId];
|
||||
|
||||
@@ -185,6 +198,29 @@ Ipv4FlowClassifier::FindFlow (FlowId flowId) const
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool
|
||||
Ipv4FlowClassifier::SortByCount::operator() (std::pair<Ipv4Header::DscpType, uint32_t> left,
|
||||
std::pair<Ipv4Header::DscpType, uint32_t> right)
|
||||
{
|
||||
return left.second > right.second;
|
||||
}
|
||||
|
||||
std::vector<std::pair<Ipv4Header::DscpType, uint32_t> >
|
||||
Ipv4FlowClassifier::GetDscpCounts (FlowId flowId) const
|
||||
{
|
||||
std::map<FlowId, std::map<Ipv4Header::DscpType, uint32_t> >::const_iterator flow
|
||||
= m_flowDscpMap.find (flowId);
|
||||
|
||||
if (flow == m_flowDscpMap.end ())
|
||||
{
|
||||
NS_FATAL_ERROR ("Could not find the flow with ID " << flowId);
|
||||
}
|
||||
|
||||
std::vector<std::pair<Ipv4Header::DscpType, uint32_t> > v (flow->second.begin (), flow->second.end ());
|
||||
std::sort (v.begin (), v.end (), SortByCount ());
|
||||
return v;
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4FlowClassifier::SerializeToXmlStream (std::ostream &os, uint16_t indent) const
|
||||
{
|
||||
@@ -200,8 +236,24 @@ Ipv4FlowClassifier::SerializeToXmlStream (std::ostream &os, uint16_t indent) con
|
||||
<< " destinationAddress=\"" << iter->first.destinationAddress << "\""
|
||||
<< " protocol=\"" << int(iter->first.protocol) << "\""
|
||||
<< " sourcePort=\"" << iter->first.sourcePort << "\""
|
||||
<< " destinationPort=\"" << iter->first.destinationPort << "\""
|
||||
<< " />\n";
|
||||
<< " destinationPort=\"" << iter->first.destinationPort << "\">\n";
|
||||
|
||||
indent += 2;
|
||||
std::map<FlowId, std::map<Ipv4Header::DscpType, uint32_t> >::const_iterator flow
|
||||
= m_flowDscpMap.find (iter->second);
|
||||
|
||||
if (flow != m_flowDscpMap.end ())
|
||||
{
|
||||
for (std::map<Ipv4Header::DscpType, uint32_t>::const_iterator i = flow->second.begin (); i != flow->second.end (); i++)
|
||||
{
|
||||
Indent (os, indent);
|
||||
os << "<Dscp value=\"0x" << std::hex << static_cast<uint32_t> (i->first) << "\""
|
||||
<< " packets=\"" << std::dec << i->second << "\" />\n";
|
||||
}
|
||||
}
|
||||
|
||||
indent -= 2;
|
||||
Indent (os, indent); os << "</Flow>\n";
|
||||
}
|
||||
|
||||
indent -= 2;
|
||||
|
||||
@@ -69,6 +69,21 @@ public:
|
||||
/// \returns the FiveTuple corresponding to flowId
|
||||
FiveTuple FindFlow (FlowId flowId) const;
|
||||
|
||||
/// Comparator used to sort the vector of DSCP values
|
||||
class SortByCount
|
||||
{
|
||||
public:
|
||||
bool operator() (std::pair<Ipv4Header::DscpType, uint32_t> left,
|
||||
std::pair<Ipv4Header::DscpType, uint32_t> right);
|
||||
};
|
||||
|
||||
/// \brief get the DSCP values of the packets belonging to the flow with the
|
||||
/// given FlowId, sorted in decreasing order of number of packets seen with
|
||||
/// that DSCP value
|
||||
/// \param flowId the identifier of the flow of interest
|
||||
/// \returns the vector of DSCP values
|
||||
std::vector<std::pair<Ipv4Header::DscpType, uint32_t> > GetDscpCounts (FlowId flowId) const;
|
||||
|
||||
virtual void SerializeToXmlStream (std::ostream &os, uint16_t indent) const;
|
||||
|
||||
private:
|
||||
@@ -77,6 +92,8 @@ private:
|
||||
std::map<FiveTuple, FlowId> m_flowMap;
|
||||
/// Map to FlowIds to FlowPacketId
|
||||
std::map<FlowId, FlowPacketId> m_flowPktIdMap;
|
||||
/// Map FlowIds to (DSCP value, packet count) pairs
|
||||
std::map<FlowId, std::map<Ipv4Header::DscpType, uint32_t> > m_flowDscpMap;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "ipv6-flow-classifier.h"
|
||||
#include "ns3/udp-header.h"
|
||||
#include "ns3/tcp-header.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -157,12 +158,24 @@ Ipv6FlowClassifier::Classify (const Ipv6Header &ipHeader, Ptr<const Packet> ipPa
|
||||
FlowId newFlowId = GetNewFlowId ();
|
||||
insert.first->second = newFlowId;
|
||||
m_flowPktIdMap[newFlowId] = 0;
|
||||
m_flowDscpMap[newFlowId];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flowPktIdMap[insert.first->second] ++;
|
||||
}
|
||||
|
||||
// increment the counter of packets with the same DSCP value
|
||||
Ipv6Header::DscpType dscp = ipHeader.GetDscp ();
|
||||
std::pair<std::map<Ipv6Header::DscpType, uint32_t>::iterator, bool> dscpInserter
|
||||
= m_flowDscpMap[insert.first->second].insert (std::pair<Ipv6Header::DscpType, uint32_t> (dscp, 1));
|
||||
|
||||
// if the insertion did not succeed, we need to increment the counter
|
||||
if (!dscpInserter.second)
|
||||
{
|
||||
m_flowDscpMap[insert.first->second][dscp] ++;
|
||||
}
|
||||
|
||||
*out_flowId = insert.first->second;
|
||||
*out_packetId = m_flowPktIdMap[*out_flowId];
|
||||
|
||||
@@ -186,6 +199,29 @@ Ipv6FlowClassifier::FindFlow (FlowId flowId) const
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool
|
||||
Ipv6FlowClassifier::SortByCount::operator() (std::pair<Ipv6Header::DscpType, uint32_t> left,
|
||||
std::pair<Ipv6Header::DscpType, uint32_t> right)
|
||||
{
|
||||
return left.second > right.second;
|
||||
}
|
||||
|
||||
std::vector<std::pair<Ipv6Header::DscpType, uint32_t> >
|
||||
Ipv6FlowClassifier::GetDscpCounts (FlowId flowId) const
|
||||
{
|
||||
std::map<FlowId, std::map<Ipv6Header::DscpType, uint32_t> >::const_iterator flow
|
||||
= m_flowDscpMap.find (flowId);
|
||||
|
||||
if (flow == m_flowDscpMap.end ())
|
||||
{
|
||||
NS_FATAL_ERROR ("Could not find the flow with ID " << flowId);
|
||||
}
|
||||
|
||||
std::vector<std::pair<Ipv6Header::DscpType, uint32_t> > v (flow->second.begin (), flow->second.end ());
|
||||
std::sort (v.begin (), v.end (), SortByCount ());
|
||||
return v;
|
||||
}
|
||||
|
||||
void
|
||||
Ipv6FlowClassifier::SerializeToXmlStream (std::ostream &os, uint16_t indent) const
|
||||
{
|
||||
@@ -201,8 +237,24 @@ Ipv6FlowClassifier::SerializeToXmlStream (std::ostream &os, uint16_t indent) con
|
||||
<< " destinationAddress=\"" << iter->first.destinationAddress << "\""
|
||||
<< " protocol=\"" << int(iter->first.protocol) << "\""
|
||||
<< " sourcePort=\"" << iter->first.sourcePort << "\""
|
||||
<< " destinationPort=\"" << iter->first.destinationPort << "\""
|
||||
<< " />\n";
|
||||
<< " destinationPort=\"" << iter->first.destinationPort << "\">\n";
|
||||
|
||||
indent += 2;
|
||||
std::map<FlowId, std::map<Ipv6Header::DscpType, uint32_t> >::const_iterator flow
|
||||
= m_flowDscpMap.find (iter->second);
|
||||
|
||||
if (flow != m_flowDscpMap.end ())
|
||||
{
|
||||
for (std::map<Ipv6Header::DscpType, uint32_t>::const_iterator i = flow->second.begin (); i != flow->second.end (); i++)
|
||||
{
|
||||
Indent (os, indent);
|
||||
os << "<Dscp value=\"0x" << std::hex << static_cast<uint32_t> (i->first) << "\""
|
||||
<< " packets=\"" << std::dec << i->second << "\" />\n";
|
||||
}
|
||||
}
|
||||
|
||||
indent -= 2;
|
||||
Indent (os, indent); os << "</Flow>\n";
|
||||
}
|
||||
|
||||
indent -= 2;
|
||||
|
||||
@@ -70,6 +70,21 @@ public:
|
||||
/// \returns the FiveTuple corresponding to flowId
|
||||
FiveTuple FindFlow (FlowId flowId) const;
|
||||
|
||||
/// Comparator used to sort the vector of DSCP values
|
||||
class SortByCount
|
||||
{
|
||||
public:
|
||||
bool operator() (std::pair<Ipv6Header::DscpType, uint32_t> left,
|
||||
std::pair<Ipv6Header::DscpType, uint32_t> right);
|
||||
};
|
||||
|
||||
/// \brief get the DSCP values of the packets belonging to the flow with the
|
||||
/// given FlowId, sorted in decreasing order of number of packets seen with
|
||||
/// that DSCP value
|
||||
/// \param flowId the identifier of the flow of interest
|
||||
/// \returns the vector of DSCP values
|
||||
std::vector<std::pair<Ipv6Header::DscpType, uint32_t> > GetDscpCounts (FlowId flowId) const;
|
||||
|
||||
virtual void SerializeToXmlStream (std::ostream &os, uint16_t indent) const;
|
||||
|
||||
private:
|
||||
@@ -78,6 +93,8 @@ private:
|
||||
std::map<FiveTuple, FlowId> m_flowMap;
|
||||
/// Map to FlowIds to FlowPacketId
|
||||
std::map<FlowId, FlowPacketId> m_flowPktIdMap;
|
||||
/// Map FlowIds to (DSCP value, packet count) pairs
|
||||
std::map<FlowId, std::map<Ipv6Header::DscpType, uint32_t> > m_flowDscpMap;
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user