diff options
author | sam <sam@FreeBSD.org> | 2006-07-09 06:04:01 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2006-07-09 06:04:01 +0000 |
commit | 2350e920372288f7ed8401d362497880b30dea50 (patch) | |
tree | 9d7fca708f49f055d33f7ea0b8387e3b17763e09 /sys/net | |
parent | d4c884886f5a791f00d676a628a847df63fd2f4d (diff) | |
download | FreeBSD-src-2350e920372288f7ed8401d362497880b30dea50.zip FreeBSD-src-2350e920372288f7ed8401d362497880b30dea50.tar.gz |
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@
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if.c | 9 | ||||
-rw-r--r-- | sys/net/if_bridge.c | 4 | ||||
-rw-r--r-- | sys/net/if_clone.c | 17 | ||||
-rw-r--r-- | sys/net/if_clone.h | 8 | ||||
-rw-r--r-- | sys/net/if_disc.c | 4 | ||||
-rw-r--r-- | sys/net/if_faith.c | 5 | ||||
-rw-r--r-- | sys/net/if_gif.c | 5 | ||||
-rw-r--r-- | sys/net/if_gre.c | 5 | ||||
-rw-r--r-- | sys/net/if_loop.c | 5 | ||||
-rw-r--r-- | sys/net/if_ppp.c | 6 | ||||
-rw-r--r-- | sys/net/if_stf.c | 4 | ||||
-rw-r--r-- | sys/net/if_vlan.c | 36 |
12 files changed, 73 insertions, 35 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index d540c95..33e26cd 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -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)); diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 3f0b171..097df3c 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -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; diff --git a/sys/net/if_clone.c b/sys/net/if_clone.c index aa2c21a..cc52126 100644 --- a/sys/net/if_clone.c +++ b/sys/net/if_clone.c @@ -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); diff --git a/sys/net/if_clone.h b/sys/net/if_clone.h index 38a0959..af3395f 100644 --- a/sys/net/if_clone.h +++ b/sys/net/if_clone.h @@ -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 */ diff --git a/sys/net/if_disc.c b/sys/net/if_disc.c index 8fd6d9d..aa76d70 100644 --- a/sys/net/if_disc.c +++ b/sys/net/if_disc.c @@ -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; diff --git a/sys/net/if_faith.c b/sys/net/if_faith.c index 6e3f446..8c00e4d 100644 --- a/sys/net/if_faith.c +++ b/sys/net/if_faith.c @@ -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; diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c index 0bb7894..2a640a6 100644 --- a/sys/net/if_gif.c +++ b/sys/net/if_gif.c @@ -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, ¶llel_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; diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c index 6cf80ea..aaac47d 100644 --- a/sys/net/if_gre.c +++ b/sys/net/if_gre.c @@ -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; diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c index 1b1ca0b..e48a270 100644 --- a/sys/net/if_loop.c +++ b/sys/net/if_loop.c @@ -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; diff --git a/sys/net/if_ppp.c b/sys/net/if_ppp.c index caea596..5a187c7 100644 --- a/sys/net/if_ppp.c +++ b/sys/net/if_ppp.c @@ -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) diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c index 594b648..2c0eca9 100644 --- a/sys/net/if_stf.c +++ b/sys/net/if_stf.c @@ -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; diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c index 0ad90ca..34ef7ee 100644 --- a/sys/net/if_vlan.c +++ b/sys/net/if_vlan.c @@ -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; |