From owner-svn-src-all@FreeBSD.ORG Wed Oct 12 08:08:08 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A4BBA106566C; Wed, 12 Oct 2011 08:08:08 +0000 (UTC) (envelope-from qingli@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 8A1158FC18; Wed, 12 Oct 2011 08:08:08 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p9C888N2053935; Wed, 12 Oct 2011 08:08:08 GMT (envelope-from qingli@svn.freebsd.org) Received: (from qingli@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p9C8882u053933; Wed, 12 Oct 2011 08:08:08 GMT (envelope-from qingli@svn.freebsd.org) Message-Id: <201110120808.p9C8882u053933@svn.freebsd.org> From: Qing Li Date: Wed, 12 Oct 2011 08:08:08 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r226287 - stable/9/sys/netinet X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2011 08:08:08 -0000 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); } /*