svn commit: r226287 - stable/9/sys/netinet
Qing Li
qingli at FreeBSD.org
Wed Oct 12 08:08:08 UTC 2011
Author: qingli
Date: Wed Oct 12 08:08:08 2011
New Revision: 226287
URL: http://svn.freebsd.org/changeset/base/226287
Log:
MFC 225946
This patch allows ARP to work properly in the presence of
self-referencing routes. This patch is a rework of r223862.
Reviewed by: bz, zec
Approved by: re (kib)
Modified:
stable/9/sys/netinet/in.c
Directory Properties:
stable/9/sys/ (props changed)
stable/9/sys/amd64/include/xen/ (props changed)
stable/9/sys/boot/ (props changed)
stable/9/sys/boot/i386/efi/ (props changed)
stable/9/sys/boot/ia64/efi/ (props changed)
stable/9/sys/boot/ia64/ski/ (props changed)
stable/9/sys/boot/powerpc/boot1.chrp/ (props changed)
stable/9/sys/boot/powerpc/ofw/ (props changed)
stable/9/sys/cddl/contrib/opensolaris/ (props changed)
stable/9/sys/conf/ (props changed)
stable/9/sys/contrib/dev/acpica/ (props changed)
stable/9/sys/contrib/octeon-sdk/ (props changed)
stable/9/sys/contrib/pf/ (props changed)
stable/9/sys/contrib/x86emu/ (props changed)
Modified: stable/9/sys/netinet/in.c
==============================================================================
--- stable/9/sys/netinet/in.c Wed Oct 12 07:16:38 2011 (r226286)
+++ stable/9/sys/netinet/in.c Wed Oct 12 08:08:08 2011 (r226287)
@@ -1411,6 +1411,8 @@ static int
in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr)
{
struct rtentry *rt;
+ struct ifnet *xifp;
+ int error = 0;
KASSERT(l3addr->sa_family == AF_INET,
("sin_family %d", l3addr->sa_family));
@@ -1418,30 +1420,35 @@ in_lltable_rtcheck(struct ifnet *ifp, u_
/* XXX rtalloc1 should take a const param */
rt = rtalloc1(__DECONST(struct sockaddr *, l3addr), 0, 0);
+ if (rt == NULL)
+ return (EINVAL);
+
/*
* If the gateway for an existing host route matches the target L3
- * address, allow for ARP to proceed.
+ * address, which is a special route inserted by some implementation
+ * such as MANET, and the interface is of the correct type, then
+ * allow for ARP to proceed.
*/
- if (rt != NULL && (rt->rt_flags & (RTF_HOST|RTF_GATEWAY)) &&
- rt->rt_gateway->sa_family == AF_INET &&
- memcmp(rt->rt_gateway->sa_data, l3addr->sa_data, 4) == 0) {
- RTFREE_LOCKED(rt);
- return (0);
- }
-
- if (rt == NULL || (!(flags & LLE_PUB) &&
- ((rt->rt_flags & RTF_GATEWAY) ||
- (rt->rt_ifp != ifp)))) {
+ if (rt->rt_flags & (RTF_GATEWAY | RTF_HOST)) {
+ xifp = rt->rt_ifp;
+
+ if (xifp && (xifp->if_type != IFT_ETHER ||
+ (xifp->if_flags & (IFF_NOARP | IFF_STATICARP)) != 0))
+ error = EINVAL;
+
+ if (memcmp(rt->rt_gateway->sa_data, l3addr->sa_data,
+ sizeof(in_addr_t)) != 0)
+ error = EINVAL;
+ } else if (!(flags & LLE_PUB) && ((rt->rt_flags & RTF_GATEWAY) ||
+ (rt->rt_ifp != ifp))) {
#ifdef DIAGNOSTIC
log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n",
inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr));
#endif
- if (rt != NULL)
- RTFREE_LOCKED(rt);
- return (EINVAL);
+ error = EINVAL;
}
RTFREE_LOCKED(rt);
- return 0;
+ return (error);
}
/*
More information about the svn-src-stable-9
mailing list