svn commit: r256740 - user/ae/inet6/sys/netinet6

Andrey V. Elsukov ae at FreeBSD.org
Fri Oct 18 13:27:35 UTC 2013


Author: ae
Date: Fri Oct 18 13:27:34 2013
New Revision: 256740
URL: http://svnweb.freebsd.org/changeset/base/256740

Log:
  Constify mcaddr argument in in6_joingroup() and rework
  in6_update_ifa_join_mc() function:
  
  * don't install routes for multicast addresses;
  * remove in6_setscope() calls;

Modified:
  user/ae/inet6/sys/netinet6/in6.c
  user/ae/inet6/sys/netinet6/in6_mcast.c
  user/ae/inet6/sys/netinet6/in6_var.h

Modified: user/ae/inet6/sys/netinet6/in6.c
==============================================================================
--- user/ae/inet6/sys/netinet6/in6.c	Fri Oct 18 13:05:18 2013	(r256739)
+++ user/ae/inet6/sys/netinet6/in6.c	Fri Oct 18 13:27:34 2013	(r256740)
@@ -852,27 +852,19 @@ in6_update_ifa_join_mc(struct ifnet *ifp
     struct in6_ifaddr *ia, int flags, struct in6_multi **in6m_sol)
 {
 	char ip6buf[INET6_ADDRSTRLEN];
-	struct sockaddr_in6 mltaddr, mltmask;
-	struct in6_addr llsol;
+	struct in6_addr mladdr;
 	struct in6_multi_mship *imm;
-	struct rtentry *rt;
 	int delay, error;
 
 	KASSERT(in6m_sol != NULL, ("%s: in6m_sol is NULL", __func__));
 
 	/* Join solicited multicast addr for new host id. */
-	bzero(&llsol, sizeof(struct in6_addr));
-	llsol.s6_addr32[0] = IPV6_ADDR_INT32_MLL;
-	llsol.s6_addr32[1] = 0;
-	llsol.s6_addr32[2] = htonl(1);
-	llsol.s6_addr32[3] = ifra->ifra_addr.sin6_addr.s6_addr32[3];
-	llsol.s6_addr8[12] = 0xff;
-	if ((error = in6_setscope(&llsol, ifp, NULL)) != 0) {
-		/* XXX: should not happen */
-		log(LOG_ERR, "%s: in6_setscope failed\n", __func__);
-		goto cleanup;
-	}
-	delay = 0;
+	bzero(&mladdr, sizeof(struct in6_addr));
+	mladdr.s6_addr32[0] = IPV6_ADDR_INT32_MLL;
+	mladdr.s6_addr32[2] = htonl(1);
+	mladdr.s6_addr32[3] = ifra->ifra_addr.sin6_addr.s6_addr32[3];
+	mladdr.s6_addr8[12] = 0xff;
+	delay = error = 0;
 	if ((flags & IN6_IFAUPDATE_DADDELAY)) {
 		/*
 		 * We need a random delay for DAD on the address being
@@ -882,64 +874,27 @@ in6_update_ifa_join_mc(struct ifnet *ifp
 		 */
 		delay = arc4random() % (MAX_RTR_SOLICITATION_DELAY * hz);
 	}
-	imm = in6_joingroup(ifp, &llsol, &error, delay);
+	imm = in6_joingroup(ifp, &mladdr, &error, delay);
 	if (imm == NULL) {
 		nd6log((LOG_WARNING, "%s: addmulti failed for %s on %s "
-		    "(errno=%d)\n", __func__, ip6_sprintf(ip6buf, &llsol),
+		    "(errno=%d)\n", __func__, ip6_sprintf(ip6buf, &mladdr),
 		    if_name(ifp), error));
 		goto cleanup;
 	}
+	/* XXX: locking */
 	LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
 	*in6m_sol = imm->i6mm_maddr;
-
-	bzero(&mltmask, sizeof(mltmask));
-	mltmask.sin6_len = sizeof(struct sockaddr_in6);
-	mltmask.sin6_family = AF_INET6;
-	mltmask.sin6_addr = in6mask32;
-#define	MLTMASK_LEN  4	/* mltmask's masklen (=32bit=4octet) */
-
 	/*
 	 * Join link-local all-nodes address.
 	 */
-	bzero(&mltaddr, sizeof(mltaddr));
-	mltaddr.sin6_len = sizeof(struct sockaddr_in6);
-	mltaddr.sin6_family = AF_INET6;
-	mltaddr.sin6_addr = in6addr_linklocal_allnodes;
-	if ((error = in6_setscope(&mltaddr.sin6_addr, ifp, NULL)) != 0)
-		goto cleanup; /* XXX: should not fail */
-
-	/*
-	 * XXX: do we really need this automatic routes?  We should probably
-	 * reconsider this stuff.  Most applications actually do not need the
-	 * routes, since they usually specify the outgoing interface.
-	 */
-	rt = in6_rtalloc1((struct sockaddr *)&mltaddr, 0, 0UL, RT_DEFAULT_FIB);
-	if (rt != NULL) {
-		/* XXX: only works in !SCOPEDROUTING case. */
-		if (memcmp(&mltaddr.sin6_addr,
-		    &((struct sockaddr_in6 *)rt_key(rt))->sin6_addr,
-		    MLTMASK_LEN)) {
-			RTFREE_LOCKED(rt);
-			rt = NULL;
-		}
-	}
-	if (rt == NULL) {
-		error = in6_rtrequest(RTM_ADD, (struct sockaddr *)&mltaddr,
-		    (struct sockaddr *)&ia->ia_addr,
-		    (struct sockaddr *)&mltmask, RTF_UP,
-		    (struct rtentry **)0, RT_DEFAULT_FIB);
-		if (error)
-			goto cleanup;
-	} else
-		RTFREE_LOCKED(rt);
-
-	imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error, 0);
+	imm = in6_joingroup(ifp, &in6addr_linklocal_allnodes, &error, 0);
 	if (imm == NULL) {
 		nd6log((LOG_WARNING, "%s: addmulti failed for %s on %s "
 		    "(errno=%d)\n", __func__, ip6_sprintf(ip6buf,
-		    &mltaddr.sin6_addr), if_name(ifp), error));
+		    &in6addr_linklocal_allnodes), if_name(ifp), error));
 		goto cleanup;
 	}
+	/* XXX: locking */
 	LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
 
 	/*
@@ -953,24 +908,24 @@ in6_update_ifa_join_mc(struct ifnet *ifp
 		 */
 		delay = arc4random() % (MAX_RTR_SOLICITATION_DELAY * hz);
 	}
-	if (in6_nigroup(ifp, NULL, -1, &mltaddr.sin6_addr) == 0) {
+	if (in6_nigroup(ifp, NULL, -1, &mladdr) == 0) {
 		/* XXX jinmei */
-		imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error, delay);
+		imm = in6_joingroup(ifp, &mladdr, &error, delay);
 		if (imm == NULL)
 			nd6log((LOG_WARNING, "%s: addmulti failed for %s on %s "
 			    "(errno=%d)\n", __func__, ip6_sprintf(ip6buf,
-			    &mltaddr.sin6_addr), if_name(ifp), error));
+			    &mladdr), if_name(ifp), error));
 			/* XXX not very fatal, go on... */
 		else
 			LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
 	}
 	if (V_icmp6_nodeinfo_oldmcprefix && 
-	     in6_nigroup_oldmcprefix(ifp, NULL, -1, &mltaddr.sin6_addr) == 0) {
-		imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error, delay);
+	     in6_nigroup_oldmcprefix(ifp, NULL, -1, &mladdr) == 0) {
+		imm = in6_joingroup(ifp, &mladdr, &error, delay);
 		if (imm == NULL)
 			nd6log((LOG_WARNING, "%s: addmulti failed for %s on %s "
 			    "(errno=%d)\n", __func__, ip6_sprintf(ip6buf,
-			    &mltaddr.sin6_addr), if_name(ifp), error));
+			    &mladdr), if_name(ifp), error));
 			/* XXX not very fatal, go on... */
 		else
 			LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
@@ -980,38 +935,15 @@ in6_update_ifa_join_mc(struct ifnet *ifp
 	 * Join interface-local all-nodes address.
 	 * (ff01::1%ifN, and ff01::%ifN/32)
 	 */
-	mltaddr.sin6_addr = in6addr_nodelocal_allnodes;
-	if ((error = in6_setscope(&mltaddr.sin6_addr, ifp, NULL)) != 0)
-		goto cleanup; /* XXX: should not fail */
-	/* XXX: again, do we really need the route? */
-	rt = in6_rtalloc1((struct sockaddr *)&mltaddr, 0, 0UL, RT_DEFAULT_FIB);
-	if (rt != NULL) {
-		if (memcmp(&mltaddr.sin6_addr,
-		    &((struct sockaddr_in6 *)rt_key(rt))->sin6_addr,
-		    MLTMASK_LEN)) {
-			RTFREE_LOCKED(rt);
-			rt = NULL;
-		}
-	}
-	if (rt == NULL) {
-		error = in6_rtrequest(RTM_ADD, (struct sockaddr *)&mltaddr,
-		    (struct sockaddr *)&ia->ia_addr,
-		    (struct sockaddr *)&mltmask, RTF_UP,
-		    (struct rtentry **)0, RT_DEFAULT_FIB);
-		if (error)
-			goto cleanup;
-	} else
-		RTFREE_LOCKED(rt);
-
-	imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error, 0);
+	imm = in6_joingroup(ifp, &in6addr_nodelocal_allnodes, &error, 0);
 	if (imm == NULL) {
 		nd6log((LOG_WARNING, "%s: addmulti failed for %s on %s "
 		    "(errno=%d)\n", __func__, ip6_sprintf(ip6buf,
-		    &mltaddr.sin6_addr), if_name(ifp), error));
+		    &in6addr_nodelocal_allnodes), if_name(ifp), error));
 		goto cleanup;
 	}
+	/* XXX: locking */
 	LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
-#undef	MLTMASK_LEN
 
 cleanup:
 	return (error);
@@ -1349,135 +1281,17 @@ in6_update_ifa(struct ifnet *ifp, struct
 }
 
 /*
- * Leave multicast groups.  Factored out from in6_purgeaddr().
- * This entire work should only be done once, for the default FIB.
+ * Leave from multicast groups we have joined for the interface.
  */
 static int
 in6_purgeaddr_mc(struct ifnet *ifp, struct in6_ifaddr *ia, struct ifaddr *ifa0)
 {
-	struct sockaddr_in6 mltaddr, mltmask;
 	struct in6_multi_mship *imm;
-	struct rtentry *rt;
-	struct sockaddr_in6 sin6;
-	int error;
 
-	/*
-	 * Leave from multicast groups we have joined for the interface.
-	 */
 	while ((imm = LIST_FIRST(&ia->ia6_memberships)) != NULL) {
 		LIST_REMOVE(imm, i6mm_chain);
 		in6_leavegroup(imm);
 	}
-
-	/*
-	 * Remove the link-local all-nodes address.
-	 */
-	bzero(&mltmask, sizeof(mltmask));
-	mltmask.sin6_len = sizeof(struct sockaddr_in6);
-	mltmask.sin6_family = AF_INET6;
-	mltmask.sin6_addr = in6mask32;
-
-	bzero(&mltaddr, sizeof(mltaddr));
-	mltaddr.sin6_len = sizeof(struct sockaddr_in6);
-	mltaddr.sin6_family = AF_INET6;
-	mltaddr.sin6_addr = in6addr_linklocal_allnodes;
-
-	if ((error = in6_setscope(&mltaddr.sin6_addr, ifp, NULL)) != 0)
-		return (error);
-
-	/*
-	 * As for the mltaddr above, proactively prepare the sin6 to avoid
-	 * rtentry un- and re-locking.
-	 */
-	if (ifa0 != NULL) {
-		bzero(&sin6, sizeof(sin6));
-		sin6.sin6_len = sizeof(sin6);
-		sin6.sin6_family = AF_INET6;
-		memcpy(&sin6.sin6_addr, &satosin6(ifa0->ifa_addr)->sin6_addr,
-		    sizeof(sin6.sin6_addr));
-		error = in6_setscope(&sin6.sin6_addr, ifa0->ifa_ifp, NULL);
-		if (error != 0)
-			return (error);
-	}
-
-	rt = in6_rtalloc1((struct sockaddr *)&mltaddr, 0, 0UL, RT_DEFAULT_FIB);
-	if (rt != NULL && rt->rt_gateway != NULL &&
-	    (memcmp(&satosin6(rt->rt_gateway)->sin6_addr,
-		    &ia->ia_addr.sin6_addr,
-		    sizeof(ia->ia_addr.sin6_addr)) == 0)) {
-		/*
-		 * If no more IPv6 address exists on this interface then
-		 * remove the multicast address route.
-		 */
-		if (ifa0 == NULL) {
-			memcpy(&mltaddr.sin6_addr,
-			    &satosin6(rt_key(rt))->sin6_addr,
-			    sizeof(mltaddr.sin6_addr));
-			RTFREE_LOCKED(rt);
-			error = in6_rtrequest(RTM_DELETE,
-			    (struct sockaddr *)&mltaddr,
-			    (struct sockaddr *)&ia->ia_addr,
-			    (struct sockaddr *)&mltmask, RTF_UP,
-			    (struct rtentry **)0, RT_DEFAULT_FIB);
-			if (error)
-				log(LOG_INFO, "%s: link-local all-nodes "
-				    "multicast address deletion error\n",
-				    __func__);
-		} else {
-			/*
-			 * Replace the gateway of the route.
-			 */
-			memcpy(rt->rt_gateway, &sin6, sizeof(sin6));
-			RTFREE_LOCKED(rt);
-		}
-	} else {
-		if (rt != NULL)
-			RTFREE_LOCKED(rt);
-	}
-
-	/*
-	 * Remove the node-local all-nodes address.
-	 */
-	mltaddr.sin6_addr = in6addr_nodelocal_allnodes;
-	if ((error = in6_setscope(&mltaddr.sin6_addr, ifp, NULL)) != 0)
-		return (error);
-
-	rt = in6_rtalloc1((struct sockaddr *)&mltaddr, 0, 0UL, RT_DEFAULT_FIB);
-	if (rt != NULL && rt->rt_gateway != NULL &&
-	    (memcmp(&satosin6(rt->rt_gateway)->sin6_addr,
-		    &ia->ia_addr.sin6_addr,
-		    sizeof(ia->ia_addr.sin6_addr)) == 0)) {
-		/*
-		 * If no more IPv6 address exists on this interface then
-		 * remove the multicast address route.
-		 */
-		if (ifa0 == NULL) {
-			memcpy(&mltaddr.sin6_addr,
-			    &satosin6(rt_key(rt))->sin6_addr,
-			    sizeof(mltaddr.sin6_addr));
-
-			RTFREE_LOCKED(rt);
-			error = in6_rtrequest(RTM_DELETE,
-			    (struct sockaddr *)&mltaddr,
-			    (struct sockaddr *)&ia->ia_addr,
-			    (struct sockaddr *)&mltmask, RTF_UP,
-			    (struct rtentry **)0, RT_DEFAULT_FIB);
-			if (error)
-				log(LOG_INFO, "%s: node-local all-nodes"
-				    "multicast address deletion error\n",
-				    __func__);
-		} else {
-			/*
-			 * Replace the gateway of the route.
-			 */
-			memcpy(rt->rt_gateway, &sin6, sizeof(sin6));
-			RTFREE_LOCKED(rt);
-		}
-	} else {
-		if (rt != NULL)
-			RTFREE_LOCKED(rt);
-	}
-
 	return (0);
 }
 

Modified: user/ae/inet6/sys/netinet6/in6_mcast.c
==============================================================================
--- user/ae/inet6/sys/netinet6/in6_mcast.c	Fri Oct 18 13:05:18 2013	(r256739)
+++ user/ae/inet6/sys/netinet6/in6_mcast.c	Fri Oct 18 13:27:34 2013	(r256740)
@@ -1080,7 +1080,7 @@ in6m_purge(struct in6_multi *inm)
  * SMPng: Assume no mc locks held by caller.
  */
 struct in6_multi_mship *
-in6_joingroup(struct ifnet *ifp, struct in6_addr *mcaddr,
+in6_joingroup(struct ifnet *ifp, const struct in6_addr *mcaddr,
     int *errorp, int delay)
 {
 	struct in6_multi_mship *imm;

Modified: user/ae/inet6/sys/netinet6/in6_var.h
==============================================================================
--- user/ae/inet6/sys/netinet6/in6_var.h	Fri Oct 18 13:05:18 2013	(r256739)
+++ user/ae/inet6/sys/netinet6/in6_var.h	Fri Oct 18 13:27:34 2013	(r256740)
@@ -793,7 +793,7 @@ int	ip6_setmoptions(struct inpcb *, stru
 
 /* Legacy KAME multicast KPIs. */
 struct in6_multi_mship *
-	in6_joingroup(struct ifnet *, struct in6_addr *, int *, int);
+	in6_joingroup(struct ifnet *, const struct in6_addr *, int *, int);
 int	in6_leavegroup(struct in6_multi_mship *);
 
 /* flags to in6_update_ifa */


More information about the svn-src-user mailing list