2.0.30/31-2 bug: ICMP redirect ignored even when ip_forward=0

Ulrik Dickow (ukd@kampsax.dk)
Fri, 20 Jun 1997 22:10:11 +0200


[ The impatient may skip directly to the patch at end ]

When Linux 2.0.30 is built with CONFIG_IP_DUMB_ROUTER undefined (by far the
most usual case), it will ignore all ICMP redirects, even when
/proc/sys/net/ipv4/ip_forward is 0 (as it will be by default if it has also
been built with CONFIG_IP_FORWARD undefined).

This is contrary to <=2.0.29, and to this requirement in net/ipv4/icmp.c:

* RFC1122 (Host Requirements -- Comm. Layer) Status:
* MUST update routing table in response to host or network redirects.
* (host OK, network OBSOLETE)

In 2.0.27-29 icmp.c used compilation constant `CONFIG_IP_FORWARD' like this:

#if defined(CONFIG_IP_FORWARD) && !defined(CONFIG_IP_DUMB_ROUTER)
[...silently ignore ICMP redirect...]
#else
[...verbosely respect ICMP redirect...]
#endif

while 2.0.30 replaced it with kernel variable `sysctl_ip_forward' in this way
(this code is still present in pre-2.0.31-2):

#if !defined(CONFIG_IP_DUMB_ROUTER)
if (sysctl_ip_forward) {
[...silently ignore ICMP redirect...]
}
#else
[...verbosely respect ICMP redirect...]
#endif

To get back the correct behaviour, my patch below changes the logic this way:

#if !defined(CONFIG_IP_DUMB_ROUTER)
if (sysctl_ip_forward) {
[...silently ignore ICMP redirect...]
goto flush_it;
}
#endif
[...verbosely respect ICMP redirect...]
flush_it:

It also corrects the indentation according to the TAB convention of icmp.c.
Beware of Usenet relays truncating long lines!

To check that the ICMP redirects are respected, look in the output from
dmesg(1), and check the dynamic routes in /proc/net/rt_cache. Note that
route(1) and netstat(1) currently only show static routes. The dynamic
routes can be sensibly listed by my Perl script `route-cache.pl' (next mail).

===========================================================================
--- linux-2.0.30/net/ipv4/icmp.c-2.0.30_shipped Fri Apr 18 19:24:32 1997
+++ linux-2.0.30/net/ipv4/icmp.c Fri Jun 20 20:16:05 1997
@@ -828,11 +828,12 @@

#if !defined(CONFIG_IP_DUMB_ROUTER)
if (sysctl_ip_forward) {
- NETDEBUG(printk(KERN_INFO "icmp: ICMP redirect ignored. dest = %lX, "
- "orig gw = %lX, \"new\" gw = %lX, device = %s.\n", ntohl(ip),
- ntohl(source), ntohl(icmph->un.gateway), dev->name));
+ NETDEBUG(printk(KERN_INFO "icmp: ICMP redirect ignored. dest = %lX, "
+ "orig gw = %lX, \"new\" gw = %lX, device = %s.\n", ntohl(ip),
+ ntohl(source), ntohl(icmph->un.gateway), dev->name));
+ goto flush_it;
}
-#else
+#endif
switch(icmph->code & 7)
{
case ICMP_REDIR_NET:
@@ -870,7 +871,6 @@
default:
break;
}
-#endif
/*
* Discard the original packet
*/
===========================================================================

-- 
Ulrik Dickow / ukd@kampsax.dk / Phone +45 36 39 08 00 / Fax +45 36 77 03 01 
.............. Linux -- the choice of a GNU generation ....................