PERFORCE change 148776 for review
Sam Leffler
sam at FreeBSD.org
Fri Aug 29 05:08:35 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=148776
Change 148776 by sam at sam_ebb on 2008/08/29 05:07:33
experimental mods to allow ifnet clone operations in-kernel;
ugly and likely not going to make the tree but keep for now
so I can do more work on the 802.11 crypto regression modules
Affected files ...
.. //depot/projects/vap/sys/net/if_bridge.c#7 edit
.. //depot/projects/vap/sys/net/if_clone.c#7 edit
.. //depot/projects/vap/sys/net/if_clone.h#6 edit
.. //depot/projects/vap/sys/net/if_disc.c#7 edit
.. //depot/projects/vap/sys/net/if_edsc.c#3 edit
.. //depot/projects/vap/sys/net/if_enc.c#6 edit
.. //depot/projects/vap/sys/net/if_faith.c#8 edit
.. //depot/projects/vap/sys/net/if_gif.c#9 edit
.. //depot/projects/vap/sys/net/if_gre.c#11 edit
.. //depot/projects/vap/sys/net/if_lagg.c#6 edit
.. //depot/projects/vap/sys/net/if_loop.c#13 edit
.. //depot/projects/vap/sys/net/if_ppp.c#7 edit
.. //depot/projects/vap/sys/net/if_stf.c#9 edit
.. //depot/projects/vap/sys/net/if_tap.c#8 edit
.. //depot/projects/vap/sys/net/if_tun.c#7 edit
.. //depot/projects/vap/sys/net/if_vlan.c#9 edit
.. //depot/projects/vap/sys/net80211/ieee80211_freebsd.c#33 edit
Differences ...
==== //depot/projects/vap/sys/net/if_bridge.c#7 (text+ko) ====
@@ -100,6 +100,7 @@
#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/uio.h>
#include <sys/vimage.h>
#include <net/bpf.h>
@@ -227,7 +228,7 @@
uma_zone_t bridge_rtnode_zone;
-static int bridge_clone_create(struct if_clone *, int, caddr_t);
+static int bridge_clone_create(struct if_clone *, int, enum uio_seg, caddr_t);
static void bridge_clone_destroy(struct ifnet *);
static int bridge_ioctl(struct ifnet *, u_long, caddr_t);
@@ -546,7 +547,7 @@
* 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, int unit, enum uio_seg as, caddr_t params)
{
struct bridge_softc *sc, *sc2;
struct ifnet *bifp, *ifp;
==== //depot/projects/vap/sys/net/if_clone.c#7 (text+ko) ====
@@ -39,6 +39,7 @@
#include <sys/systm.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/uio.h>
#include <net/if.h>
#include <net/if_clone.h>
@@ -52,7 +53,7 @@
static void if_clone_free(struct if_clone *ifc);
static int if_clone_createif(struct if_clone *ifc, char *name, size_t len,
- caddr_t params);
+ enum uio_seg as, caddr_t params);
static int if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp);
static struct mtx if_cloners_mtx;
@@ -117,11 +118,8 @@
IF_CLONERS_LOCK_INIT();
}
-/*
- * Lookup and create a clone network interface.
- */
-int
-if_clone_create(char *name, size_t len, caddr_t params)
+static int
+_if_clone_create(char *name, size_t len, enum uio_seg as, caddr_t params)
{
struct if_clone *ifc;
@@ -137,14 +135,35 @@
if (ifc == NULL)
return (EINVAL);
- return (if_clone_createif(ifc, name, len, params));
+ return (if_clone_createif(ifc, name, len, as, params));
+}
+
+/*
+ * Lookup and create a clone network interface;
+ * parameters come from user space.
+ */
+int
+if_clone_create(char *name, size_t len, caddr_t params)
+{
+ return _if_clone_create(name, len, UIO_USERSPACE, params);
+}
+
+/*
+ * Lookup and create a clone network interface;
+ * parameters come from kernel/system space.
+ */
+int
+if_clone_create_sys(char *name, size_t len, void *params)
+{
+ return _if_clone_create(name, len, UIO_SYSSPACE, params);
}
/*
* Create a clone network interface.
*/
static int
-if_clone_createif(struct if_clone *ifc, char *name, size_t len, caddr_t params)
+if_clone_createif(struct if_clone *ifc, char *name, size_t len,
+ enum uio_seg as, caddr_t params)
{
int err;
struct ifnet *ifp;
@@ -152,7 +171,7 @@
if (ifunit(name) != NULL)
return (EEXIST);
- err = (*ifc->ifc_create)(ifc, name, len, params);
+ err = (*ifc->ifc_create)(ifc, name, len, as, params);
if (!err) {
ifp = ifunit(name);
@@ -475,7 +494,8 @@
for (unit = 0; unit < ifcs->ifcs_minifs; unit++) {
snprintf(name, IFNAMSIZ, "%s%d", ifc->ifc_name, unit);
- err = if_clone_createif(ifc, name, IFNAMSIZ, NULL);
+ err = if_clone_createif(ifc, name, IFNAMSIZ,
+ UIO_USERSPACE, NULL);
KASSERT(err == 0,
("%s: failed to create required interface %s",
__func__, name));
@@ -504,7 +524,8 @@
}
int
-ifc_simple_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
+ifc_simple_create(struct if_clone *ifc, char *name, size_t len,
+ enum uio_seg as, caddr_t params)
{
char *dp;
int wildcard;
@@ -522,7 +543,7 @@
if (err != 0)
return (err);
- err = ifcs->ifcs_create(ifc, unit, params);
+ err = ifcs->ifcs_create(ifc, unit, as, params);
if (err != 0) {
ifc_free_unit(ifc, unit);
return (err);
==== //depot/projects/vap/sys/net/if_clone.h#6 (text+ko) ====
@@ -35,6 +35,8 @@
#ifdef _KERNEL
+enum uio_seg;
+
#define IFC_CLONE_INITIALIZER(name, data, maxunit, \
attach, match, create, destroy) \
{ { 0 }, name, maxunit, NULL, 0, data, attach, match, create, destroy }
@@ -61,7 +63,8 @@
/* (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, caddr_t);
+ int (*ifc_create)(struct if_clone *, char *, size_t,
+ enum uio_seg, caddr_t);
int (*ifc_destroy)(struct if_clone *, struct ifnet *);
long ifc_refcnt; /* (i) Refrence count. */
@@ -74,6 +77,7 @@
void if_clone_detach(struct if_clone *);
int if_clone_create(char *, size_t, caddr_t);
+int if_clone_create_sys(char *, size_t, void *);
int if_clone_destroy(const char *);
int if_clone_list(struct if_clonereq *);
@@ -89,7 +93,8 @@
struct ifc_simple_data {
int ifcs_minifs; /* minimum number of interfaces */
- int (*ifcs_create)(struct if_clone *, int, caddr_t);
+ int (*ifcs_create)(struct if_clone *, int,
+ enum uio_seg, caddr_t);
void (*ifcs_destroy)(struct ifnet *);
};
@@ -106,7 +111,8 @@
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, caddr_t);
+int ifc_simple_create(struct if_clone *, char *, size_t,
+ enum uio_seg, caddr_t);
int ifc_simple_destroy(struct if_clone *, struct ifnet *);
#endif /* _KERNEL */
==== //depot/projects/vap/sys/net/if_disc.c#7 (text+ko) ====
@@ -69,7 +69,7 @@
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, caddr_t);
+static int disc_clone_create(struct if_clone *, int, enum uio_seg, caddr_t);
static void disc_clone_destroy(struct ifnet *);
static MALLOC_DEFINE(M_DISC, DISCNAME, "Discard interface");
@@ -77,7 +77,7 @@
IFC_SIMPLE_DECLARE(disc, 0);
static int
-disc_clone_create(struct if_clone *ifc, int unit, caddr_t params)
+disc_clone_create(struct if_clone *ifc, int unit, enum uio_seg as, caddr_t params)
{
struct ifnet *ifp;
struct disc_softc *sc;
==== //depot/projects/vap/sys/net/if_edsc.c#3 (text+ko) ====
@@ -67,7 +67,7 @@
* Simple cloning methods.
* IFC_SIMPLE_DECLARE() expects precisely these names.
*/
-static int edsc_clone_create(struct if_clone *, int, caddr_t);
+static int edsc_clone_create(struct if_clone *, int, enum uio_seg, caddr_t);
static void edsc_clone_destroy(struct ifnet *);
/*
@@ -95,7 +95,7 @@
* Create an interface instance.
*/
static int
-edsc_clone_create(struct if_clone *ifc, int unit, caddr_t params)
+edsc_clone_create(struct if_clone *ifc, int unit, enum uio_seg as, caddr_t params)
{
struct edsc_softc *sc;
struct ifnet *ifp;
==== //depot/projects/vap/sys/net/if_enc.c#6 (text+ko) ====
@@ -86,7 +86,7 @@
static int enc_ioctl(struct ifnet *, u_long, caddr_t);
static int enc_output(struct ifnet *ifp, struct mbuf *m,
struct sockaddr *dst, struct rtentry *rt);
-static int enc_clone_create(struct if_clone *, int, caddr_t);
+static int enc_clone_create(struct if_clone *, int, enum uio_seg, caddr_t);
static void enc_clone_destroy(struct ifnet *);
IFC_SIMPLE_DECLARE(enc, 1);
@@ -128,7 +128,7 @@
}
static int
-enc_clone_create(struct if_clone *ifc, int unit, caddr_t params)
+enc_clone_create(struct if_clone *ifc, int unit, enum uio_seg as, caddr_t params)
{
struct ifnet *ifp;
struct enc_softc *sc;
==== //depot/projects/vap/sys/net/if_faith.c#8 (text+ko) ====
@@ -97,7 +97,7 @@
static MALLOC_DEFINE(M_FAITH, FAITHNAME, "Firewall Assisted Tunnel Interface");
-static int faith_clone_create(struct if_clone *, int, caddr_t);
+static int faith_clone_create(struct if_clone *, int, enum uio_seg, caddr_t);
static void faith_clone_destroy(struct ifnet *);
IFC_SIMPLE_DECLARE(faith, 0);
@@ -143,9 +143,10 @@
MODULE_VERSION(if_faith, 1);
static int
-faith_clone_create(ifc, unit, params)
+faith_clone_create(ifc, unit, as, params)
struct if_clone *ifc;
int unit;
+ enum uio_seg as;
caddr_t params;
{
struct ifnet *ifp;
==== //depot/projects/vap/sys/net/if_gif.c#9 (text+ko) ====
@@ -102,7 +102,7 @@
void (*ng_gif_detach_p)(struct ifnet *ifp);
static void gif_start(struct ifnet *);
-static int gif_clone_create(struct if_clone *, int, caddr_t);
+static int gif_clone_create(struct if_clone *, int, enum uio_seg, caddr_t);
static void gif_clone_destroy(struct ifnet *);
IFC_SIMPLE_DECLARE(gif, 0);
@@ -149,9 +149,10 @@
#endif
static int
-gif_clone_create(ifc, unit, params)
+gif_clone_create(ifc, unit, as, params)
struct if_clone *ifc;
int unit;
+ enum uio_seg as;
caddr_t params;
{
struct gif_softc *sc;
==== //depot/projects/vap/sys/net/if_gre.c#11 (text+ko) ====
@@ -105,7 +105,7 @@
struct gre_softc_head gre_softc_list;
-static int gre_clone_create(struct if_clone *, int, caddr_t);
+static int gre_clone_create(struct if_clone *, int, enum uio_seg, 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 *,
@@ -172,9 +172,10 @@
}
static int
-gre_clone_create(ifc, unit, params)
+gre_clone_create(ifc, unit, as, params)
struct if_clone *ifc;
int unit;
+ enum uio_seg as;
caddr_t params;
{
struct gre_softc *sc;
==== //depot/projects/vap/sys/net/if_lagg.c#6 (text+ko) ====
@@ -80,7 +80,7 @@
static struct mtx lagg_list_mtx;
eventhandler_tag lagg_detach_cookie = NULL;
-static int lagg_clone_create(struct if_clone *, int, caddr_t);
+static int lagg_clone_create(struct if_clone *, int, enum uio_seg, caddr_t);
static void lagg_clone_destroy(struct ifnet *);
static void lagg_lladdr(struct lagg_softc *, uint8_t *);
static void lagg_capabilities(struct lagg_softc *);
@@ -197,7 +197,7 @@
DECLARE_MODULE(if_lagg, lagg_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
static int
-lagg_clone_create(struct if_clone *ifc, int unit, caddr_t params)
+lagg_clone_create(struct if_clone *ifc, int unit, enum uio_seg as, caddr_t params)
{
struct lagg_softc *sc;
struct ifnet *ifp;
==== //depot/projects/vap/sys/net/if_loop.c#13 (text+ko) ====
@@ -49,6 +49,7 @@
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
+#include <sys/uio.h>
#include <sys/vimage.h>
#include <net/if.h>
@@ -93,7 +94,7 @@
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, caddr_t);
+static int lo_clone_create(struct if_clone *, int, enum uio_seg, caddr_t);
static void lo_clone_destroy(struct ifnet *);
struct ifnet *loif = NULL; /* Used externally */
@@ -113,7 +114,7 @@
}
static int
-lo_clone_create(struct if_clone *ifc, int unit, caddr_t params)
+lo_clone_create(struct if_clone *ifc, int unit, enum uio_seg as, caddr_t params)
{
struct ifnet *ifp;
==== //depot/projects/vap/sys/net/if_ppp.c#7 (text+ko) ====
@@ -160,7 +160,7 @@
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, caddr_t);
+static int ppp_clone_create(struct if_clone *, int, enum uio_seg, caddr_t);
static void ppp_clone_destroy(struct ifnet *);
IFC_SIMPLE_DECLARE(ppp, 0);
@@ -208,7 +208,7 @@
#endif /* PPP_COMPRESS */
static int
-ppp_clone_create(struct if_clone *ifc, int unit, caddr_t params)
+ppp_clone_create(struct if_clone *ifc, int unit, enum uio_seg as, caddr_t params)
{
struct ifnet *ifp;
struct ppp_softc *sc;
==== //depot/projects/vap/sys/net/if_stf.c#9 (text+ko) ====
@@ -179,7 +179,7 @@
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_create(struct if_clone *, char *, size_t, enum uio_seg, 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);
@@ -198,7 +198,7 @@
}
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, enum uio_seg as, caddr_t params)
{
int err, unit;
struct stf_softc *sc;
==== //depot/projects/vap/sys/net/if_tap.c#8 (text+ko) ====
@@ -94,9 +94,9 @@
static int tapifioctl(struct ifnet *, u_long, caddr_t);
static void tapifinit(void *);
-static int tap_clone_create(struct if_clone *, int, caddr_t);
+static int tap_clone_create(struct if_clone *, int, enum uio_seg, caddr_t);
static void tap_clone_destroy(struct ifnet *);
-static int vmnet_clone_create(struct if_clone *, int, caddr_t);
+static int vmnet_clone_create(struct if_clone *, int, enum uio_seg, caddr_t);
static void vmnet_clone_destroy(struct ifnet *);
IFC_SIMPLE_DECLARE(tap, 0);
@@ -176,7 +176,7 @@
DEV_MODULE(if_tap, tapmodevent, NULL);
static int
-tap_clone_create(struct if_clone *ifc, int unit, caddr_t params)
+tap_clone_create(struct if_clone *ifc, int unit, enum uio_seg as, caddr_t params)
{
struct cdev *dev;
int i;
@@ -204,9 +204,9 @@
/* vmnet devices are tap devices in disguise */
static int
-vmnet_clone_create(struct if_clone *ifc, int unit, caddr_t params)
+vmnet_clone_create(struct if_clone *ifc, int unit, enum uio_seg as, caddr_t params)
{
- return tap_clone_create(ifc, unit, params);
+ return tap_clone_create(ifc, unit, as, params);
}
static void
==== //depot/projects/vap/sys/net/if_tun.c#7 (text+ko) ====
@@ -129,7 +129,7 @@
struct rtentry *rt);
static void tunstart(struct ifnet *);
-static int tun_clone_create(struct if_clone *, int, caddr_t);
+static int tun_clone_create(struct if_clone *, int, enum uio_seg, caddr_t);
static void tun_clone_destroy(struct ifnet *);
IFC_SIMPLE_DECLARE(tun, 0);
@@ -174,7 +174,7 @@
};
static int
-tun_clone_create(struct if_clone *ifc, int unit, caddr_t params)
+tun_clone_create(struct if_clone *ifc, int unit, enum uio_seg as, caddr_t params)
{
struct cdev *dev;
int i;
==== //depot/projects/vap/sys/net/if_vlan.c#9 (text+ko) ====
@@ -195,7 +195,7 @@
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, caddr_t);
+static int vlan_clone_create(struct if_clone *, char *, size_t, enum uio_seg, caddr_t);
static int vlan_clone_destroy(struct if_clone *, struct ifnet *);
static void vlan_ifdetach(void *arg, struct ifnet *ifp);
@@ -620,7 +620,7 @@
}
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, enum uio_seg as, caddr_t params)
{
char *dp;
int wildcard;
@@ -631,7 +631,6 @@
struct ifvlan *ifv;
struct ifnet *ifp;
struct ifnet *p;
- struct vlanreq vlr;
static const u_char eaddr[ETHER_ADDR_LEN]; /* 00:00:00:00:00:00 */
/*
@@ -644,24 +643,30 @@
* supported for backwards compatibilty.
*/
if (params) {
- error = copyin(params, &vlr, sizeof(vlr));
- if (error)
- return error;
- p = ifunit(vlr.vlr_parent);
+ struct vlanreq vlr, *vlrp;
+
+ if (as == UIO_USERSPACE) {
+ error = copyin(params, &vlr, sizeof(vlr));
+ if (error)
+ return error;
+ vlrp = &vlr;
+ } else
+ vlrp = (struct vlanreq *) params;
+ p = ifunit(vlrp->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)
+ if (vlrp->vlr_tag & ~EVL_VLID_MASK)
return (EINVAL);
error = ifc_name2unit(name, &unit);
if (error != 0)
return (error);
ethertag = 1;
- tag = vlr.vlr_tag;
+ tag = vlrp->vlr_tag;
wildcard = (unit < 0);
} else if ((p = vlan_clone_match_ethertag(ifc, name, &tag)) != NULL) {
ethertag = 1;
==== //depot/projects/vap/sys/net80211/ieee80211_freebsd.c#33 (text+ko) ====
@@ -39,6 +39,7 @@
#include <sys/module.h>
#include <sys/proc.h>
#include <sys/sysctl.h>
+#include <sys/uio.h>
#include <sys/socket.h>
@@ -94,18 +95,25 @@
}
static int
-wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
+wlan_clone_create(struct if_clone *ifc, int unit, enum uio_seg as, caddr_t params)
{
- struct ieee80211_clone_params cp;
+ struct ieee80211_clone_params cp, *icp;
struct ieee80211vap *vap;
struct ieee80211com *ic;
struct ifnet *ifp;
int error;
- error = copyin(params, &cp, sizeof(cp));
- if (error)
- return error;
- ifp = ifunit(cp.icp_parent);
+ if (as == UIO_USERSPACE) {
+ error = copyin(params, &cp, sizeof(cp));
+ if (error)
+ return error;
+ icp = &cp;
+ } else {
+ if (params == NULL)
+ return EFAULT;
+ icp = (struct ieee80211_clone_params *) params;
+ }
+ ifp = ifunit(icp->icp_parent);
if (ifp == NULL)
return ENXIO;
/* XXX move printfs to DIAGNOSTIC before release */
@@ -113,21 +121,21 @@
if_printf(ifp, "%s: reject, not an 802.11 device\n", __func__);
return ENXIO;
}
- if (cp.icp_opmode >= IEEE80211_OPMODE_MAX) {
+ if (icp->icp_opmode >= IEEE80211_OPMODE_MAX) {
if_printf(ifp, "%s: invalid opmode %d\n",
- __func__, cp.icp_opmode);
+ __func__, icp->icp_opmode);
return EINVAL;
}
ic = ifp->if_l2com;
- if ((ic->ic_caps & ieee80211_opcap[cp.icp_opmode]) == 0) {
+ if ((ic->ic_caps & ieee80211_opcap[icp->icp_opmode]) == 0) {
if_printf(ifp, "%s mode not supported\n",
- ieee80211_opmode_name[cp.icp_opmode]);
+ ieee80211_opmode_name[icp->icp_opmode]);
return EOPNOTSUPP;
}
vap = ic->ic_vap_create(ic, ifc->ifc_name, unit,
- cp.icp_opmode, cp.icp_flags, cp.icp_bssid,
- cp.icp_flags & IEEE80211_CLONE_MACADDR ?
- cp.icp_macaddr : ic->ic_myaddr);
+ icp->icp_opmode, icp->icp_flags, icp->icp_bssid,
+ icp->icp_flags & IEEE80211_CLONE_MACADDR ?
+ icp->icp_macaddr : ic->ic_myaddr);
return (vap == NULL ? EIO : 0);
}
More information about the p4-projects
mailing list