svn commit: r273742 - head/sys/netinet6

Bjoern A. Zeeb bz at FreeBSD.org
Mon Oct 27 16:43:54 UTC 2014


On 27 Oct 2014, at 16:15 , Andrey V. Elsukov <ae at FreeBSD.org> wrote:

> Author: ae
> Date: Mon Oct 27 16:15:15 2014
> New Revision: 273742
> URL: https://svnweb.freebsd.org/changeset/base/273742
> 
> Log:
>  Do not automatically install routes to link-local and interface-local multicast
>  addresses.

Why?


> 
>  Obtained from:	Yandex LLC
>  Sponsored by:	Yandex LLC
> 
> Modified:
>  head/sys/netinet6/in6.c
> 
> Modified: head/sys/netinet6/in6.c
> ==============================================================================
> --- head/sys/netinet6/in6.c	Mon Oct 27 16:13:51 2014	(r273741)
> +++ head/sys/netinet6/in6.c	Mon Oct 27 16:15:15 2014	(r273742)
> @@ -782,27 +782,24 @@ 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 mltaddr;
> 	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) {
> +	bzero(&mltaddr, sizeof(struct in6_addr));
> +	mltaddr.s6_addr32[0] = IPV6_ADDR_INT32_MLL;
> +	mltaddr.s6_addr32[2] = htonl(1);
> +	mltaddr.s6_addr32[3] = ifra->ifra_addr.sin6_addr.s6_addr32[3];
> +	mltaddr.s6_addr8[12] = 0xff;
> +	if ((error = in6_setscope(&mltaddr, ifp, NULL)) != 0) {
> 		/* XXX: should not happen */
> 		log(LOG_ERR, "%s: in6_setscope failed\n", __func__);
> 		goto cleanup;
> 	}
> -	delay = 0;
> +	delay = error = 0;
> 	if ((flags & IN6_IFAUPDATE_DADDELAY)) {
> 		/*
> 		 * We need a random delay for DAD on the address being
> @@ -812,62 +809,28 @@ 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, &mltaddr, &error, delay);
> 	if (imm == NULL) {
> -		nd6log((LOG_WARNING, "%s: addmulti failed for %s on %s "
> -		    "(errno=%d)\n", __func__, ip6_sprintf(ip6buf, &llsol),
> +		nd6log((LOG_WARNING, "%s: in6_joingroup failed for %s on %s "
> +		    "(errno=%d)\n", __func__, ip6_sprintf(ip6buf, &mltaddr),
> 		    if_name(ifp), error));
> 		goto cleanup;
> 	}
> 	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)
> +	mltaddr = in6addr_linklocal_allnodes;
> +	if ((error = in6_setscope(&mltaddr, 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, &mltaddr, &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));
> +		nd6log((LOG_WARNING, "%s: in6_joingroup failed for %s on %s "
> +		    "(errno=%d)\n", __func__, ip6_sprintf(ip6buf, &mltaddr),
> +		    if_name(ifp), error));
> 		goto cleanup;
> 	}
> 	LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
> @@ -883,24 +846,26 @@ 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, &mltaddr) == 0) {
> 		/* XXX jinmei */
> -		imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error, delay);
> +		imm = in6_joingroup(ifp, &mltaddr, &error, delay);
> 		if (imm == NULL)
> -			nd6log((LOG_WARNING, "%s: addmulti failed for %s on %s "
> +			nd6log((LOG_WARNING,
> +			    "%s: in6_joingroup failed for %s on %s "
> 			    "(errno=%d)\n", __func__, ip6_sprintf(ip6buf,
> -			    &mltaddr.sin6_addr), if_name(ifp), error));
> +			    &mltaddr), 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);
> +	if (V_icmp6_nodeinfo_oldmcprefix &&
> +	    in6_nigroup_oldmcprefix(ifp, NULL, -1, &mltaddr) == 0) {
> +		imm = in6_joingroup(ifp, &mltaddr, &error, delay);
> 		if (imm == NULL)
> -			nd6log((LOG_WARNING, "%s: addmulti failed for %s on %s "
> +			nd6log((LOG_WARNING,
> +			    "%s: in6_joingroup failed for %s on %s "
> 			    "(errno=%d)\n", __func__, ip6_sprintf(ip6buf,
> -			    &mltaddr.sin6_addr), if_name(ifp), error));
> +			    &mltaddr), if_name(ifp), error));
> 			/* XXX not very fatal, go on... */
> 		else
> 			LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
> @@ -910,38 +875,18 @@ 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)
> +	mltaddr = in6addr_nodelocal_allnodes;
> +	if ((error = in6_setscope(&mltaddr, 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, &mltaddr, &error, 0);
> 	if (imm == NULL) {
> -		nd6log((LOG_WARNING, "%s: addmulti failed for %s on %s "
> +		nd6log((LOG_WARNING, "%s: in6_joingroup failed for %s on %s "
> 		    "(errno=%d)\n", __func__, ip6_sprintf(ip6buf,
> -		    &mltaddr.sin6_addr), if_name(ifp), error));
> +		    &mltaddr), if_name(ifp), error));
> 		goto cleanup;
> 	}
> 	LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
> -#undef	MLTMASK_LEN
> 
> cleanup:
> 	return (error);
> @@ -1343,135 +1288,17 @@ in6_broadcast_ifa(struct ifnet *ifp, str
> }
> 
> /*
> - * 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);
> }
> 
> 

— 
Bjoern A. Zeeb             "Come on. Learn, goddamn it.", WarGames, 1983



More information about the svn-src-all mailing list