From owner-svn-src-user@FreeBSD.ORG Mon Dec 2 05:35:51 2013 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 5946A7CD; Mon, 2 Dec 2013 05:35:51 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 467F3124D; Mon, 2 Dec 2013 05:35:51 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id rB25ZpKH047067; Mon, 2 Dec 2013 05:35:51 GMT (envelope-from ae@svn.freebsd.org) Received: (from ae@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id rB25Zp0Q047066; Mon, 2 Dec 2013 05:35:51 GMT (envelope-from ae@svn.freebsd.org) Message-Id: <201312020535.rB25Zp0Q047066@svn.freebsd.org> From: "Andrey V. Elsukov" Date: Mon, 2 Dec 2013 05:35:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r258831 - user/ae/inet6/sys/netinet6 X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 02 Dec 2013 05:35:51 -0000 Author: ae Date: Mon Dec 2 05:35:50 2013 New Revision: 258831 URL: http://svnweb.freebsd.org/changeset/base/258831 Log: Rework sa6_checkzone's checks. RFC 3493 doesn't requre sin6_scope_id must be set for multicast addresses. Only addresses from link-local and interface-local scopes must have it initialized. Modified: user/ae/inet6/sys/netinet6/scope6.c Modified: user/ae/inet6/sys/netinet6/scope6.c ============================================================================== --- user/ae/inet6/sys/netinet6/scope6.c Mon Dec 2 05:21:54 2013 (r258830) +++ user/ae/inet6/sys/netinet6/scope6.c Mon Dec 2 05:35:50 2013 (r258831) @@ -457,8 +457,9 @@ in6_getscopezone(const struct ifnet *ifp * This function is for checking sockaddr_in6 structure passed * from the application level (usually). * - * sin6_scope_id should be set for link-local unicast addresses and for - * any multicast addresses. + * sin6_scope_id should be set for link-local unicast, link-local and + * interface-local multicast addresses. + * * If it is zero, then look into default zone ids. If default zone id is * not set or disabled, then return error. */ @@ -468,25 +469,28 @@ sa6_checkzone(struct sockaddr_in6 *sa6) int scope; scope = in6_addrscope(&sa6->sin6_addr); - if (!IN6_IS_ADDR_MULTICAST(&sa6->sin6_addr)) { - if (scope == IPV6_ADDR_SCOPE_GLOBAL) - return (sa6->sin6_scope_id ? EINVAL: 0); - /* - * Since ::1 address always configured on the lo0, we can - * automatically set its zone id, when it is not specified. - * Return error, when specified zone id doesn't match with - * actual value. - */ - if (IN6_IS_ADDR_LOOPBACK(&sa6->sin6_addr)) { - if (sa6->sin6_scope_id == 0) - sa6->sin6_scope_id = in6_getscopezone( - V_loif, IPV6_ADDR_SCOPE_LINKLOCAL); - else if (sa6->sin6_scope_id != in6_getscopezone( - V_loif, IPV6_ADDR_SCOPE_LINKLOCAL)) - return (EADDRNOTAVAIL); - } + if (scope == IPV6_ADDR_SCOPE_GLOBAL) + return (sa6->sin6_scope_id ? EINVAL: 0); + if (IN6_IS_ADDR_MULTICAST(&sa6->sin6_addr) && + scope != IPV6_ADDR_SCOPE_LINKLOCAL && + scope != IPV6_ADDR_SCOPE_INTFACELOCAL) { + if (sa6->sin6_scope_id == 0 && V_ip6_use_defzone != 0) + sa6->sin6_scope_id = V_sid_default.s6id_list[scope]; + return (0); + } + /* + * Since ::1 address always configured on the lo0, we can + * automatically set its zone id, when it is not specified. + * Return error, when specified zone id doesn't match with + * actual value. + */ + if (IN6_IS_ADDR_LOOPBACK(&sa6->sin6_addr)) { + if (sa6->sin6_scope_id == 0) + sa6->sin6_scope_id = in6_getscopezone(V_loif, scope); + else if (sa6->sin6_scope_id != in6_getscopezone(V_loif, scope)) + return (EADDRNOTAVAIL); } - /* Any multicast and link-local addresses. */ + /* XXX: we can validate sin6_scope_id here */ if (sa6->sin6_scope_id != 0) return (0); if (V_ip6_use_defzone != 0) @@ -507,11 +511,11 @@ sa6_checkzone_ifp(struct ifnet *ifp, str scope = in6_addrscope(&sa6->sin6_addr); if (scope == IPV6_ADDR_SCOPE_LINKLOCAL || scope == IPV6_ADDR_SCOPE_INTFACELOCAL) { - if (sa6->sin6_scope_id != 0 && - sa6->sin6_scope_id != in6_getscopezone(ifp, scope)) - return (EADDRNOTAVAIL); - if (sa6->sin6_scope_id == 0) + if (sa6->sin6_scope_id == 0) { sa6->sin6_scope_id = in6_getscopezone(ifp, scope); + return (0); + } else if (sa6->sin6_scope_id != in6_getscopezone(ifp, scope)) + return (EADDRNOTAVAIL); } return (sa6_checkzone(sa6)); }