Date: Mon, 2 Dec 2013 05:35:51 +0000 (UTC) From: "Andrey V. Elsukov" <ae@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r258831 - user/ae/inet6/sys/netinet6 Message-ID: <201312020535.rB25Zp0Q047066@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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)); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201312020535.rB25Zp0Q047066>