From a9c9dbe15c7561168bb5d3b3aa0aed838b10e3b7 Mon Sep 17 00:00:00 2001 From: Ryan Thomas McBride Date: Fri, 30 Jan 2009 10:47:47 +0000 Subject: "XXX: should this be performed under splnet()?"... Yes, yes it should. Interface configuration causes neighbour discoverery, which runs packets through parts of the stack that require at least splsoftnet(), like pf and pfsync. ok dlg --- sys/netinet6/in6.c | 11 ++++++++--- sys/netinet6/in6_ifattach.c | 11 +++++++---- sys/netinet6/nd6_rtr.c | 10 +++++++--- 3 files changed, 22 insertions(+), 10 deletions(-) (limited to 'sys') diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index f729b1ec5fb..eda7a3a5514 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6.c,v 1.79 2008/10/01 21:17:06 claudio Exp $ */ +/* $OpenBSD: in6.c,v 1.80 2009/01/30 10:47:46 mcbride Exp $ */ /* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */ /* @@ -619,6 +619,7 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, { int i, error = 0; struct nd_prefix pr0, *pr; + int s; /* reject read-only flags */ if ((ifra->ifra_flags & IN6_IFF_DUPLICATED) != 0 || @@ -631,7 +632,10 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, * first, make or update the interface address structure, * and link it to the list. */ - if ((error = in6_update_ifa(ifp, ifra, ia)) != 0) + s = splsoftnet(); + error = in6_update_ifa(ifp, ifra, ia); + splx(s); + if (error != 0) return (error); if ((ia = in6ifa_ifpwithaddr(ifp, &ifra->ifra_addr.sin6_addr)) == NULL) { @@ -765,7 +769,6 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, * Update parameters of an IPv6 interface address. * If necessary, a new entry is created and linked into address chains. * This function is separated from in6_control(). - * XXX: should this be performed under splnet()? */ int in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, @@ -778,6 +781,8 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, struct in6_multi_mship *imm; struct rtentry *rt; + splassert(IPL_SOFTNET); + /* Validate parameters */ if (ifp == NULL || ifra == NULL) /* this maybe redundant */ return (EINVAL); diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c index 61540994c94..a49927ebca7 100644 --- a/sys/netinet6/in6_ifattach.c +++ b/sys/netinet6/in6_ifattach.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_ifattach.c,v 1.47 2008/06/11 19:00:50 mcbride Exp $ */ +/* $OpenBSD: in6_ifattach.c,v 1.48 2009/01/30 10:47:46 mcbride Exp $ */ /* $KAME: in6_ifattach.c,v 1.124 2001/07/18 08:32:51 jinmei Exp $ */ /* @@ -308,7 +308,7 @@ in6_ifattach_linklocal(struct ifnet *ifp, struct ifnet *altifp) struct in6_ifaddr *ia; struct in6_aliasreq ifra; struct nd_prefix pr0; - int i, error; + int i, s, error; /* * configure link-local address. @@ -357,8 +357,11 @@ in6_ifattach_linklocal(struct ifnet *ifp, struct ifnet *altifp) * one has already been configured, so check if it's already there * with in6ifa_ifpforlinklocal() and clobber it if it exists. */ - if ((error = in6_update_ifa(ifp, &ifra, - in6ifa_ifpforlinklocal(ifp, 0))) != 0) { + s = splsoftnet(); + error = in6_update_ifa(ifp, &ifra, in6ifa_ifpforlinklocal(ifp, 0)); + splx(s); + + if (error != 0) { /* * XXX: When the interface does not support IPv6, this call * would fail in the SIOCSIFADDR ioctl. I believe the diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c index 3df2c89ba3b..80e4160f464 100644 --- a/sys/netinet6/nd6_rtr.c +++ b/sys/netinet6/nd6_rtr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nd6_rtr.c,v 1.48 2008/09/17 05:43:15 chl Exp $ */ +/* $OpenBSD: nd6_rtr.c,v 1.49 2009/01/30 10:47:46 mcbride Exp $ */ /* $KAME: nd6_rtr.c,v 1.97 2001/02/07 11:09:13 itojun Exp $ */ /* @@ -1683,7 +1683,7 @@ in6_ifadd(struct nd_prefix *pr) struct ifaddr *ifa; struct in6_aliasreq ifra; struct in6_ifaddr *ia, *ib; - int error, plen0; + int error, s, plen0; struct in6_addr mask; int prefixlen = pr->ndpr_plen; @@ -1779,7 +1779,11 @@ in6_ifadd(struct nd_prefix *pr) ifra.ifra_flags |= IN6_IFF_AUTOCONF; /* obey autoconf */ /* allocate ifaddr structure, link into chain, etc. */ - if ((error = in6_update_ifa(ifp, &ifra, NULL)) != 0) { + s = splsoftnet(); + error = in6_update_ifa(ifp, &ifra, NULL); + splx(s); + + if (error != 0) { nd6log((LOG_ERR, "in6_ifadd: failed to make ifaddr %s on %s (errno=%d)\n", ip6_sprintf(&ifra.ifra_addr.sin6_addr), ifp->if_xname, -- cgit v1.2.3