internet: Add per-flow ECMP routing
This commit is contained in:
@@ -28,6 +28,7 @@
|
|||||||
#include "ns3/ipv4-routing-table-entry.h"
|
#include "ns3/ipv4-routing-table-entry.h"
|
||||||
#include "ns3/boolean.h"
|
#include "ns3/boolean.h"
|
||||||
#include "ns3/node.h"
|
#include "ns3/node.h"
|
||||||
|
#include "ipv4-queue-disc-item.h"
|
||||||
#include "ipv4-global-routing.h"
|
#include "ipv4-global-routing.h"
|
||||||
#include "global-route-manager.h"
|
#include "global-route-manager.h"
|
||||||
|
|
||||||
@@ -48,6 +49,11 @@ Ipv4GlobalRouting::GetTypeId (void)
|
|||||||
BooleanValue (false),
|
BooleanValue (false),
|
||||||
MakeBooleanAccessor (&Ipv4GlobalRouting::m_randomEcmpRouting),
|
MakeBooleanAccessor (&Ipv4GlobalRouting::m_randomEcmpRouting),
|
||||||
MakeBooleanChecker ())
|
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",
|
.AddAttribute ("RespondToInterfaceEvents",
|
||||||
"Set to true if you want to dynamically recompute the global routes upon Interface notification events (up/down, or add/remove address)",
|
"Set to true if you want to dynamically recompute the global routes upon Interface notification events (up/down, or add/remove address)",
|
||||||
BooleanValue (false),
|
BooleanValue (false),
|
||||||
@@ -137,7 +143,7 @@ Ipv4GlobalRouting::AddASExternalRouteTo (Ipv4Address network,
|
|||||||
|
|
||||||
|
|
||||||
Ptr<Ipv4Route>
|
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_FUNCTION (this << dest << oif);
|
||||||
NS_LOG_LOGIC ("Looking for route for destination " << dest);
|
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
|
// ECMP routing is enabled, or always select the first route
|
||||||
// consistently if random ECMP routing is disabled
|
// consistently if random ECMP routing is disabled
|
||||||
uint32_t selectIndex;
|
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);
|
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)
|
Ipv4GlobalRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
|
||||||
{
|
{
|
||||||
NS_LOG_FUNCTION (this << p << &header << oif << &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
|
// 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.
|
// 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.
|
// See if this is a unicast packet we have a route for.
|
||||||
//
|
//
|
||||||
NS_LOG_LOGIC ("Unicast destination- looking up");
|
NS_LOG_LOGIC ("Unicast destination- looking up");
|
||||||
Ptr<Ipv4Route> rtentry = LookupGlobal (header.GetDestination (), oif);
|
Ptr<Ipv4Route> rtentry = LookupGlobal (header.GetDestination (), flowHash, oif);
|
||||||
if (rtentry)
|
if (rtentry)
|
||||||
{
|
{
|
||||||
sockerr = Socket::ERROR_NOTERROR;
|
sockerr = Socket::ERROR_NOTERROR;
|
||||||
@@ -492,6 +508,13 @@ Ipv4GlobalRouting::RouteInput (Ptr<const Packet> p, const Ipv4Header &header, P
|
|||||||
LocalDeliverCallback lcb, ErrorCallback ecb)
|
LocalDeliverCallback lcb, ErrorCallback ecb)
|
||||||
{
|
{
|
||||||
NS_LOG_FUNCTION (this << p << header << header.GetSource () << header.GetDestination () << idev << &lcb << &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
|
// Check if input device supports IP
|
||||||
NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
|
NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
|
||||||
uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
|
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
|
// Next, try to find a route
|
||||||
NS_LOG_LOGIC ("Unicast destination- looking up global 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)
|
if (rtentry != 0)
|
||||||
{
|
{
|
||||||
NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
|
NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
|
||||||
|
|||||||
@@ -234,6 +234,8 @@ protected:
|
|||||||
private:
|
private:
|
||||||
/// Set to true if packets are randomly routed among ECMP; set to false for using only one route consistently
|
/// Set to true if packets are randomly routed among ECMP; set to false for using only one route consistently
|
||||||
bool m_randomEcmpRouting;
|
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
|
/// Set to true if this interface should respond to interface events by globallly recomputing routes
|
||||||
bool m_respondToInterfaceEvents;
|
bool m_respondToInterfaceEvents;
|
||||||
/// A uniform random number generator for randomly routing packets among ECMP
|
/// A uniform random number generator for randomly routing packets among ECMP
|
||||||
@@ -263,10 +265,11 @@ private:
|
|||||||
/**
|
/**
|
||||||
* \brief Lookup in the forwarding table for destination.
|
* \brief Lookup in the forwarding table for destination.
|
||||||
* \param dest destination address
|
* \param dest destination address
|
||||||
|
* \param flowHash flow hash for per-flow ECMP routing
|
||||||
* \param oif output interface if any (put 0 otherwise)
|
* \param oif output interface if any (put 0 otherwise)
|
||||||
* \return Ipv4Route to route the packet to reach dest address
|
* \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
|
HostRoutes m_hostRoutes; //!< Routes to hosts
|
||||||
NetworkRoutes m_networkRoutes; //!< Routes to networks
|
NetworkRoutes m_networkRoutes; //!< Routes to networks
|
||||||
|
|||||||
Reference in New Issue
Block a user