Author: glebius
Date: Sun Oct 13 04:25:16 2019
New Revision: 353461
URL: https://svnweb.freebsd.org/changeset/base/353461

Log:
  Don't cover in6_ifattach() with network epoch, as it may call into
  network drivers ioctls, that may sleep.
  
  PR:           241223

Modified:
  head/sys/netinet6/in6.c
  head/sys/netinet6/in6_ifattach.c
  head/sys/netinet6/nd6.c

Modified: head/sys/netinet6/in6.c
==============================================================================
--- head/sys/netinet6/in6.c     Sun Oct 13 00:08:17 2019        (r353460)
+++ head/sys/netinet6/in6.c     Sun Oct 13 04:25:16 2019        (r353461)
@@ -1930,12 +1930,12 @@ in6_if_up(struct ifnet *ifp)
                            arc4random() % (MAX_RTR_SOLICITATION_DELAY * hz));
                }
        }
+       NET_EPOCH_EXIT(et);
 
        /*
         * special cases, like 6to4, are handled in in6_ifattach
         */
        in6_ifattach(ifp, NULL);
-       NET_EPOCH_EXIT(et);
 }
 
 int

Modified: head/sys/netinet6/in6_ifattach.c
==============================================================================
--- head/sys/netinet6/in6_ifattach.c    Sun Oct 13 00:08:17 2019        
(r353460)
+++ head/sys/netinet6/in6_ifattach.c    Sun Oct 13 04:25:16 2019        
(r353461)
@@ -423,6 +423,7 @@ in6_ifattach_linklocal(struct ifnet *ifp, struct ifnet
        struct in6_ifaddr *ia;
        struct in6_aliasreq ifra;
        struct nd_prefixctl pr0;
+       struct epoch_tracker et;
        struct nd_prefix *pr;
        int error;
 
@@ -437,7 +438,10 @@ in6_ifattach_linklocal(struct ifnet *ifp, struct ifnet
                ifra.ifra_addr.sin6_addr.s6_addr32[2] = 0;
                ifra.ifra_addr.sin6_addr.s6_addr32[3] = htonl(1);
        } else {
-               if (get_ifid(ifp, altifp, &ifra.ifra_addr.sin6_addr) != 0) {
+               NET_EPOCH_ENTER(et);
+               error = get_ifid(ifp, altifp, &ifra.ifra_addr.sin6_addr);
+               NET_EPOCH_EXIT(et);
+               if (error != 0) {
                        nd6log((LOG_ERR,
                            "%s: no ifid available\n", if_name(ifp)));
                        return (-1);
@@ -472,7 +476,9 @@ in6_ifattach_linklocal(struct ifnet *ifp, struct ifnet
                return (-1);
        }
 
+       NET_EPOCH_ENTER(et);
        ia = in6ifa_ifpforlinklocal(ifp, 0);
+       NET_EPOCH_EXIT(et);
        if (ia == NULL) {
                /*
                 * Another thread removed the address that we just added.
@@ -667,8 +673,6 @@ in6_ifattach(struct ifnet *ifp, struct ifnet *altifp)
 {
        struct in6_ifaddr *ia;
 
-       NET_EPOCH_ASSERT();
-
        if (ifp->if_afdata[AF_INET6] == NULL)
                return;
        /*
@@ -718,7 +722,11 @@ in6_ifattach(struct ifnet *ifp, struct ifnet *altifp)
         */
        if (!(ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) &&
            ND_IFINFO(ifp)->flags & ND6_IFF_AUTO_LINKLOCAL) {
+               struct epoch_tracker et;
+
+               NET_EPOCH_ENTER(et);
                ia = in6ifa_ifpforlinklocal(ifp, 0);
+               NET_EPOCH_EXIT(et);
                if (ia == NULL)
                        in6_ifattach_linklocal(ifp, altifp);
                else

Modified: head/sys/netinet6/nd6.c
==============================================================================
--- head/sys/netinet6/nd6.c     Sun Oct 13 00:08:17 2019        (r353460)
+++ head/sys/netinet6/nd6.c     Sun Oct 13 04:25:16 2019        (r353461)
@@ -1691,7 +1691,6 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
                struct ifaddr *ifa;
                struct in6_ifaddr *ia;
 
-               NET_EPOCH_ENTER(et);
                if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) &&
                    !(ND.flags & ND6_IFF_IFDISABLED)) {
                        /* ifdisabled 1->0 transision */
@@ -1702,6 +1701,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
                         * do not clear ND6_IFF_IFDISABLED.
                         * See RFC 4862, Section 5.4.5.
                         */
+                       NET_EPOCH_ENTER(et);
                        CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
                                if (ifa->ifa_addr->sa_family != AF_INET6)
                                        continue;
@@ -1710,6 +1710,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
                                    IN6_IS_ADDR_LINKLOCAL(IA6_IN6(ia)))
                                        break;
                        }
+                       NET_EPOCH_EXIT(et);
 
                        if (ifa != NULL) {
                                /* LLA is duplicated. */
@@ -1730,6 +1731,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
                        ND_IFINFO(ifp)->flags |= ND6_IFF_IFDISABLED;
                        if (V_ip6_dad_count > 0 &&
                            (ND_IFINFO(ifp)->flags & ND6_IFF_NO_DAD) == 0) {
+                               NET_EPOCH_ENTER(et);
                                CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead,
                                    ifa_link) {
                                        if (ifa->ifa_addr->sa_family !=
@@ -1738,6 +1740,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
                                        ia = (struct in6_ifaddr *)ifa;
                                        ia->ia6_flags |= IN6_IFF_TENTATIVE;
                                }
+                               NET_EPOCH_EXIT(et);
                        }
                }
 
@@ -1756,6 +1759,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
                                 * address is assigned, and IFF_UP, try to
                                 * assign one.
                                 */
+                               NET_EPOCH_ENTER(et);
                                CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead,
                                    ifa_link) {
                                        if (ifa->ifa_addr->sa_family !=
@@ -1765,13 +1769,13 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
                                        if (IN6_IS_ADDR_LINKLOCAL(IA6_IN6(ia)))
                                                break;
                                }
+                               NET_EPOCH_EXIT(et);
                                if (ifa != NULL)
                                        /* No LLA is configured. */
                                        in6_ifattach(ifp, NULL);
                        }
                }
                ND_IFINFO(ifp)->flags = ND.flags;
-               NET_EPOCH_EXIT(et);
                break;
        }
 #undef ND
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to