On 27 Oct 2014, at 16:15 , Andrey V. Elsukov <a...@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

_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to