kerneld/request-route interaction bug with kernel patch

Chris Faylor (cgf@bbc.com)
Sun, 30 Jun 1996 22:53:08 -0400


I've been attempting to use kerneld to automatically dial out via PPP
when a network connection is attempted and no connection is currently
active. It works, but I think there is a bug in how it works.

The bug is that the first time a connection is attempted, the modem dials
but the kernel reports that there is no route to the host. Subsequent
connection requests succeed, of course.

I think that the problem is fixed by the patch below. Possibly there is
a better way to do this, but this is working for me. With this patch,
for example, the first 'rlogin' to a remote system will succeed. Without
it, the rlogin will fail.

-Chris

--- net/ipv4/route.c.orig Fri Jun 21 14:46:11 1996
+++ net/ipv4/route.c Mon Jun 24 23:40:38 1996
@@ -1392,7 +1392,7 @@

*/

-struct rtable * ip_rt_slow_route (__u32 daddr, int local)
+struct rtable * ip_rt_slow_route (__u32 daddr, int local)
{
unsigned hash = ip_rt_hash_code(daddr)^local;
struct rtable * rth;
@@ -1424,21 +1424,11 @@

if (!f || (fi->fib_flags & RTF_REJECT))
{
-#ifdef CONFIG_KERNELD
- char wanted_route[20];
-#endif
#if RT_CACHE_DEBUG >= 2
printk("rt_route failed @%08x\n", daddr);
#endif
ip_rt_unlock();
kfree_s(rth, sizeof(struct rtable));
-#ifdef CONFIG_KERNELD
- daddr=ntohl(daddr);
- sprintf(wanted_route, "%d.%d.%d.%d",
- (int)(daddr >> 24) & 0xff, (int)(daddr >> 16) & 0xff,
- (int)(daddr >> 8) & 0xff, (int)daddr & 0xff);
- kerneld_route(wanted_route); /* Dynamic route request */
-#endif
return NULL;
}

@@ -1506,7 +1496,7 @@
atomic_dec(&rt->rt_refcnt);
}

-struct rtable * ip_rt_route(__u32 daddr, int local)
+static __inline struct rtable * real_ip_rt_route(__u32 daddr, int local)
{
struct rtable * rth;

@@ -1524,6 +1514,24 @@
}
}
return ip_rt_slow_route (daddr, local);
+}
+
+struct rtable * ip_rt_route (__u32 daddr, int local)
+{
+#ifdef CONFIG_KERNELD
+ struct rtable *rth;
+ char wanted_route[20];
+
+ if ((rth = real_ip_rt_route(daddr, local)) != NULL)
+ return rth;
+
+ daddr=ntohl(daddr);
+ sprintf(wanted_route, "%d.%d.%d.%d",
+ (int)(daddr >> 24) & 0xff, (int)(daddr >> 16) & 0xff,
+ (int)(daddr >> 8) & 0xff, (int)daddr & 0xff);
+ kerneld_route(wanted_route); /* Dynamic route request */
+#endif
+ return real_ip_rt_route(daddr, local);
}

/*

--
http://www.bbc.com/	cgf@bbc.com			"Strange how unreal
VMS=>UNIX Solutions	Boston Business Computing	 the real can be."