summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBret Lambert <blambert@cvs.openbsd.org>2012-09-18 08:16:34 +0000
committerBret Lambert <blambert@cvs.openbsd.org>2012-09-18 08:16:34 +0000
commitdd55ef6ccbdca47c30e6113568af799083af3ec1 (patch)
tree53aca334876b58c316af0bcaf2b795df3b2e6b64
parentb259c04c18573abbb28e8dcad96a5972e95bfff0 (diff)
Wrap rtable_add() and rtable_l2set() calls inside ifioctl() inside softnet,
as functions that modify routing information shouldn't be interruptable by network traffic. Also make sure that both of those functions assert that they are called at softnet. I'm reasonably sure that there shouldn't be any, but if there is any codepath that was missed, we're going to be here for another 4 days to deal with any fallout. While here, move the multitude of "int s" declarations inside ifioctl to the beginning of the function. okay claudio@
-rw-r--r--sys/net/if.c31
-rw-r--r--sys/net/route.c8
2 files changed, 23 insertions, 16 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index e20c7e28a85..bc4522bf9ec 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.241 2012/01/03 23:41:51 bluhm Exp $ */
+/* $OpenBSD: if.c,v 1.242 2012/09/18 08:16:33 blambert Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -1211,7 +1211,7 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
struct ifgroupreq *ifgr;
char ifdescrbuf[IFDESCRSIZE];
char ifrtlabelbuf[RTLABEL_LEN];
- int error = 0;
+ int s, error = 0;
size_t bytesdone;
short oif_flags;
const char *label;
@@ -1275,12 +1275,12 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
if ((error = suser(p, 0)) != 0)
return (error);
if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
- int s = splnet();
+ s = splnet();
if_down(ifp);
splx(s);
}
if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) {
- int s = splnet();
+ s = splnet();
if_up(ifp);
splx(s);
}
@@ -1297,7 +1297,7 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
#ifdef INET6
if (ifr->ifr_flags & IFXF_NOINET6 &&
!(ifp->if_xflags & IFXF_NOINET6)) {
- int s = splnet();
+ s = splnet();
in6_ifdetach(ifp);
splx(s);
}
@@ -1306,7 +1306,7 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
ifp->if_xflags &= ~IFXF_NOINET6;
if (ifp->if_flags & IFF_UP) {
/* configure link-local address */
- int s = splnet();
+ s = splnet();
in6_if_up(ifp);
splx(s);
}
@@ -1316,7 +1316,7 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
#ifdef MPLS
if (ISSET(ifr->ifr_flags, IFXF_MPLS) &&
!ISSET(ifp->if_xflags, IFXF_MPLS)) {
- int s = splnet();
+ s = splnet();
ifp->if_xflags |= IFXF_MPLS;
ifp->if_ll_output = ifp->if_output;
ifp->if_output = mpls_output;
@@ -1324,7 +1324,7 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
}
if (ISSET(ifp->if_xflags, IFXF_MPLS) &&
!ISSET(ifr->ifr_flags, IFXF_MPLS)) {
- int s = splnet();
+ s = splnet();
ifp->if_xflags &= ~IFXF_MPLS;
ifp->if_output = ifp->if_ll_output;
ifp->if_ll_output = NULL;
@@ -1336,7 +1336,7 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
if (ifp->if_capabilities & IFCAP_WOL) {
if (ISSET(ifr->ifr_flags, IFXF_WOL) &&
!ISSET(ifp->if_xflags, IFXF_WOL)) {
- int s = splnet();
+ s = splnet();
ifp->if_xflags |= IFXF_WOL;
error = ifp->if_wol(ifp, 1);
splx(s);
@@ -1345,7 +1345,7 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
}
if (ISSET(ifp->if_xflags, IFXF_WOL) &&
!ISSET(ifr->ifr_flags, IFXF_WOL)) {
- int s = splnet();
+ s = splnet();
ifp->if_xflags &= ~IFXF_WOL;
error = ifp->if_wol(ifp, 0);
splx(s);
@@ -1477,9 +1477,12 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
/* make sure that the routing table exists */
if (!rtable_exists(ifr->ifr_rdomainid)) {
- if ((error = rtable_add(ifr->ifr_rdomainid)) != 0)
+ s = splsoftnet();
+ if ((error = rtable_add(ifr->ifr_rdomainid)) == 0)
+ rtable_l2set(ifr->ifr_rdomainid, ifr->ifr_rdomainid);
+ splx(s);
+ if (error)
return (error);
- rtable_l2set(ifr->ifr_rdomainid, ifr->ifr_rdomainid);
}
/* make sure that the routing table is a real rdomain */
@@ -1489,7 +1492,7 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
/* remove all routing entries when switching domains */
/* XXX hell this is ugly */
if (ifr->ifr_rdomainid != ifp->if_rdomain) {
- int s = splnet();
+ s = splnet();
rt_if_remove(ifp);
#ifdef INET
rti_delete(ifp);
@@ -1657,7 +1660,7 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
#ifdef INET6
if (!(ifp->if_xflags & IFXF_NOINET6) &&
(ifp->if_flags & IFF_UP) != 0) {
- int s = splnet();
+ s = splnet();
in6_if_up(ifp);
splx(s);
}
diff --git a/sys/net/route.c b/sys/net/route.c
index f23cd47cb3b..4533c371216 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.137 2012/07/13 20:27:25 claudio Exp $ */
+/* $OpenBSD: route.c,v 1.138 2012/09/18 08:16:33 blambert Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
@@ -225,10 +225,12 @@ route_init(void)
}
int
-rtable_add(u_int id) /* must be called at splsoftnet */
+rtable_add(u_int id)
{
void *p, *q;
+ splsoftassert(IPL_SOFTNET);
+
if (id > RT_TABLEID_MAX)
return (EINVAL);
@@ -271,6 +273,8 @@ rtable_l2(u_int id)
void
rtable_l2set(u_int id, u_int parent)
{
+ splsoftassert(IPL_SOFTNET);
+
if (!rtable_exists(id) || !rtable_exists(parent))
return;
rt_tab2dom[id] = parent;