From owner-svn-src-stable@FreeBSD.ORG Mon Oct 10 20:54:21 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 371C7106566B; Mon, 10 Oct 2011 20:54:21 +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 0D2F98FC08; Mon, 10 Oct 2011 20:54:21 +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 p9AKsKoa082188; Mon, 10 Oct 2011 20:54:20 GMT (envelope-from qingli@svn.freebsd.org) Received: (from qingli@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p9AKsKbY082186; Mon, 10 Oct 2011 20:54:20 GMT (envelope-from qingli@svn.freebsd.org) Message-Id: <201110102054.p9AKsKbY082186@svn.freebsd.org> From: Qing Li Date: Mon, 10 Oct 2011 20:54:20 +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: r226232 - 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: Mon, 10 Oct 2011 20:54:21 -0000 Author: qingli Date: Mon Oct 10 20:54:20 2011 New Revision: 226232 URL: http://svn.freebsd.org/changeset/base/226232 Log: MFC 225947 A system may have multiple physical interfaces, all of which are on the same prefix. Since a single route entry is installed for the prefix (without RADIX_MPATH), incoming packets on the interfaces that are not associated with the prefix route may trigger an error message about unable to allocation LLE entry, and fails L2. This patch makes sure a valid route is present in the system, and allow the aforementioned condition to exist and treats as valid. Reviewed by: bz 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:54:50 2011 (r226231) +++ stable/8/sys/netinet/in.c Mon Oct 10 20:54:20 2011 (r226232) @@ -1421,14 +1421,43 @@ in_lltable_rtcheck(struct ifnet *ifp, u_ 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))) { + } + + if (rt->rt_flags & RTF_GATEWAY) { + RTFREE_LOCKED(rt); + return (EINVAL); + } + + /* + * Make sure that at least the destination address is covered + * by the route. This is for handling the case where 2 or more + * 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; + 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; + 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)); + log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n", + inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr)); #endif - error = EINVAL; + break; + } + } } + RTFREE_LOCKED(rt); return (error); }