From owner-svn-src-stable@FreeBSD.ORG Thu Oct 13 00:37:40 2011 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2AD13106567B; Thu, 13 Oct 2011 00:37:40 +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 19C4D8FC0C; Thu, 13 Oct 2011 00:37:40 +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 p9D0bdWx090923; Thu, 13 Oct 2011 00:37:39 GMT (envelope-from qingli@svn.freebsd.org) Received: (from qingli@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p9D0bdMM090921; Thu, 13 Oct 2011 00:37:39 GMT (envelope-from qingli@svn.freebsd.org) Message-Id: <201110130037.p9D0bdMM090921@svn.freebsd.org> From: Qing Li Date: Thu, 13 Oct 2011 00:37:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r226330 - stable/8/sys/netinet X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2011 00:37:40 -0000 Author: qingli Date: Thu Oct 13 00:37:39 2011 New Revision: 226330 URL: http://svn.freebsd.org/changeset/base/226330 Log: MFC 226224 All indirect routes will fail the rtcheck, except for a special host route where the destination IP and the gateway IP is the same. This special case handling is only meant for backward compatibility reason. The last commit introduced a bug in the route check logic, where a valid special case is treated as an error. This patch fixes that bug along with some code cleanup. Suggested by: glebius smirnoff Reviewed by: kmacy, discussed with glebius smirnoff 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 Wed Oct 12 21:45:12 2011 (r226329) +++ stable/8/sys/netinet/in.c Thu Oct 13 00:37:39 2011 (r226330) @@ -1414,8 +1414,6 @@ 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)); @@ -1432,21 +1430,16 @@ in_lltable_rtcheck(struct ifnet *ifp, u_ * such as MANET, and the interface is of the correct type, then * allow for ARP to proceed. */ - 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; - } - if (rt->rt_flags & RTF_GATEWAY) { - RTFREE_LOCKED(rt); - return (EINVAL); + if (!(rt->rt_flags & RTF_HOST) || !rt->rt_ifp || + rt->rt_ifp->if_type != IFT_ETHER || + (rt->rt_ifp->if_flags & + (IFF_NOARP | IFF_STATICARP)) != 0 || + memcmp(rt->rt_gateway->sa_data, l3addr->sa_data, + sizeof(in_addr_t)) != 0) { + RTFREE_LOCKED(rt); + return (EINVAL); + } } /* @@ -1455,32 +1448,31 @@ in_lltable_rtcheck(struct ifnet *ifp, u_ * interfaces have the same prefix. An incoming packet arrives * on one interface and the corresponding outgoing packet leaves * another interface. - * */ if (rt->rt_ifp != ifp) { - char *sa, *mask, *addr, *lim; + const char *sa, *mask, *addr, *lim; int len; - sa = (char *)rt_key(rt); - mask = (char *)rt_mask(rt); - addr = (char *)__DECONST(struct sockaddr *, l3addr); - len = ((struct sockaddr_in *)__DECONST(struct sockaddr *, l3addr))->sin_len; + sa = (const char *)rt_key(rt); + mask = (const char *)rt_mask(rt); + addr = (const char *)l3addr; + len = ((const struct sockaddr_in *)l3addr)->sin_len; lim = addr + len; for ( ; addr < lim; sa++, mask++, addr++) { if ((*sa ^ *addr) & *mask) { - error = EINVAL; #ifdef DIAGNOSTIC log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n", inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr)); #endif - break; + RTFREE_LOCKED(rt); + return (EINVAL); } } } RTFREE_LOCKED(rt); - return (error); + return (0); } /*