Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 31 Jan 2007 14:39:42 +0000
From:      Bruce M Simpson <bms@incunabulum.net>
To:        net@FreeBSD.org
Subject:   [PATCH] Broadcast 169.254.0.0/16 ARP replies for RFC 3927 (Zeroconf)
Message-ID:  <45C0AA2E.30803@incunabulum.net>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------010605080409020901020105
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

I will hold off on committing this pending further feedback.

Regards,
BMS


--------------010605080409020901020105
Content-Type: text/x-patch;
 name="zeroconf-arp.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="zeroconf-arp.diff"

This patch forces the FreeBSD IPv4 ARP code to broadcast ARP replies
for IPv4 link-local addresses, as required by RFC 3927, if and only
if the request was destined for the local machine (ie not proxied).

The code does not set ar_tha by itself; it relies on the AF_ARP handler
in net/if_ethersubr.c to set it to if_broadaddr for us.

Delta 1.97-1.98 of netinet/in.h is required for the IN_LINKLOCAL() macro.

Index: if_ether.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/if_ether.c,v
retrieving revision 1.158
diff -u -p -r1.158 if_ether.c
--- if_ether.c	14 Jan 2007 18:44:17 -0000	1.158
+++ if_ether.c	31 Jan 2007 14:35:48 -0000
@@ -885,11 +885,23 @@ reply:
 		}
 	}
 
+	if (itaddr.s_addr == myaddr.s_addr &&
+	    IN_LINKLOCAL(ntohl(itaddr.s_addr))) {
+		/* RFC 3927 link-local IPv4; always reply by broadcast. */
+#ifdef DEBUG_LINKLOCAL
+		printf("arp: sending reply for link-local addr %s\n",
+		    inet_ntoa(itaddr));
+#endif
+		m->m_flags |= M_BCAST;
+		m->m_flags &= ~M_MCAST;
+	} else {
+		/* default behaviour; never reply by broadcast. */
+		m->m_flags &= ~(M_BCAST|M_MCAST);
+	}
 	(void)memcpy(ar_tpa(ah), ar_spa(ah), ah->ar_pln);
 	(void)memcpy(ar_spa(ah), &itaddr, ah->ar_pln);
 	ah->ar_op = htons(ARPOP_REPLY);
 	ah->ar_pro = htons(ETHERTYPE_IP); /* let's be sure! */
-	m->m_flags &= ~(M_BCAST|M_MCAST); /* never reply by broadcast */
 	m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + (2 * ah->ar_hln);   
 	m->m_pkthdr.len = m->m_len;   
 	sa.sa_family = AF_ARP;

--------------010605080409020901020105--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?45C0AA2E.30803>