ARP restriction fix, patch rollup

Stephen D. WIlliams (sdw@lig.net)
Wed, 13 Oct 1999 21:09:42 +0000


This is a multi-part message in MIME format.
--------------7222E04542BA913A6DBDE374
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

This is a combination of patches to prevent 2.2.X kernels from sending ARP
replies when they shouldn't. This set should be more clean than the original
patches.

+ * Stephen D. Williams: Prevent arp_send() from sending
+ * responses when the indirect interface
+ * involved has an inhibit (IFF_NOARP)
flag.
+ * Axel Dunkel : fixes requests from local clients to
farm addresses.
+ * Wensong Zhang : NOARP device (such as tunl) arp fix.

+ * David Couture : Don't ARP when IIF_LOOPBACK.

This has now been extensively tested with linux-2.2.5-15 (RedHat 6.0). It
should patch cleanly against 2.2.13+ but that has not been retested.

This is required to operate effectively in Direct Route (DR) mode with the
Linux Director patches and programs at http://www.LinuxVirtualServer.org.

sdw

--
OptimaLogic - Finding Optimal Solutions     Web/Crypto/OO/Unix/Comm/Video/DBMS
sdw@lig.net   Stephen D. Williams  Senior Consultant/Architect   http://sdw.st
43392 Wayside Cir,Ashburn,VA 20147-4622 703-724-0118W 703-995-0407Fax 5Jan1999

--------------7222E04542BA913A6DBDE374 Content-Type: text/plain; charset=us-ascii; name="sdw_fullarpfix.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="sdw_fullarpfix.patch"

*** linux-2.2.5/net/ipv4/arp.c Sun Mar 21 10:22:00 1999 --- linux/net/ipv4/arp.c Fri Sep 24 17:08:37 1999 *************** *** 65,70 **** --- 65,76 ---- * clean up the APFDDI & gen. FDDI bits. * Alexey Kuznetsov: new arp state machine; * now it is in net/core/neighbour.c. + * Stephen D. Williams: Prevent arp_send() from sending + * responses when the indirect interface + * involved has an inhibit (IFF_NOARP) flag. + * Axel Dunkel : fixes requests from local clients to farm addresses. + * Wensong Zhang : NOARP device (such as tunl) arp fix. + * David Couture : Don't ARP when IIF_LOOPBACK. */ /* RFC1122 Status: *************** *** 427,432 **** --- 438,445 ---- struct sk_buff *skb; struct arphdr *arp; unsigned char *arp_ptr; + struct device *dev_real; /* The real device this ARP is for, if not dev */ + char cbuf[320]; /* * No arp on this interface. *************** *** 436,441 **** --- 449,496 ---- return; /* + * If this ARP is for another device that doesn't want to arp, + * honor that also. (sdw@lig.net) + * All of the next few blocks prevent a number of ARP bugs from + * causing problems, especially in reverse NAT configurations. + * See http://www.LinuxVirtualServer.org for details. + */ + + /* Let's watch ARP's for fun and profit. */ + sprintf(cbuf, "%s arp_send:Re%s src_ip: %s, dest_ip: %s\n", KERN_INFO, + (type==ARPOP_REQUEST)?"quest":"sponse", in_ntoa(src_ip), in_ntoa(dest_ip)); + printk(cbuf); + + dev_real = ip_dev_find(src_ip); + + /* quick fix: warn if down interface is returned */ + if (dev_real != NULL && ( ! (dev_real->flags & IFF_UP))) { + sprintf(cbuf, "%s arp_send: fixme: multiple interfaces with different" + " up/down status but same ip %s detected\n", KERN_INFO, in_ntoa(src_ip)); + printk(cbuf); + dev_real = dev; + } + + if (dev_real != NULL && dev_real != dev) { + char complaint[120]; strcpy(complaint, "arp_send is called with another device's address"); + if (dev_real->flags&IFF_NOARP) { + /* bug fix: arp req for local clients that connect to a farm address 1999-09-17 <ad@Dunkel.de> */ + if (type == ARPOP_REQUEST) { + src_ip = inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE); + sprintf (cbuf, "%s arp_send: changing source ip to %s\n", KERN_INFO, in_ntoa(src_ip)); + printk(cbuf); + } else { /* Must be a mistaken response. */ + strcpy(complaint, " that doesn't want to arp\n"); + printk(complaint); + return; + } + } else { /* allows ARP, just note */ + strcpy(complaint, "\n"); + printk(complaint); + } + } /* Otherwise device matches IP */ + + /* * Allocate a buffer */ *************** *** 534,539 **** --- 590,596 ---- struct rtable *rt; unsigned char *sha, *tha; u32 sip, tip; + struct device *tdev; u16 dev_type = dev->type; int addr_type; struct in_device *in_dev = dev->ip_ptr; *************** *** 627,632 **** --- 684,699 ---- * addresses. If this is one such, delete it. */ if (LOOPBACK(tip) || MULTICAST(tip)) + goto out; + + /* + * Check for the device flags for the target IP. If the IFF_NOARP + * is set, just delete it. No arp reply is sent. -- WZ + * + * If IFF_LOOPBACK is set, then delete it too. /dc. + */ + if ((tdev = ip_dev_find(tip)) && + ((tdev->flags & IFF_NOARP) || (tdev->flags & IFF_LOOPBACK))) goto out; /*

--------------7222E04542BA913A6DBDE374--

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/