21 #include "ns3/names.h"
23 #include "ns3/simulator.h"
24 #include "ns3/object.h"
25 #include "ns3/packet.h"
26 #include "ns3/net-device.h"
27 #include "ns3/ipv4-route.h"
28 #include "ns3/ipv4-routing-table-entry.h"
29 #include "ns3/boolean.h"
30 #include "ipv4-global-routing.h"
31 #include "global-route-manager.h"
37 NS_OBJECT_ENSURE_REGISTERED (Ipv4GlobalRouting);
40 Ipv4GlobalRouting::GetTypeId (
void)
42 static TypeId tid = TypeId (
"ns3::Ipv4GlobalRouting")
44 .AddAttribute (
"RandomEcmpRouting",
45 "Set to true if packets are randomly routed among ECMP; set to false for using only one route consistently",
48 MakeBooleanChecker ())
49 .AddAttribute (
"RespondToInterfaceEvents",
50 "Set to true if you want to dynamically recompute the global routes upon Interface notification events (up/down, or add/remove address)",
53 MakeBooleanChecker ())
59 : m_randomEcmpRouting (false),
60 m_respondToInterfaceEvents (false)
64 m_rand = CreateObject<UniformRandomVariable> ();
67 Ipv4GlobalRouting::~Ipv4GlobalRouting ()
80 m_hostRoutes.push_back (route);
90 m_hostRoutes.push_back (route);
99 NS_LOG_FUNCTION (
this << network << networkMask << nextHop << interface);
105 m_networkRoutes.push_back (route);
118 m_networkRoutes.push_back (route);
127 NS_LOG_FUNCTION (
this << network << networkMask << nextHop << interface);
133 m_ASexternalRoutes.push_back (route);
141 NS_LOG_LOGIC (
"Looking for route for destination " << dest);
144 typedef std::vector<Ipv4RoutingTableEntry*> RouteVec_t;
145 RouteVec_t allRoutes;
147 NS_LOG_LOGIC (
"Number of m_hostRoutes = " << m_hostRoutes.size ());
148 for (HostRoutesCI i = m_hostRoutes.begin ();
149 i != m_hostRoutes.end ();
153 if ((*i)->GetDest ().IsEqual (dest))
157 if (oif != m_ipv4->GetNetDevice ((*i)->GetInterface ()))
163 allRoutes.push_back (*i);
164 NS_LOG_LOGIC (allRoutes.size () <<
"Found global host route" << *i);
167 if (allRoutes.size () == 0)
169 NS_LOG_LOGIC (
"Number of m_networkRoutes" << m_networkRoutes.size ());
170 for (NetworkRoutesI j = m_networkRoutes.begin ();
171 j != m_networkRoutes.end ();
174 Ipv4Mask mask = (*j)->GetDestNetworkMask ();
175 Ipv4Address entry = (*j)->GetDestNetwork ();
176 if (mask.IsMatch (dest, entry))
180 if (oif != m_ipv4->GetNetDevice ((*j)->GetInterface ()))
186 allRoutes.push_back (*j);
187 NS_LOG_LOGIC (allRoutes.size () <<
"Found global network route" << *j);
191 if (allRoutes.size () == 0)
193 for (ASExternalRoutesI k = m_ASexternalRoutes.begin ();
194 k != m_ASexternalRoutes.end ();
197 Ipv4Mask mask = (*k)->GetDestNetworkMask ();
198 Ipv4Address entry = (*k)->GetDestNetwork ();
199 if (mask.IsMatch (dest, entry))
204 if (oif != m_ipv4->GetNetDevice ((*k)->GetInterface ()))
210 allRoutes.push_back (*k);
215 if (allRoutes.size () > 0 )
220 uint32_t selectIndex;
229 Ipv4RoutingTableEntry* route = allRoutes.at (selectIndex);
231 rtentry = Create<Ipv4Route> ();
234 rtentry->
SetSource (m_ipv4->GetAddress (route->GetInterface (), 0).GetLocal ());
236 uint32_t interfaceIdx = route->GetInterface ();
251 n += m_hostRoutes.size ();
252 n += m_networkRoutes.size ();
253 n += m_ASexternalRoutes.size ();
261 if (index < m_hostRoutes.size ())
264 for (HostRoutesCI i = m_hostRoutes.begin ();
265 i != m_hostRoutes.end ();
275 index -= m_hostRoutes.size ();
277 if (index < m_networkRoutes.size ())
279 for (NetworkRoutesCI j = m_networkRoutes.begin ();
280 j != m_networkRoutes.end ();
290 index -= m_networkRoutes.size ();
292 for (ASExternalRoutesCI k = m_ASexternalRoutes.begin ();
293 k != m_ASexternalRoutes.end ();
310 if (index < m_hostRoutes.size ())
313 for (HostRoutesI i = m_hostRoutes.begin ();
314 i != m_hostRoutes.end ();
319 NS_LOG_LOGIC (
"Removing route " << index <<
"; size = " << m_hostRoutes.size ());
321 m_hostRoutes.erase (i);
322 NS_LOG_LOGIC (
"Done removing host route " << index <<
"; host route remaining size = " << m_hostRoutes.size ());
328 index -= m_hostRoutes.size ();
330 for (NetworkRoutesI j = m_networkRoutes.begin ();
331 j != m_networkRoutes.end ();
336 NS_LOG_LOGIC (
"Removing route " << index <<
"; size = " << m_networkRoutes.size ());
338 m_networkRoutes.erase (j);
339 NS_LOG_LOGIC (
"Done removing network route " << index <<
"; network route remaining size = " << m_networkRoutes.size ());
344 index -= m_networkRoutes.size ();
346 for (ASExternalRoutesI k = m_ASexternalRoutes.begin ();
347 k != m_ASexternalRoutes.end ();
352 NS_LOG_LOGIC (
"Removing route " << index <<
"; size = " << m_ASexternalRoutes.size ());
354 m_ASexternalRoutes.erase (k);
355 NS_LOG_LOGIC (
"Done removing network route " << index <<
"; network route remaining size = " << m_networkRoutes.size ());
375 for (HostRoutesI i = m_hostRoutes.begin ();
376 i != m_hostRoutes.end ();
377 i = m_hostRoutes.erase (i))
381 for (NetworkRoutesI j = m_networkRoutes.begin ();
382 j != m_networkRoutes.end ();
383 j = m_networkRoutes.erase (j))
387 for (ASExternalRoutesI l = m_ASexternalRoutes.begin ();
388 l != m_ASexternalRoutes.end ();
389 l = m_ASexternalRoutes.erase (l))
405 *os <<
"Destination Gateway Genmask Flags Metric Ref Use Iface" << std::endl;
408 std::ostringstream dest, gw, mask, flags;
411 *os << std::setiosflags (std::ios::left) << std::setw (16) << dest.str ();
413 *os << std::setiosflags (std::ios::left) << std::setw (16) << gw.str ();
415 *os << std::setiosflags (std::ios::left) << std::setw (16) << mask.str ();
425 *os << std::setiosflags (std::ios::left) << std::setw (6) << flags.str ();
455 NS_LOG_LOGIC (
"Multicast destination-- returning false");
465 sockerr = Socket::ERROR_NOTERROR;
469 sockerr = Socket::ERROR_NOROUTETOHOST;
480 NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
481 uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
485 NS_LOG_LOGIC (
"Multicast destination-- returning false");
502 for (uint32_t j = 0; j < m_ipv4->GetNInterfaces (); j++)
504 for (uint32_t i = 0; i < m_ipv4->GetNAddresses (j); i++)
512 NS_LOG_LOGIC (
"For me (destination " << addr <<
" match)");
518 lcb (p, header, iif);
524 lcb (p, header, iif);
531 if (m_ipv4->IsForwarding (iif) ==
false)
533 NS_LOG_LOGIC (
"Forwarding disabled for this interface");
534 ecb (p, header, Socket::ERROR_NOROUTETOHOST);
538 NS_LOG_LOGIC (
"Unicast destination- looking up global route");
542 NS_LOG_LOGIC (
"Found unicast destination- calling unicast callback");
543 ucb (rtentry, p, header);
548 NS_LOG_LOGIC (
"Did not find unicast destination- returning false");
virtual void NotifyInterfaceUp(uint32_t interface)
#define NS_LOG_FUNCTION(parameters)
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
static void InitializeRoutes()
Compute routes using a Dijkstra SPF computation and populate per-node forwarding tables.
Ipv4GlobalRouting()
Construct an empty Ipv4GlobalRouting routing protocol,.
a class to represent an Ipv4 address mask
#define NS_ASSERT(condition)
#define NS_LOG_COMPONENT_DEFINE(name)
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream) const
Print the Routing Table entries.
virtual bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb)
Route an input packet (to be forwarded or locally delivered)
bool IsMulticast(void) const
virtual void DoDispose(void)
virtual void NotifyInterfaceDown(uint32_t interface)
void RemoveRoute(uint32_t i)
Remove a route from the global unicast routing table.
Ipv4RoutingTableEntry * GetRoute(uint32_t i) const
Get a route from the global unicast routing table.
void SetSource(Ipv4Address src)
uint32_t GetInterface(void) const
Ptr< UniformRandomVariable > m_rand
A uniform random number generator for randomly routing packets among ECMP.
bool IsGateway(void) const
static Ipv4RoutingTableEntry CreateHostRouteTo(Ipv4Address dest, Ipv4Address nextHop, uint32_t interface)
void SetGateway(Ipv4Address gw)
static Ipv4RoutingTableEntry CreateNetworkRouteTo(Ipv4Address network, Ipv4Mask networkMask, Ipv4Address nextHop, uint32_t interface)
bool m_respondToInterfaceEvents
Set to true if this interface should respond to interface events by globallly recomputing routes...
bool IsBroadcast(void) const
static void DeleteGlobalRoutes()
Delete all static routes on all nodes that have a GlobalRouterInterface.
#define NS_LOG_LOGIC(msg)
bool m_randomEcmpRouting
Set to true if packets are randomly routed among ECMP; set to false for using only one route consiste...
int64_t AssignStreams(int64_t stream)
bool IsEqual(const Ipv4Address &other) const
Comparison operation between two Ipv4Addresses.
static void BuildGlobalRoutingDatabase()
Build the routing database by gathering Link State Advertisements from each node exporting a GlobalRo...
Ipv4Address GetDest(void) const
virtual Ptr< Ipv4Route > RouteOutput(Ptr< Packet > p, const Ipv4Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr)
Query routing cache for an existing route, for an outbound packet.
void SetOutputDevice(Ptr< NetDevice > outputDevice)
void AddNetworkRouteTo(Ipv4Address network, Ipv4Mask networkMask, Ipv4Address nextHop, uint32_t interface)
Add a network route to the global routing table.
Ipv4 addresses are stored in host order in this class.
a class to store IPv4 address information on an interface
Ipv4Address GetGateway(void) const
virtual void SetIpv4(Ptr< Ipv4 > ipv4)
static std::string FindName(Ptr< Object > object)
Ipv4Mask GetDestNetworkMask(void) const
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)
std::ostream * GetStream(void)
uint32_t GetNRoutes(void) const
Get the number of individual unicast routes that have been added to the routing table.
void SetDestination(Ipv4Address dest)
void AddASExternalRouteTo(Ipv4Address network, Ipv4Mask networkMask, Ipv4Address nextHop, uint32_t interface)
Add an external route to the global routing table.
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
void AddHostRouteTo(Ipv4Address dest, Ipv4Address nextHop, uint32_t interface)
Add a host route to the global routing table.