netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Default route selection and dead GW detection
@ 2005-01-11 22:03 Christian Benvenuti
  0 siblings, 0 replies; only message in thread
From: Christian Benvenuti @ 2005-01-11 22:03 UTC (permalink / raw)
  To: netdev

Hello,
  I am looking at how Linux selects a default route (when
multipath is not configured), and in particular I am looking at:

        fn_hash_select_default / fib_detect_death (kernel 2.6.9)

It seems to me this is the logic used:

  a) If there is only one default route defined (which would be the one
     previously selected by <fn_hash_lookup> and saved in "res->fi"),
     that one would be used.

  b) If there is more than one route available, then:

     b1) the first default route whose next-hop is NUD_REACHABLE
         is selected.

     b2) if there is no NUD_REACHABLE GW, then

         b3) all eligible default routes are checked and the
             last one with a NUD_VALID GW is selected
             (if != fn_hash_last_dflt)

             b4) if there is no NUD_VALID GW, all default routes
                 will be tried by <fn_hash_select_default>, one by
                 one, from first one to last one.

Did I get the logic right? Supposing I did, I have a couple of
questions about b3):

1) why does b3) check for (!=fn_hash_last_dflt) ?
   In other words, if you do not use the "fn_hash_last_dflt"
   GW for sometime, and therefore its NUD states goes to
   NUD_STALE, why would you select another NUD_VALID (but
   not NUD_REACHABLE) GW?

2) please see my second question below

static int fib_detect_death(struct fib_info *fi, int order,
			    struct fib_info **last_resort,
                            int *last_idx)
{
	struct neighbour *n;
	int state = NUD_NONE;

	n = neigh_lookup(&arp_tbl, &fi->fib_nh[0].nh_gw, fi->fib_dev);
	if (n) {
		state = n->nud_state;
		neigh_release(n);
	}
	if (state==NUD_REACHABLE)
		return 0;
	if ((state&NUD_VALID) && order != fn_hash_last_dflt)
		return 0;

/* Why does the block below keep updating <last_resort> and 
 * <last_idx> even when they are already initialized?
 * (e.g. from a previous invocation by <fn_hash_select_default>)
 * Is it just to make code simpler?
 */
	if ((state&NUD_VALID) ||
	    (*last_idx<0 && order > fn_hash_last_dflt)) {
		*last_resort = fi;
		*last_idx = order;
	}
	return 1;
}

I also have a doubt about how the "classic" configuration
of multiple default routes coexists with a multipath default
route.

Since multiple default GW are configurable both with multiple

  "route add default ..."

commands, or with a single default multipath route like 

  "ip route add default ..."

am I correct if I say that those two forms are exclusive?

You can configure default routes with both commands, the
kernel does not complain, but it seems the routing routines 
<ip_route_{input, output}_slow> do not take this possibility
into account. 

For example:

- <ip_route_output_slow> selects the default route either
  with <fib_select_multipath> or <fib_select_default>:

  ...
  #ifdef CONFIG_IP_ROUTE_MULTIPATH
	if (res.fi->fib_nhs > 1 && fl.oif == 0)
		fib_select_multipath(&fl, &res);
	else
  #endif
	if (!res.prefixlen && res.type == RTN_UNICAST && !fl.oif)
		fib_select_default(&fl, &res);
  ...

- <ip_route_input_slow> does not call <fib_select_default>
  at all:

  ...
  #ifdef CONFIG_IP_ROUTE_MULTIPATH
	if (res.fi->fib_nhs > 1 && fl.oif == 0)
		fib_select_multipath(&fl, &res);
  #endif
  ... 


Thanks in advance
-Christian

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2005-01-11 22:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-01-11 22:03 Default route selection and dead GW detection Christian Benvenuti

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).