Revise network interface cloning to take an optional opaque

parameter that can specify configuration parameters:
o rev cloner api's to add optional parameter block
o add SIOCCREATE2 that accepts parameter data
o rev vlan support to use new api (maintain old code)

Reviewed by:	arch@
This commit is contained in:
Sam Leffler 2006-07-09 06:04:01 +00:00
parent d830256f33
commit 6b7330e2d4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=160195
16 changed files with 86 additions and 39 deletions

View File

@ -121,7 +121,7 @@ struct pflog_softc pflogif[NPFLOG];
#ifdef __FreeBSD__
static void pflog_clone_destroy(struct ifnet *);
static int pflog_clone_create(struct if_clone *, int);
static int pflog_clone_create(struct if_clone *, int, caddr_t);
#else
void pflogattach(int);
#endif
@ -161,7 +161,11 @@ pflog_clone_destroy(struct ifnet *ifp)
}
static int
#ifdef __FreeBSD__
pflog_clone_create(struct if_clone *ifc, int unit, caddr_t params)
#else
pflog_clone_create(struct if_clone *ifc, int unit)
#endif
{
struct pflog_softc *sc;
struct ifnet *ifp;

View File

@ -148,7 +148,7 @@ SYSCTL_STRUCT(_net_inet_pfsync, 0, stats, CTLFLAG_RW,
*/
static void pfsync_clone_destroy(struct ifnet *);
static int pfsync_clone_create(struct if_clone *, int);
static int pfsync_clone_create(struct if_clone *, int, caddr_t params);
static void pfsync_senddef(void *);
#else
void pfsyncattach(int);
@ -205,7 +205,11 @@ pfsync_clone_destroy(struct ifnet *ifp)
}
static int
#ifdef __FreeBSD__
pfsync_clone_create(struct if_clone *ifc, int unit, caddr_t params)
#else
pfsync_clone_create(struct if_clone *ifc, int unit)
#endif
{
struct pfsync_softc *sc;
struct ifnet *ifp;

View File

@ -1748,12 +1748,15 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct thread *td)
switch (cmd) {
case SIOCIFCREATE:
case SIOCIFCREATE2:
if ((error = suser(td)) != 0)
return (error);
return (if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name),
cmd == SIOCIFCREATE2 ? ifr->ifr_data : NULL));
case SIOCIFDESTROY:
if ((error = suser(td)) != 0)
return (error);
return ((cmd == SIOCIFCREATE) ?
if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name)) :
if_clone_destroy(ifr->ifr_name));
return if_clone_destroy(ifr->ifr_name);
case SIOCIFGCLONERS:
return (if_clone_list((struct if_clonereq *)data));

View File

@ -186,7 +186,7 @@ int bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD;
uma_zone_t bridge_rtnode_zone;
static int bridge_clone_create(struct if_clone *, int);
static int bridge_clone_create(struct if_clone *, int, caddr_t);
static void bridge_clone_destroy(struct ifnet *);
static int bridge_ioctl(struct ifnet *, u_long, caddr_t);
@ -454,7 +454,7 @@ SYSCTL_PROC(_net_link_bridge, OID_AUTO, ipfw, CTLTYPE_INT|CTLFLAG_RW,
* Create a new bridge instance.
*/
static int
bridge_clone_create(struct if_clone *ifc, int unit)
bridge_clone_create(struct if_clone *ifc, int unit, caddr_t params)
{
struct bridge_softc *sc, *sc2;
struct ifnet *bifp, *ifp;

View File

@ -51,7 +51,8 @@
#include <net/route.h>
static void if_clone_free(struct if_clone *ifc);
static int if_clone_createif(struct if_clone *ifc, char *name, size_t len);
static int if_clone_createif(struct if_clone *ifc, char *name, size_t len,
caddr_t params);
static int if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp);
static struct mtx if_cloners_mtx;
@ -120,7 +121,7 @@ if_clone_init(void)
* Lookup and create a clone network interface.
*/
int
if_clone_create(char *name, size_t len)
if_clone_create(char *name, size_t len, caddr_t params)
{
struct if_clone *ifc;
@ -136,14 +137,14 @@ if_clone_create(char *name, size_t len)
if (ifc == NULL)
return (EINVAL);
return (if_clone_createif(ifc, name, len));
return (if_clone_createif(ifc, name, len, params));
}
/*
* Create a clone network interface.
*/
static int
if_clone_createif(struct if_clone *ifc, char *name, size_t len)
if_clone_createif(struct if_clone *ifc, char *name, size_t len, caddr_t params)
{
int err;
struct ifnet *ifp;
@ -151,7 +152,7 @@ if_clone_createif(struct if_clone *ifc, char *name, size_t len)
if (ifunit(name) != NULL)
return (EEXIST);
err = (*ifc->ifc_create)(ifc, name, len);
err = (*ifc->ifc_create)(ifc, name, len, params);
if (!err) {
ifp = ifunit(name);
@ -474,7 +475,7 @@ ifc_simple_attach(struct if_clone *ifc)
for (unit = 0; unit < ifcs->ifcs_minifs; unit++) {
snprintf(name, IFNAMSIZ, "%s%d", ifc->ifc_name, unit);
err = if_clone_createif(ifc, name, IFNAMSIZ);
err = if_clone_createif(ifc, name, IFNAMSIZ, NULL);
KASSERT(err == 0,
("%s: failed to create required interface %s",
__func__, name));
@ -503,7 +504,7 @@ ifc_simple_match(struct if_clone *ifc, const char *name)
}
int
ifc_simple_create(struct if_clone *ifc, char *name, size_t len)
ifc_simple_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
{
char *dp;
int wildcard;
@ -521,7 +522,7 @@ ifc_simple_create(struct if_clone *ifc, char *name, size_t len)
if (err != 0)
return (err);
err = ifcs->ifcs_create(ifc, unit);
err = ifcs->ifcs_create(ifc, unit, params);
if (err != 0) {
ifc_free_unit(ifc, unit);
return (err);

View File

@ -61,7 +61,7 @@ struct if_clone {
/* (c) Driver specific cloning functions. Called with no locks held. */
void (*ifc_attach)(struct if_clone *);
int (*ifc_match)(struct if_clone *, const char *);
int (*ifc_create)(struct if_clone *, char *, size_t);
int (*ifc_create)(struct if_clone *, char *, size_t, caddr_t);
int (*ifc_destroy)(struct if_clone *, struct ifnet *);
long ifc_refcnt; /* (i) Refrence count. */
@ -73,7 +73,7 @@ void if_clone_init(void);
void if_clone_attach(struct if_clone *);
void if_clone_detach(struct if_clone *);
int if_clone_create(char *, size_t);
int if_clone_create(char *, size_t, caddr_t);
int if_clone_destroy(const char *);
int if_clone_list(struct if_clonereq *);
@ -89,7 +89,7 @@ void ifc_free_unit(struct if_clone *, int);
struct ifc_simple_data {
int ifcs_minifs; /* minimum number of interfaces */
int (*ifcs_create)(struct if_clone *, int);
int (*ifcs_create)(struct if_clone *, int, caddr_t);
void (*ifcs_destroy)(struct ifnet *);
};
@ -106,7 +106,7 @@ struct if_clone name##_cloner = \
void ifc_simple_attach(struct if_clone *);
int ifc_simple_match(struct if_clone *, const char *);
int ifc_simple_create(struct if_clone *, char *, size_t);
int ifc_simple_create(struct if_clone *, char *, size_t, caddr_t);
int ifc_simple_destroy(struct if_clone *, struct ifnet *);
#endif /* _KERNEL */

View File

@ -69,7 +69,7 @@ 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 int disc_clone_create(struct if_clone *, int, caddr_t);
static void disc_clone_destroy(struct ifnet *);
static MALLOC_DEFINE(M_DISC, DISCNAME, "Discard interface");
@ -77,7 +77,7 @@ static MALLOC_DEFINE(M_DISC, DISCNAME, "Discard interface");
IFC_SIMPLE_DECLARE(disc, 0);
static int
disc_clone_create(struct if_clone *ifc, int unit)
disc_clone_create(struct if_clone *ifc, int unit, caddr_t params)
{
struct ifnet *ifp;
struct disc_softc *sc;

View File

@ -98,7 +98,7 @@ static int faithmodevent(module_t, int, void *);
static MALLOC_DEFINE(M_FAITH, FAITHNAME, "Firewall Assisted Tunnel Interface");
static int faith_clone_create(struct if_clone *, int);
static int faith_clone_create(struct if_clone *, int, caddr_t);
static void faith_clone_destroy(struct ifnet *);
IFC_SIMPLE_DECLARE(faith, 0);
@ -144,9 +144,10 @@ DECLARE_MODULE(if_faith, faith_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
MODULE_VERSION(if_faith, 1);
static int
faith_clone_create(ifc, unit)
faith_clone_create(ifc, unit, params)
struct if_clone *ifc;
int unit;
caddr_t params;
{
struct ifnet *ifp;
struct faith_softc *sc;

View File

@ -101,7 +101,7 @@ void (*ng_gif_attach_p)(struct ifnet *ifp);
void (*ng_gif_detach_p)(struct ifnet *ifp);
static void gif_start(struct ifnet *);
static int gif_clone_create(struct if_clone *, int);
static int gif_clone_create(struct if_clone *, int, caddr_t);
static void gif_clone_destroy(struct ifnet *);
IFC_SIMPLE_DECLARE(gif, 0);
@ -140,9 +140,10 @@ SYSCTL_INT(_net_link_gif, OID_AUTO, parallel_tunnels, CTLFLAG_RW,
&parallel_tunnels, 0, "Allow parallel tunnels?");
static int
gif_clone_create(ifc, unit)
gif_clone_create(ifc, unit, params)
struct if_clone *ifc;
int unit;
caddr_t params;
{
struct gif_softc *sc;

View File

@ -104,7 +104,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);
static int gre_clone_create(struct if_clone *, int, caddr_t);
static void gre_clone_destroy(struct ifnet *);
static int gre_ioctl(struct ifnet *, u_long, caddr_t);
static int gre_output(struct ifnet *, struct mbuf *, struct sockaddr *,
@ -171,9 +171,10 @@ greattach(void)
}
static int
gre_clone_create(ifc, unit)
gre_clone_create(ifc, unit, params)
struct if_clone *ifc;
int unit;
caddr_t params;
{
struct gre_softc *sc;

View File

@ -101,7 +101,7 @@ int loioctl(struct ifnet *, u_long, caddr_t);
static void lortrequest(int, struct rtentry *, struct rt_addrinfo *);
int looutput(struct ifnet *ifp, struct mbuf *m,
struct sockaddr *dst, struct rtentry *rt);
static int lo_clone_create(struct if_clone *, int);
static int lo_clone_create(struct if_clone *, int, caddr_t);
static void lo_clone_destroy(struct ifnet *);
struct ifnet *loif = NULL; /* Used externally */
@ -134,9 +134,10 @@ lo_clone_destroy(ifp)
}
static int
lo_clone_create(ifc, unit)
lo_clone_create(ifc, unit, params)
struct if_clone *ifc;
int unit;
caddr_t params;
{
struct ifnet *ifp;
struct lo_softc *sc;

View File

@ -157,7 +157,7 @@ static void ppp_ccp(struct ppp_softc *, struct mbuf *m, int rcvd);
static void ppp_ccp_closed(struct ppp_softc *);
static void ppp_inproc(struct ppp_softc *, struct mbuf *);
static void pppdumpm(struct mbuf *m0);
static int ppp_clone_create(struct if_clone *, int);
static int ppp_clone_create(struct if_clone *, int, caddr_t);
static void ppp_clone_destroy(struct ifnet *);
IFC_SIMPLE_DECLARE(ppp, 0);
@ -205,7 +205,7 @@ static struct compressor *ppp_compressors[8] = {
#endif /* PPP_COMPRESS */
static int
ppp_clone_create(struct if_clone *ifc, int unit)
ppp_clone_create(struct if_clone *ifc, int unit, caddr_t params)
{
struct ifnet *ifp;
struct ppp_softc *sc;
@ -328,7 +328,7 @@ pppalloc(pid)
/* Try to clone an interface if we don't have a free one */
if (sc == NULL) {
strcpy(tmpname, PPPNAME);
if (if_clone_create(tmpname, sizeof(tmpname)) != 0)
if (if_clone_create(tmpname, sizeof(tmpname), (caddr_t) 0) != 0)
return NULL;
ifp = ifunit(tmpname);
if (ifp == NULL)

View File

@ -177,7 +177,7 @@ static void stf_rtrequest(int, struct rtentry *, struct rt_addrinfo *);
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);
static int stf_clone_create(struct if_clone *, char *, size_t, caddr_t);
static int stf_clone_destroy(struct if_clone *, struct ifnet *);
struct if_clone stf_cloner = IFC_CLONE_INITIALIZER(STFNAME, NULL, 0,
NULL, stf_clone_match, stf_clone_create, stf_clone_destroy);
@ -196,7 +196,7 @@ stf_clone_match(struct if_clone *ifc, const char *name)
}
static int
stf_clone_create(struct if_clone *ifc, char *name, size_t len)
stf_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
{
int err, unit;
struct stf_softc *sc;

View File

@ -192,7 +192,7 @@ static void vlan_trunk_capabilities(struct ifnet *ifp);
static struct ifnet *vlan_clone_match_ethertag(struct if_clone *,
const char *, int *);
static int vlan_clone_match(struct if_clone *, const char *);
static int vlan_clone_create(struct if_clone *, char *, size_t);
static int vlan_clone_create(struct if_clone *, char *, size_t, caddr_t);
static int vlan_clone_destroy(struct if_clone *, struct ifnet *);
static void vlan_ifdetach(void *arg, struct ifnet *ifp);
@ -615,7 +615,7 @@ vlan_clone_match(struct if_clone *ifc, const char *name)
}
static int
vlan_clone_create(struct if_clone *ifc, char *name, size_t len)
vlan_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
{
char *dp;
int wildcard;
@ -626,9 +626,39 @@ vlan_clone_create(struct if_clone *ifc, char *name, size_t len)
struct ifvlan *ifv;
struct ifnet *ifp;
struct ifnet *p;
struct vlanreq vlr;
static const u_char eaddr[6]; /* 00:00:00:00:00:00 */
if ((p = vlan_clone_match_ethertag(ifc, name, &tag)) != NULL) {
/*
* There are 3 (ugh) ways to specify the cloned device:
* o pass a parameter block with the clone request.
* o specify parameters in the text of the clone device name
* o specify no parameters and get an unattached device that
* must be configured separately.
* The first technique is preferred; the latter two are
* supported for backwards compatibilty.
*/
if (params) {
error = copyin(params, &vlr, sizeof(vlr));
if (error)
return error;
p = ifunit(vlr.vlr_parent);
if (p == NULL)
return ENXIO;
/*
* Don't let the caller set up a VLAN tag with
* anything except VLID bits.
*/
if (vlr.vlr_tag & ~EVL_VLID_MASK)
return (EINVAL);
error = ifc_name2unit(name, &unit);
if (error != 0)
return (error);
ethertag = 1;
tag = vlr.vlr_tag;
wildcard = (unit < 0);
} else if ((p = vlan_clone_match_ethertag(ifc, name, &tag)) != NULL) {
ethertag = 1;
unit = -1;
wildcard = 0;

View File

@ -189,7 +189,7 @@ static int carp_hmac_verify(struct carp_softc *, u_int32_t *,
unsigned char *);
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);
static int carp_clone_create(struct if_clone *, int, caddr_t);
static void carp_clone_destroy(struct ifnet *);
static void carpdetach(struct carp_softc *);
static int carp_prepare_ad(struct mbuf *, struct carp_softc *,
@ -352,7 +352,7 @@ carp_setroute(struct carp_softc *sc, int cmd)
}
static int
carp_clone_create(struct if_clone *ifc, int unit)
carp_clone_create(struct if_clone *ifc, int unit, caddr_t params)
{
struct carp_softc *sc;

View File

@ -114,6 +114,7 @@
parameters */
#define SIOCIFCREATE _IOWR('i', 122, struct ifreq) /* create clone if */
#define SIOCIFCREATE2 _IOWR('i', 124, struct ifreq) /* create clone if */
#define SIOCIFDESTROY _IOW('i', 121, struct ifreq) /* destroy clone if */
#define SIOCIFGCLONERS _IOWR('i', 120, struct if_clonereq) /* get cloners */