summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2018-09-09 10:11:42 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2018-09-09 10:11:42 +0000
commit8ee1111b5be7793a6aa45062eb5c57802e5c49c2 (patch)
tree722e943d9100994309ced32fe3a4d5132ea13d8d /sys
parentbe7f4d8a3c8b34ab0eb6d01d66fd22ff7c522f1a (diff)
allow the automatically created loopback interfaces in rdomains to be
deleted if the rdomain doesn't contain any other interface. turn the rdomain back into an ordinary, empty rtable in that case. with this and the previous commits one can get rid of rdomains again without rebooting, which wasn't possible any more for some time ok bluhm, input mpi
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if_loop.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c
index 1edd9ea466e..7d8c06cf04e 100644
--- a/sys/net/if_loop.c
+++ b/sys/net/if_loop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_loop.c,v 1.87 2018/03/02 15:52:11 claudio Exp $ */
+/* $OpenBSD: if_loop.c,v 1.88 2018/09/09 10:11:41 henning Exp $ */
/* $NetBSD: if_loop.c,v 1.15 1996/05/07 02:40:33 thorpej Exp $ */
/*
@@ -195,8 +195,27 @@ loop_clone_create(struct if_clone *ifc, int unit)
int
loop_clone_destroy(struct ifnet *ifp)
{
- if (ifp->if_index == rtable_loindex(ifp->if_rdomain))
- return (EPERM);
+ struct ifnet *p;
+
+ if (ifp->if_index == rtable_loindex(ifp->if_rdomain)) {
+ /* rdomain 0 always needs a loopback */
+ if (ifp->if_rdomain == 0)
+ return (EPERM);
+
+ /* if there is any other interface in this rdomain, deny */
+ NET_LOCK();
+ TAILQ_FOREACH(p, &ifnet, if_list) {
+ if (p->if_rdomain != ifp->if_rdomain)
+ continue;
+ if (p->if_index == ifp->if_index)
+ continue;
+ NET_UNLOCK();
+ return (EBUSY);
+ }
+ NET_UNLOCK();
+
+ rtable_l2set(ifp->if_rdomain, 0, 0);
+ }
if_ih_remove(ifp, loinput, NULL);
if_detach(ifp);