This patch enables the node to respond to ARP requests for

configured proxy ARP entries.

Reviewed by:	bz
MFC after:	immediately
This commit is contained in:
Qing Li 2009-09-15 18:39:27 +00:00
parent 9a3ca99927
commit cd29a7797d

View File

@ -714,62 +714,70 @@ reply:
} else { } else {
struct llentry *lle = NULL; struct llentry *lle = NULL;
if (!V_arp_proxyall)
goto drop;
sin.sin_addr = itaddr; sin.sin_addr = itaddr;
/* XXX MRT use table 0 for arp reply */ IF_AFDATA_LOCK(ifp);
rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, 0); lle = lla_lookup(LLTABLE(ifp), 0, (struct sockaddr *)&sin);
if (!rt) IF_AFDATA_UNLOCK(ifp);
goto drop;
/* if ((lle != NULL) && (lle->la_flags & LLE_PUB)) {
* 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);
if (lle != NULL) {
(void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln); (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
(void)memcpy(ar_sha(ah), &lle->ll_addr, ah->ar_hln); (void)memcpy(ar_sha(ah), &lle->ll_addr, ah->ar_hln);
LLE_RUNLOCK(lle); LLE_RUNLOCK(lle);
} else } else {
goto drop;
/* if (lle != NULL)
* Also check that the node which sent the ARP packet LLE_RUNLOCK(lle);
* 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 */ if (!V_arp_proxyall)
rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, 0); goto drop;
if (!rt)
goto drop; sin.sin_addr = itaddr;
if (rt->rt_ifp != ifp) { /* XXX MRT use table 0 for arp reply */
log(LOG_INFO, "arp_proxy: ignoring request" rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, 0);
" from %s via %s, expecting %s\n", if (!rt)
inet_ntoa(isaddr), ifp->if_xname, goto drop;
rt->rt_ifp->if_xname);
/*
* 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;
}
RTFREE_LOCKED(rt);
(void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
(void)memcpy(ar_sha(ah), enaddr, ah->ar_hln);
/*
* 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); RTFREE_LOCKED(rt);
goto drop;
}
RTFREE_LOCKED(rt);
#ifdef DEBUG_PROXY #ifdef DEBUG_PROXY
printf("arp: proxying for %s\n", printf("arp: proxying for %s\n",
inet_ntoa(itaddr)); inet_ntoa(itaddr));
#endif #endif
}
} }
if (itaddr.s_addr == myaddr.s_addr && if (itaddr.s_addr == myaddr.s_addr &&