Wed Apr 17 18:52:25 2024 UTC (22d)
tap(4): Prune dead branches around tap_dev_destroyer.

No functional change intended.

PR kern/58166


(riastradh)
diff -r1.129 -r1.130 src/sys/net/if_tap.c

cvs diff -r1.129 -r1.130 src/sys/net/if_tap.c (expand / switch to unified diff)

--- src/sys/net/if_tap.c 2024/04/17 18:32:13 1.129
+++ src/sys/net/if_tap.c 2024/04/17 18:52:25 1.130
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if_tap.c,v 1.129 2024/04/17 18:32:13 riastradh Exp $ */ 1/* $NetBSD: if_tap.c,v 1.130 2024/04/17 18:52:25 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2003, 2004, 2008, 2009 The NetBSD Foundation. 4 * Copyright (c) 2003, 2004, 2008, 2009 The NetBSD Foundation.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -23,27 +23,27 @@ @@ -23,27 +23,27 @@
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29/* 29/*
30 * tap(4) is a virtual Ethernet interface. It appears as a real Ethernet 30 * tap(4) is a virtual Ethernet interface. It appears as a real Ethernet
31 * device to the system, but can also be accessed by userland through a 31 * device to the system, but can also be accessed by userland through a
32 * character device interface, which allows reading and injecting frames. 32 * character device interface, which allows reading and injecting frames.
33 */ 33 */
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36__KERNEL_RCSID(0, "$NetBSD: if_tap.c,v 1.129 2024/04/17 18:32:13 riastradh Exp $"); 36__KERNEL_RCSID(0, "$NetBSD: if_tap.c,v 1.130 2024/04/17 18:52:25 riastradh Exp $");
37 37
38#if defined(_KERNEL_OPT) 38#if defined(_KERNEL_OPT)
39 39
40#include "opt_modular.h" 40#include "opt_modular.h"
41#endif 41#endif
42 42
43#include <sys/param.h> 43#include <sys/param.h>
44#include <sys/atomic.h> 44#include <sys/atomic.h>
45#include <sys/conf.h> 45#include <sys/conf.h>
46#include <sys/cprng.h> 46#include <sys/cprng.h>
47#include <sys/device.h> 47#include <sys/device.h>
48#include <sys/file.h> 48#include <sys/file.h>
49#include <sys/filedesc.h> 49#include <sys/filedesc.h>
@@ -200,27 +200,27 @@ static void tap_softintr(void *); @@ -200,27 +200,27 @@ static void tap_softintr(void *);
200 * an Ethernet device. 200 * an Ethernet device.
201 * 201 *
202 * Here are the bits needed for a clonable interface. 202 * Here are the bits needed for a clonable interface.
203 */ 203 */
204static int tap_clone_create(struct if_clone *, int); 204static int tap_clone_create(struct if_clone *, int);
205static int tap_clone_destroy(struct ifnet *); 205static int tap_clone_destroy(struct ifnet *);
206 206
207struct if_clone tap_cloners = IF_CLONE_INITIALIZER("tap", 207struct if_clone tap_cloners = IF_CLONE_INITIALIZER("tap",
208 tap_clone_create, 208 tap_clone_create,
209 tap_clone_destroy); 209 tap_clone_destroy);
210 210
211/* Helper functions shared by the two cloning code paths */ 211/* Helper functions shared by the two cloning code paths */
212static struct tap_softc * tap_clone_creator(int); 212static struct tap_softc * tap_clone_creator(int);
213int tap_clone_destroyer(device_t); 213static void tap_clone_destroyer(device_t);
214 214
215static struct sysctllog *tap_sysctl_clog; 215static struct sysctllog *tap_sysctl_clog;
216 216
217#ifdef _MODULE 217#ifdef _MODULE
218devmajor_t tap_bmajor = -1, tap_cmajor = -1; 218devmajor_t tap_bmajor = -1, tap_cmajor = -1;
219#endif 219#endif
220 220
221static u_int tap_count; 221static u_int tap_count;
222 222
223void 223void
224tapattach(int n) 224tapattach(int n)
225{ 225{
226 226
@@ -615,53 +615,45 @@ tap_clone_creator(int unit) @@ -615,53 +615,45 @@ tap_clone_creator(int unit)
615 cf->cf_atname = tap_ca.ca_name; 615 cf->cf_atname = tap_ca.ca_name;
616 if (unit == -1) { 616 if (unit == -1) {
617 /* let autoconf find the first free one */ 617 /* let autoconf find the first free one */
618 cf->cf_unit = 0; 618 cf->cf_unit = 0;
619 cf->cf_fstate = FSTATE_STAR; 619 cf->cf_fstate = FSTATE_STAR;
620 } else { 620 } else {
621 cf->cf_unit = unit; 621 cf->cf_unit = unit;
622 cf->cf_fstate = FSTATE_NOTFOUND; 622 cf->cf_fstate = FSTATE_NOTFOUND;
623 } 623 }
624 624
625 return device_private(config_attach_pseudo(cf)); 625 return device_private(config_attach_pseudo(cf));
626} 626}
627 627
628/* 
629 * The clean design of if_clone and autoconf(9) makes that part 
630 * really straightforward. The second argument of config_detach 
631 * means neither QUIET nor FORCED. 
632 */ 
633static int 628static int
634tap_clone_destroy(struct ifnet *ifp) 629tap_clone_destroy(struct ifnet *ifp)
635{ 630{
636 struct tap_softc *sc = ifp->if_softc; 631 struct tap_softc *sc = ifp->if_softc;
637 int error = tap_clone_destroyer(sc->sc_dev); 
638 632
639 if (error == 0) 633 tap_clone_destroyer(sc->sc_dev);
640 atomic_dec_uint(&tap_count); 634 atomic_dec_uint(&tap_count);
641 return error; 635 return 0;
642} 636}
643 637
644int 638static void
645tap_clone_destroyer(device_t dev) 639tap_clone_destroyer(device_t dev)
646{ 640{
647 cfdata_t cf = device_cfdata(dev); 641 cfdata_t cf = device_cfdata(dev);
648 int error; 642 int error;
649 643
650 if ((error = config_detach(dev, 0)) != 0) 644 error = config_detach(dev, 0);
651 aprint_error_dev(dev, "unable to detach instance\n"); 645 KASSERTMSG(error == 0, "error=%d", error);
652 kmem_free(cf, sizeof(*cf)); 646 kmem_free(cf, sizeof(*cf));
653 
654 return error; 
655} 647}
656 648
657/* 649/*
658 * tap(4) is a bit of an hybrid device. It can be used in two different 650 * tap(4) is a bit of an hybrid device. It can be used in two different
659 * ways: 651 * ways:
660 * 1. ifconfig tapN create, then use /dev/tapN to read/write off it. 652 * 1. ifconfig tapN create, then use /dev/tapN to read/write off it.
661 * 2. open /dev/tap, get a new interface created and read/write off it. 653 * 2. open /dev/tap, get a new interface created and read/write off it.
662 * That interface is destroyed when the process that had it created exits. 654 * That interface is destroyed when the process that had it created exits.
663 * 655 *
664 * The first way is managed by the cdevsw structure, and you access interfaces 656 * The first way is managed by the cdevsw structure, and you access interfaces
665 * through a (major, minor) mapping: tap4 is obtained by the minor number 657 * through a (major, minor) mapping: tap4 is obtained by the minor number
666 * 4. The entry points for the cdevsw interface are prefixed by tap_cdev_. 658 * 4. The entry points for the cdevsw interface are prefixed by tap_cdev_.
667 * 659 *
@@ -764,45 +756,44 @@ tap_cdev_close(dev_t dev, int flags, int @@ -764,45 +756,44 @@ tap_cdev_close(dev_t dev, int flags, int
764} 756}
765 757
766/* 758/*
767 * It might happen that the administrator used ifconfig to externally destroy 759 * It might happen that the administrator used ifconfig to externally destroy
768 * the interface. In that case, tap_fops_close will be called while 760 * the interface. In that case, tap_fops_close will be called while
769 * tap_detach is already happening. If we called it again from here, we 761 * tap_detach is already happening. If we called it again from here, we
770 * would dead lock. TAP_GOING ensures that this situation doesn't happen. 762 * would dead lock. TAP_GOING ensures that this situation doesn't happen.
771 */ 763 */
772static int 764static int
773tap_fops_close(file_t *fp) 765tap_fops_close(file_t *fp)
774{ 766{
775 struct tap_softc *sc; 767 struct tap_softc *sc;
776 int unit = fp->f_devunit; 768 int unit = fp->f_devunit;
777 int error; 
778 769
779 sc = device_lookup_private(&tap_cd, unit); 770 sc = device_lookup_private(&tap_cd, unit);
780 if (sc == NULL) 771 if (sc == NULL)
781 return ENXIO; 772 return ENXIO;
782 773
783 KERNEL_LOCK(1, NULL); 774 KERNEL_LOCK(1, NULL);
784 tap_dev_close(sc); 775 tap_dev_close(sc);
785 776
786 /* Destroy the device now that it is no longer useful, 777 /*
787 * unless it's already being destroyed. */ 778 * Destroy the device now that it is no longer useful, unless
788 if ((sc->sc_flags & TAP_GOING) != 0) { 779 * it's already being destroyed.
789 KERNEL_UNLOCK_ONE(NULL); 780 */
790 return 0; 781 if ((sc->sc_flags & TAP_GOING) != 0)
791 } 782 goto out;
 783 tap_clone_destroyer(sc->sc_dev);
792 784
793 error = tap_clone_destroyer(sc->sc_dev); 785out: KERNEL_UNLOCK_ONE(NULL);
794 KERNEL_UNLOCK_ONE(NULL); 786 return 0;
795 return error; 
796} 787}
797 788
798static void 789static void
799tap_dev_close(struct tap_softc *sc) 790tap_dev_close(struct tap_softc *sc)
800{ 791{
801 struct ifnet *ifp; 792 struct ifnet *ifp;
802 int s; 793 int s;
803 794
804 s = splnet(); 795 s = splnet();
805 /* Let tap_start handle packets again */ 796 /* Let tap_start handle packets again */
806 ifp = &sc->sc_ec.ec_if; 797 ifp = &sc->sc_ec.ec_if;
807 ifp->if_flags &= ~IFF_OACTIVE; 798 ifp->if_flags &= ~IFF_OACTIVE;
808 799