nix-vector-routing: (merges !380) Provide faster lookups by IP address

Use hash table to lookup nodes by IP addresses rather than linear search
This commit is contained in:
Steven Smith
2020-08-21 15:31:04 -07:00
committed by Tom Henderson
parent 4d1387cac0
commit 8fa163fb0a
2 changed files with 93 additions and 15 deletions

View File

@@ -25,6 +25,7 @@
#include "ns3/abort.h"
#include "ns3/names.h"
#include "ns3/ipv4-list-routing.h"
#include "ns3/loopback-net-device.h"
#include "ipv4-nix-vector-routing.h"
@@ -35,6 +36,7 @@ NS_LOG_COMPONENT_DEFINE ("Ipv4NixVectorRouting");
NS_OBJECT_ENSURE_REGISTERED (Ipv4NixVectorRouting);
bool Ipv4NixVectorRouting::g_isCacheDirty = false;
Ipv4NixVectorRouting::Ipv4AddressToNodeMap Ipv4NixVectorRouting::g_ipv4AddressToNodeMap;
TypeId
Ipv4NixVectorRouting::GetTypeId (void)
@@ -105,6 +107,10 @@ Ipv4NixVectorRouting::FlushGlobalNixRoutingCache (void) const
rp->FlushNixCache ();
rp->FlushIpv4RouteCache ();
}
// IPv4 address to node mapping is potentially invalid so clear it.
// Will be repopulated in lazy evaluation when mapping is needed.
g_ipv4AddressToNodeMap.clear ();
}
void
@@ -342,29 +348,68 @@ Ipv4NixVectorRouting::GetAdjacentNetDevices (Ptr<NetDevice> netDevice, Ptr<Chann
}
}
Ptr<Node>
Ipv4NixVectorRouting::GetNodeByIp (Ipv4Address dest)
{
void
Ipv4NixVectorRouting::BuildIpv4AddressToNodeMap (void)
{
NS_LOG_FUNCTION_NOARGS ();
NodeContainer allNodes = NodeContainer::GetGlobal ();
Ptr<Node> destNode;
for (NodeContainer::Iterator i = allNodes.Begin (); i != allNodes.End (); ++i)
for (NodeList::Iterator it = NodeList::Begin (); it != NodeList::End (); ++it)
{
Ptr<Node> node = *i;
Ptr<Node> node = *it;
Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
if (ipv4->GetInterfaceForAddress (dest) != -1)
if(ipv4)
{
destNode = node;
break;
uint32_t numberOfDevices = node->GetNDevices ();
for (uint32_t deviceId = 0; deviceId < numberOfDevices; deviceId++)
{
Ptr<NetDevice> device = node->GetDevice (deviceId);
// If this is not a loopback device add the IPv4 address to the map
if ( !DynamicCast<LoopbackNetDevice>(device) )
{
int32_t interfaceIndex = (ipv4)->GetInterfaceForDevice (node->GetDevice (deviceId));
if (interfaceIndex != -1)
{
Ipv4InterfaceAddress ifAddr = ipv4->GetAddress (interfaceIndex, 0);
Ipv4Address addr = ifAddr.GetLocal ();
NS_ABORT_MSG_IF (g_ipv4AddressToNodeMap.count (addr),
"Duplicate IPv4 address (" << addr << ") found during NIX Vector map construction for node " << node->GetId ());
NS_LOG_LOGIC ("Adding IPv4 address " << addr << " for node " << node->GetId () << " to NIX Vector IPv4 address to node map");
g_ipv4AddressToNodeMap[addr] = node;
}
}
}
}
}
}
if (!destNode)
Ptr<Node>
Ipv4NixVectorRouting::GetNodeByIp (Ipv4Address dest)
{
NS_LOG_FUNCTION_NOARGS ();
// Populate lookup table if is empty.
if ( g_ipv4AddressToNodeMap.empty () )
{
BuildIpv4AddressToNodeMap ();
}
Ptr<Node> destNode;
Ipv4AddressToNodeMap::iterator iter = g_ipv4AddressToNodeMap.find(dest);
if(iter == g_ipv4AddressToNodeMap.end ())
{
NS_LOG_ERROR ("Couldn't find dest node given the IP" << dest);
return 0;
destNode = 0;
}
else
{
destNode = iter -> second;
}
return destNode;

View File

@@ -21,8 +21,6 @@
#ifndef IPV4_NIX_VECTOR_ROUTING_H
#define IPV4_NIX_VECTOR_ROUTING_H
#include <map>
#include "ns3/channel.h"
#include "ns3/node-container.h"
#include "ns3/node-list.h"
@@ -33,6 +31,9 @@
#include "ns3/bridge-net-device.h"
#include "ns3/nstime.h"
#include <map>
#include <unordered_map>
namespace ns3 {
/**
@@ -227,6 +228,11 @@ private:
*/
void CheckCacheStateAndFlush (void) const;
/**
* Build map from IPv4 Address to Node for faster lookup.
*/
void BuildIpv4AddressToNodeMap (void);
/**
* Flag to mark when caches are dirty and need to be flushed.
* Used for lazy cleanup of caches when there are many topology changes.
@@ -244,6 +250,33 @@ private:
/** Total neighbors used for nix-vector to determine number of bits */
uint32_t m_totalNeighbors;
/**
* \brief Hashing for the ipv4Address class
*/
struct Ipv4AddressHash
{
/**
* \brief operator ()
* \param address the IPv4 address to hash
* \return the hash of the address
*/
size_t operator() (const Ipv4Address &address) const
{
return std::hash<uint32_t>()(address.Get ());
}
};
/**
* Mapping of IPv4 address to ns-3 node.
*
* Used to avoid linear searching of nodes/devices to find a node in
* GetNodeByIp() method. NIX vector routing assumes IP addresses
* are unique so mapping can be done without duplication.
**/
typedef std::unordered_map<Ipv4Address, ns3::Ptr<ns3::Node>, Ipv4AddressHash > Ipv4AddressToNodeMap;
static Ipv4AddressToNodeMap g_ipv4AddressToNodeMap;
};
} // namespace ns3