traffic-control: Add a Hash method to QueueDiscItem

This commit is contained in:
Stefano Avallone
2018-05-24 00:33:23 +02:00
parent ce1c923feb
commit 949a7fb682
6 changed files with 155 additions and 0 deletions

View File

@@ -18,6 +18,8 @@
#include "ns3/log.h"
#include "ipv4-queue-disc-item.h"
#include "ns3/tcp-header.h"
#include "ns3/udp-header.h"
namespace ns3 {
@@ -109,4 +111,59 @@ Ipv4QueueDiscItem::GetUint8Value (QueueItem::Uint8Values field, uint8_t& value)
return ret;
}
uint32_t
Ipv4QueueDiscItem::Hash (uint32_t perturbation) const
{
NS_LOG_FUNCTION (this << perturbation);
Ipv4Address src = m_header.GetSource ();
Ipv4Address dest = m_header.GetDestination ();
uint8_t prot = m_header.GetProtocol ();
uint16_t fragOffset = m_header.GetFragmentOffset ();
TcpHeader tcpHdr;
UdpHeader udpHdr;
uint16_t srcPort = 0;
uint16_t destPort = 0;
if (prot == 6 && fragOffset == 0) // TCP
{
GetPacket ()->PeekHeader (tcpHdr);
srcPort = tcpHdr.GetSourcePort ();
destPort = tcpHdr.GetDestinationPort ();
}
else if (prot == 17 && fragOffset == 0) // UDP
{
GetPacket ()->PeekHeader (udpHdr);
srcPort = udpHdr.GetSourcePort ();
destPort = udpHdr.GetDestinationPort ();
}
if (prot != 6 && prot != 17)
{
NS_LOG_WARN ("Unknown transport protocol, no port number included in hash computation");
}
/* serialize the 5-tuple and the perturbation in buf */
uint8_t buf[17];
src.Serialize (buf);
dest.Serialize (buf + 4);
buf[8] = prot;
buf[9] = (srcPort >> 8) & 0xff;
buf[10] = srcPort & 0xff;
buf[11] = (destPort >> 8) & 0xff;
buf[12] = destPort & 0xff;
buf[13] = (perturbation >> 24) & 0xff;
buf[14] = (perturbation >> 16) & 0xff;
buf[15] = (perturbation >> 8) & 0xff;
buf[16] = perturbation & 0xff;
// Linux calculates jhash2 (jenkins hash), we calculate murmur3 because it is
// already available in ns-3
uint32_t hash = Hash32 ((char*) buf, 17);
NS_LOG_DEBUG ("Hash value " << hash);
return hash;
}
} // namespace ns3

View File

@@ -82,6 +82,18 @@ public:
*/
virtual bool Mark (void);
/**
* \brief Computes the hash of the packet's 5-tuple
*
* Computes the hash of the source and destination IP addresses, protocol
* number and, if the transport protocol is either UDP or TCP, the source
* and destination port
*
* \param perturbation hash perturbation value
* \return the hash of the packet's 5-tuple
*/
virtual uint32_t Hash (uint32_t perturbation) const;
private:
/**
* \brief Default constructor

View File

@@ -18,6 +18,8 @@
#include "ns3/log.h"
#include "ipv6-queue-disc-item.h"
#include "ns3/tcp-header.h"
#include "ns3/udp-header.h"
namespace ns3 {
@@ -108,4 +110,58 @@ Ipv6QueueDiscItem::GetUint8Value (QueueItem::Uint8Values field, uint8_t& value)
return ret;
}
uint32_t
Ipv6QueueDiscItem::Hash (uint32_t perturbation) const
{
NS_LOG_FUNCTION (this << perturbation);
Ipv6Address src = m_header.GetSourceAddress ();
Ipv6Address dest = m_header.GetDestinationAddress ();
uint8_t prot = m_header.GetNextHeader ();
TcpHeader tcpHdr;
UdpHeader udpHdr;
uint16_t srcPort = 0;
uint16_t destPort = 0;
if (prot == 6) // TCP
{
GetPacket ()->PeekHeader (tcpHdr);
srcPort = tcpHdr.GetSourcePort ();
destPort = tcpHdr.GetDestinationPort ();
}
else if (prot == 17) // UDP
{
GetPacket ()->PeekHeader (udpHdr);
srcPort = udpHdr.GetSourcePort ();
destPort = udpHdr.GetDestinationPort ();
}
if (prot != 6 && prot != 17)
{
NS_LOG_WARN ("Unknown transport protocol, no port number included in hash computation");
}
/* serialize the 5-tuple and the perturbation in buf */
uint8_t buf[41];
src.Serialize (buf);
dest.Serialize (buf + 16);
buf[32] = prot;
buf[33] = (srcPort >> 8) & 0xff;
buf[34] = srcPort & 0xff;
buf[35] = (destPort >> 8) & 0xff;
buf[36] = destPort & 0xff;
buf[37] = (perturbation >> 24) & 0xff;
buf[38] = (perturbation >> 16) & 0xff;
buf[39] = (perturbation >> 8) & 0xff;
buf[40] = perturbation & 0xff;
// Linux calculates jhash2 (jenkins hash), we calculate murmur3 because it is
// already available in ns-3
uint32_t hash = Hash32 ((char*) buf, 41);
NS_LOG_DEBUG ("Found Ipv6 packet; hash of the five tuple " << hash);
return hash;
}
} // namespace ns3

View File

@@ -82,6 +82,18 @@ public:
*/
virtual bool Mark (void);
/**
* \brief Computes the hash of the packet's 5-tuple
*
* Computes the hash of the source and destination IP addresses, protocol
* number and, if the transport protocol is either UDP or TCP, the source
* and destination port
*
* \param perturbation hash perturbation value
* \return the hash of the packet's 5-tuple
*/
virtual uint32_t Hash (uint32_t perturbation) const;
private:
/**
* \brief Default constructor

View File

@@ -139,4 +139,11 @@ QueueDiscItem::Print (std::ostream& os) const
;
}
uint32_t
QueueDiscItem::Hash (uint32_t perturbation) const
{
NS_LOG_WARN ("The Hash method should be redefined by subclasses");
return 0;
}
} // namespace ns3

View File

@@ -215,6 +215,17 @@ public:
*/
virtual bool Mark (void) = 0;
/**
* \brief Computes the hash of various fields of the packet header
*
* This method just returns 0. Subclasses should implement a reasonable hash
* for their protocol type, such as hashing on the TCP/IP 5-tuple.
*
* \param perturbation hash perturbation value
* \return the hash of various fields of the packet header
*/
virtual uint32_t Hash (uint32_t perturbation = 0) const;
private:
/**
* \brief Default constructor