1 /* $NetBSD: altq_conf.c,v 1.18 2006/10/20 21:55:56 elad Exp $ */
2 /* $KAME: altq_conf.c,v 1.24 2005/04/13 03:44:24 suz Exp $ */
5 * Copyright (C) 1997-2003
6 * Sony Computer Science Laboratories Inc. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/cdefs.h>
31 __KERNEL_RCSID(0, "$NetBSD: altq_conf.c,v 1.18 2006/10/20 21:55:56 elad Exp $");
39 * altq device interface.
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/socket.h>
44 #include <sys/kernel.h>
46 #include <sys/errno.h>
47 #include <sys/kauth.h>
51 #include <altq/altq.h>
52 #include <altq/altqconf.h>
53 #include <altq/altq_conf.h>
95 * altq minor device (discipline) table
97 static struct altqsw altqsw
[] = { /* minor */
98 {"altq", noopen
, noclose
, noioctl
}, /* 0 (reserved) */
100 {"cbq", cbqopen
, cbqclose
, cbqioctl
}, /* 1 */
102 {"noq", noopen
, noclose
, noioctl
}, /* 1 */
105 {"wfq", wfqopen
, wfqclose
, wfqioctl
}, /* 2 */
107 {"noq", noopen
, noclose
, noioctl
}, /* 2 */
110 {"afm", afmopen
, afmclose
, afmioctl
}, /* 3 */
112 {"noq", noopen
, noclose
, noioctl
}, /* 3 */
115 {"fifoq", fifoqopen
, fifoqclose
, fifoqioctl
}, /* 4 */
117 {"noq", noopen
, noclose
, noioctl
}, /* 4 */
120 {"red", redopen
, redclose
, redioctl
}, /* 5 */
122 {"noq", noopen
, noclose
, noioctl
}, /* 5 */
125 {"rio", rioopen
, rioclose
, rioioctl
}, /* 6 */
127 {"noq", noopen
, noclose
, noioctl
}, /* 6 */
130 {"localq",localqopen
, localqclose
, localqioctl
}, /* 7 (local use) */
132 {"noq", noopen
, noclose
, noioctl
}, /* 7 (local use) */
135 {"hfsc",hfscopen
, hfscclose
, hfscioctl
}, /* 8 */
137 {"noq", noopen
, noclose
, noioctl
}, /* 8 */
140 {"cdnr",cdnropen
, cdnrclose
, cdnrioctl
}, /* 9 */
142 {"noq", noopen
, noclose
, noioctl
}, /* 9 */
145 {"blue",blueopen
, blueclose
, blueioctl
}, /* 10 */
147 {"noq", noopen
, noclose
, noioctl
}, /* 10 */
150 {"priq",priqopen
, priqclose
, priqioctl
}, /* 11 */
152 {"noq", noopen
, noclose
, noioctl
}, /* 11 */
155 {"jobs",jobsopen
, jobsclose
, jobsioctl
}, /* 12 */
157 {"noq", noopen
, noclose
, noioctl
}, /* 12 */
162 * altq major device support
164 int naltqsw
= sizeof (altqsw
) / sizeof (altqsw
[0]);
166 dev_type_open(altqopen
);
167 dev_type_close(altqclose
);
168 dev_type_ioctl(altqioctl
);
170 const struct cdevsw altq_cdevsw
= {
171 altqopen
, altqclose
, noread
, nowrite
, altqioctl
,
172 nostop
, notty
, nopoll
, nommap
, nokqfilter
, D_OTHER
,
176 altqopen(dev_t dev
, int flag
, int fmt
, struct lwp
*l
)
178 int unit
= minor(dev
);
183 return (*altqsw
[unit
].d_open
)(dev
, flag
, fmt
, l
);
189 altqclose(dev_t dev
, int flag
, int fmt
, struct lwp
*l
)
191 int unit
= minor(dev
);
196 return (*altqsw
[unit
].d_close
)(dev
, flag
, fmt
, l
);
202 altqioctl(dev_t dev
, ioctlcmd_t cmd
, void *addr
, int flag
, struct lwp
*l
)
204 int unit
= minor(dev
);
208 struct altqreq
*typereq
;
209 struct tbrreq
*tbrreq
;
217 #if (__FreeBSD_version > 400000)
218 if ((error
= suser(p
)) != 0)
221 if ((error
= kauth_authorize_network(l
->l_cred
,
222 KAUTH_NETWORK_ALTQ
, KAUTH_REQ_NETWORK_ALTQ_CONF
,
223 NULL
, NULL
, NULL
)) != 0)
231 typereq
= (struct altqreq
*)addr
;
232 if ((ifp
= ifunit(typereq
->ifname
)) == NULL
)
234 typereq
->arg
= (u_long
)ifp
->if_snd
.altq_type
;
237 tbrreq
= (struct tbrreq
*)addr
;
238 if ((ifp
= ifunit(tbrreq
->ifname
)) == NULL
)
240 return tbr_set(&ifp
->if_snd
, &tbrreq
->tb_prof
);
242 tbrreq
= (struct tbrreq
*)addr
;
243 if ((ifp
= ifunit(tbrreq
->ifname
)) == NULL
)
245 return tbr_get(&ifp
->if_snd
, &tbrreq
->tb_prof
);
251 return (*altqsw
[unit
].d_ioctl
)(dev
, cmd
, addr
, flag
, l
);
257 static int altq_devsw_installed
= 0;
262 altq_drvinit(void *unused
)
267 mtx_init(&altq_mtx
, "altq global lock", MTX_DEF
);
269 altq_devsw_installed
= 1;
270 printf("altq: attached. Major number assigned automatically.\n");
272 /* create minor devices */
273 for (unit
= 0; unit
< naltqsw
; unit
++) {
274 if (unit
== 0 || altqsw
[unit
].d_open
!= NULL
)
275 altqsw
[unit
].dev
= make_dev(&altq_cdevsw
, unit
,
276 UID_ROOT
, GID_WHEEL
, 0644, "altq/%s",
277 altqsw
[unit
].d_name
);
281 SYSINIT(altqdev
,SI_SUB_DRIVERS
,SI_ORDER_MIDDLE
+CDEV_MAJOR
,altq_drvinit
,NULL
)
289 static int altq_module_register(struct altq_module_data
*);
290 static int altq_module_deregister(struct altq_module_data
*);
292 static struct altq_module_data
*altq_modules
[ALTQT_MAX
];
293 #if __FreeBSD_version < 502103
294 static struct altqsw noqdisc
= {"noq", noopen
, noclose
, noioctl
};
296 static struct altqsw noqdisc
= {"noq"};
299 void altq_module_incref(int type
)
301 if (type
< 0 || type
>= ALTQT_MAX
|| altq_modules
[type
] == NULL
)
304 altq_modules
[type
]->ref
++;
307 void altq_module_declref(int type
)
309 if (type
< 0 || type
>= ALTQT_MAX
|| altq_modules
[type
] == NULL
)
312 altq_modules
[type
]->ref
--;
316 altq_module_register(struct altq_module_data
*mdata
)
318 int type
= mdata
->type
;
320 if (type
< 0 || type
>= ALTQT_MAX
)
322 #if (__FreeBSD_version < 502103)
323 if (altqsw
[type
].d_open
!= noopen
)
325 if (altqsw
[type
].d_open
!= NULL
)
328 altqsw
[type
] = *mdata
->altqsw
; /* set discipline functions */
329 altq_modules
[type
] = mdata
; /* save module data pointer */
330 #if (__FreeBSD_version < 502103)
331 make_dev(&altq_cdevsw
, type
, UID_ROOT
, GID_WHEEL
, 0644,
332 "altq/%s", altqsw
[type
].d_name
);
334 altqsw
[type
].dev
= make_dev(&altq_cdevsw
, type
, UID_ROOT
, GID_WHEEL
,
335 0644, "altq/%s", altqsw
[type
].d_name
);
341 altq_module_deregister(struct altq_module_data
*mdata
)
343 int type
= mdata
->type
;
345 if (type
< 0 || type
>= ALTQT_MAX
)
347 if (mdata
!= altq_modules
[type
])
349 if (altq_modules
[type
]->ref
> 0)
351 #if (__FreeBSD_version < 502103)
352 destroy_dev(makedev(CDEV_MAJOR
, type
));
354 destroy_dev(altqsw
[type
].dev
);
356 altqsw
[type
] = noqdisc
;
357 altq_modules
[type
] = NULL
;
362 altq_module_handler(module_t mod
, int cmd
, void *arg
)
364 struct altq_module_data
*data
= (struct altq_module_data
*)arg
;
369 error
= altq_module_register(data
);
373 error
= altq_module_deregister(data
);
384 #endif /* ALTQ_KLD */
385 #endif /* ALTQ3_COMPAT */