Bug 611 - GlobalRouting::RecomputeRoutingTables() fails if PopulateRoutingTables was used on NodeContainer
GlobalRouting::RecomputeRoutingTables() fails if PopulateRoutingTables was us...
Status: RESOLVED WORKSFORME
Product: ns-3
Classification: Unclassified
Component: routing
ns-3-dev
All All
: P5 normal
Assigned To: ns-bugs
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2009-06-26 09:17 EDT by Antti Mäkelä
Modified: 2009-06-27 03:40 EDT (History)
2 users (show)

See Also:


Attachments
Slightly altered global-slash32 example (4.51 KB, text/plain)
2009-06-26 09:17 EDT, Antti Mäkelä
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Antti Mäkelä 2009-06-26 09:17:51 EDT
Created attachment 493 [details]
Slightly altered global-slash32 example

If only part of network is set up with GlobalRouting, using the call GlobalRouting::PopulateRoutingTables(NodeContainer c), when using call GlobalRouting::RecomputeRoutingTables, program segfaults.

Easy enough to test, attaching slightly modified examples/global-routing-slash32.cc where 

GlobalRouteManager::PopulateRoutingTables ();

has been changed to

GlobalRouteManager::PopulateRoutingTables (nAnB);
  GlobalRouteManager::RecomputeRoutingTables();

GDB backtrace as follows:


(gdb) bt
#0  0xa7d4314d in std::list<ns3::Ipv4RoutingTableEntry*, std::allocator<ns3::Ipv4RoutingTableEntry*> >::begin (this=0x10)
    at /usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_list.h:658
#1  0xa7d4324d in std::list<ns3::Ipv4RoutingTableEntry*, std::allocator<ns3::Ipv4RoutingTableEntry*> >::size (this=0x10)
    at /usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_list.h:764
#2  0xa7d3ee53 in ns3::Ipv4GlobalRouting::GetNRoutes (this=0x0)
    at ../src/routing/global-routing/ipv4-global-routing.cc:162
#3  0xa7d38bc9 in ns3::GlobalRouteManagerImpl::DeleteGlobalRoutes (
    this=0x9d0e938)
    at ../src/routing/global-routing/global-route-manager-impl.cc:379
#4  0xa7d2bd05 in ns3::GlobalRouteManager::DeleteGlobalRoutes ()
    at ../src/routing/global-routing/global-route-manager.cc:64
#5  0xa7d2bd23 in ns3::GlobalRouteManager::RecomputeRoutingTables ()
    at ../src/routing/global-routing/global-route-manager.cc:55
#6  0x0804ea88 in main (argc=-1476521752, argv=0x4) at ../scratch/global.cc:103

My guess is that 

GlobalRouteManagerImpl::DeleteGlobalRoutes ()

doesn't check if a node is actually running global routing, i.e. checking for null pointer. Should be easy to fix with

if (!gr) { ... } at the appropriate position...
Comment 1 Mathieu Lacage 2009-06-26 09:33:21 EDT
I believe that bug600 fixes this also
Comment 2 Antti Mäkelä 2009-06-26 14:48:09 EDT
Ok, I just pulled in latest stuff in..

And bug is not exactly fixed (well, can't test yet at least), it simply appears that I no longer have the option of NOT installing GlobalRouting on a node if I use InternetStackHelper to put the IP stack on one - it's always there. So the situation will not even arise.

So, the old way where I could only install Global Routing on some nodes is gone, so I can't bring the bug to manifest in the first place.

Would it be possible to change the Internet Stack Helper constructor - currently taking no parameters - so that there would be an option to choose which routing protocols it will include in the stack? I really don't want to run GlobalRouting on ALL nodes.

Right now the constructor takes no parameters - the parameter could be either a list of routing protocols to be installed (without parameters it should probably default to all), maybe a bitfield that can be ORred?

I could, for real, use helpers e.g. as follows

InternetStackHelper RouterHelper();  // Default, includes every protocol
InternetStackHelper StaticRouter(ROUTING_STATIC);  // Only Static
InternetStackHelper Host(ROUTING_NONE); // Nothing

So the constructor would become

// Default mask has everything enabled
InternetStackHelper::InternetStackHelper (uint32_t rflags=0xffffffff)
{
  SetTcp ("ns3::TcpL4Protocol");
  static Ipv4StaticRoutingHelper staticRouting;
  static Ipv4GlobalRoutingHelper globalRouting;
  static Ipv4ListRoutingHelper listRouting;
  if (rflags&ROUTING_STATIC) { listRouting.Add (staticRouting, 0); }
  if (rflags&ROUTING_GLOBAL) { listRouting.Add (globalRouting, -10); }
  SetRoutingHelper (listRouting);
}

(And somewhere we have these macros defined)

and then install as I want...and this can then be scaled to other protocols, e.g. InternetStackHelper OlsrNodeHelper(ROUTING_OLSR);)

The reason is that I don't want to make certain routers becoming transits - I want to filter routes, and easiest way to do that for me right now is not install a dynamic (or semi-dynamic in case of global) protocol on such a node at all, yet I want to use dynamic stuff elsewhere in simulation. 

Also, I'm in the process of adding Inject/Redistribution support to GlobalRouting (in fact, I ran into the original while writing code for that) so that external routes could propagate through the cloud, so suddendly having to deal with GlobalRouting on all nodes puts a dent in there (see http://groups.google.com/group/ns-3-users/browse_thread/thread/fe10285f3c77f047).

Anyway, if this idea of InternetStackHelper with a requestable list of routing protocols to be installed is acceptable, I can submit a patch. And then continue dealing with original issue...
Comment 3 Tom Henderson 2009-06-26 20:17:45 EDT
(In reply to comment #2)
> Ok, I just pulled in latest stuff in..
> 
> And bug is not exactly fixed (well, can't test yet at least), it simply appears
> that I no longer have the option of NOT installing GlobalRouting on a node if I
> use InternetStackHelper to put the IP stack on one - it's always there. So the
> situation will not even arise.

Here is how I believe the current API will let you do this:

  NodeContainer cWithGlobal;
  NodeContainer cWithoutGlobal;

  InternetStackHelper internet;
  internet.Install (cWithGlobal);  // Installs the default configuration
  
  Ipv4ListRoutingHelper list;
  list.Add (staticRouting, 0);
  list.Add (olsr, 10);
  internet.SetRoutingHelper (list);  // overwrites previous routing helper
  internet.Install (cWithoutGlobal);


> 
> Also, I'm in the process of adding Inject/Redistribution support to
> GlobalRouting (in fact, I ran into the original while writing code for that) so
> that external routes could propagate through the cloud, so suddendly having to
> deal with GlobalRouting on all nodes puts a dent in there (see
> http://groups.google.com/group/ns-3-users/browse_thread/thread/fe10285f3c77f047).
> 

do you have a sketch of how the API might look when you are done with the static redistribution patch?
Comment 4 Antti Mäkelä 2009-06-27 03:11:25 EDT
(In reply to comment #3)
> do you have a sketch of how the API might look when you are done with the
> static redistribution patch?

  Right now it seems that I'd be adding two public methods to ipv4-global-routing.h, basically 
Inject(Ipv4Address, Ipv4Mask) which simply saves to an std::list <Ipv4RoutingTableEntry *> what you want to inject, and GetInjectedRoutes, which returns a copy of that list. 

I also need additional helper function GetGlobalRouting which is basically copy-pasted from the similar one in ipv4-static-routing.h to get a pointer to the routing object.

  Internally, I'm making some changes to DiscoverLSAs so that it grabs that list and inserts them as Type 5 LSA's. 

  Anyway, will test with your suggestion whether the original bug still exist...thanks for the tip. 
Comment 5 Antti Mäkelä 2009-06-27 03:40:51 EDT
Ok, this truly seems to be fixed now.