Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 6 Apr 2002 16:44:32 -0800 (PST)
From:      Julian Elischer <julian@elischer.org>
To:        Brooks Davis <brooks@one-eyed-alien.net>
Cc:        net@freebsd.org
Subject:   Re: review request: minor cloning API change
Message-ID:  <Pine.BSF.4.21.0204061639400.43363-100000@InterJet.elischer.org>
In-Reply-To: <20020405230719.A13516@Odin.AC.HMC.Edu>

next in thread | previous in thread | raw e-mail | index | archive | help
Please excuse the comment if I'm way off the mark..

With a VERY BRIEF look I see that you are returning a void
from the destroy function and it is callled from the module unload code
where some destroy functions used to return ints.

this ia I think a BAD MOVE..

a driver must be able to veto it's own unloading.
If it is in use fro example. You leave no way for the driver to say
"Nope, I can't be unloaded now, I'm busy."

On Fri, 5 Apr 2002, Brooks Davis wrote:

> The following patch reverts a previous API change which change the
> return value of a clonable interfaces' destory function from void to
> int to allow the interface to refuse to delete a unit.  Since we now
> manage unit creation in the generic cloning code and the only use mux or
> I could thing of for refusing to delete a unit was forcing a certain
> number of units to exist, I've added a new member to the cloner struct,
> ifc_minifs which specifies the minimum number of units of this device
> allowed.  This changes the initilizer macro, but we already differ from
> NetBSD in that area and we get to revert to function signatures that
> match those from NetBSD in exchange.
> 
> This diff also includes code to convert the disc interface to be
> clonable and unloadable.  This will be commited seperatly.
> 
> -- Brooks
> 
> 
> Index: if.c
> ===================================================================
> RCS file: /usr/cvs/src/sys/net/if.c,v
> retrieving revision 1.137
> diff -u -p -r1.137 if.c
> --- if.c	4 Apr 2002 21:03:28 -0000	1.137
> +++ if.c	6 Apr 2002 06:38:02 -0000
> @@ -656,12 +656,15 @@ if_clone_destroy(name)
>  	struct if_clone *ifc;
>  	struct ifnet *ifp;
>  	int bytoff, bitoff;
> -	int err, unit;
> +	int unit;
>  
>  	ifc = if_clone_lookup(name, &unit);
>  	if (ifc == NULL)
>  		return (EINVAL);
>  
> +	if (unit < ifc->ifc_minifs)
> +		return (EINVAL);
> +
>  	ifp = ifunit(name);
>  	if (ifp == NULL)
>  		return (ENXIO);
> @@ -669,9 +672,7 @@ if_clone_destroy(name)
>  	if (ifc->ifc_destroy == NULL)
>  		return (EOPNOTSUPP);
>  
> -	err = (*ifc->ifc_destroy)(ifp);
> -	if (err != 0)
> -		return (err);
> +	(*ifc->ifc_destroy)(ifp);
>  
>  	/*
>  	 * Compute offset in the bitmap and deallocate the unit.
> @@ -734,8 +735,15 @@ void
>  if_clone_attach(ifc)
>  	struct if_clone *ifc;
>  {
> +	int bytoff, bitoff;
> +	int err;
>  	int len, maxclone;
> +	int unit;
>  
> +	KASSERT(ifc->ifc_minifs - 1 <= ifc->ifc_maxunit,
> +	    ("%s: %s requested more units then allowed (%d > %d)",
> +	    __func__, ifc->ifc_name, ifc->ifc_minifs,
> +	    ifc->ifc_maxunit + 1));
>  	/*
>  	 * Compute bitmap size and allocate it.
>  	 */
> @@ -745,8 +753,21 @@ if_clone_attach(ifc)
>  		len++;
>  	ifc->ifc_units = malloc(len, M_CLONE, M_WAITOK | M_ZERO);
>  	ifc->ifc_bmlen = len;
> +
>  	LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list);
>  	if_cloners_count++;
> +
> +	for (unit = 0; unit < ifc->ifc_minifs; unit++) {
> +		err = (*ifc->ifc_create)(ifc, unit);
> +		KASSERT(err == 0,
> +		    ("%s: failed to create required interface %s%d",
> +		    __func__, ifc->ifc_name, unit));
> +
> +		/* Allocate the unit in the bitmap. */
> +		bytoff = unit >> 3;
> +		bitoff = unit - (bytoff << 3);
> +		ifc->ifc_units[bytoff] |= (1 << bitoff);
> +	}
>  }
>  
>  /*
> Index: if.h
> ===================================================================
> RCS file: /usr/cvs/src/sys/net/if.h,v
> retrieving revision 1.71
> diff -u -p -r1.71 if.h
> --- if.h	19 Mar 2002 21:54:16 -0000	1.71
> +++ if.h	6 Apr 2002 05:41:12 -0000
> @@ -64,16 +64,17 @@ struct if_clone {
>  	LIST_ENTRY(if_clone) ifc_list;	/* on list of cloners */
>  	const char *ifc_name;		/* name of device, e.g. `gif' */
>  	size_t ifc_namelen;		/* length of name */
> +	int ifc_minifs;			/* minimum number of interfaces */
>  	int ifc_maxunit;		/* maximum unit number */
>  	unsigned char *ifc_units;	/* bitmap to handle units */
>  	int ifc_bmlen;			/* bitmap length */
>  
>  	int	(*ifc_create)(struct if_clone *, int);
> -	int	(*ifc_destroy)(struct ifnet *);
> +	void	(*ifc_destroy)(struct ifnet *);
>  };
>  
> -#define IF_CLONE_INITIALIZER(name, create, destroy, maxunit)		\
> -	{ { 0 }, name, sizeof(name) - 1, maxunit, NULL, 0, create, destroy }
> +#define IF_CLONE_INITIALIZER(name, create, destroy, minifs, maxunit)	\
> +    { { 0 }, name, sizeof(name) - 1, minifs, maxunit, NULL, 0, create, destroy }
>  
>  /*
>   * Structure used to query names of interface cloners.
> Index: if_disc.c
> ===================================================================
> RCS file: /usr/cvs/src/sys/net/if_disc.c,v
> retrieving revision 1.30
> diff -u -p -r1.30 if_disc.c
> --- if_disc.c	14 Dec 2001 19:27:33 -0000	1.30
> +++ if_disc.c	6 Apr 2002 06:51:56 -0000
> @@ -42,6 +42,7 @@
>  #include <sys/param.h>
>  #include <sys/systm.h>
>  #include <sys/kernel.h>
> +#include <sys/malloc.h>
>  #include <sys/module.h>
>  #include <sys/mbuf.h>
>  #include <sys/socket.h>
> @@ -61,20 +62,39 @@
>  #define DSMTU	65532
>  #endif
>  
> -static void discattach(void);
> +#define DISCNAME	"disc"
>  
> -static struct ifnet	discif;
> -static int		discoutput(struct ifnet *, struct mbuf *,
> -			    struct sockaddr *, struct rtentry *);
> -static void		discrtrequest(int, struct rtentry *, struct rt_addrinfo *);
> -static int		discioctl(struct ifnet *, u_long, caddr_t);
> +struct disc_softc {
> +	struct ifnet sc_if;	/* must be first */
> +	LIST_ENTRY(disc_softc) sc_list;
> +};
> +
> +static int	discoutput(struct ifnet *, struct mbuf *,
> +		    struct sockaddr *, struct rtentry *);
> +static void	discrtrequest(int, struct rtentry *, struct rt_addrinfo *);
> +static int	discioctl(struct ifnet *, u_long, caddr_t);
> +static int	disc_clone_create(struct if_clone *, int);
> +static void	disc_clone_destroy(struct ifnet *);
> +
> +static MALLOC_DEFINE(M_DISC, DISCNAME, "Discard interface");
> +static LIST_HEAD(, disc_softc) disc_softc_list;
> +static struct if_clone disc_cloner = IF_CLONE_INITIALIZER(DISCNAME,
> +    disc_clone_create, disc_clone_destroy, 0, IF_MAXUNIT);
>  
> -static void
> -discattach(void)
> +static int
> +disc_clone_create(struct if_clone *ifc, int unit)
>  {
> -	struct ifnet *ifp = &discif;
> +	struct ifnet		*ifp;
> +	struct disc_softc	*sc;
> +
> +	sc = malloc(sizeof(struct disc_softc), M_DISC, M_WAITOK);
> +	bzero(sc, sizeof(struct disc_softc));
> +
> +	ifp = &sc->sc_if;
>  
> -	ifp->if_name = "ds";
> +	ifp->if_softc = sc;
> +	ifp->if_name = DISCNAME;
> +	ifp->if_unit = unit;
>  	ifp->if_mtu = DSMTU;
>  	ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
>  	ifp->if_ioctl = discioctl;
> @@ -85,6 +105,23 @@ discattach(void)
>  	ifp->if_snd.ifq_maxlen = 20;
>  	if_attach(ifp);
>  	bpfattach(ifp, DLT_NULL, sizeof(u_int));
> +	LIST_INSERT_HEAD(&disc_softc_list, sc, sc_list);
> +
> +	return (0);
> +}
> +
> +static void
> +disc_clone_destroy(struct ifnet *ifp)
> +{
> +	struct disc_softc	*sc;
> +
> +	sc = ifp->if_softc;
> +
> +	LIST_REMOVE(sc, sc_list);
> +	bpfdetach(ifp);
> +	if_detach(ifp);
> +
> +	free(sc, M_DISC);
>  }
>  
>  static int
> @@ -92,11 +129,16 @@ disc_modevent(module_t mod, int type, vo
>  { 
>  	switch (type) { 
>  	case MOD_LOAD: 
> -		discattach();
> +		LIST_INIT(&disc_softc_list);
> +		if_clone_attach(&disc_cloner);
>  		break; 
>  	case MOD_UNLOAD: 
> -		printf("if_disc module unload - not possible for this module type\n"); 
> -		return EINVAL; 
> +		if_clone_detach(&disc_cloner);
> +
> +		while (!LIST_EMPTY(&disc_softc_list))
> +			disc_clone_destroy(
> +			    &LIST_FIRST(&disc_softc_list)->sc_if);
> +		break;
>  	} 
>  	return 0; 
>  } 
> @@ -123,7 +165,7 @@ discoutput(struct ifnet *ifp, struct mbu
>  		m->m_data += sizeof(int);
>  	}
>  
> -	if (discif.if_bpf) {
> +	if (ifp->if_bpf) {
>  		/*
>  		 * We need to prepend the address family as
>  		 * a four byte field.  Cons up a dummy header
> @@ -138,7 +180,7 @@ discoutput(struct ifnet *ifp, struct mbu
>  		m0.m_len = 4;
>  		m0.m_data = (char *)&af;
>  
> -		bpf_mtap(&discif, &m0);
> +		bpf_mtap(ifp, &m0);
>  	}
>  	m->m_pkthdr.rcvif = ifp;
>  
> Index: if_faith.c
> ===================================================================
> RCS file: /usr/cvs/src/sys/net/if_faith.c,v
> retrieving revision 1.14
> diff -u -p -r1.14 if_faith.c
> --- if_faith.c	19 Mar 2002 21:54:16 -0000	1.14
> +++ if_faith.c	6 Apr 2002 05:41:12 -0000
> @@ -103,10 +103,10 @@ static MALLOC_DEFINE(M_FAITH, FAITHNAME,
>  static LIST_HEAD(, faith_softc) faith_softc_list;
>  
>  int	faith_clone_create(struct if_clone *, int);
> -int	faith_clone_destroy(struct ifnet *);
> +void	faith_clone_destroy(struct ifnet *);
>  
>  struct if_clone faith_cloner = IF_CLONE_INITIALIZER(FAITHNAME,
> -    faith_clone_create, faith_clone_destroy, IF_MAXUNIT);
> +    faith_clone_create, faith_clone_destroy, 0, IF_MAXUNIT);
>  
>  #define	FAITHMTU	1500
>  
> @@ -181,7 +181,7 @@ faith_clone_create(ifc, unit)
>  	return (0);
>  }
>  
> -int
> +void
>  faith_clone_destroy(ifp)
>  	struct ifnet *ifp;
>  {
> @@ -192,7 +192,6 @@ faith_clone_destroy(ifp)
>  	if_detach(ifp);
>  
>  	free(sc, M_FAITH);
> -	return (0);
>  }
>  
>  int
> Index: if_gif.c
> ===================================================================
> RCS file: /usr/cvs/src/sys/net/if_gif.c,v
> retrieving revision 1.22
> diff -u -p -r1.22 if_gif.c
> --- if_gif.c	19 Mar 2002 21:54:18 -0000	1.22
> +++ if_gif.c	6 Apr 2002 05:41:12 -0000
> @@ -90,10 +90,10 @@ void	(*ng_gif_attach_p)(struct ifnet *if
>  void	(*ng_gif_detach_p)(struct ifnet *ifp);
>  
>  int	gif_clone_create(struct if_clone *, int);
> -int	gif_clone_destroy(struct ifnet *);
> +void	gif_clone_destroy(struct ifnet *);
>  
>  struct if_clone gif_cloner = IF_CLONE_INITIALIZER("gif",
> -    gif_clone_create, gif_clone_destroy, IF_MAXUNIT);
> +    gif_clone_create, gif_clone_destroy, 0, IF_MAXUNIT);
>  
>  static int gifmodevent(module_t, int, void *);
>  void gif_delete_tunnel(struct gif_softc *);
> @@ -207,7 +207,7 @@ gif_clone_create(ifc, unit)
>  	return (0);
>  }
>  
> -int
> +void
>  gif_clone_destroy(ifp)
>  	struct ifnet *ifp;
>  {
> @@ -231,7 +231,6 @@ gif_clone_destroy(ifp)
>  	if_detach(ifp);
>  
>  	free(sc, M_GIF);
> -	return (0);
>  }
>  
>  static int
> Index: if_loop.c
> ===================================================================
> RCS file: /usr/cvs/src/sys/net/if_loop.c,v
> retrieving revision 1.70
> diff -u -p -r1.70 if_loop.c
> --- if_loop.c	4 Apr 2002 06:03:17 -0000	1.70
> +++ if_loop.c	6 Apr 2002 05:54:06 -0000
> @@ -110,7 +110,7 @@ static void	lortrequest(int, struct rten
>  int		looutput(struct ifnet *ifp, struct mbuf *m,
>  		    struct sockaddr *dst, struct rtentry *rt);
>  int		lo_clone_create(struct if_clone *, int);
> -int		lo_clone_destroy(struct ifnet *);
> +void		lo_clone_destroy(struct ifnet *);
>  
>  struct ifnet *loif = NULL;			/* Used externally */
>  
> @@ -118,10 +118,10 @@ static MALLOC_DEFINE(M_LO, LONAME, "Loop
>  
>  static LIST_HEAD(lo_list, lo_softc) lo_list;
>  
> -struct if_clone lo_cloner =
> -    IF_CLONE_INITIALIZER(LONAME, lo_clone_create, lo_clone_destroy, IF_MAXUNIT);
> +struct if_clone lo_cloner = IF_CLONE_INITIALIZER(LONAME,
> +    lo_clone_create, lo_clone_destroy, 1, IF_MAXUNIT);
>  
> -int
> +void
>  lo_clone_destroy(ifp)
>  	struct ifnet *ifp;
>  {
> @@ -129,17 +129,13 @@ lo_clone_destroy(ifp)
>  	
>  	sc = ifp->if_softc;
>  
> -	/*
> -	 * Prevent lo0 from being destroyed.
> -	 */
> -	if (loif == ifp)
> -		return (EINVAL);
> +	/* XXX: destroying lo0 will lead to panics. */
> +	KASSERT(loif != ifp, ("%s: destroying lo0", __func__));
>  
>  	bpfdetach(ifp);
>  	if_detach(ifp);
>  	LIST_REMOVE(sc, sc_next);
>  	free(sc, M_LO);
> -	return (0);
>  }
>  
>  int
> @@ -172,16 +168,10 @@ lo_clone_create(ifc, unit)
>  static int
>  loop_modevent(module_t mod, int type, void *data) 
>  { 
> -	int err;
> -
>  	switch (type) { 
>  	case MOD_LOAD: 
>  		LIST_INIT(&lo_list);
>  		if_clone_attach(&lo_cloner);
> -
> -		/* Create lo0 */
> -		err = if_clone_create("lo0", sizeof ("lo0"));
> -		KASSERT(err == 0, ("%s: can't create lo0", __func__));
>  		break; 
>  	case MOD_UNLOAD: 
>  		printf("loop module unload - not possible for this module type\n"); 
> Index: if_stf.c
> ===================================================================
> RCS file: /usr/cvs/src/sys/net/if_stf.c,v
> retrieving revision 1.20
> diff -u -p -r1.20 if_stf.c
> --- if_stf.c	19 Mar 2002 21:54:18 -0000	1.20
> +++ if_stf.c	6 Apr 2002 05:41:13 -0000
> @@ -158,11 +158,11 @@ static void stf_rtrequest(int, struct rt
>  static int stf_ioctl(struct ifnet *, u_long, caddr_t);
>  
>  int	stf_clone_create(struct if_clone *, int);
> -int	stf_clone_destroy(struct ifnet *);
> +void	stf_clone_destroy(struct ifnet *);
>  
>  /* only one clone is currently allowed */
>  struct if_clone stf_cloner =
> -    IF_CLONE_INITIALIZER(STFNAME, stf_clone_create, stf_clone_destroy, 0);
> +    IF_CLONE_INITIALIZER(STFNAME, stf_clone_create, stf_clone_destroy, 0, 0);
>  
>  int
>  stf_clone_create(ifc, unit)
> @@ -194,7 +194,7 @@ stf_clone_create(ifc, unit)
>  	return (0);
>  }
>  
> -int
> +void
>  stf_clone_destroy(ifp)
>  	struct ifnet *ifp;
>  {
> @@ -208,7 +208,6 @@ stf_clone_destroy(ifp)
>  	if_detach(ifp);
>  
>  	free(sc, M_STF);
> -	return (0);
>  }
>  
>  static int
> Index: if_vlan.c
> ===================================================================
> RCS file: /usr/cvs/src/sys/net/if_vlan.c,v
> retrieving revision 1.40
> diff -u -p -r1.40 if_vlan.c
> --- if_vlan.c	4 Apr 2002 05:42:09 -0000	1.40
> +++ if_vlan.c	6 Apr 2002 05:41:13 -0000
> @@ -90,7 +90,7 @@ static MALLOC_DEFINE(M_VLAN, "vlan", "80
>  static LIST_HEAD(, ifvlan) ifv_list;
>  
>  static	int vlan_clone_create(struct if_clone *, int);
> -static	int vlan_clone_destroy(struct ifnet *);
> +static	void vlan_clone_destroy(struct ifnet *);
>  static	void vlan_start(struct ifnet *ifp);
>  static	void vlan_ifinit(void *foo);
>  static	int vlan_input(struct ether_header *eh, struct mbuf *m);
> @@ -102,7 +102,7 @@ static	int vlan_unconfig(struct ifnet *i
>  static	int vlan_config(struct ifvlan *ifv, struct ifnet *p);
>  
>  struct if_clone vlan_cloner = IF_CLONE_INITIALIZER("vlan",
> -    vlan_clone_create, vlan_clone_destroy, IF_MAXUNIT);
> +    vlan_clone_create, vlan_clone_destroy, 0, IF_MAXUNIT);
>  
>  /*
>   * Program our multicast filter. What we're actually doing is
> @@ -236,7 +236,7 @@ vlan_clone_create(struct if_clone *ifc, 
>  	return (0);
>  }
>  
> -static int
> +static void
>  vlan_clone_destroy(struct ifnet *ifp)
>  {
>  	struct ifvlan *ifv = ifp->if_softc;
> @@ -250,7 +250,6 @@ vlan_clone_destroy(struct ifnet *ifp)
>  	ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
>  
>  	free(ifv, M_VLAN);
> -	return (0);
>  }
>  
>  static void
> 
> -- 
> Any statement of the form "X is the one, true Y" is FALSE.
> PGP fingerprint 655D 519C 26A7 82E7 2529  9BF0 5D8E 8BE9 F238 1AD4
> 


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0204061639400.43363-100000>