This remove all but one splsoftnet() recursions when creating or
destroying cloned interfaces.
Note that I have to introduce some extra splsoftnet()/splx() dances in
tun(4) and tap(4) create functions.
ok?
Index: net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.463
diff -u -p -r1.463 if.c
--- net/if.c 28 Nov 2016 11:18:02 -0000 1.463
+++ net/if.c 28 Nov 2016 14:16:03 -0000
@@ -133,6 +133,8 @@
void if_attachsetup(struct ifnet *);
void if_attachdomain(struct ifnet *);
void if_attach_common(struct ifnet *);
+int if_setrdomain(struct ifnet *, int);
+void if_slowtimo(void *);
void if_detached_start(struct ifnet *);
int if_detached_ioctl(struct ifnet *, u_long, caddr_t);
@@ -402,6 +404,8 @@ if_attachsetup(struct ifnet *ifp)
{
unsigned long ifidx;
+ splsoftassert(IPL_SOFTNET);
+
TAILQ_INIT(&ifp->if_groups);
if_addgroup(ifp, IFG_ALL);
@@ -501,17 +505,25 @@ if_attachdomain(struct ifnet *ifp)
void
if_attachhead(struct ifnet *ifp)
{
+ int s;
+
+ s = splsoftnet();
if_attach_common(ifp);
TAILQ_INSERT_HEAD(&ifnet, ifp, if_list);
if_attachsetup(ifp);
+ splx(s);
}
void
if_attach(struct ifnet *ifp)
{
+ int s;
+
+ s = splsoftnet();
if_attach_common(ifp);
TAILQ_INSERT_TAIL(&ifnet, ifp, if_list);
if_attachsetup(ifp);
+ splx(s);
}
void
@@ -1036,7 +1048,9 @@ if_clone_create(const char *name, int rd
{
struct if_clone *ifc;
struct ifnet *ifp;
- int unit, ret, s;
+ int unit, ret;
+
+ splsoftassert(IPL_SOFTNET);
ifc = if_clone_lookup(name, &unit);
if (ifc == NULL)
@@ -1045,9 +1059,7 @@ if_clone_create(const char *name, int rd
if (ifunit(name) != NULL)
return (EEXIST);
- s = splsoftnet();
ret = (*ifc->ifc_create)(ifc, unit);
- splx(s);
if (ret != 0 || (ifp = ifunit(name)) == NULL)
return (ret);
@@ -1067,7 +1079,8 @@ if_clone_destroy(const char *name)
{
struct if_clone *ifc;
struct ifnet *ifp;
- int error, s;
+
+ splsoftassert(IPL_SOFTNET);
ifc = if_clone_lookup(name, NULL);
if (ifc == NULL)
@@ -1081,15 +1094,13 @@ if_clone_destroy(const char *name)
return (EOPNOTSUPP);
if (ifp->if_flags & IFF_UP) {
+ int s;
s = splnet();
if_down(ifp);
splx(s);
}
- s = splsoftnet();
- error = (*ifc->ifc_destroy)(ifp);
- splx(s);
- return (error);
+ return ((*ifc->ifc_destroy)(ifp));
}
/*
@@ -1594,7 +1605,7 @@ int
if_setrdomain(struct ifnet *ifp, int rdomain)
{
struct ifreq ifr;
- int s, error;
+ int error;
if (rdomain < 0 || rdomain > RT_TABLEID_MAX)
return (EINVAL);
@@ -1618,11 +1629,8 @@ if_setrdomain(struct ifnet *ifp, int rdo
if (error && (ifp != loifp || error != EEXIST))
return (error);
-
- s = splsoftnet();
if ((error = rtable_add(rdomain)) == 0)
rtable_l2set(rdomain, rdomain, loifp->if_index);
- splx(s);
if (error) {
if_clone_destroy(loifname);
return (error);
@@ -1638,6 +1646,8 @@ if_setrdomain(struct ifnet *ifp, int rdo
/* remove all routing entries when switching domains */
/* XXX this is a bit ugly */
if (rdomain != ifp->if_rdomain) {
+ int s;
+
s = splnet();
/*
* We are tearing down the world.
Index: net/if.h
===================================================================
RCS file: /cvs/src/sys/net/if.h,v
retrieving revision 1.180
diff -u -p -r1.180 if.h
--- net/if.h 27 Oct 2016 03:00:35 -0000 1.180
+++ net/if.h 28 Nov 2016 14:16:03 -0000
@@ -467,7 +467,6 @@ void if_detach(struct ifnet *);
void if_down(struct ifnet *);
void if_downall(void);
void if_link_state_change(struct ifnet *);
-void if_slowtimo(void *);
void if_up(struct ifnet *);
int ifconf(u_long, caddr_t);
void ifinit(void);
@@ -485,7 +484,6 @@ void if_congestion(void);
int if_congested(void);
__dead void unhandled_af(int);
int if_setlladdr(struct ifnet *, const uint8_t *);
-int if_setrdomain(struct ifnet *, int);
#endif /* _KERNEL */
Index: net/if_tun.c
===================================================================
RCS file: /cvs/src/sys/net/if_tun.c,v
retrieving revision 1.169
diff -u -p -r1.169 if_tun.c
--- net/if_tun.c 4 Sep 2016 15:46:39 -0000 1.169
+++ net/if_tun.c 28 Nov 2016 14:16:03 -0000
@@ -312,14 +312,17 @@ int
tunopen(dev_t dev, int flag, int mode, struct proc *p)
{
struct tun_softc *tp;
- int error;
+ unsigned int rdomain = rtable_l2(p->p_p->ps_rtableid);
if ((tp = tun_lookup(minor(dev))) == NULL) { /* create on demand */
char xname[IFNAMSIZ];
+ int s, error;
snprintf(xname, sizeof(xname), "%s%d", "tun", minor(dev));
- if ((error = if_clone_create(xname,
- rtable_l2(p->p_p->ps_rtableid))) != 0)
+ s = splsoftnet();
+ error = if_clone_create(xname, rdomain);
+ splx(s);
+ if (error != 0)
return (error);
if ((tp = tun_lookup(minor(dev))) == NULL)
@@ -334,14 +337,17 @@ int
tapopen(dev_t dev, int flag, int mode, struct proc *p)
{
struct tun_softc *tp;
- int error;
+ unsigned int rdomain = rtable_l2(p->p_p->ps_rtableid);
if ((tp = tap_lookup(minor(dev))) == NULL) { /* create on demand */
char xname[IFNAMSIZ];
+ int s, error;
snprintf(xname, sizeof(xname), "%s%d", "tap", minor(dev));
- if ((error = if_clone_create(xname,
- rtable_l2(p->p_p->ps_rtableid))) != 0)
+ s = splsoftnet();
+ error = if_clone_create(xname, rdomain);
+ splx(s);
+ if (error != 0)
return (error);
if ((tp = tap_lookup(minor(dev))) == NULL)
@@ -403,7 +409,7 @@ tapclose(dev_t dev, int flag, int mode,
int
tun_dev_close(struct tun_softc *tp, int flag, int mode, struct proc *p)
{
- int s;
+ int s, error = 0;
struct ifnet *ifp;
ifp = &tp->tun_if;
@@ -420,14 +426,16 @@ tun_dev_close(struct tun_softc *tp, int
TUNDEBUG(("%s: closed\n", ifp->if_xname));
- if (!(tp->tun_flags & TUN_STAYUP))
- return (if_clone_destroy(ifp->if_xname));
- else {
+ if (!(tp->tun_flags & TUN_STAYUP)) {
+ s = splsoftnet();
+ error = if_clone_destroy(ifp->if_xname);
+ splx(s);
+ } else {
tp->tun_pgid = 0;
selwakeup(&tp->tun_rsel);
}
- return (0);
+ return (error);
}
int