Hi folks, Linux 2.2.17 (only tested version, I assume all other 2.2 series suffer from the same problem and possibly 2.4 as well - but I havent even looked at that). Assuming a configuration with linuxbox1 eth0 has adresses 192.168.129.1 and 192.168.130.1, and IP forward being enabled, and another box on the same ethernet with IP 192.168.129.10 and a route to 192.168.130.1 via 192.168.129.1 (eg that machine doesnt handle multiple logical nets on the same ether very well). Now this machine pings eg 192.168.130.10. The linux box will issue a redirect redirecting to 192.168.130.10, assuming that 192.168.129.10 can talk directly to 192.168.130.10. Under RFC 1812 Rule 5.2.7.2 I think this is illegal (different IP networks...). There actually is the "shared_media" sysctl, which is not properly documented in Documentation/network/ip-sysctl.txt. Attached ip-sysctl.txt.patch fixes that and also documents the behaviour of the ../all/.. and the ../default/.. sysctl directories as best to my knowledge (ie, I may be wrong) That sysctl defaults to 1. It could be argued that it should be better turned be 0 (so that RFC1812 compliance is the default). But anyway, that sysctl does not work in the situation outlined above, since the inet_addr_onlink check in net/ipv4/route.c will return true, because FIB_RES_GW(res) will be 0 in that case (192.168.130.0 is directly connected). Since I am not sure if patching that inet_addr_onlink routine may break other stuff, I propose attached route.c.patch, which checks for this condition and puts in the destination address (which is the next hop in this case) on that check. Comments ? Greetings, Mario
*** route.c.orig Fri Oct 6 13:41:50 2000 --- route.c Fri Oct 6 15:12:25 2000 *************** *** 1215,1221 **** if (out_dev == in_dev && err && !(flags&(RTCF_NAT|RTCF_MASQ)) && (IN_DEV_SHARED_MEDIA(out_dev) ! || inet_addr_onlink(out_dev, saddr, FIB_RES_GW(res)))) flags |= RTCF_DOREDIRECT; if (skb->protocol != __constant_htons(ETH_P_IP)) { --- 1215,1222 ---- if (out_dev == in_dev && err && !(flags&(RTCF_NAT|RTCF_MASQ)) && (IN_DEV_SHARED_MEDIA(out_dev) ! || inet_addr_onlink(out_dev, saddr, ! FIB_RES_GW(res) ? FIB_RES_GW(res) : daddr))) flags |= RTCF_DOREDIRECT; if (skb->protocol != __constant_htons(ETH_P_IP)) {
*** ip-sysctl.txt.orig Fri Oct 6 15:14:40 2000 --- ip-sysctl.txt Fri Oct 6 15:22:41 2000 *************** *** 136,142 **** conf/interface/*: conf/all/* is special and changes the settings for all interfaces. ! Change special settings per interface. log_martians - BOOLEAN Log packets with impossible addresses to kernel log. --- 136,149 ---- conf/interface/*: conf/all/* is special and changes the settings for all interfaces. ! Change special settings per interface. Settings are logically ! ORed with the device specific settings in conf/<device>/*, ! so if you want to disable a feature on a specific device, you ! may have to disable it in conf/all/* and reenable it on all ! devices where you want that feature to be enabled. ! ! conf/default/* is special. The settings here are used as the default settings ! for all newly created interfaces. log_martians - BOOLEAN Log packets with impossible addresses to kernel log. *************** *** 165,172 **** enabled both in specific device section and in "all" section. shared_media - BOOLEAN ! undocumented. ! secure_redirects - BOOLEAN Accept ICMP redirect messages only for gateways, listed in default gateway list. --- 172,181 ---- enabled both in specific device section and in "all" section. shared_media - BOOLEAN ! If it is set the kernel does assume that different subnets ! on this device can communicate directly. ! default TRUE ! secure_redirects - BOOLEAN Accept ICMP redirect messages only for gateways, listed in default gateway list.