From owner-svn-src-head@FreeBSD.ORG Thu May 21 17:01:39 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 134C81065672; Thu, 21 May 2009 17:01:39 +0000 (UTC) (envelope-from bms@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 01E878FC16; Thu, 21 May 2009 17:01:39 +0000 (UTC) (envelope-from bms@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n4LH1c3h072814; Thu, 21 May 2009 17:01:38 GMT (envelope-from bms@svn.freebsd.org) Received: (from bms@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n4LH1cur072813; Thu, 21 May 2009 17:01:38 GMT (envelope-from bms@svn.freebsd.org) Message-Id: <200905211701.n4LH1cur072813@svn.freebsd.org> From: Bruce M Simpson Date: Thu, 21 May 2009 17:01:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r192547 - head/sys/netinet6 X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 21 May 2009 17:01:39 -0000 Author: bms Date: Thu May 21 17:01:38 2009 New Revision: 192547 URL: http://svn.freebsd.org/changeset/base/192547 Log: Pullup svn source to p4 top of tree: * Fix LOR in MLDv2 query input path. * Strip embedded KAME scope IDs for on-wire IPv6 address comparisons. Modified: head/sys/netinet6/mld6.c Modified: head/sys/netinet6/mld6.c ============================================================================== --- head/sys/netinet6/mld6.c Thu May 21 16:48:06 2009 (r192546) +++ head/sys/netinet6/mld6.c Thu May 21 17:01:38 2009 (r192547) @@ -629,8 +629,8 @@ mld_v1_input_query(struct ifnet *ifp, co #endif IN6_MULTI_LOCK(); - IF_ADDR_LOCK(ifp); MLD_LOCK(); + IF_ADDR_LOCK(ifp); mli = MLD_IFINFO(ifp); KASSERT(mli != NULL, ("%s: no mld_ifinfo for ifp %p", __func__, ifp)); @@ -661,12 +661,12 @@ mld_v1_input_query(struct ifnet *ifp, co /* * MLDv1 General Query. * If this was not sent to the all-nodes group, ignore it. - * - * XXX Do we need to check for a scope ID in the destination - * address on input and strip it? */ - if (IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, - &in6addr_linklocal_allnodes)) { + struct in6_addr dst; + + dst = ip6->ip6_dst; + in6_clearscope(&dst); + if (IN6_ARE_ADDR_EQUAL(&dst, &in6addr_linklocal_allnodes)) { /* * For each reporting group joined on this * interface, kick the report timer. @@ -685,8 +685,8 @@ mld_v1_input_query(struct ifnet *ifp, co } } - MLD_UNLOCK(); IF_ADDR_UNLOCK(ifp); + MLD_UNLOCK(); IN6_MULTI_UNLOCK(); return (0); @@ -807,8 +807,8 @@ mld_v2_input_query(struct ifnet *ifp, co return (EMSGSIZE); IN6_MULTI_LOCK(); - IF_ADDR_LOCK(ifp); MLD_LOCK(); + IF_ADDR_LOCK(ifp); mli = MLD_IFINFO(ifp); KASSERT(mli != NULL, ("%s: no mld_ifinfo for ifp %p", __func__, ifp)); @@ -819,17 +819,25 @@ mld_v2_input_query(struct ifnet *ifp, co mli->mli_qi = qqi; mli->mli_qri = maxdelay; - CTR4(KTR_MLD, "%s: qrv %d qi %d qri %d", __func__, qrv, qqi, + CTR4(KTR_MLD, "%s: qrv %d qi %d maxdelay %d", __func__, qrv, qqi, maxdelay); if (IN6_IS_ADDR_UNSPECIFIED(&mld->mld_addr)) { /* * MLDv2 General Query. + * * Schedule a current-state report on this ifp for * all groups, possibly containing source lists. + * + * Strip scope ID embedded by ip6_input(). We do not need + * to do this for the MLD payload. */ - if (!IN6_ARE_ADDR_EQUAL(&in6addr_linklocal_allnodes, - &ip6->ip6_dst) || nsrc > 0) { + struct in6_addr dst; + + dst = ip6->ip6_dst; + in6_clearscope(&dst); + if (!IN6_ARE_ADDR_EQUAL(&dst, &in6addr_linklocal_allnodes) || + nsrc > 0) { /* * General Queries SHOULD be directed to ff02::1. * A general query with a source list has undefined @@ -885,8 +893,8 @@ mld_v2_input_query(struct ifnet *ifp, co } out_locked: - MLD_UNLOCK(); IF_ADDR_UNLOCK(ifp); + MLD_UNLOCK(); IN6_MULTI_UNLOCK(); return (0); @@ -1016,15 +1024,19 @@ mld_v1_input_report(struct ifnet *ifp, c { struct in6_ifaddr *ia; struct in6_multi *inm; + struct in6_addr src, dst; #ifdef KTR char ip6tbuf[INET6_ADDRSTRLEN]; #endif if (ifp->if_flags & IFF_LOOPBACK) return (0); + if (!IN6_IS_ADDR_MULTICAST(&mld->mld_addr)) + return (EINVAL); - if (!IN6_IS_ADDR_MULTICAST(&mld->mld_addr) || - !IN6_ARE_ADDR_EQUAL(&mld->mld_addr, &ip6->ip6_dst)) + dst = ip6->ip6_dst; + in6_clearscope(&dst); + if (!IN6_ARE_ADDR_EQUAL(&mld->mld_addr, &dst)) return (EINVAL); /* @@ -1032,16 +1044,23 @@ mld_v1_input_report(struct ifnet *ifp, c * leave requires knowing that we are the only member of a * group. Assume we used the link-local address if available, * otherwise look for ::. + * + * XXX Note that scope ID comparison is needed for the address + * returned by in6ifa_ifpforlinklocal(), but SHOULD NOT be + * performed for the on-wire address. */ ia = in6ifa_ifpforlinklocal(ifp, IN6_IFF_NOTREADY|IN6_IFF_ANYCAST); + src = ip6->ip6_src; + in6_clearscope(&src); if ((ia && IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, IA6_IN6(ia))) || - (ia == NULL && IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src))) + (ia == NULL && IN6_IS_ADDR_UNSPECIFIED(&src))) return (0); CTR3(KTR_MLD, "process v1 report %s on ifp %p(%s)", ip6_sprintf(ip6tbuf, &mld->mld_addr), ifp, ifp->if_xname); IN6_MULTI_LOCK(); + MLD_LOCK(); IF_ADDR_LOCK(ifp); /* @@ -1090,6 +1109,7 @@ mld_v1_input_report(struct ifnet *ifp, c } out_locked: + MLD_UNLOCK(); IF_ADDR_UNLOCK(ifp); IN6_MULTI_UNLOCK();