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