patch-1.3.75 linux/net/ipv4/arp.c

Next file: linux/net/ipv4/icmp.c
Previous file: linux/net/ipv4/af_inet.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.74/linux/net/ipv4/arp.c linux/net/ipv4/arp.c
@@ -52,6 +52,7 @@
  *		Alan Cox	:	Missing unlock in device events.
  *		Eckes		:	ARP ioctl control errors.
  *		Alexey Kuznetsov:	Arp free fix.
+ *		Manuel Rodriguez:	Gratutious ARP.
  */
 
 /* RFC1122 Status:
@@ -783,7 +784,7 @@
 	unsigned char *arp_ptr= (unsigned char *)(arp+1);
 	struct arp_table *entry;
 	struct arp_table *proxy_entry;
-	unsigned long hash;
+	unsigned long hash, grat=0;
 	unsigned char ha[MAX_ADDR_LEN];	/* So we can enable ints again. */
 	unsigned char *sha,*tha;
 	u32 sip,tip;
@@ -928,6 +929,7 @@
  * 	check if that someone else is one of our proxies.  If it isn't,
  * 	we can toss it.
  */
+			grat = (sip == tip) && (sha == tha);
 			arp_fast_lock();
 
 			for (proxy_entry=arp_proxy_list;
@@ -949,6 +951,12 @@
 			}
 			if (proxy_entry)
 			{
+				if (grat)
+				{
+					if(!(proxy_entry->flags&ATF_PERM))
+						arp_destroy(proxy_entry);
+					goto gratuitous;
+				}
 				memcpy(ha, proxy_entry->ha, dev->addr_len);
 				arp_unlock();
 				arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,ha, sha);
@@ -957,6 +965,8 @@
 			}
 			else
 			{
+				if (grat) 
+					goto gratuitous;
 				arp_unlock();
 				kfree_skb(skb, FREE_READ);
 				return 0;
@@ -989,6 +999,8 @@
 
 	arp_fast_lock();
 
+gratuitous:
+
 	hash = HASH(sip);
 
 	for (entry=arp_tables[hash]; entry; entry=entry->next)
@@ -1026,6 +1038,10 @@
 /*
  * 	No entry found.  Need to add a new entry to the arp table.
  */
+
+		if (grat) 
+			goto end;
+
 		entry = (struct arp_table *)kmalloc(sizeof(struct arp_table),GFP_ATOMIC);
 		if(entry == NULL)
 		{
@@ -1072,6 +1088,8 @@
 /*
  *	Replies have been sent, and entries have been added.  All done.
  */
+
+end:
 	kfree_skb(skb, FREE_READ);
 	arp_unlock();
 	return 0;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this