flow-monitor: Keep track of the DSCP value of packets

This commit is contained in:
Stefano Avallone
2017-03-08 18:02:10 +01:00
parent b51598d076
commit 11bdd2e3c8
6 changed files with 155 additions and 5 deletions

View File

@@ -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>

View File

@@ -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 ();

View File

@@ -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;

View File

@@ -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;
};

View File

@@ -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;

View File

@@ -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;
};