This diff get rids of all splsoftet() in nd6 code. I converted timers to the NET_LOCK() even if ip6_output() doesn't assert for it for the moment. That's simply the way to go. Also because these functions iterates on global data structures that will need the NET_LOCK() or a rewrite.
ok? Index: netinet6/nd6.c =================================================================== RCS file: /cvs/src/sys/netinet6/nd6.c,v retrieving revision 1.199 diff -u -p -r1.199 nd6.c --- netinet6/nd6.c 20 Dec 2016 18:33:43 -0000 1.199 +++ netinet6/nd6.c 21 Dec 2016 12:47:31 -0000 @@ -127,7 +127,7 @@ nd6_init(void) nd6_init_done = 1; /* start timer */ - timeout_set(&nd6_slowtimo_ch, nd6_slowtimo, NULL); + timeout_set_proc(&nd6_slowtimo_ch, nd6_slowtimo, NULL); timeout_add_sec(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL); nd6_rs_init(); @@ -430,15 +430,16 @@ nd6_llinfo_timer(void *arg) void nd6_timer_work(void *null) { - int s; struct nd_defrouter *dr, *ndr; struct nd_prefix *pr, *npr; struct in6_ifaddr *ia6, *nia6; + int s; - s = splsoftnet(); timeout_set(&nd6_timer_ch, nd6_timer, NULL); timeout_add_sec(&nd6_timer_ch, nd6_prune); + NET_LOCK(s); + /* expire default router list */ TAILQ_FOREACH_SAFE(dr, &nd_defrouter, dr_entry, ndr) if (dr->expire && dr->expire < time_uptime) @@ -482,7 +483,7 @@ nd6_timer_work(void *null) prelist_remove(pr); } } - splx(s); + NET_UNLOCK(s); } void @@ -1120,7 +1121,6 @@ nd6_ioctl(u_long cmd, caddr_t data, stru struct in6_nbrinfo *nbi = (struct in6_nbrinfo *)data; struct rtentry *rt; int error = 0; - int s; switch (cmd) { case SIOCGIFINFO_IN6: @@ -1142,7 +1142,6 @@ nd6_ioctl(u_long cmd, caddr_t data, stru /* flush all the prefix advertised by routers */ struct nd_prefix *pr, *npr; - s = splsoftnet(); /* First purge the addresses referenced by a prefix. */ LIST_FOREACH_SAFE(pr, &nd_prefix, ndpr_entry, npr) { struct in6_ifaddr *ia6, *ia6_next; @@ -1170,7 +1169,6 @@ nd6_ioctl(u_long cmd, caddr_t data, stru prelist_remove(pr); } - splx(s); break; } case SIOCSRTRFLUSH_IN6: @@ -1178,12 +1176,10 @@ nd6_ioctl(u_long cmd, caddr_t data, stru /* flush all the default routers */ struct nd_defrouter *dr, *ndr; - s = splsoftnet(); defrouter_reset(); TAILQ_FOREACH_SAFE(dr, &nd_defrouter, dr_entry, ndr) defrtrlist_del(dr); defrouter_select(); - splx(s); break; } case SIOCGNBRINFO_IN6: @@ -1204,13 +1200,11 @@ nd6_ioctl(u_long cmd, caddr_t data, stru *idp = htons(ifp->if_index); } - s = splsoftnet(); rt = nd6_lookup(&nb_addr, 0, ifp, ifp->if_rdomain); if (rt == NULL || (ln = (struct llinfo_nd6 *)rt->rt_llinfo) == NULL) { error = EINVAL; rtfree(rt); - splx(s); break; } expire = ln->ln_rt->rt_expire; @@ -1224,7 +1218,6 @@ nd6_ioctl(u_long cmd, caddr_t data, stru nbi->isrouter = ln->ln_router; nbi->expire = expire; rtfree(rt); - splx(s); break; } @@ -1478,12 +1471,14 @@ fail: void nd6_slowtimo(void *ignored_arg) { - int s = splsoftnet(); struct nd_ifinfo *nd6if; struct ifnet *ifp; + int s; timeout_set(&nd6_slowtimo_ch, nd6_slowtimo, NULL); timeout_add_sec(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL); + + NET_LOCK(s); TAILQ_FOREACH(ifp, &ifnet, if_list) { nd6if = ND_IFINFO(ifp); if (nd6if->basereachable && /* already initialized */ @@ -1498,7 +1493,7 @@ nd6_slowtimo(void *ignored_arg) nd6if->reachable = ND_COMPUTE_RTIME(nd6if->basereachable); } } - splx(s); + NET_UNLOCK(s); } int Index: netinet6/nd6_nbr.c =================================================================== RCS file: /cvs/src/sys/netinet6/nd6_nbr.c,v retrieving revision 1.112 diff -u -p -r1.112 nd6_nbr.c --- netinet6/nd6_nbr.c 21 Dec 2016 12:30:19 -0000 1.112 +++ netinet6/nd6_nbr.c 21 Dec 2016 12:47:31 -0000 @@ -825,7 +825,6 @@ nd6_na_input(struct mbuf *m, int off, in */ struct nd_defrouter *dr; struct in6_addr *in6; - int s; in6 = &satosin6(rt_key(rt))->sin6_addr; @@ -835,7 +834,6 @@ nd6_na_input(struct mbuf *m, int off, in * is only called under the network software interrupt * context. However, we keep it just for safety. */ - s = splsoftnet(); dr = defrouter_lookup(in6, rt->rt_ifidx); if (dr) defrtrlist_del(dr); @@ -849,7 +847,6 @@ nd6_na_input(struct mbuf *m, int off, in */ rt6_flush(&ip6->ip6_src, ifp); } - splx(s); } ln->ln_router = is_router; } @@ -1080,7 +1077,7 @@ void nd6_dad_starttimer(struct dadq *dp, int ticks) { - timeout_set(&dp->dad_timer_ch, nd6_dad_timer, dp->dad_ifa); + timeout_set_proc(&dp->dad_timer_ch, nd6_dad_timer, dp->dad_ifa); timeout_add(&dp->dad_timer_ch, ticks); } @@ -1190,7 +1187,7 @@ nd6_dad_timer(void *xifa) char addr[INET6_ADDRSTRLEN]; int s; - s = splsoftnet(); /* XXX */ + NET_LOCK(s); /* Sanity check */ if (ia6 == NULL) { @@ -1281,7 +1278,7 @@ nd6_dad_timer(void *xifa) } done: - splx(s); + NET_UNLOCK(s); } void Index: netinet6/nd6_rtr.c =================================================================== RCS file: /cvs/src/sys/netinet6/nd6_rtr.c,v retrieving revision 1.153 diff -u -p -r1.153 nd6_rtr.c --- netinet6/nd6_rtr.c 28 Nov 2016 14:14:39 -0000 1.153 +++ netinet6/nd6_rtr.c 21 Dec 2016 12:47:31 -0000 @@ -94,7 +94,7 @@ int nd6_rs_timeout_count = 0; void nd6_rs_init(void) { - timeout_set(&nd6_rs_output_timer, nd6_rs_output_timo, NULL); + timeout_set_proc(&nd6_rs_output_timer, nd6_rs_output_timo, NULL); } @@ -202,7 +202,7 @@ nd6_rs_output(struct ifnet* ifp, struct struct nd_router_solicit *rs; struct ip6_moptions im6o; caddr_t mac; - int icmp6len, maxlen, s; + int icmp6len, maxlen; KASSERT(ia6 != NULL); KASSERT(ifp->if_flags & IFF_RUNNING); @@ -272,9 +272,7 @@ nd6_rs_output(struct ifnet* ifp, struct ip6->ip6_plen = htons((u_short)icmp6len); - s = splsoftnet(); ip6_output(m, NULL, NULL, 0, &im6o, NULL); - splx(s); icmp6stat.icp6s_outhist[ND_ROUTER_SOLICIT]++; } @@ -291,6 +289,7 @@ nd6_rs_output_timo(void *ignored_arg) { struct ifnet *ifp; struct in6_ifaddr *ia6; + int s; if (nd6_rs_timeout_count == 0) return; @@ -301,6 +300,7 @@ nd6_rs_output_timo(void *ignored_arg) if (nd6_rs_output_timeout > ND6_RS_OUTPUT_INTERVAL) nd6_rs_output_timeout = ND6_RS_OUTPUT_INTERVAL; + NET_LOCK(s); TAILQ_FOREACH(ifp, &ifnet, if_list) { if (ISSET(ifp->if_flags, IFF_RUNNING) && ISSET(ifp->if_xflags, IFXF_AUTOCONF6)) { @@ -309,6 +309,7 @@ nd6_rs_output_timo(void *ignored_arg) nd6_rs_output(ifp, ia6); } } + NET_UNLOCK(s); nd6_rs_output_set_timo(nd6_rs_output_timeout); } @@ -1104,8 +1105,10 @@ void prelist_remove(struct nd_prefix *pr) { struct nd_pfxrouter *pfr, *next; - int e, s; struct in6_ifextra *ext = pr->ndpr_ifp->if_afdata[AF_INET6]; + int e; + + splsoftassert(IPL_SOFTNET); /* make sure to invalidate the prefix until it is really freed. */ pr->ndpr_vltime = 0; @@ -1114,8 +1117,8 @@ prelist_remove(struct nd_prefix *pr) if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0 && (e = nd6_prefix_offlink(pr)) != 0) { char addr[INET6_ADDRSTRLEN]; - nd6log((LOG_ERR, "prelist_remove: failed to make %s/%d offlink " - "on %s, errno=%d\n", + nd6log((LOG_ERR, "%s: failed to make %s/%d offlink " + "on %s, errno=%d\n", __func__, inet_ntop(AF_INET6, &pr->ndpr_prefix.sin6_addr, addr, sizeof(addr)), pr->ndpr_plen, pr->ndpr_ifp->if_xname, e)); @@ -1125,8 +1128,6 @@ prelist_remove(struct nd_prefix *pr) if (pr->ndpr_refcnt > 0) return; /* notice here? */ - s = splsoftnet(); - /* unlink ndpr_entry from nd_prefix list */ LIST_REMOVE(pr, ndpr_entry); @@ -1136,14 +1137,13 @@ prelist_remove(struct nd_prefix *pr) ext->nprefixes--; if (ext->nprefixes < 0) { - log(LOG_WARNING, "prelist_remove: negative count on %s\n", + log(LOG_WARNING, "%s: negative count on %s\n", __func__, pr->ndpr_ifp->if_xname); } free(pr, M_IP6NDP, sizeof(*pr)); pfxlist_onlink_check(); - splx(s); } /* @@ -1406,7 +1406,7 @@ nd6_addr_add(void *prptr) struct ifaddr *ifa; int ifa_plen, autoconf, privacy, s; - s = splsoftnet(); + NET_LOCK(s); autoconf = 1; privacy = (pr->ndpr_ifp->if_xflags & IFXF_INET6_NOPRIVACY) == 0; @@ -1472,7 +1472,7 @@ nd6_addr_add(void *prptr) if (--pr->ndpr_refcnt == 0) prelist_remove(pr); - splx(s); + NET_UNLOCK(s); } /* @@ -1592,9 +1592,8 @@ pfxlist_onlink_check(void) if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0 && (pr->ndpr_stateflags & NDPRF_ONLINK) != 0) { if ((e = nd6_prefix_offlink(pr)) != 0) { - nd6log((LOG_ERR, - "pfxlist_onlink_check: failed to " - "make %s/%d offlink, errno=%d\n", + nd6log((LOG_ERR, "%s: failed to make %s/%d" + " offlink, errno=%d\n", __func__, inet_ntop(AF_INET6, &pr->ndpr_prefix.sin6_addr, addr, sizeof(addr)), @@ -1605,9 +1604,8 @@ pfxlist_onlink_check(void) (pr->ndpr_stateflags & NDPRF_ONLINK) == 0 && pr->ndpr_raf_onlink) { if ((e = nd6_prefix_onlink(pr)) != 0) { - nd6log((LOG_ERR, - "pfxlist_onlink_check: failed to " - "make %s/%d offlink, errno=%d\n", + nd6log((LOG_ERR, "%s: failed to make %s/%d" + " offlink, errno=%d\n", __func__, inet_ntop(AF_INET6, &pr->ndpr_prefix.sin6_addr, addr, sizeof(addr)), @@ -2000,7 +1998,7 @@ in6_init_address_ltimes(struct nd_prefix void rt6_flush(struct in6_addr *gateway, struct ifnet *ifp) { - int s; + splsoftassert(IPL_SOFTNET); /* We'll care only link-local addresses */ if (!IN6_IS_ADDR_LINKLOCAL(gateway)) @@ -2009,9 +2007,7 @@ rt6_flush(struct in6_addr *gateway, stru /* XXX: hack for KAME's link-local address kludge */ gateway->s6_addr16[1] = htons(ifp->if_index); - s = splsoftnet(); rtable_walk(ifp->if_rdomain, AF_INET6, rt6_deleteroute, gateway); - splx(s); } int