From f7ebbf1968980cdd64cdfb5eae828056fdbc0634 Mon Sep 17 00:00:00 2001 From: henning Date: Sun, 9 Sep 2018 10:11:41 +0000 Subject: [PATCH] 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 --- sys/net/if_loop.c | 25 ++++++++++++++++++++++--- 1 file 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); -- 2.20.1