Index: sys/net/route/route_ifaddrs.c =================================================================== --- sys/net/route/route_ifaddrs.c +++ sys/net/route/route_ifaddrs.c @@ -138,15 +138,15 @@ struct sockaddr *ia) { struct rib_cmd_info rc; - struct epoch_tracker et; int error; struct rt_addrinfo info; struct sockaddr_dl null_sdl; struct ifnet *ifp; + NET_EPOCH_ASSERT(); + ifp = ifa->ifa_ifp; - NET_EPOCH_ENTER(et); bzero(&info, sizeof(info)); if (cmd != RTM_DELETE) info.rti_ifp = V_loif; @@ -161,7 +161,6 @@ link_init_sdl(ifp, (struct sockaddr *)&null_sdl, ifp->if_type); error = rib_action(ifp->if_fib, cmd, &info, &rc); - NET_EPOCH_EXIT(et); if (error == 0 || (cmd == RTM_ADD && error == EEXIST) || Index: sys/netinet/in.c =================================================================== --- sys/netinet/in.c +++ sys/netinet/in.c @@ -604,8 +604,10 @@ eia = in_localip_more(ia); if (eia == NULL) { + NET_EPOCH_ENTER(et); error = ifa_add_loopback_route((struct ifaddr *)ia, (struct sockaddr *)&ia->ia_addr); + NET_EPOCH_EXIT(et); if (error) goto fail2; } else @@ -633,8 +635,11 @@ return (error); fail2: - if (vhid == 0) + if (vhid == 0) { + NET_EPOCH_ENTER(et); (void )in_scrubprefix(ia, LLE_STATIC); + NET_EPOCH_EXIT(et); + } fail1: if (ia->ia_ifa.ifa_carp) @@ -662,6 +667,7 @@ struct ifaddr *ifa; struct in_ifaddr *ia; bool deleteAny, iaIsLast; + struct epoch_tracker et; int error; if (td != NULL) { @@ -715,7 +721,9 @@ /* * in_scrubprefix() kills the interface route. */ + NET_EPOCH_ENTER(et); in_scrubprefix(ia, LLE_STATIC); + NET_EPOCH_EXIT(et); /* * in_ifadown gets rid of all the rest of @@ -1105,11 +1113,12 @@ int in_scrubprefix(struct in_ifaddr *target, u_int flags) { - struct epoch_tracker et; struct in_ifaddr *ia; struct in_addr prefix, mask, p, m; int error = 0; + NET_EPOCH_ASSERT(); + /* * Remove the loopback route to the interface address. */ @@ -1143,7 +1152,6 @@ return (0); } - NET_EPOCH_ENTER(et); CK_STAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { ia_getrtprefix(ia, &p, &m); @@ -1160,8 +1168,6 @@ * get a heads-up. */ if ((ia->ia_flags & IFA_ROUTE) == 0) { - ifa_ref(&ia->ia_ifa); - NET_EPOCH_EXIT(et); error = in_handle_ifaddr_route(RTM_DELETE, target); if (error == 0) target->ia_flags &= ~IFA_ROUTE; @@ -1177,11 +1183,9 @@ else log(LOG_INFO, "in_scrubprefix: err=%d, new prefix add failed\n", error); - ifa_free(&ia->ia_ifa); return (error); } } - NET_EPOCH_EXIT(et); /* * remove all L2 entries on the given prefix Index: sys/netinet/ip_carp.c =================================================================== --- sys/netinet/ip_carp.c +++ sys/netinet/ip_carp.c @@ -1070,6 +1070,9 @@ static void carp_ifa_addroute(struct ifaddr *ifa) { + struct epoch_tracker et; + + NET_EPOCH_ENTER(et); switch (ifa->ifa_addr->sa_family) { #ifdef INET @@ -1087,6 +1090,8 @@ break; #endif } + + NET_EPOCH_EXIT(et); } static void @@ -1101,6 +1106,9 @@ static void carp_ifa_delroute(struct ifaddr *ifa) { + struct epoch_tracker et; + + NET_EPOCH_ENTER(et); switch (ifa->ifa_addr->sa_family) { #ifdef INET @@ -1118,6 +1126,8 @@ break; #endif } + + NET_EPOCH_EXIT(et); } int Index: sys/netinet/raw_ip.c =================================================================== --- sys/netinet/raw_ip.c +++ sys/netinet/raw_ip.c @@ -789,7 +789,6 @@ CK_STAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { if (ia->ia_ifa.ifa_addr == sa && (ia->ia_flags & IFA_ROUTE)) { - ifa_ref(&ia->ia_ifa); /* * in_scrubprefix() kills the interface route. */ @@ -801,7 +800,6 @@ * routing process they will come back. */ in_ifadown(&ia->ia_ifa, 0); - ifa_free(&ia->ia_ifa); break; } } @@ -814,7 +812,6 @@ } if (ia == NULL || (ia->ia_flags & IFA_ROUTE)) return; - ifa_ref(&ia->ia_ifa); err = ifa_del_loopback_route((struct ifaddr *)ia, sa); @@ -825,7 +822,6 @@ err = ifa_add_loopback_route((struct ifaddr *)ia, sa); - ifa_free(&ia->ia_ifa); break; #if defined(IPSEC) || defined(IPSEC_SUPPORT) case PRC_MSGSIZE: Index: sys/netinet6/in6.c =================================================================== --- sys/netinet6/in6.c +++ sys/netinet6/in6.c @@ -1275,7 +1275,6 @@ static int in6_handle_dstaddr_rtrequest(int cmd, struct in6_ifaddr *ia) { - struct epoch_tracker et; struct ifaddr *ifa = &ia->ia_ifa; int error; @@ -1304,9 +1303,7 @@ }; /* Don't set additional per-gw filters on removal */ - NET_EPOCH_ENTER(et); error = rib_handle_ifaddr_info(ifa->ifa_ifp->if_fib, cmd, &info); - NET_EPOCH_EXIT(et); return (error); } @@ -1331,6 +1328,7 @@ struct ifnet *ifp = ifa->ifa_ifp; struct in6_ifaddr *ia = (struct in6_ifaddr *) ifa; struct in6_multi_mship *imm; + struct epoch_tracker et; int error; if (ifa->ifa_carp) @@ -1342,10 +1340,12 @@ * is not needed. */ if (ia->ia_flags & IFA_RTSELF) { + NET_EPOCH_ENTER(et); error = ifa_del_loopback_route((struct ifaddr *)ia, (struct sockaddr *)&ia->ia_addr); if (error == 0) ia->ia_flags &= ~IFA_RTSELF; + NET_EPOCH_EXIT(et); } /* stop DAD processing */ @@ -1360,11 +1360,13 @@ } /* Check if we need to remove p2p route */ if ((ia->ia_flags & IFA_ROUTE) && ifa_is_p2p(ia)) { + NET_EPOCH_ENTER(et); error = in6_handle_dstaddr_rtrequest(RTM_DELETE, ia); if (error != 0) log(LOG_INFO, "%s: err=%d, destination address delete " "failed\n", __func__, error); ia->ia_flags &= ~IFA_ROUTE; + NET_EPOCH_EXIT(et); } in6_newaddrmsg(ia, RTM_DELETE); @@ -1466,14 +1468,13 @@ struct ifaddr *ifa; struct sockaddr_in6 *pdst; char ip6buf[INET6_ADDRSTRLEN]; + struct epoch_tracker et; /* * Give the interface a chance to initialize * if this is its first address, */ if (hostIsNew != 0) { - struct epoch_tracker et; - NET_EPOCH_ENTER(et); CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { if (ifa->ifa_addr->sa_family != AF_INET6) @@ -1494,6 +1495,7 @@ * install the new destination. Note that the interface must be * p2p or loopback. */ + NET_EPOCH_ENTER(et); pdst = &ifra->ifra_dstaddr; if (pdst->sin6_family == AF_INET6 && !IN6_ARE_ADDR_EQUAL(&pdst->sin6_addr, &ia->ia_dstaddr.sin6_addr)) { @@ -1517,8 +1519,10 @@ */ if (!(ia->ia_flags & IFA_ROUTE) && ifa_is_p2p(ia)) { error = in6_handle_dstaddr_rtrequest(RTM_ADD, ia); - if (error) + if (error != 0) { + NET_EPOCH_EXIT(et); goto done; + } ia->ia_flags |= IFA_ROUTE; } @@ -1531,6 +1535,7 @@ if (error == 0) ia->ia_flags |= IFA_RTSELF; } + NET_EPOCH_EXIT(et); done: WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "Invoking IPv6 network device address event may sleep");