Home | History | Annotate | Line # | Download | only in libaltq
qop_priq.c revision 1.5.64.1
      1  1.5.64.1      tls /*	$NetBSD: qop_priq.c,v 1.5.64.1 2014/08/20 00:05:06 tls Exp $	*/
      2       1.5   itojun /*	$KAME: qop_priq.c,v 1.4 2001/12/03 08:20:55 kjc Exp $	*/
      3       1.1  thorpej /*
      4       1.1  thorpej  * Copyright (C) 2000
      5       1.1  thorpej  *	Sony Computer Science Laboratories, Inc.  All rights reserved.
      6       1.1  thorpej  *
      7       1.1  thorpej  * Redistribution and use in source and binary forms, with or without
      8       1.1  thorpej  * modification, are permitted provided that the following conditions
      9       1.1  thorpej  * are met:
     10       1.1  thorpej  * 1. Redistributions of source code must retain the above copyright
     11       1.1  thorpej  *    notice, this list of conditions and the following disclaimer.
     12       1.1  thorpej  * 2. Redistributions in binary form must reproduce the above copyright
     13       1.1  thorpej  *    notice, this list of conditions and the following disclaimer in the
     14       1.1  thorpej  *    documentation and/or other materials provided with the distribution.
     15       1.1  thorpej  *
     16       1.1  thorpej  * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND
     17       1.1  thorpej  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18       1.1  thorpej  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19       1.1  thorpej  * ARE DISCLAIMED.  IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE
     20       1.1  thorpej  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21       1.1  thorpej  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22       1.1  thorpej  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23       1.1  thorpej  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24       1.1  thorpej  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25       1.1  thorpej  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26       1.1  thorpej  * SUCH DAMAGE.
     27       1.1  thorpej  */
     28       1.1  thorpej 
     29       1.1  thorpej #include <sys/param.h>
     30       1.1  thorpej #include <sys/socket.h>
     31       1.1  thorpej #include <sys/sockio.h>
     32       1.1  thorpej #include <sys/ioctl.h>
     33       1.1  thorpej #include <sys/fcntl.h>
     34       1.1  thorpej #include <net/if.h>
     35       1.1  thorpej #include <netinet/in.h>
     36       1.1  thorpej #include <arpa/inet.h>
     37       1.1  thorpej 
     38       1.1  thorpej #include <stdio.h>
     39       1.1  thorpej #include <stdlib.h>
     40       1.1  thorpej #include <unistd.h>
     41       1.1  thorpej #include <stddef.h>
     42       1.1  thorpej #include <string.h>
     43       1.1  thorpej #include <ctype.h>
     44       1.1  thorpej #include <errno.h>
     45       1.1  thorpej #include <syslog.h>
     46       1.1  thorpej #include <netdb.h>
     47       1.1  thorpej 
     48       1.1  thorpej #include <altq/altq.h>
     49       1.1  thorpej #include <altq/altq_priq.h>
     50       1.1  thorpej #include "altq_qop.h"
     51       1.1  thorpej #include "qop_priq.h"
     52       1.1  thorpej 
     53       1.2   itojun static int qop_priq_enable_hook(struct ifinfo *);
     54       1.1  thorpej 
     55       1.2   itojun static int priq_attach(struct ifinfo *);
     56       1.2   itojun static int priq_detach(struct ifinfo *);
     57       1.2   itojun static int priq_clear(struct ifinfo *);
     58       1.2   itojun static int priq_enable(struct ifinfo *);
     59       1.2   itojun static int priq_disable(struct ifinfo *);
     60       1.2   itojun static int priq_add_class(struct classinfo *);
     61       1.2   itojun static int priq_modify_class(struct classinfo *, void *);
     62       1.2   itojun static int priq_delete_class(struct classinfo *);
     63       1.2   itojun static int priq_add_filter(struct fltrinfo *);
     64       1.2   itojun static int priq_delete_filter(struct fltrinfo *);
     65       1.1  thorpej 
     66       1.1  thorpej #define PRIQ_DEVICE	"/dev/altq/priq"
     67       1.1  thorpej 
     68       1.1  thorpej static int priq_fd = -1;
     69       1.1  thorpej static int priq_refcount = 0;
     70       1.1  thorpej 
     71       1.1  thorpej static struct qdisc_ops priq_qdisc = {
     72       1.1  thorpej 	ALTQT_PRIQ,
     73       1.1  thorpej 	"priq",
     74       1.1  thorpej 	priq_attach,
     75       1.1  thorpej 	priq_detach,
     76       1.1  thorpej 	priq_clear,
     77       1.1  thorpej 	priq_enable,
     78       1.1  thorpej 	priq_disable,
     79       1.1  thorpej 	priq_add_class,
     80       1.1  thorpej 	priq_modify_class,
     81       1.1  thorpej 	priq_delete_class,
     82       1.1  thorpej 	priq_add_filter,
     83       1.1  thorpej 	priq_delete_filter,
     84       1.1  thorpej };
     85       1.1  thorpej 
     86       1.1  thorpej #define EQUAL(s1, s2)	(strcmp((s1), (s2)) == 0)
     87       1.1  thorpej 
     88       1.1  thorpej /*
     89       1.1  thorpej  * parser interface
     90       1.1  thorpej  */
     91       1.1  thorpej int
     92       1.1  thorpej priq_interface_parser(const char *ifname, int argc, char **argv)
     93       1.1  thorpej {
     94       1.1  thorpej 	u_int  	bandwidth = 100000000;	/* 100Mbps */
     95       1.1  thorpej 	u_int	tbrsize = 0;
     96       1.1  thorpej 	int	flags = 0;
     97       1.1  thorpej 
     98       1.1  thorpej 	/*
     99       1.1  thorpej 	 * process options
    100       1.1  thorpej 	 */
    101       1.1  thorpej 	while (argc > 0) {
    102       1.1  thorpej 		if (EQUAL(*argv, "bandwidth")) {
    103       1.1  thorpej 			argc--; argv++;
    104       1.1  thorpej 			if (argc > 0)
    105       1.1  thorpej 				bandwidth = atobps(*argv);
    106       1.1  thorpej 		} else if (EQUAL(*argv, "tbrsize")) {
    107       1.1  thorpej 			argc--; argv++;
    108       1.1  thorpej 			if (argc > 0)
    109       1.1  thorpej 				tbrsize = atobytes(*argv);
    110       1.1  thorpej 		} else if (EQUAL(*argv, "priq")) {
    111       1.1  thorpej 			/* just skip */
    112       1.1  thorpej 		} else {
    113       1.5   itojun 			LOG(LOG_ERR, 0, "Unknown keyword '%s'", *argv);
    114       1.1  thorpej 			return (0);
    115       1.1  thorpej 		}
    116       1.1  thorpej 		argc--; argv++;
    117       1.1  thorpej 	}
    118       1.1  thorpej 
    119       1.1  thorpej 	if (qcmd_tbr_register(ifname, bandwidth, tbrsize) != 0)
    120       1.1  thorpej 		return (0);
    121       1.1  thorpej 
    122       1.1  thorpej 	if (qcmd_priq_add_if(ifname, bandwidth, flags) != 0)
    123       1.1  thorpej 		return (0);
    124       1.1  thorpej 	return (1);
    125       1.1  thorpej }
    126       1.1  thorpej 
    127       1.1  thorpej int
    128       1.1  thorpej priq_class_parser(const char *ifname, const char *class_name,
    129       1.1  thorpej 		  const char *parent_name, int argc, char **argv)
    130       1.1  thorpej {
    131       1.1  thorpej 	int	pri = 0, qlimit = 50;
    132       1.1  thorpej 	int	flags = 0, error;
    133       1.1  thorpej 
    134       1.1  thorpej 	while (argc > 0) {
    135       1.1  thorpej 		if (EQUAL(*argv, "priority")) {
    136       1.1  thorpej 			argc--; argv++;
    137       1.1  thorpej 			if (argc > 0)
    138       1.1  thorpej 				pri = strtoul(*argv, NULL, 0);
    139       1.1  thorpej 		} else if (EQUAL(*argv, "qlimit")) {
    140       1.1  thorpej 			argc--; argv++;
    141       1.1  thorpej 			if (argc > 0)
    142       1.1  thorpej 				qlimit = strtoul(*argv, NULL, 0);
    143       1.1  thorpej 		} else if (EQUAL(*argv, "default")) {
    144       1.1  thorpej 			flags |= PRCF_DEFAULTCLASS;
    145       1.1  thorpej 		} else if (EQUAL(*argv, "red")) {
    146       1.1  thorpej 			flags |= PRCF_RED;
    147       1.1  thorpej 		} else if (EQUAL(*argv, "ecn")) {
    148       1.1  thorpej 			flags |= PRCF_ECN;
    149       1.1  thorpej 		} else if (EQUAL(*argv, "rio")) {
    150       1.1  thorpej 			flags |= PRCF_RIO;
    151       1.1  thorpej 		} else if (EQUAL(*argv, "cleardscp")) {
    152       1.1  thorpej 			flags |= PRCF_CLEARDSCP;
    153       1.1  thorpej 		} else {
    154       1.1  thorpej 			LOG(LOG_ERR, 0,
    155       1.4   itojun 			    "Unknown keyword '%s' in %s, line %d",
    156       1.1  thorpej 			    *argv, altqconfigfile, line_no);
    157       1.1  thorpej 			return (0);
    158       1.1  thorpej 		}
    159       1.1  thorpej 
    160       1.1  thorpej 		argc--; argv++;
    161       1.1  thorpej 	}
    162       1.1  thorpej 
    163       1.1  thorpej 	if ((flags & PRCF_ECN) && (flags & (PRCF_RED|PRCF_RIO)) == 0)
    164       1.1  thorpej 		flags |= PRCF_RED;
    165       1.1  thorpej 
    166       1.1  thorpej 	error = qcmd_priq_add_class(ifname, class_name, pri, qlimit, flags);
    167       1.1  thorpej 
    168       1.1  thorpej 	if (error) {
    169       1.4   itojun 		LOG(LOG_ERR, errno, "priq_class_parser: %s",
    170       1.1  thorpej 		    qoperror(error));
    171       1.1  thorpej 		return (0);
    172       1.1  thorpej 	}
    173       1.1  thorpej 	return (1);
    174       1.1  thorpej }
    175       1.1  thorpej 
    176       1.1  thorpej /*
    177       1.1  thorpej  * qcmd api
    178       1.1  thorpej  */
    179       1.1  thorpej int
    180       1.1  thorpej qcmd_priq_add_if(const char *ifname, u_int bandwidth, int flags)
    181       1.1  thorpej {
    182       1.1  thorpej 	int error;
    183       1.1  thorpej 
    184       1.1  thorpej 	error = qop_priq_add_if(NULL, ifname, bandwidth, flags);
    185       1.1  thorpej 	if (error != 0)
    186       1.4   itojun 		LOG(LOG_ERR, errno, "%s: can't add priq on interface '%s'",
    187       1.1  thorpej 		    qoperror(error), ifname);
    188       1.1  thorpej 	return (error);
    189       1.1  thorpej }
    190       1.1  thorpej 
    191       1.1  thorpej int
    192       1.1  thorpej qcmd_priq_add_class(const char *ifname, const char *class_name,
    193       1.1  thorpej 		    int pri, int qlimit, int flags)
    194       1.1  thorpej {
    195       1.1  thorpej 	struct ifinfo *ifinfo;
    196       1.1  thorpej 	int error = 0;
    197       1.1  thorpej 
    198       1.1  thorpej 	if ((ifinfo = ifname2ifinfo(ifname)) == NULL)
    199       1.1  thorpej 		error = QOPERR_BADIF;
    200       1.1  thorpej 
    201       1.1  thorpej 	if (error == 0)
    202       1.1  thorpej 		error = qop_priq_add_class(NULL, class_name, ifinfo,
    203       1.1  thorpej 					   pri, qlimit, flags);
    204       1.1  thorpej 	if (error != 0)
    205       1.1  thorpej 		LOG(LOG_ERR, errno,
    206       1.4   itojun 		    "priq: %s: can't add class '%s' on interface '%s'",
    207       1.1  thorpej 		    qoperror(error), class_name, ifname);
    208       1.1  thorpej 	return (error);
    209       1.1  thorpej }
    210       1.1  thorpej 
    211       1.1  thorpej int
    212       1.1  thorpej qcmd_priq_modify_class(const char *ifname, const char *class_name,
    213       1.1  thorpej 		       int pri, int qlimit, int flags)
    214       1.1  thorpej {
    215       1.1  thorpej 	struct ifinfo *ifinfo;
    216       1.1  thorpej 	struct classinfo *clinfo;
    217       1.1  thorpej 
    218       1.1  thorpej 	if ((ifinfo = ifname2ifinfo(ifname)) == NULL)
    219       1.1  thorpej 		return (QOPERR_BADIF);
    220       1.1  thorpej 
    221       1.1  thorpej 	if ((clinfo = clname2clinfo(ifinfo, class_name)) == NULL)
    222       1.1  thorpej 		return (QOPERR_BADCLASS);
    223       1.1  thorpej 
    224       1.1  thorpej 	return qop_priq_modify_class(clinfo, pri, qlimit, flags);
    225       1.1  thorpej }
    226       1.1  thorpej 
    227       1.1  thorpej /*
    228       1.1  thorpej  * qop api
    229       1.1  thorpej  */
    230       1.1  thorpej int
    231       1.1  thorpej qop_priq_add_if(struct ifinfo **rp, const char *ifname,
    232       1.1  thorpej 		u_int bandwidth, int flags)
    233       1.1  thorpej {
    234       1.1  thorpej 	struct ifinfo *ifinfo = NULL;
    235       1.1  thorpej 	struct priq_ifinfo *priq_ifinfo = NULL;
    236       1.1  thorpej 	int error;
    237       1.1  thorpej 
    238       1.1  thorpej 	if ((priq_ifinfo = calloc(1, sizeof(*priq_ifinfo))) == NULL)
    239       1.1  thorpej 		return (QOPERR_NOMEM);
    240       1.1  thorpej 
    241       1.1  thorpej 	error = qop_add_if(&ifinfo, ifname, bandwidth,
    242       1.1  thorpej 			   &priq_qdisc, priq_ifinfo);
    243       1.1  thorpej 	if (error != 0)
    244       1.1  thorpej 		goto err_ret;
    245       1.1  thorpej 
    246       1.1  thorpej 	/* set enable hook */
    247       1.1  thorpej 	ifinfo->enable_hook = qop_priq_enable_hook;
    248       1.1  thorpej 
    249       1.1  thorpej 	if (rp != NULL)
    250       1.1  thorpej 		*rp = ifinfo;
    251       1.1  thorpej 	return (0);
    252       1.1  thorpej 
    253       1.1  thorpej  err_ret:
    254       1.1  thorpej 	if (priq_ifinfo != NULL) {
    255       1.1  thorpej 		free(priq_ifinfo);
    256       1.1  thorpej 		if (ifinfo != NULL)
    257       1.1  thorpej 			ifinfo->private = NULL;
    258       1.1  thorpej 	}
    259       1.1  thorpej 	return (error);
    260       1.1  thorpej }
    261       1.1  thorpej 
    262       1.1  thorpej int
    263       1.1  thorpej qop_priq_add_class(struct classinfo **rp, const char *class_name,
    264       1.1  thorpej 		   struct ifinfo *ifinfo, int pri, int qlimit, int flags)
    265       1.1  thorpej {
    266       1.1  thorpej 	struct classinfo *clinfo;
    267       1.1  thorpej 	struct priq_ifinfo *priq_ifinfo;
    268       1.1  thorpej 	struct priq_classinfo *priq_clinfo = NULL;
    269       1.1  thorpej 	int error;
    270       1.1  thorpej 
    271       1.1  thorpej 	priq_ifinfo = ifinfo->private;
    272       1.1  thorpej 	if ((flags & PRCF_DEFAULTCLASS) && priq_ifinfo->default_class != NULL)
    273       1.1  thorpej 		return (QOPERR_CLASS_INVAL);
    274       1.1  thorpej 
    275       1.1  thorpej 	if ((priq_clinfo = calloc(1, sizeof(*priq_clinfo))) == NULL) {
    276       1.1  thorpej 		error = QOPERR_NOMEM;
    277       1.1  thorpej 		goto err_ret;
    278       1.1  thorpej 	}
    279       1.1  thorpej 
    280       1.1  thorpej 	priq_clinfo->pri = pri;
    281       1.1  thorpej 	priq_clinfo->qlimit = qlimit;
    282       1.1  thorpej 	priq_clinfo->flags = flags;
    283       1.1  thorpej 
    284       1.1  thorpej 	if ((error = qop_add_class(&clinfo, class_name, ifinfo, NULL,
    285       1.1  thorpej 				   priq_clinfo)) != 0)
    286       1.1  thorpej 		goto err_ret;
    287       1.1  thorpej 
    288       1.1  thorpej 	if (flags & PRCF_DEFAULTCLASS)
    289       1.1  thorpej 		priq_ifinfo->default_class = clinfo;
    290       1.1  thorpej 
    291       1.1  thorpej 	if (rp != NULL)
    292       1.1  thorpej 		*rp = clinfo;
    293       1.1  thorpej 	return (0);
    294       1.1  thorpej 
    295       1.1  thorpej  err_ret:
    296       1.1  thorpej 	if (priq_clinfo != NULL) {
    297       1.1  thorpej 		free(priq_clinfo);
    298       1.1  thorpej 		clinfo->private = NULL;
    299       1.1  thorpej 	}
    300       1.1  thorpej 
    301       1.1  thorpej 	return (error);
    302       1.1  thorpej }
    303       1.1  thorpej 
    304       1.1  thorpej int
    305       1.1  thorpej qop_priq_modify_class(struct classinfo *clinfo,
    306       1.1  thorpej 		      int pri, int qlimit, int flags)
    307       1.1  thorpej {
    308  1.5.64.1      tls 	struct priq_classinfo *priq_clinfo;
    309       1.1  thorpej 	int error;
    310       1.1  thorpej 
    311       1.1  thorpej 	priq_clinfo = clinfo->private;
    312       1.1  thorpej 	if (clinfo->parent == NULL)
    313       1.1  thorpej 		return (QOPERR_CLASS_INVAL);
    314       1.1  thorpej 
    315       1.1  thorpej 	priq_clinfo->pri = pri;
    316       1.1  thorpej 	priq_clinfo->qlimit = qlimit;
    317       1.1  thorpej 	priq_clinfo->flags = flags;
    318       1.1  thorpej 
    319       1.1  thorpej 	error = qop_modify_class(clinfo, NULL);
    320       1.1  thorpej 	if (error == 0)
    321       1.1  thorpej 		return (0);
    322       1.1  thorpej 	return (error);
    323       1.1  thorpej }
    324       1.1  thorpej 
    325       1.1  thorpej /*
    326       1.1  thorpej  * sanity check at enabling priq:
    327       1.1  thorpej  *  1. there must one default class for an interface
    328       1.1  thorpej  */
    329       1.1  thorpej static int
    330       1.1  thorpej qop_priq_enable_hook(struct ifinfo *ifinfo)
    331       1.1  thorpej {
    332       1.1  thorpej 	struct priq_ifinfo *priq_ifinfo;
    333       1.1  thorpej 
    334       1.1  thorpej 	priq_ifinfo = ifinfo->private;
    335       1.1  thorpej 	if (priq_ifinfo->default_class == NULL) {
    336       1.4   itojun 		LOG(LOG_ERR, 0, "priq: no default class on interface %s!",
    337       1.1  thorpej 		    ifinfo->ifname);
    338       1.1  thorpej 		return (QOPERR_CLASS);
    339       1.1  thorpej 	}
    340       1.1  thorpej 	return (0);
    341       1.1  thorpej }
    342       1.1  thorpej 
    343       1.1  thorpej /*
    344       1.1  thorpej  *  system call interfaces for qdisc_ops
    345       1.1  thorpej  */
    346       1.1  thorpej static int
    347       1.1  thorpej priq_attach(struct ifinfo *ifinfo)
    348       1.1  thorpej {
    349       1.1  thorpej 	struct priq_interface iface;
    350       1.1  thorpej 
    351       1.1  thorpej 	memset(&iface, 0, sizeof(iface));
    352       1.1  thorpej 	strncpy(iface.ifname, ifinfo->ifname, IFNAMSIZ);
    353       1.1  thorpej 
    354       1.1  thorpej 	if (priq_fd < 0 &&
    355       1.1  thorpej 	    (priq_fd = open(PRIQ_DEVICE, O_RDWR)) < 0 &&
    356       1.1  thorpej 	    (priq_fd = open_module(PRIQ_DEVICE, O_RDWR)) < 0) {
    357       1.4   itojun 		LOG(LOG_ERR, errno, "PRIQ open");
    358       1.1  thorpej 		return (QOPERR_SYSCALL);
    359       1.1  thorpej 	}
    360       1.1  thorpej 
    361       1.1  thorpej 	priq_refcount++;
    362       1.1  thorpej 	memset(&iface, 0, sizeof(iface));
    363       1.1  thorpej 	strncpy(iface.ifname, ifinfo->ifname, IFNAMSIZ);
    364       1.1  thorpej 	iface.arg = ifinfo->bandwidth;
    365       1.1  thorpej 
    366       1.1  thorpej 	if (ioctl(priq_fd, PRIQ_IF_ATTACH, &iface) < 0)
    367       1.1  thorpej 		return (QOPERR_SYSCALL);
    368       1.1  thorpej 	return (0);
    369       1.1  thorpej }
    370       1.1  thorpej 
    371       1.1  thorpej static int
    372       1.1  thorpej priq_detach(struct ifinfo *ifinfo)
    373       1.1  thorpej {
    374       1.1  thorpej 	struct priq_interface iface;
    375       1.1  thorpej 
    376       1.1  thorpej 	memset(&iface, 0, sizeof(iface));
    377       1.1  thorpej 	strncpy(iface.ifname, ifinfo->ifname, IFNAMSIZ);
    378       1.1  thorpej 
    379       1.1  thorpej 	if (ioctl(priq_fd, PRIQ_IF_DETACH, &iface) < 0)
    380       1.1  thorpej 		return (QOPERR_SYSCALL);
    381       1.1  thorpej 
    382       1.1  thorpej 	if (--priq_refcount == 0) {
    383       1.1  thorpej 		close(priq_fd);
    384       1.1  thorpej 		priq_fd = -1;
    385       1.1  thorpej 	}
    386       1.1  thorpej 	return (0);
    387       1.1  thorpej }
    388       1.1  thorpej 
    389       1.1  thorpej static int
    390       1.1  thorpej priq_clear(struct ifinfo *ifinfo)
    391       1.1  thorpej {
    392       1.1  thorpej 	struct priq_interface iface;
    393       1.1  thorpej 
    394       1.1  thorpej 	memset(&iface, 0, sizeof(iface));
    395       1.1  thorpej 	strncpy(iface.ifname, ifinfo->ifname, IFNAMSIZ);
    396       1.1  thorpej 
    397       1.1  thorpej 	if (ioctl(priq_fd, PRIQ_CLEAR, &iface) < 0)
    398       1.1  thorpej 		return (QOPERR_SYSCALL);
    399       1.1  thorpej 	return (0);
    400       1.1  thorpej }
    401       1.1  thorpej 
    402       1.1  thorpej static int
    403       1.1  thorpej priq_enable(struct ifinfo *ifinfo)
    404       1.1  thorpej {
    405       1.1  thorpej 	struct priq_interface iface;
    406       1.1  thorpej 
    407       1.1  thorpej 	memset(&iface, 0, sizeof(iface));
    408       1.1  thorpej 	strncpy(iface.ifname, ifinfo->ifname, IFNAMSIZ);
    409       1.1  thorpej 
    410       1.1  thorpej 	if (ioctl(priq_fd, PRIQ_ENABLE, &iface) < 0)
    411       1.1  thorpej 		return (QOPERR_SYSCALL);
    412       1.1  thorpej 	return (0);
    413       1.1  thorpej }
    414       1.1  thorpej 
    415       1.1  thorpej static int
    416       1.1  thorpej priq_disable(struct ifinfo *ifinfo)
    417       1.1  thorpej {
    418       1.1  thorpej 	struct priq_interface iface;
    419       1.1  thorpej 
    420       1.1  thorpej 	memset(&iface, 0, sizeof(iface));
    421       1.1  thorpej 	strncpy(iface.ifname, ifinfo->ifname, IFNAMSIZ);
    422       1.1  thorpej 
    423       1.1  thorpej 	if (ioctl(priq_fd, PRIQ_DISABLE, &iface) < 0)
    424       1.1  thorpej 		return (QOPERR_SYSCALL);
    425       1.1  thorpej 	return (0);
    426       1.1  thorpej }
    427       1.1  thorpej 
    428       1.1  thorpej static int
    429       1.1  thorpej priq_add_class(struct classinfo *clinfo)
    430       1.1  thorpej {
    431       1.1  thorpej 	struct priq_add_class class_add;
    432       1.1  thorpej 	struct priq_classinfo *priq_clinfo;
    433       1.1  thorpej 
    434       1.1  thorpej 	priq_clinfo = clinfo->private;
    435       1.1  thorpej 
    436       1.1  thorpej 	memset(&class_add, 0, sizeof(class_add));
    437       1.1  thorpej 	strncpy(class_add.iface.ifname, clinfo->ifinfo->ifname, IFNAMSIZ);
    438       1.1  thorpej 
    439       1.1  thorpej 	class_add.pri = priq_clinfo->pri;
    440       1.1  thorpej 	class_add.qlimit = priq_clinfo->qlimit;
    441       1.1  thorpej 	class_add.flags = priq_clinfo->flags;
    442       1.1  thorpej 	if (ioctl(priq_fd, PRIQ_ADD_CLASS, &class_add) < 0) {
    443       1.1  thorpej 		clinfo->handle = PRIQ_NULLCLASS_HANDLE;
    444       1.1  thorpej 		return (QOPERR_SYSCALL);
    445       1.1  thorpej 	}
    446       1.1  thorpej 	clinfo->handle = class_add.class_handle;
    447       1.1  thorpej 	return (0);
    448       1.1  thorpej }
    449       1.1  thorpej 
    450       1.1  thorpej static int
    451       1.1  thorpej priq_modify_class(struct classinfo *clinfo, void *arg)
    452       1.1  thorpej {
    453       1.1  thorpej 	struct priq_modify_class class_mod;
    454       1.1  thorpej 	struct priq_classinfo *priq_clinfo;
    455       1.1  thorpej 
    456       1.1  thorpej 	priq_clinfo = clinfo->private;
    457       1.1  thorpej 
    458       1.1  thorpej 	memset(&class_mod, 0, sizeof(class_mod));
    459       1.1  thorpej 	strncpy(class_mod.iface.ifname, clinfo->ifinfo->ifname, IFNAMSIZ);
    460       1.1  thorpej 	class_mod.class_handle = clinfo->handle;
    461       1.1  thorpej 
    462       1.1  thorpej 	class_mod.pri = priq_clinfo->pri;
    463       1.1  thorpej 	class_mod.qlimit = priq_clinfo->qlimit;
    464       1.1  thorpej 	class_mod.flags = priq_clinfo->flags;
    465       1.1  thorpej 
    466       1.1  thorpej 	if (ioctl(priq_fd, PRIQ_MOD_CLASS, &class_mod) < 0)
    467       1.1  thorpej 		return (QOPERR_SYSCALL);
    468       1.1  thorpej 	return (0);
    469       1.1  thorpej }
    470       1.1  thorpej 
    471       1.1  thorpej static int
    472       1.1  thorpej priq_delete_class(struct classinfo *clinfo)
    473       1.1  thorpej {
    474       1.1  thorpej 	struct priq_delete_class class_delete;
    475       1.1  thorpej 
    476       1.1  thorpej 	if (clinfo->handle == PRIQ_NULLCLASS_HANDLE)
    477       1.1  thorpej 		return (0);
    478       1.1  thorpej 
    479       1.1  thorpej 	memset(&class_delete, 0, sizeof(class_delete));
    480       1.1  thorpej 	strncpy(class_delete.iface.ifname, clinfo->ifinfo->ifname,
    481       1.1  thorpej 		IFNAMSIZ);
    482       1.1  thorpej 	class_delete.class_handle = clinfo->handle;
    483       1.1  thorpej 
    484       1.1  thorpej 	if (ioctl(priq_fd, PRIQ_DEL_CLASS, &class_delete) < 0)
    485       1.1  thorpej 		return (QOPERR_SYSCALL);
    486       1.1  thorpej 	return (0);
    487       1.1  thorpej }
    488       1.1  thorpej 
    489       1.1  thorpej static int
    490       1.1  thorpej priq_add_filter(struct fltrinfo *fltrinfo)
    491       1.1  thorpej {
    492       1.1  thorpej 	struct priq_add_filter fltr_add;
    493       1.1  thorpej 
    494       1.1  thorpej 	memset(&fltr_add, 0, sizeof(fltr_add));
    495       1.1  thorpej 	strncpy(fltr_add.iface.ifname, fltrinfo->clinfo->ifinfo->ifname,
    496       1.1  thorpej 		IFNAMSIZ);
    497       1.1  thorpej 	fltr_add.class_handle = fltrinfo->clinfo->handle;
    498       1.1  thorpej 	fltr_add.filter = fltrinfo->fltr;
    499       1.1  thorpej 
    500       1.1  thorpej 	if (ioctl(priq_fd, PRIQ_ADD_FILTER, &fltr_add) < 0)
    501       1.1  thorpej 		return (QOPERR_SYSCALL);
    502       1.1  thorpej 	fltrinfo->handle = fltr_add.filter_handle;
    503       1.1  thorpej 	return (0);
    504       1.1  thorpej }
    505       1.1  thorpej 
    506       1.1  thorpej static int
    507       1.1  thorpej priq_delete_filter(struct fltrinfo *fltrinfo)
    508       1.1  thorpej {
    509       1.1  thorpej 	struct priq_delete_filter fltr_del;
    510       1.1  thorpej 
    511       1.1  thorpej 	memset(&fltr_del, 0, sizeof(fltr_del));
    512       1.1  thorpej 	strncpy(fltr_del.iface.ifname, fltrinfo->clinfo->ifinfo->ifname,
    513       1.1  thorpej 		IFNAMSIZ);
    514       1.1  thorpej 	fltr_del.filter_handle = fltrinfo->handle;
    515       1.1  thorpej 
    516       1.1  thorpej 	if (ioctl(priq_fd, PRIQ_DEL_FILTER, &fltr_del) < 0)
    517       1.1  thorpej 		return (QOPERR_SYSCALL);
    518       1.1  thorpej 	return (0);
    519       1.1  thorpej }
    520       1.1  thorpej 
    521       1.1  thorpej 
    522