git: 91ebcbe02a48 - main - if_clone: migrate some consumers to the new KPI.

From: Alexander V. Chernikov <melifaro_at_FreeBSD.org>
Date: Thu, 22 Sep 2022 12:32:10 UTC
The branch main has been updated by melifaro:

URL: https://cgit.FreeBSD.org/src/commit/?id=91ebcbe02a48ebd40edb49283b90f38d246da15a

commit 91ebcbe02a48ebd40edb49283b90f38d246da15a
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2022-09-22 12:30:09 +0000
Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2022-09-22 12:30:09 +0000

    if_clone: migrate some consumers to the new KPI.
    
    Convert most of the cloner customers who require custom params
     to the new if_clone KPI.
    
    Reviewed by:    kp
    Differential Revision:  https://reviews.freebsd.org/D36636
    MFC after:      2 weeks
---
 sys/dev/usb/usb_pf.c             | 23 +++++++++++++++--------
 sys/net/if_bridge.c              | 28 +++++++++++++++++++---------
 sys/net/if_epair.c               | 22 ++++++++++++----------
 sys/net/if_lagg.c                | 33 +++++++++++++++++++++------------
 sys/net/if_loop.c                | 32 +++++++++++++++++++-------------
 sys/net/if_ovpn.c                | 14 ++++++++++----
 sys/net/if_stf.c                 | 18 +++++++++++-------
 sys/net/if_tuntap.c              | 30 +++++++++++++++++++-----------
 sys/net/if_vlan.c                | 32 +++++++++++++++++++-------------
 sys/net/if_vxlan.c               | 34 ++++++++++++++++++++++------------
 sys/net80211/ieee80211_freebsd.c | 25 +++++++++++++++++--------
 sys/netpfil/pf/if_pflog.c        | 37 ++++++++++++++++++++++++++-----------
 12 files changed, 210 insertions(+), 118 deletions(-)

diff --git a/sys/dev/usb/usb_pf.c b/sys/dev/usb/usb_pf.c
index 6ccb5ebbc62b..d0b7f0889cea 100644
--- a/sys/dev/usb/usb_pf.c
+++ b/sys/dev/usb/usb_pf.c
@@ -70,8 +70,9 @@ static void usbpf_init(void *);
 static void usbpf_uninit(void *);
 static int usbpf_ioctl(struct ifnet *, u_long, caddr_t);
 static int usbpf_clone_match(struct if_clone *, const char *);
-static int usbpf_clone_create(struct if_clone *, char *, size_t, caddr_t);
-static int usbpf_clone_destroy(struct if_clone *, struct ifnet *);
+static int usbpf_clone_create(struct if_clone *, char *, size_t,
+	    struct ifc_data *, struct ifnet **);
+static int usbpf_clone_destroy(struct if_clone *, struct ifnet *, uint32_t);
 static struct usb_bus *usbpf_ifname2ubus(const char *);
 static uint32_t usbpf_aggregate_xferflags(struct usb_xfer_flags *);
 static uint32_t usbpf_aggregate_status(struct usb_xfer_flags_int *);
@@ -87,9 +88,13 @@ SYSUNINIT(usbpf_uninit, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, usbpf_uninit, NULL);
 static void
 usbpf_init(void *arg)
 {
+	struct if_clone_addreq req = {
+		.match_f = usbpf_clone_match,
+		.create_f = usbpf_clone_create,
+		.destroy_f = usbpf_clone_destroy,
+	};
 
-	usbpf_cloner = if_clone_advanced(usbusname, 0, usbpf_clone_match,
-	    usbpf_clone_create, usbpf_clone_destroy);
+	usbpf_cloner = ifc_attach_cloner(usbusname, &req);
 }
 
 static void
@@ -113,7 +118,7 @@ usbpf_uninit(void *arg)
 	for (i = 0; i < devlcnt; i++) {
 		ubus = device_get_softc(devlp[i]);
 		if (ubus != NULL && ubus->ifp != NULL)
-			usbpf_clone_destroy(usbpf_cloner, ubus->ifp);
+			usbpf_clone_destroy(usbpf_cloner, ubus->ifp, 0);
 	}
 	free(devlp, M_TEMP);
 }
@@ -164,7 +169,8 @@ usbpf_clone_match(struct if_clone *ifc, const char *name)
 }
 
 static int
-usbpf_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
+usbpf_clone_create(struct if_clone *ifc, char *name, size_t len,
+    struct ifc_data *ifd, struct ifnet **ifpp)
 {
 	int error;
 	int unit;
@@ -210,12 +216,13 @@ usbpf_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
 	 * packets would be.
 	 */
 	bpfattach(ifp, DLT_USB, USBPF_HDR_LEN);
+	*ifpp = ifp;
 
 	return (0);
 }
 
 static int
-usbpf_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
+usbpf_clone_destroy(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags)
 {
 	struct usb_bus *ubus;
 	int unit;
@@ -251,7 +258,7 @@ usbpf_detach(struct usb_bus *ubus)
 {
 
 	if (ubus->ifp != NULL)
-		usbpf_clone_destroy(usbpf_cloner, ubus->ifp);
+		usbpf_clone_destroy(usbpf_cloner, ubus->ifp, 0);
 	if (bootverbose)
 		device_printf(ubus->parent, "usbpf: Detached\n");
 }
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 664a1f885a46..f2538a78f943 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -286,8 +286,9 @@ int	bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD;
 VNET_DEFINE_STATIC(uma_zone_t, bridge_rtnode_zone);
 #define	V_bridge_rtnode_zone	VNET(bridge_rtnode_zone)
 
-static int	bridge_clone_create(struct if_clone *, int, caddr_t);
-static void	bridge_clone_destroy(struct ifnet *);
+static int	bridge_clone_create(struct if_clone *, char *, size_t,
+		    struct ifc_data *, struct ifnet **);
+static int	bridge_clone_destroy(struct if_clone *, struct ifnet *, uint32_t);
 
 static int	bridge_ioctl(struct ifnet *, u_long, caddr_t);
 static void	bridge_mutecaps(struct bridge_softc *);
@@ -585,8 +586,13 @@ vnet_bridge_init(const void *unused __unused)
 	    UMA_ALIGN_PTR, 0);
 	BRIDGE_LIST_LOCK_INIT();
 	LIST_INIT(&V_bridge_list);
-	V_bridge_cloner = if_clone_simple(bridge_name,
-	    bridge_clone_create, bridge_clone_destroy, 0);
+
+	struct if_clone_addreq req = {
+		.create_f = bridge_clone_create,
+		.destroy_f = bridge_clone_destroy,
+		.flags = IFC_F_AUTOUNIT,
+	};
+	V_bridge_cloner = ifc_attach_cloner(bridge_name, &req);
 }
 VNET_SYSINIT(vnet_bridge_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
     vnet_bridge_init, NULL);
@@ -595,7 +601,7 @@ static void
 vnet_bridge_uninit(const void *unused __unused)
 {
 
-	if_clone_detach(V_bridge_cloner);
+	ifc_detach_cloner(V_bridge_cloner);
 	V_bridge_cloner = NULL;
 	BRIDGE_LIST_LOCK_DESTROY();
 
@@ -702,7 +708,8 @@ bridge_reassign(struct ifnet *ifp, struct vnet *newvnet, char *arg)
  *	Create a new bridge instance.
  */
 static int
-bridge_clone_create(struct if_clone *ifc, int unit, caddr_t params)
+bridge_clone_create(struct if_clone *ifc, char *name, size_t len,
+    struct ifc_data *ifd, struct ifnet **ifpp)
 {
 	struct bridge_softc *sc;
 	struct ifnet *ifp;
@@ -727,7 +734,7 @@ bridge_clone_create(struct if_clone *ifc, int unit, caddr_t params)
 	CK_LIST_INIT(&sc->sc_spanlist);
 
 	ifp->if_softc = sc;
-	if_initname(ifp, bridge_name, unit);
+	if_initname(ifp, bridge_name, ifd->unit);
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_ioctl = bridge_ioctl;
 #ifdef ALTQ
@@ -757,6 +764,7 @@ bridge_clone_create(struct if_clone *ifc, int unit, caddr_t params)
 	BRIDGE_LIST_LOCK();
 	LIST_INSERT_HEAD(&V_bridge_list, sc, sc_list);
 	BRIDGE_LIST_UNLOCK();
+	*ifpp = ifp;
 
 	return (0);
 }
@@ -777,8 +785,8 @@ bridge_clone_destroy_cb(struct epoch_context *ctx)
  *
  *	Destroy a bridge instance.
  */
-static void
-bridge_clone_destroy(struct ifnet *ifp)
+static int
+bridge_clone_destroy(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags)
 {
 	struct bridge_softc *sc = ifp->if_softc;
 	struct bridge_iflist *bif;
@@ -819,6 +827,8 @@ bridge_clone_destroy(struct ifnet *ifp)
 	if_free(ifp);
 
 	NET_EPOCH_CALL(bridge_clone_destroy_cb, &sc->sc_epoch_ctx);
+
+	return (0);
 }
 
 /*
diff --git a/sys/net/if_epair.c b/sys/net/if_epair.c
index 1dc5cb695d86..6bf7481065cd 100644
--- a/sys/net/if_epair.c
+++ b/sys/net/if_epair.c
@@ -84,10 +84,6 @@ __FBSDID("$FreeBSD$");
 #endif
 #include <net/vnet.h>
 
-static int epair_clone_match(struct if_clone *, const char *);
-static int epair_clone_create(struct if_clone *, char *, size_t, caddr_t);
-static int epair_clone_destroy(struct if_clone *, struct ifnet *);
-
 static const char epairname[] = "epair";
 #define	RXRSIZE	4096	/* Probably overkill by 4-8x. */
 
@@ -612,7 +608,8 @@ epair_free_sc(struct epair_softc *sc)
 }
 
 static int
-epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
+epair_clone_create(struct if_clone *ifc, char *name, size_t len,
+    struct ifc_data *ifd, struct ifnet **ifpp)
 {
 	struct epair_softc *sca, *scb;
 	struct ifnet *ifp;
@@ -708,6 +705,8 @@ epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
 	scb->ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	if_link_state_change(scb->ifp, LINK_STATE_UP);
 
+	*ifpp = sca->ifp;
+
 	return (0);
 }
 
@@ -731,7 +730,7 @@ epair_drain_rings(struct epair_softc *sc)
 }
 
 static int
-epair_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
+epair_clone_destroy(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags)
 {
 	struct ifnet *oifp;
 	struct epair_softc *sca, *scb;
@@ -782,9 +781,12 @@ epair_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
 static void
 vnet_epair_init(const void *unused __unused)
 {
-
-	V_epair_cloner = if_clone_advanced(epairname, 0,
-	    epair_clone_match, epair_clone_create, epair_clone_destroy);
+	struct if_clone_addreq req = {
+		.match_f = epair_clone_match,
+		.create_f = epair_clone_create,
+		.destroy_f = epair_clone_destroy,
+	};
+	V_epair_cloner = ifc_attach_cloner(epairname, &req);
 }
 VNET_SYSINIT(vnet_epair_init, SI_SUB_PSEUDO, SI_ORDER_ANY,
     vnet_epair_init, NULL);
@@ -793,7 +795,7 @@ static void
 vnet_epair_uninit(const void *unused __unused)
 {
 
-	if_clone_detach(V_epair_cloner);
+	ifc_detach_cloner(V_epair_cloner);
 }
 VNET_SYSUNINIT(vnet_epair_uninit, SI_SUB_INIT_IF, SI_ORDER_ANY,
     vnet_epair_uninit, NULL);
diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c
index 8e273c4ed391..7c5e0127d7ff 100644
--- a/sys/net/if_lagg.c
+++ b/sys/net/if_lagg.c
@@ -117,8 +117,9 @@ VNET_DEFINE_STATIC(struct mtx, lagg_list_mtx);
 #define	LAGG_LIST_UNLOCK(x)		mtx_unlock(&V_lagg_list_mtx)
 eventhandler_tag	lagg_detach_cookie = NULL;
 
-static int	lagg_clone_create(struct if_clone *, int, caddr_t);
-static void	lagg_clone_destroy(struct ifnet *);
+static int	lagg_clone_create(struct if_clone *, char *, size_t,
+		    struct ifc_data *, struct ifnet **);
+static int	lagg_clone_destroy(struct if_clone *, struct ifnet *, uint32_t);
 VNET_DEFINE_STATIC(struct if_clone *, lagg_cloner);
 #define	V_lagg_cloner	VNET(lagg_cloner)
 static const char laggname[] = "lagg";
@@ -304,8 +305,12 @@ vnet_lagg_init(const void *unused __unused)
 
 	LAGG_LIST_LOCK_INIT();
 	SLIST_INIT(&V_lagg_list);
-	V_lagg_cloner = if_clone_simple(laggname, lagg_clone_create,
-	    lagg_clone_destroy, 0);
+	struct if_clone_addreq req = {
+		.create_f = lagg_clone_create,
+		.destroy_f = lagg_clone_destroy,
+		.flags = IFC_F_AUTOUNIT,
+	};
+	V_lagg_cloner = ifc_attach_cloner(laggname, &req);
 }
 VNET_SYSINIT(vnet_lagg_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
     vnet_lagg_init, NULL);
@@ -314,7 +319,7 @@ static void
 vnet_lagg_uninit(const void *unused __unused)
 {
 
-	if_clone_detach(V_lagg_cloner);
+	ifc_detach_cloner(V_lagg_cloner);
 	LAGG_LIST_LOCK_DESTROY();
 }
 VNET_SYSUNINIT(vnet_lagg_uninit, SI_SUB_INIT_IF, SI_ORDER_ANY,
@@ -504,7 +509,8 @@ lagg_unregister_vlan(void *arg, struct ifnet *ifp, u_int16_t vtag)
 }
 
 static int
-lagg_clone_create(struct if_clone *ifc, int unit, caddr_t params)
+lagg_clone_create(struct if_clone *ifc, char *name, size_t len,
+    struct ifc_data *ifd, struct ifnet **ifpp)
 {
 	struct iflaggparam iflp;
 	struct lagg_softc *sc;
@@ -513,8 +519,8 @@ lagg_clone_create(struct if_clone *ifc, int unit, caddr_t params)
 	int error;
 	static const uint8_t eaddr[LAGG_ADDR_LEN];
 
-	if (params != NULL) {
-		error = copyin(params, &iflp, sizeof(iflp));
+	if (ifd->params != NULL) {
+		error = ifc_copyin(ifd, &iflp, sizeof(iflp));
 		if (error)
 			return (error);
 
@@ -565,11 +571,11 @@ lagg_clone_create(struct if_clone *ifc, int unit, caddr_t params)
 		ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL);
 		ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO);
 
-		if_initname(ifp, laggname, unit);
+		if_initname(ifp, laggname, ifd->unit);
 		ifp->if_transmit = lagg_transmit_ethernet;
 		break;
 	case IFT_INFINIBAND:
-		if_initname(ifp, laggname, unit);
+		if_initname(ifp, laggname, ifd->unit);
 		ifp->if_transmit = lagg_transmit_infiniband;
 		break;
 	default:
@@ -612,12 +618,13 @@ lagg_clone_create(struct if_clone *ifc, int unit, caddr_t params)
 	SLIST_INSERT_HEAD(&V_lagg_list, sc, sc_entries);
 	LAGG_LIST_UNLOCK();
 	LAGG_XUNLOCK(sc);
+	*ifpp = ifp;
 
 	return (0);
 }
 
-static void
-lagg_clone_destroy(struct ifnet *ifp)
+static int
+lagg_clone_destroy(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags)
 {
 	struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc;
 	struct lagg_port *lp;
@@ -658,6 +665,8 @@ lagg_clone_destroy(struct ifnet *ifp)
 	mtx_destroy(&sc->sc_mtx);
 	LAGG_SX_DESTROY(sc);
 	free(sc, M_LAGG);
+
+	return (0);
 }
 
 static void
diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c
index 4f0b236f7f5e..f4d34c46f9f0 100644
--- a/sys/net/if_loop.c
+++ b/sys/net/if_loop.c
@@ -93,8 +93,6 @@
 static int	loioctl(struct ifnet *, u_long, caddr_t);
 static int	looutput(struct ifnet *ifp, struct mbuf *m,
 		    const struct sockaddr *dst, struct route *ro);
-static int	lo_clone_create(struct if_clone *, int, caddr_t);
-static void	lo_clone_destroy(struct ifnet *);
 
 VNET_DEFINE(struct ifnet *, loif);	/* Used externally */
 
@@ -106,9 +104,11 @@ VNET_DEFINE_STATIC(struct if_clone *, lo_cloner);
 static struct if_clone *lo_cloner;
 static const char loname[] = "lo";
 
-static void
-lo_clone_destroy(struct ifnet *ifp)
+static int
+lo_clone_destroy(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags)
 {
+	if (ifp->if_dunit == 0 && (flags & IFC_F_FORCE) == 0)
+		return (EINVAL);
 
 #ifndef VIMAGE
 	/* XXX: destroying lo0 will lead to panics. */
@@ -118,10 +118,13 @@ lo_clone_destroy(struct ifnet *ifp)
 	bpfdetach(ifp);
 	if_detach(ifp);
 	if_free(ifp);
+
+	return (0);
 }
 
 static int
-lo_clone_create(struct if_clone *ifc, int unit, caddr_t params)
+lo_clone_create(struct if_clone *ifc, char *name, size_t len,
+    struct ifc_data *ifd, struct ifnet **ifpp)
 {
 	struct ifnet *ifp;
 
@@ -129,7 +132,7 @@ lo_clone_create(struct if_clone *ifc, int unit, caddr_t params)
 	if (ifp == NULL)
 		return (ENOSPC);
 
-	if_initname(ifp, loname, unit);
+	if_initname(ifp, loname, ifd->unit);
 	ifp->if_mtu = LOMTU;
 	ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
 	ifp->if_ioctl = loioctl;
@@ -142,6 +145,7 @@ lo_clone_create(struct if_clone *ifc, int unit, caddr_t params)
 	bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
 	if (V_loif == NULL)
 		V_loif = ifp;
+	*ifpp = ifp;
 
 	return (0);
 }
@@ -149,15 +153,17 @@ lo_clone_create(struct if_clone *ifc, int unit, caddr_t params)
 static void
 vnet_loif_init(const void *unused __unused)
 {
-
+	struct if_clone_addreq req = {
+		.create_f = lo_clone_create,
+		.destroy_f = lo_clone_destroy,
+		.flags = IFC_F_AUTOUNIT,
+	};
+	lo_cloner = ifc_attach_cloner(loname, &req);
 #ifdef VIMAGE
-	lo_cloner = if_clone_simple(loname, lo_clone_create, lo_clone_destroy,
-	    1);
 	V_lo_cloner = lo_cloner;
-#else
-	lo_cloner = if_clone_simple(loname, lo_clone_create, lo_clone_destroy,
-	    1);
 #endif
+	struct ifc_data ifd = { .unit = 0 };
+	ifc_create_ifp(loname, &ifd, NULL);
 }
 VNET_SYSINIT(vnet_loif_init, SI_SUB_PSEUDO, SI_ORDER_ANY,
     vnet_loif_init, NULL);
@@ -167,7 +173,7 @@ static void
 vnet_loif_uninit(const void *unused __unused)
 {
 
-	if_clone_detach(V_lo_cloner);
+	ifc_detach_cloner(V_lo_cloner);
 	V_loif = NULL;
 }
 VNET_SYSUNINIT(vnet_loif_uninit, SI_SUB_INIT_IF, SI_ORDER_SECOND,
diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c
index 82e6dd4f6eee..286125fb42d5 100644
--- a/sys/net/if_ovpn.c
+++ b/sys/net/if_ovpn.c
@@ -2291,7 +2291,8 @@ ovpn_clone_match(struct if_clone *ifc, const char *name)
 }
 
 static int
-ovpn_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
+ovpn_clone_create(struct if_clone *ifc, char *name, size_t len,
+    struct ifc_data *ifd, struct ifnet **ifpp)
 {
 	struct ovpn_softc *sc;
 	struct ifnet *ifp;
@@ -2357,6 +2358,7 @@ ovpn_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
 
 	if_attach(ifp);
 	bpfattach(ifp, DLT_NULL, sizeof(uint32_t));
+	*ifpp = ifp;
 
 	return (0);
 }
@@ -2380,7 +2382,7 @@ ovpn_clone_destroy_cb(struct epoch_context *ctx)
 }
 
 static int
-ovpn_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
+ovpn_clone_destroy(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags)
 {
 	struct ovpn_softc *sc;
 	int unit;
@@ -2429,8 +2431,12 @@ ovpn_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
 static void
 vnet_ovpn_init(const void *unused __unused)
 {
-	V_ovpn_cloner = if_clone_advanced(ovpngroupname, 0, ovpn_clone_match,
-	    ovpn_clone_create, ovpn_clone_destroy);
+	struct if_clone_addreq req = {
+		.match_f = ovpn_clone_match,
+		.create_f = ovpn_clone_create,
+		.destroy_f = ovpn_clone_destroy,
+	};
+	V_ovpn_cloner = ifc_attach_cloner(ovpngroupname, &req);
 }
 VNET_SYSINIT(vnet_ovpn_init, SI_SUB_PSEUDO, SI_ORDER_ANY,
     vnet_ovpn_init, NULL);
diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c
index 51ea0a61ae0d..9a469a82c34c 100644
--- a/sys/net/if_stf.c
+++ b/sys/net/if_stf.c
@@ -214,9 +214,6 @@ static struct sockaddr_in *stf_getin4addr(struct stf_softc *,
 	struct sockaddr_in *, struct in6_addr, struct in6_addr);
 static int stf_ioctl(struct ifnet *, u_long, caddr_t);
 
-static int stf_clone_match(struct if_clone *, const char *);
-static int stf_clone_create(struct if_clone *, char *, size_t, caddr_t);
-static int stf_clone_destroy(struct if_clone *, struct ifnet *);
 VNET_DEFINE_STATIC(struct if_clone *, stf_cloner);
 #define V_stf_cloner	VNET(stf_cloner)
 
@@ -242,7 +239,8 @@ stf_clone_match(struct if_clone *ifc, const char *name)
 }
 
 static int
-stf_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
+stf_clone_create(struct if_clone *ifc, char *name, size_t len,
+    struct ifc_data *ifd, struct ifnet **ifpp)
 {
 	char *dp;
 	int err, unit, wildcard;
@@ -309,11 +307,13 @@ stf_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
 	ifp->if_snd.ifq_maxlen = ifqmaxlen;
 	if_attach(ifp);
 	bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
+	*ifpp = ifp;
+
 	return (0);
 }
 
 static int
-stf_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
+stf_clone_destroy(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags)
 {
 	struct stf_softc *sc = ifp->if_softc;
 	int err __unused;
@@ -333,8 +333,12 @@ stf_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
 static void
 vnet_stf_init(const void *unused __unused)
 {
-	V_stf_cloner = if_clone_advanced(stfname, 0, stf_clone_match,
-	    stf_clone_create, stf_clone_destroy);
+	struct if_clone_addreq req = {
+		.match_f = stf_clone_match,
+		.create_f = stf_clone_create,
+		.destroy_f = stf_clone_destroy,
+	};
+	V_stf_cloner = ifc_attach_cloner(stfname, &req);
 }
 VNET_SYSINIT(vnet_stf_init, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_stf_init, NULL);
 
diff --git a/sys/net/if_tuntap.c b/sys/net/if_tuntap.c
index 5e1e60933caa..8328f9f94442 100644
--- a/sys/net/if_tuntap.c
+++ b/sys/net/if_tuntap.c
@@ -235,8 +235,9 @@ static void	tunstart_l2(struct ifnet *);
 static int	tun_clone_match(struct if_clone *ifc, const char *name);
 static int	tap_clone_match(struct if_clone *ifc, const char *name);
 static int	vmnet_clone_match(struct if_clone *ifc, const char *name);
-static int	tun_clone_create(struct if_clone *, char *, size_t, caddr_t);
-static int	tun_clone_destroy(struct if_clone *, struct ifnet *);
+static int	tun_clone_create(struct if_clone *, char *, size_t,
+		    struct ifc_data *, struct ifnet **);
+static int	tun_clone_destroy(struct if_clone *, struct ifnet *, uint32_t);
 static void	tun_vnethdr_set(struct ifnet *ifp, int vhdrlen);
 
 static d_open_t		tunopen;
@@ -269,9 +270,9 @@ static struct tuntap_driver {
 	int			 ident_flags;
 	struct unrhdr		*unrhdr;
 	struct clonedevs	*clones;
-	ifc_match_t		*clone_match_fn;
-	ifc_create_t		*clone_create_fn;
-	ifc_destroy_t		*clone_destroy_fn;
+	ifc_match_f		*clone_match_fn;
+	ifc_create_f		*clone_create_fn;
+	ifc_destroy_f		*clone_destroy_fn;
 } tuntap_drivers[] = {
 	{
 		.ident_flags =	0,
@@ -514,7 +515,8 @@ vmnet_clone_match(struct if_clone *ifc, const char *name)
 }
 
 static int
-tun_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
+tun_clone_create(struct if_clone *ifc, char *name, size_t len,
+    struct ifc_data *ifd, struct ifnet **ifpp)
 {
 	struct tuntap_driver *drv;
 	struct cdev *dev;
@@ -546,8 +548,11 @@ tun_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
 	/* No preexisting struct cdev *, create one */
 	if (i != 0)
 		i = tun_create_device(drv, unit, NULL, &dev, name);
-	if (i == 0)
+	if (i == 0) {
 		tuncreate(dev);
+		struct tuntap_softc *tp = dev->si_drv1;
+		*ifpp = tp->tun_ifp;
+	}
 
 	return (i);
 }
@@ -649,7 +654,7 @@ tun_destroy(struct tuntap_softc *tp)
 }
 
 static int
-tun_clone_destroy(struct if_clone *ifc __unused, struct ifnet *ifp)
+tun_clone_destroy(struct if_clone *ifc __unused, struct ifnet *ifp, uint32_t flags)
 {
 	struct tuntap_softc *tp = ifp->if_softc;
 
@@ -673,9 +678,12 @@ vnet_tun_init(const void *unused __unused)
 		drvc = malloc(sizeof(*drvc), M_TUN, M_WAITOK | M_ZERO);
 
 		drvc->drv = drv;
-		drvc->cloner = if_clone_advanced(drv->cdevsw.d_name, 0,
-		    drv->clone_match_fn, drv->clone_create_fn,
-		    drv->clone_destroy_fn);
+		struct if_clone_addreq req = {
+			.match_f = drv->clone_match_fn,
+			.create_f = drv->clone_create_fn,
+			.destroy_f = drv->clone_destroy_fn,
+		};
+		drvc->cloner = ifc_attach_cloner(drv->cdevsw.d_name, &req);
 		SLIST_INSERT_HEAD(&V_tuntap_driver_cloners, drvc, link);
 	};
 }
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index 58df9b21fc20..6a2d1bfb3fd1 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -323,8 +323,9 @@ static	void vlan_trunk_capabilities(struct ifnet *ifp);
 
 static	struct ifnet *vlan_clone_match_ethervid(const char *, int *);
 static	int vlan_clone_match(struct if_clone *, const char *);
-static	int vlan_clone_create(struct if_clone *, char *, size_t, caddr_t);
-static	int vlan_clone_destroy(struct if_clone *, struct ifnet *);
+static	int vlan_clone_create(struct if_clone *, char *, size_t,
+    struct ifc_data *, struct ifnet **);
+static	int vlan_clone_destroy(struct if_clone *, struct ifnet *, uint32_t);
 
 static	void vlan_ifdetach(void *arg, struct ifnet *ifp);
 static  void vlan_iflladdr(void *arg, struct ifnet *ifp);
@@ -902,6 +903,12 @@ extern	void (*vlan_input_p)(struct ifnet *, struct mbuf *);
 /* For if_link_state_change() eyes only... */
 extern	void (*vlan_link_state_p)(struct ifnet *);
 
+static struct if_clone_addreq vlan_addreq = {
+	.match_f = vlan_clone_match,
+	.create_f = vlan_clone_create,
+	.destroy_f = vlan_clone_destroy,
+};
+
 static int
 vlan_modevent(module_t mod, int type, void *data)
 {
@@ -931,8 +938,7 @@ vlan_modevent(module_t mod, int type, void *data)
 		vlan_pcp_p = vlan_pcp;
 		vlan_devat_p = vlan_devat;
 #ifndef VIMAGE
-		vlan_cloner = if_clone_advanced(vlanname, 0, vlan_clone_match,
-		    vlan_clone_create, vlan_clone_destroy);
+		vlan_cloner = ifc_attach_cloner(vlanname, &vlan_addreq);
 #endif
 		if (bootverbose)
 			printf("vlan: initialized, using "
@@ -946,7 +952,7 @@ vlan_modevent(module_t mod, int type, void *data)
 		break;
 	case MOD_UNLOAD:
 #ifndef VIMAGE
-		if_clone_detach(vlan_cloner);
+		ifc_detach_cloner(vlan_cloner);
 #endif
 		EVENTHANDLER_DEREGISTER(ifnet_departure_event, ifdetach_tag);
 		EVENTHANDLER_DEREGISTER(iflladdr_event, iflladdr_tag);
@@ -982,9 +988,7 @@ MODULE_VERSION(if_vlan, 3);
 static void
 vnet_vlan_init(const void *unused __unused)
 {
-
-	vlan_cloner = if_clone_advanced(vlanname, 0, vlan_clone_match,
-		    vlan_clone_create, vlan_clone_destroy);
+	vlan_cloner = ifc_attach_cloner(vlanname, &vlan_addreq);
 	V_vlan_cloner = vlan_cloner;
 }
 VNET_SYSINIT(vnet_vlan_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
@@ -994,7 +998,7 @@ static void
 vnet_vlan_uninit(const void *unused __unused)
 {
 
-	if_clone_detach(V_vlan_cloner);
+	ifc_detach_cloner(V_vlan_cloner);
 }
 VNET_SYSUNINIT(vnet_vlan_uninit, SI_SUB_INIT_IF, SI_ORDER_ANY,
     vnet_vlan_uninit, NULL);
@@ -1058,7 +1062,8 @@ vlan_clone_match(struct if_clone *ifc, const char *name)
 }
 
 static int
-vlan_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
+vlan_clone_create(struct if_clone *ifc, char *name, size_t len,
+    struct ifc_data *ifd, struct ifnet **ifpp)
 {
 	char *dp;
 	bool wildcard = false;
@@ -1089,8 +1094,8 @@ vlan_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
 	 * called for.
 	 */
 
-	if (params) {
-		error = copyin(params, &vlr, sizeof(vlr));
+	if (ifd->params != NULL) {
+		error = ifc_copyin(ifd, &vlr, sizeof(vlr));
 		if (error)
 			return error;
 		vid = vlr.vlr_tag;
@@ -1219,12 +1224,13 @@ vlan_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
 			return (error);
 		}
 	}
+	*ifpp = ifp;
 
 	return (0);
 }
 
 static int
-vlan_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
+vlan_clone_destroy(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags)
 {
 	struct ifvlan *ifv = ifp->if_softc;
 	int unit = ifp->if_dunit;
diff --git a/sys/net/if_vxlan.c b/sys/net/if_vxlan.c
index a1e925195d74..6c9a3d7e3095 100644
--- a/sys/net/if_vxlan.c
+++ b/sys/net/if_vxlan.c
@@ -376,8 +376,9 @@ static int	vxlan_set_user_config(struct vxlan_softc *,
 		     struct ifvxlanparam *);
 static int	vxlan_set_reqcap(struct vxlan_softc *, struct ifnet *, int);
 static void	vxlan_set_hwcaps(struct vxlan_softc *);
-static int	vxlan_clone_create(struct if_clone *, int, caddr_t);
-static void	vxlan_clone_destroy(struct ifnet *);
+static int	vxlan_clone_create(struct if_clone *, char *, size_t,
+		    struct ifc_data *, struct ifnet **);
+static int	vxlan_clone_destroy(struct if_clone *, struct ifnet *, uint32_t);
 
 static uint32_t vxlan_mac_hash(struct vxlan_softc *, const uint8_t *);
 static int	vxlan_media_change(struct ifnet *);
@@ -3194,7 +3195,8 @@ done:
 }
 
 static int
-vxlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
+vxlan_clone_create(struct if_clone *ifc, char *name, size_t len,
+    struct ifc_data *ifd, struct ifnet **ifpp)
 {
 	struct vxlan_softc *sc;
 	struct ifnet *ifp;
@@ -3202,15 +3204,15 @@ vxlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
 	int error;
 
 	sc = malloc(sizeof(struct vxlan_softc), M_VXLAN, M_WAITOK | M_ZERO);
-	sc->vxl_unit = unit;
+	sc->vxl_unit = ifd->unit;
 	sc->vxl_fibnum = curthread->td_proc->p_fibnum;
 	vxlan_set_default_config(sc);
 	error = vxlan_stats_alloc(sc);
 	if (error != 0)
 		goto fail;
 
-	if (params != 0) {
-		error = copyin(params, &vxlp, sizeof(vxlp));
+	if (ifd->params != NULL) {
+		error = ifc_copyin(ifd, &vxlp, sizeof(vxlp));
 		if (error)
 			goto fail;
 
@@ -3234,7 +3236,7 @@ vxlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
 	vxlan_sysctl_setup(sc);
 
 	ifp->if_softc = sc;
-	if_initname(ifp, vxlan_name, unit);
+	if_initname(ifp, vxlan_name, ifd->unit);
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_init = vxlan_init;
 	ifp->if_ioctl = vxlan_ioctl;
@@ -3257,6 +3259,7 @@ vxlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
 	VXLAN_WLOCK(sc);
 	vxlan_setup_interface_hdrlen(sc);
 	VXLAN_WUNLOCK(sc);
+	*ifpp = ifp;
 
 	return (0);
 
@@ -3265,8 +3268,8 @@ fail:
 	return (error);
 }
 
-static void
-vxlan_clone_destroy(struct ifnet *ifp)
+static int
+vxlan_clone_destroy(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags)
 {
 	struct vxlan_softc *sc;
 
@@ -3286,6 +3289,8 @@ vxlan_clone_destroy(struct ifnet *ifp)
 	rm_destroy(&sc->vxl_lock);
 	vxlan_stats_free(sc);
 	free(sc, M_VXLAN);
+
+	return (0);
 }
 
 /* BMV: Taken from if_bridge. */
@@ -3639,8 +3644,13 @@ vxlan_load(void)
 	LIST_INIT(&vxlan_socket_list);
 	vxlan_ifdetach_event_tag = EVENTHANDLER_REGISTER(ifnet_departure_event,
 	    vxlan_ifdetach_event, NULL, EVENTHANDLER_PRI_ANY);
-	vxlan_cloner = if_clone_simple(vxlan_name, vxlan_clone_create,
-	    vxlan_clone_destroy, 0);
+
+	struct if_clone_addreq req = {
+		.create_f = vxlan_clone_create,
+		.destroy_f = vxlan_clone_destroy,
+		.flags = IFC_F_AUTOUNIT,
+	};
+	vxlan_cloner = ifc_attach_cloner(vxlan_name, &req);
 }
 
 static void
@@ -3649,7 +3659,7 @@ vxlan_unload(void)
 
 	EVENTHANDLER_DEREGISTER(ifnet_departure_event,
 	    vxlan_ifdetach_event_tag);
-	if_clone_detach(vxlan_cloner);
+	ifc_detach_cloner(vxlan_cloner);
 	mtx_destroy(&vxlan_list_mtx);
 	MPASS(LIST_EMPTY(&vxlan_socket_list));
 }
diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c
index 5511791ae2aa..ec970e217dfd 100644
--- a/sys/net80211/ieee80211_freebsd.c
+++ b/sys/net80211/ieee80211_freebsd.c
@@ -112,7 +112,8 @@ ieee80211_priv_check_create_vap(u_long cmd __unused,
 }
 
 static int
-wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
+wlan_clone_create(struct if_clone *ifc, char *name, size_t len,
+    struct ifc_data *ifd, struct ifnet **ifpp)
 {
 	struct ieee80211_clone_params cp;
 	struct ieee80211vap *vap;
@@ -123,7 +124,7 @@ wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
 	if (error)
 		return error;
 
-	error = copyin(params, &cp, sizeof(cp));
+	error = ifc_copyin(ifd, &cp, sizeof(cp));
 	if (error)
 		return error;
 	ic = ieee80211_find_com(cp.icp_parent);
@@ -149,7 +150,7 @@ wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
 		ic_printf(ic, "TDMA not supported\n");
 		return EOPNOTSUPP;
 	}
-	vap = ic->ic_vap_create(ic, wlanname, unit,
+	vap = ic->ic_vap_create(ic, wlanname, ifd->unit,
 			cp.icp_opmode, cp.icp_flags, cp.icp_bssid,
 			cp.icp_flags & IEEE80211_CLONE_MACADDR ?
 			    cp.icp_macaddr : ic->ic_macaddr);
@@ -161,16 +162,20 @@ wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
 	if (ic->ic_debugnet_meth != NULL)
 		DEBUGNET_SET(vap->iv_ifp, ieee80211);
 #endif
+	*ifpp = vap->iv_ifp;
+
 	return (0);
 }
 
-static void
-wlan_clone_destroy(struct ifnet *ifp)
+static int
+wlan_clone_destroy(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags)
 {
 	struct ieee80211vap *vap = ifp->if_softc;
 	struct ieee80211com *ic = vap->iv_ic;
 
 	ic->ic_vap_delete(vap);
+
+	return (0);
 }
 
 void
@@ -1160,11 +1165,15 @@ wlan_modevent(module_t mod, int type, void *unused)
 		    bpf_track, 0, EVENTHANDLER_PRI_ANY);
 		wlan_ifllevent = EVENTHANDLER_REGISTER(iflladdr_event,
 		    wlan_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
-		wlan_cloner = if_clone_simple(wlanname, wlan_clone_create,
-		    wlan_clone_destroy, 0);
+		struct if_clone_addreq req = {
+			.create_f = wlan_clone_create,
+			.destroy_f = wlan_clone_destroy,
+			.flags = IFC_F_AUTOUNIT,
+		};
+		wlan_cloner = ifc_attach_cloner(wlanname, &req);
 		return 0;
 	case MOD_UNLOAD:
-		if_clone_detach(wlan_cloner);
+		ifc_detach_cloner(wlan_cloner);
 		EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent);
 		EVENTHANDLER_DEREGISTER(iflladdr_event, wlan_ifllevent);
 		return 0;
diff --git a/sys/netpfil/pf/if_pflog.c b/sys/netpfil/pf/if_pflog.c
index 261c9f2a4087..b4f34cd13fba 100644
--- a/sys/netpfil/pf/if_pflog.c
+++ b/sys/netpfil/pf/if_pflog.c
@@ -91,8 +91,9 @@ static int	pflogoutput(struct ifnet *, struct mbuf *,
 static void	pflogattach(int);
 static int	pflogioctl(struct ifnet *, u_long, caddr_t);
 static void	pflogstart(struct ifnet *);
-static int	pflog_clone_create(struct if_clone *, int, caddr_t);
-static void	pflog_clone_destroy(struct ifnet *);
+static int	pflog_clone_create(struct if_clone *, char *, size_t,
+		    struct ifc_data *, struct ifnet **);
+static int	pflog_clone_destroy(struct if_clone *, struct ifnet *, uint32_t);
 
 static const char pflogname[] = "pflog";
 
@@ -108,23 +109,31 @@ pflogattach(int npflog __unused)
 	int	i;
 	for (i = 0; i < PFLOGIFS_MAX; i++)
 		V_pflogifs[i] = NULL;
-	V_pflog_cloner = if_clone_simple(pflogname, pflog_clone_create,
-	    pflog_clone_destroy, 1);
+
+	struct if_clone_addreq req = {
+		.create_f = pflog_clone_create,
+		.destroy_f = pflog_clone_destroy,
+		.flags = IFC_F_AUTOUNIT,
+	};
+	V_pflog_cloner = ifc_attach_cloner(pflogname, &req);
+	struct ifc_data ifd = { .unit = 0 };
+	ifc_create_ifp(pflogname, &ifd, NULL);
 }
 
 static int
-pflog_clone_create(struct if_clone *ifc, int unit, caddr_t param)
+pflog_clone_create(struct if_clone *ifc, char *name, size_t maxlen,
+    struct ifc_data *ifd, struct ifnet **ifpp)
 {
 	struct ifnet *ifp;
 
-	if (unit >= PFLOGIFS_MAX)
+	if (ifd->unit >= PFLOGIFS_MAX)
 		return (EINVAL);
 
 	ifp = if_alloc(IFT_PFLOG);
 	if (ifp == NULL) {
 		return (ENOSPC);
 	}
-	if_initname(ifp, pflogname, unit);
+	if_initname(ifp, pflogname, ifd->unit);
 	ifp->if_mtu = PFLOGMTU;
 	ifp->if_ioctl = pflogioctl;
 	ifp->if_output = pflogoutput;
@@ -135,16 +144,20 @@ pflog_clone_create(struct if_clone *ifc, int unit, caddr_t param)
 
 	bpfattach(ifp, DLT_PFLOG, PFLOG_HDRLEN);
 
-	V_pflogifs[unit] = ifp;
+	V_pflogifs[ifd->unit] = ifp;
+	*ifpp = ifp;
 
 	return (0);
 }
 
-static void
-pflog_clone_destroy(struct ifnet *ifp)
+static int
+pflog_clone_destroy(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags)
 {
*** 26 LINES SKIPPED ***