Skip site navigation (1)Skip section navigation (2)
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>