svn commit: r186317 - head/sys/netinet
Qing Li
qingli at FreeBSD.org
Fri Dec 19 11:07:35 UTC 2008
Author: qingli
Date: Fri Dec 19 11:07:34 2008
New Revision: 186317
URL: http://svn.freebsd.org/changeset/base/186317
Log:
The proxy-arp code was broken and responds to ARP
requests for addresses that are not proxied locally.
Modified:
head/sys/netinet/if_ether.c
Modified: head/sys/netinet/if_ether.c
==============================================================================
--- head/sys/netinet/if_ether.c Fri Dec 19 09:32:31 2008 (r186316)
+++ head/sys/netinet/if_ether.c Fri Dec 19 11:07:34 2008 (r186317)
@@ -660,69 +660,64 @@ reply:
(void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
(void)memcpy(ar_sha(ah), enaddr, ah->ar_hln);
} else {
- if (la == NULL) {
- if (!V_arp_proxyall)
- goto drop;
-
- sin.sin_addr = itaddr;
- /* XXX MRT use table 0 for arp reply */
- rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, 0);
- if (!rt)
- goto drop;
- /*
- * Don't send proxies for nodes on the same interface
- * as this one came out of, or we'll get into a fight
- * over who claims what Ether address.
- */
- if (rt->rt_ifp == ifp) {
- RTFREE_LOCKED(rt);
- goto drop;
- }
- (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
- (void)memcpy(ar_sha(ah), enaddr, ah->ar_hln);
+ struct llentry *lle = NULL;
+
+ if (!V_arp_proxyall)
+ goto drop;
+
+ sin.sin_addr = itaddr;
+ /* XXX MRT use table 0 for arp reply */
+ rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, 0);
+ if (!rt)
+ goto drop;
+
+ /*
+ * Don't send proxies for nodes on the same interface
+ * as this one came out of, or we'll get into a fight
+ * over who claims what Ether address.
+ */
+ if (!rt->rt_ifp || rt->rt_ifp == ifp) {
RTFREE_LOCKED(rt);
+ goto drop;
+ }
+ IF_AFDATA_LOCK(rt->rt_ifp);
+ lle = lla_lookup(LLTABLE(rt->rt_ifp), 0, (struct sockaddr *)&sin);
+ IF_AFDATA_UNLOCK(rt->rt_ifp);
+ RTFREE_LOCKED(rt);
- /*
- * Also check that the node which sent the ARP packet
- * is on the the interface we expect it to be on. This
- * avoids ARP chaos if an interface is connected to the
- * wrong network.
- */
- sin.sin_addr = isaddr;
-
- /* XXX MRT use table 0 for arp checks */
- rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, 0);
- if (!rt)
- goto drop;
- if (rt->rt_ifp != ifp) {
- log(LOG_INFO, "arp_proxy: ignoring request"
- " from %s via %s, expecting %s\n",
- inet_ntoa(isaddr), ifp->if_xname,
- rt->rt_ifp->if_xname);
- RTFREE_LOCKED(rt);
- goto drop;
- }
+ if (lle != NULL) {
+ (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
+ (void)memcpy(ar_sha(ah), &lle->ll_addr, ah->ar_hln);
+ LLE_RUNLOCK(lle);
+ } else
+ goto drop;
+
+ /*
+ * Also check that the node which sent the ARP packet
+ * is on the the interface we expect it to be on. This
+ * avoids ARP chaos if an interface is connected to the
+ * wrong network.
+ */
+ sin.sin_addr = isaddr;
+
+ /* XXX MRT use table 0 for arp checks */
+ rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, 0);
+ if (!rt)
+ goto drop;
+ if (rt->rt_ifp != ifp) {
+ log(LOG_INFO, "arp_proxy: ignoring request"
+ " from %s via %s, expecting %s\n",
+ inet_ntoa(isaddr), ifp->if_xname,
+ rt->rt_ifp->if_xname);
RTFREE_LOCKED(rt);
+ goto drop;
+ }
+ RTFREE_LOCKED(rt);
#ifdef DEBUG_PROXY
- printf("arp: proxying for %s\n",
- inet_ntoa(itaddr));
+ printf("arp: proxying for %s\n",
+ inet_ntoa(itaddr));
#endif
- } else {
- /*
- * Return proxied ARP replies only on the interface
- * or bridge cluster where this network resides.
- * Otherwise we may conflict with the host we are
- * proxying for.
- */
- if (la->lle_tbl->llt_ifp != ifp &&
- (la->lle_tbl->llt_ifp->if_bridge != ifp->if_bridge ||
- ifp->if_bridge == NULL)) {
- goto drop;
- }
- (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
- (void)memcpy(ar_sha(ah), &la->ll_addr, ah->ar_hln);
- }
}
if (la != NULL)
More information about the svn-src-head
mailing list