Home | History | Annotate | Line # | Download | only in altq
altq_conf.c revision 1.12.12.1
      1  1.12.12.1     peter /*	$NetBSD: altq_conf.c,v 1.12.12.1 2006/03/18 12:08:18 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.1     peter __KERNEL_RCSID(0, "$NetBSD: altq_conf.c,v 1.12.12.1 2006/03/18 12:08:18 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.1   thorpej #include <net/if.h>
     48        1.1   thorpej 
     49        1.1   thorpej #include <altq/altq.h>
     50        1.9  jdolecek #include <altq/altqconf.h>
     51        1.1   thorpej #include <altq/altq_conf.h>
     52        1.1   thorpej 
     53  1.12.12.1     peter #ifdef ALTQ3_COMPAT
     54  1.12.12.1     peter 
     55        1.1   thorpej #ifdef ALTQ_CBQ
     56        1.1   thorpej altqdev_decl(cbq);
     57        1.1   thorpej #endif
     58        1.1   thorpej #ifdef ALTQ_WFQ
     59        1.1   thorpej altqdev_decl(wfq);
     60        1.1   thorpej #endif
     61        1.1   thorpej #ifdef ALTQ_AFMAP
     62        1.1   thorpej altqdev_decl(afm);
     63        1.1   thorpej #endif
     64        1.1   thorpej #ifdef ALTQ_FIFOQ
     65        1.1   thorpej altqdev_decl(fifoq);
     66        1.1   thorpej #endif
     67        1.1   thorpej #ifdef ALTQ_RED
     68        1.1   thorpej altqdev_decl(red);
     69        1.1   thorpej #endif
     70        1.1   thorpej #ifdef ALTQ_RIO
     71        1.1   thorpej altqdev_decl(rio);
     72        1.1   thorpej #endif
     73        1.1   thorpej #ifdef ALTQ_LOCALQ
     74        1.1   thorpej altqdev_decl(localq);
     75        1.1   thorpej #endif
     76        1.1   thorpej #ifdef ALTQ_HFSC
     77        1.1   thorpej altqdev_decl(hfsc);
     78        1.1   thorpej #endif
     79        1.1   thorpej #ifdef ALTQ_CDNR
     80        1.1   thorpej altqdev_decl(cdnr);
     81        1.1   thorpej #endif
     82        1.1   thorpej #ifdef ALTQ_BLUE
     83        1.1   thorpej altqdev_decl(blue);
     84        1.1   thorpej #endif
     85        1.1   thorpej #ifdef ALTQ_PRIQ
     86        1.1   thorpej altqdev_decl(priq);
     87        1.1   thorpej #endif
     88  1.12.12.1     peter #ifdef ALTQ_JOBS
     89  1.12.12.1     peter altqdev_decl(jobs);
     90  1.12.12.1     peter #endif
     91        1.1   thorpej 
     92        1.1   thorpej /*
     93        1.1   thorpej  * altq minor device (discipline) table
     94        1.1   thorpej  */
     95        1.1   thorpej static struct altqsw altqsw[] = {				/* minor */
     96  1.12.12.1     peter 	{"altq", noopen,	noclose,	noioctl},  /* 0 (reserved) */
     97        1.1   thorpej #ifdef ALTQ_CBQ
     98        1.1   thorpej 	{"cbq",	cbqopen,	cbqclose,	cbqioctl},	/* 1 */
     99        1.1   thorpej #else
    100        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},	/* 1 */
    101        1.1   thorpej #endif
    102        1.1   thorpej #ifdef ALTQ_WFQ
    103        1.1   thorpej 	{"wfq",	wfqopen,	wfqclose,	wfqioctl},	/* 2 */
    104        1.1   thorpej #else
    105        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},	/* 2 */
    106        1.1   thorpej #endif
    107        1.1   thorpej #ifdef ALTQ_AFMAP
    108        1.1   thorpej 	{"afm",	afmopen,	afmclose,	afmioctl},	/* 3 */
    109        1.1   thorpej #else
    110        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},	/* 3 */
    111        1.1   thorpej #endif
    112        1.1   thorpej #ifdef ALTQ_FIFOQ
    113        1.1   thorpej 	{"fifoq", fifoqopen,	fifoqclose,	fifoqioctl},	/* 4 */
    114        1.1   thorpej #else
    115        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},	/* 4 */
    116        1.1   thorpej #endif
    117        1.1   thorpej #ifdef ALTQ_RED
    118        1.1   thorpej 	{"red", redopen,	redclose,	redioctl},	/* 5 */
    119        1.1   thorpej #else
    120        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},	/* 5 */
    121        1.1   thorpej #endif
    122        1.1   thorpej #ifdef ALTQ_RIO
    123        1.1   thorpej 	{"rio", rioopen,	rioclose,	rioioctl},	/* 6 */
    124        1.1   thorpej #else
    125        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},	/* 6 */
    126        1.1   thorpej #endif
    127        1.1   thorpej #ifdef ALTQ_LOCALQ
    128        1.1   thorpej 	{"localq",localqopen,	localqclose,	localqioctl}, /* 7 (local use) */
    129        1.1   thorpej #else
    130        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},  /* 7 (local use) */
    131        1.1   thorpej #endif
    132        1.1   thorpej #ifdef ALTQ_HFSC
    133        1.1   thorpej 	{"hfsc",hfscopen,	hfscclose,	hfscioctl},	/* 8 */
    134        1.1   thorpej #else
    135        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},	/* 8 */
    136        1.1   thorpej #endif
    137        1.1   thorpej #ifdef ALTQ_CDNR
    138        1.1   thorpej 	{"cdnr",cdnropen,	cdnrclose,	cdnrioctl},	/* 9 */
    139        1.1   thorpej #else
    140        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},	/* 9 */
    141        1.1   thorpej #endif
    142        1.1   thorpej #ifdef ALTQ_BLUE
    143        1.1   thorpej 	{"blue",blueopen,	blueclose,	blueioctl},	/* 10 */
    144        1.1   thorpej #else
    145        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},	/* 10 */
    146        1.1   thorpej #endif
    147        1.1   thorpej #ifdef ALTQ_PRIQ
    148        1.1   thorpej 	{"priq",priqopen,	priqclose,	priqioctl},	/* 11 */
    149        1.1   thorpej #else
    150        1.1   thorpej 	{"noq",	noopen,		noclose,	noioctl},	/* 11 */
    151        1.1   thorpej #endif
    152  1.12.12.1     peter #ifdef ALTQ_JOBS
    153  1.12.12.1     peter 	{"jobs",jobsopen,	jobsclose,	jobsioctl},	/* 12 */
    154  1.12.12.1     peter #else
    155  1.12.12.1     peter 	{"noq", noopen,		noclose,	noioctl},	/* 12 */
    156  1.12.12.1     peter #endif
    157        1.1   thorpej };
    158        1.1   thorpej 
    159        1.1   thorpej /*
    160        1.1   thorpej  * altq major device support
    161        1.1   thorpej  */
    162        1.1   thorpej int	naltqsw = sizeof (altqsw) / sizeof (altqsw[0]);
    163        1.1   thorpej 
    164        1.8   gehenna dev_type_open(altqopen);
    165        1.8   gehenna dev_type_close(altqclose);
    166        1.8   gehenna dev_type_ioctl(altqioctl);
    167        1.1   thorpej 
    168        1.7   gehenna const struct cdevsw altq_cdevsw = {
    169        1.7   gehenna 	altqopen, altqclose, noread, nowrite, altqioctl,
    170       1.10  jdolecek 	nostop, notty, nopoll, nommap, nokqfilter
    171        1.7   gehenna };
    172        1.1   thorpej 
    173        1.1   thorpej int
    174       1.12  christos altqopen(dev, flag, fmt, l)
    175        1.1   thorpej 	dev_t dev;
    176        1.1   thorpej 	int flag, fmt;
    177       1.12  christos 	struct lwp *l;
    178        1.1   thorpej {
    179        1.1   thorpej 	int unit = minor(dev);
    180        1.1   thorpej 
    181        1.1   thorpej 	if (unit == 0)
    182        1.1   thorpej 		return (0);
    183        1.1   thorpej 	if (unit < naltqsw)
    184       1.12  christos 		return (*altqsw[unit].d_open)(dev, flag, fmt, l);
    185        1.1   thorpej 
    186        1.1   thorpej 	return ENXIO;
    187        1.1   thorpej }
    188        1.1   thorpej 
    189        1.1   thorpej int
    190       1.12  christos altqclose(dev, flag, fmt, l)
    191        1.1   thorpej 	dev_t dev;
    192        1.1   thorpej 	int flag, fmt;
    193       1.12  christos 	struct lwp *l;
    194        1.1   thorpej {
    195        1.1   thorpej 	int unit = minor(dev);
    196        1.1   thorpej 
    197        1.1   thorpej 	if (unit == 0)
    198        1.1   thorpej 		return (0);
    199        1.1   thorpej 	if (unit < naltqsw)
    200       1.12  christos 		return (*altqsw[unit].d_close)(dev, flag, fmt, l);
    201        1.1   thorpej 
    202        1.1   thorpej 	return ENXIO;
    203        1.1   thorpej }
    204        1.1   thorpej 
    205        1.1   thorpej int
    206       1.12  christos altqioctl(dev, cmd, addr, flag, l)
    207        1.1   thorpej 	dev_t dev;
    208        1.1   thorpej 	ioctlcmd_t cmd;
    209        1.1   thorpej 	caddr_t addr;
    210        1.1   thorpej 	int flag;
    211       1.12  christos 	struct lwp *l;
    212        1.1   thorpej {
    213       1.12  christos 	struct proc *p = l->l_proc;
    214        1.1   thorpej 	int unit = minor(dev);
    215        1.1   thorpej 
    216        1.1   thorpej 	if (unit == 0) {
    217        1.1   thorpej 		struct ifnet *ifp;
    218        1.1   thorpej 		struct altqreq *typereq;
    219        1.1   thorpej 		struct tbrreq *tbrreq;
    220        1.1   thorpej 		int error;
    221        1.1   thorpej 
    222        1.1   thorpej 		switch (cmd) {
    223        1.1   thorpej 		case ALTQGTYPE:
    224        1.1   thorpej 		case ALTQTBRGET:
    225        1.1   thorpej 			break;
    226        1.1   thorpej 		default:
    227        1.1   thorpej #if (__FreeBSD_version > 400000)
    228        1.1   thorpej 			if ((error = suser(p)) != 0)
    229        1.1   thorpej 				return (error);
    230        1.1   thorpej #else
    231        1.1   thorpej 			if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
    232        1.1   thorpej 				return (error);
    233        1.1   thorpej #endif
    234        1.1   thorpej 			break;
    235        1.1   thorpej 		}
    236        1.1   thorpej 
    237        1.1   thorpej 		switch (cmd) {
    238        1.1   thorpej 		case ALTQGTYPE:
    239        1.1   thorpej 			typereq = (struct altqreq *)addr;
    240        1.1   thorpej 			if ((ifp = ifunit(typereq->ifname)) == NULL)
    241        1.1   thorpej 				return (EINVAL);
    242        1.1   thorpej 			typereq->arg = (u_long)ifp->if_snd.altq_type;
    243        1.1   thorpej 			return (0);
    244        1.1   thorpej 		case ALTQTBRSET:
    245        1.1   thorpej 			tbrreq = (struct tbrreq *)addr;
    246        1.1   thorpej 			if ((ifp = ifunit(tbrreq->ifname)) == NULL)
    247        1.1   thorpej 				return (EINVAL);
    248        1.1   thorpej 			return tbr_set(&ifp->if_snd, &tbrreq->tb_prof);
    249        1.1   thorpej 		case ALTQTBRGET:
    250        1.1   thorpej 			tbrreq = (struct tbrreq *)addr;
    251        1.1   thorpej 			if ((ifp = ifunit(tbrreq->ifname)) == NULL)
    252        1.1   thorpej 				return (EINVAL);
    253        1.1   thorpej 			return tbr_get(&ifp->if_snd, &tbrreq->tb_prof);
    254        1.1   thorpej 		default:
    255        1.1   thorpej 			return (EINVAL);
    256        1.1   thorpej 		}
    257        1.1   thorpej 	}
    258        1.1   thorpej 	if (unit < naltqsw)
    259       1.12  christos 		return (*altqsw[unit].d_ioctl)(dev, cmd, addr, flag, l);
    260        1.1   thorpej 
    261        1.1   thorpej 	return ENXIO;
    262        1.1   thorpej }
    263        1.1   thorpej 
    264  1.12.12.1     peter #ifdef __FreeBSD__
    265        1.1   thorpej static int altq_devsw_installed = 0;
    266        1.4   thorpej #endif
    267        1.1   thorpej 
    268        1.1   thorpej #ifdef __FreeBSD__
    269        1.1   thorpej static void
    270        1.1   thorpej altq_drvinit(unused)
    271        1.1   thorpej 	void *unused;
    272        1.1   thorpej {
    273        1.1   thorpej 	int unit;
    274        1.1   thorpej 
    275  1.12.12.1     peter #if 0
    276  1.12.12.1     peter 	mtx_init(&altq_mtx, "altq global lock", MTX_DEF);
    277  1.12.12.1     peter #endif
    278        1.1   thorpej 	altq_devsw_installed = 1;
    279  1.12.12.1     peter 	printf("altq: attached. Major number assigned automatically.\n");
    280        1.1   thorpej 
    281        1.1   thorpej 	/* create minor devices */
    282  1.12.12.1     peter 	for (unit = 0; unit < naltqsw; unit++) {
    283  1.12.12.1     peter 		if (unit == 0 || altqsw[unit].d_open != NULL)
    284  1.12.12.1     peter 			altqsw[unit].dev = make_dev(&altq_cdevsw, unit,
    285  1.12.12.1     peter 			    UID_ROOT, GID_WHEEL, 0644, "altq/%s",
    286  1.12.12.1     peter 			    altqsw[unit].d_name);
    287  1.12.12.1     peter 	}
    288        1.1   thorpej }
    289        1.1   thorpej 
    290        1.1   thorpej SYSINIT(altqdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,altq_drvinit,NULL)
    291        1.1   thorpej 
    292  1.12.12.1     peter #endif /* FreeBSD */
    293        1.1   thorpej 
    294        1.1   thorpej #ifdef ALTQ_KLD
    295        1.1   thorpej /*
    296        1.1   thorpej  * KLD support
    297        1.1   thorpej  */
    298  1.12.12.1     peter static int altq_module_register(struct altq_module_data *);
    299  1.12.12.1     peter static int altq_module_deregister(struct altq_module_data *);
    300        1.1   thorpej 
    301        1.1   thorpej static struct altq_module_data *altq_modules[ALTQT_MAX];
    302  1.12.12.1     peter #if __FreeBSD_version < 502103
    303        1.1   thorpej static struct altqsw noqdisc = {"noq", noopen, noclose, noioctl};
    304  1.12.12.1     peter #else
    305  1.12.12.1     peter static struct altqsw noqdisc = {"noq"};
    306  1.12.12.1     peter #endif
    307        1.1   thorpej 
    308        1.1   thorpej void altq_module_incref(type)
    309        1.1   thorpej 	int type;
    310        1.1   thorpej {
    311        1.1   thorpej 	if (type < 0 || type >= ALTQT_MAX || altq_modules[type] == NULL)
    312        1.1   thorpej 		return;
    313        1.1   thorpej 
    314        1.1   thorpej 	altq_modules[type]->ref++;
    315        1.1   thorpej }
    316        1.1   thorpej 
    317        1.1   thorpej void altq_module_declref(type)
    318        1.1   thorpej 	int type;
    319        1.1   thorpej {
    320        1.1   thorpej 	if (type < 0 || type >= ALTQT_MAX || altq_modules[type] == NULL)
    321        1.1   thorpej 		return;
    322        1.1   thorpej 
    323        1.1   thorpej 	altq_modules[type]->ref--;
    324        1.1   thorpej }
    325        1.1   thorpej 
    326       1.11     perry static int
    327        1.1   thorpej altq_module_register(mdata)
    328        1.1   thorpej 	struct altq_module_data *mdata;
    329        1.1   thorpej {
    330        1.1   thorpej 	int type = mdata->type;
    331        1.1   thorpej 
    332        1.1   thorpej 	if (type < 0 || type >= ALTQT_MAX)
    333        1.1   thorpej 		return (EINVAL);
    334  1.12.12.1     peter #if (__FreeBSD_version < 502103)
    335        1.1   thorpej 	if (altqsw[type].d_open != noopen)
    336  1.12.12.1     peter #else
    337  1.12.12.1     peter 	if (altqsw[type].d_open != NULL)
    338  1.12.12.1     peter #endif
    339        1.1   thorpej 		return (EBUSY);
    340        1.1   thorpej 	altqsw[type] = *mdata->altqsw;	/* set discipline functions */
    341        1.1   thorpej 	altq_modules[type] = mdata;	/* save module data pointer */
    342  1.12.12.1     peter #if (__FreeBSD_version < 502103)
    343  1.12.12.1     peter 	make_dev(&altq_cdevsw, type, UID_ROOT, GID_WHEEL, 0644,
    344  1.12.12.1     peter 		 "altq/%s", altqsw[type].d_name);
    345  1.12.12.1     peter #else
    346  1.12.12.1     peter 	altqsw[type].dev = make_dev(&altq_cdevsw, type, UID_ROOT, GID_WHEEL,
    347  1.12.12.1     peter 	    0644, "altq/%s", altqsw[type].d_name);
    348  1.12.12.1     peter #endif
    349        1.1   thorpej 	return (0);
    350        1.1   thorpej }
    351        1.1   thorpej 
    352       1.11     perry static int
    353        1.1   thorpej altq_module_deregister(mdata)
    354        1.1   thorpej 	struct altq_module_data *mdata;
    355        1.1   thorpej {
    356        1.1   thorpej 	int type = mdata->type;
    357        1.1   thorpej 
    358        1.1   thorpej 	if (type < 0 || type >= ALTQT_MAX)
    359        1.1   thorpej 		return (EINVAL);
    360        1.1   thorpej 	if (mdata != altq_modules[type])
    361        1.1   thorpej 		return (EINVAL);
    362        1.1   thorpej 	if (altq_modules[type]->ref > 0)
    363        1.1   thorpej 		return (EBUSY);
    364  1.12.12.1     peter #if (__FreeBSD_version < 502103)
    365  1.12.12.1     peter 	destroy_dev(makedev(CDEV_MAJOR, type));
    366  1.12.12.1     peter #else
    367  1.12.12.1     peter 	destroy_dev(altqsw[type].dev);
    368  1.12.12.1     peter #endif
    369        1.1   thorpej 	altqsw[type] = noqdisc;
    370        1.1   thorpej 	altq_modules[type] = NULL;
    371        1.1   thorpej 	return (0);
    372        1.1   thorpej }
    373        1.1   thorpej 
    374        1.1   thorpej int
    375        1.1   thorpej altq_module_handler(mod, cmd, arg)
    376        1.1   thorpej     module_t	mod;
    377        1.1   thorpej     int cmd;
    378        1.1   thorpej     void * arg;
    379        1.1   thorpej {
    380        1.1   thorpej 	struct altq_module_data *data = (struct altq_module_data *)arg;
    381        1.1   thorpej 	int	error = 0;
    382        1.1   thorpej 
    383        1.1   thorpej 	switch (cmd) {
    384        1.1   thorpej 	case MOD_LOAD:
    385        1.1   thorpej 		error = altq_module_register(data);
    386        1.1   thorpej 		break;
    387        1.1   thorpej 
    388        1.1   thorpej 	case MOD_UNLOAD:
    389        1.1   thorpej 		error = altq_module_deregister(data);
    390        1.1   thorpej 		break;
    391        1.1   thorpej 
    392        1.1   thorpej 	default:
    393        1.1   thorpej 		error = EINVAL;
    394        1.1   thorpej 		break;
    395        1.1   thorpej 	}
    396        1.1   thorpej 
    397        1.1   thorpej 	return(error);
    398        1.1   thorpej }
    399        1.6    itojun 
    400        1.1   thorpej #endif  /* ALTQ_KLD */
    401  1.12.12.1     peter #endif /* ALTQ3_COMPAT */
    402