From: Sepherosa Ziehau Date: Tue, 14 Dec 2010 14:06:32 +0000 (+0800) Subject: if_clone: Don't destroy iface which is not create through if_clone mechanism X-Git-Url: https://gitweb.dragonflybsd.org/~alexh/dragonfly.git/commitdiff_plain/a7e9152e0b2bf76f6f9eb691c96714b4e965f3f4 if_clone: Don't destroy iface which is not create through if_clone mechanism DragonFly-bug: http://bugs.dragonflybsd.org/issue1919 --- diff --git a/sys/net/bridge/if_bridge.c b/sys/net/bridge/if_bridge.c index 626e0ad0c2..3fffcaff04 100644 --- a/sys/net/bridge/if_bridge.c +++ b/sys/net/bridge/if_bridge.c @@ -360,7 +360,7 @@ extern void (*bridge_dn_p)(struct mbuf *, struct ifnet *); static int bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD; static int bridge_clone_create(struct if_clone *, int, caddr_t); -static void bridge_clone_destroy(struct ifnet *); +static int bridge_clone_destroy(struct ifnet *); static int bridge_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *); static void bridge_mutecaps(struct bridge_ifinfo *, struct ifnet *, int); @@ -731,7 +731,7 @@ bridge_delete_dispatch(netmsg_t msg) * * Destroy a bridge instance. */ -static void +static int bridge_clone_destroy(struct ifnet *ifp) { struct bridge_softc *sc = ifp->if_softc; @@ -762,6 +762,8 @@ bridge_clone_destroy(struct ifnet *ifp) kfree(sc->sc_iflists, M_DEVBUF); kfree(sc, M_DEVBUF); + + return 0; } /* diff --git a/sys/net/faith/if_faith.c b/sys/net/faith/if_faith.c index d452c49230..8b5982d41e 100644 --- a/sys/net/faith/if_faith.c +++ b/sys/net/faith/if_faith.c @@ -109,7 +109,7 @@ static MALLOC_DEFINE(M_FAITH, FAITHNAME, "Firewall Assisted Tunnel Interface"); LIST_HEAD(, faith_softc) faith_softc_list; int faith_clone_create (struct if_clone *, int, caddr_t); -void faith_clone_destroy (struct ifnet *); +int faith_clone_destroy (struct ifnet *); struct if_clone faith_cloner = IF_CLONE_INITIALIZER(FAITHNAME, faith_clone_create, faith_clone_destroy, NFAITH, IF_MAXUNIT); @@ -180,7 +180,7 @@ faith_clone_create(struct if_clone *ifc, int unit, caddr_t param __unused) return (0); } -void +int faith_clone_destroy(struct ifnet *ifp) { struct faith_softc *sc = (struct faith_softc *) ifp; @@ -190,6 +190,8 @@ faith_clone_destroy(struct ifnet *ifp) if_detach(ifp); kfree(sc, M_FAITH); + + return 0; } int diff --git a/sys/net/gif/if_gif.c b/sys/net/gif/if_gif.c index 2988cb38ee..5cd1b06670 100644 --- a/sys/net/gif/if_gif.c +++ b/sys/net/gif/if_gif.c @@ -90,7 +90,7 @@ static MALLOC_DEFINE(M_GIF, "gif", "Generic Tunnel Interface"); LIST_HEAD(, gif_softc) gif_softc_list; int gif_clone_create (struct if_clone *, int, caddr_t); -void gif_clone_destroy (struct ifnet *); +int gif_clone_destroy (struct ifnet *); struct if_clone gif_cloner = IF_CLONE_INITIALIZER("gif", gif_clone_create, gif_clone_destroy, 0, IF_MAXUNIT); @@ -166,7 +166,7 @@ gifattach0(struct gif_softc *sc) bpfattach(&sc->gif_if, DLT_NULL, sizeof(u_int)); } -void +int gif_clone_destroy(struct ifnet *ifp) { struct gif_softc *sc = ifp->if_softc; @@ -192,6 +192,8 @@ gif_clone_destroy(struct ifnet *ifp) if_detach(ifp); kfree(sc, M_GIF); + + return 0; } static void diff --git a/sys/net/gre/if_gre.c b/sys/net/gre/if_gre.c index 1f224c331e..5c29c2d034 100644 --- a/sys/net/gre/if_gre.c +++ b/sys/net/gre/if_gre.c @@ -102,7 +102,7 @@ static MALLOC_DEFINE(M_GRE, GRENAME, "Generic Routing Encapsulation"); struct gre_softc_head gre_softc_list; static int gre_clone_create(struct if_clone *, int, caddr_t); -static void gre_clone_destroy(struct ifnet *); +static int gre_clone_destroy(struct ifnet *); static int gre_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *); static int gre_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *rt); @@ -208,7 +208,7 @@ gre_clone_create(struct if_clone *ifc, int unit, caddr_t param __unused) return (0); } -static void +static int gre_clone_destroy(struct ifnet *ifp) { struct gre_softc *sc = ifp->if_softc; @@ -222,6 +222,8 @@ gre_clone_destroy(struct ifnet *ifp) if_detach(ifp); kfree(sc, M_GRE); + + return 0; } /* diff --git a/sys/net/if_clone.c b/sys/net/if_clone.c index 1a998f6d4f..d84c8344ff 100644 --- a/sys/net/if_clone.c +++ b/sys/net/if_clone.c @@ -132,7 +132,7 @@ if_clone_destroy(const char *name) struct if_clone *ifc; struct ifnet *ifp; int bytoff, bitoff; - int unit; + int unit, error; ifc = if_clone_lookup(name, &unit); if (ifc == NULL) @@ -148,7 +148,9 @@ if_clone_destroy(const char *name) if (ifc->ifc_destroy == NULL) return (EOPNOTSUPP); - (*ifc->ifc_destroy)(ifp); + error = ifc->ifc_destroy(ifp); + if (error) + return error; /* * Compute offset in the bitmap and deallocate the unit. diff --git a/sys/net/if_clone.h b/sys/net/if_clone.h index a8b10aa47d..da79034c81 100644 --- a/sys/net/if_clone.h +++ b/sys/net/if_clone.h @@ -58,7 +58,7 @@ struct if_clone { int ifc_bmlen; /* bitmap length */ int (*ifc_create)(struct if_clone *, int, caddr_t); - void (*ifc_destroy)(struct ifnet *); + int (*ifc_destroy)(struct ifnet *); }; #define IF_CLONE_INITIALIZER(name, create, destroy, minifs, maxunit) \ diff --git a/sys/net/pf/if_pflog.c b/sys/net/pf/if_pflog.c index 3c0439d02b..0109a504d5 100644 --- a/sys/net/pf/if_pflog.c +++ b/sys/net/pf/if_pflog.c @@ -90,7 +90,7 @@ int pflogioctl(struct ifnet *, u_long, caddr_t, struct ucred *); void pflogrtrequest(int, struct rtentry *, struct sockaddr *); void pflogstart(struct ifnet *); int pflog_clone_create(struct if_clone *, int, caddr_t); -void pflog_clone_destroy(struct ifnet *); +int pflog_clone_destroy(struct ifnet *); LIST_HEAD(, pflog_softc) pflogif_list; struct if_clone pflog_cloner = @@ -153,7 +153,7 @@ pflog_clone_create(struct if_clone *ifc, int unit, caddr_t param __unused) return (0); } -void +int pflog_clone_destroy(struct ifnet *ifp) { struct pflog_softc *pflogif = ifp->if_softc; @@ -173,6 +173,8 @@ pflog_clone_destroy(struct ifnet *ifp) lwkt_gettoken(&pf_token); kfree(pflogif, M_DEVBUF); lwkt_reltoken(&pf_token); + + return 0; } /* diff --git a/sys/net/pf/if_pfsync.c b/sys/net/pf/if_pfsync.c index 766328bc05..2a8bc8f2f3 100644 --- a/sys/net/pf/if_pfsync.c +++ b/sys/net/pf/if_pfsync.c @@ -87,7 +87,7 @@ struct pfsync_softc *pfsyncif = NULL; struct pfsyncstats pfsyncstats; void pfsyncattach(int); -static void pfsync_clone_destroy(struct ifnet *); +static int pfsync_clone_destroy(struct ifnet *); static int pfsync_clone_create(struct if_clone *, int, caddr_t); void pfsync_setmtu(struct pfsync_softc *, int); int pfsync_alloc_scrub_memory(struct pfsync_state_peer *, @@ -177,7 +177,7 @@ pfsync_clone_create(struct if_clone *ifc, int unit, caddr_t param __unused) return (0); } -static void +static int pfsync_clone_destroy(struct ifnet *ifp) { lwkt_gettoken(&pf_token); @@ -189,6 +189,8 @@ pfsync_clone_destroy(struct ifnet *ifp) lwkt_gettoken(&pf_token); kfree(pfsyncif, M_DEVBUF); pfsyncif = NULL; + + return 0; } /* diff --git a/sys/net/tap/if_tap.c b/sys/net/tap/if_tap.c index 10539bd43c..bfb36d19dd 100644 --- a/sys/net/tap/if_tap.c +++ b/sys/net/tap/if_tap.c @@ -96,7 +96,7 @@ static void tapdestroy(struct tap_softc *); /* clone */ static int tap_clone_create(struct if_clone *, int, caddr_t); -static void tap_clone_destroy(struct ifnet *); +static int tap_clone_destroy(struct ifnet *); /* network interface */ @@ -494,15 +494,19 @@ tapdestroy(struct tap_softc *tp) * * Destroy a tap instance. */ -static void +static int tap_clone_destroy(struct ifnet *ifp) { struct tap_softc *tp = ifp->if_softc; + if ((tp->tap_flags & TAP_CLONE) == 0) + return ENXIO; + TAPDEBUG(&tp->tap_if, "clone destroyed. minor = %#x tap_flags = 0x%x\n", minor(tp->tap_dev), tp->tap_flags); - if (tp->tap_flags & TAP_CLONE) - tapdestroy(tp); + tapdestroy(tp); + + return 0; } /* diff --git a/sys/net/vlan/if_vlan.c b/sys/net/vlan/if_vlan.c index cdbcb5f232..70548f5608 100644 --- a/sys/net/vlan/if_vlan.c +++ b/sys/net/vlan/if_vlan.c @@ -128,7 +128,7 @@ static MALLOC_DEFINE(M_VLAN, "vlan", "802.1Q Virtual LAN Interface"); static LIST_HEAD(, ifvlan) ifv_list; static int vlan_clone_create(struct if_clone *, int, caddr_t); -static void vlan_clone_destroy(struct ifnet *); +static int vlan_clone_destroy(struct ifnet *); static void vlan_ifdetach(void *, struct ifnet *); static void vlan_init(void *); @@ -417,7 +417,7 @@ vlan_clone_create(struct if_clone *ifc, int unit, caddr_t param __unused) return (0); } -static void +static int vlan_clone_destroy(struct ifnet *ifp) { struct ifvlan *ifv = ifp->if_softc; @@ -430,6 +430,8 @@ vlan_clone_destroy(struct ifnet *ifp) ether_ifdetach(ifp); kfree(ifv, M_VLAN); + + return 0; } static void diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index 12acb75402..73661481d0 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -180,7 +180,7 @@ static int carp_hmac_verify(struct carp_softc *, uint32_t *, static void carp_setroute(struct carp_softc *, int); static void carp_input_c(struct mbuf *, struct carp_header *, sa_family_t); static int carp_clone_create(struct if_clone *, int, caddr_t); -static void carp_clone_destroy(struct ifnet *); +static int carp_clone_destroy(struct ifnet *); static void carp_detach(struct carp_softc *, int); static int carp_prepare_ad(struct mbuf *, struct carp_softc *, struct carp_header *); @@ -421,7 +421,7 @@ carp_clone_create(struct if_clone *ifc, int unit, caddr_t param __unused) return (0); } -static void +static int carp_clone_destroy(struct ifnet *ifp) { struct carp_softc *sc = ifp->if_softc; @@ -437,6 +437,8 @@ carp_clone_destroy(struct ifnet *ifp) KASSERT(sc->sc_naddrs == 0, ("certain inet address is still active\n")); kfree(sc, M_CARP); + + return 0; } static void diff --git a/sys/netproto/802_11/wlan/ieee80211_dragonfly.c b/sys/netproto/802_11/wlan/ieee80211_dragonfly.c index 46dc35ed22..557af0c3ea 100644 --- a/sys/netproto/802_11/wlan/ieee80211_dragonfly.c +++ b/sys/netproto/802_11/wlan/ieee80211_dragonfly.c @@ -70,7 +70,7 @@ SYSCTL_INT(_net_wlan, OID_AUTO, force_swcrypto, CTLFLAG_RW, MALLOC_DEFINE(M_80211_COM, "80211com", "802.11 com state"); -static void wlan_clone_destroy(struct ifnet *); +static int wlan_clone_destroy(struct ifnet *); static int wlan_clone_create(struct if_clone *, int, caddr_t); static struct if_clone wlan_cloner = @@ -150,7 +150,7 @@ wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params) return (vap == NULL ? EIO : 0); } -static void +static int wlan_clone_destroy(struct ifnet *ifp) { struct ieee80211vap *vap = ifp->if_softc; @@ -159,6 +159,8 @@ wlan_clone_destroy(struct ifnet *ifp) wlan_serialize_enter(); /* WARNING must be global serializer */ ic->ic_vap_delete(vap); wlan_serialize_exit(); + + return 0; } const char *wlan_last_enter_func;