--- a/examples/csma/csma-multicast.cc Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/csma/csma-multicast.cc Tue Oct 26 18:02:17 2010 +0100
@@ -36,6 +36,8 @@
#include "ns3/simulator-module.h"
#include "ns3/node-module.h"
#include "ns3/helper-module.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
using namespace ns3;
--- a/examples/emulation/emu-ping.cc Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/emulation/emu-ping.cc Tue Oct 26 18:02:17 2010 +0100
@@ -58,6 +58,8 @@
#include "ns3/emu-module.h"
#include "ns3/v4ping-module.h"
#include "ns3/helper-module.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
using namespace ns3;
--- a/examples/ipv6/fragmentation-ipv6.cc Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/ipv6/fragmentation-ipv6.cc Tue Oct 26 18:02:17 2010 +0100
@@ -32,6 +32,7 @@
#include "ns3/core-module.h"
#include "ns3/simulator-module.h"
#include "ns3/helper-module.h"
+#include "ns3/ipv6-static-routing-helper.h"
#include "ns3/ipv6-routing-table-entry.h"
--- a/examples/ipv6/icmpv6-redirect.cc Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/ipv6/icmpv6-redirect.cc Tue Oct 26 18:02:17 2010 +0100
@@ -44,6 +44,7 @@
#include "ns3/core-module.h"
#include "ns3/simulator-module.h"
#include "ns3/helper-module.h"
+#include "ns3/ipv6-static-routing-helper.h"
#include "ns3/ipv6-routing-table-entry.h"
--- a/examples/ipv6/radvd-two-prefix.cc Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/ipv6/radvd-two-prefix.cc Tue Oct 26 18:02:17 2010 +0100
@@ -41,6 +41,7 @@
#include "ns3/radvd.h"
#include "ns3/radvd-interface.h"
#include "ns3/radvd-prefix.h"
+#include "ns3/ipv6-static-routing-helper.h"
using namespace ns3;
--- a/examples/routing/global-injection-slash32.cc Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/routing/global-injection-slash32.cc Tue Oct 26 18:02:17 2010 +0100
@@ -34,6 +34,8 @@
#include "ns3/ipv4-list-routing.h"
#include "ns3/ipv4-routing-table-entry.h"
#include "ns3/global-router-interface.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
using namespace ns3;
using std::cout;
--- a/examples/routing/nix-simple.cc Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/routing/nix-simple.cc Tue Oct 26 18:02:17 2010 +0100
@@ -18,6 +18,8 @@
#include "ns3/simulator-module.h"
#include "ns3/node-module.h"
#include "ns3/helper-module.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
/*
* Simple point to point links:
--- a/examples/routing/nms-p2p-nix.cc Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/routing/nms-p2p-nix.cc Tue Oct 26 18:02:17 2010 +0100
@@ -23,6 +23,8 @@
#include "ns3/packet-sink.h"
#include "ns3/point-to-point-net-device.h"
#include "ns3/simulator.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
using namespace std;
using namespace ns3;
--- a/examples/routing/simple-routing-ping6.cc Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/routing/simple-routing-ping6.cc Tue Oct 26 18:02:17 2010 +0100
@@ -32,6 +32,7 @@
#include "ns3/core-module.h"
#include "ns3/simulator-module.h"
#include "ns3/helper-module.h"
+#include "ns3/ipv6-static-routing-helper.h"
#include "ns3/ipv6-routing-table-entry.h"
--- a/examples/routing/static-routing-slash32.cc Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/routing/static-routing-slash32.cc Tue Oct 26 18:02:17 2010 +0100
@@ -29,6 +29,7 @@
#include "ns3/simulator-module.h"
#include "ns3/node-module.h"
#include "ns3/helper-module.h"
+#include "ns3/ipv4-static-routing-helper.h"
using namespace ns3;
--- a/examples/socket/socket-bound-static-routing.cc Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/socket/socket-bound-static-routing.cc Tue Oct 26 18:02:17 2010 +0100
@@ -39,6 +39,8 @@
#include "ns3/simulator-module.h"
#include "ns3/node-module.h"
#include "ns3/helper-module.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
using namespace ns3;
--- a/examples/socket/socket-bound-tcp-static-routing.cc Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/socket/socket-bound-tcp-static-routing.cc Tue Oct 26 18:02:17 2010 +0100
@@ -39,6 +39,8 @@
#include "ns3/simulator-module.h"
#include "ns3/node-module.h"
#include "ns3/helper-module.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
using namespace ns3;
--- a/examples/topology-read/topology-example-sim.cc Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/topology-read/topology-example-sim.cc Tue Oct 26 18:02:17 2010 +0100
@@ -31,6 +31,8 @@
#include "ns3/node-module.h"
#include "ns3/helper-module.h"
#include "ns3/simulator-module.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
#include "ns3/topology-read-module.h"
#include <list>
--- a/examples/wimax/wimax-multicast.cc Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/wimax/wimax-multicast.cc Tue Oct 26 18:02:17 2010 +0100
@@ -61,6 +61,8 @@
#include "ns3/global-route-manager.h"
#include "ns3/constant-position-mobility-model.h"
#include "ns3/random-waypoint-mobility-model.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
#include "ns3/vector.h"
--- a/examples/wireless/multirate.cc Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/wireless/multirate.cc Tue Oct 26 18:02:17 2010 +0100
@@ -58,6 +58,8 @@
#include "ns3/wifi-module.h"
#include "ns3/flow-monitor-helper.h"
#include "ns3/olsr-helper.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
#include <iostream>
#include <fstream>
--- a/examples/wireless/wifi-simple-adhoc-grid.cc Tue Oct 26 15:11:17 2010 +0100
+++ b/examples/wireless/wifi-simple-adhoc-grid.cc Tue Oct 26 18:02:17 2010 +0100
@@ -77,6 +77,8 @@
#include "ns3/contrib-module.h"
#include "ns3/wifi-module.h"
#include "ns3/olsr-helper.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
#include <iostream>
#include <fstream>
--- a/src/helper/internet-stack-helper.cc Tue Oct 26 15:11:17 2010 +0100
+++ b/src/helper/internet-stack-helper.cc Tue Oct 26 18:02:17 2010 +0100
@@ -164,11 +164,11 @@
#include "ns3/core-config.h"
#include "ns3/arp-l3-protocol.h"
#include "internet-stack-helper.h"
-#include "ipv4-list-routing-helper.h"
-#include "ipv4-static-routing-helper.h"
-#include "ipv4-global-routing-helper.h"
-#include "ipv6-list-routing-helper.h"
-#include "ipv6-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-global-routing-helper.h"
+#include "ns3/ipv6-list-routing-helper.h"
+#include "ns3/ipv6-static-routing-helper.h"
#include "trace-helper.h"
#include <limits>
#include <map>
--- a/src/helper/ipv4-global-routing-helper.cc Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "ipv4-global-routing-helper.h"
-#include "ns3/global-router-interface.h"
-#include "ns3/ipv4-global-routing.h"
-#include "ns3/ipv4-list-routing.h"
-#include "ns3/log.h"
-
-NS_LOG_COMPONENT_DEFINE("GlobalRoutingHelper");
-
-namespace ns3 {
-
-Ipv4GlobalRoutingHelper::Ipv4GlobalRoutingHelper ()
-{}
-
-Ipv4GlobalRoutingHelper::Ipv4GlobalRoutingHelper (const Ipv4GlobalRoutingHelper &o)
-{
-}
-
-Ipv4GlobalRoutingHelper*
-Ipv4GlobalRoutingHelper::Copy (void) const
-{
- return new Ipv4GlobalRoutingHelper (*this);
-}
-
-Ptr<Ipv4RoutingProtocol>
-Ipv4GlobalRoutingHelper::Create (Ptr<Node> node) const
-{
- NS_LOG_LOGIC ("Adding GlobalRouter interface to node " <<
- node->GetId ());
-
- Ptr<GlobalRouter> globalRouter = CreateObject<GlobalRouter> ();
- node->AggregateObject (globalRouter);
-
- NS_LOG_LOGIC ("Adding GlobalRouting Protocol to node " << node->GetId ());
- Ptr<Ipv4GlobalRouting> globalRouting = CreateObject<Ipv4GlobalRouting> ();
- globalRouter->SetRoutingProtocol (globalRouting);
-
- return globalRouting;
-}
-
-void
-Ipv4GlobalRoutingHelper::PopulateRoutingTables (void)
-{
- GlobalRouteManager::BuildGlobalRoutingDatabase ();
- GlobalRouteManager::InitializeRoutes ();
-}
-void
-Ipv4GlobalRoutingHelper::RecomputeRoutingTables (void)
-{
- GlobalRouteManager::DeleteGlobalRoutes ();
- GlobalRouteManager::BuildGlobalRoutingDatabase ();
- GlobalRouteManager::InitializeRoutes ();
-}
-
-
-} // namespace ns3
--- a/src/helper/ipv4-global-routing-helper.h Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef IPV4_GLOBAL_ROUTING_HELPER_H
-#define IPV4_GLOBAL_ROUTING_HELPER_H
-
-#include "node-container.h"
-#include "ipv4-routing-helper.h"
-
-namespace ns3 {
-
-/**
- * \brief Helper class that adds ns3::Ipv4GlobalRouting objects
- */
-class Ipv4GlobalRoutingHelper : public Ipv4RoutingHelper
-{
-public:
- /**
- * \brief Construct a GlobalRoutingHelper to make life easier for managing
- * global routing tasks.
- */
- Ipv4GlobalRoutingHelper ();
-
- /**
- * \brief Construct a GlobalRoutingHelper from another previously initialized
- * instance (Copy Constructor).
- */
- Ipv4GlobalRoutingHelper (const Ipv4GlobalRoutingHelper &);
-
- /**
- * \internal
- * \returns pointer to clone of this Ipv4GlobalRoutingHelper
- *
- * This method is mainly for internal use by the other helpers;
- * clients are expected to free the dynamic memory allocated by this method
- */
- Ipv4GlobalRoutingHelper* Copy (void) const;
-
- /**
- * \param node the node on which the routing protocol will run
- * \returns a newly-created routing protocol
- *
- * This method will be called by ns3::InternetStackHelper::Install
- */
- virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
-
- /**
- * \brief Build a routing database and initialize the routing tables of
- * the nodes in the simulation. Makes all nodes in the simulation into
- * routers.
- *
- * All this function does is call the functions
- * BuildGlobalRoutingDatabase () and InitializeRoutes ().
- *
- */
- static void PopulateRoutingTables (void);
- /**
- * \brief Remove all routes that were previously installed in a prior call
- * to either PopulateRoutingTables() or RecomputeRoutingTables(), and
- * add a new set of routes.
- *
- * This method does not change the set of nodes
- * over which GlobalRouting is being used, but it will dynamically update
- * its representation of the global topology before recomputing routes.
- * Users must first call PopulateRoutingTables() and then may subsequently
- * call RecomputeRoutingTables() at any later time in the simulation.
- *
- */
- static void RecomputeRoutingTables (void);
-private:
- /**
- * \internal
- * \brief Assignment operator declared private and not implemented to disallow
- * assignment and prevent the compiler from happily inserting its own.
- */
- Ipv4GlobalRoutingHelper &operator = (const Ipv4GlobalRoutingHelper &o);
-};
-
-} // namespace ns3
-
-#endif /* IPV4_GLOBAL_ROUTING_HELPER_H */
--- a/src/helper/ipv4-list-routing-helper.cc Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "ipv4-list-routing-helper.h"
-#include "ns3/ipv4-list-routing.h"
-#include "ns3/node.h"
-
-namespace ns3 {
-
-Ipv4ListRoutingHelper::Ipv4ListRoutingHelper()
-{}
-
-Ipv4ListRoutingHelper::~Ipv4ListRoutingHelper()
-{
- for (std::list<std::pair<const Ipv4RoutingHelper *, int16_t> >::iterator i = m_list.begin ();
- i != m_list.end (); ++i)
- {
- delete i->first;
- }
-}
-
-Ipv4ListRoutingHelper::Ipv4ListRoutingHelper (const Ipv4ListRoutingHelper &o)
-{
- std::list<std::pair<const Ipv4RoutingHelper *, int16_t> >::const_iterator i;
- for (i = o.m_list.begin (); i != o.m_list.end (); ++i)
- {
- m_list.push_back (std::make_pair (const_cast<const Ipv4RoutingHelper *> (i->first->Copy ()), i->second));
- }
-}
-
-Ipv4ListRoutingHelper*
-Ipv4ListRoutingHelper::Copy (void) const
-{
- return new Ipv4ListRoutingHelper (*this);
-}
-
-void
-Ipv4ListRoutingHelper::Add (const Ipv4RoutingHelper &routing, int16_t priority)
-{
- m_list.push_back (std::make_pair (const_cast<const Ipv4RoutingHelper *> (routing.Copy ()), priority));
-}
-
-Ptr<Ipv4RoutingProtocol>
-Ipv4ListRoutingHelper::Create (Ptr<Node> node) const
-{
- Ptr<Ipv4ListRouting> list = CreateObject<Ipv4ListRouting> ();
- for (std::list<std::pair<const Ipv4RoutingHelper *, int16_t> >::const_iterator i = m_list.begin ();
- i != m_list.end (); ++i)
- {
- Ptr<Ipv4RoutingProtocol> prot = i->first->Create (node);
- list->AddRoutingProtocol (prot,i->second);
- }
- return list;
-}
-
-} // namespace ns3
--- a/src/helper/ipv4-list-routing-helper.h Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef IPV4_LIST_ROUTING_HELPER_H
-#define IPV4_LIST_ROUTING_HELPER_H
-
-#include "ipv4-routing-helper.h"
-#include <stdint.h>
-#include <list>
-
-namespace ns3 {
-
-/**
- * \brief Helper class that adds ns3::Ipv4ListRouting objects
- *
- * This class is expected to be used in conjunction with
- * ns3::InternetStackHelper::SetRoutingHelper
- */
-class Ipv4ListRoutingHelper : public Ipv4RoutingHelper
-{
-public:
- /*
- * Construct an Ipv4ListRoutingHelper used to make installing routing
- * protocols easier.
- */
- Ipv4ListRoutingHelper ();
-
- /*
- * \internal
- * Destroy an Ipv4ListRoutingHelper.
- */
- virtual ~Ipv4ListRoutingHelper ();
-
- /**
- * \brief Construct an Ipv4ListRoutingHelper from another previously
- * initialized instance (Copy Constructor).
- */
- Ipv4ListRoutingHelper (const Ipv4ListRoutingHelper &);
-
- /**
- * \internal
- * \returns pointer to clone of this Ipv4ListRoutingHelper
- *
- * This method is mainly for internal use by the other helpers;
- * clients are expected to free the dynamic memory allocated by this method
- */
- Ipv4ListRoutingHelper* Copy (void) const;
-
- /**
- * \param routing a routing helper
- * \param priority the priority of the associated helper
- *
- * Store in the internal list a reference to the input routing helper
- * and associated priority. These helpers will be used later by
- * the ns3::Ipv4ListRoutingHelper::Create method to create
- * an ns3::Ipv4ListRouting object and add in it routing protocols
- * created with the helpers.
- */
- void Add (const Ipv4RoutingHelper &routing, int16_t priority);
- /**
- * \param node the node on which the routing protocol will run
- * \returns a newly-created routing protocol
- *
- * This method will be called by ns3::InternetStackHelper::Install
- */
- virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
-private:
- /**
- * \internal
- * \brief Assignment operator declared private and not implemented to disallow
- * assignment and prevent the compiler from happily inserting its own.
- */
- Ipv4ListRoutingHelper &operator = (const Ipv4ListRoutingHelper &o);
-
- std::list<std::pair<const Ipv4RoutingHelper *,int16_t> > m_list;
-};
-
-} // namespace ns3
-
-#endif /* IPV4_LIST_ROUTING_HELPER_H */
--- a/src/helper/ipv4-static-routing-helper.cc Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <vector>
-#include "ns3/log.h"
-#include "ns3/ptr.h"
-#include "ns3/names.h"
-#include "ns3/node.h"
-#include "ns3/ipv4.h"
-#include "ns3/ipv4-route.h"
-#include "ns3/ipv4-list-routing.h"
-#include "ns3/assert.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/ipv4-routing-protocol.h"
-#include "ipv4-static-routing-helper.h"
-
-NS_LOG_COMPONENT_DEFINE("Ipv4StaticRoutingHelper");
-
-namespace ns3 {
-
-Ipv4StaticRoutingHelper::Ipv4StaticRoutingHelper()
-{}
-
-Ipv4StaticRoutingHelper::Ipv4StaticRoutingHelper (const Ipv4StaticRoutingHelper &o)
-{
-}
-
-Ipv4StaticRoutingHelper*
-Ipv4StaticRoutingHelper::Copy (void) const
-{
- return new Ipv4StaticRoutingHelper (*this);
-}
-
-Ptr<Ipv4RoutingProtocol>
-Ipv4StaticRoutingHelper::Create (Ptr<Node> node) const
-{
- return CreateObject<Ipv4StaticRouting> ();
-}
-
-
-Ptr<Ipv4StaticRouting>
-Ipv4StaticRoutingHelper::GetStaticRouting (Ptr<Ipv4> ipv4) const
-{
- NS_LOG_FUNCTION (this);
- Ptr<Ipv4RoutingProtocol> ipv4rp = ipv4->GetRoutingProtocol ();
- NS_ASSERT_MSG (ipv4rp, "No routing protocol associated with Ipv4");
- if (DynamicCast<Ipv4StaticRouting> (ipv4rp))
- {
- NS_LOG_LOGIC ("Static routing found as the main IPv4 routing protocol.");
- return DynamicCast<Ipv4StaticRouting> (ipv4rp);
- }
- if (DynamicCast<Ipv4ListRouting> (ipv4rp))
- {
- Ptr<Ipv4ListRouting> lrp = DynamicCast<Ipv4ListRouting> (ipv4rp);
- int16_t priority;
- for (uint32_t i = 0; i < lrp->GetNRoutingProtocols (); i++)
- {
- NS_LOG_LOGIC ("Searching for static routing in list");
- Ptr<Ipv4RoutingProtocol> temp = lrp->GetRoutingProtocol (i, priority);
- if (DynamicCast<Ipv4StaticRouting> (temp))
- {
- NS_LOG_LOGIC ("Found static routing in list");
- return DynamicCast<Ipv4StaticRouting> (temp);
- }
- }
- }
- NS_LOG_LOGIC ("Static routing not found");
- return 0;
-}
-
-void
-Ipv4StaticRoutingHelper::AddMulticastRoute (
- Ptr<Node> n,
- Ipv4Address source,
- Ipv4Address group,
- Ptr<NetDevice> input,
- NetDeviceContainer output)
-{
- Ptr<Ipv4> ipv4 = n->GetObject<Ipv4> ();
-
- // We need to convert the NetDeviceContainer to an array of interface
- // numbers
- std::vector<uint32_t> outputInterfaces;
- for (NetDeviceContainer::Iterator i = output.Begin (); i != output.End (); ++i)
- {
- Ptr<NetDevice> nd = *i;
- int32_t interface = ipv4->GetInterfaceForDevice (nd);
- NS_ASSERT_MSG(interface >= 0,
- "Ipv4StaticRoutingHelper::AddMulticastRoute(): "
- "Expected an interface associated with the device nd");
- outputInterfaces.push_back(interface);
- }
-
- int32_t inputInterface = ipv4->GetInterfaceForDevice (input);
- NS_ASSERT_MSG(inputInterface >= 0,
- "Ipv4StaticRoutingHelper::AddMulticastRoute(): "
- "Expected an interface associated with the device input");
- Ipv4StaticRoutingHelper helper;
- Ptr<Ipv4StaticRouting> ipv4StaticRouting = helper.GetStaticRouting (ipv4);
- if (!ipv4StaticRouting)
- {
- NS_ASSERT_MSG (ipv4StaticRouting,
- "Ipv4StaticRoutingHelper::SetDefaultMulticastRoute(): "
- "Expected an Ipv4StaticRouting associated with this node");
- }
- ipv4StaticRouting->AddMulticastRoute (source, group, inputInterface, outputInterfaces);
-}
-
-void
-Ipv4StaticRoutingHelper::AddMulticastRoute (
- Ptr<Node> n,
- Ipv4Address source,
- Ipv4Address group,
- std::string inputName,
- NetDeviceContainer output)
-{
- Ptr<NetDevice> input = Names::Find<NetDevice> (inputName);
- AddMulticastRoute (n, source, group, input, output);
-}
-
-void
-Ipv4StaticRoutingHelper::AddMulticastRoute (
- std::string nName,
- Ipv4Address source,
- Ipv4Address group,
- Ptr<NetDevice> input,
- NetDeviceContainer output)
-{
- Ptr<Node> n = Names::Find<Node> (nName);
- AddMulticastRoute (n, source, group, input, output);
-}
-
-void
-Ipv4StaticRoutingHelper::AddMulticastRoute (
- std::string nName,
- Ipv4Address source,
- Ipv4Address group,
- std::string inputName,
- NetDeviceContainer output)
-{
- Ptr<NetDevice> input = Names::Find<NetDevice> (inputName);
- Ptr<Node> n = Names::Find<Node> (nName);
- AddMulticastRoute (n, source, group, input, output);
-}
-
-void
-Ipv4StaticRoutingHelper::SetDefaultMulticastRoute (
- Ptr<Node> n,
- Ptr<NetDevice> nd)
-{
- Ptr<Ipv4> ipv4 = n->GetObject<Ipv4> ();
- int32_t interfaceSrc = ipv4->GetInterfaceForDevice (nd);
- NS_ASSERT_MSG(interfaceSrc >= 0,
- "Ipv4StaticRoutingHelper::SetDefaultMulticastRoute(): "
- "Expected an interface associated with the device");
- Ipv4StaticRoutingHelper helper;
- Ptr<Ipv4StaticRouting> ipv4StaticRouting = helper.GetStaticRouting (ipv4);
- if (!ipv4StaticRouting)
- {
- NS_ASSERT_MSG (ipv4StaticRouting,
- "Ipv4StaticRoutingHelper::SetDefaultMulticastRoute(): "
- "Expected an Ipv4StaticRouting associated with this node");
- }
- ipv4StaticRouting->SetDefaultMulticastRoute (interfaceSrc);
-}
-
-void
-Ipv4StaticRoutingHelper::SetDefaultMulticastRoute (
- Ptr<Node> n,
- std::string ndName)
-{
- Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
- SetDefaultMulticastRoute (n, nd);
-}
-
-void
-Ipv4StaticRoutingHelper::SetDefaultMulticastRoute (
- std::string nName,
- Ptr<NetDevice> nd)
-{
- Ptr<Node> n = Names::Find<Node> (nName);
- SetDefaultMulticastRoute (n, nd);
-}
-
-void
-Ipv4StaticRoutingHelper::SetDefaultMulticastRoute (
- std::string nName,
- std::string ndName)
-{
- Ptr<Node> n = Names::Find<Node> (nName);
- Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
- SetDefaultMulticastRoute (n, nd);
-}
-
-}; // namespace ns3
--- a/src/helper/ipv4-static-routing-helper.h Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IPV4_STATIC_ROUTING_HELPER_H
-#define IPV4_STATIC_ROUTING_HELPER_H
-
-#include "ns3/ipv4.h"
-#include "ns3/ipv4-static-routing.h"
-#include "ns3/ptr.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/node.h"
-#include "ns3/net-device.h"
-#include "ipv4-routing-helper.h"
-#include "node-container.h"
-#include "net-device-container.h"
-
-namespace ns3 {
-
-/**
- * \brief Helper class that adds ns3::Ipv4StaticRouting objects
- *
- * This class is expected to be used in conjunction with
- * ns3::InternetStackHelper::SetRoutingHelper
- */
-class Ipv4StaticRoutingHelper : public Ipv4RoutingHelper
-{
-public:
- /*
- * Construct an Ipv4StaticRoutingHelper object, used to make configuration
- * of static routing easier.
- */
- Ipv4StaticRoutingHelper ();
-
- /**
- * \brief Construct an Ipv4StaticRoutingHelper from another previously
- * initialized instance (Copy Constructor).
- */
- Ipv4StaticRoutingHelper (const Ipv4StaticRoutingHelper &);
-
- /**
- * \internal
- * \returns pointer to clone of this Ipv4StaticRoutingHelper
- *
- * This method is mainly for internal use by the other helpers;
- * clients are expected to free the dynamic memory allocated by this method
- */
- Ipv4StaticRoutingHelper* Copy (void) const;
-
- /**
- * \param node the node on which the routing protocol will run
- * \returns a newly-created routing protocol
- *
- * This method will be called by ns3::InternetStackHelper::Install
- */
- virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
-
- /**
- * Try and find the static routing protocol as either the main routing
- * protocol or in the list of routing protocols associated with the
- * Ipv4 provided.
- *
- * \param ipv4 the Ptr<Ipv4> to search for the static routing protocol
- */
- Ptr<Ipv4StaticRouting> GetStaticRouting (Ptr<Ipv4> ipv4) const;
-
- /**
- * \brief Add a multicast route to a node and net device using explicit
- * Ptr<Node> and Ptr<NetDevice>
- */
- void AddMulticastRoute (Ptr<Node> n, Ipv4Address source, Ipv4Address group,
- Ptr<NetDevice> input, NetDeviceContainer output);
-
- /**
- * \brief Add a multicast route to a node and device using a name string
- * previously associated to the node using the Object Name Service and a
- * Ptr<NetDevice>
- */
- void AddMulticastRoute (std::string n, Ipv4Address source, Ipv4Address group,
- Ptr<NetDevice> input, NetDeviceContainer output);
-
- /**
- * \brief Add a multicast route to a node and device using a Ptr<Node> and a
- * name string previously associated to the device using the Object Name Service.
- */
- void AddMulticastRoute (Ptr<Node> n, Ipv4Address source, Ipv4Address group,
- std::string inputName, NetDeviceContainer output);
-
- /**
- * \brief Add a multicast route to a node and device using name strings
- * previously associated to both the node and device using the Object Name
- * Service.
- */
- void AddMulticastRoute (std::string nName, Ipv4Address source, Ipv4Address group,
- std::string inputName, NetDeviceContainer output);
-
- /**
- * \brief Add a default route to the static routing protocol to forward
- * packets out a particular interface
- *
- * Functionally equivalent to:
- * route add 224.0.0.0 netmask 240.0.0.0 dev nd
- * \param n node
- * \param nd device of the node to add default route
- */
- void SetDefaultMulticastRoute (Ptr<Node> n, Ptr<NetDevice> nd);
-
- /**
- * \brief Add a default route to the static routing protocol to forward
- * packets out a particular interface
- *
- * Functionally equivalent to:
- * route add 224.0.0.0 netmask 240.0.0.0 dev nd
- * \param n node
- * \param ndName string with name previously associated to device using the
- * Object Name Service
- */
- void SetDefaultMulticastRoute (Ptr<Node> n, std::string ndName);
-
- /**
- * \brief Add a default route to the static routing protocol to forward
- * packets out a particular interface
- *
- * Functionally equivalent to:
- * route add 224.0.0.0 netmask 240.0.0.0 dev nd
- * \param nName string with name previously associated to node using the
- * Object Name Service
- * \param nd device of the node to add default route
- */
- void SetDefaultMulticastRoute (std::string nName, Ptr<NetDevice> nd);
-
- /**
- * \brief Add a default route to the static routing protocol to forward
- * packets out a particular interface
- *
- * Functionally equivalent to:
- * route add 224.0.0.0 netmask 240.0.0.0 dev nd
- * \param nName string with name previously associated to node using the
- * Object Name Service
- * \param ndName string with name previously associated to device using the
- * Object Name Service
- */
- void SetDefaultMulticastRoute (std::string nName, std::string ndName);
-private:
- /**
- * \internal
- * \brief Assignment operator declared private and not implemented to disallow
- * assignment and prevent the compiler from happily inserting its own.
- */
- Ipv4StaticRoutingHelper &operator = (const Ipv4StaticRoutingHelper &o);
-};
-
-} // namespace ns3
-
-#endif /* IPV4_STATIC_ROUTING_HELPER_H */
--- a/src/helper/ipv6-interface-container.cc Tue Oct 26 15:11:17 2010 +0100
+++ b/src/helper/ipv6-interface-container.cc Tue Oct 26 18:02:17 2010 +0100
@@ -22,7 +22,7 @@
#include "ns3/names.h"
#include "ipv6-interface-container.h"
-#include "ipv6-static-routing-helper.h"
+#include "ns3/ipv6-static-routing-helper.h"
namespace ns3
{
--- a/src/helper/ipv6-list-routing-helper.cc Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include "ns3/ipv6-list-routing.h"
-#include "ns3/node.h"
-
-#include "ipv6-list-routing-helper.h"
-
-namespace ns3 {
-
-Ipv6ListRoutingHelper::Ipv6ListRoutingHelper ()
-{}
-
-Ipv6ListRoutingHelper::~Ipv6ListRoutingHelper()
-{
- for (std::list<std::pair<const Ipv6RoutingHelper *, int16_t> >::iterator i = m_list.begin ();
- i != m_list.end (); ++i)
- {
- delete i->first;
- }
-}
-Ipv6ListRoutingHelper::Ipv6ListRoutingHelper (const Ipv6ListRoutingHelper &o)
-{
- std::list<std::pair<const Ipv6RoutingHelper *, int16_t> >::const_iterator i;
- for (i = o.m_list.begin (); i != o.m_list.end (); ++i)
- {
- m_list.push_back (std::make_pair (const_cast<const Ipv6RoutingHelper *> (i->first->Copy ()), i->second));
- }
-}
-
-Ipv6ListRoutingHelper*
-Ipv6ListRoutingHelper::Copy (void) const
-{
- return new Ipv6ListRoutingHelper (*this);
-}
-
-void
-Ipv6ListRoutingHelper::Add (const Ipv6RoutingHelper &routing, int16_t priority)
-{
- m_list.push_back (std::make_pair (const_cast<const Ipv6RoutingHelper *> (routing.Copy ()), priority));
-}
-Ptr<Ipv6RoutingProtocol>
-Ipv6ListRoutingHelper::Create (Ptr<Node> node) const
-{
- Ptr<Ipv6ListRouting> list = CreateObject<Ipv6ListRouting> ();
- for (std::list<std::pair<const Ipv6RoutingHelper *,int16_t> >::const_iterator i = m_list.begin ();
- i != m_list.end (); ++i)
- {
- Ptr<Ipv6RoutingProtocol> prot = i->first->Create (node);
- list->AddRoutingProtocol (prot,i->second);
- }
- return list;
-}
-
-} // namespace ns3
--- a/src/helper/ipv6-list-routing-helper.h Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef IPV6_LIST_ROUTING_HELPER_H
-#define IPV6_LIST_ROUTING_HELPER_H
-
-#include <stdint.h>
-
-#include <list>
-
-#include "ipv6-routing-helper.h"
-
-namespace ns3 {
-
-/**
- * \brief Helper class that adds ns3::Ipv6ListRouting objects
- *
- * This class is expected to be used in conjunction with
- * ns3::InternetStackHelper::SetRoutingHelper
- */
-class Ipv6ListRoutingHelper : public Ipv6RoutingHelper
-{
-public:
- /**
- * Construct an Ipv6 Ipv6ListRoutingHelper which is used to make life easier
- * for people wanting to configure routing using Ipv6.
- */
- Ipv6ListRoutingHelper ();
-
- /**
- * \internal
- * \brief Destroy an Ipv6 Ipv6ListRoutingHelper.
- */
- virtual ~Ipv6ListRoutingHelper ();
-
- /**
- * \brief Construct an Ipv6ListRoutingHelper from another previously
- * initialized instance (Copy Constructor).
- */
- Ipv6ListRoutingHelper (const Ipv6ListRoutingHelper &);
-
- /**
- * \returns pointer to clone of this Ipv6ListRoutingHelper
- *
- * This method is mainly for internal use by the other helpers;
- * clients are expected to free the dynamic memory allocated by this method
- */
- Ipv6ListRoutingHelper* Copy (void) const;
-
- /**
- * \param routing a routing helper
- * \param priority the priority of the associated helper
- *
- * Store in the internal list a reference to the input routing helper
- * and associated priority. These helpers will be used later by
- * the ns3::Ipv6ListRoutingHelper::Create method to create
- * an ns3::Ipv6ListRouting object and add in it routing protocols
- * created with the helpers.
- */
- void Add (const Ipv6RoutingHelper &routing, int16_t priority);
- /**
- * \param node the node on which the routing protocol will run
- * \returns a newly-created routing protocol
- *
- * This method will be called by ns3::InternetStackHelper::Install
- */
- virtual Ptr<Ipv6RoutingProtocol> Create (Ptr<Node> node) const;
-private:
- /**
- * \internal
- * \brief Assignment operator declared private and not implemented to disallow
- * assignment and prevent the compiler from happily inserting its own.
- */
- Ipv6ListRoutingHelper &operator = (const Ipv6ListRoutingHelper &o);
-
- std::list<std::pair<const Ipv6RoutingHelper *,int16_t> > m_list;
-};
-
-} // namespace ns3
-
-#endif /* IPV6_LIST_ROUTING_HELPER_H */
-
--- a/src/helper/ipv6-static-routing-helper.cc Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,213 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <vector>
-
-#include "ns3/log.h"
-#include "ns3/ptr.h"
-#include "ns3/names.h"
-#include "ns3/node.h"
-#include "ns3/ipv6.h"
-#include "ns3/ipv6-route.h"
-#include "ns3/ipv6-list-routing.h"
-#include "ns3/assert.h"
-#include "ns3/ipv6-address.h"
-#include "ns3/ipv6-routing-protocol.h"
-
-#include "ipv6-static-routing-helper.h"
-
-NS_LOG_COMPONENT_DEFINE ("Ipv6StaticRoutingHelper");
-
-namespace ns3 {
-
-Ipv6StaticRoutingHelper::Ipv6StaticRoutingHelper ()
-{}
-
-Ipv6StaticRoutingHelper::Ipv6StaticRoutingHelper (const Ipv6StaticRoutingHelper &o)
-{
-}
-
-Ipv6StaticRoutingHelper*
-Ipv6StaticRoutingHelper::Copy (void) const
-{
- return new Ipv6StaticRoutingHelper (*this);
-}
-
-Ptr<Ipv6RoutingProtocol>
-Ipv6StaticRoutingHelper::Create (Ptr<Node> node) const
-{
- return CreateObject<Ipv6StaticRouting> ();
-}
-
-Ptr<Ipv6StaticRouting>
-Ipv6StaticRoutingHelper::GetStaticRouting (Ptr<Ipv6> ipv6) const
-{
- NS_LOG_FUNCTION (this);
- Ptr<Ipv6RoutingProtocol> ipv6rp = ipv6->GetRoutingProtocol ();
- NS_ASSERT_MSG (ipv6rp, "No routing protocol associated with Ipv6");
- if (DynamicCast<Ipv6StaticRouting> (ipv6rp))
- {
- NS_LOG_LOGIC ("Static routing found as the main IPv4 routing protocol.");
- return DynamicCast<Ipv6StaticRouting> (ipv6rp);
- }
- if (DynamicCast<Ipv6ListRouting> (ipv6rp))
- {
- Ptr<Ipv6ListRouting> lrp = DynamicCast<Ipv6ListRouting> (ipv6rp);
- int16_t priority;
- for (uint32_t i = 0; i < lrp->GetNRoutingProtocols (); i++)
- {
- NS_LOG_LOGIC ("Searching for static routing in list");
- Ptr<Ipv6RoutingProtocol> temp = lrp->GetRoutingProtocol (i, priority);
- if (DynamicCast<Ipv6StaticRouting> (temp))
- {
- NS_LOG_LOGIC ("Found static routing in list");
- return DynamicCast<Ipv6StaticRouting> (temp);
- }
- }
- }
- NS_LOG_LOGIC ("Static routing not found");
- return 0;
-}
-
-void
-Ipv6StaticRoutingHelper::AddMulticastRoute (
- Ptr<Node> n,
- Ipv6Address source,
- Ipv6Address group,
- Ptr<NetDevice> input,
- NetDeviceContainer output)
-{
- Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
-
- // We need to convert the NetDeviceContainer to an array of interface
- // numbers
- std::vector<uint32_t> outputInterfaces;
- for (NetDeviceContainer::Iterator i = output.Begin (); i != output.End (); ++i)
- {
- Ptr<NetDevice> nd = *i;
- int32_t interface = ipv6->GetInterfaceForDevice (nd);
- NS_ASSERT_MSG (interface >= 0,
- "Ipv6StaticRoutingHelper::AddMulticastRoute (): "
- "Expected an interface associated with the device nd");
- outputInterfaces.push_back (interface);
- }
-
- int32_t inputInterface = ipv6->GetInterfaceForDevice (input);
- NS_ASSERT_MSG (inputInterface >= 0,
- "Ipv6StaticRoutingHelper::AddMulticastRoute (): "
- "Expected an interface associated with the device input");
- Ipv6StaticRoutingHelper helper;
- Ptr<Ipv6StaticRouting> ipv6StaticRouting = helper.GetStaticRouting (ipv6);
- if (!ipv6StaticRouting)
- {
- NS_ASSERT_MSG (ipv6StaticRouting,
- "Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (): "
- "Expected an Ipv6StaticRouting associated with this node");
- }
- ipv6StaticRouting->AddMulticastRoute (source, group, inputInterface, outputInterfaces);
-}
-
-void
-Ipv6StaticRoutingHelper::AddMulticastRoute (
- Ptr<Node> n,
- Ipv6Address source,
- Ipv6Address group,
- std::string inputName,
- NetDeviceContainer output)
-{
- Ptr<NetDevice> input = Names::Find<NetDevice> (inputName);
- AddMulticastRoute (n, source, group, input, output);
-}
-
-void
-Ipv6StaticRoutingHelper::AddMulticastRoute (
- std::string nName,
- Ipv6Address source,
- Ipv6Address group,
- Ptr<NetDevice> input,
- NetDeviceContainer output)
-{
- Ptr<Node> n = Names::Find<Node> (nName);
- AddMulticastRoute (n, source, group, input, output);
-}
-
-void
-Ipv6StaticRoutingHelper::AddMulticastRoute (
- std::string nName,
- Ipv6Address source,
- Ipv6Address group,
- std::string inputName,
- NetDeviceContainer output)
-{
- Ptr<NetDevice> input = Names::Find<NetDevice> (inputName);
- Ptr<Node> n = Names::Find<Node> (nName);
- AddMulticastRoute (n, source, group, input, output);
-}
-
-#if 0
-void
-Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (
- Ptr<Node> n,
- Ptr<NetDevice> nd)
-{
- Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
- int32_t interfaceSrc = ipv6->GetInterfaceForDevice (nd);
- NS_ASSERT_MSG (interfaceSrc >= 0,
- "Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (): "
- "Expected an interface associated with the device");
- Ipv6StaticRoutingHelper helper;
- Ptr<Ipv6StaticRouting> ipv6StaticRouting = helper.GetStaticRouting (ipv6);
- if (!ipv6StaticRouting)
- {
- NS_ASSERT_MSG (ipv6StaticRouting,
- "Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (): "
- "Expected an Ipv6StaticRouting associated with this node");
- }
- ipv6StaticRouting->SetDefaultMulticastRoute (interfaceSrc);
-}
-
-void
-Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (
- Ptr<Node> n,
- std::string ndName)
-{
- Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
- SetDefaultMulticastRoute (n, nd);
-}
-
-void
-Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (
- std::string nName,
- Ptr<NetDevice> nd)
-{
- Ptr<Node> n = Names::Find<Node> (nName);
- SetDefaultMulticastRoute (n, nd);
-}
-
-void
-Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (
- std::string nName,
- std::string ndName)
-{
- Ptr<Node> n = Names::Find<Node> (nName);
- Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
- SetDefaultMulticastRoute (n, nd);
-}
-#endif
-
-}; // namespace ns3
--- a/src/helper/ipv6-static-routing-helper.h Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IPV6_STATIC_ROUTING_HELPER_H
-#define IPV6_STATIC_ROUTING_HELPER_H
-
-#include "ns3/ipv6.h"
-#include "ns3/ipv6-static-routing.h"
-#include "ns3/ptr.h"
-#include "ns3/ipv6-address.h"
-#include "ns3/node.h"
-#include "ns3/net-device.h"
-
-#include "node-container.h"
-#include "net-device-container.h"
-#include "ipv6-routing-helper.h"
-
-namespace ns3 {
-
-/**
- * \brief Helper class that adds ns3::Ipv6StaticRouting objects
- *
- * This class is expected to be used in conjunction with
- * ns3::InternetStackHelper::SetRoutingHelper
- */
-class Ipv6StaticRoutingHelper : public Ipv6RoutingHelper
-{
-public:
- /**
- * \brief Constructor.
- */
- Ipv6StaticRoutingHelper ();
-
- /**
- * \brief Construct an Ipv6ListRoutingHelper from another previously
- * initialized instance (Copy Constructor).
- */
- Ipv6StaticRoutingHelper (const Ipv6StaticRoutingHelper &);
-
- /**
- * \internal
- * \returns pointer to clone of this Ipv6StaticRoutingHelper
- *
- * This method is mainly for internal use by the other helpers;
- * clients are expected to free the dynamic memory allocated by this method
- */
- Ipv6StaticRoutingHelper* Copy (void) const;
-
- /**
- * \param node the node on which the routing protocol will run
- * \returns a newly-created routing protocol
- *
- * This method will be called by ns3::InternetStackHelper::Install
- */
- virtual Ptr<Ipv6RoutingProtocol> Create (Ptr<Node> node) const;
-
- /**
- * \brief Get Ipv6StaticRouting pointer from IPv6 stack.
- * \param ipv6 Ipv6 pointer
- * \return Ipv6StaticRouting pointer or 0 if not exist
- */
- Ptr<Ipv6StaticRouting> GetStaticRouting (Ptr<Ipv6> ipv6) const;
-
- /**
- * \brief Add a multicast route to a node and net device using explicit
- * Ptr<Node> and Ptr<NetDevice>
- */
- void AddMulticastRoute (Ptr<Node> n, Ipv6Address source, Ipv6Address group,
- Ptr<NetDevice> input, NetDeviceContainer output);
-
- /**
- * \brief Add a multicast route to a node and device using a name string
- * previously associated to the node using the Object Name Service and a
- * Ptr<NetDevice>
- */
- void AddMulticastRoute (std::string n, Ipv6Address source, Ipv6Address group,
- Ptr<NetDevice> input, NetDeviceContainer output);
-
- /**
- * \brief Add a multicast route to a node and device using a Ptr<Node> and a
- * name string previously associated to the device using the Object Name Service.
- */
- void AddMulticastRoute (Ptr<Node> n, Ipv6Address source, Ipv6Address group,
- std::string inputName, NetDeviceContainer output);
-
- /**
- * \brief Add a multicast route to a node and device using name strings
- * previously associated to both the node and device using the Object Name
- * Service.
- */
- void AddMulticastRoute (std::string nName, Ipv6Address source, Ipv6Address group,
- std::string inputName, NetDeviceContainer output);
-
-#if 0
- /**
- * \brief Add a default route to the static routing protocol to forward
- * packets out a particular interface
- */
- void SetDefaultMulticastRoute (Ptr<Node> n, Ptr<NetDevice> nd);
- void SetDefaultMulticastRoute (Ptr<Node> n, std::string ndName);
- void SetDefaultMulticastRoute (std::string nName, Ptr<NetDevice> nd);
- void SetDefaultMulticastRoute (std::string nName, std::string ndName);
-#endif
-private:
- /**
- * \internal
- * \brief Assignment operator declared private and not implemented to disallow
- * assignment and prevent the compiler from happily inserting its own.
- */
- Ipv6StaticRoutingHelper &operator = (const Ipv6StaticRoutingHelper &o);
-};
-
-} // namespace ns3
-
-#endif /* IPV6_STATIC_ROUTING_HELPER_H */
-
--- a/src/helper/wscript Tue Oct 26 15:11:17 2010 +0100
+++ b/src/helper/wscript Tue Oct 26 18:02:17 2010 +0100
@@ -1,7 +1,7 @@
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
def build(bld):
- helper = bld.create_ns3_module('helper', ['internet-stack', 'wifi', 'point-to-point', 'csma', 'global-routing', 'onoff', 'packet-sink', 'udp-echo', 'spectrum'])
+ helper = bld.create_ns3_module('helper', ['internet-stack', 'wifi', 'point-to-point', 'csma', 'onoff', 'packet-sink', 'udp-echo', 'spectrum'])
helper.source = [
'node-container.cc',
'net-device-container.cc',
@@ -11,7 +11,6 @@
'mobility-helper.cc',
'ns2-mobility-helper.cc',
'ipv4-address-helper.cc',
- 'ipv4-static-routing-helper.cc',
'internet-stack-helper.cc',
'application-container.cc',
'on-off-helper.cc',
@@ -26,8 +25,6 @@
'nqos-wifi-mac-helper.cc',
'qos-wifi-mac-helper.cc',
'ipv4-nix-vector-helper.cc',
- 'ipv4-global-routing-helper.cc',
- 'ipv4-list-routing-helper.cc',
'ipv4-routing-helper.cc',
'aodv-helper.cc',
'mesh-helper.cc',
@@ -36,8 +33,6 @@
'athstats-helper.cc',
'ipv6-address-helper.cc',
'ipv6-interface-container.cc',
- 'ipv6-static-routing-helper.cc',
- 'ipv6-list-routing-helper.cc',
'ipv6-routing-helper.cc',
'ping6-helper.cc',
'animation-interface.cc',
@@ -65,7 +60,6 @@
'mobility-helper.h',
'ns2-mobility-helper.h',
'ipv4-address-helper.h',
- 'ipv4-static-routing-helper.h',
'internet-stack-helper.h',
'application-container.h',
'on-off-helper.h',
@@ -80,8 +74,6 @@
'nqos-wifi-mac-helper.h',
'qos-wifi-mac-helper.h',
'ipv4-nix-vector-helper.h',
- 'ipv4-global-routing-helper.h',
- 'ipv4-list-routing-helper.h',
'ipv4-routing-helper.h',
'aodv-helper.h',
'mesh-helper.h',
@@ -91,8 +83,6 @@
'athstats-helper.h',
'ipv6-address-helper.h',
'ipv6-interface-container.h',
- 'ipv6-static-routing-helper.h',
- 'ipv6-list-routing-helper.h',
'ipv6-routing-helper.h',
'ping6-helper.h',
'animation-interface.h',
--- a/src/routing/global-routing/candidate-queue.cc Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright 2007 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <algorithm>
-#include <iostream>
-#include "ns3/log.h"
-#include "ns3/assert.h"
-#include "candidate-queue.h"
-#include "global-route-manager-impl.h"
-
-NS_LOG_COMPONENT_DEFINE ("CandidateQueue");
-
-namespace ns3 {
-
-std::ostream&
-operator<< (std::ostream& os, const SPFVertex::VertexType& t)
-{
- switch (t)
- {
- case SPFVertex::VertexRouter: os << "router"; break;
- case SPFVertex::VertexNetwork: os << "network"; break;
- default: os << "unknown"; break;
- };
- return os;
-}
-
-std::ostream&
-operator<< (std::ostream& os, const CandidateQueue& q)
-{
- typedef CandidateQueue::CandidateList_t List_t;
- typedef List_t::const_iterator CIter_t;
- const CandidateQueue::CandidateList_t& list = q.m_candidates;
-
- os << "*** CandidateQueue Begin (<id, distance, LSA-type>) ***" << std::endl;
- for (CIter_t iter = list.begin (); iter != list.end (); iter++)
- {
- os << "<"
- << (*iter)->GetVertexId () << ", "
- << (*iter)->GetDistanceFromRoot () << ", "
- << (*iter)->GetVertexType () << ">" << std::endl;
- }
- os << "*** CandidateQueue End ***";
- return os;
-}
-
-CandidateQueue::CandidateQueue()
- : m_candidates ()
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
-CandidateQueue::~CandidateQueue()
-{
- NS_LOG_FUNCTION_NOARGS ();
- Clear ();
-}
-
- void
-CandidateQueue::Clear (void)
-{
- NS_LOG_FUNCTION_NOARGS ();
- while (!m_candidates.empty ())
- {
- SPFVertex *p = Pop ();
- delete p;
- p = 0;
- }
-}
-
- void
-CandidateQueue::Push (SPFVertex *vNew)
-{
- NS_LOG_FUNCTION (this << vNew);
-
- CandidateList_t::iterator i = std::upper_bound (
- m_candidates.begin (), m_candidates.end (), vNew,
- &CandidateQueue::CompareSPFVertex
- );
- m_candidates.insert (i, vNew);
-}
-
- SPFVertex *
-CandidateQueue::Pop (void)
-{
- NS_LOG_FUNCTION_NOARGS ();
- if (m_candidates.empty ())
- {
- return 0;
- }
-
- SPFVertex *v = m_candidates.front ();
- m_candidates.pop_front ();
- return v;
-}
-
- SPFVertex *
-CandidateQueue::Top (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- if (m_candidates.empty ())
- {
- return 0;
- }
-
- return m_candidates.front ();
-}
-
- bool
-CandidateQueue::Empty (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_candidates.empty ();
-}
-
- uint32_t
-CandidateQueue::Size (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_candidates.size ();
-}
-
- SPFVertex *
-CandidateQueue::Find (const Ipv4Address addr) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- CandidateList_t::const_iterator i = m_candidates.begin ();
-
- for (; i != m_candidates.end (); i++)
- {
- SPFVertex *v = *i;
- if (v->GetVertexId() == addr)
- {
- return v;
- }
- }
-
- return 0;
-}
-
- void
-CandidateQueue::Reorder (void)
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- m_candidates.sort (&CandidateQueue::CompareSPFVertex);
- NS_LOG_LOGIC ("After reordering the CandidateQueue");
- NS_LOG_LOGIC (*this);
-}
-
-/*
- * In this implementation, SPFVertex follows the ordering where
- * a vertex is ranked first if its GetDistanceFromRoot () is smaller;
- * In case of a tie, NetworkLSA is always ranked before RouterLSA.
- *
- * This ordering is necessary for implementing ECMP
- */
-bool
-CandidateQueue::CompareSPFVertex (const SPFVertex* v1, const SPFVertex* v2)
-{
- NS_LOG_FUNCTION (&v1 << &v2);
-
- bool result = false;
- if (v1->GetDistanceFromRoot () < v2->GetDistanceFromRoot ())
- {
- result = true;
- }
- else if (v1->GetDistanceFromRoot () == v2->GetDistanceFromRoot ())
- {
- if (v1->GetVertexType () == SPFVertex::VertexNetwork
- && v2->GetVertexType () == SPFVertex::VertexRouter)
- {
- result = true;
- }
- }
- return result;
-}
-
-} // namespace ns3
--- a/src/routing/global-routing/candidate-queue.h Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,200 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright 2007 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Craig Dowell (craigdo@ee.washington.edu)
- */
-
-#ifndef CANDIDATE_QUEUE_H
-#define CANDIDATE_QUEUE_H
-
-#include <stdint.h>
-#include <list>
-#include "ns3/ipv4-address.h"
-
-namespace ns3 {
-
-class SPFVertex;
-
-/**
- * \brief A Candidate Queue used in static routing.
- *
- * The CandidateQueue is used in the OSPF shortest path computations. It
- * is a priority queue used to store candidates for the shortest path to a
- * given network.
- *
- * The queue holds Shortest Path First Vertex pointers and orders them
- * according to the lowest value of the field m_distanceFromRoot. Remaining
- * vertices are ordered according to increasing distance. This implements a
- * priority queue.
- *
- * Although a STL priority_queue almost does what we want, the requirement
- * for a Find () operation, the dynamic nature of the data and the derived
- * requirement for a Reorder () operation led us to implement this simple
- * enhanced priority queue.
- */
-class CandidateQueue
-{
-public:
-/**
- * @brief Create an empty SPF Candidate Queue.
- * @internal
- *
- * @see SPFVertex
- */
- CandidateQueue ();
-
-/**
- * @internal Destroy an SPF Candidate Queue and release any resources held
- * by the contents.
- * @internal
- *
- * @see SPFVertex
- */
- virtual ~CandidateQueue ();
-
-/**
- * @brief Empty the Candidate Queue and release all of the resources
- * associated with the Shortest Path First Vertex pointers in the queue.
- * @internal
- *
- * @see SPFVertex
- */
- void Clear (void);
-
-/**
- * @brief Push a Shortest Path First Vertex pointer onto the queue according
- * to the priority scheme.
- * @internal
- *
- * On completion, the top of the queue will hold the Shortest Path First
- * Vertex pointer that points to a vertex having lowest value of the field
- * m_distanceFromRoot. Remaining vertices are ordered according to
- * increasing distance.
- *
- * @see SPFVertex
- * @param vNew The Shortest Path First Vertex to add to the queue.
- */
- void Push (SPFVertex *vNew);
-
-/**
- * @brief Pop the Shortest Path First Vertex pointer at the top of the queue.
- * @internal
- *
- * The caller is given the responsibility for releasing the resources
- * associated with the vertex.
- *
- * @see SPFVertex
- * @see Top ()
- * @returns The Shortest Path First Vertex pointer at the top of the queue.
- */
- SPFVertex* Pop (void);
-
-/**
- * @brief Return the Shortest Path First Vertex pointer at the top of the
- * queue.
- * @internal
- *
- * This method does not pop the SPFVertex* off of the queue, it simply
- * returns the pointer.
- *
- * @see SPFVertex
- * @see Pop ()
- * @returns The Shortest Path First Vertex pointer at the top of the queue.
- */
- SPFVertex* Top (void) const;
-
-/**
- * @brief Test the Candidate Queue to determine if it is empty.
- * @internal
- *
- * @returns True if the queue is empty, false otherwise.
- */
- bool Empty (void) const;
-
-/**
- * @brief Return the number of Shortest Path First Vertex pointers presently
- * stored in the Candidate Queue.
- * @internal
- *
- * @see SPFVertex
- * @returns The number of SPFVertex* pointers in the Candidate Queue.
- */
- uint32_t Size (void) const;
-
-/**
- * @brief Searches the Candidate Queue for a Shortest Path First Vertex
- * pointer that points to a vertex having the given IP address.
- * @internal
- *
- * @see SPFVertex
- * @param addr The IP address to search for.
- * @returns The SPFVertex* pointer corresponding to the given IP address.
- */
- SPFVertex* Find (const Ipv4Address addr) const;
-
-/**
- * @brief Reorders the Candidate Queue according to the priority scheme.
- * @internal
- *
- * On completion, the top of the queue will hold the Shortest Path First
- * Vertex pointer that points to a vertex having lowest value of the field
- * m_distanceFromRoot. Remaining vertices are ordered according to
- * increasing distance.
- *
- * This method is provided in case the values of m_distanceFromRoot change
- * during the routing calculations.
- *
- * @see SPFVertex
- */
- void Reorder (void);
-
-private:
-/**
- * Candidate Queue copy construction is disallowed (not implemented) to
- * prevent the compiler from slipping in incorrect versions that don't
- * properly deal with deep copies.
- * \param sr object to copy
- */
- CandidateQueue (CandidateQueue& sr);
-
-/**
- * Candidate Queue assignment operator is disallowed (not implemented) to
- * prevent the compiler from slipping in incorrect versions that don't
- * properly deal with deep copies.
- * \param sr object to assign
- */
- CandidateQueue& operator= (CandidateQueue& sr);
-/**
- * \brief return true if v1 < v2
- *
- * SPFVertexes are added into the queue according to the ordering
- * defined by this method. If v1 should be popped before v2, this
- * method return true; false otherwise
- *
- * \return True if v1 should be popped before v2; false otherwise
- */
- static bool CompareSPFVertex (const SPFVertex* v1, const SPFVertex* v2);
-
- typedef std::list<SPFVertex*> CandidateList_t;
- CandidateList_t m_candidates;
-
- friend std::ostream& operator<< (std::ostream& os, const CandidateQueue& q);
-};
-
-} // namespace ns3
-
-#endif /* CANDIDATE_QUEUE_H */
--- a/src/routing/global-routing/global-route-manager-impl.cc Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2402 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright 2007 University of Washington
- * Copyright (C) 1999, 2000 Kunihiro Ishiguro, Toshiaki Takada
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors: Tom Henderson (tomhend@u.washington.edu)
- *
- * Kunihiro Ishigura, Toshiaki Takada (GNU Zebra) are attributed authors
- * of the quagga 0.99.7/src/ospfd/ospf_spf.c code which was ported here
- */
-
-#include <utility>
-#include <vector>
-#include <queue>
-#include <algorithm>
-#include <iostream>
-#include "ns3/assert.h"
-#include "ns3/fatal-error.h"
-#include "ns3/log.h"
-#include "ns3/node-list.h"
-#include "ns3/ipv4.h"
-#include "ns3/ipv4-routing-protocol.h"
-#include "ns3/ipv4-list-routing.h"
-#include "ns3/mpi-interface.h"
-#include "global-router-interface.h"
-#include "global-route-manager-impl.h"
-#include "candidate-queue.h"
-#include "ipv4-global-routing.h"
-
-NS_LOG_COMPONENT_DEFINE ("GlobalRouteManager");
-
-namespace ns3 {
-
-std::ostream&
-operator<< (std::ostream& os, const SPFVertex::NodeExit_t& exit)
-{
- os << "(" << exit.first << " ," << exit.second << ")";
- return os;
-}
-
-std::ostream&
-operator<< (std::ostream& os, const SPFVertex::ListOfSPFVertex_t& vs)
-{
- typedef SPFVertex::ListOfSPFVertex_t::const_iterator CIter_t;
- os << "{";
- for (CIter_t iter = vs.begin (); iter != vs.end ();)
- {
- os << (*iter)->m_vertexId;
- if (++iter != vs.end ())
- {
- os << ", ";
- }
- else
- {
- break;
- }
- }
- os << "}";
- return os;
-}
-
-// ---------------------------------------------------------------------------
-//
-// SPFVertex Implementation
-//
-// ---------------------------------------------------------------------------
-
-SPFVertex::SPFVertex () :
- m_vertexType (VertexUnknown),
- m_vertexId ("255.255.255.255"),
- m_lsa (0),
- m_distanceFromRoot (SPF_INFINITY),
- m_rootOif (SPF_INFINITY),
- m_nextHop ("0.0.0.0"),
- m_parents (),
- m_children (),
- m_vertexProcessed (false)
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
-SPFVertex::SPFVertex (GlobalRoutingLSA* lsa) :
- m_vertexId (lsa->GetLinkStateId ()),
- m_lsa (lsa),
- m_distanceFromRoot (SPF_INFINITY),
- m_rootOif (SPF_INFINITY),
- m_nextHop ("0.0.0.0"),
- m_parents (),
- m_children (),
- m_vertexProcessed (false)
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- if (lsa->GetLSType () == GlobalRoutingLSA::RouterLSA)
- {
- NS_LOG_LOGIC ("Setting m_vertexType to VertexRouter");
- m_vertexType = SPFVertex::VertexRouter;
- }
- else if (lsa->GetLSType () == GlobalRoutingLSA::NetworkLSA)
- {
- NS_LOG_LOGIC ("Setting m_vertexType to VertexNetwork");
- m_vertexType = SPFVertex::VertexNetwork;
- }
-}
-
-SPFVertex::~SPFVertex ()
-{
- NS_LOG_FUNCTION (m_vertexId);
-
- NS_LOG_LOGIC ("Children vertices - " << m_children);
- NS_LOG_LOGIC ("Parent verteices - " << m_parents);
-
- // find this node from all its parents and remove the entry of this node
- // from all its parents
- for (ListOfSPFVertex_t::iterator piter = m_parents.begin ();
- piter != m_parents.end ();
- piter++)
- {
- // remove the current vertex from its parent's children list. Check
- // if the size of the list is reduced, or the child<->parent relation
- // is not bidirectional
- uint32_t orgCount = (*piter)->m_children.size ();
- (*piter)->m_children.remove (this);
- uint32_t newCount = (*piter)->m_children.size ();
- if (orgCount > newCount)
- {
- NS_ASSERT_MSG (orgCount > newCount, "Unable to find the current vertex from its parents --- impossible!");
- }
- }
-
- // delete children
- while (m_children.size () > 0)
- {
- // pop out children one by one. Some children may disapper
- // when deleting some other children in the list. As a result,
- // it is necessary to use pop to walk through all children, instead
- // of using iterator.
- //
- // Note that m_children.pop_front () is not necessary as this
- // p is removed from the children list when p is deleted
- SPFVertex* p = m_children.front ();
- // 'p' == 0, this child is already deleted by its other parent
- if (p == 0) continue;
- NS_LOG_LOGIC ("Parent vertex-" << m_vertexId << " deleting its child vertex-" << p->GetVertexId ());
- delete p;
- p = 0;
- }
- m_children.clear ();
- // delete parents
- m_parents.clear ();
- // delete root exit direction
- m_ecmpRootExits.clear ();
-
- NS_LOG_LOGIC ("Vertex-" << m_vertexId << " completed deleted");
-}
-
- void
-SPFVertex::SetVertexType (SPFVertex::VertexType type)
-{
- NS_LOG_FUNCTION (type);
- m_vertexType = type;
-}
-
- SPFVertex::VertexType
-SPFVertex::GetVertexType (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_vertexType;
-}
-
- void
-SPFVertex::SetVertexId (Ipv4Address id)
-{
- NS_LOG_FUNCTION (id);
- m_vertexId = id;
-}
-
- Ipv4Address
-SPFVertex::GetVertexId (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_vertexId;
-}
-
- void
-SPFVertex::SetLSA (GlobalRoutingLSA* lsa)
-{
- NS_LOG_FUNCTION (lsa);
- m_lsa = lsa;
-}
-
- GlobalRoutingLSA*
-SPFVertex::GetLSA (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_lsa;
-}
-
- void
-SPFVertex::SetDistanceFromRoot (uint32_t distance)
-{
- NS_LOG_FUNCTION (distance);
- m_distanceFromRoot = distance;
-}
-
- uint32_t
-SPFVertex::GetDistanceFromRoot (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_distanceFromRoot;
-}
-
- void
-SPFVertex::SetParent (SPFVertex* parent)
-{
- NS_LOG_FUNCTION (parent);
-
- // always maintain only one parent when using setter/getter methods
- m_parents.clear ();
- m_parents.push_back (parent);
-}
-
- SPFVertex*
-SPFVertex::GetParent (uint32_t i) const
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- // If the index i is out-of-range, return 0 and do nothing
- if (m_parents.size () <= i)
- {
- NS_LOG_LOGIC ("Index to SPFVertex's parent is out-of-range.");
- return 0;
- }
- ListOfSPFVertex_t::const_iterator iter = m_parents.begin ();
- while (i-- > 0)
- {
- iter++;
- }
- return *iter;
-}
-
-void
-SPFVertex::MergeParent (const SPFVertex* v)
-{
- NS_LOG_FUNCTION (v);
-
- NS_LOG_LOGIC ("Before merge, list of parents = " << m_parents);
- // combine the two lists first, and then remove any duplicated after
- m_parents.insert (m_parents.end (),
- v->m_parents.begin (), v->m_parents.end ());
- // remove duplication
- m_parents.sort ();
- m_parents.unique ();
- NS_LOG_LOGIC ("After merge, list of parents = " << m_parents);
-}
-
-void
-SPFVertex::SetRootExitDirection (Ipv4Address nextHop, int32_t id)
-{
- NS_LOG_FUNCTION (nextHop << id);
-
- // always maintain only one root's exit
- m_ecmpRootExits.clear ();
- m_ecmpRootExits.push_back (NodeExit_t (nextHop, id));
- // update the following in order to be backward compatitable with
- // GetNextHop and GetOutgoingInterface methods
- m_nextHop = nextHop;
- m_rootOif = id;
-}
-
-void
-SPFVertex::SetRootExitDirection (SPFVertex::NodeExit_t exit)
-{
- NS_LOG_FUNCTION (exit);
- SetRootExitDirection (exit.first, exit.second);
-}
-
-SPFVertex::NodeExit_t
-SPFVertex::GetRootExitDirection (uint32_t i) const
-{
- NS_LOG_FUNCTION (i);
- typedef ListOfNodeExit_t::const_iterator CIter_t;
-
- NS_ASSERT_MSG (i < m_ecmpRootExits.size (), "Index out-of-range when accessing SPFVertex::m_ecmpRootExits!");
- CIter_t iter = m_ecmpRootExits.begin ();
- while (i-- > 0) {iter++;}
-
- return *iter;
-}
-
-SPFVertex::NodeExit_t
-SPFVertex::GetRootExitDirection () const
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- NS_ASSERT_MSG (m_ecmpRootExits.size () <= 1, "Assumed there is at most one exit from the root to this vertex");
- return GetRootExitDirection (0);
-}
-
-void
-SPFVertex::MergeRootExitDirections (const SPFVertex* vertex)
-{
- NS_LOG_FUNCTION (vertex);
-
- // obtain the external list of exit directions
- //
- // Append the external list into 'this' and remove duplication afterward
- const ListOfNodeExit_t& extList = vertex->m_ecmpRootExits;
- m_ecmpRootExits.insert (m_ecmpRootExits.end (),
- extList.begin(), extList.end ());
- m_ecmpRootExits.sort ();
- m_ecmpRootExits.unique ();
-}
-
-void
-SPFVertex::InheritAllRootExitDirections (const SPFVertex* vertex)
-{
- NS_LOG_FUNCTION (vertex);
-
- // discard all exit direction currently associated with this vertex,
- // and copy all the exit directions from the given vertex
- if (m_ecmpRootExits.size () > 0)
- {
- NS_LOG_WARN ("x root exit directions in this vertex are going to be discarded");
- }
- m_ecmpRootExits.clear ();
- m_ecmpRootExits.insert (m_ecmpRootExits.end (),
- vertex->m_ecmpRootExits.begin (), vertex->m_ecmpRootExits.end ());
-}
-
-uint32_t
-SPFVertex::GetNRootExitDirections () const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_ecmpRootExits.size ();
-}
-
-uint32_t
-SPFVertex::GetNChildren (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_children.size ();
-}
-
- SPFVertex*
-SPFVertex::GetChild (uint32_t n) const
-{
- NS_LOG_FUNCTION (n);
- uint32_t j = 0;
-
- for ( ListOfSPFVertex_t::const_iterator i = m_children.begin ();
- i != m_children.end ();
- i++, j++)
- {
- if (j == n)
- {
- return *i;
- }
- }
- NS_ASSERT_MSG (false, "Index <n> out of range.");
- return 0;
-}
-
- uint32_t
-SPFVertex::AddChild (SPFVertex* child)
-{
- NS_LOG_FUNCTION (child);
- m_children.push_back (child);
- return m_children.size ();
-}
-
-void
-SPFVertex::SetVertexProcessed (bool value)
-{
- m_vertexProcessed = value;
-}
-
-bool
-SPFVertex::IsVertexProcessed (void) const
-{
- return m_vertexProcessed;
-}
-
-void
-SPFVertex::ClearVertexProcessed (void)
-{
- for (uint32_t i = 0; i < this->GetNChildren (); i++)
- {
- this->GetChild (i)->ClearVertexProcessed ();
- }
- this->SetVertexProcessed (false);
-}
-
-// ---------------------------------------------------------------------------
-//
-// GlobalRouteManagerLSDB Implementation
-//
-// ---------------------------------------------------------------------------
-
-GlobalRouteManagerLSDB::GlobalRouteManagerLSDB ()
-:
- m_database (),
- m_extdatabase ()
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
-GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB ()
-{
- NS_LOG_FUNCTION_NOARGS ();
- LSDBMap_t::iterator i;
- for (i= m_database.begin (); i!= m_database.end (); i++)
- {
- NS_LOG_LOGIC ("free LSA");
- GlobalRoutingLSA* temp = i->second;
- delete temp;
- }
- for (uint32_t j = 0; j < m_extdatabase.size (); j++)
- {
- NS_LOG_LOGIC ("free ASexternalLSA");
- GlobalRoutingLSA* temp = m_extdatabase.at (j);
- delete temp;
- }
- NS_LOG_LOGIC ("clear map");
- m_database.clear ();
-}
-
- void
-GlobalRouteManagerLSDB::Initialize ()
-{
- NS_LOG_FUNCTION_NOARGS ();
- LSDBMap_t::iterator i;
- for (i= m_database.begin (); i!= m_database.end (); i++)
- {
- GlobalRoutingLSA* temp = i->second;
- temp->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
- }
-}
-
- void
-GlobalRouteManagerLSDB::Insert (Ipv4Address addr, GlobalRoutingLSA* lsa)
-{
- NS_LOG_FUNCTION (addr << lsa);
- if (lsa->GetLSType () == GlobalRoutingLSA::ASExternalLSAs)
- {
- m_extdatabase.push_back (lsa);
- }
- else
- {
- m_database.insert (LSDBPair_t (addr, lsa));
- }
-}
-
- GlobalRoutingLSA*
-GlobalRouteManagerLSDB::GetExtLSA (uint32_t index) const
-{
- return m_extdatabase.at (index);
-}
-
- uint32_t
-GlobalRouteManagerLSDB::GetNumExtLSAs () const
-{
- return m_extdatabase.size ();
-}
-
- GlobalRoutingLSA*
-GlobalRouteManagerLSDB::GetLSA (Ipv4Address addr) const
-{
- NS_LOG_FUNCTION (addr);
-//
-// Look up an LSA by its address.
-//
- LSDBMap_t::const_iterator i;
- for (i= m_database.begin (); i!= m_database.end (); i++)
- {
- if (i->first == addr)
- {
- return i->second;
- }
- }
- return 0;
-}
-
- GlobalRoutingLSA*
-GlobalRouteManagerLSDB::GetLSAByLinkData (Ipv4Address addr) const
-{
- NS_LOG_FUNCTION (addr);
-//
-// Look up an LSA by its address.
-//
- LSDBMap_t::const_iterator i;
- for (i= m_database.begin (); i!= m_database.end (); i++)
- {
- GlobalRoutingLSA* temp = i->second;
-// Iterate among temp's Link Records
- for (uint32_t j = 0; j < temp->GetNLinkRecords (); j++)
- {
- GlobalRoutingLinkRecord *lr = temp->GetLinkRecord (j);
- if ( lr->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork &&
- lr->GetLinkData () == addr)
- {
- return temp;
- }
- }
- }
- return 0;
-}
-
-// ---------------------------------------------------------------------------
-//
-// GlobalRouteManagerImpl Implementation
-//
-// ---------------------------------------------------------------------------
-
-GlobalRouteManagerImpl::GlobalRouteManagerImpl ()
-:
- m_spfroot (0)
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_lsdb = new GlobalRouteManagerLSDB ();
-}
-
-GlobalRouteManagerImpl::~GlobalRouteManagerImpl ()
-{
- NS_LOG_FUNCTION_NOARGS ();
- if (m_lsdb)
- {
- delete m_lsdb;
- }
-}
-
- void
-GlobalRouteManagerImpl::DebugUseLsdb (GlobalRouteManagerLSDB* lsdb)
-{
- NS_LOG_FUNCTION (lsdb);
- if (m_lsdb)
- {
- delete m_lsdb;
- }
- m_lsdb = lsdb;
-}
-
- void
-GlobalRouteManagerImpl::DeleteGlobalRoutes ()
-{
- NS_LOG_FUNCTION_NOARGS ();
- NodeList::Iterator listEnd = NodeList::End ();
- for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
- {
- Ptr<Node> node = *i;
- Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
- if (router == 0)
- {
- continue;
- }
- Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
- uint32_t j = 0;
- uint32_t nRoutes = gr->GetNRoutes ();
- NS_LOG_LOGIC ("Deleting " << gr->GetNRoutes ()<< " routes from node " << node->GetId ());
- // Each time we delete route 0, the route index shifts downward
- // We can delete all routes if we delete the route numbered 0
- // nRoutes times
- for (j = 0; j < nRoutes; j++)
- {
- NS_LOG_LOGIC ("Deleting global route " << j << " from node " << node->GetId ());
- gr->RemoveRoute (0);
- }
- NS_LOG_LOGIC ("Deleted " << j << " global routes from node "<< node->GetId ());
- }
- if (m_lsdb)
- {
- NS_LOG_LOGIC ("Deleting LSDB, creating new one");
- delete m_lsdb;
- m_lsdb = new GlobalRouteManagerLSDB ();
- }
-}
-
-//
-// In order to build the routing database, we need to walk the list of nodes
-// in the system and look for those that support the GlobalRouter interface.
-// These routers will export a number of Link State Advertisements (LSAs)
-// that describe the links and networks that are "adjacent" (i.e., that are
-// on the other side of a point-to-point link). We take these LSAs and put
-// add them to the Link State DataBase (LSDB) from which the routes will
-// ultimately be computed.
-//
- void
-GlobalRouteManagerImpl::BuildGlobalRoutingDatabase ()
-{
- NS_LOG_FUNCTION_NOARGS ();
-//
-// Walk the list of nodes looking for the GlobalRouter Interface. Nodes with
-// global router interfaces are, not too surprisingly, our routers.
-//
- NodeList::Iterator listEnd = NodeList::End ();
- for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
- {
- Ptr<Node> node = *i;
-
- Ptr<GlobalRouter> rtr = node->GetObject<GlobalRouter> ();
-//
-// Ignore nodes that aren't participating in routing.
-//
- if (!rtr)
- {
- continue;
- }
-//
-// You must call DiscoverLSAs () before trying to use any routing info or to
-// update LSAs. DiscoverLSAs () drives the process of discovering routes in
-// the GlobalRouter. Afterward, you may use GetNumLSAs (), which is a very
-// computationally inexpensive call. If you call GetNumLSAs () before calling
-// DiscoverLSAs () will get zero as the number since no routes have been
-// found.
-//
- Ptr<Ipv4GlobalRouting> grouting = rtr->GetRoutingProtocol ();
- uint32_t numLSAs = rtr->DiscoverLSAs ();
- NS_LOG_LOGIC ("Found " << numLSAs << " LSAs");
-
- for (uint32_t j = 0; j < numLSAs; ++j)
- {
- GlobalRoutingLSA* lsa = new GlobalRoutingLSA ();
-//
-// This is the call to actually fetch a Link State Advertisement from the
-// router.
-//
- rtr->GetLSA (j, *lsa);
- NS_LOG_LOGIC (*lsa);
-//
-// Write the newly discovered link state advertisement to the database.
-//
- m_lsdb->Insert (lsa->GetLinkStateId (), lsa);
- }
- }
-}
-
-//
-// For each node that is a global router (which is determined by the presence
-// of an aggregated GlobalRouter interface), run the Dijkstra SPF calculation
-// on the database rooted at that router, and populate the node forwarding
-// tables.
-//
-// This function parallels RFC2328, Section 16.1.1, and quagga ospfd
-//
-// This calculation yields the set of intra-area routes associated
-// with an area (called hereafter Area A). A router calculates the
-// shortest-path tree using itself as the root. The formation
-// of the shortest path tree is done here in two stages. In the
-// first stage, only links between routers and transit networks are
-// considered. Using the Dijkstra algorithm, a tree is formed from
-// this subset of the link state database. In the second stage,
-// leaves are added to the tree by considering the links to stub
-// networks.
-//
-// The area's link state database is represented as a directed graph.
-// The graph's vertices are routers, transit networks and stub networks.
-//
-// The first stage of the procedure (i.e., the Dijkstra algorithm)
-// can now be summarized as follows. At each iteration of the
-// algorithm, there is a list of candidate vertices. Paths from
-// the root to these vertices have been found, but not necessarily
-// the shortest ones. However, the paths to the candidate vertex
-// that is closest to the root are guaranteed to be shortest; this
-// vertex is added to the shortest-path tree, removed from the
-// candidate list, and its adjacent vertices are examined for
-// possible addition to/modification of the candidate list. The
-// algorithm then iterates again. It terminates when the candidate
-// list becomes empty.
-//
- void
-GlobalRouteManagerImpl::InitializeRoutes ()
-{
- NS_LOG_FUNCTION_NOARGS ();
-//
-// Walk the list of nodes in the system.
-//
- NS_LOG_INFO ("About to start SPF calculation");
- NodeList::Iterator listEnd = NodeList::End ();
- for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
- {
- Ptr<Node> node = *i;
-//
-// Look for the GlobalRouter interface that indicates that the node is
-// participating in routing.
-//
- Ptr<GlobalRouter> rtr =
- node->GetObject<GlobalRouter> ();
-
- // Ignore nodes that are not assigned to our systemId (distributed sim)
- if (node->GetSystemId () != MpiInterface::GetSystemId ())
- {
- continue;
- }
-
-//
-// if the node has a global router interface, then run the global routing
-// algorithms.
-//
- if (rtr && rtr->GetNumLSAs () )
- {
- SPFCalculate (rtr->GetRouterId ());
- }
- }
- NS_LOG_INFO ("Finished SPF calculation");
-}
-
-//
-// This method is derived from quagga ospf_spf_next (). See RFC2328 Section
-// 16.1 (2) for further details.
-//
-// We're passed a parameter <v> that is a vertex which is already in the SPF
-// tree. A vertex represents a router node. We also get a reference to the
-// SPF candidate queue, which is a priority queue containing the shortest paths
-// to the networks we know about.
-//
-// We examine the links in v's LSA and update the list of candidates with any
-// vertices not already on the list. If a lower-cost path is found to a
-// vertex already on the candidate list, store the new (lower) cost.
-//
- void
-GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate)
-{
- NS_LOG_FUNCTION (v << &candidate);
-
- SPFVertex* w = 0;
- GlobalRoutingLSA* w_lsa = 0;
- GlobalRoutingLinkRecord *l = 0;
- uint32_t distance = 0;
- uint32_t numRecordsInVertex = 0;
-//
-// V points to a Router-LSA or Network-LSA
-// Loop over the links in router LSA or attached routers in Network LSA
-//
- if (v->GetVertexType () == SPFVertex::VertexRouter)
- {
- numRecordsInVertex = v->GetLSA ()->GetNLinkRecords ();
- }
- if (v->GetVertexType () == SPFVertex::VertexNetwork)
- {
- numRecordsInVertex = v->GetLSA ()->GetNAttachedRouters ();
- }
-
- for (uint32_t i = 0; i < numRecordsInVertex; i++)
- {
-// Get w_lsa: In case of V is Router-LSA
- if (v->GetVertexType () == SPFVertex::VertexRouter)
- {
- NS_LOG_LOGIC ("Examining link " << i << " of " <<
- v->GetVertexId () << "'s " <<
- v->GetLSA ()->GetNLinkRecords () << " link records");
-//
-// (a) If this is a link to a stub network, examine the next link in V's LSA.
-// Links to stub networks will be considered in the second stage of the
-// shortest path calculation.
-//
- l = v->GetLSA ()->GetLinkRecord (i);
- if (l->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork)
- {
- NS_LOG_LOGIC ("Found a Stub record to " << l->GetLinkId ());
- continue;
- }
-//
-// (b) Otherwise, W is a transit vertex (router or transit network). Look up
-// the vertex W's LSA (router-LSA or network-LSA) in Area A's link state
-// database.
-//
- if (l->GetLinkType () == GlobalRoutingLinkRecord::PointToPoint)
- {
-//
-// Lookup the link state advertisement of the new link -- we call it <w> in
-// the link state database.
-//
- w_lsa = m_lsdb->GetLSA (l->GetLinkId ());
- NS_ASSERT (w_lsa);
- NS_LOG_LOGIC ("Found a P2P record from " <<
- v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
- }
- else if (l->GetLinkType () ==
- GlobalRoutingLinkRecord::TransitNetwork)
- {
- w_lsa = m_lsdb->GetLSA (l->GetLinkId ());
- NS_ASSERT (w_lsa);
- NS_LOG_LOGIC ("Found a Transit record from " <<
- v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
- }
- else
- {
- NS_ASSERT_MSG (0, "illegal Link Type");
- }
- }
-// Get w_lsa: In case of V is Network-LSA
- if (v->GetVertexType () == SPFVertex::VertexNetwork)
- {
- w_lsa = m_lsdb->GetLSAByLinkData
- (v->GetLSA ()->GetAttachedRouter (i));
- if (!w_lsa)
- {
- continue;
- }
- NS_LOG_LOGIC ("Found a Network LSA from " <<
- v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
- }
-
-// Note: w_lsa at this point may be either RouterLSA or NetworkLSA
-//
-// (c) If vertex W is already on the shortest-path tree, examine the next
-// link in the LSA.
-//
-// If the link is to a router that is already in the shortest path first tree
-// then we have it covered -- ignore it.
-//
- if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_IN_SPFTREE)
- {
- NS_LOG_LOGIC ("Skipping -> LSA "<<
- w_lsa->GetLinkStateId () << " already in SPF tree");
- continue;
- }
-//
-// (d) Calculate the link state cost D of the resulting path from the root to
-// vertex W. D is equal to the sum of the link state cost of the (already
-// calculated) shortest path to vertex V and the advertised cost of the link
-// between vertices V and W.
-//
- if (v->GetLSA ()->GetLSType () == GlobalRoutingLSA::RouterLSA)
- {
- distance = v->GetDistanceFromRoot () + l->GetMetric ();
- }
- else
- {
- distance = v->GetDistanceFromRoot ();
- }
-
- NS_LOG_LOGIC ("Considering w_lsa " << w_lsa->GetLinkStateId ());
-
-// Is there already vertex w in candidate list?
- if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED)
- {
-// Calculate nexthop to w
-// We need to figure out how to actually get to the new router represented
-// by <w>. This will (among other things) find the next hop address to send
-// packets destined for this network to, and also find the outbound interface
-// used to forward the packets.
-
-// prepare vertex w
- w = new SPFVertex (w_lsa);
- if (SPFNexthopCalculation (v, w, l, distance))
- {
- w_lsa->SetStatus (GlobalRoutingLSA::LSA_SPF_CANDIDATE);
-//
-// Push this new vertex onto the priority queue (ordered by distance from the
-// root node).
-//
- candidate.Push (w);
- NS_LOG_LOGIC ("Pushing " <<
- w->GetVertexId () << ", parent vertexId: " <<
- v->GetVertexId () << ", distance: " <<
- w->GetDistanceFromRoot ());
- }
- else
- NS_ASSERT_MSG (0, "SPFNexthopCalculation never "
- << "return false, but it does now!");
- }
- else if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_CANDIDATE)
- {
-//
-// We have already considered the link represented by <w>. What wse have to
-// do now is to decide if this new router represents a route with a shorter
-// distance metric.
-//
-// So, locate the vertex in the candidate queue and take a look at the
-// distance.
-
-/* (quagga-0.98.6) W is already on the candidate list; call it cw.
-* Compare the previously calculated cost (cw->distance)
-* with the cost we just determined (w->distance) to see
-* if we've found a shorter path.
-*/
- SPFVertex* cw;
- cw = candidate.Find (w_lsa->GetLinkStateId ());
- if (cw->GetDistanceFromRoot () < distance)
- {
-//
-// This is not a shorter path, so don't do anything.
-//
- continue;
- }
- else if (cw->GetDistanceFromRoot () == distance)
- {
-//
-// This path is one with an equal cost.
-//
- NS_LOG_LOGIC ("Equal cost multiple paths found.");
-
-// At this point, there are two instances 'w' and 'cw' of the
-// same vertex, the vertex that is currently being considered
-// for adding into the shortest path tree. 'w' is the instance
-// as seen from the root via vertex 'v', and 'cw' is the instance
-// as seen from the root via some other vertices other than 'v'.
-// These two instances are being merged in the following code.
-// In particular, the parent nodes, the next hops, and the root's
-// output interfaces of the two instances are being merged.
-//
-// Note that this is functionally equivalent to calling
-// ospf_nexthop_merge (cw->nexthop, w->nexthop) in quagga-0.98.6
-// (ospf_spf.c::859), although the detail implementation
-// is very different from quagga (blame ns3::GlobalRouteManagerImpl)
-
-// prepare vertex w
- w = new SPFVertex (w_lsa);
- SPFNexthopCalculation (v, w, l, distance);
- cw->MergeRootExitDirections (w);
- cw->MergeParent (w);
-// SPFVertexAddParent (w) is necessary as the destructor of
-// SPFVertex checks if the vertex and its parent is linked
-// bidirectionally
- SPFVertexAddParent (w);
- delete w;
- }
- else // cw->GetDistanceFromRoot () > w->GetDistanceFromRoot ()
- {
-//
-// this path represents a new, lower-cost path to <w> (the vertex we found in
-// the current link record of the link state advertisement of the current root
-// (vertex <v>)
-//
-// N.B. the nexthop_calculation is conditional, if it finds a valid nexthop
-// it will call spf_add_parents, which will flush the old parents
-//
- if (SPFNexthopCalculation (v, cw, l, distance))
- {
-//
-// If we've changed the cost to get to the vertex represented by <w>, we
-// must reorder the priority queue keyed to that cost.
-//
- candidate.Reorder ();
- }
- } // new lower cost path found
- } // end W is already on the candidate list
- } // end loop over the links in V's LSA
-}
-
-//
-// This method is derived from quagga ospf_nexthop_calculation() 16.1.1.
-//
-// Calculate nexthop from root through V (parent) to vertex W (destination)
-// with given distance from root->W.
-//
-// As appropriate, set w's parent, distance, and nexthop information
-//
-// For now, this is greatly simplified from the quagga code
-//
- int
-GlobalRouteManagerImpl::SPFNexthopCalculation (
- SPFVertex* v,
- SPFVertex* w,
- GlobalRoutingLinkRecord* l,
- uint32_t distance)
-{
- NS_LOG_FUNCTION (v << w << l << distance);
-//
-// If w is a NetworkVertex, l should be null
-/*
- if (w->GetVertexType () == SPFVertex::VertexNetwork && l)
- {
- NS_ASSERT_MSG (0, "Error: SPFNexthopCalculation parameter problem");
- }
-*/
-
-//
-// The vertex m_spfroot is a distinguished vertex representing the node at
-// the root of the calculations. That is, it is the node for which we are
-// calculating the routes.
-//
-// There are two distinct cases for calculating the next hop information.
-// First, if we're considering a hop from the root to an "adjacent" network
-// (one that is on the other side of a point-to-point link connected to the
-// root), then we need to store the information needed to forward down that
-// link. The second case is if the network is not directly adjacent. In that
-// case we need to use the forwarding information from the vertex on the path
-// to the destination that is directly adjacent [node 1] in both cases of the
-// diagram below.
-//
-// (1) [root] -> [point-to-point] -> [node 1]
-// (2) [root] -> [point-to-point] -> [node 1] -> [point-to-point] -> [node 2]
-//
-// We call the propagation of next hop information down vertices of a path
-// "inheriting" the next hop information.
-//
-// The point-to-point link information is only useful in this calculation when
-// we are examining the root node.
-//
- if (v == m_spfroot)
- {
-//
-// In this case <v> is the root node, which means it is the starting point
-// for the packets forwarded by that node. This also means that the next hop
-// address of packets headed for some arbitrary off-network destination must
-// be the destination at the other end of one of the links off of the root
-// node if this root node is a router. We then need to see if this node <w>
-// is a router.
-//
- if (w->GetVertexType () == SPFVertex::VertexRouter)
- {
-//
-// In the case of point-to-point links, the link data field (m_linkData) of a
-// Global Router Link Record contains the local IP address. If we look at the
-// link record describing the link from the perspecive of <w> (the remote
-// node from the viewpoint of <v>) back to the root node, we can discover the
-// IP address of the router to which <v> is adjacent. This is a distinguished
-// address -- the next hop address to get from <v> to <w> and all networks
-// accessed through that path.
-//
-// SPFGetNextLink () is a little odd. used in this way it is just going to
-// return the link record describing the link from <w> to <v>. Think of it as
-// SPFGetLink.
-//
- NS_ASSERT (l);
- GlobalRoutingLinkRecord *linkRemote = 0;
- linkRemote = SPFGetNextLink (w, v, linkRemote);
-//
-// At this point, <l> is the Global Router Link Record describing the point-
-// to point link from <v> to <w> from the perspective of <v>; and <linkRemote>
-// is the Global Router Link Record describing that same link from the
-// perspective of <w> (back to <v>). Now we can just copy the next hop
-// address from the m_linkData member variable.
-//
-// The next hop member variable we put in <w> has the sense "in order to get
-// from the root node to the host represented by vertex <w>, you have to send
-// the packet to the next hop address specified in w->m_nextHop.
-//
- Ipv4Address nextHop = linkRemote->GetLinkData ();
-//
-// Now find the outgoing interface corresponding to the point to point link
-// from the perspective of <v> -- remember that <l> is the link "from"
-// <v> "to" <w>.
-//
- uint32_t outIf = FindOutgoingInterfaceId (l->GetLinkData ());
-
- w->SetRootExitDirection (nextHop, outIf);
- w->SetDistanceFromRoot (distance);
- w->SetParent (v);
- NS_LOG_LOGIC ("Next hop from " <<
- v->GetVertexId () << " to " << w->GetVertexId () <<
- " goes through next hop " << nextHop <<
- " via outgoing interface " << outIf <<
- " with distance " << distance);
- } // end W is a router vertes
- else
- {
- NS_ASSERT (w->GetVertexType () == SPFVertex::VertexNetwork);
-// W is a directly connected network; no next hop is required
- GlobalRoutingLSA* w_lsa = w->GetLSA ();
- NS_ASSERT (w_lsa->GetLSType () == GlobalRoutingLSA::NetworkLSA);
-// Find outgoing interface ID for this network
- uint32_t outIf = FindOutgoingInterfaceId (w_lsa->GetLinkStateId (),
- w_lsa->GetNetworkLSANetworkMask () );
-// Set the next hop to 0.0.0.0 meaning "not exist"
- Ipv4Address nextHop = Ipv4Address::GetZero ();
- w->SetRootExitDirection (nextHop, outIf);
- w->SetDistanceFromRoot (distance);
- w->SetParent (v);
- NS_LOG_LOGIC ("Next hop from " <<
- v->GetVertexId () << " to network " << w->GetVertexId () <<
- " via outgoing interface " << outIf <<
- " with distance " << distance);
- return 1;
- }
- } // end v is the root
- else if (v->GetVertexType () == SPFVertex::VertexNetwork)
- {
-// See if any of v's parents are the root
- if (v->GetParent () == m_spfroot)
- {
-// 16.1.1 para 5. ...the parent vertex is a network that
-// directly connects the calculating router to the destination
-// router. The list of next hops is then determined by
-// examining the destination's router-LSA...
- NS_ASSERT (w->GetVertexType () == SPFVertex::VertexRouter);
- GlobalRoutingLinkRecord *linkRemote = 0;
- while ((linkRemote = SPFGetNextLink (w, v, linkRemote)))
- {
-/* ...For each link in the router-LSA that points back to the
- * parent network, the link's Link Data field provides the IP
- * address of a next hop router. The outgoing interface to
- * use can then be derived from the next hop IP address (or
- * it can be inherited from the parent network).
- */
- Ipv4Address nextHop = linkRemote->GetLinkData ();
- uint32_t outIf = v->GetRootExitDirection ().second;
- w->SetRootExitDirection (nextHop, outIf);
- NS_LOG_LOGIC ("Next hop from " <<
- v->GetVertexId () << " to " << w->GetVertexId () <<
- " goes through next hop " << nextHop <<
- " via outgoing interface " << outIf);
- }
- }
- else
- {
- w->SetRootExitDirection (v->GetRootExitDirection ());
- }
- }
- else
- {
-//
-// If we're calculating the next hop information from a node (v) that is
-// *not* the root, then we need to "inherit" the information needed to
-// forward the packet from the vertex closer to the root. That is, we'll
-// still send packets to the next hop address of the router adjacent to the
-// root on the path toward <w>.
-//
-// Above, when we were considering the root node, we calculated the next hop
-// address and outgoing interface required to get off of the root network.
-// At this point, we are further away from the root network along one of the
-// (shortest) paths. So the next hop and outoing interface remain the same
-// (are inherited).
-//
- w->InheritAllRootExitDirections (v);
- }
-//
-// In all cases, we need valid values for the distance metric and a parent.
-//
- w->SetDistanceFromRoot (distance);
- w->SetParent (v);
-
- return 1;
-}
-
-//
-// This method is derived from quagga ospf_get_next_link ()
-//
-// First search the Global Router Link Records of vertex <v> for one
-// representing a point-to point link to vertex <w>.
-//
-// What is done depends on prev_link. Contrary to appearances, prev_link just
-// acts as a flag here. If prev_link is NULL, we return the first Global
-// Router Link Record we find that describes a point-to-point link from <v>
-// to <w>. If prev_link is not NULL, we return a Global Router Link Record
-// representing a possible *second* link from <v> to <w>.
-//
- GlobalRoutingLinkRecord*
-GlobalRouteManagerImpl::SPFGetNextLink (
- SPFVertex* v,
- SPFVertex* w,
- GlobalRoutingLinkRecord* prev_link)
-{
- NS_LOG_FUNCTION (v << w << prev_link);
-
- bool skip = true;
- bool found_prev_link = false;
- GlobalRoutingLinkRecord* l;
-//
-// If prev_link is 0, we are really looking for the first link, not the next
-// link.
-//
- if (prev_link == 0)
- {
- skip = false;
- found_prev_link = true;
- }
-//
-// Iterate through the Global Router Link Records advertised by the vertex
-// <v> looking for records representing the point-to-point links off of this
-// vertex.
-//
- for (uint32_t i = 0; i < v->GetLSA ()->GetNLinkRecords (); ++i)
- {
- l = v->GetLSA ()->GetLinkRecord (i);
-//
-// The link ID of a link record representing a point-to-point link is set to
-// the router ID of the neighboring router -- the router to which the link
-// connects from the perspective of <v> in this case. The vertex ID is also
-// set to the router ID (using the link state advertisement of a router node).
-// We're just checking to see if the link <l> is actually the link from <v> to
-// <w>.
-//
- if (l->GetLinkId () == w->GetVertexId ())
- {
- if (!found_prev_link)
- {
- NS_LOG_LOGIC ("Skipping links before prev_link found");
- found_prev_link = true;
- continue;
- }
-
- NS_LOG_LOGIC ("Found matching link l: linkId = " <<
- l->GetLinkId () << " linkData = " << l->GetLinkData ());
-//
-// If skip is false, don't (not too surprisingly) skip the link found -- it's
-// the one we're interested in. That's either because we didn't pass in a
-// previous link, and we're interested in the first one, or because we've
-// skipped a previous link and moved forward to the next (which is then the
-// one we want).
-//
- if (skip == false)
- {
- NS_LOG_LOGIC ("Returning the found link");
- return l;
- }
- else
- {
-//
-// Skip is true and we've found a link from <v> to <w>. We want the next one.
-// Setting skip to false gets us the next point-to-point global router link
-// record in the LSA from <v>.
-//
- NS_LOG_LOGIC ("Skipping the found link");
- skip = false;
- continue;
- }
- }
- }
- return 0;
-}
-
-//
-// Used for unit tests.
-//
- void
-GlobalRouteManagerImpl::DebugSPFCalculate (Ipv4Address root)
-{
- NS_LOG_FUNCTION (root);
- SPFCalculate (root);
-}
-
-//
-// Used to test if a node is a stub, from an OSPF sense.
-// If there is only one link of type 1 or 2, then a default route
-// can safely be added to the next-hop router and SPF does not need
-// to be run
-//
-bool
-GlobalRouteManagerImpl::CheckForStubNode (Ipv4Address root)
-{
- NS_LOG_FUNCTION (root);
- GlobalRoutingLSA *rlsa = m_lsdb->GetLSA (root);
- Ipv4Address myRouterId = rlsa->GetLinkStateId ();
- int transits = 0;
- GlobalRoutingLinkRecord *transitLink = 0;
- for (uint32_t i = 0; i < rlsa->GetNLinkRecords (); i++)
- {
- GlobalRoutingLinkRecord *l = rlsa->GetLinkRecord (i);
- if (l->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork)
- {
- transits++;
- transitLink = l;
- }
- else if (l->GetLinkType () == GlobalRoutingLinkRecord::PointToPoint)
- {
- transits++;
- transitLink = l;
- }
- }
- if (transits == 0)
- {
- // This router is not connected to any router. Probably, global
- // routing should not be called for this node, but we can just raise
- // a warning here and return true.
- NS_LOG_WARN ("all nodes should have at least one transit link:" << root );
- return true;
- }
- if (transits == 1)
- {
- if (transitLink->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork)
- {
- // Install default route to next hop router
- // What is the next hop? We need to check all neighbors on the link.
- // If there is a single router that has two transit links, then
- // that is the default next hop. If there are more than one
- // routers on link with multiple transit links, return false.
- // Not yet implemented, so simply return false
- NS_LOG_LOGIC ("TBD: Would have inserted default for transit");
- return false;
- }
- else if (transitLink->GetLinkType () == GlobalRoutingLinkRecord::PointToPoint)
- {
- // Install default route to next hop
- // The link record LinkID is the router ID of the peer.
- // The Link Data is the local IP interface address
- GlobalRoutingLSA *w_lsa = m_lsdb->GetLSA (transitLink->GetLinkId ());
- uint32_t nLinkRecords = w_lsa->GetNLinkRecords ();
- for (uint32_t j = 0; j < nLinkRecords; ++j)
- {
- //
- // We are only concerned about point-to-point links
- //
- GlobalRoutingLinkRecord *lr = w_lsa->GetLinkRecord (j);
- if (lr->GetLinkType () != GlobalRoutingLinkRecord::PointToPoint)
- {
- continue;
- }
- // Find the link record that corresponds to our routerId
- if (lr->GetLinkId () == myRouterId)
- {
- // Next hop is stored in the LinkID field of lr
- Ptr<GlobalRouter> router = rlsa->GetNode ()->GetObject<GlobalRouter> ();
- NS_ASSERT (router);
- Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
- NS_ASSERT (gr);
- gr->AddNetworkRouteTo (Ipv4Address ("0.0.0.0"), Ipv4Mask ("0.0.0.0"), lr->GetLinkData (),
- FindOutgoingInterfaceId (transitLink->GetLinkData ()));
- NS_LOG_LOGIC ("Inserting default route for node " << myRouterId << " to next hop " <<
- lr->GetLinkData () << " via interface " <<
- FindOutgoingInterfaceId(transitLink->GetLinkData()));
- return true;
- }
- }
- }
- }
- return false;
-}
-
-// quagga ospf_spf_calculate
- void
-GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root)
-{
- NS_LOG_FUNCTION (this << root);
-
- SPFVertex *v;
-//
-// Initialize the Link State Database.
-//
- m_lsdb->Initialize ();
-//
-// The candidate queue is a priority queue of SPFVertex objects, with the top
-// of the queue being the closest vertex in terms of distance from the root
-// of the tree. Initially, this queue is empty.
-//
- CandidateQueue candidate;
- NS_ASSERT (candidate.Size () == 0);
-//
-// Initialize the shortest-path tree to only contain the router doing the
-// calculation. Each router (and corresponding network) is a vertex in the
-// shortest path first (SPF) tree.
-//
- v = new SPFVertex (m_lsdb->GetLSA (root));
-//
-// This vertex is the root of the SPF tree and it is distance 0 from the root.
-// We also mark this vertex as being in the SPF tree.
-//
- m_spfroot= v;
- v->SetDistanceFromRoot (0);
- v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE);
- NS_LOG_LOGIC ("Starting SPFCalculate for node " << root);
-
-//
-// Optimize SPF calculation, for ns-3.
-// We do not need to calculate SPF for every node in the network if this
-// node has only one interface through which another router can be
-// reached. Instead, short-circuit this computation and just install
-// a default route in the CheckForStubNode() method.
-//
- if (NodeList::GetNNodes () > 0 && CheckForStubNode (root))
- {
- NS_LOG_LOGIC ("SPFCalculate truncated for stub node " << root);
- delete m_spfroot;
- return;
- }
-
- for (;;)
- {
-//
-// The operations we need to do are given in the OSPF RFC which we reference
-// as we go along.
-//
-// RFC2328 16.1. (2).
-//
-// We examine the Global Router Link Records in the Link State
-// Advertisements of the current vertex. If there are any point-to-point
-// links to unexplored adjacent vertices we add them to the tree and update
-// the distance and next hop information on how to get there. We also add
-// the new vertices to the candidate queue (the priority queue ordered by
-// shortest path). If the new vertices represent shorter paths, we use them
-// and update the path cost.
-//
- SPFNext (v, candidate);
-//
-// RFC2328 16.1. (3).
-//
-// If at this step the candidate list is empty, the shortest-path tree (of
-// transit vertices) has been completely built and this stage of the
-// procedure terminates.
-//
- if (candidate.Size () == 0)
- {
- break;
- }
-//
-// Choose the vertex belonging to the candidate list that is closest to the
-// root, and add it to the shortest-path tree (removing it from the candidate
-// list in the process).
-//
-// Recall that in the previous step, we created SPFVertex structures for each
-// of the routers found in the Global Router Link Records and added tehm to
-// the candidate list.
-//
- NS_LOG_LOGIC (candidate);
- v = candidate.Pop ();
- NS_LOG_LOGIC ("Popped vertex " << v->GetVertexId ());
-//
-// Update the status field of the vertex to indicate that it is in the SPF
-// tree.
-//
- v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE);
-//
-// The current vertex has a parent pointer. By calling this rather oddly
-// named method (blame quagga) we add the current vertex to the list of
-// children of that parent vertex. In the next hop calculation called during
-// SPFNext, the parent pointer was set but the vertex has been orphaned up
-// to now.
-//
- SPFVertexAddParent (v);
-//
-// Note that when there is a choice of vertices closest to the root, network
-// vertices must be chosen before router vertices in order to necessarily
-// find all equal-cost paths.
-//
-// RFC2328 16.1. (4).
-//
-// This is the method that actually adds the routes. It'll walk the list
-// of nodes in the system, looking for the node corresponding to the router
-// ID of the root of the tree -- that is the router we're building the routes
-// for. It looks for the Ipv4 interface of that node and remembers it. So
-// we are only actually adding routes to that one node at the root of the SPF
-// tree.
-//
-// We're going to pop of a pointer to every vertex in the tree except the
-// root in order of distance from the root. For each of the vertices, we call
-// SPFIntraAddRouter (). Down in SPFIntraAddRouter, we look at all of the
-// point-to-point Global Router Link Records (the links to nodes adjacent to
-// the node represented by the vertex). We add a route to the IP address
-// specified by the m_linkData field of each of those link records. This will
-// be the *local* IP address associated with the interface attached to the
-// link. We use the outbound interface and next hop information present in
-// the vertex <v> which have possibly been inherited from the root.
-//
-// To summarize, we're going to look at the node represented by <v> and loop
-// through its point-to-point links, adding a *host* route to the local IP
-// address (at the <v> side) for each of those links.
-//
- if (v->GetVertexType () == SPFVertex::VertexRouter)
- {
- SPFIntraAddRouter (v);
- }
- else if (v->GetVertexType () == SPFVertex::VertexNetwork)
- {
- SPFIntraAddTransit (v);
- }
- else
- {
- NS_ASSERT_MSG (0, "illegal SPFVertex type");
- }
-//
-// RFC2328 16.1. (5).
-//
-// Iterate the algorithm by returning to Step 2 until there are no more
-// candidate vertices.
-
- } // end for loop
-
-// Second stage of SPF calculation procedure
- SPFProcessStubs (m_spfroot);
- for (uint32_t i = 0; i < m_lsdb->GetNumExtLSAs (); i++)
- {
- m_spfroot->ClearVertexProcessed ();
- GlobalRoutingLSA *extlsa = m_lsdb->GetExtLSA (i);
- NS_LOG_LOGIC ("Processing External LSA with id " << extlsa->GetLinkStateId ());
- ProcessASExternals (m_spfroot, extlsa);
- }
-
-//
-// We're all done setting the routing information for the node at the root of
-// the SPF tree. Delete all of the vertices and corresponding resources. Go
-// possibly do it again for the next router.
-//
- delete m_spfroot;
- m_spfroot = 0;
-}
-
-void
-GlobalRouteManagerImpl::ProcessASExternals (SPFVertex* v, GlobalRoutingLSA* extlsa)
-{
- NS_LOG_FUNCTION_NOARGS ();
- NS_LOG_LOGIC ("Processing external for destination " <<
- extlsa->GetLinkStateId () <<
- ", for router " << v->GetVertexId () <<
- ", advertised by " << extlsa->GetAdvertisingRouter ());
- if (v->GetVertexType () == SPFVertex::VertexRouter)
- {
- GlobalRoutingLSA *rlsa = v->GetLSA ();
- NS_LOG_LOGIC ("Processing router LSA with id " << rlsa->GetLinkStateId ());
- if ((rlsa->GetLinkStateId ()) == (extlsa->GetAdvertisingRouter ()))
- {
- NS_LOG_LOGIC ("Found advertising router to destination");
- SPFAddASExternal(extlsa,v);
- }
- }
- for (uint32_t i = 0; i < v->GetNChildren (); i++)
- {
- if (!v->GetChild (i)->IsVertexProcessed ())
- {
- NS_LOG_LOGIC ("Vertex's child " << i << " not yet processed, processing...");
- ProcessASExternals (v->GetChild (i), extlsa);
- v->GetChild (i)->SetVertexProcessed (true);
- }
- }
-}
-
-//
-// Adding external routes to routing table - modeled after
-// SPFAddIntraAddStub()
-//
-
-void
-GlobalRouteManagerImpl::SPFAddASExternal (GlobalRoutingLSA *extlsa, SPFVertex *v)
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- NS_ASSERT_MSG (m_spfroot, "GlobalRouteManagerImpl::SPFAddASExternal (): Root pointer not set");
-// Two cases to consider: We are advertising the external ourselves
-// => No need to add anything
-// OR find best path to the advertising router
- if (v->GetVertexId () == m_spfroot->GetVertexId ())
- {
- NS_LOG_LOGIC ("External is on local host: "
- << v->GetVertexId () << "; returning");
- return;
- }
- NS_LOG_LOGIC ("External is on remote host: "
- << extlsa->GetAdvertisingRouter () << "; installing");
-
- Ipv4Address routerId = m_spfroot->GetVertexId ();
-
- NS_LOG_LOGIC ("Vertex ID = " << routerId);
-//
-// We need to walk the list of nodes looking for the one that has the router
-// ID corresponding to the root vertex. This is the one we're going to write
-// the routing information to.
-//
- NodeList::Iterator i = NodeList::Begin ();
- NodeList::Iterator listEnd = NodeList::End ();
- for (; i != listEnd; i++)
- {
- Ptr<Node> node = *i;
-//
-// The router ID is accessible through the GlobalRouter interface, so we need
-// to QI for that interface. If there's no GlobalRouter interface, the node
-// in question cannot be the router we want, so we continue.
-//
- Ptr<GlobalRouter> rtr = node->GetObject<GlobalRouter> ();
-
- if (rtr == 0)
- {
- NS_LOG_LOGIC ("No GlobalRouter interface on node " << node->GetId ());
- continue;
- }
-//
-// If the router ID of the current node is equal to the router ID of the
-// root of the SPF tree, then this node is the one for which we need to
-// write the routing tables.
-//
- NS_LOG_LOGIC ("Considering router " << rtr->GetRouterId ());
-
- if (rtr->GetRouterId () == routerId)
- {
- NS_LOG_LOGIC ("Setting routes for node " << node->GetId ());
-//
-// Routing information is updated using the Ipv4 interface. We need to QI
-// for that interface. If the node is acting as an IP version 4 router, it
-// should absolutely have an Ipv4 interface.
-//
- Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
- NS_ASSERT_MSG (ipv4,
- "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
- "QI for <Ipv4> interface failed");
-//
-// Get the Global Router Link State Advertisement from the vertex we're
-// adding the routes to. The LSA will have a number of attached Global Router
-// Link Records corresponding to links off of that vertex / node. We're going
-// to be interested in the records corresponding to point-to-point links.
-//
- NS_ASSERT_MSG (v->GetLSA (),
- "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
- "Expected valid LSA in SPFVertex* v");
- Ipv4Mask tempmask = extlsa->GetNetworkLSANetworkMask ();
- Ipv4Address tempip = extlsa->GetLinkStateId ();
- tempip = tempip.CombineMask (tempmask);
-
-//
-// Here's why we did all of that work. We're going to add a host route to the
-// host address found in the m_linkData field of the point-to-point link
-// record. In the case of a point-to-point link, this is the local IP address
-// of the node connected to the link. Each of these point-to-point links
-// will correspond to a local interface that has an IP address to which
-// the node at the root of the SPF tree can send packets. The vertex <v>
-// (corresponding to the node that has these links and interfaces) has
-// an m_nextHop address precalculated for us that is the address to which the
-// root node should send packets to be forwarded to these IP addresses.
-// Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
-// which the packets should be send for forwarding.
-//
- Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
- if (router == 0)
- {
- continue;
- }
- Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
- NS_ASSERT (gr);
- // walk through all next-hop-IPs and out-going-interfaces for reaching
- // the stub network gateway 'v' from the root node
- for (uint32_t i = 0; i < v->GetNRootExitDirections (); i++)
- {
- SPFVertex::NodeExit_t exit = v->GetRootExitDirection (i);
- Ipv4Address nextHop = exit.first;
- int32_t outIf = exit.second;
- if (outIf >= 0)
- {
- gr->AddASExternalRouteTo (tempip, tempmask, nextHop, outIf);
- NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
- " add external network route to " << tempip <<
- " using next hop " << nextHop <<
- " via interface " << outIf);
- }
- else
- {
- NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
- " NOT able to add network route to " << tempip <<
- " using next hop " << nextHop <<
- " since outgoing interface id is negative");
- }
- }
- return;
- } // if
- } // for
-}
-
-
-// Processing logic from RFC 2328, page 166 and quagga ospf_spf_process_stubs ()
-// stub link records will exist for point-to-point interfaces and for
-// broadcast interfaces for which no neighboring router can be found
-void
-GlobalRouteManagerImpl::SPFProcessStubs (SPFVertex* v)
-{
- NS_LOG_FUNCTION_NOARGS ();
- NS_LOG_LOGIC ("Processing stubs for " << v->GetVertexId ());
- if (v->GetVertexType () == SPFVertex::VertexRouter)
- {
- GlobalRoutingLSA *rlsa = v->GetLSA ();
- NS_LOG_LOGIC ("Processing router LSA with id " << rlsa->GetLinkStateId ());
- for (uint32_t i = 0; i < rlsa->GetNLinkRecords (); i++)
- {
- NS_LOG_LOGIC ("Examining link " << i << " of " <<
- v->GetVertexId () << "'s " <<
- v->GetLSA ()->GetNLinkRecords () << " link records");
- GlobalRoutingLinkRecord *l = v->GetLSA ()->GetLinkRecord (i);
- if (l->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork)
- {
- NS_LOG_LOGIC ("Found a Stub record to " << l->GetLinkId ());
- SPFIntraAddStub (l, v);
- continue;
- }
- }
- }
- for (uint32_t i = 0; i < v->GetNChildren (); i++)
- {
- if (!v->GetChild (i)->IsVertexProcessed ())
- {
- SPFProcessStubs (v->GetChild (i));
- v->GetChild (i)->SetVertexProcessed (true);
- }
- }
-}
-
-// RFC2328 16.1. second stage.
-void
-GlobalRouteManagerImpl::SPFIntraAddStub (GlobalRoutingLinkRecord *l, SPFVertex* v)
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- NS_ASSERT_MSG (m_spfroot,
- "GlobalRouteManagerImpl::SPFIntraAddStub (): Root pointer not set");
-
- // XXX simplifed logic for the moment. There are two cases to consider:
- // 1) the stub network is on this router; do nothing for now
- // (already handled above)
- // 2) the stub network is on a remote router, so I should use the
- // same next hop that I use to get to vertex v
- if (v->GetVertexId () == m_spfroot->GetVertexId ())
- {
- NS_LOG_LOGIC ("Stub is on local host: " << v->GetVertexId () << "; returning");
- return;
- }
- NS_LOG_LOGIC ("Stub is on remote host: " << v->GetVertexId () << "; installing");
-//
-// The root of the Shortest Path First tree is the router to which we are
-// going to write the actual routing table entries. The vertex corresponding
-// to this router has a vertex ID which is the router ID of that node. We're
-// going to use this ID to discover which node it is that we're actually going
-// to update.
-//
- Ipv4Address routerId = m_spfroot->GetVertexId ();
-
- NS_LOG_LOGIC ("Vertex ID = " << routerId);
-//
-// We need to walk the list of nodes looking for the one that has the router
-// ID corresponding to the root vertex. This is the one we're going to write
-// the routing information to.
-//
- NodeList::Iterator i = NodeList::Begin ();
- NodeList::Iterator listEnd = NodeList::End ();
- for (; i != listEnd; i++)
- {
- Ptr<Node> node = *i;
-//
-// The router ID is accessible through the GlobalRouter interface, so we need
-// to QI for that interface. If there's no GlobalRouter interface, the node
-// in question cannot be the router we want, so we continue.
-//
- Ptr<GlobalRouter> rtr =
- node->GetObject<GlobalRouter> ();
-
- if (rtr == 0)
- {
- NS_LOG_LOGIC ("No GlobalRouter interface on node " <<
- node->GetId ());
- continue;
- }
-//
-// If the router ID of the current node is equal to the router ID of the
-// root of the SPF tree, then this node is the one for which we need to
-// write the routing tables.
-//
- NS_LOG_LOGIC ("Considering router " << rtr->GetRouterId ());
-
- if (rtr->GetRouterId () == routerId)
- {
- NS_LOG_LOGIC ("Setting routes for node " << node->GetId ());
-//
-// Routing information is updated using the Ipv4 interface. We need to QI
-// for that interface. If the node is acting as an IP version 4 router, it
-// should absolutely have an Ipv4 interface.
-//
- Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
- NS_ASSERT_MSG (ipv4,
- "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
- "QI for <Ipv4> interface failed");
-//
-// Get the Global Router Link State Advertisement from the vertex we're
-// adding the routes to. The LSA will have a number of attached Global Router
-// Link Records corresponding to links off of that vertex / node. We're going
-// to be interested in the records corresponding to point-to-point links.
-//
- NS_ASSERT_MSG (v->GetLSA (),
- "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
- "Expected valid LSA in SPFVertex* v");
- Ipv4Mask tempmask (l->GetLinkData ().Get ());
- Ipv4Address tempip = l->GetLinkId ();
- tempip = tempip.CombineMask (tempmask);
-//
-// Here's why we did all of that work. We're going to add a host route to the
-// host address found in the m_linkData field of the point-to-point link
-// record. In the case of a point-to-point link, this is the local IP address
-// of the node connected to the link. Each of these point-to-point links
-// will correspond to a local interface that has an IP address to which
-// the node at the root of the SPF tree can send packets. The vertex <v>
-// (corresponding to the node that has these links and interfaces) has
-// an m_nextHop address precalculated for us that is the address to which the
-// root node should send packets to be forwarded to these IP addresses.
-// Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
-// which the packets should be send for forwarding.
-//
-
- Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
- if (router == 0)
- {
- continue;
- }
- Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
- NS_ASSERT (gr);
- // walk through all next-hop-IPs and out-going-interfaces for reaching
- // the stub network gateway 'v' from the root node
- for (uint32_t i = 0; i < v->GetNRootExitDirections (); i++)
- {
- SPFVertex::NodeExit_t exit = v->GetRootExitDirection (i);
- Ipv4Address nextHop = exit.first;
- int32_t outIf = exit.second;
- if (outIf >= 0)
- {
- gr->AddNetworkRouteTo (tempip, tempmask, nextHop, outIf);
- NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
- " add network route to " << tempip <<
- " using next hop " << nextHop <<
- " via interface " << outIf);
- }
- else
- {
- NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
- " NOT able to add network route to " << tempip <<
- " using next hop " << nextHop <<
- " since outgoing interface id is negative");
- }
- }
- return;
- } // if
- } // for
-}
-
-//
-// Return the interface number corresponding to a given IP address and mask
-// This is a wrapper around GetInterfaceForPrefix(), but we first
-// have to find the right node pointer to pass to that function.
-// If no such interface is found, return -1 (note: unit test framework
-// for routing assumes -1 to be a legal return value)
-//
-int32_t
-GlobalRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a, Ipv4Mask amask)
-{
- NS_LOG_FUNCTION (a << amask);
-//
-// We have an IP address <a> and a vertex ID of the root of the SPF tree.
-// The question is what interface index does this address correspond to.
-// The answer is a little complicated since we have to find a pointer to
-// the node corresponding to the vertex ID, find the Ipv4 interface on that
-// node in order to iterate the interfaces and find the one corresponding to
-// the address in question.
-//
- Ipv4Address routerId = m_spfroot->GetVertexId ();
-//
-// Walk the list of nodes in the system looking for the one corresponding to
-// the node at the root of the SPF tree. This is the node for which we are
-// building the routing table.
-//
- NodeList::Iterator i = NodeList::Begin ();
- NodeList::Iterator listEnd = NodeList::End ();
- for (; i != listEnd; i++)
- {
- Ptr<Node> node = *i;
-
- Ptr<GlobalRouter> rtr =
- node->GetObject<GlobalRouter> ();
-//
-// If the node doesn't have a GlobalRouter interface it can't be the one
-// we're interested in.
-//
- if (rtr == 0)
- {
- continue;
- }
-
- if (rtr->GetRouterId () == routerId)
- {
-//
-// This is the node we're building the routing table for. We're going to need
-// the Ipv4 interface to look for the ipv4 interface index. Since this node
-// is participating in routing IP version 4 packets, it certainly must have
-// an Ipv4 interface.
-//
- Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
- NS_ASSERT_MSG (ipv4,
- "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): "
- "GetObject for <Ipv4> interface failed");
-//
-// Look through the interfaces on this node for one that has the IP address
-// we're looking for. If we find one, return the corresponding interface
-// index, or -1 if not found.
-//
- int32_t interface = ipv4->GetInterfaceForPrefix (a, amask);
-
-#if 0
- if (interface < 0)
- {
- NS_FATAL_ERROR ("GlobalRouteManagerImpl::FindOutgoingInterfaceId(): "
- "Expected an interface associated with address a:" << a);
- }
-#endif
- return interface;
- }
- }
-//
-// Couldn't find it.
-//
- NS_LOG_LOGIC ("FindOutgoingInterfaceId():Can't find root node " << routerId);
- return -1;
-}
-
-//
-// This method is derived from quagga ospf_intra_add_router ()
-//
-// This is where we are actually going to add the host routes to the routing
-// tables of the individual nodes.
-//
-// The vertex passed as a parameter has just been added to the SPF tree.
-// This vertex must have a valid m_root_oid, corresponding to the outgoing
-// interface on the root router of the tree that is the first hop on the path
-// to the vertex. The vertex must also have a next hop address, corresponding
-// to the next hop on the path to the vertex. The vertex has an m_lsa field
-// that has some number of link records. For each point to point link record,
-// the m_linkData is the local IP address of the link. This corresponds to
-// a destination IP address, reachable from the root, to which we add a host
-// route.
-//
- void
-GlobalRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v)
-{
- NS_LOG_FUNCTION (v);
-
- NS_ASSERT_MSG (m_spfroot,
- "GlobalRouteManagerImpl::SPFIntraAddRouter (): Root pointer not set");
-//
-// The root of the Shortest Path First tree is the router to which we are
-// going to write the actual routing table entries. The vertex corresponding
-// to this router has a vertex ID which is the router ID of that node. We're
-// going to use this ID to discover which node it is that we're actually going
-// to update.
-//
- Ipv4Address routerId = m_spfroot->GetVertexId ();
-
- NS_LOG_LOGIC ("Vertex ID = " << routerId);
-//
-// We need to walk the list of nodes looking for the one that has the router
-// ID corresponding to the root vertex. This is the one we're going to write
-// the routing information to.
-//
- NodeList::Iterator i = NodeList::Begin ();
- NodeList::Iterator listEnd = NodeList::End ();
- for (; i != listEnd; i++)
- {
- Ptr<Node> node = *i;
-//
-// The router ID is accessible through the GlobalRouter interface, so we need
-// to GetObject for that interface. If there's no GlobalRouter interface,
-// the node in question cannot be the router we want, so we continue.
-//
- Ptr<GlobalRouter> rtr =
- node->GetObject<GlobalRouter> ();
-
- if (rtr == 0)
- {
- NS_LOG_LOGIC ("No GlobalRouter interface on node " <<
- node->GetId ());
- continue;
- }
-//
-// If the router ID of the current node is equal to the router ID of the
-// root of the SPF tree, then this node is the one for which we need to
-// write the routing tables.
-//
- NS_LOG_LOGIC ("Considering router " << rtr->GetRouterId ());
-
- if (rtr->GetRouterId () == routerId)
- {
- NS_LOG_LOGIC ("Setting routes for node " << node->GetId ());
-//
-// Routing information is updated using the Ipv4 interface. We need to
-// GetObject for that interface. If the node is acting as an IP version 4
-// router, it should absolutely have an Ipv4 interface.
-//
- Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
- NS_ASSERT_MSG (ipv4,
- "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
- "GetObject for <Ipv4> interface failed");
-//
-// Get the Global Router Link State Advertisement from the vertex we're
-// adding the routes to. The LSA will have a number of attached Global Router
-// Link Records corresponding to links off of that vertex / node. We're going
-// to be interested in the records corresponding to point-to-point links.
-//
- GlobalRoutingLSA *lsa = v->GetLSA ();
- NS_ASSERT_MSG (lsa,
- "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
- "Expected valid LSA in SPFVertex* v");
-
- uint32_t nLinkRecords = lsa->GetNLinkRecords ();
-//
-// Iterate through the link records on the vertex to which we're going to add
-// routes. To make sure we're being clear, we're going to add routing table
-// entries to the tables on the node corresping to the root of the SPF tree.
-// These entries will have routes to the IP addresses we find from looking at
-// the local side of the point-to-point links found on the node described by
-// the vertex <v>.
-//
- NS_LOG_LOGIC (" Node " << node->GetId () <<
- " found " << nLinkRecords << " link records in LSA " << lsa << "with LinkStateId "<< lsa->GetLinkStateId ());
- for (uint32_t j = 0; j < nLinkRecords; ++j)
- {
-//
-// We are only concerned about point-to-point links
-//
- GlobalRoutingLinkRecord *lr = lsa->GetLinkRecord (j);
- if (lr->GetLinkType () != GlobalRoutingLinkRecord::PointToPoint)
- {
- continue;
- }
-//
-// Here's why we did all of that work. We're going to add a host route to the
-// host address found in the m_linkData field of the point-to-point link
-// record. In the case of a point-to-point link, this is the local IP address
-// of the node connected to the link. Each of these point-to-point links
-// will correspond to a local interface that has an IP address to which
-// the node at the root of the SPF tree can send packets. The vertex <v>
-// (corresponding to the node that has these links and interfaces) has
-// an m_nextHop address precalculated for us that is the address to which the
-// root node should send packets to be forwarded to these IP addresses.
-// Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
-// which the packets should be send for forwarding.
-//
- Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
- if (router == 0)
- {
- continue;
- }
- Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
- NS_ASSERT (gr);
- // walk through all available exit directions due to ECMP,
- // and add host route for each of the exit direction toward
- // the vertex 'v'
- for (uint32_t i = 0; i < v->GetNRootExitDirections (); i++)
- {
- SPFVertex::NodeExit_t exit = v->GetRootExitDirection (i);
- Ipv4Address nextHop = exit.first;
- int32_t outIf = exit.second;
- if (outIf >= 0)
- {
- gr->AddHostRouteTo (lr->GetLinkData (), nextHop,
- outIf);
- NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
- " adding host route to " << lr->GetLinkData () <<
- " using next hop " << nextHop <<
- " and outgoing interface " << outIf);
- }
- else
- {
- NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
- " NOT able to add host route to " << lr->GetLinkData () <<
- " using next hop " << nextHop <<
- " since outgoing interface id is negative " << outIf);
- }
- } // for all routes from the root the vertex 'v'
- }
-//
-// Done adding the routes for the selected node.
-//
- return;
- }
- }
-}
- void
-GlobalRouteManagerImpl::SPFIntraAddTransit (SPFVertex* v)
-{
- NS_LOG_FUNCTION (v);
-
- NS_ASSERT_MSG (m_spfroot,
- "GlobalRouteManagerImpl::SPFIntraAddTransit (): Root pointer not set");
-//
-// The root of the Shortest Path First tree is the router to which we are
-// going to write the actual routing table entries. The vertex corresponding
-// to this router has a vertex ID which is the router ID of that node. We're
-// going to use this ID to discover which node it is that we're actually going
-// to update.
-//
- Ipv4Address routerId = m_spfroot->GetVertexId ();
-
- NS_LOG_LOGIC ("Vertex ID = " << routerId);
-//
-// We need to walk the list of nodes looking for the one that has the router
-// ID corresponding to the root vertex. This is the one we're going to write
-// the routing information to.
-//
- NodeList::Iterator i = NodeList::Begin ();
- NodeList::Iterator listEnd = NodeList::End ();
- for (; i != listEnd; i++)
- {
- Ptr<Node> node = *i;
-//
-// The router ID is accessible through the GlobalRouter interface, so we need
-// to GetObject for that interface. If there's no GlobalRouter interface,
-// the node in question cannot be the router we want, so we continue.
-//
- Ptr<GlobalRouter> rtr =
- node->GetObject<GlobalRouter> ();
-
- if (rtr == 0)
- {
- NS_LOG_LOGIC ("No GlobalRouter interface on node " <<
- node->GetId ());
- continue;
- }
-//
-// If the router ID of the current node is equal to the router ID of the
-// root of the SPF tree, then this node is the one for which we need to
-// write the routing tables.
-//
- NS_LOG_LOGIC ("Considering router " << rtr->GetRouterId ());
-
- if (rtr->GetRouterId () == routerId)
- {
- NS_LOG_LOGIC ("setting routes for node " << node->GetId ());
-//
-// Routing information is updated using the Ipv4 interface. We need to
-// GetObject for that interface. If the node is acting as an IP version 4
-// router, it should absolutely have an Ipv4 interface.
-//
- Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
- NS_ASSERT_MSG (ipv4,
- "GlobalRouteManagerImpl::SPFIntraAddTransit (): "
- "GetObject for <Ipv4> interface failed");
-//
-// Get the Global Router Link State Advertisement from the vertex we're
-// adding the routes to. The LSA will have a number of attached Global Router
-// Link Records corresponding to links off of that vertex / node. We're going
-// to be interested in the records corresponding to point-to-point links.
-//
- GlobalRoutingLSA *lsa = v->GetLSA ();
- NS_ASSERT_MSG (lsa,
- "GlobalRouteManagerImpl::SPFIntraAddTransit (): "
- "Expected valid LSA in SPFVertex* v");
- Ipv4Mask tempmask = lsa->GetNetworkLSANetworkMask ();
- Ipv4Address tempip = lsa->GetLinkStateId ();
- tempip = tempip.CombineMask (tempmask);
- Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
- if (router == 0)
- {
- continue;
- }
- Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
- NS_ASSERT (gr);
- // walk through all available exit directions due to ECMP,
- // and add host route for each of the exit direction toward
- // the vertex 'v'
- for (uint32_t i = 0; i < v->GetNRootExitDirections (); i++)
- {
- SPFVertex::NodeExit_t exit = v->GetRootExitDirection (i);
- Ipv4Address nextHop = exit.first;
- int32_t outIf = exit.second;
-
- if (outIf >= 0)
- {
- gr->AddNetworkRouteTo (tempip, tempmask, nextHop, outIf);
- NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
- " add network route to " << tempip <<
- " using next hop " << nextHop <<
- " via interface " << outIf);
- }
- else
- {
- NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
- " NOT able to add network route to " << tempip <<
- " using next hop " << nextHop <<
- " since outgoing interface id is negative " << outIf);
- }
- }
- }
- }
-}
-
-// Derived from quagga ospf_vertex_add_parents ()
-//
-// This is a somewhat oddly named method (blame quagga). Although you might
-// expect it to add a parent *to* something, it actually adds a vertex
-// to the list of children *in* each of its parents.
-//
-// Given a pointer to a vertex, it links back to the vertex's parent that it
-// already has set and adds itself to that vertex's list of children.
-//
- void
-GlobalRouteManagerImpl::SPFVertexAddParent (SPFVertex* v)
-{
- NS_LOG_FUNCTION (v);
-
- for (uint32_t i=0;;)
- {
- SPFVertex* parent;
- // check if all parents of vertex v
- if ((parent = v->GetParent (i++)) == 0) break;
- parent->AddChild (v);
- }
-}
-
-} // namespace ns3
-
-
-#include "ns3/test.h"
-#include "ns3/simulator.h"
-#include <stdlib.h> // for rand()
-
-namespace ns3 {
-
-class GlobalRouteManagerImplTestCase : public TestCase
-{
-public:
- GlobalRouteManagerImplTestCase();
- virtual bool DoRun(void);
-};
-
-GlobalRouteManagerImplTestCase::GlobalRouteManagerImplTestCase()
- : TestCase("GlobalRouteManagerImplTestCase")
-{}
-bool
-GlobalRouteManagerImplTestCase::DoRun(void)
-{
- CandidateQueue candidate;
-
- for (int i = 0; i < 100; ++i)
- {
- SPFVertex *v = new SPFVertex;
- v->SetDistanceFromRoot (rand () % 100);
- candidate.Push (v);
- }
-
- uint32_t lastDistance = 0;
-
- for (int i = 0; i < 100; ++i)
- {
- SPFVertex *v = candidate.Pop ();
- if (v->GetDistanceFromRoot () < lastDistance)
- {
- // XXX does nothing.
- UpdateErrorStatus (false);
- }
- lastDistance = v->GetDistanceFromRoot ();
- delete v;
- v = 0;
- }
-
- // Build fake link state database; four routers (0-3), 3 point-to-point
- // links
- //
- // n0
- // \ link 0
- // \ link 2
- // n2 -------------------------n3
- // /
- // / link 1
- // n1
- //
- // link0: 10.1.1.1/30, 10.1.1.2/30
- // link1: 10.1.2.1/30, 10.1.2.2/30
- // link2: 10.1.3.1/30, 10.1.3.2/30
- //
- // Router 0
- GlobalRoutingLinkRecord* lr0 = new GlobalRoutingLinkRecord (
- GlobalRoutingLinkRecord::PointToPoint,
- "0.0.0.2", // router ID 0.0.0.2
- "10.1.1.1", // local ID
- 1); // metric
-
- GlobalRoutingLinkRecord* lr1 = new GlobalRoutingLinkRecord (
- GlobalRoutingLinkRecord::StubNetwork,
- "10.1.1.1",
- "255.255.255.252",
- 1);
-
- GlobalRoutingLSA* lsa0 = new GlobalRoutingLSA ();
- lsa0->SetLSType (GlobalRoutingLSA::RouterLSA);
- lsa0->SetLinkStateId ("0.0.0.0");
- lsa0->SetAdvertisingRouter ("0.0.0.0");
- lsa0->AddLinkRecord (lr0);
- lsa0->AddLinkRecord (lr1);
-
- // Router 1
- GlobalRoutingLinkRecord* lr2 = new GlobalRoutingLinkRecord (
- GlobalRoutingLinkRecord::PointToPoint,
- "0.0.0.2",
- "10.1.2.1",
- 1);
-
- GlobalRoutingLinkRecord* lr3 = new GlobalRoutingLinkRecord (
- GlobalRoutingLinkRecord::StubNetwork,
- "10.1.2.1",
- "255.255.255.252",
- 1);
-
- GlobalRoutingLSA* lsa1 = new GlobalRoutingLSA ();
- lsa1->SetLSType (GlobalRoutingLSA::RouterLSA);
- lsa1->SetLinkStateId ("0.0.0.1");
- lsa1->SetAdvertisingRouter ("0.0.0.1");
- lsa1->AddLinkRecord (lr2);
- lsa1->AddLinkRecord (lr3);
-
- // Router 2
- GlobalRoutingLinkRecord* lr4 = new GlobalRoutingLinkRecord (
- GlobalRoutingLinkRecord::PointToPoint,
- "0.0.0.0",
- "10.1.1.2",
- 1);
-
- GlobalRoutingLinkRecord* lr5 = new GlobalRoutingLinkRecord (
- GlobalRoutingLinkRecord::StubNetwork,
- "10.1.1.2",
- "255.255.255.252",
- 1);
-
- GlobalRoutingLinkRecord* lr6 = new GlobalRoutingLinkRecord (
- GlobalRoutingLinkRecord::PointToPoint,
- "0.0.0.1",
- "10.1.2.2",
- 1);
-
- GlobalRoutingLinkRecord* lr7 = new GlobalRoutingLinkRecord (
- GlobalRoutingLinkRecord::StubNetwork,
- "10.1.2.2",
- "255.255.255.252",
- 1);
-
- GlobalRoutingLinkRecord* lr8 = new GlobalRoutingLinkRecord (
- GlobalRoutingLinkRecord::PointToPoint,
- "0.0.0.3",
- "10.1.3.2",
- 1);
-
- GlobalRoutingLinkRecord* lr9 = new GlobalRoutingLinkRecord (
- GlobalRoutingLinkRecord::StubNetwork,
- "10.1.3.2",
- "255.255.255.252",
- 1);
-
- GlobalRoutingLSA* lsa2 = new GlobalRoutingLSA ();
- lsa2->SetLSType (GlobalRoutingLSA::RouterLSA);
- lsa2->SetLinkStateId ("0.0.0.2");
- lsa2->SetAdvertisingRouter ("0.0.0.2");
- lsa2->AddLinkRecord (lr4);
- lsa2->AddLinkRecord (lr5);
- lsa2->AddLinkRecord (lr6);
- lsa2->AddLinkRecord (lr7);
- lsa2->AddLinkRecord (lr8);
- lsa2->AddLinkRecord (lr9);
-
- // Router 3
- GlobalRoutingLinkRecord* lr10 = new GlobalRoutingLinkRecord (
- GlobalRoutingLinkRecord::PointToPoint,
- "0.0.0.2",
- "10.1.2.1",
- 1);
-
- GlobalRoutingLinkRecord* lr11 = new GlobalRoutingLinkRecord (
- GlobalRoutingLinkRecord::StubNetwork,
- "10.1.2.1",
- "255.255.255.252",
- 1);
-
- GlobalRoutingLSA* lsa3 = new GlobalRoutingLSA ();
- lsa3->SetLSType (GlobalRoutingLSA::RouterLSA);
- lsa3->SetLinkStateId ("0.0.0.3");
- lsa3->SetAdvertisingRouter ("0.0.0.3");
- lsa3->AddLinkRecord (lr10);
- lsa3->AddLinkRecord (lr11);
-
- // Test the database
- GlobalRouteManagerLSDB* srmlsdb = new GlobalRouteManagerLSDB ();
- srmlsdb->Insert (lsa0->GetLinkStateId (), lsa0);
- srmlsdb->Insert (lsa1->GetLinkStateId (), lsa1);
- srmlsdb->Insert (lsa2->GetLinkStateId (), lsa2);
- srmlsdb->Insert (lsa3->GetLinkStateId (), lsa3);
- NS_ASSERT (lsa2 == srmlsdb->GetLSA (lsa2->GetLinkStateId ()));
-
- // next, calculate routes based on the manually created LSDB
- GlobalRouteManagerImpl* srm = new GlobalRouteManagerImpl ();
- srm->DebugUseLsdb (srmlsdb); // manually add in an LSDB
- // Note-- this will succeed without any nodes in the topology
- // because the NodeList is empty
- srm->DebugSPFCalculate (lsa0->GetLinkStateId ()); // node n0
-
- Simulator::Run ();
-
-// XXX here we should do some verification of the routes built
-
- Simulator::Destroy ();
-
- // This delete clears the srm, which deletes the LSDB, which clears
- // all of the LSAs, which each destroys the attached LinkRecords.
- delete srm;
-
- // XXX
- // No testing has actually been done other than making sure that this code
- // does not crash
- return GetErrorStatus ();
-}
-
-
-static class GlobalRouteManagerImplTestSuite : public TestSuite
-{
-public:
- GlobalRouteManagerImplTestSuite()
- : TestSuite("global-route-manager-impl", UNIT)
- {
- AddTestCase(new GlobalRouteManagerImplTestCase());
- }
-} g_globalRoutingManagerImplTestSuite;
-
-} // namespace ns3
--- a/src/routing/global-routing/global-route-manager-impl.h Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,781 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright 2007 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors: Craig Dowell (craigdo@ee.washington.edu)
- * Tom Henderson (tomhend@u.washington.edu)
- */
-
-#ifndef GLOBAL_ROUTE_MANAGER_IMPL_H
-#define GLOBAL_ROUTE_MANAGER_IMPL_H
-
-#include <stdint.h>
-#include <list>
-#include <queue>
-#include <map>
-#include <vector>
-#include "ns3/object.h"
-#include "ns3/ptr.h"
-#include "ns3/ipv4-address.h"
-#include "global-router-interface.h"
-
-namespace ns3 {
-
-const uint32_t SPF_INFINITY = 0xffffffff;
-
-class CandidateQueue;
-class Ipv4GlobalRouting;
-
-/**
- * @brief Vertex used in shortest path first (SPF) computations. See RFC 2328,
- * Section 16.
- *
- * Each router in the simulation is associated with an SPFVertex object. When
- * calculating routes, each of these routers is, in turn, chosen as the "root"
- * of the calculation and routes to all of the other routers are eventually
- * saved in the routing tables of each of the chosen nodes. Each of these
- * routers in the calculation has an associated SPFVertex.
- *
- * The "Root" vertex is the SPFVertex representing the router that is having
- * its routing tables set. The SPFVertex objects representing other routers
- * or networks in the simulation are arranged in the SPF tree. It is this
- * tree that represents the Shortest Paths to the other networks.
- *
- * Each SPFVertex has a pointer to the Global Router Link State Advertisement
- * (LSA) that its underlying router has exported. Within these LSAs are
- * Global Router Link Records that describe the point to point links from the
- * underlying router to other nodes (represented by other SPFVertex objects)
- * in the simulation topology. The combination of the arrangement of the
- * SPFVertex objects in the SPF tree, along with the details of the link
- * records that connect them provide the information required to construct the
- * required routes.
- */
-class SPFVertex
-{
-public:
-/**
- * @brief Enumeration of the possible types of SPFVertex objects.
- * @internal
- *
- * Currently we use VertexRouter to identify objects that represent a router
- * in the simulation topology, and VertexNetwork to identify objects that
- * represent a network.
- */
- enum VertexType {
- VertexUnknown = 0, /**< Uninitialized Link Record */
- VertexRouter, /**< Vertex representing a router in the topology */
- VertexNetwork /**< Vertex representing a network in the topology */
- };
-
-/**
- * @brief Construct an empty ("uninitialized") SPFVertex (Shortest Path First
- * Vertex).
- * @internal
- *
- * The Vertex Type is set to VertexUnknown, the Vertex ID is set to
- * 255.255.255.255, and the distance from root is set to infinity
- * (UINT32_MAX). The referenced Link State Advertisement (LSA) is set to
- * null as is the parent SPFVertex. The outgoing interface index is set to
- * infinity, the next hop address is set to 0.0.0.0 and the list of children
- * of the SPFVertex is initialized to empty.
- *
- * @see VertexType
- */
- SPFVertex();
-
-/**
- * @brief Construct an initialized SPFVertex (Shortest Path First Vertex).
- * @internal
- *
- * The Vertex Type is initialized to VertexRouter and the Vertex ID is found
- * from the Link State ID of the Link State Advertisement (LSA) passed as a
- * parameter. The Link State ID is set to the Router ID of the advertising
- * router. The referenced LSA (m_lsa) is set to the given LSA. Other than
- * these members, initialization is as in the default constructor.
- * of the SPFVertex is initialized to empty.
- *
- * @see SPFVertex::SPFVertex ()
- * @see VertexType
- * @see GlobalRoutingLSA
- * @param lsa The Link State Advertisement used for finding initial values.
- */
- SPFVertex(GlobalRoutingLSA* lsa);
-
-/**
- * @brief Destroy an SPFVertex (Shortest Path First Vertex).
- * @internal
- *
- * The children vertices of the SPFVertex are recursively deleted.
- *
- * @see SPFVertex::SPFVertex ()
- */
- ~SPFVertex();
-
-/**
- * @brief Get the Vertex Type field of a SPFVertex object.
- * @internal
- *
- * The Vertex Type describes the kind of simulation object a given SPFVertex
- * represents.
- *
- * @see VertexType
- * @returns The VertexType of the current SPFVertex object.
- */
- VertexType GetVertexType (void) const;
-
-/**
- * @brief Set the Vertex Type field of a SPFVertex object.
- * @internal
- *
- * The Vertex Type describes the kind of simulation object a given SPFVertex
- * represents.
- *
- * @see VertexType
- * @param type The new VertexType for the current SPFVertex object.
- */
- void SetVertexType (VertexType type);
-
-/**
- * @brief Get the Vertex ID field of a SPFVertex object.
- * @internal
- *
- * The Vertex ID uniquely identifies the simulation object a given SPFVertex
- * represents. Typically, this is the Router ID for SPFVertex objects
- * representing routers, and comes from the Link State Advertisement of a
- * router aggregated to a node in the simulation. These IDs are allocated
- * automatically by the routing environment and look like IP addresses
- * beginning at 0.0.0.0 and monotonically increasing as new routers are
- * instantiated.
- *
- * @returns The Ipv4Address Vertex ID of the current SPFVertex object.
- */
- Ipv4Address GetVertexId (void) const;
-
-/**
- * @brief Set the Vertex ID field of a SPFVertex object.
- * @internal
- *
- * The Vertex ID uniquely identifies the simulation object a given SPFVertex
- * represents. Typically, this is the Router ID for SPFVertex objects
- * representing routers, and comes from the Link State Advertisement of a
- * router aggregated to a node in the simulation. These IDs are allocated
- * automatically by the routing environment and look like IP addresses
- * beginning at 0.0.0.0 and monotonically increase as new routers are
- * instantiated. This method is an explicit override of the automatically
- * generated value.
- *
- * @param id The new Ipv4Address Vertex ID for the current SPFVertex object.
- */
- void SetVertexId (Ipv4Address id);
-
-/**
- * @brief Get the Global Router Link State Advertisement returned by the
- * Global Router represented by this SPFVertex during the route discovery
- * process.
- * @internal
- *
- * @see GlobalRouter
- * @see GlobalRoutingLSA
- * @see GlobalRouter::DiscoverLSAs ()
- * @returns A pointer to the GlobalRoutingLSA found by the router represented
- * by this SPFVertex object.
- */
- GlobalRoutingLSA* GetLSA (void) const;
-
-/**
- * @brief Set the Global Router Link State Advertisement returned by the
- * Global Router represented by this SPFVertex during the route discovery
- * process.
- * @internal
- *
- * @see SPFVertex::GetLSA ()
- * @see GlobalRouter
- * @see GlobalRoutingLSA
- * @see GlobalRouter::DiscoverLSAs ()
- * @warning Ownership of the LSA is transferred to the "this" SPFVertex. You
- * must not delete the LSA after calling this method.
- * @param lsa A pointer to the GlobalRoutingLSA.
- */
- void SetLSA (GlobalRoutingLSA* lsa);
-
-/**
- * @brief Get the distance from the root vertex to "this" SPFVertex object.
- * @internal
- *
- * Each router in the simulation is associated with an SPFVertex object. When
- * calculating routes, each of these routers is, in turn, chosen as the "root"
- * of the calculation and routes to all of the other routers are eventually
- * saved in the routing tables of each of the chosen nodes. Each of these
- * routers in the calculation has an associated SPFVertex.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set. The "this" SPFVertex is the vertex to which
- * a route is being calculated from the root. The distance from the root that
- * we're asking for is the number of hops from the root vertex to the vertex
- * in question.
- *
- * The distance is calculated during route discovery and is stored in a
- * member variable. This method simply fetches that value.
- *
- * @returns The distance, in hops, from the root SPFVertex to "this" SPFVertex.
- */
- uint32_t GetDistanceFromRoot (void) const;
-
-/**
- * @brief Set the distance from the root vertex to "this" SPFVertex object.
- * @internal
- *
- * Each router in the simulation is associated with an SPFVertex object. When
- * calculating routes, each of these routers is, in turn, chosen as the "root"
- * of the calculation and routes to all of the other routers are eventually
- * saved in the routing tables of each of the chosen nodes. Each of these
- * routers in the calculation has an associated SPFVertex.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set. The "this" SPFVertex is the vertex to which
- * a route is being calculated from the root. The distance from the root that
- * we're asking for is the number of hops from the root vertex to the vertex
- * in question.
- *
- * @param distance The distance, in hops, from the root SPFVertex to "this"
- * SPFVertex.
- */
- void SetDistanceFromRoot (uint32_t distance);
-
-/**
- * @brief Set the IP address and outgoing interface index that should be used
- * to begin forwarding packets from the root SPFVertex to "this" SPFVertex.
- * @internal
- *
- * Each router node in the simulation is associated with an SPFVertex object.
- * When calculating routes, each of these routers is, in turn, chosen as the
- * "root" of the calculation and routes to all of the other routers are
- * eventually saved in the routing tables of each of the chosen nodes.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set. The "this" SPFVertex is the vertex that
- * represents the host or network to which a route is being calculated from
- * the root. The IP address that we're asking for is the address on the
- * remote side of a link off of the root node that should be used as the
- * destination for packets along the path to "this" vertex.
- *
- * When initializing the root SPFVertex, the IP address used when forwarding
- * packets is determined by examining the Global Router Link Records of the
- * Link State Advertisement generated by the root node's GlobalRouter. This
- * address is used to forward packets off of the root's network down those
- * links. As other vertices / nodes are discovered which are further away
- * from the root, they will be accessible down one of the paths via a link
- * described by one of these Global Router Link Records.
- *
- * To forward packets to these hosts or networks, the root node must begin
- * the forwarding process by sending the packets to a first hop router down
- * an interface. This means that the first hop address and interface ID must
- * be the same for all downstream SPFVertices. We call this "inheriting"
- * the interface and next hop.
- *
- * In this method we are telling the root node which exit direction it should send
- * should I send a packet to the network or host represented by 'this' SPFVertex.
- *
- * @see GlobalRouter
- * @see GlobalRoutingLSA
- * @see GlobalRoutingLinkRecord
- * @param nextHop The IP address to use when forwarding packets to the host
- * or network represented by "this" SPFVertex.
- * @param id The interface index to use when forwarding packets to the host or
- * network represented by "this" SPFVertex.
- */
- void SetRootExitDirection (Ipv4Address nextHop, int32_t id = SPF_INFINITY);
- typedef std::pair<Ipv4Address, int32_t> NodeExit_t;
-/**
- * @brief Set the IP address and outgoing interface index that should be used
- * to begin forwarding packets from the root SPFVertex to "this" SPFVertex.
- * @internal
- *
- * Each router node in the simulation is associated with an SPFVertex object.
- * When calculating routes, each of these routers is, in turn, chosen as the
- * "root" of the calculation and routes to all of the other routers are
- * eventually saved in the routing tables of each of the chosen nodes.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set. The "this" SPFVertex is the vertex that
- * represents the host or network to which a route is being calculated from
- * the root. The IP address that we're asking for is the address on the
- * remote side of a link off of the root node that should be used as the
- * destination for packets along the path to "this" vertex.
- *
- * When initializing the root SPFVertex, the IP address used when forwarding
- * packets is determined by examining the Global Router Link Records of the
- * Link State Advertisement generated by the root node's GlobalRouter. This
- * address is used to forward packets off of the root's network down those
- * links. As other vertices / nodes are discovered which are further away
- * from the root, they will be accessible down one of the paths via a link
- * described by one of these Global Router Link Records.
- *
- * To forward packets to these hosts or networks, the root node must begin
- * the forwarding process by sending the packets to a first hop router down
- * an interface. This means that the first hop address and interface ID must
- * be the same for all downstream SPFVertices. We call this "inheriting"
- * the interface and next hop.
- *
- * In this method we are telling the root node which exit direction it should send
- * should I send a packet to the network or host represented by 'this' SPFVertex.
- *
- * @see GlobalRouter
- * @see GlobalRoutingLSA
- * @see GlobalRoutingLinkRecord
- * @param nextHop The IP address to use when forwarding packets to the host
- * or network represented by "this" SPFVertex.
- * @param exit The pair of next-hop-IP and outgoing-interface-index to use when
- * forwarding packets to the host or network represented by "this" SPFVertex.
- */
- void SetRootExitDirection (SPFVertex::NodeExit_t exit);
- /**
- * \brief Obtain a pair indicating the exit direction from the root
- *
- * \param i An index to a pair
- * \return A pair of next-hop-IP and outgoing-interface-index for
- * indicating an exit direction from the root. It is 0 if the index 'i'
- * is out-of-range
- */
- NodeExit_t GetRootExitDirection (uint32_t i) const;
- /**
- * \brief Obtain a pair indicating the exit direction from the root
- *
- * This method assumes there is only a single exit direction from the root.
- * Error occur if this assumption is invalid.
- *
- * \return The pair of next-hop-IP and outgoing-interface-index for reaching
- * 'this' vertex from the root
- */
- NodeExit_t GetRootExitDirection () const;
- /**
- * \brief Merge into 'this' vertex the list of exit directions from
- * another vertex
- *
- * This merge is necessary when ECMP are found.
- *
- * \param vertex From which the list of exit directions are obtain
- * and are merged into 'this' vertex
- */
- void MergeRootExitDirections (const SPFVertex* vertex);
- /**
- * \brief Inherit all root exit directions from a given vertex to 'this' vertex
- * \param vertex The vertex from which all root exit directions are to be inherited
- *
- * After the call of this method, the original root exit directions
- * in 'this' vertex are all lost.
- */
- void InheritAllRootExitDirections (const SPFVertex* vertex);
- /**
- * \brief Get the number of exit directions from root for reaching 'this' vertex
- * \return The number of exit directions from root
- */
- uint32_t GetNRootExitDirections () const;
-
-/**
- * @brief Get a pointer to the SPFVector that is the parent of "this"
- * SPFVertex.
- * @internal
- *
- * Each router node in the simulation is associated with an SPFVertex object.
- * When calculating routes, each of these routers is, in turn, chosen as the
- * "root" of the calculation and routes to all of the other routers are
- * eventually saved in the routing tables of each of the chosen nodes.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set and is the root of the SPF tree.
- *
- * This method returns a pointer to the parent node of "this" SPFVertex
- * (both of which reside in that SPF tree).
- *
- * @param i The index to one of the parents
- * @returns A pointer to the SPFVertex that is the parent of "this" SPFVertex
- * in the SPF tree.
- */
- SPFVertex* GetParent (uint32_t i = 0) const;
-
-/**
- * @brief Set the pointer to the SPFVector that is the parent of "this"
- * SPFVertex.
- * @internal
- *
- * Each router node in the simulation is associated with an SPFVertex object.
- * When calculating routes, each of these routers is, in turn, chosen as the
- * "root" of the calculation and routes to all of the other routers are
- * eventually saved in the routing tables of each of the chosen nodes.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set and is the root of the SPF tree.
- *
- * This method sets the parent pointer of "this" SPFVertex (both of which
- * reside in that SPF tree).
- *
- * @param parent A pointer to the SPFVertex that is the parent of "this"
- * SPFVertex* in the SPF tree.
- */
- void SetParent (SPFVertex* parent);
- /**
- * \brief Merge the Parent list from the v into this vertex
- *
- * \param v The vertex from which its list of Parent is read
- * and then merged into the list of Parent of *this* vertex.
- * Note that the list in v remains intact
- */
- void MergeParent (const SPFVertex* v);
-
-/**
- * @brief Get the number of children of "this" SPFVertex.
- * @internal
- *
- * Each router node in the simulation is associated with an SPFVertex object.
- * When calculating routes, each of these routers is, in turn, chosen as the
- * "root" of the calculation and routes to all of the other routers are
- * eventually saved in the routing tables of each of the chosen nodes.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set and is the root of the SPF tree. Each vertex
- * in the SPF tree can have a number of children that represent host or
- * network routes available via that vertex.
- *
- * This method returns the number of children of "this" SPFVertex (which
- * reside in the SPF tree).
- *
- * @returns The number of children of "this" SPFVertex (which reside in the
- * SPF tree).
- */
- uint32_t GetNChildren (void) const;
-
-/**
- * @brief Get a borrowed SPFVertex pointer to the specified child of "this"
- * SPFVertex.
- * @internal
- *
- * Each router node in the simulation is associated with an SPFVertex object.
- * When calculating routes, each of these routers is, in turn, chosen as the
- * "root" of the calculation and routes to all of the other routers are
- * eventually saved in the routing tables of each of the chosen nodes.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set and is the root of the SPF tree. Each vertex
- * in the SPF tree can have a number of children that represent host or
- * network routes available via that vertex.
- *
- * This method the number of children of "this" SPFVertex (which reside in
- * the SPF tree.
- *
- * @see SPFVertex::GetNChildren
- * @param n The index (from 0 to the number of children minus 1) of the
- * child SPFVertex to return.
- * @warning The pointer returned by GetChild () is a borrowed pointer. You
- * do not have any ownership of the underlying object and must not delete
- * that object.
- * @returns A pointer to the specified child SPFVertex (which resides in the
- * SPF tree).
- */
- SPFVertex* GetChild (uint32_t n) const;
-
-/**
- * @brief Get a borrowed SPFVertex pointer to the specified child of "this"
- * SPFVertex.
- * @internal
- *
- * Each router node in the simulation is associated with an SPFVertex object.
- * When calculating routes, each of these routers is, in turn, chosen as the
- * "root" of the calculation and routes to all of the other routers are
- * eventually saved in the routing tables of each of the chosen nodes.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set and is the root of the SPF tree. Each vertex
- * in the SPF tree can have a number of children that represent host or
- * network routes available via that vertex.
- *
- * This method the number of children of "this" SPFVertex (which reside in
- * the SPF tree.
- *
- * @see SPFVertex::GetNChildren
- * @warning Ownership of the pointer added to the children of "this"
- * SPFVertex is transferred to the "this" SPFVertex. You must not delete the
- * (now) child SPFVertex after calling this method.
- * @param child A pointer to the SPFVertex (which resides in the SPF tree) to
- * be added to the list of children of "this" SPFVertex.
- * @returns The number of children of "this" SPFVertex after the addition of
- * the new child.
- */
- uint32_t AddChild (SPFVertex* child);
-
- /**
- * @brief Set the value of the VertexProcessed flag
- *
- * Flag to note whether vertex has been processed in stage two of
- * SPF computation
- * @param value boolean value to set the flag
- */
- void SetVertexProcessed (bool value);
-
- /**
- * @brief Check the value of the VertexProcessed flag
- *
- * Flag to note whether vertex has been processed in stage two of
- * SPF computation
- * @returns value of underlying flag
- */
- bool IsVertexProcessed (void) const;
-
- void ClearVertexProcessed (void);
-
-private:
- VertexType m_vertexType;
- Ipv4Address m_vertexId;
- GlobalRoutingLSA* m_lsa;
- uint32_t m_distanceFromRoot;
- int32_t m_rootOif;
- Ipv4Address m_nextHop;
- typedef std::list< NodeExit_t > ListOfNodeExit_t;
- /// store the multiple root's exits for supporting ECMP
- ListOfNodeExit_t m_ecmpRootExits;
- typedef std::list<SPFVertex*> ListOfSPFVertex_t;
- ListOfSPFVertex_t m_parents;
- ListOfSPFVertex_t m_children;
- bool m_vertexProcessed;
-
-/**
- * @brief The SPFVertex copy construction is disallowed. There's no need for
- * it and a compiler provided shallow copy would be wrong.
- */
- SPFVertex (SPFVertex& v);
-
-/**
- * @brief The SPFVertex copy assignment operator is disallowed. There's no
- * need for it and a compiler provided shallow copy would be wrong.
- */
- SPFVertex& operator= (SPFVertex& v);
-
- //friend std::ostream& operator<< (std::ostream& os, const ListOfIf_t& ifs);
- //friend std::ostream& operator<< (std::ostream& os, const ListOfAddr_t& addrs);
- friend std::ostream& operator<< (std::ostream& os, const SPFVertex::ListOfSPFVertex_t& vs);
-};
-
-/**
- * @brief The Link State DataBase (LSDB) of the Global Route Manager.
- *
- * Each node in the simulation participating in global routing has a
- * GlobalRouter interface. The primary job of this interface is to export
- * Global Router Link State Advertisements (LSAs). These advertisements in
- * turn contain a number of Global Router Link Records that describe the
- * point to point links from the underlying node to other nodes (that will
- * also export their own LSAs.
- *
- * This class implements a searchable database of LSAs gathered from every
- * router in the simulation.
- */
-class GlobalRouteManagerLSDB
-{
-public:
-/**
- * @brief Construct an empty Global Router Manager Link State Database.
- * @internal
- *
- * The database map composing the Link State Database is initialized in
- * this constructor.
- */
- GlobalRouteManagerLSDB ();
-
-/**
- * @brief Destroy an empty Global Router Manager Link State Database.
- * @internal
- *
- * The database map is walked and all of the Link State Advertisements stored
- * in the database are freed; then the database map itself is clear ()ed to
- * release any remaining resources.
- */
- ~GlobalRouteManagerLSDB ();
-
-/**
- * @brief Insert an IP address / Link State Advertisement pair into the Link
- * State Database.
- * @internal
- *
- * The IPV4 address and the GlobalRoutingLSA given as parameters are converted
- * to an STL pair and are inserted into the database map.
- *
- * @see GlobalRoutingLSA
- * @see Ipv4Address
- * @param addr The IP address associated with the LSA. Typically the Router
- * ID.
- * @param lsa A pointer to the Link State Advertisement for the router.
- */
- void Insert(Ipv4Address addr, GlobalRoutingLSA* lsa);
-
-/**
- * @brief Look up the Link State Advertisement associated with the given
- * link state ID (address).
- * @internal
- *
- * The database map is searched for the given IPV4 address and corresponding
- * GlobalRoutingLSA is returned.
- *
- * @see GlobalRoutingLSA
- * @see Ipv4Address
- * @param addr The IP address associated with the LSA. Typically the Router
- * ID.
- * @returns A pointer to the Link State Advertisement for the router specified
- * by the IP address addr.
- */
- GlobalRoutingLSA* GetLSA (Ipv4Address addr) const;
-/**
- * @brief Look up the Link State Advertisement associated with the given
- * link state ID (address). This is a variation of the GetLSA call
- * to allow the LSA to be found by matching addr with the LinkData field
- * of the TransitNetwork link record.
- * @internal
- *
- * @see GetLSA
- * @param addr The IP address associated with the LSA. Typically the Router
- * @returns A pointer to the Link State Advertisement for the router specified
- * by the IP address addr.
- * ID.
- */
- GlobalRoutingLSA* GetLSAByLinkData (Ipv4Address addr) const;
-
-/**
- * @brief Set all LSA flags to an initialized state, for SPF computation
- * @internal
- *
- * This function walks the database and resets the status flags of all of the
- * contained Link State Advertisements to LSA_SPF_NOT_EXPLORED. This is done
- * prior to each SPF calculation to reset the state of the SPFVertex structures
- * that will reference the LSAs during the calculation.
- *
- * @see GlobalRoutingLSA
- * @see SPFVertex
- */
- void Initialize ();
-
- GlobalRoutingLSA* GetExtLSA (uint32_t index) const;
- uint32_t GetNumExtLSAs () const;
-
-
-private:
- typedef std::map<Ipv4Address, GlobalRoutingLSA*> LSDBMap_t;
- typedef std::pair<Ipv4Address, GlobalRoutingLSA*> LSDBPair_t;
-
- LSDBMap_t m_database;
- std::vector<GlobalRoutingLSA*> m_extdatabase;
-
-/**
- * @brief GlobalRouteManagerLSDB copy construction is disallowed. There's no
- * need for it and a compiler provided shallow copy would be wrong.
- */
- GlobalRouteManagerLSDB (GlobalRouteManagerLSDB& lsdb);
-
-/**
- * @brief The SPFVertex copy assignment operator is disallowed. There's no
- * need for it and a compiler provided shallow copy would be wrong.
- */
- GlobalRouteManagerLSDB& operator= (GlobalRouteManagerLSDB& lsdb);
-};
-
-/**
- * @brief A global router implementation.
- *
- * This singleton object can query interface each node in the system
- * for a GlobalRouter interface. For those nodes, it fetches one or
- * more Link State Advertisements and stores them in a local database.
- * Then, it can compute shortest paths on a per-node basis to all routers,
- * and finally configure each of the node's forwarding tables.
- *
- * The design is guided by OSPFv2 RFC 2328 section 16.1.1 and quagga ospfd.
- */
-class GlobalRouteManagerImpl
-{
-public:
- GlobalRouteManagerImpl ();
- virtual ~GlobalRouteManagerImpl ();
-/**
- * @brief Delete all static routes on all nodes that have a
- * GlobalRouterInterface
- *
- * TODO: separate manually assigned static routes from static routes that
- * the global routing code injects, and only delete the latter
- * @internal
- *
- */
- virtual void DeleteGlobalRoutes ();
-
-/**
- * @brief Build the routing database by gathering Link State Advertisements
- * from each node exporting a GlobalRouter interface.
- * @internal
- */
- virtual void BuildGlobalRoutingDatabase ();
-
-/**
- * @brief Compute routes using a Dijkstra SPF computation and populate
- * per-node forwarding tables
- * @internal
- */
- virtual void InitializeRoutes ();
-
-/**
- * @brief Debugging routine; allow client code to supply a pre-built LSDB
- * @internal
- */
- void DebugUseLsdb (GlobalRouteManagerLSDB*);
-
-/**
- * @brief Debugging routine; call the core SPF from the unit tests
- * @internal
- */
- void DebugSPFCalculate (Ipv4Address root);
-
-private:
-/**
- * @brief GlobalRouteManagerImpl copy construction is disallowed.
- * There's no need for it and a compiler provided shallow copy would be
- * wrong.
- */
- GlobalRouteManagerImpl (GlobalRouteManagerImpl& srmi);
-
-/**
- * @brief Global Route Manager Implementation assignment operator is
- * disallowed. There's no need for it and a compiler provided shallow copy
- * would be hopelessly wrong.
- */
- GlobalRouteManagerImpl& operator= (GlobalRouteManagerImpl& srmi);
-
- SPFVertex* m_spfroot;
- GlobalRouteManagerLSDB* m_lsdb;
- bool CheckForStubNode (Ipv4Address root);
- void SPFCalculate (Ipv4Address root);
- void SPFProcessStubs (SPFVertex* v);
- void ProcessASExternals (SPFVertex* v, GlobalRoutingLSA* extlsa);
- void SPFNext (SPFVertex*, CandidateQueue&);
- int SPFNexthopCalculation (SPFVertex* v, SPFVertex* w,
- GlobalRoutingLinkRecord* l, uint32_t distance);
- void SPFVertexAddParent (SPFVertex* v);
- GlobalRoutingLinkRecord* SPFGetNextLink (SPFVertex* v, SPFVertex* w,
- GlobalRoutingLinkRecord* prev_link);
- void SPFIntraAddRouter (SPFVertex* v);
- void SPFIntraAddTransit (SPFVertex* v);
- void SPFIntraAddStub (GlobalRoutingLinkRecord *l, SPFVertex* v);
- void SPFAddASExternal (GlobalRoutingLSA *extlsa, SPFVertex *v);
- int32_t FindOutgoingInterfaceId (Ipv4Address a,
- Ipv4Mask amask = Ipv4Mask("255.255.255.255"));
-};
-
-} // namespace ns3
-
-#endif /* GLOBAL_ROUTE_MANAGER_IMPL_H */
--- a/src/routing/global-routing/global-route-manager.cc Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright 2007 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Tom Henderson (tomhend@u.washington.edu)
- */
-
-#include "ns3/assert.h"
-#include "ns3/log.h"
-#include "ns3/simulation-singleton.h"
-#include "global-route-manager.h"
-#include "global-route-manager-impl.h"
-
-namespace ns3 {
-
-// ---------------------------------------------------------------------------
-//
-// GlobalRouteManager Implementation
-//
-// ---------------------------------------------------------------------------
-
- void
-GlobalRouteManager::DeleteGlobalRoutes ()
-{
- SimulationSingleton<GlobalRouteManagerImpl>::Get ()->
- DeleteGlobalRoutes ();
-}
-
- void
-GlobalRouteManager::BuildGlobalRoutingDatabase (void)
-{
- SimulationSingleton<GlobalRouteManagerImpl>::Get ()->
- BuildGlobalRoutingDatabase ();
-}
-
- void
-GlobalRouteManager::InitializeRoutes (void)
-{
- SimulationSingleton<GlobalRouteManagerImpl>::Get ()->
- InitializeRoutes ();
-}
-
- uint32_t
-GlobalRouteManager::AllocateRouterId (void)
-{
- static uint32_t routerId = 0;
- return routerId++;
-}
-
-
-} // namespace ns3
--- a/src/routing/global-routing/global-route-manager.h Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright 2007 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors: Craig Dowell (craigdo@ee.washington.edu)
- * Tom Henderson (tomhend@u.washington.edu)
- */
-
-#ifndef GLOBAL_ROUTE_MANAGER_H
-#define GLOBAL_ROUTE_MANAGER_H
-
-#include "ns3/deprecated.h"
-
-namespace ns3 {
-
-/**
- * @brief A global global router
- *
- * This singleton object can query interface each node in the system
- * for a GlobalRouter interface. For those nodes, it fetches one or
- * more Link State Advertisements and stores them in a local database.
- * Then, it can compute shortest paths on a per-node basis to all routers,
- * and finally configure each of the node's forwarding tables.
- *
- * The design is guided by OSPFv2 RFC 2328 section 16.1.1 and quagga ospfd.
- */
-class GlobalRouteManager
-{
-public:
-/**
- * @brief Allocate a 32-bit router ID from monotonically increasing counter.
- */
- static uint32_t AllocateRouterId ();
-
-/**
- * @brief Delete all static routes on all nodes that have a
- * GlobalRouterInterface
- *
- */
- static void DeleteGlobalRoutes ();
-
-/**
- * @brief Build the routing database by gathering Link State Advertisements
- * from each node exporting a GlobalRouter interface.
- * @internal
- *
- */
- static void BuildGlobalRoutingDatabase ();
-
-/**
- * @brief Compute routes using a Dijkstra SPF computation and populate
- * per-node forwarding tables
- * @internal
- */
- static void InitializeRoutes ();
-
-private:
-/**
- * @brief Global Route Manager copy construction is disallowed. There's no
- * need for it and a compiler provided shallow copy would be wrong.
- *
- */
- GlobalRouteManager (GlobalRouteManager& srm);
-
-/**
- * @brief Global Router copy assignment operator is disallowed. There's no
- * need for it and a compiler provided shallow copy would be wrong.
- */
- GlobalRouteManager& operator= (GlobalRouteManager& srm);
-};
-
-} // namespace ns3
-
-#endif /* GLOBAL_ROUTE_MANAGER_H */
--- a/src/routing/global-routing/global-router-interface.cc Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1694 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright 2007 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors: Tom Henderson (tomhend@u.washington.edu)
- */
-
-#include "ns3/log.h"
-#include "ns3/assert.h"
-#include "ns3/abort.h"
-#include "ns3/channel.h"
-#include "ns3/net-device.h"
-#include "ns3/node.h"
-#include "ns3/node-list.h"
-#include "ns3/ipv4.h"
-#include "ns3/bridge-net-device.h"
-#include "ipv4-global-routing.h"
-#include "global-router-interface.h"
-#include <vector>
-
-NS_LOG_COMPONENT_DEFINE ("GlobalRouter");
-
-namespace ns3 {
-
-// ---------------------------------------------------------------------------
-//
-// GlobalRoutingLinkRecord Implementation
-//
-// ---------------------------------------------------------------------------
-
-GlobalRoutingLinkRecord::GlobalRoutingLinkRecord ()
-:
- m_linkId ("0.0.0.0"),
- m_linkData ("0.0.0.0"),
- m_linkType (Unknown),
- m_metric (0)
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
-GlobalRoutingLinkRecord::GlobalRoutingLinkRecord (
- LinkType linkType,
- Ipv4Address linkId,
- Ipv4Address linkData,
- uint16_t metric)
-:
- m_linkId (linkId),
- m_linkData (linkData),
- m_linkType (linkType),
- m_metric (metric)
-{
- NS_LOG_FUNCTION (this << linkType << linkId << linkData << metric);
-}
-
-GlobalRoutingLinkRecord::~GlobalRoutingLinkRecord ()
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
- Ipv4Address
-GlobalRoutingLinkRecord::GetLinkId (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_linkId;
-}
-
- void
-GlobalRoutingLinkRecord::SetLinkId (Ipv4Address addr)
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_linkId = addr;
-}
-
- Ipv4Address
-GlobalRoutingLinkRecord::GetLinkData (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_linkData;
-}
-
- void
-GlobalRoutingLinkRecord::SetLinkData (Ipv4Address addr)
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_linkData = addr;
-}
-
- GlobalRoutingLinkRecord::LinkType
-GlobalRoutingLinkRecord::GetLinkType (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_linkType;
-}
-
- void
-GlobalRoutingLinkRecord::SetLinkType (
- GlobalRoutingLinkRecord::LinkType linkType)
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_linkType = linkType;
-}
-
- uint16_t
-GlobalRoutingLinkRecord::GetMetric (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_metric;
-}
-
- void
-GlobalRoutingLinkRecord::SetMetric (uint16_t metric)
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_metric = metric;
-}
-
-// ---------------------------------------------------------------------------
-//
-// GlobalRoutingLSA Implementation
-//
-// ---------------------------------------------------------------------------
-
-GlobalRoutingLSA::GlobalRoutingLSA()
- :
- m_lsType (GlobalRoutingLSA::Unknown),
- m_linkStateId("0.0.0.0"),
- m_advertisingRtr("0.0.0.0"),
- m_linkRecords(),
- m_networkLSANetworkMask("0.0.0.0"),
- m_attachedRouters(),
- m_status(GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED),
- m_node_id(0)
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
-GlobalRoutingLSA::GlobalRoutingLSA (
- GlobalRoutingLSA::SPFStatus status,
- Ipv4Address linkStateId,
- Ipv4Address advertisingRtr)
-:
- m_lsType (GlobalRoutingLSA::Unknown),
- m_linkStateId(linkStateId),
- m_advertisingRtr(advertisingRtr),
- m_linkRecords(),
- m_networkLSANetworkMask("0.0.0.0"),
- m_attachedRouters(),
- m_status(status),
- m_node_id(0)
-{
- NS_LOG_FUNCTION (this << status << linkStateId << advertisingRtr);
-}
-
-GlobalRoutingLSA::GlobalRoutingLSA (GlobalRoutingLSA& lsa)
- : m_lsType(lsa.m_lsType), m_linkStateId(lsa.m_linkStateId),
- m_advertisingRtr(lsa.m_advertisingRtr),
- m_networkLSANetworkMask(lsa.m_networkLSANetworkMask),
- m_status(lsa.m_status),
- m_node_id(lsa.m_node_id)
-{
- NS_LOG_FUNCTION_NOARGS ();
- NS_ASSERT_MSG(IsEmpty(),
- "GlobalRoutingLSA::GlobalRoutingLSA (): Non-empty LSA in constructor");
- CopyLinkRecords (lsa);
-}
-
- GlobalRoutingLSA&
-GlobalRoutingLSA::operator= (const GlobalRoutingLSA& lsa)
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_lsType = lsa.m_lsType;
- m_linkStateId = lsa.m_linkStateId;
- m_advertisingRtr = lsa.m_advertisingRtr;
- m_networkLSANetworkMask = lsa.m_networkLSANetworkMask,
- m_status = lsa.m_status;
- m_node_id = lsa.m_node_id;
-
- ClearLinkRecords ();
- CopyLinkRecords (lsa);
- return *this;
-}
-
- void
-GlobalRoutingLSA::CopyLinkRecords (const GlobalRoutingLSA& lsa)
-{
- NS_LOG_FUNCTION_NOARGS ();
- for (ListOfLinkRecords_t::const_iterator i = lsa.m_linkRecords.begin ();
- i != lsa.m_linkRecords.end ();
- i++)
- {
- GlobalRoutingLinkRecord *pSrc = *i;
- GlobalRoutingLinkRecord *pDst = new GlobalRoutingLinkRecord;
-
- pDst->SetLinkType (pSrc->GetLinkType ());
- pDst->SetLinkId (pSrc->GetLinkId ());
- pDst->SetLinkData (pSrc->GetLinkData ());
- pDst->SetMetric (pSrc->GetMetric ());
-
- m_linkRecords.push_back(pDst);
- pDst = 0;
- }
-
- m_attachedRouters = lsa.m_attachedRouters;
-}
-
-GlobalRoutingLSA::~GlobalRoutingLSA()
-{
- NS_LOG_FUNCTION_NOARGS ();
- ClearLinkRecords ();
-}
-
- void
-GlobalRoutingLSA::ClearLinkRecords(void)
-{
- NS_LOG_FUNCTION_NOARGS ();
- for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin ();
- i != m_linkRecords.end ();
- i++)
- {
- NS_LOG_LOGIC ("Free link record");
-
- GlobalRoutingLinkRecord *p = *i;
- delete p;
- p = 0;
-
- *i = 0;
- }
- NS_LOG_LOGIC ("Clear list");
- m_linkRecords.clear();
-}
-
- uint32_t
-GlobalRoutingLSA::AddLinkRecord (GlobalRoutingLinkRecord* lr)
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_linkRecords.push_back (lr);
- return m_linkRecords.size ();
-}
-
- uint32_t
-GlobalRoutingLSA::GetNLinkRecords (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_linkRecords.size ();
-}
-
- GlobalRoutingLinkRecord *
-GlobalRoutingLSA::GetLinkRecord (uint32_t n) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- uint32_t j = 0;
- for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin ();
- i != m_linkRecords.end ();
- i++, j++)
- {
- if (j == n)
- {
- return *i;
- }
- }
- NS_ASSERT_MSG(false, "GlobalRoutingLSA::GetLinkRecord (): invalid index");
- return 0;
-}
-
- bool
-GlobalRoutingLSA::IsEmpty (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_linkRecords.size () == 0;
-}
-
- GlobalRoutingLSA::LSType
-GlobalRoutingLSA::GetLSType (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_lsType;
-}
-
- void
-GlobalRoutingLSA::SetLSType (GlobalRoutingLSA::LSType typ)
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_lsType = typ;
-}
-
- Ipv4Address
-GlobalRoutingLSA::GetLinkStateId (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_linkStateId;
-}
-
- void
-GlobalRoutingLSA::SetLinkStateId (Ipv4Address addr)
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_linkStateId = addr;
-}
-
- Ipv4Address
-GlobalRoutingLSA::GetAdvertisingRouter (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_advertisingRtr;
-}
-
- void
-GlobalRoutingLSA::SetAdvertisingRouter (Ipv4Address addr)
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_advertisingRtr = addr;
-}
-
- void
-GlobalRoutingLSA::SetNetworkLSANetworkMask (Ipv4Mask mask)
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_networkLSANetworkMask = mask;
-}
-
- Ipv4Mask
-GlobalRoutingLSA::GetNetworkLSANetworkMask (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_networkLSANetworkMask;
-}
-
- GlobalRoutingLSA::SPFStatus
-GlobalRoutingLSA::GetStatus (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_status;
-}
-
- uint32_t
-GlobalRoutingLSA::AddAttachedRouter (Ipv4Address addr)
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_attachedRouters.push_back (addr);
- return m_attachedRouters.size ();
-}
-
- uint32_t
-GlobalRoutingLSA::GetNAttachedRouters (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_attachedRouters.size ();
-}
-
- Ipv4Address
-GlobalRoutingLSA::GetAttachedRouter (uint32_t n) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- uint32_t j = 0;
- for ( ListOfAttachedRouters_t::const_iterator i = m_attachedRouters.begin ();
- i != m_attachedRouters.end ();
- i++, j++)
- {
- if (j == n)
- {
- return *i;
- }
- }
- NS_ASSERT_MSG(false, "GlobalRoutingLSA::GetAttachedRouter (): invalid index");
- return Ipv4Address("0.0.0.0");
-}
-
- void
-GlobalRoutingLSA::SetStatus (GlobalRoutingLSA::SPFStatus status)
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_status = status;
-}
-
- Ptr<Node>
-GlobalRoutingLSA::GetNode (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return NodeList::GetNode (m_node_id);
-}
-
- void
-GlobalRoutingLSA::SetNode (Ptr<Node> node)
-{
- NS_LOG_FUNCTION (node);
- m_node_id = node->GetId ();
-}
-
- void
-GlobalRoutingLSA::Print (std::ostream &os) const
-{
- os << std::endl;
- os << "========== Global Routing LSA ==========" << std::endl;
- os << "m_lsType = " << m_lsType;
- if (m_lsType == GlobalRoutingLSA::RouterLSA)
- {
- os << " (GlobalRoutingLSA::RouterLSA)";
- }
- else if (m_lsType == GlobalRoutingLSA::NetworkLSA)
- {
- os << " (GlobalRoutingLSA::NetworkLSA)";
- }
- else if (m_lsType == GlobalRoutingLSA::ASExternalLSAs)
- {
- os << " (GlobalRoutingLSA::ASExternalLSA)";
- }
- else
- {
- os << "(Unknown LSType)";
- }
- os << std::endl;
-
- os << "m_linkStateId = " << m_linkStateId << " (Router ID)" << std::endl;
- os << "m_advertisingRtr = " << m_advertisingRtr << " (Router ID)" << std::endl;
-
- if (m_lsType == GlobalRoutingLSA::RouterLSA)
- {
- for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin ();
- i != m_linkRecords.end ();
- i++)
- {
- GlobalRoutingLinkRecord *p = *i;
-
- os << "---------- RouterLSA Link Record ----------" << std::endl;
- os << "m_linkType = " << p->m_linkType;
- if (p->m_linkType == GlobalRoutingLinkRecord::PointToPoint)
- {
- os << " (GlobalRoutingLinkRecord::PointToPoint)" << std::endl;
- os << "m_linkId = " << p->m_linkId << std::endl;
- os << "m_linkData = " << p->m_linkData << std::endl;
- os << "m_metric = " << p->m_metric << std::endl;
- }
- else if (p->m_linkType == GlobalRoutingLinkRecord::TransitNetwork)
- {
- os << " (GlobalRoutingLinkRecord::TransitNetwork)" << std::endl;
- os << "m_linkId = " << p->m_linkId << " (Designated router for network)" << std::endl;
- os << "m_linkData = " << p->m_linkData << " (This router's IP address)" << std::endl;
- os << "m_metric = " << p->m_metric << std::endl;
- }
- else if (p->m_linkType == GlobalRoutingLinkRecord::StubNetwork)
- {
- os << " (GlobalRoutingLinkRecord::StubNetwork)" << std::endl;
- os << "m_linkId = " << p->m_linkId << " (Network number of attached network)" << std::endl;
- os << "m_linkData = " << p->m_linkData << " (Network mask of attached network)" << std::endl;
- os << "m_metric = " << p->m_metric << std::endl;
- }
- else
- {
- os << " (Unknown LinkType)" << std::endl;
- os << "m_linkId = " << p->m_linkId << std::endl;
- os << "m_linkData = " << p->m_linkData << std::endl;
- os << "m_metric = " << p->m_metric << std::endl;
- }
- os << "---------- End RouterLSA Link Record ----------" << std::endl;
- }
- }
- else if (m_lsType == GlobalRoutingLSA::NetworkLSA)
- {
- os << "---------- NetworkLSA Link Record ----------" << std::endl;
- os << "m_networkLSANetworkMask = " << m_networkLSANetworkMask << std::endl;
- for ( ListOfAttachedRouters_t::const_iterator i = m_attachedRouters.begin (); i != m_attachedRouters.end (); i++)
- {
- Ipv4Address p = *i;
- os << "attachedRouter = " << p << std::endl;
- }
- os << "---------- End NetworkLSA Link Record ----------" << std::endl;
- }
- else if (m_lsType == GlobalRoutingLSA::ASExternalLSAs)
- {
- os << "---------- ASExternalLSA Link Record --------" << std::endl;
- os << "m_linkStateId = " << m_linkStateId << std::endl;
- os << "m_networkLSANetworkMask = " << m_networkLSANetworkMask << std::endl;
- }
- else
- {
- NS_ASSERT_MSG(0, "Illegal LSA LSType: " << m_lsType);
- }
- os << "========== End Global Routing LSA ==========" << std::endl;
-}
-
-std::ostream& operator<< (std::ostream& os, GlobalRoutingLSA& lsa)
-{
- lsa.Print (os);
- return os;
-}
-
-// ---------------------------------------------------------------------------
-//
-// GlobalRouter Implementation
-//
-// ---------------------------------------------------------------------------
-
-NS_OBJECT_ENSURE_REGISTERED (GlobalRouter);
-
-TypeId
-GlobalRouter::GetTypeId (void)
-{
- static TypeId tid = TypeId ("ns3::GlobalRouter")
- .SetParent<Object> ();
- return tid;
-}
-
-GlobalRouter::GlobalRouter ()
- : m_LSAs()
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_routerId.Set(GlobalRouteManager::AllocateRouterId ());
-}
-
-GlobalRouter::~GlobalRouter ()
-{
- NS_LOG_FUNCTION_NOARGS ();
- ClearLSAs();
-}
-
-void
-GlobalRouter::SetRoutingProtocol (Ptr<Ipv4GlobalRouting> routing)
-{
- m_routingProtocol = routing;
-}
-Ptr<Ipv4GlobalRouting>
-GlobalRouter::GetRoutingProtocol (void)
-{
- return m_routingProtocol;
-}
-
-void
-GlobalRouter::DoDispose ()
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_routingProtocol = 0;
- for (InjectedRoutesI k = m_injectedRoutes.begin ();
- k != m_injectedRoutes.end ();
- k = m_injectedRoutes.erase (k))
- {
- delete (*k);
- }
- Object::DoDispose ();
-}
-
- void
-GlobalRouter::ClearLSAs ()
-{
- NS_LOG_FUNCTION_NOARGS ();
- for ( ListOfLSAs_t::iterator i = m_LSAs.begin ();
- i != m_LSAs.end ();
- i++)
- {
- NS_LOG_LOGIC ("Free LSA");
-
- GlobalRoutingLSA *p = *i;
- delete p;
- p = 0;
-
- *i = 0;
- }
- NS_LOG_LOGIC ("Clear list of LSAs");
- m_LSAs.clear();
-}
-
- Ipv4Address
-GlobalRouter::GetRouterId (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_routerId;
-}
-
-//
-// DiscoverLSAs is called on all nodes in the system that have a GlobalRouter
-// interface aggregated. We need to go out and discover any adjacent routers
-// and build the Link State Advertisements that reflect them and their associated
-// networks.
-//
-uint32_t
-GlobalRouter::DiscoverLSAs ()
-{
- NS_LOG_FUNCTION_NOARGS ();
- Ptr<Node> node = GetObject<Node> ();
- NS_ABORT_MSG_UNLESS (node, "GlobalRouter::DiscoverLSAs (): GetObject for <Node> interface failed");
- NS_LOG_LOGIC ("For node " << node->GetId () );
-
- ClearLSAs ();
-
- //
- // While building the Router-LSA, keep a list of those NetDevices for
- // which the current node is the designated router and we will later build
- // a NetworkLSA for.
- //
- NetDeviceContainer c;
-
- //
- // We're aggregated to a node. We need to ask the node for a pointer to its
- // Ipv4 interface. This is where the information regarding the attached
- // interfaces lives. If we're a router, we had better have an Ipv4 interface.
- //
- Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
- NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::DiscoverLSAs (): GetObject for <Ipv4> interface failed");
-
- //
- // Every router node originates a Router-LSA
- //
- GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
- pLSA->SetLSType (GlobalRoutingLSA::RouterLSA);
- pLSA->SetLinkStateId (m_routerId);
- pLSA->SetAdvertisingRouter (m_routerId);
- pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
- pLSA->SetNode (node);
-
- //
- // Ask the node for the number of net devices attached. This isn't necessarily
- // equal to the number of links to adjacent nodes (other routers) as the number
- // of devices may include those for stub networks (e.g., ethernets, etc.) and
- // bridge devices also take up an "extra" net device.
- //
- uint32_t numDevices = node->GetNDevices();
-
- //
- // Iterate through the devices on the node and walk the channel to see what's
- // on the other side of the standalone devices..
- //
- for (uint32_t i = 0; i < numDevices; ++i)
- {
- Ptr<NetDevice> ndLocal = node->GetDevice(i);
-
- //
- // There is an assumption that bridge ports must never have an IP address
- // associated with them. This turns out to be a very convenient place to
- // check and make sure that this is the case.
- //
- if (NetDeviceIsBridged (ndLocal))
- {
- uint32_t interfaceBridge;
- bool rc = FindInterfaceForDevice(node, ndLocal, interfaceBridge);
- NS_ABORT_MSG_IF (rc, "GlobalRouter::DiscoverLSAs(): Bridge ports must not have an IPv4 interface index");
- }
-
- //
- // Check to see if the net device we just got has a corresponding IP
- // interface (could be a pure L2 NetDevice) -- for example a net device
- // associated with a bridge. We are only going to involve devices with
- // IP addresses in routing.
- //
- bool isForwarding = false;
- for (uint32_t j = 0; j < ipv4Local->GetNInterfaces (); ++j )
- {
- if (ipv4Local->GetNetDevice (j) == ndLocal && ipv4Local->IsUp (j) &&
- ipv4Local->IsForwarding (j))
- {
- isForwarding = true;
- break;
- }
- }
-
- if (!isForwarding)
- {
- NS_LOG_LOGIC ("Net device " << ndLocal << "has no IP interface or is not enabled for forwarding, skipping");
- continue;
- }
-
- //
- // We have a net device that we need to check out. If it suports
- // broadcast and is not a point-point link, then it will be either a stub
- // network or a transit network depending on the number of routers on
- // the segment. We add the appropriate link record to the LSA.
- //
- // If the device is a point to point link, we treat it separately. In
- // that case, there may be zero, one, or two link records added.
- //
-
- if (ndLocal->IsBroadcast () && !ndLocal->IsPointToPoint () )
- {
- NS_LOG_LOGIC ("Broadcast link");
- ProcessBroadcastLink (ndLocal, pLSA, c);
- }
- else if (ndLocal->IsPointToPoint () )
- {
- NS_LOG_LOGIC ("Point=to-point link");
- ProcessPointToPointLink (ndLocal, pLSA);
- }
- else
- {
- NS_ASSERT_MSG(0, "GlobalRouter::DiscoverLSAs (): unknown link type");
- }
- }
-
- NS_LOG_LOGIC ("========== LSA for node " << node->GetId () << " ==========");
- NS_LOG_LOGIC (*pLSA);
- m_LSAs.push_back (pLSA);
- pLSA = 0;
-
- //
- // Now, determine whether we need to build a NetworkLSA. This is the case if
- // we found at least one designated router.
- //
- uint32_t nDesignatedRouters = c.GetN ();
- if (nDesignatedRouters > 0)
- {
- NS_LOG_LOGIC ("Build Network LSAs");
- BuildNetworkLSAs (c);
- }
-
- //
- // Build injected route LSAs as external routes
- // RFC 2328, section 12.4.4
- //
- for (InjectedRoutesCI i = m_injectedRoutes.begin();
- i != m_injectedRoutes.end();
- i++)
- {
- GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
- pLSA->SetLSType (GlobalRoutingLSA::ASExternalLSAs);
- pLSA->SetLinkStateId ((*i)->GetDestNetwork ());
- pLSA->SetAdvertisingRouter (m_routerId);
- pLSA->SetNetworkLSANetworkMask ((*i)->GetDestNetworkMask ());
- pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
- m_LSAs.push_back (pLSA);
- }
- return m_LSAs.size ();
-}
-
- void
-GlobalRouter::ProcessBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c)
-{
- NS_LOG_FUNCTION (nd << pLSA << &c);
-
- if (nd->IsBridge ())
- {
- ProcessBridgedBroadcastLink (nd, pLSA, c);
- }
- else
- {
- ProcessSingleBroadcastLink (nd, pLSA, c);
- }
-}
-
- void
-GlobalRouter::ProcessSingleBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c)
-{
- NS_LOG_FUNCTION (nd << pLSA << &c);
-
- GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord;
- NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessSingleBroadcastLink(): Can't alloc link record");
-
- //
- // We have some preliminaries to do to get enough information to proceed.
- // This information we need comes from the internet stack, so notice that
- // there is an implied assumption that global routing is only going to
- // work with devices attached to the internet stack (have an ipv4 interface
- // associated to them.
- //
- Ptr<Node> node = nd->GetNode ();
-
- uint32_t interfaceLocal;
- bool rc = FindInterfaceForDevice(node, nd, interfaceLocal);
- NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessSingleBroadcastLink(): No interface index associated with device");
-
- Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
- NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessSingleBroadcastLink (): GetObject for <Ipv4> interface failed");
-
- if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
- {
- NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
- }
- Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
- Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();
- NS_LOG_LOGIC ("Working with local address " << addrLocal);
- uint16_t metricLocal = ipv4Local->GetMetric (interfaceLocal);
-
- //
- // Check to see if the net device is connected to a channel/network that has
- // another router on it. If there is no other router on the link (but us) then
- // this is a stub network. If we find another router, then what we have here
- // is a transit network.
- //
- if (AnotherRouterOnLink (nd, true) == false)
- {
- //
- // This is a net device connected to a stub network
- //
- NS_LOG_LOGIC("Router-LSA Stub Network");
- plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
-
- //
- // According to OSPF, the Link ID is the IP network number of
- // the attached network.
- //
- plr->SetLinkId (addrLocal.CombineMask(maskLocal));
-
- //
- // and the Link Data is the network mask; converted to Ipv4Address
- //
- Ipv4Address maskLocalAddr;
- maskLocalAddr.Set(maskLocal.Get ());
- plr->SetLinkData (maskLocalAddr);
- plr->SetMetric (metricLocal);
- pLSA->AddLinkRecord(plr);
- plr = 0;
- }
- else
- {
- //
- // We have multiple routers on a broadcast interface, so this is
- // a transit network.
- //
- NS_LOG_LOGIC ("Router-LSA Transit Network");
- plr->SetLinkType (GlobalRoutingLinkRecord::TransitNetwork);
-
- //
- // By definition, the router with the lowest IP address is the
- // designated router for the network. OSPF says that the Link ID
- // gets the IP interface address of the designated router in this
- // case.
- //
- Ipv4Address desigRtr = FindDesignatedRouterForLink (nd, true);
-
- //
- // Let's double-check that any designated router we find out on our
- // network is really on our network.
- //
- if (desigRtr != "255.255.255.255")
- {
- Ipv4Address networkHere = addrLocal.CombineMask (maskLocal);
- Ipv4Address networkThere = desigRtr.CombineMask (maskLocal);
- NS_ABORT_MSG_UNLESS (networkHere == networkThere,
- "GlobalRouter::ProcessSingleBroadcastLink(): Network number confusion");
- }
- if (desigRtr == addrLocal)
- {
- c.Add (nd);
- NS_LOG_LOGIC ("Node " << node->GetId () << " elected a designated router");
- }
- plr->SetLinkId (desigRtr);
-
- //
- // OSPF says that the Link Data is this router's own IP address.
- //
- plr->SetLinkData (addrLocal);
- plr->SetMetric (metricLocal);
- pLSA->AddLinkRecord (plr);
- plr = 0;
- }
-}
-
- void
-GlobalRouter::ProcessBridgedBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c)
-{
- NS_LOG_FUNCTION (nd << pLSA << &c);
- NS_ASSERT_MSG (nd->IsBridge (), "GlobalRouter::ProcessBridgedBroadcastLink(): Called with non-bridge net device");
-
-#if 0
- //
- // It is possible to admit the possibility that a bridge device on a node
- // can also participate in routing. This would surprise people who don't
- // come from Microsoft-land where they do use such a construct. Based on
- // the principle of least-surprise, we will leave the relatively simple
- // code in place to do this, but not enable it until someone really wants
- // the capability. Even then, we will not enable this code as a default
- // but rather something you will have to go and turn on.
- //
-
- Ptr<BridgeNetDevice> bnd = nd->GetObject<BridgeNetDevice> ();
- NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for <BridgeNetDevice> failed");
-
- //
- // We have some preliminaries to do to get enough information to proceed.
- // This information we need comes from the internet stack, so notice that
- // there is an implied assumption that global routing is only going to
- // work with devices attached to the internet stack (have an ipv4 interface
- // associated to them.
- //
- Ptr<Node> node = nd->GetNode ();
-
- uint32_t interfaceLocal;
- bool rc = FindInterfaceForDevice(node, nd, interfaceLocal);
- NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessBridgedBroadcastLink(): No interface index associated with device");
-
- Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
- NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessBridgedBroadcastLink (): GetObject for <Ipv4> interface failed");
-
- if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
- {
- NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
- }
- Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
- Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();;
- NS_LOG_LOGIC ("Working with local address " << addrLocal);
- uint16_t metricLocal = ipv4Local->GetMetric (interfaceLocal);
-
- //
- // We need to handle a bridge on the router. This means that we have been
- // given a net device that is a BridgeNetDevice. It has an associated Ipv4
- // interface index and address. Some number of other net devices live "under"
- // the bridge device as so-called bridge ports. In a nutshell, what we have
- // to do is to repeat what is done for a single broadcast link on all of
- // those net devices living under the bridge (trolls?)
- //
-
- bool areTransitNetwork = false;
- Ipv4Address desigRtr ("255.255.255.255");
-
- for (uint32_t i = 0; i < bnd->GetNBridgePorts (); ++i)
- {
- Ptr<NetDevice> ndTemp = bnd->GetBridgePort (i);
-
- //
- // We have to decide if we are a transit network. This is characterized
- // by the presence of another router on the network segment. If we find
- // another router on any of our bridged links, we are a transit network.
- //
- if (AnotherRouterOnLink (ndTemp, true))
- {
- areTransitNetwork = true;
-
- //
- // If we're going to be a transit network, then we have got to elect
- // a designated router for the whole bridge. This means finding the
- // router with the lowest IP address on the whole bridge. We ask
- // for the lowest address on each segment and pick the lowest of them
- // all.
- //
- Ipv4Address desigRtrTemp = FindDesignatedRouterForLink (ndTemp, true);
-
- //
- // Let's double-check that any designated router we find out on our
- // network is really on our network.
- //
- if (desigRtrTemp != "255.255.255.255")
- {
- Ipv4Address networkHere = addrLocal.CombineMask (maskLocal);
- Ipv4Address networkThere = desigRtrTemp.CombineMask (maskLocal);
- NS_ABORT_MSG_UNLESS (networkHere == networkThere,
- "GlobalRouter::ProcessSingleBroadcastLink(): Network number confusion");
- }
- if (desigRtrTemp < desigRtr)
- {
- desigRtr = desigRtrTemp;
- }
- }
- }
- //
- // That's all the information we need to put it all together, just like we did
- // in the case of a single broadcast link.
- //
-
- GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord;
- NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessBridgedBroadcastLink(): Can't alloc link record");
-
- if (areTransitNetwork == false)
- {
- //
- // This is a net device connected to a bridge of stub networks
- //
- NS_LOG_LOGIC("Router-LSA Stub Network");
- plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
-
- //
- // According to OSPF, the Link ID is the IP network number of
- // the attached network.
- //
- plr->SetLinkId (addrLocal.CombineMask(maskLocal));
-
- //
- // and the Link Data is the network mask; converted to Ipv4Address
- //
- Ipv4Address maskLocalAddr;
- maskLocalAddr.Set(maskLocal.Get ());
- plr->SetLinkData (maskLocalAddr);
- plr->SetMetric (metricLocal);
- pLSA->AddLinkRecord(plr);
- plr = 0;
- }
- else
- {
- //
- // We have multiple routers on a bridged broadcast interface, so this is
- // a transit network.
- //
- NS_LOG_LOGIC ("Router-LSA Transit Network");
- plr->SetLinkType (GlobalRoutingLinkRecord::TransitNetwork);
-
- //
- // By definition, the router with the lowest IP address is the
- // designated router for the network. OSPF says that the Link ID
- // gets the IP interface address of the designated router in this
- // case.
- //
- if (desigRtr == addrLocal)
- {
- c.Add (nd);
- NS_LOG_LOGIC ("Node " << node->GetId () << " elected a designated router");
- }
- plr->SetLinkId (desigRtr);
-
- //
- // OSPF says that the Link Data is this router's own IP address.
- //
- plr->SetLinkData (addrLocal);
- plr->SetMetric (metricLocal);
- pLSA->AddLinkRecord (plr);
- plr = 0;
- }
-#endif
-}
-
- void
-GlobalRouter::ProcessPointToPointLink (Ptr<NetDevice> ndLocal, GlobalRoutingLSA *pLSA)
-{
- NS_LOG_FUNCTION (ndLocal << pLSA);
-
- //
- // We have some preliminaries to do to get enough information to proceed.
- // This information we need comes from the internet stack, so notice that
- // there is an implied assumption that global routing is only going to
- // work with devices attached to the internet stack (have an ipv4 interface
- // associated to them.
- //
- Ptr<Node> nodeLocal = ndLocal->GetNode ();
-
- uint32_t interfaceLocal;
- bool rc = FindInterfaceForDevice(nodeLocal, ndLocal, interfaceLocal);
- NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessPointToPointLink (): No interface index associated with device");
-
- Ptr<Ipv4> ipv4Local = nodeLocal->GetObject<Ipv4> ();
- NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessPointToPointLink (): GetObject for <Ipv4> interface failed");
-
- if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
- {
- NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
- }
- Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
- Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();
- NS_LOG_LOGIC ("Working with local address " << addrLocal);
- uint16_t metricLocal = ipv4Local->GetMetric (interfaceLocal);
-
- //
- // Now, we're going to walk over to the remote net device on the other end of
- // the point-to-point channel we know we have. This is where our adjacent
- // router (to use OSPF lingo) is running.
- //
- Ptr<Channel> ch = ndLocal->GetChannel();
-
- //
- // Get the net device on the other side of the point-to-point channel.
- //
- Ptr<NetDevice> ndRemote = GetAdjacent(ndLocal, ch);
-
- //
- // The adjacent net device is aggregated to a node. We need to ask that net
- // device for its node, then ask that node for its Ipv4 interface. Note a
- // requirement that nodes on either side of a point-to-point link must have
- // internet stacks; and an assumption that point-to-point links are incompatible
- // with bridging.
- //
- Ptr<Node> nodeRemote = ndRemote->GetNode();
- Ptr<Ipv4> ipv4Remote = nodeRemote->GetObject<Ipv4> ();
- NS_ABORT_MSG_UNLESS (ipv4Remote,
- "GlobalRouter::ProcessPointToPointLink(): GetObject for remote <Ipv4> failed");
-
- //
- // Further note the requirement that nodes on either side of a point-to-point
- // link must participate in global routing and therefore have a GlobalRouter
- // interface aggregated.
- //
- Ptr<GlobalRouter> rtrRemote = nodeRemote->GetObject<GlobalRouter> ();
- if (rtrRemote == 0)
- {
- // This case is possible if the remote does not participate in global routing
- return;
- }
- //
- // We're going to need the remote router ID, so we might as well get it now.
- //
- Ipv4Address rtrIdRemote = rtrRemote->GetRouterId();
- NS_LOG_LOGIC ("Working with remote router " << rtrIdRemote);
-
- //
- // Now, just like we did above, we need to get the IP interface index for the
- // net device on the other end of the point-to-point channel.
- //
- uint32_t interfaceRemote;
- rc = FindInterfaceForDevice(nodeRemote, ndRemote, interfaceRemote);
- NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessPointToPointLinks(): No interface index associated with remote device");
-
- //
- // Now that we have the Ipv4 interface, we can get the (remote) address and
- // mask we need.
- //
- if (ipv4Remote->GetNAddresses (interfaceRemote) > 1)
- {
- NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
- }
- Ipv4Address addrRemote = ipv4Remote->GetAddress (interfaceRemote, 0).GetLocal ();
- Ipv4Mask maskRemote = ipv4Remote->GetAddress (interfaceRemote, 0).GetMask ();
- NS_LOG_LOGIC ("Working with remote address " << addrRemote);
-
- //
- // Now we can fill out the link records for this link. There are always two
- // link records; the first is a point-to-point record describing the link and
- // the second is a stub network record with the network number.
- //
- GlobalRoutingLinkRecord *plr;
- if (ipv4Remote->IsUp (interfaceRemote))
- {
- NS_LOG_LOGIC ("Remote side interface " << interfaceRemote << " is up-- add a type 1 link");
-
- plr = new GlobalRoutingLinkRecord;
- NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record");
- plr->SetLinkType (GlobalRoutingLinkRecord::PointToPoint);
- plr->SetLinkId (rtrIdRemote);
- plr->SetLinkData (addrLocal);
- plr->SetMetric (metricLocal);
- pLSA->AddLinkRecord (plr);
- plr = 0;
- }
-
- // Regardless of state of peer, add a type 3 link (RFC 2328: 12.4.1.1)
- plr = new GlobalRoutingLinkRecord;
- NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record");
- plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
- plr->SetLinkId (addrRemote);
- plr->SetLinkData (Ipv4Address(maskRemote.Get())); // Frown
- plr->SetMetric (metricLocal);
- pLSA->AddLinkRecord (plr);
- plr = 0;
-}
-
- void
-GlobalRouter::BuildNetworkLSAs (NetDeviceContainer c)
-{
- NS_LOG_FUNCTION (&c);
-
- uint32_t nDesignatedRouters = c.GetN ();
-
- for (uint32_t i = 0; i < nDesignatedRouters; ++i)
- {
- //
- // Build one NetworkLSA for each net device talking to a network that we are the
- // designated router for. These devices are in the provided container.
- //
- Ptr<NetDevice> ndLocal = c.Get (i);
- Ptr<Node> node = ndLocal->GetNode ();
-
- uint32_t interfaceLocal;
- bool rc = FindInterfaceForDevice(node, ndLocal, interfaceLocal);
- NS_ABORT_MSG_IF (rc == false, "GlobalRouter::BuildNetworkLSAs (): No interface index associated with device");
-
- Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
- NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessPointToPointLink (): GetObject for <Ipv4> interface failed");
-
- if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
- {
- NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
- }
- Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
- Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();
-
- GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
- NS_ABORT_MSG_IF (pLSA == 0, "GlobalRouter::BuildNetworkLSAs(): Can't alloc link record");
-
- pLSA->SetLSType (GlobalRoutingLSA::NetworkLSA);
- pLSA->SetLinkStateId (addrLocal);
- pLSA->SetAdvertisingRouter (m_routerId);
- pLSA->SetNetworkLSANetworkMask (maskLocal);
- pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
- pLSA->SetNode (node);
-
- //
- // Build a list of AttachedRouters by walking the devices in the channel
- // and, if we find a node with a GlobalRouter interface and an IPv4
- // interface associated with that device, we call it an attached router.
- //
- Ptr<Channel> ch = ndLocal->GetChannel();
- uint32_t nDevices = ch->GetNDevices();
- NS_ASSERT (nDevices);
-
- for (uint32_t i = 0; i < nDevices; i++)
- {
- Ptr<NetDevice> tempNd = ch->GetDevice (i);
- NS_ASSERT (tempNd);
- Ptr<Node> tempNode = tempNd->GetNode ();
-
- //
- // Does the node in question have a GlobalRouter interface? If not it can
- // hardly be considered an attached router.
- //
- Ptr<GlobalRouter> rtr = tempNode->GetObject<GlobalRouter> ();
- if (rtr == 0)
- {
- continue;
- }
-
- //
- // Does the attached node have an ipv4 interface for the device we're probing?
- // If not, it can't play router.
- //
- uint32_t tempInterface;
- if (FindInterfaceForDevice (tempNode, tempNd, tempInterface))
- {
- Ptr<Ipv4> tempIpv4 = tempNode->GetObject<Ipv4> ();
- NS_ASSERT (tempIpv4);
- if (!tempIpv4->IsUp (tempInterface))
- {
- NS_LOG_LOGIC ("Remote side interface " << tempInterface << " not up");
- }
- else
- {
- if (tempIpv4->GetNAddresses (tempInterface) > 1)
- {
- NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
- }
- Ipv4Address tempAddr = tempIpv4->GetAddress(tempInterface, 0).GetLocal ();
- pLSA->AddAttachedRouter (tempAddr);
- }
- }
- }
- m_LSAs.push_back (pLSA);
- pLSA = 0;
- }
-}
-
-//
-// Given a local net device, we need to walk the channel to which the net device is
-// attached and look for nodes with GlobalRouter interfaces on them (one of them
-// will be us). Of these, the router with the lowest IP address on the net device
-// connecting to the channel becomes the designated router for the link.
-//
- Ipv4Address
-GlobalRouter::FindDesignatedRouterForLink (Ptr<NetDevice> ndLocal, bool allowRecursion) const
-{
- NS_LOG_FUNCTION (ndLocal << allowRecursion);
-
- Ptr<Channel> ch = ndLocal->GetChannel();
- uint32_t nDevices = ch->GetNDevices();
- NS_ASSERT (nDevices);
-
- NS_LOG_LOGIC ("Looking for designated router off of net device " << ndLocal << " on node " <<
- ndLocal->GetNode ()->GetId ());
-
- Ipv4Address desigRtr ("255.255.255.255");
-
- //
- // Look through all of the devices on the channel to which the net device
- // in question is attached.
- //
- for (uint32_t i = 0; i < nDevices; i++)
- {
- Ptr<NetDevice> ndOther = ch->GetDevice (i);
- NS_ASSERT (ndOther);
-
- Ptr<Node> nodeOther = ndOther->GetNode ();
-
- NS_LOG_LOGIC ("Examine channel device " << i << " on node " << nodeOther->GetId ());
-
- //
- // For all other net devices, we need to check and see if a router
- // is present. If the net device on the other side is a bridged
- // device, we need to consider all of the other devices on the
- // bridge as well (all of the bridge ports.
- //
- NS_LOG_LOGIC ("checking to see if the device is bridged");
- Ptr<BridgeNetDevice> bnd = NetDeviceIsBridged (ndOther);
- if (bnd)
- {
- NS_LOG_LOGIC ("Device is bridged by BridgeNetDevice " << bnd);
-
- //
- // It is possible that the bridge net device is sitting under a
- // router, so we have to check for the presence of that router
- // before we run off and follow all the links
- //
- // We require a designated router to have a GlobalRouter interface and
- // an internet stack that includes the Ipv4 interface. If it doesn't
- // it can't play router.
- //
- NS_LOG_LOGIC ("Checking for router on bridge net device " << bnd);
- Ptr<GlobalRouter> rtr = nodeOther->GetObject<GlobalRouter> ();
- Ptr<Ipv4> ipv4 = nodeOther->GetObject<Ipv4> ();
- if (rtr && ipv4)
- {
- uint32_t interfaceOther;
- if (FindInterfaceForDevice(nodeOther, bnd, interfaceOther))
- {
- NS_LOG_LOGIC ("Found router on bridge net device " << bnd);
- if (!ipv4->IsUp (interfaceOther))
- {
- NS_LOG_LOGIC ("Remote side interface " << interfaceOther << " not up");
- continue;
- }
- if (ipv4->GetNAddresses (interfaceOther) > 1)
- {
- NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
- }
- Ipv4Address addrOther = ipv4->GetAddress (interfaceOther, 0).GetLocal ();
- desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
- NS_LOG_LOGIC ("designated router now " << desigRtr);
- }
- }
-
- NS_LOG_LOGIC ("Looking through bridge ports of bridge net device " << bnd);
- for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
- {
- Ptr<NetDevice> ndBridged = bnd->GetBridgePort (j);
- NS_LOG_LOGIC ("Examining bridge port " << j << " device " << ndBridged);
- if (ndBridged == ndOther)
- {
- NS_LOG_LOGIC ("That bridge port is me, don't walk backward");
- continue;
- }
-
- if (allowRecursion)
- {
- NS_LOG_LOGIC ("Recursively looking for routers down bridge port " << ndBridged);
- Ipv4Address addrOther = FindDesignatedRouterForLink (ndBridged, false);
- desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
- NS_LOG_LOGIC ("designated router now " << desigRtr);
- }
- }
- }
- else
- {
- NS_LOG_LOGIC ("This device is not bridged");
- Ptr<Node> nodeOther = ndOther->GetNode ();
- NS_ASSERT (nodeOther);
-
- //
- // We require a designated router to have a GlobalRouter interface and
- // an internet stack that includes the Ipv4 interface. If it doesn't
- //
- Ptr<GlobalRouter> rtr = nodeOther->GetObject<GlobalRouter> ();
- Ptr<Ipv4> ipv4 = nodeOther->GetObject<Ipv4> ();
- if (rtr && ipv4)
- {
- uint32_t interfaceOther;
- if (FindInterfaceForDevice(nodeOther, ndOther, interfaceOther))
- {
- if (!ipv4->IsUp (interfaceOther))
- {
- NS_LOG_LOGIC ("Remote side interface " << interfaceOther << " not up");
- continue;
- }
- NS_LOG_LOGIC ("Found router on net device " << ndOther);
- if (ipv4->GetNAddresses (interfaceOther) > 1)
- {
- NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
- }
- Ipv4Address addrOther = ipv4->GetAddress (interfaceOther, 0).GetLocal ();
- desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
- NS_LOG_LOGIC ("designated router now " << desigRtr);
- }
- }
- }
- }
- return desigRtr;
-}
-
-//
-// Given a node and an attached net device, take a look off in the channel to
-// which the net device is attached and look for a node on the other side
-// that has a GlobalRouter interface aggregated. Life gets more complicated
-// when there is a bridged net device on the other side.
-//
- bool
-GlobalRouter::AnotherRouterOnLink (Ptr<NetDevice> nd, bool allowRecursion) const
-{
- NS_LOG_FUNCTION (nd << allowRecursion);
-
- Ptr<Channel> ch = nd->GetChannel();
- if (!ch)
- {
- // It may be that this net device is a stub device, without a channel
- return false;
- }
- uint32_t nDevices = ch->GetNDevices();
- NS_ASSERT (nDevices);
-
- NS_LOG_LOGIC ("Looking for routers off of net device " << nd << " on node " << nd->GetNode ()->GetId ());
-
- //
- // Look through all of the devices on the channel to which the net device
- // in question is attached.
- //
- for (uint32_t i = 0; i < nDevices; i++)
- {
- Ptr<NetDevice> ndOther = ch->GetDevice (i);
- NS_ASSERT (ndOther);
-
- NS_LOG_LOGIC ("Examine channel device " << i << " on node " << ndOther->GetNode ()->GetId ());
-
- //
- // Ignore the net device itself.
- //
- if (ndOther == nd)
- {
- NS_LOG_LOGIC ("Myself, skip");
- continue;
- }
-
- //
- // For all other net devices, we need to check and see if a router
- // is present. If the net device on the other side is a bridged
- // device, we need to consider all of the other devices on the
- // bridge.
- //
- NS_LOG_LOGIC ("checking to see if device is bridged");
- Ptr<BridgeNetDevice> bnd = NetDeviceIsBridged (ndOther);
- if (bnd)
- {
- NS_LOG_LOGIC ("Device is bridged by net device " << bnd);
- NS_LOG_LOGIC ("Looking through bridge ports of bridge net device " << bnd);
- for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
- {
- Ptr<NetDevice> ndBridged = bnd->GetBridgePort (j);
- NS_LOG_LOGIC ("Examining bridge port " << j << " device " << ndBridged);
- if (ndBridged == ndOther)
- {
- NS_LOG_LOGIC ("That bridge port is me, skip");
- continue;
- }
-
- if (allowRecursion)
- {
- NS_LOG_LOGIC ("Recursively looking for routers on bridge port " << ndBridged);
- if (AnotherRouterOnLink (ndBridged, false))
- {
- NS_LOG_LOGIC ("Found routers on bridge port, return true");
- return true;
- }
- }
- }
- NS_LOG_LOGIC ("No routers on bridged net device, return false");
- return false;
- }
-
- NS_LOG_LOGIC ("This device is not bridged");
- Ptr<Node> nodeTemp = ndOther->GetNode ();
- NS_ASSERT (nodeTemp);
-
- Ptr<GlobalRouter> rtr = nodeTemp->GetObject<GlobalRouter> ();
- if (rtr)
- {
- NS_LOG_LOGIC ("Found GlobalRouter interface, return true");
- return true;
- }
- else
- {
- NS_LOG_LOGIC ("No GlobalRouter interface on device, continue search");
- }
- }
- NS_LOG_LOGIC ("No routers found, return false");
- return false;
-}
-
- uint32_t
-GlobalRouter::GetNumLSAs (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_LSAs.size ();
-}
-
-//
-// Get the nth link state advertisement from this router.
-//
- bool
-GlobalRouter::GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- NS_ASSERT_MSG(lsa.IsEmpty(), "GlobalRouter::GetLSA (): Must pass empty LSA");
-//
-// All of the work was done in GetNumLSAs. All we have to do here is to
-// walk the list of link state advertisements created there and return the
-// one the client is interested in.
-//
- ListOfLSAs_t::const_iterator i = m_LSAs.begin ();
- uint32_t j = 0;
-
- for (; i != m_LSAs.end (); i++, j++)
- {
- if (j == n)
- {
- GlobalRoutingLSA *p = *i;
- lsa = *p;
- return true;
- }
- }
-
- return false;
-}
-
-void
-GlobalRouter::InjectRoute (Ipv4Address network, Ipv4Mask networkMask)
-{
- NS_LOG_FUNCTION (network << networkMask);
- Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
-//
-// Interface number does not matter here, using 1.
-//
- *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
- networkMask,
- 1);
- m_injectedRoutes.push_back (route);
-}
-
-Ipv4RoutingTableEntry *
-GlobalRouter::GetInjectedRoute (uint32_t index)
-{
- NS_LOG_FUNCTION (index);
- if (index < m_injectedRoutes.size ())
- {
- uint32_t tmp = 0;
- for (InjectedRoutesCI i = m_injectedRoutes.begin ();
- i != m_injectedRoutes.end ();
- i++)
- {
- if (tmp == index)
- {
- return *i;
- }
- tmp++;
- }
- }
- NS_ASSERT (false);
- // quiet compiler.
- return 0;
-}
-
-uint32_t
-GlobalRouter::GetNInjectedRoutes ()
-{
- return m_injectedRoutes.size ();
-}
-
-void
-GlobalRouter::RemoveInjectedRoute (uint32_t index)
-{
- NS_LOG_FUNCTION (index);
- NS_ASSERT (index < m_injectedRoutes.size ());
- uint32_t tmp = 0;
- for (InjectedRoutesI i = m_injectedRoutes.begin (); i != m_injectedRoutes.end (); i++)
- {
- if (tmp == index)
- {
- NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_injectedRoutes.size());
- delete *i;
- m_injectedRoutes.erase (i);
- return;
- }
- tmp++;
- }
-}
-
-bool
-GlobalRouter::WithdrawRoute (Ipv4Address network, Ipv4Mask networkMask)
-{
- NS_LOG_FUNCTION (network << networkMask);
- for (InjectedRoutesI i = m_injectedRoutes.begin (); i != m_injectedRoutes.end (); i++)
- {
- if ((*i)->GetDestNetwork () == network && (*i)->GetDestNetworkMask () == networkMask)
- {
- NS_LOG_LOGIC ("Withdrawing route to network/mask " << network << "/" << networkMask);
- delete *i;
- m_injectedRoutes.erase (i);
- return true;
- }
- }
- return false;
-}
-
-
-//
-// Link through the given channel and find the net device that's on the
-// other end. This only makes sense with a point-to-point channel.
-//
- Ptr<NetDevice>
-GlobalRouter::GetAdjacent (Ptr<NetDevice> nd, Ptr<Channel> ch) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- NS_ASSERT_MSG(ch->GetNDevices() == 2, "GlobalRouter::GetAdjacent (): Channel with other than two devices");
-//
-// This is a point to point channel with two endpoints. Get both of them.
-//
- Ptr<NetDevice> nd1 = ch->GetDevice(0);
- Ptr<NetDevice> nd2 = ch->GetDevice(1);
-//
-// One of the endpoints is going to be "us" -- that is the net device attached
-// to the node on which we're running -- i.e., "nd". The other endpoint (the
-// one to which we are connected via the channel) is the adjacent router.
-//
- if (nd1 == nd)
- {
- return nd2;
- }
- else if (nd2 == nd)
- {
- return nd1;
- }
- else
- {
- NS_ASSERT_MSG(false,
- "GlobalRouter::GetAdjacent (): Wrong or confused channel?");
- return 0;
- }
-}
-
-//
-// Given a node and a net device, find an IPV4 interface index that corresponds
-// to that net device. This function may fail for various reasons. If a node
-// does not have an internet stack (for example if it is a bridge) we won't have
-// an IPv4 at all. If the node does have a stack, but the net device in question
-// is bridged, there will not be an interface associated directly with the device.
-//
- bool
-GlobalRouter::FindInterfaceForDevice (Ptr<Node> node, Ptr<NetDevice> nd, uint32_t &index) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- NS_LOG_LOGIC("For node " << node->GetId () << " for net device " << nd );
-
- Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
- if (ipv4 == 0)
- {
- NS_LOG_LOGIC ("No Ipv4 interface on node " << node->GetId ());
- return false;
- }
-
- for (uint32_t i = 0; i < ipv4->GetNInterfaces(); ++i )
- {
- if (ipv4->GetNetDevice(i) == nd)
- {
- NS_LOG_LOGIC ("Device " << nd << " has associated ipv4 index " << i);
- index = i;
- return true;
- }
- }
-
- NS_LOG_LOGIC ("Device " << nd << " has no associated ipv4 index");
- return false;
-}
-
-//
-// Decide whether or not a given net device is being bridged by a BridgeNetDevice.
-//
- Ptr<BridgeNetDevice>
-GlobalRouter::NetDeviceIsBridged (Ptr<NetDevice> nd) const
-{
- NS_LOG_FUNCTION (nd);
-
- Ptr<Node> node = nd->GetNode ();
- uint32_t nDevices = node->GetNDevices();
-
- //
- // There is no bit on a net device that says it is being bridged, so we have
- // to look for bridges on the node to which the device is attached. If we
- // find a bridge, we need to look through its bridge ports (the devices it
- // bridges) to see if we find the device in question.
- //
- for (uint32_t i = 0; i < nDevices; ++i)
- {
- Ptr<NetDevice> ndTest = node->GetDevice(i);
- NS_LOG_LOGIC ("Examine device " << i << " " << ndTest);
-
- if (ndTest->IsBridge ())
- {
- NS_LOG_LOGIC ("device " << i << " is a bridge net device");
- Ptr<BridgeNetDevice> bnd = ndTest->GetObject<BridgeNetDevice> ();
- NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for <BridgeNetDevice> failed");
-
- for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
- {
- NS_LOG_LOGIC ("Examine bridge port " << j << " " << bnd->GetBridgePort (j));
- if (bnd->GetBridgePort (j) == nd)
- {
- NS_LOG_LOGIC ("Net device " << nd << " is bridged by " << bnd);
- return bnd;
- }
- }
- }
- }
- NS_LOG_LOGIC ("Net device " << nd << " is not bridged");
- return 0;
-}
-
-} // namespace ns3
--- a/src/routing/global-routing/global-router-interface.h Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,754 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright 2007 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors: Craig Dowell (craigdo@ee.washington.edu)
- * Tom Henderson (tomhend@u.washington.edu)
- */
-
-#ifndef GLOBAL_ROUTER_INTERFACE_H
-#define GLOBAL_ROUTER_INTERFACE_H
-
-#include <stdint.h>
-#include <list>
-#include "ns3/object.h"
-#include "ns3/ptr.h"
-#include "ns3/node.h"
-#include "ns3/channel.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/net-device-container.h"
-#include "ns3/bridge-net-device.h"
-#include "ns3/global-route-manager.h"
-#include "ns3/ipv4-routing-table-entry.h"
-
-namespace ns3 {
-
-class GlobalRouter;
-class Ipv4GlobalRouting;
-
-/**
- * @brief A single link record for a link state advertisement.
- *
- * The GlobalRoutingLinkRecord is modeled after the OSPF link record field of
- * a Link State Advertisement. Right now we will only see two types of link
- * records corresponding to a stub network and a point-to-point link (channel).
- */
-class GlobalRoutingLinkRecord
-{
-public:
- friend class GlobalRoutingLSA;
-/**
- * @enum LinkType
- * @brief Enumeration of the possible types of Global Routing Link Records.
- *
- * These values are defined in the OSPF spec. We currently only use
- * PointToPoint and StubNetwork types.
- */
- enum LinkType {
- Unknown = 0, /**< Uninitialized Link Record */
- PointToPoint, /**< Record representing a point to point channel */
- TransitNetwork, /**< Unused -- for future OSPF compatibility */
- StubNetwork, /**< Record represents a leaf node network */
- VirtualLink /**< Unused -- for future OSPF compatibility */
- };
-
-/**
- * @brief Construct an empty ("uninitialized") Global Routing Link Record.
- *
- * The Link ID and Link Data Ipv4 addresses are set to "0.0.0.0";
- * The Link Type is set to Unknown;
- * The metric is set to 0.
- */
- GlobalRoutingLinkRecord ();
-
-/**
- * Construct an initialized Global Routing Link Record.
- *
- * @param linkType The type of link record to construct.
- * @param linkId The link ID for the record.
- * @param linkData The link data field for the record.
- * @param metric The metric field for the record.
- * @see LinkType
- * @see SetLinkId
- * @see SetLinkData
- */
- GlobalRoutingLinkRecord (
- LinkType linkType,
- Ipv4Address linkId,
- Ipv4Address linkData,
- uint16_t metric);
-
-/**
- * @brief Destroy a Global Routing Link Record.
- *
- * Currently does nothing. Here as a placeholder only.
- */
- ~GlobalRoutingLinkRecord ();
-
-/**
- * Get the Link ID field of the Global Routing Link Record.
- *
- * For an OSPF type 1 link (PointToPoint) the Link ID will be the Router ID
- * of the neighboring router.
- *
- * For an OSPF type 3 link (StubNetwork), the Link ID will be the adjacent
- * neighbor's IP address
- *
- * @returns The Ipv4Address corresponding to the Link ID field of the record.
- */
- Ipv4Address GetLinkId(void) const;
-
-/**
- * @brief Set the Link ID field of the Global Routing Link Record.
- *
- * For an OSPF type 1 link (PointToPoint) the Link ID must be the Router ID
- * of the neighboring router.
- *
- * For an OSPF type 3 link (StubNetwork), the Link ID must be the adjacent
- * neighbor's IP address
- *
- * @param addr An Ipv4Address to store in the Link ID field of the record.
- */
- void SetLinkId(Ipv4Address addr);
-
-/**
- * @brief Get the Link Data field of the Global Routing Link Record.
- *
- * For an OSPF type 1 link (PointToPoint) the Link Data will be the IP
- * address of the node of the local side of the link.
- *
- * For an OSPF type 3 link (StubNetwork), the Link Data will be the
- * network mask
- *
- * @returns The Ipv4Address corresponding to the Link Data field of the record.
- */
- Ipv4Address GetLinkData(void) const;
-
-/**
- * @brief Set the Link Data field of the Global Routing Link Record.
- *
- * For an OSPF type 1 link (PointToPoint) the Link Data must be the IP
- * address of the node of the local side of the link.
- *
- * For an OSPF type 3 link (StubNetwork), the Link Data must be set to the
- * network mask
- *
- * @param addr An Ipv4Address to store in the Link Data field of the record.
- */
- void SetLinkData(Ipv4Address addr);
-
-/**
- * @brief Get the Link Type field of the Global Routing Link Record.
- *
- * The Link Type describes the kind of link a given record represents. The
- * values are defined by OSPF.
- *
- * @see LinkType
- * @returns The LinkType of the current Global Routing Link Record.
- */
- LinkType GetLinkType(void) const;
-
-/**
- * @brief Set the Link Type field of the Global Routing Link Record.
- *
- * The Link Type describes the kind of link a given record represents. The
- * values are defined by OSPF.
- *
- * @see LinkType
- * @param linkType The new LinkType for the current Global Routing Link Record.
- */
- void SetLinkType(LinkType linkType);
-
-/**
- * @brief Get the Metric Data field of the Global Routing Link Record.
- *
- * The metric is an abstract cost associated with forwarding a packet across
- * a link. A sum of metrics must have a well-defined meaning. That is, you
- * shouldn't use bandwidth as a metric (how does the sum of the bandwidth of
- * two hops relate to the cost of sending a packet); rather you should use
- * something like delay.
- *
- * @returns The metric field of the Global Routing Link Record.
- */
- uint16_t GetMetric(void) const;
-
-/**
- * @brief Set the Metric Data field of the Global Routing Link Record.
- *
- * The metric is an abstract cost associated with forwarding a packet across
- * a link. A sum of metrics must have a well-defined meaning. That is, you
- * shouldn't use bandwidth as a metric (how does the sum of the bandwidth of
- * two hops relate to the cost of sending a packet); rather you should use
- * something like delay.
- *
- * @param metric The new metric for the current Global Routing Link Record.
- */
- void SetMetric(uint16_t metric);
-
-private:
-/**
- * m_linkId and m_linkData are defined by OSPF to have different meanings
- * depending on the type of link a given link records represents. They work
- * together.
- *
- * For Type 1 link (PointToPoint), set m_linkId to Router ID of
- * neighboring router.
- *
- * For Type 3 link (Stub), set m_linkId to neighbor's IP address
- */
- Ipv4Address m_linkId;
-
-/**
- * m_linkId and m_linkData are defined by OSPF to have different meanings
- * depending on the type of link a given link records represents. They work
- * together.
- *
- * For Type 1 link (PointToPoint), set m_linkData to local IP address
- *
- * For Type 3 link (Stub), set m_linkData to mask
- */
- Ipv4Address m_linkData; // for links to RouterLSA,
-
-/**
- * The type of the Global Routing Link Record. Defined in the OSPF spec.
- * We currently only use PointToPoint and StubNetwork types.
- */
- LinkType m_linkType;
-
-/**
- * The metric for a given link.
- *
- * A metric is abstract cost associated with forwarding a packet across a
- * link. A sum of metrics must have a well-defined meaning. That is, you
- * shouldn't use bandwidth as a metric (how does the sum of the bandwidth
- * of two hops relate to the cost of sending a packet); rather you should
- * use something like delay.
- */
- uint16_t m_metric;
-};
-
-/**
- * @brief a Link State Advertisement (LSA) for a router, used in global
- * routing.
- *
- * Roughly equivalent to a global incarnation of the OSPF link state header
- * combined with a list of Link Records. Since it's global, there's
- * no need for age or sequence number. See RFC 2328, Appendix A.
- */
-class GlobalRoutingLSA
-{
-public:
-/**
- * @enum LSType
- * @brief corresponds to LS type field of RFC 2328 OSPF LSA header
- */
- enum LSType {
- Unknown = 0, /**< Uninitialized Type */
- RouterLSA,
- NetworkLSA,
- SummaryLSA,
- SummaryLSA_ASBR,
- ASExternalLSAs
- };
-/**
- * @enum SPFStatus
- * @brief Enumeration of the possible values of the status flag in the Routing
- * Link State Advertisements.
- */
- enum SPFStatus {
- LSA_SPF_NOT_EXPLORED = 0, /**< New vertex not yet considered */
- LSA_SPF_CANDIDATE, /**< Vertex is in the SPF candidate queue */
- LSA_SPF_IN_SPFTREE /**< Vertex is in the SPF tree */
- };
-/**
- * @brief Create a blank Global Routing Link State Advertisement.
- *
- * On completion Ipv4Address variables initialized to 0.0.0.0 and the
- * list of Link State Records is empty.
- */
- GlobalRoutingLSA();
-
-/**
- * @brief Create an initialized Global Routing Link State Advertisement.
- *
- * On completion the list of Link State Records is empty.
- *
- * @param status The status to of the new LSA.
- * @param linkStateId The Ipv4Address for the link state ID field.
- * @param advertisingRtr The Ipv4Address for the advertising router field.
- */
- GlobalRoutingLSA(SPFStatus status, Ipv4Address linkStateId,
- Ipv4Address advertisingRtr);
-
-/**
- * @brief Copy constructor for a Global Routing Link State Advertisement.
- *
- * Takes a piece of memory and constructs a semantically identical copy of
- * the given LSA.
- *
- * @param lsa The existing LSA to be used as the source.
- */
- GlobalRoutingLSA (GlobalRoutingLSA& lsa);
-
-/**
- * @brief Destroy an existing Global Routing Link State Advertisement.
- *
- * Any Global Routing Link Records present in the list are freed.
- */
- ~GlobalRoutingLSA();
-
-/**
- * @brief Assignment operator for a Global Routing Link State Advertisement.
- *
- * Takes an existing Global Routing Link State Advertisement and overwrites
- * it to make a semantically identical copy of a given prototype LSA.
- *
- * If there are any Global Routing Link Records present in the existing
- * LSA, they are freed before the assignment happens.
- *
- * @param lsa The existing LSA to be used as the source.
- * @returns Reference to the overwritten LSA.
- */
- GlobalRoutingLSA& operator= (const GlobalRoutingLSA& lsa);
-
-/**
- * @brief Copy any Global Routing Link Records in a given Global Routing Link
- * State Advertisement to the current LSA.
- *
- * Existing Link Records are not deleted -- this is a concatenation of Link
- * Records.
- *
- * @see ClearLinkRecords ()
- * @param lsa The LSA to copy the Link Records from.
- */
- void CopyLinkRecords (const GlobalRoutingLSA& lsa);
-
-/**
- * @brief Add a given Global Routing Link Record to the LSA.
- *
- * @param lr The Global Routing Link Record to be added.
- * @returns The number of link records in the list.
- */
- uint32_t AddLinkRecord (GlobalRoutingLinkRecord* lr);
-
-/**
- * @brief Return the number of Global Routing Link Records in the LSA.
- *
- * @returns The number of link records in the list.
- */
- uint32_t GetNLinkRecords (void) const;
-
-/**
- * @brief Return a pointer to the specified Global Routing Link Record.
- *
- * @param n The LSA number desired.
- * @returns The number of link records in the list.
- */
- GlobalRoutingLinkRecord* GetLinkRecord (uint32_t n) const;
-
-/**
- * @brief Release all of the Global Routing Link Records present in the Global
- * Routing Link State Advertisement and make the list of link records empty.
- */
- void ClearLinkRecords(void);
-
-/**
- * @brief Check to see if the list of Global Routing Link Records present in the
- * Global Routing Link State Advertisement is empty.
- *
- * @returns True if the list is empty, false otherwise.
- */
- bool IsEmpty(void) const;
-
-/**
- * @brief Print the contents of the Global Routing Link State Advertisement and
- * any Global Routing Link Records present in the list. Quite verbose.
- */
- void Print (std::ostream &os) const;
-
-/**
- * @brief Return the LSType field of the LSA
- */
- LSType GetLSType (void) const;
-/**
- * @brief Set the LS type field of the LSA
- */
- void SetLSType (LSType typ);
-
-/**
- * @brief Get the Link State ID as defined by the OSPF spec. We always set it
- * to the router ID of the router making the advertisement.
- *
- * @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouting::GetRouterId ()
- * @returns The Ipv4Address stored as the link state ID.
- */
- Ipv4Address GetLinkStateId (void) const;
-
-/**
- * @brief Set the Link State ID is defined by the OSPF spec. We always set it
- * to the router ID of the router making the advertisement.
- * @param addr IPv4 address which will act as ID
- * @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouting::GetRouterId ()
- */
- void SetLinkStateId (Ipv4Address addr);
-
-/**
- * @brief Get the Advertising Router as defined by the OSPF spec. We always
- * set it to the router ID of the router making the advertisement.
- *
- * @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouting::GetRouterId ()
- * @returns The Ipv4Address stored as the advertising router.
- */
- Ipv4Address GetAdvertisingRouter (void) const;
-
-/**
- * @brief Set the Advertising Router as defined by the OSPF spec. We always
- * set it to the router ID of the router making the advertisement.
- *
- * @param rtr ID of the router making advertisement
- * @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouting::GetRouterId ()
- */
- void SetAdvertisingRouter (Ipv4Address rtr);
-
-/**
- * @brief For a Network LSA, set the Network Mask field that precedes
- * the list of attached routers.
- */
- void SetNetworkLSANetworkMask (Ipv4Mask mask);
-
-/**
- * @brief For a Network LSA, get the Network Mask field that precedes
- * the list of attached routers.
- *
- * @returns the NetworkLSANetworkMask
- */
- Ipv4Mask GetNetworkLSANetworkMask (void) const;
-
-/**
- * @brief Add an attached router to the list in the NetworkLSA
- *
- * @param addr The Ipv4Address of the interface on the network link
- * @returns The number of addresses in the list.
- */
- uint32_t AddAttachedRouter (Ipv4Address addr);
-
-/**
- * @brief Return the number of attached routers listed in the NetworkLSA
- *
- * @returns The number of attached routers.
- */
- uint32_t GetNAttachedRouters (void) const;
-
-/**
- * @brief Return an Ipv4Address corresponding to the specified attached router
- *
- * @param n The attached router number desired (number in the list).
- * @returns The Ipv4Address of the requested router
- */
- Ipv4Address GetAttachedRouter (uint32_t n) const;
-
-/**
- * @brief Get the SPF status of the advertisement.
- *
- * @see SPFStatus
- * @returns The SPFStatus of the LSA.
- */
- SPFStatus GetStatus (void) const;
-
-/**
- * @brief Set the SPF status of the advertisement
- * @param status SPF status to set
- * @see SPFStatus
- */
- void SetStatus (SPFStatus status);
-
-/**
- * @brief Get the Node pointer of the node that originated this LSA
- * @returns Node pointer
- */
- Ptr<Node> GetNode (void) const;
-
-/**
- * @brief Set the Node pointer of the node that originated this LSA
- * @param node Node pointer
- */
- void SetNode (Ptr<Node> node);
-
-private:
-/**
- * The type of the LSA. Each LSA type has a separate advertisement
- * format.
- */
- LSType m_lsType;
-/**
- * The Link State ID is defined by the OSPF spec. We always set it to the
- * router ID of the router making the advertisement.
- *
- * @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouting::GetRouterId ()
- */
- Ipv4Address m_linkStateId;
-
-/**
- * The Advertising Router is defined by the OSPF spec. We always set it to
- * the router ID of the router making the advertisement.
- *
- * @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouting::GetRouterId ()
- */
- Ipv4Address m_advertisingRtr;
-
-/**
- * A convenience typedef to avoid too much writers cramp.
- */
- typedef std::list<GlobalRoutingLinkRecord*> ListOfLinkRecords_t;
-
-/**
- * Each Link State Advertisement contains a number of Link Records that
- * describe the kinds of links that are attached to a given node. We
- * consider PointToPoint and StubNetwork links.
- *
- * m_linkRecords is an STL list container to hold the Link Records that have
- * been discovered and prepared for the advertisement.
- *
- * @see GlobalRouting::DiscoverLSAs ()
- */
- ListOfLinkRecords_t m_linkRecords;
-
-/**
- * Each Network LSA contains the network mask of the attached network
- */
- Ipv4Mask m_networkLSANetworkMask;
-
-/**
- * A convenience typedef to avoid too much writers cramp.
- */
- typedef std::list<Ipv4Address> ListOfAttachedRouters_t;
-
-/**
- * Each Network LSA contains a list of attached routers
- *
- * m_attachedRouters is an STL list container to hold the addresses that have
- * been discovered and prepared for the advertisement.
- *
- * @see GlobalRouting::DiscoverLSAs ()
- */
- ListOfAttachedRouters_t m_attachedRouters;
-
-/**
- * This is a tristate flag used internally in the SPF computation to mark
- * if an SPFVertex (a data structure representing a vertex in the SPF tree
- * -- a router) is new, is a candidate for a shortest path, or is in its
- * proper position in the tree.
- */
- SPFStatus m_status;
- uint32_t m_node_id;
-};
-
-std::ostream& operator<< (std::ostream& os, GlobalRoutingLSA& lsa);
-
-/**
- * @brief An interface aggregated to a node to provide global routing info
- *
- * An interface aggregated to a node that provides global routing information
- * to a global route manager. The presence of the interface indicates that
- * the node is a router. The interface is the mechanism by which the router
- * advertises its connections to neighboring routers. We're basically
- * allowing the route manager to query for link state advertisements.
- */
-class GlobalRouter : public Object
-{
-public:
-/**
- * @brief The Interface ID of the Global Router interface.
- *
- * @see Object::GetObject ()
- */
- static TypeId GetTypeId (void);
-
-/**
- * @brief Create a Global Router class
- */
- GlobalRouter ();
-
-
- void SetRoutingProtocol (Ptr<Ipv4GlobalRouting> routing);
- Ptr<Ipv4GlobalRouting> GetRoutingProtocol (void);
-
-/**
- * @brief Get the Router ID associated with this Global Router.
- *
- * The Router IDs are allocated in the RoutingEnvironment -- one per Router,
- * starting at 0.0.0.1 and incrementing with each instantiation of a router.
- *
- * @see RoutingEnvironment::AllocateRouterId ()
- * @returns The Router ID associated with the Global Router.
- */
- Ipv4Address GetRouterId (void) const;
-
-/**
- * @brief Walk the connected channels, discover the adjacent routers and build
- * the associated number of Global Routing Link State Advertisements that
- * this router can export.
- *
- * This is a fairly expensive operation in that every time it is called
- * the current list of LSAs is built by walking connected point-to-point
- * channels and peeking into adjacent IPV4 stacks to get address information.
- * This is done to allow for limited dynamics of the Global Routing
- * environment. By that we mean that you can discover new link state
- * advertisements after a network topology change by calling DiscoverLSAs
- * and then by reading those advertisements.
- *
- * @see GlobalRoutingLSA
- * @see GlobalRouter::GetLSA ()
- * @returns The number of Global Routing Link State Advertisements.
- */
- uint32_t DiscoverLSAs (void);
-
-/**
- * @brief Get the Number of Global Routing Link State Advertisements that this
- * router can export.
- *
- * To get meaningful information you must have previously called DiscoverLSAs.
- * After you know how many LSAs are present in the router, you may call
- * GetLSA () to retrieve the actual advertisement.
- *
- * @see GlobalRouterLSA
- * @see GlobalRouting::DiscoverLSAs ()
- * @see GlobalRouting::GetLSA ()
- * @returns The number of Global Routing Link State Advertisements.
- */
- uint32_t GetNumLSAs (void) const;
-
-/**
- * @brief Get a Global Routing Link State Advertisements that this router has
- * said that it can export.
- *
- * This is a fairly inexpensive expensive operation in that the hard work
- * was done in GetNumLSAs. We just copy the indicated Global Routing Link
- * State Advertisement into the requested GlobalRoutingLSA object.
- *
- * You must call GlobalRouter::GetNumLSAs before calling this method in
- * order to discover the adjacent routers and build the advertisements.
- * GetNumLSAs will return the number of LSAs this router advertises.
- * The parameter n (requested LSA number) must be in the range 0 to
- * GetNumLSAs() - 1.
- *
- * @see GlobalRoutingLSA
- * @see GlobalRouting::GetNumLSAs ()
- * @param n The index number of the LSA you want to read.
- * @param lsa The GlobalRoutingLSA class to receive the LSA information.
- * @returns The number of Global Router Link State Advertisements.
- */
- bool GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const;
-
-/**
- * @brief Inject a route to be circulated to other routers as an external
- * route
- *
- * @param network The Network to inject
- * @param networkMask The Network Mask to inject
- */
- void InjectRoute (Ipv4Address network, Ipv4Mask networkMask);
-
-/**
- * @brief Get the number of injected routes that have been added
- * to the routing table.
- * @return number of injected routes
- */
- uint32_t GetNInjectedRoutes (void);
-
-/**
- * @brief Return the injected route indexed by i
- * @param i the index of the route
- * @return a pointer to that Ipv4RoutingTableEntry is returned
- *
- */
- Ipv4RoutingTableEntry *GetInjectedRoute (uint32_t i);
-
-/**
- * @brief Withdraw a route from the global unicast routing table.
- *
- * Calling this function will cause all indexed routes numbered above
- * index i to have their index decremented. For instance, it is possible to
- * remove N injected routes by calling RemoveInjectedRoute (0) N times.
- *
- * @param i The index (into the injected routing list) of the route to remove.
- *
- * @see GlobalRouter::WithdrawRoute ()
- */
- void RemoveInjectedRoute (uint32_t i);
-
-/**
- * @brief Withdraw a route from the global unicast routing table.
- *
- * @param network The Network to withdraw
- * @param networkMask The Network Mask to withdraw
- * @return whether the operation succeeded (will return false if no such route)
- *
- * @see GlobalRouter::RemoveInjectedRoute ()
- */
- bool WithdrawRoute (Ipv4Address network, Ipv4Mask networkMask);
-
-private:
- virtual ~GlobalRouter ();
- void ClearLSAs (void);
-
- Ptr<NetDevice> GetAdjacent(Ptr<NetDevice> nd, Ptr<Channel> ch) const;
- bool FindInterfaceForDevice(Ptr<Node> node, Ptr<NetDevice> nd, uint32_t &index) const;
- Ipv4Address FindDesignatedRouterForLink (Ptr<NetDevice> ndLocal, bool allowRecursion) const;
- bool AnotherRouterOnLink (Ptr<NetDevice> nd, bool allowRecursion) const;
- void ProcessBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);
- void ProcessSingleBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);
- void ProcessBridgedBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);
-
- void ProcessPointToPointLink (Ptr<NetDevice> ndLocal, GlobalRoutingLSA *pLSA);
- void BuildNetworkLSAs (NetDeviceContainer c);
- Ptr<BridgeNetDevice> NetDeviceIsBridged (Ptr<NetDevice> nd) const;
-
-
- typedef std::list<GlobalRoutingLSA*> ListOfLSAs_t;
- ListOfLSAs_t m_LSAs;
-
- Ipv4Address m_routerId;
- Ptr<Ipv4GlobalRouting> m_routingProtocol;
-
- typedef std::list<Ipv4RoutingTableEntry *> InjectedRoutes;
- typedef std::list<Ipv4RoutingTableEntry *>::const_iterator InjectedRoutesCI;
- typedef std::list<Ipv4RoutingTableEntry *>::iterator InjectedRoutesI;
- InjectedRoutes m_injectedRoutes; // Routes we are exporting
-
- // inherited from Object
- virtual void DoDispose (void);
-
-/**
- * @brief Global Router copy construction is disallowed.
- */
- GlobalRouter (GlobalRouter& sr);
-
-/**
- * @brief Global Router assignment operator is disallowed.
- */
- GlobalRouter& operator= (GlobalRouter& sr);
-};
-
-} // namespace ns3
-
-#endif /* GLOBAL_ROUTER_INTERFACE_H */
--- a/src/routing/global-routing/global-routing.h Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright 2008 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/**
- * \ingroup routing
- * \defgroup globalrouting Global Routing
- *
- * \section model Model
- *
- * ns-3 global routing performs pre-simulation static route computation
- * on a layer-3 Ipv4 topology. The user API from the script level is
- * fairly minimal; once a topology has been constructed and addresses
- * assigned, the user may call ns3::GlobalRouteManager::PopulateRoutingTables()
- * and the simulator will initialize the routing database and set up
- * static unicast forwarding tables for each node.
- *
- * 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. 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.
- *
- * 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 two attributes of Ipv4GlobalRouting that govern behavior.
- * - Ipv4GlobalRouting::RandomEcmpRouting
- * - Ipv4GlobalRouting::RespondToInterfaceEvents
- *
- * \section impl Implementation
- *
- * A singleton object, ns3::GlobalRouteManager, builds a global routing
- * database of information about the topology, and executes a Dijkstra
- * Shortest Path First (SPF) algorithm on the topology for each node, and
- * stores the computed routes in each node's IPv4 forwarding table by
- * making use of the routing API in class ns3::Ipv4.
- *
- * The nodes that export data are those that have had an ns3::GlobalRouter
- * object aggregated to them. The ns3::GlobalRouter can be thought of
- * as a per-node agent that exports topology information to the
- * ns3::GlobalRouteManager. When it comes time to build the global
- * routing database, the list of nodes is iterated and each node with
- * an ns3::GlobalRouter object is asked to export routing information
- * concerning the links to which it is attached.
- *
- * The format of the data exported conforms to the OSPFv2 standard
- * (http://www.ietf.org/rfc/rfc2328.txt). In particular, the
- * information is exported in the form of ns3::GlobalLSA objects that
- * semantically match the Link State Advertisements of OSPF.
- *
- * By using a standard data format for reporting topology, existing
- * OSPF route computation code can be reused, and that is what is done
- * by the ns3::GlobalRouteManager. The main computation functions are
- * ported from the quagga routing suite (http://www.quagga.net).
- *
- */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/helper/ipv4-global-routing-helper.cc Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,74 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "ipv4-global-routing-helper.h"
+#include "ns3/global-router-interface.h"
+#include "ns3/ipv4-global-routing.h"
+#include "ns3/ipv4-list-routing.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE("GlobalRoutingHelper");
+
+namespace ns3 {
+
+Ipv4GlobalRoutingHelper::Ipv4GlobalRoutingHelper ()
+{}
+
+Ipv4GlobalRoutingHelper::Ipv4GlobalRoutingHelper (const Ipv4GlobalRoutingHelper &o)
+{
+}
+
+Ipv4GlobalRoutingHelper*
+Ipv4GlobalRoutingHelper::Copy (void) const
+{
+ return new Ipv4GlobalRoutingHelper (*this);
+}
+
+Ptr<Ipv4RoutingProtocol>
+Ipv4GlobalRoutingHelper::Create (Ptr<Node> node) const
+{
+ NS_LOG_LOGIC ("Adding GlobalRouter interface to node " <<
+ node->GetId ());
+
+ Ptr<GlobalRouter> globalRouter = CreateObject<GlobalRouter> ();
+ node->AggregateObject (globalRouter);
+
+ NS_LOG_LOGIC ("Adding GlobalRouting Protocol to node " << node->GetId ());
+ Ptr<Ipv4GlobalRouting> globalRouting = CreateObject<Ipv4GlobalRouting> ();
+ globalRouter->SetRoutingProtocol (globalRouting);
+
+ return globalRouting;
+}
+
+void
+Ipv4GlobalRoutingHelper::PopulateRoutingTables (void)
+{
+ GlobalRouteManager::BuildGlobalRoutingDatabase ();
+ GlobalRouteManager::InitializeRoutes ();
+}
+void
+Ipv4GlobalRoutingHelper::RecomputeRoutingTables (void)
+{
+ GlobalRouteManager::DeleteGlobalRoutes ();
+ GlobalRouteManager::BuildGlobalRoutingDatabase ();
+ GlobalRouteManager::InitializeRoutes ();
+}
+
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/helper/ipv4-global-routing-helper.h Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,97 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef IPV4_GLOBAL_ROUTING_HELPER_H
+#define IPV4_GLOBAL_ROUTING_HELPER_H
+
+#include "ns3/node-container.h"
+#include "ns3/ipv4-routing-helper.h"
+
+namespace ns3 {
+
+/**
+ * \brief Helper class that adds ns3::Ipv4GlobalRouting objects
+ */
+class Ipv4GlobalRoutingHelper : public Ipv4RoutingHelper
+{
+public:
+ /**
+ * \brief Construct a GlobalRoutingHelper to make life easier for managing
+ * global routing tasks.
+ */
+ Ipv4GlobalRoutingHelper ();
+
+ /**
+ * \brief Construct a GlobalRoutingHelper from another previously initialized
+ * instance (Copy Constructor).
+ */
+ Ipv4GlobalRoutingHelper (const Ipv4GlobalRoutingHelper &);
+
+ /**
+ * \internal
+ * \returns pointer to clone of this Ipv4GlobalRoutingHelper
+ *
+ * This method is mainly for internal use by the other helpers;
+ * clients are expected to free the dynamic memory allocated by this method
+ */
+ Ipv4GlobalRoutingHelper* Copy (void) const;
+
+ /**
+ * \param node the node on which the routing protocol will run
+ * \returns a newly-created routing protocol
+ *
+ * This method will be called by ns3::InternetStackHelper::Install
+ */
+ virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
+
+ /**
+ * \brief Build a routing database and initialize the routing tables of
+ * the nodes in the simulation. Makes all nodes in the simulation into
+ * routers.
+ *
+ * All this function does is call the functions
+ * BuildGlobalRoutingDatabase () and InitializeRoutes ().
+ *
+ */
+ static void PopulateRoutingTables (void);
+ /**
+ * \brief Remove all routes that were previously installed in a prior call
+ * to either PopulateRoutingTables() or RecomputeRoutingTables(), and
+ * add a new set of routes.
+ *
+ * This method does not change the set of nodes
+ * over which GlobalRouting is being used, but it will dynamically update
+ * its representation of the global topology before recomputing routes.
+ * Users must first call PopulateRoutingTables() and then may subsequently
+ * call RecomputeRoutingTables() at any later time in the simulation.
+ *
+ */
+ static void RecomputeRoutingTables (void);
+private:
+ /**
+ * \internal
+ * \brief Assignment operator declared private and not implemented to disallow
+ * assignment and prevent the compiler from happily inserting its own.
+ */
+ Ipv4GlobalRoutingHelper &operator = (const Ipv4GlobalRoutingHelper &o);
+};
+
+} // namespace ns3
+
+#endif /* IPV4_GLOBAL_ROUTING_HELPER_H */
--- a/src/routing/global-routing/ipv4-global-routing.cc Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,551 +0,0 @@
-// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2008 University of Washington
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-
-#include "ns3/log.h"
-#include "ns3/simulator.h"
-#include "ns3/object.h"
-#include "ns3/packet.h"
-#include "ns3/net-device.h"
-#include "ns3/ipv4-route.h"
-#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");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (Ipv4GlobalRouting);
-
-TypeId
-Ipv4GlobalRouting::GetTypeId (void)
-{
- static TypeId tid = TypeId ("ns3::Ipv4GlobalRouting")
- .SetParent<Object> ()
- .AddAttribute ("RandomEcmpRouting",
- "Set to true if packets are randomly routed among ECMP; set to false for using only one route consistently",
- 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_respondToInterfaceEvents (false)
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
-Ipv4GlobalRouting::~Ipv4GlobalRouting ()
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
-void
-Ipv4GlobalRouting::AddHostRouteTo (Ipv4Address dest,
- Ipv4Address nextHop,
- uint32_t interface)
-{
- NS_LOG_FUNCTION (dest << nextHop << interface);
- Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
- *route = Ipv4RoutingTableEntry::CreateHostRouteTo (dest, nextHop, interface);
- m_hostRoutes.push_back (route);
-}
-
-void
-Ipv4GlobalRouting::AddHostRouteTo (Ipv4Address dest,
- uint32_t interface)
-{
- NS_LOG_FUNCTION (dest << interface);
- Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
- *route = Ipv4RoutingTableEntry::CreateHostRouteTo (dest, interface);
- m_hostRoutes.push_back (route);
-}
-
-void
-Ipv4GlobalRouting::AddNetworkRouteTo (Ipv4Address network,
- Ipv4Mask networkMask,
- Ipv4Address nextHop,
- uint32_t interface)
-{
- NS_LOG_FUNCTION (network << networkMask << nextHop << interface);
- Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
- *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
- networkMask,
- nextHop,
- interface);
- m_networkRoutes.push_back (route);
-}
-
-void
-Ipv4GlobalRouting::AddNetworkRouteTo (Ipv4Address network,
- Ipv4Mask networkMask,
- uint32_t interface)
-{
- NS_LOG_FUNCTION (network << networkMask << interface);
- Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
- *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
- networkMask,
- interface);
- m_networkRoutes.push_back (route);
-}
-
-void
-Ipv4GlobalRouting::AddASExternalRouteTo (Ipv4Address network,
- Ipv4Mask networkMask,
- Ipv4Address nextHop,
- uint32_t interface)
-{
- NS_LOG_FUNCTION (network << networkMask << nextHop);
- Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
- *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
- networkMask,
- nextHop,
- interface);
- m_ASexternalRoutes.push_back (route);
-}
-
-
-Ptr<Ipv4Route>
-Ipv4GlobalRouting::LookupGlobal (Ipv4Address dest, Ptr<NetDevice> oif)
-{
- NS_LOG_FUNCTION_NOARGS ();
- NS_LOG_LOGIC ("Looking for route for destination " << dest);
- Ptr<Ipv4Route> rtentry = 0;
- // store all available routes that bring packets to their destination
- typedef std::vector<Ipv4RoutingTableEntry*> RouteVec_t;
- RouteVec_t allRoutes;
-
- NS_LOG_LOGIC ("Number of m_hostRoutes = " << m_hostRoutes.size ());
- for (HostRoutesCI i = m_hostRoutes.begin ();
- i != m_hostRoutes.end ();
- i++)
- {
- NS_ASSERT ((*i)->IsHost ());
- if ((*i)->GetDest ().IsEqual (dest))
- {
- if (oif != 0)
- {
- if (oif != m_ipv4->GetNetDevice((*i)->GetInterface ()))
- {
- NS_LOG_LOGIC ("Not on requested interface, skipping");
- continue;
- }
- }
- allRoutes.push_back (*i);
- NS_LOG_LOGIC (allRoutes.size () << "Found global host route" << *i);
- }
- }
- if (allRoutes.size () == 0) // if no host route is found
- {
- NS_LOG_LOGIC ("Number of m_networkRoutes" << m_networkRoutes.size ());
- for (NetworkRoutesI j = m_networkRoutes.begin ();
- j != m_networkRoutes.end ();
- j++)
- {
- Ipv4Mask mask = (*j)->GetDestNetworkMask ();
- Ipv4Address entry = (*j)->GetDestNetwork ();
- if (mask.IsMatch (dest, entry))
- {
- if (oif != 0)
- {
- if (oif != m_ipv4->GetNetDevice((*j)->GetInterface ()))
- {
- NS_LOG_LOGIC ("Not on requested interface, skipping");
- continue;
- }
- }
- allRoutes.push_back (*j);
- NS_LOG_LOGIC (allRoutes.size () << "Found global network route" << *j);
- }
- }
- }
- if (allRoutes.size () == 0) // consider external if no host/network found
- {
- for (ASExternalRoutesI k = m_ASexternalRoutes.begin ();
- k != m_ASexternalRoutes.end ();
- k++)
- {
- Ipv4Mask mask = (*k)->GetDestNetworkMask ();
- Ipv4Address entry = (*k)->GetDestNetwork ();
- if (mask.IsMatch (dest, entry))
- {
- NS_LOG_LOGIC ("Found external route" << *k);
- if (oif != 0)
- {
- if (oif != m_ipv4->GetNetDevice((*k)->GetInterface ()))
- {
- NS_LOG_LOGIC ("Not on requested interface, skipping");
- continue;
- }
- }
- allRoutes.push_back (*k);
- break;
- }
- }
- }
- if (allRoutes.size () > 0 ) // if route(s) is found
- {
- // pick up one of the routes uniformly at random if random
- // ECMP routing is enabled, or always select the first route
- // consistently if random ECMP routing is disabled
- uint32_t selectIndex;
- if (m_randomEcmpRouting)
- {
- selectIndex = m_rand.GetInteger (0, allRoutes.size ()-1);
- }
- else
- {
- selectIndex = 0;
- }
- Ipv4RoutingTableEntry* route = allRoutes.at (selectIndex);
- // create a Ipv4Route object from the selected routing table entry
- rtentry = Create<Ipv4Route> ();
- rtentry->SetDestination (route->GetDest ());
- // XXX handle multi-address case
- rtentry->SetSource (m_ipv4->GetAddress (route->GetInterface(), 0).GetLocal ());
- rtentry->SetGateway (route->GetGateway ());
- uint32_t interfaceIdx = route->GetInterface ();
- rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
- return rtentry;
- }
- else
- {
- return 0;
- }
-}
-
-uint32_t
-Ipv4GlobalRouting::GetNRoutes (void)
-{
- NS_LOG_FUNCTION_NOARGS ();
- uint32_t n = 0;
- n += m_hostRoutes.size ();
- n += m_networkRoutes.size ();
- n += m_ASexternalRoutes.size ();
- return n;
-}
-
-Ipv4RoutingTableEntry *
-Ipv4GlobalRouting::GetRoute (uint32_t index)
-{
- NS_LOG_FUNCTION (index);
- if (index < m_hostRoutes.size ())
- {
- uint32_t tmp = 0;
- for (HostRoutesCI i = m_hostRoutes.begin ();
- i != m_hostRoutes.end ();
- i++)
- {
- if (tmp == index)
- {
- return *i;
- }
- tmp++;
- }
- }
- index -= m_hostRoutes.size ();
- uint32_t tmp = 0;
- if (index < m_networkRoutes.size())
- {
- for (NetworkRoutesI j = m_networkRoutes.begin ();
- j != m_networkRoutes.end ();
- j++)
- {
- if (tmp == index)
- {
- return *j;
- }
- tmp++;
- }
- }
- index -= m_networkRoutes.size();
- tmp = 0;
- for (ASExternalRoutesI k = m_ASexternalRoutes.begin ();
- k != m_ASexternalRoutes.end ();
- k++)
- {
- if (tmp == index)
- {
- return *k;
- }
- tmp++;
- }
- NS_ASSERT (false);
- // quiet compiler.
- return 0;
-}
-void
-Ipv4GlobalRouting::RemoveRoute (uint32_t index)
-{
- NS_LOG_FUNCTION (index);
- if (index < m_hostRoutes.size ())
- {
- uint32_t tmp = 0;
- for (HostRoutesI i = m_hostRoutes.begin ();
- i != m_hostRoutes.end ();
- i++)
- {
- if (tmp == index)
- {
- NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_hostRoutes.size());
- delete *i;
- m_hostRoutes.erase (i);
- NS_LOG_LOGIC ("Done removing host route " << index << "; host route remaining size = " << m_hostRoutes.size());
- return;
- }
- tmp++;
- }
- }
- index -= m_hostRoutes.size ();
- uint32_t tmp = 0;
- for (NetworkRoutesI j = m_networkRoutes.begin ();
- j != m_networkRoutes.end ();
- j++)
- {
- if (tmp == index)
- {
- NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_networkRoutes.size());
- delete *j;
- m_networkRoutes.erase (j);
- NS_LOG_LOGIC ("Done removing network route " << index << "; network route remaining size = " << m_networkRoutes.size());
- return;
- }
- tmp++;
- }
- index -= m_networkRoutes.size ();
- tmp = 0;
- for (ASExternalRoutesI k = m_ASexternalRoutes.begin ();
- k != m_ASexternalRoutes.end ();
- k++)
- {
- if (tmp == index)
- {
- NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_ASexternalRoutes.size());
- delete *k;
- m_ASexternalRoutes.erase (k);
- NS_LOG_LOGIC ("Done removing network route " << index << "; network route remaining size = " << m_networkRoutes.size());
- return;
- }
- tmp++;
- }
- NS_ASSERT (false);
-}
-
-void
-Ipv4GlobalRouting::DoDispose (void)
-{
- NS_LOG_FUNCTION_NOARGS ();
- for (HostRoutesI i = m_hostRoutes.begin ();
- i != m_hostRoutes.end ();
- i = m_hostRoutes.erase (i))
- {
- delete (*i);
- }
- for (NetworkRoutesI j = m_networkRoutes.begin ();
- j != m_networkRoutes.end ();
- j = m_networkRoutes.erase (j))
- {
- delete (*j);
- }
- for (ASExternalRoutesI l = m_ASexternalRoutes.begin ();
- l != m_ASexternalRoutes.end ();
- l = m_ASexternalRoutes.erase (l))
- {
- delete (*l);
- }
-
- Ipv4RoutingProtocol::DoDispose ();
-}
-
-Ptr<Ipv4Route>
-Ipv4GlobalRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
-{
-
-//
-// 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.
-//
- if (header.GetDestination().IsMulticast ())
- {
- NS_LOG_LOGIC ("Multicast destination-- returning false");
- return 0; // Let other routing protocols try to handle this
- }
-//
-// 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);
- if (rtentry)
- {
- sockerr = Socket::ERROR_NOTERROR;
- }
- else
- {
- sockerr = Socket::ERROR_NOROUTETOHOST;
- }
- return rtentry;
-}
-
-bool
-Ipv4GlobalRouting::RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb,
- LocalDeliverCallback lcb, ErrorCallback ecb)
-{
-
- NS_LOG_FUNCTION (this << p << header << header.GetSource () << header.GetDestination () << idev);
- // Check if input device supports IP
- NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
- uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
-
- if (header.GetDestination ().IsMulticast ())
- {
- NS_LOG_LOGIC ("Multicast destination-- returning false");
- return false; // Let other routing protocols try to handle this
- }
-
- if (header.GetDestination ().IsBroadcast ())
- {
- NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)");
- // TODO: Local Deliver for broadcast
- // TODO: Forward broadcast
- }
-
- // TODO: Configurable option to enable RFC 1222 Strong End System Model
- // Right now, we will be permissive and allow a source to send us
- // a packet to one of our other interface addresses; that is, the
- // destination unicast address does not match one of the iif addresses,
- // but we check our other interfaces. This could be an option
- // (to remove the outer loop immediately below and just check iif).
- for (uint32_t j = 0; j < m_ipv4->GetNInterfaces (); j++)
- {
- for (uint32_t i = 0; i < m_ipv4->GetNAddresses (j); i++)
- {
- Ipv4InterfaceAddress iaddr = m_ipv4->GetAddress (j, i);
- Ipv4Address addr = iaddr.GetLocal ();
- if (addr.IsEqual (header.GetDestination ()))
- {
- if (j == iif)
- {
- NS_LOG_LOGIC ("For me (destination " << addr << " match)");
- }
- else
- {
- NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestination ());
- }
- lcb (p, header, iif);
- return true;
- }
- if (header.GetDestination ().IsEqual (iaddr.GetBroadcast ()))
- {
- NS_LOG_LOGIC ("For me (interface broadcast address)");
- lcb (p, header, iif);
- return true;
- }
- NS_LOG_LOGIC ("Address "<< addr << " not a match");
- }
- }
- // Check if input device supports IP forwarding
- if (m_ipv4->IsForwarding (iif) == false)
- {
- NS_LOG_LOGIC ("Forwarding disabled for this interface");
- ecb (p, header, Socket::ERROR_NOROUTETOHOST);
- return false;
- }
- // Next, try to find a route
- NS_LOG_LOGIC ("Unicast destination- looking up global route");
- Ptr<Ipv4Route> rtentry = LookupGlobal (header.GetDestination ());
- if (rtentry != 0)
- {
- NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
- ucb (rtentry, p, header);
- return true;
- }
- else
- {
- NS_LOG_LOGIC ("Did not find unicast destination- returning false");
- return false; // Let other routing protocols try to handle this
- // route request.
- }
-}
-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)
-{
- NS_LOG_FUNCTION(this << ipv4);
- NS_ASSERT (m_ipv4 == 0 && ipv4 != 0);
- m_ipv4 = ipv4;
-}
-
-
-}//namespace ns3
--- a/src/routing/global-routing/ipv4-global-routing.h Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,245 +0,0 @@
-// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2008 University of Washington
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-//
-
-#ifndef IPV4_GLOBAL_ROUTING_H
-#define IPV4_GLOBAL_ROUTING_H
-
-#include <list>
-#include <stdint.h>
-#include "ns3/ipv4-address.h"
-#include "ns3/ipv4-header.h"
-#include "ns3/ptr.h"
-#include "ns3/ipv4.h"
-#include "ns3/ipv4-routing-protocol.h"
-#include "ns3/random-variable.h"
-
-namespace ns3 {
-
-class Packet;
-class NetDevice;
-class Ipv4Interface;
-class Ipv4Address;
-class Ipv4Header;
-class Ipv4RoutingTableEntry;
-class Ipv4MulticastRoutingTableEntry;
-class Node;
-
-
-/**
- * \brief Global routing protocol for IP version 4 stacks.
- *
- * In ns-3 we have the concept of a pluggable routing protocol. Routing
- * protocols are added to a list maintained by the Ipv4L3Protocol. Every
- * stack gets one routing protocol for free -- the Ipv4StaticRouting routing
- * protocol is added in the constructor of the Ipv4L3Protocol (this is the
- * piece of code that implements the functionality of the IP layer).
- *
- * As an option to running a dynamic routing protocol, a GlobalRouteManager
- * object has been created to allow users to build routes for all participating
- * nodes. One can think of this object as a "routing oracle"; it has
- * an omniscient view of the topology, and can construct shortest path
- * routes between all pairs of nodes. These routes must be stored
- * somewhere in the node, so therefore this class Ipv4GlobalRouting
- * is used as one of the pluggable routing protocols. It is kept distinct
- * from Ipv4StaticRouting because these routes may be dynamically cleared
- * and rebuilt in the middle of the simulation, while manually entered
- * routes into the Ipv4StaticRouting may need to be kept distinct.
- *
- * This class deals with Ipv4 unicast routes only.
- *
- * \see Ipv4RoutingProtocol
- * \see GlobalRouteManager
- */
-class Ipv4GlobalRouting : public Ipv4RoutingProtocol
-{
-public:
- static TypeId GetTypeId (void);
-/**
- * \brief Construct an empty Ipv4GlobalRouting routing protocol,
- *
- * The Ipv4GlobalRouting class supports host and network unicast routes.
- * This method initializes the lists containing these routes to empty.
- *
- * \see Ipv4GlobalRouting
- */
- 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,
- UnicastForwardCallback ucb, MulticastForwardCallback mcb,
- LocalDeliverCallback lcb, ErrorCallback ecb);
- virtual void NotifyInterfaceUp (uint32_t interface);
- virtual void NotifyInterfaceDown (uint32_t interface);
- virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
- virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
- virtual void SetIpv4 (Ptr<Ipv4> ipv4);
-
-/**
- * \brief Add a host route to the global routing table.
- *
- * \param dest The Ipv4Address destination for this route.
- * \param nextHop The Ipv4Address of the next hop in the route.
- * \param interface The network interface index used to send packets to the
- * destination.
- *
- * \see Ipv4Address
- */
- void AddHostRouteTo (Ipv4Address dest,
- Ipv4Address nextHop,
- uint32_t interface);
-/**
- * \brief Add a host route to the global routing table.
- *
- * \param dest The Ipv4Address destination for this route.
- * \param interface The network interface index used to send packets to the
- * destination.
- *
- * \see Ipv4Address
- */
- void AddHostRouteTo (Ipv4Address dest,
- uint32_t interface);
-
-/**
- * \brief Add a network route to the global routing table.
- *
- * \param network The Ipv4Address network for this route.
- * \param networkMask The Ipv4Mask to extract the network.
- * \param nextHop The next hop in the route to the destination network.
- * \param interface The network interface index used to send packets to the
- * destination.
- *
- * \see Ipv4Address
- */
- void AddNetworkRouteTo (Ipv4Address network,
- Ipv4Mask networkMask,
- Ipv4Address nextHop,
- uint32_t interface);
-
-/**
- * \brief Add a network route to the global routing table.
- *
- * \param network The Ipv4Address network for this route.
- * \param networkMask The Ipv4Mask to extract the network.
- * \param interface The network interface index used to send packets to the
- * destination.
- *
- * \see Ipv4Address
- */
- void AddNetworkRouteTo (Ipv4Address network,
- Ipv4Mask networkMask,
- uint32_t interface);
-
-/**
- * \brief Add an external route to the global routing table.
- *
- * \param network The Ipv4Address network for this route.
- * \param networkMask The Ipv4Mask to extract the network.
- * \param nextHop The next hop Ipv4Address
- * \param interface The network interface index used to send packets to the
- * destination.
- */
- void AddASExternalRouteTo (Ipv4Address network,
- Ipv4Mask networkMask,
- Ipv4Address nextHop,
- uint32_t interface);
-
-/**
- * \brief Get the number of individual unicast routes that have been added
- * to the routing table.
- *
- * \warning The default route counts as one of the routes.
- */
- uint32_t GetNRoutes (void);
-
-/**
- * \brief Get a route from the global unicast routing table.
- *
- * Externally, the unicast global routing table appears simply as a table with
- * n entries. The one subtlety of note is that if a default route has been set
- * it will appear as the zeroth entry in the table. This means that if you
- * add only a default route, the table will have one entry that can be accessed
- * either by explicitly calling GetDefaultRoute () or by calling GetRoute (0).
- *
- * Similarly, if the default route has been set, calling RemoveRoute (0) will
- * remove the default route.
- *
- * \param i The index (into the routing table) of the route to retrieve. If
- * the default route has been set, it will occupy index zero.
- * \return If route is set, a pointer to that Ipv4RoutingTableEntry is returned, otherwise
- * a zero pointer is returned.
- *
- * \see Ipv4RoutingTableEntry
- * \see Ipv4GlobalRouting::RemoveRoute
- */
- Ipv4RoutingTableEntry *GetRoute (uint32_t i);
-
-/**
- * \brief Remove a route from the global unicast routing table.
- *
- * Externally, the unicast global routing table appears simply as a table with
- * n entries. The one subtlety of note is that if a default route has been set
- * it will appear as the zeroth entry in the table. This means that if the
- * default route has been set, calling RemoveRoute (0) will remove the
- * default route.
- *
- * \param i The index (into the routing table) of the route to remove. If
- * the default route has been set, it will occupy index zero.
- *
- * \see Ipv4RoutingTableEntry
- * \see Ipv4GlobalRouting::GetRoute
- * \see Ipv4GlobalRouting::AddRoute
- */
- void RemoveRoute (uint32_t i);
-
-protected:
- void DoDispose (void);
-
-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;
-
- typedef std::list<Ipv4RoutingTableEntry *> HostRoutes;
- typedef std::list<Ipv4RoutingTableEntry *>::const_iterator HostRoutesCI;
- typedef std::list<Ipv4RoutingTableEntry *>::iterator HostRoutesI;
- typedef std::list<Ipv4RoutingTableEntry *> NetworkRoutes;
- typedef std::list<Ipv4RoutingTableEntry *>::const_iterator NetworkRoutesCI;
- typedef std::list<Ipv4RoutingTableEntry *>::iterator NetworkRoutesI;
- typedef std::list<Ipv4RoutingTableEntry *> ASExternalRoutes;
- typedef std::list<Ipv4RoutingTableEntry *>::const_iterator ASExternalRoutesCI;
- typedef std::list<Ipv4RoutingTableEntry *>::iterator ASExternalRoutesI;
-
- Ptr<Ipv4Route> LookupGlobal (Ipv4Address dest, Ptr<NetDevice> oif = 0);
-
- HostRoutes m_hostRoutes;
- NetworkRoutes m_networkRoutes;
- ASExternalRoutes m_ASexternalRoutes; // External routes imported
-
- Ptr<Ipv4> m_ipv4;
-};
-
-} // Namespace ns3
-
-#endif /* IPV4_GLOBAL_ROUTING_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/candidate-queue.cc Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,193 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2007 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <algorithm>
+#include <iostream>
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "candidate-queue.h"
+#include "global-route-manager-impl.h"
+
+NS_LOG_COMPONENT_DEFINE ("CandidateQueue");
+
+namespace ns3 {
+
+std::ostream&
+operator<< (std::ostream& os, const SPFVertex::VertexType& t)
+{
+ switch (t)
+ {
+ case SPFVertex::VertexRouter: os << "router"; break;
+ case SPFVertex::VertexNetwork: os << "network"; break;
+ default: os << "unknown"; break;
+ };
+ return os;
+}
+
+std::ostream&
+operator<< (std::ostream& os, const CandidateQueue& q)
+{
+ typedef CandidateQueue::CandidateList_t List_t;
+ typedef List_t::const_iterator CIter_t;
+ const CandidateQueue::CandidateList_t& list = q.m_candidates;
+
+ os << "*** CandidateQueue Begin (<id, distance, LSA-type>) ***" << std::endl;
+ for (CIter_t iter = list.begin (); iter != list.end (); iter++)
+ {
+ os << "<"
+ << (*iter)->GetVertexId () << ", "
+ << (*iter)->GetDistanceFromRoot () << ", "
+ << (*iter)->GetVertexType () << ">" << std::endl;
+ }
+ os << "*** CandidateQueue End ***";
+ return os;
+}
+
+CandidateQueue::CandidateQueue()
+ : m_candidates ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+CandidateQueue::~CandidateQueue()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Clear ();
+}
+
+ void
+CandidateQueue::Clear (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ while (!m_candidates.empty ())
+ {
+ SPFVertex *p = Pop ();
+ delete p;
+ p = 0;
+ }
+}
+
+ void
+CandidateQueue::Push (SPFVertex *vNew)
+{
+ NS_LOG_FUNCTION (this << vNew);
+
+ CandidateList_t::iterator i = std::upper_bound (
+ m_candidates.begin (), m_candidates.end (), vNew,
+ &CandidateQueue::CompareSPFVertex
+ );
+ m_candidates.insert (i, vNew);
+}
+
+ SPFVertex *
+CandidateQueue::Pop (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ if (m_candidates.empty ())
+ {
+ return 0;
+ }
+
+ SPFVertex *v = m_candidates.front ();
+ m_candidates.pop_front ();
+ return v;
+}
+
+ SPFVertex *
+CandidateQueue::Top (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ if (m_candidates.empty ())
+ {
+ return 0;
+ }
+
+ return m_candidates.front ();
+}
+
+ bool
+CandidateQueue::Empty (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_candidates.empty ();
+}
+
+ uint32_t
+CandidateQueue::Size (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_candidates.size ();
+}
+
+ SPFVertex *
+CandidateQueue::Find (const Ipv4Address addr) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ CandidateList_t::const_iterator i = m_candidates.begin ();
+
+ for (; i != m_candidates.end (); i++)
+ {
+ SPFVertex *v = *i;
+ if (v->GetVertexId() == addr)
+ {
+ return v;
+ }
+ }
+
+ return 0;
+}
+
+ void
+CandidateQueue::Reorder (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ m_candidates.sort (&CandidateQueue::CompareSPFVertex);
+ NS_LOG_LOGIC ("After reordering the CandidateQueue");
+ NS_LOG_LOGIC (*this);
+}
+
+/*
+ * In this implementation, SPFVertex follows the ordering where
+ * a vertex is ranked first if its GetDistanceFromRoot () is smaller;
+ * In case of a tie, NetworkLSA is always ranked before RouterLSA.
+ *
+ * This ordering is necessary for implementing ECMP
+ */
+bool
+CandidateQueue::CompareSPFVertex (const SPFVertex* v1, const SPFVertex* v2)
+{
+ NS_LOG_FUNCTION (&v1 << &v2);
+
+ bool result = false;
+ if (v1->GetDistanceFromRoot () < v2->GetDistanceFromRoot ())
+ {
+ result = true;
+ }
+ else if (v1->GetDistanceFromRoot () == v2->GetDistanceFromRoot ())
+ {
+ if (v1->GetVertexType () == SPFVertex::VertexNetwork
+ && v2->GetVertexType () == SPFVertex::VertexRouter)
+ {
+ result = true;
+ }
+ }
+ return result;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/candidate-queue.h Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,200 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2007 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Craig Dowell (craigdo@ee.washington.edu)
+ */
+
+#ifndef CANDIDATE_QUEUE_H
+#define CANDIDATE_QUEUE_H
+
+#include <stdint.h>
+#include <list>
+#include "ns3/ipv4-address.h"
+
+namespace ns3 {
+
+class SPFVertex;
+
+/**
+ * \brief A Candidate Queue used in static routing.
+ *
+ * The CandidateQueue is used in the OSPF shortest path computations. It
+ * is a priority queue used to store candidates for the shortest path to a
+ * given network.
+ *
+ * The queue holds Shortest Path First Vertex pointers and orders them
+ * according to the lowest value of the field m_distanceFromRoot. Remaining
+ * vertices are ordered according to increasing distance. This implements a
+ * priority queue.
+ *
+ * Although a STL priority_queue almost does what we want, the requirement
+ * for a Find () operation, the dynamic nature of the data and the derived
+ * requirement for a Reorder () operation led us to implement this simple
+ * enhanced priority queue.
+ */
+class CandidateQueue
+{
+public:
+/**
+ * @brief Create an empty SPF Candidate Queue.
+ * @internal
+ *
+ * @see SPFVertex
+ */
+ CandidateQueue ();
+
+/**
+ * @internal Destroy an SPF Candidate Queue and release any resources held
+ * by the contents.
+ * @internal
+ *
+ * @see SPFVertex
+ */
+ virtual ~CandidateQueue ();
+
+/**
+ * @brief Empty the Candidate Queue and release all of the resources
+ * associated with the Shortest Path First Vertex pointers in the queue.
+ * @internal
+ *
+ * @see SPFVertex
+ */
+ void Clear (void);
+
+/**
+ * @brief Push a Shortest Path First Vertex pointer onto the queue according
+ * to the priority scheme.
+ * @internal
+ *
+ * On completion, the top of the queue will hold the Shortest Path First
+ * Vertex pointer that points to a vertex having lowest value of the field
+ * m_distanceFromRoot. Remaining vertices are ordered according to
+ * increasing distance.
+ *
+ * @see SPFVertex
+ * @param vNew The Shortest Path First Vertex to add to the queue.
+ */
+ void Push (SPFVertex *vNew);
+
+/**
+ * @brief Pop the Shortest Path First Vertex pointer at the top of the queue.
+ * @internal
+ *
+ * The caller is given the responsibility for releasing the resources
+ * associated with the vertex.
+ *
+ * @see SPFVertex
+ * @see Top ()
+ * @returns The Shortest Path First Vertex pointer at the top of the queue.
+ */
+ SPFVertex* Pop (void);
+
+/**
+ * @brief Return the Shortest Path First Vertex pointer at the top of the
+ * queue.
+ * @internal
+ *
+ * This method does not pop the SPFVertex* off of the queue, it simply
+ * returns the pointer.
+ *
+ * @see SPFVertex
+ * @see Pop ()
+ * @returns The Shortest Path First Vertex pointer at the top of the queue.
+ */
+ SPFVertex* Top (void) const;
+
+/**
+ * @brief Test the Candidate Queue to determine if it is empty.
+ * @internal
+ *
+ * @returns True if the queue is empty, false otherwise.
+ */
+ bool Empty (void) const;
+
+/**
+ * @brief Return the number of Shortest Path First Vertex pointers presently
+ * stored in the Candidate Queue.
+ * @internal
+ *
+ * @see SPFVertex
+ * @returns The number of SPFVertex* pointers in the Candidate Queue.
+ */
+ uint32_t Size (void) const;
+
+/**
+ * @brief Searches the Candidate Queue for a Shortest Path First Vertex
+ * pointer that points to a vertex having the given IP address.
+ * @internal
+ *
+ * @see SPFVertex
+ * @param addr The IP address to search for.
+ * @returns The SPFVertex* pointer corresponding to the given IP address.
+ */
+ SPFVertex* Find (const Ipv4Address addr) const;
+
+/**
+ * @brief Reorders the Candidate Queue according to the priority scheme.
+ * @internal
+ *
+ * On completion, the top of the queue will hold the Shortest Path First
+ * Vertex pointer that points to a vertex having lowest value of the field
+ * m_distanceFromRoot. Remaining vertices are ordered according to
+ * increasing distance.
+ *
+ * This method is provided in case the values of m_distanceFromRoot change
+ * during the routing calculations.
+ *
+ * @see SPFVertex
+ */
+ void Reorder (void);
+
+private:
+/**
+ * Candidate Queue copy construction is disallowed (not implemented) to
+ * prevent the compiler from slipping in incorrect versions that don't
+ * properly deal with deep copies.
+ * \param sr object to copy
+ */
+ CandidateQueue (CandidateQueue& sr);
+
+/**
+ * Candidate Queue assignment operator is disallowed (not implemented) to
+ * prevent the compiler from slipping in incorrect versions that don't
+ * properly deal with deep copies.
+ * \param sr object to assign
+ */
+ CandidateQueue& operator= (CandidateQueue& sr);
+/**
+ * \brief return true if v1 < v2
+ *
+ * SPFVertexes are added into the queue according to the ordering
+ * defined by this method. If v1 should be popped before v2, this
+ * method return true; false otherwise
+ *
+ * \return True if v1 should be popped before v2; false otherwise
+ */
+ static bool CompareSPFVertex (const SPFVertex* v1, const SPFVertex* v2);
+
+ typedef std::list<SPFVertex*> CandidateList_t;
+ CandidateList_t m_candidates;
+
+ friend std::ostream& operator<< (std::ostream& os, const CandidateQueue& q);
+};
+
+} // namespace ns3
+
+#endif /* CANDIDATE_QUEUE_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/global-route-manager-impl.cc Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,2402 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2007 University of Washington
+ * Copyright (C) 1999, 2000 Kunihiro Ishiguro, Toshiaki Takada
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors: Tom Henderson (tomhend@u.washington.edu)
+ *
+ * Kunihiro Ishigura, Toshiaki Takada (GNU Zebra) are attributed authors
+ * of the quagga 0.99.7/src/ospfd/ospf_spf.c code which was ported here
+ */
+
+#include <utility>
+#include <vector>
+#include <queue>
+#include <algorithm>
+#include <iostream>
+#include "ns3/assert.h"
+#include "ns3/fatal-error.h"
+#include "ns3/log.h"
+#include "ns3/node-list.h"
+#include "ns3/ipv4.h"
+#include "ns3/ipv4-routing-protocol.h"
+#include "ns3/ipv4-list-routing.h"
+#include "ns3/mpi-interface.h"
+#include "global-router-interface.h"
+#include "global-route-manager-impl.h"
+#include "candidate-queue.h"
+#include "ipv4-global-routing.h"
+
+NS_LOG_COMPONENT_DEFINE ("GlobalRouteManager");
+
+namespace ns3 {
+
+std::ostream&
+operator<< (std::ostream& os, const SPFVertex::NodeExit_t& exit)
+{
+ os << "(" << exit.first << " ," << exit.second << ")";
+ return os;
+}
+
+std::ostream&
+operator<< (std::ostream& os, const SPFVertex::ListOfSPFVertex_t& vs)
+{
+ typedef SPFVertex::ListOfSPFVertex_t::const_iterator CIter_t;
+ os << "{";
+ for (CIter_t iter = vs.begin (); iter != vs.end ();)
+ {
+ os << (*iter)->m_vertexId;
+ if (++iter != vs.end ())
+ {
+ os << ", ";
+ }
+ else
+ {
+ break;
+ }
+ }
+ os << "}";
+ return os;
+}
+
+// ---------------------------------------------------------------------------
+//
+// SPFVertex Implementation
+//
+// ---------------------------------------------------------------------------
+
+SPFVertex::SPFVertex () :
+ m_vertexType (VertexUnknown),
+ m_vertexId ("255.255.255.255"),
+ m_lsa (0),
+ m_distanceFromRoot (SPF_INFINITY),
+ m_rootOif (SPF_INFINITY),
+ m_nextHop ("0.0.0.0"),
+ m_parents (),
+ m_children (),
+ m_vertexProcessed (false)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+SPFVertex::SPFVertex (GlobalRoutingLSA* lsa) :
+ m_vertexId (lsa->GetLinkStateId ()),
+ m_lsa (lsa),
+ m_distanceFromRoot (SPF_INFINITY),
+ m_rootOif (SPF_INFINITY),
+ m_nextHop ("0.0.0.0"),
+ m_parents (),
+ m_children (),
+ m_vertexProcessed (false)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ if (lsa->GetLSType () == GlobalRoutingLSA::RouterLSA)
+ {
+ NS_LOG_LOGIC ("Setting m_vertexType to VertexRouter");
+ m_vertexType = SPFVertex::VertexRouter;
+ }
+ else if (lsa->GetLSType () == GlobalRoutingLSA::NetworkLSA)
+ {
+ NS_LOG_LOGIC ("Setting m_vertexType to VertexNetwork");
+ m_vertexType = SPFVertex::VertexNetwork;
+ }
+}
+
+SPFVertex::~SPFVertex ()
+{
+ NS_LOG_FUNCTION (m_vertexId);
+
+ NS_LOG_LOGIC ("Children vertices - " << m_children);
+ NS_LOG_LOGIC ("Parent verteices - " << m_parents);
+
+ // find this node from all its parents and remove the entry of this node
+ // from all its parents
+ for (ListOfSPFVertex_t::iterator piter = m_parents.begin ();
+ piter != m_parents.end ();
+ piter++)
+ {
+ // remove the current vertex from its parent's children list. Check
+ // if the size of the list is reduced, or the child<->parent relation
+ // is not bidirectional
+ uint32_t orgCount = (*piter)->m_children.size ();
+ (*piter)->m_children.remove (this);
+ uint32_t newCount = (*piter)->m_children.size ();
+ if (orgCount > newCount)
+ {
+ NS_ASSERT_MSG (orgCount > newCount, "Unable to find the current vertex from its parents --- impossible!");
+ }
+ }
+
+ // delete children
+ while (m_children.size () > 0)
+ {
+ // pop out children one by one. Some children may disapper
+ // when deleting some other children in the list. As a result,
+ // it is necessary to use pop to walk through all children, instead
+ // of using iterator.
+ //
+ // Note that m_children.pop_front () is not necessary as this
+ // p is removed from the children list when p is deleted
+ SPFVertex* p = m_children.front ();
+ // 'p' == 0, this child is already deleted by its other parent
+ if (p == 0) continue;
+ NS_LOG_LOGIC ("Parent vertex-" << m_vertexId << " deleting its child vertex-" << p->GetVertexId ());
+ delete p;
+ p = 0;
+ }
+ m_children.clear ();
+ // delete parents
+ m_parents.clear ();
+ // delete root exit direction
+ m_ecmpRootExits.clear ();
+
+ NS_LOG_LOGIC ("Vertex-" << m_vertexId << " completed deleted");
+}
+
+ void
+SPFVertex::SetVertexType (SPFVertex::VertexType type)
+{
+ NS_LOG_FUNCTION (type);
+ m_vertexType = type;
+}
+
+ SPFVertex::VertexType
+SPFVertex::GetVertexType (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_vertexType;
+}
+
+ void
+SPFVertex::SetVertexId (Ipv4Address id)
+{
+ NS_LOG_FUNCTION (id);
+ m_vertexId = id;
+}
+
+ Ipv4Address
+SPFVertex::GetVertexId (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_vertexId;
+}
+
+ void
+SPFVertex::SetLSA (GlobalRoutingLSA* lsa)
+{
+ NS_LOG_FUNCTION (lsa);
+ m_lsa = lsa;
+}
+
+ GlobalRoutingLSA*
+SPFVertex::GetLSA (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_lsa;
+}
+
+ void
+SPFVertex::SetDistanceFromRoot (uint32_t distance)
+{
+ NS_LOG_FUNCTION (distance);
+ m_distanceFromRoot = distance;
+}
+
+ uint32_t
+SPFVertex::GetDistanceFromRoot (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_distanceFromRoot;
+}
+
+ void
+SPFVertex::SetParent (SPFVertex* parent)
+{
+ NS_LOG_FUNCTION (parent);
+
+ // always maintain only one parent when using setter/getter methods
+ m_parents.clear ();
+ m_parents.push_back (parent);
+}
+
+ SPFVertex*
+SPFVertex::GetParent (uint32_t i) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ // If the index i is out-of-range, return 0 and do nothing
+ if (m_parents.size () <= i)
+ {
+ NS_LOG_LOGIC ("Index to SPFVertex's parent is out-of-range.");
+ return 0;
+ }
+ ListOfSPFVertex_t::const_iterator iter = m_parents.begin ();
+ while (i-- > 0)
+ {
+ iter++;
+ }
+ return *iter;
+}
+
+void
+SPFVertex::MergeParent (const SPFVertex* v)
+{
+ NS_LOG_FUNCTION (v);
+
+ NS_LOG_LOGIC ("Before merge, list of parents = " << m_parents);
+ // combine the two lists first, and then remove any duplicated after
+ m_parents.insert (m_parents.end (),
+ v->m_parents.begin (), v->m_parents.end ());
+ // remove duplication
+ m_parents.sort ();
+ m_parents.unique ();
+ NS_LOG_LOGIC ("After merge, list of parents = " << m_parents);
+}
+
+void
+SPFVertex::SetRootExitDirection (Ipv4Address nextHop, int32_t id)
+{
+ NS_LOG_FUNCTION (nextHop << id);
+
+ // always maintain only one root's exit
+ m_ecmpRootExits.clear ();
+ m_ecmpRootExits.push_back (NodeExit_t (nextHop, id));
+ // update the following in order to be backward compatitable with
+ // GetNextHop and GetOutgoingInterface methods
+ m_nextHop = nextHop;
+ m_rootOif = id;
+}
+
+void
+SPFVertex::SetRootExitDirection (SPFVertex::NodeExit_t exit)
+{
+ NS_LOG_FUNCTION (exit);
+ SetRootExitDirection (exit.first, exit.second);
+}
+
+SPFVertex::NodeExit_t
+SPFVertex::GetRootExitDirection (uint32_t i) const
+{
+ NS_LOG_FUNCTION (i);
+ typedef ListOfNodeExit_t::const_iterator CIter_t;
+
+ NS_ASSERT_MSG (i < m_ecmpRootExits.size (), "Index out-of-range when accessing SPFVertex::m_ecmpRootExits!");
+ CIter_t iter = m_ecmpRootExits.begin ();
+ while (i-- > 0) {iter++;}
+
+ return *iter;
+}
+
+SPFVertex::NodeExit_t
+SPFVertex::GetRootExitDirection () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ NS_ASSERT_MSG (m_ecmpRootExits.size () <= 1, "Assumed there is at most one exit from the root to this vertex");
+ return GetRootExitDirection (0);
+}
+
+void
+SPFVertex::MergeRootExitDirections (const SPFVertex* vertex)
+{
+ NS_LOG_FUNCTION (vertex);
+
+ // obtain the external list of exit directions
+ //
+ // Append the external list into 'this' and remove duplication afterward
+ const ListOfNodeExit_t& extList = vertex->m_ecmpRootExits;
+ m_ecmpRootExits.insert (m_ecmpRootExits.end (),
+ extList.begin(), extList.end ());
+ m_ecmpRootExits.sort ();
+ m_ecmpRootExits.unique ();
+}
+
+void
+SPFVertex::InheritAllRootExitDirections (const SPFVertex* vertex)
+{
+ NS_LOG_FUNCTION (vertex);
+
+ // discard all exit direction currently associated with this vertex,
+ // and copy all the exit directions from the given vertex
+ if (m_ecmpRootExits.size () > 0)
+ {
+ NS_LOG_WARN ("x root exit directions in this vertex are going to be discarded");
+ }
+ m_ecmpRootExits.clear ();
+ m_ecmpRootExits.insert (m_ecmpRootExits.end (),
+ vertex->m_ecmpRootExits.begin (), vertex->m_ecmpRootExits.end ());
+}
+
+uint32_t
+SPFVertex::GetNRootExitDirections () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_ecmpRootExits.size ();
+}
+
+uint32_t
+SPFVertex::GetNChildren (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_children.size ();
+}
+
+ SPFVertex*
+SPFVertex::GetChild (uint32_t n) const
+{
+ NS_LOG_FUNCTION (n);
+ uint32_t j = 0;
+
+ for ( ListOfSPFVertex_t::const_iterator i = m_children.begin ();
+ i != m_children.end ();
+ i++, j++)
+ {
+ if (j == n)
+ {
+ return *i;
+ }
+ }
+ NS_ASSERT_MSG (false, "Index <n> out of range.");
+ return 0;
+}
+
+ uint32_t
+SPFVertex::AddChild (SPFVertex* child)
+{
+ NS_LOG_FUNCTION (child);
+ m_children.push_back (child);
+ return m_children.size ();
+}
+
+void
+SPFVertex::SetVertexProcessed (bool value)
+{
+ m_vertexProcessed = value;
+}
+
+bool
+SPFVertex::IsVertexProcessed (void) const
+{
+ return m_vertexProcessed;
+}
+
+void
+SPFVertex::ClearVertexProcessed (void)
+{
+ for (uint32_t i = 0; i < this->GetNChildren (); i++)
+ {
+ this->GetChild (i)->ClearVertexProcessed ();
+ }
+ this->SetVertexProcessed (false);
+}
+
+// ---------------------------------------------------------------------------
+//
+// GlobalRouteManagerLSDB Implementation
+//
+// ---------------------------------------------------------------------------
+
+GlobalRouteManagerLSDB::GlobalRouteManagerLSDB ()
+:
+ m_database (),
+ m_extdatabase ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ LSDBMap_t::iterator i;
+ for (i= m_database.begin (); i!= m_database.end (); i++)
+ {
+ NS_LOG_LOGIC ("free LSA");
+ GlobalRoutingLSA* temp = i->second;
+ delete temp;
+ }
+ for (uint32_t j = 0; j < m_extdatabase.size (); j++)
+ {
+ NS_LOG_LOGIC ("free ASexternalLSA");
+ GlobalRoutingLSA* temp = m_extdatabase.at (j);
+ delete temp;
+ }
+ NS_LOG_LOGIC ("clear map");
+ m_database.clear ();
+}
+
+ void
+GlobalRouteManagerLSDB::Initialize ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ LSDBMap_t::iterator i;
+ for (i= m_database.begin (); i!= m_database.end (); i++)
+ {
+ GlobalRoutingLSA* temp = i->second;
+ temp->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
+ }
+}
+
+ void
+GlobalRouteManagerLSDB::Insert (Ipv4Address addr, GlobalRoutingLSA* lsa)
+{
+ NS_LOG_FUNCTION (addr << lsa);
+ if (lsa->GetLSType () == GlobalRoutingLSA::ASExternalLSAs)
+ {
+ m_extdatabase.push_back (lsa);
+ }
+ else
+ {
+ m_database.insert (LSDBPair_t (addr, lsa));
+ }
+}
+
+ GlobalRoutingLSA*
+GlobalRouteManagerLSDB::GetExtLSA (uint32_t index) const
+{
+ return m_extdatabase.at (index);
+}
+
+ uint32_t
+GlobalRouteManagerLSDB::GetNumExtLSAs () const
+{
+ return m_extdatabase.size ();
+}
+
+ GlobalRoutingLSA*
+GlobalRouteManagerLSDB::GetLSA (Ipv4Address addr) const
+{
+ NS_LOG_FUNCTION (addr);
+//
+// Look up an LSA by its address.
+//
+ LSDBMap_t::const_iterator i;
+ for (i= m_database.begin (); i!= m_database.end (); i++)
+ {
+ if (i->first == addr)
+ {
+ return i->second;
+ }
+ }
+ return 0;
+}
+
+ GlobalRoutingLSA*
+GlobalRouteManagerLSDB::GetLSAByLinkData (Ipv4Address addr) const
+{
+ NS_LOG_FUNCTION (addr);
+//
+// Look up an LSA by its address.
+//
+ LSDBMap_t::const_iterator i;
+ for (i= m_database.begin (); i!= m_database.end (); i++)
+ {
+ GlobalRoutingLSA* temp = i->second;
+// Iterate among temp's Link Records
+ for (uint32_t j = 0; j < temp->GetNLinkRecords (); j++)
+ {
+ GlobalRoutingLinkRecord *lr = temp->GetLinkRecord (j);
+ if ( lr->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork &&
+ lr->GetLinkData () == addr)
+ {
+ return temp;
+ }
+ }
+ }
+ return 0;
+}
+
+// ---------------------------------------------------------------------------
+//
+// GlobalRouteManagerImpl Implementation
+//
+// ---------------------------------------------------------------------------
+
+GlobalRouteManagerImpl::GlobalRouteManagerImpl ()
+:
+ m_spfroot (0)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_lsdb = new GlobalRouteManagerLSDB ();
+}
+
+GlobalRouteManagerImpl::~GlobalRouteManagerImpl ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ if (m_lsdb)
+ {
+ delete m_lsdb;
+ }
+}
+
+ void
+GlobalRouteManagerImpl::DebugUseLsdb (GlobalRouteManagerLSDB* lsdb)
+{
+ NS_LOG_FUNCTION (lsdb);
+ if (m_lsdb)
+ {
+ delete m_lsdb;
+ }
+ m_lsdb = lsdb;
+}
+
+ void
+GlobalRouteManagerImpl::DeleteGlobalRoutes ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ NodeList::Iterator listEnd = NodeList::End ();
+ for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
+ {
+ Ptr<Node> node = *i;
+ Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
+ if (router == 0)
+ {
+ continue;
+ }
+ Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
+ uint32_t j = 0;
+ uint32_t nRoutes = gr->GetNRoutes ();
+ NS_LOG_LOGIC ("Deleting " << gr->GetNRoutes ()<< " routes from node " << node->GetId ());
+ // Each time we delete route 0, the route index shifts downward
+ // We can delete all routes if we delete the route numbered 0
+ // nRoutes times
+ for (j = 0; j < nRoutes; j++)
+ {
+ NS_LOG_LOGIC ("Deleting global route " << j << " from node " << node->GetId ());
+ gr->RemoveRoute (0);
+ }
+ NS_LOG_LOGIC ("Deleted " << j << " global routes from node "<< node->GetId ());
+ }
+ if (m_lsdb)
+ {
+ NS_LOG_LOGIC ("Deleting LSDB, creating new one");
+ delete m_lsdb;
+ m_lsdb = new GlobalRouteManagerLSDB ();
+ }
+}
+
+//
+// In order to build the routing database, we need to walk the list of nodes
+// in the system and look for those that support the GlobalRouter interface.
+// These routers will export a number of Link State Advertisements (LSAs)
+// that describe the links and networks that are "adjacent" (i.e., that are
+// on the other side of a point-to-point link). We take these LSAs and put
+// add them to the Link State DataBase (LSDB) from which the routes will
+// ultimately be computed.
+//
+ void
+GlobalRouteManagerImpl::BuildGlobalRoutingDatabase ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+//
+// Walk the list of nodes looking for the GlobalRouter Interface. Nodes with
+// global router interfaces are, not too surprisingly, our routers.
+//
+ NodeList::Iterator listEnd = NodeList::End ();
+ for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
+ {
+ Ptr<Node> node = *i;
+
+ Ptr<GlobalRouter> rtr = node->GetObject<GlobalRouter> ();
+//
+// Ignore nodes that aren't participating in routing.
+//
+ if (!rtr)
+ {
+ continue;
+ }
+//
+// You must call DiscoverLSAs () before trying to use any routing info or to
+// update LSAs. DiscoverLSAs () drives the process of discovering routes in
+// the GlobalRouter. Afterward, you may use GetNumLSAs (), which is a very
+// computationally inexpensive call. If you call GetNumLSAs () before calling
+// DiscoverLSAs () will get zero as the number since no routes have been
+// found.
+//
+ Ptr<Ipv4GlobalRouting> grouting = rtr->GetRoutingProtocol ();
+ uint32_t numLSAs = rtr->DiscoverLSAs ();
+ NS_LOG_LOGIC ("Found " << numLSAs << " LSAs");
+
+ for (uint32_t j = 0; j < numLSAs; ++j)
+ {
+ GlobalRoutingLSA* lsa = new GlobalRoutingLSA ();
+//
+// This is the call to actually fetch a Link State Advertisement from the
+// router.
+//
+ rtr->GetLSA (j, *lsa);
+ NS_LOG_LOGIC (*lsa);
+//
+// Write the newly discovered link state advertisement to the database.
+//
+ m_lsdb->Insert (lsa->GetLinkStateId (), lsa);
+ }
+ }
+}
+
+//
+// For each node that is a global router (which is determined by the presence
+// of an aggregated GlobalRouter interface), run the Dijkstra SPF calculation
+// on the database rooted at that router, and populate the node forwarding
+// tables.
+//
+// This function parallels RFC2328, Section 16.1.1, and quagga ospfd
+//
+// This calculation yields the set of intra-area routes associated
+// with an area (called hereafter Area A). A router calculates the
+// shortest-path tree using itself as the root. The formation
+// of the shortest path tree is done here in two stages. In the
+// first stage, only links between routers and transit networks are
+// considered. Using the Dijkstra algorithm, a tree is formed from
+// this subset of the link state database. In the second stage,
+// leaves are added to the tree by considering the links to stub
+// networks.
+//
+// The area's link state database is represented as a directed graph.
+// The graph's vertices are routers, transit networks and stub networks.
+//
+// The first stage of the procedure (i.e., the Dijkstra algorithm)
+// can now be summarized as follows. At each iteration of the
+// algorithm, there is a list of candidate vertices. Paths from
+// the root to these vertices have been found, but not necessarily
+// the shortest ones. However, the paths to the candidate vertex
+// that is closest to the root are guaranteed to be shortest; this
+// vertex is added to the shortest-path tree, removed from the
+// candidate list, and its adjacent vertices are examined for
+// possible addition to/modification of the candidate list. The
+// algorithm then iterates again. It terminates when the candidate
+// list becomes empty.
+//
+ void
+GlobalRouteManagerImpl::InitializeRoutes ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+//
+// Walk the list of nodes in the system.
+//
+ NS_LOG_INFO ("About to start SPF calculation");
+ NodeList::Iterator listEnd = NodeList::End ();
+ for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
+ {
+ Ptr<Node> node = *i;
+//
+// Look for the GlobalRouter interface that indicates that the node is
+// participating in routing.
+//
+ Ptr<GlobalRouter> rtr =
+ node->GetObject<GlobalRouter> ();
+
+ // Ignore nodes that are not assigned to our systemId (distributed sim)
+ if (node->GetSystemId () != MpiInterface::GetSystemId ())
+ {
+ continue;
+ }
+
+//
+// if the node has a global router interface, then run the global routing
+// algorithms.
+//
+ if (rtr && rtr->GetNumLSAs () )
+ {
+ SPFCalculate (rtr->GetRouterId ());
+ }
+ }
+ NS_LOG_INFO ("Finished SPF calculation");
+}
+
+//
+// This method is derived from quagga ospf_spf_next (). See RFC2328 Section
+// 16.1 (2) for further details.
+//
+// We're passed a parameter <v> that is a vertex which is already in the SPF
+// tree. A vertex represents a router node. We also get a reference to the
+// SPF candidate queue, which is a priority queue containing the shortest paths
+// to the networks we know about.
+//
+// We examine the links in v's LSA and update the list of candidates with any
+// vertices not already on the list. If a lower-cost path is found to a
+// vertex already on the candidate list, store the new (lower) cost.
+//
+ void
+GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate)
+{
+ NS_LOG_FUNCTION (v << &candidate);
+
+ SPFVertex* w = 0;
+ GlobalRoutingLSA* w_lsa = 0;
+ GlobalRoutingLinkRecord *l = 0;
+ uint32_t distance = 0;
+ uint32_t numRecordsInVertex = 0;
+//
+// V points to a Router-LSA or Network-LSA
+// Loop over the links in router LSA or attached routers in Network LSA
+//
+ if (v->GetVertexType () == SPFVertex::VertexRouter)
+ {
+ numRecordsInVertex = v->GetLSA ()->GetNLinkRecords ();
+ }
+ if (v->GetVertexType () == SPFVertex::VertexNetwork)
+ {
+ numRecordsInVertex = v->GetLSA ()->GetNAttachedRouters ();
+ }
+
+ for (uint32_t i = 0; i < numRecordsInVertex; i++)
+ {
+// Get w_lsa: In case of V is Router-LSA
+ if (v->GetVertexType () == SPFVertex::VertexRouter)
+ {
+ NS_LOG_LOGIC ("Examining link " << i << " of " <<
+ v->GetVertexId () << "'s " <<
+ v->GetLSA ()->GetNLinkRecords () << " link records");
+//
+// (a) If this is a link to a stub network, examine the next link in V's LSA.
+// Links to stub networks will be considered in the second stage of the
+// shortest path calculation.
+//
+ l = v->GetLSA ()->GetLinkRecord (i);
+ if (l->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork)
+ {
+ NS_LOG_LOGIC ("Found a Stub record to " << l->GetLinkId ());
+ continue;
+ }
+//
+// (b) Otherwise, W is a transit vertex (router or transit network). Look up
+// the vertex W's LSA (router-LSA or network-LSA) in Area A's link state
+// database.
+//
+ if (l->GetLinkType () == GlobalRoutingLinkRecord::PointToPoint)
+ {
+//
+// Lookup the link state advertisement of the new link -- we call it <w> in
+// the link state database.
+//
+ w_lsa = m_lsdb->GetLSA (l->GetLinkId ());
+ NS_ASSERT (w_lsa);
+ NS_LOG_LOGIC ("Found a P2P record from " <<
+ v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
+ }
+ else if (l->GetLinkType () ==
+ GlobalRoutingLinkRecord::TransitNetwork)
+ {
+ w_lsa = m_lsdb->GetLSA (l->GetLinkId ());
+ NS_ASSERT (w_lsa);
+ NS_LOG_LOGIC ("Found a Transit record from " <<
+ v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
+ }
+ else
+ {
+ NS_ASSERT_MSG (0, "illegal Link Type");
+ }
+ }
+// Get w_lsa: In case of V is Network-LSA
+ if (v->GetVertexType () == SPFVertex::VertexNetwork)
+ {
+ w_lsa = m_lsdb->GetLSAByLinkData
+ (v->GetLSA ()->GetAttachedRouter (i));
+ if (!w_lsa)
+ {
+ continue;
+ }
+ NS_LOG_LOGIC ("Found a Network LSA from " <<
+ v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
+ }
+
+// Note: w_lsa at this point may be either RouterLSA or NetworkLSA
+//
+// (c) If vertex W is already on the shortest-path tree, examine the next
+// link in the LSA.
+//
+// If the link is to a router that is already in the shortest path first tree
+// then we have it covered -- ignore it.
+//
+ if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_IN_SPFTREE)
+ {
+ NS_LOG_LOGIC ("Skipping -> LSA "<<
+ w_lsa->GetLinkStateId () << " already in SPF tree");
+ continue;
+ }
+//
+// (d) Calculate the link state cost D of the resulting path from the root to
+// vertex W. D is equal to the sum of the link state cost of the (already
+// calculated) shortest path to vertex V and the advertised cost of the link
+// between vertices V and W.
+//
+ if (v->GetLSA ()->GetLSType () == GlobalRoutingLSA::RouterLSA)
+ {
+ distance = v->GetDistanceFromRoot () + l->GetMetric ();
+ }
+ else
+ {
+ distance = v->GetDistanceFromRoot ();
+ }
+
+ NS_LOG_LOGIC ("Considering w_lsa " << w_lsa->GetLinkStateId ());
+
+// Is there already vertex w in candidate list?
+ if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED)
+ {
+// Calculate nexthop to w
+// We need to figure out how to actually get to the new router represented
+// by <w>. This will (among other things) find the next hop address to send
+// packets destined for this network to, and also find the outbound interface
+// used to forward the packets.
+
+// prepare vertex w
+ w = new SPFVertex (w_lsa);
+ if (SPFNexthopCalculation (v, w, l, distance))
+ {
+ w_lsa->SetStatus (GlobalRoutingLSA::LSA_SPF_CANDIDATE);
+//
+// Push this new vertex onto the priority queue (ordered by distance from the
+// root node).
+//
+ candidate.Push (w);
+ NS_LOG_LOGIC ("Pushing " <<
+ w->GetVertexId () << ", parent vertexId: " <<
+ v->GetVertexId () << ", distance: " <<
+ w->GetDistanceFromRoot ());
+ }
+ else
+ NS_ASSERT_MSG (0, "SPFNexthopCalculation never "
+ << "return false, but it does now!");
+ }
+ else if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_CANDIDATE)
+ {
+//
+// We have already considered the link represented by <w>. What wse have to
+// do now is to decide if this new router represents a route with a shorter
+// distance metric.
+//
+// So, locate the vertex in the candidate queue and take a look at the
+// distance.
+
+/* (quagga-0.98.6) W is already on the candidate list; call it cw.
+* Compare the previously calculated cost (cw->distance)
+* with the cost we just determined (w->distance) to see
+* if we've found a shorter path.
+*/
+ SPFVertex* cw;
+ cw = candidate.Find (w_lsa->GetLinkStateId ());
+ if (cw->GetDistanceFromRoot () < distance)
+ {
+//
+// This is not a shorter path, so don't do anything.
+//
+ continue;
+ }
+ else if (cw->GetDistanceFromRoot () == distance)
+ {
+//
+// This path is one with an equal cost.
+//
+ NS_LOG_LOGIC ("Equal cost multiple paths found.");
+
+// At this point, there are two instances 'w' and 'cw' of the
+// same vertex, the vertex that is currently being considered
+// for adding into the shortest path tree. 'w' is the instance
+// as seen from the root via vertex 'v', and 'cw' is the instance
+// as seen from the root via some other vertices other than 'v'.
+// These two instances are being merged in the following code.
+// In particular, the parent nodes, the next hops, and the root's
+// output interfaces of the two instances are being merged.
+//
+// Note that this is functionally equivalent to calling
+// ospf_nexthop_merge (cw->nexthop, w->nexthop) in quagga-0.98.6
+// (ospf_spf.c::859), although the detail implementation
+// is very different from quagga (blame ns3::GlobalRouteManagerImpl)
+
+// prepare vertex w
+ w = new SPFVertex (w_lsa);
+ SPFNexthopCalculation (v, w, l, distance);
+ cw->MergeRootExitDirections (w);
+ cw->MergeParent (w);
+// SPFVertexAddParent (w) is necessary as the destructor of
+// SPFVertex checks if the vertex and its parent is linked
+// bidirectionally
+ SPFVertexAddParent (w);
+ delete w;
+ }
+ else // cw->GetDistanceFromRoot () > w->GetDistanceFromRoot ()
+ {
+//
+// this path represents a new, lower-cost path to <w> (the vertex we found in
+// the current link record of the link state advertisement of the current root
+// (vertex <v>)
+//
+// N.B. the nexthop_calculation is conditional, if it finds a valid nexthop
+// it will call spf_add_parents, which will flush the old parents
+//
+ if (SPFNexthopCalculation (v, cw, l, distance))
+ {
+//
+// If we've changed the cost to get to the vertex represented by <w>, we
+// must reorder the priority queue keyed to that cost.
+//
+ candidate.Reorder ();
+ }
+ } // new lower cost path found
+ } // end W is already on the candidate list
+ } // end loop over the links in V's LSA
+}
+
+//
+// This method is derived from quagga ospf_nexthop_calculation() 16.1.1.
+//
+// Calculate nexthop from root through V (parent) to vertex W (destination)
+// with given distance from root->W.
+//
+// As appropriate, set w's parent, distance, and nexthop information
+//
+// For now, this is greatly simplified from the quagga code
+//
+ int
+GlobalRouteManagerImpl::SPFNexthopCalculation (
+ SPFVertex* v,
+ SPFVertex* w,
+ GlobalRoutingLinkRecord* l,
+ uint32_t distance)
+{
+ NS_LOG_FUNCTION (v << w << l << distance);
+//
+// If w is a NetworkVertex, l should be null
+/*
+ if (w->GetVertexType () == SPFVertex::VertexNetwork && l)
+ {
+ NS_ASSERT_MSG (0, "Error: SPFNexthopCalculation parameter problem");
+ }
+*/
+
+//
+// The vertex m_spfroot is a distinguished vertex representing the node at
+// the root of the calculations. That is, it is the node for which we are
+// calculating the routes.
+//
+// There are two distinct cases for calculating the next hop information.
+// First, if we're considering a hop from the root to an "adjacent" network
+// (one that is on the other side of a point-to-point link connected to the
+// root), then we need to store the information needed to forward down that
+// link. The second case is if the network is not directly adjacent. In that
+// case we need to use the forwarding information from the vertex on the path
+// to the destination that is directly adjacent [node 1] in both cases of the
+// diagram below.
+//
+// (1) [root] -> [point-to-point] -> [node 1]
+// (2) [root] -> [point-to-point] -> [node 1] -> [point-to-point] -> [node 2]
+//
+// We call the propagation of next hop information down vertices of a path
+// "inheriting" the next hop information.
+//
+// The point-to-point link information is only useful in this calculation when
+// we are examining the root node.
+//
+ if (v == m_spfroot)
+ {
+//
+// In this case <v> is the root node, which means it is the starting point
+// for the packets forwarded by that node. This also means that the next hop
+// address of packets headed for some arbitrary off-network destination must
+// be the destination at the other end of one of the links off of the root
+// node if this root node is a router. We then need to see if this node <w>
+// is a router.
+//
+ if (w->GetVertexType () == SPFVertex::VertexRouter)
+ {
+//
+// In the case of point-to-point links, the link data field (m_linkData) of a
+// Global Router Link Record contains the local IP address. If we look at the
+// link record describing the link from the perspecive of <w> (the remote
+// node from the viewpoint of <v>) back to the root node, we can discover the
+// IP address of the router to which <v> is adjacent. This is a distinguished
+// address -- the next hop address to get from <v> to <w> and all networks
+// accessed through that path.
+//
+// SPFGetNextLink () is a little odd. used in this way it is just going to
+// return the link record describing the link from <w> to <v>. Think of it as
+// SPFGetLink.
+//
+ NS_ASSERT (l);
+ GlobalRoutingLinkRecord *linkRemote = 0;
+ linkRemote = SPFGetNextLink (w, v, linkRemote);
+//
+// At this point, <l> is the Global Router Link Record describing the point-
+// to point link from <v> to <w> from the perspective of <v>; and <linkRemote>
+// is the Global Router Link Record describing that same link from the
+// perspective of <w> (back to <v>). Now we can just copy the next hop
+// address from the m_linkData member variable.
+//
+// The next hop member variable we put in <w> has the sense "in order to get
+// from the root node to the host represented by vertex <w>, you have to send
+// the packet to the next hop address specified in w->m_nextHop.
+//
+ Ipv4Address nextHop = linkRemote->GetLinkData ();
+//
+// Now find the outgoing interface corresponding to the point to point link
+// from the perspective of <v> -- remember that <l> is the link "from"
+// <v> "to" <w>.
+//
+ uint32_t outIf = FindOutgoingInterfaceId (l->GetLinkData ());
+
+ w->SetRootExitDirection (nextHop, outIf);
+ w->SetDistanceFromRoot (distance);
+ w->SetParent (v);
+ NS_LOG_LOGIC ("Next hop from " <<
+ v->GetVertexId () << " to " << w->GetVertexId () <<
+ " goes through next hop " << nextHop <<
+ " via outgoing interface " << outIf <<
+ " with distance " << distance);
+ } // end W is a router vertes
+ else
+ {
+ NS_ASSERT (w->GetVertexType () == SPFVertex::VertexNetwork);
+// W is a directly connected network; no next hop is required
+ GlobalRoutingLSA* w_lsa = w->GetLSA ();
+ NS_ASSERT (w_lsa->GetLSType () == GlobalRoutingLSA::NetworkLSA);
+// Find outgoing interface ID for this network
+ uint32_t outIf = FindOutgoingInterfaceId (w_lsa->GetLinkStateId (),
+ w_lsa->GetNetworkLSANetworkMask () );
+// Set the next hop to 0.0.0.0 meaning "not exist"
+ Ipv4Address nextHop = Ipv4Address::GetZero ();
+ w->SetRootExitDirection (nextHop, outIf);
+ w->SetDistanceFromRoot (distance);
+ w->SetParent (v);
+ NS_LOG_LOGIC ("Next hop from " <<
+ v->GetVertexId () << " to network " << w->GetVertexId () <<
+ " via outgoing interface " << outIf <<
+ " with distance " << distance);
+ return 1;
+ }
+ } // end v is the root
+ else if (v->GetVertexType () == SPFVertex::VertexNetwork)
+ {
+// See if any of v's parents are the root
+ if (v->GetParent () == m_spfroot)
+ {
+// 16.1.1 para 5. ...the parent vertex is a network that
+// directly connects the calculating router to the destination
+// router. The list of next hops is then determined by
+// examining the destination's router-LSA...
+ NS_ASSERT (w->GetVertexType () == SPFVertex::VertexRouter);
+ GlobalRoutingLinkRecord *linkRemote = 0;
+ while ((linkRemote = SPFGetNextLink (w, v, linkRemote)))
+ {
+/* ...For each link in the router-LSA that points back to the
+ * parent network, the link's Link Data field provides the IP
+ * address of a next hop router. The outgoing interface to
+ * use can then be derived from the next hop IP address (or
+ * it can be inherited from the parent network).
+ */
+ Ipv4Address nextHop = linkRemote->GetLinkData ();
+ uint32_t outIf = v->GetRootExitDirection ().second;
+ w->SetRootExitDirection (nextHop, outIf);
+ NS_LOG_LOGIC ("Next hop from " <<
+ v->GetVertexId () << " to " << w->GetVertexId () <<
+ " goes through next hop " << nextHop <<
+ " via outgoing interface " << outIf);
+ }
+ }
+ else
+ {
+ w->SetRootExitDirection (v->GetRootExitDirection ());
+ }
+ }
+ else
+ {
+//
+// If we're calculating the next hop information from a node (v) that is
+// *not* the root, then we need to "inherit" the information needed to
+// forward the packet from the vertex closer to the root. That is, we'll
+// still send packets to the next hop address of the router adjacent to the
+// root on the path toward <w>.
+//
+// Above, when we were considering the root node, we calculated the next hop
+// address and outgoing interface required to get off of the root network.
+// At this point, we are further away from the root network along one of the
+// (shortest) paths. So the next hop and outoing interface remain the same
+// (are inherited).
+//
+ w->InheritAllRootExitDirections (v);
+ }
+//
+// In all cases, we need valid values for the distance metric and a parent.
+//
+ w->SetDistanceFromRoot (distance);
+ w->SetParent (v);
+
+ return 1;
+}
+
+//
+// This method is derived from quagga ospf_get_next_link ()
+//
+// First search the Global Router Link Records of vertex <v> for one
+// representing a point-to point link to vertex <w>.
+//
+// What is done depends on prev_link. Contrary to appearances, prev_link just
+// acts as a flag here. If prev_link is NULL, we return the first Global
+// Router Link Record we find that describes a point-to-point link from <v>
+// to <w>. If prev_link is not NULL, we return a Global Router Link Record
+// representing a possible *second* link from <v> to <w>.
+//
+ GlobalRoutingLinkRecord*
+GlobalRouteManagerImpl::SPFGetNextLink (
+ SPFVertex* v,
+ SPFVertex* w,
+ GlobalRoutingLinkRecord* prev_link)
+{
+ NS_LOG_FUNCTION (v << w << prev_link);
+
+ bool skip = true;
+ bool found_prev_link = false;
+ GlobalRoutingLinkRecord* l;
+//
+// If prev_link is 0, we are really looking for the first link, not the next
+// link.
+//
+ if (prev_link == 0)
+ {
+ skip = false;
+ found_prev_link = true;
+ }
+//
+// Iterate through the Global Router Link Records advertised by the vertex
+// <v> looking for records representing the point-to-point links off of this
+// vertex.
+//
+ for (uint32_t i = 0; i < v->GetLSA ()->GetNLinkRecords (); ++i)
+ {
+ l = v->GetLSA ()->GetLinkRecord (i);
+//
+// The link ID of a link record representing a point-to-point link is set to
+// the router ID of the neighboring router -- the router to which the link
+// connects from the perspective of <v> in this case. The vertex ID is also
+// set to the router ID (using the link state advertisement of a router node).
+// We're just checking to see if the link <l> is actually the link from <v> to
+// <w>.
+//
+ if (l->GetLinkId () == w->GetVertexId ())
+ {
+ if (!found_prev_link)
+ {
+ NS_LOG_LOGIC ("Skipping links before prev_link found");
+ found_prev_link = true;
+ continue;
+ }
+
+ NS_LOG_LOGIC ("Found matching link l: linkId = " <<
+ l->GetLinkId () << " linkData = " << l->GetLinkData ());
+//
+// If skip is false, don't (not too surprisingly) skip the link found -- it's
+// the one we're interested in. That's either because we didn't pass in a
+// previous link, and we're interested in the first one, or because we've
+// skipped a previous link and moved forward to the next (which is then the
+// one we want).
+//
+ if (skip == false)
+ {
+ NS_LOG_LOGIC ("Returning the found link");
+ return l;
+ }
+ else
+ {
+//
+// Skip is true and we've found a link from <v> to <w>. We want the next one.
+// Setting skip to false gets us the next point-to-point global router link
+// record in the LSA from <v>.
+//
+ NS_LOG_LOGIC ("Skipping the found link");
+ skip = false;
+ continue;
+ }
+ }
+ }
+ return 0;
+}
+
+//
+// Used for unit tests.
+//
+ void
+GlobalRouteManagerImpl::DebugSPFCalculate (Ipv4Address root)
+{
+ NS_LOG_FUNCTION (root);
+ SPFCalculate (root);
+}
+
+//
+// Used to test if a node is a stub, from an OSPF sense.
+// If there is only one link of type 1 or 2, then a default route
+// can safely be added to the next-hop router and SPF does not need
+// to be run
+//
+bool
+GlobalRouteManagerImpl::CheckForStubNode (Ipv4Address root)
+{
+ NS_LOG_FUNCTION (root);
+ GlobalRoutingLSA *rlsa = m_lsdb->GetLSA (root);
+ Ipv4Address myRouterId = rlsa->GetLinkStateId ();
+ int transits = 0;
+ GlobalRoutingLinkRecord *transitLink = 0;
+ for (uint32_t i = 0; i < rlsa->GetNLinkRecords (); i++)
+ {
+ GlobalRoutingLinkRecord *l = rlsa->GetLinkRecord (i);
+ if (l->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork)
+ {
+ transits++;
+ transitLink = l;
+ }
+ else if (l->GetLinkType () == GlobalRoutingLinkRecord::PointToPoint)
+ {
+ transits++;
+ transitLink = l;
+ }
+ }
+ if (transits == 0)
+ {
+ // This router is not connected to any router. Probably, global
+ // routing should not be called for this node, but we can just raise
+ // a warning here and return true.
+ NS_LOG_WARN ("all nodes should have at least one transit link:" << root );
+ return true;
+ }
+ if (transits == 1)
+ {
+ if (transitLink->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork)
+ {
+ // Install default route to next hop router
+ // What is the next hop? We need to check all neighbors on the link.
+ // If there is a single router that has two transit links, then
+ // that is the default next hop. If there are more than one
+ // routers on link with multiple transit links, return false.
+ // Not yet implemented, so simply return false
+ NS_LOG_LOGIC ("TBD: Would have inserted default for transit");
+ return false;
+ }
+ else if (transitLink->GetLinkType () == GlobalRoutingLinkRecord::PointToPoint)
+ {
+ // Install default route to next hop
+ // The link record LinkID is the router ID of the peer.
+ // The Link Data is the local IP interface address
+ GlobalRoutingLSA *w_lsa = m_lsdb->GetLSA (transitLink->GetLinkId ());
+ uint32_t nLinkRecords = w_lsa->GetNLinkRecords ();
+ for (uint32_t j = 0; j < nLinkRecords; ++j)
+ {
+ //
+ // We are only concerned about point-to-point links
+ //
+ GlobalRoutingLinkRecord *lr = w_lsa->GetLinkRecord (j);
+ if (lr->GetLinkType () != GlobalRoutingLinkRecord::PointToPoint)
+ {
+ continue;
+ }
+ // Find the link record that corresponds to our routerId
+ if (lr->GetLinkId () == myRouterId)
+ {
+ // Next hop is stored in the LinkID field of lr
+ Ptr<GlobalRouter> router = rlsa->GetNode ()->GetObject<GlobalRouter> ();
+ NS_ASSERT (router);
+ Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
+ NS_ASSERT (gr);
+ gr->AddNetworkRouteTo (Ipv4Address ("0.0.0.0"), Ipv4Mask ("0.0.0.0"), lr->GetLinkData (),
+ FindOutgoingInterfaceId (transitLink->GetLinkData ()));
+ NS_LOG_LOGIC ("Inserting default route for node " << myRouterId << " to next hop " <<
+ lr->GetLinkData () << " via interface " <<
+ FindOutgoingInterfaceId(transitLink->GetLinkData()));
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+// quagga ospf_spf_calculate
+ void
+GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root)
+{
+ NS_LOG_FUNCTION (this << root);
+
+ SPFVertex *v;
+//
+// Initialize the Link State Database.
+//
+ m_lsdb->Initialize ();
+//
+// The candidate queue is a priority queue of SPFVertex objects, with the top
+// of the queue being the closest vertex in terms of distance from the root
+// of the tree. Initially, this queue is empty.
+//
+ CandidateQueue candidate;
+ NS_ASSERT (candidate.Size () == 0);
+//
+// Initialize the shortest-path tree to only contain the router doing the
+// calculation. Each router (and corresponding network) is a vertex in the
+// shortest path first (SPF) tree.
+//
+ v = new SPFVertex (m_lsdb->GetLSA (root));
+//
+// This vertex is the root of the SPF tree and it is distance 0 from the root.
+// We also mark this vertex as being in the SPF tree.
+//
+ m_spfroot= v;
+ v->SetDistanceFromRoot (0);
+ v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE);
+ NS_LOG_LOGIC ("Starting SPFCalculate for node " << root);
+
+//
+// Optimize SPF calculation, for ns-3.
+// We do not need to calculate SPF for every node in the network if this
+// node has only one interface through which another router can be
+// reached. Instead, short-circuit this computation and just install
+// a default route in the CheckForStubNode() method.
+//
+ if (NodeList::GetNNodes () > 0 && CheckForStubNode (root))
+ {
+ NS_LOG_LOGIC ("SPFCalculate truncated for stub node " << root);
+ delete m_spfroot;
+ return;
+ }
+
+ for (;;)
+ {
+//
+// The operations we need to do are given in the OSPF RFC which we reference
+// as we go along.
+//
+// RFC2328 16.1. (2).
+//
+// We examine the Global Router Link Records in the Link State
+// Advertisements of the current vertex. If there are any point-to-point
+// links to unexplored adjacent vertices we add them to the tree and update
+// the distance and next hop information on how to get there. We also add
+// the new vertices to the candidate queue (the priority queue ordered by
+// shortest path). If the new vertices represent shorter paths, we use them
+// and update the path cost.
+//
+ SPFNext (v, candidate);
+//
+// RFC2328 16.1. (3).
+//
+// If at this step the candidate list is empty, the shortest-path tree (of
+// transit vertices) has been completely built and this stage of the
+// procedure terminates.
+//
+ if (candidate.Size () == 0)
+ {
+ break;
+ }
+//
+// Choose the vertex belonging to the candidate list that is closest to the
+// root, and add it to the shortest-path tree (removing it from the candidate
+// list in the process).
+//
+// Recall that in the previous step, we created SPFVertex structures for each
+// of the routers found in the Global Router Link Records and added tehm to
+// the candidate list.
+//
+ NS_LOG_LOGIC (candidate);
+ v = candidate.Pop ();
+ NS_LOG_LOGIC ("Popped vertex " << v->GetVertexId ());
+//
+// Update the status field of the vertex to indicate that it is in the SPF
+// tree.
+//
+ v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE);
+//
+// The current vertex has a parent pointer. By calling this rather oddly
+// named method (blame quagga) we add the current vertex to the list of
+// children of that parent vertex. In the next hop calculation called during
+// SPFNext, the parent pointer was set but the vertex has been orphaned up
+// to now.
+//
+ SPFVertexAddParent (v);
+//
+// Note that when there is a choice of vertices closest to the root, network
+// vertices must be chosen before router vertices in order to necessarily
+// find all equal-cost paths.
+//
+// RFC2328 16.1. (4).
+//
+// This is the method that actually adds the routes. It'll walk the list
+// of nodes in the system, looking for the node corresponding to the router
+// ID of the root of the tree -- that is the router we're building the routes
+// for. It looks for the Ipv4 interface of that node and remembers it. So
+// we are only actually adding routes to that one node at the root of the SPF
+// tree.
+//
+// We're going to pop of a pointer to every vertex in the tree except the
+// root in order of distance from the root. For each of the vertices, we call
+// SPFIntraAddRouter (). Down in SPFIntraAddRouter, we look at all of the
+// point-to-point Global Router Link Records (the links to nodes adjacent to
+// the node represented by the vertex). We add a route to the IP address
+// specified by the m_linkData field of each of those link records. This will
+// be the *local* IP address associated with the interface attached to the
+// link. We use the outbound interface and next hop information present in
+// the vertex <v> which have possibly been inherited from the root.
+//
+// To summarize, we're going to look at the node represented by <v> and loop
+// through its point-to-point links, adding a *host* route to the local IP
+// address (at the <v> side) for each of those links.
+//
+ if (v->GetVertexType () == SPFVertex::VertexRouter)
+ {
+ SPFIntraAddRouter (v);
+ }
+ else if (v->GetVertexType () == SPFVertex::VertexNetwork)
+ {
+ SPFIntraAddTransit (v);
+ }
+ else
+ {
+ NS_ASSERT_MSG (0, "illegal SPFVertex type");
+ }
+//
+// RFC2328 16.1. (5).
+//
+// Iterate the algorithm by returning to Step 2 until there are no more
+// candidate vertices.
+
+ } // end for loop
+
+// Second stage of SPF calculation procedure
+ SPFProcessStubs (m_spfroot);
+ for (uint32_t i = 0; i < m_lsdb->GetNumExtLSAs (); i++)
+ {
+ m_spfroot->ClearVertexProcessed ();
+ GlobalRoutingLSA *extlsa = m_lsdb->GetExtLSA (i);
+ NS_LOG_LOGIC ("Processing External LSA with id " << extlsa->GetLinkStateId ());
+ ProcessASExternals (m_spfroot, extlsa);
+ }
+
+//
+// We're all done setting the routing information for the node at the root of
+// the SPF tree. Delete all of the vertices and corresponding resources. Go
+// possibly do it again for the next router.
+//
+ delete m_spfroot;
+ m_spfroot = 0;
+}
+
+void
+GlobalRouteManagerImpl::ProcessASExternals (SPFVertex* v, GlobalRoutingLSA* extlsa)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_LOGIC ("Processing external for destination " <<
+ extlsa->GetLinkStateId () <<
+ ", for router " << v->GetVertexId () <<
+ ", advertised by " << extlsa->GetAdvertisingRouter ());
+ if (v->GetVertexType () == SPFVertex::VertexRouter)
+ {
+ GlobalRoutingLSA *rlsa = v->GetLSA ();
+ NS_LOG_LOGIC ("Processing router LSA with id " << rlsa->GetLinkStateId ());
+ if ((rlsa->GetLinkStateId ()) == (extlsa->GetAdvertisingRouter ()))
+ {
+ NS_LOG_LOGIC ("Found advertising router to destination");
+ SPFAddASExternal(extlsa,v);
+ }
+ }
+ for (uint32_t i = 0; i < v->GetNChildren (); i++)
+ {
+ if (!v->GetChild (i)->IsVertexProcessed ())
+ {
+ NS_LOG_LOGIC ("Vertex's child " << i << " not yet processed, processing...");
+ ProcessASExternals (v->GetChild (i), extlsa);
+ v->GetChild (i)->SetVertexProcessed (true);
+ }
+ }
+}
+
+//
+// Adding external routes to routing table - modeled after
+// SPFAddIntraAddStub()
+//
+
+void
+GlobalRouteManagerImpl::SPFAddASExternal (GlobalRoutingLSA *extlsa, SPFVertex *v)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ NS_ASSERT_MSG (m_spfroot, "GlobalRouteManagerImpl::SPFAddASExternal (): Root pointer not set");
+// Two cases to consider: We are advertising the external ourselves
+// => No need to add anything
+// OR find best path to the advertising router
+ if (v->GetVertexId () == m_spfroot->GetVertexId ())
+ {
+ NS_LOG_LOGIC ("External is on local host: "
+ << v->GetVertexId () << "; returning");
+ return;
+ }
+ NS_LOG_LOGIC ("External is on remote host: "
+ << extlsa->GetAdvertisingRouter () << "; installing");
+
+ Ipv4Address routerId = m_spfroot->GetVertexId ();
+
+ NS_LOG_LOGIC ("Vertex ID = " << routerId);
+//
+// We need to walk the list of nodes looking for the one that has the router
+// ID corresponding to the root vertex. This is the one we're going to write
+// the routing information to.
+//
+ NodeList::Iterator i = NodeList::Begin ();
+ NodeList::Iterator listEnd = NodeList::End ();
+ for (; i != listEnd; i++)
+ {
+ Ptr<Node> node = *i;
+//
+// The router ID is accessible through the GlobalRouter interface, so we need
+// to QI for that interface. If there's no GlobalRouter interface, the node
+// in question cannot be the router we want, so we continue.
+//
+ Ptr<GlobalRouter> rtr = node->GetObject<GlobalRouter> ();
+
+ if (rtr == 0)
+ {
+ NS_LOG_LOGIC ("No GlobalRouter interface on node " << node->GetId ());
+ continue;
+ }
+//
+// If the router ID of the current node is equal to the router ID of the
+// root of the SPF tree, then this node is the one for which we need to
+// write the routing tables.
+//
+ NS_LOG_LOGIC ("Considering router " << rtr->GetRouterId ());
+
+ if (rtr->GetRouterId () == routerId)
+ {
+ NS_LOG_LOGIC ("Setting routes for node " << node->GetId ());
+//
+// Routing information is updated using the Ipv4 interface. We need to QI
+// for that interface. If the node is acting as an IP version 4 router, it
+// should absolutely have an Ipv4 interface.
+//
+ Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+ NS_ASSERT_MSG (ipv4,
+ "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
+ "QI for <Ipv4> interface failed");
+//
+// Get the Global Router Link State Advertisement from the vertex we're
+// adding the routes to. The LSA will have a number of attached Global Router
+// Link Records corresponding to links off of that vertex / node. We're going
+// to be interested in the records corresponding to point-to-point links.
+//
+ NS_ASSERT_MSG (v->GetLSA (),
+ "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
+ "Expected valid LSA in SPFVertex* v");
+ Ipv4Mask tempmask = extlsa->GetNetworkLSANetworkMask ();
+ Ipv4Address tempip = extlsa->GetLinkStateId ();
+ tempip = tempip.CombineMask (tempmask);
+
+//
+// Here's why we did all of that work. We're going to add a host route to the
+// host address found in the m_linkData field of the point-to-point link
+// record. In the case of a point-to-point link, this is the local IP address
+// of the node connected to the link. Each of these point-to-point links
+// will correspond to a local interface that has an IP address to which
+// the node at the root of the SPF tree can send packets. The vertex <v>
+// (corresponding to the node that has these links and interfaces) has
+// an m_nextHop address precalculated for us that is the address to which the
+// root node should send packets to be forwarded to these IP addresses.
+// Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
+// which the packets should be send for forwarding.
+//
+ Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
+ if (router == 0)
+ {
+ continue;
+ }
+ Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
+ NS_ASSERT (gr);
+ // walk through all next-hop-IPs and out-going-interfaces for reaching
+ // the stub network gateway 'v' from the root node
+ for (uint32_t i = 0; i < v->GetNRootExitDirections (); i++)
+ {
+ SPFVertex::NodeExit_t exit = v->GetRootExitDirection (i);
+ Ipv4Address nextHop = exit.first;
+ int32_t outIf = exit.second;
+ if (outIf >= 0)
+ {
+ gr->AddASExternalRouteTo (tempip, tempmask, nextHop, outIf);
+ NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
+ " add external network route to " << tempip <<
+ " using next hop " << nextHop <<
+ " via interface " << outIf);
+ }
+ else
+ {
+ NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
+ " NOT able to add network route to " << tempip <<
+ " using next hop " << nextHop <<
+ " since outgoing interface id is negative");
+ }
+ }
+ return;
+ } // if
+ } // for
+}
+
+
+// Processing logic from RFC 2328, page 166 and quagga ospf_spf_process_stubs ()
+// stub link records will exist for point-to-point interfaces and for
+// broadcast interfaces for which no neighboring router can be found
+void
+GlobalRouteManagerImpl::SPFProcessStubs (SPFVertex* v)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_LOGIC ("Processing stubs for " << v->GetVertexId ());
+ if (v->GetVertexType () == SPFVertex::VertexRouter)
+ {
+ GlobalRoutingLSA *rlsa = v->GetLSA ();
+ NS_LOG_LOGIC ("Processing router LSA with id " << rlsa->GetLinkStateId ());
+ for (uint32_t i = 0; i < rlsa->GetNLinkRecords (); i++)
+ {
+ NS_LOG_LOGIC ("Examining link " << i << " of " <<
+ v->GetVertexId () << "'s " <<
+ v->GetLSA ()->GetNLinkRecords () << " link records");
+ GlobalRoutingLinkRecord *l = v->GetLSA ()->GetLinkRecord (i);
+ if (l->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork)
+ {
+ NS_LOG_LOGIC ("Found a Stub record to " << l->GetLinkId ());
+ SPFIntraAddStub (l, v);
+ continue;
+ }
+ }
+ }
+ for (uint32_t i = 0; i < v->GetNChildren (); i++)
+ {
+ if (!v->GetChild (i)->IsVertexProcessed ())
+ {
+ SPFProcessStubs (v->GetChild (i));
+ v->GetChild (i)->SetVertexProcessed (true);
+ }
+ }
+}
+
+// RFC2328 16.1. second stage.
+void
+GlobalRouteManagerImpl::SPFIntraAddStub (GlobalRoutingLinkRecord *l, SPFVertex* v)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ NS_ASSERT_MSG (m_spfroot,
+ "GlobalRouteManagerImpl::SPFIntraAddStub (): Root pointer not set");
+
+ // XXX simplifed logic for the moment. There are two cases to consider:
+ // 1) the stub network is on this router; do nothing for now
+ // (already handled above)
+ // 2) the stub network is on a remote router, so I should use the
+ // same next hop that I use to get to vertex v
+ if (v->GetVertexId () == m_spfroot->GetVertexId ())
+ {
+ NS_LOG_LOGIC ("Stub is on local host: " << v->GetVertexId () << "; returning");
+ return;
+ }
+ NS_LOG_LOGIC ("Stub is on remote host: " << v->GetVertexId () << "; installing");
+//
+// The root of the Shortest Path First tree is the router to which we are
+// going to write the actual routing table entries. The vertex corresponding
+// to this router has a vertex ID which is the router ID of that node. We're
+// going to use this ID to discover which node it is that we're actually going
+// to update.
+//
+ Ipv4Address routerId = m_spfroot->GetVertexId ();
+
+ NS_LOG_LOGIC ("Vertex ID = " << routerId);
+//
+// We need to walk the list of nodes looking for the one that has the router
+// ID corresponding to the root vertex. This is the one we're going to write
+// the routing information to.
+//
+ NodeList::Iterator i = NodeList::Begin ();
+ NodeList::Iterator listEnd = NodeList::End ();
+ for (; i != listEnd; i++)
+ {
+ Ptr<Node> node = *i;
+//
+// The router ID is accessible through the GlobalRouter interface, so we need
+// to QI for that interface. If there's no GlobalRouter interface, the node
+// in question cannot be the router we want, so we continue.
+//
+ Ptr<GlobalRouter> rtr =
+ node->GetObject<GlobalRouter> ();
+
+ if (rtr == 0)
+ {
+ NS_LOG_LOGIC ("No GlobalRouter interface on node " <<
+ node->GetId ());
+ continue;
+ }
+//
+// If the router ID of the current node is equal to the router ID of the
+// root of the SPF tree, then this node is the one for which we need to
+// write the routing tables.
+//
+ NS_LOG_LOGIC ("Considering router " << rtr->GetRouterId ());
+
+ if (rtr->GetRouterId () == routerId)
+ {
+ NS_LOG_LOGIC ("Setting routes for node " << node->GetId ());
+//
+// Routing information is updated using the Ipv4 interface. We need to QI
+// for that interface. If the node is acting as an IP version 4 router, it
+// should absolutely have an Ipv4 interface.
+//
+ Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+ NS_ASSERT_MSG (ipv4,
+ "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
+ "QI for <Ipv4> interface failed");
+//
+// Get the Global Router Link State Advertisement from the vertex we're
+// adding the routes to. The LSA will have a number of attached Global Router
+// Link Records corresponding to links off of that vertex / node. We're going
+// to be interested in the records corresponding to point-to-point links.
+//
+ NS_ASSERT_MSG (v->GetLSA (),
+ "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
+ "Expected valid LSA in SPFVertex* v");
+ Ipv4Mask tempmask (l->GetLinkData ().Get ());
+ Ipv4Address tempip = l->GetLinkId ();
+ tempip = tempip.CombineMask (tempmask);
+//
+// Here's why we did all of that work. We're going to add a host route to the
+// host address found in the m_linkData field of the point-to-point link
+// record. In the case of a point-to-point link, this is the local IP address
+// of the node connected to the link. Each of these point-to-point links
+// will correspond to a local interface that has an IP address to which
+// the node at the root of the SPF tree can send packets. The vertex <v>
+// (corresponding to the node that has these links and interfaces) has
+// an m_nextHop address precalculated for us that is the address to which the
+// root node should send packets to be forwarded to these IP addresses.
+// Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
+// which the packets should be send for forwarding.
+//
+
+ Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
+ if (router == 0)
+ {
+ continue;
+ }
+ Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
+ NS_ASSERT (gr);
+ // walk through all next-hop-IPs and out-going-interfaces for reaching
+ // the stub network gateway 'v' from the root node
+ for (uint32_t i = 0; i < v->GetNRootExitDirections (); i++)
+ {
+ SPFVertex::NodeExit_t exit = v->GetRootExitDirection (i);
+ Ipv4Address nextHop = exit.first;
+ int32_t outIf = exit.second;
+ if (outIf >= 0)
+ {
+ gr->AddNetworkRouteTo (tempip, tempmask, nextHop, outIf);
+ NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
+ " add network route to " << tempip <<
+ " using next hop " << nextHop <<
+ " via interface " << outIf);
+ }
+ else
+ {
+ NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
+ " NOT able to add network route to " << tempip <<
+ " using next hop " << nextHop <<
+ " since outgoing interface id is negative");
+ }
+ }
+ return;
+ } // if
+ } // for
+}
+
+//
+// Return the interface number corresponding to a given IP address and mask
+// This is a wrapper around GetInterfaceForPrefix(), but we first
+// have to find the right node pointer to pass to that function.
+// If no such interface is found, return -1 (note: unit test framework
+// for routing assumes -1 to be a legal return value)
+//
+int32_t
+GlobalRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a, Ipv4Mask amask)
+{
+ NS_LOG_FUNCTION (a << amask);
+//
+// We have an IP address <a> and a vertex ID of the root of the SPF tree.
+// The question is what interface index does this address correspond to.
+// The answer is a little complicated since we have to find a pointer to
+// the node corresponding to the vertex ID, find the Ipv4 interface on that
+// node in order to iterate the interfaces and find the one corresponding to
+// the address in question.
+//
+ Ipv4Address routerId = m_spfroot->GetVertexId ();
+//
+// Walk the list of nodes in the system looking for the one corresponding to
+// the node at the root of the SPF tree. This is the node for which we are
+// building the routing table.
+//
+ NodeList::Iterator i = NodeList::Begin ();
+ NodeList::Iterator listEnd = NodeList::End ();
+ for (; i != listEnd; i++)
+ {
+ Ptr<Node> node = *i;
+
+ Ptr<GlobalRouter> rtr =
+ node->GetObject<GlobalRouter> ();
+//
+// If the node doesn't have a GlobalRouter interface it can't be the one
+// we're interested in.
+//
+ if (rtr == 0)
+ {
+ continue;
+ }
+
+ if (rtr->GetRouterId () == routerId)
+ {
+//
+// This is the node we're building the routing table for. We're going to need
+// the Ipv4 interface to look for the ipv4 interface index. Since this node
+// is participating in routing IP version 4 packets, it certainly must have
+// an Ipv4 interface.
+//
+ Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+ NS_ASSERT_MSG (ipv4,
+ "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): "
+ "GetObject for <Ipv4> interface failed");
+//
+// Look through the interfaces on this node for one that has the IP address
+// we're looking for. If we find one, return the corresponding interface
+// index, or -1 if not found.
+//
+ int32_t interface = ipv4->GetInterfaceForPrefix (a, amask);
+
+#if 0
+ if (interface < 0)
+ {
+ NS_FATAL_ERROR ("GlobalRouteManagerImpl::FindOutgoingInterfaceId(): "
+ "Expected an interface associated with address a:" << a);
+ }
+#endif
+ return interface;
+ }
+ }
+//
+// Couldn't find it.
+//
+ NS_LOG_LOGIC ("FindOutgoingInterfaceId():Can't find root node " << routerId);
+ return -1;
+}
+
+//
+// This method is derived from quagga ospf_intra_add_router ()
+//
+// This is where we are actually going to add the host routes to the routing
+// tables of the individual nodes.
+//
+// The vertex passed as a parameter has just been added to the SPF tree.
+// This vertex must have a valid m_root_oid, corresponding to the outgoing
+// interface on the root router of the tree that is the first hop on the path
+// to the vertex. The vertex must also have a next hop address, corresponding
+// to the next hop on the path to the vertex. The vertex has an m_lsa field
+// that has some number of link records. For each point to point link record,
+// the m_linkData is the local IP address of the link. This corresponds to
+// a destination IP address, reachable from the root, to which we add a host
+// route.
+//
+ void
+GlobalRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v)
+{
+ NS_LOG_FUNCTION (v);
+
+ NS_ASSERT_MSG (m_spfroot,
+ "GlobalRouteManagerImpl::SPFIntraAddRouter (): Root pointer not set");
+//
+// The root of the Shortest Path First tree is the router to which we are
+// going to write the actual routing table entries. The vertex corresponding
+// to this router has a vertex ID which is the router ID of that node. We're
+// going to use this ID to discover which node it is that we're actually going
+// to update.
+//
+ Ipv4Address routerId = m_spfroot->GetVertexId ();
+
+ NS_LOG_LOGIC ("Vertex ID = " << routerId);
+//
+// We need to walk the list of nodes looking for the one that has the router
+// ID corresponding to the root vertex. This is the one we're going to write
+// the routing information to.
+//
+ NodeList::Iterator i = NodeList::Begin ();
+ NodeList::Iterator listEnd = NodeList::End ();
+ for (; i != listEnd; i++)
+ {
+ Ptr<Node> node = *i;
+//
+// The router ID is accessible through the GlobalRouter interface, so we need
+// to GetObject for that interface. If there's no GlobalRouter interface,
+// the node in question cannot be the router we want, so we continue.
+//
+ Ptr<GlobalRouter> rtr =
+ node->GetObject<GlobalRouter> ();
+
+ if (rtr == 0)
+ {
+ NS_LOG_LOGIC ("No GlobalRouter interface on node " <<
+ node->GetId ());
+ continue;
+ }
+//
+// If the router ID of the current node is equal to the router ID of the
+// root of the SPF tree, then this node is the one for which we need to
+// write the routing tables.
+//
+ NS_LOG_LOGIC ("Considering router " << rtr->GetRouterId ());
+
+ if (rtr->GetRouterId () == routerId)
+ {
+ NS_LOG_LOGIC ("Setting routes for node " << node->GetId ());
+//
+// Routing information is updated using the Ipv4 interface. We need to
+// GetObject for that interface. If the node is acting as an IP version 4
+// router, it should absolutely have an Ipv4 interface.
+//
+ Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+ NS_ASSERT_MSG (ipv4,
+ "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
+ "GetObject for <Ipv4> interface failed");
+//
+// Get the Global Router Link State Advertisement from the vertex we're
+// adding the routes to. The LSA will have a number of attached Global Router
+// Link Records corresponding to links off of that vertex / node. We're going
+// to be interested in the records corresponding to point-to-point links.
+//
+ GlobalRoutingLSA *lsa = v->GetLSA ();
+ NS_ASSERT_MSG (lsa,
+ "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
+ "Expected valid LSA in SPFVertex* v");
+
+ uint32_t nLinkRecords = lsa->GetNLinkRecords ();
+//
+// Iterate through the link records on the vertex to which we're going to add
+// routes. To make sure we're being clear, we're going to add routing table
+// entries to the tables on the node corresping to the root of the SPF tree.
+// These entries will have routes to the IP addresses we find from looking at
+// the local side of the point-to-point links found on the node described by
+// the vertex <v>.
+//
+ NS_LOG_LOGIC (" Node " << node->GetId () <<
+ " found " << nLinkRecords << " link records in LSA " << lsa << "with LinkStateId "<< lsa->GetLinkStateId ());
+ for (uint32_t j = 0; j < nLinkRecords; ++j)
+ {
+//
+// We are only concerned about point-to-point links
+//
+ GlobalRoutingLinkRecord *lr = lsa->GetLinkRecord (j);
+ if (lr->GetLinkType () != GlobalRoutingLinkRecord::PointToPoint)
+ {
+ continue;
+ }
+//
+// Here's why we did all of that work. We're going to add a host route to the
+// host address found in the m_linkData field of the point-to-point link
+// record. In the case of a point-to-point link, this is the local IP address
+// of the node connected to the link. Each of these point-to-point links
+// will correspond to a local interface that has an IP address to which
+// the node at the root of the SPF tree can send packets. The vertex <v>
+// (corresponding to the node that has these links and interfaces) has
+// an m_nextHop address precalculated for us that is the address to which the
+// root node should send packets to be forwarded to these IP addresses.
+// Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
+// which the packets should be send for forwarding.
+//
+ Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
+ if (router == 0)
+ {
+ continue;
+ }
+ Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
+ NS_ASSERT (gr);
+ // walk through all available exit directions due to ECMP,
+ // and add host route for each of the exit direction toward
+ // the vertex 'v'
+ for (uint32_t i = 0; i < v->GetNRootExitDirections (); i++)
+ {
+ SPFVertex::NodeExit_t exit = v->GetRootExitDirection (i);
+ Ipv4Address nextHop = exit.first;
+ int32_t outIf = exit.second;
+ if (outIf >= 0)
+ {
+ gr->AddHostRouteTo (lr->GetLinkData (), nextHop,
+ outIf);
+ NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
+ " adding host route to " << lr->GetLinkData () <<
+ " using next hop " << nextHop <<
+ " and outgoing interface " << outIf);
+ }
+ else
+ {
+ NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
+ " NOT able to add host route to " << lr->GetLinkData () <<
+ " using next hop " << nextHop <<
+ " since outgoing interface id is negative " << outIf);
+ }
+ } // for all routes from the root the vertex 'v'
+ }
+//
+// Done adding the routes for the selected node.
+//
+ return;
+ }
+ }
+}
+ void
+GlobalRouteManagerImpl::SPFIntraAddTransit (SPFVertex* v)
+{
+ NS_LOG_FUNCTION (v);
+
+ NS_ASSERT_MSG (m_spfroot,
+ "GlobalRouteManagerImpl::SPFIntraAddTransit (): Root pointer not set");
+//
+// The root of the Shortest Path First tree is the router to which we are
+// going to write the actual routing table entries. The vertex corresponding
+// to this router has a vertex ID which is the router ID of that node. We're
+// going to use this ID to discover which node it is that we're actually going
+// to update.
+//
+ Ipv4Address routerId = m_spfroot->GetVertexId ();
+
+ NS_LOG_LOGIC ("Vertex ID = " << routerId);
+//
+// We need to walk the list of nodes looking for the one that has the router
+// ID corresponding to the root vertex. This is the one we're going to write
+// the routing information to.
+//
+ NodeList::Iterator i = NodeList::Begin ();
+ NodeList::Iterator listEnd = NodeList::End ();
+ for (; i != listEnd; i++)
+ {
+ Ptr<Node> node = *i;
+//
+// The router ID is accessible through the GlobalRouter interface, so we need
+// to GetObject for that interface. If there's no GlobalRouter interface,
+// the node in question cannot be the router we want, so we continue.
+//
+ Ptr<GlobalRouter> rtr =
+ node->GetObject<GlobalRouter> ();
+
+ if (rtr == 0)
+ {
+ NS_LOG_LOGIC ("No GlobalRouter interface on node " <<
+ node->GetId ());
+ continue;
+ }
+//
+// If the router ID of the current node is equal to the router ID of the
+// root of the SPF tree, then this node is the one for which we need to
+// write the routing tables.
+//
+ NS_LOG_LOGIC ("Considering router " << rtr->GetRouterId ());
+
+ if (rtr->GetRouterId () == routerId)
+ {
+ NS_LOG_LOGIC ("setting routes for node " << node->GetId ());
+//
+// Routing information is updated using the Ipv4 interface. We need to
+// GetObject for that interface. If the node is acting as an IP version 4
+// router, it should absolutely have an Ipv4 interface.
+//
+ Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+ NS_ASSERT_MSG (ipv4,
+ "GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+ "GetObject for <Ipv4> interface failed");
+//
+// Get the Global Router Link State Advertisement from the vertex we're
+// adding the routes to. The LSA will have a number of attached Global Router
+// Link Records corresponding to links off of that vertex / node. We're going
+// to be interested in the records corresponding to point-to-point links.
+//
+ GlobalRoutingLSA *lsa = v->GetLSA ();
+ NS_ASSERT_MSG (lsa,
+ "GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+ "Expected valid LSA in SPFVertex* v");
+ Ipv4Mask tempmask = lsa->GetNetworkLSANetworkMask ();
+ Ipv4Address tempip = lsa->GetLinkStateId ();
+ tempip = tempip.CombineMask (tempmask);
+ Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
+ if (router == 0)
+ {
+ continue;
+ }
+ Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
+ NS_ASSERT (gr);
+ // walk through all available exit directions due to ECMP,
+ // and add host route for each of the exit direction toward
+ // the vertex 'v'
+ for (uint32_t i = 0; i < v->GetNRootExitDirections (); i++)
+ {
+ SPFVertex::NodeExit_t exit = v->GetRootExitDirection (i);
+ Ipv4Address nextHop = exit.first;
+ int32_t outIf = exit.second;
+
+ if (outIf >= 0)
+ {
+ gr->AddNetworkRouteTo (tempip, tempmask, nextHop, outIf);
+ NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
+ " add network route to " << tempip <<
+ " using next hop " << nextHop <<
+ " via interface " << outIf);
+ }
+ else
+ {
+ NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
+ " NOT able to add network route to " << tempip <<
+ " using next hop " << nextHop <<
+ " since outgoing interface id is negative " << outIf);
+ }
+ }
+ }
+ }
+}
+
+// Derived from quagga ospf_vertex_add_parents ()
+//
+// This is a somewhat oddly named method (blame quagga). Although you might
+// expect it to add a parent *to* something, it actually adds a vertex
+// to the list of children *in* each of its parents.
+//
+// Given a pointer to a vertex, it links back to the vertex's parent that it
+// already has set and adds itself to that vertex's list of children.
+//
+ void
+GlobalRouteManagerImpl::SPFVertexAddParent (SPFVertex* v)
+{
+ NS_LOG_FUNCTION (v);
+
+ for (uint32_t i=0;;)
+ {
+ SPFVertex* parent;
+ // check if all parents of vertex v
+ if ((parent = v->GetParent (i++)) == 0) break;
+ parent->AddChild (v);
+ }
+}
+
+} // namespace ns3
+
+
+#include "ns3/test.h"
+#include "ns3/simulator.h"
+#include <stdlib.h> // for rand()
+
+namespace ns3 {
+
+class GlobalRouteManagerImplTestCase : public TestCase
+{
+public:
+ GlobalRouteManagerImplTestCase();
+ virtual bool DoRun(void);
+};
+
+GlobalRouteManagerImplTestCase::GlobalRouteManagerImplTestCase()
+ : TestCase("GlobalRouteManagerImplTestCase")
+{}
+bool
+GlobalRouteManagerImplTestCase::DoRun(void)
+{
+ CandidateQueue candidate;
+
+ for (int i = 0; i < 100; ++i)
+ {
+ SPFVertex *v = new SPFVertex;
+ v->SetDistanceFromRoot (rand () % 100);
+ candidate.Push (v);
+ }
+
+ uint32_t lastDistance = 0;
+
+ for (int i = 0; i < 100; ++i)
+ {
+ SPFVertex *v = candidate.Pop ();
+ if (v->GetDistanceFromRoot () < lastDistance)
+ {
+ // XXX does nothing.
+ UpdateErrorStatus (false);
+ }
+ lastDistance = v->GetDistanceFromRoot ();
+ delete v;
+ v = 0;
+ }
+
+ // Build fake link state database; four routers (0-3), 3 point-to-point
+ // links
+ //
+ // n0
+ // \ link 0
+ // \ link 2
+ // n2 -------------------------n3
+ // /
+ // / link 1
+ // n1
+ //
+ // link0: 10.1.1.1/30, 10.1.1.2/30
+ // link1: 10.1.2.1/30, 10.1.2.2/30
+ // link2: 10.1.3.1/30, 10.1.3.2/30
+ //
+ // Router 0
+ GlobalRoutingLinkRecord* lr0 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::PointToPoint,
+ "0.0.0.2", // router ID 0.0.0.2
+ "10.1.1.1", // local ID
+ 1); // metric
+
+ GlobalRoutingLinkRecord* lr1 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::StubNetwork,
+ "10.1.1.1",
+ "255.255.255.252",
+ 1);
+
+ GlobalRoutingLSA* lsa0 = new GlobalRoutingLSA ();
+ lsa0->SetLSType (GlobalRoutingLSA::RouterLSA);
+ lsa0->SetLinkStateId ("0.0.0.0");
+ lsa0->SetAdvertisingRouter ("0.0.0.0");
+ lsa0->AddLinkRecord (lr0);
+ lsa0->AddLinkRecord (lr1);
+
+ // Router 1
+ GlobalRoutingLinkRecord* lr2 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::PointToPoint,
+ "0.0.0.2",
+ "10.1.2.1",
+ 1);
+
+ GlobalRoutingLinkRecord* lr3 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::StubNetwork,
+ "10.1.2.1",
+ "255.255.255.252",
+ 1);
+
+ GlobalRoutingLSA* lsa1 = new GlobalRoutingLSA ();
+ lsa1->SetLSType (GlobalRoutingLSA::RouterLSA);
+ lsa1->SetLinkStateId ("0.0.0.1");
+ lsa1->SetAdvertisingRouter ("0.0.0.1");
+ lsa1->AddLinkRecord (lr2);
+ lsa1->AddLinkRecord (lr3);
+
+ // Router 2
+ GlobalRoutingLinkRecord* lr4 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::PointToPoint,
+ "0.0.0.0",
+ "10.1.1.2",
+ 1);
+
+ GlobalRoutingLinkRecord* lr5 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::StubNetwork,
+ "10.1.1.2",
+ "255.255.255.252",
+ 1);
+
+ GlobalRoutingLinkRecord* lr6 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::PointToPoint,
+ "0.0.0.1",
+ "10.1.2.2",
+ 1);
+
+ GlobalRoutingLinkRecord* lr7 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::StubNetwork,
+ "10.1.2.2",
+ "255.255.255.252",
+ 1);
+
+ GlobalRoutingLinkRecord* lr8 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::PointToPoint,
+ "0.0.0.3",
+ "10.1.3.2",
+ 1);
+
+ GlobalRoutingLinkRecord* lr9 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::StubNetwork,
+ "10.1.3.2",
+ "255.255.255.252",
+ 1);
+
+ GlobalRoutingLSA* lsa2 = new GlobalRoutingLSA ();
+ lsa2->SetLSType (GlobalRoutingLSA::RouterLSA);
+ lsa2->SetLinkStateId ("0.0.0.2");
+ lsa2->SetAdvertisingRouter ("0.0.0.2");
+ lsa2->AddLinkRecord (lr4);
+ lsa2->AddLinkRecord (lr5);
+ lsa2->AddLinkRecord (lr6);
+ lsa2->AddLinkRecord (lr7);
+ lsa2->AddLinkRecord (lr8);
+ lsa2->AddLinkRecord (lr9);
+
+ // Router 3
+ GlobalRoutingLinkRecord* lr10 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::PointToPoint,
+ "0.0.0.2",
+ "10.1.2.1",
+ 1);
+
+ GlobalRoutingLinkRecord* lr11 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::StubNetwork,
+ "10.1.2.1",
+ "255.255.255.252",
+ 1);
+
+ GlobalRoutingLSA* lsa3 = new GlobalRoutingLSA ();
+ lsa3->SetLSType (GlobalRoutingLSA::RouterLSA);
+ lsa3->SetLinkStateId ("0.0.0.3");
+ lsa3->SetAdvertisingRouter ("0.0.0.3");
+ lsa3->AddLinkRecord (lr10);
+ lsa3->AddLinkRecord (lr11);
+
+ // Test the database
+ GlobalRouteManagerLSDB* srmlsdb = new GlobalRouteManagerLSDB ();
+ srmlsdb->Insert (lsa0->GetLinkStateId (), lsa0);
+ srmlsdb->Insert (lsa1->GetLinkStateId (), lsa1);
+ srmlsdb->Insert (lsa2->GetLinkStateId (), lsa2);
+ srmlsdb->Insert (lsa3->GetLinkStateId (), lsa3);
+ NS_ASSERT (lsa2 == srmlsdb->GetLSA (lsa2->GetLinkStateId ()));
+
+ // next, calculate routes based on the manually created LSDB
+ GlobalRouteManagerImpl* srm = new GlobalRouteManagerImpl ();
+ srm->DebugUseLsdb (srmlsdb); // manually add in an LSDB
+ // Note-- this will succeed without any nodes in the topology
+ // because the NodeList is empty
+ srm->DebugSPFCalculate (lsa0->GetLinkStateId ()); // node n0
+
+ Simulator::Run ();
+
+// XXX here we should do some verification of the routes built
+
+ Simulator::Destroy ();
+
+ // This delete clears the srm, which deletes the LSDB, which clears
+ // all of the LSAs, which each destroys the attached LinkRecords.
+ delete srm;
+
+ // XXX
+ // No testing has actually been done other than making sure that this code
+ // does not crash
+ return GetErrorStatus ();
+}
+
+
+static class GlobalRouteManagerImplTestSuite : public TestSuite
+{
+public:
+ GlobalRouteManagerImplTestSuite()
+ : TestSuite("global-route-manager-impl", UNIT)
+ {
+ AddTestCase(new GlobalRouteManagerImplTestCase());
+ }
+} g_globalRoutingManagerImplTestSuite;
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/global-route-manager-impl.h Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,781 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2007 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors: Craig Dowell (craigdo@ee.washington.edu)
+ * Tom Henderson (tomhend@u.washington.edu)
+ */
+
+#ifndef GLOBAL_ROUTE_MANAGER_IMPL_H
+#define GLOBAL_ROUTE_MANAGER_IMPL_H
+
+#include <stdint.h>
+#include <list>
+#include <queue>
+#include <map>
+#include <vector>
+#include "ns3/object.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv4-address.h"
+#include "global-router-interface.h"
+
+namespace ns3 {
+
+const uint32_t SPF_INFINITY = 0xffffffff;
+
+class CandidateQueue;
+class Ipv4GlobalRouting;
+
+/**
+ * @brief Vertex used in shortest path first (SPF) computations. See RFC 2328,
+ * Section 16.
+ *
+ * Each router in the simulation is associated with an SPFVertex object. When
+ * calculating routes, each of these routers is, in turn, chosen as the "root"
+ * of the calculation and routes to all of the other routers are eventually
+ * saved in the routing tables of each of the chosen nodes. Each of these
+ * routers in the calculation has an associated SPFVertex.
+ *
+ * The "Root" vertex is the SPFVertex representing the router that is having
+ * its routing tables set. The SPFVertex objects representing other routers
+ * or networks in the simulation are arranged in the SPF tree. It is this
+ * tree that represents the Shortest Paths to the other networks.
+ *
+ * Each SPFVertex has a pointer to the Global Router Link State Advertisement
+ * (LSA) that its underlying router has exported. Within these LSAs are
+ * Global Router Link Records that describe the point to point links from the
+ * underlying router to other nodes (represented by other SPFVertex objects)
+ * in the simulation topology. The combination of the arrangement of the
+ * SPFVertex objects in the SPF tree, along with the details of the link
+ * records that connect them provide the information required to construct the
+ * required routes.
+ */
+class SPFVertex
+{
+public:
+/**
+ * @brief Enumeration of the possible types of SPFVertex objects.
+ * @internal
+ *
+ * Currently we use VertexRouter to identify objects that represent a router
+ * in the simulation topology, and VertexNetwork to identify objects that
+ * represent a network.
+ */
+ enum VertexType {
+ VertexUnknown = 0, /**< Uninitialized Link Record */
+ VertexRouter, /**< Vertex representing a router in the topology */
+ VertexNetwork /**< Vertex representing a network in the topology */
+ };
+
+/**
+ * @brief Construct an empty ("uninitialized") SPFVertex (Shortest Path First
+ * Vertex).
+ * @internal
+ *
+ * The Vertex Type is set to VertexUnknown, the Vertex ID is set to
+ * 255.255.255.255, and the distance from root is set to infinity
+ * (UINT32_MAX). The referenced Link State Advertisement (LSA) is set to
+ * null as is the parent SPFVertex. The outgoing interface index is set to
+ * infinity, the next hop address is set to 0.0.0.0 and the list of children
+ * of the SPFVertex is initialized to empty.
+ *
+ * @see VertexType
+ */
+ SPFVertex();
+
+/**
+ * @brief Construct an initialized SPFVertex (Shortest Path First Vertex).
+ * @internal
+ *
+ * The Vertex Type is initialized to VertexRouter and the Vertex ID is found
+ * from the Link State ID of the Link State Advertisement (LSA) passed as a
+ * parameter. The Link State ID is set to the Router ID of the advertising
+ * router. The referenced LSA (m_lsa) is set to the given LSA. Other than
+ * these members, initialization is as in the default constructor.
+ * of the SPFVertex is initialized to empty.
+ *
+ * @see SPFVertex::SPFVertex ()
+ * @see VertexType
+ * @see GlobalRoutingLSA
+ * @param lsa The Link State Advertisement used for finding initial values.
+ */
+ SPFVertex(GlobalRoutingLSA* lsa);
+
+/**
+ * @brief Destroy an SPFVertex (Shortest Path First Vertex).
+ * @internal
+ *
+ * The children vertices of the SPFVertex are recursively deleted.
+ *
+ * @see SPFVertex::SPFVertex ()
+ */
+ ~SPFVertex();
+
+/**
+ * @brief Get the Vertex Type field of a SPFVertex object.
+ * @internal
+ *
+ * The Vertex Type describes the kind of simulation object a given SPFVertex
+ * represents.
+ *
+ * @see VertexType
+ * @returns The VertexType of the current SPFVertex object.
+ */
+ VertexType GetVertexType (void) const;
+
+/**
+ * @brief Set the Vertex Type field of a SPFVertex object.
+ * @internal
+ *
+ * The Vertex Type describes the kind of simulation object a given SPFVertex
+ * represents.
+ *
+ * @see VertexType
+ * @param type The new VertexType for the current SPFVertex object.
+ */
+ void SetVertexType (VertexType type);
+
+/**
+ * @brief Get the Vertex ID field of a SPFVertex object.
+ * @internal
+ *
+ * The Vertex ID uniquely identifies the simulation object a given SPFVertex
+ * represents. Typically, this is the Router ID for SPFVertex objects
+ * representing routers, and comes from the Link State Advertisement of a
+ * router aggregated to a node in the simulation. These IDs are allocated
+ * automatically by the routing environment and look like IP addresses
+ * beginning at 0.0.0.0 and monotonically increasing as new routers are
+ * instantiated.
+ *
+ * @returns The Ipv4Address Vertex ID of the current SPFVertex object.
+ */
+ Ipv4Address GetVertexId (void) const;
+
+/**
+ * @brief Set the Vertex ID field of a SPFVertex object.
+ * @internal
+ *
+ * The Vertex ID uniquely identifies the simulation object a given SPFVertex
+ * represents. Typically, this is the Router ID for SPFVertex objects
+ * representing routers, and comes from the Link State Advertisement of a
+ * router aggregated to a node in the simulation. These IDs are allocated
+ * automatically by the routing environment and look like IP addresses
+ * beginning at 0.0.0.0 and monotonically increase as new routers are
+ * instantiated. This method is an explicit override of the automatically
+ * generated value.
+ *
+ * @param id The new Ipv4Address Vertex ID for the current SPFVertex object.
+ */
+ void SetVertexId (Ipv4Address id);
+
+/**
+ * @brief Get the Global Router Link State Advertisement returned by the
+ * Global Router represented by this SPFVertex during the route discovery
+ * process.
+ * @internal
+ *
+ * @see GlobalRouter
+ * @see GlobalRoutingLSA
+ * @see GlobalRouter::DiscoverLSAs ()
+ * @returns A pointer to the GlobalRoutingLSA found by the router represented
+ * by this SPFVertex object.
+ */
+ GlobalRoutingLSA* GetLSA (void) const;
+
+/**
+ * @brief Set the Global Router Link State Advertisement returned by the
+ * Global Router represented by this SPFVertex during the route discovery
+ * process.
+ * @internal
+ *
+ * @see SPFVertex::GetLSA ()
+ * @see GlobalRouter
+ * @see GlobalRoutingLSA
+ * @see GlobalRouter::DiscoverLSAs ()
+ * @warning Ownership of the LSA is transferred to the "this" SPFVertex. You
+ * must not delete the LSA after calling this method.
+ * @param lsa A pointer to the GlobalRoutingLSA.
+ */
+ void SetLSA (GlobalRoutingLSA* lsa);
+
+/**
+ * @brief Get the distance from the root vertex to "this" SPFVertex object.
+ * @internal
+ *
+ * Each router in the simulation is associated with an SPFVertex object. When
+ * calculating routes, each of these routers is, in turn, chosen as the "root"
+ * of the calculation and routes to all of the other routers are eventually
+ * saved in the routing tables of each of the chosen nodes. Each of these
+ * routers in the calculation has an associated SPFVertex.
+ *
+ * The "Root" vertex is then the SPFVertex representing the router that is
+ * having its routing tables set. The "this" SPFVertex is the vertex to which
+ * a route is being calculated from the root. The distance from the root that
+ * we're asking for is the number of hops from the root vertex to the vertex
+ * in question.
+ *
+ * The distance is calculated during route discovery and is stored in a
+ * member variable. This method simply fetches that value.
+ *
+ * @returns The distance, in hops, from the root SPFVertex to "this" SPFVertex.
+ */
+ uint32_t GetDistanceFromRoot (void) const;
+
+/**
+ * @brief Set the distance from the root vertex to "this" SPFVertex object.
+ * @internal
+ *
+ * Each router in the simulation is associated with an SPFVertex object. When
+ * calculating routes, each of these routers is, in turn, chosen as the "root"
+ * of the calculation and routes to all of the other routers are eventually
+ * saved in the routing tables of each of the chosen nodes. Each of these
+ * routers in the calculation has an associated SPFVertex.
+ *
+ * The "Root" vertex is then the SPFVertex representing the router that is
+ * having its routing tables set. The "this" SPFVertex is the vertex to which
+ * a route is being calculated from the root. The distance from the root that
+ * we're asking for is the number of hops from the root vertex to the vertex
+ * in question.
+ *
+ * @param distance The distance, in hops, from the root SPFVertex to "this"
+ * SPFVertex.
+ */
+ void SetDistanceFromRoot (uint32_t distance);
+
+/**
+ * @brief Set the IP address and outgoing interface index that should be used
+ * to begin forwarding packets from the root SPFVertex to "this" SPFVertex.
+ * @internal
+ *
+ * Each router node in the simulation is associated with an SPFVertex object.
+ * When calculating routes, each of these routers is, in turn, chosen as the
+ * "root" of the calculation and routes to all of the other routers are
+ * eventually saved in the routing tables of each of the chosen nodes.
+ *
+ * The "Root" vertex is then the SPFVertex representing the router that is
+ * having its routing tables set. The "this" SPFVertex is the vertex that
+ * represents the host or network to which a route is being calculated from
+ * the root. The IP address that we're asking for is the address on the
+ * remote side of a link off of the root node that should be used as the
+ * destination for packets along the path to "this" vertex.
+ *
+ * When initializing the root SPFVertex, the IP address used when forwarding
+ * packets is determined by examining the Global Router Link Records of the
+ * Link State Advertisement generated by the root node's GlobalRouter. This
+ * address is used to forward packets off of the root's network down those
+ * links. As other vertices / nodes are discovered which are further away
+ * from the root, they will be accessible down one of the paths via a link
+ * described by one of these Global Router Link Records.
+ *
+ * To forward packets to these hosts or networks, the root node must begin
+ * the forwarding process by sending the packets to a first hop router down
+ * an interface. This means that the first hop address and interface ID must
+ * be the same for all downstream SPFVertices. We call this "inheriting"
+ * the interface and next hop.
+ *
+ * In this method we are telling the root node which exit direction it should send
+ * should I send a packet to the network or host represented by 'this' SPFVertex.
+ *
+ * @see GlobalRouter
+ * @see GlobalRoutingLSA
+ * @see GlobalRoutingLinkRecord
+ * @param nextHop The IP address to use when forwarding packets to the host
+ * or network represented by "this" SPFVertex.
+ * @param id The interface index to use when forwarding packets to the host or
+ * network represented by "this" SPFVertex.
+ */
+ void SetRootExitDirection (Ipv4Address nextHop, int32_t id = SPF_INFINITY);
+ typedef std::pair<Ipv4Address, int32_t> NodeExit_t;
+/**
+ * @brief Set the IP address and outgoing interface index that should be used
+ * to begin forwarding packets from the root SPFVertex to "this" SPFVertex.
+ * @internal
+ *
+ * Each router node in the simulation is associated with an SPFVertex object.
+ * When calculating routes, each of these routers is, in turn, chosen as the
+ * "root" of the calculation and routes to all of the other routers are
+ * eventually saved in the routing tables of each of the chosen nodes.
+ *
+ * The "Root" vertex is then the SPFVertex representing the router that is
+ * having its routing tables set. The "this" SPFVertex is the vertex that
+ * represents the host or network to which a route is being calculated from
+ * the root. The IP address that we're asking for is the address on the
+ * remote side of a link off of the root node that should be used as the
+ * destination for packets along the path to "this" vertex.
+ *
+ * When initializing the root SPFVertex, the IP address used when forwarding
+ * packets is determined by examining the Global Router Link Records of the
+ * Link State Advertisement generated by the root node's GlobalRouter. This
+ * address is used to forward packets off of the root's network down those
+ * links. As other vertices / nodes are discovered which are further away
+ * from the root, they will be accessible down one of the paths via a link
+ * described by one of these Global Router Link Records.
+ *
+ * To forward packets to these hosts or networks, the root node must begin
+ * the forwarding process by sending the packets to a first hop router down
+ * an interface. This means that the first hop address and interface ID must
+ * be the same for all downstream SPFVertices. We call this "inheriting"
+ * the interface and next hop.
+ *
+ * In this method we are telling the root node which exit direction it should send
+ * should I send a packet to the network or host represented by 'this' SPFVertex.
+ *
+ * @see GlobalRouter
+ * @see GlobalRoutingLSA
+ * @see GlobalRoutingLinkRecord
+ * @param nextHop The IP address to use when forwarding packets to the host
+ * or network represented by "this" SPFVertex.
+ * @param exit The pair of next-hop-IP and outgoing-interface-index to use when
+ * forwarding packets to the host or network represented by "this" SPFVertex.
+ */
+ void SetRootExitDirection (SPFVertex::NodeExit_t exit);
+ /**
+ * \brief Obtain a pair indicating the exit direction from the root
+ *
+ * \param i An index to a pair
+ * \return A pair of next-hop-IP and outgoing-interface-index for
+ * indicating an exit direction from the root. It is 0 if the index 'i'
+ * is out-of-range
+ */
+ NodeExit_t GetRootExitDirection (uint32_t i) const;
+ /**
+ * \brief Obtain a pair indicating the exit direction from the root
+ *
+ * This method assumes there is only a single exit direction from the root.
+ * Error occur if this assumption is invalid.
+ *
+ * \return The pair of next-hop-IP and outgoing-interface-index for reaching
+ * 'this' vertex from the root
+ */
+ NodeExit_t GetRootExitDirection () const;
+ /**
+ * \brief Merge into 'this' vertex the list of exit directions from
+ * another vertex
+ *
+ * This merge is necessary when ECMP are found.
+ *
+ * \param vertex From which the list of exit directions are obtain
+ * and are merged into 'this' vertex
+ */
+ void MergeRootExitDirections (const SPFVertex* vertex);
+ /**
+ * \brief Inherit all root exit directions from a given vertex to 'this' vertex
+ * \param vertex The vertex from which all root exit directions are to be inherited
+ *
+ * After the call of this method, the original root exit directions
+ * in 'this' vertex are all lost.
+ */
+ void InheritAllRootExitDirections (const SPFVertex* vertex);
+ /**
+ * \brief Get the number of exit directions from root for reaching 'this' vertex
+ * \return The number of exit directions from root
+ */
+ uint32_t GetNRootExitDirections () const;
+
+/**
+ * @brief Get a pointer to the SPFVector that is the parent of "this"
+ * SPFVertex.
+ * @internal
+ *
+ * Each router node in the simulation is associated with an SPFVertex object.
+ * When calculating routes, each of these routers is, in turn, chosen as the
+ * "root" of the calculation and routes to all of the other routers are
+ * eventually saved in the routing tables of each of the chosen nodes.
+ *
+ * The "Root" vertex is then the SPFVertex representing the router that is
+ * having its routing tables set and is the root of the SPF tree.
+ *
+ * This method returns a pointer to the parent node of "this" SPFVertex
+ * (both of which reside in that SPF tree).
+ *
+ * @param i The index to one of the parents
+ * @returns A pointer to the SPFVertex that is the parent of "this" SPFVertex
+ * in the SPF tree.
+ */
+ SPFVertex* GetParent (uint32_t i = 0) const;
+
+/**
+ * @brief Set the pointer to the SPFVector that is the parent of "this"
+ * SPFVertex.
+ * @internal
+ *
+ * Each router node in the simulation is associated with an SPFVertex object.
+ * When calculating routes, each of these routers is, in turn, chosen as the
+ * "root" of the calculation and routes to all of the other routers are
+ * eventually saved in the routing tables of each of the chosen nodes.
+ *
+ * The "Root" vertex is then the SPFVertex representing the router that is
+ * having its routing tables set and is the root of the SPF tree.
+ *
+ * This method sets the parent pointer of "this" SPFVertex (both of which
+ * reside in that SPF tree).
+ *
+ * @param parent A pointer to the SPFVertex that is the parent of "this"
+ * SPFVertex* in the SPF tree.
+ */
+ void SetParent (SPFVertex* parent);
+ /**
+ * \brief Merge the Parent list from the v into this vertex
+ *
+ * \param v The vertex from which its list of Parent is read
+ * and then merged into the list of Parent of *this* vertex.
+ * Note that the list in v remains intact
+ */
+ void MergeParent (const SPFVertex* v);
+
+/**
+ * @brief Get the number of children of "this" SPFVertex.
+ * @internal
+ *
+ * Each router node in the simulation is associated with an SPFVertex object.
+ * When calculating routes, each of these routers is, in turn, chosen as the
+ * "root" of the calculation and routes to all of the other routers are
+ * eventually saved in the routing tables of each of the chosen nodes.
+ *
+ * The "Root" vertex is then the SPFVertex representing the router that is
+ * having its routing tables set and is the root of the SPF tree. Each vertex
+ * in the SPF tree can have a number of children that represent host or
+ * network routes available via that vertex.
+ *
+ * This method returns the number of children of "this" SPFVertex (which
+ * reside in the SPF tree).
+ *
+ * @returns The number of children of "this" SPFVertex (which reside in the
+ * SPF tree).
+ */
+ uint32_t GetNChildren (void) const;
+
+/**
+ * @brief Get a borrowed SPFVertex pointer to the specified child of "this"
+ * SPFVertex.
+ * @internal
+ *
+ * Each router node in the simulation is associated with an SPFVertex object.
+ * When calculating routes, each of these routers is, in turn, chosen as the
+ * "root" of the calculation and routes to all of the other routers are
+ * eventually saved in the routing tables of each of the chosen nodes.
+ *
+ * The "Root" vertex is then the SPFVertex representing the router that is
+ * having its routing tables set and is the root of the SPF tree. Each vertex
+ * in the SPF tree can have a number of children that represent host or
+ * network routes available via that vertex.
+ *
+ * This method the number of children of "this" SPFVertex (which reside in
+ * the SPF tree.
+ *
+ * @see SPFVertex::GetNChildren
+ * @param n The index (from 0 to the number of children minus 1) of the
+ * child SPFVertex to return.
+ * @warning The pointer returned by GetChild () is a borrowed pointer. You
+ * do not have any ownership of the underlying object and must not delete
+ * that object.
+ * @returns A pointer to the specified child SPFVertex (which resides in the
+ * SPF tree).
+ */
+ SPFVertex* GetChild (uint32_t n) const;
+
+/**
+ * @brief Get a borrowed SPFVertex pointer to the specified child of "this"
+ * SPFVertex.
+ * @internal
+ *
+ * Each router node in the simulation is associated with an SPFVertex object.
+ * When calculating routes, each of these routers is, in turn, chosen as the
+ * "root" of the calculation and routes to all of the other routers are
+ * eventually saved in the routing tables of each of the chosen nodes.
+ *
+ * The "Root" vertex is then the SPFVertex representing the router that is
+ * having its routing tables set and is the root of the SPF tree. Each vertex
+ * in the SPF tree can have a number of children that represent host or
+ * network routes available via that vertex.
+ *
+ * This method the number of children of "this" SPFVertex (which reside in
+ * the SPF tree.
+ *
+ * @see SPFVertex::GetNChildren
+ * @warning Ownership of the pointer added to the children of "this"
+ * SPFVertex is transferred to the "this" SPFVertex. You must not delete the
+ * (now) child SPFVertex after calling this method.
+ * @param child A pointer to the SPFVertex (which resides in the SPF tree) to
+ * be added to the list of children of "this" SPFVertex.
+ * @returns The number of children of "this" SPFVertex after the addition of
+ * the new child.
+ */
+ uint32_t AddChild (SPFVertex* child);
+
+ /**
+ * @brief Set the value of the VertexProcessed flag
+ *
+ * Flag to note whether vertex has been processed in stage two of
+ * SPF computation
+ * @param value boolean value to set the flag
+ */
+ void SetVertexProcessed (bool value);
+
+ /**
+ * @brief Check the value of the VertexProcessed flag
+ *
+ * Flag to note whether vertex has been processed in stage two of
+ * SPF computation
+ * @returns value of underlying flag
+ */
+ bool IsVertexProcessed (void) const;
+
+ void ClearVertexProcessed (void);
+
+private:
+ VertexType m_vertexType;
+ Ipv4Address m_vertexId;
+ GlobalRoutingLSA* m_lsa;
+ uint32_t m_distanceFromRoot;
+ int32_t m_rootOif;
+ Ipv4Address m_nextHop;
+ typedef std::list< NodeExit_t > ListOfNodeExit_t;
+ /// store the multiple root's exits for supporting ECMP
+ ListOfNodeExit_t m_ecmpRootExits;
+ typedef std::list<SPFVertex*> ListOfSPFVertex_t;
+ ListOfSPFVertex_t m_parents;
+ ListOfSPFVertex_t m_children;
+ bool m_vertexProcessed;
+
+/**
+ * @brief The SPFVertex copy construction is disallowed. There's no need for
+ * it and a compiler provided shallow copy would be wrong.
+ */
+ SPFVertex (SPFVertex& v);
+
+/**
+ * @brief The SPFVertex copy assignment operator is disallowed. There's no
+ * need for it and a compiler provided shallow copy would be wrong.
+ */
+ SPFVertex& operator= (SPFVertex& v);
+
+ //friend std::ostream& operator<< (std::ostream& os, const ListOfIf_t& ifs);
+ //friend std::ostream& operator<< (std::ostream& os, const ListOfAddr_t& addrs);
+ friend std::ostream& operator<< (std::ostream& os, const SPFVertex::ListOfSPFVertex_t& vs);
+};
+
+/**
+ * @brief The Link State DataBase (LSDB) of the Global Route Manager.
+ *
+ * Each node in the simulation participating in global routing has a
+ * GlobalRouter interface. The primary job of this interface is to export
+ * Global Router Link State Advertisements (LSAs). These advertisements in
+ * turn contain a number of Global Router Link Records that describe the
+ * point to point links from the underlying node to other nodes (that will
+ * also export their own LSAs.
+ *
+ * This class implements a searchable database of LSAs gathered from every
+ * router in the simulation.
+ */
+class GlobalRouteManagerLSDB
+{
+public:
+/**
+ * @brief Construct an empty Global Router Manager Link State Database.
+ * @internal
+ *
+ * The database map composing the Link State Database is initialized in
+ * this constructor.
+ */
+ GlobalRouteManagerLSDB ();
+
+/**
+ * @brief Destroy an empty Global Router Manager Link State Database.
+ * @internal
+ *
+ * The database map is walked and all of the Link State Advertisements stored
+ * in the database are freed; then the database map itself is clear ()ed to
+ * release any remaining resources.
+ */
+ ~GlobalRouteManagerLSDB ();
+
+/**
+ * @brief Insert an IP address / Link State Advertisement pair into the Link
+ * State Database.
+ * @internal
+ *
+ * The IPV4 address and the GlobalRoutingLSA given as parameters are converted
+ * to an STL pair and are inserted into the database map.
+ *
+ * @see GlobalRoutingLSA
+ * @see Ipv4Address
+ * @param addr The IP address associated with the LSA. Typically the Router
+ * ID.
+ * @param lsa A pointer to the Link State Advertisement for the router.
+ */
+ void Insert(Ipv4Address addr, GlobalRoutingLSA* lsa);
+
+/**
+ * @brief Look up the Link State Advertisement associated with the given
+ * link state ID (address).
+ * @internal
+ *
+ * The database map is searched for the given IPV4 address and corresponding
+ * GlobalRoutingLSA is returned.
+ *
+ * @see GlobalRoutingLSA
+ * @see Ipv4Address
+ * @param addr The IP address associated with the LSA. Typically the Router
+ * ID.
+ * @returns A pointer to the Link State Advertisement for the router specified
+ * by the IP address addr.
+ */
+ GlobalRoutingLSA* GetLSA (Ipv4Address addr) const;
+/**
+ * @brief Look up the Link State Advertisement associated with the given
+ * link state ID (address). This is a variation of the GetLSA call
+ * to allow the LSA to be found by matching addr with the LinkData field
+ * of the TransitNetwork link record.
+ * @internal
+ *
+ * @see GetLSA
+ * @param addr The IP address associated with the LSA. Typically the Router
+ * @returns A pointer to the Link State Advertisement for the router specified
+ * by the IP address addr.
+ * ID.
+ */
+ GlobalRoutingLSA* GetLSAByLinkData (Ipv4Address addr) const;
+
+/**
+ * @brief Set all LSA flags to an initialized state, for SPF computation
+ * @internal
+ *
+ * This function walks the database and resets the status flags of all of the
+ * contained Link State Advertisements to LSA_SPF_NOT_EXPLORED. This is done
+ * prior to each SPF calculation to reset the state of the SPFVertex structures
+ * that will reference the LSAs during the calculation.
+ *
+ * @see GlobalRoutingLSA
+ * @see SPFVertex
+ */
+ void Initialize ();
+
+ GlobalRoutingLSA* GetExtLSA (uint32_t index) const;
+ uint32_t GetNumExtLSAs () const;
+
+
+private:
+ typedef std::map<Ipv4Address, GlobalRoutingLSA*> LSDBMap_t;
+ typedef std::pair<Ipv4Address, GlobalRoutingLSA*> LSDBPair_t;
+
+ LSDBMap_t m_database;
+ std::vector<GlobalRoutingLSA*> m_extdatabase;
+
+/**
+ * @brief GlobalRouteManagerLSDB copy construction is disallowed. There's no
+ * need for it and a compiler provided shallow copy would be wrong.
+ */
+ GlobalRouteManagerLSDB (GlobalRouteManagerLSDB& lsdb);
+
+/**
+ * @brief The SPFVertex copy assignment operator is disallowed. There's no
+ * need for it and a compiler provided shallow copy would be wrong.
+ */
+ GlobalRouteManagerLSDB& operator= (GlobalRouteManagerLSDB& lsdb);
+};
+
+/**
+ * @brief A global router implementation.
+ *
+ * This singleton object can query interface each node in the system
+ * for a GlobalRouter interface. For those nodes, it fetches one or
+ * more Link State Advertisements and stores them in a local database.
+ * Then, it can compute shortest paths on a per-node basis to all routers,
+ * and finally configure each of the node's forwarding tables.
+ *
+ * The design is guided by OSPFv2 RFC 2328 section 16.1.1 and quagga ospfd.
+ */
+class GlobalRouteManagerImpl
+{
+public:
+ GlobalRouteManagerImpl ();
+ virtual ~GlobalRouteManagerImpl ();
+/**
+ * @brief Delete all static routes on all nodes that have a
+ * GlobalRouterInterface
+ *
+ * TODO: separate manually assigned static routes from static routes that
+ * the global routing code injects, and only delete the latter
+ * @internal
+ *
+ */
+ virtual void DeleteGlobalRoutes ();
+
+/**
+ * @brief Build the routing database by gathering Link State Advertisements
+ * from each node exporting a GlobalRouter interface.
+ * @internal
+ */
+ virtual void BuildGlobalRoutingDatabase ();
+
+/**
+ * @brief Compute routes using a Dijkstra SPF computation and populate
+ * per-node forwarding tables
+ * @internal
+ */
+ virtual void InitializeRoutes ();
+
+/**
+ * @brief Debugging routine; allow client code to supply a pre-built LSDB
+ * @internal
+ */
+ void DebugUseLsdb (GlobalRouteManagerLSDB*);
+
+/**
+ * @brief Debugging routine; call the core SPF from the unit tests
+ * @internal
+ */
+ void DebugSPFCalculate (Ipv4Address root);
+
+private:
+/**
+ * @brief GlobalRouteManagerImpl copy construction is disallowed.
+ * There's no need for it and a compiler provided shallow copy would be
+ * wrong.
+ */
+ GlobalRouteManagerImpl (GlobalRouteManagerImpl& srmi);
+
+/**
+ * @brief Global Route Manager Implementation assignment operator is
+ * disallowed. There's no need for it and a compiler provided shallow copy
+ * would be hopelessly wrong.
+ */
+ GlobalRouteManagerImpl& operator= (GlobalRouteManagerImpl& srmi);
+
+ SPFVertex* m_spfroot;
+ GlobalRouteManagerLSDB* m_lsdb;
+ bool CheckForStubNode (Ipv4Address root);
+ void SPFCalculate (Ipv4Address root);
+ void SPFProcessStubs (SPFVertex* v);
+ void ProcessASExternals (SPFVertex* v, GlobalRoutingLSA* extlsa);
+ void SPFNext (SPFVertex*, CandidateQueue&);
+ int SPFNexthopCalculation (SPFVertex* v, SPFVertex* w,
+ GlobalRoutingLinkRecord* l, uint32_t distance);
+ void SPFVertexAddParent (SPFVertex* v);
+ GlobalRoutingLinkRecord* SPFGetNextLink (SPFVertex* v, SPFVertex* w,
+ GlobalRoutingLinkRecord* prev_link);
+ void SPFIntraAddRouter (SPFVertex* v);
+ void SPFIntraAddTransit (SPFVertex* v);
+ void SPFIntraAddStub (GlobalRoutingLinkRecord *l, SPFVertex* v);
+ void SPFAddASExternal (GlobalRoutingLSA *extlsa, SPFVertex *v);
+ int32_t FindOutgoingInterfaceId (Ipv4Address a,
+ Ipv4Mask amask = Ipv4Mask("255.255.255.255"));
+};
+
+} // namespace ns3
+
+#endif /* GLOBAL_ROUTE_MANAGER_IMPL_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/global-route-manager.cc Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,64 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2007 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Tom Henderson (tomhend@u.washington.edu)
+ */
+
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/simulation-singleton.h"
+#include "global-route-manager.h"
+#include "global-route-manager-impl.h"
+
+namespace ns3 {
+
+// ---------------------------------------------------------------------------
+//
+// GlobalRouteManager Implementation
+//
+// ---------------------------------------------------------------------------
+
+ void
+GlobalRouteManager::DeleteGlobalRoutes ()
+{
+ SimulationSingleton<GlobalRouteManagerImpl>::Get ()->
+ DeleteGlobalRoutes ();
+}
+
+ void
+GlobalRouteManager::BuildGlobalRoutingDatabase (void)
+{
+ SimulationSingleton<GlobalRouteManagerImpl>::Get ()->
+ BuildGlobalRoutingDatabase ();
+}
+
+ void
+GlobalRouteManager::InitializeRoutes (void)
+{
+ SimulationSingleton<GlobalRouteManagerImpl>::Get ()->
+ InitializeRoutes ();
+}
+
+ uint32_t
+GlobalRouteManager::AllocateRouterId (void)
+{
+ static uint32_t routerId = 0;
+ return routerId++;
+}
+
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/global-route-manager.h Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,87 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2007 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors: Craig Dowell (craigdo@ee.washington.edu)
+ * Tom Henderson (tomhend@u.washington.edu)
+ */
+
+#ifndef GLOBAL_ROUTE_MANAGER_H
+#define GLOBAL_ROUTE_MANAGER_H
+
+#include "ns3/deprecated.h"
+
+namespace ns3 {
+
+/**
+ * @brief A global global router
+ *
+ * This singleton object can query interface each node in the system
+ * for a GlobalRouter interface. For those nodes, it fetches one or
+ * more Link State Advertisements and stores them in a local database.
+ * Then, it can compute shortest paths on a per-node basis to all routers,
+ * and finally configure each of the node's forwarding tables.
+ *
+ * The design is guided by OSPFv2 RFC 2328 section 16.1.1 and quagga ospfd.
+ */
+class GlobalRouteManager
+{
+public:
+/**
+ * @brief Allocate a 32-bit router ID from monotonically increasing counter.
+ */
+ static uint32_t AllocateRouterId ();
+
+/**
+ * @brief Delete all static routes on all nodes that have a
+ * GlobalRouterInterface
+ *
+ */
+ static void DeleteGlobalRoutes ();
+
+/**
+ * @brief Build the routing database by gathering Link State Advertisements
+ * from each node exporting a GlobalRouter interface.
+ * @internal
+ *
+ */
+ static void BuildGlobalRoutingDatabase ();
+
+/**
+ * @brief Compute routes using a Dijkstra SPF computation and populate
+ * per-node forwarding tables
+ * @internal
+ */
+ static void InitializeRoutes ();
+
+private:
+/**
+ * @brief Global Route Manager copy construction is disallowed. There's no
+ * need for it and a compiler provided shallow copy would be wrong.
+ *
+ */
+ GlobalRouteManager (GlobalRouteManager& srm);
+
+/**
+ * @brief Global Router copy assignment operator is disallowed. There's no
+ * need for it and a compiler provided shallow copy would be wrong.
+ */
+ GlobalRouteManager& operator= (GlobalRouteManager& srm);
+};
+
+} // namespace ns3
+
+#endif /* GLOBAL_ROUTE_MANAGER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/global-router-interface.cc Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,1694 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2007 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors: Tom Henderson (tomhend@u.washington.edu)
+ */
+
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "ns3/abort.h"
+#include "ns3/channel.h"
+#include "ns3/net-device.h"
+#include "ns3/node.h"
+#include "ns3/node-list.h"
+#include "ns3/ipv4.h"
+#include "ns3/bridge-net-device.h"
+#include "ipv4-global-routing.h"
+#include "global-router-interface.h"
+#include <vector>
+
+NS_LOG_COMPONENT_DEFINE ("GlobalRouter");
+
+namespace ns3 {
+
+// ---------------------------------------------------------------------------
+//
+// GlobalRoutingLinkRecord Implementation
+//
+// ---------------------------------------------------------------------------
+
+GlobalRoutingLinkRecord::GlobalRoutingLinkRecord ()
+:
+ m_linkId ("0.0.0.0"),
+ m_linkData ("0.0.0.0"),
+ m_linkType (Unknown),
+ m_metric (0)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+GlobalRoutingLinkRecord::GlobalRoutingLinkRecord (
+ LinkType linkType,
+ Ipv4Address linkId,
+ Ipv4Address linkData,
+ uint16_t metric)
+:
+ m_linkId (linkId),
+ m_linkData (linkData),
+ m_linkType (linkType),
+ m_metric (metric)
+{
+ NS_LOG_FUNCTION (this << linkType << linkId << linkData << metric);
+}
+
+GlobalRoutingLinkRecord::~GlobalRoutingLinkRecord ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+ Ipv4Address
+GlobalRoutingLinkRecord::GetLinkId (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_linkId;
+}
+
+ void
+GlobalRoutingLinkRecord::SetLinkId (Ipv4Address addr)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_linkId = addr;
+}
+
+ Ipv4Address
+GlobalRoutingLinkRecord::GetLinkData (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_linkData;
+}
+
+ void
+GlobalRoutingLinkRecord::SetLinkData (Ipv4Address addr)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_linkData = addr;
+}
+
+ GlobalRoutingLinkRecord::LinkType
+GlobalRoutingLinkRecord::GetLinkType (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_linkType;
+}
+
+ void
+GlobalRoutingLinkRecord::SetLinkType (
+ GlobalRoutingLinkRecord::LinkType linkType)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_linkType = linkType;
+}
+
+ uint16_t
+GlobalRoutingLinkRecord::GetMetric (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_metric;
+}
+
+ void
+GlobalRoutingLinkRecord::SetMetric (uint16_t metric)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_metric = metric;
+}
+
+// ---------------------------------------------------------------------------
+//
+// GlobalRoutingLSA Implementation
+//
+// ---------------------------------------------------------------------------
+
+GlobalRoutingLSA::GlobalRoutingLSA()
+ :
+ m_lsType (GlobalRoutingLSA::Unknown),
+ m_linkStateId("0.0.0.0"),
+ m_advertisingRtr("0.0.0.0"),
+ m_linkRecords(),
+ m_networkLSANetworkMask("0.0.0.0"),
+ m_attachedRouters(),
+ m_status(GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED),
+ m_node_id(0)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+GlobalRoutingLSA::GlobalRoutingLSA (
+ GlobalRoutingLSA::SPFStatus status,
+ Ipv4Address linkStateId,
+ Ipv4Address advertisingRtr)
+:
+ m_lsType (GlobalRoutingLSA::Unknown),
+ m_linkStateId(linkStateId),
+ m_advertisingRtr(advertisingRtr),
+ m_linkRecords(),
+ m_networkLSANetworkMask("0.0.0.0"),
+ m_attachedRouters(),
+ m_status(status),
+ m_node_id(0)
+{
+ NS_LOG_FUNCTION (this << status << linkStateId << advertisingRtr);
+}
+
+GlobalRoutingLSA::GlobalRoutingLSA (GlobalRoutingLSA& lsa)
+ : m_lsType(lsa.m_lsType), m_linkStateId(lsa.m_linkStateId),
+ m_advertisingRtr(lsa.m_advertisingRtr),
+ m_networkLSANetworkMask(lsa.m_networkLSANetworkMask),
+ m_status(lsa.m_status),
+ m_node_id(lsa.m_node_id)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ NS_ASSERT_MSG(IsEmpty(),
+ "GlobalRoutingLSA::GlobalRoutingLSA (): Non-empty LSA in constructor");
+ CopyLinkRecords (lsa);
+}
+
+ GlobalRoutingLSA&
+GlobalRoutingLSA::operator= (const GlobalRoutingLSA& lsa)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_lsType = lsa.m_lsType;
+ m_linkStateId = lsa.m_linkStateId;
+ m_advertisingRtr = lsa.m_advertisingRtr;
+ m_networkLSANetworkMask = lsa.m_networkLSANetworkMask,
+ m_status = lsa.m_status;
+ m_node_id = lsa.m_node_id;
+
+ ClearLinkRecords ();
+ CopyLinkRecords (lsa);
+ return *this;
+}
+
+ void
+GlobalRoutingLSA::CopyLinkRecords (const GlobalRoutingLSA& lsa)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ for (ListOfLinkRecords_t::const_iterator i = lsa.m_linkRecords.begin ();
+ i != lsa.m_linkRecords.end ();
+ i++)
+ {
+ GlobalRoutingLinkRecord *pSrc = *i;
+ GlobalRoutingLinkRecord *pDst = new GlobalRoutingLinkRecord;
+
+ pDst->SetLinkType (pSrc->GetLinkType ());
+ pDst->SetLinkId (pSrc->GetLinkId ());
+ pDst->SetLinkData (pSrc->GetLinkData ());
+ pDst->SetMetric (pSrc->GetMetric ());
+
+ m_linkRecords.push_back(pDst);
+ pDst = 0;
+ }
+
+ m_attachedRouters = lsa.m_attachedRouters;
+}
+
+GlobalRoutingLSA::~GlobalRoutingLSA()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ ClearLinkRecords ();
+}
+
+ void
+GlobalRoutingLSA::ClearLinkRecords(void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin ();
+ i != m_linkRecords.end ();
+ i++)
+ {
+ NS_LOG_LOGIC ("Free link record");
+
+ GlobalRoutingLinkRecord *p = *i;
+ delete p;
+ p = 0;
+
+ *i = 0;
+ }
+ NS_LOG_LOGIC ("Clear list");
+ m_linkRecords.clear();
+}
+
+ uint32_t
+GlobalRoutingLSA::AddLinkRecord (GlobalRoutingLinkRecord* lr)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_linkRecords.push_back (lr);
+ return m_linkRecords.size ();
+}
+
+ uint32_t
+GlobalRoutingLSA::GetNLinkRecords (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_linkRecords.size ();
+}
+
+ GlobalRoutingLinkRecord *
+GlobalRoutingLSA::GetLinkRecord (uint32_t n) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ uint32_t j = 0;
+ for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin ();
+ i != m_linkRecords.end ();
+ i++, j++)
+ {
+ if (j == n)
+ {
+ return *i;
+ }
+ }
+ NS_ASSERT_MSG(false, "GlobalRoutingLSA::GetLinkRecord (): invalid index");
+ return 0;
+}
+
+ bool
+GlobalRoutingLSA::IsEmpty (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_linkRecords.size () == 0;
+}
+
+ GlobalRoutingLSA::LSType
+GlobalRoutingLSA::GetLSType (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_lsType;
+}
+
+ void
+GlobalRoutingLSA::SetLSType (GlobalRoutingLSA::LSType typ)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_lsType = typ;
+}
+
+ Ipv4Address
+GlobalRoutingLSA::GetLinkStateId (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_linkStateId;
+}
+
+ void
+GlobalRoutingLSA::SetLinkStateId (Ipv4Address addr)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_linkStateId = addr;
+}
+
+ Ipv4Address
+GlobalRoutingLSA::GetAdvertisingRouter (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_advertisingRtr;
+}
+
+ void
+GlobalRoutingLSA::SetAdvertisingRouter (Ipv4Address addr)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_advertisingRtr = addr;
+}
+
+ void
+GlobalRoutingLSA::SetNetworkLSANetworkMask (Ipv4Mask mask)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_networkLSANetworkMask = mask;
+}
+
+ Ipv4Mask
+GlobalRoutingLSA::GetNetworkLSANetworkMask (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_networkLSANetworkMask;
+}
+
+ GlobalRoutingLSA::SPFStatus
+GlobalRoutingLSA::GetStatus (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_status;
+}
+
+ uint32_t
+GlobalRoutingLSA::AddAttachedRouter (Ipv4Address addr)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_attachedRouters.push_back (addr);
+ return m_attachedRouters.size ();
+}
+
+ uint32_t
+GlobalRoutingLSA::GetNAttachedRouters (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_attachedRouters.size ();
+}
+
+ Ipv4Address
+GlobalRoutingLSA::GetAttachedRouter (uint32_t n) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ uint32_t j = 0;
+ for ( ListOfAttachedRouters_t::const_iterator i = m_attachedRouters.begin ();
+ i != m_attachedRouters.end ();
+ i++, j++)
+ {
+ if (j == n)
+ {
+ return *i;
+ }
+ }
+ NS_ASSERT_MSG(false, "GlobalRoutingLSA::GetAttachedRouter (): invalid index");
+ return Ipv4Address("0.0.0.0");
+}
+
+ void
+GlobalRoutingLSA::SetStatus (GlobalRoutingLSA::SPFStatus status)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_status = status;
+}
+
+ Ptr<Node>
+GlobalRoutingLSA::GetNode (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return NodeList::GetNode (m_node_id);
+}
+
+ void
+GlobalRoutingLSA::SetNode (Ptr<Node> node)
+{
+ NS_LOG_FUNCTION (node);
+ m_node_id = node->GetId ();
+}
+
+ void
+GlobalRoutingLSA::Print (std::ostream &os) const
+{
+ os << std::endl;
+ os << "========== Global Routing LSA ==========" << std::endl;
+ os << "m_lsType = " << m_lsType;
+ if (m_lsType == GlobalRoutingLSA::RouterLSA)
+ {
+ os << " (GlobalRoutingLSA::RouterLSA)";
+ }
+ else if (m_lsType == GlobalRoutingLSA::NetworkLSA)
+ {
+ os << " (GlobalRoutingLSA::NetworkLSA)";
+ }
+ else if (m_lsType == GlobalRoutingLSA::ASExternalLSAs)
+ {
+ os << " (GlobalRoutingLSA::ASExternalLSA)";
+ }
+ else
+ {
+ os << "(Unknown LSType)";
+ }
+ os << std::endl;
+
+ os << "m_linkStateId = " << m_linkStateId << " (Router ID)" << std::endl;
+ os << "m_advertisingRtr = " << m_advertisingRtr << " (Router ID)" << std::endl;
+
+ if (m_lsType == GlobalRoutingLSA::RouterLSA)
+ {
+ for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin ();
+ i != m_linkRecords.end ();
+ i++)
+ {
+ GlobalRoutingLinkRecord *p = *i;
+
+ os << "---------- RouterLSA Link Record ----------" << std::endl;
+ os << "m_linkType = " << p->m_linkType;
+ if (p->m_linkType == GlobalRoutingLinkRecord::PointToPoint)
+ {
+ os << " (GlobalRoutingLinkRecord::PointToPoint)" << std::endl;
+ os << "m_linkId = " << p->m_linkId << std::endl;
+ os << "m_linkData = " << p->m_linkData << std::endl;
+ os << "m_metric = " << p->m_metric << std::endl;
+ }
+ else if (p->m_linkType == GlobalRoutingLinkRecord::TransitNetwork)
+ {
+ os << " (GlobalRoutingLinkRecord::TransitNetwork)" << std::endl;
+ os << "m_linkId = " << p->m_linkId << " (Designated router for network)" << std::endl;
+ os << "m_linkData = " << p->m_linkData << " (This router's IP address)" << std::endl;
+ os << "m_metric = " << p->m_metric << std::endl;
+ }
+ else if (p->m_linkType == GlobalRoutingLinkRecord::StubNetwork)
+ {
+ os << " (GlobalRoutingLinkRecord::StubNetwork)" << std::endl;
+ os << "m_linkId = " << p->m_linkId << " (Network number of attached network)" << std::endl;
+ os << "m_linkData = " << p->m_linkData << " (Network mask of attached network)" << std::endl;
+ os << "m_metric = " << p->m_metric << std::endl;
+ }
+ else
+ {
+ os << " (Unknown LinkType)" << std::endl;
+ os << "m_linkId = " << p->m_linkId << std::endl;
+ os << "m_linkData = " << p->m_linkData << std::endl;
+ os << "m_metric = " << p->m_metric << std::endl;
+ }
+ os << "---------- End RouterLSA Link Record ----------" << std::endl;
+ }
+ }
+ else if (m_lsType == GlobalRoutingLSA::NetworkLSA)
+ {
+ os << "---------- NetworkLSA Link Record ----------" << std::endl;
+ os << "m_networkLSANetworkMask = " << m_networkLSANetworkMask << std::endl;
+ for ( ListOfAttachedRouters_t::const_iterator i = m_attachedRouters.begin (); i != m_attachedRouters.end (); i++)
+ {
+ Ipv4Address p = *i;
+ os << "attachedRouter = " << p << std::endl;
+ }
+ os << "---------- End NetworkLSA Link Record ----------" << std::endl;
+ }
+ else if (m_lsType == GlobalRoutingLSA::ASExternalLSAs)
+ {
+ os << "---------- ASExternalLSA Link Record --------" << std::endl;
+ os << "m_linkStateId = " << m_linkStateId << std::endl;
+ os << "m_networkLSANetworkMask = " << m_networkLSANetworkMask << std::endl;
+ }
+ else
+ {
+ NS_ASSERT_MSG(0, "Illegal LSA LSType: " << m_lsType);
+ }
+ os << "========== End Global Routing LSA ==========" << std::endl;
+}
+
+std::ostream& operator<< (std::ostream& os, GlobalRoutingLSA& lsa)
+{
+ lsa.Print (os);
+ return os;
+}
+
+// ---------------------------------------------------------------------------
+//
+// GlobalRouter Implementation
+//
+// ---------------------------------------------------------------------------
+
+NS_OBJECT_ENSURE_REGISTERED (GlobalRouter);
+
+TypeId
+GlobalRouter::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::GlobalRouter")
+ .SetParent<Object> ();
+ return tid;
+}
+
+GlobalRouter::GlobalRouter ()
+ : m_LSAs()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_routerId.Set(GlobalRouteManager::AllocateRouterId ());
+}
+
+GlobalRouter::~GlobalRouter ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ ClearLSAs();
+}
+
+void
+GlobalRouter::SetRoutingProtocol (Ptr<Ipv4GlobalRouting> routing)
+{
+ m_routingProtocol = routing;
+}
+Ptr<Ipv4GlobalRouting>
+GlobalRouter::GetRoutingProtocol (void)
+{
+ return m_routingProtocol;
+}
+
+void
+GlobalRouter::DoDispose ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_routingProtocol = 0;
+ for (InjectedRoutesI k = m_injectedRoutes.begin ();
+ k != m_injectedRoutes.end ();
+ k = m_injectedRoutes.erase (k))
+ {
+ delete (*k);
+ }
+ Object::DoDispose ();
+}
+
+ void
+GlobalRouter::ClearLSAs ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ for ( ListOfLSAs_t::iterator i = m_LSAs.begin ();
+ i != m_LSAs.end ();
+ i++)
+ {
+ NS_LOG_LOGIC ("Free LSA");
+
+ GlobalRoutingLSA *p = *i;
+ delete p;
+ p = 0;
+
+ *i = 0;
+ }
+ NS_LOG_LOGIC ("Clear list of LSAs");
+ m_LSAs.clear();
+}
+
+ Ipv4Address
+GlobalRouter::GetRouterId (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_routerId;
+}
+
+//
+// DiscoverLSAs is called on all nodes in the system that have a GlobalRouter
+// interface aggregated. We need to go out and discover any adjacent routers
+// and build the Link State Advertisements that reflect them and their associated
+// networks.
+//
+uint32_t
+GlobalRouter::DiscoverLSAs ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Ptr<Node> node = GetObject<Node> ();
+ NS_ABORT_MSG_UNLESS (node, "GlobalRouter::DiscoverLSAs (): GetObject for <Node> interface failed");
+ NS_LOG_LOGIC ("For node " << node->GetId () );
+
+ ClearLSAs ();
+
+ //
+ // While building the Router-LSA, keep a list of those NetDevices for
+ // which the current node is the designated router and we will later build
+ // a NetworkLSA for.
+ //
+ NetDeviceContainer c;
+
+ //
+ // We're aggregated to a node. We need to ask the node for a pointer to its
+ // Ipv4 interface. This is where the information regarding the attached
+ // interfaces lives. If we're a router, we had better have an Ipv4 interface.
+ //
+ Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
+ NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::DiscoverLSAs (): GetObject for <Ipv4> interface failed");
+
+ //
+ // Every router node originates a Router-LSA
+ //
+ GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
+ pLSA->SetLSType (GlobalRoutingLSA::RouterLSA);
+ pLSA->SetLinkStateId (m_routerId);
+ pLSA->SetAdvertisingRouter (m_routerId);
+ pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
+ pLSA->SetNode (node);
+
+ //
+ // Ask the node for the number of net devices attached. This isn't necessarily
+ // equal to the number of links to adjacent nodes (other routers) as the number
+ // of devices may include those for stub networks (e.g., ethernets, etc.) and
+ // bridge devices also take up an "extra" net device.
+ //
+ uint32_t numDevices = node->GetNDevices();
+
+ //
+ // Iterate through the devices on the node and walk the channel to see what's
+ // on the other side of the standalone devices..
+ //
+ for (uint32_t i = 0; i < numDevices; ++i)
+ {
+ Ptr<NetDevice> ndLocal = node->GetDevice(i);
+
+ //
+ // There is an assumption that bridge ports must never have an IP address
+ // associated with them. This turns out to be a very convenient place to
+ // check and make sure that this is the case.
+ //
+ if (NetDeviceIsBridged (ndLocal))
+ {
+ uint32_t interfaceBridge;
+ bool rc = FindInterfaceForDevice(node, ndLocal, interfaceBridge);
+ NS_ABORT_MSG_IF (rc, "GlobalRouter::DiscoverLSAs(): Bridge ports must not have an IPv4 interface index");
+ }
+
+ //
+ // Check to see if the net device we just got has a corresponding IP
+ // interface (could be a pure L2 NetDevice) -- for example a net device
+ // associated with a bridge. We are only going to involve devices with
+ // IP addresses in routing.
+ //
+ bool isForwarding = false;
+ for (uint32_t j = 0; j < ipv4Local->GetNInterfaces (); ++j )
+ {
+ if (ipv4Local->GetNetDevice (j) == ndLocal && ipv4Local->IsUp (j) &&
+ ipv4Local->IsForwarding (j))
+ {
+ isForwarding = true;
+ break;
+ }
+ }
+
+ if (!isForwarding)
+ {
+ NS_LOG_LOGIC ("Net device " << ndLocal << "has no IP interface or is not enabled for forwarding, skipping");
+ continue;
+ }
+
+ //
+ // We have a net device that we need to check out. If it suports
+ // broadcast and is not a point-point link, then it will be either a stub
+ // network or a transit network depending on the number of routers on
+ // the segment. We add the appropriate link record to the LSA.
+ //
+ // If the device is a point to point link, we treat it separately. In
+ // that case, there may be zero, one, or two link records added.
+ //
+
+ if (ndLocal->IsBroadcast () && !ndLocal->IsPointToPoint () )
+ {
+ NS_LOG_LOGIC ("Broadcast link");
+ ProcessBroadcastLink (ndLocal, pLSA, c);
+ }
+ else if (ndLocal->IsPointToPoint () )
+ {
+ NS_LOG_LOGIC ("Point=to-point link");
+ ProcessPointToPointLink (ndLocal, pLSA);
+ }
+ else
+ {
+ NS_ASSERT_MSG(0, "GlobalRouter::DiscoverLSAs (): unknown link type");
+ }
+ }
+
+ NS_LOG_LOGIC ("========== LSA for node " << node->GetId () << " ==========");
+ NS_LOG_LOGIC (*pLSA);
+ m_LSAs.push_back (pLSA);
+ pLSA = 0;
+
+ //
+ // Now, determine whether we need to build a NetworkLSA. This is the case if
+ // we found at least one designated router.
+ //
+ uint32_t nDesignatedRouters = c.GetN ();
+ if (nDesignatedRouters > 0)
+ {
+ NS_LOG_LOGIC ("Build Network LSAs");
+ BuildNetworkLSAs (c);
+ }
+
+ //
+ // Build injected route LSAs as external routes
+ // RFC 2328, section 12.4.4
+ //
+ for (InjectedRoutesCI i = m_injectedRoutes.begin();
+ i != m_injectedRoutes.end();
+ i++)
+ {
+ GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
+ pLSA->SetLSType (GlobalRoutingLSA::ASExternalLSAs);
+ pLSA->SetLinkStateId ((*i)->GetDestNetwork ());
+ pLSA->SetAdvertisingRouter (m_routerId);
+ pLSA->SetNetworkLSANetworkMask ((*i)->GetDestNetworkMask ());
+ pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
+ m_LSAs.push_back (pLSA);
+ }
+ return m_LSAs.size ();
+}
+
+ void
+GlobalRouter::ProcessBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c)
+{
+ NS_LOG_FUNCTION (nd << pLSA << &c);
+
+ if (nd->IsBridge ())
+ {
+ ProcessBridgedBroadcastLink (nd, pLSA, c);
+ }
+ else
+ {
+ ProcessSingleBroadcastLink (nd, pLSA, c);
+ }
+}
+
+ void
+GlobalRouter::ProcessSingleBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c)
+{
+ NS_LOG_FUNCTION (nd << pLSA << &c);
+
+ GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord;
+ NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessSingleBroadcastLink(): Can't alloc link record");
+
+ //
+ // We have some preliminaries to do to get enough information to proceed.
+ // This information we need comes from the internet stack, so notice that
+ // there is an implied assumption that global routing is only going to
+ // work with devices attached to the internet stack (have an ipv4 interface
+ // associated to them.
+ //
+ Ptr<Node> node = nd->GetNode ();
+
+ uint32_t interfaceLocal;
+ bool rc = FindInterfaceForDevice(node, nd, interfaceLocal);
+ NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessSingleBroadcastLink(): No interface index associated with device");
+
+ Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
+ NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessSingleBroadcastLink (): GetObject for <Ipv4> interface failed");
+
+ if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
+ {
+ NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+ }
+ Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
+ Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();
+ NS_LOG_LOGIC ("Working with local address " << addrLocal);
+ uint16_t metricLocal = ipv4Local->GetMetric (interfaceLocal);
+
+ //
+ // Check to see if the net device is connected to a channel/network that has
+ // another router on it. If there is no other router on the link (but us) then
+ // this is a stub network. If we find another router, then what we have here
+ // is a transit network.
+ //
+ if (AnotherRouterOnLink (nd, true) == false)
+ {
+ //
+ // This is a net device connected to a stub network
+ //
+ NS_LOG_LOGIC("Router-LSA Stub Network");
+ plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
+
+ //
+ // According to OSPF, the Link ID is the IP network number of
+ // the attached network.
+ //
+ plr->SetLinkId (addrLocal.CombineMask(maskLocal));
+
+ //
+ // and the Link Data is the network mask; converted to Ipv4Address
+ //
+ Ipv4Address maskLocalAddr;
+ maskLocalAddr.Set(maskLocal.Get ());
+ plr->SetLinkData (maskLocalAddr);
+ plr->SetMetric (metricLocal);
+ pLSA->AddLinkRecord(plr);
+ plr = 0;
+ }
+ else
+ {
+ //
+ // We have multiple routers on a broadcast interface, so this is
+ // a transit network.
+ //
+ NS_LOG_LOGIC ("Router-LSA Transit Network");
+ plr->SetLinkType (GlobalRoutingLinkRecord::TransitNetwork);
+
+ //
+ // By definition, the router with the lowest IP address is the
+ // designated router for the network. OSPF says that the Link ID
+ // gets the IP interface address of the designated router in this
+ // case.
+ //
+ Ipv4Address desigRtr = FindDesignatedRouterForLink (nd, true);
+
+ //
+ // Let's double-check that any designated router we find out on our
+ // network is really on our network.
+ //
+ if (desigRtr != "255.255.255.255")
+ {
+ Ipv4Address networkHere = addrLocal.CombineMask (maskLocal);
+ Ipv4Address networkThere = desigRtr.CombineMask (maskLocal);
+ NS_ABORT_MSG_UNLESS (networkHere == networkThere,
+ "GlobalRouter::ProcessSingleBroadcastLink(): Network number confusion");
+ }
+ if (desigRtr == addrLocal)
+ {
+ c.Add (nd);
+ NS_LOG_LOGIC ("Node " << node->GetId () << " elected a designated router");
+ }
+ plr->SetLinkId (desigRtr);
+
+ //
+ // OSPF says that the Link Data is this router's own IP address.
+ //
+ plr->SetLinkData (addrLocal);
+ plr->SetMetric (metricLocal);
+ pLSA->AddLinkRecord (plr);
+ plr = 0;
+ }
+}
+
+ void
+GlobalRouter::ProcessBridgedBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c)
+{
+ NS_LOG_FUNCTION (nd << pLSA << &c);
+ NS_ASSERT_MSG (nd->IsBridge (), "GlobalRouter::ProcessBridgedBroadcastLink(): Called with non-bridge net device");
+
+#if 0
+ //
+ // It is possible to admit the possibility that a bridge device on a node
+ // can also participate in routing. This would surprise people who don't
+ // come from Microsoft-land where they do use such a construct. Based on
+ // the principle of least-surprise, we will leave the relatively simple
+ // code in place to do this, but not enable it until someone really wants
+ // the capability. Even then, we will not enable this code as a default
+ // but rather something you will have to go and turn on.
+ //
+
+ Ptr<BridgeNetDevice> bnd = nd->GetObject<BridgeNetDevice> ();
+ NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for <BridgeNetDevice> failed");
+
+ //
+ // We have some preliminaries to do to get enough information to proceed.
+ // This information we need comes from the internet stack, so notice that
+ // there is an implied assumption that global routing is only going to
+ // work with devices attached to the internet stack (have an ipv4 interface
+ // associated to them.
+ //
+ Ptr<Node> node = nd->GetNode ();
+
+ uint32_t interfaceLocal;
+ bool rc = FindInterfaceForDevice(node, nd, interfaceLocal);
+ NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessBridgedBroadcastLink(): No interface index associated with device");
+
+ Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
+ NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessBridgedBroadcastLink (): GetObject for <Ipv4> interface failed");
+
+ if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
+ {
+ NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+ }
+ Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
+ Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();;
+ NS_LOG_LOGIC ("Working with local address " << addrLocal);
+ uint16_t metricLocal = ipv4Local->GetMetric (interfaceLocal);
+
+ //
+ // We need to handle a bridge on the router. This means that we have been
+ // given a net device that is a BridgeNetDevice. It has an associated Ipv4
+ // interface index and address. Some number of other net devices live "under"
+ // the bridge device as so-called bridge ports. In a nutshell, what we have
+ // to do is to repeat what is done for a single broadcast link on all of
+ // those net devices living under the bridge (trolls?)
+ //
+
+ bool areTransitNetwork = false;
+ Ipv4Address desigRtr ("255.255.255.255");
+
+ for (uint32_t i = 0; i < bnd->GetNBridgePorts (); ++i)
+ {
+ Ptr<NetDevice> ndTemp = bnd->GetBridgePort (i);
+
+ //
+ // We have to decide if we are a transit network. This is characterized
+ // by the presence of another router on the network segment. If we find
+ // another router on any of our bridged links, we are a transit network.
+ //
+ if (AnotherRouterOnLink (ndTemp, true))
+ {
+ areTransitNetwork = true;
+
+ //
+ // If we're going to be a transit network, then we have got to elect
+ // a designated router for the whole bridge. This means finding the
+ // router with the lowest IP address on the whole bridge. We ask
+ // for the lowest address on each segment and pick the lowest of them
+ // all.
+ //
+ Ipv4Address desigRtrTemp = FindDesignatedRouterForLink (ndTemp, true);
+
+ //
+ // Let's double-check that any designated router we find out on our
+ // network is really on our network.
+ //
+ if (desigRtrTemp != "255.255.255.255")
+ {
+ Ipv4Address networkHere = addrLocal.CombineMask (maskLocal);
+ Ipv4Address networkThere = desigRtrTemp.CombineMask (maskLocal);
+ NS_ABORT_MSG_UNLESS (networkHere == networkThere,
+ "GlobalRouter::ProcessSingleBroadcastLink(): Network number confusion");
+ }
+ if (desigRtrTemp < desigRtr)
+ {
+ desigRtr = desigRtrTemp;
+ }
+ }
+ }
+ //
+ // That's all the information we need to put it all together, just like we did
+ // in the case of a single broadcast link.
+ //
+
+ GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord;
+ NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessBridgedBroadcastLink(): Can't alloc link record");
+
+ if (areTransitNetwork == false)
+ {
+ //
+ // This is a net device connected to a bridge of stub networks
+ //
+ NS_LOG_LOGIC("Router-LSA Stub Network");
+ plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
+
+ //
+ // According to OSPF, the Link ID is the IP network number of
+ // the attached network.
+ //
+ plr->SetLinkId (addrLocal.CombineMask(maskLocal));
+
+ //
+ // and the Link Data is the network mask; converted to Ipv4Address
+ //
+ Ipv4Address maskLocalAddr;
+ maskLocalAddr.Set(maskLocal.Get ());
+ plr->SetLinkData (maskLocalAddr);
+ plr->SetMetric (metricLocal);
+ pLSA->AddLinkRecord(plr);
+ plr = 0;
+ }
+ else
+ {
+ //
+ // We have multiple routers on a bridged broadcast interface, so this is
+ // a transit network.
+ //
+ NS_LOG_LOGIC ("Router-LSA Transit Network");
+ plr->SetLinkType (GlobalRoutingLinkRecord::TransitNetwork);
+
+ //
+ // By definition, the router with the lowest IP address is the
+ // designated router for the network. OSPF says that the Link ID
+ // gets the IP interface address of the designated router in this
+ // case.
+ //
+ if (desigRtr == addrLocal)
+ {
+ c.Add (nd);
+ NS_LOG_LOGIC ("Node " << node->GetId () << " elected a designated router");
+ }
+ plr->SetLinkId (desigRtr);
+
+ //
+ // OSPF says that the Link Data is this router's own IP address.
+ //
+ plr->SetLinkData (addrLocal);
+ plr->SetMetric (metricLocal);
+ pLSA->AddLinkRecord (plr);
+ plr = 0;
+ }
+#endif
+}
+
+ void
+GlobalRouter::ProcessPointToPointLink (Ptr<NetDevice> ndLocal, GlobalRoutingLSA *pLSA)
+{
+ NS_LOG_FUNCTION (ndLocal << pLSA);
+
+ //
+ // We have some preliminaries to do to get enough information to proceed.
+ // This information we need comes from the internet stack, so notice that
+ // there is an implied assumption that global routing is only going to
+ // work with devices attached to the internet stack (have an ipv4 interface
+ // associated to them.
+ //
+ Ptr<Node> nodeLocal = ndLocal->GetNode ();
+
+ uint32_t interfaceLocal;
+ bool rc = FindInterfaceForDevice(nodeLocal, ndLocal, interfaceLocal);
+ NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessPointToPointLink (): No interface index associated with device");
+
+ Ptr<Ipv4> ipv4Local = nodeLocal->GetObject<Ipv4> ();
+ NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessPointToPointLink (): GetObject for <Ipv4> interface failed");
+
+ if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
+ {
+ NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+ }
+ Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
+ Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();
+ NS_LOG_LOGIC ("Working with local address " << addrLocal);
+ uint16_t metricLocal = ipv4Local->GetMetric (interfaceLocal);
+
+ //
+ // Now, we're going to walk over to the remote net device on the other end of
+ // the point-to-point channel we know we have. This is where our adjacent
+ // router (to use OSPF lingo) is running.
+ //
+ Ptr<Channel> ch = ndLocal->GetChannel();
+
+ //
+ // Get the net device on the other side of the point-to-point channel.
+ //
+ Ptr<NetDevice> ndRemote = GetAdjacent(ndLocal, ch);
+
+ //
+ // The adjacent net device is aggregated to a node. We need to ask that net
+ // device for its node, then ask that node for its Ipv4 interface. Note a
+ // requirement that nodes on either side of a point-to-point link must have
+ // internet stacks; and an assumption that point-to-point links are incompatible
+ // with bridging.
+ //
+ Ptr<Node> nodeRemote = ndRemote->GetNode();
+ Ptr<Ipv4> ipv4Remote = nodeRemote->GetObject<Ipv4> ();
+ NS_ABORT_MSG_UNLESS (ipv4Remote,
+ "GlobalRouter::ProcessPointToPointLink(): GetObject for remote <Ipv4> failed");
+
+ //
+ // Further note the requirement that nodes on either side of a point-to-point
+ // link must participate in global routing and therefore have a GlobalRouter
+ // interface aggregated.
+ //
+ Ptr<GlobalRouter> rtrRemote = nodeRemote->GetObject<GlobalRouter> ();
+ if (rtrRemote == 0)
+ {
+ // This case is possible if the remote does not participate in global routing
+ return;
+ }
+ //
+ // We're going to need the remote router ID, so we might as well get it now.
+ //
+ Ipv4Address rtrIdRemote = rtrRemote->GetRouterId();
+ NS_LOG_LOGIC ("Working with remote router " << rtrIdRemote);
+
+ //
+ // Now, just like we did above, we need to get the IP interface index for the
+ // net device on the other end of the point-to-point channel.
+ //
+ uint32_t interfaceRemote;
+ rc = FindInterfaceForDevice(nodeRemote, ndRemote, interfaceRemote);
+ NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessPointToPointLinks(): No interface index associated with remote device");
+
+ //
+ // Now that we have the Ipv4 interface, we can get the (remote) address and
+ // mask we need.
+ //
+ if (ipv4Remote->GetNAddresses (interfaceRemote) > 1)
+ {
+ NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+ }
+ Ipv4Address addrRemote = ipv4Remote->GetAddress (interfaceRemote, 0).GetLocal ();
+ Ipv4Mask maskRemote = ipv4Remote->GetAddress (interfaceRemote, 0).GetMask ();
+ NS_LOG_LOGIC ("Working with remote address " << addrRemote);
+
+ //
+ // Now we can fill out the link records for this link. There are always two
+ // link records; the first is a point-to-point record describing the link and
+ // the second is a stub network record with the network number.
+ //
+ GlobalRoutingLinkRecord *plr;
+ if (ipv4Remote->IsUp (interfaceRemote))
+ {
+ NS_LOG_LOGIC ("Remote side interface " << interfaceRemote << " is up-- add a type 1 link");
+
+ plr = new GlobalRoutingLinkRecord;
+ NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record");
+ plr->SetLinkType (GlobalRoutingLinkRecord::PointToPoint);
+ plr->SetLinkId (rtrIdRemote);
+ plr->SetLinkData (addrLocal);
+ plr->SetMetric (metricLocal);
+ pLSA->AddLinkRecord (plr);
+ plr = 0;
+ }
+
+ // Regardless of state of peer, add a type 3 link (RFC 2328: 12.4.1.1)
+ plr = new GlobalRoutingLinkRecord;
+ NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record");
+ plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
+ plr->SetLinkId (addrRemote);
+ plr->SetLinkData (Ipv4Address(maskRemote.Get())); // Frown
+ plr->SetMetric (metricLocal);
+ pLSA->AddLinkRecord (plr);
+ plr = 0;
+}
+
+ void
+GlobalRouter::BuildNetworkLSAs (NetDeviceContainer c)
+{
+ NS_LOG_FUNCTION (&c);
+
+ uint32_t nDesignatedRouters = c.GetN ();
+
+ for (uint32_t i = 0; i < nDesignatedRouters; ++i)
+ {
+ //
+ // Build one NetworkLSA for each net device talking to a network that we are the
+ // designated router for. These devices are in the provided container.
+ //
+ Ptr<NetDevice> ndLocal = c.Get (i);
+ Ptr<Node> node = ndLocal->GetNode ();
+
+ uint32_t interfaceLocal;
+ bool rc = FindInterfaceForDevice(node, ndLocal, interfaceLocal);
+ NS_ABORT_MSG_IF (rc == false, "GlobalRouter::BuildNetworkLSAs (): No interface index associated with device");
+
+ Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
+ NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessPointToPointLink (): GetObject for <Ipv4> interface failed");
+
+ if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
+ {
+ NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+ }
+ Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
+ Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();
+
+ GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
+ NS_ABORT_MSG_IF (pLSA == 0, "GlobalRouter::BuildNetworkLSAs(): Can't alloc link record");
+
+ pLSA->SetLSType (GlobalRoutingLSA::NetworkLSA);
+ pLSA->SetLinkStateId (addrLocal);
+ pLSA->SetAdvertisingRouter (m_routerId);
+ pLSA->SetNetworkLSANetworkMask (maskLocal);
+ pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
+ pLSA->SetNode (node);
+
+ //
+ // Build a list of AttachedRouters by walking the devices in the channel
+ // and, if we find a node with a GlobalRouter interface and an IPv4
+ // interface associated with that device, we call it an attached router.
+ //
+ Ptr<Channel> ch = ndLocal->GetChannel();
+ uint32_t nDevices = ch->GetNDevices();
+ NS_ASSERT (nDevices);
+
+ for (uint32_t i = 0; i < nDevices; i++)
+ {
+ Ptr<NetDevice> tempNd = ch->GetDevice (i);
+ NS_ASSERT (tempNd);
+ Ptr<Node> tempNode = tempNd->GetNode ();
+
+ //
+ // Does the node in question have a GlobalRouter interface? If not it can
+ // hardly be considered an attached router.
+ //
+ Ptr<GlobalRouter> rtr = tempNode->GetObject<GlobalRouter> ();
+ if (rtr == 0)
+ {
+ continue;
+ }
+
+ //
+ // Does the attached node have an ipv4 interface for the device we're probing?
+ // If not, it can't play router.
+ //
+ uint32_t tempInterface;
+ if (FindInterfaceForDevice (tempNode, tempNd, tempInterface))
+ {
+ Ptr<Ipv4> tempIpv4 = tempNode->GetObject<Ipv4> ();
+ NS_ASSERT (tempIpv4);
+ if (!tempIpv4->IsUp (tempInterface))
+ {
+ NS_LOG_LOGIC ("Remote side interface " << tempInterface << " not up");
+ }
+ else
+ {
+ if (tempIpv4->GetNAddresses (tempInterface) > 1)
+ {
+ NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+ }
+ Ipv4Address tempAddr = tempIpv4->GetAddress(tempInterface, 0).GetLocal ();
+ pLSA->AddAttachedRouter (tempAddr);
+ }
+ }
+ }
+ m_LSAs.push_back (pLSA);
+ pLSA = 0;
+ }
+}
+
+//
+// Given a local net device, we need to walk the channel to which the net device is
+// attached and look for nodes with GlobalRouter interfaces on them (one of them
+// will be us). Of these, the router with the lowest IP address on the net device
+// connecting to the channel becomes the designated router for the link.
+//
+ Ipv4Address
+GlobalRouter::FindDesignatedRouterForLink (Ptr<NetDevice> ndLocal, bool allowRecursion) const
+{
+ NS_LOG_FUNCTION (ndLocal << allowRecursion);
+
+ Ptr<Channel> ch = ndLocal->GetChannel();
+ uint32_t nDevices = ch->GetNDevices();
+ NS_ASSERT (nDevices);
+
+ NS_LOG_LOGIC ("Looking for designated router off of net device " << ndLocal << " on node " <<
+ ndLocal->GetNode ()->GetId ());
+
+ Ipv4Address desigRtr ("255.255.255.255");
+
+ //
+ // Look through all of the devices on the channel to which the net device
+ // in question is attached.
+ //
+ for (uint32_t i = 0; i < nDevices; i++)
+ {
+ Ptr<NetDevice> ndOther = ch->GetDevice (i);
+ NS_ASSERT (ndOther);
+
+ Ptr<Node> nodeOther = ndOther->GetNode ();
+
+ NS_LOG_LOGIC ("Examine channel device " << i << " on node " << nodeOther->GetId ());
+
+ //
+ // For all other net devices, we need to check and see if a router
+ // is present. If the net device on the other side is a bridged
+ // device, we need to consider all of the other devices on the
+ // bridge as well (all of the bridge ports.
+ //
+ NS_LOG_LOGIC ("checking to see if the device is bridged");
+ Ptr<BridgeNetDevice> bnd = NetDeviceIsBridged (ndOther);
+ if (bnd)
+ {
+ NS_LOG_LOGIC ("Device is bridged by BridgeNetDevice " << bnd);
+
+ //
+ // It is possible that the bridge net device is sitting under a
+ // router, so we have to check for the presence of that router
+ // before we run off and follow all the links
+ //
+ // We require a designated router to have a GlobalRouter interface and
+ // an internet stack that includes the Ipv4 interface. If it doesn't
+ // it can't play router.
+ //
+ NS_LOG_LOGIC ("Checking for router on bridge net device " << bnd);
+ Ptr<GlobalRouter> rtr = nodeOther->GetObject<GlobalRouter> ();
+ Ptr<Ipv4> ipv4 = nodeOther->GetObject<Ipv4> ();
+ if (rtr && ipv4)
+ {
+ uint32_t interfaceOther;
+ if (FindInterfaceForDevice(nodeOther, bnd, interfaceOther))
+ {
+ NS_LOG_LOGIC ("Found router on bridge net device " << bnd);
+ if (!ipv4->IsUp (interfaceOther))
+ {
+ NS_LOG_LOGIC ("Remote side interface " << interfaceOther << " not up");
+ continue;
+ }
+ if (ipv4->GetNAddresses (interfaceOther) > 1)
+ {
+ NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+ }
+ Ipv4Address addrOther = ipv4->GetAddress (interfaceOther, 0).GetLocal ();
+ desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
+ NS_LOG_LOGIC ("designated router now " << desigRtr);
+ }
+ }
+
+ NS_LOG_LOGIC ("Looking through bridge ports of bridge net device " << bnd);
+ for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
+ {
+ Ptr<NetDevice> ndBridged = bnd->GetBridgePort (j);
+ NS_LOG_LOGIC ("Examining bridge port " << j << " device " << ndBridged);
+ if (ndBridged == ndOther)
+ {
+ NS_LOG_LOGIC ("That bridge port is me, don't walk backward");
+ continue;
+ }
+
+ if (allowRecursion)
+ {
+ NS_LOG_LOGIC ("Recursively looking for routers down bridge port " << ndBridged);
+ Ipv4Address addrOther = FindDesignatedRouterForLink (ndBridged, false);
+ desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
+ NS_LOG_LOGIC ("designated router now " << desigRtr);
+ }
+ }
+ }
+ else
+ {
+ NS_LOG_LOGIC ("This device is not bridged");
+ Ptr<Node> nodeOther = ndOther->GetNode ();
+ NS_ASSERT (nodeOther);
+
+ //
+ // We require a designated router to have a GlobalRouter interface and
+ // an internet stack that includes the Ipv4 interface. If it doesn't
+ //
+ Ptr<GlobalRouter> rtr = nodeOther->GetObject<GlobalRouter> ();
+ Ptr<Ipv4> ipv4 = nodeOther->GetObject<Ipv4> ();
+ if (rtr && ipv4)
+ {
+ uint32_t interfaceOther;
+ if (FindInterfaceForDevice(nodeOther, ndOther, interfaceOther))
+ {
+ if (!ipv4->IsUp (interfaceOther))
+ {
+ NS_LOG_LOGIC ("Remote side interface " << interfaceOther << " not up");
+ continue;
+ }
+ NS_LOG_LOGIC ("Found router on net device " << ndOther);
+ if (ipv4->GetNAddresses (interfaceOther) > 1)
+ {
+ NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+ }
+ Ipv4Address addrOther = ipv4->GetAddress (interfaceOther, 0).GetLocal ();
+ desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
+ NS_LOG_LOGIC ("designated router now " << desigRtr);
+ }
+ }
+ }
+ }
+ return desigRtr;
+}
+
+//
+// Given a node and an attached net device, take a look off in the channel to
+// which the net device is attached and look for a node on the other side
+// that has a GlobalRouter interface aggregated. Life gets more complicated
+// when there is a bridged net device on the other side.
+//
+ bool
+GlobalRouter::AnotherRouterOnLink (Ptr<NetDevice> nd, bool allowRecursion) const
+{
+ NS_LOG_FUNCTION (nd << allowRecursion);
+
+ Ptr<Channel> ch = nd->GetChannel();
+ if (!ch)
+ {
+ // It may be that this net device is a stub device, without a channel
+ return false;
+ }
+ uint32_t nDevices = ch->GetNDevices();
+ NS_ASSERT (nDevices);
+
+ NS_LOG_LOGIC ("Looking for routers off of net device " << nd << " on node " << nd->GetNode ()->GetId ());
+
+ //
+ // Look through all of the devices on the channel to which the net device
+ // in question is attached.
+ //
+ for (uint32_t i = 0; i < nDevices; i++)
+ {
+ Ptr<NetDevice> ndOther = ch->GetDevice (i);
+ NS_ASSERT (ndOther);
+
+ NS_LOG_LOGIC ("Examine channel device " << i << " on node " << ndOther->GetNode ()->GetId ());
+
+ //
+ // Ignore the net device itself.
+ //
+ if (ndOther == nd)
+ {
+ NS_LOG_LOGIC ("Myself, skip");
+ continue;
+ }
+
+ //
+ // For all other net devices, we need to check and see if a router
+ // is present. If the net device on the other side is a bridged
+ // device, we need to consider all of the other devices on the
+ // bridge.
+ //
+ NS_LOG_LOGIC ("checking to see if device is bridged");
+ Ptr<BridgeNetDevice> bnd = NetDeviceIsBridged (ndOther);
+ if (bnd)
+ {
+ NS_LOG_LOGIC ("Device is bridged by net device " << bnd);
+ NS_LOG_LOGIC ("Looking through bridge ports of bridge net device " << bnd);
+ for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
+ {
+ Ptr<NetDevice> ndBridged = bnd->GetBridgePort (j);
+ NS_LOG_LOGIC ("Examining bridge port " << j << " device " << ndBridged);
+ if (ndBridged == ndOther)
+ {
+ NS_LOG_LOGIC ("That bridge port is me, skip");
+ continue;
+ }
+
+ if (allowRecursion)
+ {
+ NS_LOG_LOGIC ("Recursively looking for routers on bridge port " << ndBridged);
+ if (AnotherRouterOnLink (ndBridged, false))
+ {
+ NS_LOG_LOGIC ("Found routers on bridge port, return true");
+ return true;
+ }
+ }
+ }
+ NS_LOG_LOGIC ("No routers on bridged net device, return false");
+ return false;
+ }
+
+ NS_LOG_LOGIC ("This device is not bridged");
+ Ptr<Node> nodeTemp = ndOther->GetNode ();
+ NS_ASSERT (nodeTemp);
+
+ Ptr<GlobalRouter> rtr = nodeTemp->GetObject<GlobalRouter> ();
+ if (rtr)
+ {
+ NS_LOG_LOGIC ("Found GlobalRouter interface, return true");
+ return true;
+ }
+ else
+ {
+ NS_LOG_LOGIC ("No GlobalRouter interface on device, continue search");
+ }
+ }
+ NS_LOG_LOGIC ("No routers found, return false");
+ return false;
+}
+
+ uint32_t
+GlobalRouter::GetNumLSAs (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_LSAs.size ();
+}
+
+//
+// Get the nth link state advertisement from this router.
+//
+ bool
+GlobalRouter::GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ NS_ASSERT_MSG(lsa.IsEmpty(), "GlobalRouter::GetLSA (): Must pass empty LSA");
+//
+// All of the work was done in GetNumLSAs. All we have to do here is to
+// walk the list of link state advertisements created there and return the
+// one the client is interested in.
+//
+ ListOfLSAs_t::const_iterator i = m_LSAs.begin ();
+ uint32_t j = 0;
+
+ for (; i != m_LSAs.end (); i++, j++)
+ {
+ if (j == n)
+ {
+ GlobalRoutingLSA *p = *i;
+ lsa = *p;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void
+GlobalRouter::InjectRoute (Ipv4Address network, Ipv4Mask networkMask)
+{
+ NS_LOG_FUNCTION (network << networkMask);
+ Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
+//
+// Interface number does not matter here, using 1.
+//
+ *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
+ networkMask,
+ 1);
+ m_injectedRoutes.push_back (route);
+}
+
+Ipv4RoutingTableEntry *
+GlobalRouter::GetInjectedRoute (uint32_t index)
+{
+ NS_LOG_FUNCTION (index);
+ if (index < m_injectedRoutes.size ())
+ {
+ uint32_t tmp = 0;
+ for (InjectedRoutesCI i = m_injectedRoutes.begin ();
+ i != m_injectedRoutes.end ();
+ i++)
+ {
+ if (tmp == index)
+ {
+ return *i;
+ }
+ tmp++;
+ }
+ }
+ NS_ASSERT (false);
+ // quiet compiler.
+ return 0;
+}
+
+uint32_t
+GlobalRouter::GetNInjectedRoutes ()
+{
+ return m_injectedRoutes.size ();
+}
+
+void
+GlobalRouter::RemoveInjectedRoute (uint32_t index)
+{
+ NS_LOG_FUNCTION (index);
+ NS_ASSERT (index < m_injectedRoutes.size ());
+ uint32_t tmp = 0;
+ for (InjectedRoutesI i = m_injectedRoutes.begin (); i != m_injectedRoutes.end (); i++)
+ {
+ if (tmp == index)
+ {
+ NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_injectedRoutes.size());
+ delete *i;
+ m_injectedRoutes.erase (i);
+ return;
+ }
+ tmp++;
+ }
+}
+
+bool
+GlobalRouter::WithdrawRoute (Ipv4Address network, Ipv4Mask networkMask)
+{
+ NS_LOG_FUNCTION (network << networkMask);
+ for (InjectedRoutesI i = m_injectedRoutes.begin (); i != m_injectedRoutes.end (); i++)
+ {
+ if ((*i)->GetDestNetwork () == network && (*i)->GetDestNetworkMask () == networkMask)
+ {
+ NS_LOG_LOGIC ("Withdrawing route to network/mask " << network << "/" << networkMask);
+ delete *i;
+ m_injectedRoutes.erase (i);
+ return true;
+ }
+ }
+ return false;
+}
+
+
+//
+// Link through the given channel and find the net device that's on the
+// other end. This only makes sense with a point-to-point channel.
+//
+ Ptr<NetDevice>
+GlobalRouter::GetAdjacent (Ptr<NetDevice> nd, Ptr<Channel> ch) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ NS_ASSERT_MSG(ch->GetNDevices() == 2, "GlobalRouter::GetAdjacent (): Channel with other than two devices");
+//
+// This is a point to point channel with two endpoints. Get both of them.
+//
+ Ptr<NetDevice> nd1 = ch->GetDevice(0);
+ Ptr<NetDevice> nd2 = ch->GetDevice(1);
+//
+// One of the endpoints is going to be "us" -- that is the net device attached
+// to the node on which we're running -- i.e., "nd". The other endpoint (the
+// one to which we are connected via the channel) is the adjacent router.
+//
+ if (nd1 == nd)
+ {
+ return nd2;
+ }
+ else if (nd2 == nd)
+ {
+ return nd1;
+ }
+ else
+ {
+ NS_ASSERT_MSG(false,
+ "GlobalRouter::GetAdjacent (): Wrong or confused channel?");
+ return 0;
+ }
+}
+
+//
+// Given a node and a net device, find an IPV4 interface index that corresponds
+// to that net device. This function may fail for various reasons. If a node
+// does not have an internet stack (for example if it is a bridge) we won't have
+// an IPv4 at all. If the node does have a stack, but the net device in question
+// is bridged, there will not be an interface associated directly with the device.
+//
+ bool
+GlobalRouter::FindInterfaceForDevice (Ptr<Node> node, Ptr<NetDevice> nd, uint32_t &index) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_LOGIC("For node " << node->GetId () << " for net device " << nd );
+
+ Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+ if (ipv4 == 0)
+ {
+ NS_LOG_LOGIC ("No Ipv4 interface on node " << node->GetId ());
+ return false;
+ }
+
+ for (uint32_t i = 0; i < ipv4->GetNInterfaces(); ++i )
+ {
+ if (ipv4->GetNetDevice(i) == nd)
+ {
+ NS_LOG_LOGIC ("Device " << nd << " has associated ipv4 index " << i);
+ index = i;
+ return true;
+ }
+ }
+
+ NS_LOG_LOGIC ("Device " << nd << " has no associated ipv4 index");
+ return false;
+}
+
+//
+// Decide whether or not a given net device is being bridged by a BridgeNetDevice.
+//
+ Ptr<BridgeNetDevice>
+GlobalRouter::NetDeviceIsBridged (Ptr<NetDevice> nd) const
+{
+ NS_LOG_FUNCTION (nd);
+
+ Ptr<Node> node = nd->GetNode ();
+ uint32_t nDevices = node->GetNDevices();
+
+ //
+ // There is no bit on a net device that says it is being bridged, so we have
+ // to look for bridges on the node to which the device is attached. If we
+ // find a bridge, we need to look through its bridge ports (the devices it
+ // bridges) to see if we find the device in question.
+ //
+ for (uint32_t i = 0; i < nDevices; ++i)
+ {
+ Ptr<NetDevice> ndTest = node->GetDevice(i);
+ NS_LOG_LOGIC ("Examine device " << i << " " << ndTest);
+
+ if (ndTest->IsBridge ())
+ {
+ NS_LOG_LOGIC ("device " << i << " is a bridge net device");
+ Ptr<BridgeNetDevice> bnd = ndTest->GetObject<BridgeNetDevice> ();
+ NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for <BridgeNetDevice> failed");
+
+ for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
+ {
+ NS_LOG_LOGIC ("Examine bridge port " << j << " " << bnd->GetBridgePort (j));
+ if (bnd->GetBridgePort (j) == nd)
+ {
+ NS_LOG_LOGIC ("Net device " << nd << " is bridged by " << bnd);
+ return bnd;
+ }
+ }
+ }
+ }
+ NS_LOG_LOGIC ("Net device " << nd << " is not bridged");
+ return 0;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/global-router-interface.h Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,754 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2007 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors: Craig Dowell (craigdo@ee.washington.edu)
+ * Tom Henderson (tomhend@u.washington.edu)
+ */
+
+#ifndef GLOBAL_ROUTER_INTERFACE_H
+#define GLOBAL_ROUTER_INTERFACE_H
+
+#include <stdint.h>
+#include <list>
+#include "ns3/object.h"
+#include "ns3/ptr.h"
+#include "ns3/node.h"
+#include "ns3/channel.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/net-device-container.h"
+#include "ns3/bridge-net-device.h"
+#include "ns3/global-route-manager.h"
+#include "ns3/ipv4-routing-table-entry.h"
+
+namespace ns3 {
+
+class GlobalRouter;
+class Ipv4GlobalRouting;
+
+/**
+ * @brief A single link record for a link state advertisement.
+ *
+ * The GlobalRoutingLinkRecord is modeled after the OSPF link record field of
+ * a Link State Advertisement. Right now we will only see two types of link
+ * records corresponding to a stub network and a point-to-point link (channel).
+ */
+class GlobalRoutingLinkRecord
+{
+public:
+ friend class GlobalRoutingLSA;
+/**
+ * @enum LinkType
+ * @brief Enumeration of the possible types of Global Routing Link Records.
+ *
+ * These values are defined in the OSPF spec. We currently only use
+ * PointToPoint and StubNetwork types.
+ */
+ enum LinkType {
+ Unknown = 0, /**< Uninitialized Link Record */
+ PointToPoint, /**< Record representing a point to point channel */
+ TransitNetwork, /**< Unused -- for future OSPF compatibility */
+ StubNetwork, /**< Record represents a leaf node network */
+ VirtualLink /**< Unused -- for future OSPF compatibility */
+ };
+
+/**
+ * @brief Construct an empty ("uninitialized") Global Routing Link Record.
+ *
+ * The Link ID and Link Data Ipv4 addresses are set to "0.0.0.0";
+ * The Link Type is set to Unknown;
+ * The metric is set to 0.
+ */
+ GlobalRoutingLinkRecord ();
+
+/**
+ * Construct an initialized Global Routing Link Record.
+ *
+ * @param linkType The type of link record to construct.
+ * @param linkId The link ID for the record.
+ * @param linkData The link data field for the record.
+ * @param metric The metric field for the record.
+ * @see LinkType
+ * @see SetLinkId
+ * @see SetLinkData
+ */
+ GlobalRoutingLinkRecord (
+ LinkType linkType,
+ Ipv4Address linkId,
+ Ipv4Address linkData,
+ uint16_t metric);
+
+/**
+ * @brief Destroy a Global Routing Link Record.
+ *
+ * Currently does nothing. Here as a placeholder only.
+ */
+ ~GlobalRoutingLinkRecord ();
+
+/**
+ * Get the Link ID field of the Global Routing Link Record.
+ *
+ * For an OSPF type 1 link (PointToPoint) the Link ID will be the Router ID
+ * of the neighboring router.
+ *
+ * For an OSPF type 3 link (StubNetwork), the Link ID will be the adjacent
+ * neighbor's IP address
+ *
+ * @returns The Ipv4Address corresponding to the Link ID field of the record.
+ */
+ Ipv4Address GetLinkId(void) const;
+
+/**
+ * @brief Set the Link ID field of the Global Routing Link Record.
+ *
+ * For an OSPF type 1 link (PointToPoint) the Link ID must be the Router ID
+ * of the neighboring router.
+ *
+ * For an OSPF type 3 link (StubNetwork), the Link ID must be the adjacent
+ * neighbor's IP address
+ *
+ * @param addr An Ipv4Address to store in the Link ID field of the record.
+ */
+ void SetLinkId(Ipv4Address addr);
+
+/**
+ * @brief Get the Link Data field of the Global Routing Link Record.
+ *
+ * For an OSPF type 1 link (PointToPoint) the Link Data will be the IP
+ * address of the node of the local side of the link.
+ *
+ * For an OSPF type 3 link (StubNetwork), the Link Data will be the
+ * network mask
+ *
+ * @returns The Ipv4Address corresponding to the Link Data field of the record.
+ */
+ Ipv4Address GetLinkData(void) const;
+
+/**
+ * @brief Set the Link Data field of the Global Routing Link Record.
+ *
+ * For an OSPF type 1 link (PointToPoint) the Link Data must be the IP
+ * address of the node of the local side of the link.
+ *
+ * For an OSPF type 3 link (StubNetwork), the Link Data must be set to the
+ * network mask
+ *
+ * @param addr An Ipv4Address to store in the Link Data field of the record.
+ */
+ void SetLinkData(Ipv4Address addr);
+
+/**
+ * @brief Get the Link Type field of the Global Routing Link Record.
+ *
+ * The Link Type describes the kind of link a given record represents. The
+ * values are defined by OSPF.
+ *
+ * @see LinkType
+ * @returns The LinkType of the current Global Routing Link Record.
+ */
+ LinkType GetLinkType(void) const;
+
+/**
+ * @brief Set the Link Type field of the Global Routing Link Record.
+ *
+ * The Link Type describes the kind of link a given record represents. The
+ * values are defined by OSPF.
+ *
+ * @see LinkType
+ * @param linkType The new LinkType for the current Global Routing Link Record.
+ */
+ void SetLinkType(LinkType linkType);
+
+/**
+ * @brief Get the Metric Data field of the Global Routing Link Record.
+ *
+ * The metric is an abstract cost associated with forwarding a packet across
+ * a link. A sum of metrics must have a well-defined meaning. That is, you
+ * shouldn't use bandwidth as a metric (how does the sum of the bandwidth of
+ * two hops relate to the cost of sending a packet); rather you should use
+ * something like delay.
+ *
+ * @returns The metric field of the Global Routing Link Record.
+ */
+ uint16_t GetMetric(void) const;
+
+/**
+ * @brief Set the Metric Data field of the Global Routing Link Record.
+ *
+ * The metric is an abstract cost associated with forwarding a packet across
+ * a link. A sum of metrics must have a well-defined meaning. That is, you
+ * shouldn't use bandwidth as a metric (how does the sum of the bandwidth of
+ * two hops relate to the cost of sending a packet); rather you should use
+ * something like delay.
+ *
+ * @param metric The new metric for the current Global Routing Link Record.
+ */
+ void SetMetric(uint16_t metric);
+
+private:
+/**
+ * m_linkId and m_linkData are defined by OSPF to have different meanings
+ * depending on the type of link a given link records represents. They work
+ * together.
+ *
+ * For Type 1 link (PointToPoint), set m_linkId to Router ID of
+ * neighboring router.
+ *
+ * For Type 3 link (Stub), set m_linkId to neighbor's IP address
+ */
+ Ipv4Address m_linkId;
+
+/**
+ * m_linkId and m_linkData are defined by OSPF to have different meanings
+ * depending on the type of link a given link records represents. They work
+ * together.
+ *
+ * For Type 1 link (PointToPoint), set m_linkData to local IP address
+ *
+ * For Type 3 link (Stub), set m_linkData to mask
+ */
+ Ipv4Address m_linkData; // for links to RouterLSA,
+
+/**
+ * The type of the Global Routing Link Record. Defined in the OSPF spec.
+ * We currently only use PointToPoint and StubNetwork types.
+ */
+ LinkType m_linkType;
+
+/**
+ * The metric for a given link.
+ *
+ * A metric is abstract cost associated with forwarding a packet across a
+ * link. A sum of metrics must have a well-defined meaning. That is, you
+ * shouldn't use bandwidth as a metric (how does the sum of the bandwidth
+ * of two hops relate to the cost of sending a packet); rather you should
+ * use something like delay.
+ */
+ uint16_t m_metric;
+};
+
+/**
+ * @brief a Link State Advertisement (LSA) for a router, used in global
+ * routing.
+ *
+ * Roughly equivalent to a global incarnation of the OSPF link state header
+ * combined with a list of Link Records. Since it's global, there's
+ * no need for age or sequence number. See RFC 2328, Appendix A.
+ */
+class GlobalRoutingLSA
+{
+public:
+/**
+ * @enum LSType
+ * @brief corresponds to LS type field of RFC 2328 OSPF LSA header
+ */
+ enum LSType {
+ Unknown = 0, /**< Uninitialized Type */
+ RouterLSA,
+ NetworkLSA,
+ SummaryLSA,
+ SummaryLSA_ASBR,
+ ASExternalLSAs
+ };
+/**
+ * @enum SPFStatus
+ * @brief Enumeration of the possible values of the status flag in the Routing
+ * Link State Advertisements.
+ */
+ enum SPFStatus {
+ LSA_SPF_NOT_EXPLORED = 0, /**< New vertex not yet considered */
+ LSA_SPF_CANDIDATE, /**< Vertex is in the SPF candidate queue */
+ LSA_SPF_IN_SPFTREE /**< Vertex is in the SPF tree */
+ };
+/**
+ * @brief Create a blank Global Routing Link State Advertisement.
+ *
+ * On completion Ipv4Address variables initialized to 0.0.0.0 and the
+ * list of Link State Records is empty.
+ */
+ GlobalRoutingLSA();
+
+/**
+ * @brief Create an initialized Global Routing Link State Advertisement.
+ *
+ * On completion the list of Link State Records is empty.
+ *
+ * @param status The status to of the new LSA.
+ * @param linkStateId The Ipv4Address for the link state ID field.
+ * @param advertisingRtr The Ipv4Address for the advertising router field.
+ */
+ GlobalRoutingLSA(SPFStatus status, Ipv4Address linkStateId,
+ Ipv4Address advertisingRtr);
+
+/**
+ * @brief Copy constructor for a Global Routing Link State Advertisement.
+ *
+ * Takes a piece of memory and constructs a semantically identical copy of
+ * the given LSA.
+ *
+ * @param lsa The existing LSA to be used as the source.
+ */
+ GlobalRoutingLSA (GlobalRoutingLSA& lsa);
+
+/**
+ * @brief Destroy an existing Global Routing Link State Advertisement.
+ *
+ * Any Global Routing Link Records present in the list are freed.
+ */
+ ~GlobalRoutingLSA();
+
+/**
+ * @brief Assignment operator for a Global Routing Link State Advertisement.
+ *
+ * Takes an existing Global Routing Link State Advertisement and overwrites
+ * it to make a semantically identical copy of a given prototype LSA.
+ *
+ * If there are any Global Routing Link Records present in the existing
+ * LSA, they are freed before the assignment happens.
+ *
+ * @param lsa The existing LSA to be used as the source.
+ * @returns Reference to the overwritten LSA.
+ */
+ GlobalRoutingLSA& operator= (const GlobalRoutingLSA& lsa);
+
+/**
+ * @brief Copy any Global Routing Link Records in a given Global Routing Link
+ * State Advertisement to the current LSA.
+ *
+ * Existing Link Records are not deleted -- this is a concatenation of Link
+ * Records.
+ *
+ * @see ClearLinkRecords ()
+ * @param lsa The LSA to copy the Link Records from.
+ */
+ void CopyLinkRecords (const GlobalRoutingLSA& lsa);
+
+/**
+ * @brief Add a given Global Routing Link Record to the LSA.
+ *
+ * @param lr The Global Routing Link Record to be added.
+ * @returns The number of link records in the list.
+ */
+ uint32_t AddLinkRecord (GlobalRoutingLinkRecord* lr);
+
+/**
+ * @brief Return the number of Global Routing Link Records in the LSA.
+ *
+ * @returns The number of link records in the list.
+ */
+ uint32_t GetNLinkRecords (void) const;
+
+/**
+ * @brief Return a pointer to the specified Global Routing Link Record.
+ *
+ * @param n The LSA number desired.
+ * @returns The number of link records in the list.
+ */
+ GlobalRoutingLinkRecord* GetLinkRecord (uint32_t n) const;
+
+/**
+ * @brief Release all of the Global Routing Link Records present in the Global
+ * Routing Link State Advertisement and make the list of link records empty.
+ */
+ void ClearLinkRecords(void);
+
+/**
+ * @brief Check to see if the list of Global Routing Link Records present in the
+ * Global Routing Link State Advertisement is empty.
+ *
+ * @returns True if the list is empty, false otherwise.
+ */
+ bool IsEmpty(void) const;
+
+/**
+ * @brief Print the contents of the Global Routing Link State Advertisement and
+ * any Global Routing Link Records present in the list. Quite verbose.
+ */
+ void Print (std::ostream &os) const;
+
+/**
+ * @brief Return the LSType field of the LSA
+ */
+ LSType GetLSType (void) const;
+/**
+ * @brief Set the LS type field of the LSA
+ */
+ void SetLSType (LSType typ);
+
+/**
+ * @brief Get the Link State ID as defined by the OSPF spec. We always set it
+ * to the router ID of the router making the advertisement.
+ *
+ * @see RoutingEnvironment::AllocateRouterId ()
+ * @see GlobalRouting::GetRouterId ()
+ * @returns The Ipv4Address stored as the link state ID.
+ */
+ Ipv4Address GetLinkStateId (void) const;
+
+/**
+ * @brief Set the Link State ID is defined by the OSPF spec. We always set it
+ * to the router ID of the router making the advertisement.
+ * @param addr IPv4 address which will act as ID
+ * @see RoutingEnvironment::AllocateRouterId ()
+ * @see GlobalRouting::GetRouterId ()
+ */
+ void SetLinkStateId (Ipv4Address addr);
+
+/**
+ * @brief Get the Advertising Router as defined by the OSPF spec. We always
+ * set it to the router ID of the router making the advertisement.
+ *
+ * @see RoutingEnvironment::AllocateRouterId ()
+ * @see GlobalRouting::GetRouterId ()
+ * @returns The Ipv4Address stored as the advertising router.
+ */
+ Ipv4Address GetAdvertisingRouter (void) const;
+
+/**
+ * @brief Set the Advertising Router as defined by the OSPF spec. We always
+ * set it to the router ID of the router making the advertisement.
+ *
+ * @param rtr ID of the router making advertisement
+ * @see RoutingEnvironment::AllocateRouterId ()
+ * @see GlobalRouting::GetRouterId ()
+ */
+ void SetAdvertisingRouter (Ipv4Address rtr);
+
+/**
+ * @brief For a Network LSA, set the Network Mask field that precedes
+ * the list of attached routers.
+ */
+ void SetNetworkLSANetworkMask (Ipv4Mask mask);
+
+/**
+ * @brief For a Network LSA, get the Network Mask field that precedes
+ * the list of attached routers.
+ *
+ * @returns the NetworkLSANetworkMask
+ */
+ Ipv4Mask GetNetworkLSANetworkMask (void) const;
+
+/**
+ * @brief Add an attached router to the list in the NetworkLSA
+ *
+ * @param addr The Ipv4Address of the interface on the network link
+ * @returns The number of addresses in the list.
+ */
+ uint32_t AddAttachedRouter (Ipv4Address addr);
+
+/**
+ * @brief Return the number of attached routers listed in the NetworkLSA
+ *
+ * @returns The number of attached routers.
+ */
+ uint32_t GetNAttachedRouters (void) const;
+
+/**
+ * @brief Return an Ipv4Address corresponding to the specified attached router
+ *
+ * @param n The attached router number desired (number in the list).
+ * @returns The Ipv4Address of the requested router
+ */
+ Ipv4Address GetAttachedRouter (uint32_t n) const;
+
+/**
+ * @brief Get the SPF status of the advertisement.
+ *
+ * @see SPFStatus
+ * @returns The SPFStatus of the LSA.
+ */
+ SPFStatus GetStatus (void) const;
+
+/**
+ * @brief Set the SPF status of the advertisement
+ * @param status SPF status to set
+ * @see SPFStatus
+ */
+ void SetStatus (SPFStatus status);
+
+/**
+ * @brief Get the Node pointer of the node that originated this LSA
+ * @returns Node pointer
+ */
+ Ptr<Node> GetNode (void) const;
+
+/**
+ * @brief Set the Node pointer of the node that originated this LSA
+ * @param node Node pointer
+ */
+ void SetNode (Ptr<Node> node);
+
+private:
+/**
+ * The type of the LSA. Each LSA type has a separate advertisement
+ * format.
+ */
+ LSType m_lsType;
+/**
+ * The Link State ID is defined by the OSPF spec. We always set it to the
+ * router ID of the router making the advertisement.
+ *
+ * @see RoutingEnvironment::AllocateRouterId ()
+ * @see GlobalRouting::GetRouterId ()
+ */
+ Ipv4Address m_linkStateId;
+
+/**
+ * The Advertising Router is defined by the OSPF spec. We always set it to
+ * the router ID of the router making the advertisement.
+ *
+ * @see RoutingEnvironment::AllocateRouterId ()
+ * @see GlobalRouting::GetRouterId ()
+ */
+ Ipv4Address m_advertisingRtr;
+
+/**
+ * A convenience typedef to avoid too much writers cramp.
+ */
+ typedef std::list<GlobalRoutingLinkRecord*> ListOfLinkRecords_t;
+
+/**
+ * Each Link State Advertisement contains a number of Link Records that
+ * describe the kinds of links that are attached to a given node. We
+ * consider PointToPoint and StubNetwork links.
+ *
+ * m_linkRecords is an STL list container to hold the Link Records that have
+ * been discovered and prepared for the advertisement.
+ *
+ * @see GlobalRouting::DiscoverLSAs ()
+ */
+ ListOfLinkRecords_t m_linkRecords;
+
+/**
+ * Each Network LSA contains the network mask of the attached network
+ */
+ Ipv4Mask m_networkLSANetworkMask;
+
+/**
+ * A convenience typedef to avoid too much writers cramp.
+ */
+ typedef std::list<Ipv4Address> ListOfAttachedRouters_t;
+
+/**
+ * Each Network LSA contains a list of attached routers
+ *
+ * m_attachedRouters is an STL list container to hold the addresses that have
+ * been discovered and prepared for the advertisement.
+ *
+ * @see GlobalRouting::DiscoverLSAs ()
+ */
+ ListOfAttachedRouters_t m_attachedRouters;
+
+/**
+ * This is a tristate flag used internally in the SPF computation to mark
+ * if an SPFVertex (a data structure representing a vertex in the SPF tree
+ * -- a router) is new, is a candidate for a shortest path, or is in its
+ * proper position in the tree.
+ */
+ SPFStatus m_status;
+ uint32_t m_node_id;
+};
+
+std::ostream& operator<< (std::ostream& os, GlobalRoutingLSA& lsa);
+
+/**
+ * @brief An interface aggregated to a node to provide global routing info
+ *
+ * An interface aggregated to a node that provides global routing information
+ * to a global route manager. The presence of the interface indicates that
+ * the node is a router. The interface is the mechanism by which the router
+ * advertises its connections to neighboring routers. We're basically
+ * allowing the route manager to query for link state advertisements.
+ */
+class GlobalRouter : public Object
+{
+public:
+/**
+ * @brief The Interface ID of the Global Router interface.
+ *
+ * @see Object::GetObject ()
+ */
+ static TypeId GetTypeId (void);
+
+/**
+ * @brief Create a Global Router class
+ */
+ GlobalRouter ();
+
+
+ void SetRoutingProtocol (Ptr<Ipv4GlobalRouting> routing);
+ Ptr<Ipv4GlobalRouting> GetRoutingProtocol (void);
+
+/**
+ * @brief Get the Router ID associated with this Global Router.
+ *
+ * The Router IDs are allocated in the RoutingEnvironment -- one per Router,
+ * starting at 0.0.0.1 and incrementing with each instantiation of a router.
+ *
+ * @see RoutingEnvironment::AllocateRouterId ()
+ * @returns The Router ID associated with the Global Router.
+ */
+ Ipv4Address GetRouterId (void) const;
+
+/**
+ * @brief Walk the connected channels, discover the adjacent routers and build
+ * the associated number of Global Routing Link State Advertisements that
+ * this router can export.
+ *
+ * This is a fairly expensive operation in that every time it is called
+ * the current list of LSAs is built by walking connected point-to-point
+ * channels and peeking into adjacent IPV4 stacks to get address information.
+ * This is done to allow for limited dynamics of the Global Routing
+ * environment. By that we mean that you can discover new link state
+ * advertisements after a network topology change by calling DiscoverLSAs
+ * and then by reading those advertisements.
+ *
+ * @see GlobalRoutingLSA
+ * @see GlobalRouter::GetLSA ()
+ * @returns The number of Global Routing Link State Advertisements.
+ */
+ uint32_t DiscoverLSAs (void);
+
+/**
+ * @brief Get the Number of Global Routing Link State Advertisements that this
+ * router can export.
+ *
+ * To get meaningful information you must have previously called DiscoverLSAs.
+ * After you know how many LSAs are present in the router, you may call
+ * GetLSA () to retrieve the actual advertisement.
+ *
+ * @see GlobalRouterLSA
+ * @see GlobalRouting::DiscoverLSAs ()
+ * @see GlobalRouting::GetLSA ()
+ * @returns The number of Global Routing Link State Advertisements.
+ */
+ uint32_t GetNumLSAs (void) const;
+
+/**
+ * @brief Get a Global Routing Link State Advertisements that this router has
+ * said that it can export.
+ *
+ * This is a fairly inexpensive expensive operation in that the hard work
+ * was done in GetNumLSAs. We just copy the indicated Global Routing Link
+ * State Advertisement into the requested GlobalRoutingLSA object.
+ *
+ * You must call GlobalRouter::GetNumLSAs before calling this method in
+ * order to discover the adjacent routers and build the advertisements.
+ * GetNumLSAs will return the number of LSAs this router advertises.
+ * The parameter n (requested LSA number) must be in the range 0 to
+ * GetNumLSAs() - 1.
+ *
+ * @see GlobalRoutingLSA
+ * @see GlobalRouting::GetNumLSAs ()
+ * @param n The index number of the LSA you want to read.
+ * @param lsa The GlobalRoutingLSA class to receive the LSA information.
+ * @returns The number of Global Router Link State Advertisements.
+ */
+ bool GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const;
+
+/**
+ * @brief Inject a route to be circulated to other routers as an external
+ * route
+ *
+ * @param network The Network to inject
+ * @param networkMask The Network Mask to inject
+ */
+ void InjectRoute (Ipv4Address network, Ipv4Mask networkMask);
+
+/**
+ * @brief Get the number of injected routes that have been added
+ * to the routing table.
+ * @return number of injected routes
+ */
+ uint32_t GetNInjectedRoutes (void);
+
+/**
+ * @brief Return the injected route indexed by i
+ * @param i the index of the route
+ * @return a pointer to that Ipv4RoutingTableEntry is returned
+ *
+ */
+ Ipv4RoutingTableEntry *GetInjectedRoute (uint32_t i);
+
+/**
+ * @brief Withdraw a route from the global unicast routing table.
+ *
+ * Calling this function will cause all indexed routes numbered above
+ * index i to have their index decremented. For instance, it is possible to
+ * remove N injected routes by calling RemoveInjectedRoute (0) N times.
+ *
+ * @param i The index (into the injected routing list) of the route to remove.
+ *
+ * @see GlobalRouter::WithdrawRoute ()
+ */
+ void RemoveInjectedRoute (uint32_t i);
+
+/**
+ * @brief Withdraw a route from the global unicast routing table.
+ *
+ * @param network The Network to withdraw
+ * @param networkMask The Network Mask to withdraw
+ * @return whether the operation succeeded (will return false if no such route)
+ *
+ * @see GlobalRouter::RemoveInjectedRoute ()
+ */
+ bool WithdrawRoute (Ipv4Address network, Ipv4Mask networkMask);
+
+private:
+ virtual ~GlobalRouter ();
+ void ClearLSAs (void);
+
+ Ptr<NetDevice> GetAdjacent(Ptr<NetDevice> nd, Ptr<Channel> ch) const;
+ bool FindInterfaceForDevice(Ptr<Node> node, Ptr<NetDevice> nd, uint32_t &index) const;
+ Ipv4Address FindDesignatedRouterForLink (Ptr<NetDevice> ndLocal, bool allowRecursion) const;
+ bool AnotherRouterOnLink (Ptr<NetDevice> nd, bool allowRecursion) const;
+ void ProcessBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);
+ void ProcessSingleBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);
+ void ProcessBridgedBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);
+
+ void ProcessPointToPointLink (Ptr<NetDevice> ndLocal, GlobalRoutingLSA *pLSA);
+ void BuildNetworkLSAs (NetDeviceContainer c);
+ Ptr<BridgeNetDevice> NetDeviceIsBridged (Ptr<NetDevice> nd) const;
+
+
+ typedef std::list<GlobalRoutingLSA*> ListOfLSAs_t;
+ ListOfLSAs_t m_LSAs;
+
+ Ipv4Address m_routerId;
+ Ptr<Ipv4GlobalRouting> m_routingProtocol;
+
+ typedef std::list<Ipv4RoutingTableEntry *> InjectedRoutes;
+ typedef std::list<Ipv4RoutingTableEntry *>::const_iterator InjectedRoutesCI;
+ typedef std::list<Ipv4RoutingTableEntry *>::iterator InjectedRoutesI;
+ InjectedRoutes m_injectedRoutes; // Routes we are exporting
+
+ // inherited from Object
+ virtual void DoDispose (void);
+
+/**
+ * @brief Global Router copy construction is disallowed.
+ */
+ GlobalRouter (GlobalRouter& sr);
+
+/**
+ * @brief Global Router assignment operator is disallowed.
+ */
+ GlobalRouter& operator= (GlobalRouter& sr);
+};
+
+} // namespace ns3
+
+#endif /* GLOBAL_ROUTER_INTERFACE_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/global-routing.h Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,85 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2008 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/**
+ * \ingroup routing
+ * \defgroup globalrouting Global Routing
+ *
+ * \section model Model
+ *
+ * ns-3 global routing performs pre-simulation static route computation
+ * on a layer-3 Ipv4 topology. The user API from the script level is
+ * fairly minimal; once a topology has been constructed and addresses
+ * assigned, the user may call ns3::GlobalRouteManager::PopulateRoutingTables()
+ * and the simulator will initialize the routing database and set up
+ * static unicast forwarding tables for each node.
+ *
+ * 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. 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.
+ *
+ * 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 two attributes of Ipv4GlobalRouting that govern behavior.
+ * - Ipv4GlobalRouting::RandomEcmpRouting
+ * - Ipv4GlobalRouting::RespondToInterfaceEvents
+ *
+ * \section impl Implementation
+ *
+ * A singleton object, ns3::GlobalRouteManager, builds a global routing
+ * database of information about the topology, and executes a Dijkstra
+ * Shortest Path First (SPF) algorithm on the topology for each node, and
+ * stores the computed routes in each node's IPv4 forwarding table by
+ * making use of the routing API in class ns3::Ipv4.
+ *
+ * The nodes that export data are those that have had an ns3::GlobalRouter
+ * object aggregated to them. The ns3::GlobalRouter can be thought of
+ * as a per-node agent that exports topology information to the
+ * ns3::GlobalRouteManager. When it comes time to build the global
+ * routing database, the list of nodes is iterated and each node with
+ * an ns3::GlobalRouter object is asked to export routing information
+ * concerning the links to which it is attached.
+ *
+ * The format of the data exported conforms to the OSPFv2 standard
+ * (http://www.ietf.org/rfc/rfc2328.txt). In particular, the
+ * information is exported in the form of ns3::GlobalLSA objects that
+ * semantically match the Link State Advertisements of OSPF.
+ *
+ * By using a standard data format for reporting topology, existing
+ * OSPF route computation code can be reused, and that is what is done
+ * by the ns3::GlobalRouteManager. The main computation functions are
+ * ported from the quagga routing suite (http://www.quagga.net).
+ *
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/ipv4-global-routing.cc Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,551 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2008 University of Washington
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/object.h"
+#include "ns3/packet.h"
+#include "ns3/net-device.h"
+#include "ns3/ipv4-route.h"
+#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");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv4GlobalRouting);
+
+TypeId
+Ipv4GlobalRouting::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::Ipv4GlobalRouting")
+ .SetParent<Object> ()
+ .AddAttribute ("RandomEcmpRouting",
+ "Set to true if packets are randomly routed among ECMP; set to false for using only one route consistently",
+ 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_respondToInterfaceEvents (false)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv4GlobalRouting::~Ipv4GlobalRouting ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+void
+Ipv4GlobalRouting::AddHostRouteTo (Ipv4Address dest,
+ Ipv4Address nextHop,
+ uint32_t interface)
+{
+ NS_LOG_FUNCTION (dest << nextHop << interface);
+ Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
+ *route = Ipv4RoutingTableEntry::CreateHostRouteTo (dest, nextHop, interface);
+ m_hostRoutes.push_back (route);
+}
+
+void
+Ipv4GlobalRouting::AddHostRouteTo (Ipv4Address dest,
+ uint32_t interface)
+{
+ NS_LOG_FUNCTION (dest << interface);
+ Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
+ *route = Ipv4RoutingTableEntry::CreateHostRouteTo (dest, interface);
+ m_hostRoutes.push_back (route);
+}
+
+void
+Ipv4GlobalRouting::AddNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ Ipv4Address nextHop,
+ uint32_t interface)
+{
+ NS_LOG_FUNCTION (network << networkMask << nextHop << interface);
+ Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
+ *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
+ networkMask,
+ nextHop,
+ interface);
+ m_networkRoutes.push_back (route);
+}
+
+void
+Ipv4GlobalRouting::AddNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ uint32_t interface)
+{
+ NS_LOG_FUNCTION (network << networkMask << interface);
+ Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
+ *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
+ networkMask,
+ interface);
+ m_networkRoutes.push_back (route);
+}
+
+void
+Ipv4GlobalRouting::AddASExternalRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ Ipv4Address nextHop,
+ uint32_t interface)
+{
+ NS_LOG_FUNCTION (network << networkMask << nextHop);
+ Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
+ *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
+ networkMask,
+ nextHop,
+ interface);
+ m_ASexternalRoutes.push_back (route);
+}
+
+
+Ptr<Ipv4Route>
+Ipv4GlobalRouting::LookupGlobal (Ipv4Address dest, Ptr<NetDevice> oif)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_LOGIC ("Looking for route for destination " << dest);
+ Ptr<Ipv4Route> rtentry = 0;
+ // store all available routes that bring packets to their destination
+ typedef std::vector<Ipv4RoutingTableEntry*> RouteVec_t;
+ RouteVec_t allRoutes;
+
+ NS_LOG_LOGIC ("Number of m_hostRoutes = " << m_hostRoutes.size ());
+ for (HostRoutesCI i = m_hostRoutes.begin ();
+ i != m_hostRoutes.end ();
+ i++)
+ {
+ NS_ASSERT ((*i)->IsHost ());
+ if ((*i)->GetDest ().IsEqual (dest))
+ {
+ if (oif != 0)
+ {
+ if (oif != m_ipv4->GetNetDevice((*i)->GetInterface ()))
+ {
+ NS_LOG_LOGIC ("Not on requested interface, skipping");
+ continue;
+ }
+ }
+ allRoutes.push_back (*i);
+ NS_LOG_LOGIC (allRoutes.size () << "Found global host route" << *i);
+ }
+ }
+ if (allRoutes.size () == 0) // if no host route is found
+ {
+ NS_LOG_LOGIC ("Number of m_networkRoutes" << m_networkRoutes.size ());
+ for (NetworkRoutesI j = m_networkRoutes.begin ();
+ j != m_networkRoutes.end ();
+ j++)
+ {
+ Ipv4Mask mask = (*j)->GetDestNetworkMask ();
+ Ipv4Address entry = (*j)->GetDestNetwork ();
+ if (mask.IsMatch (dest, entry))
+ {
+ if (oif != 0)
+ {
+ if (oif != m_ipv4->GetNetDevice((*j)->GetInterface ()))
+ {
+ NS_LOG_LOGIC ("Not on requested interface, skipping");
+ continue;
+ }
+ }
+ allRoutes.push_back (*j);
+ NS_LOG_LOGIC (allRoutes.size () << "Found global network route" << *j);
+ }
+ }
+ }
+ if (allRoutes.size () == 0) // consider external if no host/network found
+ {
+ for (ASExternalRoutesI k = m_ASexternalRoutes.begin ();
+ k != m_ASexternalRoutes.end ();
+ k++)
+ {
+ Ipv4Mask mask = (*k)->GetDestNetworkMask ();
+ Ipv4Address entry = (*k)->GetDestNetwork ();
+ if (mask.IsMatch (dest, entry))
+ {
+ NS_LOG_LOGIC ("Found external route" << *k);
+ if (oif != 0)
+ {
+ if (oif != m_ipv4->GetNetDevice((*k)->GetInterface ()))
+ {
+ NS_LOG_LOGIC ("Not on requested interface, skipping");
+ continue;
+ }
+ }
+ allRoutes.push_back (*k);
+ break;
+ }
+ }
+ }
+ if (allRoutes.size () > 0 ) // if route(s) is found
+ {
+ // pick up one of the routes uniformly at random if random
+ // ECMP routing is enabled, or always select the first route
+ // consistently if random ECMP routing is disabled
+ uint32_t selectIndex;
+ if (m_randomEcmpRouting)
+ {
+ selectIndex = m_rand.GetInteger (0, allRoutes.size ()-1);
+ }
+ else
+ {
+ selectIndex = 0;
+ }
+ Ipv4RoutingTableEntry* route = allRoutes.at (selectIndex);
+ // create a Ipv4Route object from the selected routing table entry
+ rtentry = Create<Ipv4Route> ();
+ rtentry->SetDestination (route->GetDest ());
+ // XXX handle multi-address case
+ rtentry->SetSource (m_ipv4->GetAddress (route->GetInterface(), 0).GetLocal ());
+ rtentry->SetGateway (route->GetGateway ());
+ uint32_t interfaceIdx = route->GetInterface ();
+ rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
+ return rtentry;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+uint32_t
+Ipv4GlobalRouting::GetNRoutes (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ uint32_t n = 0;
+ n += m_hostRoutes.size ();
+ n += m_networkRoutes.size ();
+ n += m_ASexternalRoutes.size ();
+ return n;
+}
+
+Ipv4RoutingTableEntry *
+Ipv4GlobalRouting::GetRoute (uint32_t index)
+{
+ NS_LOG_FUNCTION (index);
+ if (index < m_hostRoutes.size ())
+ {
+ uint32_t tmp = 0;
+ for (HostRoutesCI i = m_hostRoutes.begin ();
+ i != m_hostRoutes.end ();
+ i++)
+ {
+ if (tmp == index)
+ {
+ return *i;
+ }
+ tmp++;
+ }
+ }
+ index -= m_hostRoutes.size ();
+ uint32_t tmp = 0;
+ if (index < m_networkRoutes.size())
+ {
+ for (NetworkRoutesI j = m_networkRoutes.begin ();
+ j != m_networkRoutes.end ();
+ j++)
+ {
+ if (tmp == index)
+ {
+ return *j;
+ }
+ tmp++;
+ }
+ }
+ index -= m_networkRoutes.size();
+ tmp = 0;
+ for (ASExternalRoutesI k = m_ASexternalRoutes.begin ();
+ k != m_ASexternalRoutes.end ();
+ k++)
+ {
+ if (tmp == index)
+ {
+ return *k;
+ }
+ tmp++;
+ }
+ NS_ASSERT (false);
+ // quiet compiler.
+ return 0;
+}
+void
+Ipv4GlobalRouting::RemoveRoute (uint32_t index)
+{
+ NS_LOG_FUNCTION (index);
+ if (index < m_hostRoutes.size ())
+ {
+ uint32_t tmp = 0;
+ for (HostRoutesI i = m_hostRoutes.begin ();
+ i != m_hostRoutes.end ();
+ i++)
+ {
+ if (tmp == index)
+ {
+ NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_hostRoutes.size());
+ delete *i;
+ m_hostRoutes.erase (i);
+ NS_LOG_LOGIC ("Done removing host route " << index << "; host route remaining size = " << m_hostRoutes.size());
+ return;
+ }
+ tmp++;
+ }
+ }
+ index -= m_hostRoutes.size ();
+ uint32_t tmp = 0;
+ for (NetworkRoutesI j = m_networkRoutes.begin ();
+ j != m_networkRoutes.end ();
+ j++)
+ {
+ if (tmp == index)
+ {
+ NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_networkRoutes.size());
+ delete *j;
+ m_networkRoutes.erase (j);
+ NS_LOG_LOGIC ("Done removing network route " << index << "; network route remaining size = " << m_networkRoutes.size());
+ return;
+ }
+ tmp++;
+ }
+ index -= m_networkRoutes.size ();
+ tmp = 0;
+ for (ASExternalRoutesI k = m_ASexternalRoutes.begin ();
+ k != m_ASexternalRoutes.end ();
+ k++)
+ {
+ if (tmp == index)
+ {
+ NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_ASexternalRoutes.size());
+ delete *k;
+ m_ASexternalRoutes.erase (k);
+ NS_LOG_LOGIC ("Done removing network route " << index << "; network route remaining size = " << m_networkRoutes.size());
+ return;
+ }
+ tmp++;
+ }
+ NS_ASSERT (false);
+}
+
+void
+Ipv4GlobalRouting::DoDispose (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ for (HostRoutesI i = m_hostRoutes.begin ();
+ i != m_hostRoutes.end ();
+ i = m_hostRoutes.erase (i))
+ {
+ delete (*i);
+ }
+ for (NetworkRoutesI j = m_networkRoutes.begin ();
+ j != m_networkRoutes.end ();
+ j = m_networkRoutes.erase (j))
+ {
+ delete (*j);
+ }
+ for (ASExternalRoutesI l = m_ASexternalRoutes.begin ();
+ l != m_ASexternalRoutes.end ();
+ l = m_ASexternalRoutes.erase (l))
+ {
+ delete (*l);
+ }
+
+ Ipv4RoutingProtocol::DoDispose ();
+}
+
+Ptr<Ipv4Route>
+Ipv4GlobalRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
+{
+
+//
+// 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.
+//
+ if (header.GetDestination().IsMulticast ())
+ {
+ NS_LOG_LOGIC ("Multicast destination-- returning false");
+ return 0; // Let other routing protocols try to handle this
+ }
+//
+// 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);
+ if (rtentry)
+ {
+ sockerr = Socket::ERROR_NOTERROR;
+ }
+ else
+ {
+ sockerr = Socket::ERROR_NOROUTETOHOST;
+ }
+ return rtentry;
+}
+
+bool
+Ipv4GlobalRouting::RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb)
+{
+
+ NS_LOG_FUNCTION (this << p << header << header.GetSource () << header.GetDestination () << idev);
+ // Check if input device supports IP
+ NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
+ uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
+
+ if (header.GetDestination ().IsMulticast ())
+ {
+ NS_LOG_LOGIC ("Multicast destination-- returning false");
+ return false; // Let other routing protocols try to handle this
+ }
+
+ if (header.GetDestination ().IsBroadcast ())
+ {
+ NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)");
+ // TODO: Local Deliver for broadcast
+ // TODO: Forward broadcast
+ }
+
+ // TODO: Configurable option to enable RFC 1222 Strong End System Model
+ // Right now, we will be permissive and allow a source to send us
+ // a packet to one of our other interface addresses; that is, the
+ // destination unicast address does not match one of the iif addresses,
+ // but we check our other interfaces. This could be an option
+ // (to remove the outer loop immediately below and just check iif).
+ for (uint32_t j = 0; j < m_ipv4->GetNInterfaces (); j++)
+ {
+ for (uint32_t i = 0; i < m_ipv4->GetNAddresses (j); i++)
+ {
+ Ipv4InterfaceAddress iaddr = m_ipv4->GetAddress (j, i);
+ Ipv4Address addr = iaddr.GetLocal ();
+ if (addr.IsEqual (header.GetDestination ()))
+ {
+ if (j == iif)
+ {
+ NS_LOG_LOGIC ("For me (destination " << addr << " match)");
+ }
+ else
+ {
+ NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestination ());
+ }
+ lcb (p, header, iif);
+ return true;
+ }
+ if (header.GetDestination ().IsEqual (iaddr.GetBroadcast ()))
+ {
+ NS_LOG_LOGIC ("For me (interface broadcast address)");
+ lcb (p, header, iif);
+ return true;
+ }
+ NS_LOG_LOGIC ("Address "<< addr << " not a match");
+ }
+ }
+ // Check if input device supports IP forwarding
+ if (m_ipv4->IsForwarding (iif) == false)
+ {
+ NS_LOG_LOGIC ("Forwarding disabled for this interface");
+ ecb (p, header, Socket::ERROR_NOROUTETOHOST);
+ return false;
+ }
+ // Next, try to find a route
+ NS_LOG_LOGIC ("Unicast destination- looking up global route");
+ Ptr<Ipv4Route> rtentry = LookupGlobal (header.GetDestination ());
+ if (rtentry != 0)
+ {
+ NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
+ ucb (rtentry, p, header);
+ return true;
+ }
+ else
+ {
+ NS_LOG_LOGIC ("Did not find unicast destination- returning false");
+ return false; // Let other routing protocols try to handle this
+ // route request.
+ }
+}
+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)
+{
+ NS_LOG_FUNCTION(this << ipv4);
+ NS_ASSERT (m_ipv4 == 0 && ipv4 != 0);
+ m_ipv4 = ipv4;
+}
+
+
+}//namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/model/ipv4-global-routing.h Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,245 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2008 University of Washington
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+//
+
+#ifndef IPV4_GLOBAL_ROUTING_H
+#define IPV4_GLOBAL_ROUTING_H
+
+#include <list>
+#include <stdint.h>
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4-header.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv4.h"
+#include "ns3/ipv4-routing-protocol.h"
+#include "ns3/random-variable.h"
+
+namespace ns3 {
+
+class Packet;
+class NetDevice;
+class Ipv4Interface;
+class Ipv4Address;
+class Ipv4Header;
+class Ipv4RoutingTableEntry;
+class Ipv4MulticastRoutingTableEntry;
+class Node;
+
+
+/**
+ * \brief Global routing protocol for IP version 4 stacks.
+ *
+ * In ns-3 we have the concept of a pluggable routing protocol. Routing
+ * protocols are added to a list maintained by the Ipv4L3Protocol. Every
+ * stack gets one routing protocol for free -- the Ipv4StaticRouting routing
+ * protocol is added in the constructor of the Ipv4L3Protocol (this is the
+ * piece of code that implements the functionality of the IP layer).
+ *
+ * As an option to running a dynamic routing protocol, a GlobalRouteManager
+ * object has been created to allow users to build routes for all participating
+ * nodes. One can think of this object as a "routing oracle"; it has
+ * an omniscient view of the topology, and can construct shortest path
+ * routes between all pairs of nodes. These routes must be stored
+ * somewhere in the node, so therefore this class Ipv4GlobalRouting
+ * is used as one of the pluggable routing protocols. It is kept distinct
+ * from Ipv4StaticRouting because these routes may be dynamically cleared
+ * and rebuilt in the middle of the simulation, while manually entered
+ * routes into the Ipv4StaticRouting may need to be kept distinct.
+ *
+ * This class deals with Ipv4 unicast routes only.
+ *
+ * \see Ipv4RoutingProtocol
+ * \see GlobalRouteManager
+ */
+class Ipv4GlobalRouting : public Ipv4RoutingProtocol
+{
+public:
+ static TypeId GetTypeId (void);
+/**
+ * \brief Construct an empty Ipv4GlobalRouting routing protocol,
+ *
+ * The Ipv4GlobalRouting class supports host and network unicast routes.
+ * This method initializes the lists containing these routes to empty.
+ *
+ * \see Ipv4GlobalRouting
+ */
+ 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,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb);
+ virtual void NotifyInterfaceUp (uint32_t interface);
+ virtual void NotifyInterfaceDown (uint32_t interface);
+ virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
+ virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
+ virtual void SetIpv4 (Ptr<Ipv4> ipv4);
+
+/**
+ * \brief Add a host route to the global routing table.
+ *
+ * \param dest The Ipv4Address destination for this route.
+ * \param nextHop The Ipv4Address of the next hop in the route.
+ * \param interface The network interface index used to send packets to the
+ * destination.
+ *
+ * \see Ipv4Address
+ */
+ void AddHostRouteTo (Ipv4Address dest,
+ Ipv4Address nextHop,
+ uint32_t interface);
+/**
+ * \brief Add a host route to the global routing table.
+ *
+ * \param dest The Ipv4Address destination for this route.
+ * \param interface The network interface index used to send packets to the
+ * destination.
+ *
+ * \see Ipv4Address
+ */
+ void AddHostRouteTo (Ipv4Address dest,
+ uint32_t interface);
+
+/**
+ * \brief Add a network route to the global routing table.
+ *
+ * \param network The Ipv4Address network for this route.
+ * \param networkMask The Ipv4Mask to extract the network.
+ * \param nextHop The next hop in the route to the destination network.
+ * \param interface The network interface index used to send packets to the
+ * destination.
+ *
+ * \see Ipv4Address
+ */
+ void AddNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ Ipv4Address nextHop,
+ uint32_t interface);
+
+/**
+ * \brief Add a network route to the global routing table.
+ *
+ * \param network The Ipv4Address network for this route.
+ * \param networkMask The Ipv4Mask to extract the network.
+ * \param interface The network interface index used to send packets to the
+ * destination.
+ *
+ * \see Ipv4Address
+ */
+ void AddNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ uint32_t interface);
+
+/**
+ * \brief Add an external route to the global routing table.
+ *
+ * \param network The Ipv4Address network for this route.
+ * \param networkMask The Ipv4Mask to extract the network.
+ * \param nextHop The next hop Ipv4Address
+ * \param interface The network interface index used to send packets to the
+ * destination.
+ */
+ void AddASExternalRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ Ipv4Address nextHop,
+ uint32_t interface);
+
+/**
+ * \brief Get the number of individual unicast routes that have been added
+ * to the routing table.
+ *
+ * \warning The default route counts as one of the routes.
+ */
+ uint32_t GetNRoutes (void);
+
+/**
+ * \brief Get a route from the global unicast routing table.
+ *
+ * Externally, the unicast global routing table appears simply as a table with
+ * n entries. The one subtlety of note is that if a default route has been set
+ * it will appear as the zeroth entry in the table. This means that if you
+ * add only a default route, the table will have one entry that can be accessed
+ * either by explicitly calling GetDefaultRoute () or by calling GetRoute (0).
+ *
+ * Similarly, if the default route has been set, calling RemoveRoute (0) will
+ * remove the default route.
+ *
+ * \param i The index (into the routing table) of the route to retrieve. If
+ * the default route has been set, it will occupy index zero.
+ * \return If route is set, a pointer to that Ipv4RoutingTableEntry is returned, otherwise
+ * a zero pointer is returned.
+ *
+ * \see Ipv4RoutingTableEntry
+ * \see Ipv4GlobalRouting::RemoveRoute
+ */
+ Ipv4RoutingTableEntry *GetRoute (uint32_t i);
+
+/**
+ * \brief Remove a route from the global unicast routing table.
+ *
+ * Externally, the unicast global routing table appears simply as a table with
+ * n entries. The one subtlety of note is that if a default route has been set
+ * it will appear as the zeroth entry in the table. This means that if the
+ * default route has been set, calling RemoveRoute (0) will remove the
+ * default route.
+ *
+ * \param i The index (into the routing table) of the route to remove. If
+ * the default route has been set, it will occupy index zero.
+ *
+ * \see Ipv4RoutingTableEntry
+ * \see Ipv4GlobalRouting::GetRoute
+ * \see Ipv4GlobalRouting::AddRoute
+ */
+ void RemoveRoute (uint32_t i);
+
+protected:
+ void DoDispose (void);
+
+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;
+
+ typedef std::list<Ipv4RoutingTableEntry *> HostRoutes;
+ typedef std::list<Ipv4RoutingTableEntry *>::const_iterator HostRoutesCI;
+ typedef std::list<Ipv4RoutingTableEntry *>::iterator HostRoutesI;
+ typedef std::list<Ipv4RoutingTableEntry *> NetworkRoutes;
+ typedef std::list<Ipv4RoutingTableEntry *>::const_iterator NetworkRoutesCI;
+ typedef std::list<Ipv4RoutingTableEntry *>::iterator NetworkRoutesI;
+ typedef std::list<Ipv4RoutingTableEntry *> ASExternalRoutes;
+ typedef std::list<Ipv4RoutingTableEntry *>::const_iterator ASExternalRoutesCI;
+ typedef std::list<Ipv4RoutingTableEntry *>::iterator ASExternalRoutesI;
+
+ Ptr<Ipv4Route> LookupGlobal (Ipv4Address dest, Ptr<NetDevice> oif = 0);
+
+ HostRoutes m_hostRoutes;
+ NetworkRoutes m_networkRoutes;
+ ASExternalRoutes m_ASexternalRoutes; // External routes imported
+
+ Ptr<Ipv4> m_ipv4;
+};
+
+} // Namespace ns3
+
+#endif /* IPV4_GLOBAL_ROUTING_H */
--- a/src/routing/global-routing/wscript Tue Oct 26 15:11:17 2010 +0100
+++ b/src/routing/global-routing/wscript Tue Oct 26 18:02:17 2010 +0100
@@ -3,17 +3,19 @@
def build(bld):
module = bld.create_ns3_module('global-routing', ['node'])
module.source = [
- 'global-router-interface.cc',
- 'global-route-manager.cc',
- 'global-route-manager-impl.cc',
- 'candidate-queue.cc',
- 'ipv4-global-routing.cc',
+ 'model/global-router-interface.cc',
+ 'model/global-route-manager.cc',
+ 'model/global-route-manager-impl.cc',
+ 'model/candidate-queue.cc',
+ 'model/ipv4-global-routing.cc',
+ 'helper/ipv4-global-routing-helper.cc',
]
headers = bld.new_task_gen('ns3header')
headers.module = 'global-routing'
headers.source = [
- 'global-router-interface.h',
- 'global-route-manager.h',
- 'ipv4-global-routing.h',
+ 'model/global-router-interface.h',
+ 'model/global-route-manager.h',
+ 'model/ipv4-global-routing.h',
+ 'helper/ipv4-global-routing-helper.h',
]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/list-routing/helper/ipv4-list-routing-helper.cc Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,72 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "ipv4-list-routing-helper.h"
+#include "ns3/ipv4-list-routing.h"
+#include "ns3/node.h"
+
+namespace ns3 {
+
+Ipv4ListRoutingHelper::Ipv4ListRoutingHelper()
+{}
+
+Ipv4ListRoutingHelper::~Ipv4ListRoutingHelper()
+{
+ for (std::list<std::pair<const Ipv4RoutingHelper *, int16_t> >::iterator i = m_list.begin ();
+ i != m_list.end (); ++i)
+ {
+ delete i->first;
+ }
+}
+
+Ipv4ListRoutingHelper::Ipv4ListRoutingHelper (const Ipv4ListRoutingHelper &o)
+{
+ std::list<std::pair<const Ipv4RoutingHelper *, int16_t> >::const_iterator i;
+ for (i = o.m_list.begin (); i != o.m_list.end (); ++i)
+ {
+ m_list.push_back (std::make_pair (const_cast<const Ipv4RoutingHelper *> (i->first->Copy ()), i->second));
+ }
+}
+
+Ipv4ListRoutingHelper*
+Ipv4ListRoutingHelper::Copy (void) const
+{
+ return new Ipv4ListRoutingHelper (*this);
+}
+
+void
+Ipv4ListRoutingHelper::Add (const Ipv4RoutingHelper &routing, int16_t priority)
+{
+ m_list.push_back (std::make_pair (const_cast<const Ipv4RoutingHelper *> (routing.Copy ()), priority));
+}
+
+Ptr<Ipv4RoutingProtocol>
+Ipv4ListRoutingHelper::Create (Ptr<Node> node) const
+{
+ Ptr<Ipv4ListRouting> list = CreateObject<Ipv4ListRouting> ();
+ for (std::list<std::pair<const Ipv4RoutingHelper *, int16_t> >::const_iterator i = m_list.begin ();
+ i != m_list.end (); ++i)
+ {
+ Ptr<Ipv4RoutingProtocol> prot = i->first->Create (node);
+ list->AddRoutingProtocol (prot,i->second);
+ }
+ return list;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/list-routing/helper/ipv4-list-routing-helper.h Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,96 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef IPV4_LIST_ROUTING_HELPER_H
+#define IPV4_LIST_ROUTING_HELPER_H
+
+#include "ns3/ipv4-routing-helper.h"
+#include <stdint.h>
+#include <list>
+
+namespace ns3 {
+
+/**
+ * \brief Helper class that adds ns3::Ipv4ListRouting objects
+ *
+ * This class is expected to be used in conjunction with
+ * ns3::InternetStackHelper::SetRoutingHelper
+ */
+class Ipv4ListRoutingHelper : public Ipv4RoutingHelper
+{
+public:
+ /*
+ * Construct an Ipv4ListRoutingHelper used to make installing routing
+ * protocols easier.
+ */
+ Ipv4ListRoutingHelper ();
+
+ /*
+ * \internal
+ * Destroy an Ipv4ListRoutingHelper.
+ */
+ virtual ~Ipv4ListRoutingHelper ();
+
+ /**
+ * \brief Construct an Ipv4ListRoutingHelper from another previously
+ * initialized instance (Copy Constructor).
+ */
+ Ipv4ListRoutingHelper (const Ipv4ListRoutingHelper &);
+
+ /**
+ * \internal
+ * \returns pointer to clone of this Ipv4ListRoutingHelper
+ *
+ * This method is mainly for internal use by the other helpers;
+ * clients are expected to free the dynamic memory allocated by this method
+ */
+ Ipv4ListRoutingHelper* Copy (void) const;
+
+ /**
+ * \param routing a routing helper
+ * \param priority the priority of the associated helper
+ *
+ * Store in the internal list a reference to the input routing helper
+ * and associated priority. These helpers will be used later by
+ * the ns3::Ipv4ListRoutingHelper::Create method to create
+ * an ns3::Ipv4ListRouting object and add in it routing protocols
+ * created with the helpers.
+ */
+ void Add (const Ipv4RoutingHelper &routing, int16_t priority);
+ /**
+ * \param node the node on which the routing protocol will run
+ * \returns a newly-created routing protocol
+ *
+ * This method will be called by ns3::InternetStackHelper::Install
+ */
+ virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
+private:
+ /**
+ * \internal
+ * \brief Assignment operator declared private and not implemented to disallow
+ * assignment and prevent the compiler from happily inserting its own.
+ */
+ Ipv4ListRoutingHelper &operator = (const Ipv4ListRoutingHelper &o);
+
+ std::list<std::pair<const Ipv4RoutingHelper *,int16_t> > m_list;
+};
+
+} // namespace ns3
+
+#endif /* IPV4_LIST_ROUTING_HELPER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/list-routing/helper/ipv6-list-routing-helper.cc Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,72 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "ns3/ipv6-list-routing.h"
+#include "ns3/node.h"
+
+#include "ipv6-list-routing-helper.h"
+
+namespace ns3 {
+
+Ipv6ListRoutingHelper::Ipv6ListRoutingHelper ()
+{}
+
+Ipv6ListRoutingHelper::~Ipv6ListRoutingHelper()
+{
+ for (std::list<std::pair<const Ipv6RoutingHelper *, int16_t> >::iterator i = m_list.begin ();
+ i != m_list.end (); ++i)
+ {
+ delete i->first;
+ }
+}
+Ipv6ListRoutingHelper::Ipv6ListRoutingHelper (const Ipv6ListRoutingHelper &o)
+{
+ std::list<std::pair<const Ipv6RoutingHelper *, int16_t> >::const_iterator i;
+ for (i = o.m_list.begin (); i != o.m_list.end (); ++i)
+ {
+ m_list.push_back (std::make_pair (const_cast<const Ipv6RoutingHelper *> (i->first->Copy ()), i->second));
+ }
+}
+
+Ipv6ListRoutingHelper*
+Ipv6ListRoutingHelper::Copy (void) const
+{
+ return new Ipv6ListRoutingHelper (*this);
+}
+
+void
+Ipv6ListRoutingHelper::Add (const Ipv6RoutingHelper &routing, int16_t priority)
+{
+ m_list.push_back (std::make_pair (const_cast<const Ipv6RoutingHelper *> (routing.Copy ()), priority));
+}
+Ptr<Ipv6RoutingProtocol>
+Ipv6ListRoutingHelper::Create (Ptr<Node> node) const
+{
+ Ptr<Ipv6ListRouting> list = CreateObject<Ipv6ListRouting> ();
+ for (std::list<std::pair<const Ipv6RoutingHelper *,int16_t> >::const_iterator i = m_list.begin ();
+ i != m_list.end (); ++i)
+ {
+ Ptr<Ipv6RoutingProtocol> prot = i->first->Create (node);
+ list->AddRoutingProtocol (prot,i->second);
+ }
+ return list;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/list-routing/helper/ipv6-list-routing-helper.h Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,98 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef IPV6_LIST_ROUTING_HELPER_H
+#define IPV6_LIST_ROUTING_HELPER_H
+
+#include <stdint.h>
+
+#include <list>
+
+#include "ns3/ipv6-routing-helper.h"
+
+namespace ns3 {
+
+/**
+ * \brief Helper class that adds ns3::Ipv6ListRouting objects
+ *
+ * This class is expected to be used in conjunction with
+ * ns3::InternetStackHelper::SetRoutingHelper
+ */
+class Ipv6ListRoutingHelper : public Ipv6RoutingHelper
+{
+public:
+ /**
+ * Construct an Ipv6 Ipv6ListRoutingHelper which is used to make life easier
+ * for people wanting to configure routing using Ipv6.
+ */
+ Ipv6ListRoutingHelper ();
+
+ /**
+ * \internal
+ * \brief Destroy an Ipv6 Ipv6ListRoutingHelper.
+ */
+ virtual ~Ipv6ListRoutingHelper ();
+
+ /**
+ * \brief Construct an Ipv6ListRoutingHelper from another previously
+ * initialized instance (Copy Constructor).
+ */
+ Ipv6ListRoutingHelper (const Ipv6ListRoutingHelper &);
+
+ /**
+ * \returns pointer to clone of this Ipv6ListRoutingHelper
+ *
+ * This method is mainly for internal use by the other helpers;
+ * clients are expected to free the dynamic memory allocated by this method
+ */
+ Ipv6ListRoutingHelper* Copy (void) const;
+
+ /**
+ * \param routing a routing helper
+ * \param priority the priority of the associated helper
+ *
+ * Store in the internal list a reference to the input routing helper
+ * and associated priority. These helpers will be used later by
+ * the ns3::Ipv6ListRoutingHelper::Create method to create
+ * an ns3::Ipv6ListRouting object and add in it routing protocols
+ * created with the helpers.
+ */
+ void Add (const Ipv6RoutingHelper &routing, int16_t priority);
+ /**
+ * \param node the node on which the routing protocol will run
+ * \returns a newly-created routing protocol
+ *
+ * This method will be called by ns3::InternetStackHelper::Install
+ */
+ virtual Ptr<Ipv6RoutingProtocol> Create (Ptr<Node> node) const;
+private:
+ /**
+ * \internal
+ * \brief Assignment operator declared private and not implemented to disallow
+ * assignment and prevent the compiler from happily inserting its own.
+ */
+ Ipv6ListRoutingHelper &operator = (const Ipv6ListRoutingHelper &o);
+
+ std::list<std::pair<const Ipv6RoutingHelper *,int16_t> > m_list;
+};
+
+} // namespace ns3
+
+#endif /* IPV6_LIST_ROUTING_HELPER_H */
+
--- a/src/routing/list-routing/ipv4-list-routing.cc Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,394 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "ns3/log.h"
-#include "ns3/ipv4.h"
-#include "ns3/ipv4-route.h"
-#include "ns3/node.h"
-#include "ns3/ipv4-static-routing.h"
-#include "ipv4-list-routing.h"
-
-NS_LOG_COMPONENT_DEFINE ("Ipv4ListRouting");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (Ipv4ListRouting);
-
-TypeId
-Ipv4ListRouting::GetTypeId (void)
-{
- static TypeId tid = TypeId ("ns3::Ipv4ListRouting")
- .SetParent<Ipv4RoutingProtocol> ()
- .AddConstructor<Ipv4ListRouting> ()
- ;
- return tid;
-}
-
-
-Ipv4ListRouting::Ipv4ListRouting ()
- : m_ipv4 (0)
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
-Ipv4ListRouting::~Ipv4ListRouting ()
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
-void
-Ipv4ListRouting::DoDispose (void)
-{
- NS_LOG_FUNCTION_NOARGS ();
- for (Ipv4RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin ();
- rprotoIter != m_routingProtocols.end (); rprotoIter++)
- {
- // Note: Calling dispose on these protocols causes memory leak
- // The routing protocols should not maintain a pointer to
- // this object, so Dispose() shouldn't be necessary.
- (*rprotoIter).second = 0;
- }
- m_routingProtocols.clear ();
- m_ipv4 = 0;
-}
-
-void
-Ipv4ListRouting::DoStart (void)
-{
- for (Ipv4RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin ();
- rprotoIter != m_routingProtocols.end (); rprotoIter++)
- {
- Ptr<Ipv4RoutingProtocol> protocol = (*rprotoIter).second;
- protocol->Start ();
- }
- Ipv4RoutingProtocol::DoStart ();
-}
-
-
-Ptr<Ipv4Route>
-Ipv4ListRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, enum Socket::SocketErrno &sockerr)
-{
- NS_LOG_FUNCTION (this << header.GetDestination () << " " << header.GetSource () << " " << oif);
- Ptr<Ipv4Route> route;
-
- for (Ipv4RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
- i != m_routingProtocols.end (); i++)
- {
- NS_LOG_LOGIC ("Checking protocol " << (*i).second->GetInstanceTypeId () << " with priority " << (*i).first);
- NS_LOG_LOGIC ("Requesting source address for destination " << header.GetDestination ());
- route = (*i).second->RouteOutput (p, header, oif, sockerr);
- if (route)
- {
- NS_LOG_LOGIC ("Found route " << route);
- sockerr = Socket::ERROR_NOTERROR;
- return route;
- }
- }
- NS_LOG_LOGIC ("Done checking " << GetTypeId ());
- NS_LOG_LOGIC ("");
- sockerr = Socket::ERROR_NOROUTETOHOST;
- return 0;
-}
-
-// Patterned after Linux ip_route_input and ip_route_input_slow
-bool
-Ipv4ListRouting::RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
- UnicastForwardCallback ucb, MulticastForwardCallback mcb,
- LocalDeliverCallback lcb, ErrorCallback ecb)
-{
- bool retVal = false;
- NS_LOG_FUNCTION (p << header << idev);
- NS_LOG_LOGIC ("RouteInput logic for node: " << m_ipv4->GetObject<Node> ()->GetId ());
-
- NS_ASSERT (m_ipv4 != 0);
- // Check if input device supports IP
- NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
- uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
-
- retVal = m_ipv4->IsDestinationAddress (header.GetDestination (), iif);
- if (retVal == true)
- {
- NS_LOG_LOGIC ("Address "<< header.GetDestination () << " is a match for local delivery");
- if (header.GetDestination ().IsMulticast ())
- {
- Ptr<Packet> packetCopy = p->Copy();
- lcb (packetCopy, header, iif);
- retVal = true;
- // Fall through
- }
- else
- {
- lcb (p, header, iif);
- return true;
- }
- }
- // Check if input device supports IP forwarding
- if (m_ipv4->IsForwarding (iif) == false)
- {
- NS_LOG_LOGIC ("Forwarding disabled for this interface");
- ecb (p, header, Socket::ERROR_NOROUTETOHOST);
- return false;
- }
- // Next, try to find a route
- // If we have already delivered a packet locally (e.g. multicast)
- // we suppress further downstream local delivery by nulling the callback
- LocalDeliverCallback downstreamLcb = lcb;
- if (retVal == true)
- {
- downstreamLcb = MakeNullCallback<void, Ptr<const Packet>, const Ipv4Header &, uint32_t > ();
- }
- for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
- m_routingProtocols.begin ();
- rprotoIter != m_routingProtocols.end ();
- rprotoIter++)
- {
- if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, downstreamLcb, ecb))
- {
- NS_LOG_LOGIC ("Route found to forward packet in protocol " << (*rprotoIter).second->GetInstanceTypeId ().GetName ());
- return true;
- }
- }
- // No routing protocol has found a route.
- return retVal;
-}
-
-void
-Ipv4ListRouting::NotifyInterfaceUp (uint32_t interface)
-{
- NS_LOG_FUNCTION (this << interface);
- for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
- m_routingProtocols.begin ();
- rprotoIter != m_routingProtocols.end ();
- rprotoIter++)
- {
- (*rprotoIter).second->NotifyInterfaceUp (interface);
- }
-}
-void
-Ipv4ListRouting::NotifyInterfaceDown (uint32_t interface)
-{
- NS_LOG_FUNCTION (this << interface);
- for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
- m_routingProtocols.begin ();
- rprotoIter != m_routingProtocols.end ();
- rprotoIter++)
- {
- (*rprotoIter).second->NotifyInterfaceDown (interface);
- }
-}
-void
-Ipv4ListRouting::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)
-{
- NS_LOG_FUNCTION(this << interface << address);
- for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
- m_routingProtocols.begin ();
- rprotoIter != m_routingProtocols.end ();
- rprotoIter++)
- {
- (*rprotoIter).second->NotifyAddAddress (interface, address);
- }
-}
-void
-Ipv4ListRouting::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)
-{
- NS_LOG_FUNCTION(this << interface << address);
- for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
- m_routingProtocols.begin ();
- rprotoIter != m_routingProtocols.end ();
- rprotoIter++)
- {
- (*rprotoIter).second->NotifyRemoveAddress (interface, address);
- }
-}
-void
-Ipv4ListRouting::SetIpv4 (Ptr<Ipv4> ipv4)
-{
- NS_LOG_FUNCTION(this << ipv4);
- NS_ASSERT (m_ipv4 == 0);
- for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
- m_routingProtocols.begin ();
- rprotoIter != m_routingProtocols.end ();
- rprotoIter++)
- {
- (*rprotoIter).second->SetIpv4 (ipv4);
- }
- m_ipv4 = ipv4;
-}
-
-void
-Ipv4ListRouting::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol, int16_t priority)
-{
- NS_LOG_FUNCTION (this << routingProtocol->GetInstanceTypeId () << priority);
- m_routingProtocols.push_back (std::make_pair (priority, routingProtocol));
- m_routingProtocols.sort ( Compare );
- if (m_ipv4 != 0)
- {
- routingProtocol->SetIpv4 (m_ipv4);
- }
-}
-
-uint32_t
-Ipv4ListRouting::GetNRoutingProtocols (void) const
-{
- NS_LOG_FUNCTION (this);
- return m_routingProtocols.size ();
-}
-
-Ptr<Ipv4RoutingProtocol>
-Ipv4ListRouting::GetRoutingProtocol (uint32_t index, int16_t& priority) const
-{
- NS_LOG_FUNCTION (index);
- if (index > m_routingProtocols.size ())
- {
- NS_FATAL_ERROR ("Ipv4ListRouting::GetRoutingProtocol(): index " << index << " out of range");
- }
- uint32_t i = 0;
- for (Ipv4RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin ();
- rprotoIter != m_routingProtocols.end (); rprotoIter++, i++)
- {
- if (i == index)
- {
- priority = (*rprotoIter).first;
- return (*rprotoIter).second;
- }
- }
- return 0;
-}
-
-bool
-Ipv4ListRouting::Compare (const Ipv4RoutingProtocolEntry& a, const Ipv4RoutingProtocolEntry& b)
-{
- return a.first > b.first;
-}
-
-
-} // namespace ns3
-
-#include "ns3/test.h"
-#include "ipv4-list-routing.h"
-#include "ns3/ipv4-routing-protocol.h"
-
-namespace ns3 {
-
-class Ipv4ARouting : public Ipv4RoutingProtocol {
-public:
- Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr) { return 0;}
- bool RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
- UnicastForwardCallback ucb, MulticastForwardCallback mcb,
- LocalDeliverCallback lcb, ErrorCallback ecb) {return false;}
- void NotifyInterfaceUp (uint32_t interface) {}
- void NotifyInterfaceDown (uint32_t interface) {}
- void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
- void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
- void SetIpv4 (Ptr<Ipv4> ipv4) {}
-};
-
-class Ipv4BRouting : public Ipv4RoutingProtocol {
-public:
- Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr) { return 0;}
- bool RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
- UnicastForwardCallback ucb, MulticastForwardCallback mcb,
- LocalDeliverCallback lcb, ErrorCallback ecb) {return false;}
- void NotifyInterfaceUp (uint32_t interface) {}
- void NotifyInterfaceDown (uint32_t interface) {}
- void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
- void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
- void SetIpv4 (Ptr<Ipv4> ipv4) {}
-};
-
-class Ipv4ListRoutingNegativeTestCase : public TestCase
-{
-public:
- Ipv4ListRoutingNegativeTestCase();
- virtual bool DoRun (void);
-};
-
-Ipv4ListRoutingNegativeTestCase::Ipv4ListRoutingNegativeTestCase()
- : TestCase("Check negative priorities")
-{}
-bool
-Ipv4ListRoutingNegativeTestCase::DoRun (void)
-{
- Ptr<Ipv4ListRouting> lr = CreateObject<Ipv4ListRouting> ();
- Ptr<Ipv4RoutingProtocol> aRouting = CreateObject<Ipv4ARouting> ();
- Ptr<Ipv4RoutingProtocol> bRouting = CreateObject<Ipv4BRouting> ();
- // The Ipv4BRouting should be added with higher priority (larger integer value)
- lr->AddRoutingProtocol (aRouting, -10);
- lr->AddRoutingProtocol (bRouting, -5);
- int16_t first = 3;
- uint32_t num = lr->GetNRoutingProtocols ();
- NS_TEST_ASSERT_MSG_EQ (num, 2, "XXX");
- Ptr<Ipv4RoutingProtocol> firstRp = lr->GetRoutingProtocol (0, first);
- NS_TEST_ASSERT_MSG_EQ (-5, first, "XXX");
- NS_TEST_ASSERT_MSG_EQ (firstRp, bRouting, "XXX");
-
- // XXX
- return false;
-}
-
-class Ipv4ListRoutingPositiveTestCase : public TestCase
-{
-public:
- Ipv4ListRoutingPositiveTestCase();
- virtual bool DoRun (void);
-};
-
-Ipv4ListRoutingPositiveTestCase::Ipv4ListRoutingPositiveTestCase()
- : TestCase("Check positive priorities")
-{}
-bool
-Ipv4ListRoutingPositiveTestCase::DoRun (void)
-{
- Ptr<Ipv4ListRouting> lr = CreateObject<Ipv4ListRouting> ();
- Ptr<Ipv4RoutingProtocol> aRouting = CreateObject<Ipv4ARouting> ();
- Ptr<Ipv4RoutingProtocol> bRouting = CreateObject<Ipv4BRouting> ();
- // The Ipv4ARouting should be added with higher priority (larger integer
- // value) and will be fetched first below
- lr->AddRoutingProtocol (aRouting, 10);
- lr->AddRoutingProtocol (bRouting, 5);
- int16_t first = 3;
- int16_t second = 3;
- uint32_t num = lr->GetNRoutingProtocols ();
- NS_TEST_ASSERT_MSG_EQ (num, 2, "XXX");
- Ptr<Ipv4RoutingProtocol> firstRp = lr->GetRoutingProtocol (0, first);
- NS_TEST_ASSERT_MSG_EQ (10, first, "XXX");
- NS_TEST_ASSERT_MSG_EQ (firstRp, aRouting, "XXX");
- Ptr<Ipv4RoutingProtocol> secondRp = lr->GetRoutingProtocol (1, second);
- NS_TEST_ASSERT_MSG_EQ (5, second, "XXX");
- NS_TEST_ASSERT_MSG_EQ (secondRp, bRouting, "XXX");
-
- // XXX
- return false;
-}
-
-static class Ipv4ListRoutingTestSuite : public TestSuite
-{
-public:
- Ipv4ListRoutingTestSuite()
- : TestSuite("ipv4-list-routing", UNIT)
- {
- AddTestCase(new Ipv4ListRoutingPositiveTestCase());
- AddTestCase(new Ipv4ListRoutingNegativeTestCase());
- }
-
-} g_ipv4ListRoutingTestSuite;
-
-} // namespace ns3
-
-
--- a/src/routing/list-routing/ipv4-list-routing.h Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IPV4_LIST_ROUTING_H
-#define IPV4_LIST_ROUTING_H
-
-#include <list>
-#include "ns3/ipv4-routing-protocol.h"
-
-namespace ns3 {
-
-/**
- * \ingroup routing
- * \defgroup ipv4ListRouting Ipv4 List Routing
- */
-/**
- * \ingroup ipv4ListRouting
- *
- * This class is a specialization of Ipv4RoutingProtocol that allows
- * other instances of Ipv4RoutingProtocol to be inserted in a
- * prioritized list. Routing protocols in the list are consulted one
- * by one, from highest to lowest priority, until a routing protocol
- * is found that will take the packet (this corresponds to a non-zero
- * return value to RouteOutput, or a return value of true to RouteInput).
- * The order by which routing protocols with the same priority value
- * are consulted is undefined.
- *
- */
-class Ipv4ListRouting : public Ipv4RoutingProtocol
-{
-public:
- static TypeId GetTypeId (void);
-
- Ipv4ListRouting ();
- virtual ~Ipv4ListRouting ();
-
- /**
- * \brief Register a new routing protocol to be used in this IPv4 stack
- *
- * \param routingProtocol new routing protocol implementation object
- * \param priority priority to give to this routing protocol.
- * Values may range between -32768 and +32767.
- */
- virtual void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol, int16_t priority);
- /**
- * \return number of routing protocols in the list
- */
- virtual uint32_t GetNRoutingProtocols (void) const;
- /**
- * Return pointer to routing protocol stored at index, with the
- * first protocol (index 0) the highest priority, the next one (index 1)
- * the second highest priority, and so on. The priority parameter is an
- * output parameter and it returns the integer priority of the protocol.
- *
- * \return pointer to routing protocol indexed by
- * \param index index of protocol to return
- * \param priority output parameter, set to the priority of the protocol
- being returned
- */
- virtual Ptr<Ipv4RoutingProtocol> GetRoutingProtocol (uint32_t index, int16_t& priority) const;
-
- // Below are from Ipv4RoutingProtocol
- 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,
- UnicastForwardCallback ucb, MulticastForwardCallback mcb,
- LocalDeliverCallback lcb, ErrorCallback ecb);
- virtual void NotifyInterfaceUp (uint32_t interface);
- virtual void NotifyInterfaceDown (uint32_t interface);
- virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
- virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
- virtual void SetIpv4 (Ptr<Ipv4> ipv4);
-
-protected:
- void DoDispose (void);
- void DoStart (void);
-private:
- typedef std::pair<int16_t, Ptr<Ipv4RoutingProtocol> > Ipv4RoutingProtocolEntry;
- typedef std::list<Ipv4RoutingProtocolEntry> Ipv4RoutingProtocolList;
- Ipv4RoutingProtocolList m_routingProtocols;
- static bool Compare (const Ipv4RoutingProtocolEntry& a, const Ipv4RoutingProtocolEntry& b);
- Ptr<Ipv4> m_ipv4;
-
-};
-
-} //namespace ns3
-
-#endif /* IPV4_LIST_ROUTING_H */
--- a/src/routing/list-routing/ipv6-list-routing.cc Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,452 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "ns3/log.h"
-#include "ns3/ipv6.h"
-#include "ns3/ipv6-route.h"
-#include "ns3/node.h"
-#include "ns3/ipv6-static-routing.h"
-#include "ipv6-list-routing.h"
-
-NS_LOG_COMPONENT_DEFINE ("Ipv6ListRouting");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (Ipv6ListRouting);
-
-TypeId
-Ipv6ListRouting::GetTypeId (void)
-{
- static TypeId tid = TypeId ("ns3::Ipv6ListRouting")
- .SetParent<Ipv6RoutingProtocol> ()
- .AddConstructor<Ipv6ListRouting> ()
- ;
- return tid;
-}
-
-
-Ipv6ListRouting::Ipv6ListRouting ()
- : m_ipv6 (0)
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
-Ipv6ListRouting::~Ipv6ListRouting ()
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
-void
-Ipv6ListRouting::DoDispose (void)
-{
- NS_LOG_FUNCTION_NOARGS ();
- for (Ipv6RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin ();
- rprotoIter != m_routingProtocols.end (); rprotoIter++)
- {
- // Note: Calling dispose on these protocols causes memory leak
- // The routing protocols should not maintain a pointer to
- // this object, so Dispose () shouldn't be necessary.
- (*rprotoIter).second = 0;
- }
- m_routingProtocols.clear ();
- m_ipv6 = 0;
-}
-
-Ptr<Ipv6Route>
-Ipv6ListRouting::RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, enum Socket::SocketErrno &sockerr)
-{
- NS_LOG_FUNCTION (this << header.GetDestinationAddress () << header.GetSourceAddress () << oif);
- Ptr<Ipv6Route> route;
-
- for (Ipv6RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
- i != m_routingProtocols.end (); i++)
- {
- NS_LOG_LOGIC ("Checking protocol " << (*i).second->GetInstanceTypeId () << " with priority " << (*i).first);
- NS_LOG_LOGIC ("Requesting source address for destination " << header.GetDestinationAddress ());
- route = (*i).second->RouteOutput (p, header, oif, sockerr);
- if (route)
- {
- NS_LOG_LOGIC ("Found route " << route);
- sockerr = Socket::ERROR_NOTERROR;
- return route;
- }
- }
- NS_LOG_LOGIC ("Done checking " << GetTypeId ());
- NS_LOG_LOGIC ("");
- sockerr = Socket::ERROR_NOROUTETOHOST;
- return 0;
-}
-
-// Patterned after Linux ip_route_input and ip_route_input_slow
-bool
-Ipv6ListRouting::RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
- UnicastForwardCallback ucb, MulticastForwardCallback mcb,
- LocalDeliverCallback lcb, ErrorCallback ecb)
-{
- bool retVal = false;
- NS_LOG_FUNCTION (p << header << idev);
- NS_LOG_LOGIC ("RouteInput logic for node: " << m_ipv6->GetObject<Node> ()->GetId ());
-
- NS_ASSERT (m_ipv6 != 0);
- // Check if input device supports IP
- NS_ASSERT (m_ipv6->GetInterfaceForDevice (idev) >= 0);
- uint32_t iif = m_ipv6->GetInterfaceForDevice (idev);
- Ipv6Address dst = header.GetDestinationAddress ();
-
- // Multicast recognition; handle local delivery here
- //
- if (dst.IsMulticast ())
- {
-#ifdef NOTYET
- if (m_ipv6->MulticastCheckGroup (iif, dst))
-#endif
- if (true)
- {
- NS_LOG_LOGIC ("Multicast packet for me-- local deliver");
- Ptr<Packet> packetCopy = p->Copy ();
- // Here may want to disable lcb callback in recursive RouteInput
- // call below
- lcb (packetCopy, header, iif);
- // Fall through-- we may also need to forward this
- retVal = true;
- }
-
- /* do not forward link-local multicast address */
- if (dst == Ipv6Address::GetAllNodesMulticast () || dst == Ipv6Address::GetAllRoutersMulticast () || dst == Ipv6Address::GetAllHostsMulticast ())
- {
- return retVal;
- }
-
- for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
- m_routingProtocols.begin (); rprotoIter != m_routingProtocols.end ();
- rprotoIter++)
- {
- NS_LOG_LOGIC ("Multicast packet for me-- trying to forward");
- if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, ecb))
- {
- retVal = true;
- }
- }
- return retVal;
- }
-
- // TODO: Configurable option to enable RFC 1222 Strong End System Model
- // Right now, we will be permissive and allow a source to send us
- // a packet to one of our other interface addresses; that is, the
- // destination unicast address does not match one of the iif addresses,
- // but we check our other interfaces. This could be an option
- // (to remove the outer loop immediately below and just check iif).
- for (uint32_t j = 0; j < m_ipv6->GetNInterfaces (); j++)
- {
- for (uint32_t i = 0; i < m_ipv6->GetNAddresses (j); i++)
- {
- Ipv6InterfaceAddress iaddr = m_ipv6->GetAddress (j, i);
- Ipv6Address addr = iaddr.GetAddress ();
- if (addr.IsEqual (header.GetDestinationAddress ()))
- {
- if (j == iif)
- {
- NS_LOG_LOGIC ("For me (destination " << addr << " match)");
- }
- else
- {
- NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestinationAddress ());
- }
- lcb (p, header, iif);
- return true;
- }
- NS_LOG_LOGIC ("Address "<< addr << " not a match");
- }
- }
- // Check if input device supports IP forwarding
- if (m_ipv6->IsForwarding (iif) == false)
- {
- NS_LOG_LOGIC ("Forwarding disabled for this interface");
- ecb (p, header, Socket::ERROR_NOROUTETOHOST);
- return false;
- }
- // Next, try to find a route
- for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
- m_routingProtocols.begin ();
- rprotoIter != m_routingProtocols.end ();
- rprotoIter++)
- {
- if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, ecb))
- {
- return true;
- }
- }
- // No routing protocol has found a route.
- return retVal;
-}
-
-void
-Ipv6ListRouting::NotifyInterfaceUp (uint32_t interface)
-{
- NS_LOG_FUNCTION (this << interface);
- for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
- m_routingProtocols.begin ();
- rprotoIter != m_routingProtocols.end ();
- rprotoIter++)
- {
- (*rprotoIter).second->NotifyInterfaceUp (interface);
- }
-}
-void
-Ipv6ListRouting::NotifyInterfaceDown (uint32_t interface)
-{
- NS_LOG_FUNCTION (this << interface);
- for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
- m_routingProtocols.begin ();
- rprotoIter != m_routingProtocols.end ();
- rprotoIter++)
- {
- (*rprotoIter).second->NotifyInterfaceDown (interface);
- }
-}
-void
-Ipv6ListRouting::NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address)
-{
- NS_LOG_FUNCTION (this << interface << address);
- for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
- m_routingProtocols.begin ();
- rprotoIter != m_routingProtocols.end ();
- rprotoIter++)
- {
- (*rprotoIter).second->NotifyAddAddress (interface, address);
- }
-}
-void
-Ipv6ListRouting::NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address)
-{
- NS_LOG_FUNCTION (this << interface << address);
- for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
- m_routingProtocols.begin ();
- rprotoIter != m_routingProtocols.end ();
- rprotoIter++)
- {
- (*rprotoIter).second->NotifyRemoveAddress (interface, address);
- }
-}
-
-void Ipv6ListRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
-{
- NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
- for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
- m_routingProtocols.begin ();
- rprotoIter != m_routingProtocols.end ();
- rprotoIter++)
- {
- (*rprotoIter).second->NotifyAddRoute (dst, mask, nextHop, interface, prefixToUse);
- }
-}
-
-void Ipv6ListRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
-{
- NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
- for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
- m_routingProtocols.begin ();
- rprotoIter != m_routingProtocols.end ();
- rprotoIter++)
- {
- (*rprotoIter).second->NotifyRemoveRoute (dst, mask, nextHop, interface, prefixToUse);
- }
-}
-
-void
-Ipv6ListRouting::SetIpv6 (Ptr<Ipv6> ipv6)
-{
- NS_LOG_FUNCTION (this << ipv6);
- NS_ASSERT (m_ipv6 == 0);
- for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
- m_routingProtocols.begin ();
- rprotoIter != m_routingProtocols.end ();
- rprotoIter++)
- {
- (*rprotoIter).second->SetIpv6 (ipv6);
- }
- m_ipv6 = ipv6;
-}
-
-void
-Ipv6ListRouting::AddRoutingProtocol (Ptr<Ipv6RoutingProtocol> routingProtocol, int16_t priority)
-{
- NS_LOG_FUNCTION (this << routingProtocol->GetInstanceTypeId () << priority);
- m_routingProtocols.push_back (std::make_pair (priority, routingProtocol));
- m_routingProtocols.sort ( Compare );
- if (m_ipv6 != 0)
- {
- routingProtocol->SetIpv6 (m_ipv6);
- }
-}
-
-uint32_t
-Ipv6ListRouting::GetNRoutingProtocols (void) const
-{
- NS_LOG_FUNCTION (this);
- return m_routingProtocols.size ();
-}
-
-Ptr<Ipv6RoutingProtocol>
-Ipv6ListRouting::GetRoutingProtocol (uint32_t index, int16_t& priority) const
-{
- NS_LOG_FUNCTION (index);
- if (index > m_routingProtocols.size ())
- {
- NS_FATAL_ERROR ("Ipv6ListRouting::GetRoutingProtocol (): index " << index << " out of range");
- }
- uint32_t i = 0;
- for (Ipv6RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin ();
- rprotoIter != m_routingProtocols.end (); rprotoIter++, i++)
- {
- if (i == index)
- {
- priority = (*rprotoIter).first;
- return (*rprotoIter).second;
- }
- }
- return 0;
-}
-
-bool
-Ipv6ListRouting::Compare (const Ipv6RoutingProtocolEntry& a, const Ipv6RoutingProtocolEntry& b)
-{
- return a.first > b.first;
-}
-
-
-} // namespace ns3
-
-
-#include "ns3/test.h"
-#include "ipv6-list-routing.h"
-#include "ns3/ipv6-routing-protocol.h"
-
-namespace ns3 {
-
- class Ipv6ARouting : public Ipv6RoutingProtocol {
- public:
- Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr) { return 0;}
- bool RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
- UnicastForwardCallback ucb, MulticastForwardCallback mcb,
- LocalDeliverCallback lcb, ErrorCallback ecb) {return false;}
- void NotifyInterfaceUp (uint32_t interface) {}
- void NotifyInterfaceDown (uint32_t interface) {}
- void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
- void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
- void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::
- GetZero ()) {}
- void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse) {}
- void SetIpv6 (Ptr<Ipv6> ipv6) {}
- };
-
- class Ipv6BRouting : public Ipv6RoutingProtocol {
- public:
- Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr) { return 0;}
- bool RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
- UnicastForwardCallback ucb, MulticastForwardCallback mcb,
- LocalDeliverCallback lcb, ErrorCallback ecb) {return false;}
- void NotifyInterfaceUp (uint32_t interface) {}
- void NotifyInterfaceDown (uint32_t interface) {}
- void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
- void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
- void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::
- GetZero ()) {}
- void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse) {}
- void SetIpv6 (Ptr<Ipv6> ipv6) {}
- };
-
- class Ipv6ListRoutingNegativeTestCase : public TestCase
- {
- public:
- Ipv6ListRoutingNegativeTestCase();
- virtual bool DoRun (void);
- };
-
- Ipv6ListRoutingNegativeTestCase::Ipv6ListRoutingNegativeTestCase()
- : TestCase("Check negative priorities")
- {}
- bool
- Ipv6ListRoutingNegativeTestCase::DoRun (void)
- {
- Ptr<Ipv6ListRouting> lr = CreateObject<Ipv6ListRouting> ();
- Ptr<Ipv6RoutingProtocol> aRouting = CreateObject<Ipv6ARouting> ();
- Ptr<Ipv6RoutingProtocol> bRouting = CreateObject<Ipv6BRouting> ();
- // The Ipv6BRouting should be added with higher priority (larger integer value)
- lr->AddRoutingProtocol (aRouting, -10);
- lr->AddRoutingProtocol (bRouting, -5);
- int16_t first = 3;
- uint32_t num = lr->GetNRoutingProtocols ();
- NS_TEST_ASSERT_MSG_EQ (num, 2, "XXX");
- Ptr<Ipv6RoutingProtocol> firstRp = lr->GetRoutingProtocol (0, first);
- NS_TEST_ASSERT_MSG_EQ (-5, first, "XXX");
- NS_TEST_ASSERT_MSG_EQ (firstRp, bRouting, "XXX");
-
- // XXX
- return false;
- }
-
- class Ipv6ListRoutingPositiveTestCase : public TestCase
- {
- public:
- Ipv6ListRoutingPositiveTestCase();
- virtual bool DoRun (void);
- };
-
- Ipv6ListRoutingPositiveTestCase::Ipv6ListRoutingPositiveTestCase()
- : TestCase("Check positive priorities")
- {}
- bool
- Ipv6ListRoutingPositiveTestCase::DoRun (void)
- {
- Ptr<Ipv6ListRouting> lr = CreateObject<Ipv6ListRouting> ();
- Ptr<Ipv6RoutingProtocol> aRouting = CreateObject<Ipv6ARouting> ();
- Ptr<Ipv6RoutingProtocol> bRouting = CreateObject<Ipv6BRouting> ();
- // The Ipv6ARouting should be added with higher priority (larger integer
- // value) and will be fetched first below
- lr->AddRoutingProtocol (aRouting, 10);
- lr->AddRoutingProtocol (bRouting, 5);
- int16_t first = 3;
- int16_t second = 3;
- uint32_t num = lr->GetNRoutingProtocols ();
- NS_TEST_ASSERT_MSG_EQ (num, 2, "XXX");
- Ptr<Ipv6RoutingProtocol> firstRp = lr->GetRoutingProtocol (0, first);
- NS_TEST_ASSERT_MSG_EQ (10, first, "XXX");
- NS_TEST_ASSERT_MSG_EQ (firstRp, aRouting, "XXX");
- Ptr<Ipv6RoutingProtocol> secondRp = lr->GetRoutingProtocol (1, second);
- NS_TEST_ASSERT_MSG_EQ (5, second, "XXX");
- NS_TEST_ASSERT_MSG_EQ (secondRp, bRouting, "XXX");
-
- // XXX
- return false;
- }
-
- static class Ipv6ListRoutingTestSuite : public TestSuite
- {
- public:
- Ipv6ListRoutingTestSuite()
- : TestSuite("ipv6-list-routing", UNIT)
- {
- AddTestCase(new Ipv6ListRoutingPositiveTestCase());
- AddTestCase(new Ipv6ListRoutingNegativeTestCase());
- }
-
- } g_ipv6ListRoutingTestSuite;
-
-} // namespace ns3
--- a/src/routing/list-routing/ipv6-list-routing.h Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IPV6_LIST_ROUTING_H
-#define IPV6_LIST_ROUTING_H
-
-#include <list>
-#include "ns3/ipv6-routing-protocol.h"
-
-namespace ns3 {
-
-/**
- * \ingroup routing
- * \defgroup ipv6ListRouting Ipv6 List Routing
- */
-
-/**
- * \ingroup ipv6ListRouting
- * \class Ipv6ListRouting
- * \brief Hold list of Ipv6RoutingProtocol objects.
- *
- * This class is a specialization of Ipv6RoutingProtocol that allows
- * other instances of Ipv6RoutingProtocol to be inserted in a
- * prioritized list. Routing protocols in the list are consulted one
- * by one, from highest to lowest priority, until a routing protocol
- * is found that will take the packet (this corresponds to a non-zero
- * return value to RouteOutput, or a return value of true to RouteInput).
- * The order by which routing protocols with the same priority value
- * are consulted is undefined.
- *
- */
-class Ipv6ListRouting : public Ipv6RoutingProtocol
-{
-public:
- /**
- * \brief Get the type ID of this class.
- * \return type ID
- */
- static TypeId GetTypeId (void);
-
- /**
- * \brief Constructor.
- */
- Ipv6ListRouting ();
-
- /**
- * \brief Destructor.
- */
- virtual ~Ipv6ListRouting ();
-
- /**
- * \brief Register a new routing protocol to be used in this IPv4 stack
- * \param routingProtocol new routing protocol implementation object
- * \param priority priority to give to this routing protocol.
- * Values may range between -32768 and +32767.
- */
- virtual void AddRoutingProtocol (Ptr<Ipv6RoutingProtocol> routingProtocol, int16_t priority);
-
- /**
- * \brief Get the number of routing protocols.
- * \return number of routing protocols in the list
- */
- virtual uint32_t GetNRoutingProtocols (void) const;
-
- /**
- * \brief Get pointer to routing protocol stored at index,
- *
- * The first protocol (index 0) the highest priority, the next one (index 1)
- * the second highest priority, and so on. The priority parameter is an
- * output parameter and it returns the integer priority of the protocol.
- * \param index index of protocol to return
- * \param priority output parameter, set to the priority of the protocol
- * being returned
- * \return pointer to routing protocol indexed by
- */
- virtual Ptr<Ipv6RoutingProtocol> GetRoutingProtocol (uint32_t index, int16_t& priority) const;
-
- // Below are from Ipv6RoutingProtocol
- virtual Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
-
- virtual bool RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
- UnicastForwardCallback ucb, MulticastForwardCallback mcb,
- LocalDeliverCallback lcb, ErrorCallback ecb);
- virtual void NotifyInterfaceUp (uint32_t interface);
- virtual void NotifyInterfaceDown (uint32_t interface);
- virtual void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address);
- virtual void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address);
- virtual void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
- virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
- virtual void SetIpv6 (Ptr<Ipv6> ipv6);
-
-protected:
- /**
- * \brief Dispose this object.
- */
- void DoDispose (void);
-
-private:
- typedef std::pair<int16_t, Ptr<Ipv6RoutingProtocol> > Ipv6RoutingProtocolEntry;
- typedef std::list<Ipv6RoutingProtocolEntry> Ipv6RoutingProtocolList;
-
- /**
- * \brief Compare two routing protocols.
- * \param a first object to compare
- * \param b second object to compare
- * \return true if they are the same, false otherwise
- */
- static bool Compare (const Ipv6RoutingProtocolEntry& a, const Ipv6RoutingProtocolEntry& b);
-
- /**
- * \brief List of routing protocols.
- */
- Ipv6RoutingProtocolList m_routingProtocols;
-
- /**
- * \brief Ipv6 reference.
- */
- Ptr<Ipv6> m_ipv6;
-};
-
-} //namespace ns3
-
-#endif /* IPV6_LIST_ROUTING_H */
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/list-routing/model/ipv4-list-routing.cc Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,394 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "ns3/log.h"
+#include "ns3/ipv4.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/node.h"
+#include "ns3/ipv4-static-routing.h"
+#include "ipv4-list-routing.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv4ListRouting");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv4ListRouting);
+
+TypeId
+Ipv4ListRouting::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::Ipv4ListRouting")
+ .SetParent<Ipv4RoutingProtocol> ()
+ .AddConstructor<Ipv4ListRouting> ()
+ ;
+ return tid;
+}
+
+
+Ipv4ListRouting::Ipv4ListRouting ()
+ : m_ipv4 (0)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv4ListRouting::~Ipv4ListRouting ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+void
+Ipv4ListRouting::DoDispose (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ for (Ipv4RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end (); rprotoIter++)
+ {
+ // Note: Calling dispose on these protocols causes memory leak
+ // The routing protocols should not maintain a pointer to
+ // this object, so Dispose() shouldn't be necessary.
+ (*rprotoIter).second = 0;
+ }
+ m_routingProtocols.clear ();
+ m_ipv4 = 0;
+}
+
+void
+Ipv4ListRouting::DoStart (void)
+{
+ for (Ipv4RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end (); rprotoIter++)
+ {
+ Ptr<Ipv4RoutingProtocol> protocol = (*rprotoIter).second;
+ protocol->Start ();
+ }
+ Ipv4RoutingProtocol::DoStart ();
+}
+
+
+Ptr<Ipv4Route>
+Ipv4ListRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, enum Socket::SocketErrno &sockerr)
+{
+ NS_LOG_FUNCTION (this << header.GetDestination () << " " << header.GetSource () << " " << oif);
+ Ptr<Ipv4Route> route;
+
+ for (Ipv4RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
+ i != m_routingProtocols.end (); i++)
+ {
+ NS_LOG_LOGIC ("Checking protocol " << (*i).second->GetInstanceTypeId () << " with priority " << (*i).first);
+ NS_LOG_LOGIC ("Requesting source address for destination " << header.GetDestination ());
+ route = (*i).second->RouteOutput (p, header, oif, sockerr);
+ if (route)
+ {
+ NS_LOG_LOGIC ("Found route " << route);
+ sockerr = Socket::ERROR_NOTERROR;
+ return route;
+ }
+ }
+ NS_LOG_LOGIC ("Done checking " << GetTypeId ());
+ NS_LOG_LOGIC ("");
+ sockerr = Socket::ERROR_NOROUTETOHOST;
+ return 0;
+}
+
+// Patterned after Linux ip_route_input and ip_route_input_slow
+bool
+Ipv4ListRouting::RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb)
+{
+ bool retVal = false;
+ NS_LOG_FUNCTION (p << header << idev);
+ NS_LOG_LOGIC ("RouteInput logic for node: " << m_ipv4->GetObject<Node> ()->GetId ());
+
+ NS_ASSERT (m_ipv4 != 0);
+ // Check if input device supports IP
+ NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
+ uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
+
+ retVal = m_ipv4->IsDestinationAddress (header.GetDestination (), iif);
+ if (retVal == true)
+ {
+ NS_LOG_LOGIC ("Address "<< header.GetDestination () << " is a match for local delivery");
+ if (header.GetDestination ().IsMulticast ())
+ {
+ Ptr<Packet> packetCopy = p->Copy();
+ lcb (packetCopy, header, iif);
+ retVal = true;
+ // Fall through
+ }
+ else
+ {
+ lcb (p, header, iif);
+ return true;
+ }
+ }
+ // Check if input device supports IP forwarding
+ if (m_ipv4->IsForwarding (iif) == false)
+ {
+ NS_LOG_LOGIC ("Forwarding disabled for this interface");
+ ecb (p, header, Socket::ERROR_NOROUTETOHOST);
+ return false;
+ }
+ // Next, try to find a route
+ // If we have already delivered a packet locally (e.g. multicast)
+ // we suppress further downstream local delivery by nulling the callback
+ LocalDeliverCallback downstreamLcb = lcb;
+ if (retVal == true)
+ {
+ downstreamLcb = MakeNullCallback<void, Ptr<const Packet>, const Ipv4Header &, uint32_t > ();
+ }
+ for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, downstreamLcb, ecb))
+ {
+ NS_LOG_LOGIC ("Route found to forward packet in protocol " << (*rprotoIter).second->GetInstanceTypeId ().GetName ());
+ return true;
+ }
+ }
+ // No routing protocol has found a route.
+ return retVal;
+}
+
+void
+Ipv4ListRouting::NotifyInterfaceUp (uint32_t interface)
+{
+ NS_LOG_FUNCTION (this << interface);
+ for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ (*rprotoIter).second->NotifyInterfaceUp (interface);
+ }
+}
+void
+Ipv4ListRouting::NotifyInterfaceDown (uint32_t interface)
+{
+ NS_LOG_FUNCTION (this << interface);
+ for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ (*rprotoIter).second->NotifyInterfaceDown (interface);
+ }
+}
+void
+Ipv4ListRouting::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)
+{
+ NS_LOG_FUNCTION(this << interface << address);
+ for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ (*rprotoIter).second->NotifyAddAddress (interface, address);
+ }
+}
+void
+Ipv4ListRouting::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)
+{
+ NS_LOG_FUNCTION(this << interface << address);
+ for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ (*rprotoIter).second->NotifyRemoveAddress (interface, address);
+ }
+}
+void
+Ipv4ListRouting::SetIpv4 (Ptr<Ipv4> ipv4)
+{
+ NS_LOG_FUNCTION(this << ipv4);
+ NS_ASSERT (m_ipv4 == 0);
+ for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ (*rprotoIter).second->SetIpv4 (ipv4);
+ }
+ m_ipv4 = ipv4;
+}
+
+void
+Ipv4ListRouting::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol, int16_t priority)
+{
+ NS_LOG_FUNCTION (this << routingProtocol->GetInstanceTypeId () << priority);
+ m_routingProtocols.push_back (std::make_pair (priority, routingProtocol));
+ m_routingProtocols.sort ( Compare );
+ if (m_ipv4 != 0)
+ {
+ routingProtocol->SetIpv4 (m_ipv4);
+ }
+}
+
+uint32_t
+Ipv4ListRouting::GetNRoutingProtocols (void) const
+{
+ NS_LOG_FUNCTION (this);
+ return m_routingProtocols.size ();
+}
+
+Ptr<Ipv4RoutingProtocol>
+Ipv4ListRouting::GetRoutingProtocol (uint32_t index, int16_t& priority) const
+{
+ NS_LOG_FUNCTION (index);
+ if (index > m_routingProtocols.size ())
+ {
+ NS_FATAL_ERROR ("Ipv4ListRouting::GetRoutingProtocol(): index " << index << " out of range");
+ }
+ uint32_t i = 0;
+ for (Ipv4RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end (); rprotoIter++, i++)
+ {
+ if (i == index)
+ {
+ priority = (*rprotoIter).first;
+ return (*rprotoIter).second;
+ }
+ }
+ return 0;
+}
+
+bool
+Ipv4ListRouting::Compare (const Ipv4RoutingProtocolEntry& a, const Ipv4RoutingProtocolEntry& b)
+{
+ return a.first > b.first;
+}
+
+
+} // namespace ns3
+
+#include "ns3/test.h"
+#include "ipv4-list-routing.h"
+#include "ns3/ipv4-routing-protocol.h"
+
+namespace ns3 {
+
+class Ipv4ARouting : public Ipv4RoutingProtocol {
+public:
+ Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr) { return 0;}
+ bool RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb) {return false;}
+ void NotifyInterfaceUp (uint32_t interface) {}
+ void NotifyInterfaceDown (uint32_t interface) {}
+ void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
+ void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
+ void SetIpv4 (Ptr<Ipv4> ipv4) {}
+};
+
+class Ipv4BRouting : public Ipv4RoutingProtocol {
+public:
+ Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr) { return 0;}
+ bool RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb) {return false;}
+ void NotifyInterfaceUp (uint32_t interface) {}
+ void NotifyInterfaceDown (uint32_t interface) {}
+ void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
+ void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
+ void SetIpv4 (Ptr<Ipv4> ipv4) {}
+};
+
+class Ipv4ListRoutingNegativeTestCase : public TestCase
+{
+public:
+ Ipv4ListRoutingNegativeTestCase();
+ virtual bool DoRun (void);
+};
+
+Ipv4ListRoutingNegativeTestCase::Ipv4ListRoutingNegativeTestCase()
+ : TestCase("Check negative priorities")
+{}
+bool
+Ipv4ListRoutingNegativeTestCase::DoRun (void)
+{
+ Ptr<Ipv4ListRouting> lr = CreateObject<Ipv4ListRouting> ();
+ Ptr<Ipv4RoutingProtocol> aRouting = CreateObject<Ipv4ARouting> ();
+ Ptr<Ipv4RoutingProtocol> bRouting = CreateObject<Ipv4BRouting> ();
+ // The Ipv4BRouting should be added with higher priority (larger integer value)
+ lr->AddRoutingProtocol (aRouting, -10);
+ lr->AddRoutingProtocol (bRouting, -5);
+ int16_t first = 3;
+ uint32_t num = lr->GetNRoutingProtocols ();
+ NS_TEST_ASSERT_MSG_EQ (num, 2, "XXX");
+ Ptr<Ipv4RoutingProtocol> firstRp = lr->GetRoutingProtocol (0, first);
+ NS_TEST_ASSERT_MSG_EQ (-5, first, "XXX");
+ NS_TEST_ASSERT_MSG_EQ (firstRp, bRouting, "XXX");
+
+ // XXX
+ return false;
+}
+
+class Ipv4ListRoutingPositiveTestCase : public TestCase
+{
+public:
+ Ipv4ListRoutingPositiveTestCase();
+ virtual bool DoRun (void);
+};
+
+Ipv4ListRoutingPositiveTestCase::Ipv4ListRoutingPositiveTestCase()
+ : TestCase("Check positive priorities")
+{}
+bool
+Ipv4ListRoutingPositiveTestCase::DoRun (void)
+{
+ Ptr<Ipv4ListRouting> lr = CreateObject<Ipv4ListRouting> ();
+ Ptr<Ipv4RoutingProtocol> aRouting = CreateObject<Ipv4ARouting> ();
+ Ptr<Ipv4RoutingProtocol> bRouting = CreateObject<Ipv4BRouting> ();
+ // The Ipv4ARouting should be added with higher priority (larger integer
+ // value) and will be fetched first below
+ lr->AddRoutingProtocol (aRouting, 10);
+ lr->AddRoutingProtocol (bRouting, 5);
+ int16_t first = 3;
+ int16_t second = 3;
+ uint32_t num = lr->GetNRoutingProtocols ();
+ NS_TEST_ASSERT_MSG_EQ (num, 2, "XXX");
+ Ptr<Ipv4RoutingProtocol> firstRp = lr->GetRoutingProtocol (0, first);
+ NS_TEST_ASSERT_MSG_EQ (10, first, "XXX");
+ NS_TEST_ASSERT_MSG_EQ (firstRp, aRouting, "XXX");
+ Ptr<Ipv4RoutingProtocol> secondRp = lr->GetRoutingProtocol (1, second);
+ NS_TEST_ASSERT_MSG_EQ (5, second, "XXX");
+ NS_TEST_ASSERT_MSG_EQ (secondRp, bRouting, "XXX");
+
+ // XXX
+ return false;
+}
+
+static class Ipv4ListRoutingTestSuite : public TestSuite
+{
+public:
+ Ipv4ListRoutingTestSuite()
+ : TestSuite("ipv4-list-routing", UNIT)
+ {
+ AddTestCase(new Ipv4ListRoutingPositiveTestCase());
+ AddTestCase(new Ipv4ListRoutingNegativeTestCase());
+ }
+
+} g_ipv4ListRoutingTestSuite;
+
+} // namespace ns3
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/list-routing/model/ipv4-list-routing.h Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef IPV4_LIST_ROUTING_H
+#define IPV4_LIST_ROUTING_H
+
+#include <list>
+#include "ns3/ipv4-routing-protocol.h"
+
+namespace ns3 {
+
+/**
+ * \ingroup routing
+ * \defgroup ipv4ListRouting Ipv4 List Routing
+ */
+/**
+ * \ingroup ipv4ListRouting
+ *
+ * This class is a specialization of Ipv4RoutingProtocol that allows
+ * other instances of Ipv4RoutingProtocol to be inserted in a
+ * prioritized list. Routing protocols in the list are consulted one
+ * by one, from highest to lowest priority, until a routing protocol
+ * is found that will take the packet (this corresponds to a non-zero
+ * return value to RouteOutput, or a return value of true to RouteInput).
+ * The order by which routing protocols with the same priority value
+ * are consulted is undefined.
+ *
+ */
+class Ipv4ListRouting : public Ipv4RoutingProtocol
+{
+public:
+ static TypeId GetTypeId (void);
+
+ Ipv4ListRouting ();
+ virtual ~Ipv4ListRouting ();
+
+ /**
+ * \brief Register a new routing protocol to be used in this IPv4 stack
+ *
+ * \param routingProtocol new routing protocol implementation object
+ * \param priority priority to give to this routing protocol.
+ * Values may range between -32768 and +32767.
+ */
+ virtual void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol, int16_t priority);
+ /**
+ * \return number of routing protocols in the list
+ */
+ virtual uint32_t GetNRoutingProtocols (void) const;
+ /**
+ * Return pointer to routing protocol stored at index, with the
+ * first protocol (index 0) the highest priority, the next one (index 1)
+ * the second highest priority, and so on. The priority parameter is an
+ * output parameter and it returns the integer priority of the protocol.
+ *
+ * \return pointer to routing protocol indexed by
+ * \param index index of protocol to return
+ * \param priority output parameter, set to the priority of the protocol
+ being returned
+ */
+ virtual Ptr<Ipv4RoutingProtocol> GetRoutingProtocol (uint32_t index, int16_t& priority) const;
+
+ // Below are from Ipv4RoutingProtocol
+ 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,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb);
+ virtual void NotifyInterfaceUp (uint32_t interface);
+ virtual void NotifyInterfaceDown (uint32_t interface);
+ virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
+ virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
+ virtual void SetIpv4 (Ptr<Ipv4> ipv4);
+
+protected:
+ void DoDispose (void);
+ void DoStart (void);
+private:
+ typedef std::pair<int16_t, Ptr<Ipv4RoutingProtocol> > Ipv4RoutingProtocolEntry;
+ typedef std::list<Ipv4RoutingProtocolEntry> Ipv4RoutingProtocolList;
+ Ipv4RoutingProtocolList m_routingProtocols;
+ static bool Compare (const Ipv4RoutingProtocolEntry& a, const Ipv4RoutingProtocolEntry& b);
+ Ptr<Ipv4> m_ipv4;
+
+};
+
+} //namespace ns3
+
+#endif /* IPV4_LIST_ROUTING_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/list-routing/model/ipv6-list-routing.cc Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,452 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "ns3/log.h"
+#include "ns3/ipv6.h"
+#include "ns3/ipv6-route.h"
+#include "ns3/node.h"
+#include "ns3/ipv6-static-routing.h"
+#include "ipv6-list-routing.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6ListRouting");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6ListRouting);
+
+TypeId
+Ipv6ListRouting::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::Ipv6ListRouting")
+ .SetParent<Ipv6RoutingProtocol> ()
+ .AddConstructor<Ipv6ListRouting> ()
+ ;
+ return tid;
+}
+
+
+Ipv6ListRouting::Ipv6ListRouting ()
+ : m_ipv6 (0)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6ListRouting::~Ipv6ListRouting ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+void
+Ipv6ListRouting::DoDispose (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ for (Ipv6RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end (); rprotoIter++)
+ {
+ // Note: Calling dispose on these protocols causes memory leak
+ // The routing protocols should not maintain a pointer to
+ // this object, so Dispose () shouldn't be necessary.
+ (*rprotoIter).second = 0;
+ }
+ m_routingProtocols.clear ();
+ m_ipv6 = 0;
+}
+
+Ptr<Ipv6Route>
+Ipv6ListRouting::RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, enum Socket::SocketErrno &sockerr)
+{
+ NS_LOG_FUNCTION (this << header.GetDestinationAddress () << header.GetSourceAddress () << oif);
+ Ptr<Ipv6Route> route;
+
+ for (Ipv6RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
+ i != m_routingProtocols.end (); i++)
+ {
+ NS_LOG_LOGIC ("Checking protocol " << (*i).second->GetInstanceTypeId () << " with priority " << (*i).first);
+ NS_LOG_LOGIC ("Requesting source address for destination " << header.GetDestinationAddress ());
+ route = (*i).second->RouteOutput (p, header, oif, sockerr);
+ if (route)
+ {
+ NS_LOG_LOGIC ("Found route " << route);
+ sockerr = Socket::ERROR_NOTERROR;
+ return route;
+ }
+ }
+ NS_LOG_LOGIC ("Done checking " << GetTypeId ());
+ NS_LOG_LOGIC ("");
+ sockerr = Socket::ERROR_NOROUTETOHOST;
+ return 0;
+}
+
+// Patterned after Linux ip_route_input and ip_route_input_slow
+bool
+Ipv6ListRouting::RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb)
+{
+ bool retVal = false;
+ NS_LOG_FUNCTION (p << header << idev);
+ NS_LOG_LOGIC ("RouteInput logic for node: " << m_ipv6->GetObject<Node> ()->GetId ());
+
+ NS_ASSERT (m_ipv6 != 0);
+ // Check if input device supports IP
+ NS_ASSERT (m_ipv6->GetInterfaceForDevice (idev) >= 0);
+ uint32_t iif = m_ipv6->GetInterfaceForDevice (idev);
+ Ipv6Address dst = header.GetDestinationAddress ();
+
+ // Multicast recognition; handle local delivery here
+ //
+ if (dst.IsMulticast ())
+ {
+#ifdef NOTYET
+ if (m_ipv6->MulticastCheckGroup (iif, dst))
+#endif
+ if (true)
+ {
+ NS_LOG_LOGIC ("Multicast packet for me-- local deliver");
+ Ptr<Packet> packetCopy = p->Copy ();
+ // Here may want to disable lcb callback in recursive RouteInput
+ // call below
+ lcb (packetCopy, header, iif);
+ // Fall through-- we may also need to forward this
+ retVal = true;
+ }
+
+ /* do not forward link-local multicast address */
+ if (dst == Ipv6Address::GetAllNodesMulticast () || dst == Ipv6Address::GetAllRoutersMulticast () || dst == Ipv6Address::GetAllHostsMulticast ())
+ {
+ return retVal;
+ }
+
+ for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin (); rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ NS_LOG_LOGIC ("Multicast packet for me-- trying to forward");
+ if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, ecb))
+ {
+ retVal = true;
+ }
+ }
+ return retVal;
+ }
+
+ // TODO: Configurable option to enable RFC 1222 Strong End System Model
+ // Right now, we will be permissive and allow a source to send us
+ // a packet to one of our other interface addresses; that is, the
+ // destination unicast address does not match one of the iif addresses,
+ // but we check our other interfaces. This could be an option
+ // (to remove the outer loop immediately below and just check iif).
+ for (uint32_t j = 0; j < m_ipv6->GetNInterfaces (); j++)
+ {
+ for (uint32_t i = 0; i < m_ipv6->GetNAddresses (j); i++)
+ {
+ Ipv6InterfaceAddress iaddr = m_ipv6->GetAddress (j, i);
+ Ipv6Address addr = iaddr.GetAddress ();
+ if (addr.IsEqual (header.GetDestinationAddress ()))
+ {
+ if (j == iif)
+ {
+ NS_LOG_LOGIC ("For me (destination " << addr << " match)");
+ }
+ else
+ {
+ NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestinationAddress ());
+ }
+ lcb (p, header, iif);
+ return true;
+ }
+ NS_LOG_LOGIC ("Address "<< addr << " not a match");
+ }
+ }
+ // Check if input device supports IP forwarding
+ if (m_ipv6->IsForwarding (iif) == false)
+ {
+ NS_LOG_LOGIC ("Forwarding disabled for this interface");
+ ecb (p, header, Socket::ERROR_NOROUTETOHOST);
+ return false;
+ }
+ // Next, try to find a route
+ for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, ecb))
+ {
+ return true;
+ }
+ }
+ // No routing protocol has found a route.
+ return retVal;
+}
+
+void
+Ipv6ListRouting::NotifyInterfaceUp (uint32_t interface)
+{
+ NS_LOG_FUNCTION (this << interface);
+ for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ (*rprotoIter).second->NotifyInterfaceUp (interface);
+ }
+}
+void
+Ipv6ListRouting::NotifyInterfaceDown (uint32_t interface)
+{
+ NS_LOG_FUNCTION (this << interface);
+ for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ (*rprotoIter).second->NotifyInterfaceDown (interface);
+ }
+}
+void
+Ipv6ListRouting::NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address)
+{
+ NS_LOG_FUNCTION (this << interface << address);
+ for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ (*rprotoIter).second->NotifyAddAddress (interface, address);
+ }
+}
+void
+Ipv6ListRouting::NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address)
+{
+ NS_LOG_FUNCTION (this << interface << address);
+ for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ (*rprotoIter).second->NotifyRemoveAddress (interface, address);
+ }
+}
+
+void Ipv6ListRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+ NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
+ for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ (*rprotoIter).second->NotifyAddRoute (dst, mask, nextHop, interface, prefixToUse);
+ }
+}
+
+void Ipv6ListRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+ NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
+ for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ (*rprotoIter).second->NotifyRemoveRoute (dst, mask, nextHop, interface, prefixToUse);
+ }
+}
+
+void
+Ipv6ListRouting::SetIpv6 (Ptr<Ipv6> ipv6)
+{
+ NS_LOG_FUNCTION (this << ipv6);
+ NS_ASSERT (m_ipv6 == 0);
+ for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ (*rprotoIter).second->SetIpv6 (ipv6);
+ }
+ m_ipv6 = ipv6;
+}
+
+void
+Ipv6ListRouting::AddRoutingProtocol (Ptr<Ipv6RoutingProtocol> routingProtocol, int16_t priority)
+{
+ NS_LOG_FUNCTION (this << routingProtocol->GetInstanceTypeId () << priority);
+ m_routingProtocols.push_back (std::make_pair (priority, routingProtocol));
+ m_routingProtocols.sort ( Compare );
+ if (m_ipv6 != 0)
+ {
+ routingProtocol->SetIpv6 (m_ipv6);
+ }
+}
+
+uint32_t
+Ipv6ListRouting::GetNRoutingProtocols (void) const
+{
+ NS_LOG_FUNCTION (this);
+ return m_routingProtocols.size ();
+}
+
+Ptr<Ipv6RoutingProtocol>
+Ipv6ListRouting::GetRoutingProtocol (uint32_t index, int16_t& priority) const
+{
+ NS_LOG_FUNCTION (index);
+ if (index > m_routingProtocols.size ())
+ {
+ NS_FATAL_ERROR ("Ipv6ListRouting::GetRoutingProtocol (): index " << index << " out of range");
+ }
+ uint32_t i = 0;
+ for (Ipv6RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end (); rprotoIter++, i++)
+ {
+ if (i == index)
+ {
+ priority = (*rprotoIter).first;
+ return (*rprotoIter).second;
+ }
+ }
+ return 0;
+}
+
+bool
+Ipv6ListRouting::Compare (const Ipv6RoutingProtocolEntry& a, const Ipv6RoutingProtocolEntry& b)
+{
+ return a.first > b.first;
+}
+
+
+} // namespace ns3
+
+
+#include "ns3/test.h"
+#include "ipv6-list-routing.h"
+#include "ns3/ipv6-routing-protocol.h"
+
+namespace ns3 {
+
+ class Ipv6ARouting : public Ipv6RoutingProtocol {
+ public:
+ Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr) { return 0;}
+ bool RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb) {return false;}
+ void NotifyInterfaceUp (uint32_t interface) {}
+ void NotifyInterfaceDown (uint32_t interface) {}
+ void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
+ void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
+ void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::
+ GetZero ()) {}
+ void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse) {}
+ void SetIpv6 (Ptr<Ipv6> ipv6) {}
+ };
+
+ class Ipv6BRouting : public Ipv6RoutingProtocol {
+ public:
+ Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr) { return 0;}
+ bool RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb) {return false;}
+ void NotifyInterfaceUp (uint32_t interface) {}
+ void NotifyInterfaceDown (uint32_t interface) {}
+ void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
+ void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
+ void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::
+ GetZero ()) {}
+ void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse) {}
+ void SetIpv6 (Ptr<Ipv6> ipv6) {}
+ };
+
+ class Ipv6ListRoutingNegativeTestCase : public TestCase
+ {
+ public:
+ Ipv6ListRoutingNegativeTestCase();
+ virtual bool DoRun (void);
+ };
+
+ Ipv6ListRoutingNegativeTestCase::Ipv6ListRoutingNegativeTestCase()
+ : TestCase("Check negative priorities")
+ {}
+ bool
+ Ipv6ListRoutingNegativeTestCase::DoRun (void)
+ {
+ Ptr<Ipv6ListRouting> lr = CreateObject<Ipv6ListRouting> ();
+ Ptr<Ipv6RoutingProtocol> aRouting = CreateObject<Ipv6ARouting> ();
+ Ptr<Ipv6RoutingProtocol> bRouting = CreateObject<Ipv6BRouting> ();
+ // The Ipv6BRouting should be added with higher priority (larger integer value)
+ lr->AddRoutingProtocol (aRouting, -10);
+ lr->AddRoutingProtocol (bRouting, -5);
+ int16_t first = 3;
+ uint32_t num = lr->GetNRoutingProtocols ();
+ NS_TEST_ASSERT_MSG_EQ (num, 2, "XXX");
+ Ptr<Ipv6RoutingProtocol> firstRp = lr->GetRoutingProtocol (0, first);
+ NS_TEST_ASSERT_MSG_EQ (-5, first, "XXX");
+ NS_TEST_ASSERT_MSG_EQ (firstRp, bRouting, "XXX");
+
+ // XXX
+ return false;
+ }
+
+ class Ipv6ListRoutingPositiveTestCase : public TestCase
+ {
+ public:
+ Ipv6ListRoutingPositiveTestCase();
+ virtual bool DoRun (void);
+ };
+
+ Ipv6ListRoutingPositiveTestCase::Ipv6ListRoutingPositiveTestCase()
+ : TestCase("Check positive priorities")
+ {}
+ bool
+ Ipv6ListRoutingPositiveTestCase::DoRun (void)
+ {
+ Ptr<Ipv6ListRouting> lr = CreateObject<Ipv6ListRouting> ();
+ Ptr<Ipv6RoutingProtocol> aRouting = CreateObject<Ipv6ARouting> ();
+ Ptr<Ipv6RoutingProtocol> bRouting = CreateObject<Ipv6BRouting> ();
+ // The Ipv6ARouting should be added with higher priority (larger integer
+ // value) and will be fetched first below
+ lr->AddRoutingProtocol (aRouting, 10);
+ lr->AddRoutingProtocol (bRouting, 5);
+ int16_t first = 3;
+ int16_t second = 3;
+ uint32_t num = lr->GetNRoutingProtocols ();
+ NS_TEST_ASSERT_MSG_EQ (num, 2, "XXX");
+ Ptr<Ipv6RoutingProtocol> firstRp = lr->GetRoutingProtocol (0, first);
+ NS_TEST_ASSERT_MSG_EQ (10, first, "XXX");
+ NS_TEST_ASSERT_MSG_EQ (firstRp, aRouting, "XXX");
+ Ptr<Ipv6RoutingProtocol> secondRp = lr->GetRoutingProtocol (1, second);
+ NS_TEST_ASSERT_MSG_EQ (5, second, "XXX");
+ NS_TEST_ASSERT_MSG_EQ (secondRp, bRouting, "XXX");
+
+ // XXX
+ return false;
+ }
+
+ static class Ipv6ListRoutingTestSuite : public TestSuite
+ {
+ public:
+ Ipv6ListRoutingTestSuite()
+ : TestSuite("ipv6-list-routing", UNIT)
+ {
+ AddTestCase(new Ipv6ListRoutingPositiveTestCase());
+ AddTestCase(new Ipv6ListRoutingNegativeTestCase());
+ }
+
+ } g_ipv6ListRoutingTestSuite;
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/list-routing/model/ipv6-list-routing.h Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,139 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef IPV6_LIST_ROUTING_H
+#define IPV6_LIST_ROUTING_H
+
+#include <list>
+#include "ns3/ipv6-routing-protocol.h"
+
+namespace ns3 {
+
+/**
+ * \ingroup routing
+ * \defgroup ipv6ListRouting Ipv6 List Routing
+ */
+
+/**
+ * \ingroup ipv6ListRouting
+ * \class Ipv6ListRouting
+ * \brief Hold list of Ipv6RoutingProtocol objects.
+ *
+ * This class is a specialization of Ipv6RoutingProtocol that allows
+ * other instances of Ipv6RoutingProtocol to be inserted in a
+ * prioritized list. Routing protocols in the list are consulted one
+ * by one, from highest to lowest priority, until a routing protocol
+ * is found that will take the packet (this corresponds to a non-zero
+ * return value to RouteOutput, or a return value of true to RouteInput).
+ * The order by which routing protocols with the same priority value
+ * are consulted is undefined.
+ *
+ */
+class Ipv6ListRouting : public Ipv6RoutingProtocol
+{
+public:
+ /**
+ * \brief Get the type ID of this class.
+ * \return type ID
+ */
+ static TypeId GetTypeId (void);
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6ListRouting ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6ListRouting ();
+
+ /**
+ * \brief Register a new routing protocol to be used in this IPv4 stack
+ * \param routingProtocol new routing protocol implementation object
+ * \param priority priority to give to this routing protocol.
+ * Values may range between -32768 and +32767.
+ */
+ virtual void AddRoutingProtocol (Ptr<Ipv6RoutingProtocol> routingProtocol, int16_t priority);
+
+ /**
+ * \brief Get the number of routing protocols.
+ * \return number of routing protocols in the list
+ */
+ virtual uint32_t GetNRoutingProtocols (void) const;
+
+ /**
+ * \brief Get pointer to routing protocol stored at index,
+ *
+ * The first protocol (index 0) the highest priority, the next one (index 1)
+ * the second highest priority, and so on. The priority parameter is an
+ * output parameter and it returns the integer priority of the protocol.
+ * \param index index of protocol to return
+ * \param priority output parameter, set to the priority of the protocol
+ * being returned
+ * \return pointer to routing protocol indexed by
+ */
+ virtual Ptr<Ipv6RoutingProtocol> GetRoutingProtocol (uint32_t index, int16_t& priority) const;
+
+ // Below are from Ipv6RoutingProtocol
+ virtual Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
+
+ virtual bool RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb);
+ virtual void NotifyInterfaceUp (uint32_t interface);
+ virtual void NotifyInterfaceDown (uint32_t interface);
+ virtual void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address);
+ virtual void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address);
+ virtual void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
+ virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
+ virtual void SetIpv6 (Ptr<Ipv6> ipv6);
+
+protected:
+ /**
+ * \brief Dispose this object.
+ */
+ void DoDispose (void);
+
+private:
+ typedef std::pair<int16_t, Ptr<Ipv6RoutingProtocol> > Ipv6RoutingProtocolEntry;
+ typedef std::list<Ipv6RoutingProtocolEntry> Ipv6RoutingProtocolList;
+
+ /**
+ * \brief Compare two routing protocols.
+ * \param a first object to compare
+ * \param b second object to compare
+ * \return true if they are the same, false otherwise
+ */
+ static bool Compare (const Ipv6RoutingProtocolEntry& a, const Ipv6RoutingProtocolEntry& b);
+
+ /**
+ * \brief List of routing protocols.
+ */
+ Ipv6RoutingProtocolList m_routingProtocols;
+
+ /**
+ * \brief Ipv6 reference.
+ */
+ Ptr<Ipv6> m_ipv6;
+};
+
+} //namespace ns3
+
+#endif /* IPV6_LIST_ROUTING_H */
+
--- a/src/routing/list-routing/wscript Tue Oct 26 15:11:17 2010 +0100
+++ b/src/routing/list-routing/wscript Tue Oct 26 18:02:17 2010 +0100
@@ -3,13 +3,17 @@
def build(bld):
module = bld.create_ns3_module('list-routing', ['node'])
module.source = [
- 'ipv4-list-routing.cc',
- 'ipv6-list-routing.cc',
+ 'model/ipv4-list-routing.cc',
+ 'model/ipv6-list-routing.cc',
+ 'helper/ipv4-list-routing-helper.cc',
+ 'helper/ipv6-list-routing-helper.cc',
]
headers = bld.new_task_gen('ns3header')
headers.module = 'list-routing'
headers.source = [
- 'ipv4-list-routing.h',
- 'ipv6-list-routing.h',
+ 'model/ipv4-list-routing.h',
+ 'model/ipv6-list-routing.h',
+ 'helper/ipv4-list-routing-helper.h',
+ 'helper/ipv6-list-routing-helper.h',
]
--- a/src/routing/olsr/examples/olsr-hna.cc Tue Oct 26 15:11:17 2010 +0100
+++ b/src/routing/olsr/examples/olsr-hna.cc Tue Oct 26 18:02:17 2010 +0100
@@ -60,6 +60,8 @@
#include "ns3/ipv4-list-routing.h"
#include "ns3/olsr-routing-protocol.h"
#include "ns3/olsr-helper.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
#include <iostream>
#include <fstream>
--- a/src/routing/olsr/examples/simple-point-to-point-olsr.cc Tue Oct 26 15:11:17 2010 +0100
+++ b/src/routing/olsr/examples/simple-point-to-point-olsr.cc Tue Oct 26 18:02:17 2010 +0100
@@ -45,6 +45,8 @@
#include "ns3/node-module.h"
#include "ns3/helper-module.h"
#include "ns3/olsr-helper.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
using namespace ns3;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/helper/ipv4-static-routing-helper.cc Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,210 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <vector>
+#include "ns3/log.h"
+#include "ns3/ptr.h"
+#include "ns3/names.h"
+#include "ns3/node.h"
+#include "ns3/ipv4.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/ipv4-list-routing.h"
+#include "ns3/assert.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4-routing-protocol.h"
+#include "ipv4-static-routing-helper.h"
+
+NS_LOG_COMPONENT_DEFINE("Ipv4StaticRoutingHelper");
+
+namespace ns3 {
+
+Ipv4StaticRoutingHelper::Ipv4StaticRoutingHelper()
+{}
+
+Ipv4StaticRoutingHelper::Ipv4StaticRoutingHelper (const Ipv4StaticRoutingHelper &o)
+{
+}
+
+Ipv4StaticRoutingHelper*
+Ipv4StaticRoutingHelper::Copy (void) const
+{
+ return new Ipv4StaticRoutingHelper (*this);
+}
+
+Ptr<Ipv4RoutingProtocol>
+Ipv4StaticRoutingHelper::Create (Ptr<Node> node) const
+{
+ return CreateObject<Ipv4StaticRouting> ();
+}
+
+
+Ptr<Ipv4StaticRouting>
+Ipv4StaticRoutingHelper::GetStaticRouting (Ptr<Ipv4> ipv4) const
+{
+ NS_LOG_FUNCTION (this);
+ Ptr<Ipv4RoutingProtocol> ipv4rp = ipv4->GetRoutingProtocol ();
+ NS_ASSERT_MSG (ipv4rp, "No routing protocol associated with Ipv4");
+ if (DynamicCast<Ipv4StaticRouting> (ipv4rp))
+ {
+ NS_LOG_LOGIC ("Static routing found as the main IPv4 routing protocol.");
+ return DynamicCast<Ipv4StaticRouting> (ipv4rp);
+ }
+ if (DynamicCast<Ipv4ListRouting> (ipv4rp))
+ {
+ Ptr<Ipv4ListRouting> lrp = DynamicCast<Ipv4ListRouting> (ipv4rp);
+ int16_t priority;
+ for (uint32_t i = 0; i < lrp->GetNRoutingProtocols (); i++)
+ {
+ NS_LOG_LOGIC ("Searching for static routing in list");
+ Ptr<Ipv4RoutingProtocol> temp = lrp->GetRoutingProtocol (i, priority);
+ if (DynamicCast<Ipv4StaticRouting> (temp))
+ {
+ NS_LOG_LOGIC ("Found static routing in list");
+ return DynamicCast<Ipv4StaticRouting> (temp);
+ }
+ }
+ }
+ NS_LOG_LOGIC ("Static routing not found");
+ return 0;
+}
+
+void
+Ipv4StaticRoutingHelper::AddMulticastRoute (
+ Ptr<Node> n,
+ Ipv4Address source,
+ Ipv4Address group,
+ Ptr<NetDevice> input,
+ NetDeviceContainer output)
+{
+ Ptr<Ipv4> ipv4 = n->GetObject<Ipv4> ();
+
+ // We need to convert the NetDeviceContainer to an array of interface
+ // numbers
+ std::vector<uint32_t> outputInterfaces;
+ for (NetDeviceContainer::Iterator i = output.Begin (); i != output.End (); ++i)
+ {
+ Ptr<NetDevice> nd = *i;
+ int32_t interface = ipv4->GetInterfaceForDevice (nd);
+ NS_ASSERT_MSG(interface >= 0,
+ "Ipv4StaticRoutingHelper::AddMulticastRoute(): "
+ "Expected an interface associated with the device nd");
+ outputInterfaces.push_back(interface);
+ }
+
+ int32_t inputInterface = ipv4->GetInterfaceForDevice (input);
+ NS_ASSERT_MSG(inputInterface >= 0,
+ "Ipv4StaticRoutingHelper::AddMulticastRoute(): "
+ "Expected an interface associated with the device input");
+ Ipv4StaticRoutingHelper helper;
+ Ptr<Ipv4StaticRouting> ipv4StaticRouting = helper.GetStaticRouting (ipv4);
+ if (!ipv4StaticRouting)
+ {
+ NS_ASSERT_MSG (ipv4StaticRouting,
+ "Ipv4StaticRoutingHelper::SetDefaultMulticastRoute(): "
+ "Expected an Ipv4StaticRouting associated with this node");
+ }
+ ipv4StaticRouting->AddMulticastRoute (source, group, inputInterface, outputInterfaces);
+}
+
+void
+Ipv4StaticRoutingHelper::AddMulticastRoute (
+ Ptr<Node> n,
+ Ipv4Address source,
+ Ipv4Address group,
+ std::string inputName,
+ NetDeviceContainer output)
+{
+ Ptr<NetDevice> input = Names::Find<NetDevice> (inputName);
+ AddMulticastRoute (n, source, group, input, output);
+}
+
+void
+Ipv4StaticRoutingHelper::AddMulticastRoute (
+ std::string nName,
+ Ipv4Address source,
+ Ipv4Address group,
+ Ptr<NetDevice> input,
+ NetDeviceContainer output)
+{
+ Ptr<Node> n = Names::Find<Node> (nName);
+ AddMulticastRoute (n, source, group, input, output);
+}
+
+void
+Ipv4StaticRoutingHelper::AddMulticastRoute (
+ std::string nName,
+ Ipv4Address source,
+ Ipv4Address group,
+ std::string inputName,
+ NetDeviceContainer output)
+{
+ Ptr<NetDevice> input = Names::Find<NetDevice> (inputName);
+ Ptr<Node> n = Names::Find<Node> (nName);
+ AddMulticastRoute (n, source, group, input, output);
+}
+
+void
+Ipv4StaticRoutingHelper::SetDefaultMulticastRoute (
+ Ptr<Node> n,
+ Ptr<NetDevice> nd)
+{
+ Ptr<Ipv4> ipv4 = n->GetObject<Ipv4> ();
+ int32_t interfaceSrc = ipv4->GetInterfaceForDevice (nd);
+ NS_ASSERT_MSG(interfaceSrc >= 0,
+ "Ipv4StaticRoutingHelper::SetDefaultMulticastRoute(): "
+ "Expected an interface associated with the device");
+ Ipv4StaticRoutingHelper helper;
+ Ptr<Ipv4StaticRouting> ipv4StaticRouting = helper.GetStaticRouting (ipv4);
+ if (!ipv4StaticRouting)
+ {
+ NS_ASSERT_MSG (ipv4StaticRouting,
+ "Ipv4StaticRoutingHelper::SetDefaultMulticastRoute(): "
+ "Expected an Ipv4StaticRouting associated with this node");
+ }
+ ipv4StaticRouting->SetDefaultMulticastRoute (interfaceSrc);
+}
+
+void
+Ipv4StaticRoutingHelper::SetDefaultMulticastRoute (
+ Ptr<Node> n,
+ std::string ndName)
+{
+ Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
+ SetDefaultMulticastRoute (n, nd);
+}
+
+void
+Ipv4StaticRoutingHelper::SetDefaultMulticastRoute (
+ std::string nName,
+ Ptr<NetDevice> nd)
+{
+ Ptr<Node> n = Names::Find<Node> (nName);
+ SetDefaultMulticastRoute (n, nd);
+}
+
+void
+Ipv4StaticRoutingHelper::SetDefaultMulticastRoute (
+ std::string nName,
+ std::string ndName)
+{
+ Ptr<Node> n = Names::Find<Node> (nName);
+ Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
+ SetDefaultMulticastRoute (n, nd);
+}
+
+}; // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/helper/ipv4-static-routing-helper.h Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,169 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef IPV4_STATIC_ROUTING_HELPER_H
+#define IPV4_STATIC_ROUTING_HELPER_H
+
+#include "ns3/ipv4.h"
+#include "ns3/ipv4-static-routing.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/node.h"
+#include "ns3/net-device.h"
+#include "ns3/ipv4-routing-helper.h"
+#include "ns3/node-container.h"
+#include "ns3/net-device-container.h"
+
+namespace ns3 {
+
+/**
+ * \brief Helper class that adds ns3::Ipv4StaticRouting objects
+ *
+ * This class is expected to be used in conjunction with
+ * ns3::InternetStackHelper::SetRoutingHelper
+ */
+class Ipv4StaticRoutingHelper : public Ipv4RoutingHelper
+{
+public:
+ /*
+ * Construct an Ipv4StaticRoutingHelper object, used to make configuration
+ * of static routing easier.
+ */
+ Ipv4StaticRoutingHelper ();
+
+ /**
+ * \brief Construct an Ipv4StaticRoutingHelper from another previously
+ * initialized instance (Copy Constructor).
+ */
+ Ipv4StaticRoutingHelper (const Ipv4StaticRoutingHelper &);
+
+ /**
+ * \internal
+ * \returns pointer to clone of this Ipv4StaticRoutingHelper
+ *
+ * This method is mainly for internal use by the other helpers;
+ * clients are expected to free the dynamic memory allocated by this method
+ */
+ Ipv4StaticRoutingHelper* Copy (void) const;
+
+ /**
+ * \param node the node on which the routing protocol will run
+ * \returns a newly-created routing protocol
+ *
+ * This method will be called by ns3::InternetStackHelper::Install
+ */
+ virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
+
+ /**
+ * Try and find the static routing protocol as either the main routing
+ * protocol or in the list of routing protocols associated with the
+ * Ipv4 provided.
+ *
+ * \param ipv4 the Ptr<Ipv4> to search for the static routing protocol
+ */
+ Ptr<Ipv4StaticRouting> GetStaticRouting (Ptr<Ipv4> ipv4) const;
+
+ /**
+ * \brief Add a multicast route to a node and net device using explicit
+ * Ptr<Node> and Ptr<NetDevice>
+ */
+ void AddMulticastRoute (Ptr<Node> n, Ipv4Address source, Ipv4Address group,
+ Ptr<NetDevice> input, NetDeviceContainer output);
+
+ /**
+ * \brief Add a multicast route to a node and device using a name string
+ * previously associated to the node using the Object Name Service and a
+ * Ptr<NetDevice>
+ */
+ void AddMulticastRoute (std::string n, Ipv4Address source, Ipv4Address group,
+ Ptr<NetDevice> input, NetDeviceContainer output);
+
+ /**
+ * \brief Add a multicast route to a node and device using a Ptr<Node> and a
+ * name string previously associated to the device using the Object Name Service.
+ */
+ void AddMulticastRoute (Ptr<Node> n, Ipv4Address source, Ipv4Address group,
+ std::string inputName, NetDeviceContainer output);
+
+ /**
+ * \brief Add a multicast route to a node and device using name strings
+ * previously associated to both the node and device using the Object Name
+ * Service.
+ */
+ void AddMulticastRoute (std::string nName, Ipv4Address source, Ipv4Address group,
+ std::string inputName, NetDeviceContainer output);
+
+ /**
+ * \brief Add a default route to the static routing protocol to forward
+ * packets out a particular interface
+ *
+ * Functionally equivalent to:
+ * route add 224.0.0.0 netmask 240.0.0.0 dev nd
+ * \param n node
+ * \param nd device of the node to add default route
+ */
+ void SetDefaultMulticastRoute (Ptr<Node> n, Ptr<NetDevice> nd);
+
+ /**
+ * \brief Add a default route to the static routing protocol to forward
+ * packets out a particular interface
+ *
+ * Functionally equivalent to:
+ * route add 224.0.0.0 netmask 240.0.0.0 dev nd
+ * \param n node
+ * \param ndName string with name previously associated to device using the
+ * Object Name Service
+ */
+ void SetDefaultMulticastRoute (Ptr<Node> n, std::string ndName);
+
+ /**
+ * \brief Add a default route to the static routing protocol to forward
+ * packets out a particular interface
+ *
+ * Functionally equivalent to:
+ * route add 224.0.0.0 netmask 240.0.0.0 dev nd
+ * \param nName string with name previously associated to node using the
+ * Object Name Service
+ * \param nd device of the node to add default route
+ */
+ void SetDefaultMulticastRoute (std::string nName, Ptr<NetDevice> nd);
+
+ /**
+ * \brief Add a default route to the static routing protocol to forward
+ * packets out a particular interface
+ *
+ * Functionally equivalent to:
+ * route add 224.0.0.0 netmask 240.0.0.0 dev nd
+ * \param nName string with name previously associated to node using the
+ * Object Name Service
+ * \param ndName string with name previously associated to device using the
+ * Object Name Service
+ */
+ void SetDefaultMulticastRoute (std::string nName, std::string ndName);
+private:
+ /**
+ * \internal
+ * \brief Assignment operator declared private and not implemented to disallow
+ * assignment and prevent the compiler from happily inserting its own.
+ */
+ Ipv4StaticRoutingHelper &operator = (const Ipv4StaticRoutingHelper &o);
+};
+
+} // namespace ns3
+
+#endif /* IPV4_STATIC_ROUTING_HELPER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/helper/ipv6-static-routing-helper.cc Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,213 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <vector>
+
+#include "ns3/log.h"
+#include "ns3/ptr.h"
+#include "ns3/names.h"
+#include "ns3/node.h"
+#include "ns3/ipv6.h"
+#include "ns3/ipv6-route.h"
+#include "ns3/ipv6-list-routing.h"
+#include "ns3/assert.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/ipv6-routing-protocol.h"
+
+#include "ipv6-static-routing-helper.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6StaticRoutingHelper");
+
+namespace ns3 {
+
+Ipv6StaticRoutingHelper::Ipv6StaticRoutingHelper ()
+{}
+
+Ipv6StaticRoutingHelper::Ipv6StaticRoutingHelper (const Ipv6StaticRoutingHelper &o)
+{
+}
+
+Ipv6StaticRoutingHelper*
+Ipv6StaticRoutingHelper::Copy (void) const
+{
+ return new Ipv6StaticRoutingHelper (*this);
+}
+
+Ptr<Ipv6RoutingProtocol>
+Ipv6StaticRoutingHelper::Create (Ptr<Node> node) const
+{
+ return CreateObject<Ipv6StaticRouting> ();
+}
+
+Ptr<Ipv6StaticRouting>
+Ipv6StaticRoutingHelper::GetStaticRouting (Ptr<Ipv6> ipv6) const
+{
+ NS_LOG_FUNCTION (this);
+ Ptr<Ipv6RoutingProtocol> ipv6rp = ipv6->GetRoutingProtocol ();
+ NS_ASSERT_MSG (ipv6rp, "No routing protocol associated with Ipv6");
+ if (DynamicCast<Ipv6StaticRouting> (ipv6rp))
+ {
+ NS_LOG_LOGIC ("Static routing found as the main IPv4 routing protocol.");
+ return DynamicCast<Ipv6StaticRouting> (ipv6rp);
+ }
+ if (DynamicCast<Ipv6ListRouting> (ipv6rp))
+ {
+ Ptr<Ipv6ListRouting> lrp = DynamicCast<Ipv6ListRouting> (ipv6rp);
+ int16_t priority;
+ for (uint32_t i = 0; i < lrp->GetNRoutingProtocols (); i++)
+ {
+ NS_LOG_LOGIC ("Searching for static routing in list");
+ Ptr<Ipv6RoutingProtocol> temp = lrp->GetRoutingProtocol (i, priority);
+ if (DynamicCast<Ipv6StaticRouting> (temp))
+ {
+ NS_LOG_LOGIC ("Found static routing in list");
+ return DynamicCast<Ipv6StaticRouting> (temp);
+ }
+ }
+ }
+ NS_LOG_LOGIC ("Static routing not found");
+ return 0;
+}
+
+void
+Ipv6StaticRoutingHelper::AddMulticastRoute (
+ Ptr<Node> n,
+ Ipv6Address source,
+ Ipv6Address group,
+ Ptr<NetDevice> input,
+ NetDeviceContainer output)
+{
+ Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
+
+ // We need to convert the NetDeviceContainer to an array of interface
+ // numbers
+ std::vector<uint32_t> outputInterfaces;
+ for (NetDeviceContainer::Iterator i = output.Begin (); i != output.End (); ++i)
+ {
+ Ptr<NetDevice> nd = *i;
+ int32_t interface = ipv6->GetInterfaceForDevice (nd);
+ NS_ASSERT_MSG (interface >= 0,
+ "Ipv6StaticRoutingHelper::AddMulticastRoute (): "
+ "Expected an interface associated with the device nd");
+ outputInterfaces.push_back (interface);
+ }
+
+ int32_t inputInterface = ipv6->GetInterfaceForDevice (input);
+ NS_ASSERT_MSG (inputInterface >= 0,
+ "Ipv6StaticRoutingHelper::AddMulticastRoute (): "
+ "Expected an interface associated with the device input");
+ Ipv6StaticRoutingHelper helper;
+ Ptr<Ipv6StaticRouting> ipv6StaticRouting = helper.GetStaticRouting (ipv6);
+ if (!ipv6StaticRouting)
+ {
+ NS_ASSERT_MSG (ipv6StaticRouting,
+ "Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (): "
+ "Expected an Ipv6StaticRouting associated with this node");
+ }
+ ipv6StaticRouting->AddMulticastRoute (source, group, inputInterface, outputInterfaces);
+}
+
+void
+Ipv6StaticRoutingHelper::AddMulticastRoute (
+ Ptr<Node> n,
+ Ipv6Address source,
+ Ipv6Address group,
+ std::string inputName,
+ NetDeviceContainer output)
+{
+ Ptr<NetDevice> input = Names::Find<NetDevice> (inputName);
+ AddMulticastRoute (n, source, group, input, output);
+}
+
+void
+Ipv6StaticRoutingHelper::AddMulticastRoute (
+ std::string nName,
+ Ipv6Address source,
+ Ipv6Address group,
+ Ptr<NetDevice> input,
+ NetDeviceContainer output)
+{
+ Ptr<Node> n = Names::Find<Node> (nName);
+ AddMulticastRoute (n, source, group, input, output);
+}
+
+void
+Ipv6StaticRoutingHelper::AddMulticastRoute (
+ std::string nName,
+ Ipv6Address source,
+ Ipv6Address group,
+ std::string inputName,
+ NetDeviceContainer output)
+{
+ Ptr<NetDevice> input = Names::Find<NetDevice> (inputName);
+ Ptr<Node> n = Names::Find<Node> (nName);
+ AddMulticastRoute (n, source, group, input, output);
+}
+
+#if 0
+void
+Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (
+ Ptr<Node> n,
+ Ptr<NetDevice> nd)
+{
+ Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
+ int32_t interfaceSrc = ipv6->GetInterfaceForDevice (nd);
+ NS_ASSERT_MSG (interfaceSrc >= 0,
+ "Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (): "
+ "Expected an interface associated with the device");
+ Ipv6StaticRoutingHelper helper;
+ Ptr<Ipv6StaticRouting> ipv6StaticRouting = helper.GetStaticRouting (ipv6);
+ if (!ipv6StaticRouting)
+ {
+ NS_ASSERT_MSG (ipv6StaticRouting,
+ "Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (): "
+ "Expected an Ipv6StaticRouting associated with this node");
+ }
+ ipv6StaticRouting->SetDefaultMulticastRoute (interfaceSrc);
+}
+
+void
+Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (
+ Ptr<Node> n,
+ std::string ndName)
+{
+ Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
+ SetDefaultMulticastRoute (n, nd);
+}
+
+void
+Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (
+ std::string nName,
+ Ptr<NetDevice> nd)
+{
+ Ptr<Node> n = Names::Find<Node> (nName);
+ SetDefaultMulticastRoute (n, nd);
+}
+
+void
+Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (
+ std::string nName,
+ std::string ndName)
+{
+ Ptr<Node> n = Names::Find<Node> (nName);
+ Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
+ SetDefaultMulticastRoute (n, nd);
+}
+#endif
+
+}; // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/helper/ipv6-static-routing-helper.h Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,131 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef IPV6_STATIC_ROUTING_HELPER_H
+#define IPV6_STATIC_ROUTING_HELPER_H
+
+#include "ns3/ipv6.h"
+#include "ns3/ipv6-static-routing.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/node.h"
+#include "ns3/net-device.h"
+
+#include "ns3/node-container.h"
+#include "ns3/net-device-container.h"
+#include "ns3/ipv6-routing-helper.h"
+
+namespace ns3 {
+
+/**
+ * \brief Helper class that adds ns3::Ipv6StaticRouting objects
+ *
+ * This class is expected to be used in conjunction with
+ * ns3::InternetStackHelper::SetRoutingHelper
+ */
+class Ipv6StaticRoutingHelper : public Ipv6RoutingHelper
+{
+public:
+ /**
+ * \brief Constructor.
+ */
+ Ipv6StaticRoutingHelper ();
+
+ /**
+ * \brief Construct an Ipv6ListRoutingHelper from another previously
+ * initialized instance (Copy Constructor).
+ */
+ Ipv6StaticRoutingHelper (const Ipv6StaticRoutingHelper &);
+
+ /**
+ * \internal
+ * \returns pointer to clone of this Ipv6StaticRoutingHelper
+ *
+ * This method is mainly for internal use by the other helpers;
+ * clients are expected to free the dynamic memory allocated by this method
+ */
+ Ipv6StaticRoutingHelper* Copy (void) const;
+
+ /**
+ * \param node the node on which the routing protocol will run
+ * \returns a newly-created routing protocol
+ *
+ * This method will be called by ns3::InternetStackHelper::Install
+ */
+ virtual Ptr<Ipv6RoutingProtocol> Create (Ptr<Node> node) const;
+
+ /**
+ * \brief Get Ipv6StaticRouting pointer from IPv6 stack.
+ * \param ipv6 Ipv6 pointer
+ * \return Ipv6StaticRouting pointer or 0 if not exist
+ */
+ Ptr<Ipv6StaticRouting> GetStaticRouting (Ptr<Ipv6> ipv6) const;
+
+ /**
+ * \brief Add a multicast route to a node and net device using explicit
+ * Ptr<Node> and Ptr<NetDevice>
+ */
+ void AddMulticastRoute (Ptr<Node> n, Ipv6Address source, Ipv6Address group,
+ Ptr<NetDevice> input, NetDeviceContainer output);
+
+ /**
+ * \brief Add a multicast route to a node and device using a name string
+ * previously associated to the node using the Object Name Service and a
+ * Ptr<NetDevice>
+ */
+ void AddMulticastRoute (std::string n, Ipv6Address source, Ipv6Address group,
+ Ptr<NetDevice> input, NetDeviceContainer output);
+
+ /**
+ * \brief Add a multicast route to a node and device using a Ptr<Node> and a
+ * name string previously associated to the device using the Object Name Service.
+ */
+ void AddMulticastRoute (Ptr<Node> n, Ipv6Address source, Ipv6Address group,
+ std::string inputName, NetDeviceContainer output);
+
+ /**
+ * \brief Add a multicast route to a node and device using name strings
+ * previously associated to both the node and device using the Object Name
+ * Service.
+ */
+ void AddMulticastRoute (std::string nName, Ipv6Address source, Ipv6Address group,
+ std::string inputName, NetDeviceContainer output);
+
+#if 0
+ /**
+ * \brief Add a default route to the static routing protocol to forward
+ * packets out a particular interface
+ */
+ void SetDefaultMulticastRoute (Ptr<Node> n, Ptr<NetDevice> nd);
+ void SetDefaultMulticastRoute (Ptr<Node> n, std::string ndName);
+ void SetDefaultMulticastRoute (std::string nName, Ptr<NetDevice> nd);
+ void SetDefaultMulticastRoute (std::string nName, std::string ndName);
+#endif
+private:
+ /**
+ * \internal
+ * \brief Assignment operator declared private and not implemented to disallow
+ * assignment and prevent the compiler from happily inserting its own.
+ */
+ Ipv6StaticRoutingHelper &operator = (const Ipv6StaticRoutingHelper &o);
+};
+
+} // namespace ns3
+
+#endif /* IPV6_STATIC_ROUTING_HELPER_H */
+
--- a/src/routing/static-routing/ipv4-routing-table-entry.cc Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,333 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include "ipv4-routing-table-entry.h"
-#include "ns3/assert.h"
-
-namespace ns3 {
-
-/*****************************************************
- * Network Ipv4RoutingTableEntry
- *****************************************************/
-
-Ipv4RoutingTableEntry::Ipv4RoutingTableEntry ()
-{}
-
-Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4RoutingTableEntry const &route)
- : m_dest (route.m_dest),
- m_destNetworkMask (route.m_destNetworkMask),
- m_gateway (route.m_gateway),
- m_interface (route.m_interface)
-{}
-
-Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4RoutingTableEntry const *route)
- : m_dest (route->m_dest),
- m_destNetworkMask (route->m_destNetworkMask),
- m_gateway (route->m_gateway),
- m_interface (route->m_interface)
-{}
-
-Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4Address dest,
- Ipv4Address gateway,
- uint32_t interface)
- : m_dest (dest),
- m_destNetworkMask (Ipv4Mask::GetOnes ()),
- m_gateway (gateway),
- m_interface (interface)
-{}
-Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4Address dest,
- uint32_t interface)
- : m_dest (dest),
- m_destNetworkMask (Ipv4Mask::GetOnes ()),
- m_gateway (Ipv4Address::GetZero ()),
- m_interface (interface)
-{}
-Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4Address network,
- Ipv4Mask networkMask,
- Ipv4Address gateway,
- uint32_t interface)
- : m_dest (network),
- m_destNetworkMask (networkMask),
- m_gateway (gateway),
- m_interface (interface)
-{}
-Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4Address network,
- Ipv4Mask networkMask,
- uint32_t interface)
- : m_dest (network),
- m_destNetworkMask (networkMask),
- m_gateway (Ipv4Address::GetZero ()),
- m_interface (interface)
-{}
-
-bool
-Ipv4RoutingTableEntry::IsHost (void) const
-{
- if (m_destNetworkMask.IsEqual (Ipv4Mask::GetOnes ()))
- {
- return true;
- }
- else
- {
- return false;
- }
-}
-Ipv4Address
-Ipv4RoutingTableEntry::GetDest (void) const
-{
- return m_dest;
-}
-bool
-Ipv4RoutingTableEntry::IsNetwork (void) const
-{
- return !IsHost ();
-}
-bool
-Ipv4RoutingTableEntry::IsDefault (void) const
-{
- if (m_dest.IsEqual (Ipv4Address::GetZero ()))
- {
- return true;
- }
- else
- {
- return false;
- }
-}
-Ipv4Address
-Ipv4RoutingTableEntry::GetDestNetwork (void) const
-{
- return m_dest;
-}
-Ipv4Mask
-Ipv4RoutingTableEntry::GetDestNetworkMask (void) const
-{
- return m_destNetworkMask;
-}
-bool
-Ipv4RoutingTableEntry::IsGateway (void) const
-{
- if (m_gateway.IsEqual (Ipv4Address::GetZero ()))
- {
- return false;
- }
- else
- {
- return true;
- }
-}
-Ipv4Address
-Ipv4RoutingTableEntry::GetGateway (void) const
-{
- return m_gateway;
-}
-uint32_t
-Ipv4RoutingTableEntry::GetInterface (void) const
-{
- return m_interface;
-}
-
-Ipv4RoutingTableEntry
-Ipv4RoutingTableEntry::CreateHostRouteTo (Ipv4Address dest,
- Ipv4Address nextHop,
- uint32_t interface)
-{
- return Ipv4RoutingTableEntry (dest, nextHop, interface);
-}
-Ipv4RoutingTableEntry
-Ipv4RoutingTableEntry::CreateHostRouteTo (Ipv4Address dest,
- uint32_t interface)
-{
- return Ipv4RoutingTableEntry (dest, interface);
-}
-Ipv4RoutingTableEntry
-Ipv4RoutingTableEntry::CreateNetworkRouteTo (Ipv4Address network,
- Ipv4Mask networkMask,
- Ipv4Address nextHop,
- uint32_t interface)
-{
- return Ipv4RoutingTableEntry (network, networkMask,
- nextHop, interface);
-}
-Ipv4RoutingTableEntry
-Ipv4RoutingTableEntry::CreateNetworkRouteTo (Ipv4Address network,
- Ipv4Mask networkMask,
- uint32_t interface)
-{
- return Ipv4RoutingTableEntry (network, networkMask,
- interface);
-}
-Ipv4RoutingTableEntry
-Ipv4RoutingTableEntry::CreateDefaultRoute (Ipv4Address nextHop,
- uint32_t interface)
-{
- return Ipv4RoutingTableEntry (Ipv4Address::GetZero (), nextHop, interface);
-}
-
-
-std::ostream& operator<< (std::ostream& os, Ipv4RoutingTableEntry const& route)
-{
- if (route.IsDefault ())
- {
- NS_ASSERT (route.IsGateway ());
- os << "default out=" << route.GetInterface () << ", next hop=" << route.GetGateway ();
- }
- else if (route.IsHost ())
- {
- if (route.IsGateway ())
- {
- os << "host="<< route.GetDest () <<
- ", out=" << route.GetInterface () <<
- ", next hop=" << route.GetGateway ();
- }
- else
- {
- os << "host="<< route.GetDest () <<
- ", out=" << route.GetInterface ();
- }
- }
- else if (route.IsNetwork ())
- {
- if (route.IsGateway ())
- {
- os << "network=" << route.GetDestNetwork () <<
- ", mask=" << route.GetDestNetworkMask () <<
- ",out=" << route.GetInterface () <<
- ", next hop=" << route.GetGateway ();
- }
- else
- {
- os << "network=" << route.GetDestNetwork () <<
- ", mask=" << route.GetDestNetworkMask () <<
- ",out=" << route.GetInterface ();
- }
- }
- else
- {
- NS_ASSERT (false);
- }
- return os;
-}
-
-/*****************************************************
- * Ipv4MulticastRoutingTableEntry
- *****************************************************/
-
-Ipv4MulticastRoutingTableEntry::Ipv4MulticastRoutingTableEntry ()
-{
-}
-
-Ipv4MulticastRoutingTableEntry::Ipv4MulticastRoutingTableEntry (Ipv4MulticastRoutingTableEntry const &route)
-:
- m_origin (route.m_origin),
- m_group (route.m_group),
- m_inputInterface (route.m_inputInterface),
- m_outputInterfaces (route.m_outputInterfaces)
-{
-}
-
-Ipv4MulticastRoutingTableEntry::Ipv4MulticastRoutingTableEntry (Ipv4MulticastRoutingTableEntry const *route)
-:
- m_origin (route->m_origin),
- m_group (route->m_group),
- m_inputInterface (route->m_inputInterface),
- m_outputInterfaces (route->m_outputInterfaces)
-{
-}
-
-Ipv4MulticastRoutingTableEntry::Ipv4MulticastRoutingTableEntry (
- Ipv4Address origin,
- Ipv4Address group,
- uint32_t inputInterface,
- std::vector<uint32_t> outputInterfaces)
-{
- m_origin = origin;
- m_group = group;
- m_inputInterface = inputInterface;
- m_outputInterfaces = outputInterfaces;
-}
-
-Ipv4Address
-Ipv4MulticastRoutingTableEntry::GetOrigin (void) const
-{
- return m_origin;
-}
-
-Ipv4Address
-Ipv4MulticastRoutingTableEntry::GetGroup (void) const
-{
- return m_group;
-}
-
-uint32_t
-Ipv4MulticastRoutingTableEntry::GetInputInterface (void) const
-{
- return m_inputInterface;
-}
-
-uint32_t
-Ipv4MulticastRoutingTableEntry::GetNOutputInterfaces (void) const
-{
- return m_outputInterfaces.size ();
-}
-
-uint32_t
-Ipv4MulticastRoutingTableEntry::GetOutputInterface (uint32_t n) const
-{
- NS_ASSERT_MSG(n < m_outputInterfaces.size (),
- "Ipv4MulticastRoutingTableEntry::GetOutputInterface (): index out of bounds");
-
- return m_outputInterfaces[n];
-}
-
-std::vector<uint32_t>
-Ipv4MulticastRoutingTableEntry::GetOutputInterfaces (void) const
-{
- return m_outputInterfaces;
-}
-
-Ipv4MulticastRoutingTableEntry
-Ipv4MulticastRoutingTableEntry::CreateMulticastRoute (
- Ipv4Address origin,
- Ipv4Address group,
- uint32_t inputInterface,
- std::vector<uint32_t> outputInterfaces)
-{
- return Ipv4MulticastRoutingTableEntry (origin, group, inputInterface, outputInterfaces);
-}
-
-std::ostream&
-operator<< (std::ostream& os, Ipv4MulticastRoutingTableEntry const& route)
-{
- os << "origin=" << route.GetOrigin () <<
- ", group=" << route.GetGroup () <<
- ", input interface=" << route.GetInputInterface () <<
- ", output interfaces=";
-
- for (uint32_t i = 0; i < route.GetNOutputInterfaces (); ++i)
- {
- os << route.GetOutputInterface (i) << " ";
-
- }
-
- return os;
-}
-
-}//namespace ns3
--- a/src/routing/static-routing/ipv4-routing-table-entry.h Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,231 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef IPV4_ROUTING_TABLE_ENTRY_H
-#define IPV4_ROUTING_TABLE_ENTRY_H
-
-#include <list>
-#include <vector>
-#include <ostream>
-
-#include "ns3/ipv4-address.h"
-
-namespace ns3 {
-
-/**
- * \ingroup routing
- *
- * A record of an IPv4 routing table entry for Ipv4GlobalRouting and
- * Ipv4StaticRouting. This is not a reference counted object.
- */
-class Ipv4RoutingTableEntry {
-public:
- /**
- * \brief This constructor does nothing
- */
- Ipv4RoutingTableEntry ();
- /**
- * \brief Copy Constructor
- * \param route The route to copy
- */
- Ipv4RoutingTableEntry (Ipv4RoutingTableEntry const &route);
- /**
- * \brief Copy Constructor
- * \param route The route to copy
- */
- Ipv4RoutingTableEntry (Ipv4RoutingTableEntry const *route);
- /**
- * \return True if this route is a host route (mask of all ones); false otherwise
- */
- bool IsHost (void) const;
- /**
- * \return True if this route is not a host route (mask is not all ones); false otherwise
- *
- * This method is implemented as !IsHost ().
- */
- bool IsNetwork (void) const;
- /**
- * \return True if this route is a default route; false otherwise
- */
- bool IsDefault (void) const;
- /**
- * \return True if this route is a gateway route; false otherwise
- */
- bool IsGateway (void) const;
- /**
- * \return address of the gateway stored in this entry
- */
- Ipv4Address GetGateway (void) const;
- /**
- * \return The IPv4 address of the destination of this route
- */
- Ipv4Address GetDest (void) const;
- /**
- * \return The IPv4 network number of the destination of this route
- */
- Ipv4Address GetDestNetwork (void) const;
- /**
- * \return The IPv4 network mask of the destination of this route
- */
- Ipv4Mask GetDestNetworkMask (void) const;
- /**
- * \return The Ipv4 interface number used for sending outgoing packets
- */
- uint32_t GetInterface (void) const;
- /**
- * \return An Ipv4RoutingTableEntry object corresponding to the input parameters.
- * \param dest Ipv4Address of the destination
- * \param nextHop Ipv4Address of the next hop
- * \param interface Outgoing interface
- */
- static Ipv4RoutingTableEntry CreateHostRouteTo (Ipv4Address dest,
- Ipv4Address nextHop,
- uint32_t interface);
- /**
- * \return An Ipv4RoutingTableEntry object corresponding to the input parameters.
- * \param dest Ipv4Address of the destination
- * \param interface Outgoing interface
- */
- static Ipv4RoutingTableEntry CreateHostRouteTo (Ipv4Address dest,
- uint32_t interface);
- /**
- * \return An Ipv4RoutingTableEntry object corresponding to the input parameters.
- * \param network Ipv4Address of the destination network
- * \param networkMask Ipv4Mask of the destination network mask
- * \param nextHop Ipv4Address of the next hop
- * \param interface Outgoing interface
- */
- static Ipv4RoutingTableEntry CreateNetworkRouteTo (Ipv4Address network,
- Ipv4Mask networkMask,
- Ipv4Address nextHop,
- uint32_t interface);
- /**
- * \return An Ipv4RoutingTableEntry object corresponding to the input parameters.
- * \param network Ipv4Address of the destination network
- * \param networkMask Ipv4Mask of the destination network mask
- * \param interface Outgoing interface
- */
- static Ipv4RoutingTableEntry CreateNetworkRouteTo (Ipv4Address network,
- Ipv4Mask networkMask,
- uint32_t interface);
- /**
- * \return An Ipv4RoutingTableEntry object corresponding to the input
- * parameters. This route is distinguished; it will match any
- * destination for which a more specific route does not exist.
- * \param nextHop Ipv4Address of the next hop
- * \param interface Outgoing interface
- */
- static Ipv4RoutingTableEntry CreateDefaultRoute (Ipv4Address nextHop,
- uint32_t interface);
-
-private:
- Ipv4RoutingTableEntry (Ipv4Address network,
- Ipv4Mask mask,
- Ipv4Address gateway,
- uint32_t interface);
- Ipv4RoutingTableEntry (Ipv4Address dest,
- Ipv4Mask mask,
- uint32_t interface);
- Ipv4RoutingTableEntry (Ipv4Address dest,
- Ipv4Address gateway,
- uint32_t interface);
- Ipv4RoutingTableEntry (Ipv4Address dest,
- uint32_t interface);
-
- Ipv4Address m_dest;
- Ipv4Mask m_destNetworkMask;
- Ipv4Address m_gateway;
- uint32_t m_interface;
-};
-
-std::ostream& operator<< (std::ostream& os, Ipv4RoutingTableEntry const& route);
-
-/**
- * \ingroup routing
- *
- * \brief A record of an IPv4 multicast route for Ipv4GlobalRouting and Ipv4StaticRouting
- */
-class Ipv4MulticastRoutingTableEntry {
-public:
- /**
- * \brief This constructor does nothing
- */
- Ipv4MulticastRoutingTableEntry ();
-
- /**
- * \brief Copy Constructor
- * \param route The route to copy
- */
- Ipv4MulticastRoutingTableEntry (Ipv4MulticastRoutingTableEntry const &route);
- /**
- * \brief Copy Constructor
- * \param route The route to copy
- */
- Ipv4MulticastRoutingTableEntry (Ipv4MulticastRoutingTableEntry const *route);
- /**
- * \return The IPv4 address of the source of this route
- */
- Ipv4Address GetOrigin (void) const;
- /**
- * \return The IPv4 address of the multicast group of this route
- */
- Ipv4Address GetGroup (void) const;
- /**
- * \return The IPv4 address of the input interface of this route
- */
- uint32_t GetInputInterface (void) const;
- /**
- * \return The number of output interfaces of this route
- */
- uint32_t GetNOutputInterfaces (void) const;
- /**
- * \param n interface index
- * \return A specified output interface.
- */
- uint32_t GetOutputInterface (uint32_t n) const;
- /**
- * \return A vector of all of the output interfaces of this route.
- */
- std::vector<uint32_t> GetOutputInterfaces (void) const;
- /**
- * \return Ipv4MulticastRoutingTableEntry corresponding to the input parameters.
- * \param origin Source address for the multicast route
- * \param group Group destination address for the multicast route
- * \param inputInterface Input interface that multicast datagram must be received on
- * \param outputInterfaces vector of output interfaces to copy and forward the datagram to
- */
- static Ipv4MulticastRoutingTableEntry CreateMulticastRoute (Ipv4Address origin,
- Ipv4Address group, uint32_t inputInterface,
- std::vector<uint32_t> outputInterfaces);
-
-private:
- Ipv4MulticastRoutingTableEntry (Ipv4Address origin, Ipv4Address group,
- uint32_t inputInterface, std::vector<uint32_t> outputInterfaces);
-
- Ipv4Address m_origin;
- Ipv4Address m_group;
- uint32_t m_inputInterface;
- std::vector<uint32_t> m_outputInterfaces;
-};
-
-std::ostream& operator<< (std::ostream& os, Ipv4MulticastRoutingTableEntry const& route);
-
-}//namespace ns3
-
-#endif /* IPV4_ROUTING_TABLE_ENTRY_H */
--- a/src/routing/static-routing/ipv4-static-routing.cc Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,729 +0,0 @@
-// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-// Gustavo Carneiro <gjc@inescporto.pt>
-
-#define NS_LOG_APPEND_CONTEXT \
- if (m_ipv4 && m_ipv4->GetObject<Node> ()) { \
- std::clog << Simulator::Now ().GetSeconds () \
- << " [node " << m_ipv4->GetObject<Node> ()->GetId () << "] "; }
-
-#include "ns3/log.h"
-#include "ns3/packet.h"
-#include "ns3/node.h"
-#include "ns3/simulator.h"
-#include "ns3/ipv4-route.h"
-#include "ipv4-static-routing.h"
-#include "ipv4-routing-table-entry.h"
-
-NS_LOG_COMPONENT_DEFINE ("Ipv4StaticRouting");
-
-using std::make_pair;
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (Ipv4StaticRouting);
-
-TypeId
-Ipv4StaticRouting::GetTypeId (void)
-{
- static TypeId tid = TypeId ("ns3::Ipv4StaticRouting")
- .SetParent<Ipv4RoutingProtocol> ()
- .AddConstructor<Ipv4StaticRouting> ()
- ;
- return tid;
-}
-
-Ipv4StaticRouting::Ipv4StaticRouting ()
-: m_ipv4 (0)
-{
- NS_LOG_FUNCTION (this);
-}
-
-void
-Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network,
- Ipv4Mask networkMask,
- Ipv4Address nextHop,
- uint32_t interface,
- uint32_t metric)
-{
- NS_LOG_FUNCTION (this << network << " " << networkMask << " " << nextHop << " " << interface << " " << metric);
- Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
- *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
- networkMask,
- nextHop,
- interface);
- m_networkRoutes.push_back (make_pair(route,metric));
-}
-
-void
-Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network,
- Ipv4Mask networkMask,
- uint32_t interface,
- uint32_t metric)
-{
- NS_LOG_FUNCTION (this << network << " " << networkMask << " " << interface << " " << metric);
- Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
- *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
- networkMask,
- interface);
- m_networkRoutes.push_back (make_pair (route,metric));
-}
-
-void
-Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest,
- Ipv4Address nextHop,
- uint32_t interface,
- uint32_t metric)
-{
- NS_LOG_FUNCTION (this << dest << " " << nextHop << " " << interface << " " << metric);
- AddNetworkRouteTo (dest, Ipv4Mask::GetOnes (), nextHop, interface, metric);
-}
-
-void
-Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest,
- uint32_t interface,
- uint32_t metric)
-{
- NS_LOG_FUNCTION (this << dest << " " << interface << " " << metric);
- AddNetworkRouteTo (dest, Ipv4Mask::GetOnes (), interface, metric);
-}
-
-void
-Ipv4StaticRouting::SetDefaultRoute (Ipv4Address nextHop,
- uint32_t interface,
- uint32_t metric)
-{
- NS_LOG_FUNCTION (this << nextHop << " " << interface << " " << metric);
- AddNetworkRouteTo (Ipv4Address ("0.0.0.0"), Ipv4Mask::GetZero (), nextHop, interface, metric);
-}
-
-void
-Ipv4StaticRouting::AddMulticastRoute(Ipv4Address origin,
- Ipv4Address group,
- uint32_t inputInterface,
- std::vector<uint32_t> outputInterfaces)
-{
- NS_LOG_FUNCTION (this << origin << " " << group << " " << inputInterface);
- Ipv4MulticastRoutingTableEntry *route = new Ipv4MulticastRoutingTableEntry ();
- *route = Ipv4MulticastRoutingTableEntry::CreateMulticastRoute (origin, group,
- inputInterface, outputInterfaces);
- m_multicastRoutes.push_back (route);
-}
-
-// default multicast routes are stored as a network route
-// these routes are _not_ consulted in the forwarding process-- only
-// for originating packets
-void
-Ipv4StaticRouting::SetDefaultMulticastRoute(uint32_t outputInterface)
-{
- NS_LOG_FUNCTION (this << outputInterface);
- Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
- Ipv4Address network = Ipv4Address ("224.0.0.0");
- Ipv4Mask networkMask = Ipv4Mask ("240.0.0.0");
- *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
- networkMask,
- outputInterface);
- m_networkRoutes.push_back (make_pair(route,0));
-}
-
-uint32_t
-Ipv4StaticRouting::GetNMulticastRoutes (void) const
-{
- NS_LOG_FUNCTION (this);
- return m_multicastRoutes.size ();
-}
-
-Ipv4MulticastRoutingTableEntry
-Ipv4StaticRouting::GetMulticastRoute (uint32_t index) const
-{
- NS_LOG_FUNCTION (this << index);
- NS_ASSERT_MSG(index < m_multicastRoutes.size (),
- "Ipv4StaticRouting::GetMulticastRoute (): Index out of range");
-
- if (index < m_multicastRoutes.size ())
- {
- uint32_t tmp = 0;
- for (MulticastRoutesCI i = m_multicastRoutes.begin ();
- i != m_multicastRoutes.end ();
- i++)
- {
- if (tmp == index)
- {
- return *i;
- }
- tmp++;
- }
- }
- return 0;
-}
-
-bool
-Ipv4StaticRouting::RemoveMulticastRoute(Ipv4Address origin,
- Ipv4Address group,
- uint32_t inputInterface)
-{
- NS_LOG_FUNCTION (this << origin << " " << group << " " << inputInterface);
- for (MulticastRoutesI i = m_multicastRoutes.begin ();
- i != m_multicastRoutes.end ();
- i++)
- {
- Ipv4MulticastRoutingTableEntry *route = *i;
- if (origin == route->GetOrigin () &&
- group == route->GetGroup () &&
- inputInterface == route->GetInputInterface ())
- {
- delete *i;
- m_multicastRoutes.erase (i);
- return true;
- }
- }
- return false;
-}
-
-void
-Ipv4StaticRouting::RemoveMulticastRoute(uint32_t index)
-{
- NS_LOG_FUNCTION (this << index);
- uint32_t tmp = 0;
- for (MulticastRoutesI i = m_multicastRoutes.begin ();
- i != m_multicastRoutes.end ();
- i++)
- {
- if (tmp == index)
- {
- delete *i;
- m_multicastRoutes.erase (i);
- return;
- }
- tmp++;
- }
-}
-
-Ptr<Ipv4Route>
-Ipv4StaticRouting::LookupStatic (Ipv4Address dest, Ptr<NetDevice> oif)
-{
- NS_LOG_FUNCTION (this << dest << " " << oif);
- Ptr<Ipv4Route> rtentry = 0;
- uint16_t longest_mask = 0;
- uint32_t shortest_metric = 0xffffffff;
- /* when sending on local multicast, there have to be interface specified */
- if (dest.IsLocalMulticast ())
- {
- NS_ASSERT_MSG (oif, "Try to send on link-local multicast address, and no interface index is given!");
-
- rtentry = Create<Ipv4Route> ();
- rtentry->SetDestination (dest);
- rtentry->SetGateway (Ipv4Address::GetZero ());
- rtentry->SetOutputDevice (oif);
- rtentry->SetSource (m_ipv4->GetAddress (oif->GetIfIndex (), 0).GetLocal ());
- return rtentry;
- }
-
-
- for (NetworkRoutesI i = m_networkRoutes.begin ();
- i != m_networkRoutes.end ();
- i++)
- {
- Ipv4RoutingTableEntry *j=i->first;
- uint32_t metric =i->second;
- Ipv4Mask mask = (j)->GetDestNetworkMask ();
- uint16_t masklen = mask.GetPrefixLength ();
- Ipv4Address entry = (j)->GetDestNetwork ();
- NS_LOG_LOGIC ("Searching for route to " << dest << ", checking against route to " << entry << "/" << masklen);
- if (mask.IsMatch (dest, entry))
- {
- NS_LOG_LOGIC ("Found global network route " << j << ", mask length " << masklen << ", metric " << metric);
- if (oif != 0)
- {
- if (oif != m_ipv4->GetNetDevice (j->GetInterface ()))
- {
- NS_LOG_LOGIC ("Not on requested interface, skipping");
- continue;
- }
- }
- if (masklen < longest_mask) // Not interested if got shorter mask
- {
- NS_LOG_LOGIC ("Previous match longer, skipping");
- continue;
- }
- if (masklen > longest_mask) // Reset metric if longer masklen
- {
- shortest_metric = 0xffffffff;
- }
- longest_mask = masklen;
- if (metric > shortest_metric)
- {
- NS_LOG_LOGIC ("Equal mask length, but previous metric shorter, skipping");
- continue;
- }
- shortest_metric = metric;
- Ipv4RoutingTableEntry* route = (j);
- uint32_t interfaceIdx = route->GetInterface ();
- rtentry = Create<Ipv4Route> ();
- rtentry->SetDestination (route->GetDest ());
- rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetDest ()));
- rtentry->SetGateway (route->GetGateway ());
- rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
- }
- }
- if (rtentry != 0)
- {
- NS_LOG_LOGIC ("Matching route via " << rtentry->GetGateway () << " at the end");
- }
- else
- {
- NS_LOG_LOGIC ("No matching route to " << dest << " found");
- }
- return rtentry;
-}
-
-Ptr<Ipv4MulticastRoute>
-Ipv4StaticRouting::LookupStatic (
- Ipv4Address origin,
- Ipv4Address group,
- uint32_t interface)
-{
- NS_LOG_FUNCTION (this << origin << " " << group << " " << interface);
- Ptr<Ipv4MulticastRoute> mrtentry = 0;
-
- for (MulticastRoutesI i = m_multicastRoutes.begin ();
- i != m_multicastRoutes.end ();
- i++)
- {
- Ipv4MulticastRoutingTableEntry *route = *i;
-//
-// We've been passed an origin address, a multicast group address and an
-// interface index. We have to decide if the current route in the list is
-// a match.
-//
-// The first case is the restrictive case where the origin, group and index
-// matches.
-//
- if (origin == route->GetOrigin () && group == route->GetGroup ())
- {
- // Skipping this case (SSM) for now
- NS_LOG_LOGIC ("Found multicast source specific route" << *i);
- }
- if (group == route->GetGroup ())
- {
- if (interface == Ipv4::IF_ANY ||
- interface == route->GetInputInterface ())
- {
- NS_LOG_LOGIC ("Found multicast route" << *i);
- mrtentry = Create<Ipv4MulticastRoute> ();
- mrtentry->SetGroup (route->GetGroup ());
- mrtentry->SetOrigin (route->GetOrigin ());
- mrtentry->SetParent (route->GetInputInterface ());
- for (uint32_t j = 0; j < route->GetNOutputInterfaces (); j++)
- {
- if (route->GetOutputInterface (j))
- {
- NS_LOG_LOGIC ("Setting output interface index " << route->GetOutputInterface (j));
- mrtentry->SetOutputTtl (route->GetOutputInterface (j), Ipv4MulticastRoute::MAX_TTL - 1);
- }
- }
- return mrtentry;
- }
- }
- }
- return mrtentry;
-}
-
-uint32_t
-Ipv4StaticRouting::GetNRoutes (void)
-{
- NS_LOG_FUNCTION (this);
- return m_networkRoutes.size ();;
-}
-
-Ipv4RoutingTableEntry
-Ipv4StaticRouting::GetDefaultRoute ()
-{
- NS_LOG_FUNCTION (this);
- // Basically a repeat of LookupStatic, retained for backward compatibility
- Ipv4Address dest ("0.0.0.0");
- uint32_t shortest_metric = 0xffffffff;
- Ipv4RoutingTableEntry *result = 0;
- for (NetworkRoutesI i = m_networkRoutes.begin ();
- i != m_networkRoutes.end ();
- i++)
- {
- Ipv4RoutingTableEntry *j = i->first;
- uint32_t metric = i->second;
- Ipv4Mask mask = (j)->GetDestNetworkMask ();
- uint16_t masklen = mask.GetPrefixLength ();
- Ipv4Address entry = (j)->GetDestNetwork ();
- if (masklen != 0)
- {
- continue;
- }
- if (metric > shortest_metric)
- {
- continue;
- }
- shortest_metric = metric;
- result = j;
- }
- if (result)
- {
- return result;
- }
- else
- {
- return Ipv4RoutingTableEntry ();
- }
-}
-
-Ipv4RoutingTableEntry
-Ipv4StaticRouting::GetRoute (uint32_t index)
-{
- NS_LOG_FUNCTION (this << index);
- uint32_t tmp = 0;
- for (NetworkRoutesI j = m_networkRoutes.begin ();
- j != m_networkRoutes.end ();
- j++)
- {
- if (tmp == index)
- {
- return j->first;
- }
- tmp++;
- }
- NS_ASSERT (false);
- // quiet compiler.
- return 0;
-}
-
-uint32_t
-Ipv4StaticRouting::GetMetric (uint32_t index)
-{
- NS_LOG_FUNCTION (this << index);
- uint32_t tmp = 0;
- for (NetworkRoutesI j = m_networkRoutes.begin ();
- j != m_networkRoutes.end ();
- j++)
- {
- if (tmp == index)
- {
- return j->second;
- }
- tmp++;
- }
- NS_ASSERT (false);
- // quiet compiler.
- return 0;
-}
-void
-Ipv4StaticRouting::RemoveRoute (uint32_t index)
-{
- NS_LOG_FUNCTION (this << index);
- uint32_t tmp = 0;
- for (NetworkRoutesI j = m_networkRoutes.begin ();
- j != m_networkRoutes.end ();
- j++)
- {
- if (tmp == index)
- {
- delete j->first;
- m_networkRoutes.erase (j);
- return;
- }
- tmp++;
- }
- NS_ASSERT (false);
-}
-
-Ptr<Ipv4Route>
-Ipv4StaticRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
-{
- NS_LOG_FUNCTION (this << header << oif);
- Ipv4Address destination = header.GetDestination ();
- Ptr<Ipv4Route> rtentry = 0;
-
- // Multicast goes here
- if (destination.IsMulticast ())
- {
- // Note: Multicast routes for outbound packets are stored in the
- // normal unicast table. An implication of this is that it is not
- // possible to source multicast datagrams on multiple interfaces.
- // This is a well-known property of sockets implementation on
- // many Unix variants.
- // So, we just log it and fall through to LookupStatic ()
- NS_LOG_LOGIC ("RouteOutput()::Multicast destination");
- }
- rtentry = LookupStatic (destination, oif);
- if (rtentry)
- {
- sockerr = Socket::ERROR_NOTERROR;
- }
- else
- {
- sockerr = Socket::ERROR_NOROUTETOHOST;
- }
- return rtentry;
-}
-
-bool
-Ipv4StaticRouting::RouteInput (Ptr<const Packet> p, const Ipv4Header &ipHeader, Ptr<const NetDevice> idev,
- UnicastForwardCallback ucb, MulticastForwardCallback mcb,
- LocalDeliverCallback lcb, ErrorCallback ecb)
-{
- NS_LOG_FUNCTION (this << p << ipHeader << ipHeader.GetSource () << ipHeader.GetDestination () << idev);
-
- NS_ASSERT (m_ipv4 != 0);
- // Check if input device supports IP
- NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
- uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
-
- // Multicast recognition; handle local delivery here
- //
- if (ipHeader.GetDestination ().IsMulticast ())
- {
- NS_LOG_LOGIC ("Multicast destination");
- Ptr<Ipv4MulticastRoute> mrtentry = LookupStatic(ipHeader.GetSource (),
- ipHeader.GetDestination (), m_ipv4->GetInterfaceForDevice (idev));
-
- if (mrtentry)
- {
- NS_LOG_LOGIC ("Multicast route found");
- mcb (mrtentry, p, ipHeader); // multicast forwarding callback
- return true;
- }
- else
- {
- NS_LOG_LOGIC ("Multicast route not found");
- return false; // Let other routing protocols try to handle this
- }
- }
- if (ipHeader.GetDestination ().IsBroadcast ())
- {
- NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)");
- // TODO: Local Deliver for broadcast
- // TODO: Forward broadcast
- }
-
- NS_LOG_LOGIC ("Unicast destination");
- // TODO: Configurable option to enable RFC 1222 Strong End System Model
- // Right now, we will be permissive and allow a source to send us
- // a packet to one of our other interface addresses; that is, the
- // destination unicast address does not match one of the iif addresses,
- // but we check our other interfaces. This could be an option
- // (to remove the outer loop immediately below and just check iif).
- for (uint32_t j = 0; j < m_ipv4->GetNInterfaces (); j++)
- {
- for (uint32_t i = 0; i < m_ipv4->GetNAddresses (j); i++)
- {
- Ipv4InterfaceAddress iaddr = m_ipv4->GetAddress (j, i);
- Ipv4Address addr = iaddr.GetLocal ();
- if (addr.IsEqual (ipHeader.GetDestination ()))
- {
- if (j == iif)
- {
- NS_LOG_LOGIC ("For me (destination " << addr << " match)");
- }
- else
- {
- NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << ipHeader.GetDestination ());
- }
- lcb (p, ipHeader, iif);
- return true;
- }
- if (ipHeader.GetDestination ().IsEqual (iaddr.GetBroadcast ()))
- {
- NS_LOG_LOGIC ("For me (interface broadcast address)");
- lcb (p, ipHeader, iif);
- return true;
- }
- NS_LOG_LOGIC ("Address "<< addr << " not a match");
- }
- }
- // Check if input device supports IP forwarding
- if (m_ipv4->IsForwarding (iif) == false)
- {
- NS_LOG_LOGIC ("Forwarding disabled for this interface");
- ecb (p, ipHeader, Socket::ERROR_NOROUTETOHOST);
- return false;
- }
- // Next, try to find a route
- Ptr<Ipv4Route> rtentry = LookupStatic (ipHeader.GetDestination ());
- if (rtentry != 0)
- {
- NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
- ucb (rtentry, p, ipHeader); // unicast forwarding callback
- return true;
- }
- else
- {
- NS_LOG_LOGIC ("Did not find unicast destination- returning false");
- return false; // Let other routing protocols try to handle this
- }
-}
-
-Ipv4StaticRouting::~Ipv4StaticRouting ()
-{
-}
-
-void
-Ipv4StaticRouting::DoDispose (void)
-{
- for (NetworkRoutesI j = m_networkRoutes.begin ();
- j != m_networkRoutes.end ();
- j = m_networkRoutes.erase (j))
- {
- delete (j->first);
- }
- for (MulticastRoutesI i = m_multicastRoutes.begin ();
- i != m_multicastRoutes.end ();
- i = m_multicastRoutes.erase (i))
- {
- delete (*i);
- }
- m_ipv4 = 0;
- Ipv4RoutingProtocol::DoDispose ();
-}
-
-void
-Ipv4StaticRouting::NotifyInterfaceUp (uint32_t i)
-{
- NS_LOG_FUNCTION (this << i);
- // If interface address and network mask have been set, add a route
- // to the network of the interface (like e.g. ifconfig does on a
- // Linux box)
- for (uint32_t j = 0; j < m_ipv4->GetNAddresses (i); j++)
- {
- if (m_ipv4->GetAddress (i,j).GetLocal () != Ipv4Address () &&
- m_ipv4->GetAddress (i,j).GetMask () != Ipv4Mask () &&
- m_ipv4->GetAddress (i,j).GetMask () != Ipv4Mask::GetOnes())
- {
- AddNetworkRouteTo (m_ipv4->GetAddress (i,j).GetLocal ().CombineMask (m_ipv4->GetAddress (i,j).GetMask ()),
- m_ipv4->GetAddress (i,j).GetMask (), i);
- }
- }
-}
-
-void
-Ipv4StaticRouting::NotifyInterfaceDown (uint32_t i)
-{
- NS_LOG_FUNCTION (this << i);
- // Remove all static routes that are going through this interface
- uint32_t j = 0;
- while (j < GetNRoutes())
- {
- Ipv4RoutingTableEntry route = GetRoute (j);
- if (route.GetInterface () == i)
- {
- RemoveRoute (j);
- }
- else
- {
- j++;
- }
- }
-}
-
-void
-Ipv4StaticRouting::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)
-{
- NS_LOG_FUNCTION (this << interface << " " << address.GetLocal());
- if (!m_ipv4->IsUp (interface))
- {
- return;
- }
-
- Ipv4Address networkAddress = address.GetLocal ().CombineMask (address.GetMask ());
- Ipv4Mask networkMask = address.GetMask ();
- if (address.GetLocal () != Ipv4Address () &&
- address.GetMask () != Ipv4Mask ())
- {
- AddNetworkRouteTo (networkAddress,
- networkMask, interface);
- }
-}
-void
-Ipv4StaticRouting::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)
-{
- NS_LOG_FUNCTION (this << interface << " " << address.GetLocal());
- if (!m_ipv4->IsUp (interface))
- {
- return;
- }
- Ipv4Address networkAddress = address.GetLocal ().CombineMask (address.GetMask ());
- Ipv4Mask networkMask = address.GetMask ();
- // Remove all static routes that are going through this interface
- // which reference this network
- for (uint32_t j = 0; j < GetNRoutes (); j++)
- {
- Ipv4RoutingTableEntry route = GetRoute (j);
- if (route.GetInterface () == interface &&
- route.IsNetwork () &&
- route.GetDestNetwork () == networkAddress &&
- route.GetDestNetworkMask () == networkMask)
- {
- RemoveRoute (j);
- }
- }
-}
-
-void
-Ipv4StaticRouting::SetIpv4 (Ptr<Ipv4> ipv4)
-{
- NS_LOG_FUNCTION (this << ipv4);
- NS_ASSERT (m_ipv4 == 0 && ipv4 != 0);
- m_ipv4 = ipv4;
- for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
- {
- if (m_ipv4->IsUp (i))
- {
- NotifyInterfaceUp (i);
- }
- else
- {
- NotifyInterfaceDown (i);
- }
- }
-}
-
-Ipv4Address
-Ipv4StaticRouting::SourceAddressSelection (uint32_t interfaceIdx, Ipv4Address dest)
-{
- NS_LOG_FUNCTION (this << interfaceIdx << " " << dest);
- if (m_ipv4->GetNAddresses (interfaceIdx) == 1) // common case
- {
- return m_ipv4->GetAddress (interfaceIdx, 0).GetLocal ();
- }
- // no way to determine the scope of the destination, so adopt the
- // following rule: pick the first available address (index 0) unless
- // a subsequent address is on link (in which case, pick the primary
- // address if there are multiple)
- Ipv4Address candidate = m_ipv4->GetAddress (interfaceIdx, 0).GetLocal ();
- for (uint32_t i = 0; i < m_ipv4->GetNAddresses (interfaceIdx); i++)
- {
- Ipv4InterfaceAddress test = m_ipv4->GetAddress (interfaceIdx, i);
- if (test.GetLocal ().CombineMask (test.GetMask ()) == dest.CombineMask (test.GetMask ()))
- {
- if (test.IsSecondary () == false)
- {
- return test.GetLocal ();
- }
- }
- }
- return candidate;
-}
-
-}//namespace ns3
--- a/src/routing/static-routing/ipv4-static-routing.h Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,399 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 Georgia Tech Research Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: George F. Riley<riley@ece.gatech.edu>
- * Gustavo Carneiro <gjc@inescporto.pt>
- */
-
-#ifndef IPV4_STATIC_ROUTING_H
-#define IPV4_STATIC_ROUTING_H
-
-#include <list>
-#include <utility>
-#include <stdint.h>
-#include "ns3/ipv4-address.h"
-#include "ns3/ipv4-header.h"
-#include "ns3/socket.h"
-#include "ns3/ptr.h"
-#include "ns3/ipv4.h"
-#include "ns3/ipv4-routing-protocol.h"
-
-namespace ns3 {
-
-class Packet;
-class NetDevice;
-class Ipv4Interface;
-class Ipv4Address;
-class Ipv4Header;
-class Ipv4RoutingTableEntry;
-class Ipv4MulticastRoutingTableEntry;
-class Node;
-
-/**
- * \ingroup routing
- * \defgroup ipv4StaticRouting Ipv4StaticRouting
- */
-/**
- * \ingroup ipv4StaticRouting
- *
- * \brief Static routing protocol for IP version 4 stacks.
- *
- * This class provides a basic set of methods for inserting static
- * unicast and multicast routes into the Ipv4 routing system.
- * This particular protocol is designed to be inserted into an
- * Ipv4ListRouting protocol but can be used also as a standalone
- * protocol.
- *
- * The Ipv4StaticRouting class inherits from the abstract base class
- * Ipv4RoutingProtocol that defines the interface methods that a routing
- * protocol must support.
- *
- * \see Ipv4RoutingProtocol
- * \see Ipv4ListRouting
- * \see Ipv4ListRouting::AddRoutingProtocol
- */
-class Ipv4StaticRouting : public Ipv4RoutingProtocol
-{
-public:
- static TypeId GetTypeId (void);
-
- Ipv4StaticRouting ();
- virtual ~Ipv4StaticRouting ();
-
- 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,
- UnicastForwardCallback ucb, MulticastForwardCallback mcb,
- LocalDeliverCallback lcb, ErrorCallback ecb);
-
- virtual void NotifyInterfaceUp (uint32_t interface);
- virtual void NotifyInterfaceDown (uint32_t interface);
- virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
- virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
- virtual void SetIpv4 (Ptr<Ipv4> ipv4);
-
-/**
- * \brief Add a network route to the static routing table.
- *
- * \param network The Ipv4Address network for this route.
- * \param networkMask The Ipv4Mask to extract the network.
- * \param nextHop The next hop in the route to the destination network.
- * \param interface The network interface index used to send packets to the
- * destination.
- * \param metric Metric of route in case of multiple routes to same destination
- *
- * \see Ipv4Address
- */
- void AddNetworkRouteTo (Ipv4Address network,
- Ipv4Mask networkMask,
- Ipv4Address nextHop,
- uint32_t interface,
- uint32_t metric = 0);
-
-/**
- * \brief Add a network route to the static routing table.
- *
- * \param network The Ipv4Address network for this route.
- * \param networkMask The Ipv4Mask to extract the network.
- * \param interface The network interface index used to send packets to the
- * destination.
- * \param metric Metric of route in case of multiple routes to same destination
- *
- * \see Ipv4Address
- */
- void AddNetworkRouteTo (Ipv4Address network,
- Ipv4Mask networkMask,
- uint32_t interface,
- uint32_t metric = 0);
-
-/**
- * \brief Add a host route to the static routing table.
- *
- * \param dest The Ipv4Address destination for this route.
- * \param nextHop The Ipv4Address of the next hop in the route.
- * \param interface The network interface index used to send packets to the
- * destination.
- * \param metric Metric of route in case of multiple routes to same destination
- *
- * \see Ipv4Address
- */
- void AddHostRouteTo (Ipv4Address dest,
- Ipv4Address nextHop,
- uint32_t interface,
- uint32_t metric = 0);
-/**
- * \brief Add a host route to the static routing table.
- *
- * \param dest The Ipv4Address destination for this route.
- * \param interface The network interface index used to send packets to the
- * destination.
- * \param metric Metric of route in case of multiple routes to same destination
- *
- * \see Ipv4Address
- */
- void AddHostRouteTo (Ipv4Address dest,
- uint32_t interface,
- uint32_t metric = 0);
-/**
- * \brief Add a default route to the static routing table.
- *
- * This method tells the routing system what to do in the case where a specific
- * route to a destination is not found. The system forwards packets to the
- * specified node in the hope that it knows better how to route the packet.
- *
- * If the default route is set, it is returned as the selected route from
- * LookupStatic irrespective of destination address if no specific route is
- * found.
- *
- * \param nextHop The Ipv4Address to send packets to in the hope that they
- * will be forwarded correctly.
- * \param interface The network interface index used to send packets.
- * \param metric Metric of route in case of multiple routes to same destination
- *
- * \see Ipv4Address
- * \see Ipv4StaticRouting::Lookup
- */
- void SetDefaultRoute (Ipv4Address nextHop,
- uint32_t interface,
- uint32_t metric = 0);
-
-/**
- * \brief Get the number of individual unicast routes that have been added
- * to the routing table.
- *
- * \warning The default route counts as one of the routes.
- */
- uint32_t GetNRoutes (void);
-
-/**
- * \brief Get the default route with lowest metric from the static routing table.
- *
- * \return If the default route is set, a pointer to that Ipv4RoutingTableEntry is
- * returned, otherwise an empty routing table entry is returned.
-* If multiple default routes exist, the one with lowest metric is returned.
- *
- * \see Ipv4RoutingTableEntry
- */
- Ipv4RoutingTableEntry GetDefaultRoute (void);
-
-/**
- * \brief Get a route from the static unicast routing table.
- *
- * Externally, the unicast static routing table appears simply as a table with
- * n entries.
- *
- * \param i The index (into the routing table) of the route to retrieve.
- * \return If route is set, a pointer to that Ipv4RoutingTableEntry is returned, otherwise
- * a zero pointer is returned.
- *
- * \see Ipv4RoutingTableEntry
- * \see Ipv4StaticRouting::RemoveRoute
- */
- Ipv4RoutingTableEntry GetRoute (uint32_t i);
-
-/**
- * \brief Get a metric for route from the static unicast routing table.
- *
- * \param index The index (into the routing table) of the route to retrieve.
- * \return If route is set, the metric is returned. If not, an infinity metric (0xffffffff) is returned
- *
- */
- uint32_t GetMetric (uint32_t index);
-
-/**
- * \brief Remove a route from the static unicast routing table.
- *
- * Externally, the unicast static routing table appears simply as a table with
- * n entries.
- *
- * \param i The index (into the routing table) of the route to remove.
- *
- * \see Ipv4RoutingTableEntry
- * \see Ipv4StaticRouting::GetRoute
- * \see Ipv4StaticRouting::AddRoute
- */
- void RemoveRoute (uint32_t i);
-
-/**
- * \brief Add a multicast route to the static routing table.
- *
- * A multicast route must specify an origin IP address, a multicast group and
- * an input network interface index as conditions and provide a vector of
- * output network interface indices over which packets matching the conditions
- * are sent.
- *
- * Typically there are two main types of multicast routes: routes of the
- * first kind are used during forwarding. All of the conditions must be
- * explicitly provided. The second kind of routes are used to get packets off
- * of a local node. The difference is in the input interface. Routes for
- * forwarding will always have an explicit input interface specified. Routes
- * off of a node will always set the input interface to a wildcard specified
- * by the index Ipv4RoutingProtocol::INTERFACE_ANY.
- *
- * For routes off of a local node wildcards may be used in the origin and
- * multicast group addresses. The wildcard used for Ipv4Adresses is that
- * address returned by Ipv4Address::GetAny () -- typically "0.0.0.0". Usage
- * of a wildcard allows one to specify default behavior to varying degrees.
- *
- * For example, making the origin address a wildcard, but leaving the
- * multicast group specific allows one (in the case of a node with multiple
- * interfaces) to create different routes using different output interfaces
- * for each multicast group.
- *
- * If the origin and multicast addresses are made wildcards, you have created
- * essentially a default multicast address that can forward to multiple
- * interfaces. Compare this to the actual default multicast address that is
- * limited to specifying a single output interface for compatibility with
- * existing functionality in other systems.
- *
- * \param origin The Ipv4Address of the origin of packets for this route. May
- * be Ipv4Address:GetAny for open groups.
- * \param group The Ipv4Address of the multicast group or this route.
- * \param inputInterface The input network interface index over which to
- * expect packets destined for this route. May be
- * Ipv4RoutingProtocol::INTERFACE_ANY for packets of local origin.
- * \param outputInterfaces A vector of network interface indices used to specify
- * how to send packets to the destination(s).
- *
- * \see Ipv4Address
- */
- void AddMulticastRoute (Ipv4Address origin,
- Ipv4Address group,
- uint32_t inputInterface,
- std::vector<uint32_t> outputInterfaces);
-
-/**
- * \brief Add a default multicast route to the static routing table.
- *
- * This is the multicast equivalent of the unicast version SetDefaultRoute.
- * We tell the routing system what to do in the case where a specific route
- * to a destination multicast group is not found. The system forwards
- * packets out the specified interface in the hope that "something out there"
- * knows better how to route the packet. This method is only used in
- * initially sending packets off of a host. The default multicast route is
- * not consulted during forwarding -- exact routes must be specified using
- * AddMulticastRoute for that case.
- *
- * Since we're basically sending packets to some entity we think may know
- * better what to do, we don't pay attention to "subtleties" like origin
- * address, nor do we worry about forwarding out multiple interfaces. If the
- * default multicast route is set, it is returned as the selected route from
- * LookupStatic irrespective of origin or multicast group if another specific
- * route is not found.
- *
- * \param outputInterface The network interface index used to specify where
- * to send packets in the case of unknown routes.
- *
- * \see Ipv4Address
- */
- void SetDefaultMulticastRoute (uint32_t outputInterface);
-
-/**
- * \brief Get the number of individual multicast routes that have been added
- * to the routing table.
- *
- * \warning The default multicast route counts as one of the routes.
- */
- uint32_t GetNMulticastRoutes (void) const;
-
-/**
- * \brief Get a route from the static multicast routing table.
- *
- * Externally, the multicast static routing table appears simply as a table
- * with n entries.
- *
- * \param i The index (into the routing table) of the multicast route to
- * retrieve.
- * \return If route \e i is set, a pointer to that Ipv4MulticastRoutingTableEntry is
- * returned, otherwise a zero pointer is returned.
- *
- * \see Ipv4MulticastRoutingTableEntry
- * \see Ipv4StaticRouting::RemoveRoute
- */
- Ipv4MulticastRoutingTableEntry GetMulticastRoute (uint32_t i) const;
-
-/**
- * \brief Remove a route from the static multicast routing table.
- *
- * Externally, the multicast static routing table appears simply as a table
- * with n entries.
- * This method causes the multicast routing table to be searched for the first
- * route that matches the parameters and removes it.
- *
- * Wildcards may be provided to this function, but the wildcards are used to
- * exactly match wildcards in the routes (see AddMulticastRoute). That is,
- * calling RemoveMulticastRoute with the origin set to "0.0.0.0" will not
- * remove routes with any address in the origin, but will only remove routes
- * with "0.0.0.0" set as the the origin.
- *
- * \param origin The IP address specified as the origin of packets for the
- * route.
- * \param group The IP address specified as the multicast group address of
- * the route.
- * \param inputInterface The network interface index specified as the expected
- * input interface for the route.
- * \returns true if a route was found and removed, false otherwise.
- *
- * \see Ipv4MulticastRoutingTableEntry
- * \see Ipv4StaticRouting::AddMulticastRoute
- */
- bool RemoveMulticastRoute (Ipv4Address origin,
- Ipv4Address group,
- uint32_t inputInterface);
-
-/**
- * \brief Remove a route from the static multicast routing table.
- *
- * Externally, the multicast static routing table appears simply as a table
- * with n entries.
- *
- * \param index The index (into the multicast routing table) of the route to
- * remove.
- *
- * \see Ipv4RoutingTableEntry
- * \see Ipv4StaticRouting::GetRoute
- * \see Ipv4StaticRouting::AddRoute
- */
- void RemoveMulticastRoute (uint32_t index);
-
-protected:
- virtual void DoDispose (void);
-
-private:
- typedef std::list<std::pair <Ipv4RoutingTableEntry *, uint32_t> > NetworkRoutes;
- typedef std::list<std::pair <Ipv4RoutingTableEntry *, uint32_t> >::const_iterator NetworkRoutesCI;
- typedef std::list<std::pair <Ipv4RoutingTableEntry *, uint32_t> >::iterator NetworkRoutesI;
-
- typedef std::list<Ipv4MulticastRoutingTableEntry *> MulticastRoutes;
- typedef std::list<Ipv4MulticastRoutingTableEntry *>::const_iterator MulticastRoutesCI;
- typedef std::list<Ipv4MulticastRoutingTableEntry *>::iterator MulticastRoutesI;
-
- Ptr<Ipv4Route> LookupStatic (Ipv4Address dest, Ptr<NetDevice> oif = 0);
- Ptr<Ipv4MulticastRoute> LookupStatic (Ipv4Address origin, Ipv4Address group,
- uint32_t interface);
-
- Ipv4Address SourceAddressSelection (uint32_t interface, Ipv4Address dest);
-
- NetworkRoutes m_networkRoutes;
- MulticastRoutes m_multicastRoutes;
-
- Ptr<Ipv4> m_ipv4;
-};
-
-} // Namespace ns3
-
-#endif /* IPV4_STATIC_ROUTING_H */
--- a/src/routing/static-routing/ipv6-routing-table-entry.cc Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,331 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007-2009 Strasbourg University
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
- */
-
-#include "ns3/assert.h"
-
-#include "ipv6-routing-table-entry.h"
-
-namespace ns3
-{
-
-Ipv6RoutingTableEntry::Ipv6RoutingTableEntry ()
-{
-}
-
-Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6RoutingTableEntry const& route)
- : m_dest (route.m_dest),
- m_destNetworkPrefix (route.m_destNetworkPrefix),
- m_gateway (route.m_gateway),
- m_interface (route.m_interface),
- m_prefixToUse (route.m_prefixToUse)
-{
-}
-
-Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6RoutingTableEntry const* route)
- : m_dest (route->m_dest),
- m_destNetworkPrefix (route->m_destNetworkPrefix),
- m_gateway (route->m_gateway),
- m_interface (route->m_interface),
- m_prefixToUse (route->m_prefixToUse)
-{
-}
-
-Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address dest, Ipv6Address gateway, uint32_t interface)
- : m_dest (dest),
- m_destNetworkPrefix (Ipv6Prefix::GetZero ()),
- m_gateway (gateway),
- m_interface (interface),
- m_prefixToUse (Ipv6Address ("::"))
-{
-}
-
-Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address dest, uint32_t interface)
- : m_dest (dest),
- m_destNetworkPrefix (Ipv6Prefix::GetOnes ()),
- m_gateway (Ipv6Address::GetZero ()),
- m_interface (interface),
- m_prefixToUse (Ipv6Address ("::"))
-{
-}
-
-Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address gateway, uint32_t interface, Ipv6Address prefixToUse)
- : m_dest (network),
- m_destNetworkPrefix (networkPrefix),
- m_gateway (gateway),
- m_interface (interface),
- m_prefixToUse (prefixToUse)
-{
-}
-
-Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address gateway, uint32_t interface)
- : m_dest (network),
- m_destNetworkPrefix (networkPrefix),
- m_gateway (gateway),
- m_interface (interface),
- m_prefixToUse (Ipv6Address::GetZero ())
-{
-}
-
-
-Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, Ipv6Address prefixToUse)
- : m_dest (network),
- m_destNetworkPrefix (networkPrefix),
- m_gateway (Ipv6Address::GetZero ()),
- m_interface (interface),
- m_prefixToUse (prefixToUse)
-{
-}
-
-Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface)
- : m_dest (network),
- m_destNetworkPrefix (networkPrefix),
- m_gateway (Ipv6Address::GetZero ()),
- m_interface (interface),
- m_prefixToUse (Ipv6Address ("::"))
-{
-}
-
-Ipv6RoutingTableEntry::~Ipv6RoutingTableEntry ()
-{
-}
-
-bool Ipv6RoutingTableEntry::IsHost () const
-{
- if (m_destNetworkPrefix.IsEqual (Ipv6Prefix::GetOnes ()))
- {
- return true;
- }
- return false;
-}
-
-Ipv6Address Ipv6RoutingTableEntry::GetDest () const
-{
- return m_dest;
-}
-
-Ipv6Address Ipv6RoutingTableEntry::GetPrefixToUse () const
-{
- return m_prefixToUse;
-}
-
-void Ipv6RoutingTableEntry::SetPrefixToUse (Ipv6Address prefix)
-{
- m_prefixToUse = prefix;
-}
-
-bool Ipv6RoutingTableEntry::IsNetwork () const
-{
- return !IsHost ();
-}
-
-bool Ipv6RoutingTableEntry::IsDefault () const
-{
- if (m_dest.IsEqual (Ipv6Address::GetZero ()))
- {
- return true;
- }
- return false;
-}
-
-Ipv6Address Ipv6RoutingTableEntry::GetDestNetwork () const
-{
- return m_dest;
-}
-
-Ipv6Prefix Ipv6RoutingTableEntry::GetDestNetworkPrefix () const
-{
- return m_destNetworkPrefix;
-}
-
-bool Ipv6RoutingTableEntry::IsGateway () const
-{
- if (m_gateway.IsEqual (Ipv6Address::GetZero ()))
- {
- return false;
- }
- return true;
-}
-
-Ipv6Address Ipv6RoutingTableEntry::GetGateway () const
-{
- return m_gateway;
-}
-
-Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
-{
- return Ipv6RoutingTableEntry (dest, Ipv6Prefix::GetOnes (), nextHop, interface, prefixToUse);
-}
-
-Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateHostRouteTo (Ipv6Address dest, uint32_t interface)
-{
- return Ipv6RoutingTableEntry (dest, interface);
-}
-
-Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface)
-{
- return Ipv6RoutingTableEntry (network, networkPrefix, nextHop, interface);
-}
-
-Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
-{
- return Ipv6RoutingTableEntry (network, networkPrefix, nextHop, interface, prefixToUse);
-}
-
-Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface)
-{
- return Ipv6RoutingTableEntry (network, networkPrefix, interface, network);
-}
-
-Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateDefaultRoute (Ipv6Address nextHop, uint32_t interface)
-{
- return Ipv6RoutingTableEntry (Ipv6Address::GetZero (), nextHop, interface);
-}
-
-uint32_t Ipv6RoutingTableEntry::GetInterface () const
-{
- return m_interface;
-}
-
-std::ostream& operator<< (std::ostream& os, Ipv6RoutingTableEntry const& route)
-{
- if (route.IsDefault ())
- {
- NS_ASSERT (route.IsGateway ());
- os << "default out =" << route.GetInterface () << ", next hop =" << route.GetGateway ();
- }
- else if (route.IsHost ())
- {
- if (route.IsGateway ())
- {
- os << "host ="<< route.GetDest () <<
- ", out =" << route.GetInterface () <<
- ", next hop =" << route.GetGateway ();
- }
- else
- {
- os << "host =" << route.GetDest () <<
- ", out =" << route.GetInterface ();
- }
- }
- else if (route.IsNetwork ())
- {
- if (route.IsGateway ())
- {
- os << "network =" << route.GetDestNetwork () <<
- ", mask =" << route.GetDestNetworkPrefix () <<
- ",out =" << route.GetInterface () <<
- ", next hop =" << route.GetGateway ();
- }
- else
- {
- os << "network =" << route.GetDestNetwork () <<
- ", mask =" << route.GetDestNetworkPrefix () <<
- ",out =" << route.GetInterface ();
- }
- }
- else
- {
- NS_ASSERT (false);
- }
- return os;
-}
-
-Ipv6MulticastRoutingTableEntry::Ipv6MulticastRoutingTableEntry ()
-{
-}
-
-Ipv6MulticastRoutingTableEntry::Ipv6MulticastRoutingTableEntry (Ipv6MulticastRoutingTableEntry const & route)
- : m_origin (route.m_origin),
- m_group (route.m_group),
- m_inputInterface (route.m_inputInterface),
- m_outputInterfaces (route.m_outputInterfaces)
-{
-}
-
-Ipv6MulticastRoutingTableEntry::Ipv6MulticastRoutingTableEntry (Ipv6MulticastRoutingTableEntry const* route)
- : m_origin (route->m_origin),
- m_group (route->m_group),
- m_inputInterface (route->m_inputInterface),
- m_outputInterfaces (route->m_outputInterfaces)
-{
-}
-
-Ipv6MulticastRoutingTableEntry::Ipv6MulticastRoutingTableEntry (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
- : m_origin (origin),
- m_group (group),
- m_inputInterface (inputInterface),
- m_outputInterfaces (outputInterfaces)
-{
-}
-
-Ipv6Address Ipv6MulticastRoutingTableEntry::GetOrigin () const
-{
- return m_origin;
-}
-
-Ipv6Address Ipv6MulticastRoutingTableEntry::GetGroup () const
-{
- return m_group;
-}
-
-uint32_t Ipv6MulticastRoutingTableEntry::GetInputInterface () const
-{
- return m_inputInterface;
-}
-
-uint32_t Ipv6MulticastRoutingTableEntry::GetNOutputInterfaces () const
-{
- return m_outputInterfaces.size ();
-}
-
-uint32_t Ipv6MulticastRoutingTableEntry::GetOutputInterface (uint32_t n) const
-{
- NS_ASSERT_MSG (n < m_outputInterfaces.size (), "Ipv6MulticastRoutingTableEntry::GetOutputInterface () : index out of bounds");
-
- return m_outputInterfaces[n];
-}
-
-std::vector <uint32_t> Ipv6MulticastRoutingTableEntry::GetOutputInterfaces () const
-{
- return m_outputInterfaces;
-}
-
-Ipv6MulticastRoutingTableEntry Ipv6MulticastRoutingTableEntry::CreateMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
-{
- return Ipv6MulticastRoutingTableEntry (origin, group, inputInterface, outputInterfaces);
-}
-
-std::ostream& operator<< (std::ostream& os, Ipv6MulticastRoutingTableEntry const& route)
-{
- os << "origin =" << route.GetOrigin () <<
- ", group =" << route.GetGroup () <<
- ", input interface =" << route.GetInputInterface () <<
- ", output interfaces =";
-
- for (uint32_t i = 0; i < route.GetNOutputInterfaces (); ++i)
- {
- os << route.GetOutputInterface (i) << " ";
- }
-
- return os;
-}
-
-} /* namespace ns3 */
-
--- a/src/routing/static-routing/ipv6-routing-table-entry.h Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,372 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007-2009 Strasbourg University
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
- */
-
-#ifndef IPV6_ROUTING_TABLE_ENTRY_H
-#define IPV6_ROUTING_TABLE_ENTRY_H
-
-#include <list>
-#include <vector>
-#include <ostream>
-
-#include "ns3/ipv6-address.h"
-
-namespace ns3
-{
-
-/**
- * \class Ipv6RoutingTableEntry
- * \brief A record of an IPv6 route.
- */
-class Ipv6RoutingTableEntry
-{
-public:
- /**
- * \brief Constructor.
- */
- Ipv6RoutingTableEntry ();
-
- /**
- * \brief Copy constructor.
- * \param route the route to copy
- */
- Ipv6RoutingTableEntry (Ipv6RoutingTableEntry const & route);
-
- /**
- * \brief Copy constructor.
- * \param route the route to copy
- */
- Ipv6RoutingTableEntry (Ipv6RoutingTableEntry const* route);
-
- /**
- * \brief Destructor
- */
- ~Ipv6RoutingTableEntry ();
-
- /**
- * \brief Is the route entry correspond to a host ?
- * \return true if the route is a host, false otherwise
- */
- bool IsHost () const;
-
- /**
- * \brief Get the destination.
- * \return the IPv6 address of the destination of this route
- */
- Ipv6Address GetDest () const;
-
- /**
- * \brief Get the prefix to use (for multihomed link).
- * \return prefix address to use
- */
- Ipv6Address GetPrefixToUse () const;
-
- /**
- * \brief Set the prefix to use.
- * \param prefix prefix to use
- */
- void SetPrefixToUse (Ipv6Address prefix);
-
- /**
- * \brief Is the route entry correspond to a network ?
- * \return true if the route is a network, false otherwise
- */
- bool IsNetwork () const;
-
- /**
- * \brief Get the destination network.
- * \return the destination network
- */
- Ipv6Address GetDestNetwork () const;
-
- /**
- * \brief Get the destination prefix.
- * \return the destination prefix
- */
- Ipv6Prefix GetDestNetworkPrefix () const;
-
- /**
- * \brief Is it the default route ?
- * \return true if this route is a default route, false otherwise
- */
- bool IsDefault () const;
-
- /**
- * \brief Is it the gateway ?
- * \return true if this route is a gateway, false otherwise
- */
- bool IsGateway () const;
-
- /**
- * \brief Get the gateway.
- * \return the IPv6 address of the gateway
- */
- Ipv6Address GetGateway () const;
-
- /**
- * \brief Get the interface index.
- * \return the index of the interface
- */
- uint32_t GetInterface () const;
-
- /**
- * \brief Create a route to a host.
- * \param dest destination address
- * \param nextHop next hop address to route the packet
- * \param interface interface index
- * \param prefixToUse prefix that should be used for source address for this destination
- * \return IPv6Route object
- */
- static Ipv6RoutingTableEntry CreateHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address ());
-
- /**
- * \brief Create a route to a host.
- * \param dest destination address
- * \param interface interface index
- * \return IPv6Route object
- */
- static Ipv6RoutingTableEntry CreateHostRouteTo (Ipv6Address dest, uint32_t interface);
-
- /**
- * \brief Create a route to a network.
- * \param network network address
- * \param networkPrefix network prefix
- * \param nextHop next hop address to route the packet
- * \param interface interface index
- * \return IPv6Route object
- */
- static Ipv6RoutingTableEntry CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface);
-
- /**
- * \brief Create a route to a network.
- * \param network network address
- * \param networkPrefix network prefix
- * \param nextHop next hop address to route the packet
- * \param interface interface index
- * \param prefixToUse prefix that should be used for source address for this destination
- * \return IPv6Route object
- */
- static Ipv6RoutingTableEntry CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse);
-
- /**
- * \brief Create a route to a network.
- * \param network network address
- * \param networkPrefix network prefix
- * \param interface interface index
- * \return IPv6Route object
- */
- static Ipv6RoutingTableEntry CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface);
-
- /**
- * \brief Create a default route.
- * \param nextHop next hop address to route the packet
- * \param interface interface index
- * \return IPv6Route object
- */
- static Ipv6RoutingTableEntry CreateDefaultRoute (Ipv6Address nextHop, uint32_t interface);
-
-private:
- /**
- * \brief Constructor.
- * \param network network address
- * \param prefix network prefix
- * \param gateway the gateway
- * \param interface the interface index
- */
- Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix prefix, Ipv6Address gateway, uint32_t interface);
-
- /**
- * \brief Constructor.
- * \param network network address
- * \param prefix network prefix
- * \param interface the interface index
- * \param prefixToUse prefix to use
- */
- Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix prefix, uint32_t interface, Ipv6Address prefixToUse);
-
- /**
- * \brief Constructor.
- * \param network network address
- * \param prefix network prefix
- * \param gateway the gateway
- * \param interface the interface index
- * \param prefixToUse prefix to use
- */
- Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix prefix, Ipv6Address gateway, uint32_t interface, Ipv6Address prefixToUse);
-
- /**
- * \brief Constructor.
- * \param dest destination address
- * \param prefix destination prefix
- * \param interface interface index
- */
- Ipv6RoutingTableEntry (Ipv6Address dest, Ipv6Prefix prefix, uint32_t interface);
-
- /**
- * \brief Constructor.
- * \param dest destination address
- * \param gateway the gateway
- * \param interface interface index
- */
- Ipv6RoutingTableEntry (Ipv6Address dest, Ipv6Address gateway, uint32_t interface);
-
- /**
- * \brief Constructor.
- * \param dest destination address
- * \param interface interface index
- */
- Ipv6RoutingTableEntry (Ipv6Address dest, uint32_t interface);
-
- /**
- * \brief IPv6 address of the destination.
- */
- Ipv6Address m_dest;
-
- /**
- * \brief IPv6 prefix of the destination
- */
- Ipv6Prefix m_destNetworkPrefix;
-
- /**
- * \brief IPv6 address of the gateway.
- */
- Ipv6Address m_gateway;
-
- /**
- * \brief The interface index.
- */
- uint32_t m_interface;
-
- /**
- * \brief Prefix to use.
- */
- Ipv6Address m_prefixToUse;
-
-};
-
-std::ostream& operator<< (std::ostream& os, Ipv6RoutingTableEntry const& route);
-
-/**
- * \class Ipv6MulticastRoutingTableEntry
- * \brief A record of an IPv6 multicast route.
- */
-class Ipv6MulticastRoutingTableEntry
-{
-public:
- /**
- * \brief Constructor.
- */
- Ipv6MulticastRoutingTableEntry ();
-
- /**
- * \brief Copy constructor.
- * \param route the route to copy
- */
- Ipv6MulticastRoutingTableEntry (Ipv6MulticastRoutingTableEntry const & route);
-
- /**
- * \brief Copy constructor.
- * \param route the route to copy
- */
- Ipv6MulticastRoutingTableEntry (Ipv6MulticastRoutingTableEntry const* route);
-
- /**
- * \brief Get the source of this route
- * \return IPv6 address of the source of this route
- */
- Ipv6Address GetOrigin () const;
-
- /**
- * \brief Get the group.
- * \return IPv6 address of the multicast group of this route
- */
- Ipv6Address GetGroup () const;
-
- /**
- * \brief Get the input interface address.
- * \return input interface index
- */
- uint32_t GetInputInterface () const;
-
- /**
- * \brief Get the number of output interfaces of this route.
- * \return number of output interfaces of this route.
- */
- uint32_t GetNOutputInterfaces () const;
-
- /**
- * \brief Get a specified output interface.
- * \param n index
- * \return a specified output interface
- */
- uint32_t GetOutputInterface (uint32_t n) const;
-
- /**
- * \brief Get all of the output interfaces of this route.
- * \return a vector of all output interfaces of this route
- */
- std::vector<uint32_t> GetOutputInterfaces () const;
-
- /**
- * \brief Create a multicast route.
- * \param origin IPv6 address of the origin source
- * \param group Ipv6Address of the group
- * \param inputInterface interface number
- * \param outputInterfaces list of output interface number
- * \return a multicast route
- */
- static Ipv6MulticastRoutingTableEntry CreateMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces);
-
-private:
- /**
- * \brief Constructor.
- * \param origin IPv6 address of the source
- * \param group IPv6 address of the group
- * \param inputInterface interface number
- * \param outputInterfaces list of output interface number
- */
- Ipv6MulticastRoutingTableEntry (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces);
-
- /**
- * \brief The IPv6 address of the source.
- */
- Ipv6Address m_origin;
-
- /**
- * \brief The IPv6 address of the group.
- */
- Ipv6Address m_group;
-
- /**
- * \brief The input interface.
- */
- uint32_t m_inputInterface;
-
- /**
- * \brief The output interfaces.
- */
- std::vector<uint32_t> m_outputInterfaces;
-};
-
-std::ostream& operator<< (std::ostream& os, Ipv6MulticastRoutingTableEntry const& route);
-
-} /* namespace ns3 */
-
-#endif /* IPV6_ROUTING_TABLE_ENTRY_H */
-
--- a/src/routing/static-routing/ipv6-static-routing.cc Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,758 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007-2009 Strasbourg University
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
- */
-
-#include "ns3/log.h"
-#include "ns3/packet.h"
-#include "ns3/ipv6-route.h"
-#include "ns3/net-device.h"
-
-#include "ipv6-static-routing.h"
-#include "ipv6-routing-table-entry.h"
-
-namespace ns3
-{
-
-NS_LOG_COMPONENT_DEFINE ("Ipv6StaticRouting");
-NS_OBJECT_ENSURE_REGISTERED (Ipv6StaticRouting);
-
-TypeId Ipv6StaticRouting::GetTypeId ()
-{
- static TypeId tid = TypeId ("ns3::Ipv6StaticRouting")
- .SetParent<Ipv6RoutingProtocol> ()
- .AddConstructor<Ipv6StaticRouting> ()
- ;
- return tid;
-}
-
-Ipv6StaticRouting::Ipv6StaticRouting ()
- : m_ipv6 (0)
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
-Ipv6StaticRouting::~Ipv6StaticRouting ()
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
-void Ipv6StaticRouting::SetIpv6 (Ptr<Ipv6> ipv6)
-{
- NS_LOG_FUNCTION (this << ipv6);
- NS_ASSERT (m_ipv6 == 0 && ipv6 != 0);
- uint32_t i = 0;
- m_ipv6 = ipv6;
-
- for (i = 0 ; i < m_ipv6->GetNInterfaces () ; i++)
- {
- if (m_ipv6->IsUp (i))
- {
- NotifyInterfaceUp (i);
- }
- else
- {
- NotifyInterfaceDown (i);
- }
- }
-}
-
-void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
-{
- NS_LOG_FUNCTION (this << dst << nextHop << interface << prefixToUse << metric);
- AddNetworkRouteTo (dst, Ipv6Prefix::GetOnes (), nextHop, interface, prefixToUse, metric);
-}
-
-void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, uint32_t interface, uint32_t metric)
-{
- NS_LOG_FUNCTION (this << dst << interface << metric);
- AddNetworkRouteTo (dst, Ipv6Prefix::GetOnes (), interface, metric);
-}
-
-void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, uint32_t metric)
-{
- NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << metric);
- Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
- *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface);
- m_networkRoutes.push_back (std::make_pair (route, metric));
-}
-
-void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
-{
- NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << prefixToUse << metric);
- Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
- *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface, prefixToUse);
- m_networkRoutes.push_back (std::make_pair (route, metric));
-}
-
-void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, uint32_t metric)
-{
- NS_LOG_FUNCTION (this << network << networkPrefix << interface);
- Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
- *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, interface);
- m_networkRoutes.push_back (std::make_pair (route, metric));
-}
-
-void Ipv6StaticRouting::SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
-{
- NS_LOG_FUNCTION (this << nextHop << interface << prefixToUse);
- AddNetworkRouteTo (Ipv6Address ("::"), Ipv6Prefix::GetZero (), nextHop, interface, prefixToUse, metric);
-}
-
-void Ipv6StaticRouting::AddMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
-{
- NS_LOG_FUNCTION (this << origin << group << inputInterface);
- Ipv6MulticastRoutingTableEntry* route = new Ipv6MulticastRoutingTableEntry ();
- *route = Ipv6MulticastRoutingTableEntry::CreateMulticastRoute (origin, group, inputInterface, outputInterfaces);
- m_multicastRoutes.push_back (route);
-}
-
-void Ipv6StaticRouting::SetDefaultMulticastRoute (uint32_t outputInterface)
-{
- NS_LOG_FUNCTION (this << outputInterface);
- Ipv6RoutingTableEntry *route = new Ipv6RoutingTableEntry ();
- Ipv6Address network = Ipv6Address ("ff00::"); /* RFC 3513 */
- Ipv6Prefix networkMask = Ipv6Prefix (8);
- *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkMask, outputInterface);
- m_networkRoutes.push_back (std::make_pair (route, 0));
-}
-
-uint32_t Ipv6StaticRouting::GetNMulticastRoutes () const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_multicastRoutes.size ();
-}
-
-Ipv6MulticastRoutingTableEntry Ipv6StaticRouting::GetMulticastRoute (uint32_t index) const
-{
- NS_LOG_FUNCTION (this << index);
- NS_ASSERT_MSG (index < m_multicastRoutes.size (), "Ipv6StaticRouting::GetMulticastRoute () : Index out of range");
-
- if (index < m_multicastRoutes.size ())
- {
- uint32_t tmp = 0;
- for (MulticastRoutesCI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i++)
- {
- if (tmp == index)
- {
- return *i;
- }
- tmp++;
- }
- }
- return 0;
-}
-
-bool Ipv6StaticRouting::RemoveMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface)
-{
- NS_LOG_FUNCTION (this << origin << group << inputInterface);
- for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
- {
- Ipv6MulticastRoutingTableEntry *route = *i;
- if (origin == route->GetOrigin () &&
- group == route->GetGroup () &&
- inputInterface == route->GetInputInterface ())
- {
- delete *i;
- m_multicastRoutes.erase (i);
- return true;
- }
- }
- return false;
-}
-
-void Ipv6StaticRouting::RemoveMulticastRoute (uint32_t index)
-{
- NS_LOG_FUNCTION (this << index);
- uint32_t tmp = 0;
-
- for (MulticastRoutesI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i++)
- {
- if (tmp == index)
- {
- delete *i;
- m_multicastRoutes.erase (i);
- return;
- }
- tmp++;
- }
-}
-
-bool Ipv6StaticRouting::HasNetworkDest (Ipv6Address network, uint32_t interfaceIndex)
-{
- NS_LOG_FUNCTION (this << network << interfaceIndex);
-
- /* in the network table */
- for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
- {
- Ipv6RoutingTableEntry* rtentry = j->first;
- Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
- Ipv6Address entry = rtentry->GetDestNetwork ();
-
- if (prefix.IsMatch (network, entry) && rtentry->GetInterface () == interfaceIndex)
- {
- return true;
- }
- }
-
- /* beuh!!! not route at all */
- return false;
-}
-
-Ptr<Ipv6Route> Ipv6StaticRouting::LookupStatic (Ipv6Address dst, Ptr<NetDevice> interface)
-{
- NS_LOG_FUNCTION (this << dst << interface);
- Ptr<Ipv6Route> rtentry = 0;
- uint16_t longestMask = 0;
- uint32_t shortestMetric = 0xffffffff;
-
- /* when sending on link-local multicast, there have to be interface specified */
- if (dst == Ipv6Address::GetAllNodesMulticast () || dst.IsSolicitedMulticast () ||
- dst == Ipv6Address::GetAllRoutersMulticast () || dst == Ipv6Address::GetAllHostsMulticast ())
- {
- NS_ASSERT_MSG (interface, "Try to send on link-local multicast address, and no interface index is given!");
- rtentry = Create<Ipv6Route> ();
- rtentry->SetSource (SourceAddressSelection (m_ipv6->GetInterfaceForDevice (interface), dst));
- rtentry->SetDestination (dst);
- rtentry->SetGateway (Ipv6Address::GetZero ());
- rtentry->SetOutputDevice (interface);
- return rtentry;
- }
-
- for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
- {
- Ipv6RoutingTableEntry* j = it->first;
- uint32_t metric = it->second;
- Ipv6Prefix mask = j->GetDestNetworkPrefix ();
- uint16_t maskLen = mask.GetPrefixLength ();
- Ipv6Address entry = j->GetDestNetwork ();
-
- NS_LOG_LOGIC ("Searching for route to " << dst << ", mask length " << maskLen << ", metric " << metric);
-
- if (mask.IsMatch (dst, entry))
- {
- NS_LOG_LOGIC ("Found global network route " << j << ", mask length " << maskLen << ", metric " << metric);
-
- /* if interface is given, check the route will output on this interface */
- if (!interface || interface == m_ipv6->GetNetDevice (j->GetInterface ()))
- {
- if (maskLen < longestMask)
- {
- NS_LOG_LOGIC ("Previous match longer, skipping");
- continue;
- }
-
- if (maskLen > longestMask)
- {
- shortestMetric = 0xffffffff;
- }
-
- longestMask = maskLen;
- if (metric > shortestMetric)
- {
- NS_LOG_LOGIC ("Equal mask length, but previous metric shorter, skipping");
- continue;
- }
-
- shortestMetric = metric;
- Ipv6RoutingTableEntry* route = j;
- uint32_t interfaceIdx = route->GetInterface ();
- rtentry = Create<Ipv6Route> ();
-
- if (route->GetGateway ().IsAny ())
- {
- rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetDest ()));
- }
- else if (route->GetDest ().IsAny ()) /* default route */
- {
- rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetPrefixToUse ().IsAny () ? route->GetGateway () : route->GetPrefixToUse ()));
- }
- else
- {
- rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetGateway ()));
- }
-
- rtentry->SetDestination (route->GetDest ());
- rtentry->SetGateway (route->GetGateway ());
- rtentry->SetOutputDevice (m_ipv6->GetNetDevice (interfaceIdx));
- }
- }
- }
-
- if(rtentry)
- {
- NS_LOG_LOGIC ("Matching route via " << rtentry->GetDestination () << " (throught " << rtentry->GetGateway () << ") at the end");
- }
- return rtentry;
-}
-
-void Ipv6StaticRouting::DoDispose ()
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j = m_networkRoutes.erase (j))
- {
- delete j->first;
- }
- m_networkRoutes.clear ();
-
- for (MulticastRoutesI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i = m_multicastRoutes.erase (i))
- {
- delete (*i);
- }
- m_multicastRoutes.clear ();
-
- m_ipv6 = 0;
- Ipv6RoutingProtocol::DoDispose ();
-}
-
-Ptr<Ipv6MulticastRoute> Ipv6StaticRouting::LookupStatic (Ipv6Address origin, Ipv6Address group, uint32_t interface)
-{
- NS_LOG_FUNCTION (this << origin << group << interface);
- Ptr<Ipv6MulticastRoute> mrtentry = 0;
-
- for (MulticastRoutesI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i++)
- {
- Ipv6MulticastRoutingTableEntry* route = *i;
-
- /*
- We've been passed an origin address, a multicast group address and an
- interface index. We have to decide if the current route in the list is
- a match.
-
- The first case is the restrictive case where the origin, group and index
- matches. This picks up exact routes during forwarded and exact routes from
- the local node (in which case the ifIndex is a wildcard).
- */
-
- if (origin == route->GetOrigin () && group == route->GetGroup ())
- {
- /* skipping SSM case */
- NS_LOG_LOGIC ("Find source specific multicast route" << *i);
- }
-
- if (group == route->GetGroup ())
- {
- if (interface == Ipv6::IF_ANY || interface == route->GetInputInterface ())
- {
- NS_LOG_LOGIC ("Found multicast route" << *i);
- mrtentry = Create<Ipv6MulticastRoute> ();
- mrtentry->SetGroup (route->GetGroup ());
- mrtentry->SetOrigin (route->GetOrigin ());
- mrtentry->SetParent (route->GetInputInterface ());
- for (uint32_t j = 0 ; j < route->GetNOutputInterfaces () ; j++)
- {
- if (route->GetOutputInterface (j))
- {
- NS_LOG_LOGIC ("Setting output interface index " << route->GetOutputInterface (j));
- mrtentry->SetOutputTtl (route->GetOutputInterface (j), Ipv6MulticastRoute::MAX_TTL - 1);
- }
- }
- return mrtentry;
- }
- }
- }
- return mrtentry;
-}
-
-uint32_t Ipv6StaticRouting::GetNRoutes ()
-{
- return m_networkRoutes.size ();
-}
-
-Ipv6RoutingTableEntry Ipv6StaticRouting::GetDefaultRoute ()
-{
- NS_LOG_FUNCTION_NOARGS ();
- Ipv6Address dst ("::");
- uint32_t shortestMetric = 0xffffffff;
- Ipv6RoutingTableEntry* result = 0;
-
- for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
- {
- Ipv6RoutingTableEntry* j = it->first;
- uint32_t metric = it->second;
- Ipv6Prefix mask = j->GetDestNetworkPrefix ();
- uint16_t maskLen = mask.GetPrefixLength ();
- Ipv6Address entry = j->GetDestNetwork ();
-
- if (maskLen)
- {
- continue;
- }
-
- if (metric > shortestMetric)
- {
- continue;
- }
- shortestMetric = metric;
- result = j;
- }
-
- if (result)
- {
- return result;
- }
- else
- {
- return Ipv6RoutingTableEntry ();
- }
-}
-
-Ipv6RoutingTableEntry Ipv6StaticRouting::GetRoute (uint32_t index)
-{
- NS_LOG_FUNCTION (this << index);
- uint32_t tmp = 0;
-
- for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
- {
- if (tmp == index)
- {
- return it->first;
- }
- tmp++;
- }
- NS_ASSERT (false);
- // quiet compiler.
- return 0;
-}
-
-uint32_t Ipv6StaticRouting::GetMetric (uint32_t index)
-{
- NS_LOG_FUNCTION_NOARGS ();
- uint32_t tmp = 0;
-
- for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
- {
- if (tmp == index)
- {
- return it->second;
- }
- tmp++;
- }
- NS_ASSERT (false);
- // quiet compiler.
- return 0;
-}
-
-void Ipv6StaticRouting::RemoveRoute (uint32_t index)
-{
- NS_LOG_FUNCTION (this << index);
- uint32_t tmp = 0;
-
- for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
- {
- if (tmp == index)
- {
- delete it->first;
- m_networkRoutes.erase (it);
- return;
- }
- tmp++;
- }
- NS_ASSERT (false);
-}
-
-void Ipv6StaticRouting::RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex, Ipv6Address prefixToUse)
-{
- NS_LOG_FUNCTION (this << network << prefix << ifIndex);
-
- for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
- {
- Ipv6RoutingTableEntry* rtentry = it->first;
- if (network == rtentry->GetDest () && rtentry->GetInterface () == ifIndex &&
- rtentry->GetPrefixToUse () == prefixToUse)
- {
- delete it->first;
- m_networkRoutes.erase (it);
- return;
- }
- }
-}
-
-Ptr<Ipv6Route> Ipv6StaticRouting::RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
-{
- NS_LOG_FUNCTION (this << header << oif);
- Ipv6Address destination = header.GetDestinationAddress ();
- Ptr<Ipv6Route> rtentry = 0;
-
- if (destination.IsMulticast ())
- {
- // Note: Multicast routes for outbound packets are stored in the
- // normal unicast table. An implication of this is that it is not
- // possible to source multicast datagrams on multiple interfaces.
- // This is a well-known property of sockets implementation on
- // many Unix variants.
- // So, we just log it and fall through to LookupStatic ()
- NS_LOG_LOGIC ("RouteOutput ()::Multicast destination");
- }
-
- rtentry = LookupStatic (destination, oif);
- if (rtentry)
- {
- sockerr = Socket::ERROR_NOTERROR;
- }
- else
- {
- sockerr = Socket::ERROR_NOROUTETOHOST;
- }
- return rtentry;
-}
-
-bool Ipv6StaticRouting::RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
- UnicastForwardCallback ucb, MulticastForwardCallback mcb,
- LocalDeliverCallback lcb, ErrorCallback ecb)
-{
- NS_LOG_FUNCTION (this << p << header << header.GetSourceAddress () << header.GetDestinationAddress () << idev);
- NS_ASSERT (m_ipv6 != 0);
- // Check if input device supports IP
- NS_ASSERT (m_ipv6->GetInterfaceForDevice (idev) >= 0);
- uint32_t iif = m_ipv6->GetInterfaceForDevice (idev);
- Ipv6Address dst = header.GetDestinationAddress ();
-
- if (dst.IsMulticast ())
- {
- NS_LOG_LOGIC ("Multicast destination");
- Ptr<Ipv6MulticastRoute> mrtentry = LookupStatic (header.GetSourceAddress (),
- header.GetDestinationAddress (), m_ipv6->GetInterfaceForDevice (idev));
-
- if (mrtentry)
- {
- NS_LOG_LOGIC ("Multicast route found");
- mcb (mrtentry, p, header); // multicast forwarding callback
- return true;
- }
- else
- {
- NS_LOG_LOGIC ("Multicast route not found");
- return false; // Let other routing protocols try to handle this
- }
- }
-
- // TODO: Configurable option to enable RFC 1222 Strong End System Model
- // Right now, we will be permissive and allow a source to send us
- // a packet to one of our other interface addresses; that is, the
- // destination unicast address does not match one of the iif addresses,
- // but we check our other interfaces. This could be an option
- // (to remove the outer loop immediately below and just check iif).
- for (uint32_t j = 0; j < m_ipv6->GetNInterfaces (); j++)
- {
- for (uint32_t i = 0; i < m_ipv6->GetNAddresses (j); i++)
- {
- Ipv6InterfaceAddress iaddr = m_ipv6->GetAddress (j, i);
- Ipv6Address addr = iaddr.GetAddress ();
- if (addr.IsEqual (header.GetDestinationAddress ()))
- {
- if (j == iif)
- {
- NS_LOG_LOGIC ("For me (destination " << addr << " match)");
- }
- else
- {
- NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestinationAddress ());
- }
- lcb (p, header, iif);
- return true;
- }
- NS_LOG_LOGIC ("Address "<< addr << " not a match");
- }
- }
- // Check if input device supports IP forwarding
- if (m_ipv6->IsForwarding (iif) == false)
- {
- NS_LOG_LOGIC ("Forwarding disabled for this interface");
- ecb (p, header, Socket::ERROR_NOROUTETOHOST);
- return false;
- }
- // Next, try to find a route
- NS_LOG_LOGIC ("Unicast destination");
- Ptr<Ipv6Route> rtentry = LookupStatic (header.GetDestinationAddress ());
-
- if (rtentry != 0)
- {
- NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
- ucb (rtentry, p, header); // unicast forwarding callback
- return true;
- }
- else
- {
- NS_LOG_LOGIC ("Did not find unicast destination- returning false");
- return false; // Let other routing protocols try to handle this
- }
-}
-
-void Ipv6StaticRouting::NotifyInterfaceUp (uint32_t i)
-{
- for (uint32_t j = 0 ; j < m_ipv6->GetNAddresses (i) ; j++)
- {
- if (m_ipv6->GetAddress (i, j).GetAddress () != Ipv6Address () &&
- m_ipv6->GetAddress (i, j).GetPrefix () != Ipv6Prefix ())
- {
- if (m_ipv6->GetAddress (i, j).GetPrefix () == Ipv6Prefix (128))
- {
- /* host route */
- AddHostRouteTo (m_ipv6->GetAddress (i, j).GetAddress (), i);
- }
- else
- {
- AddNetworkRouteTo (m_ipv6->GetAddress (i, j).GetAddress ().CombinePrefix (m_ipv6->GetAddress (i, j).GetPrefix ()),
- m_ipv6->GetAddress (i, j).GetPrefix (), i);
- }
- }
- }
-}
-
-void Ipv6StaticRouting::NotifyInterfaceDown (uint32_t i)
-{
- NS_LOG_FUNCTION (this << i);
- uint32_t j = 0;
- uint32_t max = GetNRoutes ();
-
- /* remove all static routes that are going through this interface */
- while (j < max)
- {
- Ipv6RoutingTableEntry route = GetRoute (j);
-
- if (route.GetInterface () == i)
- {
- RemoveRoute (j);
- }
- else
- {
- j++;
- }
- }
-}
-
-void Ipv6StaticRouting::NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address)
-{
- if (!m_ipv6->IsUp (interface))
- {
- return;
- }
-
- Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
- Ipv6Prefix networkMask = address.GetPrefix ();
-
- if (address.GetAddress () != Ipv6Address () && address.GetPrefix () != Ipv6Prefix ())
- {
- AddNetworkRouteTo (networkAddress, networkMask, interface);
- }
-}
-
-void Ipv6StaticRouting::NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address)
-{
- if (!m_ipv6->IsUp (interface))
- {
- return;
- }
-
- Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
- Ipv6Prefix networkMask = address.GetPrefix ();
-
- // Remove all static routes that are going through this interface
- // which reference this network
- for (uint32_t j = 0 ; j < GetNRoutes () ; j++)
- {
- Ipv6RoutingTableEntry route = GetRoute (j);
-
- if (route.GetInterface () == interface &&
- route.IsNetwork () &&
- route.GetDestNetwork () == networkAddress &&
- route.GetDestNetworkPrefix () == networkMask)
- {
- RemoveRoute (j);
- }
- }
-}
-
-void Ipv6StaticRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
-{
- NS_LOG_INFO (this << dst << mask << nextHop << interface << prefixToUse);
- if (dst != Ipv6Address::GetZero ())
- {
- AddNetworkRouteTo (dst, mask, nextHop, interface);
- }
- else /* default route */
- {
- /* this case is mainly used by configuring default route following RA processing,
- * in case of multipe prefix in RA, the first will configured default route
- */
-
- /* for the moment, all default route has the same metric
- * so according to the longest prefix algorithm,
- * the default route choosen will be the last added
- */
- SetDefaultRoute (nextHop, interface, prefixToUse);
- }
-}
-
-void Ipv6StaticRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
-{
- NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
- if (dst != Ipv6Address::GetZero ())
- {
- for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
- {
- Ipv6RoutingTableEntry* rtentry = j->first;
- Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
- Ipv6Address entry = rtentry->GetDestNetwork ();
-
- if (dst == entry && prefix == mask && rtentry->GetInterface () == interface)
- {
- delete j->first;
- m_networkRoutes.erase (j);
- }
- }
- }
- else
- {
- /* default route case */
- RemoveRoute (dst, mask, interface, prefixToUse);
- }
-}
-
-Ipv6Address Ipv6StaticRouting::SourceAddressSelection (uint32_t interface, Ipv6Address dest)
-{
- NS_LOG_FUNCTION (this << interface << dest);
- Ipv6Address ret;
-
- /* first address of an IPv6 interface is link-local ones */
- ret = m_ipv6->GetAddress (interface, 0).GetAddress ();
-
- if (dest == Ipv6Address::GetAllNodesMulticast () || dest == Ipv6Address::GetAllRoutersMulticast () || dest == Ipv6Address::GetAllHostsMulticast ())
- {
- return ret;
- }
-
- /* useally IPv6 interfaces have one link-local address and one global address */
-
- for (uint32_t i = 1 ; i < m_ipv6->GetNAddresses (interface) ; i++)
- {
- Ipv6InterfaceAddress test = m_ipv6->GetAddress (interface, i);
-
- if (test.GetAddress ().CombinePrefix (test.GetPrefix ()) == dest.CombinePrefix (test.GetPrefix ()))
- {
- return test.GetAddress ();
- }
- }
-
- return ret;
-}
-
-} /* namespace ns3 */
-
--- a/src/routing/static-routing/ipv6-static-routing.h Tue Oct 26 15:11:17 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,299 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007-2009 Strasbourg University
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
- */
-
-#ifndef IPV6_STATIC_ROUTING_H
-#define IPV6_STATIC_ROUTING_H
-
-#include <stdint.h>
-
-#include <list>
-
-#include "ns3/ptr.h"
-#include "ns3/ipv6-address.h"
-#include "ns3/ipv6.h"
-#include "ns3/ipv6-header.h"
-#include "ns3/ipv6-routing-protocol.h"
-
-namespace ns3
-{
-
-class Packet;
-class NetDevice;
-class Ipv6Interface;
-class Ipv6Route;
-class Node;
-class Ipv6RoutingTableEntry;
-class Ipv6MulticastRoutingTableEntry;
-
-/**
- * \ingroup routing
- * \defgroup ipv6StaticRouting Ipv6StaticRouting
- */
-/**
- * \ingroup ipv6StaticRouting
- * \class Ipv6StaticRouting
- * \brief Static routing protocol for IP version 6 stack.
- * \see Ipv6RoutingProtocol
- * \see Ipv6ListRouting
- */
-class Ipv6StaticRouting : public Ipv6RoutingProtocol
-{
-public:
- /**
- * \brief The interface Id associated with this class.
- * \return type identifier
- */
- static TypeId GetTypeId ();
-
- /**
- * \brief Constructor.
- */
- Ipv6StaticRouting ();
-
- /**
- * \brief Destructor.
- */
- virtual ~Ipv6StaticRouting ();
-
- /**
- * \brief Add route to host.
- * \param dest destination address
- * \param nextHop next hop address to route the packet
- * \param interface interface index
- * \param prefixToUse prefix that should be used for source address for this destination
- * \param metric metric of route in case of multiple routes to same destination
- */
- void AddHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address ("::"), uint32_t metric = 0);
-
- /**
- * \brief Add route to host.
- * \param dest destination address.
- * \param interface interface index
- * \param metric metric of route in case of multiple routes to same destination
- */
- void AddHostRouteTo (Ipv6Address dest, uint32_t interface, uint32_t metric = 0);
-
- /**
- * \brief Add route to network.
- * \param network network address
- * \param networkPrefix network prefix*
- * \param nextHop next hop address to route the packet
- * \param interface interface index
- * \param metric metric of route in case of multiple routes to same destination
- */
- void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, uint32_t metric = 0);
-
- /**
- * \brief Add route to network.
- * \param network network address
- * \param networkPrefix network prefix*
- * \param nextHop next hop address to route the packet
- * \param interface interface index
- * \param prefixToUse prefix that should be used for source address for this destination
- * \param metric metric of route in case of multiple routes to same destination
- */
- void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric = 0);
-
- /**
- * \brief Add route to network.
- * \param network network address
- * \param networkPrefix network prefix
- * \param interface interface index
- * \param metric metric of route in case of multiple routes to same destination
- */
- void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, uint32_t metric = 0);
-
- /**
- * \brief Set the default route.
- * \param nextHop next hop address to route the packet
- * \param interface interface index
- * \param prefixToUse prefix to use (i.e for multihoming)
- * \param metric metric of route in case of multiple routes to same destination
- */
- void SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address ("::"), uint32_t metric = 0);
-
- /**
- * \brief Get the number or entries in the routing table.
- * \return number of entries
- */
- uint32_t GetNRoutes ();
-
- /**
- * \brief Get the default route.
- *
- * If multiple default routes exist, the one with lowest metric is returned.
- * \return default Ipv6Route
- */
- Ipv6RoutingTableEntry GetDefaultRoute ();
-
- /**
- * \brief Get a specified route.
- * \param i index
- * \return the route whose index is i
- */
- Ipv6RoutingTableEntry GetRoute (uint32_t i);
-
- /**
- * \brief Get a metric for route from the static unicast routing table.
- * \param index The index (into the routing table) of the route to retrieve.
- * \return If route is set, the metric is returned. If not, an infinity metric (0xffffffff) is returned
- */
- uint32_t GetMetric (uint32_t index);
-
- /**
- * \brief Remove a route from the routing table.
- * \param i index
- */
- void RemoveRoute (uint32_t i);
-
- /**
- * \brief Remove a route from the routing table.
- * \param network IPv6 network
- * \param prefix IPv6 prefix
- * \param ifIndex interface index
- * \param prefixToUse IPv6 prefix to use with this route (multihoming)
- */
- void RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex, Ipv6Address prefixToUse);
-
- /**
- * \brief Add a multicast route for a given multicast source and group.
- * \param origin IPv6 address of the source
- * \param group the multicast group address.
- * \param inputInterface the interface index
- * \param outputInterfaces the list of output interface indices over which the packet
- * should be sent (excluding the inputInterface).
- */
- void AddMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces);
-
- /**
- * \brief Set the default multicast route.
- * \param outputInterface default output interface
- */
- void SetDefaultMulticastRoute (uint32_t outputInterface);
-
- /**
- * \brief Get the number of entries in the multicast routing table.
- * \return number of entries
- */
- uint32_t GetNMulticastRoutes () const;
-
- /**
- * \brief Get the specified multicast route.
- * \param i index
- * \return the route whose index is i
- */
- Ipv6MulticastRoutingTableEntry GetMulticastRoute (uint32_t i) const;
-
- /**
- * \brief Remove a static multicast route.
- * \param origin IPv6 address of the source
- * \param group the multicast group address.
- * \param inputInterface the input interface index
- */
- bool RemoveMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface);
-
- /**
- * \brief Remove a multicast route.
- * \param i index of route to remove
- */
- void RemoveMulticastRoute (uint32_t i);
-
- /**
- * \brief If the destination is already present in network destination list.
- * \param dest destination address
- * \param interfaceIndex interface index
- * \return true if dest is already in list, false otherwise
- */
- bool HasNetworkDest (Ipv6Address dest, uint32_t interfaceIndex);
-
- virtual Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
-
- virtual bool RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
- UnicastForwardCallback ucb, MulticastForwardCallback mcb,
- LocalDeliverCallback lcb, ErrorCallback ecb);
-
- virtual void NotifyInterfaceUp (uint32_t interface);
- virtual void NotifyInterfaceDown (uint32_t interface);
- virtual void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address);
- virtual void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address);
- virtual void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
- virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
- virtual void SetIpv6 (Ptr<Ipv6> ipv6);
-
-protected:
- /**
- * \brief Dispose this object.
- */
- void DoDispose ();
-
-private:
- typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> > NetworkRoutes;
- typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> >::const_iterator NetworkRoutesCI;
- typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> >::iterator NetworkRoutesI;
-
- typedef std::list<Ipv6MulticastRoutingTableEntry *> MulticastRoutes;
- typedef std::list<Ipv6MulticastRoutingTableEntry *>::const_iterator MulticastRoutesCI;
- typedef std::list<Ipv6MulticastRoutingTableEntry *>::iterator MulticastRoutesI;
-
- /**
- * \brief Lookup in the forwarding table for destination.
- * \param dest destination address
- * \param interface output interface if any (put 0 otherwise)
- * \return Ipv6Route to route the packet to reach dest address
- */
- Ptr<Ipv6Route> LookupStatic (Ipv6Address dest, Ptr<NetDevice> = 0);
-
- /**
- * \brief Lookup in the multicast forwarding table for destination.
- * \param origin source address
- * \param group group multicast address
- * \param ifIndex interface index
- * \return Ipv6MulticastRoute to route the packet to reach dest address
- */
- Ptr<Ipv6MulticastRoute> LookupStatic (Ipv6Address origin, Ipv6Address group, uint32_t ifIndex);
-
- /**
- * \brief Choose the source address to use with destination address.
- * \param interface interface index
- * \param dest IPv6 destination address
- * \return IPv6 source address to use
- */
- Ipv6Address SourceAddressSelection (uint32_t interface, Ipv6Address dest);
-
- /**
- * \brief the forwarding table for network.
- */
- NetworkRoutes m_networkRoutes;
-
- /**
- * \brief the forwarding table for multicast.
- */
- MulticastRoutes m_multicastRoutes;
-
- /**
- * \brief Ipv6 reference.
- */
- Ptr<Ipv6> m_ipv6;
-};
-
-} /* namespace ns3 */
-
-#endif /* IPV6_STATIC_ROUTING_H */
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/model/ipv4-routing-table-entry.cc Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,333 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "ipv4-routing-table-entry.h"
+#include "ns3/assert.h"
+
+namespace ns3 {
+
+/*****************************************************
+ * Network Ipv4RoutingTableEntry
+ *****************************************************/
+
+Ipv4RoutingTableEntry::Ipv4RoutingTableEntry ()
+{}
+
+Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4RoutingTableEntry const &route)
+ : m_dest (route.m_dest),
+ m_destNetworkMask (route.m_destNetworkMask),
+ m_gateway (route.m_gateway),
+ m_interface (route.m_interface)
+{}
+
+Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4RoutingTableEntry const *route)
+ : m_dest (route->m_dest),
+ m_destNetworkMask (route->m_destNetworkMask),
+ m_gateway (route->m_gateway),
+ m_interface (route->m_interface)
+{}
+
+Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4Address dest,
+ Ipv4Address gateway,
+ uint32_t interface)
+ : m_dest (dest),
+ m_destNetworkMask (Ipv4Mask::GetOnes ()),
+ m_gateway (gateway),
+ m_interface (interface)
+{}
+Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4Address dest,
+ uint32_t interface)
+ : m_dest (dest),
+ m_destNetworkMask (Ipv4Mask::GetOnes ()),
+ m_gateway (Ipv4Address::GetZero ()),
+ m_interface (interface)
+{}
+Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4Address network,
+ Ipv4Mask networkMask,
+ Ipv4Address gateway,
+ uint32_t interface)
+ : m_dest (network),
+ m_destNetworkMask (networkMask),
+ m_gateway (gateway),
+ m_interface (interface)
+{}
+Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4Address network,
+ Ipv4Mask networkMask,
+ uint32_t interface)
+ : m_dest (network),
+ m_destNetworkMask (networkMask),
+ m_gateway (Ipv4Address::GetZero ()),
+ m_interface (interface)
+{}
+
+bool
+Ipv4RoutingTableEntry::IsHost (void) const
+{
+ if (m_destNetworkMask.IsEqual (Ipv4Mask::GetOnes ()))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+Ipv4Address
+Ipv4RoutingTableEntry::GetDest (void) const
+{
+ return m_dest;
+}
+bool
+Ipv4RoutingTableEntry::IsNetwork (void) const
+{
+ return !IsHost ();
+}
+bool
+Ipv4RoutingTableEntry::IsDefault (void) const
+{
+ if (m_dest.IsEqual (Ipv4Address::GetZero ()))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+Ipv4Address
+Ipv4RoutingTableEntry::GetDestNetwork (void) const
+{
+ return m_dest;
+}
+Ipv4Mask
+Ipv4RoutingTableEntry::GetDestNetworkMask (void) const
+{
+ return m_destNetworkMask;
+}
+bool
+Ipv4RoutingTableEntry::IsGateway (void) const
+{
+ if (m_gateway.IsEqual (Ipv4Address::GetZero ()))
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
+Ipv4Address
+Ipv4RoutingTableEntry::GetGateway (void) const
+{
+ return m_gateway;
+}
+uint32_t
+Ipv4RoutingTableEntry::GetInterface (void) const
+{
+ return m_interface;
+}
+
+Ipv4RoutingTableEntry
+Ipv4RoutingTableEntry::CreateHostRouteTo (Ipv4Address dest,
+ Ipv4Address nextHop,
+ uint32_t interface)
+{
+ return Ipv4RoutingTableEntry (dest, nextHop, interface);
+}
+Ipv4RoutingTableEntry
+Ipv4RoutingTableEntry::CreateHostRouteTo (Ipv4Address dest,
+ uint32_t interface)
+{
+ return Ipv4RoutingTableEntry (dest, interface);
+}
+Ipv4RoutingTableEntry
+Ipv4RoutingTableEntry::CreateNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ Ipv4Address nextHop,
+ uint32_t interface)
+{
+ return Ipv4RoutingTableEntry (network, networkMask,
+ nextHop, interface);
+}
+Ipv4RoutingTableEntry
+Ipv4RoutingTableEntry::CreateNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ uint32_t interface)
+{
+ return Ipv4RoutingTableEntry (network, networkMask,
+ interface);
+}
+Ipv4RoutingTableEntry
+Ipv4RoutingTableEntry::CreateDefaultRoute (Ipv4Address nextHop,
+ uint32_t interface)
+{
+ return Ipv4RoutingTableEntry (Ipv4Address::GetZero (), nextHop, interface);
+}
+
+
+std::ostream& operator<< (std::ostream& os, Ipv4RoutingTableEntry const& route)
+{
+ if (route.IsDefault ())
+ {
+ NS_ASSERT (route.IsGateway ());
+ os << "default out=" << route.GetInterface () << ", next hop=" << route.GetGateway ();
+ }
+ else if (route.IsHost ())
+ {
+ if (route.IsGateway ())
+ {
+ os << "host="<< route.GetDest () <<
+ ", out=" << route.GetInterface () <<
+ ", next hop=" << route.GetGateway ();
+ }
+ else
+ {
+ os << "host="<< route.GetDest () <<
+ ", out=" << route.GetInterface ();
+ }
+ }
+ else if (route.IsNetwork ())
+ {
+ if (route.IsGateway ())
+ {
+ os << "network=" << route.GetDestNetwork () <<
+ ", mask=" << route.GetDestNetworkMask () <<
+ ",out=" << route.GetInterface () <<
+ ", next hop=" << route.GetGateway ();
+ }
+ else
+ {
+ os << "network=" << route.GetDestNetwork () <<
+ ", mask=" << route.GetDestNetworkMask () <<
+ ",out=" << route.GetInterface ();
+ }
+ }
+ else
+ {
+ NS_ASSERT (false);
+ }
+ return os;
+}
+
+/*****************************************************
+ * Ipv4MulticastRoutingTableEntry
+ *****************************************************/
+
+Ipv4MulticastRoutingTableEntry::Ipv4MulticastRoutingTableEntry ()
+{
+}
+
+Ipv4MulticastRoutingTableEntry::Ipv4MulticastRoutingTableEntry (Ipv4MulticastRoutingTableEntry const &route)
+:
+ m_origin (route.m_origin),
+ m_group (route.m_group),
+ m_inputInterface (route.m_inputInterface),
+ m_outputInterfaces (route.m_outputInterfaces)
+{
+}
+
+Ipv4MulticastRoutingTableEntry::Ipv4MulticastRoutingTableEntry (Ipv4MulticastRoutingTableEntry const *route)
+:
+ m_origin (route->m_origin),
+ m_group (route->m_group),
+ m_inputInterface (route->m_inputInterface),
+ m_outputInterfaces (route->m_outputInterfaces)
+{
+}
+
+Ipv4MulticastRoutingTableEntry::Ipv4MulticastRoutingTableEntry (
+ Ipv4Address origin,
+ Ipv4Address group,
+ uint32_t inputInterface,
+ std::vector<uint32_t> outputInterfaces)
+{
+ m_origin = origin;
+ m_group = group;
+ m_inputInterface = inputInterface;
+ m_outputInterfaces = outputInterfaces;
+}
+
+Ipv4Address
+Ipv4MulticastRoutingTableEntry::GetOrigin (void) const
+{
+ return m_origin;
+}
+
+Ipv4Address
+Ipv4MulticastRoutingTableEntry::GetGroup (void) const
+{
+ return m_group;
+}
+
+uint32_t
+Ipv4MulticastRoutingTableEntry::GetInputInterface (void) const
+{
+ return m_inputInterface;
+}
+
+uint32_t
+Ipv4MulticastRoutingTableEntry::GetNOutputInterfaces (void) const
+{
+ return m_outputInterfaces.size ();
+}
+
+uint32_t
+Ipv4MulticastRoutingTableEntry::GetOutputInterface (uint32_t n) const
+{
+ NS_ASSERT_MSG(n < m_outputInterfaces.size (),
+ "Ipv4MulticastRoutingTableEntry::GetOutputInterface (): index out of bounds");
+
+ return m_outputInterfaces[n];
+}
+
+std::vector<uint32_t>
+Ipv4MulticastRoutingTableEntry::GetOutputInterfaces (void) const
+{
+ return m_outputInterfaces;
+}
+
+Ipv4MulticastRoutingTableEntry
+Ipv4MulticastRoutingTableEntry::CreateMulticastRoute (
+ Ipv4Address origin,
+ Ipv4Address group,
+ uint32_t inputInterface,
+ std::vector<uint32_t> outputInterfaces)
+{
+ return Ipv4MulticastRoutingTableEntry (origin, group, inputInterface, outputInterfaces);
+}
+
+std::ostream&
+operator<< (std::ostream& os, Ipv4MulticastRoutingTableEntry const& route)
+{
+ os << "origin=" << route.GetOrigin () <<
+ ", group=" << route.GetGroup () <<
+ ", input interface=" << route.GetInputInterface () <<
+ ", output interfaces=";
+
+ for (uint32_t i = 0; i < route.GetNOutputInterfaces (); ++i)
+ {
+ os << route.GetOutputInterface (i) << " ";
+
+ }
+
+ return os;
+}
+
+}//namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/model/ipv4-routing-table-entry.h Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,231 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef IPV4_ROUTING_TABLE_ENTRY_H
+#define IPV4_ROUTING_TABLE_ENTRY_H
+
+#include <list>
+#include <vector>
+#include <ostream>
+
+#include "ns3/ipv4-address.h"
+
+namespace ns3 {
+
+/**
+ * \ingroup routing
+ *
+ * A record of an IPv4 routing table entry for Ipv4GlobalRouting and
+ * Ipv4StaticRouting. This is not a reference counted object.
+ */
+class Ipv4RoutingTableEntry {
+public:
+ /**
+ * \brief This constructor does nothing
+ */
+ Ipv4RoutingTableEntry ();
+ /**
+ * \brief Copy Constructor
+ * \param route The route to copy
+ */
+ Ipv4RoutingTableEntry (Ipv4RoutingTableEntry const &route);
+ /**
+ * \brief Copy Constructor
+ * \param route The route to copy
+ */
+ Ipv4RoutingTableEntry (Ipv4RoutingTableEntry const *route);
+ /**
+ * \return True if this route is a host route (mask of all ones); false otherwise
+ */
+ bool IsHost (void) const;
+ /**
+ * \return True if this route is not a host route (mask is not all ones); false otherwise
+ *
+ * This method is implemented as !IsHost ().
+ */
+ bool IsNetwork (void) const;
+ /**
+ * \return True if this route is a default route; false otherwise
+ */
+ bool IsDefault (void) const;
+ /**
+ * \return True if this route is a gateway route; false otherwise
+ */
+ bool IsGateway (void) const;
+ /**
+ * \return address of the gateway stored in this entry
+ */
+ Ipv4Address GetGateway (void) const;
+ /**
+ * \return The IPv4 address of the destination of this route
+ */
+ Ipv4Address GetDest (void) const;
+ /**
+ * \return The IPv4 network number of the destination of this route
+ */
+ Ipv4Address GetDestNetwork (void) const;
+ /**
+ * \return The IPv4 network mask of the destination of this route
+ */
+ Ipv4Mask GetDestNetworkMask (void) const;
+ /**
+ * \return The Ipv4 interface number used for sending outgoing packets
+ */
+ uint32_t GetInterface (void) const;
+ /**
+ * \return An Ipv4RoutingTableEntry object corresponding to the input parameters.
+ * \param dest Ipv4Address of the destination
+ * \param nextHop Ipv4Address of the next hop
+ * \param interface Outgoing interface
+ */
+ static Ipv4RoutingTableEntry CreateHostRouteTo (Ipv4Address dest,
+ Ipv4Address nextHop,
+ uint32_t interface);
+ /**
+ * \return An Ipv4RoutingTableEntry object corresponding to the input parameters.
+ * \param dest Ipv4Address of the destination
+ * \param interface Outgoing interface
+ */
+ static Ipv4RoutingTableEntry CreateHostRouteTo (Ipv4Address dest,
+ uint32_t interface);
+ /**
+ * \return An Ipv4RoutingTableEntry object corresponding to the input parameters.
+ * \param network Ipv4Address of the destination network
+ * \param networkMask Ipv4Mask of the destination network mask
+ * \param nextHop Ipv4Address of the next hop
+ * \param interface Outgoing interface
+ */
+ static Ipv4RoutingTableEntry CreateNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ Ipv4Address nextHop,
+ uint32_t interface);
+ /**
+ * \return An Ipv4RoutingTableEntry object corresponding to the input parameters.
+ * \param network Ipv4Address of the destination network
+ * \param networkMask Ipv4Mask of the destination network mask
+ * \param interface Outgoing interface
+ */
+ static Ipv4RoutingTableEntry CreateNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ uint32_t interface);
+ /**
+ * \return An Ipv4RoutingTableEntry object corresponding to the input
+ * parameters. This route is distinguished; it will match any
+ * destination for which a more specific route does not exist.
+ * \param nextHop Ipv4Address of the next hop
+ * \param interface Outgoing interface
+ */
+ static Ipv4RoutingTableEntry CreateDefaultRoute (Ipv4Address nextHop,
+ uint32_t interface);
+
+private:
+ Ipv4RoutingTableEntry (Ipv4Address network,
+ Ipv4Mask mask,
+ Ipv4Address gateway,
+ uint32_t interface);
+ Ipv4RoutingTableEntry (Ipv4Address dest,
+ Ipv4Mask mask,
+ uint32_t interface);
+ Ipv4RoutingTableEntry (Ipv4Address dest,
+ Ipv4Address gateway,
+ uint32_t interface);
+ Ipv4RoutingTableEntry (Ipv4Address dest,
+ uint32_t interface);
+
+ Ipv4Address m_dest;
+ Ipv4Mask m_destNetworkMask;
+ Ipv4Address m_gateway;
+ uint32_t m_interface;
+};
+
+std::ostream& operator<< (std::ostream& os, Ipv4RoutingTableEntry const& route);
+
+/**
+ * \ingroup routing
+ *
+ * \brief A record of an IPv4 multicast route for Ipv4GlobalRouting and Ipv4StaticRouting
+ */
+class Ipv4MulticastRoutingTableEntry {
+public:
+ /**
+ * \brief This constructor does nothing
+ */
+ Ipv4MulticastRoutingTableEntry ();
+
+ /**
+ * \brief Copy Constructor
+ * \param route The route to copy
+ */
+ Ipv4MulticastRoutingTableEntry (Ipv4MulticastRoutingTableEntry const &route);
+ /**
+ * \brief Copy Constructor
+ * \param route The route to copy
+ */
+ Ipv4MulticastRoutingTableEntry (Ipv4MulticastRoutingTableEntry const *route);
+ /**
+ * \return The IPv4 address of the source of this route
+ */
+ Ipv4Address GetOrigin (void) const;
+ /**
+ * \return The IPv4 address of the multicast group of this route
+ */
+ Ipv4Address GetGroup (void) const;
+ /**
+ * \return The IPv4 address of the input interface of this route
+ */
+ uint32_t GetInputInterface (void) const;
+ /**
+ * \return The number of output interfaces of this route
+ */
+ uint32_t GetNOutputInterfaces (void) const;
+ /**
+ * \param n interface index
+ * \return A specified output interface.
+ */
+ uint32_t GetOutputInterface (uint32_t n) const;
+ /**
+ * \return A vector of all of the output interfaces of this route.
+ */
+ std::vector<uint32_t> GetOutputInterfaces (void) const;
+ /**
+ * \return Ipv4MulticastRoutingTableEntry corresponding to the input parameters.
+ * \param origin Source address for the multicast route
+ * \param group Group destination address for the multicast route
+ * \param inputInterface Input interface that multicast datagram must be received on
+ * \param outputInterfaces vector of output interfaces to copy and forward the datagram to
+ */
+ static Ipv4MulticastRoutingTableEntry CreateMulticastRoute (Ipv4Address origin,
+ Ipv4Address group, uint32_t inputInterface,
+ std::vector<uint32_t> outputInterfaces);
+
+private:
+ Ipv4MulticastRoutingTableEntry (Ipv4Address origin, Ipv4Address group,
+ uint32_t inputInterface, std::vector<uint32_t> outputInterfaces);
+
+ Ipv4Address m_origin;
+ Ipv4Address m_group;
+ uint32_t m_inputInterface;
+ std::vector<uint32_t> m_outputInterfaces;
+};
+
+std::ostream& operator<< (std::ostream& os, Ipv4MulticastRoutingTableEntry const& route);
+
+}//namespace ns3
+
+#endif /* IPV4_ROUTING_TABLE_ENTRY_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/model/ipv4-static-routing.cc Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,729 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: George F. Riley<riley@ece.gatech.edu>
+// Gustavo Carneiro <gjc@inescporto.pt>
+
+#define NS_LOG_APPEND_CONTEXT \
+ if (m_ipv4 && m_ipv4->GetObject<Node> ()) { \
+ std::clog << Simulator::Now ().GetSeconds () \
+ << " [node " << m_ipv4->GetObject<Node> ()->GetId () << "] "; }
+
+#include "ns3/log.h"
+#include "ns3/packet.h"
+#include "ns3/node.h"
+#include "ns3/simulator.h"
+#include "ns3/ipv4-route.h"
+#include "ipv4-static-routing.h"
+#include "ipv4-routing-table-entry.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv4StaticRouting");
+
+using std::make_pair;
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv4StaticRouting);
+
+TypeId
+Ipv4StaticRouting::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::Ipv4StaticRouting")
+ .SetParent<Ipv4RoutingProtocol> ()
+ .AddConstructor<Ipv4StaticRouting> ()
+ ;
+ return tid;
+}
+
+Ipv4StaticRouting::Ipv4StaticRouting ()
+: m_ipv4 (0)
+{
+ NS_LOG_FUNCTION (this);
+}
+
+void
+Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ Ipv4Address nextHop,
+ uint32_t interface,
+ uint32_t metric)
+{
+ NS_LOG_FUNCTION (this << network << " " << networkMask << " " << nextHop << " " << interface << " " << metric);
+ Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
+ *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
+ networkMask,
+ nextHop,
+ interface);
+ m_networkRoutes.push_back (make_pair(route,metric));
+}
+
+void
+Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ uint32_t interface,
+ uint32_t metric)
+{
+ NS_LOG_FUNCTION (this << network << " " << networkMask << " " << interface << " " << metric);
+ Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
+ *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
+ networkMask,
+ interface);
+ m_networkRoutes.push_back (make_pair (route,metric));
+}
+
+void
+Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest,
+ Ipv4Address nextHop,
+ uint32_t interface,
+ uint32_t metric)
+{
+ NS_LOG_FUNCTION (this << dest << " " << nextHop << " " << interface << " " << metric);
+ AddNetworkRouteTo (dest, Ipv4Mask::GetOnes (), nextHop, interface, metric);
+}
+
+void
+Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest,
+ uint32_t interface,
+ uint32_t metric)
+{
+ NS_LOG_FUNCTION (this << dest << " " << interface << " " << metric);
+ AddNetworkRouteTo (dest, Ipv4Mask::GetOnes (), interface, metric);
+}
+
+void
+Ipv4StaticRouting::SetDefaultRoute (Ipv4Address nextHop,
+ uint32_t interface,
+ uint32_t metric)
+{
+ NS_LOG_FUNCTION (this << nextHop << " " << interface << " " << metric);
+ AddNetworkRouteTo (Ipv4Address ("0.0.0.0"), Ipv4Mask::GetZero (), nextHop, interface, metric);
+}
+
+void
+Ipv4StaticRouting::AddMulticastRoute(Ipv4Address origin,
+ Ipv4Address group,
+ uint32_t inputInterface,
+ std::vector<uint32_t> outputInterfaces)
+{
+ NS_LOG_FUNCTION (this << origin << " " << group << " " << inputInterface);
+ Ipv4MulticastRoutingTableEntry *route = new Ipv4MulticastRoutingTableEntry ();
+ *route = Ipv4MulticastRoutingTableEntry::CreateMulticastRoute (origin, group,
+ inputInterface, outputInterfaces);
+ m_multicastRoutes.push_back (route);
+}
+
+// default multicast routes are stored as a network route
+// these routes are _not_ consulted in the forwarding process-- only
+// for originating packets
+void
+Ipv4StaticRouting::SetDefaultMulticastRoute(uint32_t outputInterface)
+{
+ NS_LOG_FUNCTION (this << outputInterface);
+ Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
+ Ipv4Address network = Ipv4Address ("224.0.0.0");
+ Ipv4Mask networkMask = Ipv4Mask ("240.0.0.0");
+ *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
+ networkMask,
+ outputInterface);
+ m_networkRoutes.push_back (make_pair(route,0));
+}
+
+uint32_t
+Ipv4StaticRouting::GetNMulticastRoutes (void) const
+{
+ NS_LOG_FUNCTION (this);
+ return m_multicastRoutes.size ();
+}
+
+Ipv4MulticastRoutingTableEntry
+Ipv4StaticRouting::GetMulticastRoute (uint32_t index) const
+{
+ NS_LOG_FUNCTION (this << index);
+ NS_ASSERT_MSG(index < m_multicastRoutes.size (),
+ "Ipv4StaticRouting::GetMulticastRoute (): Index out of range");
+
+ if (index < m_multicastRoutes.size ())
+ {
+ uint32_t tmp = 0;
+ for (MulticastRoutesCI i = m_multicastRoutes.begin ();
+ i != m_multicastRoutes.end ();
+ i++)
+ {
+ if (tmp == index)
+ {
+ return *i;
+ }
+ tmp++;
+ }
+ }
+ return 0;
+}
+
+bool
+Ipv4StaticRouting::RemoveMulticastRoute(Ipv4Address origin,
+ Ipv4Address group,
+ uint32_t inputInterface)
+{
+ NS_LOG_FUNCTION (this << origin << " " << group << " " << inputInterface);
+ for (MulticastRoutesI i = m_multicastRoutes.begin ();
+ i != m_multicastRoutes.end ();
+ i++)
+ {
+ Ipv4MulticastRoutingTableEntry *route = *i;
+ if (origin == route->GetOrigin () &&
+ group == route->GetGroup () &&
+ inputInterface == route->GetInputInterface ())
+ {
+ delete *i;
+ m_multicastRoutes.erase (i);
+ return true;
+ }
+ }
+ return false;
+}
+
+void
+Ipv4StaticRouting::RemoveMulticastRoute(uint32_t index)
+{
+ NS_LOG_FUNCTION (this << index);
+ uint32_t tmp = 0;
+ for (MulticastRoutesI i = m_multicastRoutes.begin ();
+ i != m_multicastRoutes.end ();
+ i++)
+ {
+ if (tmp == index)
+ {
+ delete *i;
+ m_multicastRoutes.erase (i);
+ return;
+ }
+ tmp++;
+ }
+}
+
+Ptr<Ipv4Route>
+Ipv4StaticRouting::LookupStatic (Ipv4Address dest, Ptr<NetDevice> oif)
+{
+ NS_LOG_FUNCTION (this << dest << " " << oif);
+ Ptr<Ipv4Route> rtentry = 0;
+ uint16_t longest_mask = 0;
+ uint32_t shortest_metric = 0xffffffff;
+ /* when sending on local multicast, there have to be interface specified */
+ if (dest.IsLocalMulticast ())
+ {
+ NS_ASSERT_MSG (oif, "Try to send on link-local multicast address, and no interface index is given!");
+
+ rtentry = Create<Ipv4Route> ();
+ rtentry->SetDestination (dest);
+ rtentry->SetGateway (Ipv4Address::GetZero ());
+ rtentry->SetOutputDevice (oif);
+ rtentry->SetSource (m_ipv4->GetAddress (oif->GetIfIndex (), 0).GetLocal ());
+ return rtentry;
+ }
+
+
+ for (NetworkRoutesI i = m_networkRoutes.begin ();
+ i != m_networkRoutes.end ();
+ i++)
+ {
+ Ipv4RoutingTableEntry *j=i->first;
+ uint32_t metric =i->second;
+ Ipv4Mask mask = (j)->GetDestNetworkMask ();
+ uint16_t masklen = mask.GetPrefixLength ();
+ Ipv4Address entry = (j)->GetDestNetwork ();
+ NS_LOG_LOGIC ("Searching for route to " << dest << ", checking against route to " << entry << "/" << masklen);
+ if (mask.IsMatch (dest, entry))
+ {
+ NS_LOG_LOGIC ("Found global network route " << j << ", mask length " << masklen << ", metric " << metric);
+ if (oif != 0)
+ {
+ if (oif != m_ipv4->GetNetDevice (j->GetInterface ()))
+ {
+ NS_LOG_LOGIC ("Not on requested interface, skipping");
+ continue;
+ }
+ }
+ if (masklen < longest_mask) // Not interested if got shorter mask
+ {
+ NS_LOG_LOGIC ("Previous match longer, skipping");
+ continue;
+ }
+ if (masklen > longest_mask) // Reset metric if longer masklen
+ {
+ shortest_metric = 0xffffffff;
+ }
+ longest_mask = masklen;
+ if (metric > shortest_metric)
+ {
+ NS_LOG_LOGIC ("Equal mask length, but previous metric shorter, skipping");
+ continue;
+ }
+ shortest_metric = metric;
+ Ipv4RoutingTableEntry* route = (j);
+ uint32_t interfaceIdx = route->GetInterface ();
+ rtentry = Create<Ipv4Route> ();
+ rtentry->SetDestination (route->GetDest ());
+ rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetDest ()));
+ rtentry->SetGateway (route->GetGateway ());
+ rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
+ }
+ }
+ if (rtentry != 0)
+ {
+ NS_LOG_LOGIC ("Matching route via " << rtentry->GetGateway () << " at the end");
+ }
+ else
+ {
+ NS_LOG_LOGIC ("No matching route to " << dest << " found");
+ }
+ return rtentry;
+}
+
+Ptr<Ipv4MulticastRoute>
+Ipv4StaticRouting::LookupStatic (
+ Ipv4Address origin,
+ Ipv4Address group,
+ uint32_t interface)
+{
+ NS_LOG_FUNCTION (this << origin << " " << group << " " << interface);
+ Ptr<Ipv4MulticastRoute> mrtentry = 0;
+
+ for (MulticastRoutesI i = m_multicastRoutes.begin ();
+ i != m_multicastRoutes.end ();
+ i++)
+ {
+ Ipv4MulticastRoutingTableEntry *route = *i;
+//
+// We've been passed an origin address, a multicast group address and an
+// interface index. We have to decide if the current route in the list is
+// a match.
+//
+// The first case is the restrictive case where the origin, group and index
+// matches.
+//
+ if (origin == route->GetOrigin () && group == route->GetGroup ())
+ {
+ // Skipping this case (SSM) for now
+ NS_LOG_LOGIC ("Found multicast source specific route" << *i);
+ }
+ if (group == route->GetGroup ())
+ {
+ if (interface == Ipv4::IF_ANY ||
+ interface == route->GetInputInterface ())
+ {
+ NS_LOG_LOGIC ("Found multicast route" << *i);
+ mrtentry = Create<Ipv4MulticastRoute> ();
+ mrtentry->SetGroup (route->GetGroup ());
+ mrtentry->SetOrigin (route->GetOrigin ());
+ mrtentry->SetParent (route->GetInputInterface ());
+ for (uint32_t j = 0; j < route->GetNOutputInterfaces (); j++)
+ {
+ if (route->GetOutputInterface (j))
+ {
+ NS_LOG_LOGIC ("Setting output interface index " << route->GetOutputInterface (j));
+ mrtentry->SetOutputTtl (route->GetOutputInterface (j), Ipv4MulticastRoute::MAX_TTL - 1);
+ }
+ }
+ return mrtentry;
+ }
+ }
+ }
+ return mrtentry;
+}
+
+uint32_t
+Ipv4StaticRouting::GetNRoutes (void)
+{
+ NS_LOG_FUNCTION (this);
+ return m_networkRoutes.size ();;
+}
+
+Ipv4RoutingTableEntry
+Ipv4StaticRouting::GetDefaultRoute ()
+{
+ NS_LOG_FUNCTION (this);
+ // Basically a repeat of LookupStatic, retained for backward compatibility
+ Ipv4Address dest ("0.0.0.0");
+ uint32_t shortest_metric = 0xffffffff;
+ Ipv4RoutingTableEntry *result = 0;
+ for (NetworkRoutesI i = m_networkRoutes.begin ();
+ i != m_networkRoutes.end ();
+ i++)
+ {
+ Ipv4RoutingTableEntry *j = i->first;
+ uint32_t metric = i->second;
+ Ipv4Mask mask = (j)->GetDestNetworkMask ();
+ uint16_t masklen = mask.GetPrefixLength ();
+ Ipv4Address entry = (j)->GetDestNetwork ();
+ if (masklen != 0)
+ {
+ continue;
+ }
+ if (metric > shortest_metric)
+ {
+ continue;
+ }
+ shortest_metric = metric;
+ result = j;
+ }
+ if (result)
+ {
+ return result;
+ }
+ else
+ {
+ return Ipv4RoutingTableEntry ();
+ }
+}
+
+Ipv4RoutingTableEntry
+Ipv4StaticRouting::GetRoute (uint32_t index)
+{
+ NS_LOG_FUNCTION (this << index);
+ uint32_t tmp = 0;
+ for (NetworkRoutesI j = m_networkRoutes.begin ();
+ j != m_networkRoutes.end ();
+ j++)
+ {
+ if (tmp == index)
+ {
+ return j->first;
+ }
+ tmp++;
+ }
+ NS_ASSERT (false);
+ // quiet compiler.
+ return 0;
+}
+
+uint32_t
+Ipv4StaticRouting::GetMetric (uint32_t index)
+{
+ NS_LOG_FUNCTION (this << index);
+ uint32_t tmp = 0;
+ for (NetworkRoutesI j = m_networkRoutes.begin ();
+ j != m_networkRoutes.end ();
+ j++)
+ {
+ if (tmp == index)
+ {
+ return j->second;
+ }
+ tmp++;
+ }
+ NS_ASSERT (false);
+ // quiet compiler.
+ return 0;
+}
+void
+Ipv4StaticRouting::RemoveRoute (uint32_t index)
+{
+ NS_LOG_FUNCTION (this << index);
+ uint32_t tmp = 0;
+ for (NetworkRoutesI j = m_networkRoutes.begin ();
+ j != m_networkRoutes.end ();
+ j++)
+ {
+ if (tmp == index)
+ {
+ delete j->first;
+ m_networkRoutes.erase (j);
+ return;
+ }
+ tmp++;
+ }
+ NS_ASSERT (false);
+}
+
+Ptr<Ipv4Route>
+Ipv4StaticRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
+{
+ NS_LOG_FUNCTION (this << header << oif);
+ Ipv4Address destination = header.GetDestination ();
+ Ptr<Ipv4Route> rtentry = 0;
+
+ // Multicast goes here
+ if (destination.IsMulticast ())
+ {
+ // Note: Multicast routes for outbound packets are stored in the
+ // normal unicast table. An implication of this is that it is not
+ // possible to source multicast datagrams on multiple interfaces.
+ // This is a well-known property of sockets implementation on
+ // many Unix variants.
+ // So, we just log it and fall through to LookupStatic ()
+ NS_LOG_LOGIC ("RouteOutput()::Multicast destination");
+ }
+ rtentry = LookupStatic (destination, oif);
+ if (rtentry)
+ {
+ sockerr = Socket::ERROR_NOTERROR;
+ }
+ else
+ {
+ sockerr = Socket::ERROR_NOROUTETOHOST;
+ }
+ return rtentry;
+}
+
+bool
+Ipv4StaticRouting::RouteInput (Ptr<const Packet> p, const Ipv4Header &ipHeader, Ptr<const NetDevice> idev,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb)
+{
+ NS_LOG_FUNCTION (this << p << ipHeader << ipHeader.GetSource () << ipHeader.GetDestination () << idev);
+
+ NS_ASSERT (m_ipv4 != 0);
+ // Check if input device supports IP
+ NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
+ uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
+
+ // Multicast recognition; handle local delivery here
+ //
+ if (ipHeader.GetDestination ().IsMulticast ())
+ {
+ NS_LOG_LOGIC ("Multicast destination");
+ Ptr<Ipv4MulticastRoute> mrtentry = LookupStatic(ipHeader.GetSource (),
+ ipHeader.GetDestination (), m_ipv4->GetInterfaceForDevice (idev));
+
+ if (mrtentry)
+ {
+ NS_LOG_LOGIC ("Multicast route found");
+ mcb (mrtentry, p, ipHeader); // multicast forwarding callback
+ return true;
+ }
+ else
+ {
+ NS_LOG_LOGIC ("Multicast route not found");
+ return false; // Let other routing protocols try to handle this
+ }
+ }
+ if (ipHeader.GetDestination ().IsBroadcast ())
+ {
+ NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)");
+ // TODO: Local Deliver for broadcast
+ // TODO: Forward broadcast
+ }
+
+ NS_LOG_LOGIC ("Unicast destination");
+ // TODO: Configurable option to enable RFC 1222 Strong End System Model
+ // Right now, we will be permissive and allow a source to send us
+ // a packet to one of our other interface addresses; that is, the
+ // destination unicast address does not match one of the iif addresses,
+ // but we check our other interfaces. This could be an option
+ // (to remove the outer loop immediately below and just check iif).
+ for (uint32_t j = 0; j < m_ipv4->GetNInterfaces (); j++)
+ {
+ for (uint32_t i = 0; i < m_ipv4->GetNAddresses (j); i++)
+ {
+ Ipv4InterfaceAddress iaddr = m_ipv4->GetAddress (j, i);
+ Ipv4Address addr = iaddr.GetLocal ();
+ if (addr.IsEqual (ipHeader.GetDestination ()))
+ {
+ if (j == iif)
+ {
+ NS_LOG_LOGIC ("For me (destination " << addr << " match)");
+ }
+ else
+ {
+ NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << ipHeader.GetDestination ());
+ }
+ lcb (p, ipHeader, iif);
+ return true;
+ }
+ if (ipHeader.GetDestination ().IsEqual (iaddr.GetBroadcast ()))
+ {
+ NS_LOG_LOGIC ("For me (interface broadcast address)");
+ lcb (p, ipHeader, iif);
+ return true;
+ }
+ NS_LOG_LOGIC ("Address "<< addr << " not a match");
+ }
+ }
+ // Check if input device supports IP forwarding
+ if (m_ipv4->IsForwarding (iif) == false)
+ {
+ NS_LOG_LOGIC ("Forwarding disabled for this interface");
+ ecb (p, ipHeader, Socket::ERROR_NOROUTETOHOST);
+ return false;
+ }
+ // Next, try to find a route
+ Ptr<Ipv4Route> rtentry = LookupStatic (ipHeader.GetDestination ());
+ if (rtentry != 0)
+ {
+ NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
+ ucb (rtentry, p, ipHeader); // unicast forwarding callback
+ return true;
+ }
+ else
+ {
+ NS_LOG_LOGIC ("Did not find unicast destination- returning false");
+ return false; // Let other routing protocols try to handle this
+ }
+}
+
+Ipv4StaticRouting::~Ipv4StaticRouting ()
+{
+}
+
+void
+Ipv4StaticRouting::DoDispose (void)
+{
+ for (NetworkRoutesI j = m_networkRoutes.begin ();
+ j != m_networkRoutes.end ();
+ j = m_networkRoutes.erase (j))
+ {
+ delete (j->first);
+ }
+ for (MulticastRoutesI i = m_multicastRoutes.begin ();
+ i != m_multicastRoutes.end ();
+ i = m_multicastRoutes.erase (i))
+ {
+ delete (*i);
+ }
+ m_ipv4 = 0;
+ Ipv4RoutingProtocol::DoDispose ();
+}
+
+void
+Ipv4StaticRouting::NotifyInterfaceUp (uint32_t i)
+{
+ NS_LOG_FUNCTION (this << i);
+ // If interface address and network mask have been set, add a route
+ // to the network of the interface (like e.g. ifconfig does on a
+ // Linux box)
+ for (uint32_t j = 0; j < m_ipv4->GetNAddresses (i); j++)
+ {
+ if (m_ipv4->GetAddress (i,j).GetLocal () != Ipv4Address () &&
+ m_ipv4->GetAddress (i,j).GetMask () != Ipv4Mask () &&
+ m_ipv4->GetAddress (i,j).GetMask () != Ipv4Mask::GetOnes())
+ {
+ AddNetworkRouteTo (m_ipv4->GetAddress (i,j).GetLocal ().CombineMask (m_ipv4->GetAddress (i,j).GetMask ()),
+ m_ipv4->GetAddress (i,j).GetMask (), i);
+ }
+ }
+}
+
+void
+Ipv4StaticRouting::NotifyInterfaceDown (uint32_t i)
+{
+ NS_LOG_FUNCTION (this << i);
+ // Remove all static routes that are going through this interface
+ uint32_t j = 0;
+ while (j < GetNRoutes())
+ {
+ Ipv4RoutingTableEntry route = GetRoute (j);
+ if (route.GetInterface () == i)
+ {
+ RemoveRoute (j);
+ }
+ else
+ {
+ j++;
+ }
+ }
+}
+
+void
+Ipv4StaticRouting::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)
+{
+ NS_LOG_FUNCTION (this << interface << " " << address.GetLocal());
+ if (!m_ipv4->IsUp (interface))
+ {
+ return;
+ }
+
+ Ipv4Address networkAddress = address.GetLocal ().CombineMask (address.GetMask ());
+ Ipv4Mask networkMask = address.GetMask ();
+ if (address.GetLocal () != Ipv4Address () &&
+ address.GetMask () != Ipv4Mask ())
+ {
+ AddNetworkRouteTo (networkAddress,
+ networkMask, interface);
+ }
+}
+void
+Ipv4StaticRouting::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)
+{
+ NS_LOG_FUNCTION (this << interface << " " << address.GetLocal());
+ if (!m_ipv4->IsUp (interface))
+ {
+ return;
+ }
+ Ipv4Address networkAddress = address.GetLocal ().CombineMask (address.GetMask ());
+ Ipv4Mask networkMask = address.GetMask ();
+ // Remove all static routes that are going through this interface
+ // which reference this network
+ for (uint32_t j = 0; j < GetNRoutes (); j++)
+ {
+ Ipv4RoutingTableEntry route = GetRoute (j);
+ if (route.GetInterface () == interface &&
+ route.IsNetwork () &&
+ route.GetDestNetwork () == networkAddress &&
+ route.GetDestNetworkMask () == networkMask)
+ {
+ RemoveRoute (j);
+ }
+ }
+}
+
+void
+Ipv4StaticRouting::SetIpv4 (Ptr<Ipv4> ipv4)
+{
+ NS_LOG_FUNCTION (this << ipv4);
+ NS_ASSERT (m_ipv4 == 0 && ipv4 != 0);
+ m_ipv4 = ipv4;
+ for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
+ {
+ if (m_ipv4->IsUp (i))
+ {
+ NotifyInterfaceUp (i);
+ }
+ else
+ {
+ NotifyInterfaceDown (i);
+ }
+ }
+}
+
+Ipv4Address
+Ipv4StaticRouting::SourceAddressSelection (uint32_t interfaceIdx, Ipv4Address dest)
+{
+ NS_LOG_FUNCTION (this << interfaceIdx << " " << dest);
+ if (m_ipv4->GetNAddresses (interfaceIdx) == 1) // common case
+ {
+ return m_ipv4->GetAddress (interfaceIdx, 0).GetLocal ();
+ }
+ // no way to determine the scope of the destination, so adopt the
+ // following rule: pick the first available address (index 0) unless
+ // a subsequent address is on link (in which case, pick the primary
+ // address if there are multiple)
+ Ipv4Address candidate = m_ipv4->GetAddress (interfaceIdx, 0).GetLocal ();
+ for (uint32_t i = 0; i < m_ipv4->GetNAddresses (interfaceIdx); i++)
+ {
+ Ipv4InterfaceAddress test = m_ipv4->GetAddress (interfaceIdx, i);
+ if (test.GetLocal ().CombineMask (test.GetMask ()) == dest.CombineMask (test.GetMask ()))
+ {
+ if (test.IsSecondary () == false)
+ {
+ return test.GetLocal ();
+ }
+ }
+ }
+ return candidate;
+}
+
+}//namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/model/ipv4-static-routing.h Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,399 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 Georgia Tech Research Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: George F. Riley<riley@ece.gatech.edu>
+ * Gustavo Carneiro <gjc@inescporto.pt>
+ */
+
+#ifndef IPV4_STATIC_ROUTING_H
+#define IPV4_STATIC_ROUTING_H
+
+#include <list>
+#include <utility>
+#include <stdint.h>
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4-header.h"
+#include "ns3/socket.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv4.h"
+#include "ns3/ipv4-routing-protocol.h"
+
+namespace ns3 {
+
+class Packet;
+class NetDevice;
+class Ipv4Interface;
+class Ipv4Address;
+class Ipv4Header;
+class Ipv4RoutingTableEntry;
+class Ipv4MulticastRoutingTableEntry;
+class Node;
+
+/**
+ * \ingroup routing
+ * \defgroup ipv4StaticRouting Ipv4StaticRouting
+ */
+/**
+ * \ingroup ipv4StaticRouting
+ *
+ * \brief Static routing protocol for IP version 4 stacks.
+ *
+ * This class provides a basic set of methods for inserting static
+ * unicast and multicast routes into the Ipv4 routing system.
+ * This particular protocol is designed to be inserted into an
+ * Ipv4ListRouting protocol but can be used also as a standalone
+ * protocol.
+ *
+ * The Ipv4StaticRouting class inherits from the abstract base class
+ * Ipv4RoutingProtocol that defines the interface methods that a routing
+ * protocol must support.
+ *
+ * \see Ipv4RoutingProtocol
+ * \see Ipv4ListRouting
+ * \see Ipv4ListRouting::AddRoutingProtocol
+ */
+class Ipv4StaticRouting : public Ipv4RoutingProtocol
+{
+public:
+ static TypeId GetTypeId (void);
+
+ Ipv4StaticRouting ();
+ virtual ~Ipv4StaticRouting ();
+
+ 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,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb);
+
+ virtual void NotifyInterfaceUp (uint32_t interface);
+ virtual void NotifyInterfaceDown (uint32_t interface);
+ virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
+ virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
+ virtual void SetIpv4 (Ptr<Ipv4> ipv4);
+
+/**
+ * \brief Add a network route to the static routing table.
+ *
+ * \param network The Ipv4Address network for this route.
+ * \param networkMask The Ipv4Mask to extract the network.
+ * \param nextHop The next hop in the route to the destination network.
+ * \param interface The network interface index used to send packets to the
+ * destination.
+ * \param metric Metric of route in case of multiple routes to same destination
+ *
+ * \see Ipv4Address
+ */
+ void AddNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ Ipv4Address nextHop,
+ uint32_t interface,
+ uint32_t metric = 0);
+
+/**
+ * \brief Add a network route to the static routing table.
+ *
+ * \param network The Ipv4Address network for this route.
+ * \param networkMask The Ipv4Mask to extract the network.
+ * \param interface The network interface index used to send packets to the
+ * destination.
+ * \param metric Metric of route in case of multiple routes to same destination
+ *
+ * \see Ipv4Address
+ */
+ void AddNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ uint32_t interface,
+ uint32_t metric = 0);
+
+/**
+ * \brief Add a host route to the static routing table.
+ *
+ * \param dest The Ipv4Address destination for this route.
+ * \param nextHop The Ipv4Address of the next hop in the route.
+ * \param interface The network interface index used to send packets to the
+ * destination.
+ * \param metric Metric of route in case of multiple routes to same destination
+ *
+ * \see Ipv4Address
+ */
+ void AddHostRouteTo (Ipv4Address dest,
+ Ipv4Address nextHop,
+ uint32_t interface,
+ uint32_t metric = 0);
+/**
+ * \brief Add a host route to the static routing table.
+ *
+ * \param dest The Ipv4Address destination for this route.
+ * \param interface The network interface index used to send packets to the
+ * destination.
+ * \param metric Metric of route in case of multiple routes to same destination
+ *
+ * \see Ipv4Address
+ */
+ void AddHostRouteTo (Ipv4Address dest,
+ uint32_t interface,
+ uint32_t metric = 0);
+/**
+ * \brief Add a default route to the static routing table.
+ *
+ * This method tells the routing system what to do in the case where a specific
+ * route to a destination is not found. The system forwards packets to the
+ * specified node in the hope that it knows better how to route the packet.
+ *
+ * If the default route is set, it is returned as the selected route from
+ * LookupStatic irrespective of destination address if no specific route is
+ * found.
+ *
+ * \param nextHop The Ipv4Address to send packets to in the hope that they
+ * will be forwarded correctly.
+ * \param interface The network interface index used to send packets.
+ * \param metric Metric of route in case of multiple routes to same destination
+ *
+ * \see Ipv4Address
+ * \see Ipv4StaticRouting::Lookup
+ */
+ void SetDefaultRoute (Ipv4Address nextHop,
+ uint32_t interface,
+ uint32_t metric = 0);
+
+/**
+ * \brief Get the number of individual unicast routes that have been added
+ * to the routing table.
+ *
+ * \warning The default route counts as one of the routes.
+ */
+ uint32_t GetNRoutes (void);
+
+/**
+ * \brief Get the default route with lowest metric from the static routing table.
+ *
+ * \return If the default route is set, a pointer to that Ipv4RoutingTableEntry is
+ * returned, otherwise an empty routing table entry is returned.
+* If multiple default routes exist, the one with lowest metric is returned.
+ *
+ * \see Ipv4RoutingTableEntry
+ */
+ Ipv4RoutingTableEntry GetDefaultRoute (void);
+
+/**
+ * \brief Get a route from the static unicast routing table.
+ *
+ * Externally, the unicast static routing table appears simply as a table with
+ * n entries.
+ *
+ * \param i The index (into the routing table) of the route to retrieve.
+ * \return If route is set, a pointer to that Ipv4RoutingTableEntry is returned, otherwise
+ * a zero pointer is returned.
+ *
+ * \see Ipv4RoutingTableEntry
+ * \see Ipv4StaticRouting::RemoveRoute
+ */
+ Ipv4RoutingTableEntry GetRoute (uint32_t i);
+
+/**
+ * \brief Get a metric for route from the static unicast routing table.
+ *
+ * \param index The index (into the routing table) of the route to retrieve.
+ * \return If route is set, the metric is returned. If not, an infinity metric (0xffffffff) is returned
+ *
+ */
+ uint32_t GetMetric (uint32_t index);
+
+/**
+ * \brief Remove a route from the static unicast routing table.
+ *
+ * Externally, the unicast static routing table appears simply as a table with
+ * n entries.
+ *
+ * \param i The index (into the routing table) of the route to remove.
+ *
+ * \see Ipv4RoutingTableEntry
+ * \see Ipv4StaticRouting::GetRoute
+ * \see Ipv4StaticRouting::AddRoute
+ */
+ void RemoveRoute (uint32_t i);
+
+/**
+ * \brief Add a multicast route to the static routing table.
+ *
+ * A multicast route must specify an origin IP address, a multicast group and
+ * an input network interface index as conditions and provide a vector of
+ * output network interface indices over which packets matching the conditions
+ * are sent.
+ *
+ * Typically there are two main types of multicast routes: routes of the
+ * first kind are used during forwarding. All of the conditions must be
+ * explicitly provided. The second kind of routes are used to get packets off
+ * of a local node. The difference is in the input interface. Routes for
+ * forwarding will always have an explicit input interface specified. Routes
+ * off of a node will always set the input interface to a wildcard specified
+ * by the index Ipv4RoutingProtocol::INTERFACE_ANY.
+ *
+ * For routes off of a local node wildcards may be used in the origin and
+ * multicast group addresses. The wildcard used for Ipv4Adresses is that
+ * address returned by Ipv4Address::GetAny () -- typically "0.0.0.0". Usage
+ * of a wildcard allows one to specify default behavior to varying degrees.
+ *
+ * For example, making the origin address a wildcard, but leaving the
+ * multicast group specific allows one (in the case of a node with multiple
+ * interfaces) to create different routes using different output interfaces
+ * for each multicast group.
+ *
+ * If the origin and multicast addresses are made wildcards, you have created
+ * essentially a default multicast address that can forward to multiple
+ * interfaces. Compare this to the actual default multicast address that is
+ * limited to specifying a single output interface for compatibility with
+ * existing functionality in other systems.
+ *
+ * \param origin The Ipv4Address of the origin of packets for this route. May
+ * be Ipv4Address:GetAny for open groups.
+ * \param group The Ipv4Address of the multicast group or this route.
+ * \param inputInterface The input network interface index over which to
+ * expect packets destined for this route. May be
+ * Ipv4RoutingProtocol::INTERFACE_ANY for packets of local origin.
+ * \param outputInterfaces A vector of network interface indices used to specify
+ * how to send packets to the destination(s).
+ *
+ * \see Ipv4Address
+ */
+ void AddMulticastRoute (Ipv4Address origin,
+ Ipv4Address group,
+ uint32_t inputInterface,
+ std::vector<uint32_t> outputInterfaces);
+
+/**
+ * \brief Add a default multicast route to the static routing table.
+ *
+ * This is the multicast equivalent of the unicast version SetDefaultRoute.
+ * We tell the routing system what to do in the case where a specific route
+ * to a destination multicast group is not found. The system forwards
+ * packets out the specified interface in the hope that "something out there"
+ * knows better how to route the packet. This method is only used in
+ * initially sending packets off of a host. The default multicast route is
+ * not consulted during forwarding -- exact routes must be specified using
+ * AddMulticastRoute for that case.
+ *
+ * Since we're basically sending packets to some entity we think may know
+ * better what to do, we don't pay attention to "subtleties" like origin
+ * address, nor do we worry about forwarding out multiple interfaces. If the
+ * default multicast route is set, it is returned as the selected route from
+ * LookupStatic irrespective of origin or multicast group if another specific
+ * route is not found.
+ *
+ * \param outputInterface The network interface index used to specify where
+ * to send packets in the case of unknown routes.
+ *
+ * \see Ipv4Address
+ */
+ void SetDefaultMulticastRoute (uint32_t outputInterface);
+
+/**
+ * \brief Get the number of individual multicast routes that have been added
+ * to the routing table.
+ *
+ * \warning The default multicast route counts as one of the routes.
+ */
+ uint32_t GetNMulticastRoutes (void) const;
+
+/**
+ * \brief Get a route from the static multicast routing table.
+ *
+ * Externally, the multicast static routing table appears simply as a table
+ * with n entries.
+ *
+ * \param i The index (into the routing table) of the multicast route to
+ * retrieve.
+ * \return If route \e i is set, a pointer to that Ipv4MulticastRoutingTableEntry is
+ * returned, otherwise a zero pointer is returned.
+ *
+ * \see Ipv4MulticastRoutingTableEntry
+ * \see Ipv4StaticRouting::RemoveRoute
+ */
+ Ipv4MulticastRoutingTableEntry GetMulticastRoute (uint32_t i) const;
+
+/**
+ * \brief Remove a route from the static multicast routing table.
+ *
+ * Externally, the multicast static routing table appears simply as a table
+ * with n entries.
+ * This method causes the multicast routing table to be searched for the first
+ * route that matches the parameters and removes it.
+ *
+ * Wildcards may be provided to this function, but the wildcards are used to
+ * exactly match wildcards in the routes (see AddMulticastRoute). That is,
+ * calling RemoveMulticastRoute with the origin set to "0.0.0.0" will not
+ * remove routes with any address in the origin, but will only remove routes
+ * with "0.0.0.0" set as the the origin.
+ *
+ * \param origin The IP address specified as the origin of packets for the
+ * route.
+ * \param group The IP address specified as the multicast group address of
+ * the route.
+ * \param inputInterface The network interface index specified as the expected
+ * input interface for the route.
+ * \returns true if a route was found and removed, false otherwise.
+ *
+ * \see Ipv4MulticastRoutingTableEntry
+ * \see Ipv4StaticRouting::AddMulticastRoute
+ */
+ bool RemoveMulticastRoute (Ipv4Address origin,
+ Ipv4Address group,
+ uint32_t inputInterface);
+
+/**
+ * \brief Remove a route from the static multicast routing table.
+ *
+ * Externally, the multicast static routing table appears simply as a table
+ * with n entries.
+ *
+ * \param index The index (into the multicast routing table) of the route to
+ * remove.
+ *
+ * \see Ipv4RoutingTableEntry
+ * \see Ipv4StaticRouting::GetRoute
+ * \see Ipv4StaticRouting::AddRoute
+ */
+ void RemoveMulticastRoute (uint32_t index);
+
+protected:
+ virtual void DoDispose (void);
+
+private:
+ typedef std::list<std::pair <Ipv4RoutingTableEntry *, uint32_t> > NetworkRoutes;
+ typedef std::list<std::pair <Ipv4RoutingTableEntry *, uint32_t> >::const_iterator NetworkRoutesCI;
+ typedef std::list<std::pair <Ipv4RoutingTableEntry *, uint32_t> >::iterator NetworkRoutesI;
+
+ typedef std::list<Ipv4MulticastRoutingTableEntry *> MulticastRoutes;
+ typedef std::list<Ipv4MulticastRoutingTableEntry *>::const_iterator MulticastRoutesCI;
+ typedef std::list<Ipv4MulticastRoutingTableEntry *>::iterator MulticastRoutesI;
+
+ Ptr<Ipv4Route> LookupStatic (Ipv4Address dest, Ptr<NetDevice> oif = 0);
+ Ptr<Ipv4MulticastRoute> LookupStatic (Ipv4Address origin, Ipv4Address group,
+ uint32_t interface);
+
+ Ipv4Address SourceAddressSelection (uint32_t interface, Ipv4Address dest);
+
+ NetworkRoutes m_networkRoutes;
+ MulticastRoutes m_multicastRoutes;
+
+ Ptr<Ipv4> m_ipv4;
+};
+
+} // Namespace ns3
+
+#endif /* IPV4_STATIC_ROUTING_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/model/ipv6-routing-table-entry.cc Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,331 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include "ns3/assert.h"
+
+#include "ipv6-routing-table-entry.h"
+
+namespace ns3
+{
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry ()
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6RoutingTableEntry const& route)
+ : m_dest (route.m_dest),
+ m_destNetworkPrefix (route.m_destNetworkPrefix),
+ m_gateway (route.m_gateway),
+ m_interface (route.m_interface),
+ m_prefixToUse (route.m_prefixToUse)
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6RoutingTableEntry const* route)
+ : m_dest (route->m_dest),
+ m_destNetworkPrefix (route->m_destNetworkPrefix),
+ m_gateway (route->m_gateway),
+ m_interface (route->m_interface),
+ m_prefixToUse (route->m_prefixToUse)
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address dest, Ipv6Address gateway, uint32_t interface)
+ : m_dest (dest),
+ m_destNetworkPrefix (Ipv6Prefix::GetZero ()),
+ m_gateway (gateway),
+ m_interface (interface),
+ m_prefixToUse (Ipv6Address ("::"))
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address dest, uint32_t interface)
+ : m_dest (dest),
+ m_destNetworkPrefix (Ipv6Prefix::GetOnes ()),
+ m_gateway (Ipv6Address::GetZero ()),
+ m_interface (interface),
+ m_prefixToUse (Ipv6Address ("::"))
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address gateway, uint32_t interface, Ipv6Address prefixToUse)
+ : m_dest (network),
+ m_destNetworkPrefix (networkPrefix),
+ m_gateway (gateway),
+ m_interface (interface),
+ m_prefixToUse (prefixToUse)
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address gateway, uint32_t interface)
+ : m_dest (network),
+ m_destNetworkPrefix (networkPrefix),
+ m_gateway (gateway),
+ m_interface (interface),
+ m_prefixToUse (Ipv6Address::GetZero ())
+{
+}
+
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, Ipv6Address prefixToUse)
+ : m_dest (network),
+ m_destNetworkPrefix (networkPrefix),
+ m_gateway (Ipv6Address::GetZero ()),
+ m_interface (interface),
+ m_prefixToUse (prefixToUse)
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface)
+ : m_dest (network),
+ m_destNetworkPrefix (networkPrefix),
+ m_gateway (Ipv6Address::GetZero ()),
+ m_interface (interface),
+ m_prefixToUse (Ipv6Address ("::"))
+{
+}
+
+Ipv6RoutingTableEntry::~Ipv6RoutingTableEntry ()
+{
+}
+
+bool Ipv6RoutingTableEntry::IsHost () const
+{
+ if (m_destNetworkPrefix.IsEqual (Ipv6Prefix::GetOnes ()))
+ {
+ return true;
+ }
+ return false;
+}
+
+Ipv6Address Ipv6RoutingTableEntry::GetDest () const
+{
+ return m_dest;
+}
+
+Ipv6Address Ipv6RoutingTableEntry::GetPrefixToUse () const
+{
+ return m_prefixToUse;
+}
+
+void Ipv6RoutingTableEntry::SetPrefixToUse (Ipv6Address prefix)
+{
+ m_prefixToUse = prefix;
+}
+
+bool Ipv6RoutingTableEntry::IsNetwork () const
+{
+ return !IsHost ();
+}
+
+bool Ipv6RoutingTableEntry::IsDefault () const
+{
+ if (m_dest.IsEqual (Ipv6Address::GetZero ()))
+ {
+ return true;
+ }
+ return false;
+}
+
+Ipv6Address Ipv6RoutingTableEntry::GetDestNetwork () const
+{
+ return m_dest;
+}
+
+Ipv6Prefix Ipv6RoutingTableEntry::GetDestNetworkPrefix () const
+{
+ return m_destNetworkPrefix;
+}
+
+bool Ipv6RoutingTableEntry::IsGateway () const
+{
+ if (m_gateway.IsEqual (Ipv6Address::GetZero ()))
+ {
+ return false;
+ }
+ return true;
+}
+
+Ipv6Address Ipv6RoutingTableEntry::GetGateway () const
+{
+ return m_gateway;
+}
+
+Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+ return Ipv6RoutingTableEntry (dest, Ipv6Prefix::GetOnes (), nextHop, interface, prefixToUse);
+}
+
+Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateHostRouteTo (Ipv6Address dest, uint32_t interface)
+{
+ return Ipv6RoutingTableEntry (dest, interface);
+}
+
+Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface)
+{
+ return Ipv6RoutingTableEntry (network, networkPrefix, nextHop, interface);
+}
+
+Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+ return Ipv6RoutingTableEntry (network, networkPrefix, nextHop, interface, prefixToUse);
+}
+
+Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface)
+{
+ return Ipv6RoutingTableEntry (network, networkPrefix, interface, network);
+}
+
+Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateDefaultRoute (Ipv6Address nextHop, uint32_t interface)
+{
+ return Ipv6RoutingTableEntry (Ipv6Address::GetZero (), nextHop, interface);
+}
+
+uint32_t Ipv6RoutingTableEntry::GetInterface () const
+{
+ return m_interface;
+}
+
+std::ostream& operator<< (std::ostream& os, Ipv6RoutingTableEntry const& route)
+{
+ if (route.IsDefault ())
+ {
+ NS_ASSERT (route.IsGateway ());
+ os << "default out =" << route.GetInterface () << ", next hop =" << route.GetGateway ();
+ }
+ else if (route.IsHost ())
+ {
+ if (route.IsGateway ())
+ {
+ os << "host ="<< route.GetDest () <<
+ ", out =" << route.GetInterface () <<
+ ", next hop =" << route.GetGateway ();
+ }
+ else
+ {
+ os << "host =" << route.GetDest () <<
+ ", out =" << route.GetInterface ();
+ }
+ }
+ else if (route.IsNetwork ())
+ {
+ if (route.IsGateway ())
+ {
+ os << "network =" << route.GetDestNetwork () <<
+ ", mask =" << route.GetDestNetworkPrefix () <<
+ ",out =" << route.GetInterface () <<
+ ", next hop =" << route.GetGateway ();
+ }
+ else
+ {
+ os << "network =" << route.GetDestNetwork () <<
+ ", mask =" << route.GetDestNetworkPrefix () <<
+ ",out =" << route.GetInterface ();
+ }
+ }
+ else
+ {
+ NS_ASSERT (false);
+ }
+ return os;
+}
+
+Ipv6MulticastRoutingTableEntry::Ipv6MulticastRoutingTableEntry ()
+{
+}
+
+Ipv6MulticastRoutingTableEntry::Ipv6MulticastRoutingTableEntry (Ipv6MulticastRoutingTableEntry const & route)
+ : m_origin (route.m_origin),
+ m_group (route.m_group),
+ m_inputInterface (route.m_inputInterface),
+ m_outputInterfaces (route.m_outputInterfaces)
+{
+}
+
+Ipv6MulticastRoutingTableEntry::Ipv6MulticastRoutingTableEntry (Ipv6MulticastRoutingTableEntry const* route)
+ : m_origin (route->m_origin),
+ m_group (route->m_group),
+ m_inputInterface (route->m_inputInterface),
+ m_outputInterfaces (route->m_outputInterfaces)
+{
+}
+
+Ipv6MulticastRoutingTableEntry::Ipv6MulticastRoutingTableEntry (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
+ : m_origin (origin),
+ m_group (group),
+ m_inputInterface (inputInterface),
+ m_outputInterfaces (outputInterfaces)
+{
+}
+
+Ipv6Address Ipv6MulticastRoutingTableEntry::GetOrigin () const
+{
+ return m_origin;
+}
+
+Ipv6Address Ipv6MulticastRoutingTableEntry::GetGroup () const
+{
+ return m_group;
+}
+
+uint32_t Ipv6MulticastRoutingTableEntry::GetInputInterface () const
+{
+ return m_inputInterface;
+}
+
+uint32_t Ipv6MulticastRoutingTableEntry::GetNOutputInterfaces () const
+{
+ return m_outputInterfaces.size ();
+}
+
+uint32_t Ipv6MulticastRoutingTableEntry::GetOutputInterface (uint32_t n) const
+{
+ NS_ASSERT_MSG (n < m_outputInterfaces.size (), "Ipv6MulticastRoutingTableEntry::GetOutputInterface () : index out of bounds");
+
+ return m_outputInterfaces[n];
+}
+
+std::vector <uint32_t> Ipv6MulticastRoutingTableEntry::GetOutputInterfaces () const
+{
+ return m_outputInterfaces;
+}
+
+Ipv6MulticastRoutingTableEntry Ipv6MulticastRoutingTableEntry::CreateMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
+{
+ return Ipv6MulticastRoutingTableEntry (origin, group, inputInterface, outputInterfaces);
+}
+
+std::ostream& operator<< (std::ostream& os, Ipv6MulticastRoutingTableEntry const& route)
+{
+ os << "origin =" << route.GetOrigin () <<
+ ", group =" << route.GetGroup () <<
+ ", input interface =" << route.GetInputInterface () <<
+ ", output interfaces =";
+
+ for (uint32_t i = 0; i < route.GetNOutputInterfaces (); ++i)
+ {
+ os << route.GetOutputInterface (i) << " ";
+ }
+
+ return os;
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/model/ipv6-routing-table-entry.h Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,372 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef IPV6_ROUTING_TABLE_ENTRY_H
+#define IPV6_ROUTING_TABLE_ENTRY_H
+
+#include <list>
+#include <vector>
+#include <ostream>
+
+#include "ns3/ipv6-address.h"
+
+namespace ns3
+{
+
+/**
+ * \class Ipv6RoutingTableEntry
+ * \brief A record of an IPv6 route.
+ */
+class Ipv6RoutingTableEntry
+{
+public:
+ /**
+ * \brief Constructor.
+ */
+ Ipv6RoutingTableEntry ();
+
+ /**
+ * \brief Copy constructor.
+ * \param route the route to copy
+ */
+ Ipv6RoutingTableEntry (Ipv6RoutingTableEntry const & route);
+
+ /**
+ * \brief Copy constructor.
+ * \param route the route to copy
+ */
+ Ipv6RoutingTableEntry (Ipv6RoutingTableEntry const* route);
+
+ /**
+ * \brief Destructor
+ */
+ ~Ipv6RoutingTableEntry ();
+
+ /**
+ * \brief Is the route entry correspond to a host ?
+ * \return true if the route is a host, false otherwise
+ */
+ bool IsHost () const;
+
+ /**
+ * \brief Get the destination.
+ * \return the IPv6 address of the destination of this route
+ */
+ Ipv6Address GetDest () const;
+
+ /**
+ * \brief Get the prefix to use (for multihomed link).
+ * \return prefix address to use
+ */
+ Ipv6Address GetPrefixToUse () const;
+
+ /**
+ * \brief Set the prefix to use.
+ * \param prefix prefix to use
+ */
+ void SetPrefixToUse (Ipv6Address prefix);
+
+ /**
+ * \brief Is the route entry correspond to a network ?
+ * \return true if the route is a network, false otherwise
+ */
+ bool IsNetwork () const;
+
+ /**
+ * \brief Get the destination network.
+ * \return the destination network
+ */
+ Ipv6Address GetDestNetwork () const;
+
+ /**
+ * \brief Get the destination prefix.
+ * \return the destination prefix
+ */
+ Ipv6Prefix GetDestNetworkPrefix () const;
+
+ /**
+ * \brief Is it the default route ?
+ * \return true if this route is a default route, false otherwise
+ */
+ bool IsDefault () const;
+
+ /**
+ * \brief Is it the gateway ?
+ * \return true if this route is a gateway, false otherwise
+ */
+ bool IsGateway () const;
+
+ /**
+ * \brief Get the gateway.
+ * \return the IPv6 address of the gateway
+ */
+ Ipv6Address GetGateway () const;
+
+ /**
+ * \brief Get the interface index.
+ * \return the index of the interface
+ */
+ uint32_t GetInterface () const;
+
+ /**
+ * \brief Create a route to a host.
+ * \param dest destination address
+ * \param nextHop next hop address to route the packet
+ * \param interface interface index
+ * \param prefixToUse prefix that should be used for source address for this destination
+ * \return IPv6Route object
+ */
+ static Ipv6RoutingTableEntry CreateHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address ());
+
+ /**
+ * \brief Create a route to a host.
+ * \param dest destination address
+ * \param interface interface index
+ * \return IPv6Route object
+ */
+ static Ipv6RoutingTableEntry CreateHostRouteTo (Ipv6Address dest, uint32_t interface);
+
+ /**
+ * \brief Create a route to a network.
+ * \param network network address
+ * \param networkPrefix network prefix
+ * \param nextHop next hop address to route the packet
+ * \param interface interface index
+ * \return IPv6Route object
+ */
+ static Ipv6RoutingTableEntry CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface);
+
+ /**
+ * \brief Create a route to a network.
+ * \param network network address
+ * \param networkPrefix network prefix
+ * \param nextHop next hop address to route the packet
+ * \param interface interface index
+ * \param prefixToUse prefix that should be used for source address for this destination
+ * \return IPv6Route object
+ */
+ static Ipv6RoutingTableEntry CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse);
+
+ /**
+ * \brief Create a route to a network.
+ * \param network network address
+ * \param networkPrefix network prefix
+ * \param interface interface index
+ * \return IPv6Route object
+ */
+ static Ipv6RoutingTableEntry CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface);
+
+ /**
+ * \brief Create a default route.
+ * \param nextHop next hop address to route the packet
+ * \param interface interface index
+ * \return IPv6Route object
+ */
+ static Ipv6RoutingTableEntry CreateDefaultRoute (Ipv6Address nextHop, uint32_t interface);
+
+private:
+ /**
+ * \brief Constructor.
+ * \param network network address
+ * \param prefix network prefix
+ * \param gateway the gateway
+ * \param interface the interface index
+ */
+ Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix prefix, Ipv6Address gateway, uint32_t interface);
+
+ /**
+ * \brief Constructor.
+ * \param network network address
+ * \param prefix network prefix
+ * \param interface the interface index
+ * \param prefixToUse prefix to use
+ */
+ Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix prefix, uint32_t interface, Ipv6Address prefixToUse);
+
+ /**
+ * \brief Constructor.
+ * \param network network address
+ * \param prefix network prefix
+ * \param gateway the gateway
+ * \param interface the interface index
+ * \param prefixToUse prefix to use
+ */
+ Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix prefix, Ipv6Address gateway, uint32_t interface, Ipv6Address prefixToUse);
+
+ /**
+ * \brief Constructor.
+ * \param dest destination address
+ * \param prefix destination prefix
+ * \param interface interface index
+ */
+ Ipv6RoutingTableEntry (Ipv6Address dest, Ipv6Prefix prefix, uint32_t interface);
+
+ /**
+ * \brief Constructor.
+ * \param dest destination address
+ * \param gateway the gateway
+ * \param interface interface index
+ */
+ Ipv6RoutingTableEntry (Ipv6Address dest, Ipv6Address gateway, uint32_t interface);
+
+ /**
+ * \brief Constructor.
+ * \param dest destination address
+ * \param interface interface index
+ */
+ Ipv6RoutingTableEntry (Ipv6Address dest, uint32_t interface);
+
+ /**
+ * \brief IPv6 address of the destination.
+ */
+ Ipv6Address m_dest;
+
+ /**
+ * \brief IPv6 prefix of the destination
+ */
+ Ipv6Prefix m_destNetworkPrefix;
+
+ /**
+ * \brief IPv6 address of the gateway.
+ */
+ Ipv6Address m_gateway;
+
+ /**
+ * \brief The interface index.
+ */
+ uint32_t m_interface;
+
+ /**
+ * \brief Prefix to use.
+ */
+ Ipv6Address m_prefixToUse;
+
+};
+
+std::ostream& operator<< (std::ostream& os, Ipv6RoutingTableEntry const& route);
+
+/**
+ * \class Ipv6MulticastRoutingTableEntry
+ * \brief A record of an IPv6 multicast route.
+ */
+class Ipv6MulticastRoutingTableEntry
+{
+public:
+ /**
+ * \brief Constructor.
+ */
+ Ipv6MulticastRoutingTableEntry ();
+
+ /**
+ * \brief Copy constructor.
+ * \param route the route to copy
+ */
+ Ipv6MulticastRoutingTableEntry (Ipv6MulticastRoutingTableEntry const & route);
+
+ /**
+ * \brief Copy constructor.
+ * \param route the route to copy
+ */
+ Ipv6MulticastRoutingTableEntry (Ipv6MulticastRoutingTableEntry const* route);
+
+ /**
+ * \brief Get the source of this route
+ * \return IPv6 address of the source of this route
+ */
+ Ipv6Address GetOrigin () const;
+
+ /**
+ * \brief Get the group.
+ * \return IPv6 address of the multicast group of this route
+ */
+ Ipv6Address GetGroup () const;
+
+ /**
+ * \brief Get the input interface address.
+ * \return input interface index
+ */
+ uint32_t GetInputInterface () const;
+
+ /**
+ * \brief Get the number of output interfaces of this route.
+ * \return number of output interfaces of this route.
+ */
+ uint32_t GetNOutputInterfaces () const;
+
+ /**
+ * \brief Get a specified output interface.
+ * \param n index
+ * \return a specified output interface
+ */
+ uint32_t GetOutputInterface (uint32_t n) const;
+
+ /**
+ * \brief Get all of the output interfaces of this route.
+ * \return a vector of all output interfaces of this route
+ */
+ std::vector<uint32_t> GetOutputInterfaces () const;
+
+ /**
+ * \brief Create a multicast route.
+ * \param origin IPv6 address of the origin source
+ * \param group Ipv6Address of the group
+ * \param inputInterface interface number
+ * \param outputInterfaces list of output interface number
+ * \return a multicast route
+ */
+ static Ipv6MulticastRoutingTableEntry CreateMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces);
+
+private:
+ /**
+ * \brief Constructor.
+ * \param origin IPv6 address of the source
+ * \param group IPv6 address of the group
+ * \param inputInterface interface number
+ * \param outputInterfaces list of output interface number
+ */
+ Ipv6MulticastRoutingTableEntry (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces);
+
+ /**
+ * \brief The IPv6 address of the source.
+ */
+ Ipv6Address m_origin;
+
+ /**
+ * \brief The IPv6 address of the group.
+ */
+ Ipv6Address m_group;
+
+ /**
+ * \brief The input interface.
+ */
+ uint32_t m_inputInterface;
+
+ /**
+ * \brief The output interfaces.
+ */
+ std::vector<uint32_t> m_outputInterfaces;
+};
+
+std::ostream& operator<< (std::ostream& os, Ipv6MulticastRoutingTableEntry const& route);
+
+} /* namespace ns3 */
+
+#endif /* IPV6_ROUTING_TABLE_ENTRY_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/model/ipv6-static-routing.cc Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,758 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include "ns3/log.h"
+#include "ns3/packet.h"
+#include "ns3/ipv6-route.h"
+#include "ns3/net-device.h"
+
+#include "ipv6-static-routing.h"
+#include "ipv6-routing-table-entry.h"
+
+namespace ns3
+{
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6StaticRouting");
+NS_OBJECT_ENSURE_REGISTERED (Ipv6StaticRouting);
+
+TypeId Ipv6StaticRouting::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6StaticRouting")
+ .SetParent<Ipv6RoutingProtocol> ()
+ .AddConstructor<Ipv6StaticRouting> ()
+ ;
+ return tid;
+}
+
+Ipv6StaticRouting::Ipv6StaticRouting ()
+ : m_ipv6 (0)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6StaticRouting::~Ipv6StaticRouting ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+void Ipv6StaticRouting::SetIpv6 (Ptr<Ipv6> ipv6)
+{
+ NS_LOG_FUNCTION (this << ipv6);
+ NS_ASSERT (m_ipv6 == 0 && ipv6 != 0);
+ uint32_t i = 0;
+ m_ipv6 = ipv6;
+
+ for (i = 0 ; i < m_ipv6->GetNInterfaces () ; i++)
+ {
+ if (m_ipv6->IsUp (i))
+ {
+ NotifyInterfaceUp (i);
+ }
+ else
+ {
+ NotifyInterfaceDown (i);
+ }
+ }
+}
+
+void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
+{
+ NS_LOG_FUNCTION (this << dst << nextHop << interface << prefixToUse << metric);
+ AddNetworkRouteTo (dst, Ipv6Prefix::GetOnes (), nextHop, interface, prefixToUse, metric);
+}
+
+void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, uint32_t interface, uint32_t metric)
+{
+ NS_LOG_FUNCTION (this << dst << interface << metric);
+ AddNetworkRouteTo (dst, Ipv6Prefix::GetOnes (), interface, metric);
+}
+
+void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, uint32_t metric)
+{
+ NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << metric);
+ Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
+ *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface);
+ m_networkRoutes.push_back (std::make_pair (route, metric));
+}
+
+void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
+{
+ NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << prefixToUse << metric);
+ Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
+ *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface, prefixToUse);
+ m_networkRoutes.push_back (std::make_pair (route, metric));
+}
+
+void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, uint32_t metric)
+{
+ NS_LOG_FUNCTION (this << network << networkPrefix << interface);
+ Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
+ *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, interface);
+ m_networkRoutes.push_back (std::make_pair (route, metric));
+}
+
+void Ipv6StaticRouting::SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
+{
+ NS_LOG_FUNCTION (this << nextHop << interface << prefixToUse);
+ AddNetworkRouteTo (Ipv6Address ("::"), Ipv6Prefix::GetZero (), nextHop, interface, prefixToUse, metric);
+}
+
+void Ipv6StaticRouting::AddMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
+{
+ NS_LOG_FUNCTION (this << origin << group << inputInterface);
+ Ipv6MulticastRoutingTableEntry* route = new Ipv6MulticastRoutingTableEntry ();
+ *route = Ipv6MulticastRoutingTableEntry::CreateMulticastRoute (origin, group, inputInterface, outputInterfaces);
+ m_multicastRoutes.push_back (route);
+}
+
+void Ipv6StaticRouting::SetDefaultMulticastRoute (uint32_t outputInterface)
+{
+ NS_LOG_FUNCTION (this << outputInterface);
+ Ipv6RoutingTableEntry *route = new Ipv6RoutingTableEntry ();
+ Ipv6Address network = Ipv6Address ("ff00::"); /* RFC 3513 */
+ Ipv6Prefix networkMask = Ipv6Prefix (8);
+ *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkMask, outputInterface);
+ m_networkRoutes.push_back (std::make_pair (route, 0));
+}
+
+uint32_t Ipv6StaticRouting::GetNMulticastRoutes () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_multicastRoutes.size ();
+}
+
+Ipv6MulticastRoutingTableEntry Ipv6StaticRouting::GetMulticastRoute (uint32_t index) const
+{
+ NS_LOG_FUNCTION (this << index);
+ NS_ASSERT_MSG (index < m_multicastRoutes.size (), "Ipv6StaticRouting::GetMulticastRoute () : Index out of range");
+
+ if (index < m_multicastRoutes.size ())
+ {
+ uint32_t tmp = 0;
+ for (MulticastRoutesCI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i++)
+ {
+ if (tmp == index)
+ {
+ return *i;
+ }
+ tmp++;
+ }
+ }
+ return 0;
+}
+
+bool Ipv6StaticRouting::RemoveMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface)
+{
+ NS_LOG_FUNCTION (this << origin << group << inputInterface);
+ for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
+ {
+ Ipv6MulticastRoutingTableEntry *route = *i;
+ if (origin == route->GetOrigin () &&
+ group == route->GetGroup () &&
+ inputInterface == route->GetInputInterface ())
+ {
+ delete *i;
+ m_multicastRoutes.erase (i);
+ return true;
+ }
+ }
+ return false;
+}
+
+void Ipv6StaticRouting::RemoveMulticastRoute (uint32_t index)
+{
+ NS_LOG_FUNCTION (this << index);
+ uint32_t tmp = 0;
+
+ for (MulticastRoutesI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i++)
+ {
+ if (tmp == index)
+ {
+ delete *i;
+ m_multicastRoutes.erase (i);
+ return;
+ }
+ tmp++;
+ }
+}
+
+bool Ipv6StaticRouting::HasNetworkDest (Ipv6Address network, uint32_t interfaceIndex)
+{
+ NS_LOG_FUNCTION (this << network << interfaceIndex);
+
+ /* in the network table */
+ for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
+ {
+ Ipv6RoutingTableEntry* rtentry = j->first;
+ Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
+ Ipv6Address entry = rtentry->GetDestNetwork ();
+
+ if (prefix.IsMatch (network, entry) && rtentry->GetInterface () == interfaceIndex)
+ {
+ return true;
+ }
+ }
+
+ /* beuh!!! not route at all */
+ return false;
+}
+
+Ptr<Ipv6Route> Ipv6StaticRouting::LookupStatic (Ipv6Address dst, Ptr<NetDevice> interface)
+{
+ NS_LOG_FUNCTION (this << dst << interface);
+ Ptr<Ipv6Route> rtentry = 0;
+ uint16_t longestMask = 0;
+ uint32_t shortestMetric = 0xffffffff;
+
+ /* when sending on link-local multicast, there have to be interface specified */
+ if (dst == Ipv6Address::GetAllNodesMulticast () || dst.IsSolicitedMulticast () ||
+ dst == Ipv6Address::GetAllRoutersMulticast () || dst == Ipv6Address::GetAllHostsMulticast ())
+ {
+ NS_ASSERT_MSG (interface, "Try to send on link-local multicast address, and no interface index is given!");
+ rtentry = Create<Ipv6Route> ();
+ rtentry->SetSource (SourceAddressSelection (m_ipv6->GetInterfaceForDevice (interface), dst));
+ rtentry->SetDestination (dst);
+ rtentry->SetGateway (Ipv6Address::GetZero ());
+ rtentry->SetOutputDevice (interface);
+ return rtentry;
+ }
+
+ for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
+ {
+ Ipv6RoutingTableEntry* j = it->first;
+ uint32_t metric = it->second;
+ Ipv6Prefix mask = j->GetDestNetworkPrefix ();
+ uint16_t maskLen = mask.GetPrefixLength ();
+ Ipv6Address entry = j->GetDestNetwork ();
+
+ NS_LOG_LOGIC ("Searching for route to " << dst << ", mask length " << maskLen << ", metric " << metric);
+
+ if (mask.IsMatch (dst, entry))
+ {
+ NS_LOG_LOGIC ("Found global network route " << j << ", mask length " << maskLen << ", metric " << metric);
+
+ /* if interface is given, check the route will output on this interface */
+ if (!interface || interface == m_ipv6->GetNetDevice (j->GetInterface ()))
+ {
+ if (maskLen < longestMask)
+ {
+ NS_LOG_LOGIC ("Previous match longer, skipping");
+ continue;
+ }
+
+ if (maskLen > longestMask)
+ {
+ shortestMetric = 0xffffffff;
+ }
+
+ longestMask = maskLen;
+ if (metric > shortestMetric)
+ {
+ NS_LOG_LOGIC ("Equal mask length, but previous metric shorter, skipping");
+ continue;
+ }
+
+ shortestMetric = metric;
+ Ipv6RoutingTableEntry* route = j;
+ uint32_t interfaceIdx = route->GetInterface ();
+ rtentry = Create<Ipv6Route> ();
+
+ if (route->GetGateway ().IsAny ())
+ {
+ rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetDest ()));
+ }
+ else if (route->GetDest ().IsAny ()) /* default route */
+ {
+ rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetPrefixToUse ().IsAny () ? route->GetGateway () : route->GetPrefixToUse ()));
+ }
+ else
+ {
+ rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetGateway ()));
+ }
+
+ rtentry->SetDestination (route->GetDest ());
+ rtentry->SetGateway (route->GetGateway ());
+ rtentry->SetOutputDevice (m_ipv6->GetNetDevice (interfaceIdx));
+ }
+ }
+ }
+
+ if(rtentry)
+ {
+ NS_LOG_LOGIC ("Matching route via " << rtentry->GetDestination () << " (throught " << rtentry->GetGateway () << ") at the end");
+ }
+ return rtentry;
+}
+
+void Ipv6StaticRouting::DoDispose ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j = m_networkRoutes.erase (j))
+ {
+ delete j->first;
+ }
+ m_networkRoutes.clear ();
+
+ for (MulticastRoutesI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i = m_multicastRoutes.erase (i))
+ {
+ delete (*i);
+ }
+ m_multicastRoutes.clear ();
+
+ m_ipv6 = 0;
+ Ipv6RoutingProtocol::DoDispose ();
+}
+
+Ptr<Ipv6MulticastRoute> Ipv6StaticRouting::LookupStatic (Ipv6Address origin, Ipv6Address group, uint32_t interface)
+{
+ NS_LOG_FUNCTION (this << origin << group << interface);
+ Ptr<Ipv6MulticastRoute> mrtentry = 0;
+
+ for (MulticastRoutesI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i++)
+ {
+ Ipv6MulticastRoutingTableEntry* route = *i;
+
+ /*
+ We've been passed an origin address, a multicast group address and an
+ interface index. We have to decide if the current route in the list is
+ a match.
+
+ The first case is the restrictive case where the origin, group and index
+ matches. This picks up exact routes during forwarded and exact routes from
+ the local node (in which case the ifIndex is a wildcard).
+ */
+
+ if (origin == route->GetOrigin () && group == route->GetGroup ())
+ {
+ /* skipping SSM case */
+ NS_LOG_LOGIC ("Find source specific multicast route" << *i);
+ }
+
+ if (group == route->GetGroup ())
+ {
+ if (interface == Ipv6::IF_ANY || interface == route->GetInputInterface ())
+ {
+ NS_LOG_LOGIC ("Found multicast route" << *i);
+ mrtentry = Create<Ipv6MulticastRoute> ();
+ mrtentry->SetGroup (route->GetGroup ());
+ mrtentry->SetOrigin (route->GetOrigin ());
+ mrtentry->SetParent (route->GetInputInterface ());
+ for (uint32_t j = 0 ; j < route->GetNOutputInterfaces () ; j++)
+ {
+ if (route->GetOutputInterface (j))
+ {
+ NS_LOG_LOGIC ("Setting output interface index " << route->GetOutputInterface (j));
+ mrtentry->SetOutputTtl (route->GetOutputInterface (j), Ipv6MulticastRoute::MAX_TTL - 1);
+ }
+ }
+ return mrtentry;
+ }
+ }
+ }
+ return mrtentry;
+}
+
+uint32_t Ipv6StaticRouting::GetNRoutes ()
+{
+ return m_networkRoutes.size ();
+}
+
+Ipv6RoutingTableEntry Ipv6StaticRouting::GetDefaultRoute ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Ipv6Address dst ("::");
+ uint32_t shortestMetric = 0xffffffff;
+ Ipv6RoutingTableEntry* result = 0;
+
+ for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
+ {
+ Ipv6RoutingTableEntry* j = it->first;
+ uint32_t metric = it->second;
+ Ipv6Prefix mask = j->GetDestNetworkPrefix ();
+ uint16_t maskLen = mask.GetPrefixLength ();
+ Ipv6Address entry = j->GetDestNetwork ();
+
+ if (maskLen)
+ {
+ continue;
+ }
+
+ if (metric > shortestMetric)
+ {
+ continue;
+ }
+ shortestMetric = metric;
+ result = j;
+ }
+
+ if (result)
+ {
+ return result;
+ }
+ else
+ {
+ return Ipv6RoutingTableEntry ();
+ }
+}
+
+Ipv6RoutingTableEntry Ipv6StaticRouting::GetRoute (uint32_t index)
+{
+ NS_LOG_FUNCTION (this << index);
+ uint32_t tmp = 0;
+
+ for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
+ {
+ if (tmp == index)
+ {
+ return it->first;
+ }
+ tmp++;
+ }
+ NS_ASSERT (false);
+ // quiet compiler.
+ return 0;
+}
+
+uint32_t Ipv6StaticRouting::GetMetric (uint32_t index)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ uint32_t tmp = 0;
+
+ for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
+ {
+ if (tmp == index)
+ {
+ return it->second;
+ }
+ tmp++;
+ }
+ NS_ASSERT (false);
+ // quiet compiler.
+ return 0;
+}
+
+void Ipv6StaticRouting::RemoveRoute (uint32_t index)
+{
+ NS_LOG_FUNCTION (this << index);
+ uint32_t tmp = 0;
+
+ for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
+ {
+ if (tmp == index)
+ {
+ delete it->first;
+ m_networkRoutes.erase (it);
+ return;
+ }
+ tmp++;
+ }
+ NS_ASSERT (false);
+}
+
+void Ipv6StaticRouting::RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex, Ipv6Address prefixToUse)
+{
+ NS_LOG_FUNCTION (this << network << prefix << ifIndex);
+
+ for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
+ {
+ Ipv6RoutingTableEntry* rtentry = it->first;
+ if (network == rtentry->GetDest () && rtentry->GetInterface () == ifIndex &&
+ rtentry->GetPrefixToUse () == prefixToUse)
+ {
+ delete it->first;
+ m_networkRoutes.erase (it);
+ return;
+ }
+ }
+}
+
+Ptr<Ipv6Route> Ipv6StaticRouting::RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
+{
+ NS_LOG_FUNCTION (this << header << oif);
+ Ipv6Address destination = header.GetDestinationAddress ();
+ Ptr<Ipv6Route> rtentry = 0;
+
+ if (destination.IsMulticast ())
+ {
+ // Note: Multicast routes for outbound packets are stored in the
+ // normal unicast table. An implication of this is that it is not
+ // possible to source multicast datagrams on multiple interfaces.
+ // This is a well-known property of sockets implementation on
+ // many Unix variants.
+ // So, we just log it and fall through to LookupStatic ()
+ NS_LOG_LOGIC ("RouteOutput ()::Multicast destination");
+ }
+
+ rtentry = LookupStatic (destination, oif);
+ if (rtentry)
+ {
+ sockerr = Socket::ERROR_NOTERROR;
+ }
+ else
+ {
+ sockerr = Socket::ERROR_NOROUTETOHOST;
+ }
+ return rtentry;
+}
+
+bool Ipv6StaticRouting::RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb)
+{
+ NS_LOG_FUNCTION (this << p << header << header.GetSourceAddress () << header.GetDestinationAddress () << idev);
+ NS_ASSERT (m_ipv6 != 0);
+ // Check if input device supports IP
+ NS_ASSERT (m_ipv6->GetInterfaceForDevice (idev) >= 0);
+ uint32_t iif = m_ipv6->GetInterfaceForDevice (idev);
+ Ipv6Address dst = header.GetDestinationAddress ();
+
+ if (dst.IsMulticast ())
+ {
+ NS_LOG_LOGIC ("Multicast destination");
+ Ptr<Ipv6MulticastRoute> mrtentry = LookupStatic (header.GetSourceAddress (),
+ header.GetDestinationAddress (), m_ipv6->GetInterfaceForDevice (idev));
+
+ if (mrtentry)
+ {
+ NS_LOG_LOGIC ("Multicast route found");
+ mcb (mrtentry, p, header); // multicast forwarding callback
+ return true;
+ }
+ else
+ {
+ NS_LOG_LOGIC ("Multicast route not found");
+ return false; // Let other routing protocols try to handle this
+ }
+ }
+
+ // TODO: Configurable option to enable RFC 1222 Strong End System Model
+ // Right now, we will be permissive and allow a source to send us
+ // a packet to one of our other interface addresses; that is, the
+ // destination unicast address does not match one of the iif addresses,
+ // but we check our other interfaces. This could be an option
+ // (to remove the outer loop immediately below and just check iif).
+ for (uint32_t j = 0; j < m_ipv6->GetNInterfaces (); j++)
+ {
+ for (uint32_t i = 0; i < m_ipv6->GetNAddresses (j); i++)
+ {
+ Ipv6InterfaceAddress iaddr = m_ipv6->GetAddress (j, i);
+ Ipv6Address addr = iaddr.GetAddress ();
+ if (addr.IsEqual (header.GetDestinationAddress ()))
+ {
+ if (j == iif)
+ {
+ NS_LOG_LOGIC ("For me (destination " << addr << " match)");
+ }
+ else
+ {
+ NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestinationAddress ());
+ }
+ lcb (p, header, iif);
+ return true;
+ }
+ NS_LOG_LOGIC ("Address "<< addr << " not a match");
+ }
+ }
+ // Check if input device supports IP forwarding
+ if (m_ipv6->IsForwarding (iif) == false)
+ {
+ NS_LOG_LOGIC ("Forwarding disabled for this interface");
+ ecb (p, header, Socket::ERROR_NOROUTETOHOST);
+ return false;
+ }
+ // Next, try to find a route
+ NS_LOG_LOGIC ("Unicast destination");
+ Ptr<Ipv6Route> rtentry = LookupStatic (header.GetDestinationAddress ());
+
+ if (rtentry != 0)
+ {
+ NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
+ ucb (rtentry, p, header); // unicast forwarding callback
+ return true;
+ }
+ else
+ {
+ NS_LOG_LOGIC ("Did not find unicast destination- returning false");
+ return false; // Let other routing protocols try to handle this
+ }
+}
+
+void Ipv6StaticRouting::NotifyInterfaceUp (uint32_t i)
+{
+ for (uint32_t j = 0 ; j < m_ipv6->GetNAddresses (i) ; j++)
+ {
+ if (m_ipv6->GetAddress (i, j).GetAddress () != Ipv6Address () &&
+ m_ipv6->GetAddress (i, j).GetPrefix () != Ipv6Prefix ())
+ {
+ if (m_ipv6->GetAddress (i, j).GetPrefix () == Ipv6Prefix (128))
+ {
+ /* host route */
+ AddHostRouteTo (m_ipv6->GetAddress (i, j).GetAddress (), i);
+ }
+ else
+ {
+ AddNetworkRouteTo (m_ipv6->GetAddress (i, j).GetAddress ().CombinePrefix (m_ipv6->GetAddress (i, j).GetPrefix ()),
+ m_ipv6->GetAddress (i, j).GetPrefix (), i);
+ }
+ }
+ }
+}
+
+void Ipv6StaticRouting::NotifyInterfaceDown (uint32_t i)
+{
+ NS_LOG_FUNCTION (this << i);
+ uint32_t j = 0;
+ uint32_t max = GetNRoutes ();
+
+ /* remove all static routes that are going through this interface */
+ while (j < max)
+ {
+ Ipv6RoutingTableEntry route = GetRoute (j);
+
+ if (route.GetInterface () == i)
+ {
+ RemoveRoute (j);
+ }
+ else
+ {
+ j++;
+ }
+ }
+}
+
+void Ipv6StaticRouting::NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address)
+{
+ if (!m_ipv6->IsUp (interface))
+ {
+ return;
+ }
+
+ Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
+ Ipv6Prefix networkMask = address.GetPrefix ();
+
+ if (address.GetAddress () != Ipv6Address () && address.GetPrefix () != Ipv6Prefix ())
+ {
+ AddNetworkRouteTo (networkAddress, networkMask, interface);
+ }
+}
+
+void Ipv6StaticRouting::NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address)
+{
+ if (!m_ipv6->IsUp (interface))
+ {
+ return;
+ }
+
+ Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
+ Ipv6Prefix networkMask = address.GetPrefix ();
+
+ // Remove all static routes that are going through this interface
+ // which reference this network
+ for (uint32_t j = 0 ; j < GetNRoutes () ; j++)
+ {
+ Ipv6RoutingTableEntry route = GetRoute (j);
+
+ if (route.GetInterface () == interface &&
+ route.IsNetwork () &&
+ route.GetDestNetwork () == networkAddress &&
+ route.GetDestNetworkPrefix () == networkMask)
+ {
+ RemoveRoute (j);
+ }
+ }
+}
+
+void Ipv6StaticRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+ NS_LOG_INFO (this << dst << mask << nextHop << interface << prefixToUse);
+ if (dst != Ipv6Address::GetZero ())
+ {
+ AddNetworkRouteTo (dst, mask, nextHop, interface);
+ }
+ else /* default route */
+ {
+ /* this case is mainly used by configuring default route following RA processing,
+ * in case of multipe prefix in RA, the first will configured default route
+ */
+
+ /* for the moment, all default route has the same metric
+ * so according to the longest prefix algorithm,
+ * the default route choosen will be the last added
+ */
+ SetDefaultRoute (nextHop, interface, prefixToUse);
+ }
+}
+
+void Ipv6StaticRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+ NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
+ if (dst != Ipv6Address::GetZero ())
+ {
+ for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
+ {
+ Ipv6RoutingTableEntry* rtentry = j->first;
+ Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
+ Ipv6Address entry = rtentry->GetDestNetwork ();
+
+ if (dst == entry && prefix == mask && rtentry->GetInterface () == interface)
+ {
+ delete j->first;
+ m_networkRoutes.erase (j);
+ }
+ }
+ }
+ else
+ {
+ /* default route case */
+ RemoveRoute (dst, mask, interface, prefixToUse);
+ }
+}
+
+Ipv6Address Ipv6StaticRouting::SourceAddressSelection (uint32_t interface, Ipv6Address dest)
+{
+ NS_LOG_FUNCTION (this << interface << dest);
+ Ipv6Address ret;
+
+ /* first address of an IPv6 interface is link-local ones */
+ ret = m_ipv6->GetAddress (interface, 0).GetAddress ();
+
+ if (dest == Ipv6Address::GetAllNodesMulticast () || dest == Ipv6Address::GetAllRoutersMulticast () || dest == Ipv6Address::GetAllHostsMulticast ())
+ {
+ return ret;
+ }
+
+ /* useally IPv6 interfaces have one link-local address and one global address */
+
+ for (uint32_t i = 1 ; i < m_ipv6->GetNAddresses (interface) ; i++)
+ {
+ Ipv6InterfaceAddress test = m_ipv6->GetAddress (interface, i);
+
+ if (test.GetAddress ().CombinePrefix (test.GetPrefix ()) == dest.CombinePrefix (test.GetPrefix ()))
+ {
+ return test.GetAddress ();
+ }
+ }
+
+ return ret;
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/model/ipv6-static-routing.h Tue Oct 26 18:02:17 2010 +0100
@@ -0,0 +1,299 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef IPV6_STATIC_ROUTING_H
+#define IPV6_STATIC_ROUTING_H
+
+#include <stdint.h>
+
+#include <list>
+
+#include "ns3/ptr.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/ipv6.h"
+#include "ns3/ipv6-header.h"
+#include "ns3/ipv6-routing-protocol.h"
+
+namespace ns3
+{
+
+class Packet;
+class NetDevice;
+class Ipv6Interface;
+class Ipv6Route;
+class Node;
+class Ipv6RoutingTableEntry;
+class Ipv6MulticastRoutingTableEntry;
+
+/**
+ * \ingroup routing
+ * \defgroup ipv6StaticRouting Ipv6StaticRouting
+ */
+/**
+ * \ingroup ipv6StaticRouting
+ * \class Ipv6StaticRouting
+ * \brief Static routing protocol for IP version 6 stack.
+ * \see Ipv6RoutingProtocol
+ * \see Ipv6ListRouting
+ */
+class Ipv6StaticRouting : public Ipv6RoutingProtocol
+{
+public:
+ /**
+ * \brief The interface Id associated with this class.
+ * \return type identifier
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6StaticRouting ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6StaticRouting ();
+
+ /**
+ * \brief Add route to host.
+ * \param dest destination address
+ * \param nextHop next hop address to route the packet
+ * \param interface interface index
+ * \param prefixToUse prefix that should be used for source address for this destination
+ * \param metric metric of route in case of multiple routes to same destination
+ */
+ void AddHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address ("::"), uint32_t metric = 0);
+
+ /**
+ * \brief Add route to host.
+ * \param dest destination address.
+ * \param interface interface index
+ * \param metric metric of route in case of multiple routes to same destination
+ */
+ void AddHostRouteTo (Ipv6Address dest, uint32_t interface, uint32_t metric = 0);
+
+ /**
+ * \brief Add route to network.
+ * \param network network address
+ * \param networkPrefix network prefix*
+ * \param nextHop next hop address to route the packet
+ * \param interface interface index
+ * \param metric metric of route in case of multiple routes to same destination
+ */
+ void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, uint32_t metric = 0);
+
+ /**
+ * \brief Add route to network.
+ * \param network network address
+ * \param networkPrefix network prefix*
+ * \param nextHop next hop address to route the packet
+ * \param interface interface index
+ * \param prefixToUse prefix that should be used for source address for this destination
+ * \param metric metric of route in case of multiple routes to same destination
+ */
+ void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric = 0);
+
+ /**
+ * \brief Add route to network.
+ * \param network network address
+ * \param networkPrefix network prefix
+ * \param interface interface index
+ * \param metric metric of route in case of multiple routes to same destination
+ */
+ void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, uint32_t metric = 0);
+
+ /**
+ * \brief Set the default route.
+ * \param nextHop next hop address to route the packet
+ * \param interface interface index
+ * \param prefixToUse prefix to use (i.e for multihoming)
+ * \param metric metric of route in case of multiple routes to same destination
+ */
+ void SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address ("::"), uint32_t metric = 0);
+
+ /**
+ * \brief Get the number or entries in the routing table.
+ * \return number of entries
+ */
+ uint32_t GetNRoutes ();
+
+ /**
+ * \brief Get the default route.
+ *
+ * If multiple default routes exist, the one with lowest metric is returned.
+ * \return default Ipv6Route
+ */
+ Ipv6RoutingTableEntry GetDefaultRoute ();
+
+ /**
+ * \brief Get a specified route.
+ * \param i index
+ * \return the route whose index is i
+ */
+ Ipv6RoutingTableEntry GetRoute (uint32_t i);
+
+ /**
+ * \brief Get a metric for route from the static unicast routing table.
+ * \param index The index (into the routing table) of the route to retrieve.
+ * \return If route is set, the metric is returned. If not, an infinity metric (0xffffffff) is returned
+ */
+ uint32_t GetMetric (uint32_t index);
+
+ /**
+ * \brief Remove a route from the routing table.
+ * \param i index
+ */
+ void RemoveRoute (uint32_t i);
+
+ /**
+ * \brief Remove a route from the routing table.
+ * \param network IPv6 network
+ * \param prefix IPv6 prefix
+ * \param ifIndex interface index
+ * \param prefixToUse IPv6 prefix to use with this route (multihoming)
+ */
+ void RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex, Ipv6Address prefixToUse);
+
+ /**
+ * \brief Add a multicast route for a given multicast source and group.
+ * \param origin IPv6 address of the source
+ * \param group the multicast group address.
+ * \param inputInterface the interface index
+ * \param outputInterfaces the list of output interface indices over which the packet
+ * should be sent (excluding the inputInterface).
+ */
+ void AddMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces);
+
+ /**
+ * \brief Set the default multicast route.
+ * \param outputInterface default output interface
+ */
+ void SetDefaultMulticastRoute (uint32_t outputInterface);
+
+ /**
+ * \brief Get the number of entries in the multicast routing table.
+ * \return number of entries
+ */
+ uint32_t GetNMulticastRoutes () const;
+
+ /**
+ * \brief Get the specified multicast route.
+ * \param i index
+ * \return the route whose index is i
+ */
+ Ipv6MulticastRoutingTableEntry GetMulticastRoute (uint32_t i) const;
+
+ /**
+ * \brief Remove a static multicast route.
+ * \param origin IPv6 address of the source
+ * \param group the multicast group address.
+ * \param inputInterface the input interface index
+ */
+ bool RemoveMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface);
+
+ /**
+ * \brief Remove a multicast route.
+ * \param i index of route to remove
+ */
+ void RemoveMulticastRoute (uint32_t i);
+
+ /**
+ * \brief If the destination is already present in network destination list.
+ * \param dest destination address
+ * \param interfaceIndex interface index
+ * \return true if dest is already in list, false otherwise
+ */
+ bool HasNetworkDest (Ipv6Address dest, uint32_t interfaceIndex);
+
+ virtual Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
+
+ virtual bool RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb);
+
+ virtual void NotifyInterfaceUp (uint32_t interface);
+ virtual void NotifyInterfaceDown (uint32_t interface);
+ virtual void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address);
+ virtual void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address);
+ virtual void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
+ virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
+ virtual void SetIpv6 (Ptr<Ipv6> ipv6);
+
+protected:
+ /**
+ * \brief Dispose this object.
+ */
+ void DoDispose ();
+
+private:
+ typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> > NetworkRoutes;
+ typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> >::const_iterator NetworkRoutesCI;
+ typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> >::iterator NetworkRoutesI;
+
+ typedef std::list<Ipv6MulticastRoutingTableEntry *> MulticastRoutes;
+ typedef std::list<Ipv6MulticastRoutingTableEntry *>::const_iterator MulticastRoutesCI;
+ typedef std::list<Ipv6MulticastRoutingTableEntry *>::iterator MulticastRoutesI;
+
+ /**
+ * \brief Lookup in the forwarding table for destination.
+ * \param dest destination address
+ * \param interface output interface if any (put 0 otherwise)
+ * \return Ipv6Route to route the packet to reach dest address
+ */
+ Ptr<Ipv6Route> LookupStatic (Ipv6Address dest, Ptr<NetDevice> = 0);
+
+ /**
+ * \brief Lookup in the multicast forwarding table for destination.
+ * \param origin source address
+ * \param group group multicast address
+ * \param ifIndex interface index
+ * \return Ipv6MulticastRoute to route the packet to reach dest address
+ */
+ Ptr<Ipv6MulticastRoute> LookupStatic (Ipv6Address origin, Ipv6Address group, uint32_t ifIndex);
+
+ /**
+ * \brief Choose the source address to use with destination address.
+ * \param interface interface index
+ * \param dest IPv6 destination address
+ * \return IPv6 source address to use
+ */
+ Ipv6Address SourceAddressSelection (uint32_t interface, Ipv6Address dest);
+
+ /**
+ * \brief the forwarding table for network.
+ */
+ NetworkRoutes m_networkRoutes;
+
+ /**
+ * \brief the forwarding table for multicast.
+ */
+ MulticastRoutes m_multicastRoutes;
+
+ /**
+ * \brief Ipv6 reference.
+ */
+ Ptr<Ipv6> m_ipv6;
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_STATIC_ROUTING_H */
+
--- a/src/routing/static-routing/wscript Tue Oct 26 15:11:17 2010 +0100
+++ b/src/routing/static-routing/wscript Tue Oct 26 18:02:17 2010 +0100
@@ -3,17 +3,21 @@
def build(bld):
module = bld.create_ns3_module('static-routing', ['node'])
module.source = [
- 'ipv4-static-routing.cc',
- 'ipv4-routing-table-entry.cc',
- 'ipv6-static-routing.cc',
- 'ipv6-routing-table-entry.cc',
+ 'model/ipv4-static-routing.cc',
+ 'model/ipv4-routing-table-entry.cc',
+ 'model/ipv6-static-routing.cc',
+ 'model/ipv6-routing-table-entry.cc',
+ 'helper/ipv4-static-routing-helper.cc',
+ 'helper/ipv6-static-routing-helper.cc',
]
headers = bld.new_task_gen('ns3header')
headers.module = 'static-routing'
headers.source = [
- 'ipv4-static-routing.h',
- 'ipv4-routing-table-entry.h',
- 'ipv6-static-routing.h',
- 'ipv6-routing-table-entry.h',
+ 'model/ipv4-static-routing.h',
+ 'model/ipv4-routing-table-entry.h',
+ 'model/ipv6-static-routing.h',
+ 'model/ipv6-routing-table-entry.h',
+ 'helper/ipv4-static-routing-helper.h',
+ 'helper/ipv6-static-routing-helper.h',
]