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