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.
  
  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);
 }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to