Date: Mon, 10 Oct 2011 19:41:00 +0000 (UTC) From: Qing Li <qingli@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r226230 - stable/8/sys/netinet Message-ID: <201110101941.p9AJf0Zv078749@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: qingli Date: Mon Oct 10 19:41:00 2011 New Revision: 226230 URL: http://svn.freebsd.org/changeset/base/226230 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 Modified: stable/8/sys/netinet/in.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) Modified: stable/8/sys/netinet/in.c ============================================================================== --- stable/8/sys/netinet/in.c Mon Oct 10 19:07:55 2011 (r226229) +++ stable/8/sys/netinet/in.c Mon Oct 10 19:41:00 2011 (r226230) @@ -1393,6 +1393,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)); @@ -1400,30 +1402,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); } /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110101941.p9AJf0Zv078749>