bug 702: make global routing robust to link/device events
This commit is contained in:
@@ -62,6 +62,10 @@ the user to specify a list of received packets that should be errored. The
|
||||
list corresponds not to the packet UID but to the sequence of received
|
||||
packets as observed by the error model. See src/common/error-model.h
|
||||
</ul>
|
||||
<ul><b>Respond to interface events:"</b> New attribute for Ipv4GlobalRouting,
|
||||
"RespondToInterfaceEvents", which when enabled, will cause global routes
|
||||
to be recomputed upon any interface or address notification event from IPv4.
|
||||
</ul>
|
||||
|
||||
<h2>Changes to existing API:</h2>
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ many cases referencing the Bugzilla bug number
|
||||
in IPv4 or IPv6 ascii traces
|
||||
- ICMPv4 objects not properly registered; affected serialization code
|
||||
- bug 875 - Set FCS included flag in Radiotap header
|
||||
- bug 702 - Global routing doesn't respond to interface events
|
||||
|
||||
Known issues
|
||||
------------
|
||||
|
||||
@@ -147,6 +147,16 @@ at time 5 seconds:
|
||||
&Ipv4GlobalRoutingHelper::RecomputeRoutingTables);
|
||||
@end verbatim
|
||||
|
||||
There are two attributes that govern the behavior. The first is
|
||||
Ipv4GlobalRouting::RandomEcmpRouting. If set to true, packets are randomly
|
||||
routed across equal-cost multipath routes. If set to false (default),
|
||||
only one route is consistently used. The second is
|
||||
Ipv4GlobalRouting::RespondToInterfaceEvents. If set to true, dynamically
|
||||
recompute the global routes upon Interface notification events (up/down,
|
||||
or add/remove address). If set to false (default), routing may break
|
||||
unless the user manually calls RecomputeRoutingTables() after such events.
|
||||
The default is set to false to preserve legacy ns-3 program behavior.
|
||||
|
||||
@subsection Global Routing Implementation
|
||||
|
||||
This section is for those readers who care about how this is implemented.
|
||||
|
||||
@@ -18,7 +18,10 @@
|
||||
|
||||
|
||||
// This script exercises global routing code in a mixed point-to-point
|
||||
// and csma/cd environment
|
||||
// and csma/cd environment. We bring up and down interfaces and observe
|
||||
// the effect on global routing. We explicitly enable the attribute
|
||||
// to respond to interface events, so that routes are recomputed
|
||||
// automatically.
|
||||
//
|
||||
// Network topology
|
||||
//
|
||||
@@ -41,33 +44,20 @@
|
||||
// n1 to n6 is via the direct point-to-point link
|
||||
// At time 1s, start CBR traffic flow from n1 to n6
|
||||
// At time 2s, set the n1 point-to-point interface to down. Packets
|
||||
// will start to be dropped
|
||||
// At time 3s, call RecomputeRoutingTables() and traffic will
|
||||
// start flowing again on the alternate path
|
||||
// At time 4s, re-enable the n1/n6 interface to up. Will not change routing
|
||||
// At time 5s, call RecomputeRoutingTables() and traffic will start flowing
|
||||
// again on the original path
|
||||
// will be diverted to the n1-n2-n5-n6 path
|
||||
// At time 4s, re-enable the n1/n6 interface to up. n1-n6 route restored.
|
||||
// At time 6s, set the n6-n1 point-to-point Ipv4 interface to down (note, this
|
||||
// keeps the point-to-point link "up" from n1's perspective). Packets
|
||||
// will traverse the link and be dropped at n6 upon receipt. These drops
|
||||
// are not visible in the pcap trace but in the ascii trace.
|
||||
// At time 7s, call RecomputeRoutingTables() and traffic will flow again
|
||||
// through the path n1-n2-n5-n6
|
||||
// At time 8s, bring the interface back up.
|
||||
// At time 9s, call RecomputeRoutingTables() and traffic will flow again
|
||||
// through the path n1-n6
|
||||
// keeps the point-to-point link "up" from n1's perspective). Traffic will
|
||||
// flow through the path n1-n2-n5-n6
|
||||
// At time 8s, bring the interface back up. Path n1-n6 is restored
|
||||
// At time 10s, stop the first flow.
|
||||
// At time 11s, start a new flow, but to n6's other IP address (the one
|
||||
// on the n1/n6 p2p link)
|
||||
// At time 12s, bring the n1 interface down between n1 and n6. Packets
|
||||
// will start to be dropped
|
||||
// At time 13s, call RecomputeRoutingTables() and traffic will
|
||||
// start flowing again on the alternate path
|
||||
// will be diverted to the alternate path
|
||||
// At time 14s, re-enable the n1/n6 interface to up. This will change
|
||||
// routing back to n1-n6 since the interface up notification will cause
|
||||
// a new local interface route, at higher priority than global routing
|
||||
// At time 15s, call RecomputeRoutingTables(), but there is no effect
|
||||
// since global routing is lower in priority than static routing
|
||||
// At time 16s, stop the second flow.
|
||||
|
||||
// - Tracing of queues and packet receptions to file "dynamic-global-routing.tr"
|
||||
@@ -89,6 +79,10 @@ NS_LOG_COMPONENT_DEFINE ("DynamicGlobalRoutingExample");
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
// The below value configures the default behavior of global routing.
|
||||
// By default, it is disabled. To respond to interface events, set to true
|
||||
Config::SetDefault ("ns3::Ipv4GlobalRouting::RespondToInterfaceEvents", BooleanValue (true));
|
||||
|
||||
// Allow the user to override any of the defaults and the above
|
||||
// Bind ()s at run-time, via command-line arguments
|
||||
CommandLine cmd;
|
||||
@@ -206,9 +200,7 @@ main (int argc, char *argv[])
|
||||
uint32_t ipv4ifIndex1 = 2;
|
||||
|
||||
Simulator::Schedule (Seconds (2),&Ipv4::SetDown,ipv41, ipv4ifIndex1);
|
||||
Simulator::Schedule (Seconds (3),&Ipv4GlobalRoutingHelper::RecomputeRoutingTables);
|
||||
Simulator::Schedule (Seconds (4),&Ipv4::SetUp,ipv41, ipv4ifIndex1);
|
||||
Simulator::Schedule (Seconds (5),&Ipv4GlobalRoutingHelper::RecomputeRoutingTables);
|
||||
|
||||
Ptr<Node> n6 = c.Get (6);
|
||||
Ptr<Ipv4> ipv46 = n6->GetObject<Ipv4> ();
|
||||
@@ -216,14 +208,10 @@ main (int argc, char *argv[])
|
||||
// then the next p2p is numbered 2
|
||||
uint32_t ipv4ifIndex6 = 2;
|
||||
Simulator::Schedule (Seconds (6),&Ipv4::SetDown,ipv46, ipv4ifIndex6);
|
||||
Simulator::Schedule (Seconds (7),&Ipv4GlobalRoutingHelper::RecomputeRoutingTables);
|
||||
Simulator::Schedule (Seconds (8),&Ipv4::SetUp,ipv46, ipv4ifIndex6);
|
||||
Simulator::Schedule (Seconds (9),&Ipv4GlobalRoutingHelper::RecomputeRoutingTables);
|
||||
|
||||
Simulator::Schedule (Seconds (12),&Ipv4::SetDown,ipv41, ipv4ifIndex1);
|
||||
Simulator::Schedule (Seconds (13),&Ipv4GlobalRoutingHelper::RecomputeRoutingTables);
|
||||
Simulator::Schedule (Seconds (14),&Ipv4::SetUp,ipv41, ipv4ifIndex1);
|
||||
Simulator::Schedule (Seconds (15),&Ipv4GlobalRoutingHelper::RecomputeRoutingTables);
|
||||
|
||||
NS_LOG_INFO ("Run Simulation.");
|
||||
Simulator::Run ();
|
||||
|
||||
@@ -33,22 +33,28 @@
|
||||
* The model assumes that all nodes on an ns-3 channel are reachable to
|
||||
* one another, regardless of whether the nodes can use the channel
|
||||
* successfully (in the case of wireless). Therefore, this model
|
||||
* should typically be used only on wired topologies. API does not
|
||||
* yet exist to control the subset of a topology to which this global
|
||||
* static routing is applied.
|
||||
* should typically be used only on wired topologies. Layer-2 bridge
|
||||
* devices are supported. API does not yet exist to control the subset
|
||||
* of a topology to which this global static routing is applied.
|
||||
*
|
||||
* This model also does not yet deal with the possible presence of
|
||||
* layer-2 relays such as switches, bridges, and hubs, although ns-3 does
|
||||
* not have such devices yet.
|
||||
* If the topology changes during the simulation, by default, routing
|
||||
* will not adjust. There are two ways to make it adjust.
|
||||
* - Set the attribute Ipv4GlobalRouting::RespondToInterfaceEvents to true
|
||||
* - Manually call the sequence of GlobalRouteManager methods to delte global
|
||||
* routes, build global routing database, and initialize routes.
|
||||
* There is a helper method that encapsulates this
|
||||
* (Ipv4GlobalRoutingHelper::RecomputeRoutingTables())
|
||||
*
|
||||
* \section api API and Usage
|
||||
*
|
||||
* Users must include ns3/global-route-manager.h header file. After the
|
||||
* IPv4 topology has been built and addresses assigned, users call
|
||||
* ns3::GlobalRouteManager::PopulateRoutingTables (), prior to the
|
||||
* ns3::Simulator::Run() call. There are no other attributes or
|
||||
* public methods that are typically called, or ways to parameterize
|
||||
* the behavior.
|
||||
* ns3::Simulator::Run() call.
|
||||
*
|
||||
* There are two attributes of Ipv4GlobalRouting that govern behavior.
|
||||
* - Ipv4GlobalRouting::RandomEcmpRouting
|
||||
* - Ipv4GlobalRouting::RespondToInterfaceEvents
|
||||
*
|
||||
* \section impl Implementation
|
||||
*
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
//
|
||||
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/net-device.h"
|
||||
@@ -24,6 +25,7 @@
|
||||
#include "ns3/ipv4-routing-table-entry.h"
|
||||
#include "ns3/boolean.h"
|
||||
#include "ipv4-global-routing.h"
|
||||
#include "global-route-manager.h"
|
||||
#include <vector>
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("Ipv4GlobalRouting");
|
||||
@@ -42,12 +44,18 @@ Ipv4GlobalRouting::GetTypeId (void)
|
||||
BooleanValue(false),
|
||||
MakeBooleanAccessor (&Ipv4GlobalRouting::m_randomEcmpRouting),
|
||||
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),
|
||||
MakeBooleanAccessor (&Ipv4GlobalRouting::m_respondToInterfaceEvents),
|
||||
MakeBooleanChecker ())
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
Ipv4GlobalRouting::Ipv4GlobalRouting ()
|
||||
: m_randomEcmpRouting (false)
|
||||
: m_randomEcmpRouting (false),
|
||||
m_respondToInterfaceEvents (false)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
}
|
||||
@@ -485,16 +493,52 @@ Ipv4GlobalRouting::RouteInput (Ptr<const Packet> p, const Ipv4Header &header, P
|
||||
}
|
||||
void
|
||||
Ipv4GlobalRouting::NotifyInterfaceUp (uint32_t i)
|
||||
{}
|
||||
{
|
||||
NS_LOG_FUNCTION (this << i);
|
||||
if (m_respondToInterfaceEvents && Simulator::Now ().GetSeconds () > 0) // avoid startup events
|
||||
{
|
||||
GlobalRouteManager::DeleteGlobalRoutes ();
|
||||
GlobalRouteManager::BuildGlobalRoutingDatabase ();
|
||||
GlobalRouteManager::InitializeRoutes ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4GlobalRouting::NotifyInterfaceDown (uint32_t i)
|
||||
{}
|
||||
{
|
||||
NS_LOG_FUNCTION (this << i);
|
||||
if (m_respondToInterfaceEvents && Simulator::Now ().GetSeconds () > 0) // avoid startup events
|
||||
{
|
||||
GlobalRouteManager::DeleteGlobalRoutes ();
|
||||
GlobalRouteManager::BuildGlobalRoutingDatabase ();
|
||||
GlobalRouteManager::InitializeRoutes ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4GlobalRouting::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)
|
||||
{}
|
||||
{
|
||||
NS_LOG_FUNCTION (this << interface << address);
|
||||
if (m_respondToInterfaceEvents && Simulator::Now ().GetSeconds () > 0) // avoid startup events
|
||||
{
|
||||
GlobalRouteManager::DeleteGlobalRoutes ();
|
||||
GlobalRouteManager::BuildGlobalRoutingDatabase ();
|
||||
GlobalRouteManager::InitializeRoutes ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4GlobalRouting::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)
|
||||
{}
|
||||
{
|
||||
NS_LOG_FUNCTION (this << interface << address);
|
||||
if (m_respondToInterfaceEvents && Simulator::Now ().GetSeconds () > 0) // avoid startup events
|
||||
{
|
||||
GlobalRouteManager::DeleteGlobalRoutes ();
|
||||
GlobalRouteManager::BuildGlobalRoutingDatabase ();
|
||||
GlobalRouteManager::InitializeRoutes ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4GlobalRouting::SetIpv4 (Ptr<Ipv4> ipv4)
|
||||
{
|
||||
|
||||
@@ -81,6 +81,7 @@ public:
|
||||
Ipv4GlobalRouting ();
|
||||
virtual ~Ipv4GlobalRouting ();
|
||||
|
||||
// These methods inherited from base class
|
||||
virtual Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
|
||||
|
||||
virtual bool RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
|
||||
@@ -215,6 +216,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 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
|
||||
UniformVariable m_rand;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user