Home | History | Annotate | Line # | Download | only in altq
altq_conf.c revision 1.12.12.3
      1  1.12.12.3     peter /*	$NetBSD: altq_conf.c,v 1.12.12.3 2006/09/25 03:56:59 peter Exp $	*/
      2  1.12.12.1     peter /*	$KAME: altq_conf.c,v 1.24 2005/04/13 03:44:24 suz Exp $	*/
      3        1.1   thorpej 
      4        1.1   thorpej /*
      5  1.12.12.1     peter  * Copyright (C) 1997-2003
      6        1.1   thorpej  *	Sony Computer Science Laboratories Inc.  All rights reserved.
      7        1.1   thorpej  *
      8        1.1   thorpej  * Redistribution and use in source and binary forms, with or without
      9        1.1   thorpej  * modification, are permitted provided that the following conditions
     10        1.1   thorpej  * are met:
     11        1.1   thorpej  * 1. Redistributions of source code must retain the above copyright
     12        1.1   thorpej  *    notice, this list of conditions and the following disclaimer.
     13        1.1   thorpej  * 2. Redistributions in binary form must reproduce the above copyright
     14        1.1   thorpej  *    notice, this list of conditions and the following disclaimer in the
     15        1.1   thorpej  *    documentation and/or other materials provided with the distribution.
     16        1.1   thorpej  *
     17        1.1   thorpej  * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND
     18        1.1   thorpej  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19        1.1   thorpej  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20        1.1   thorpej  * ARE DISCLAIMED.  IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE
     21        1.1   thorpej  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     22        1.1   thorpej  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     23        1.1   thorpej  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     24        1.1   thorpej  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     25        1.1   thorpej  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     26        1.1   thorpej  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     27        1.1   thorpej  * SUCH DAMAGE.
     28        1.1   thorpej  */
     29        1.5     lukem 
     30        1.5     lukem #include <sys/cdefs.h>
     31  1.12.12.3     peter __KERNEL_RCSID(0, "$NetBSD: altq_conf.c,v 1.12.12.3 2006/09/25 03:56:59 peter Exp $");
     32        1.1   thorpej 
     33  1.12.12.1     peter #ifdef _KERNEL_OPT
     34        1.1   thorpej #include "opt_altq.h"
     35        1.1   thorpej #include "opt_inet.h"
     36        1.1   thorpej #endif
     37        1.1   thorpej 
     38        1.1   thorpej /*
     39        1.1   thorpej  * altq device interface.
     40        1.1   thorpej  */
     41        1.1   thorpej #include <sys/param.h>
     42        1.1   thorpej #include <sys/systm.h>
     43        1.1   thorpej #include <sys/socket.h>
     44        1.1   thorpej #include <sys/kernel.h>
     45        1.1   thorpej #include <sys/proc.h>
     46        1.1   thorpej #include <sys/errno.h>
     47  1.12.12.2     peter #include <sys/kauth.h>
     48  1.12.12.2     peter 
     49        1.1   thorpej #include <net/if.h>
     50        1.1   thorpej 
     51        1.1   thorpej #include <altq/altq.h>
     52        1.9  jdolecek #include <altq/altqconf.h>
     53        1.1   thorpej #include <altq/altq_conf.h>
     54        1.1   thorpej 
     55  1.12.12.1     peter #ifdef ALTQ3_COMPAT
     56  1.12.12.1     peter 
     57        1.1   thorpej #ifdef ALTQ_CBQ
     58        1.1   thorpej altqdev_decl(cbq);
     59        1.1   thorpej #endif
     60        1.1   thorpej #ifdef ALTQ_WFQ
     61        1.1   thorpej altqdev_decl(wfq);
     62        1.1   thorpej #endif
     63        1.1   thorpej #ifdef ALTQ_AFMAP
     64        1.1   thorpej altqdev_decl(afm);
     65        1.1   thorpej #endif
     66        1.1   thorpej #ifdef ALTQ_FIFOQ
     67        1.1   thorpej altqdev_decl(fifoq);
     68        1.1   thorpej #endif
     69        1.1   thorpej #ifdef ALTQ_RED
     70        1.1   thorpej altqdev_decl(red);
     71        1.1   thorpej #endif
     72        1.1   thorpej #ifdef ALTQ_RIO
     73        1.1   thorpej altqdev_decl(rio);
     74        1.1   thorpej #endif
     75        1.1   thorpej #ifdef ALTQ_LOCALQ
     76        1.1   thorpej altqdev_decl(localq);
     77        1.1   thorpej #endif
     78        1.1   thorpej #ifdef ALTQ_HFSC
     79        1.1   thorpej altqdev_decl(hfsc);
     80        1.1   thorpej #endif
     81        1.1   thorpej #ifdef ALTQ_CDNR
     82        1.1   thorpej altqdev_decl(cdnr);
     83        1.1   thorpej #endif
     84        1.1   thorpej #ifdef ALTQ_BLUE
     85        1.1   thorpej altqdev_decl(blue);
     86        1.1   thorpej #endif
     87        1.1   thorpej #ifdef ALTQ_PRIQ
     88        1.1   thorpej altqdev_decl(priq);
     89        1.1   thorpej #endif
     90  1.12.12.1     peter #ifdef ALTQ_JOBS
     91  1.12.12.1     peter altqdev_decl(jobs);
     92  1.12.12.1     peter #endif
     93        1.1   thorpej 
     94        1.1   thorpej /*
     95        1.1   thorpej  * altq minor device (discipline) table
     96        1.1   thorpej  */
     97        1.1   thorpej static struct altqsw altqsw[] = {				/* minor */
     98  1.12.12.1     peter 	{"altq", noopen,	noclose,	noioctl},  /* 0 (reserved) */
     99        1.1   thorpej #ifdef ALTQ_CBQ
    100        1.1   thorpej 	{"cbq",	cbqopen,	cbqclose,	cbqioctl},	/* 1 */
    101        1.1   thorpej #else
    102        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},	/* 1 */
    103        1.1   thorpej #endif
    104        1.1   thorpej #ifdef ALTQ_WFQ
    105        1.1   thorpej 	{"wfq",	wfqopen,	wfqclose,	wfqioctl},	/* 2 */
    106        1.1   thorpej #else
    107        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},	/* 2 */
    108        1.1   thorpej #endif
    109        1.1   thorpej #ifdef ALTQ_AFMAP
    110        1.1   thorpej 	{"afm",	afmopen,	afmclose,	afmioctl},	/* 3 */
    111        1.1   thorpej #else
    112        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},	/* 3 */
    113        1.1   thorpej #endif
    114        1.1   thorpej #ifdef ALTQ_FIFOQ
    115        1.1   thorpej 	{"fifoq", fifoqopen,	fifoqclose,	fifoqioctl},	/* 4 */
    116        1.1   thorpej #else
    117        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},	/* 4 */
    118        1.1   thorpej #endif
    119        1.1   thorpej #ifdef ALTQ_RED
    120        1.1   thorpej 	{"red", redopen,	redclose,	redioctl},	/* 5 */
    121        1.1   thorpej #else
    122        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},	/* 5 */
    123        1.1   thorpej #endif
    124        1.1   thorpej #ifdef ALTQ_RIO
    125        1.1   thorpej 	{"rio", rioopen,	rioclose,	rioioctl},	/* 6 */
    126        1.1   thorpej #else
    127        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},	/* 6 */
    128        1.1   thorpej #endif
    129        1.1   thorpej #ifdef ALTQ_LOCALQ
    130        1.1   thorpej 	{"localq",localqopen,	localqclose,	localqioctl}, /* 7 (local use) */
    131        1.1   thorpej #else
    132        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},  /* 7 (local use) */
    133        1.1   thorpej #endif
    134        1.1   thorpej #ifdef ALTQ_HFSC
    135        1.1   thorpej 	{"hfsc",hfscopen,	hfscclose,	hfscioctl},	/* 8 */
    136        1.1   thorpej #else
    137        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},	/* 8 */
    138        1.1   thorpej #endif
    139        1.1   thorpej #ifdef ALTQ_CDNR
    140        1.1   thorpej 	{"cdnr",cdnropen,	cdnrclose,	cdnrioctl},	/* 9 */
    141        1.1   thorpej #else
    142        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},	/* 9 */
    143        1.1   thorpej #endif
    144        1.1   thorpej #ifdef ALTQ_BLUE
    145        1.1   thorpej 	{"blue",blueopen,	blueclose,	blueioctl},	/* 10 */
    146        1.1   thorpej #else
    147        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},	/* 10 */
    148        1.1   thorpej #endif
    149        1.1   thorpej #ifdef ALTQ_PRIQ
    150        1.1   thorpej 	{"priq",priqopen,	priqclose,	priqioctl},	/* 11 */
    151        1.1   thorpej #else
    152        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},	/* 11 */
    153        1.1   thorpej #endif
    154  1.12.12.1     peter #ifdef ALTQ_JOBS
    155  1.12.12.1     peter 	{"jobs",jobsopen,	jobsclose,	jobsioctl},	/* 12 */
    156  1.12.12.1     peter #else
    157  1.12.12.1     peter 	{"noq", noopen,		noclose,	noioctl},	/* 12 */
    158  1.12.12.1     peter #endif
    159        1.1   thorpej };
    160        1.1   thorpej 
    161        1.1   thorpej /*
    162        1.1   thorpej  * altq major device support
    163        1.1   thorpej  */
    164        1.1   thorpej int	naltqsw = sizeof (altqsw) / sizeof (altqsw[0]);
    165        1.1   thorpej 
    166        1.8   gehenna dev_type_open(altqopen);
    167        1.8   gehenna dev_type_close(altqclose);
    168        1.8   gehenna dev_type_ioctl(altqioctl);
    169        1.1   thorpej 
    170        1.7   gehenna const struct cdevsw altq_cdevsw = {
    171        1.7   gehenna 	altqopen, altqclose, noread, nowrite, altqioctl,
    172  1.12.12.3     peter 	nostop, notty, nopoll, nommap, nokqfilter, D_OTHER,
    173        1.7   gehenna };
    174        1.1   thorpej 
    175        1.1   thorpej int
    176       1.12  christos altqopen(dev, flag, fmt, l)
    177        1.1   thorpej 	dev_t dev;
    178        1.1   thorpej 	int flag, fmt;
    179       1.12  christos 	struct lwp *l;
    180        1.1   thorpej {
    181        1.1   thorpej 	int unit = minor(dev);
    182        1.1   thorpej 
    183        1.1   thorpej 	if (unit == 0)
    184        1.1   thorpej 		return (0);
    185        1.1   thorpej 	if (unit < naltqsw)
    186       1.12  christos 		return (*altqsw[unit].d_open)(dev, flag, fmt, l);
    187        1.1   thorpej 
    188        1.1   thorpej 	return ENXIO;
    189        1.1   thorpej }
    190        1.1   thorpej 
    191        1.1   thorpej int
    192       1.12  christos altqclose(dev, flag, fmt, l)
    193        1.1   thorpej 	dev_t dev;
    194        1.1   thorpej 	int flag, fmt;
    195       1.12  christos 	struct lwp *l;
    196        1.1   thorpej {
    197        1.1   thorpej 	int unit = minor(dev);
    198        1.1   thorpej 
    199        1.1   thorpej 	if (unit == 0)
    200        1.1   thorpej 		return (0);
    201        1.1   thorpej 	if (unit < naltqsw)
    202       1.12  christos 		return (*altqsw[unit].d_close)(dev, flag, fmt, l);
    203        1.1   thorpej 
    204        1.1   thorpej 	return ENXIO;
    205        1.1   thorpej }
    206        1.1   thorpej 
    207        1.1   thorpej int
    208       1.12  christos altqioctl(dev, cmd, addr, flag, l)
    209        1.1   thorpej 	dev_t dev;
    210        1.1   thorpej 	ioctlcmd_t cmd;
    211        1.1   thorpej 	caddr_t addr;
    212        1.1   thorpej 	int flag;
    213       1.12  christos 	struct lwp *l;
    214        1.1   thorpej {
    215        1.1   thorpej 	int unit = minor(dev);
    216        1.1   thorpej 
    217        1.1   thorpej 	if (unit == 0) {
    218        1.1   thorpej 		struct ifnet *ifp;
    219        1.1   thorpej 		struct altqreq *typereq;
    220        1.1   thorpej 		struct tbrreq *tbrreq;
    221        1.1   thorpej 		int error;
    222        1.1   thorpej 
    223        1.1   thorpej 		switch (cmd) {
    224        1.1   thorpej 		case ALTQGTYPE:
    225        1.1   thorpej 		case ALTQTBRGET:
    226        1.1   thorpej 			break;
    227        1.1   thorpej 		default:
    228        1.1   thorpej #if (__FreeBSD_version > 400000)
    229        1.1   thorpej 			if ((error = suser(p)) != 0)
    230        1.1   thorpej 				return (error);
    231        1.1   thorpej #else
    232  1.12.12.3     peter 			if ((error = kauth_authorize_generic(l->l_cred,
    233  1.12.12.3     peter 			    KAUTH_GENERIC_ISSUSER, &l->l_acflag)) != 0)
    234        1.1   thorpej 				return (error);
    235        1.1   thorpej #endif
    236        1.1   thorpej 			break;
    237        1.1   thorpej 		}
    238        1.1   thorpej 
    239        1.1   thorpej 		switch (cmd) {
    240        1.1   thorpej 		case ALTQGTYPE:
    241        1.1   thorpej 			typereq = (struct altqreq *)addr;
    242        1.1   thorpej 			if ((ifp = ifunit(typereq->ifname)) == NULL)
    243        1.1   thorpej 				return (EINVAL);
    244        1.1   thorpej 			typereq->arg = (u_long)ifp->if_snd.altq_type;
    245        1.1   thorpej 			return (0);
    246        1.1   thorpej 		case ALTQTBRSET:
    247        1.1   thorpej 			tbrreq = (struct tbrreq *)addr;
    248        1.1   thorpej 			if ((ifp = ifunit(tbrreq->ifname)) == NULL)
    249        1.1   thorpej 				return (EINVAL);
    250        1.1   thorpej 			return tbr_set(&ifp->if_snd, &tbrreq->tb_prof);
    251        1.1   thorpej 		case ALTQTBRGET:
    252        1.1   thorpej 			tbrreq = (struct tbrreq *)addr;
    253        1.1   thorpej 			if ((ifp = ifunit(tbrreq->ifname)) == NULL)
    254        1.1   thorpej 				return (EINVAL);
    255        1.1   thorpej 			return tbr_get(&ifp->if_snd, &tbrreq->tb_prof);
    256        1.1   thorpej 		default:
    257        1.1   thorpej 			return (EINVAL);
    258        1.1   thorpej 		}
    259        1.1   thorpej 	}
    260        1.1   thorpej 	if (unit < naltqsw)
    261       1.12  christos 		return (*altqsw[unit].d_ioctl)(dev, cmd, addr, flag, l);
    262        1.1   thorpej 
    263        1.1   thorpej 	return ENXIO;
    264        1.1   thorpej }
    265        1.1   thorpej 
    266  1.12.12.1     peter #ifdef __FreeBSD__
    267        1.1   thorpej static int altq_devsw_installed = 0;
    268        1.4   thorpej #endif
    269        1.1   thorpej 
    270        1.1   thorpej #ifdef __FreeBSD__
    271        1.1   thorpej static void
    272        1.1   thorpej altq_drvinit(unused)
    273        1.1   thorpej 	void *unused;
    274        1.1   thorpej {
    275        1.1   thorpej 	int unit;
    276        1.1   thorpej 
    277  1.12.12.1     peter #if 0
    278  1.12.12.1     peter 	mtx_init(&altq_mtx, "altq global lock", MTX_DEF);
    279  1.12.12.1     peter #endif
    280        1.1   thorpej 	altq_devsw_installed = 1;
    281  1.12.12.1     peter 	printf("altq: attached. Major number assigned automatically.\n");
    282        1.1   thorpej 
    283        1.1   thorpej 	/* create minor devices */
    284  1.12.12.1     peter 	for (unit = 0; unit < naltqsw; unit++) {
    285  1.12.12.1     peter 		if (unit == 0 || altqsw[unit].d_open != NULL)
    286  1.12.12.1     peter 			altqsw[unit].dev = make_dev(&altq_cdevsw, unit,
    287  1.12.12.1     peter 			    UID_ROOT, GID_WHEEL, 0644, "altq/%s",
    288  1.12.12.1     peter 			    altqsw[unit].d_name);
    289  1.12.12.1     peter 	}
    290        1.1   thorpej }
    291        1.1   thorpej 
    292        1.1   thorpej SYSINIT(altqdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,altq_drvinit,NULL)
    293        1.1   thorpej 
    294  1.12.12.1     peter #endif /* FreeBSD */
    295        1.1   thorpej 
    296        1.1   thorpej #ifdef ALTQ_KLD
    297        1.1   thorpej /*
    298        1.1   thorpej  * KLD support
    299        1.1   thorpej  */
    300  1.12.12.1     peter static int altq_module_register(struct altq_module_data *);
    301  1.12.12.1     peter static int altq_module_deregister(struct altq_module_data *);
    302        1.1   thorpej 
    303        1.1   thorpej static struct altq_module_data *altq_modules[ALTQT_MAX];
    304  1.12.12.1     peter #if __FreeBSD_version < 502103
    305        1.1   thorpej static struct altqsw noqdisc = {"noq", noopen, noclose, noioctl};
    306  1.12.12.1     peter #else
    307  1.12.12.1     peter static struct altqsw noqdisc = {"noq"};
    308  1.12.12.1     peter #endif
    309        1.1   thorpej 
    310        1.1   thorpej void altq_module_incref(type)
    311        1.1   thorpej 	int type;
    312        1.1   thorpej {
    313        1.1   thorpej 	if (type < 0 || type >= ALTQT_MAX || altq_modules[type] == NULL)
    314        1.1   thorpej 		return;
    315        1.1   thorpej 
    316        1.1   thorpej 	altq_modules[type]->ref++;
    317        1.1   thorpej }
    318        1.1   thorpej 
    319        1.1   thorpej void altq_module_declref(type)
    320        1.1   thorpej 	int type;
    321        1.1   thorpej {
    322        1.1   thorpej 	if (type < 0 || type >= ALTQT_MAX || altq_modules[type] == NULL)
    323        1.1   thorpej 		return;
    324        1.1   thorpej 
    325        1.1   thorpej 	altq_modules[type]->ref--;
    326        1.1   thorpej }
    327        1.1   thorpej 
    328       1.11     perry static int
    329        1.1   thorpej altq_module_register(mdata)
    330        1.1   thorpej 	struct altq_module_data *mdata;
    331        1.1   thorpej {
    332        1.1   thorpej 	int type = mdata->type;
    333        1.1   thorpej 
    334        1.1   thorpej 	if (type < 0 || type >= ALTQT_MAX)
    335        1.1   thorpej 		return (EINVAL);
    336  1.12.12.1     peter #if (__FreeBSD_version < 502103)
    337        1.1   thorpej 	if (altqsw[type].d_open != noopen)
    338  1.12.12.1     peter #else
    339  1.12.12.1     peter 	if (altqsw[type].d_open != NULL)
    340  1.12.12.1     peter #endif
    341        1.1   thorpej 		return (EBUSY);
    342        1.1   thorpej 	altqsw[type] = *mdata->altqsw;	/* set discipline functions */
    343        1.1   thorpej 	altq_modules[type] = mdata;	/* save module data pointer */
    344  1.12.12.1     peter #if (__FreeBSD_version < 502103)
    345  1.12.12.1     peter 	make_dev(&altq_cdevsw, type, UID_ROOT, GID_WHEEL, 0644,
    346  1.12.12.1     peter 		 "altq/%s", altqsw[type].d_name);
    347  1.12.12.1     peter #else
    348  1.12.12.1     peter 	altqsw[type].dev = make_dev(&altq_cdevsw, type, UID_ROOT, GID_WHEEL,
    349  1.12.12.1     peter 	    0644, "altq/%s", altqsw[type].d_name);
    350  1.12.12.1     peter #endif
    351        1.1   thorpej 	return (0);
    352        1.1   thorpej }
    353        1.1   thorpej 
    354       1.11     perry static int
    355        1.1   thorpej altq_module_deregister(mdata)
    356        1.1   thorpej 	struct altq_module_data *mdata;
    357        1.1   thorpej {
    358        1.1   thorpej 	int type = mdata->type;
    359        1.1   thorpej 
    360        1.1   thorpej 	if (type < 0 || type >= ALTQT_MAX)
    361        1.1   thorpej 		return (EINVAL);
    362        1.1   thorpej 	if (mdata != altq_modules[type])
    363        1.1   thorpej 		return (EINVAL);
    364        1.1   thorpej 	if (altq_modules[type]->ref > 0)
    365        1.1   thorpej 		return (EBUSY);
    366  1.12.12.1     peter #if (__FreeBSD_version < 502103)
    367  1.12.12.1     peter 	destroy_dev(makedev(CDEV_MAJOR, type));
    368  1.12.12.1     peter #else
    369  1.12.12.1     peter 	destroy_dev(altqsw[type].dev);
    370  1.12.12.1     peter #endif
    371        1.1   thorpej 	altqsw[type] = noqdisc;
    372        1.1   thorpej 	altq_modules[type] = NULL;
    373        1.1   thorpej 	return (0);
    374        1.1   thorpej }
    375        1.1   thorpej 
    376        1.1   thorpej int
    377        1.1   thorpej altq_module_handler(mod, cmd, arg)
    378        1.1   thorpej     module_t	mod;
    379        1.1   thorpej     int cmd;
    380        1.1   thorpej     void * arg;
    381        1.1   thorpej {
    382        1.1   thorpej 	struct altq_module_data *data = (struct altq_module_data *)arg;
    383        1.1   thorpej 	int	error = 0;
    384        1.1   thorpej 
    385        1.1   thorpej 	switch (cmd) {
    386        1.1   thorpej 	case MOD_LOAD:
    387        1.1   thorpej 		error = altq_module_register(data);
    388        1.1   thorpej 		break;
    389        1.1   thorpej 
    390        1.1   thorpej 	case MOD_UNLOAD:
    391        1.1   thorpej 		error = altq_module_deregister(data);
    392        1.1   thorpej 		break;
    393        1.1   thorpej 
    394        1.1   thorpej 	default:
    395        1.1   thorpej 		error = EINVAL;
    396        1.1   thorpej 		break;
    397        1.1   thorpej 	}
    398        1.1   thorpej 
    399        1.1   thorpej 	return(error);
    400        1.1   thorpej }
    401        1.6    itojun 
    402        1.1   thorpej #endif  /* ALTQ_KLD */
    403  1.12.12.1     peter #endif /* ALTQ3_COMPAT */
    404