summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2014-10-07 08:47:29 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2014-10-07 08:47:29 +0000
commit760f776a7ddeb43d69746282cc5b3f03a86d10d3 (patch)
tree985eee6f0952dc7bdebef9ab5347a2f9e92afd1c
parentf65cbbd9acc27d42ed33838bbf0bac14a7b80b2b (diff)
Do not protect the SIOCSIFADDR call by splnet(). Drivers already
raise it inside their ioctl handler (except for carp(4), what else?). In general, global structures manipulated in the softnet codepath only require a splsoftnet() protection when they are modified in process (ioctl) context. Also put some IPL_SOFNET asserts in functions accessing global structures. Previous version diff ok mikeb@, with inputs from and ok bluhm@
-rw-r--r--sys/net/if_loop.c6
-rw-r--r--sys/netinet/in.c7
-rw-r--r--sys/netinet/ip_carp.c6
-rw-r--r--sys/netinet6/in6.c16
-rw-r--r--sys/netinet6/nd6_rtr.c9
5 files changed, 22 insertions, 22 deletions
diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c
index 1e9172ce622..07f8c172a4a 100644
--- a/sys/net/if_loop.c
+++ b/sys/net/if_loop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_loop.c,v 1.57 2014/07/22 11:06:09 mpi Exp $ */
+/* $OpenBSD: if_loop.c,v 1.58 2014/10/07 08:47:28 mpi Exp $ */
/* $NetBSD: if_loop.c,v 1.15 1996/05/07 02:40:33 thorpej Exp $ */
/*
@@ -288,15 +288,13 @@ loioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
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)
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index 0725446536f..992b39c605a 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in.c,v 1.105 2014/10/02 12:12:51 mpi Exp $ */
+/* $OpenBSD: in.c,v 1.106 2014/10/07 08:47:28 mpi Exp $ */
/* $NetBSD: in.c,v 1.26 1996/02/13 23:41:39 christos Exp $ */
/*
@@ -612,7 +612,7 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin,
{
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_ifaddr *ia, struct sockaddr_in *sin,
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_ifaddr *ia, struct sockaddr_in *sin,
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))
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index ffa5ffe1f70..20678436cfe 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_carp.c,v 1.235 2014/09/28 14:26:42 reyk Exp $ */
+/* $OpenBSD: ip_carp.c,v 1.236 2014/10/07 08:47:28 mpi Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff. All rights reserved.
@@ -2058,10 +2058,11 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
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:
@@ -2086,6 +2087,7 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
break;
}
break;
+ splx(s);
case SIOCSIFFLAGS:
vhe = LIST_FIRST(&sc->carp_vhosts);
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 6174d47b06c..1c6faae9cd1 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in6.c,v 1.140 2014/08/26 21:44:29 florian Exp $ */
+/* $OpenBSD: in6.c,v 1.141 2014/10/07 08:47:28 mpi Exp $ */
/* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */
/*
@@ -172,7 +172,7 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp)
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 cmd, caddr_t data, struct ifnet *ifp)
{
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 cmd, caddr_t data, struct ifnet *ifp)
}
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, struct ifnet *ifp)
* 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_ifaddr *ia6, int newhost)
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;
diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c
index 3fe355e249a..4ef50837cb6 100644
--- a/sys/netinet6/nd6_rtr.c
+++ b/sys/netinet6/nd6_rtr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nd6_rtr.c,v 1.87 2014/09/09 20:33:24 dlg Exp $ */
+/* $OpenBSD: nd6_rtr.c,v 1.88 2014/10/07 08:47:28 mpi Exp $ */
/* $KAME: nd6_rtr.c,v 1.97 2001/02/07 11:09:13 itojun Exp $ */
/*
@@ -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, struct nd_defrouter *dr,
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);
}