Date: Fri, 25 Oct 2013 00:35:26 +0000 (UTC) From: "Andrey V. Elsukov" <ae@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r257083 - user/ae/inet6/sys/netinet6 Message-ID: <201310250035.r9P0ZQYE007797@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ae Date: Fri Oct 25 00:35:26 2013 New Revision: 257083 URL: http://svnweb.freebsd.org/changeset/base/257083 Log: Remove all assumptions about embedded form of addresses: * cleanup comments; * remove in6_setscope(), in6_clearscope() and sa6_embedscope() calls; * use in6_getscopezone() to initialize sin6_scope_id; * use sa6_checkzone() to check addresses for correctness; * don't check unsigned ifindex for negative values. Modified: user/ae/inet6/sys/netinet6/in6_mcast.c Modified: user/ae/inet6/sys/netinet6/in6_mcast.c ============================================================================== --- user/ae/inet6/sys/netinet6/in6_mcast.c Fri Oct 25 00:24:55 2013 (r257082) +++ user/ae/inet6/sys/netinet6/in6_mcast.c Fri Oct 25 00:35:26 2013 (r257083) @@ -330,7 +330,6 @@ im6o_match_source(const struct ip6_mopti psa = (const sockunion_t *)src; find.im6s_addr = psa->sin6.sin6_addr; - in6_clearscope(&find.im6s_addr); /* XXX */ ims = RB_FIND(ip6_msource_tree, &imf->im6f_sources, &find); return ((struct in6_msource *)ims); @@ -1162,20 +1161,8 @@ in6_mc_join_locked(struct ifnet *ifp, co char ip6tbuf[INET6_ADDRSTRLEN]; #endif -#ifdef INVARIANTS - /* - * Sanity: Check scope zone ID was set for ifp, if and - * only if group is scoped to an interface. - */ KASSERT(IN6_IS_ADDR_MULTICAST(mcaddr), ("%s: not a multicast address", __func__)); - if (IN6_IS_ADDR_MC_LINKLOCAL(mcaddr) || - IN6_IS_ADDR_MC_INTFACELOCAL(mcaddr)) { - KASSERT(mcaddr->s6_addr16[1] != 0, - ("%s: scope zone ID not set", __func__)); - } -#endif - IN6_MULTI_LOCK_ASSERT(); CTR4(KTR_MLD, "%s: join %s on %p(%s))", __func__, @@ -1375,9 +1362,6 @@ in6p_block_unblock_source(struct inpcb * if (!IN6_IS_ADDR_MULTICAST(&gsa->sin6.sin6_addr)) return (EINVAL); - - (void)in6_setscope(&gsa->sin6.sin6_addr, ifp, NULL); - /* * Check if we are actually a member of this group. */ @@ -1595,7 +1579,6 @@ in6p_get_source_filters(struct inpcb *in ifp = ifnet_byindex(msfr.msfr_ifindex); if (ifp == NULL) return (EADDRNOTAVAIL); - (void)in6_setscope(&gsa->sin6.sin6_addr, ifp, NULL); INP_WLOCK(inp); @@ -1873,25 +1856,23 @@ in6p_join_group(struct inpcb *inp, struc gsa->sin6.sin6_len != sizeof(struct sockaddr_in6)) return (EINVAL); + if (gsr.gsr_interface == 0 || V_if_index < gsr.gsr_interface) + return (EADDRNOTAVAIL); + ifp = ifnet_byindex(gsr.gsr_interface); + if (ifp == NULL) + return (EADDRNOTAVAIL); + if (sopt->sopt_name == MCAST_JOIN_SOURCE_GROUP) { if (ssa->sin6.sin6_family != AF_INET6 || ssa->sin6.sin6_len != sizeof(struct sockaddr_in6)) return (EINVAL); if (IN6_IS_ADDR_MULTICAST(&ssa->sin6.sin6_addr)) return (EINVAL); - /* - * TODO: Validate embedded scope ID in source - * list entry against passed-in ifp, if and only - * if source list filter entry is iface or node local. - */ - in6_clearscope(&ssa->sin6.sin6_addr); ssa->sin6.sin6_port = 0; - ssa->sin6.sin6_scope_id = 0; + ssa->sin6.sin6_scope_id = in6_getscopezone(ifp, + in6_addrscope(&ssa->sin6.sin6_addr)); } - if (gsr.gsr_interface == 0 || V_if_index < gsr.gsr_interface) - return (EADDRNOTAVAIL); - ifp = ifnet_byindex(gsr.gsr_interface); break; default: @@ -1908,15 +1889,12 @@ in6p_join_group(struct inpcb *inp, struc return (EADDRNOTAVAIL); gsa->sin6.sin6_port = 0; - gsa->sin6.sin6_scope_id = 0; - /* * Always set the scope zone ID on memberships created from userland. * Use the passed-in ifp to do this. - * XXX The in6_setscope() return value is meaningless. - * XXX SCOPE6_LOCK() is taken by in6_setscope(). */ - (void)in6_setscope(&gsa->sin6.sin6_addr, ifp, NULL); + gsa->sin6.sin6_scope_id = in6_getscopezone(ifp, + in6_addrscope(&gsa->sin6.sin6_addr)); imo = in6p_findmoptions(inp); idx = im6o_match_group(imo, ifp, &gsa->sa); @@ -2122,9 +2100,6 @@ in6p_leave_group(struct inpcb *inp, stru /* * Chew everything passed in up into a struct group_source_req * as that is easier to process. - * Note: Any embedded scope ID in the multicast group passed - * in by userland is ignored, the interface index is the recommended - * mechanism to specify an interface; see below. */ switch (sopt->sopt_name) { case IPV6_LEAVE_GROUP: @@ -2163,12 +2138,6 @@ in6p_leave_group(struct inpcb *inp, stru return (EINVAL); if (IN6_IS_ADDR_MULTICAST(&ssa->sin6.sin6_addr)) return (EINVAL); - /* - * TODO: Validate embedded scope ID in source - * list entry against passed-in ifp, if and only - * if source list filter entry is iface or node local. - */ - in6_clearscope(&ssa->sin6.sin6_addr); } gsa->sin6.sin6_port = 0; gsa->sin6.sin6_scope_id = 0; @@ -2190,38 +2159,26 @@ in6p_leave_group(struct inpcb *inp, stru * was provided separately, attempt to look the membership up * from the default scope as a last resort to disambiguate * the membership we are being asked to leave. - * XXX SCOPE6 lock potentially taken here. */ if (ifindex != 0) { - if (ifindex < 0 || V_if_index < ifindex) + if (V_if_index < ifindex) return (EADDRNOTAVAIL); ifp = ifnet_byindex(ifindex); if (ifp == NULL) return (EADDRNOTAVAIL); - (void)in6_setscope(&gsa->sin6.sin6_addr, ifp, NULL); } else { - error = sa6_embedscope(&gsa->sin6, V_ip6_use_defzone); + error = sa6_checkzone(&gsa->sin6); if (error) - return (EADDRNOTAVAIL); + return (error); /* * Some badly behaved applications don't pass an ifindex * or a scope ID, which is an API violation. In this case, * perform a lookup as per a v6 join. - * - * XXX For now, stomp on zone ID for the corner case. - * This is not the 'KAME way', but we need to see the ifp - * directly until such time as this implementation is - * refactored, assuming the scope IDs are the way to go. */ - ifindex = ntohs(gsa->sin6.sin6_addr.s6_addr16[1]); - if (ifindex == 0) { - CTR2(KTR_MLD, "%s: warning: no ifindex, looking up " - "ifp for group %s.", __func__, - ip6_sprintf(ip6tbuf, &gsa->sin6.sin6_addr)); - ifp = in6p_lookup_mcast_ifp(inp, &gsa->sin6); - } else { - ifp = ifnet_byindex(ifindex); - } + CTR2(KTR_MLD, "%s: warning: no ifindex, looking up " + "ifp for group %s.", __func__, ip6_sprintf(ip6tbuf, + &gsa->sin6.sin6_addr)); + ifp = in6p_lookup_mcast_ifp(inp, &gsa->sin6); if (ifp == NULL) return (EADDRNOTAVAIL); } @@ -2351,7 +2308,7 @@ in6p_set_multicast_if(struct inpcb *inp, error = sooptcopyin(sopt, &ifindex, sizeof(u_int), sizeof(u_int)); if (error) return (error); - if (ifindex < 0 || V_if_index < ifindex) + if (V_if_index < ifindex) return (EINVAL); ifp = ifnet_byindex(ifindex); @@ -2409,8 +2366,6 @@ in6p_set_source_filters(struct inpcb *in ifp = ifnet_byindex(msfr.msfr_ifindex); if (ifp == NULL) return (EADDRNOTAVAIL); - (void)in6_setscope(&gsa->sin6.sin6_addr, ifp, NULL); - /* * Take the INP write lock. * Check if this socket is a member of this group. @@ -2491,12 +2446,6 @@ in6p_set_source_filters(struct inpcb *in error = EINVAL; break; } - /* - * TODO: Validate embedded scope ID in source - * list entry against passed-in ifp, if and only - * if source list filter entry is iface or node local. - */ - in6_clearscope(&psin->sin6_addr); error = im6f_get_source(imf, psin, &lims); if (error) break; @@ -2687,7 +2636,7 @@ sysctl_ip6_mcast_filters(SYSCTL_HANDLER_ return (EINVAL); ifindex = name[0]; - if (ifindex <= 0 || ifindex > V_if_index) { + if (ifindex > V_if_index) { CTR2(KTR_MLD, "%s: ifindex %u out of range", __func__, ifindex); return (ENOENT); @@ -2706,11 +2655,6 @@ sysctl_ip6_mcast_filters(SYSCTL_HANDLER_ __func__, ifindex); return (ENOENT); } - /* - * Internal MLD lookups require that scope/zone ID is set. - */ - (void)in6_setscope(&mcaddr, ifp, NULL); - retval = sysctl_wire_old_buffer(req, sizeof(uint32_t) + (in6_mcast_maxgrpsrc * sizeof(struct in6_addr))); if (retval)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201310250035.r9P0ZQYE007797>