diff options
Diffstat (limited to 'sys/altq/altq_conf.c')
-rw-r--r-- | sys/altq/altq_conf.c | 424 |
1 files changed, 424 insertions, 0 deletions
diff --git a/sys/altq/altq_conf.c b/sys/altq/altq_conf.c new file mode 100644 index 00000000000..4baac8d2634 --- /dev/null +++ b/sys/altq/altq_conf.c @@ -0,0 +1,424 @@ +/* $OpenBSD: altq_conf.c,v 1.1 2001/06/27 05:28:35 kjc Exp $ */ +/* $KAME: altq_conf.c,v 1.11 2001/06/21 11:00:36 kjc Exp $ */ + +/* + * Copyright (C) 1997-2000 + * Sony Computer Science Laboratories Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(__FreeBSD__) || defined(__NetBSD__) +#include "opt_altq.h" +#if (__FreeBSD__ != 2) +#include "opt_inet.h" +#ifdef __FreeBSD__ +#include "opt_inet6.h" +#endif +#endif +#endif /* __FreeBSD__ || __NetBSD__ */ + +/* + * altq device interface. + */ +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/socket.h> +#include <sys/kernel.h> +#include <sys/proc.h> +#include <sys/errno.h> +#if defined(__FreeBSD__) && (__FreeBSD_version < 400000) && defined(DEVFS) +#include <sys/devfsext.h> +#endif /*DEVFS*/ +#include <net/if.h> + +#include <altq/altq.h> +#include <altq/altq_conf.h> + +#ifdef ALTQ_CBQ +altqdev_decl(cbq); +#endif +#ifdef ALTQ_WFQ +altqdev_decl(wfq); +#endif +#ifdef ALTQ_AFMAP +altqdev_decl(afm); +#endif +#ifdef ALTQ_FIFOQ +altqdev_decl(fifoq); +#endif +#ifdef ALTQ_RED +altqdev_decl(red); +#endif +#ifdef ALTQ_RIO +altqdev_decl(rio); +#endif +#ifdef ALTQ_LOCALQ +altqdev_decl(localq); +#endif +#ifdef ALTQ_HFSC +altqdev_decl(hfsc); +#endif +#ifdef ALTQ_CDNR +altqdev_decl(cdnr); +#endif +#ifdef ALTQ_BLUE +altqdev_decl(blue); +#endif +#ifdef ALTQ_PRIQ +altqdev_decl(priq); +#endif + +/* + * altq minor device (discipline) table + */ +static struct altqsw altqsw[] = { /* minor */ + {"noq", noopen, noclose, noioctl}, /* 0 (reserved) */ +#ifdef ALTQ_CBQ + {"cbq", cbqopen, cbqclose, cbqioctl}, /* 1 */ +#else + {"noq", noopen, noclose, noioctl}, /* 1 */ +#endif +#ifdef ALTQ_WFQ + {"wfq", wfqopen, wfqclose, wfqioctl}, /* 2 */ +#else + {"noq", noopen, noclose, noioctl}, /* 2 */ +#endif +#ifdef ALTQ_AFMAP + {"afm", afmopen, afmclose, afmioctl}, /* 3 */ +#else + {"noq", noopen, noclose, noioctl}, /* 3 */ +#endif +#ifdef ALTQ_FIFOQ + {"fifoq", fifoqopen, fifoqclose, fifoqioctl}, /* 4 */ +#else + {"noq", noopen, noclose, noioctl}, /* 4 */ +#endif +#ifdef ALTQ_RED + {"red", redopen, redclose, redioctl}, /* 5 */ +#else + {"noq", noopen, noclose, noioctl}, /* 5 */ +#endif +#ifdef ALTQ_RIO + {"rio", rioopen, rioclose, rioioctl}, /* 6 */ +#else + {"noq", noopen, noclose, noioctl}, /* 6 */ +#endif +#ifdef ALTQ_LOCALQ + {"localq",localqopen, localqclose, localqioctl}, /* 7 (local use) */ +#else + {"noq", noopen, noclose, noioctl}, /* 7 (local use) */ +#endif +#ifdef ALTQ_HFSC + {"hfsc",hfscopen, hfscclose, hfscioctl}, /* 8 */ +#else + {"noq", noopen, noclose, noioctl}, /* 8 */ +#endif +#ifdef ALTQ_CDNR + {"cdnr",cdnropen, cdnrclose, cdnrioctl}, /* 9 */ +#else + {"noq", noopen, noclose, noioctl}, /* 9 */ +#endif +#ifdef ALTQ_BLUE + {"blue",blueopen, blueclose, blueioctl}, /* 10 */ +#else + {"noq", noopen, noclose, noioctl}, /* 10 */ +#endif +#ifdef ALTQ_PRIQ + {"priq",priqopen, priqclose, priqioctl}, /* 11 */ +#else + {"noq", noopen, noclose, noioctl}, /* 11 */ +#endif +}; + +/* + * altq major device support + */ +int naltqsw = sizeof (altqsw) / sizeof (altqsw[0]); + +#ifdef __FreeBSD__ +static d_open_t altqopen; +static d_close_t altqclose; +static d_ioctl_t altqioctl; +static void altq_drvinit __P((void *)); +#else +void altqattach __P((int)); +#endif + +#if defined(__FreeBSD__) +#define CDEV_MAJOR 96 /* FreeBSD official number */ + +#if (__FreeBSD_version < 400000) +static struct cdevsw altq_cdevsw = + { altqopen, altqclose, noread, nowrite, + altqioctl, nostop, nullreset, nodevtotty, + seltrue, nommap, NULL, "altq", NULL, -1 }; +#else +static struct cdevsw altq_cdevsw = + { altqopen, altqclose, noread, nowrite, + altqioctl, seltrue, nommap, nostrategy, + "altq", CDEV_MAJOR, nodump, nopsize, 0, -1 }; +#endif +#endif /* FreeBSD */ + +#ifdef __FreeBSD__ +static +#endif +int +altqopen(dev, flag, fmt, p) + dev_t dev; + int flag, fmt; + struct proc *p; +{ + int unit = minor(dev); + + if (unit == 0) + return (0); + if (unit < naltqsw) + return (*altqsw[unit].d_open)(dev, flag, fmt, p); + + return ENXIO; +} + +#ifdef __FreeBSD__ +static +#endif +int +altqclose(dev, flag, fmt, p) + dev_t dev; + int flag, fmt; + struct proc *p; +{ + int unit = minor(dev); + + if (unit == 0) + return (0); + if (unit < naltqsw) + return (*altqsw[unit].d_close)(dev, flag, fmt, p); + + return ENXIO; +} + +#ifdef __FreeBSD__ +static +#endif +int +altqioctl(dev, cmd, addr, flag, p) + dev_t dev; + ioctlcmd_t cmd; + caddr_t addr; + int flag; + struct proc *p; +{ + int unit = minor(dev); + + if (unit == 0) { + struct ifnet *ifp; + struct altqreq *typereq; + struct tbrreq *tbrreq; + int error; + + switch (cmd) { + case ALTQGTYPE: + case ALTQTBRGET: + break; + default: +#if (__FreeBSD_version > 400000) + if ((error = suser(p)) != 0) + return (error); +#else + if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) + return (error); +#endif + break; + } + + switch (cmd) { + case ALTQGTYPE: + typereq = (struct altqreq *)addr; + if ((ifp = ifunit(typereq->ifname)) == NULL) + return (EINVAL); + typereq->arg = (u_long)ifp->if_snd.altq_type; + return (0); + case ALTQTBRSET: + tbrreq = (struct tbrreq *)addr; + if ((ifp = ifunit(tbrreq->ifname)) == NULL) + return (EINVAL); + return tbr_set(&ifp->if_snd, &tbrreq->tb_prof); + case ALTQTBRGET: + tbrreq = (struct tbrreq *)addr; + if ((ifp = ifunit(tbrreq->ifname)) == NULL) + return (EINVAL); + return tbr_get(&ifp->if_snd, &tbrreq->tb_prof); + default: + return (EINVAL); + } + } + if (unit < naltqsw) + return (*altqsw[unit].d_ioctl)(dev, cmd, addr, flag, p); + + return ENXIO; +} + +#ifdef __FreeBSD__ + +static int altq_devsw_installed = 0; + +#if (__FreeBSD_version < 400000) +#ifdef DEVFS +static void *altq_devfs_token[sizeof (altqsw) / sizeof (altqsw[0])]; +#endif + +static void +altq_drvinit(unused) + void *unused; +{ + dev_t dev; +#ifdef DEVFS + int i; +#endif + + if (!altq_devsw_installed) { + dev = makedev(CDEV_MAJOR,0); + cdevsw_add(&dev,&altq_cdevsw,NULL); + altq_devsw_installed = 1; +#ifdef DEVFS + for (i=0; i<naltqsw; i++) + altq_devfs_token[i] = + devfs_add_devswf(&altq_cdevsw, i, DV_CHR, + 0, 0, 0644, altqsw[i].d_name); +#endif + printf("altq: major number is %d\n", CDEV_MAJOR); + } +} + +#else /* FreeBSD 4.x */ + +static void +altq_drvinit(unused) + void *unused; +{ + int unit; + + cdevsw_add(&altq_cdevsw); + altq_devsw_installed = 1; + printf("altq: major number is %d\n", CDEV_MAJOR); + + /* create minor devices */ + for (unit = 0; unit < naltqsw; unit++) + make_dev(&altq_cdevsw, unit, 0, 0, 0644, + altqsw[unit].d_name); +} + +#endif /* FreeBSD 4.x */ + +SYSINIT(altqdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,altq_drvinit,NULL) + +#endif /* FreeBSD */ + +#ifdef ALTQ_KLD +/* + * KLD support + */ +static int altq_module_register __P((struct altq_module_data *)); +static int altq_module_deregister __P((struct altq_module_data *)); + +static struct altq_module_data *altq_modules[ALTQT_MAX]; +static struct altqsw noqdisc = {"noq", noopen, noclose, noioctl}; + +void altq_module_incref(type) + int type; +{ + if (type < 0 || type >= ALTQT_MAX || altq_modules[type] == NULL) + return; + + altq_modules[type]->ref++; +} + +void altq_module_declref(type) + int type; +{ + if (type < 0 || type >= ALTQT_MAX || altq_modules[type] == NULL) + return; + + altq_modules[type]->ref--; +} + +static int +altq_module_register(mdata) + struct altq_module_data *mdata; +{ + int type = mdata->type; + + if (type < 0 || type >= ALTQT_MAX) + return (EINVAL); + if (altqsw[type].d_open != noopen) + return (EBUSY); + altqsw[type] = *mdata->altqsw; /* set discipline functions */ + altq_modules[type] = mdata; /* save module data pointer */ + return (0); +} + +static int +altq_module_deregister(mdata) + struct altq_module_data *mdata; +{ + int type = mdata->type; + + if (type < 0 || type >= ALTQT_MAX) + return (EINVAL); + if (mdata != altq_modules[type]) + return (EINVAL); + if (altq_modules[type]->ref > 0) + return (EBUSY); + altqsw[type] = noqdisc; + altq_modules[type] = NULL; + return (0); +} + +int +altq_module_handler(mod, cmd, arg) + module_t mod; + int cmd; + void * arg; +{ + struct altq_module_data *data = (struct altq_module_data *)arg; + int error = 0; + + switch (cmd) { + case MOD_LOAD: + error = altq_module_register(data); + break; + + case MOD_UNLOAD: + error = altq_module_deregister(data); + break; + + default: + error = EINVAL; + break; + } + + return(error); +} + +#endif /* ALTQ_KLD */ |