On 11/09/14(Thu) 10:49, Martin Pieuchot wrote: > On 03/09/14(Wed) 20:59, Alexander Bluhm wrote: > > On Wed, Sep 03, 2014 at 03:53:34PM +0200, Martin Pieuchot wrote: > > > @@ -1078,7 +1079,7 @@ in6_purgeaddr(struct ifaddr *ifa) > > > void > > > in6_unlink_ifa(struct in6_ifaddr *ia6, struct ifnet *ifp) > > > { > > > - int s = splnet(); > > > + splsoftassert(IPL_SOFTNET); > > > > > > ifa_del(ifp, &ia6->ia_ifa); > > > > > > > I think there are code paths that can trigger this assertion > > > > netinet6/in6.c: in6_unlink_ifa() > > netinet6/in6.c: in6_purgeaddr() > > netinet6/nd6_rtr.c: purge_detached() > > netinet6/nd6_rtr.c: nd6_prelist_add() > > netinet6/in6.c: in6_control() > > netinet/tcp_usrreq.c: tcp_usrreq() > > kern/sys_socket.c: soo_ioctl() > > > > netinet6/in6.c: in6_unlink_ifa() > > netinet6/in6.c: in6_purgeaddr() > > netinet6/nd6_rtr.c: purge_detached() > > netinet6/nd6_rtr.c: nd6_prelist_add() > > netinet6/in6_ifattach.c: in6_ifattach_linklocal() > > netinet/ip_carp.c carp_set_enaddr() > > netinet/ip_carp.c carp_ioctl() > > ... > > > > nd6_prelist_add() does some splsoftnet() already. I think you > > should put one around purge_detached() there. > > Nice catch, updated diff below.
Any comment or ok? > Index: net/if_loop.c > =================================================================== > RCS file: /home/ncvs/src/sys/net/if_loop.c,v > retrieving revision 1.57 > diff -u -p -r1.57 if_loop.c > --- net/if_loop.c 22 Jul 2014 11:06:09 -0000 1.57 > +++ net/if_loop.c 11 Sep 2014 08:45:29 -0000 > @@ -288,15 +288,13 @@ loioctl(struct ifnet *ifp, u_long cmd, c > { > struct ifaddr *ifa; > struct ifreq *ifr; > - int s, error = 0; > + int error = 0; > > switch (cmd) { > > case SIOCSIFADDR: > - s = splnet(); > ifp->if_flags |= IFF_RUNNING; > if_up(ifp); /* send up RTM_IFINFO */ > - splx(s); > > ifa = (struct ifaddr *)data; > if (ifa != 0) > Index: netinet/in.c > =================================================================== > RCS file: /home/ncvs/src/sys/netinet/in.c,v > retrieving revision 1.103 > diff -u -p -r1.103 in.c > --- netinet/in.c 3 Sep 2014 08:59:06 -0000 1.103 > +++ netinet/in.c 11 Sep 2014 08:45:29 -0000 > @@ -612,7 +612,7 @@ in_ifinit(struct ifnet *ifp, struct in_i > { > u_int32_t i = sin->sin_addr.s_addr; > struct sockaddr_in oldaddr; > - int s, error = 0; > + int error = 0; > > splsoftassert(IPL_SOFTNET); > > @@ -627,7 +627,6 @@ in_ifinit(struct ifnet *ifp, struct in_i > rt_ifa_delloop(&ia->ia_ifa); > ifa_del(ifp, &ia->ia_ifa); > } > - s = splnet(); > oldaddr = ia->ia_addr; > ia->ia_addr = *sin; > > @@ -639,10 +638,8 @@ in_ifinit(struct ifnet *ifp, struct in_i > if (ifp->if_ioctl && > (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) { > ia->ia_addr = oldaddr; > - splx(s); > goto out; > } > - splx(s); > > if (ia->ia_netmask == 0) { > if (IN_CLASSA(i)) > Index: netinet/ip_carp.c > =================================================================== > RCS file: /home/ncvs/src/sys/netinet/ip_carp.c,v > retrieving revision 1.234 > diff -u -p -r1.234 ip_carp.c > --- netinet/ip_carp.c 8 Sep 2014 06:24:13 -0000 1.234 > +++ netinet/ip_carp.c 11 Sep 2014 08:45:29 -0000 > @@ -2059,10 +2059,11 @@ carp_ioctl(struct ifnet *ifp, u_long cmd > struct ifaddr *ifa = (struct ifaddr *)addr; > struct ifreq *ifr = (struct ifreq *)addr; > struct ifnet *cdev = NULL; > - int i, error = 0; > + int s, i, error = 0; > > switch (cmd) { > case SIOCSIFADDR: > + s = splnet(); > switch (ifa->ifa_addr->sa_family) { > #ifdef INET > case AF_INET: > @@ -2087,6 +2088,7 @@ carp_ioctl(struct ifnet *ifp, u_long cmd > break; > } > break; > + splx(s); > > case SIOCSIFFLAGS: > vhe = LIST_FIRST(&sc->carp_vhosts); > Index: netinet6/in6.c > =================================================================== > RCS file: /home/ncvs/src/sys/netinet6/in6.c,v > retrieving revision 1.140 > diff -u -p -r1.140 in6.c > --- netinet6/in6.c 26 Aug 2014 21:44:29 -0000 1.140 > +++ netinet6/in6.c 11 Sep 2014 08:45:29 -0000 > @@ -172,7 +172,7 @@ in6_control(struct socket *so, u_long cm > struct in6_ifaddr *ia6 = NULL; > struct in6_aliasreq *ifra = (struct in6_aliasreq *)data; > struct sockaddr_in6 *sa6; > - int privileged; > + int s, privileged; > > privileged = 0; > if ((so->so_state & SS_PRIV) != 0) > @@ -463,7 +463,6 @@ in6_control(struct socket *so, u_long cm > { > int i, error = 0; > struct nd_prefix pr0, *pr; > - int s; > > /* reject read-only flags */ > if ((ifra->ifra_flags & IN6_IFF_DUPLICATED) != 0 || > @@ -561,8 +560,10 @@ in6_control(struct socket *so, u_long cm > } > > case SIOCDIFADDR_IN6: > + s = splsoftnet(); > in6_purgeaddr(&ia6->ia_ifa); > dohooks(ifp->if_addrhooks, 0); > + splx(s); > break; > > default: > @@ -1078,7 +1079,7 @@ in6_purgeaddr(struct ifaddr *ifa) > void > in6_unlink_ifa(struct in6_ifaddr *ia6, struct ifnet *ifp) > { > - int s = splnet(); > + splsoftassert(IPL_SOFTNET); > > ifa_del(ifp, &ia6->ia_ifa); > > @@ -1107,8 +1108,6 @@ in6_unlink_ifa(struct in6_ifaddr *ia6, s > * Note that we should decrement the refcnt at least once for all *BSD. > */ > ifafree(&ia6->ia_ifa); > - > - splx(s); > } > > /* > @@ -1355,9 +1354,10 @@ int > in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia6, int newhost) > { > int error = 0, plen, ifacount = 0; > - int s = splnet(); > struct ifaddr *ifa; > > + splsoftassert(IPL_SOFTNET); > + > /* > * Give the interface a chance to initialize > * if this is its first address (or it is a CARP interface) > @@ -1374,10 +1374,8 @@ in6_ifinit(struct ifnet *ifp, struct in6 > if ((ifacount <= 1 || ifp->if_type == IFT_CARP || > (ifp->if_flags & IFF_POINTOPOINT)) && ifp->if_ioctl && > (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia6))) { > - splx(s); > return (error); > } > - splx(s); > > ia6->ia_ifa.ifa_metric = ifp->if_metric; > > Index: netinet6/nd6_rtr.c > =================================================================== > RCS file: /home/ncvs/src/sys/netinet6/nd6_rtr.c,v > retrieving revision 1.87 > diff -u -p -r1.87 nd6_rtr.c > --- netinet6/nd6_rtr.c 9 Sep 2014 20:33:24 -0000 1.87 > +++ netinet6/nd6_rtr.c 11 Sep 2014 08:45:29 -0000 > @@ -990,6 +990,8 @@ purge_detached(struct ifnet *ifp) > struct in6_ifaddr *ia6; > struct ifaddr *ifa, *ifa_next; > > + splsoftassert(IPL_SOFTNET); > + > LIST_FOREACH_SAFE(pr, &nd_prefix, ndpr_entry, pr_next) { > /* > * This function is called when we need to make more room for > @@ -1025,8 +1027,11 @@ nd6_prelist_add(struct nd_prefix *pr, st > struct in6_ifextra *ext = pr->ndpr_ifp->if_afdata[AF_INET6]; > > if (ip6_maxifprefixes >= 0) { > - if (ext->nprefixes >= ip6_maxifprefixes / 2) > + if (ext->nprefixes >= ip6_maxifprefixes / 2) { > + s = splsoftnet(); > purge_detached(pr->ndpr_ifp); > + splx(s); > + } > if (ext->nprefixes >= ip6_maxifprefixes) > return(ENOMEM); > } >