Date: Fri, 29 Aug 2008 05:08:34 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 148776 for review Message-ID: <200808290508.m7T58YqC057056@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=148776 Change 148776 by sam@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); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200808290508.m7T58YqC057056>