1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
*** 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;
/*
|