NOTE: this starts off as a diald configuration issue, but leads to a pppd
source question (with diffs attached)
I have been trying to get diald and pppd to work correctly on my machine
in regards to how they handle default routes. I am now running 2.0.36 (RH
5.2) which has ppp 2.3.5 (which looking at sunsite is only at 2.3.4... is
this a different ppp?). I am using diald 0.16.5.
Diald creates a proxy interface and default route (device sl0). The
default route has a gateway address of 0.0.0.0 and a metric of 1. When
pppd kicks in as the real physical link, it was my reading of the docs
that diald creates a default route for ppp link. In a email discussion
with someone with much older versions of diald/ppp/linux, it appears the
route on his system is added by diald and has a lower metric than the sl0
default route. In fact his sl0 is 2000 and the pp0 route is 500.
In examining my syslogs, I got the following error message:
pppd[951]: not replacing existing default route to sl0 [0.0.0.0]
Here pppd is trying to add a default route (due to the defaultroute
option in the ppp options file). It fails because of an existing default
route (the sl0 device route). From what I can tell with diald running,
ppp shouldn't even be trying to add its own route, and if someone can
tell me how to make this happen I would appreciate it. I have taken
defaultroute and many other options in and out of both diald.conf and the
ppp options file (and I have read the Warning in the diald man page about
taking out almost all ppp options). I think that ultimately there is a
diald issue to be resolved in setting the default route for the physical
link.
In the meantime, I looked at the pppd source and in particular the file
sys_linux.c. In this file I noticed (in sifdefaultroute()) that default
routes are added after checking for existing default routes. If a default
route exists and it has a different gateway address then pppd will not
add the new default route. It would seem better to check the metric value
and if the metric value is different then it should be safe to add the
route, especially when the gateway *is* different between the
pre-existing default routes and the new one. Also I think there is a bug
in this same area, because after checking for existing default routes it
goes through an extra if-case to check the gateway address and if its not
a match then it logs the error (the one seen above in this message). Then
it drops out of the if-case and does a return 0 (no add of default
route). This seems strange... why not a syslog for all default routes not
being added (due to a pre-existing route) versus a message for just the
ones with a different gateway and silence for the rest. I think the
return was meant to be in the same if-case as the syslog message.
In order to check metrics the read_route_table() routine had to be
slightly extended to read the value and stuff it into the route data
structure.
When I looked at the other sys_*.c files, none of the other OS versions
seem to reject adding default routes, especially with such pre-checking.
I made changes to use metrics as well as the gateway name to check if it
is okay to add a default route in the pppd code (sys_linux.c). I am
attaching it here, and would be interested in feedback on what I think I
am seeing as a problem.
Thanks,
-Art
*** sys-linux.c.ORIG Thu Mar 18 22:01:29 1999
--- sys-linux.c Fri Mar 19 22:18:04 1999
***************
*** 1215,1220 ****
--- 1215,1221 ----
{
static char delims[] = " \t\n";
char *dev_ptr, *dst_ptr, *gw_ptr, *flag_ptr;
+ char *refcnt_ptr, *use_ptr, *metric_ptr;
memset (rt, '\0', sizeof (struct rtentry));
***************
*** 1230,1235 ****
--- 1231,1239 ----
dst_ptr = strtok (NULL, delims); /* destination address */
gw_ptr = strtok (NULL, delims); /* gateway */
flag_ptr = strtok (NULL, delims); /* flags */
+ refcnt_ptr = strtok (NULL, delims); /* reference count */
+ use_ptr = strtok (NULL, delims); /* use */
+ metric_ptr = strtok (NULL, delims); /* metric */
if (flag_ptr == (char *) 0) /* assume that we failed, somewhere. */
{
***************
*** 1251,1256 ****
--- 1255,1261 ----
strtoul (gw_ptr, NULL, 16);
rt->rt_flags = (short) strtoul (flag_ptr, NULL, 16);
+ rt->rt_metric = (short) strtoul (metric_ptr, NULL, 16);
rt->rt_dev = dev_ptr;
return 1;
***************
*** 1302,1315 ****
struct in_addr old_gateway =
((struct sockaddr_in *) (&rt.rt_gateway))-> sin_addr;
! if (old_gateway.s_addr != gateway)
{
syslog (LOG_ERR,
"not replacing existing default route to %s [%s]",
rt.rt_dev,
inet_ntoa (old_gateway));
}
- return 0;
}
memset (&rt, '\0', sizeof (rt));
--- 1307,1327 ----
struct in_addr old_gateway =
((struct sockaddr_in *) (&rt.rt_gateway))-> sin_addr;
! /* if the existing default route is for another gateway, check
! the metric value and if it is the same metric do not add
! the new route or that would cause a route conflict
! NOTE: Can this all be reduced to just checking the metric and
! not the gateway addr? Why does linux only do the
checking
! for conflicts?
! */
! if ((old_gateway.s_addr != gateway) && (rt.rt_metric==0))
{
syslog (LOG_ERR,
"not replacing existing default route to %s [%s]",
rt.rt_dev,
inet_ntoa (old_gateway));
+ return 0; /* do not add only if it creates a clear conflict */
}
}
memset (&rt, '\0', sizeof (rt));
-
To unsubscribe from this list: send the line "unsubscribe linux-ppp" in
the body of a message to [EMAIL PROTECTED]