diff options
author | Kenjiro Cho <kjc@cvs.openbsd.org> | 2002-12-16 09:18:07 +0000 |
---|---|---|
committer | Kenjiro Cho <kjc@cvs.openbsd.org> | 2002-12-16 09:18:07 +0000 |
commit | b832c86cc52bdbf120e78217d21df3af5977a61a (patch) | |
tree | ffa7692cbbba583d4becd2d93be35cbe22f09192 | |
parent | 322f5fb510ece19f248fa04cf2639fabfa5b74ea (diff) |
switchover to pf-based altq.
- remove files which are no longer used, or we don't have plans to support
in pf in the near future.
- remove altq ioctl related stuff.
- convert the PRIQ, HFSC and RIO modules to pf-based altq.
(these are not enabled in GENERIC, CDNR is not converted yet.)
-rw-r--r-- | sys/altq/altq_afmap.c | 400 | ||||
-rw-r--r-- | sys/altq/altq_afmap.h | 104 | ||||
-rw-r--r-- | sys/altq/altq_blue.c | 670 | ||||
-rw-r--r-- | sys/altq/altq_blue.h | 119 | ||||
-rw-r--r-- | sys/altq/altq_cbq.c | 712 | ||||
-rw-r--r-- | sys/altq/altq_cbq.h | 96 | ||||
-rw-r--r-- | sys/altq/altq_cdnr.c | 247 | ||||
-rw-r--r-- | sys/altq/altq_cdnr.h | 34 | ||||
-rw-r--r-- | sys/altq/altq_conf.c | 414 | ||||
-rw-r--r-- | sys/altq/altq_conf.h | 108 | ||||
-rw-r--r-- | sys/altq/altq_fifoq.c | 408 | ||||
-rw-r--r-- | sys/altq/altq_fifoq.h | 80 | ||||
-rw-r--r-- | sys/altq/altq_flowvalve.h | 93 | ||||
-rw-r--r-- | sys/altq/altq_hfsc.c | 1092 | ||||
-rw-r--r-- | sys/altq/altq_hfsc.h | 121 | ||||
-rw-r--r-- | sys/altq/altq_localq.c | 65 | ||||
-rw-r--r-- | sys/altq/altq_priq.c | 540 | ||||
-rw-r--r-- | sys/altq/altq_priq.h | 71 | ||||
-rw-r--r-- | sys/altq/altq_red.c | 859 | ||||
-rw-r--r-- | sys/altq/altq_red.h | 70 | ||||
-rw-r--r-- | sys/altq/altq_rio.c | 370 | ||||
-rw-r--r-- | sys/altq/altq_rio.h | 13 | ||||
-rw-r--r-- | sys/altq/altq_rmclass.c | 6 | ||||
-rw-r--r-- | sys/altq/altq_subr.c | 1089 | ||||
-rw-r--r-- | sys/altq/altq_var.h | 139 | ||||
-rw-r--r-- | sys/altq/altq_wfq.c | 739 | ||||
-rw-r--r-- | sys/altq/altq_wfq.h | 125 | ||||
-rw-r--r-- | sys/altq/altqconf.h | 16 |
28 files changed, 830 insertions, 7970 deletions
diff --git a/sys/altq/altq_afmap.c b/sys/altq/altq_afmap.c deleted file mode 100644 index d718226e2c1..00000000000 --- a/sys/altq/altq_afmap.c +++ /dev/null @@ -1,400 +0,0 @@ -/* $OpenBSD: altq_afmap.c,v 1.4 2002/11/26 01:03:33 henning Exp $ */ -/* $KAME: altq_afmap.c,v 1.7 2000/12/14 08:12:45 thorpej Exp $ */ - -/* - * Copyright (C) 1997-2000 - * Sony Computer Science Laboratories Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * experimental: - * mapping an ip flow to atm vpi/vci. - * this module is not related to queueing at all, but uses the altq - * flowinfo mechanism. it's just put in the altq framework since - * it is easy to add devices to altq. - */ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/malloc.h> -#include <sys/mbuf.h> -#include <sys/uio.h> -#include <sys/socket.h> -#include <sys/systm.h> -#include <sys/proc.h> -#include <sys/errno.h> -#include <sys/time.h> -#include <sys/kernel.h> - -#include <net/if.h> -#include <net/if_types.h> -#include <netinet/in.h> - -#include <altq/altq.h> -#include <altq/altq_conf.h> -#include <altq/altq_afmap.h> - -LIST_HEAD(, afm_head) afhead_chain; - -static struct afm *afm_match4(struct afm_head *, struct flowinfo_in *); -#ifdef INET6 -static struct afm *afm_match6(struct afm_head *, struct flowinfo_in6 *); -#endif - -/* - * rules to block interrupts: afm_match can be called from a net - * level interrupt so that other routines handling the lists should - * be called in splnet(). - */ -int -afm_alloc(ifp) - struct ifnet *ifp; -{ - struct afm_head *head; - - MALLOC(head, struct afm_head *, sizeof(struct afm_head), - M_DEVBUF, M_WAITOK); - if (head == NULL) - panic("afm_alloc: malloc failed!"); - bzero(head, sizeof(struct afm_head)); - - /* initialize per interface afmap list */ - LIST_INIT(&head->afh_head); - - head->afh_ifp = ifp; - - /* add this afm_head to the chain */ - LIST_INSERT_HEAD(&afhead_chain, head, afh_chain); - - return (0); -} - -int -afm_dealloc(ifp) - struct ifnet *ifp; -{ - struct afm_head *head; - - for (head = afhead_chain.lh_first; head != NULL; - head = head->afh_chain.le_next) - if (head->afh_ifp == ifp) - break; - if (head == NULL) - return (-1); - - afm_removeall(ifp); - - LIST_REMOVE(head, afh_chain); - - FREE(head, M_DEVBUF); - return 0; -} - -struct afm * -afm_top(ifp) - struct ifnet *ifp; -{ - struct afm_head *head; - - for (head = afhead_chain.lh_first; head != NULL; - head = head->afh_chain.le_next) - if (head->afh_ifp == ifp) - break; - if (head == NULL) - return NULL; - - return (head->afh_head.lh_first); -} - -int afm_add(ifp, flowmap) - struct ifnet *ifp; - struct atm_flowmap *flowmap; -{ - struct afm_head *head; - struct afm *afm; - - for (head = afhead_chain.lh_first; head != NULL; - head = head->afh_chain.le_next) - if (head->afh_ifp == ifp) - break; - if (head == NULL) - return (-1); - - if (flowmap->af_flowinfo.fi_family == AF_INET) { - if (flowmap->af_flowinfo.fi_len != sizeof(struct flowinfo_in)) - return (EINVAL); -#ifdef INET6 - } else if (flowmap->af_flowinfo.fi_family == AF_INET6) { - if (flowmap->af_flowinfo.fi_len != sizeof(struct flowinfo_in6)) - return (EINVAL); -#endif - } else - return (EINVAL); - - MALLOC(afm, struct afm *, sizeof(struct afm), - M_DEVBUF, M_WAITOK); - if (afm == NULL) - return (ENOMEM); - bzero(afm, sizeof(struct afm)); - - afm->afm_vci = flowmap->af_vci; - afm->afm_vpi = flowmap->af_vpi; - bcopy(&flowmap->af_flowinfo, &afm->afm_flowinfo, - flowmap->af_flowinfo.fi_len); - - LIST_INSERT_HEAD(&head->afh_head, afm, afm_list); - return 0; -} - -int -afm_remove(afm) - struct afm *afm; -{ - LIST_REMOVE(afm, afm_list); - FREE(afm, M_DEVBUF); - return (0); -} - -int -afm_removeall(ifp) - struct ifnet *ifp; -{ - struct afm_head *head; - struct afm *afm; - - for (head = afhead_chain.lh_first; head != NULL; - head = head->afh_chain.le_next) - if (head->afh_ifp == ifp) - break; - if (head == NULL) - return (-1); - - while ((afm = head->afh_head.lh_first) != NULL) - afm_remove(afm); - return (0); -} - -struct afm * -afm_lookup(ifp, vpi, vci) - struct ifnet *ifp; - int vpi, vci; -{ - struct afm_head *head; - struct afm *afm; - - for (head = afhead_chain.lh_first; head != NULL; - head = head->afh_chain.le_next) - if (head->afh_ifp == ifp) - break; - if (head == NULL) - return NULL; - - for (afm = head->afh_head.lh_first; afm != NULL; - afm = afm->afm_list.le_next) - if (afm->afm_vpi == vpi && afm->afm_vci == vci) - break; - return afm; -} - -static struct afm * -afm_match4(head, fp) - struct afm_head *head; - struct flowinfo_in *fp; -{ - struct afm *afm; - - for (afm = head->afh_head.lh_first; afm != NULL; - afm = afm->afm_list.le_next) { - if (afm->afm_flowinfo4.fi_dst.s_addr != 0 && - afm->afm_flowinfo4.fi_dst.s_addr != fp->fi_dst.s_addr) - continue; - if (afm->afm_flowinfo4.fi_dport != 0 && - afm->afm_flowinfo4.fi_dport != fp->fi_dport) - continue; - if (afm->afm_flowinfo4.fi_src.s_addr != 0 && - afm->afm_flowinfo4.fi_src.s_addr != fp->fi_src.s_addr) - continue; - if (afm->afm_flowinfo4.fi_sport != 0 && - afm->afm_flowinfo4.fi_sport != fp->fi_sport) - continue; - if (afm->afm_flowinfo4.fi_proto != 0 && - afm->afm_flowinfo4.fi_proto != fp->fi_proto) - continue; - /* match found! */ - return (afm); - } - return NULL; -} - -#ifdef INET6 -static struct afm * -afm_match6(head, fp) - struct afm_head *head; - struct flowinfo_in6 *fp; -{ - struct afm *afm; - - for (afm = head->afh_head.lh_first; afm != NULL; - afm = afm->afm_list.le_next) { - if (afm->afm_flowinfo6.fi6_flowlabel != 0 && - afm->afm_flowinfo6.fi6_flowlabel != fp->fi6_flowlabel) - continue; -#ifdef notyet - if (!IN6_IS_ADDR_UNSPECIFIED(&afm->afm_flowinfo6.fi6_dst) && - !IN6_ARE_ADDR_EQUAL(&afm->afm_flowinfo6.fi6_dst, - &fp->fi6_dst)) - continue; - if (afm->afm_flowinfo6.fi6_dport != 0 && - afm->afm_flowinfo6.fi6_dport != fp->fi6_dport) - continue; -#endif - if (!IN6_IS_ADDR_UNSPECIFIED(&afm->afm_flowinfo6.fi6_src) && - !IN6_ARE_ADDR_EQUAL(&afm->afm_flowinfo6.fi6_src, - &fp->fi6_src)) - continue; -#ifdef notyet - if (afm->afm_flowinfo6.fi6_sport != 0 && - afm->afm_flowinfo6.fi6_sport != fp->fi6_sport) - continue; -#endif - if (afm->afm_flowinfo6.fi6_proto != 0 && - afm->afm_flowinfo6.fi6_proto != fp->fi6_proto) - continue; - /* match found! */ - return (afm); - } - return NULL; -} -#endif - -/* should be called in splimp() */ -struct afm * -afm_match(ifp, flow) - struct ifnet *ifp; - struct flowinfo *flow; -{ - struct afm_head *head; - - for (head = afhead_chain.lh_first; head != NULL; - head = head->afh_chain.le_next) - if (head->afh_ifp == ifp) - break; - if (head == NULL) - return NULL; - - switch (flow->fi_family) { - case AF_INET: - return (afm_match4(head, (struct flowinfo_in *)flow)); - -#ifdef INET6 - case AF_INET6: - return (afm_match6(head, (struct flowinfo_in6 *)flow)); -#endif - - default: - return NULL; - } -} - -/* - * afm device interface - */ -altqdev_decl(afm); - -int -afmopen(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - return 0; -} - -int -afmclose(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - int err, error = 0; - struct atm_flowmap fmap; - struct afm_head *head; - - for (head = afhead_chain.lh_first; head != NULL; - head = head->afh_chain.le_next) { - - /* call interface to clean up maps */ -#if defined(__NetBSD__) || defined(__OpenBSD__) - sprintf(fmap.af_ifname, "%s", head->afh_ifp->if_xname); -#else - sprintf(fmap.af_ifname, "%s%d", - head->afh_ifp->if_name, head->afh_ifp->if_unit); -#endif - err = afmioctl(dev, AFM_CLEANFMAP, (caddr_t)&fmap, flag, p); - if (err && error == 0) - error = err; - } - - return error; -} - -int -afmioctl(dev, cmd, addr, flag, p) - dev_t dev; - ioctlcmd_t cmd; - caddr_t addr; - int flag; - struct proc *p; -{ - int error = 0; - struct atm_flowmap *flowmap; - struct ifnet *ifp; - - /* check cmd for superuser only */ - switch (cmd) { - case AFM_GETFMAP: - break; - default: -#if (__FreeBSD_version > 400000) - error = suser(p); -#else - error = suser(p->p_ucred, &p->p_acflag); -#endif - if (error) - return (error); - break; - } - - /* lookup interface */ - flowmap = (struct atm_flowmap *)addr; - flowmap->af_ifname[IFNAMSIZ-1] = '\0'; - ifp = ifunit(flowmap->af_ifname); - if (ifp == NULL || ifp->if_ioctl == NULL || - (ifp->if_flags & IFF_RUNNING) == 0) - error = ENXIO; - else - error = ifp->if_ioctl(ifp, cmd, addr); - - return error; -} diff --git a/sys/altq/altq_afmap.h b/sys/altq/altq_afmap.h deleted file mode 100644 index 5bf014b25d9..00000000000 --- a/sys/altq/altq_afmap.h +++ /dev/null @@ -1,104 +0,0 @@ -/* $OpenBSD: altq_afmap.h,v 1.2 2002/03/14 01:26:26 millert Exp $ */ -/* $KAME: altq_afmap.h,v 1.5 2000/12/14 08:12:45 thorpej Exp $ */ - -/* - * Copyright (C) 1997-2000 - * Sony Computer Science Laboratories Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _ALTQ_ALTQ_AFMAP_H_ -#define _ALTQ_ALTQ_AFMAP_H_ - -#include <sys/queue.h> -#include <altq/altq.h> - -struct atm_flowmap { - char af_ifname[IFNAMSIZ]; /* if name, e.g. "en0" */ - u_int8_t af_vpi; - u_int16_t af_vci; - u_int32_t af_pcr; /* peek cell rate */ - union { - struct flowinfo afu_fi; - struct flowinfo_in afu_fi4; -#ifdef SIN6_LEN - struct flowinfo_in6 afu_fi6; -#endif - } af_fiu; -#define af_flowinfo af_fiu.afu_fi -#define af_flowinfo4 af_fiu.afu_fi4 -#define af_flowinfo6 af_fiu.afu_fi6 - - /* statistics */ - u_int32_t afs_packets; /* total packet count */ - u_int32_t afs_bytes; /* total byte count */ -}; - -/* set or get flowmap */ -#define AFM_ADDFMAP _IOWR('F', 30, struct atm_flowmap) -#define AFM_DELFMAP _IOWR('F', 31, struct atm_flowmap) -#define AFM_CLEANFMAP _IOWR('F', 32, struct atm_flowmap) -#define AFM_GETFMAP _IOWR('F', 33, struct atm_flowmap) - -#ifdef _KERNEL - -/* per flow information */ -struct afm { - LIST_ENTRY(afm) afm_list; - u_int16_t afm_vci; - u_int8_t afm_vpi; - union { - struct flowinfo afmu_fi; - struct flowinfo_in afmu_fi4; -#ifdef SIN6_LEN - struct flowinfo_in6 afmu_fi6; -#endif - } afm_fiu; -#define afm_flowinfo afm_fiu.afmu_fi -#define afm_flowinfo4 afm_fiu.afmu_fi4 -#define afm_flowinfo6 afm_fiu.afmu_fi6 - - /* statistics */ - u_int32_t afms_packets; /* total packet count */ - u_int32_t afms_bytes; /* total byte count */ -}; - -/* per interface */ -struct afm_head { - LIST_ENTRY(afm_head) afh_chain; - LIST_HEAD(, afm) afh_head; - struct ifnet *afh_ifp; -}; - -struct afm *afm_top(struct ifnet *); -int afm_alloc(struct ifnet *); -int afm_dealloc(struct ifnet *); -int afm_add(struct ifnet *, struct atm_flowmap *); -int afm_remove(struct afm *); -int afm_removeall(struct ifnet *); -struct afm *afm_lookup(struct ifnet *, int, int); -struct afm *afm_match(struct ifnet *, struct flowinfo *); - -#endif /* _KERNEL */ - -#endif /* _ALTQ_ALTQ_AFMAP_H_ */ diff --git a/sys/altq/altq_blue.c b/sys/altq/altq_blue.c deleted file mode 100644 index d08ab09ebf4..00000000000 --- a/sys/altq/altq_blue.c +++ /dev/null @@ -1,670 +0,0 @@ -/* $OpenBSD: altq_blue.c,v 1.7 2002/11/26 01:03:34 henning Exp $ */ -/* $KAME: altq_blue.c,v 1.9 2002/04/03 05:38:50 kjc Exp $ */ - -/* - * Copyright (C) 1997-2002 - * Sony Computer Science Laboratories Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ -/* - * Copyright (c) 1990-1994 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Computer Systems - * Engineering Group at Lawrence Berkeley Laboratory. - * 4. Neither the name of the University nor of the Laboratory may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/param.h> -#include <sys/malloc.h> -#include <sys/mbuf.h> -#include <sys/socket.h> -#include <sys/sockio.h> -#include <sys/systm.h> -#include <sys/proc.h> -#include <sys/errno.h> -#include <sys/kernel.h> - -#include <net/if.h> -#include <net/if_types.h> -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#ifdef INET6 -#include <netinet/ip6.h> -#endif - -#include <altq/altq.h> -#include <altq/altq_conf.h> -#include <altq/altq_blue.h> - -/* - * Blue is proposed and implemented by Wu-chang Feng <wuchang@eecs.umich.edu>. - * more information on Blue is available from - * http://www.eecs.umich.edu/~wuchang/blue/ - */ - -/* fixed-point uses 12-bit decimal places */ -#define FP_SHIFT 12 /* fixed-point shift */ - -#define BLUE_LIMIT 200 /* default max queue length */ -#define BLUE_STATS /* collect statistics */ - -/* blue_list keeps all blue_state_t's allocated. */ -static blue_queue_t *blue_list = NULL; - -/* internal function prototypes */ -static int blue_enqueue(struct ifaltq *, struct mbuf *, - struct altq_pktattr *); -static struct mbuf *blue_dequeue(struct ifaltq *, int); -static int drop_early(blue_t *); -static int mark_ecn(struct mbuf *, struct altq_pktattr *, int); -static int blue_detach(blue_queue_t *); -static int blue_request(struct ifaltq *, int, void *); - -/* - * blue device interface - */ -altqdev_decl(blue); - -int -blueopen(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - /* everything will be done when the queueing scheme is attached. */ - return 0; -} - -int -blueclose(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - blue_queue_t *rqp; - int err, error = 0; - - while ((rqp = blue_list) != NULL) { - /* destroy all */ - err = blue_detach(rqp); - if (err != 0 && error == 0) - error = err; - } - - return error; -} - -int -blueioctl(dev, cmd, addr, flag, p) - dev_t dev; - ioctlcmd_t cmd; - caddr_t addr; - int flag; - struct proc *p; -{ - blue_queue_t *rqp; - struct blue_interface *ifacep; - struct ifnet *ifp; - int error = 0; - - /* check super-user privilege */ - switch (cmd) { - case BLUE_GETSTATS: - break; - default: -#if (__FreeBSD_version > 400000) - if ((error = suser(p)) != 0) - return (error); -#else - if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) - return (error); -#endif - break; - } - - switch (cmd) { - - case BLUE_ENABLE: - ifacep = (struct blue_interface *)addr; - if ((rqp = altq_lookup(ifacep->blue_ifname, ALTQT_BLUE)) == NULL) { - error = EBADF; - break; - } - error = altq_enable(rqp->rq_ifq); - break; - - case BLUE_DISABLE: - ifacep = (struct blue_interface *)addr; - if ((rqp = altq_lookup(ifacep->blue_ifname, ALTQT_BLUE)) == NULL) { - error = EBADF; - break; - } - error = altq_disable(rqp->rq_ifq); - break; - - case BLUE_IF_ATTACH: - ifp = ifunit(((struct blue_interface *)addr)->blue_ifname); - if (ifp == NULL) { - error = ENXIO; - break; - } - - /* allocate and initialize blue_state_t */ - MALLOC(rqp, blue_queue_t *, sizeof(blue_queue_t), M_DEVBUF, M_WAITOK); - bzero(rqp, sizeof(blue_queue_t)); - - MALLOC(rqp->rq_q, class_queue_t *, sizeof(class_queue_t), - M_DEVBUF, M_WAITOK); - bzero(rqp->rq_q, sizeof(class_queue_t)); - - MALLOC(rqp->rq_blue, blue_t *, sizeof(blue_t), M_DEVBUF, M_WAITOK); - bzero(rqp->rq_blue, sizeof(blue_t)); - - rqp->rq_ifq = &ifp->if_snd; - qtail(rqp->rq_q) = NULL; - qlen(rqp->rq_q) = 0; - qlimit(rqp->rq_q) = BLUE_LIMIT; - - /* default packet time: 1000 bytes / 10Mbps * 8 * 1000000 */ - blue_init(rqp->rq_blue, 0, 800, 1000, 50000); - - /* - * set BLUE to this ifnet structure. - */ - error = altq_attach(rqp->rq_ifq, ALTQT_BLUE, rqp, - blue_enqueue, blue_dequeue, blue_request, - NULL, NULL); - if (error) { - FREE(rqp->rq_blue, M_DEVBUF); - FREE(rqp->rq_q, M_DEVBUF); - FREE(rqp, M_DEVBUF); - break; - } - - /* add this state to the blue list */ - rqp->rq_next = blue_list; - blue_list = rqp; - break; - - case BLUE_IF_DETACH: - ifacep = (struct blue_interface *)addr; - if ((rqp = altq_lookup(ifacep->blue_ifname, ALTQT_BLUE)) == NULL) { - error = EBADF; - break; - } - error = blue_detach(rqp); - break; - - case BLUE_GETSTATS: - do { - struct blue_stats *q_stats; - blue_t *rp; - - q_stats = (struct blue_stats *)addr; - if ((rqp = altq_lookup(q_stats->iface.blue_ifname, - ALTQT_BLUE)) == NULL) { - error = EBADF; - break; - } - - q_stats->q_len = qlen(rqp->rq_q); - q_stats->q_limit = qlimit(rqp->rq_q); - - rp = rqp->rq_blue; - q_stats->q_pmark = rp->blue_pmark; - q_stats->xmit_packets = rp->blue_stats.xmit_packets; - q_stats->xmit_bytes = rp->blue_stats.xmit_bytes; - q_stats->drop_packets = rp->blue_stats.drop_packets; - q_stats->drop_bytes = rp->blue_stats.drop_bytes; - q_stats->drop_forced = rp->blue_stats.drop_forced; - q_stats->drop_unforced = rp->blue_stats.drop_unforced; - q_stats->marked_packets = rp->blue_stats.marked_packets; - - } while (0); - break; - - case BLUE_CONFIG: - do { - struct blue_conf *fc; - int limit; - - fc = (struct blue_conf *)addr; - if ((rqp = altq_lookup(fc->iface.blue_ifname, - ALTQT_BLUE)) == NULL) { - error = EBADF; - break; - } - limit = fc->blue_limit; - qlimit(rqp->rq_q) = limit; - fc->blue_limit = limit; /* write back the new value */ - if (fc->blue_pkttime > 0) - rqp->rq_blue->blue_pkttime = fc->blue_pkttime; - if (fc->blue_max_pmark > 0) - rqp->rq_blue->blue_max_pmark = fc->blue_max_pmark; - if (fc->blue_hold_time > 0) - rqp->rq_blue->blue_hold_time = fc->blue_hold_time; - rqp->rq_blue->blue_flags = fc->blue_flags; - - blue_init(rqp->rq_blue, rqp->rq_blue->blue_flags, - rqp->rq_blue->blue_pkttime, - rqp->rq_blue->blue_max_pmark, - rqp->rq_blue->blue_hold_time); - } while (0); - break; - - default: - error = EINVAL; - break; - } - return error; -} - -static int blue_detach(rqp) - blue_queue_t *rqp; -{ - blue_queue_t *tmp; - int error = 0; - - if (ALTQ_IS_ENABLED(rqp->rq_ifq)) - altq_disable(rqp->rq_ifq); - - if ((error = altq_detach(rqp->rq_ifq))) - return (error); - - if (blue_list == rqp) - blue_list = rqp->rq_next; - else { - for (tmp = blue_list; tmp != NULL; tmp = tmp->rq_next) - if (tmp->rq_next == rqp) { - tmp->rq_next = rqp->rq_next; - break; - } - if (tmp == NULL) - printf("blue_detach: no state found in blue_list!\n"); - } - - FREE(rqp->rq_q, M_DEVBUF); - FREE(rqp->rq_blue, M_DEVBUF); - FREE(rqp, M_DEVBUF); - return (error); -} - -/* - * blue support routines - */ - -int -blue_init(rp, flags, pkttime, blue_max_pmark, blue_hold_time) - blue_t *rp; - int flags; - int pkttime; - int blue_max_pmark; - int blue_hold_time; -{ - int npkts_per_sec; - - rp->blue_idle = 1; - rp->blue_flags = flags; - rp->blue_pkttime = pkttime; - rp->blue_max_pmark = blue_max_pmark; - rp->blue_hold_time = blue_hold_time; - if (pkttime == 0) - rp->blue_pkttime = 1; - - /* when the link is very slow, adjust blue parameters */ - npkts_per_sec = 1000000 / rp->blue_pkttime; - if (npkts_per_sec < 50) { - } - else if (npkts_per_sec < 300) { - } - - microtime(&rp->blue_last); - return (0); -} - -/* - * enqueue routine: - * - * returns: 0 when successfully queued. - * ENOBUFS when drop occurs. - */ -static int -blue_enqueue(ifq, m, pktattr) - struct ifaltq *ifq; - struct mbuf *m; - struct altq_pktattr *pktattr; -{ - blue_queue_t *rqp = (blue_queue_t *)ifq->altq_disc; - int error = 0; - - if (blue_addq(rqp->rq_blue, rqp->rq_q, m, pktattr) == 0) - ifq->ifq_len++; - else - error = ENOBUFS; - return error; -} - -#define DTYPE_NODROP 0 /* no drop */ -#define DTYPE_FORCED 1 /* a "forced" drop */ -#define DTYPE_EARLY 2 /* an "unforced" (early) drop */ - -int -blue_addq(rp, q, m, pktattr) - blue_t *rp; - class_queue_t *q; - struct mbuf *m; - struct altq_pktattr *pktattr; -{ - int droptype; - - /* - * if we were idle, this is an enqueue onto an empty queue - * and we should decrement marking probability - * - */ - if (rp->blue_idle) { - struct timeval now; - int t; - rp->blue_idle = 0; - microtime(&now); - t = (now.tv_sec - rp->blue_last.tv_sec); - if ( t > 1) { - rp->blue_pmark = 1; - microtime(&rp->blue_last); - } else { - t = t * 1000000 + (now.tv_usec - rp->blue_last.tv_usec); - if (t > rp->blue_hold_time) { - rp->blue_pmark--; - if (rp->blue_pmark < 0) rp->blue_pmark = 0; - microtime(&rp->blue_last); - } - } - } - - /* see if we drop early */ - droptype = DTYPE_NODROP; - if (drop_early(rp) && qlen(q) > 1) { - /* mark or drop by blue */ - if ((rp->blue_flags & BLUEF_ECN) && - mark_ecn(m, pktattr, rp->blue_flags)) { - /* successfully marked. do not drop. */ -#ifdef BLUE_STATS - rp->blue_stats.marked_packets++; -#endif - } else { - /* unforced drop by blue */ - droptype = DTYPE_EARLY; - } - } - - /* - * if the queue length hits the hard limit, it's a forced drop. - */ - if (droptype == DTYPE_NODROP && qlen(q) >= qlimit(q)) - droptype = DTYPE_FORCED; - - /* if successful or forced drop, enqueue this packet. */ - if (droptype != DTYPE_EARLY) - _addq(q, m); - - if (droptype != DTYPE_NODROP) { - if (droptype == DTYPE_EARLY) { - /* drop the incoming packet */ -#ifdef BLUE_STATS - rp->blue_stats.drop_unforced++; -#endif - } else { - struct timeval now; - int t; - /* forced drop, select a victim packet in the queue. */ - m = _getq_random(q); - microtime(&now); - t = (now.tv_sec - rp->blue_last.tv_sec); - t = t * 1000000 + (now.tv_usec - rp->blue_last.tv_usec); - if (t > rp->blue_hold_time) { - rp->blue_pmark += rp->blue_max_pmark >> 3; - if (rp->blue_pmark > rp->blue_max_pmark) - rp->blue_pmark = rp->blue_max_pmark; - microtime(&rp->blue_last); - } -#ifdef BLUE_STATS - rp->blue_stats.drop_forced++; -#endif - } -#ifdef BLUE_STATS - rp->blue_stats.drop_packets++; - rp->blue_stats.drop_bytes += m->m_pkthdr.len; -#endif - m_freem(m); - return (-1); - } - /* successfully queued */ - return (0); -} - -/* - * early-drop probability is kept in blue_pmark - * - */ -static int -drop_early(rp) - blue_t *rp; -{ - if ((random() % rp->blue_max_pmark) < rp->blue_pmark) { - /* drop or mark */ - return (1); - } - /* no drop/mark */ - return (0); -} - -/* - * try to mark CE bit to the packet. - * returns 1 if successfully marked, 0 otherwise. - */ -static int -mark_ecn(m, pktattr, flags) - struct mbuf *m; - struct altq_pktattr *pktattr; - int flags; -{ - struct mbuf *m0; - - if (pktattr == NULL || - (pktattr->pattr_af != AF_INET && pktattr->pattr_af != AF_INET6)) - return (0); - - /* verify that pattr_hdr is within the mbuf data */ - for (m0 = m; m0 != NULL; m0 = m0->m_next) - if ((pktattr->pattr_hdr >= m0->m_data) && - (pktattr->pattr_hdr < m0->m_data + m0->m_len)) - break; - if (m0 == NULL) { - /* ick, pattr_hdr is stale */ - pktattr->pattr_af = AF_UNSPEC; - return (0); - } - - switch (pktattr->pattr_af) { - case AF_INET: - if (flags & BLUEF_ECN4) { - struct ip *ip = (struct ip *)pktattr->pattr_hdr; - u_int8_t otos; - int sum; - - if (ip->ip_v != 4) - return (0); /* version mismatch! */ - if ((ip->ip_tos & IPTOS_ECN_MASK) == IPTOS_ECN_NOTECT) - return (0); /* not-ECT */ - if ((ip->ip_tos & IPTOS_ECN_MASK) == IPTOS_ECN_CE) - return (1); /* already marked */ - - /* - * ecn-capable but not marked, - * mark CE and update checksum - */ - otos = ip->ip_tos; - ip->ip_tos |= IPTOS_ECN_CE; - /* - * update checksum (from RFC1624) - * HC' = ~(~HC + ~m + m') - */ - sum = ~ntohs(ip->ip_sum) & 0xffff; - sum += (~otos & 0xffff) + ip->ip_tos; - sum = (sum >> 16) + (sum & 0xffff); - sum += (sum >> 16); /* add carry */ - ip->ip_sum = htons(~sum & 0xffff); - return (1); - } - break; -#ifdef INET6 - case AF_INET6: - if (flags & BLUEF_ECN6) { - struct ip6_hdr *ip6 = (struct ip6_hdr *)pktattr->pattr_hdr; - u_int32_t flowlabel; - - flowlabel = ntohl(ip6->ip6_flow); - if ((flowlabel >> 28) != 6) - return (0); /* version mismatch! */ - if ((flowlabel & (IPTOS_ECN_MASK << 20)) == - (IPTOS_ECN_NOTECT << 20)) - return (0); /* not-ECT */ - if ((flowlabel & (IPTOS_ECN_MASK << 20)) == - (IPTOS_ECN_CE << 20)) - return (1); /* already marked */ - /* - * ecn-capable but not marked, mark CE - */ - flowlabel |= (IPTOS_ECN_CE << 20); - ip6->ip6_flow = htonl(flowlabel); - return (1); - } - break; -#endif /* INET6 */ - } - - /* not marked */ - return (0); -} - -/* - * dequeue routine: - * must be called in splimp. - * - * returns: mbuf dequeued. - * NULL when no packet is available in the queue. - */ - -static struct mbuf * -blue_dequeue(ifq, op) - struct ifaltq *ifq; - int op; -{ - blue_queue_t *rqp = (blue_queue_t *)ifq->altq_disc; - struct mbuf *m = NULL; - - if (op == ALTDQ_POLL) - return (qhead(rqp->rq_q)); - - m = blue_getq(rqp->rq_blue, rqp->rq_q); - if (m != NULL) - ifq->ifq_len--; - return m; -} - -struct mbuf *blue_getq(rp, q) - blue_t *rp; - class_queue_t *q; -{ - struct mbuf *m; - - if ((m = _getq(q)) == NULL) { - if (rp->blue_idle == 0) { - rp->blue_idle = 1; - microtime(&rp->blue_last); - } - return NULL; - } - - rp->blue_idle = 0; -#ifdef BLUE_STATS - rp->blue_stats.xmit_packets++; - rp->blue_stats.xmit_bytes += m->m_pkthdr.len; -#endif - return (m); -} - -static int -blue_request(ifq, req, arg) - struct ifaltq *ifq; - int req; - void *arg; -{ - blue_queue_t *rqp = (blue_queue_t *)ifq->altq_disc; - - switch (req) { - case ALTRQ_PURGE: - _flushq(rqp->rq_q); - if (ALTQ_IS_ENABLED(ifq)) - ifq->ifq_len = 0; - break; - } - return (0); -} - - -#ifdef KLD_MODULE - -static struct altqsw blue_sw = - {"blue", blueopen, blueclose, blueioctl}; - -ALTQ_MODULE(altq_blue, ALTQT_BLUE, &blue_sw); - -#endif /* KLD_MODULE */ diff --git a/sys/altq/altq_blue.h b/sys/altq/altq_blue.h deleted file mode 100644 index e2cb567bf80..00000000000 --- a/sys/altq/altq_blue.h +++ /dev/null @@ -1,119 +0,0 @@ -/* $OpenBSD: altq_blue.h,v 1.4 2002/11/26 01:03:34 henning Exp $ */ -/* $KAME: altq_blue.h,v 1.5 2000/12/14 08:12:45 thorpej Exp $ */ - -/* - * Copyright (C) 1997-2000 - * Sony Computer Science Laboratories Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _ALTQ_ALTQ_BLUE_H_ -#define _ALTQ_ALTQ_BLUE_H_ - -#include <altq/altq_classq.h> - -struct blue_interface { - char blue_ifname[IFNAMSIZ]; -}; - -struct blue_stats { - struct blue_interface iface; - int q_len; - int q_limit; - int q_pmark; - u_quad_t xmit_packets; - u_quad_t xmit_bytes; - u_quad_t drop_packets; - u_quad_t drop_bytes; - u_quad_t drop_forced; - u_quad_t drop_unforced; - u_quad_t marked_packets; -}; - -struct blue_conf { - struct blue_interface iface; - int blue_limit; - int blue_max_pmark; - int blue_hold_time; - int blue_pkttime; /* average packet time in usec */ - int blue_flags; /* see below */ -}; - -/* blue flags */ -#define BLUEF_ECN4 0x01 /* use packet marking for IPv4 packets */ -#define BLUEF_ECN6 0x02 /* use packet marking for IPv6 packets */ -#define BLUEF_ECN (BLUEF_ECN4 | BLUEF_ECN6) - -/* - * IOCTLs for BLUE - */ -#define BLUE_IF_ATTACH _IOW('Q', 1, struct blue_interface) -#define BLUE_IF_DETACH _IOW('Q', 2, struct blue_interface) -#define BLUE_ENABLE _IOW('Q', 3, struct blue_interface) -#define BLUE_DISABLE _IOW('Q', 4, struct blue_interface) -#define BLUE_CONFIG _IOWR('Q', 6, struct blue_conf) -#define BLUE_GETSTATS _IOWR('Q', 12, struct blue_stats) - -#ifdef _KERNEL - -typedef struct blue { - int blue_pkttime; /* average packet time in micro sec - used for idle calibration */ - int blue_flags; /* blue flags */ - - /* blue parameters */ - int blue_pmark; /* 0-1000 (mark probability*10000) */ - int blue_max_pmark; /* sets precision of marking probability */ - int blue_hold_time; /* hold time in usec */ - - int blue_idle; /* queue was empty */ - struct timeval blue_last; /* timestamp when the queue becomes idle */ - - struct { - u_quad_t xmit_packets; - u_quad_t xmit_bytes; - u_quad_t drop_packets; - u_quad_t drop_bytes; - u_quad_t drop_forced; - u_quad_t drop_unforced; - u_quad_t marked_packets; - } blue_stats; -} blue_t; - -typedef struct blue_queue { - struct blue_queue *rq_next; /* next blue_state in the list */ - struct ifaltq *rq_ifq; /* backpointer to ifaltq */ - - class_queue_t *rq_q; - - blue_t *rq_blue; -} blue_queue_t; - -extern int blue_init(blue_t *, int, int, int, int); -extern int blue_addq(blue_t *, class_queue_t *, struct mbuf *, - struct altq_pktattr *); -extern struct mbuf *blue_getq(blue_t *, class_queue_t *); - -#endif /* _KERNEL */ - -#endif /* _ALTQ_ALTQ_BLUE_H_ */ diff --git a/sys/altq/altq_cbq.c b/sys/altq/altq_cbq.c index ac467528809..719eeb59d9a 100644 --- a/sys/altq/altq_cbq.c +++ b/sys/altq/altq_cbq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: altq_cbq.c,v 1.7 2002/11/26 01:03:34 henning Exp $ */ +/* $OpenBSD: altq_cbq.c,v 1.8 2002/12/16 09:18:05 kjc Exp $ */ /* $KAME: altq_cbq.c,v 1.9 2000/12/14 08:12:45 thorpej Exp $ */ /* @@ -34,244 +34,32 @@ #include <sys/param.h> #include <sys/malloc.h> #include <sys/mbuf.h> -#include <sys/uio.h> #include <sys/socket.h> #include <sys/systm.h> -#include <sys/proc.h> #include <sys/errno.h> #include <sys/time.h> -#include <sys/kernel.h> #include <net/if.h> -#include <net/if_types.h> #include <netinet/in.h> #include <net/pfvar.h> #include <altq/altq.h> -#include <altq/altq_conf.h> #include <altq/altq_cbq.h> /* - * Local Data structures. - */ -static cbq_state_t *cbq_list = NULL; - -/* * Forward Declarations. */ - -static int cbq_add_class(struct cbq_add_class *); -static int cbq_delete_class(struct cbq_delete_class *); -static int cbq_modify_class(struct cbq_modify_class *); -static int cbq_class_create(cbq_state_t *, struct cbq_add_class *, - struct rm_class *, struct rm_class *); static int cbq_class_destroy(cbq_state_t *, struct rm_class *); static struct rm_class *clh_to_clp(cbq_state_t *, u_int32_t); -static int cbq_add_filter(struct cbq_add_filter *); -static int cbq_delete_filter(struct cbq_delete_filter *); - -static int cbq_clear_hierarchy(struct cbq_interface *); static int cbq_clear_interface(cbq_state_t *); static int cbq_request(struct ifaltq *, int, void *); -static int cbq_set_enable(struct cbq_interface *, int); -static int cbq_ifattach(struct cbq_interface *); -static int cbq_ifdetach(struct cbq_interface *); static int cbq_enqueue(struct ifaltq *, struct mbuf *, - struct altq_pktattr *); + struct altq_pktattr *); static struct mbuf *cbq_dequeue(struct ifaltq *, int); static void cbqrestart(struct ifaltq *); static void get_class_stats(class_stats_t *, struct rm_class *); -static int cbq_getstats(struct cbq_getstats *); static void cbq_purge(cbq_state_t *); -static int -cbq_add_class(acp) - struct cbq_add_class *acp; -{ - char *ifacename; - struct rm_class *borrow, *parent; - cbq_state_t *cbqp; - - ifacename = acp->cbq_iface.cbq_ifacename; - if ((cbqp = altq_lookup(ifacename, ALTQT_CBQ)) == NULL) - return (EBADF); - - /* check parameters */ - if (acp->cbq_class.priority >= RM_MAXPRIO || - acp->cbq_class.maxq > CBQ_MAXQSIZE) - return (EINVAL); - - /* Get pointers to parent and borrow classes. */ - parent = clh_to_clp(cbqp, acp->cbq_class.parent_class_handle); - borrow = clh_to_clp(cbqp, acp->cbq_class.borrow_class_handle); - - /* - * A class must borrow from it's parent or it can not - * borrow at all. Hence, borrow can be null. - */ - if (parent == NULL && (acp->cbq_class.flags & CBQCLF_ROOTCLASS) == 0) { - printf("cbq_add_class: no parent class!\n"); - return (EINVAL); - } - - if ((borrow != parent) && (borrow != NULL)) { - printf("cbq_add_class: borrow class != parent\n"); - return (EINVAL); - } - - return cbq_class_create(cbqp, acp, parent, borrow); -} - -static int -cbq_delete_class(dcp) - struct cbq_delete_class *dcp; -{ - char *ifacename; - struct rm_class *cl; - cbq_state_t *cbqp; - - ifacename = dcp->cbq_iface.cbq_ifacename; - if ((cbqp = altq_lookup(ifacename, ALTQT_CBQ)) == NULL) - return (EBADF); - - if ((cl = clh_to_clp(cbqp, dcp->cbq_class_handle)) == NULL) - return (EINVAL); - - /* if we are a parent class, then return an error. */ - if (is_a_parent_class(cl)) - return (EINVAL); - - /* if a filter has a reference to this class delete the filter */ - acc_discard_filters(&cbqp->cbq_classifier, cl, 0); - - return cbq_class_destroy(cbqp, cl); -} - -static int -cbq_modify_class(acp) - struct cbq_modify_class *acp; -{ - char *ifacename; - struct rm_class *cl; - cbq_state_t *cbqp; - - ifacename = acp->cbq_iface.cbq_ifacename; - if ((cbqp = altq_lookup(ifacename, ALTQT_CBQ)) == NULL) - return (EBADF); - - /* Get pointer to this class */ - if ((cl = clh_to_clp(cbqp, acp->cbq_class_handle)) == NULL) - return (EINVAL); - - if (rmc_modclass(cl, acp->cbq_class.nano_sec_per_byte, - acp->cbq_class.maxq, acp->cbq_class.maxidle, - acp->cbq_class.minidle, acp->cbq_class.offtime, - acp->cbq_class.pktsize) < 0) - return (EINVAL); - return (0); -} - -/* - * struct rm_class * - * cbq_class_create(cbq_mod_state_t *cbqp, struct cbq_add_class *acp, - * u_int32_t handle, struct rm_class *parent, - * struct rm_class *borrow) - * - * This function create a new traffic class in the CBQ class hierarchy of - * given paramters. The class that created is either the root, default, - * or a new dynamic class. If CBQ is not initilaized, the the root class - * will be created. - */ -static int -cbq_class_create(cbqp, acp, parent, borrow) - cbq_state_t *cbqp; - struct cbq_add_class *acp; - struct rm_class *parent, *borrow; -{ - struct rm_class *cl; - cbq_class_spec_t *spec = &acp->cbq_class; - u_int32_t chandle; - int i; - - /* - * allocate class handle - */ - switch (spec->flags & CBQCLF_CLASSMASK) { - case CBQCLF_ROOTCLASS: - if (parent != NULL) - return (EINVAL); - if (cbqp->ifnp.root_) - return (EINVAL); - chandle = ROOT_CLASS_HANDLE; - break; - case CBQCLF_DEFCLASS: - if (cbqp->ifnp.default_) - return (EINVAL); - chandle = DEFAULT_CLASS_HANDLE; - break; - case CBQCLF_CTLCLASS: - if (cbqp->ifnp.ctl_) - return (EINVAL); - chandle = CTL_CLASS_HANDLE; - break; - case 0: - /* find a free class slot */ - for (i = 0; i < CBQ_MAX_CLASSES; i++) - if (cbqp->cbq_class_tbl[i] == NULL) - break; - if (i == CBQ_MAX_CLASSES) - return (ENOSPC); - chandle = (u_int32_t)i; - break; - default: - /* more than two flags bits set */ - return (EINVAL); - } - - /* - * create a class. if this is a root class, initialize the - * interface. - */ - if (chandle == ROOT_CLASS_HANDLE) { - rmc_init(cbqp->ifnp.ifq_, &cbqp->ifnp, spec->nano_sec_per_byte, - cbqrestart, spec->maxq, RM_MAXQUEUED, - spec->maxidle, spec->minidle, spec->offtime, - spec->flags); - cl = cbqp->ifnp.root_; - } else { - cl = rmc_newclass(spec->priority, - &cbqp->ifnp, spec->nano_sec_per_byte, - rmc_delay_action, spec->maxq, parent, borrow, - spec->maxidle, spec->minidle, spec->offtime, - spec->pktsize, spec->flags); - } - if (cl == NULL) - return (ENOMEM); - - /* return handle to user space. */ - acp->cbq_class_handle = chandle; - - cl->stats_.handle = chandle; - cl->stats_.depth = cl->depth_; - - /* save the allocated class */ - switch (chandle) { - case NULL_CLASS_HANDLE: - case ROOT_CLASS_HANDLE: - break; - case DEFAULT_CLASS_HANDLE: - cbqp->ifnp.default_ = cl; - break; - case CTL_CLASS_HANDLE: - cbqp->ifnp.ctl_ = cl; - break; - default: - cbqp->cbq_class_tbl[chandle] = cl; - break; - } - return (0); -} - /* * int * cbq_class_destroy(cbq_mod_state_t *, struct rm_class *) - This @@ -338,68 +126,12 @@ clh_to_clp(cbqp, chandle) } static int -cbq_add_filter(afp) - struct cbq_add_filter *afp; -{ - char *ifacename; - cbq_state_t *cbqp; - struct rm_class *cl; - - ifacename = afp->cbq_iface.cbq_ifacename; - if ((cbqp = altq_lookup(ifacename, ALTQT_CBQ)) == NULL) - return (EBADF); - - /* Get the pointer to class. */ - if ((cl = clh_to_clp(cbqp, afp->cbq_class_handle)) == NULL) - return (EINVAL); - - return acc_add_filter(&cbqp->cbq_classifier, &afp->cbq_filter, - cl, &afp->cbq_filter_handle); -} - -static int -cbq_delete_filter(dfp) - struct cbq_delete_filter *dfp; -{ - char *ifacename; - cbq_state_t *cbqp; - - ifacename = dfp->cbq_iface.cbq_ifacename; - if ((cbqp = altq_lookup(ifacename, ALTQT_CBQ)) == NULL) - return (EBADF); - - return acc_delete_filter(&cbqp->cbq_classifier, - dfp->cbq_filter_handle); -} - -/* - * cbq_clear_hierarchy deletes all classes and their filters on the - * given interface. - */ -static int -cbq_clear_hierarchy(ifacep) - struct cbq_interface *ifacep; -{ - char *ifacename; - cbq_state_t *cbqp; - - ifacename = ifacep->cbq_ifacename; - if ((cbqp = altq_lookup(ifacename, ALTQT_CBQ)) == NULL) - return (EBADF); - - return cbq_clear_interface(cbqp); -} - -static int cbq_clear_interface(cbqp) cbq_state_t *cbqp; { int again, i; struct rm_class *cl; - /* free the filters for this interface */ - acc_discard_filters(&cbqp->cbq_classifier, NULL, 1); - /* clear out the classes now */ do { again = 0; @@ -449,53 +181,6 @@ cbq_request(ifq, req, arg) return (0); } -/* - * static int - * cbq_set_enable(struct cbq_enable *ep) - this function processed the - * ioctl request to enable class based queueing. It searches the list - * of interfaces for the specified interface and then enables CBQ on - * that interface. - * - * Returns: 0, for no error. - * EBADF, for specified inteface not found. - */ - -static int -cbq_set_enable(ep, enable) - struct cbq_interface *ep; - int enable; -{ - int error = 0; - cbq_state_t *cbqp; - char *ifacename; - - ifacename = ep->cbq_ifacename; - if ((cbqp = altq_lookup(ifacename, ALTQT_CBQ)) == NULL) - return (EBADF); - - switch (enable) { - case ENABLE: - if (cbqp->ifnp.root_ == NULL || cbqp->ifnp.default_ == NULL || - cbqp->ifnp.ctl_ == NULL) { - if (cbqp->ifnp.root_ == NULL) - printf("No Root Class for %s\n", ifacename); - if (cbqp->ifnp.default_ == NULL) - printf("No Default Class for %s\n", ifacename); - if (cbqp->ifnp.ctl_ == NULL) - printf("No Control Class for %s\n", ifacename); - error = EINVAL; - } else if ((error = altq_enable(cbqp->ifnp.ifq_)) == 0) { - cbqp->cbq_qlen = 0; - } - break; - - case DISABLE: - error = altq_disable(cbqp->ifnp.ifq_); - break; - } - return (error); -} - /* copy the stats info in rm_class to class_states_t */ static void get_class_stats(statsp, cl) @@ -531,66 +216,6 @@ get_class_stats(statsp, cl) #endif } -static int -cbq_getstats(gsp) - struct cbq_getstats *gsp; -{ - char *ifacename; - int chandle, n, nclasses; - cbq_state_t *cbqp; - struct rm_class *cl; - class_stats_t stats, *usp; - int error = 0; - - ifacename = gsp->iface.cbq_ifacename; - nclasses = gsp->nclasses; - usp = gsp->stats; - - if ((cbqp = altq_lookup(ifacename, ALTQT_CBQ)) == NULL) - return (EBADF); - if (nclasses <= 0) - return (EINVAL); - - for (n = 0, chandle = 0; n < nclasses && chandle < CBQ_MAX_CLASSES; - n++) { - switch(n) { - case 0: - cl = cbqp->ifnp.root_; - stats.handle = ROOT_CLASS_HANDLE; - break; - case 1: - cl = cbqp->ifnp.default_; - stats.handle = DEFAULT_CLASS_HANDLE; - break; - case 2: - cl = cbqp->ifnp.ctl_; - stats.handle = CTL_CLASS_HANDLE; -#if 1 /* PFALTQ */ - if (cl != NULL) -#endif - break; - default: - while ((cl = cbqp->cbq_class_tbl[chandle]) == NULL) - if (++chandle >= CBQ_MAX_CLASSES) - goto out; - stats.handle = chandle++; - break; - } - - get_class_stats(&stats, cl); - - if ((error = copyout((caddr_t)&stats, (caddr_t)usp++, - sizeof(stats))) != 0) - return (error); - } - - out: - gsp->nclasses = n; - return (error); -} - -#if 1 /* PFALTQ */ - int cbq_pfattach(struct pf_altq *a) { @@ -613,9 +238,9 @@ cbq_add_altq(struct pf_altq *a) struct ifnet *ifp; if ((ifp = ifunit(a->ifname)) == NULL) - return (ENXIO); + return (EINVAL); if (!ALTQ_IS_READY(&ifp->if_snd)) - return (ENXIO); + return (ENODEV); /* allocate and initialize cbq_state_t */ MALLOC(cbqp, cbq_state_t *, sizeof(cbq_state_t), M_DEVBUF, M_WAITOK); @@ -623,23 +248,12 @@ cbq_add_altq(struct pf_altq *a) return (ENOMEM); bzero(cbqp, sizeof(cbq_state_t)); CALLOUT_INIT(&cbqp->cbq_callout); - MALLOC(cbqp->cbq_class_tbl, struct rm_class **, - sizeof(struct rm_class *) * CBQ_MAX_CLASSES, M_DEVBUF, M_WAITOK); - if (cbqp->cbq_class_tbl == NULL) { - FREE(cbqp, M_DEVBUF); - return (ENOMEM); - } - bzero(cbqp->cbq_class_tbl, sizeof(struct rm_class *) * CBQ_MAX_CLASSES); cbqp->cbq_qlen = 0; cbqp->ifnp.ifq_ = &ifp->if_snd; /* keep the ifq */ /* keep the state in pf_altq */ a->altq_disc = cbqp; - /* prepend to the list of cbq_state_t's. */ - cbqp->cbq_next = cbq_list; - cbq_list = cbqp; - return (0); } @@ -661,22 +275,7 @@ cbq_remove_altq(struct pf_altq *a) if (cbqp->ifnp.root_) cbq_class_destroy(cbqp, cbqp->ifnp.root_); - /* remove from the list of cbq_state_t's. */ - if (cbq_list == cbqp) - cbq_list = cbqp->cbq_next; - else { - cbq_state_t *cp; - - for (cp = cbq_list; cp != NULL; cp = cp->cbq_next) - if (cp->cbq_next == cbqp) { - cp->cbq_next = cbqp->cbq_next; - break; - } - ASSERT(cp != NULL); - } - /* deallocate cbq_state_t */ - FREE(cbqp->cbq_class_tbl, M_DEVBUF); FREE(cbqp, M_DEVBUF); return (0); @@ -744,13 +343,8 @@ cbq_add_queue(struct pf_altq *a) chandle = CTL_CLASS_HANDLE; break; case 0: - /* find a free class slot */ -#if 1 /* PFALTQ */ - /* for now, reserve qid 0 */ + /* find a free class slot. for now, reserve qid 0 */ for (i = 1; i < CBQ_MAX_CLASSES; i++) -#else - for (i = 0; i < CBQ_MAX_CLASSES; i++) -#endif if (cbqp->cbq_class_tbl[i] == NULL) break; if (i == CBQ_MAX_CLASSES) @@ -877,104 +471,6 @@ cbq_getqstats(struct pf_altq *a, void *ubuf, int *nbytes) return (0); } -#endif /* PFALTQ */ - -static int -cbq_ifattach(ifacep) - struct cbq_interface *ifacep; -{ - int error = 0; - char *ifacename; - cbq_state_t *new_cbqp; - struct ifnet *ifp; - - ifacename = ifacep->cbq_ifacename; - if ((ifp = ifunit(ifacename)) == NULL) - return (ENXIO); - if (!ALTQ_IS_READY(&ifp->if_snd)) - return (ENXIO); - - /* allocate and initialize cbq_state_t */ - MALLOC(new_cbqp, cbq_state_t *, sizeof(cbq_state_t), M_DEVBUF, M_WAITOK); - if (new_cbqp == NULL) - return (ENOMEM); - bzero(new_cbqp, sizeof(cbq_state_t)); - CALLOUT_INIT(&new_cbqp->cbq_callout); - MALLOC(new_cbqp->cbq_class_tbl, struct rm_class **, - sizeof(struct rm_class *) * CBQ_MAX_CLASSES, M_DEVBUF, M_WAITOK); - if (new_cbqp->cbq_class_tbl == NULL) { - FREE(new_cbqp, M_DEVBUF); - return (ENOMEM); - } - bzero(new_cbqp->cbq_class_tbl, sizeof(struct rm_class *) * CBQ_MAX_CLASSES); - new_cbqp->cbq_qlen = 0; - new_cbqp->ifnp.ifq_ = &ifp->if_snd; /* keep the ifq */ - - /* - * set CBQ to this ifnet structure. - */ - error = altq_attach(&ifp->if_snd, ALTQT_CBQ, new_cbqp, - cbq_enqueue, cbq_dequeue, cbq_request, - &new_cbqp->cbq_classifier, acc_classify); - if (error) { - FREE(new_cbqp->cbq_class_tbl, M_DEVBUF); - FREE(new_cbqp, M_DEVBUF); - return (error); - } - - /* prepend to the list of cbq_state_t's. */ - new_cbqp->cbq_next = cbq_list; - cbq_list = new_cbqp; - - return (0); -} - -static int -cbq_ifdetach(ifacep) - struct cbq_interface *ifacep; -{ - char *ifacename; - cbq_state_t *cbqp; - - ifacename = ifacep->cbq_ifacename; - if ((cbqp = altq_lookup(ifacename, ALTQT_CBQ)) == NULL) - return (EBADF); - - (void)cbq_set_enable(ifacep, DISABLE); - - cbq_clear_interface(cbqp); - - if (cbqp->ifnp.ctl_) - cbq_class_destroy(cbqp, cbqp->ifnp.ctl_); - if (cbqp->ifnp.default_) - cbq_class_destroy(cbqp, cbqp->ifnp.default_); - if (cbqp->ifnp.root_) - cbq_class_destroy(cbqp, cbqp->ifnp.root_); - - /* remove CBQ from the ifnet structure. */ - (void)altq_detach(cbqp->ifnp.ifq_); - - /* remove from the list of cbq_state_t's. */ - if (cbq_list == cbqp) - cbq_list = cbqp->cbq_next; - else { - cbq_state_t *cp; - - for (cp = cbq_list; cp != NULL; cp = cp->cbq_next) - if (cp->cbq_next == cbqp) { - cp->cbq_next = cbqp->cbq_next; - break; - } - ASSERT(cp != NULL); - } - - /* deallocate cbq_state_t */ - FREE(cbqp->cbq_class_tbl, M_DEVBUF); - FREE(cbqp, M_DEVBUF); - - return (0); -} - /* * int * cbq_enqueue(struct ifaltq *ifq, struct mbuf *m, struct altq_pktattr *pattr) @@ -998,27 +494,19 @@ cbq_enqueue(ifq, m, pktattr) { cbq_state_t *cbqp = (cbq_state_t *)ifq->altq_disc; struct rm_class *cl; + struct m_tag *t; int len; /* grab class set by classifier */ - if (PFALTQ_IS_ACTIVE()) { - struct m_tag *t; - - t = m_tag_find(m, PACKET_TAG_PF_QID, NULL); - if (t == NULL || - (cl = clh_to_clp(cbqp, ((struct altq_tag *)(t+1))->qid)) - == NULL) { - cl = cbqp->ifnp.default_; - if (cl == NULL) { - m_freem(m); - return (ENOBUFS); - } + t = m_tag_find(m, PACKET_TAG_PF_QID, NULL); + if (t == NULL || + (cl = clh_to_clp(cbqp, ((struct altq_tag *)(t+1))->qid)) == NULL) { + cl = cbqp->ifnp.default_; + if (cl == NULL) { + m_freem(m); + return (ENOBUFS); } cl->pktattr_ = NULL; - } else { - if (pktattr == NULL || (cl = pktattr->pattr_class) == NULL) - cl = cbqp->ifnp.default_; - cl->pktattr_ = pktattr; /* save proto hdr used by ECN */ } len = m_pktlen(m); @@ -1094,177 +582,3 @@ static void cbq_purge(cbqp) if (ALTQ_IS_ENABLED(cbqp->ifnp.ifq_)) cbqp->ifnp.ifq_->ifq_len = 0; } - -/* - * cbq device interface - */ - -altqdev_decl(cbq); - -int -cbqopen(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - if (PFALTQ_IS_ACTIVE()) - return (EBUSY); - return (0); -} - -int -cbqclose(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - struct ifnet *ifp; - struct cbq_interface iface; - int err, error = 0; - - while (cbq_list) { - ifp = cbq_list->ifnp.ifq_->altq_ifp; -#if defined(__NetBSD__) || defined(__OpenBSD__) - sprintf(iface.cbq_ifacename, "%s", ifp->if_xname); -#else - sprintf(iface.cbq_ifacename, - "%s%d", ifp->if_name, ifp->if_unit); -#endif - err = cbq_ifdetach(&iface); - if (err != 0 && error == 0) - error = err; - } - - return (error); -} - -int -cbqioctl(dev, cmd, addr, flag, p) - dev_t dev; - ioctlcmd_t cmd; - caddr_t addr; - int flag; - struct proc *p; -{ - int error = 0; - - /* check cmd for superuser only */ - switch (cmd) { - case CBQ_GETSTATS: - /* currently only command that an ordinary user can call */ - break; - default: -#if (__FreeBSD_version > 400000) - error = suser(p); -#else - error = suser(p->p_ucred, &p->p_acflag); -#endif - if (error) - return (error); - break; - } - - switch (cmd) { - - case CBQ_ENABLE: - error = cbq_set_enable((struct cbq_interface *)addr, ENABLE); - break; - - case CBQ_DISABLE: - error = cbq_set_enable((struct cbq_interface *)addr, DISABLE); - break; - - case CBQ_ADD_FILTER: - error = cbq_add_filter((struct cbq_add_filter *)addr); - break; - - case CBQ_DEL_FILTER: - error = cbq_delete_filter((struct cbq_delete_filter *)addr); - break; - - case CBQ_ADD_CLASS: - error = cbq_add_class((struct cbq_add_class *)addr); - break; - - case CBQ_DEL_CLASS: - error = cbq_delete_class((struct cbq_delete_class *)addr); - break; - - case CBQ_MODIFY_CLASS: - error = cbq_modify_class((struct cbq_modify_class *)addr); - break; - - case CBQ_CLEAR_HIERARCHY: - error = cbq_clear_hierarchy((struct cbq_interface *)addr); - break; - - case CBQ_IF_ATTACH: - error = cbq_ifattach((struct cbq_interface *)addr); - break; - - case CBQ_IF_DETACH: - error = cbq_ifdetach((struct cbq_interface *)addr); - break; - - case CBQ_GETSTATS: - error = cbq_getstats((struct cbq_getstats *)addr); - break; - - default: - error = EINVAL; - break; - } - - return error; -} - -#if 0 -/* for debug */ -static void cbq_class_dump(int); - -static void cbq_class_dump(i) - int i; -{ - struct rm_class *cl; - rm_class_stats_t *s; - struct _class_queue_ *q; - - if (cbq_list == NULL) { - printf("cbq_class_dump: no cbq_state found\n"); - return; - } - cl = cbq_list->cbq_class_tbl[i]; - - printf("class %d cl=%p\n", i, cl); - if (cl != NULL) { - s = &cl->stats_; - q = cl->q_; - - printf("pri=%d, depth=%d, maxrate=%d, allotment=%d\n", - cl->pri_, cl->depth_, cl->maxrate_, cl->allotment_); - printf("w_allotment=%d, bytes_alloc=%d, avgidle=%d, maxidle=%d\n", - cl->w_allotment_, cl->bytes_alloc_, cl->avgidle_, - cl->maxidle_); - printf("minidle=%d, offtime=%d, sleeping=%d, leaf=%d\n", - cl->minidle_, cl->offtime_, cl->sleeping_, cl->leaf_); - printf("handle=%d, depth=%d, packets=%d, bytes=%d\n", - s->handle, s->depth, - (int)s->xmit_cnt.packets, (int)s->xmit_cnt.bytes); - printf("over=%d\n, borrows=%d, drops=%d, overactions=%d, delays=%d\n", - s->over, s->borrows, (int)s->drop_cnt.packets, - s->overactions, s->delays); - printf("tail=%p, head=%p, qlen=%d, qlim=%d, qthresh=%d,qtype=%d\n", - q->tail_, q->head_, q->qlen_, q->qlim_, - q->qthresh_, q->qtype_); - } -} -#endif /* 0 */ - -#ifdef KLD_MODULE - -static struct altqsw cbq_sw = - {"cbq", cbqopen, cbqclose, cbqioctl}; - -ALTQ_MODULE(altq_cbq, ALTQT_CBQ, &cbq_sw); - -#endif /* KLD_MODULE */ diff --git a/sys/altq/altq_cbq.h b/sys/altq/altq_cbq.h index a8f62807490..b6fc350686b 100644 --- a/sys/altq/altq_cbq.h +++ b/sys/altq/altq_cbq.h @@ -1,4 +1,4 @@ -/* $OpenBSD: altq_cbq.h,v 1.4 2002/11/26 01:03:34 henning Exp $ */ +/* $OpenBSD: altq_cbq.h,v 1.5 2002/12/16 09:18:05 kjc Exp $ */ /* $KAME: altq_cbq.h,v 1.5 2000/12/02 13:44:40 kjc Exp $ */ /* @@ -34,14 +34,11 @@ #ifndef _ALTQ_ALTQ_CBQ_H_ #define _ALTQ_ALTQ_CBQ_H_ -#include <sys/ioccom.h> #include <altq/altq.h> #include <altq/altq_rmclass.h> #include <altq/altq_red.h> #include <altq/altq_rio.h> -/* #pragma ident "@(#)cbq.h 1.18 98/05/13 SMI" */ - #ifdef __cplusplus extern "C" { #endif @@ -54,33 +51,6 @@ extern "C" { #define DEFAULT_CLASS_HANDLE 0xfffffffd #define CTL_CLASS_HANDLE 0xfffffffc -/* - * Define structures associated with IOCTLS for cbq. - */ - -/* - * Define the CBQ interface structure. This must be included in all - * IOCTL's such that the CBQ driver may find the appropriate CBQ module - * associated with the network interface to be affected. - */ -struct cbq_interface { - char cbq_ifacename[IFNAMSIZ]; -}; - -typedef struct cbq_class_spec { - u_int priority; - u_int nano_sec_per_byte; - u_int maxq; - u_int maxidle; - int minidle; - u_int offtime; - u_int32_t parent_class_handle; - u_int32_t borrow_class_handle; - - u_int pktsize; - int flags; -} cbq_class_spec_t; - /* class flags shoud be same as class flags in rm_class.h */ #define CBQCLF_RED 0x0001 /* use RED */ #define CBQCLF_ECN 0x0002 /* use RED/ECN */ @@ -101,38 +71,6 @@ typedef struct cbq_class_spec { #define CBQ_MAXQSIZE 200 -struct cbq_add_class { - struct cbq_interface cbq_iface; - - cbq_class_spec_t cbq_class; - u_int32_t cbq_class_handle; -}; - -struct cbq_delete_class { - struct cbq_interface cbq_iface; - u_int32_t cbq_class_handle; -}; - -struct cbq_modify_class { - struct cbq_interface cbq_iface; - - cbq_class_spec_t cbq_class; - u_int32_t cbq_class_handle; -}; - -struct cbq_add_filter { - struct cbq_interface cbq_iface; - u_int32_t cbq_class_handle; - struct flow_filter cbq_filter; - - u_long cbq_filter_handle; -}; - -struct cbq_delete_filter { - struct cbq_interface cbq_iface; - u_long cbq_filter_handle; -}; - typedef struct _cbq_class_stats_ { u_int32_t handle; u_int depth; @@ -161,55 +99,25 @@ typedef struct _cbq_class_stats_ { struct redstats red[3]; } class_stats_t; -/* number of classes are returned in nclasses field */ -struct cbq_getstats { - struct cbq_interface iface; - int nclasses; - class_stats_t *stats; -}; - -/* - * Define IOCTLs for CBQ. - */ -#define CBQ_IF_ATTACH _IOW('Q', 1, struct cbq_interface) -#define CBQ_IF_DETACH _IOW('Q', 2, struct cbq_interface) -#define CBQ_ENABLE _IOW('Q', 3, struct cbq_interface) -#define CBQ_DISABLE _IOW('Q', 4, struct cbq_interface) -#define CBQ_CLEAR_HIERARCHY _IOW('Q', 5, struct cbq_interface) -#define CBQ_ADD_CLASS _IOWR('Q', 7, struct cbq_add_class) -#define CBQ_DEL_CLASS _IOW('Q', 8, struct cbq_delete_class) -#define CBQ_MODIFY_CLASS _IOWR('Q', 9, struct cbq_modify_class) -#define CBQ_ADD_FILTER _IOWR('Q', 10, struct cbq_add_filter) -#define CBQ_DEL_FILTER _IOW('Q', 11, struct cbq_delete_filter) -#define CBQ_GETSTATS _IOWR('Q', 12, struct cbq_getstats) - #ifdef _KERNEL /* * Define macros only good for kernel drivers and modules. */ - -#define DISABLE 0x00 -#define ENABLE 0x01 - #define CBQ_WATCHDOG (HZ / 20) #define CBQ_TIMEOUT 10 #define CBQ_LS_TIMEOUT (20 * hz / 1000) #define CBQ_MAX_CLASSES 256 -#define CBQ_MAX_FILTERS 256 /* * Define State structures. */ typedef struct cbqstate { - struct cbqstate *cbq_next; int cbq_qlen; /* # of packets in cbq */ - struct rm_class **cbq_class_tbl; + struct rm_class *cbq_class_tbl[CBQ_MAX_CLASSES]; struct rm_ifdat ifnp; struct callout cbq_callout; /* for timeouts */ - - struct acc_classifier cbq_classifier; } cbq_state_t; #endif /* _KERNEL */ diff --git a/sys/altq/altq_cdnr.c b/sys/altq/altq_cdnr.c index a9059f37e06..68747472dc3 100644 --- a/sys/altq/altq_cdnr.c +++ b/sys/altq/altq_cdnr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: altq_cdnr.c,v 1.5 2002/11/26 01:03:34 henning Exp $ */ +/* $OpenBSD: altq_cdnr.c,v 1.6 2002/12/16 09:18:05 kjc Exp $ */ /* $KAME: altq_cdnr.c,v 1.8 2000/12/14 08:12:45 thorpej Exp $ */ /* @@ -31,7 +31,6 @@ #include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/socket.h> -#include <sys/sockio.h> #include <sys/systm.h> #include <sys/proc.h> #include <sys/errno.h> @@ -48,7 +47,6 @@ #endif #include <altq/altq.h> -#include <altq/altq_conf.h> #include <altq/altq_cdnr.h> /* @@ -60,10 +58,6 @@ int altq_cdnr_enabled = 0; /* cdnr_list keeps all cdnr's allocated. */ static LIST_HEAD(, top_cdnr) tcb_list; -int cdnropen(dev_t, int, int, struct proc *); -int cdnrclose(dev_t, int, int, struct proc *); -int cdnrioctl(dev_t, ioctlcmd_t, caddr_t, int, struct proc *); - static int altq_cdnr_input(struct mbuf *, int); static struct top_cdnr *tcb_lookup(char *ifname); static struct cdnr_block *cdnr_handle2cb(u_long); @@ -105,8 +99,6 @@ static int cdnrcmd_if_attach(char *); static int cdnrcmd_if_detach(char *); static int cdnrcmd_add_element(struct cdnr_add_element *); static int cdnrcmd_delete_element(struct cdnr_delete_element *); -static int cdnrcmd_add_filter(struct cdnr_add_filter *); -static int cdnrcmd_delete_filter(struct cdnr_delete_filter *); static int cdnrcmd_add_tbm(struct cdnr_add_tbmeter *); static int cdnrcmd_modify_tbm(struct cdnr_modify_tbmeter *); static int cdnrcmd_tbm_stats(struct cdnr_tbmeter_stats *); @@ -117,6 +109,32 @@ static int cdnrcmd_add_tswtcm(struct cdnr_add_tswtcm *); static int cdnrcmd_modify_tswtcm(struct cdnr_modify_tswtcm *); static int cdnrcmd_get_stats(struct cdnr_get_stats *); +#if 1 +/* dummy */ +int cdnr_dummy(void); + +int cdnr_dummy(void) +{ + altq_cdnr_input(NULL, 0); + + cdnrcmd_if_attach(NULL); + cdnrcmd_if_detach(NULL); + cdnrcmd_add_element(NULL); + cdnrcmd_delete_element(NULL); + cdnrcmd_add_tbm(NULL); + cdnrcmd_modify_tbm(NULL); + cdnrcmd_tbm_stats(NULL); + cdnrcmd_add_trtcm(NULL); + cdnrcmd_modify_trtcm(NULL); + cdnrcmd_tcm_stats(NULL); + cdnrcmd_add_tswtcm(NULL); + cdnrcmd_modify_tswtcm(NULL); + cdnrcmd_get_stats(NULL); + return (0); +} + +#endif + /* * top level input function called from ip_input. * should be called before converting header fields to host-byte-order. @@ -154,7 +172,9 @@ altq_cdnr_input(m, af) tca = NULL; +#if 0 cb = acc_classify(&top->tc_classifier, m, af); +#endif if (cb != NULL) tca = &cb->cb_action; @@ -302,9 +322,6 @@ cdnr_cbdestroy(cblock) { struct cdnr_block *cb = cblock; - /* delete filters belonging to this cdnr */ - acc_discard_filters(&cb->cb_top->tc_classifier, cb, 0); - /* remove from the top level cdnr */ if (cb->cb_top != cblock) LIST_REMOVE(cb, cb_next); @@ -928,35 +945,6 @@ cdnrcmd_delete_element(ap) } static int -cdnrcmd_add_filter(ap) - struct cdnr_add_filter *ap; -{ - struct top_cdnr *top; - struct cdnr_block *cb; - - if ((top = tcb_lookup(ap->iface.cdnr_ifname)) == NULL) - return (EBADF); - - if ((cb = cdnr_handle2cb(ap->cdnr_handle)) == NULL) - return (EINVAL); - - return acc_add_filter(&top->tc_classifier, &ap->filter, - cb, &ap->filter_handle); -} - -static int -cdnrcmd_delete_filter(ap) - struct cdnr_delete_filter *ap; -{ - struct top_cdnr *top; - - if ((top = tcb_lookup(ap->iface.cdnr_ifname)) == NULL) - return (EBADF); - - return acc_delete_filter(&top->tc_classifier, ap->filter_handle); -} - -static int cdnrcmd_add_tbm(ap) struct cdnr_add_tbmeter *ap; { @@ -1181,180 +1169,3 @@ cdnrcmd_get_stats(ap) return (0); } - -/* - * conditioner device interface - */ -int -cdnropen(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - if (machclk_freq == 0) - init_machclk(); - - if (machclk_freq == 0) { - printf("cdnr: no cpu clock available!\n"); - return (ENXIO); - } - - /* everything will be done when the queueing scheme is attached. */ - return 0; -} - -int -cdnrclose(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - struct top_cdnr *top; - int err, error = 0; - - while ((top = LIST_FIRST(&tcb_list)) != NULL) { - /* destroy all */ - err = top_destroy(top); - if (err != 0 && error == 0) - error = err; - } - altq_input = NULL; - - return (error); -} - -int -cdnrioctl(dev, cmd, addr, flag, p) - dev_t dev; - ioctlcmd_t cmd; - caddr_t addr; - int flag; - struct proc *p; -{ - struct top_cdnr *top; - struct cdnr_interface *ifacep; - int s, error = 0; - - /* check super-user privilege */ - switch (cmd) { - case CDNR_GETSTATS: - break; - default: -#if (__FreeBSD_version > 400000) - if ((error = suser(p)) != 0) -#else - if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) -#endif - return (error); - break; - } - - s = splimp(); - switch (cmd) { - - case CDNR_IF_ATTACH: - ifacep = (struct cdnr_interface *)addr; - error = cdnrcmd_if_attach(ifacep->cdnr_ifname); - break; - - case CDNR_IF_DETACH: - ifacep = (struct cdnr_interface *)addr; - error = cdnrcmd_if_detach(ifacep->cdnr_ifname); - break; - - case CDNR_ENABLE: - case CDNR_DISABLE: - ifacep = (struct cdnr_interface *)addr; - if ((top = tcb_lookup(ifacep->cdnr_ifname)) == NULL) { - error = EBADF; - break; - } - - switch (cmd) { - - case CDNR_ENABLE: - ALTQ_SET_CNDTNING(top->tc_ifq); - if (altq_input == NULL) - altq_input = altq_cdnr_input; - break; - - case CDNR_DISABLE: - ALTQ_CLEAR_CNDTNING(top->tc_ifq); - LIST_FOREACH(top, &tcb_list, tc_next) - if (ALTQ_IS_CNDTNING(top->tc_ifq)) - break; - if (top == NULL) - altq_input = NULL; - break; - } - break; - - case CDNR_ADD_ELEM: - error = cdnrcmd_add_element((struct cdnr_add_element *)addr); - break; - - case CDNR_DEL_ELEM: - error = cdnrcmd_delete_element((struct cdnr_delete_element *)addr); - break; - - case CDNR_ADD_TBM: - error = cdnrcmd_add_tbm((struct cdnr_add_tbmeter *)addr); - break; - - case CDNR_MOD_TBM: - error = cdnrcmd_modify_tbm((struct cdnr_modify_tbmeter *)addr); - break; - - case CDNR_TBM_STATS: - error = cdnrcmd_tbm_stats((struct cdnr_tbmeter_stats *)addr); - break; - - case CDNR_ADD_TCM: - error = cdnrcmd_add_trtcm((struct cdnr_add_trtcm *)addr); - break; - - case CDNR_MOD_TCM: - error = cdnrcmd_modify_trtcm((struct cdnr_modify_trtcm *)addr); - break; - - case CDNR_TCM_STATS: - error = cdnrcmd_tcm_stats((struct cdnr_tcm_stats *)addr); - break; - - case CDNR_ADD_FILTER: - error = cdnrcmd_add_filter((struct cdnr_add_filter *)addr); - break; - - case CDNR_DEL_FILTER: - error = cdnrcmd_delete_filter((struct cdnr_delete_filter *)addr); - break; - - case CDNR_GETSTATS: - error = cdnrcmd_get_stats((struct cdnr_get_stats *)addr); - break; - - case CDNR_ADD_TSW: - error = cdnrcmd_add_tswtcm((struct cdnr_add_tswtcm *)addr); - break; - - case CDNR_MOD_TSW: - error = cdnrcmd_modify_tswtcm((struct cdnr_modify_tswtcm *)addr); - break; - - default: - error = EINVAL; - break; - } - splx(s); - - return error; -} - -#ifdef KLD_MODULE - -static struct altqsw cdnr_sw = - {"cdnr", cdnropen, cdnrclose, cdnrioctl}; - -ALTQ_MODULE(altq_cdnr, ALTQT_CDNR, &cdnr_sw); - -#endif /* KLD_MODULE */ diff --git a/sys/altq/altq_cdnr.h b/sys/altq/altq_cdnr.h index 7ad53bd5bd5..9cf388b917b 100644 --- a/sys/altq/altq_cdnr.h +++ b/sys/altq/altq_cdnr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: altq_cdnr.h,v 1.2 2002/11/26 01:03:34 henning Exp $ */ +/* $OpenBSD: altq_cdnr.h,v 1.3 2002/12/16 09:18:05 kjc Exp $ */ /* $KAME: altq_cdnr.h,v 1.6 2000/12/14 08:12:45 thorpej Exp $ */ /* @@ -163,19 +163,6 @@ struct cdnr_modify_tswtcm { u_int32_t avg_interval; /* averaging interval (msec) */ }; -struct cdnr_add_filter { - struct cdnr_interface iface; - u_long cdnr_handle; - struct flow_filter filter; - - u_long filter_handle; /* return value */ -}; - -struct cdnr_delete_filter { - struct cdnr_interface iface; - u_long filter_handle; -}; - struct tce_stats { u_long tce_handle; /* tc element handle */ int tce_type; /* e.g., TCETYPE_ELEMENT */ @@ -192,24 +179,6 @@ struct cdnr_get_stats { struct tce_stats *tce_stats; /* pointer to stats array */ }; -#define CDNR_IF_ATTACH _IOW('Q', 1, struct cdnr_interface) -#define CDNR_IF_DETACH _IOW('Q', 2, struct cdnr_interface) -#define CDNR_ENABLE _IOW('Q', 3, struct cdnr_interface) -#define CDNR_DISABLE _IOW('Q', 4, struct cdnr_interface) -#define CDNR_ADD_FILTER _IOWR('Q', 10, struct cdnr_add_filter) -#define CDNR_DEL_FILTER _IOW('Q', 11, struct cdnr_delete_filter) -#define CDNR_GETSTATS _IOWR('Q', 12, struct cdnr_get_stats) -#define CDNR_ADD_ELEM _IOWR('Q', 30, struct cdnr_add_element) -#define CDNR_DEL_ELEM _IOW('Q', 31, struct cdnr_delete_element) -#define CDNR_ADD_TBM _IOWR('Q', 32, struct cdnr_add_tbmeter) -#define CDNR_MOD_TBM _IOW('Q', 33, struct cdnr_modify_tbmeter) -#define CDNR_TBM_STATS _IOWR('Q', 34, struct cdnr_tbmeter_stats) -#define CDNR_ADD_TCM _IOWR('Q', 35, struct cdnr_add_trtcm) -#define CDNR_MOD_TCM _IOWR('Q', 36, struct cdnr_modify_trtcm) -#define CDNR_TCM_STATS _IOWR('Q', 37, struct cdnr_tcm_stats) -#define CDNR_ADD_TSW _IOWR('Q', 38, struct cdnr_add_tswtcm) -#define CDNR_MOD_TSW _IOWR('Q', 39, struct cdnr_modify_tswtcm) - #ifndef DSCP_EF /* diffserve code points */ #define DSCP_MASK 0xfc @@ -266,7 +235,6 @@ struct top_cdnr { struct ifaltq *tc_ifq; LIST_HEAD(, cdnr_block) tc_elements; - struct acc_classifier tc_classifier; struct pktcntr tc_cnts[TCACODE_MAX+1]; }; diff --git a/sys/altq/altq_conf.c b/sys/altq/altq_conf.c deleted file mode 100644 index 1a5a5b51205..00000000000 --- a/sys/altq/altq_conf.c +++ /dev/null @@ -1,414 +0,0 @@ -/* $OpenBSD: altq_conf.c,v 1.4 2002/11/26 01:03:34 henning Exp $ */ -/* $KAME: altq_conf.c,v 1.11 2001/06/21 11:00:36 kjc Exp $ */ - -/* - * Copyright (C) 1997-2000 - * Sony Computer Science Laboratories Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * altq device interface. - */ -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/socket.h> -#include <sys/kernel.h> -#include <sys/proc.h> -#include <sys/errno.h> -#if defined(__FreeBSD__) && (__FreeBSD_version < 400000) && defined(DEVFS) -#include <sys/devfsext.h> -#endif /*DEVFS*/ -#include <net/if.h> - -#include <altq/altq.h> -#include <altq/altq_conf.h> - -#ifdef ALTQ_CBQ -altqdev_decl(cbq); -#endif -#ifdef ALTQ_WFQ -altqdev_decl(wfq); -#endif -#ifdef ALTQ_AFMAP -altqdev_decl(afm); -#endif -#ifdef ALTQ_FIFOQ -altqdev_decl(fifoq); -#endif -#ifdef ALTQ_RED -altqdev_decl(red); -#endif -#ifdef ALTQ_RIO -altqdev_decl(rio); -#endif -#ifdef ALTQ_LOCALQ -altqdev_decl(localq); -#endif -#ifdef ALTQ_HFSC -altqdev_decl(hfsc); -#endif -#ifdef ALTQ_CDNR -altqdev_decl(cdnr); -#endif -#ifdef ALTQ_BLUE -altqdev_decl(blue); -#endif -#ifdef ALTQ_PRIQ -altqdev_decl(priq); -#endif - -/* - * altq minor device (discipline) table - */ -static struct altqsw altqsw[] = { /* minor */ - {"noq", noopen, noclose, noioctl}, /* 0 (reserved) */ -#ifdef ALTQ_CBQ - {"cbq", cbqopen, cbqclose, cbqioctl}, /* 1 */ -#else - {"noq", noopen, noclose, noioctl}, /* 1 */ -#endif -#ifdef ALTQ_WFQ - {"wfq", wfqopen, wfqclose, wfqioctl}, /* 2 */ -#else - {"noq", noopen, noclose, noioctl}, /* 2 */ -#endif -#ifdef ALTQ_AFMAP - {"afm", afmopen, afmclose, afmioctl}, /* 3 */ -#else - {"noq", noopen, noclose, noioctl}, /* 3 */ -#endif -#ifdef ALTQ_FIFOQ - {"fifoq", fifoqopen, fifoqclose, fifoqioctl}, /* 4 */ -#else - {"noq", noopen, noclose, noioctl}, /* 4 */ -#endif -#ifdef ALTQ_RED - {"red", redopen, redclose, redioctl}, /* 5 */ -#else - {"noq", noopen, noclose, noioctl}, /* 5 */ -#endif -#ifdef ALTQ_RIO - {"rio", rioopen, rioclose, rioioctl}, /* 6 */ -#else - {"noq", noopen, noclose, noioctl}, /* 6 */ -#endif -#ifdef ALTQ_LOCALQ - {"localq",localqopen, localqclose, localqioctl}, /* 7 (local use) */ -#else - {"noq", noopen, noclose, noioctl}, /* 7 (local use) */ -#endif -#ifdef ALTQ_HFSC - {"hfsc",hfscopen, hfscclose, hfscioctl}, /* 8 */ -#else - {"noq", noopen, noclose, noioctl}, /* 8 */ -#endif -#ifdef ALTQ_CDNR - {"cdnr",cdnropen, cdnrclose, cdnrioctl}, /* 9 */ -#else - {"noq", noopen, noclose, noioctl}, /* 9 */ -#endif -#ifdef ALTQ_BLUE - {"blue",blueopen, blueclose, blueioctl}, /* 10 */ -#else - {"noq", noopen, noclose, noioctl}, /* 10 */ -#endif -#ifdef ALTQ_PRIQ - {"priq",priqopen, priqclose, priqioctl}, /* 11 */ -#else - {"noq", noopen, noclose, noioctl}, /* 11 */ -#endif -}; - -/* - * altq major device support - */ -int naltqsw = sizeof (altqsw) / sizeof (altqsw[0]); - -#ifdef __FreeBSD__ -static d_open_t altqopen; -static d_close_t altqclose; -static d_ioctl_t altqioctl; -static void altq_drvinit(void *); -#else -void altqattach(int); -#endif - -#if defined(__FreeBSD__) -#define CDEV_MAJOR 96 /* FreeBSD official number */ - -#if (__FreeBSD_version < 400000) -static struct cdevsw altq_cdevsw = - { altqopen, altqclose, noread, nowrite, - altqioctl, nostop, nullreset, nodevtotty, - seltrue, nommap, NULL, "altq", NULL, -1 }; -#else -static struct cdevsw altq_cdevsw = - { altqopen, altqclose, noread, nowrite, - altqioctl, seltrue, nommap, nostrategy, - "altq", CDEV_MAJOR, nodump, nopsize, 0, -1 }; -#endif -#endif /* FreeBSD */ - -#ifdef __FreeBSD__ -static -#endif -int -altqopen(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - int unit = minor(dev); - - if (unit == 0) - return (0); - if (unit < naltqsw) - return (*altqsw[unit].d_open)(dev, flag, fmt, p); - - return ENXIO; -} - -#ifdef __FreeBSD__ -static -#endif -int -altqclose(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - int unit = minor(dev); - - if (unit == 0) - return (0); - if (unit < naltqsw) - return (*altqsw[unit].d_close)(dev, flag, fmt, p); - - return ENXIO; -} - -#ifdef __FreeBSD__ -static -#endif -int -altqioctl(dev, cmd, addr, flag, p) - dev_t dev; - ioctlcmd_t cmd; - caddr_t addr; - int flag; - struct proc *p; -{ - int unit = minor(dev); - - if (unit == 0) { - struct ifnet *ifp; - struct altqreq *typereq; - struct tbrreq *tbrreq; - int error; - - switch (cmd) { - case ALTQGTYPE: - case ALTQTBRGET: - break; - default: -#if (__FreeBSD_version > 400000) - if ((error = suser(p)) != 0) - return (error); -#else - if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) - return (error); -#endif - break; - } - - switch (cmd) { - case ALTQGTYPE: - typereq = (struct altqreq *)addr; - if ((ifp = ifunit(typereq->ifname)) == NULL) - return (EINVAL); - typereq->arg = (u_long)ifp->if_snd.altq_type; - return (0); - case ALTQTBRSET: - tbrreq = (struct tbrreq *)addr; - if ((ifp = ifunit(tbrreq->ifname)) == NULL) - return (EINVAL); - return tbr_set(&ifp->if_snd, &tbrreq->tb_prof); - case ALTQTBRGET: - tbrreq = (struct tbrreq *)addr; - if ((ifp = ifunit(tbrreq->ifname)) == NULL) - return (EINVAL); - return tbr_get(&ifp->if_snd, &tbrreq->tb_prof); - default: - return (EINVAL); - } - } - if (unit < naltqsw) - return (*altqsw[unit].d_ioctl)(dev, cmd, addr, flag, p); - - return ENXIO; -} - -#ifdef __FreeBSD__ - -static int altq_devsw_installed = 0; - -#if (__FreeBSD_version < 400000) -#ifdef DEVFS -static void *altq_devfs_token[sizeof (altqsw) / sizeof (altqsw[0])]; -#endif - -static void -altq_drvinit(unused) - void *unused; -{ - dev_t dev; -#ifdef DEVFS - int i; -#endif - - if (!altq_devsw_installed) { - dev = makedev(CDEV_MAJOR,0); - cdevsw_add(&dev,&altq_cdevsw,NULL); - altq_devsw_installed = 1; -#ifdef DEVFS - for (i=0; i<naltqsw; i++) - altq_devfs_token[i] = - devfs_add_devswf(&altq_cdevsw, i, DV_CHR, - 0, 0, 0644, altqsw[i].d_name); -#endif - printf("altq: major number is %d\n", CDEV_MAJOR); - } -} - -#else /* FreeBSD 4.x */ - -static void -altq_drvinit(unused) - void *unused; -{ - int unit; - - cdevsw_add(&altq_cdevsw); - altq_devsw_installed = 1; - printf("altq: major number is %d\n", CDEV_MAJOR); - - /* create minor devices */ - for (unit = 0; unit < naltqsw; unit++) - make_dev(&altq_cdevsw, unit, 0, 0, 0644, - altqsw[unit].d_name); -} - -#endif /* FreeBSD 4.x */ - -SYSINIT(altqdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,altq_drvinit,NULL) - -#endif /* FreeBSD */ - -#ifdef ALTQ_KLD -/* - * KLD support - */ -static int altq_module_register(struct altq_module_data *); -static int altq_module_deregister(struct altq_module_data *); - -static struct altq_module_data *altq_modules[ALTQT_MAX]; -static struct altqsw noqdisc = {"noq", noopen, noclose, noioctl}; - -void altq_module_incref(type) - int type; -{ - if (type < 0 || type >= ALTQT_MAX || altq_modules[type] == NULL) - return; - - altq_modules[type]->ref++; -} - -void altq_module_declref(type) - int type; -{ - if (type < 0 || type >= ALTQT_MAX || altq_modules[type] == NULL) - return; - - altq_modules[type]->ref--; -} - -static int -altq_module_register(mdata) - struct altq_module_data *mdata; -{ - int type = mdata->type; - - if (type < 0 || type >= ALTQT_MAX) - return (EINVAL); - if (altqsw[type].d_open != noopen) - return (EBUSY); - altqsw[type] = *mdata->altqsw; /* set discipline functions */ - altq_modules[type] = mdata; /* save module data pointer */ - return (0); -} - -static int -altq_module_deregister(mdata) - struct altq_module_data *mdata; -{ - int type = mdata->type; - - if (type < 0 || type >= ALTQT_MAX) - return (EINVAL); - if (mdata != altq_modules[type]) - return (EINVAL); - if (altq_modules[type]->ref > 0) - return (EBUSY); - altqsw[type] = noqdisc; - altq_modules[type] = NULL; - return (0); -} - -int -altq_module_handler(mod, cmd, arg) - module_t mod; - int cmd; - void * arg; -{ - struct altq_module_data *data = (struct altq_module_data *)arg; - int error = 0; - - switch (cmd) { - case MOD_LOAD: - error = altq_module_register(data); - break; - - case MOD_UNLOAD: - error = altq_module_deregister(data); - break; - - default: - error = EINVAL; - break; - } - - return(error); -} - -#endif /* ALTQ_KLD */ diff --git a/sys/altq/altq_conf.h b/sys/altq/altq_conf.h deleted file mode 100644 index 601901d6eca..00000000000 --- a/sys/altq/altq_conf.h +++ /dev/null @@ -1,108 +0,0 @@ -/* $OpenBSD: altq_conf.h,v 1.2 2002/03/14 01:26:26 millert Exp $ */ -/* $KAME: altq_conf.h,v 1.6 2001/01/29 19:59:09 itojun Exp $ */ - -/* - * Copyright (C) 1998-2000 - * Sony Computer Science Laboratories Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -#ifndef _ALTQ_ALTQ_CONF_H_ -#define _ALTQ_ALTQ_CONF_H_ - -#ifdef _KERNEL - -#include <sys/param.h> -#include <sys/conf.h> -#include <sys/kernel.h> - -#if (__FreeBSD_version > 300000) -#define ALTQ_KLD -#endif - -#ifdef ALTQ_KLD -#include <sys/module.h> -#endif - -#ifndef dev_decl -#ifdef __STDC__ -#define dev_decl(n,t) d_ ## t ## _t n ## t -#else -#define dev_decl(n,t) d_/**/t/**/_t n/**/t -#endif -#endif - -#if defined(__NetBSD__) || defined(__OpenBSD__) -typedef int d_open_t(dev_t, int, int, struct proc *); -typedef int d_close_t(dev_t, int, int, struct proc *); -typedef int d_ioctl_t(dev_t, u_long, caddr_t, int, struct proc *); - -#define noopen (dev_type_open((*))) enodev -#define noclose (dev_type_close((*))) enodev -#define noioctl (dev_type_ioctl((*))) enodev -#endif /* __NetBSD__ || __OpenBSD__ */ - -#if defined(__OpenBSD__) -int altqopen(dev_t, int, int, struct proc *); -int altqclose(dev_t, int, int, struct proc *); -int altqioctl(dev_t, u_long, caddr_t, int, struct proc *); -#endif - -/* - * altq queueing discipline switch structure - */ -struct altqsw { - char *d_name; - d_open_t *d_open; - d_close_t *d_close; - d_ioctl_t *d_ioctl; -}; - -#define altqdev_decl(n) \ - dev_decl(n,open); dev_decl(n,close); dev_decl(n,ioctl) - -#ifdef ALTQ_KLD - -struct altq_module_data { - int type; /* discipline type */ - int ref; /* reference count */ - struct altqsw *altqsw; /* discipline functions */ -}; - -#define ALTQ_MODULE(name, type, devsw) \ -static struct altq_module_data name##_moddata = { type, 0, devsw }; \ - \ -moduledata_t name##_mod = { \ - #name, \ - altq_module_handler, \ - &name##_moddata \ -}; \ -DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+96) - -void altq_module_incref(int); -void altq_module_declref(int); -int altq_module_handler(module_t, int, void *); - -#endif /* ALTQ_KLD */ - -#endif /* _KERNEL */ -#endif /* _ALTQ_ALTQ_CONF_H_ */ diff --git a/sys/altq/altq_fifoq.c b/sys/altq/altq_fifoq.c deleted file mode 100644 index ccb6075b73d..00000000000 --- a/sys/altq/altq_fifoq.c +++ /dev/null @@ -1,408 +0,0 @@ -/* $OpenBSD: altq_fifoq.c,v 1.5 2002/11/26 01:03:34 henning Exp $ */ -/* $KAME: altq_fifoq.c,v 1.7 2000/12/14 08:12:45 thorpej Exp $ */ - -/* - * Copyright (C) 1997-2000 - * Sony Computer Science Laboratories Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * FIFOQ is an altq sample implementation. There will be little - * need to use FIFOQ as an alternative queueing scheme. - * But this code is provided as a template for those who want to - * write their own queueing schemes. - */ - -#include <sys/param.h> -#include <sys/malloc.h> -#include <sys/mbuf.h> -#include <sys/socket.h> -#include <sys/sockio.h> -#include <sys/systm.h> -#include <sys/proc.h> -#include <sys/errno.h> -#include <sys/kernel.h> - -#include <net/if.h> -#include <net/if_types.h> -#include <netinet/in.h> - -#include <altq/altq.h> -#include <altq/altq_conf.h> -#include <altq/altq_fifoq.h> - -#define FIFOQ_STATS /* collect statistics */ - -/* fifoq_list keeps all fifoq_state_t's allocated. */ -static fifoq_state_t *fifoq_list = NULL; - -/* internal function prototypes */ -static int fifoq_enqueue(struct ifaltq *, struct mbuf *, - struct altq_pktattr *); -static struct mbuf *fifoq_dequeue(struct ifaltq *, int); -static int fifoq_detach(fifoq_state_t *); -static int fifoq_request(struct ifaltq *, int, void *); -static void fifoq_purge(fifoq_state_t *); - -/* - * fifoq device interface - */ -altqdev_decl(fifoq); - -int -fifoqopen(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - /* everything will be done when the queueing scheme is attached. */ - return 0; -} - -/* - * there are 2 ways to act on close. - * detach-all-on-close: - * use for the daemon style approach. if the daemon dies, all the - * resource will be released. - * no-action-on-close: - * use for the command style approach. (e.g. fifoq on/off) - * - * note: close is called not on every close but when the last reference - * is removed (only once with multiple simultaneous references.) - */ -int -fifoqclose(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - fifoq_state_t *q; - int err, error = 0; - - while ((q = fifoq_list) != NULL) { - /* destroy all */ - err = fifoq_detach(q); - if (err != 0 && error == 0) - error = err; - } - - return error; -} - -int -fifoqioctl(dev, cmd, addr, flag, p) - dev_t dev; - ioctlcmd_t cmd; - caddr_t addr; - int flag; - struct proc *p; -{ - fifoq_state_t *q; - struct fifoq_interface *ifacep; - struct ifnet *ifp; - int error = 0; - - /* check super-user privilege */ - switch (cmd) { - case FIFOQ_GETSTATS: - break; - default: -#if (__FreeBSD_version > 400000) - if ((error = suser(p)) != 0) - return (error); -#else - if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) - return (error); -#endif - break; - } - - switch (cmd) { - case FIFOQ_ENABLE: - ifacep = (struct fifoq_interface *)addr; - if ((q = altq_lookup(ifacep->fifoq_ifname, ALTQT_FIFOQ)) - == NULL) { - error = EBADF; - break; - } - error = altq_enable(q->q_ifq); - break; - - case FIFOQ_DISABLE: - ifacep = (struct fifoq_interface *)addr; - if ((q = altq_lookup(ifacep->fifoq_ifname, ALTQT_FIFOQ)) - == NULL) { - error = EBADF; - break; - } - error = altq_disable(q->q_ifq); - break; - - case FIFOQ_IF_ATTACH: - ifp = ifunit(((struct fifoq_interface *)addr)->fifoq_ifname); - if (ifp == NULL) { - error = ENXIO; - break; - } - - /* allocate and initialize fifoq_state_t */ - MALLOC(q, fifoq_state_t *, sizeof(fifoq_state_t), - M_DEVBUF, M_WAITOK); - if (q == NULL) { - error = ENOMEM; - break; - } - bzero(q, sizeof(fifoq_state_t)); - - q->q_ifq = &ifp->if_snd; - q->q_head = q->q_tail = NULL; - q->q_len = 0; - q->q_limit = FIFOQ_LIMIT; - - /* - * set FIFOQ to this ifnet structure. - */ - error = altq_attach(q->q_ifq, ALTQT_FIFOQ, q, - fifoq_enqueue, fifoq_dequeue, fifoq_request, - NULL, NULL); - if (error) { - FREE(q, M_DEVBUF); - break; - } - - /* add this state to the fifoq list */ - q->q_next = fifoq_list; - fifoq_list = q; - break; - - case FIFOQ_IF_DETACH: - ifacep = (struct fifoq_interface *)addr; - if ((q = altq_lookup(ifacep->fifoq_ifname, ALTQT_FIFOQ)) - == NULL) { - error = EBADF; - break; - } - error = fifoq_detach(q); - break; - - case FIFOQ_GETSTATS: - do { - struct fifoq_getstats *q_stats; - - q_stats = (struct fifoq_getstats *)addr; - if ((q = altq_lookup(q_stats->iface.fifoq_ifname, - ALTQT_FIFOQ)) == NULL) { - error = EBADF; - break; - } - - q_stats->q_len = q->q_len; - q_stats->q_limit = q->q_limit; - q_stats->xmit_cnt = q->q_stats.xmit_cnt; - q_stats->drop_cnt = q->q_stats.drop_cnt; - q_stats->period = q->q_stats.period; - } while (0); - break; - - case FIFOQ_CONFIG: - do { - struct fifoq_conf *fc; - int limit; - - fc = (struct fifoq_conf *)addr; - if ((q = altq_lookup(fc->iface.fifoq_ifname, - ALTQT_FIFOQ)) == NULL) { - error = EBADF; - break; - } - limit = fc->fifoq_limit; - if (limit < 0) - limit = 0; - q->q_limit = limit; - fc->fifoq_limit = limit; - } while (0); - break; - - default: - error = EINVAL; - break; - } - return error; -} - -/* - * fifoq support routines - */ - -/* - * enqueue routine: - * - * returns: 0 when successfully queued. - * ENOBUFS when drop occurs. - */ -static int -fifoq_enqueue(ifq, m, pktattr) - struct ifaltq *ifq; - struct mbuf *m; - struct altq_pktattr *pktattr; -{ - fifoq_state_t *q = (fifoq_state_t *)ifq->altq_disc; - - /* if the queue is full, drop the incoming packet(drop-tail) */ - if (q->q_len >= q->q_limit) { -#ifdef FIFOQ_STATS - PKTCNTR_ADD(&q->q_stats.drop_cnt, m_pktlen(m)); -#endif - m_freem(m); - return (ENOBUFS); - } - - /* enqueue the packet at the taile of the queue */ - m->m_nextpkt = NULL; - if (q->q_tail == NULL) - q->q_head = m; - else - q->q_tail->m_nextpkt = m; - q->q_tail = m; - q->q_len++; - ifq->ifq_len++; - return 0; -} - -/* - * dequeue routine: - * must be called in splimp. - * - * returns: mbuf dequeued. - * NULL when no packet is available in the queue. - */ -/* - * ALTDQ_PEEK is provided for drivers which need to know the next packet - * to send in advance. - * when ALTDQ_PEEK is specified, the next packet to be dequeued is - * returned without dequeueing the packet. - * when ALTDQ_DEQUEUE is called *immediately after* an ALTDQ_PEEK - * operation, the same packet should be returned. - */ -static struct mbuf * -fifoq_dequeue(ifq, op) - struct ifaltq *ifq; - int op; -{ - fifoq_state_t *q = (fifoq_state_t *)ifq->altq_disc; - struct mbuf *m = NULL; - - if (op == ALTDQ_POLL) - return (q->q_head); - - if ((m = q->q_head) == NULL) - return (NULL); - - if ((q->q_head = m->m_nextpkt) == NULL) - q->q_tail = NULL; - m->m_nextpkt = NULL; - q->q_len--; - ifq->ifq_len--; -#ifdef FIFOQ_STATS - PKTCNTR_ADD(&q->q_stats.xmit_cnt, m_pktlen(m)); - if (q->q_len == 0) - q->q_stats.period++; -#endif - return (m); -} - -static int -fifoq_request(ifq, req, arg) - struct ifaltq *ifq; - int req; - void *arg; -{ - fifoq_state_t *q = (fifoq_state_t *)ifq->altq_disc; - - switch (req) { - case ALTRQ_PURGE: - fifoq_purge(q); - break; - } - return (0); -} - - -static int fifoq_detach(q) - fifoq_state_t *q; -{ - fifoq_state_t *tmp; - int error = 0; - - if (ALTQ_IS_ENABLED(q->q_ifq)) - altq_disable(q->q_ifq); - - fifoq_purge(q); - - if ((error = altq_detach(q->q_ifq))) - return (error); - - if (fifoq_list == q) - fifoq_list = q->q_next; - else { - for (tmp = fifoq_list; tmp != NULL; tmp = tmp->q_next) - if (tmp->q_next == q) { - tmp->q_next = q->q_next; - break; - } - if (tmp == NULL) - printf("fifoq_detach: no state in fifoq_list!\n"); - } - - FREE(q, M_DEVBUF); - return (error); -} - -/* - * fifoq_purge - * should be called in splimp or after disabling the fifoq. - */ -static void fifoq_purge(q) - fifoq_state_t *q; -{ - struct mbuf *m; - - while ((m = q->q_head) != NULL) { - q->q_head = m->m_nextpkt; - m_freem(m); - } - q->q_tail = NULL; - q->q_len = 0; - if (ALTQ_IS_ENABLED(q->q_ifq)) - q->q_ifq->ifq_len = 0; -} - -#ifdef KLD_MODULE - -static struct altqsw fifoq_sw = - {"fifoq", fifoqopen, fifoqclose, fifoqioctl}; - -ALTQ_MODULE(altq_fifoq, ALTQT_FIFOQ, &fifoq_sw); - -#endif /* KLD_MODULE */ diff --git a/sys/altq/altq_fifoq.h b/sys/altq/altq_fifoq.h deleted file mode 100644 index 7774eff6d3a..00000000000 --- a/sys/altq/altq_fifoq.h +++ /dev/null @@ -1,80 +0,0 @@ -/* $OpenBSD: altq_fifoq.h,v 1.3 2002/11/26 01:03:34 henning Exp $ */ -/* $KAME: altq_fifoq.h,v 1.6 2000/12/14 08:12:45 thorpej Exp $ */ - -/* - * Copyright (C) 1997-2000 - * Sony Computer Science Laboratories Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _ALTQ_ALTQ_FIFOQ_H_ -#define _ALTQ_ALTQ_FIFOQ_H_ - -typedef struct fifoq_state { - struct fifoq_state *q_next; /* next fifoq_state in the list */ - struct ifaltq *q_ifq; /* backpointer to ifaltq */ - - struct mbuf *q_head; /* head of queue */ - struct mbuf *q_tail; /* tail of queue */ - int q_len; /* queue length */ - int q_limit; /* max queue length */ - - /* statistics */ - struct { - struct pktcntr xmit_cnt; - struct pktcntr drop_cnt; - u_int period; - } q_stats; -} fifoq_state_t; - -struct fifoq_interface { - char fifoq_ifname[IFNAMSIZ]; -}; - -struct fifoq_getstats { - struct fifoq_interface iface; - int q_len; - int q_limit; - struct pktcntr xmit_cnt; - struct pktcntr drop_cnt; - u_int period; -}; - -struct fifoq_conf { - struct fifoq_interface iface; - int fifoq_limit; -}; - -#define FIFOQ_LIMIT 50 /* default max queue length */ - -/* - * IOCTLs for FIFOQ - */ -#define FIFOQ_IF_ATTACH _IOW('Q', 1, struct fifoq_interface) -#define FIFOQ_IF_DETACH _IOW('Q', 2, struct fifoq_interface) -#define FIFOQ_ENABLE _IOW('Q', 3, struct fifoq_interface) -#define FIFOQ_DISABLE _IOW('Q', 4, struct fifoq_interface) -#define FIFOQ_CONFIG _IOWR('Q', 6, struct fifoq_conf) -#define FIFOQ_GETSTATS _IOWR('Q', 12, struct fifoq_getstats) - -#endif /* _ALTQ_ALTQ_FIFOQ_H_ */ diff --git a/sys/altq/altq_flowvalve.h b/sys/altq/altq_flowvalve.h deleted file mode 100644 index 39d5c4b383e..00000000000 --- a/sys/altq/altq_flowvalve.h +++ /dev/null @@ -1,93 +0,0 @@ -/* $OpenBSD: altq_flowvalve.h,v 1.1 2001/06/27 05:28:35 kjc Exp $ */ -/* $KAME: altq_flowvalve.h,v 1.4 2000/12/14 08:12:46 thorpej Exp $ */ - -/* - * Copyright (C) 1998-2000 - * Sony Computer Science Laboratories Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _ALTQ_ALTQ_FLOWVALVE_H_ -#define _ALTQ_ALTQ_FLOWVALVE_H_ - -#ifdef _KERNEL - -/* fv_flow structure to define a unique address pair */ -struct fv_flow { - int flow_af; /* address family */ - union { - struct { - struct in_addr ip_src; - struct in_addr ip_dst; - } _ip; -#ifdef INET6 - struct { - struct in6_addr ip6_src; - struct in6_addr ip6_dst; - } _ip6; -#endif - } flow_un; -}; - -#define flow_ip flow_un._ip -#define flow_ip6 flow_un._ip6 - -/* flowvalve entry */ -struct fve { - TAILQ_ENTRY(fve) fve_lru; /* for LRU list */ - - enum fv_state { Green, Red } fve_state; - - int fve_p; /* scaled average drop rate */ - int fve_f; /* scaled average fraction */ - int fve_count; /* counter to update f */ - u_int fve_ifseq; /* ifseq at the last update of f */ - struct timeval fve_lastdrop; /* timestamp of the last drop */ - - struct fv_flow fve_flow; /* unique address pair */ -}; - -/* flowvalve structure */ -struct flowvalve { - u_int fv_ifseq; /* packet sequence number */ - int fv_flows; /* number of valid flows in the flowlist */ - int fv_pthresh; /* drop rate threshold */ - - TAILQ_HEAD(fv_flowhead, fve) fv_flowlist; /* LRU list */ - - struct fve *fv_fves; /* pointer to the allocated fves */ - - int *fv_p2ftab; /* drop rate to fraction table */ - - struct { - u_int pass; /* # of packets that have the fve - but aren't predropped */ - u_int predrop; /* # of packets predropped */ - u_int alloc; /* # of fves assigned */ - u_int escape; /* # of fves escaped */ - } fv_stats; -}; - -#endif /* _KERNEL */ - -#endif /* _ALTQ_ALTQ_FLOWVALVE_H_ */ diff --git a/sys/altq/altq_hfsc.c b/sys/altq/altq_hfsc.c index 5646337e007..f29989b476f 100644 --- a/sys/altq/altq_hfsc.c +++ b/sys/altq/altq_hfsc.c @@ -1,5 +1,5 @@ -/* $OpenBSD: altq_hfsc.c,v 1.7 2002/11/29 07:52:31 kjc Exp $ */ -/* $KAME: altq_hfsc.c,v 1.13 2002/05/16 11:02:58 kjc Exp $ */ +/* $OpenBSD: altq_hfsc.c,v 1.8 2002/12/16 09:18:05 kjc Exp $ */ +/* $KAME: altq_hfsc.c,v 1.17 2002/11/29 07:48:33 kjc Exp $ */ /* * Copyright (c) 1997-1999 Carnegie Mellon University. All Rights Reserved. @@ -38,41 +38,39 @@ * "A Hierarchical Fair Service Curve Algorithm for Link-Sharing, * Real-Time and Priority Service" * by Ion Stoica, Hui Zhang, and T. S. Eugene Ng. + * + * Oleg Cherevko <olwi@aq.ml.com.ua> added the upperlimit for link-sharing. + * when a class has an upperlimit, the fit-time is computed from the + * upperlimit service curve. the link-sharing scheduler does not schedule + * a class whose fit-time exceeds the current time. */ #include <sys/param.h> #include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/socket.h> -#include <sys/sockio.h> #include <sys/systm.h> -#include <sys/proc.h> #include <sys/errno.h> -#include <sys/kernel.h> #include <sys/queue.h> #include <net/if.h> -#include <net/if_types.h> +#include <netinet/in.h> +#include <net/pfvar.h> #include <altq/altq.h> -#include <altq/altq_conf.h> #include <altq/altq_hfsc.h> /* * function prototypes */ -static struct hfsc_if *hfsc_attach(struct ifaltq *, u_int); -static int hfsc_detach(struct hfsc_if *); static int hfsc_clear_interface(struct hfsc_if *); static int hfsc_request(struct ifaltq *, int, void *); static void hfsc_purge(struct hfsc_if *); static struct hfsc_class *hfsc_class_create(struct hfsc_if *, - struct service_curve *, struct hfsc_class *, int, int); + struct service_curve *, struct service_curve *, struct service_curve *, + struct hfsc_class *, int, int); static int hfsc_class_destroy(struct hfsc_class *); -static int hfsc_class_modify(struct hfsc_class *, - struct service_curve *, struct service_curve *); static struct hfsc_class *hfsc_nextclass(struct hfsc_class *); - static int hfsc_enqueue(struct ifaltq *, struct mbuf *, struct altq_pktattr *); static struct mbuf *hfsc_dequeue(struct ifaltq *, int); @@ -81,25 +79,27 @@ static struct mbuf *hfsc_getq(struct hfsc_class *); static struct mbuf *hfsc_pollq(struct hfsc_class *); static void hfsc_purgeq(struct hfsc_class *); +static void update_cfmin(struct hfsc_class *); static void set_active(struct hfsc_class *, int); static void set_passive(struct hfsc_class *); static void init_ed(struct hfsc_class *, int); static void update_ed(struct hfsc_class *, int); static void update_d(struct hfsc_class *, int); -static void init_v(struct hfsc_class *, int); -static void update_v(struct hfsc_class *, int); +static void init_vf(struct hfsc_class *, int); +static void update_vf(struct hfsc_class *, int, u_int64_t); static ellist_t *ellist_alloc(void); static void ellist_destroy(ellist_t *); static void ellist_insert(struct hfsc_class *); static void ellist_remove(struct hfsc_class *); static void ellist_update(struct hfsc_class *); -struct hfsc_class *ellist_get_mindl(ellist_t *); +struct hfsc_class *ellist_get_mindl(ellist_t *, u_int64_t); static actlist_t *actlist_alloc(void); static void actlist_destroy(actlist_t *); static void actlist_insert(struct hfsc_class *); static void actlist_remove(struct hfsc_class *); static void actlist_update(struct hfsc_class *); +static struct hfsc_class *actlist_firstfit(struct hfsc_class *, u_int64_t); static __inline u_int64_t seg_x2y(u_int64_t, u_int64_t); static __inline u_int64_t seg_y2x(u_int64_t, u_int64_t); @@ -117,39 +117,45 @@ static u_int64_t rtsc_x2y(struct runtime_sc *, u_int64_t); static void rtsc_min(struct runtime_sc *, struct internal_sc *, u_int64_t, u_int64_t); -int hfscopen(dev_t, int, int, struct proc *); -int hfscclose(dev_t, int, int, struct proc *); -int hfscioctl(dev_t, ioctlcmd_t, caddr_t, int, struct proc *); -static int hfsccmd_if_attach(struct hfsc_attach *); -static int hfsccmd_if_detach(struct hfsc_interface *); -static int hfsccmd_add_class(struct hfsc_add_class *); -static int hfsccmd_delete_class(struct hfsc_delete_class *); -static int hfsccmd_modify_class(struct hfsc_modify_class *); -static int hfsccmd_add_filter(struct hfsc_add_filter *); -static int hfsccmd_delete_filter(struct hfsc_delete_filter *); -static int hfsccmd_class_stats(struct hfsc_class_stats *); -static void get_class_stats(struct class_stats *, struct hfsc_class *); -static struct hfsc_class *clh_to_clp(struct hfsc_if *, u_long); -static u_long clp_to_clh(struct hfsc_class *); +static void get_class_stats(struct hfsc_classstats *, struct hfsc_class *); +static struct hfsc_class *clh_to_clp(struct hfsc_if *, u_int32_t); /* * macros */ #define is_a_parent_class(cl) ((cl)->cl_children != NULL) -/* hif_list keeps all hfsc_if's allocated. */ -static struct hfsc_if *hif_list = NULL; +#define HT_INFINITY 0xffffffffffffffffLL /* infinite time value */ -static struct hfsc_if * -hfsc_attach(ifq, bandwidth) - struct ifaltq *ifq; - u_int bandwidth; +int +hfsc_pfattach(struct pf_altq *a) +{ + struct ifnet *ifp; + int s, error; + + if ((ifp = ifunit(a->ifname)) == NULL || a->altq_disc == NULL) + return (EINVAL); + s = splimp(); + error = altq_attach(&ifp->if_snd, ALTQT_HFSC, a->altq_disc, + hfsc_enqueue, hfsc_dequeue, hfsc_request, NULL, NULL); + splx(s); + return (error); +} + +int +hfsc_add_altq(struct pf_altq *a) { struct hfsc_if *hif; + struct ifnet *ifp; struct service_curve root_sc; + if ((ifp = ifunit(a->ifname)) == NULL) + return (EINVAL); + if (!ALTQ_IS_READY(&ifp->if_snd)) + return (ENODEV); + MALLOC(hif, struct hfsc_if *, sizeof(struct hfsc_if), - M_DEVBUF, M_WAITOK); + M_DEVBUF, M_WAITOK); if (hif == NULL) return (NULL); bzero(hif, sizeof(struct hfsc_if)); @@ -160,47 +166,37 @@ hfsc_attach(ifq, bandwidth) return NULL; } - hif->hif_ifq = ifq; + hif->hif_ifq = &ifp->if_snd; /* * create root class */ - root_sc.m1 = bandwidth; + root_sc.m1 = a->ifbandwidth; root_sc.d = 0; - root_sc.m2 = bandwidth; - if ((hif->hif_rootclass = - hfsc_class_create(hif, &root_sc, NULL, 0, 0)) == NULL) { + root_sc.m2 = a->ifbandwidth; + if ((hif->hif_rootclass = hfsc_class_create(hif, + &root_sc, &root_sc, NULL, NULL, 0, 0)) == NULL) { FREE(hif, M_DEVBUF); - return (NULL); + return (ENOMEM); } - /* add this state to the hfsc list */ - hif->hif_next = hif_list; - hif_list = hif; + /* keep the state in pf_altq */ + a->altq_disc = hif; - return (hif); + return (0); } -static int -hfsc_detach(hif) - struct hfsc_if *hif; +int +hfsc_remove_altq(struct pf_altq *a) { - (void)hfsc_clear_interface(hif); - (void)hfsc_class_destroy(hif->hif_rootclass); + struct hfsc_if *hif; - /* remove this interface from the hif list */ - if (hif_list == hif) - hif_list = hif->hif_next; - else { - struct hfsc_if *h; + if ((hif = a->altq_disc) == NULL) + return (EINVAL); + a->altq_disc = NULL; - for (h = hif_list; h != NULL; h = h->hif_next) - if (h->hif_next == hif) { - h->hif_next = hif->hif_next; - break; - } - ASSERT(h != NULL); - } + (void)hfsc_clear_interface(hif); + (void)hfsc_class_destroy(hif->hif_rootclass); ellist_destroy(hif->hif_eligible); @@ -209,6 +205,83 @@ hfsc_detach(hif) return (0); } +int +hfsc_add_queue(struct pf_altq *a) +{ + struct hfsc_if *hif; + struct hfsc_class *cl, *parent; + struct hfsc_opts *opts; + struct service_curve rtsc, lssc, ulsc; + + if ((hif = a->altq_disc) == NULL) + return (EINVAL); + + opts = &a->pq_u.hfsc_opts; + + parent = clh_to_clp(hif, a->parent_qid); + if (parent == NULL) + return (EINVAL); + rtsc.m1 = opts->rtsc_m1; + rtsc.d = opts->rtsc_d; + rtsc.m2 = opts->rtsc_m2; + lssc.m1 = opts->lssc_m1; + lssc.d = opts->lssc_d; + lssc.m2 = opts->lssc_m2; + ulsc.m1 = opts->ulsc_m1; + ulsc.d = opts->ulsc_d; + ulsc.m2 = opts->ulsc_m2; + + cl = hfsc_class_create(hif, &rtsc, &lssc, &ulsc, + parent, a->qlimit, opts->flags); + if (cl == NULL) + return (ENOMEM); + + /* return handle to user space. */ + a->qid = cl->cl_handle; + + return (0); +} + +int +hfsc_remove_queue(struct pf_altq *a) +{ + struct hfsc_if *hif; + struct hfsc_class *cl; + + if ((hif = a->altq_disc) == NULL) + return (EINVAL); + + if ((cl = clh_to_clp(hif, a->qid)) == NULL) + return (EINVAL); + + return (hfsc_class_destroy(cl)); +} + +int +hfsc_getqstats(struct pf_altq *a, void *ubuf, int *nbytes) +{ + struct hfsc_if *hif; + struct hfsc_class *cl; + struct hfsc_classstats stats; + int error = 0; + + if ((hif = altq_lookup(a->ifname, ALTQT_HFSC)) == NULL) + return (EBADF); + + if ((cl = clh_to_clp(hif, a->qid)) == NULL) + return (EINVAL); + + if (*nbytes < sizeof(stats)) + return (EINVAL); + + get_class_stats(&stats, cl); + + if ((error = copyout((caddr_t)&stats, ubuf, sizeof(stats))) != 0) + return (error); + *nbytes = sizeof(stats); + return (0); +} + /* * bring the interface back to the initial state by discarding * all the filters and classes except the root class. @@ -219,9 +292,6 @@ hfsc_clear_interface(hif) { struct hfsc_class *cl; - /* free the filters for this interface */ - acc_discard_filters(&hif->hif_classifier, NULL, 1); - /* clear out the classes */ while ((cl = hif->hif_rootclass->cl_children) != NULL) { /* @@ -270,14 +340,14 @@ hfsc_purge(hif) } struct hfsc_class * -hfsc_class_create(hif, sc, parent, qlimit, flags) +hfsc_class_create(hif, rsc, fsc, usc, parent, qlimit, flags) struct hfsc_if *hif; - struct service_curve *sc; + struct service_curve *rsc, *fsc, *usc; struct hfsc_class *parent; int qlimit, flags; { struct hfsc_class *cl, *p; - int s; + int i, s, chandle; #ifndef ALTQ_RED if (flags & HFCF_RED) { @@ -288,6 +358,14 @@ hfsc_class_create(hif, sc, parent, qlimit, flags) } #endif + /* find a free class slot. */ + for (i = 0; i < HFSC_MAX_CLASSES; i++) + if (hif->hif_class_tbl[i] == NULL) + break; + if (i == HFSC_MAX_CLASSES) + return (NULL); + chandle = i + 1; + MALLOC(cl, struct hfsc_class *, sizeof(struct hfsc_class), M_DEVBUF, M_WAITOK); if (cl == NULL) @@ -313,6 +391,15 @@ hfsc_class_create(hif, sc, parent, qlimit, flags) #ifdef ALTQ_RED if (flags & (HFCF_RED|HFCF_RIO)) { int red_flags, red_pkttime; + u_int m2; + + m2 = 0; + if (rsc != NULL && rsc->m2 > m2) + m2 = rsc->m2; + if (fsc != NULL && fsc->m2 > m2) + m2 = fsc->m2; + if (usc != NULL && usc->m2 > m2) + m2 = usc->m2; red_flags = 0; if (flags & HFCF_ECN) @@ -321,21 +408,21 @@ hfsc_class_create(hif, sc, parent, qlimit, flags) if (flags & HFCF_CLEARDSCP) red_flags |= RIOF_CLEARDSCP; #endif - if (sc->m2 < 8) + if (m2 < 8) red_pkttime = 1000 * 1000 * 1000; /* 1 sec */ else red_pkttime = (int64_t)hif->hif_ifq->altq_ifp->if_mtu - * 1000 * 1000 * 1000 / (sc->m2 / 8); + * 1000 * 1000 * 1000 / (m2 / 8); if (flags & HFCF_RED) { cl->cl_red = red_alloc(0, 0, 0, 0, - red_flags, red_pkttime); + red_flags, red_pkttime); if (cl->cl_red != NULL) qtype(cl->cl_q) = Q_RED; } #ifdef ALTQ_RIO else { cl->cl_red = (red_t *)rio_alloc(0, NULL, - red_flags, red_pkttime); + red_flags, red_pkttime); if (cl->cl_red != NULL) qtype(cl->cl_q) = Q_RIO; } @@ -343,32 +430,40 @@ hfsc_class_create(hif, sc, parent, qlimit, flags) } #endif /* ALTQ_RED */ - if (sc != NULL && (sc->m1 != 0 || sc->m2 != 0)) { + if (rsc != NULL && (rsc->m1 != 0 || rsc->m2 != 0)) { MALLOC(cl->cl_rsc, struct internal_sc *, - sizeof(struct internal_sc), M_DEVBUF, M_WAITOK); + sizeof(struct internal_sc), M_DEVBUF, M_WAITOK); if (cl->cl_rsc == NULL) goto err_ret; - bzero(cl->cl_rsc, sizeof(struct internal_sc)); - sc2isc(sc, cl->cl_rsc); + sc2isc(rsc, cl->cl_rsc); rtsc_init(&cl->cl_deadline, cl->cl_rsc, 0, 0); rtsc_init(&cl->cl_eligible, cl->cl_rsc, 0, 0); - + } + if (fsc != NULL && (fsc->m1 != 0 || fsc->m2 != 0)) { MALLOC(cl->cl_fsc, struct internal_sc *, - sizeof(struct internal_sc), M_DEVBUF, M_WAITOK); + sizeof(struct internal_sc), M_DEVBUF, M_WAITOK); if (cl->cl_fsc == NULL) goto err_ret; - bzero(cl->cl_fsc, sizeof(struct internal_sc)); - sc2isc(sc, cl->cl_fsc); + sc2isc(fsc, cl->cl_fsc); rtsc_init(&cl->cl_virtual, cl->cl_fsc, 0, 0); } + if (usc != NULL && (usc->m1 != 0 || usc->m2 != 0)) { + MALLOC(cl->cl_usc, struct internal_sc *, + sizeof(struct internal_sc), M_DEVBUF, M_WAITOK); + if (cl->cl_usc == NULL) + goto err_ret; + sc2isc(usc, cl->cl_usc); + rtsc_init(&cl->cl_ulimit, cl->cl_usc, 0, 0); + } cl->cl_id = hif->hif_classid++; - cl->cl_handle = (u_long)cl; /* XXX: just a pointer to this class */ + cl->cl_handle = chandle; cl->cl_hif = hif; cl->cl_parent = parent; s = splimp(); hif->hif_classes++; + hif->hif_class_tbl[chandle - 1] = cl; if (flags & HFCF_DEFAULTCLASS) hif->hif_defaultclass = cl; @@ -404,6 +499,8 @@ hfsc_class_create(hif, sc, parent, qlimit, flags) FREE(cl->cl_fsc, M_DEVBUF); if (cl->cl_rsc != NULL) FREE(cl->cl_rsc, M_DEVBUF); + if (cl->cl_usc != NULL) + FREE(cl->cl_usc, M_DEVBUF); if (cl->cl_q != NULL) FREE(cl->cl_q, M_DEVBUF); FREE(cl, M_DEVBUF); @@ -421,9 +518,6 @@ hfsc_class_destroy(cl) s = splimp(); - /* delete filters referencing to this class */ - acc_discard_filters(&cl->cl_hif->hif_classifier, cl, 0); - if (!qempty(cl->cl_q)) hfsc_purgeq(cl); @@ -442,6 +536,7 @@ hfsc_class_destroy(cl) } while ((p = p->cl_siblings) != NULL); ASSERT(p != NULL); } + cl->cl_hif->hif_class_tbl[cl->cl_handle - 1] = NULL; cl->cl_hif->hif_classes--; splx(s); @@ -457,6 +552,8 @@ hfsc_class_destroy(cl) red_destroy(cl->cl_red); #endif } + if (cl->cl_usc != NULL) + FREE(cl->cl_usc, M_DEVBUF); if (cl->cl_fsc != NULL) FREE(cl->cl_fsc, M_DEVBUF); if (cl->cl_rsc != NULL) @@ -467,68 +564,6 @@ hfsc_class_destroy(cl) return (0); } -static int -hfsc_class_modify(cl, rsc, fsc) - struct hfsc_class *cl; - struct service_curve *rsc, *fsc; -{ - struct internal_sc *rsc_tmp, *fsc_tmp; - int s; - - if (rsc != NULL && (rsc->m1 != 0 || rsc->m2 != 0) && - cl->cl_rsc == NULL) { - MALLOC(rsc_tmp, struct internal_sc *, - sizeof(struct internal_sc), M_DEVBUF, M_WAITOK); - if (rsc_tmp == NULL) - return (ENOMEM); - } - if (fsc != NULL && (fsc->m1 != 0 || fsc->m2 != 0) && - cl->cl_fsc == NULL) { - MALLOC(fsc_tmp, struct internal_sc *, - sizeof(struct internal_sc), M_DEVBUF, M_WAITOK); - if (fsc_tmp == NULL) - return (ENOMEM); - } - - s = splimp(); - if (!qempty(cl->cl_q)) - hfsc_purgeq(cl); - - if (rsc != NULL) { - if (rsc->m1 == 0 && rsc->m2 == 0) { - if (cl->cl_rsc != NULL) { - FREE(cl->cl_rsc, M_DEVBUF); - cl->cl_rsc = NULL; - } - } else { - if (cl->cl_rsc == NULL) - cl->cl_rsc = rsc_tmp; - bzero(cl->cl_rsc, sizeof(struct internal_sc)); - sc2isc(rsc, cl->cl_rsc); - rtsc_init(&cl->cl_deadline, cl->cl_rsc, 0, 0); - rtsc_init(&cl->cl_eligible, cl->cl_rsc, 0, 0); - } - } - - if (fsc != NULL) { - if (fsc->m1 == 0 && fsc->m2 == 0) { - if (cl->cl_fsc != NULL) { - FREE(cl->cl_fsc, M_DEVBUF); - cl->cl_fsc = NULL; - } - } else { - if (cl->cl_fsc == NULL) - cl->cl_fsc = fsc_tmp; - bzero(cl->cl_fsc, sizeof(struct internal_sc)); - sc2isc(fsc, cl->cl_fsc); - rtsc_init(&cl->cl_virtual, cl->cl_fsc, 0, 0); - } - } - splx(s); - - return (0); -} - /* * hfsc_nextclass returns the next class in the tree. * usage: @@ -566,12 +601,21 @@ hfsc_enqueue(ifq, m, pktattr) { struct hfsc_if *hif = (struct hfsc_if *)ifq->altq_disc; struct hfsc_class *cl; + struct m_tag *t; int len; /* grab class set by classifier */ - if (pktattr == NULL || (cl = pktattr->pattr_class) == NULL) + t = m_tag_find(m, PACKET_TAG_PF_QID, NULL); + if (t == NULL || + (cl = clh_to_clp(hif, ((struct altq_tag *)(t+1))->qid)) == NULL || + is_a_parent_class(cl)) { cl = hif->hif_defaultclass; - cl->cl_pktattr = pktattr; /* save proto hdr used by ECN */ + if (cl == NULL) { + m_freem(m); + return (ENOBUFS); + } + cl->cl_pktattr = NULL; + } len = m_pktlen(m); if (hfsc_addq(cl, m) != 0) { @@ -586,9 +630,6 @@ hfsc_enqueue(ifq, m, pktattr) if (qlen(cl->cl_q) == 1) set_active(cl, m_pktlen(m)); -#ifdef HFSC_PKTLOG - /* put the logging_hook here */ -#endif return (0); } @@ -611,39 +652,58 @@ hfsc_dequeue(ifq, op) struct mbuf *m; int len, next_len; int realtime = 0; + u_int64_t cur_time; if (hif->hif_packets == 0) /* no packet in the tree */ return (NULL); + cur_time = read_machclk(); + if (op == ALTDQ_REMOVE && hif->hif_pollcache != NULL) { - u_int64_t cur_time; cl = hif->hif_pollcache; hif->hif_pollcache = NULL; /* check if the class was scheduled by real-time criteria */ - if (cl->cl_rsc != NULL) { - cur_time = read_machclk(); + if (cl->cl_rsc != NULL) realtime = (cl->cl_e <= cur_time); - } } else { /* * if there are eligible classes, use real-time criteria. * find the class with the minimum deadline among * the eligible classes. */ - if ((cl = ellist_get_mindl(hif->hif_eligible)) != NULL) { + if ((cl = ellist_get_mindl(hif->hif_eligible, cur_time)) + != NULL) { realtime = 1; } else { +#ifdef ALTQ_DEBUG + int fits = 0; +#endif /* * use link-sharing criteria * get the class with the minimum vt in the hierarchy */ cl = hif->hif_rootclass; while (is_a_parent_class(cl)) { - cl = actlist_first(cl->cl_actc); - if (cl == NULL) + + cl = actlist_firstfit(cl, cur_time); + if (cl == NULL) { +#ifdef ALTQ_DEBUG + if (fits > 0) + printf("%d fit but none found\n",fits); +#endif return (NULL); + } + /* + * update parent's cl_cvtmin. + * don't update if the new vt is smaller. + */ + if (cl->cl_parent->cl_cvtmin < cl->cl_vt) + cl->cl_parent->cl_cvtmin = cl->cl_vt; +#ifdef ALTQ_DEBUG + fits++; +#endif } } @@ -655,12 +715,14 @@ hfsc_dequeue(ifq, op) } m = hfsc_getq(cl); + if (m == NULL) + panic("hfsc_dequeue:"); len = m_pktlen(m); cl->cl_hif->hif_packets--; IFQ_DEC_LEN(ifq); PKTCNTR_ADD(&cl->cl_stats.xmit_cnt, len); - update_v(cl, len); + update_vf(cl, len, cur_time); if (realtime) cl->cl_cumul += len; @@ -679,10 +741,6 @@ hfsc_dequeue(ifq, op) set_passive(cl); } -#ifdef HFSC_PKTLOG - /* put the logging_hook here */ -#endif - return (m); } @@ -748,9 +806,12 @@ hfsc_purgeq(cl) while ((m = _getq(cl->cl_q)) != NULL) { PKTCNTR_ADD(&cl->cl_stats.drop_cnt, m_pktlen(m)); m_freem(m); + cl->cl_hif->hif_packets--; + IFQ_DEC_LEN(cl->cl_hif->hif_ifq); } ASSERT(qlen(cl->cl_q) == 0); + update_vf(cl, 0, 0); /* remove cl from the actlist */ set_passive(cl); } @@ -762,7 +823,7 @@ set_active(cl, len) if (cl->cl_rsc != NULL) init_ed(cl, len); if (cl->cl_fsc != NULL) - init_v(cl, len); + init_vf(cl, len); cl->cl_stats.period++; } @@ -774,19 +835,10 @@ set_passive(cl) if (cl->cl_rsc != NULL) ellist_remove(cl); - if (cl->cl_fsc != NULL) { - while (cl->cl_parent != NULL) { - if (--cl->cl_nactive == 0) { - /* remove this class from the vt list */ - actlist_remove(cl); - } else - /* still has active children */ - break; - - /* go up to the parent class */ - cl = cl->cl_parent; - } - } + /* + * actlist is now handled in update_vf() so that update_vf(cl, 0, 0) + * needs to be called explicitly to remove a class from actlist + */ } static void @@ -839,78 +891,207 @@ update_d(cl, next_len) } static void -init_v(cl, len) +init_vf(cl, len) struct hfsc_class *cl; int len; { - struct hfsc_class *min_cl, *max_cl; + struct hfsc_class *max_cl, *p; + u_int64_t vt, f, cur_time; + int go_active; - while (cl->cl_parent != NULL) { + cur_time = 0; + go_active = 1; + for ( ; cl->cl_parent != NULL; cl = cl->cl_parent) { - if (cl->cl_nactive++ > 0) - /* already active */ - break; - - /* - * if parent became idle while this class was idle. - * reset vt and the runtime service curve. - */ - if (cl->cl_parent->cl_nactive == 0 || - cl->cl_parent->cl_vtperiod != cl->cl_parentperiod) { - cl->cl_vt = 0; - rtsc_init(&cl->cl_virtual, cl->cl_fsc, - 0, cl->cl_total); - } - min_cl = actlist_first(cl->cl_parent->cl_actc); - if (min_cl != NULL) { - u_int64_t vt; + if (go_active && cl->cl_nactive++ == 0) + go_active = 1; + else + go_active = 0; - /* - * set vt to the average of the min and max classes. - * if the parent's period didn't change, - * don't decrease vt of the class. - */ + if (go_active) { max_cl = actlist_last(cl->cl_parent->cl_actc); - vt = (min_cl->cl_vt + max_cl->cl_vt) / 2; - if (cl->cl_parent->cl_vtperiod != cl->cl_parentperiod - || vt > cl->cl_vt) - cl->cl_vt = vt; + if (max_cl != NULL) { + /* + * set vt to the average of the min and max + * classes. if the parent's period didn't + * change, don't decrease vt of the class. + */ + vt = max_cl->cl_vt; + if (cl->cl_parent->cl_cvtmin != 0) + vt = (cl->cl_parent->cl_cvtmin + vt)/2; + + if (cl->cl_parent->cl_vtperiod != + cl->cl_parentperiod || vt > cl->cl_vt) + cl->cl_vt = vt; + } else { + /* + * first child for a new parent backlog period. + * add parent's cvtmax to vtoff of children + * to make a new vt (vtoff + vt) larger than + * the vt in the last period for all children. + */ + vt = cl->cl_parent->cl_cvtmax; + for (p = cl->cl_parent->cl_children; p != NULL; + p = p->cl_siblings) + p->cl_vtoff += vt; + cl->cl_vt = 0; + cl->cl_parent->cl_cvtmax = 0; + cl->cl_parent->cl_cvtmin = 0; + } + cl->cl_initvt = cl->cl_vt; + + /* update the virtual curve */ + vt = cl->cl_vt + cl->cl_vtoff; + rtsc_min(&cl->cl_virtual, cl->cl_fsc, vt, cl->cl_total); + if (cl->cl_virtual.x == vt) { + cl->cl_virtual.x -= cl->cl_vtoff; + cl->cl_vtoff = 0; + } + cl->cl_vtadj = 0; + + cl->cl_vtperiod++; /* increment vt period */ + cl->cl_parentperiod = cl->cl_parent->cl_vtperiod; + if (cl->cl_parent->cl_nactive == 0) + cl->cl_parentperiod++; + cl->cl_f = 0; + + actlist_insert(cl); + + if (cl->cl_usc != NULL) { + /* class has upper limit curve */ + if (cur_time == 0) + cur_time = read_machclk(); + + /* update the ulimit curve */ + rtsc_min(&cl->cl_ulimit, cl->cl_usc, cur_time, + cl->cl_total); + /* compute myf */ + cl->cl_myf = rtsc_y2x(&cl->cl_ulimit, + cl->cl_total); + cl->cl_myfadj = 0; + } } - /* update the virtual curve */ - rtsc_min(&cl->cl_virtual, cl->cl_fsc, cl->cl_vt, cl->cl_total); - - cl->cl_vtperiod++; /* increment vt period */ - cl->cl_parentperiod = cl->cl_parent->cl_vtperiod; - if (cl->cl_parent->cl_nactive == 0) - cl->cl_parentperiod++; - - actlist_insert(cl); - - /* go up to the parent class */ - cl = cl->cl_parent; + if (cl->cl_myf > cl->cl_cfmin) + f = cl->cl_myf; + else + f = cl->cl_cfmin; + if (f != cl->cl_f) { + cl->cl_f = f; + update_cfmin(cl->cl_parent); + } } } static void -update_v(cl, len) +update_vf(cl, len, cur_time) struct hfsc_class *cl; int len; + u_int64_t cur_time; { - while (cl->cl_parent != NULL) { + u_int64_t f, myf_bound, delta; + int go_passive; + + go_passive = qempty(cl->cl_q); + + for (; cl->cl_parent != NULL; cl = cl->cl_parent) { cl->cl_total += len; - if (cl->cl_fsc != NULL) { - cl->cl_vt = rtsc_y2x(&cl->cl_virtual, cl->cl_total); + if (cl->cl_fsc == NULL || cl->cl_nactive == 0) + continue; + + if (go_passive && --cl->cl_nactive == 0) + go_passive = 1; + else + go_passive = 0; + + if (go_passive) { + /* no more active child, going passive */ + + /* update cvtmax of the parent class */ + if (cl->cl_vt > cl->cl_parent->cl_cvtmax) + cl->cl_parent->cl_cvtmax = cl->cl_vt; + + /* remove this class from the vt list */ + actlist_remove(cl); + + update_cfmin(cl->cl_parent); - /* update the vt list */ - actlist_update(cl); + continue; } - /* go up to the parent class */ - cl = cl->cl_parent; + /* + * update vt and f + */ + cl->cl_vt = rtsc_y2x(&cl->cl_virtual, cl->cl_total) + - cl->cl_vtoff + cl->cl_vtadj; + + /* + * if vt of the class is smaller than cvtmin, + * the class was skipped in the past due to non-fit. + * if so, we need to adjust vtadj. + */ + if (cl->cl_vt < cl->cl_parent->cl_cvtmin) { + cl->cl_vtadj += cl->cl_parent->cl_cvtmin - cl->cl_vt; + cl->cl_vt = cl->cl_parent->cl_cvtmin; + } + + /* update the vt list */ + actlist_update(cl); + + if (cl->cl_usc != NULL) { + cl->cl_myf = cl->cl_myfadj + + rtsc_y2x(&cl->cl_ulimit, cl->cl_total); + + /* + * if myf lags behind by more than one clock tick + * from the current time, adjust myfadj to prevent + * a rate-limited class from going greedy. + * in a steady state under rate-limiting, myf + * fluctuates within one clock tick. + */ + myf_bound = cur_time - machclk_per_tick; + if (cl->cl_myf < myf_bound) { + delta = cur_time - cl->cl_myf; + cl->cl_myfadj += delta; + cl->cl_myf += delta; + } + } + + /* cl_f is max(cl_myf, cl_cfmin) */ + if (cl->cl_myf > cl->cl_cfmin) + f = cl->cl_myf; + else + f = cl->cl_cfmin; + if (f != cl->cl_f) { + cl->cl_f = f; + update_cfmin(cl->cl_parent); + } + } +} + +static void +update_cfmin(cl) + struct hfsc_class *cl; +{ + struct hfsc_class *p; + u_int64_t cfmin; + + if (TAILQ_EMPTY(cl->cl_actc)) { + cl->cl_cfmin = 0; + return; + } + cfmin = HT_INFINITY; + TAILQ_FOREACH(p, cl->cl_actc, cl_actlist) { + if (p->cl_f == 0) { + cl->cl_cfmin = 0; + return; + } + if (p->cl_f < cfmin) + cfmin = p->cl_f; } + cl->cl_cfmin = cfmin; } /* @@ -1011,13 +1192,11 @@ ellist_update(cl) /* find the class with the minimum deadline among the eligible classes */ struct hfsc_class * -ellist_get_mindl(head) +ellist_get_mindl(head, cur_time) ellist_t *head; + u_int64_t cur_time; { struct hfsc_class *p, *cl = NULL; - u_int64_t cur_time; - - cur_time = read_machclk(); TAILQ_FOREACH(p, head, cl_ellist) { if (p->cl_e > cur_time) @@ -1090,7 +1269,7 @@ actlist_update(cl) * if the next entry has a larger virtual time, nothing to do. */ p = TAILQ_NEXT(cl, cl_actlist); - if (p == NULL || cl->cl_vt <= p->cl_vt) + if (p == NULL || cl->cl_vt < p->cl_vt) return; /* check the last entry */ @@ -1116,6 +1295,20 @@ actlist_update(cl) ASSERT(0); /* should not reach here */ } +static struct hfsc_class * +actlist_firstfit(cl, cur_time) + struct hfsc_class *cl; + u_int64_t cur_time; +{ + struct hfsc_class *p; + + TAILQ_FOREACH(p, cl->cl_actc, cl_actlist) { + if (p->cl_f <= cur_time) + return (p); + } + return (NULL); +} + /* * service curve support functions * @@ -1132,7 +1325,7 @@ actlist_update(cl) * speed. SM_SHIFT and ISM_SHIFT are selected to have at least 3 effective * digits in decimal using the following table. * - * bits/set 100Kbps 1Mbps 10Mbps 100Mbps 1Gbps + * bits/sec 100Kbps 1Mbps 10Mbps 100Mbps 1Gbps * ----------+------------------------------------------------------- * bytes/nsec 12.5e-6 125e-6 1250e-6 12500e-6 125000e-6 * sm(500MHz) 25.0e-6 250e-6 2500e-6 25000e-6 250000e-6 @@ -1145,8 +1338,8 @@ actlist_update(cl) #define SM_SHIFT 24 #define ISM_SHIFT 10 -#define SC_LARGEVAL (1LL << 32) -#define SC_INFINITY 0xffffffffffffffffLL +#define SM_MASK ((1LL << SM_SHIFT) - 1) +#define ISM_MASK ((1LL << ISM_SHIFT) - 1) static __inline u_int64_t seg_x2y(x, sm) @@ -1155,10 +1348,12 @@ seg_x2y(x, sm) { u_int64_t y; - if (x < SC_LARGEVAL) - y = x * sm >> SM_SHIFT; - else - y = (x >> SM_SHIFT) * sm; + /* + * compute + * y = x * sm >> SM_SHIFT + * but divide it for the upper and lower bits to avoid overflow + */ + y = (x >> SM_SHIFT) * sm + (((x & SM_MASK) * sm) >> SM_SHIFT); return (y); } @@ -1171,12 +1366,12 @@ seg_y2x(y, ism) if (y == 0) x = 0; - else if (ism == SC_INFINITY) - x = SC_INFINITY; - else if (y < SC_LARGEVAL) - x = y * ism >> ISM_SHIFT; - else - x = (y >> ISM_SHIFT) * ism; + else if (ism == HT_INFINITY) + x = HT_INFINITY; + else { + x = (y >> ISM_SHIFT) * ism + + (((y & ISM_MASK) * ism) >> ISM_SHIFT); + } return (x); } @@ -1197,7 +1392,7 @@ m2ism(m) u_int64_t ism; if (m == 0) - ism = SC_INFINITY; + ism = HT_INFINITY; else ism = ((u_int64_t)machclk_freq << ISM_SHIFT) * 8 / m; return (ism); @@ -1379,345 +1574,13 @@ rtsc_min(rtsc, isc, x, y) return; } -/* - * hfsc device interface - */ -int -hfscopen(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - if (machclk_freq == 0) - init_machclk(); - - if (machclk_freq == 0) { - printf("hfsc: no cpu clock available!\n"); - return (ENXIO); - } - - /* everything will be done when the queueing scheme is attached. */ - return 0; -} - -int -hfscclose(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - struct hfsc_if *hif; - int err, error = 0; - - while ((hif = hif_list) != NULL) { - /* destroy all */ - if (ALTQ_IS_ENABLED(hif->hif_ifq)) - altq_disable(hif->hif_ifq); - - err = altq_detach(hif->hif_ifq); - if (err == 0) - err = hfsc_detach(hif); - if (err != 0 && error == 0) - error = err; - } - - return error; -} - -int -hfscioctl(dev, cmd, addr, flag, p) - dev_t dev; - ioctlcmd_t cmd; - caddr_t addr; - int flag; - struct proc *p; -{ - struct hfsc_if *hif; - struct hfsc_interface *ifacep; - int error = 0; - - /* check super-user privilege */ - switch (cmd) { - case HFSC_GETSTATS: - break; - default: -#if (__FreeBSD_version > 400000) - if ((error = suser(p)) != 0) - return (error); -#else - if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) - return (error); -#endif - break; - } - - switch (cmd) { - - case HFSC_IF_ATTACH: - error = hfsccmd_if_attach((struct hfsc_attach *)addr); - break; - - case HFSC_IF_DETACH: - error = hfsccmd_if_detach((struct hfsc_interface *)addr); - break; - - case HFSC_ENABLE: - case HFSC_DISABLE: - case HFSC_CLEAR_HIERARCHY: - ifacep = (struct hfsc_interface *)addr; - if ((hif = altq_lookup(ifacep->hfsc_ifname, - ALTQT_HFSC)) == NULL) { - error = EBADF; - break; - } - - switch (cmd) { - - case HFSC_ENABLE: - if (hif->hif_defaultclass == NULL) { -#ifdef ALTQ_DEBUG - printf("hfsc: no default class\n"); -#endif - error = EINVAL; - break; - } - error = altq_enable(hif->hif_ifq); - break; - - case HFSC_DISABLE: - error = altq_disable(hif->hif_ifq); - break; - - case HFSC_CLEAR_HIERARCHY: - hfsc_clear_interface(hif); - break; - } - break; - - case HFSC_ADD_CLASS: - error = hfsccmd_add_class((struct hfsc_add_class *)addr); - break; - - case HFSC_DEL_CLASS: - error = hfsccmd_delete_class((struct hfsc_delete_class *)addr); - break; - - case HFSC_MOD_CLASS: - error = hfsccmd_modify_class((struct hfsc_modify_class *)addr); - break; - - case HFSC_ADD_FILTER: - error = hfsccmd_add_filter((struct hfsc_add_filter *)addr); - break; - - case HFSC_DEL_FILTER: - error = hfsccmd_delete_filter((struct hfsc_delete_filter *)addr); - break; - - case HFSC_GETSTATS: - error = hfsccmd_class_stats((struct hfsc_class_stats *)addr); - break; - - default: - error = EINVAL; - break; - } - return error; -} - -static int -hfsccmd_if_attach(ap) - struct hfsc_attach *ap; -{ - struct hfsc_if *hif; - struct ifnet *ifp; - int error; - - if ((ifp = ifunit(ap->iface.hfsc_ifname)) == NULL) - return (ENXIO); - - if ((hif = hfsc_attach(&ifp->if_snd, ap->bandwidth)) == NULL) - return (ENOMEM); - - /* - * set HFSC to this ifnet structure. - */ - if ((error = altq_attach(&ifp->if_snd, ALTQT_HFSC, hif, - hfsc_enqueue, hfsc_dequeue, hfsc_request, - &hif->hif_classifier, acc_classify)) != 0) - (void)hfsc_detach(hif); - - return (error); -} - -static int -hfsccmd_if_detach(ap) - struct hfsc_interface *ap; -{ - struct hfsc_if *hif; - int error; - - if ((hif = altq_lookup(ap->hfsc_ifname, ALTQT_HFSC)) == NULL) - return (EBADF); - - if (ALTQ_IS_ENABLED(hif->hif_ifq)) - altq_disable(hif->hif_ifq); - - if ((error = altq_detach(hif->hif_ifq))) - return (error); - - return hfsc_detach(hif); -} - -static int -hfsccmd_add_class(ap) - struct hfsc_add_class *ap; -{ - struct hfsc_if *hif; - struct hfsc_class *cl, *parent; - - if ((hif = altq_lookup(ap->iface.hfsc_ifname, ALTQT_HFSC)) == NULL) - return (EBADF); - - if ((parent = clh_to_clp(hif, ap->parent_handle)) == NULL) { - if (ap->parent_handle == HFSC_ROOTCLASS_HANDLE) - parent = hif->hif_rootclass; - else - return (EINVAL); - } - - if ((cl = hfsc_class_create(hif, &ap->service_curve, parent, - ap->qlimit, ap->flags)) == NULL) - return (ENOMEM); - - /* return a class handle to the user */ - ap->class_handle = clp_to_clh(cl); - return (0); -} - -static int -hfsccmd_delete_class(ap) - struct hfsc_delete_class *ap; -{ - struct hfsc_if *hif; - struct hfsc_class *cl; - - if ((hif = altq_lookup(ap->iface.hfsc_ifname, ALTQT_HFSC)) == NULL) - return (EBADF); - - if ((cl = clh_to_clp(hif, ap->class_handle)) == NULL) - return (EINVAL); - - return hfsc_class_destroy(cl); -} - -static int -hfsccmd_modify_class(ap) - struct hfsc_modify_class *ap; -{ - struct hfsc_if *hif; - struct hfsc_class *cl; - struct service_curve *rsc = NULL; - struct service_curve *fsc = NULL; - - if ((hif = altq_lookup(ap->iface.hfsc_ifname, ALTQT_HFSC)) == NULL) - return (EBADF); - - if ((cl = clh_to_clp(hif, ap->class_handle)) == NULL) - return (EINVAL); - - if (ap->sctype & HFSC_REALTIMESC) - rsc = &ap->service_curve; - if (ap->sctype & HFSC_LINKSHARINGSC) - fsc = &ap->service_curve; - - return hfsc_class_modify(cl, rsc, fsc); -} - -static int -hfsccmd_add_filter(ap) - struct hfsc_add_filter *ap; -{ - struct hfsc_if *hif; - struct hfsc_class *cl; - - if ((hif = altq_lookup(ap->iface.hfsc_ifname, ALTQT_HFSC)) == NULL) - return (EBADF); - - if ((cl = clh_to_clp(hif, ap->class_handle)) == NULL) - return (EINVAL); - - if (is_a_parent_class(cl)) { -#ifdef ALTQ_DEBUG - printf("hfsccmd_add_filter: not a leaf class!\n"); -#endif - return (EINVAL); - } - - return acc_add_filter(&hif->hif_classifier, &ap->filter, - cl, &ap->filter_handle); -} - -static int -hfsccmd_delete_filter(ap) - struct hfsc_delete_filter *ap; -{ - struct hfsc_if *hif; - - if ((hif = altq_lookup(ap->iface.hfsc_ifname, ALTQT_HFSC)) == NULL) - return (EBADF); - - return acc_delete_filter(&hif->hif_classifier, - ap->filter_handle); -} - -static int -hfsccmd_class_stats(ap) - struct hfsc_class_stats *ap; -{ - struct hfsc_if *hif; - struct hfsc_class *cl; - struct class_stats stats, *usp; - int n, nclasses, error; - - if ((hif = altq_lookup(ap->iface.hfsc_ifname, ALTQT_HFSC)) == NULL) - return (EBADF); - - ap->cur_time = read_machclk(); - ap->hif_classes = hif->hif_classes; - ap->hif_packets = hif->hif_packets; - - /* skip the first N classes in the tree */ - nclasses = ap->nskip; - for (cl = hif->hif_rootclass, n = 0; cl != NULL && n < nclasses; - cl = hfsc_nextclass(cl), n++) - ; - if (n != nclasses) - return (EINVAL); - - /* then, read the next N classes in the tree */ - nclasses = ap->nclasses; - usp = ap->stats; - for (n = 0; cl != NULL && n < nclasses; cl = hfsc_nextclass(cl), n++) { - - get_class_stats(&stats, cl); - - if ((error = copyout((caddr_t)&stats, (caddr_t)usp++, - sizeof(stats))) != 0) - return (error); - } - - ap->nclasses = n; - - return (0); -} - -static void get_class_stats(sp, cl) - struct class_stats *sp; +static void +get_class_stats(sp, cl) + struct hfsc_classstats *sp; struct hfsc_class *cl; { sp->class_id = cl->cl_id; - sp->class_handle = clp_to_clh(cl); + sp->class_handle = cl->cl_handle; if (cl->cl_rsc != NULL) { sp->rsc.m1 = sm2m(cl->cl_rsc->sm1); @@ -1737,6 +1600,15 @@ static void get_class_stats(sp, cl) sp->fsc.d = 0; sp->fsc.m2 = 0; } + if (cl->cl_usc != NULL) { + sp->usc.m1 = sm2m(cl->cl_usc->sm1); + sp->usc.d = dx2d(cl->cl_usc->dx); + sp->usc.m2 = sm2m(cl->cl_usc->sm2); + } else { + sp->usc.m1 = 0; + sp->usc.d = 0; + sp->usc.m2 = 0; + } sp->total = cl->cl_total; sp->cumul = cl->cl_cumul; @@ -1744,8 +1616,25 @@ static void get_class_stats(sp, cl) sp->d = cl->cl_d; sp->e = cl->cl_e; sp->vt = cl->cl_vt; + sp->f = cl->cl_f; + + sp->initvt = cl->cl_initvt; + sp->vtperiod = cl->cl_vtperiod; + sp->parentperiod = cl->cl_parentperiod; + sp->nactive = cl->cl_nactive; + sp->vtoff = cl->cl_vtoff; + sp->cvtmax = cl->cl_cvtmax; + sp->myf = cl->cl_myf; + sp->cfmin = cl->cl_cfmin; + sp->cvtmin = cl->cl_cvtmin; + sp->myfadj = cl->cl_myfadj; + sp->vtadj = cl->cl_vtadj; + + sp->cur_time = read_machclk(); + sp->machclk_freq = machclk_freq; sp->qlength = qlen(cl->cl_q); + sp->qlimit = qlimit(cl->cl_q); sp->xmit_cnt = cl->cl_stats.xmit_cnt; sp->drop_cnt = cl->cl_stats.drop_cnt; sp->period = cl->cl_stats.period; @@ -1765,39 +1654,14 @@ static void get_class_stats(sp, cl) static struct hfsc_class * clh_to_clp(hif, chandle) struct hfsc_if *hif; - u_long chandle; + u_int32_t chandle; { - struct hfsc_class *cl; + int idx; - cl = (struct hfsc_class *)chandle; - if (chandle != ALIGN(cl)) { -#ifdef ALTQ_DEBUG - printf("clh_to_cl: unaligned pointer %p\n", cl); -#endif + if (chandle == 0) return (NULL); - } - - if (cl == NULL || cl->cl_handle != chandle || cl->cl_hif != hif) + idx = chandle - 1; + if (idx >= HFSC_MAX_CLASSES) return (NULL); - - return (cl); -} - -/* convert a class pointer to the corresponding class handle */ -static u_long -clp_to_clh(cl) - struct hfsc_class *cl; -{ - if (cl->cl_parent == NULL) - return (HFSC_ROOTCLASS_HANDLE); /* XXX */ - return (cl->cl_handle); + return (hif->hif_class_tbl[idx]); } - -#ifdef KLD_MODULE - -static struct altqsw hfsc_sw = - {"hfsc", hfscopen, hfscclose, hfscioctl}; - -ALTQ_MODULE(altq_hfsc, ALTQT_HFSC, &hfsc_sw); - -#endif /* KLD_MODULE */ diff --git a/sys/altq/altq_hfsc.h b/sys/altq/altq_hfsc.h index f11bea3877d..93f17eca30b 100644 --- a/sys/altq/altq_hfsc.h +++ b/sys/altq/altq_hfsc.h @@ -1,5 +1,5 @@ -/* $OpenBSD: altq_hfsc.h,v 1.2 2002/11/26 01:03:34 henning Exp $ */ -/* $KAME: altq_hfsc.h,v 1.6 2000/12/14 08:12:46 thorpej Exp $ */ +/* $OpenBSD: altq_hfsc.h,v 1.3 2002/12/16 09:18:05 kjc Exp $ */ +/* $KAME: altq_hfsc.h,v 1.8 2002/11/29 04:36:23 kjc Exp $ */ /* * Copyright (c) 1997-1999 Carnegie Mellon University. All Rights Reserved. @@ -45,34 +45,16 @@ extern "C" { #endif -struct hfsc_interface { - char hfsc_ifname[IFNAMSIZ]; /* interface name (e.g., fxp0) */ -}; - -struct hfsc_attach { - struct hfsc_interface iface; - u_int bandwidth; /* link bandwidth in bits/sec */ -}; - struct service_curve { u_int m1; /* slope of the first segment in bits/sec */ u_int d; /* the x-projection of the first segment in msec */ u_int m2; /* slope of the second segment in bits/sec */ }; -struct hfsc_add_class { - struct hfsc_interface iface; - u_long parent_handle; - struct service_curve service_curve; - int qlimit; - int flags; - - u_long class_handle; /* return value */ -}; - /* special class handles */ -#define HFSC_ROOTCLASS_HANDLE 0 #define HFSC_NULLCLASS_HANDLE 0 +#define HFSC_ROOTCLASS_HANDLE 1 +#define HFSC_MAX_CLASSES 64 /* hfsc class flags */ #define HFCF_RED 0x0001 /* use RED */ @@ -81,41 +63,18 @@ struct hfsc_add_class { #define HFCF_CLEARDSCP 0x0010 /* clear diffserv codepoint */ #define HFCF_DEFAULTCLASS 0x1000 /* default class */ -struct hfsc_delete_class { - struct hfsc_interface iface; - u_long class_handle; -}; - /* service curve types */ #define HFSC_REALTIMESC 1 #define HFSC_LINKSHARINGSC 2 +#define HFSC_UPPERLIMITSC 4 #define HFSC_DEFAULTSC (HFSC_REALTIMESC|HFSC_LINKSHARINGSC) -struct hfsc_modify_class { - struct hfsc_interface iface; - u_long class_handle; - struct service_curve service_curve; - int sctype; -}; - -struct hfsc_add_filter { - struct hfsc_interface iface; - u_long class_handle; - struct flow_filter filter; - - u_long filter_handle; /* return value */ -}; - -struct hfsc_delete_filter { - struct hfsc_interface iface; - u_long filter_handle; -}; - -struct class_stats { +struct hfsc_classstats { u_int class_id; - u_long class_handle; + u_int32_t class_handle; struct service_curve rsc; struct service_curve fsc; + struct service_curve usc; /* upper limit service curve */ u_int64_t total; /* total work in bytes */ u_int64_t cumul; /* cumulative work in bytes @@ -123,39 +82,35 @@ struct class_stats { u_int64_t d; /* deadline */ u_int64_t e; /* eligible time */ u_int64_t vt; /* virtual time */ + u_int64_t f; /* fit time for upper-limit */ + + /* info helpful for debugging */ + u_int64_t initvt; /* init virtual time */ + u_int64_t vtoff; /* cl_vt_ipoff */ + u_int64_t cvtmax; /* cl_maxvt */ + u_int64_t myf; /* cl_myf */ + u_int64_t cfmin; /* cl_mincf */ + u_int64_t cvtmin; /* cl_mincvt */ + u_int64_t myfadj; /* cl_myfadj */ + u_int64_t vtadj; /* cl_vtadj */ + u_int64_t cur_time; + u_int32_t machclk_freq; u_int qlength; + u_int qlimit; struct pktcntr xmit_cnt; struct pktcntr drop_cnt; u_int period; + u_int vtperiod; /* vt period sequence no */ + u_int parentperiod; /* parent's vt period seqno */ + int nactive; /* number of active children */ + /* red and rio related info */ int qtype; struct redstats red[3]; }; -struct hfsc_class_stats { - struct hfsc_interface iface; - int nskip; /* skip # of classes */ - int nclasses; /* # of class stats (WR) */ - u_int64_t cur_time; /* current time */ - u_int hif_classes; /* # of classes in the tree */ - u_int hif_packets; /* # of packets in the tree */ - struct class_stats *stats; /* pointer to stats array */ -}; - -#define HFSC_IF_ATTACH _IOW('Q', 1, struct hfsc_attach) -#define HFSC_IF_DETACH _IOW('Q', 2, struct hfsc_interface) -#define HFSC_ENABLE _IOW('Q', 3, struct hfsc_interface) -#define HFSC_DISABLE _IOW('Q', 4, struct hfsc_interface) -#define HFSC_CLEAR_HIERARCHY _IOW('Q', 5, struct hfsc_interface) -#define HFSC_ADD_CLASS _IOWR('Q', 7, struct hfsc_add_class) -#define HFSC_DEL_CLASS _IOW('Q', 8, struct hfsc_delete_class) -#define HFSC_MOD_CLASS _IOW('Q', 9, struct hfsc_modify_class) -#define HFSC_ADD_FILTER _IOWR('Q', 10, struct hfsc_add_filter) -#define HFSC_DEL_FILTER _IOW('Q', 11, struct hfsc_delete_filter) -#define HFSC_GETSTATS _IOWR('Q', 12, struct hfsc_class_stats) - #ifdef _KERNEL /* * kernel internal service curve representation @@ -211,7 +166,7 @@ typedef TAILQ_ENTRY(hfsc_class) actentry_t; struct hfsc_class { u_int cl_id; /* class id (just for debug) */ - u_long cl_handle; /* class handle */ + u_int32_t cl_handle; /* class handle */ struct hfsc_if *cl_hif; /* back pointer to struct hfsc_if */ int cl_flags; /* misc flags */ @@ -229,12 +184,31 @@ struct hfsc_class { u_int64_t cl_d; /* deadline */ u_int64_t cl_e; /* eligible time */ u_int64_t cl_vt; /* virtual time */ + u_int64_t cl_f; /* time when this class will fit for + link-sharing, max(myf, cfmin) */ + u_int64_t cl_myf; /* my fit-time (as calculated from this + class's own upperlimit curve) */ + u_int64_t cl_myfadj; /* my fit-time adjustment + (to cancel history dependence) */ + u_int64_t cl_cfmin; /* earliest children's fit-time (used + with cl_myf to obtain cl_f) */ + u_int64_t cl_cvtmin; /* minimal virtual time among the + children fit for link-sharing + (monotonic within a period) */ + u_int64_t cl_vtadj; /* intra-period cumulative vt + adjustment */ + u_int64_t cl_vtoff; /* inter-period cumulative vt offset */ + u_int64_t cl_cvtmax; /* max child's vt in the last period */ + + u_int64_t cl_initvt; /* init virtual time (for debugging) */ struct internal_sc *cl_rsc; /* internal real-time service curve */ struct internal_sc *cl_fsc; /* internal fair service curve */ + struct internal_sc *cl_usc; /* internal upperlimit service curve */ struct runtime_sc cl_deadline; /* deadline curve */ struct runtime_sc cl_eligible; /* eligible curve */ struct runtime_sc cl_virtual; /* virtual curve */ + struct runtime_sc cl_ulimit; /* upperlimit curve */ u_int cl_vtperiod; /* vt period sequence no */ u_int cl_parentperiod; /* parent's vt period seqno */ @@ -259,6 +233,7 @@ struct hfsc_if { struct ifaltq *hif_ifq; /* backpointer to ifaltq */ struct hfsc_class *hif_rootclass; /* root class */ struct hfsc_class *hif_defaultclass; /* default class */ + struct hfsc_class *hif_class_tbl[HFSC_MAX_CLASSES]; struct hfsc_class *hif_pollcache; /* cache for poll operation */ u_int hif_classes; /* # of classes in the tree */ @@ -266,8 +241,6 @@ struct hfsc_if { u_int hif_classid; /* class id sequence number */ ellist_t *hif_eligible; /* eligible list */ - - struct acc_classifier hif_classifier; }; #endif /* _KERNEL */ diff --git a/sys/altq/altq_localq.c b/sys/altq/altq_localq.c deleted file mode 100644 index 6538e9360fe..00000000000 --- a/sys/altq/altq_localq.c +++ /dev/null @@ -1,65 +0,0 @@ -/* $OpenBSD: altq_localq.c,v 1.4 2002/11/26 01:03:34 henning Exp $ */ -/* $KAME: altq_localq.c,v 1.4 2001/08/16 11:28:25 kjc Exp $ */ -/* - * a skeleton file for implementing a new queueing discipline. - * this file is in the public domain. - */ - -#include <sys/param.h> -#include <sys/mbuf.h> -#include <sys/socket.h> -#include <sys/sockio.h> - -#include <net/if.h> -#include <netinet/in.h> - -#include <altq/altq.h> -#include <altq/altq_conf.h> - -/* - * localq device interface - */ -altqdev_decl(localq); - -int -localqopen(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - /* everything will be done when the queueing scheme is attached. */ - return 0; -} - -int -localqclose(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - int error = 0; - - return error; -} - -int -localqioctl(dev, cmd, addr, flag, p) - dev_t dev; - ioctlcmd_t cmd; - caddr_t addr; - int flag; - struct proc *p; -{ - int error = 0; - - return error; -} - -#ifdef KLD_MODULE - -static struct altqsw localq_sw = - {"localq", localqopen, localqclose, localqioctl}; - -ALTQ_MODULE(altq_localq, ALTQT_LOCALQ, &localq_sw); - -#endif /* KLD_MODULE */ diff --git a/sys/altq/altq_priq.c b/sys/altq/altq_priq.c index 96fe6219a44..9d665e5f90d 100644 --- a/sys/altq/altq_priq.c +++ b/sys/altq/altq_priq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: altq_priq.c,v 1.6 2002/11/29 07:52:31 kjc Exp $ */ +/* $OpenBSD: altq_priq.c,v 1.7 2002/12/16 09:18:05 kjc Exp $ */ /* $KAME: altq_priq.c,v 1.1 2000/10/18 09:15:23 kjc Exp $ */ /* * Copyright (C) 2000 @@ -33,7 +33,6 @@ #include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/socket.h> -#include <sys/sockio.h> #include <sys/systm.h> #include <sys/proc.h> #include <sys/errno.h> @@ -41,22 +40,19 @@ #include <sys/queue.h> #include <net/if.h> -#include <net/if_types.h> +#include <netinet/in.h> +#include <net/pfvar.h> #include <altq/altq.h> -#include <altq/altq_conf.h> #include <altq/altq_priq.h> /* * function prototypes */ -static struct priq_if *priq_attach(struct ifaltq *, u_int); -static int priq_detach(struct priq_if *); static int priq_clear_interface(struct priq_if *); static int priq_request(struct ifaltq *, int, void *); static void priq_purge(struct priq_if *); -static struct priq_class *priq_class_create(struct priq_if *, - int, int, int); +static struct priq_class *priq_class_create(struct priq_if *, int, int, int); static int priq_class_destroy(struct priq_class *); static int priq_enqueue(struct ifaltq *, struct mbuf *, struct altq_pktattr *); @@ -67,71 +63,132 @@ static struct mbuf *priq_getq(struct priq_class *); static struct mbuf *priq_pollq(struct priq_class *); static void priq_purgeq(struct priq_class *); -int priqopen(dev_t, int, int, struct proc *); -int priqclose(dev_t, int, int, struct proc *); -int priqioctl(dev_t, ioctlcmd_t, caddr_t, int, struct proc *); -static int priqcmd_if_attach(struct priq_interface *); -static int priqcmd_if_detach(struct priq_interface *); -static int priqcmd_add_class(struct priq_add_class *); -static int priqcmd_delete_class(struct priq_delete_class *); -static int priqcmd_modify_class(struct priq_modify_class *); -static int priqcmd_add_filter(struct priq_add_filter *); -static int priqcmd_delete_filter(struct priq_delete_filter *); -static int priqcmd_class_stats(struct priq_class_stats *); -static void get_class_stats(struct class_stats *, struct priq_class *); -static struct priq_class *clh_to_clp(struct priq_if *, u_long); -static u_long clp_to_clh(struct priq_class *); - -/* pif_list keeps all priq_if's allocated. */ -static struct priq_if *pif_list = NULL; - -static struct priq_if * -priq_attach(ifq, bandwidth) - struct ifaltq *ifq; - u_int bandwidth; +static void get_class_stats(struct priq_classstats *, struct priq_class *); +static struct priq_class *clh_to_clp(struct priq_if *, u_int32_t); + +int +priq_pfattach(struct pf_altq *a) +{ + struct ifnet *ifp; + int s, error; + + if ((ifp = ifunit(a->ifname)) == NULL || a->altq_disc == NULL) + return (EINVAL); + s = splimp(); + error = altq_attach(&ifp->if_snd, ALTQT_PRIQ, a->altq_disc, + priq_enqueue, priq_dequeue, priq_request, NULL, NULL); + splx(s); + return (error); +} + +int +priq_add_altq(struct pf_altq *a) { struct priq_if *pif; + struct ifnet *ifp; + + if ((ifp = ifunit(a->ifname)) == NULL) + return (EINVAL); + if (!ALTQ_IS_READY(&ifp->if_snd)) + return (ENODEV); MALLOC(pif, struct priq_if *, sizeof(struct priq_if), - M_DEVBUF, M_WAITOK); + M_DEVBUF, M_WAITOK); if (pif == NULL) - return (NULL); + return (ENOMEM); bzero(pif, sizeof(struct priq_if)); - pif->pif_bandwidth = bandwidth; + pif->pif_bandwidth = a->ifbandwidth; pif->pif_maxpri = -1; - pif->pif_ifq = ifq; + pif->pif_ifq = &ifp->if_snd; - /* add this state to the priq list */ - pif->pif_next = pif_list; - pif_list = pif; + /* keep the state in pf_altq */ + a->altq_disc = pif; - return (pif); + return (0); } -static int -priq_detach(pif) - struct priq_if *pif; +int +priq_remove_altq(struct pf_altq *a) { - (void)priq_clear_interface(pif); + struct priq_if *pif; - /* remove this interface from the pif list */ - if (pif_list == pif) - pif_list = pif->pif_next; - else { - struct priq_if *p; + if ((pif = a->altq_disc) == NULL) + return (EINVAL); + a->altq_disc = NULL; - for (p = pif_list; p != NULL; p = p->pif_next) - if (p->pif_next == pif) { - p->pif_next = pif->pif_next; - break; - } - ASSERT(p != NULL); - } + (void)priq_clear_interface(pif); FREE(pif, M_DEVBUF); return (0); } +int +priq_add_queue(struct pf_altq *a) +{ + struct priq_if *pif; + struct priq_class *cl; + + if ((pif = a->altq_disc) == NULL) + return (EINVAL); + + /* check parameters */ + if (a->priority >= PRIQ_MAXPRI) + return (EINVAL); + + cl = priq_class_create(pif, a->priority, a->qlimit, + a->pq_u.priq_opts.flags); + if (cl == NULL) + return (ENOMEM); + + /* return handle to user space. */ + a->qid = cl->cl_handle; + + return (0); +} + +int +priq_remove_queue(struct pf_altq *a) +{ + struct priq_if *pif; + struct priq_class *cl; + + if ((pif = a->altq_disc) == NULL) + return (EINVAL); + + if ((cl = clh_to_clp(pif, a->qid)) == NULL) + return (EINVAL); + + return (priq_class_destroy(cl)); +} + +int +priq_getqstats(struct pf_altq *a, void *ubuf, int *nbytes) +{ + struct priq_if *pif; + struct priq_class *cl; + struct priq_classstats stats; + int error = 0; + + if ((pif = altq_lookup(a->ifname, ALTQT_PRIQ)) == NULL) + return (EBADF); + + if ((cl = clh_to_clp(pif, a->qid)) == NULL) + return (EINVAL); + + if (*nbytes < sizeof(stats)) + return (EINVAL); + + get_class_stats(&stats, cl); +#if 0 + stats.handle = a->qid; +#endif + + if ((error = copyout((caddr_t)&stats, ubuf, sizeof(stats))) != 0) + return (error); + *nbytes = sizeof(stats); + return (0); +} + /* * bring the interface back to the initial state by discarding * all the filters and classes. @@ -143,9 +200,6 @@ priq_clear_interface(pif) struct priq_class *cl; int pri; - /* free the filters for this interface */ - acc_discard_filters(&pif->pif_classifier, NULL, 1); - /* clear out the classes */ for (pri = 0; pri <= pif->pif_maxpri; pri++) if ((cl = pif->pif_classes[pri]) != NULL) @@ -244,7 +298,7 @@ priq_class_create(pif, pri, qlimit, flags) if (pri > pif->pif_maxpri) pif->pif_maxpri = pri; cl->cl_pif = pif; - cl->cl_handle = (u_long)cl; /* XXX: just a pointer to this class */ + cl->cl_handle = pri + 1; #ifdef ALTQ_RED if (flags & (PRCF_RED|PRCF_RIO)) { @@ -307,9 +361,6 @@ priq_class_destroy(cl) s = splimp(); - /* delete filters referencing to this class */ - acc_discard_filters(&cl->cl_pif->pif_classifier, cl, 0); - if (!qempty(cl->cl_q)) priq_purgeq(cl); @@ -353,12 +404,20 @@ priq_enqueue(ifq, m, pktattr) { struct priq_if *pif = (struct priq_if *)ifq->altq_disc; struct priq_class *cl; + struct m_tag *t; int len; /* grab class set by classifier */ - if (pktattr == NULL || (cl = pktattr->pattr_class) == NULL) + t = m_tag_find(m, PACKET_TAG_PF_QID, NULL); + if (t == NULL || + (cl = clh_to_clp(pif, ((struct altq_tag *)(t+1))->qid)) == NULL) { cl = pif->pif_default; - cl->cl_pktattr = pktattr; /* save proto hdr used by ECN */ + if (cl == NULL) { + m_freem(m); + return (ENOBUFS); + } + cl->cl_pktattr = NULL; + } len = m_pktlen(m); if (priq_addq(cl, m) != 0) { @@ -480,325 +539,14 @@ priq_purgeq(cl) ASSERT(qlen(cl->cl_q) == 0); } -/* - * priq device interface - */ -int -priqopen(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - /* everything will be done when the queueing scheme is attached. */ - return 0; -} - -int -priqclose(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - struct priq_if *pif; - int err, error = 0; - - while ((pif = pif_list) != NULL) { - /* destroy all */ - if (ALTQ_IS_ENABLED(pif->pif_ifq)) - altq_disable(pif->pif_ifq); - - err = altq_detach(pif->pif_ifq); - if (err == 0) - err = priq_detach(pif); - if (err != 0 && error == 0) - error = err; - } - - return error; -} - -int -priqioctl(dev, cmd, addr, flag, p) - dev_t dev; - ioctlcmd_t cmd; - caddr_t addr; - int flag; - struct proc *p; -{ - struct priq_if *pif; - struct priq_interface *ifacep; - int error = 0; - - /* check super-user privilege */ - switch (cmd) { - case PRIQ_GETSTATS: - break; - default: -#if (__FreeBSD_version > 400000) - if ((error = suser(p)) != 0) - return (error); -#else - if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) - return (error); -#endif - break; - } - - switch (cmd) { - - case PRIQ_IF_ATTACH: - error = priqcmd_if_attach((struct priq_interface *)addr); - break; - - case PRIQ_IF_DETACH: - error = priqcmd_if_detach((struct priq_interface *)addr); - break; - - case PRIQ_ENABLE: - case PRIQ_DISABLE: - case PRIQ_CLEAR: - ifacep = (struct priq_interface *)addr; - if ((pif = altq_lookup(ifacep->ifname, - ALTQT_PRIQ)) == NULL) { - error = EBADF; - break; - } - - switch (cmd) { - case PRIQ_ENABLE: - if (pif->pif_default == NULL) { -#ifdef ALTQ_DEBUG - printf("priq: no default class\n"); -#endif - error = EINVAL; - break; - } - error = altq_enable(pif->pif_ifq); - break; - - case PRIQ_DISABLE: - error = altq_disable(pif->pif_ifq); - break; - - case PRIQ_CLEAR: - priq_clear_interface(pif); - break; - } - break; - - case PRIQ_ADD_CLASS: - error = priqcmd_add_class((struct priq_add_class *)addr); - break; - - case PRIQ_DEL_CLASS: - error = priqcmd_delete_class((struct priq_delete_class *)addr); - break; - - case PRIQ_MOD_CLASS: - error = priqcmd_modify_class((struct priq_modify_class *)addr); - break; - - case PRIQ_ADD_FILTER: - error = priqcmd_add_filter((struct priq_add_filter *)addr); - break; - - case PRIQ_DEL_FILTER: - error = priqcmd_delete_filter((struct priq_delete_filter *)addr); - break; - - case PRIQ_GETSTATS: - error = priqcmd_class_stats((struct priq_class_stats *)addr); - break; - - default: - error = EINVAL; - break; - } - return error; -} - -static int -priqcmd_if_attach(ap) - struct priq_interface *ap; -{ - struct priq_if *pif; - struct ifnet *ifp; - int error; - - if ((ifp = ifunit(ap->ifname)) == NULL) - return (ENXIO); - - if ((pif = priq_attach(&ifp->if_snd, ap->arg)) == NULL) - return (ENOMEM); - - /* - * set PRIQ to this ifnet structure. - */ - if ((error = altq_attach(&ifp->if_snd, ALTQT_PRIQ, pif, - priq_enqueue, priq_dequeue, priq_request, - &pif->pif_classifier, acc_classify)) != 0) - (void)priq_detach(pif); - - return (error); -} - -static int -priqcmd_if_detach(ap) - struct priq_interface *ap; -{ - struct priq_if *pif; - int error; - - if ((pif = altq_lookup(ap->ifname, ALTQT_PRIQ)) == NULL) - return (EBADF); - - if (ALTQ_IS_ENABLED(pif->pif_ifq)) - altq_disable(pif->pif_ifq); - - if ((error = altq_detach(pif->pif_ifq))) - return (error); - - return priq_detach(pif); -} - -static int -priqcmd_add_class(ap) - struct priq_add_class *ap; -{ - struct priq_if *pif; - struct priq_class *cl; - - if ((pif = altq_lookup(ap->iface.ifname, ALTQT_PRIQ)) == NULL) - return (EBADF); - - if (ap->pri < 0 || ap->pri >= PRIQ_MAXPRI) - return (EINVAL); - - if ((cl = priq_class_create(pif, ap->pri, - ap->qlimit, ap->flags)) == NULL) - return (ENOMEM); - - /* return a class handle to the user */ - ap->class_handle = clp_to_clh(cl); - return (0); -} - -static int -priqcmd_delete_class(ap) - struct priq_delete_class *ap; -{ - struct priq_if *pif; - struct priq_class *cl; - - if ((pif = altq_lookup(ap->iface.ifname, ALTQT_PRIQ)) == NULL) - return (EBADF); - - if ((cl = clh_to_clp(pif, ap->class_handle)) == NULL) - return (EINVAL); - - return priq_class_destroy(cl); -} - -static int -priqcmd_modify_class(ap) - struct priq_modify_class *ap; -{ - struct priq_if *pif; - struct priq_class *cl; - - if ((pif = altq_lookup(ap->iface.ifname, ALTQT_PRIQ)) == NULL) - return (EBADF); - - if (ap->pri < 0 || ap->pri >= PRIQ_MAXPRI) - return (EINVAL); - - if ((cl = clh_to_clp(pif, ap->class_handle)) == NULL) - return (EINVAL); - - /* - * if priority is changed, move the class to the new priority - */ - if (pif->pif_classes[ap->pri] != cl) { - if (pif->pif_classes[ap->pri] != NULL) - return (EEXIST); - pif->pif_classes[cl->cl_pri] = NULL; - pif->pif_classes[ap->pri] = cl; - cl->cl_pri = ap->pri; - } - - /* call priq_class_create to change class parameters */ - if ((cl = priq_class_create(pif, ap->pri, - ap->qlimit, ap->flags)) == NULL) - return (ENOMEM); - return 0; -} - -static int -priqcmd_add_filter(ap) - struct priq_add_filter *ap; -{ - struct priq_if *pif; - struct priq_class *cl; - - if ((pif = altq_lookup(ap->iface.ifname, ALTQT_PRIQ)) == NULL) - return (EBADF); - - if ((cl = clh_to_clp(pif, ap->class_handle)) == NULL) - return (EINVAL); - - return acc_add_filter(&pif->pif_classifier, &ap->filter, - cl, &ap->filter_handle); -} - -static int -priqcmd_delete_filter(ap) - struct priq_delete_filter *ap; -{ - struct priq_if *pif; - - if ((pif = altq_lookup(ap->iface.ifname, ALTQT_PRIQ)) == NULL) - return (EBADF); - - return acc_delete_filter(&pif->pif_classifier, - ap->filter_handle); -} - -static int -priqcmd_class_stats(ap) - struct priq_class_stats *ap; -{ - struct priq_if *pif; - struct priq_class *cl; - struct class_stats stats, *usp; - int pri, error; - - if ((pif = altq_lookup(ap->iface.ifname, ALTQT_PRIQ)) == NULL) - return (EBADF); - - ap->maxpri = pif->pif_maxpri; - - /* then, read the next N classes in the tree */ - usp = ap->stats; - for (pri = 0; pri <= pif->pif_maxpri; pri++) { - cl = pif->pif_classes[pri]; - if (cl != NULL) - get_class_stats(&stats, cl); - else - bzero(&stats, sizeof(stats)); - if ((error = copyout((caddr_t)&stats, (caddr_t)usp++, - sizeof(stats))) != 0) - return (error); - } - return (0); -} - -static void get_class_stats(sp, cl) - struct class_stats *sp; +static void +get_class_stats(sp, cl) + struct priq_classstats *sp; struct priq_class *cl; { - sp->class_handle = clp_to_clh(cl); - + sp->class_handle = cl->cl_handle; sp->qlength = qlen(cl->cl_q); + sp->qlimit = qlimit(cl->cl_q); sp->period = cl->cl_period; sp->xmitcnt = cl->cl_xmitcnt; sp->dropcnt = cl->cl_dropcnt; @@ -819,36 +567,14 @@ static void get_class_stats(sp, cl) static struct priq_class * clh_to_clp(pif, chandle) struct priq_if *pif; - u_long chandle; + u_int32_t chandle; { - struct priq_class *cl; + int idx; - cl = (struct priq_class *)chandle; - if (chandle != ALIGN(cl)) { -#ifdef ALTQ_DEBUG - printf("clh_to_cl: unaligned pointer %p\n", cl); -#endif + if (chandle == 0) return (NULL); - } - - if (cl == NULL || cl->cl_handle != chandle || cl->cl_pif != pif) + idx = chandle - 1; + if (idx >= PRIQ_MAXPRI) return (NULL); - return (cl); + return (pif->pif_classes[idx]); } - -/* convert a class pointer to the corresponding class handle */ -static u_long -clp_to_clh(cl) - struct priq_class *cl; -{ - return (cl->cl_handle); -} - -#ifdef KLD_MODULE - -static struct altqsw priq_sw = - {"priq", priqopen, priqclose, priqioctl}; - -ALTQ_MODULE(altq_priq, ALTQT_PRIQ, &priq_sw); - -#endif /* KLD_MODULE */ diff --git a/sys/altq/altq_priq.h b/sys/altq/altq_priq.h index 1bdc0533d28..b1eb873a2df 100644 --- a/sys/altq/altq_priq.h +++ b/sys/altq/altq_priq.h @@ -1,7 +1,7 @@ -/* $OpenBSD: altq_priq.h,v 1.2 2002/11/26 01:03:34 henning Exp $ */ +/* $OpenBSD: altq_priq.h,v 1.3 2002/12/16 09:18:05 kjc Exp $ */ /* $KAME: altq_priq.h,v 1.1 2000/10/18 09:15:23 kjc Exp $ */ /* - * Copyright (C) 2000 + * Copyright (C) 2000-2002 * Sony Computer Science Laboratories Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,20 +40,6 @@ extern "C" { #define PRIQ_MAXPRI 16 /* upper limit of the number of priorities */ -struct priq_interface { - char ifname[IFNAMSIZ]; /* interface name (e.g., fxp0) */ - u_long arg; /* request-specific argument */ -}; - -struct priq_add_class { - struct priq_interface iface; - int pri; /* priority (0 is the lowest) */ - int qlimit; /* queue size limit */ - int flags; /* misc flags (see below) */ - - u_long class_handle; /* return value */ -}; - /* priq class flags */ #define PRCF_RED 0x0001 /* use RED */ #define PRCF_ECN 0x0002 /* use RED/ECN */ @@ -64,36 +50,11 @@ struct priq_add_class { /* special class handles */ #define PRIQ_NULLCLASS_HANDLE 0 -struct priq_delete_class { - struct priq_interface iface; - u_long class_handle; -}; - -struct priq_modify_class { - struct priq_interface iface; - u_long class_handle; - int pri; - int qlimit; - int flags; -}; - -struct priq_add_filter { - struct priq_interface iface; - u_long class_handle; - struct flow_filter filter; - - u_long filter_handle; /* return value */ -}; - -struct priq_delete_filter { - struct priq_interface iface; - u_long filter_handle; -}; - -struct class_stats { - u_long class_handle; +struct priq_classstats { + u_int32_t class_handle; u_int qlength; + u_int qlimit; u_int period; struct pktcntr xmitcnt; /* transmitted packet counter */ struct pktcntr dropcnt; /* dropped packet counter */ @@ -103,29 +64,10 @@ struct class_stats { struct redstats red[3]; /* rio has 3 red stats */ }; -struct priq_class_stats { - struct priq_interface iface; - int maxpri; /* in/out */ - - struct class_stats *stats; /* pointer to stats array */ -}; - -#define PRIQ_IF_ATTACH _IOW('Q', 1, struct priq_interface) -#define PRIQ_IF_DETACH _IOW('Q', 2, struct priq_interface) -#define PRIQ_ENABLE _IOW('Q', 3, struct priq_interface) -#define PRIQ_DISABLE _IOW('Q', 4, struct priq_interface) -#define PRIQ_CLEAR _IOW('Q', 5, struct priq_interface) -#define PRIQ_ADD_CLASS _IOWR('Q', 7, struct priq_add_class) -#define PRIQ_DEL_CLASS _IOW('Q', 8, struct priq_delete_class) -#define PRIQ_MOD_CLASS _IOW('Q', 9, struct priq_modify_class) -#define PRIQ_ADD_FILTER _IOWR('Q', 10, struct priq_add_filter) -#define PRIQ_DEL_FILTER _IOW('Q', 11, struct priq_delete_filter) -#define PRIQ_GETSTATS _IOWR('Q', 12, struct priq_class_stats) - #ifdef _KERNEL struct priq_class { - u_long cl_handle; /* class handle */ + u_int32_t cl_handle; /* class handle */ class_queue_t *cl_q; /* class queue structure */ struct red *cl_red; /* RED state */ int cl_pri; /* priority */ @@ -149,7 +91,6 @@ struct priq_if { int pif_maxpri; /* max priority in use */ struct priq_class *pif_default; /* default class */ struct priq_class *pif_classes[PRIQ_MAXPRI]; /* classes */ - struct acc_classifier pif_classifier; /* classifier */ }; #endif /* _KERNEL */ diff --git a/sys/altq/altq_red.c b/sys/altq/altq_red.c index 08dd2a703c1..9adcf19a008 100644 --- a/sys/altq/altq_red.c +++ b/sys/altq/altq_red.c @@ -1,4 +1,4 @@ -/* $OpenBSD: altq_red.c,v 1.7 2002/11/26 01:03:34 henning Exp $ */ +/* $OpenBSD: altq_red.c,v 1.8 2002/12/16 09:18:05 kjc Exp $ */ /* $KAME: altq_red.c,v 1.10 2002/04/03 05:38:51 kjc Exp $ */ /* @@ -64,15 +64,8 @@ #include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/socket.h> -#include <sys/sockio.h> #include <sys/systm.h> -#include <sys/proc.h> #include <sys/errno.h> -#include <sys/kernel.h> -#ifdef ALTQ_FLOWVALVE -#include <sys/queue.h> -#include <sys/time.h> -#endif #include <net/if.h> #include <net/if_types.h> @@ -86,11 +79,7 @@ #include <net/pfvar.h> #include <altq/altq.h> -#include <altq/altq_conf.h> #include <altq/altq_red.h> -#ifdef ALTQ_FLOWVALVE -#include <altq/altq_flowvalve.h> -#endif /* * ALTQ/RED (Random Early Detection) implementation using 32-bit @@ -157,346 +146,14 @@ * to switch to the random-drop policy, define "RED_RANDOM_DROP". */ -#ifdef ALTQ_FLOWVALVE -/* - * flow-valve is an extention to protect red from unresponsive flows - * and to promote end-to-end congestion control. - * flow-valve observes the average drop rates of the flows that have - * experienced packet drops in the recent past. - * when the average drop rate exceeds the threshold, the flow is - * blocked by the flow-valve. the trapped flow should back off - * exponentially to escape from the flow-valve. - */ -#ifdef RED_RANDOM_DROP -#error "random-drop can't be used with flow-valve!" -#endif -#endif /* ALTQ_FLOWVALVE */ - -/* red_list keeps all red_queue_t's allocated. */ -static red_queue_t *red_list = NULL; - /* default red parameter values */ static int default_th_min = TH_MIN; static int default_th_max = TH_MAX; static int default_inv_pmax = INV_P_MAX; -/* internal function prototypes */ -static int red_enqueue(struct ifaltq *, struct mbuf *, - struct altq_pktattr *); -static struct mbuf *red_dequeue(struct ifaltq *, int); -static int red_request(struct ifaltq *, int, void *); -static void red_purgeq(red_queue_t *); -static int red_detach(red_queue_t *); -#ifdef ALTQ_FLOWVALVE -static __inline struct fve *flowlist_lookup(struct flowvalve *, - struct altq_pktattr *, struct timeval *); -static __inline struct fve *flowlist_reclaim(struct flowvalve *, - struct altq_pktattr *); -static __inline void flowlist_move_to_head(struct flowvalve *, - struct fve *); -static __inline int fv_p2f(struct flowvalve *, int); -static struct flowvalve *fv_alloc(struct red *); -static void fv_destroy(struct flowvalve *); -static int fv_checkflow(struct flowvalve *, struct altq_pktattr *, - struct fve **); -static void fv_dropbyred(struct flowvalve *fv, struct altq_pktattr *, - struct fve *); -#endif - -/* - * red device interface - */ -altqdev_decl(red); - -int -redopen(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - /* everything will be done when the queueing scheme is attached. */ - return 0; -} - -int -redclose(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - red_queue_t *rqp; - int err, error = 0; - - while ((rqp = red_list) != NULL) { - /* destroy all */ - err = red_detach(rqp); - if (err != 0 && error == 0) - error = err; - } - - return error; -} - -int -redioctl(dev, cmd, addr, flag, p) - dev_t dev; - ioctlcmd_t cmd; - caddr_t addr; - int flag; - struct proc *p; -{ - red_queue_t *rqp; - struct red_interface *ifacep; - struct ifnet *ifp; - int error = 0; - - /* check super-user privilege */ - switch (cmd) { - case RED_GETSTATS: - break; - default: -#if (__FreeBSD_version > 400000) - if ((error = suser(p)) != 0) -#else - if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) -#endif - return (error); - break; - } - - switch (cmd) { - - case RED_ENABLE: - ifacep = (struct red_interface *)addr; - if ((rqp = altq_lookup(ifacep->red_ifname, ALTQT_RED)) == NULL) { - error = EBADF; - break; - } - error = altq_enable(rqp->rq_ifq); - break; - - case RED_DISABLE: - ifacep = (struct red_interface *)addr; - if ((rqp = altq_lookup(ifacep->red_ifname, ALTQT_RED)) == NULL) { - error = EBADF; - break; - } - error = altq_disable(rqp->rq_ifq); - break; - - case RED_IF_ATTACH: - ifp = ifunit(((struct red_interface *)addr)->red_ifname); - if (ifp == NULL) { - error = ENXIO; - break; - } - - /* allocate and initialize red_queue_t */ - MALLOC(rqp, red_queue_t *, sizeof(red_queue_t), M_DEVBUF, M_WAITOK); - if (rqp == NULL) { - error = ENOMEM; - break; - } - bzero(rqp, sizeof(red_queue_t)); - - MALLOC(rqp->rq_q, class_queue_t *, sizeof(class_queue_t), - M_DEVBUF, M_WAITOK); - if (rqp->rq_q == NULL) { - FREE(rqp, M_DEVBUF); - error = ENOMEM; - break; - } - bzero(rqp->rq_q, sizeof(class_queue_t)); - - rqp->rq_red = red_alloc(0, 0, 0, 0, 0, 0); - if (rqp->rq_red == NULL) { - FREE(rqp->rq_q, M_DEVBUF); - FREE(rqp, M_DEVBUF); - error = ENOMEM; - break; - } - - rqp->rq_ifq = &ifp->if_snd; - qtail(rqp->rq_q) = NULL; - qlen(rqp->rq_q) = 0; - qlimit(rqp->rq_q) = RED_LIMIT; - qtype(rqp->rq_q) = Q_RED; - - /* - * set RED to this ifnet structure. - */ - error = altq_attach(rqp->rq_ifq, ALTQT_RED, rqp, - red_enqueue, red_dequeue, red_request, - NULL, NULL); - if (error) { - red_destroy(rqp->rq_red); - FREE(rqp->rq_q, M_DEVBUF); - FREE(rqp, M_DEVBUF); - break; - } - - /* add this state to the red list */ - rqp->rq_next = red_list; - red_list = rqp; - break; - - case RED_IF_DETACH: - ifacep = (struct red_interface *)addr; - if ((rqp = altq_lookup(ifacep->red_ifname, ALTQT_RED)) == NULL) { - error = EBADF; - break; - } - error = red_detach(rqp); - break; - - case RED_GETSTATS: - do { - struct red_stats *q_stats; - red_t *rp; - - q_stats = (struct red_stats *)addr; - if ((rqp = altq_lookup(q_stats->iface.red_ifname, - ALTQT_RED)) == NULL) { - error = EBADF; - break; - } - - q_stats->q_len = qlen(rqp->rq_q); - q_stats->q_limit = qlimit(rqp->rq_q); - - rp = rqp->rq_red; - q_stats->q_avg = rp->red_avg >> rp->red_wshift; - q_stats->xmit_cnt = rp->red_stats.xmit_cnt; - q_stats->drop_cnt = rp->red_stats.drop_cnt; - q_stats->drop_forced = rp->red_stats.drop_forced; - q_stats->drop_unforced = rp->red_stats.drop_unforced; - q_stats->marked_packets = rp->red_stats.marked_packets; - - q_stats->weight = rp->red_weight; - q_stats->inv_pmax = rp->red_inv_pmax; - q_stats->th_min = rp->red_thmin; - q_stats->th_max = rp->red_thmax; - -#ifdef ALTQ_FLOWVALVE - if (rp->red_flowvalve != NULL) { - struct flowvalve *fv = rp->red_flowvalve; - q_stats->fv_flows = fv->fv_flows; - q_stats->fv_pass = fv->fv_stats.pass; - q_stats->fv_predrop = fv->fv_stats.predrop; - q_stats->fv_alloc = fv->fv_stats.alloc; - q_stats->fv_escape = fv->fv_stats.escape; - } else { -#endif /* ALTQ_FLOWVALVE */ - q_stats->fv_flows = 0; - q_stats->fv_pass = 0; - q_stats->fv_predrop = 0; - q_stats->fv_alloc = 0; - q_stats->fv_escape = 0; -#ifdef ALTQ_FLOWVALVE - } -#endif /* ALTQ_FLOWVALVE */ - } while (0); - break; - - case RED_CONFIG: - do { - struct red_conf *fc; - red_t *new; - int s, limit; - - fc = (struct red_conf *)addr; - if ((rqp = altq_lookup(fc->iface.red_ifname, - ALTQT_RED)) == NULL) { - error = EBADF; - break; - } - new = red_alloc(fc->red_weight, - fc->red_inv_pmax, - fc->red_thmin, - fc->red_thmax, - fc->red_flags, - fc->red_pkttime); - if (new == NULL) { - error = ENOMEM; - break; - } - - s = splimp(); - red_purgeq(rqp); - limit = fc->red_limit; - if (limit < fc->red_thmax) - limit = fc->red_thmax; - qlimit(rqp->rq_q) = limit; - fc->red_limit = limit; /* write back the new value */ - - red_destroy(rqp->rq_red); - rqp->rq_red = new; - - splx(s); - - /* write back new values */ - fc->red_limit = limit; - fc->red_inv_pmax = rqp->rq_red->red_inv_pmax; - fc->red_thmin = rqp->rq_red->red_thmin; - fc->red_thmax = rqp->rq_red->red_thmax; - - } while (0); - break; - - case RED_SETDEFAULTS: - do { - struct redparams *rp; - - rp = (struct redparams *)addr; - - default_th_min = rp->th_min; - default_th_max = rp->th_max; - default_inv_pmax = rp->inv_pmax; - } while (0); - break; - - default: - error = EINVAL; - break; - } - return error; -} - -static int -red_detach(rqp) - red_queue_t *rqp; -{ - red_queue_t *tmp; - int error = 0; - - if (ALTQ_IS_ENABLED(rqp->rq_ifq)) - altq_disable(rqp->rq_ifq); - - if ((error = altq_detach(rqp->rq_ifq))) - return (error); - - if (red_list == rqp) - red_list = rqp->rq_next; - else { - for (tmp = red_list; tmp != NULL; tmp = tmp->rq_next) - if (tmp->rq_next == rqp) { - tmp->rq_next = rqp->rq_next; - break; - } - if (tmp == NULL) - printf("red_detach: no state found in red_list!\n"); - } - - red_destroy(rqp->rq_red); - FREE(rqp->rq_q, M_DEVBUF); - FREE(rqp, M_DEVBUF); - return (error); -} - /* * red support routines */ - red_t * red_alloc(weight, inv_pmax, th_min, th_max, flags, pkttime) int weight, inv_pmax, th_min, th_max; @@ -581,11 +238,6 @@ red_alloc(weight, inv_pmax, th_min, th_max, flags, pkttime) rp->red_wtab = wtab_alloc(rp->red_weight); microtime(&rp->red_last); -#ifdef ALTQ_FLOWVALVE - if (flags & REDF_FLOWVALVE) - rp->red_flowvalve = fv_alloc(rp); - /* if fv_alloc failes, flowvalve is just disabled */ -#endif return (rp); } @@ -593,10 +245,6 @@ void red_destroy(rp) red_t *rp; { -#ifdef ALTQ_FLOWVALVE - if (rp->red_flowvalve != NULL) - fv_destroy(rp->red_flowvalve); -#endif wtab_destroy(rp->red_wtab); FREE(rp, M_DEVBUF); } @@ -614,26 +262,6 @@ red_getstats(rp, sp) sp->marked_packets = rp->red_stats.marked_packets; } -/* - * enqueue routine: - * - * returns: 0 when successfully queued. - * ENOBUFS when drop occurs. - */ -static int -red_enqueue(ifq, m, pktattr) - struct ifaltq *ifq; - struct mbuf *m; - struct altq_pktattr *pktattr; -{ - red_queue_t *rqp = (red_queue_t *)ifq->altq_disc; - - if (red_addq(rqp->rq_red, rqp->rq_q, m, pktattr) < 0) - return ENOBUFS; - ifq->ifq_len++; - return 0; -} - int red_addq(rp, q, m, pktattr) red_t *rp; @@ -643,15 +271,6 @@ red_addq(rp, q, m, pktattr) { int avg, droptype; int n; -#ifdef ALTQ_FLOWVALVE - struct fve *fve = NULL; - - if (rp->red_flowvalve != NULL && rp->red_flowvalve->fv_flows > 0) - if (fv_checkflow(rp->red_flowvalve, pktattr, &fve)) { - m_freem(m); - return (-1); - } -#endif avg = rp->red_avg; @@ -757,10 +376,6 @@ red_addq(rp, q, m, pktattr) PKTCNTR_ADD(&rp->red_stats.drop_cnt, m_pktlen(m)); #endif rp->red_count = 0; -#ifdef ALTQ_FLOWVALVE - if (rp->red_flowvalve != NULL) - fv_dropbyred(rp->red_flowvalve, pktattr, fve); -#endif m_freem(m); return (-1); } @@ -823,24 +438,16 @@ mark_ecn(m, pktattr, flags) void *hdr; int af; - if (PFALTQ_IS_ACTIVE()) { - t = m_tag_find(m, PACKET_TAG_PF_QID, NULL); - if (t == NULL) - return (0); - at = (struct altq_tag *)(t + 1); - - if (at == NULL) - return (0); + t = m_tag_find(m, PACKET_TAG_PF_QID, NULL); + if (t == NULL) + return (0); + at = (struct altq_tag *)(t + 1); - af = at->af; - hdr = at->hdr; - } else { - if (pktattr == NULL) - return (0); + if (at == NULL) + return (0); - af = pktattr->pattr_af; - hdr = pktattr->pattr_hdr; - } + af = at->af; + hdr = at->hdr; if (af != AF_INET && af != AF_INET6) return (0); @@ -918,32 +525,6 @@ mark_ecn(m, pktattr, flags) return (0); } -/* - * dequeue routine: - * must be called in splimp. - * - * returns: mbuf dequeued. - * NULL when no packet is available in the queue. - */ - -static struct mbuf * -red_dequeue(ifq, op) - struct ifaltq *ifq; - int op; -{ - red_queue_t *rqp = (red_queue_t *)ifq->altq_disc; - struct mbuf *m; - - if (op == ALTDQ_POLL) - return qhead(rqp->rq_q); - - /* op == ALTDQ_REMOVE */ - m = red_getq(rqp->rq_red, rqp->rq_q); - if (m != NULL) - ifq->ifq_len--; - return (m); -} - struct mbuf * red_getq(rp, q) red_t *rp; @@ -963,32 +544,6 @@ red_getq(rp, q) return (m); } -static int -red_request(ifq, req, arg) - struct ifaltq *ifq; - int req; - void *arg; -{ - red_queue_t *rqp = (red_queue_t *)ifq->altq_disc; - - switch (req) { - case ALTRQ_PURGE: - red_purgeq(rqp); - break; - } - return (0); -} - -static void -red_purgeq(rqp) - red_queue_t *rqp; -{ - _flushq(rqp->rq_q); - if (ALTQ_IS_ENABLED(rqp->rq_ifq)) - rqp->rq_ifq->ifq_len = 0; -} - - /* * helper routine to calibrate avg during idle. * pow_w(wtab, n) returns (1 - Wq)^n in fixed-point @@ -1079,399 +634,3 @@ pow_w(w, n) } return (val); } - -#ifdef ALTQ_FLOWVALVE - -#define FV_PSHIFT 7 /* weight of average drop rate -- 1/128 */ -#define FV_PSCALE(x) ((x) << FV_PSHIFT) -#define FV_PUNSCALE(x) ((x) >> FV_PSHIFT) -#define FV_FSHIFT 5 /* weight of average fraction -- 1/32 */ -#define FV_FSCALE(x) ((x) << FV_FSHIFT) -#define FV_FUNSCALE(x) ((x) >> FV_FSHIFT) - -#define FV_TIMER (3 * hz) /* timer value for garbage collector */ -#define FV_FLOWLISTSIZE 64 /* how many flows in flowlist */ - -#define FV_N 10 /* update fve_f every FV_N packets */ - -#define FV_BACKOFFTHRESH 1 /* backoff threshold interval in second */ -#define FV_TTHRESH 3 /* time threshold to delete fve */ -#define FV_ALPHA 5 /* extra packet count */ - -#define FV_STATS - -#if (__FreeBSD_version > 300000) -#define FV_TIMESTAMP(tp) getmicrotime(tp) -#else -#define FV_TIMESTAMP(tp) { (*(tp)) = time; } -#endif - -/* - * Brtt table: 127 entry table to convert drop rate (p) to - * the corresponding bandwidth fraction (f) - * the following equation is implemented to use scaled values, - * fve_p and fve_f, in the fixed point format. - * - * Brtt(p) = 1 /(sqrt(4*p/3) + min(1,3*sqrt(p*6/8)) * p * (1+32 * p*p)) - * f = Brtt(p) / (max_th + alpha) - */ -#define BRTT_SIZE 128 -#define BRTT_SHIFT 12 -#define BRTT_MASK 0x0007f000 -#define BRTT_PMAX (1 << (FV_PSHIFT + FP_SHIFT)) - -const int brtt_tab[BRTT_SIZE] = { - 0, 1262010, 877019, 703694, 598706, 525854, 471107, 427728, - 392026, 361788, 335598, 312506, 291850, 273158, 256081, 240361, - 225800, 212247, 199585, 187788, 178388, 169544, 161207, 153333, - 145888, 138841, 132165, 125836, 119834, 114141, 108739, 103612, - 98747, 94129, 89746, 85585, 81637, 77889, 74333, 70957, - 67752, 64711, 61824, 59084, 56482, 54013, 51667, 49440, - 47325, 45315, 43406, 41591, 39866, 38227, 36667, 35184, - 33773, 32430, 31151, 29933, 28774, 27668, 26615, 25611, - 24653, 23740, 22868, 22035, 21240, 20481, 19755, 19062, - 18399, 17764, 17157, 16576, 16020, 15487, 14976, 14487, - 14017, 13567, 13136, 12721, 12323, 11941, 11574, 11222, - 10883, 10557, 10243, 9942, 9652, 9372, 9103, 8844, - 8594, 8354, 8122, 7898, 7682, 7474, 7273, 7079, - 6892, 6711, 6536, 6367, 6204, 6046, 5893, 5746, - 5603, 5464, 5330, 5201, 5075, 4954, 4836, 4722, - 4611, 4504, 4400, 4299, 4201, 4106, 4014, 3924 -}; - -static __inline struct fve * -flowlist_lookup(fv, pktattr, now) - struct flowvalve *fv; - struct altq_pktattr *pktattr; - struct timeval *now; -{ - struct fve *fve; - int flows; - struct ip *ip; -#ifdef INET6 - struct ip6_hdr *ip6; -#endif - struct timeval tthresh; - - if (pktattr == NULL) - return (NULL); - - tthresh.tv_sec = now->tv_sec - FV_TTHRESH; - flows = 0; - /* - * search the flow list - */ - switch (pktattr->pattr_af) { - case AF_INET: - ip = (struct ip *)pktattr->pattr_hdr; - TAILQ_FOREACH(fve, &fv->fv_flowlist, fve_lru){ - if (fve->fve_lastdrop.tv_sec == 0) - break; - if (fve->fve_lastdrop.tv_sec < tthresh.tv_sec) { - fve->fve_lastdrop.tv_sec = 0; - break; - } - if (fve->fve_flow.flow_af == AF_INET && - fve->fve_flow.flow_ip.ip_src.s_addr == - ip->ip_src.s_addr && - fve->fve_flow.flow_ip.ip_dst.s_addr == - ip->ip_dst.s_addr) - return (fve); - flows++; - } - break; -#ifdef INET6 - case AF_INET6: - ip6 = (struct ip6_hdr *)pktattr->pattr_hdr; - TAILQ_FOREACH(fve, &fv->fv_flowlist, fve_lru){ - if (fve->fve_lastdrop.tv_sec == 0) - break; - if (fve->fve_lastdrop.tv_sec < tthresh.tv_sec) { - fve->fve_lastdrop.tv_sec = 0; - break; - } - if (fve->fve_flow.flow_af == AF_INET6 && - IN6_ARE_ADDR_EQUAL(&fve->fve_flow.flow_ip6.ip6_src, - &ip6->ip6_src) && - IN6_ARE_ADDR_EQUAL(&fve->fve_flow.flow_ip6.ip6_dst, - &ip6->ip6_dst)) - return (fve); - flows++; - } - break; -#endif /* INET6 */ - - default: - /* unknown protocol. no drop. */ - return (NULL); - } - fv->fv_flows = flows; /* save the number of active fve's */ - return (NULL); -} - -static __inline struct fve * -flowlist_reclaim(fv, pktattr) - struct flowvalve *fv; - struct altq_pktattr *pktattr; -{ - struct fve *fve; - struct ip *ip; -#ifdef INET6 - struct ip6_hdr *ip6; -#endif - - /* - * get an entry from the tail of the LRU list. - */ - fve = TAILQ_LAST(&fv->fv_flowlist, fv_flowhead); - - switch (pktattr->pattr_af) { - case AF_INET: - ip = (struct ip *)pktattr->pattr_hdr; - fve->fve_flow.flow_af = AF_INET; - fve->fve_flow.flow_ip.ip_src = ip->ip_src; - fve->fve_flow.flow_ip.ip_dst = ip->ip_dst; - break; -#ifdef INET6 - case AF_INET6: - ip6 = (struct ip6_hdr *)pktattr->pattr_hdr; - fve->fve_flow.flow_af = AF_INET6; - fve->fve_flow.flow_ip6.ip6_src = ip6->ip6_src; - fve->fve_flow.flow_ip6.ip6_dst = ip6->ip6_dst; - break; -#endif - } - - fve->fve_state = Green; - fve->fve_p = 0.0; - fve->fve_f = 0.0; - fve->fve_ifseq = fv->fv_ifseq - 1; - fve->fve_count = 0; - - fv->fv_flows++; -#ifdef FV_STATS - fv->fv_stats.alloc++; -#endif - return (fve); -} - -static __inline void -flowlist_move_to_head(fv, fve) - struct flowvalve *fv; - struct fve *fve; -{ - if (TAILQ_FIRST(&fv->fv_flowlist) != fve) { - TAILQ_REMOVE(&fv->fv_flowlist, fve, fve_lru); - TAILQ_INSERT_HEAD(&fv->fv_flowlist, fve, fve_lru); - } -} - -/* - * allocate flowvalve structure - */ -static struct flowvalve * -fv_alloc(rp) - struct red *rp; -{ - struct flowvalve *fv; - struct fve *fve; - int i, num; - - num = FV_FLOWLISTSIZE; - MALLOC(fv, struct flowvalve *, sizeof(struct flowvalve), - M_DEVBUF, M_WAITOK); - if (fv == NULL) - return (NULL); - bzero(fv, sizeof(struct flowvalve)); - - MALLOC(fv->fv_fves, struct fve *, sizeof(struct fve) * num, - M_DEVBUF, M_WAITOK); - if (fv->fv_fves == NULL) { - FREE(fv, M_DEVBUF); - return (NULL); - } - bzero(fv->fv_fves, sizeof(struct fve) * num); - - fv->fv_flows = 0; - TAILQ_INIT(&fv->fv_flowlist); - for (i = 0; i < num; i++) { - fve = &fv->fv_fves[i]; - fve->fve_lastdrop.tv_sec = 0; - TAILQ_INSERT_TAIL(&fv->fv_flowlist, fve, fve_lru); - } - - /* initialize drop rate threshold in scaled fixed-point */ - fv->fv_pthresh = (FV_PSCALE(1) << FP_SHIFT) / rp->red_inv_pmax; - - /* initialize drop rate to fraction table */ - MALLOC(fv->fv_p2ftab, int *, sizeof(int) * BRTT_SIZE, - M_DEVBUF, M_WAITOK); - if (fv->fv_p2ftab == NULL) { - FREE(fv->fv_fves, M_DEVBUF); - FREE(fv, M_DEVBUF); - return (NULL); - } - /* - * create the p2f table. - * (shift is used to keep the precision) - */ - for (i = 1; i < BRTT_SIZE; i++) { - int f; - - f = brtt_tab[i] << 8; - fv->fv_p2ftab[i] = (f / (rp->red_thmax + FV_ALPHA)) >> 8; - } - - return (fv); -} - -static void fv_destroy(fv) - struct flowvalve *fv; -{ - FREE(fv->fv_p2ftab, M_DEVBUF); - FREE(fv->fv_fves, M_DEVBUF); - FREE(fv, M_DEVBUF); -} - -static __inline int -fv_p2f(fv, p) - struct flowvalve *fv; - int p; -{ - int val, f; - - if (p >= BRTT_PMAX) - f = fv->fv_p2ftab[BRTT_SIZE-1]; - else if ((val = (p & BRTT_MASK))) - f = fv->fv_p2ftab[(val >> BRTT_SHIFT)]; - else - f = fv->fv_p2ftab[1]; - return (f); -} - -/* - * check if an arriving packet should be pre-dropped. - * called from red_addq() when a packet arrives. - * returns 1 when the packet should be pre-dropped. - * should be called in splimp. - */ -static int -fv_checkflow(fv, pktattr, fcache) - struct flowvalve *fv; - struct altq_pktattr *pktattr; - struct fve **fcache; -{ - struct fve *fve; - struct timeval now; - - fv->fv_ifseq++; - FV_TIMESTAMP(&now); - - if ((fve = flowlist_lookup(fv, pktattr, &now)) == NULL) - /* no matching entry in the flowlist */ - return (0); - - *fcache = fve; - - /* update fraction f for every FV_N packets */ - if (++fve->fve_count == FV_N) { - /* - * f = Wf * N / (fv_ifseq - fve_ifseq) + (1 - Wf) * f - */ - fve->fve_f = - (FV_N << FP_SHIFT) / (fv->fv_ifseq - fve->fve_ifseq) - + fve->fve_f - FV_FUNSCALE(fve->fve_f); - fve->fve_ifseq = fv->fv_ifseq; - fve->fve_count = 0; - } - - /* - * overpumping test - */ - if (fve->fve_state == Green && fve->fve_p > fv->fv_pthresh) { - int fthresh; - - /* calculate a threshold */ - fthresh = fv_p2f(fv, fve->fve_p); - if (fve->fve_f > fthresh) - fve->fve_state = Red; - } - - if (fve->fve_state == Red) { - /* - * backoff test - */ - if (now.tv_sec - fve->fve_lastdrop.tv_sec > FV_BACKOFFTHRESH) { - /* no drop for at least FV_BACKOFFTHRESH sec */ - fve->fve_p = 0; - fve->fve_state = Green; -#ifdef FV_STATS - fv->fv_stats.escape++; -#endif - } else { - /* block this flow */ - flowlist_move_to_head(fv, fve); - fve->fve_lastdrop = now; -#ifdef FV_STATS - fv->fv_stats.predrop++; -#endif - return (1); - } - } - - /* - * p = (1 - Wp) * p - */ - fve->fve_p -= FV_PUNSCALE(fve->fve_p); - if (fve->fve_p < 0) - fve->fve_p = 0; -#ifdef FV_STATS - fv->fv_stats.pass++; -#endif - return (0); -} - -/* - * called from red_addq when a packet is dropped by red. - * should be called in splimp. - */ -static void fv_dropbyred(fv, pktattr, fcache) - struct flowvalve *fv; - struct altq_pktattr *pktattr; - struct fve *fcache; -{ - struct fve *fve; - struct timeval now; - - if (pktattr == NULL) - return; - FV_TIMESTAMP(&now); - - if (fcache != NULL) - /* the fve of this packet is already cached */ - fve = fcache; - else if ((fve = flowlist_lookup(fv, pktattr, &now)) == NULL) - fve = flowlist_reclaim(fv, pktattr); - - flowlist_move_to_head(fv, fve); - - /* - * update p: the following line cancels the update - * in fv_checkflow() and calculate - * p = Wp + (1 - Wp) * p - */ - fve->fve_p = (1 << FP_SHIFT) + fve->fve_p; - - fve->fve_lastdrop = now; -} - -#endif /* ALTQ_FLOWVALVE */ - -#ifdef KLD_MODULE - -static struct altqsw red_sw = - {"red", redopen, redclose, redioctl}; - -ALTQ_MODULE(altq_red, ALTQT_RED, &red_sw); - -#endif /* KLD_MODULE */ diff --git a/sys/altq/altq_red.h b/sys/altq/altq_red.h index ef6fd036204..65e9355ccad 100644 --- a/sys/altq/altq_red.h +++ b/sys/altq/altq_red.h @@ -1,8 +1,8 @@ -/* $OpenBSD: altq_red.h,v 1.3 2002/11/26 01:03:34 henning Exp $ */ +/* $OpenBSD: altq_red.h,v 1.4 2002/12/16 09:18:05 kjc Exp $ */ /* $KAME: altq_red.h,v 1.5 2000/12/14 08:12:46 thorpej Exp $ */ /* - * Copyright (C) 1997-2000 + * Copyright (C) 1997-2002 * Sony Computer Science Laboratories Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,47 +32,6 @@ #include <altq/altq_classq.h> -struct red_interface { - char red_ifname[IFNAMSIZ]; -}; - -struct red_stats { - struct red_interface iface; - int q_len; - int q_avg; - - struct pktcntr xmit_cnt; - struct pktcntr drop_cnt; - u_int drop_forced; - u_int drop_unforced; - u_int marked_packets; - - /* static red parameters */ - int q_limit; - int weight; - int inv_pmax; - int th_min; - int th_max; - - /* flowvalve related stuff */ - u_int fv_flows; - u_int fv_pass; - u_int fv_predrop; - u_int fv_alloc; - u_int fv_escape; -}; - -struct red_conf { - struct red_interface iface; - int red_weight; /* weight for EWMA */ - int red_inv_pmax; /* inverse of max drop probability */ - int red_thmin; /* red min threshold */ - int red_thmax; /* red max threshold */ - int red_limit; /* max queue length */ - int red_pkttime; /* average packet time in usec */ - int red_flags; /* see below */ -}; - /* red flags */ #define REDF_ECN4 0x01 /* use packet marking for IPv4 packets */ #define REDF_ECN6 0x02 /* use packet marking for IPv6 packets */ @@ -98,22 +57,8 @@ struct redstats { u_int marked_packets; }; - -/* - * IOCTLs for RED - */ -#define RED_IF_ATTACH _IOW('Q', 1, struct red_interface) -#define RED_IF_DETACH _IOW('Q', 2, struct red_interface) -#define RED_ENABLE _IOW('Q', 3, struct red_interface) -#define RED_DISABLE _IOW('Q', 4, struct red_interface) -#define RED_CONFIG _IOWR('Q', 6, struct red_conf) -#define RED_GETSTATS _IOWR('Q', 12, struct red_stats) -#define RED_SETDEFAULTS _IOW('Q', 30, struct redparams) - #ifdef _KERNEL -struct flowvalve; - /* weight table structure for idle time calibration */ struct wtab { struct wtab *w_next; @@ -148,8 +93,6 @@ typedef struct red { struct wtab *red_wtab; /* weight table */ struct timeval red_last; /* timestamp when the queue becomes idle */ - struct flowvalve *red_flowvalve; /* flowvalve state */ - struct { struct pktcntr xmit_cnt; struct pktcntr drop_cnt; @@ -159,15 +102,6 @@ typedef struct red { } red_stats; } red_t; -typedef struct red_queue { - struct red_queue *rq_next; /* next red_state in the list */ - struct ifaltq *rq_ifq; /* backpointer to ifaltq */ - - class_queue_t *rq_q; - - red_t *rq_red; -} red_queue_t; - /* red drop types */ #define DTYPE_NODROP 0 /* no drop */ #define DTYPE_FORCED 1 /* a "forced" drop */ diff --git a/sys/altq/altq_rio.c b/sys/altq/altq_rio.c index a18795121fe..eafa84aaf26 100644 --- a/sys/altq/altq_rio.c +++ b/sys/altq/altq_rio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: altq_rio.c,v 1.6 2002/11/29 07:52:31 kjc Exp $ */ +/* $OpenBSD: altq_rio.c,v 1.7 2002/12/16 09:18:05 kjc Exp $ */ /* $KAME: altq_rio.c,v 1.8 2000/12/14 08:12:46 thorpej Exp $ */ /* @@ -63,11 +63,8 @@ #include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/socket.h> -#include <sys/sockio.h> #include <sys/systm.h> -#include <sys/proc.h> #include <sys/errno.h> -#include <sys/kernel.h> #include <net/if.h> #include <net/if_types.h> @@ -79,8 +76,8 @@ #include <netinet/ip6.h> #endif +#include <net/pfvar.h> #include <altq/altq.h> -#include <altq/altq_conf.h> #include <altq/altq_cdnr.h> #include <altq/altq_red.h> #include <altq/altq_rio.h> @@ -157,8 +154,6 @@ } \ } -/* rio_list keeps all rio_queue_t's allocated. */ -static rio_queue_t *rio_list = NULL; /* default rio parameter values */ static struct redparams default_rio_params[RIO_NDROPPREC] = { /* th_min, th_max, inv_pmax */ @@ -168,313 +163,8 @@ static struct redparams default_rio_params[RIO_NDROPPREC] = { }; /* internal function prototypes */ -static int rio_enqueue(struct ifaltq *, struct mbuf *, - struct altq_pktattr *); -static struct mbuf *rio_dequeue(struct ifaltq *, int); -static int rio_request(struct ifaltq *, int, void *); -static int rio_detach(rio_queue_t *); static int dscp2index(u_int8_t); -/* - * rio device interface - */ -altqdev_decl(rio); - -int -rioopen(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - /* everything will be done when the queueing scheme is attached. */ - return 0; -} - -int -rioclose(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - rio_queue_t *rqp; - int err, error = 0; - - while ((rqp = rio_list) != NULL) { - /* destroy all */ - err = rio_detach(rqp); - if (err != 0 && error == 0) - error = err; - } - - return error; -} - -int -rioioctl(dev, cmd, addr, flag, p) - dev_t dev; - ioctlcmd_t cmd; - caddr_t addr; - int flag; - struct proc *p; -{ - rio_queue_t *rqp; - struct rio_interface *ifacep; - struct ifnet *ifp; - int error = 0; - - /* check super-user privilege */ - switch (cmd) { - case RIO_GETSTATS: - break; - default: -#if (__FreeBSD_version > 400000) - if ((error = suser(p)) != 0) - return (error); -#else - if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) - return (error); -#endif - break; - } - - switch (cmd) { - - case RIO_ENABLE: - ifacep = (struct rio_interface *)addr; - if ((rqp = altq_lookup(ifacep->rio_ifname, ALTQT_RIO)) == NULL) { - error = EBADF; - break; - } - error = altq_enable(rqp->rq_ifq); - break; - - case RIO_DISABLE: - ifacep = (struct rio_interface *)addr; - if ((rqp = altq_lookup(ifacep->rio_ifname, ALTQT_RIO)) == NULL) { - error = EBADF; - break; - } - error = altq_disable(rqp->rq_ifq); - break; - - case RIO_IF_ATTACH: - ifp = ifunit(((struct rio_interface *)addr)->rio_ifname); - if (ifp == NULL) { - error = ENXIO; - break; - } - - /* allocate and initialize rio_queue_t */ - MALLOC(rqp, rio_queue_t *, sizeof(rio_queue_t), M_DEVBUF, M_WAITOK); - if (rqp == NULL) { - error = ENOMEM; - break; - } - bzero(rqp, sizeof(rio_queue_t)); - - MALLOC(rqp->rq_q, class_queue_t *, sizeof(class_queue_t), - M_DEVBUF, M_WAITOK); - if (rqp->rq_q == NULL) { - FREE(rqp, M_DEVBUF); - error = ENOMEM; - break; - } - bzero(rqp->rq_q, sizeof(class_queue_t)); - - rqp->rq_rio = rio_alloc(0, NULL, 0, 0); - if (rqp->rq_rio == NULL) { - FREE(rqp->rq_q, M_DEVBUF); - FREE(rqp, M_DEVBUF); - error = ENOMEM; - break; - } - - rqp->rq_ifq = &ifp->if_snd; - qtail(rqp->rq_q) = NULL; - qlen(rqp->rq_q) = 0; - qlimit(rqp->rq_q) = RIO_LIMIT; - qtype(rqp->rq_q) = Q_RIO; - - /* - * set RIO to this ifnet structure. - */ - error = altq_attach(rqp->rq_ifq, ALTQT_RIO, rqp, - rio_enqueue, rio_dequeue, rio_request, - NULL, NULL); - if (error) { - rio_destroy(rqp->rq_rio); - FREE(rqp->rq_q, M_DEVBUF); - FREE(rqp, M_DEVBUF); - break; - } - - /* add this state to the rio list */ - rqp->rq_next = rio_list; - rio_list = rqp; - break; - - case RIO_IF_DETACH: - ifacep = (struct rio_interface *)addr; - if ((rqp = altq_lookup(ifacep->rio_ifname, ALTQT_RIO)) == NULL) { - error = EBADF; - break; - } - error = rio_detach(rqp); - break; - - case RIO_GETSTATS: - do { - struct rio_stats *q_stats; - rio_t *rp; - int i; - - q_stats = (struct rio_stats *)addr; - if ((rqp = altq_lookup(q_stats->iface.rio_ifname, - ALTQT_RIO)) == NULL) { - error = EBADF; - break; - } - - rp = rqp->rq_rio; - - q_stats->q_limit = qlimit(rqp->rq_q); - q_stats->weight = rp->rio_weight; - q_stats->flags = rp->rio_flags; - - for (i = 0; i < RIO_NDROPPREC; i++) { - q_stats->q_len[i] = rp->rio_precstate[i].qlen; - bcopy(&rp->q_stats[i], &q_stats->q_stats[i], - sizeof(struct redstats)); - q_stats->q_stats[i].q_avg = - rp->rio_precstate[i].avg >> rp->rio_wshift; - - q_stats->q_params[i].inv_pmax - = rp->rio_precstate[i].inv_pmax; - q_stats->q_params[i].th_min - = rp->rio_precstate[i].th_min; - q_stats->q_params[i].th_max - = rp->rio_precstate[i].th_max; - } - } while (0); - break; - - case RIO_CONFIG: - do { - struct rio_conf *fc; - rio_t *new; - int s, limit, i; - - fc = (struct rio_conf *)addr; - if ((rqp = altq_lookup(fc->iface.rio_ifname, - ALTQT_RIO)) == NULL) { - error = EBADF; - break; - } - - new = rio_alloc(fc->rio_weight, &fc->q_params[0], - fc->rio_flags, fc->rio_pkttime); - if (new == NULL) { - error = ENOMEM; - break; - } - - s = splimp(); - _flushq(rqp->rq_q); - limit = fc->rio_limit; - if (limit < fc->q_params[RIO_NDROPPREC-1].th_max) - limit = fc->q_params[RIO_NDROPPREC-1].th_max; - qlimit(rqp->rq_q) = limit; - - rio_destroy(rqp->rq_rio); - rqp->rq_rio = new; - - splx(s); - - /* write back new values */ - fc->rio_limit = limit; - for (i = 0; i < RIO_NDROPPREC; i++) { - fc->q_params[i].inv_pmax = - rqp->rq_rio->rio_precstate[i].inv_pmax; - fc->q_params[i].th_min = - rqp->rq_rio->rio_precstate[i].th_min; - fc->q_params[i].th_max = - rqp->rq_rio->rio_precstate[i].th_max; - } - } while (0); - break; - - case RIO_SETDEFAULTS: - do { - struct redparams *rp; - int i; - - rp = (struct redparams *)addr; - for (i = 0; i < RIO_NDROPPREC; i++) - default_rio_params[i] = rp[i]; - } while (0); - break; - - default: - error = EINVAL; - break; - } - - return error; -} - -static int -rio_detach(rqp) - rio_queue_t *rqp; -{ - rio_queue_t *tmp; - int error = 0; - - if (ALTQ_IS_ENABLED(rqp->rq_ifq)) - altq_disable(rqp->rq_ifq); - - if ((error = altq_detach(rqp->rq_ifq))) - return (error); - - if (rio_list == rqp) - rio_list = rqp->rq_next; - else { - for (tmp = rio_list; tmp != NULL; tmp = tmp->rq_next) - if (tmp->rq_next == rqp) { - tmp->rq_next = rqp->rq_next; - break; - } - if (tmp == NULL) - printf("rio_detach: no state found in rio_list!\n"); - } - - rio_destroy(rqp->rq_rio); - FREE(rqp->rq_q, M_DEVBUF); - FREE(rqp, M_DEVBUF); - return (error); -} - -/* - * rio support routines - */ -static int -rio_request(ifq, req, arg) - struct ifaltq *ifq; - int req; - void *arg; -{ - rio_queue_t *rqp = (rio_queue_t *)ifq->altq_disc; - - switch (req) { - case ALTRQ_PURGE: - _flushq(rqp->rq_q); - if (ALTQ_IS_ENABLED(ifq)) - ifq->ifq_len = 0; - break; - } - return (0); -} - - rio_t * rio_alloc(weight, params, flags, pkttime) int weight; @@ -590,28 +280,6 @@ rio_getstats(rp, sp) } } -/* - * enqueue routine: - * - * returns: 0 when successfully queued. - * ENOBUFS when drop occurs. - */ -static int -rio_enqueue(ifq, m, pktattr) - struct ifaltq *ifq; - struct mbuf *m; - struct altq_pktattr *pktattr; -{ - rio_queue_t *rqp = (rio_queue_t *)ifq->altq_disc; - int error = 0; - - if (rio_addq(rqp->rq_rio, rqp->rq_q, m, pktattr) == 0) - ifq->ifq_len++; - else - error = ENOBUFS; - return error; -} - #if (RIO_NDROPPREC == 3) /* * internally, a drop precedence value is converted to an index @@ -757,31 +425,6 @@ rio_addq(rp, q, m, pktattr) return (0); } -/* - * dequeue routine: - * must be called in splimp. - * - * returns: mbuf dequeued. - * NULL when no packet is available in the queue. - */ - -static struct mbuf * -rio_dequeue(ifq, op) - struct ifaltq *ifq; - int op; -{ - rio_queue_t *rqp = (rio_queue_t *)ifq->altq_disc; - struct mbuf *m = NULL; - - if (op == ALTDQ_POLL) - return qhead(rqp->rq_q); - - m = rio_getq(rqp->rq_rio, rqp->rq_q); - if (m != NULL) - ifq->ifq_len--; - return m; -} - struct mbuf * rio_getq(rp, q) rio_t *rp; @@ -804,12 +447,3 @@ rio_getq(rp, q) } return (m); } - -#ifdef KLD_MODULE - -static struct altqsw rio_sw = - {"rio", rioopen, rioclose, rioioctl}; - -ALTQ_MODULE(altq_rio, ALTQT_RIO, &rio_sw); - -#endif /* KLD_MODULE */ diff --git a/sys/altq/altq_rio.h b/sys/altq/altq_rio.h index fdc39fb9fe5..20332b23415 100644 --- a/sys/altq/altq_rio.h +++ b/sys/altq/altq_rio.h @@ -1,4 +1,4 @@ -/* $OpenBSD: altq_rio.h,v 1.3 2002/11/26 01:03:34 henning Exp $ */ +/* $OpenBSD: altq_rio.h,v 1.4 2002/12/16 09:18:05 kjc Exp $ */ /* $KAME: altq_rio.h,v 1.5 2000/12/14 08:12:46 thorpej Exp $ */ /* @@ -69,17 +69,6 @@ struct rio_conf { #define RIOF_ECN (RIOF_ECN4 | RIOF_ECN6) #define RIOF_CLEARDSCP 0x200 /* clear diffserv codepoint */ -/* - * IOCTLs for RIO - */ -#define RIO_IF_ATTACH _IOW('Q', 1, struct rio_interface) -#define RIO_IF_DETACH _IOW('Q', 2, struct rio_interface) -#define RIO_ENABLE _IOW('Q', 3, struct rio_interface) -#define RIO_DISABLE _IOW('Q', 4, struct rio_interface) -#define RIO_CONFIG _IOWR('Q', 6, struct rio_conf) -#define RIO_GETSTATS _IOWR('Q', 12, struct rio_stats) -#define RIO_SETDEFAULTS _IOW('Q', 30, struct redparams[RIO_NDROPPREC]) - #ifdef _KERNEL typedef struct rio { diff --git a/sys/altq/altq_rmclass.c b/sys/altq/altq_rmclass.c index 1821a30232f..50c3554f411 100644 --- a/sys/altq/altq_rmclass.c +++ b/sys/altq/altq_rmclass.c @@ -1,4 +1,4 @@ -/* $OpenBSD: altq_rmclass.c,v 1.5 2002/11/29 07:52:31 kjc Exp $ */ +/* $OpenBSD: altq_rmclass.c,v 1.6 2002/12/16 09:18:05 kjc Exp $ */ /* $KAME: altq_rmclass.c,v 1.10 2001/02/09 07:20:40 kjc Exp $ */ /* @@ -44,12 +44,8 @@ #include <sys/systm.h> #include <sys/errno.h> #include <sys/time.h> -#include <sys/kernel.h> #include <net/if.h> -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> #include <altq/altq.h> #include <altq/altq_rmclass.h> diff --git a/sys/altq/altq_subr.c b/sys/altq/altq_subr.c index 203e9350227..a4c0d1ff25d 100644 --- a/sys/altq/altq_subr.c +++ b/sys/altq/altq_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: altq_subr.c,v 1.12 2002/11/29 07:51:54 kjc Exp $ */ +/* $OpenBSD: altq_subr.c,v 1.13 2002/12/16 09:18:05 kjc Exp $ */ /* $KAME: altq_subr.c,v 1.11 2002/01/11 08:11:49 kjc Exp $ */ /* @@ -56,7 +56,6 @@ #include <net/pfvar.h> #include <altq/altq.h> -#include <altq/altq_conf.h> /* machine dependent clock related includes */ #if defined(__i386__) @@ -68,33 +67,6 @@ * internal function prototypes */ static void tbr_timeout(void *); -static int extract_ports4(struct mbuf *, struct ip *, - struct flowinfo_in *); -#ifdef INET6 -static int extract_ports6(struct mbuf *, struct ip6_hdr *, - struct flowinfo_in6 *); -#endif -static int apply_filter4(u_int32_t, struct flow_filter *, - struct flowinfo_in *); -static int apply_ppfilter4(u_int32_t, struct flow_filter *, - struct flowinfo_in *); -#ifdef INET6 -static int apply_filter6(u_int32_t, struct flow_filter6 *, - struct flowinfo_in6 *); -#endif -static int apply_tosfilter4(u_int32_t, struct flow_filter *, - struct flowinfo_in *); -static u_long get_filt_handle(struct acc_classifier *, int); -static struct acc_filter *filth_to_filtp(struct acc_classifier *, - u_long); -static u_int32_t filt2fibmask(struct flow_filter *); - -static void ip4f_cache(struct ip *, struct flowinfo_in *); -static int ip4f_lookup(struct ip *, struct flowinfo_in *); -static int ip4f_init(void); -static struct ip4_frag *ip4f_alloc(void); -static void ip4f_free(struct ip4_frag *); - int (*altq_input)(struct mbuf *, int) = NULL; static int tbr_timer = 0; /* token bucket regulator timer */ static struct callout tbr_callout = CALLOUT_INITIALIZER; @@ -135,14 +107,12 @@ altq_attach(ifq, type, discipline, enqueue, dequeue, request, clfier, classify) if (!ALTQ_IS_READY(ifq)) return ENXIO; - if (PFALTQ_IS_ACTIVE()) { - /* pfaltq can override the existing discipline */ - } else { - if (ALTQ_IS_ENABLED(ifq)) - return EBUSY; - if (ALTQ_IS_ATTACHED(ifq)) - return EEXIST; - } +#if 0 /* pfaltq can override the existing discipline */ + if (ALTQ_IS_ENABLED(ifq)) + return EBUSY; + if (ALTQ_IS_ATTACHED(ifq)) + return EEXIST; +#endif ifq->altq_type = type; ifq->altq_disc = discipline; ifq->altq_enqueue = enqueue; @@ -150,14 +120,8 @@ altq_attach(ifq, type, discipline, enqueue, dequeue, request, clfier, classify) ifq->altq_request = request; ifq->altq_clfier = clfier; ifq->altq_classify = classify; - if (PFALTQ_IS_ACTIVE()) - ifq->altq_flags &= (ALTQF_CANTCHANGE|ALTQF_ENABLED); - else - ifq->altq_flags &= ALTQF_CANTCHANGE; + ifq->altq_flags &= (ALTQF_CANTCHANGE|ALTQF_ENABLED); -#ifdef ALTQ_KLD - altq_module_incref(type); -#endif return 0; } @@ -172,9 +136,6 @@ altq_detach(ifq) if (!ALTQ_IS_ATTACHED(ifq)) return (0); -#ifdef ALTQ_KLD - altq_module_declref(ifq->altq_type); -#endif ifq->altq_type = ALTQT_NONE; ifq->altq_disc = NULL; ifq->altq_enqueue = NULL; @@ -364,16 +325,7 @@ tbr_timeout(arg) active = 0; s = splimp(); -#ifdef __FreeBSD__ -#if (__FreeBSD_version < 300000) - for (ifp = ifnet; ifp; ifp = ifp->if_next) -#else - for (ifp = ifnet.tqh_first; ifp != NULL; ifp = ifp->if_link.tqe_next) -#endif -#else /* !FreeBSD */ - for (ifp = ifnet.tqh_first; ifp != NULL; ifp = ifp->if_list.tqe_next) -#endif - { + for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) { if (!TBR_IS_ENABLED(&ifp->if_snd)) continue; active++; @@ -436,11 +388,23 @@ altq_pfattach(struct pf_altq *a) switch (a->scheduler) { case ALTQT_NONE: break; +#ifdef ALTQ_CBQ case ALTQT_CBQ: error = cbq_pfattach(a); break; +#endif +#ifdef ALTQ_PRIQ + case ALTQT_PRIQ: + error = priq_pfattach(a); + break; +#endif +#ifdef ALTQ_HFSC + case ALTQT_HFSC: + error = hfsc_pfattach(a); + break; +#endif default: - error = EINVAL; + error = ENXIO; } ifp = ifunit(a->ifname); @@ -502,12 +466,29 @@ altq_add(struct pf_altq *a) if (a->qname[0] != 0) return (altq_add_queue(a)); + if (machclk_freq == 0) + init_machclk(); + if (machclk_freq == 0) + panic("altq_add: no cpu clock"); + switch (a->scheduler) { +#ifdef ALTQ_CBQ case ALTQT_CBQ: error = cbq_add_altq(a); break; +#endif +#ifdef ALTQ_PRIQ + case ALTQT_PRIQ: + error = priq_add_altq(a); + break; +#endif +#ifdef ALTQ_HFSC + case ALTQT_HFSC: + error = hfsc_add_altq(a); + break; +#endif default: - error = EINVAL; + error = ENXIO; } return (error); @@ -525,11 +506,23 @@ altq_remove(struct pf_altq *a) return (altq_remove_queue(a)); switch (a->scheduler) { +#ifdef ALTQ_CBQ case ALTQT_CBQ: error = cbq_remove_altq(a); break; +#endif +#ifdef ALTQ_PRIQ + case ALTQT_PRIQ: + error = priq_remove_altq(a); + break; +#endif +#ifdef ALTQ_HFSC + case ALTQT_HFSC: + error = hfsc_remove_altq(a); + break; +#endif default: - error = EINVAL; + error = ENXIO; } return (error); @@ -544,11 +537,23 @@ altq_add_queue(struct pf_altq *a) int error = 0; switch (a->scheduler) { +#ifdef ALTQ_CBQ case ALTQT_CBQ: error = cbq_add_queue(a); break; +#endif +#ifdef ALTQ_PRIQ + case ALTQT_PRIQ: + error = priq_add_queue(a); + break; +#endif +#ifdef ALTQ_HFSC + case ALTQT_HFSC: + error = hfsc_add_queue(a); + break; +#endif default: - error = EINVAL; + error = ENXIO; } return (error); @@ -563,11 +568,23 @@ altq_remove_queue(struct pf_altq *a) int error = 0; switch (a->scheduler) { +#ifdef ALTQ_CBQ case ALTQT_CBQ: error = cbq_remove_queue(a); break; +#endif +#ifdef ALTQ_PRIQ + case ALTQT_PRIQ: + error = priq_remove_queue(a); + break; +#endif +#ifdef ALTQ_HFSC + case ALTQT_HFSC: + error = hfsc_remove_queue(a); + break; +#endif default: - error = EINVAL; + error = ENXIO; } return (error); @@ -582,956 +599,28 @@ altq_getqstats(struct pf_altq *a, void *ubuf, int *nbytes) int error = 0; switch (a->scheduler) { +#ifdef ALTQ_CBQ case ALTQT_CBQ: error = cbq_getqstats(a, ubuf, nbytes); break; - default: - error = EINVAL; - } - - return (error); -} - - -#ifndef IPPROTO_ESP -#define IPPROTO_ESP 50 /* encapsulating security payload */ #endif -#ifndef IPPROTO_AH -#define IPPROTO_AH 51 /* authentication header */ -#endif - -/* - * extract flow information from a given packet. - * filt_mask shows flowinfo fields required. - * we assume the ip header is in one mbuf, and addresses and ports are - * in network byte order. - */ -int -altq_extractflow(m, af, flow, filt_bmask) - struct mbuf *m; - int af; - struct flowinfo *flow; - u_int32_t filt_bmask; -{ - - switch (af) { - case PF_INET: { - struct flowinfo_in *fin; - struct ip *ip; - - ip = mtod(m, struct ip *); - - if (ip->ip_v != 4) - break; - - fin = (struct flowinfo_in *)flow; - fin->fi_len = sizeof(struct flowinfo_in); - fin->fi_family = AF_INET; - - fin->fi_proto = ip->ip_p; - fin->fi_tos = ip->ip_tos; - - fin->fi_src.s_addr = ip->ip_src.s_addr; - fin->fi_dst.s_addr = ip->ip_dst.s_addr; - - if (filt_bmask & FIMB4_PORTS) - /* if port info is required, extract port numbers */ - extract_ports4(m, ip, fin); - else { - fin->fi_sport = 0; - fin->fi_dport = 0; - fin->fi_gpi = 0; - } - return (1); - } - -#ifdef INET6 - case PF_INET6: { - struct flowinfo_in6 *fin6; - struct ip6_hdr *ip6; - - ip6 = mtod(m, struct ip6_hdr *); - /* should we check the ip version? */ - - fin6 = (struct flowinfo_in6 *)flow; - fin6->fi6_len = sizeof(struct flowinfo_in6); - fin6->fi6_family = AF_INET6; - - fin6->fi6_proto = ip6->ip6_nxt; - fin6->fi6_tclass = (ntohl(ip6->ip6_flow) >> 20) & 0xff; - - fin6->fi6_flowlabel = ip6->ip6_flow & htonl(0x000fffff); - fin6->fi6_src = ip6->ip6_src; - fin6->fi6_dst = ip6->ip6_dst; - - if ((filt_bmask & FIMB6_PORTS) || - ((filt_bmask & FIMB6_PROTO) - && ip6->ip6_nxt > IPPROTO_IPV6)) - /* - * if port info is required, or proto is required - * but there are option headers, extract port - * and protocol numbers. - */ - extract_ports6(m, ip6, fin6); - else { - fin6->fi6_sport = 0; - fin6->fi6_dport = 0; - fin6->fi6_gpi = 0; - } - return (1); - } -#endif /* INET6 */ - - default: +#ifdef ALTQ_PRIQ + case ALTQT_PRIQ: + error = priq_getqstats(a, ubuf, nbytes); break; - } - - /* failed */ - flow->fi_len = sizeof(struct flowinfo); - flow->fi_family = AF_UNSPEC; - return (0); -} - -/* - * helper routine to extract port numbers - */ -/* structure for ipsec and ipv6 option header template */ -struct _opt6 { - u_int8_t opt6_nxt; /* next header */ - u_int8_t opt6_hlen; /* header extension length */ - u_int16_t _pad; - u_int32_t ah_spi; /* security parameter index - for authentication header */ -}; - -/* - * extract port numbers from a ipv4 packet. - */ -static int -extract_ports4(m, ip, fin) - struct mbuf *m; - struct ip *ip; - struct flowinfo_in *fin; -{ - struct mbuf *m0; - u_short ip_off; - u_int8_t proto; - int off; - - fin->fi_sport = 0; - fin->fi_dport = 0; - fin->fi_gpi = 0; - - ip_off = ntohs(ip->ip_off); - /* if it is a fragment, try cached fragment info */ - if (ip_off & IP_OFFMASK) { - ip4f_lookup(ip, fin); - return (1); - } - - /* locate the mbuf containing the protocol header */ - for (m0 = m; m0 != NULL; m0 = m0->m_next) - if (((caddr_t)ip >= m0->m_data) && - ((caddr_t)ip < m0->m_data + m0->m_len)) - break; - if (m0 == NULL) { -#ifdef ALTQ_DEBUG - printf("extract_ports4: can't locate header! ip=%p\n", ip); -#endif - return (0); - } - off = ((caddr_t)ip - m0->m_data) + (ip->ip_hl << 2); - proto = ip->ip_p; - -#ifdef ALTQ_IPSEC - again: #endif - while (off >= m0->m_len) { - off -= m0->m_len; - m0 = m0->m_next; - if (m0 == NULL) - return (0); /* bogus ip_hl! */ - } - if (m0->m_len < off + 4) - return (0); - - switch (proto) { - case IPPROTO_TCP: - case IPPROTO_UDP: { - struct udphdr *udp; - - udp = (struct udphdr *)(mtod(m0, caddr_t) + off); - fin->fi_sport = udp->uh_sport; - fin->fi_dport = udp->uh_dport; - fin->fi_proto = proto; - } +#ifdef ALTQ_HFSC + case ALTQT_HFSC: + error = hfsc_getqstats(a, ubuf, nbytes); break; - -#ifdef ALTQ_IPSEC - case IPPROTO_ESP: - if (fin->fi_gpi == 0){ - u_int32_t *gpi; - - gpi = (u_int32_t *)(mtod(m0, caddr_t) + off); - fin->fi_gpi = *gpi; - } - fin->fi_proto = proto; - break; - - case IPPROTO_AH: { - /* get next header and header length */ - struct _opt6 *opt6; - - opt6 = (struct _opt6 *)(mtod(m0, caddr_t) + off); - proto = opt6->opt6_nxt; - off += 8 + (opt6->opt6_hlen * 4); - if (fin->fi_gpi == 0 && m0->m_len >= off + 8) - fin->fi_gpi = opt6->ah_spi; - } - /* goto the next header */ - goto again; -#endif /* ALTQ_IPSEC */ - - default: - fin->fi_proto = proto; - return (0); - } - - /* if this is a first fragment, cache it. */ - if (ip_off & IP_MF) - ip4f_cache(ip, fin); - - return (1); -} - -#ifdef INET6 -static int -extract_ports6(m, ip6, fin6) - struct mbuf *m; - struct ip6_hdr *ip6; - struct flowinfo_in6 *fin6; -{ - struct mbuf *m0; - int off; - u_int8_t proto; - - fin6->fi6_gpi = 0; - fin6->fi6_sport = 0; - fin6->fi6_dport = 0; - - /* locate the mbuf containing the protocol header */ - for (m0 = m; m0 != NULL; m0 = m0->m_next) - if (((caddr_t)ip6 >= m0->m_data) && - ((caddr_t)ip6 < m0->m_data + m0->m_len)) - break; - if (m0 == NULL) { -#ifdef ALTQ_DEBUG - printf("extract_ports6: can't locate header! ip6=%p\n", ip6); -#endif - return (0); - } - off = ((caddr_t)ip6 - m0->m_data) + sizeof(struct ip6_hdr); - - proto = ip6->ip6_nxt; - do { - while (off >= m0->m_len) { - off -= m0->m_len; - m0 = m0->m_next; - if (m0 == NULL) - return (0); - } - if (m0->m_len < off + 4) - return (0); - - switch (proto) { - case IPPROTO_TCP: - case IPPROTO_UDP: { - struct udphdr *udp; - - udp = (struct udphdr *)(mtod(m0, caddr_t) + off); - fin6->fi6_sport = udp->uh_sport; - fin6->fi6_dport = udp->uh_dport; - fin6->fi6_proto = proto; - } - return (1); - - case IPPROTO_ESP: - if (fin6->fi6_gpi == 0) { - u_int32_t *gpi; - - gpi = (u_int32_t *)(mtod(m0, caddr_t) + off); - fin6->fi6_gpi = *gpi; - } - fin6->fi6_proto = proto; - return (1); - - case IPPROTO_AH: { - /* get next header and header length */ - struct _opt6 *opt6; - - opt6 = (struct _opt6 *)(mtod(m0, caddr_t) + off); - if (fin6->fi6_gpi == 0 && m0->m_len >= off + 8) - fin6->fi6_gpi = opt6->ah_spi; - proto = opt6->opt6_nxt; - off += 8 + (opt6->opt6_hlen * 4); - /* goto the next header */ - break; - } - - case IPPROTO_HOPOPTS: - case IPPROTO_ROUTING: - case IPPROTO_DSTOPTS: { - /* get next header and header length */ - struct _opt6 *opt6; - - opt6 = (struct _opt6 *)(mtod(m0, caddr_t) + off); - proto = opt6->opt6_nxt; - off += (opt6->opt6_hlen + 1) * 8; - /* goto the next header */ - break; - } - - case IPPROTO_FRAGMENT: - /* ipv6 fragmentations are not supported yet */ - default: - fin6->fi6_proto = proto; - return (0); - } - } while (1); - /*NOTREACHED*/ -} -#endif /* INET6 */ - -/* - * altq common classifier - */ -int -acc_add_filter(classifier, filter, class, phandle) - struct acc_classifier *classifier; - struct flow_filter *filter; - void *class; - u_long *phandle; -{ - struct acc_filter *afp, *prev, *tmp; - int i, s; - -#ifdef INET6 - if (filter->ff_flow.fi_family != AF_INET && - filter->ff_flow.fi_family != AF_INET6) - return (EINVAL); -#else - if (filter->ff_flow.fi_family != AF_INET) - return (EINVAL); #endif - - MALLOC(afp, struct acc_filter *, sizeof(struct acc_filter), - M_DEVBUF, M_WAITOK); - if (afp == NULL) - return (ENOMEM); - bzero(afp, sizeof(struct acc_filter)); - - afp->f_filter = *filter; - afp->f_class = class; - - i = ACC_WILDCARD_INDEX; - if (filter->ff_flow.fi_family == AF_INET) { - struct flow_filter *filter4 = &afp->f_filter; - - /* - * if address is 0, it's a wildcard. if address mask - * isn't set, use full mask. - */ - if (filter4->ff_flow.fi_dst.s_addr == 0) - filter4->ff_mask.mask_dst.s_addr = 0; - else if (filter4->ff_mask.mask_dst.s_addr == 0) - filter4->ff_mask.mask_dst.s_addr = 0xffffffff; - if (filter4->ff_flow.fi_src.s_addr == 0) - filter4->ff_mask.mask_src.s_addr = 0; - else if (filter4->ff_mask.mask_src.s_addr == 0) - filter4->ff_mask.mask_src.s_addr = 0xffffffff; - - /* clear extra bits in addresses */ - filter4->ff_flow.fi_dst.s_addr &= - filter4->ff_mask.mask_dst.s_addr; - filter4->ff_flow.fi_src.s_addr &= - filter4->ff_mask.mask_src.s_addr; - - /* - * if dst address is a wildcard, use hash-entry - * ACC_WILDCARD_INDEX. - */ - if (filter4->ff_mask.mask_dst.s_addr != 0xffffffff) - i = ACC_WILDCARD_INDEX; - else - i = ACC_GET_HASH_INDEX(filter4->ff_flow.fi_dst.s_addr); - } -#ifdef INET6 - else if (filter->ff_flow.fi_family == AF_INET6) { - struct flow_filter6 *filter6 = - (struct flow_filter6 *)&afp->f_filter; -#ifndef IN6MASK0 /* taken from kame ipv6 */ -#define IN6MASK0 {{{ 0, 0, 0, 0 }}} -#define IN6MASK128 {{{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }}} - const struct in6_addr in6mask0 = IN6MASK0; - const struct in6_addr in6mask128 = IN6MASK128; -#endif - - if (IN6_IS_ADDR_UNSPECIFIED(&filter6->ff_flow6.fi6_dst)) - filter6->ff_mask6.mask6_dst = in6mask0; - else if (IN6_IS_ADDR_UNSPECIFIED(&filter6->ff_mask6.mask6_dst)) - filter6->ff_mask6.mask6_dst = in6mask128; - if (IN6_IS_ADDR_UNSPECIFIED(&filter6->ff_flow6.fi6_src)) - filter6->ff_mask6.mask6_src = in6mask0; - else if (IN6_IS_ADDR_UNSPECIFIED(&filter6->ff_mask6.mask6_src)) - filter6->ff_mask6.mask6_src = in6mask128; - - /* clear extra bits in addresses */ - for (i = 0; i < 16; i++) - filter6->ff_flow6.fi6_dst.s6_addr[i] &= - filter6->ff_mask6.mask6_dst.s6_addr[i]; - for (i = 0; i < 16; i++) - filter6->ff_flow6.fi6_src.s6_addr[i] &= - filter6->ff_mask6.mask6_src.s6_addr[i]; - - if (filter6->ff_flow6.fi6_flowlabel == 0) - i = ACC_WILDCARD_INDEX; - else - i = ACC_GET_HASH_INDEX(filter6->ff_flow6.fi6_flowlabel); - } -#endif /* INET6 */ - - afp->f_handle = get_filt_handle(classifier, i); - - /* update filter bitmask */ - afp->f_fbmask = filt2fibmask(filter); - classifier->acc_fbmask |= afp->f_fbmask; - - /* - * add this filter to the filter list. - * filters are ordered from the highest rule number. - */ - s = splimp(); - prev = NULL; - LIST_FOREACH(tmp, &classifier->acc_filters[i], f_chain) { - if (tmp->f_filter.ff_ruleno > afp->f_filter.ff_ruleno) - prev = tmp; - else - break; - } - if (prev == NULL) - LIST_INSERT_HEAD(&classifier->acc_filters[i], afp, f_chain); - else - LIST_INSERT_AFTER(prev, afp, f_chain); - splx(s); - - *phandle = afp->f_handle; - return (0); -} - -int -acc_delete_filter(classifier, handle) - struct acc_classifier *classifier; - u_long handle; -{ - struct acc_filter *afp; - int s; - - if ((afp = filth_to_filtp(classifier, handle)) == NULL) - return (EINVAL); - - s = splimp(); - LIST_REMOVE(afp, f_chain); - splx(s); - - FREE(afp, M_DEVBUF); - - /* todo: update filt_bmask */ - - return (0); -} - -/* - * delete filters referencing to the specified class. - * if the all flag is not 0, delete all the filters. - */ -int -acc_discard_filters(classifier, class, all) - struct acc_classifier *classifier; - void *class; - int all; -{ - struct acc_filter *afp; - int i, s; - -#if 1 /* PFALTQ */ - if (classifier == NULL) - return (0); -#endif - s = splimp(); - for (i = 0; i < ACC_FILTER_TABLESIZE; i++) { - do { - LIST_FOREACH(afp, &classifier->acc_filters[i], f_chain) - if (all || afp->f_class == class) { - LIST_REMOVE(afp, f_chain); - FREE(afp, M_DEVBUF); - /* start again from the head */ - break; - } - } while (afp != NULL); - } - splx(s); - - if (all) - classifier->acc_fbmask = 0; - - return (0); -} - -void * -acc_classify(clfier, m, af) - void *clfier; - struct mbuf *m; - int af; -{ - struct acc_classifier *classifier; - struct flowinfo flow; - struct acc_filter *afp; - int i; - - classifier = (struct acc_classifier *)clfier; - altq_extractflow(m, af, &flow, classifier->acc_fbmask); - - if (flow.fi_family == AF_INET) { - struct flowinfo_in *fp = (struct flowinfo_in *)&flow; - - if ((classifier->acc_fbmask & FIMB4_ALL) == FIMB4_TOS) { - /* only tos is used */ - LIST_FOREACH(afp, - &classifier->acc_filters[ACC_WILDCARD_INDEX], - f_chain) - if (apply_tosfilter4(afp->f_fbmask, - &afp->f_filter, fp)) - /* filter matched */ - return (afp->f_class); - } else if ((classifier->acc_fbmask & - (~(FIMB4_PROTO|FIMB4_SPORT|FIMB4_DPORT) & FIMB4_ALL)) - == 0) { - /* only proto and ports are used */ - LIST_FOREACH(afp, - &classifier->acc_filters[ACC_WILDCARD_INDEX], - f_chain) - if (apply_ppfilter4(afp->f_fbmask, - &afp->f_filter, fp)) - /* filter matched */ - return (afp->f_class); - } else { - /* get the filter hash entry from its dest address */ - i = ACC_GET_HASH_INDEX(fp->fi_dst.s_addr); - do { - /* - * go through this loop twice. first for dst - * hash, second for wildcards. - */ - LIST_FOREACH(afp, &classifier->acc_filters[i], - f_chain) - if (apply_filter4(afp->f_fbmask, - &afp->f_filter, fp)) - /* filter matched */ - return (afp->f_class); - - /* - * check again for filters with a dst addr - * wildcard. - * (daddr == 0 || dmask != 0xffffffff). - */ - if (i != ACC_WILDCARD_INDEX) - i = ACC_WILDCARD_INDEX; - else - break; - } while (1); - } - } -#ifdef INET6 - else if (flow.fi_family == AF_INET6) { - struct flowinfo_in6 *fp6 = (struct flowinfo_in6 *)&flow; - - /* get the filter hash entry from its flow ID */ - if (fp6->fi6_flowlabel != 0) - i = ACC_GET_HASH_INDEX(fp6->fi6_flowlabel); - else - /* flowlable can be zero */ - i = ACC_WILDCARD_INDEX; - - /* go through this loop twice. first for flow hash, second - for wildcards. */ - do { - LIST_FOREACH(afp, &classifier->acc_filters[i], f_chain) - if (apply_filter6(afp->f_fbmask, - (struct flow_filter6 *)&afp->f_filter, - fp6)) - /* filter matched */ - return (afp->f_class); - - /* - * check again for filters with a wildcard. - */ - if (i != ACC_WILDCARD_INDEX) - i = ACC_WILDCARD_INDEX; - else - break; - } while (1); - } -#endif /* INET6 */ - - /* no filter matched */ - return (NULL); -} - -static int -apply_filter4(fbmask, filt, pkt) - u_int32_t fbmask; - struct flow_filter *filt; - struct flowinfo_in *pkt; -{ - if (filt->ff_flow.fi_family != AF_INET) - return (0); - if ((fbmask & FIMB4_SPORT) && filt->ff_flow.fi_sport != pkt->fi_sport) - return (0); - if ((fbmask & FIMB4_DPORT) && filt->ff_flow.fi_dport != pkt->fi_dport) - return (0); - if ((fbmask & FIMB4_DADDR) && - filt->ff_flow.fi_dst.s_addr != - (pkt->fi_dst.s_addr & filt->ff_mask.mask_dst.s_addr)) - return (0); - if ((fbmask & FIMB4_SADDR) && - filt->ff_flow.fi_src.s_addr != - (pkt->fi_src.s_addr & filt->ff_mask.mask_src.s_addr)) - return (0); - if ((fbmask & FIMB4_PROTO) && filt->ff_flow.fi_proto != pkt->fi_proto) - return (0); - if ((fbmask & FIMB4_TOS) && filt->ff_flow.fi_tos != - (pkt->fi_tos & filt->ff_mask.mask_tos)) - return (0); - if ((fbmask & FIMB4_GPI) && filt->ff_flow.fi_gpi != (pkt->fi_gpi)) - return (0); - /* match */ - return (1); -} - -/* - * filter matching function optimized for a common case that checks - * only protocol and port numbers - */ -static int -apply_ppfilter4(fbmask, filt, pkt) - u_int32_t fbmask; - struct flow_filter *filt; - struct flowinfo_in *pkt; -{ - if (filt->ff_flow.fi_family != AF_INET) - return (0); - if ((fbmask & FIMB4_SPORT) && filt->ff_flow.fi_sport != pkt->fi_sport) - return (0); - if ((fbmask & FIMB4_DPORT) && filt->ff_flow.fi_dport != pkt->fi_dport) - return (0); - if ((fbmask & FIMB4_PROTO) && filt->ff_flow.fi_proto != pkt->fi_proto) - return (0); - /* match */ - return (1); -} - -/* - * filter matching function only for tos field. - */ -static int -apply_tosfilter4(fbmask, filt, pkt) - u_int32_t fbmask; - struct flow_filter *filt; - struct flowinfo_in *pkt; -{ - if (filt->ff_flow.fi_family != AF_INET) - return (0); - if ((fbmask & FIMB4_TOS) && filt->ff_flow.fi_tos != - (pkt->fi_tos & filt->ff_mask.mask_tos)) - return (0); - /* match */ - return (1); -} - -#ifdef INET6 -static int -apply_filter6(fbmask, filt, pkt) - u_int32_t fbmask; - struct flow_filter6 *filt; - struct flowinfo_in6 *pkt; -{ - int i; - - if (filt->ff_flow6.fi6_family != AF_INET6) - return (0); - if ((fbmask & FIMB6_FLABEL) && - filt->ff_flow6.fi6_flowlabel != pkt->fi6_flowlabel) - return (0); - if ((fbmask & FIMB6_PROTO) && - filt->ff_flow6.fi6_proto != pkt->fi6_proto) - return (0); - if ((fbmask & FIMB6_SPORT) && - filt->ff_flow6.fi6_sport != pkt->fi6_sport) - return (0); - if ((fbmask & FIMB6_DPORT) && - filt->ff_flow6.fi6_dport != pkt->fi6_dport) - return (0); - if (fbmask & FIMB6_SADDR) { - for (i = 0; i < 4; i++) - if (filt->ff_flow6.fi6_src.s6_addr32[i] != - (pkt->fi6_src.s6_addr32[i] & - filt->ff_mask6.mask6_src.s6_addr32[i])) - return (0); - } - if (fbmask & FIMB6_DADDR) { - for (i = 0; i < 4; i++) - if (filt->ff_flow6.fi6_dst.s6_addr32[i] != - (pkt->fi6_dst.s6_addr32[i] & - filt->ff_mask6.mask6_dst.s6_addr32[i])) - return (0); - } - if ((fbmask & FIMB6_TCLASS) && - filt->ff_flow6.fi6_tclass != - (pkt->fi6_tclass & filt->ff_mask6.mask6_tclass)) - return (0); - if ((fbmask & FIMB6_GPI) && - filt->ff_flow6.fi6_gpi != pkt->fi6_gpi) - return (0); - /* match */ - return (1); -} -#endif /* INET6 */ - -/* - * filter handle: - * bit 20-28: index to the filter hash table - * bit 0-19: unique id in the hash bucket. - */ -static u_long -get_filt_handle(classifier, i) - struct acc_classifier *classifier; - int i; -{ - static u_long handle_number = 1; - u_long handle; - struct acc_filter *afp; - - while (1) { - handle = handle_number++ & 0x000fffff; - - if (LIST_EMPTY(&classifier->acc_filters[i])) - break; - - LIST_FOREACH(afp, &classifier->acc_filters[i], f_chain) - if ((afp->f_handle & 0x000fffff) == handle) - break; - if (afp == NULL) - break; - /* this handle is already used, try again */ - } - - return ((i << 20) | handle); -} - -/* convert filter handle to filter pointer */ -static struct acc_filter * -filth_to_filtp(classifier, handle) - struct acc_classifier *classifier; - u_long handle; -{ - struct acc_filter *afp; - int i; - - i = ACC_GET_HINDEX(handle); - - LIST_FOREACH(afp, &classifier->acc_filters[i], f_chain) - if (afp->f_handle == handle) - return (afp); - - return (NULL); -} - -/* create flowinfo bitmask */ -static u_int32_t -filt2fibmask(filt) - struct flow_filter *filt; -{ - u_int32_t mask = 0; -#ifdef INET6 - struct flow_filter6 *filt6; -#endif - - switch (filt->ff_flow.fi_family) { - case AF_INET: - if (filt->ff_flow.fi_proto != 0) - mask |= FIMB4_PROTO; - if (filt->ff_flow.fi_tos != 0) - mask |= FIMB4_TOS; - if (filt->ff_flow.fi_dst.s_addr != 0) - mask |= FIMB4_DADDR; - if (filt->ff_flow.fi_src.s_addr != 0) - mask |= FIMB4_SADDR; - if (filt->ff_flow.fi_sport != 0) - mask |= FIMB4_SPORT; - if (filt->ff_flow.fi_dport != 0) - mask |= FIMB4_DPORT; - if (filt->ff_flow.fi_gpi != 0) - mask |= FIMB4_GPI; - break; -#ifdef INET6 - case AF_INET6: - filt6 = (struct flow_filter6 *)filt; - - if (filt6->ff_flow6.fi6_proto != 0) - mask |= FIMB6_PROTO; - if (filt6->ff_flow6.fi6_tclass != 0) - mask |= FIMB6_TCLASS; - if (!IN6_IS_ADDR_UNSPECIFIED(&filt6->ff_flow6.fi6_dst)) - mask |= FIMB6_DADDR; - if (!IN6_IS_ADDR_UNSPECIFIED(&filt6->ff_flow6.fi6_src)) - mask |= FIMB6_SADDR; - if (filt6->ff_flow6.fi6_sport != 0) - mask |= FIMB6_SPORT; - if (filt6->ff_flow6.fi6_dport != 0) - mask |= FIMB6_DPORT; - if (filt6->ff_flow6.fi6_gpi != 0) - mask |= FIMB6_GPI; - if (filt6->ff_flow6.fi6_flowlabel != 0) - mask |= FIMB6_FLABEL; - break; -#endif /* INET6 */ - } - return (mask); -} - - -/* - * helper functions to handle IPv4 fragments. - * currently only in-sequence fragments are handled. - * - fragment info is cached in a LRU list. - * - when a first fragment is found, cache its flow info. - * - when a non-first fragment is found, lookup the cache. - */ - -struct ip4_frag { - TAILQ_ENTRY(ip4_frag) ip4f_chain; - char ip4f_valid; - u_short ip4f_id; - struct flowinfo_in ip4f_info; -}; - -static TAILQ_HEAD(ip4f_list, ip4_frag) ip4f_list; /* IPv4 fragment cache */ - -#define IP4F_TABSIZE 16 /* IPv4 fragment cache size */ - - -static void -ip4f_cache(ip, fin) - struct ip *ip; - struct flowinfo_in *fin; -{ - struct ip4_frag *fp; - - if (TAILQ_EMPTY(&ip4f_list)) { - /* first time call, allocate fragment cache entries. */ - if (ip4f_init() < 0) - /* allocation failed! */ - return; - } - - fp = ip4f_alloc(); - fp->ip4f_id = ip->ip_id; - fp->ip4f_info.fi_proto = ip->ip_p; - fp->ip4f_info.fi_src.s_addr = ip->ip_src.s_addr; - fp->ip4f_info.fi_dst.s_addr = ip->ip_dst.s_addr; - - /* save port numbers */ - fp->ip4f_info.fi_sport = fin->fi_sport; - fp->ip4f_info.fi_dport = fin->fi_dport; - fp->ip4f_info.fi_gpi = fin->fi_gpi; -} - -static int -ip4f_lookup(ip, fin) - struct ip *ip; - struct flowinfo_in *fin; -{ - struct ip4_frag *fp; - - for (fp = TAILQ_FIRST(&ip4f_list); fp != NULL && fp->ip4f_valid; - fp = TAILQ_NEXT(fp, ip4f_chain)) - if (ip->ip_id == fp->ip4f_id && - ip->ip_src.s_addr == fp->ip4f_info.fi_src.s_addr && - ip->ip_dst.s_addr == fp->ip4f_info.fi_dst.s_addr && - ip->ip_p == fp->ip4f_info.fi_proto) { - - /* found the matching entry */ - fin->fi_sport = fp->ip4f_info.fi_sport; - fin->fi_dport = fp->ip4f_info.fi_dport; - fin->fi_gpi = fp->ip4f_info.fi_gpi; - - if ((ntohs(ip->ip_off) & IP_MF) == 0) - /* this is the last fragment, - release the entry. */ - ip4f_free(fp); - - return (1); - } - - /* no matching entry found */ - return (0); -} - -static int -ip4f_init(void) -{ - struct ip4_frag *fp; - int i; - - TAILQ_INIT(&ip4f_list); - for (i=0; i<IP4F_TABSIZE; i++) { - MALLOC(fp, struct ip4_frag *, sizeof(struct ip4_frag), - M_DEVBUF, M_NOWAIT); - if (fp == NULL) { - printf("ip4f_init: can't alloc %dth entry!\n", i); - if (i == 0) - return (-1); - return (0); - } - fp->ip4f_valid = 0; - TAILQ_INSERT_TAIL(&ip4f_list, fp, ip4f_chain); + default: + error = ENXIO; } - return (0); -} - -static struct ip4_frag * -ip4f_alloc(void) -{ - struct ip4_frag *fp; - - /* reclaim an entry at the tail, put it at the head */ - fp = TAILQ_LAST(&ip4f_list, ip4f_list); - TAILQ_REMOVE(&ip4f_list, fp, ip4f_chain); - fp->ip4f_valid = 1; - TAILQ_INSERT_HEAD(&ip4f_list, fp, ip4f_chain); - return (fp); -} -static void -ip4f_free(fp) - struct ip4_frag *fp; -{ - TAILQ_REMOVE(&ip4f_list, fp, ip4f_chain); - fp->ip4f_valid = 0; - TAILQ_INSERT_TAIL(&ip4f_list, fp, ip4f_chain); + return (error); } - /* * read and write diffserv field in IPv4 or IPv6 header */ diff --git a/sys/altq/altq_var.h b/sys/altq/altq_var.h index 7f6610acd44..4a7cc34adf5 100644 --- a/sys/altq/altq_var.h +++ b/sys/altq/altq_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: altq_var.h,v 1.9 2002/11/29 07:51:54 kjc Exp $ */ +/* $OpenBSD: altq_var.h,v 1.10 2002/12/16 09:18:06 kjc Exp $ */ /* $KAME: altq_var.h,v 1.8 2001/02/09 09:44:41 kjc Exp $ */ /* @@ -43,67 +43,6 @@ #endif /* - * filter structure for altq common classifier - */ -struct acc_filter { - LIST_ENTRY(acc_filter) f_chain; - void *f_class; /* pointer to the class */ - u_long f_handle; /* filter id */ - u_int32_t f_fbmask; /* filter bitmask */ - struct flow_filter f_filter; /* filter value */ -}; - -/* - * XXX ACC_FILTER_TABLESIZE can't be larger than 2048 unless we fix - * the handle assignment. - */ -#define ACC_FILTER_TABLESIZE (256+1) -#define ACC_FILTER_MASK (ACC_FILTER_TABLESIZE - 2) -#define ACC_WILDCARD_INDEX (ACC_FILTER_TABLESIZE - 1) -#ifdef __GNUC__ -#define ACC_GET_HASH_INDEX(addr) \ - ({int x = (addr) + ((addr) >> 16); (x + (x >> 8)) & ACC_FILTER_MASK;}) -#else -#define ACC_GET_HASH_INDEX(addr) \ - (((addr) + ((addr) >> 8) + ((addr) >> 16) + ((addr) >> 24)) \ - & ACC_FILTER_MASK) -#endif -#define ACC_GET_HINDEX(handle) ((handle) >> 20) - -struct acc_classifier { - u_int32_t acc_fbmask; - LIST_HEAD(filt, acc_filter) acc_filters[ACC_FILTER_TABLESIZE]; -}; - -/* - * flowinfo mask bits used by classifier - */ -/* for ipv4 */ -#define FIMB4_PROTO 0x0001 -#define FIMB4_TOS 0x0002 -#define FIMB4_DADDR 0x0004 -#define FIMB4_SADDR 0x0008 -#define FIMB4_DPORT 0x0010 -#define FIMB4_SPORT 0x0020 -#define FIMB4_GPI 0x0040 -#define FIMB4_ALL 0x007f -/* for ipv6 */ -#define FIMB6_PROTO 0x0100 -#define FIMB6_TCLASS 0x0200 -#define FIMB6_DADDR 0x0400 -#define FIMB6_SADDR 0x0800 -#define FIMB6_DPORT 0x1000 -#define FIMB6_SPORT 0x2000 -#define FIMB6_GPI 0x4000 -#define FIMB6_FLABEL 0x8000 -#define FIMB6_ALL 0xff00 - -#define FIMB_ALL (FIMB4_ALL|FIMB6_ALL) - -#define FIMB4_PORTS (FIMB4_DPORT|FIMB4_SPORT|FIMB4_GPI) -#define FIMB6_PORTS (FIMB6_DPORT|FIMB6_SPORT|FIMB6_GPI) - -/* * machine dependent clock * a 64bit high resolution time counter. */ @@ -129,42 +68,8 @@ extern u_int64_t read_machclk(void); /* * misc stuff for compatibility */ -/* ioctl cmd type */ -#if defined(__FreeBSD__) && (__FreeBSD__ < 3) -typedef int ioctlcmd_t; -#else -typedef u_long ioctlcmd_t; -#endif - -/* - * queue macros: - * the interface of TAILQ_LAST macro changed after the introduction - * of softupdate. redefine it here to make it work with pre-2.2.7. - */ -#undef TAILQ_LAST -#define TAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) - -#ifndef TAILQ_EMPTY -#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) -#endif -#ifndef TAILQ_FOREACH -#define TAILQ_FOREACH(var, head, field) \ - for (var = TAILQ_FIRST(head); var; var = TAILQ_NEXT(var, field)) -#endif /* macro for timeout/untimeout */ -#if (__FreeBSD_version > 300000) || defined(__NetBSD__) -/* use callout */ -#include <sys/callout.h> - -#define CALLOUT_INIT(c) callout_init((c)) -#define CALLOUT_RESET(c,t,f,a) callout_reset((c),(t),(f),(a)) -#define CALLOUT_STOP(c) callout_stop((c)) -#ifndef CALLOUT_INITIALIZER -#define CALLOUT_INITIALIZER { { { NULL } }, 0, NULL, NULL, 0 } -#endif -#elif defined(__OpenBSD__) #include <sys/timeout.h> /* callout structure as a wrapper of struct timeout */ struct callout { @@ -176,41 +81,17 @@ struct callout { timeout_add(&(c)->c_to, (t)); } while (0) #define CALLOUT_STOP(c) timeout_del(&(c)->c_to) #define CALLOUT_INITIALIZER { { { NULL }, NULL, NULL, 0, 0 } } -#else -/* use old-style timeout/untimeout */ -/* dummy callout structure */ -struct callout { - void *c_arg; /* function argument */ - void (*c_func)(void *); /* function to call */ -}; -#define CALLOUT_INIT(c) do { bzero((c), sizeof(*(c))); } while (0) -#define CALLOUT_RESET(c,t,f,a) do { (c)->c_arg = (a); \ - (c)->c_func = (f); \ - timeout((f),(a),(t)); } while (0) -#define CALLOUT_STOP(c) untimeout((c)->c_func,(c)->c_arg) -#define CALLOUT_INITIALIZER { NULL, NULL } -#endif -#if !defined(__FreeBSD__) + typedef void (timeout_t)(void *); -#endif #define m_pktlen(m) ((m)->m_pkthdr.len) -/* define a macro to check pf/altq until the transition is complete */ -#define PFALTQ_IS_ACTIVE() (!TAILQ_EMPTY(pf_altqs_active)) - extern int pfaltq_running; -struct ifnet; struct mbuf; struct flowinfo; +struct ifnet; struct mbuf;; struct pf_altq; struct pf_qstats; void *altq_lookup(char *, int); -int altq_extractflow(struct mbuf *, int, struct flowinfo *, u_int32_t); -int acc_add_filter(struct acc_classifier *, struct flow_filter *, - void *, u_long *); -int acc_delete_filter(struct acc_classifier *, u_long); -int acc_discard_filters(struct acc_classifier *, void *, int); -void *acc_classify(void *, struct mbuf *, int); u_int8_t read_dsfield(struct mbuf *, struct altq_pktattr *); void write_dsfield(struct mbuf *, struct altq_pktattr *, u_int8_t); void altq_assert(const char *, int, const char *); @@ -231,5 +112,19 @@ int cbq_add_queue(struct pf_altq *); int cbq_remove_queue(struct pf_altq *); int cbq_getqstats(struct pf_altq *, void *, int *); +int priq_pfattach(struct pf_altq *); +int priq_add_altq(struct pf_altq *); +int priq_remove_altq(struct pf_altq *); +int priq_add_queue(struct pf_altq *); +int priq_remove_queue(struct pf_altq *); +int priq_getqstats(struct pf_altq *, void *, int *); + +int hfsc_pfattach(struct pf_altq *); +int hfsc_add_altq(struct pf_altq *); +int hfsc_remove_altq(struct pf_altq *); +int hfsc_add_queue(struct pf_altq *); +int hfsc_remove_queue(struct pf_altq *); +int hfsc_getqstats(struct pf_altq *, void *, int *); + #endif /* _KERNEL */ #endif /* _ALTQ_ALTQ_VAR_H_ */ diff --git a/sys/altq/altq_wfq.c b/sys/altq/altq_wfq.c deleted file mode 100644 index afc9ed91108..00000000000 --- a/sys/altq/altq_wfq.c +++ /dev/null @@ -1,739 +0,0 @@ -/* $OpenBSD: altq_wfq.c,v 1.4 2002/11/26 01:03:34 henning Exp $ */ -/* $KAME: altq_wfq.c,v 1.7 2000/12/14 08:12:46 thorpej Exp $ */ - -/* - * Copyright (C) 1997-2000 - * Sony Computer Science Laboratories Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* - * March 27, 1997. Written by Hiroshi Kyusojin of Keio University - * (kyu@mt.cs.keio.ac.jp). - */ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/malloc.h> -#include <sys/mbuf.h> -#include <sys/uio.h> -#include <sys/socket.h> -#include <sys/systm.h> -#include <sys/proc.h> -#include <sys/errno.h> -#include <sys/time.h> -#include <sys/kernel.h> - -#include <net/if.h> -#include <net/if_types.h> -#include <netinet/in.h> - -#include <altq/altq.h> -#include <altq/altq_conf.h> -#include <altq/altq_wfq.h> - -/* -#define WFQ_DEBUG -*/ - -static int wfq_setenable(struct wfq_interface *, int); -static int wfq_ifattach(struct wfq_interface *); -static int wfq_ifdetach(struct wfq_interface *); -static int wfq_ifenqueue(struct ifaltq *, struct mbuf *, - struct altq_pktattr *); -static u_long wfq_hash(struct flowinfo *, int); -static __inline u_long wfq_hashbydstaddr(struct flowinfo *, int); -static __inline u_long wfq_hashbysrcport(struct flowinfo *, int); -static wfq *wfq_maxqueue(wfq_state_t *); -static struct mbuf *wfq_ifdequeue(struct ifaltq *, int); -static int wfq_getqid(struct wfq_getqid *); -static int wfq_setweight(struct wfq_setweight *); -static int wfq_getstats(struct wfq_getstats *); -static int wfq_config(struct wfq_conf *); -static int wfq_request(struct ifaltq *, int, void *); -static int wfq_flush(struct ifaltq *); -static void *wfq_classify(void *, struct mbuf *, int); - -/* global value : pointer to wfq queue list */ -static wfq_state_t *wfq_list = NULL; - -static int -wfq_setenable(ifacep, flag) - struct wfq_interface *ifacep; - int flag; -{ - wfq_state_t *wfqp; - int error = 0; - - if ((wfqp = altq_lookup(ifacep->wfq_ifacename, ALTQT_WFQ)) == NULL) - return (EBADF); - - switch(flag){ - case ENABLE: - error = altq_enable(wfqp->ifq); - break; - case DISABLE: - error = altq_disable(wfqp->ifq); - break; - } - return error; -} - - -static int -wfq_ifattach(ifacep) - struct wfq_interface *ifacep; -{ - int error = 0, i; - struct ifnet *ifp; - wfq_state_t *new_wfqp; - wfq *queue; - - if ((ifp = ifunit(ifacep->wfq_ifacename)) == NULL) { -#ifdef WFQ_DEBUG - printf("wfq_ifattach()...no ifp found\n"); -#endif - return (ENXIO); - } - - if (!ALTQ_IS_READY(&ifp->if_snd)) { -#ifdef WFQ_DEBUG - printf("wfq_ifattach()...altq is not ready\n"); -#endif - return (ENXIO); - } - - /* allocate and initialize wfq_state_t */ - MALLOC(new_wfqp, wfq_state_t *, sizeof(wfq_state_t), - M_DEVBUF, M_WAITOK); - if (new_wfqp == NULL) - return (ENOMEM); - bzero(new_wfqp, sizeof(wfq_state_t)); - MALLOC(queue, wfq *, sizeof(wfq) * DEFAULT_QSIZE, - M_DEVBUF, M_WAITOK); - if (queue == NULL) { - FREE(new_wfqp, M_DEVBUF); - return (ENOMEM); - } - bzero(queue, sizeof(wfq) * DEFAULT_QSIZE); - - /* keep the ifq */ - new_wfqp->ifq = &ifp->if_snd; - new_wfqp->nums = DEFAULT_QSIZE; - new_wfqp->hwm = HWM; - new_wfqp->bytes = 0; - new_wfqp->rrp = NULL; - new_wfqp->queue = queue; - new_wfqp->hash_func = wfq_hashbydstaddr; - new_wfqp->fbmask = FIMB4_DADDR; - - for (i = 0; i < new_wfqp->nums; i++, queue++) { - queue->next = queue->prev = NULL; - queue->head = queue->tail = NULL; - queue->bytes = queue->quota = 0; - queue->weight = 100; - } - - /* - * set WFQ to this ifnet structure. - */ - if ((error = altq_attach(&ifp->if_snd, ALTQT_WFQ, new_wfqp, - wfq_ifenqueue, wfq_ifdequeue, wfq_request, - new_wfqp, wfq_classify)) != 0) { - FREE(queue, M_DEVBUF); - FREE(new_wfqp, M_DEVBUF); - return (error); - } - - new_wfqp->next = wfq_list; - wfq_list = new_wfqp; - - return (error); -} - - -static int -wfq_ifdetach(ifacep) - struct wfq_interface *ifacep; -{ - int error = 0; - wfq_state_t *wfqp; - - if ((wfqp = altq_lookup(ifacep->wfq_ifacename, ALTQT_WFQ)) == NULL) - return (EBADF); - - /* free queued mbuf */ - wfq_flush(wfqp->ifq); - - /* remove WFQ from the ifnet structure. */ - (void)altq_disable(wfqp->ifq); - (void)altq_detach(wfqp->ifq); - - /* remove from the wfqstate list */ - if (wfq_list == wfqp) - wfq_list = wfqp->next; - else { - wfq_state_t *wp = wfq_list; - do { - if (wp->next == wfqp) { - wp->next = wfqp->next; - break; - } - } while ((wp = wp->next) != NULL); - } - - /* deallocate wfq_state_t */ - FREE(wfqp->queue, M_DEVBUF); - FREE(wfqp, M_DEVBUF); - return (error); -} - -static int -wfq_request(ifq, req, arg) - struct ifaltq *ifq; - int req; - void *arg; -{ - wfq_state_t *wfqp = (wfq_state_t *)ifq->altq_disc; - - switch (req) { - case ALTRQ_PURGE: - wfq_flush(wfqp->ifq); - break; - } - return (0); -} - - -static int -wfq_flush(ifq) - struct ifaltq *ifq; -{ - struct mbuf *mp; - - while ((mp = wfq_ifdequeue(ifq, ALTDQ_REMOVE)) != NULL) - m_freem(mp); - if (ALTQ_IS_ENABLED(ifq)) - ifq->ifq_len = 0; - return 0; -} - -static void * -wfq_classify(clfier, m, af) - void *clfier; - struct mbuf *m; - int af; -{ - wfq_state_t *wfqp = (wfq_state_t *)clfier; - struct flowinfo flow; - - altq_extractflow(m, af, &flow, wfqp->fbmask); - return (&wfqp->queue[(*wfqp->hash_func)(&flow, wfqp->nums)]); -} - -static int -wfq_ifenqueue(ifq, mp, pktattr) - struct ifaltq *ifq; - struct mbuf *mp; - struct altq_pktattr *pktattr; -{ - wfq_state_t *wfqp; - wfq *queue; - int byte, error = 0; - - wfqp = (wfq_state_t *)ifq->altq_disc; - mp->m_nextpkt = NULL; - - /* grab a queue selected by classifier */ - if (pktattr == NULL || (queue = pktattr->pattr_class) == NULL) - queue = &wfqp->queue[0]; - - if (queue->tail == NULL) - queue->head = mp; - else - queue->tail->m_nextpkt = mp; - queue->tail = mp; - byte = mp->m_pkthdr.len; - queue->bytes += byte; - wfqp->bytes += byte; - ifq->ifq_len++; - - if (queue->next == NULL) { - /* this queue gets active. add the queue to the active list */ - if (wfqp->rrp == NULL){ - /* no queue in the active list */ - queue->next = queue->prev = queue; - wfqp->rrp = queue; - WFQ_ADDQUOTA(queue); - } else { - /* insert the queue at the tail of the active list */ - queue->prev = wfqp->rrp->prev; - wfqp->rrp->prev->next = queue; - wfqp->rrp->prev = queue; - queue->next = wfqp->rrp; - queue->quota = 0; - } - } - - /* check overflow. if the total size exceeds the high water mark, - drop packets from the longest queue. */ - while (wfqp->bytes > wfqp->hwm) { - wfq *drop_queue = wfq_maxqueue(wfqp); - - /* drop the packet at the head. */ - mp = drop_queue->head; - if ((drop_queue->head = mp->m_nextpkt) == NULL) - drop_queue->tail = NULL; - mp->m_nextpkt = NULL; - byte = mp->m_pkthdr.len; - drop_queue->bytes -= byte; - PKTCNTR_ADD(&drop_queue->drop_cnt, byte); - wfqp->bytes -= byte; - m_freem(mp); - ifq->ifq_len--; - if(drop_queue == queue) - /* the queue for this flow is selected to drop */ - error = ENOBUFS; - } - return error; -} - - -static u_long wfq_hash(flow, n) - struct flowinfo *flow; - int n; -{ - u_long val = 0; - - if (flow != NULL) { - if (flow->fi_family == AF_INET) { - struct flowinfo_in *fp = (struct flowinfo_in *)flow; - u_long val2; - - val = fp->fi_dst.s_addr ^ fp->fi_src.s_addr; - val = val ^ (val >> 8) ^ (val >> 16) ^ (val >> 24); - val2 = fp->fi_dport ^ fp->fi_sport ^ fp->fi_proto; - val2 = val2 ^ (val2 >> 8); - val = val ^ val2; - } -#ifdef INET6 - else if (flow->fi_family == AF_INET6) { - struct flowinfo_in6 *fp6 = (struct flowinfo_in6 *)flow; - - val = ntohl(fp6->fi6_flowlabel); - } -#endif - } - - return (val % n); -} - - -static __inline u_long wfq_hashbydstaddr(flow, n) - struct flowinfo *flow; - int n; -{ - u_long val = 0; - - if (flow != NULL) { - if (flow->fi_family == AF_INET) { - struct flowinfo_in *fp = (struct flowinfo_in *)flow; - - val = fp->fi_dst.s_addr; - val = val ^ (val >> 8) ^ (val >> 16) ^ (val >> 24); - } -#ifdef INET6 - else if (flow->fi_family == AF_INET6) { - struct flowinfo_in6 *fp6 = (struct flowinfo_in6 *)flow; - - val = ntohl(fp6->fi6_flowlabel); - } -#endif - } - - return (val % n); -} - -static __inline u_long wfq_hashbysrcport(flow, n) - struct flowinfo *flow; - int n; -{ - u_long val = 0; - - if (flow != NULL) { - if (flow->fi_family == AF_INET) { - struct flowinfo_in *fp = (struct flowinfo_in *)flow; - - val = fp->fi_sport; - } -#ifdef INET6 - else if (flow->fi_family == AF_INET6) { - struct flowinfo_in6 *fp6 = (struct flowinfo_in6 *)flow; - - val = fp6->fi6_sport; - } -#endif - } - val = val ^ (val >> 8); - - return (val % n); -} - -static wfq *wfq_maxqueue(wfqp) - wfq_state_t *wfqp; -{ - int byte, max_byte = 0; - wfq *queue, *max_queue = NULL; - - if((queue = wfqp->rrp) == NULL) - /* never happens */ - return NULL; - do{ - if ((byte = queue->bytes * 100 / queue->weight) > max_byte) { - max_queue = queue; - max_byte = byte; - } - } while ((queue = queue->next) != wfqp->rrp); - - return max_queue; -} - - -static struct mbuf * -wfq_ifdequeue(ifq, op) - struct ifaltq *ifq; - int op; -{ - wfq_state_t *wfqp; - wfq *queue; - struct mbuf *mp; - int byte; - - wfqp = (wfq_state_t *)ifq->altq_disc; - - if ((wfqp->bytes == 0) || ((queue = wfqp->rrp) == NULL)) - /* no packet in the queues */ - return NULL; - - while (1) { - if (queue->quota > 0) { - if (queue->bytes <= 0) { - /* this queue no longer has packet. - remove the queue from the active list. */ - if (queue->next == queue){ - /* no other active queue - -- this case never happens in - this algorithm. */ - queue->next = queue->prev = NULL; - wfqp->rrp = NULL; - return NULL; - } else { - queue->prev->next = queue->next; - queue->next->prev = queue->prev; - /* the round-robin pointer points - to this queue, advance the rrp */ - wfqp->rrp = queue->next; - queue->next = queue->prev = NULL; - queue = wfqp->rrp; - WFQ_ADDQUOTA(queue); - continue; - } - } - - /* dequeue a packet from this queue */ - mp = queue->head; - if (op == ALTDQ_REMOVE) { - if((queue->head = mp->m_nextpkt) == NULL) - queue->tail = NULL; - byte = mp->m_pkthdr.len; - mp->m_nextpkt = NULL; - queue->quota -= byte; - queue->bytes -= byte; - PKTCNTR_ADD(&queue->xmit_cnt, byte); - wfqp->bytes -= byte; - if (ALTQ_IS_ENABLED(ifq)) - ifq->ifq_len--; - } - return mp; - - /* if the queue gets empty by this dequeueing, - the queue will be removed from the active list - at the next round */ - } - - /* advance the round-robin pointer */ - queue = wfqp->rrp = queue->next; - WFQ_ADDQUOTA(queue); - } -} - -static int -wfq_getqid(gqidp) - struct wfq_getqid *gqidp; -{ - wfq_state_t *wfqp; - - if ((wfqp = altq_lookup(gqidp->iface.wfq_ifacename, ALTQT_WFQ)) - == NULL) - return (EBADF); - - gqidp->qid = (*wfqp->hash_func)(&gqidp->flow, wfqp->nums); - return 0; -} - -static int -wfq_setweight(swp) - struct wfq_setweight *swp; -{ - wfq_state_t *wfqp; - wfq *queue; - int old; - - if (swp->weight < 0) { - printf("set weight in natural number\n"); - return (EINVAL); - } - - if ((wfqp = altq_lookup(swp->iface.wfq_ifacename, ALTQT_WFQ)) == NULL) - return (EBADF); - - queue = &wfqp->queue[swp->qid]; - old = queue->weight; - queue->weight = swp->weight; - swp->weight = old; - return 0; -} - - -static int -wfq_getstats(gsp) - struct wfq_getstats *gsp; -{ - wfq_state_t *wfqp; - wfq *queue; - queue_stats *stats; - - if ((wfqp = altq_lookup(gsp->iface.wfq_ifacename, ALTQT_WFQ)) == NULL) - return (EBADF); - - if (gsp->qid >= wfqp->nums) - return (EINVAL); - - queue = &wfqp->queue[gsp->qid]; - stats = &gsp->stats; - - stats->bytes = queue->bytes; - stats->weight = queue->weight; - stats->xmit_cnt = queue->xmit_cnt; - stats->drop_cnt = queue->drop_cnt; - - return 0; -} - - -static int -wfq_config(cf) - struct wfq_conf *cf; -{ - wfq_state_t *wfqp; - wfq *queue; - int i, error = 0; - - if ((wfqp = altq_lookup(cf->iface.wfq_ifacename, ALTQT_WFQ)) == NULL) - return (EBADF); - - if(cf->nqueues <= 0 || MAX_QSIZE < cf->nqueues) - cf->nqueues = DEFAULT_QSIZE; - - if (cf->nqueues != wfqp->nums) { - /* free queued mbuf */ - wfq_flush(wfqp->ifq); - FREE(wfqp->queue, M_DEVBUF); - - MALLOC(queue, wfq *, sizeof(wfq) * cf->nqueues, - M_DEVBUF, M_WAITOK); - if (queue == NULL) - return (ENOMEM); - bzero(queue, sizeof(wfq) * cf->nqueues); - - wfqp->nums = cf->nqueues; - wfqp->bytes = 0; - wfqp->rrp = NULL; - wfqp->queue = queue; - for (i = 0; i < wfqp->nums; i++, queue++) { - queue->next = queue->prev = NULL; - queue->head = queue->tail = NULL; - queue->bytes = queue->quota = 0; - queue->weight = 100; - } - } - - if (cf->qlimit != 0) - wfqp->hwm = cf->qlimit; - - switch (cf->hash_policy) { - case WFQ_HASH_DSTADDR: - wfqp->hash_func = wfq_hashbydstaddr; - wfqp->fbmask = FIMB4_DADDR; -#ifdef INET6 - wfqp->fbmask |= FIMB6_FLABEL; /* use flowlabel for ipv6 */ -#endif - break; - case WFQ_HASH_SRCPORT: - wfqp->hash_func = wfq_hashbysrcport; - wfqp->fbmask = FIMB4_SPORT; -#ifdef INET6 - wfqp->fbmask |= FIMB6_SPORT; -#endif - break; - case WFQ_HASH_FULL: - wfqp->hash_func = wfq_hash; - wfqp->fbmask = FIMB4_ALL; -#ifdef INET6 - wfqp->fbmask |= FIMB6_FLABEL; /* use flowlabel for ipv6 */ -#endif - break; - default: - error = EINVAL; - break; - } - return error; -} - -/* - * wfq device interface - */ - -altqdev_decl(wfq); - -int -wfqopen(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - return 0; -} - -int -wfqclose(dev, flag, fmt, p) - dev_t dev; - int flag, fmt; - struct proc *p; -{ - struct ifnet *ifp; - struct wfq_interface iface; - wfq_state_t *wfqp; - int s; - - s = splimp(); - while ((wfqp = wfq_list) != NULL) { - ifp = wfqp->ifq->altq_ifp; -#if defined(__NetBSD__) || defined(__OpenBSD__) - sprintf(iface.wfq_ifacename, "%s", ifp->if_xname); -#else - sprintf(iface.wfq_ifacename, "%s%d", - ifp->if_name, ifp->if_unit); -#endif - wfq_ifdetach(&iface); - } - splx(s); - return 0; -} - -int -wfqioctl(dev, cmd, addr, flag, p) - dev_t dev; - ioctlcmd_t cmd; - caddr_t addr; - int flag; - struct proc *p; -{ - int error = 0; - int s; - - /* check cmd for superuser only */ - switch (cmd) { - case WFQ_GET_QID: - case WFQ_GET_STATS: - break; - default: -#if (__FreeBSD_version > 400000) - if ((error = suser(p)) != 0) -#else - if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) -#endif - return (error); - break; - } - - s = splimp(); - switch (cmd) { - - case WFQ_ENABLE: - error = wfq_setenable((struct wfq_interface *)addr, ENABLE); - break; - - case WFQ_DISABLE: - error = wfq_setenable((struct wfq_interface *)addr, DISABLE); - break; - - case WFQ_IF_ATTACH: - error = wfq_ifattach((struct wfq_interface *)addr); - break; - - case WFQ_IF_DETACH: - error = wfq_ifdetach((struct wfq_interface *)addr); - break; - - case WFQ_GET_QID: - error = wfq_getqid((struct wfq_getqid *)addr); - break; - - case WFQ_SET_WEIGHT: - error = wfq_setweight((struct wfq_setweight *)addr); - break; - - case WFQ_GET_STATS: - error = wfq_getstats((struct wfq_getstats *)addr); - break; - - case WFQ_CONFIG: - error = wfq_config((struct wfq_conf *)addr); - break; - - default: - error = EINVAL; - break; - } - splx(s); - return error; -} - -#ifdef KLD_MODULE - -static struct altqsw wfq_sw = - {"wfq", wfqopen, wfqclose, wfqioctl}; - -ALTQ_MODULE(altq_wfq, ALTQT_WFQ, &wfq_sw); - -#endif /* KLD_MODULE */ diff --git a/sys/altq/altq_wfq.h b/sys/altq/altq_wfq.h deleted file mode 100644 index 8c42000e08c..00000000000 --- a/sys/altq/altq_wfq.h +++ /dev/null @@ -1,125 +0,0 @@ -/* $OpenBSD: altq_wfq.h,v 1.2 2002/11/26 01:03:34 henning Exp $ */ -/* $KAME: altq_wfq.h,v 1.5 2000/12/14 08:12:46 thorpej Exp $ */ - -/* - * Copyright (C) 1997-2000 - * Sony Computer Science Laboratories Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* - * March 27, 1997. Written by Hiroshi Kyusojin of Keio University - * (kyu@mt.cs.keio.ac.jp). - */ - -#ifndef _ALTQ_ALTQ_WFQ_H_ -#define _ALTQ_ALTQ_WFQ_H_ - -#include <altq/altq.h> - -#define DEFAULT_QSIZE 256 -#define MAX_QSIZE 2048 - -struct wfq_interface{ - char wfq_ifacename[IFNAMSIZ]; -}; - -struct wfq_getqid{ - struct wfq_interface iface; - struct flowinfo flow; - u_long qid; -}; - -struct wfq_setweight { - struct wfq_interface iface; - int qid; - int weight; -}; - -typedef struct each_queue_stats { - int bytes; /* bytes in this queue */ - int weight; /* weight in percent */ - struct pktcntr xmit_cnt; - struct pktcntr drop_cnt; -} queue_stats; - -struct wfq_getstats { - struct wfq_interface iface; - int qid; - queue_stats stats; -}; - -struct wfq_conf { - struct wfq_interface iface; - int hash_policy; /* hash policy */ - int nqueues; /* number of queues */ - int qlimit; /* queue size in bytes */ -}; - -#define WFQ_HASH_DSTADDR 0 /* hash by dst address */ -#define WFQ_HASH_SRCPORT 1 /* hash by src port */ -#define WFQ_HASH_FULL 2 /* hash by all fields */ - -#define WFQ_IF_ATTACH _IOW('Q', 1, struct wfq_interface) -#define WFQ_IF_DETACH _IOW('Q', 2, struct wfq_interface) -#define WFQ_ENABLE _IOW('Q', 3, struct wfq_interface) -#define WFQ_DISABLE _IOW('Q', 4, struct wfq_interface) -#define WFQ_CONFIG _IOWR('Q', 6, struct wfq_conf) -#define WFQ_GET_STATS _IOWR('Q', 12, struct wfq_getstats) -#define WFQ_GET_QID _IOWR('Q', 30, struct wfq_getqid) -#define WFQ_SET_WEIGHT _IOWR('Q', 31, struct wfq_setweight) - -#ifdef _KERNEL - -#define HWM (64 * 1024) -#define WFQ_QUOTA 512 /* quota bytes to send at a time */ -#define WFQ_ADDQUOTA(q) ((q)->quota += WFQ_QUOTA * (q)->weight / 100) -#define ENABLE 0 -#define DISABLE 1 - -typedef struct weighted_fair_queue{ - struct weighted_fair_queue *next, *prev; - struct mbuf *head, *tail; - int bytes; /* bytes in this queue */ - int quota; /* bytes sent in this round */ - int weight; /* weight in percent */ - - struct pktcntr xmit_cnt; - struct pktcntr drop_cnt; -} wfq; - - -typedef struct wfqstate { - struct wfqstate *next; /* for wfqstate list */ - struct ifaltq *ifq; - int nums; /* number of queues */ - int hwm; /* high water mark */ - int bytes; /* total bytes in all the queues */ - wfq *rrp; /* round robin pointer */ - wfq *queue; /* pointer to queue list */ - u_long (*hash_func)(struct flowinfo *, int); - u_int32_t fbmask; /* filter bitmask */ -} wfq_state_t; - -#endif /* _KERNEL */ - -#endif /* _ALTQ_ALTQ_WFQ_H */ diff --git a/sys/altq/altqconf.h b/sys/altq/altqconf.h deleted file mode 100644 index 5666ffbe797..00000000000 --- a/sys/altq/altqconf.h +++ /dev/null @@ -1,16 +0,0 @@ -/* $OpenBSD: altqconf.h,v 1.1 2001/06/27 05:28:36 kjc Exp $ */ -/* $NetBSD: altqconf.h,v 1.2 2001/05/30 11:57:16 mrg Exp $ */ - -#ifdef ALTQ -#define NALTQ 1 -#else -#define NALTQ 0 -#endif - -cdev_decl(altq); - -#define cdev_altq_init(c,n) { \ - dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \ - (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \ - (dev_type_stop((*))) enodev, 0, (dev_type_select((*))) enodev, \ - (dev_type_mmap((*))) enodev } |