internet: Add per-flow ECMP routing

This commit is contained in:
F5
2022-11-30 13:47:49 +00:00
parent 787a3093b2
commit 753def9f7e
2 changed files with 31 additions and 5 deletions

View File

@@ -28,6 +28,7 @@
#include "ns3/ipv4-routing-table-entry.h"
#include "ns3/boolean.h"
#include "ns3/node.h"
#include "ipv4-queue-disc-item.h"
#include "ipv4-global-routing.h"
#include "global-route-manager.h"
@@ -48,6 +49,11 @@ Ipv4GlobalRouting::GetTypeId (void)
BooleanValue (false),
MakeBooleanAccessor (&Ipv4GlobalRouting::m_randomEcmpRouting),
MakeBooleanChecker ())
.AddAttribute ("FlowEcmpRouting",
"Set to true if flows are randomly routed among ECMP; set to false for using only one route consistently",
BooleanValue (false),
MakeBooleanAccessor (&Ipv4GlobalRouting::m_flowEcmpRouting),
MakeBooleanChecker ())
.AddAttribute ("RespondToInterfaceEvents",
"Set to true if you want to dynamically recompute the global routes upon Interface notification events (up/down, or add/remove address)",
BooleanValue (false),
@@ -137,7 +143,7 @@ Ipv4GlobalRouting::AddASExternalRouteTo (Ipv4Address network,
Ptr<Ipv4Route>
Ipv4GlobalRouting::LookupGlobal (Ipv4Address dest, Ptr<NetDevice> oif)
Ipv4GlobalRouting::LookupGlobal (Ipv4Address dest, uint32_t flowHash, Ptr<NetDevice> oif)
{
NS_LOG_FUNCTION (this << dest << oif);
NS_LOG_LOGIC ("Looking for route for destination " << dest);
@@ -220,7 +226,11 @@ Ipv4GlobalRouting::LookupGlobal (Ipv4Address dest, Ptr<NetDevice> oif)
// ECMP routing is enabled, or always select the first route
// consistently if random ECMP routing is disabled
uint32_t selectIndex;
if (m_randomEcmpRouting)
if (m_flowEcmpRouting)
{
selectIndex = flowHash % allRoutes.size ();
}
else if (m_randomEcmpRouting)
{
selectIndex = m_rand->GetInteger (0, allRoutes.size ()-1);
}
@@ -462,6 +472,12 @@ Ptr<Ipv4Route>
Ipv4GlobalRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
{
NS_LOG_FUNCTION (this << p << &header << oif << &sockerr);
uint32_t flowHash = 0;
if (m_flowEcmpRouting)
{
flowHash = Ipv4QueueDiscItem (p, Address (), header.GetProtocol (), header).Hash (0);
}
//
// First, see if this is a multicast packet we have a route for. If we
// have a route, then send the packet down each of the specified interfaces.
@@ -475,7 +491,7 @@ Ipv4GlobalRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<Net
// See if this is a unicast packet we have a route for.
//
NS_LOG_LOGIC ("Unicast destination- looking up");
Ptr<Ipv4Route> rtentry = LookupGlobal (header.GetDestination (), oif);
Ptr<Ipv4Route> rtentry = LookupGlobal (header.GetDestination (), flowHash, oif);
if (rtentry)
{
sockerr = Socket::ERROR_NOTERROR;
@@ -492,6 +508,13 @@ Ipv4GlobalRouting::RouteInput (Ptr<const Packet> p, const Ipv4Header &header, P
LocalDeliverCallback lcb, ErrorCallback ecb)
{
NS_LOG_FUNCTION (this << p << header << header.GetSource () << header.GetDestination () << idev << &lcb << &ecb);
uint32_t flowHash = 0;
if (m_flowEcmpRouting)
{
flowHash = Ipv4QueueDiscItem (p->Copy (), Address (), header.GetProtocol (), header).Hash (0);
}
// Check if input device supports IP
NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
@@ -524,7 +547,7 @@ Ipv4GlobalRouting::RouteInput (Ptr<const Packet> p, const Ipv4Header &header, P
}
// Next, try to find a route
NS_LOG_LOGIC ("Unicast destination- looking up global route");
Ptr<Ipv4Route> rtentry = LookupGlobal (header.GetDestination ());
Ptr<Ipv4Route> rtentry = LookupGlobal (header.GetDestination (), flowHash);
if (rtentry != 0)
{
NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");

View File

@@ -234,6 +234,8 @@ protected:
private:
/// Set to true if packets are randomly routed among ECMP; set to false for using only one route consistently
bool m_randomEcmpRouting;
/// Set to true if flows are randomly routed among ECMP; set to false for using only one route consistently
bool m_flowEcmpRouting;
/// Set to true if this interface should respond to interface events by globallly recomputing routes
bool m_respondToInterfaceEvents;
/// A uniform random number generator for randomly routing packets among ECMP
@@ -263,10 +265,11 @@ private:
/**
* \brief Lookup in the forwarding table for destination.
* \param dest destination address
* \param flowHash flow hash for per-flow ECMP routing
* \param oif output interface if any (put 0 otherwise)
* \return Ipv4Route to route the packet to reach dest address
*/
Ptr<Ipv4Route> LookupGlobal (Ipv4Address dest, Ptr<NetDevice> oif = 0);
Ptr<Ipv4Route> LookupGlobal (Ipv4Address dest, uint32_t flowHash = 0, Ptr<NetDevice> oif = 0);
HostRoutes m_hostRoutes; //!< Routes to hosts
NetworkRoutes m_networkRoutes; //!< Routes to networks