summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2006-07-09 06:04:01 +0000
committersam <sam@FreeBSD.org>2006-07-09 06:04:01 +0000
commit2350e920372288f7ed8401d362497880b30dea50 (patch)
tree9d7fca708f49f055d33f7ea0b8387e3b17763e09
parentd4c884886f5a791f00d676a628a847df63fd2f4d (diff)
downloadFreeBSD-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@
-rw-r--r--sys/contrib/pf/net/if_pflog.c6
-rw-r--r--sys/contrib/pf/net/if_pfsync.c6
-rw-r--r--sys/net/if.c9
-rw-r--r--sys/net/if_bridge.c4
-rw-r--r--sys/net/if_clone.c17
-rw-r--r--sys/net/if_clone.h8
-rw-r--r--sys/net/if_disc.c4
-rw-r--r--sys/net/if_faith.c5
-rw-r--r--sys/net/if_gif.c5
-rw-r--r--sys/net/if_gre.c5
-rw-r--r--sys/net/if_loop.c5
-rw-r--r--sys/net/if_ppp.c6
-rw-r--r--sys/net/if_stf.c4
-rw-r--r--sys/net/if_vlan.c36
-rw-r--r--sys/netinet/ip_carp.c4
-rw-r--r--sys/sys/sockio.h1
16 files changed, 86 insertions, 39 deletions
diff --git a/sys/contrib/pf/net/if_pflog.c b/sys/contrib/pf/net/if_pflog.c
index 54f7129..6ddf212 100644
--- a/sys/contrib/pf/net/if_pflog.c
+++ b/sys/contrib/pf/net/if_pflog.c
@@ -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;
diff --git a/sys/contrib/pf/net/if_pfsync.c b/sys/contrib/pf/net/if_pfsync.c
index 1c0c6c3..957bc7e 100644
--- a/sys/contrib/pf/net/if_pfsync.c
+++ b/sys/contrib/pf/net/if_pfsync.c
@@ -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;
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,
&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;
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;
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index 1da5387..48c85e0 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -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;
diff --git a/sys/sys/sockio.h b/sys/sys/sockio.h
index e25aee2..18acd3f 100644
--- a/sys/sys/sockio.h
+++ b/sys/sys/sockio.h
@@ -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 */
OpenPOWER on IntegriCloud