Bug 779 - NixVectorRouting ignores specified outgoing interface in RouteOutput()
NixVectorRouting ignores specified outgoing interface in RouteOutput()
Status: RESOLVED FIXED
Product: ns-3
Classification: Unclassified
Component: routing
pre-release
All All
: P5 normal
Assigned To: Josh Pelkey
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2009-12-15 23:51 UTC by Tom Henderson
Modified: 2010-01-13 10:03 UTC (History)
2 users (show)

See Also:


Attachments
Use oif in RouteOutput (2.37 KB, patch)
2009-12-16 10:55 UTC, Josh Pelkey
Details | Diff
Use of oif in RouteOutput (16.91 KB, patch)
2010-01-06 11:07 UTC, Josh Pelkey
Details | Diff
Use of oif in RouteOutput (17.05 KB, patch)
2010-01-07 17:49 UTC, Josh Pelkey
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Tom Henderson 2009-12-15 23:51:41 UTC
NixVector does not do anything with the oif parameter, which may be set by
Socket::BindToDevice().  This was changed from an interface index to a device
pointer when bug 742 was resolved, but NixVector has not been handling this parameter yet.

Ptr<Ipv4Route>
RoutingProtocol::RouteOutput (Ptr<Packet> p, const Ipv4Header &header,
    Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
Comment 1 Josh Pelkey 2009-12-16 10:55:24 UTC
Created attachment 701 [details]
Use oif in RouteOutput

I think that I understand what should be done here.  Please let me know if I am wrong.  Essentially, if oif parameter is not null, then this net-device must be used as the output device.  I think I have accomplished this with the attached patch.
Comment 2 Tom Henderson 2010-01-06 01:19:19 UTC
(In reply to comment #1)
> Created an attachment (id=701) [details]
> Use oif in RouteOutput
> 
> I think that I understand what should be done here.  Please let me know if I am
> wrong.  Essentially, if oif parameter is not null, then this net-device must be
> used as the output device.  I think I have accomplished this with the attached
> patch.

Sorry, I did not see your patch until tonight (the cc list is fixed now).

I am not sure your patch is totally correct because I would assume that you want to build a nix vector with the outbound device as a constraining argument to the below method:

       GetNixVector (m_node, header.GetDestination ());

but it seems that you are not constraining the construction of nix vectors with your patch but just modifying the resulting rtentry to force an output device, regardless of what the code would naturally choose.  Do I understand your patch correctly?
Comment 3 Josh Pelkey 2010-01-06 11:07:46 UTC
Created attachment 710 [details]
Use of oif in RouteOutput
Comment 4 Josh Pelkey 2010-01-06 11:08:28 UTC
(In reply to comment #2)
> (In reply to comment #1)
> > Created an attachment (id=701) [details] [details]
> > Use oif in RouteOutput
> > 
> > I think that I understand what should be done here.  Please let me know if I am
> > wrong.  Essentially, if oif parameter is not null, then this net-device must be
> > used as the output device.  I think I have accomplished this with the attached
> > patch.
> 
> Sorry, I did not see your patch until tonight (the cc list is fixed now).
> 
> I am not sure your patch is totally correct because I would assume that you
> want to build a nix vector with the outbound device as a constraining argument
> to the below method:
> 
>        GetNixVector (m_node, header.GetDestination ());
> 
> but it seems that you are not constraining the construction of nix vectors with
> your patch but just modifying the resulting rtentry to force an output device,
> regardless of what the code would naturally choose.  Do I understand your patch
> correctly?

You are right. I should have been creating nix-vectors differently if the output device is specified. Now GetNixVector take in oif, which eventually passes it down to the breadth-first search. The BFS checks to see if oif is specified, and if so, on the first hop it forces this direction. Then it proceeds as normal.(In reply to comment #3)
> Created an attachment (id=710) [details]
> Use of oif in RouteOutput

You are right. I should have been creating nix-vectors differently if the output device is specified. Now GetNixVector take in oif, which eventually passes it down to the breadth-first search. The BFS checks to see if oif is specified, and if so, on the first hop it forces this direction. Then it proceeds as normal.
Comment 5 Tom Henderson 2010-01-06 13:16:31 UTC


> 
> You are right. I should have been creating nix-vectors differently if the
> output device is specified. Now GetNixVector take in oif, which eventually
> passes it down to the breadth-first search. The BFS checks to see if oif is
> specified, and if so, on the first hop it forces this direction. Then it
> proceeds as normal.

My one remaining comment is:

+      // Search here in a cache for this node index 
+      // and look for a Ipv4Route, if output device, 
+      // oif, is not specified
+      if (!oif)
+        {
+          rtentry = GetIpv4RouteInCache (header.GetDestination ());
+        }
+      // not in cache or a specified output
+      // device is to be used

it seems like presence of oif will mean that the route is never cached.  Would it be better to still cache it and just check whether the oif is valid?

rtentry = GetIpv4RouteInCache()
if (oif && rtentry.oif == oif)
 {
   // use cache entry
 }
else
 {
   // flush cache entry, and continue (fall through to the step that does a new BFS)
 }

I think that the above pseudocode would avoid doing the BFS for each packet.  It would still not catch the case where there was a cache entry built with a previous value of oif, user then sets oif to zero, route output is called, and the cache entry is used even though there is a better route that could be found if oif was not previously constrained.  Some kind of check at the top of RouteOutput such as 

if (m_savedOif != oif)
  {
    // flush cache
  }

would probably do the trick.
Comment 6 Josh Pelkey 2010-01-06 13:44:20 UTC
> My one remaining comment is:
> 
> +      // Search here in a cache for this node index 
> +      // and look for a Ipv4Route, if output device, 
> +      // oif, is not specified
> +      if (!oif)
> +        {
> +          rtentry = GetIpv4RouteInCache (header.GetDestination ());
> +        }
> +      // not in cache or a specified output
> +      // device is to be used
> 
> it seems like presence of oif will mean that the route is never cached.  Would
> it be better to still cache it and just check whether the oif is valid?
> 
> rtentry = GetIpv4RouteInCache()
> if (oif && rtentry.oif == oif)
>  {
>    // use cache entry
>  }
> else
>  {
>    // flush cache entry, and continue (fall through to the step that does a new
> BFS)
>  }
> 
> I think that the above pseudocode would avoid doing the BFS for each packet. 
> It would still not catch the case where there was a cache entry built with a
> previous value of oif, user then sets oif to zero, route output is called, and
> the cache entry is used even though there is a better route that could be found
> if oif was not previously constrained.  Some kind of check at the top of
> RouteOutput such as 
> 
> if (m_savedOif != oif)
>   {
>     // flush cache
>   }
> 
> would probably do the trick.

Right again.  I'm confused about this part though:

> It would still not catch the case where there was a cache entry built with a
> previous value of oif, user then sets oif to zero, route output is called, and
> the cache entry is used even though there is a better route that could be found

Given your psuedo-code, if oif was set at first and then reset later, the cached route wouldn't be used.  It would fall through to the else statement, erase the value in the map, proceed with the BFS, and cache the new route.  Did I understand this incorrectly?  Here is what I was thinking of doing:

 rtentry = GetIpv4RouteInCache()
 if (rtentry && rtentry.oif == oif)
  {
    // we are cached, and the oif is the same,
    // use it
  }
 else
  {
    // need a new route
  }
Comment 7 Tom Henderson 2010-01-07 16:59:52 UTC
> Given your psuedo-code, if oif was set at first and then reset later, the
> cached route wouldn't be used.  It would fall through to the else statement,
> erase the value in the map, proceed with the BFS, and cache the new route.  Did
> I understand this incorrectly?  Here is what I was thinking of doing:
> 
>  rtentry = GetIpv4RouteInCache()
>  if (rtentry && rtentry.oif == oif)
>   {
>     // we are cached, and the oif is the same,
>     // use it
>   }
>  else
>   {
>     // need a new route
>   }

agree.
Comment 8 Josh Pelkey 2010-01-07 17:49:58 UTC
Created attachment 713 [details]
Use of oif in RouteOutput

changeset 408970e134cb
Comment 9 Josh Pelkey 2010-01-13 10:03:22 UTC
(In reply to comment #8)
> Created an attachment (id=713) [details]
> Use of oif in RouteOutput
> 
> changeset 408970e134cb

Above changeset was reverted due to code freeze.  Bug is now fixed in changeset 681058254595