mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-02 08:42:48 +00:00
Import parts of the ALTQ framework from latest KAME snapshot (which is up to
HEAD at this point). This will not exactly live in a vendor branch, but have the vendor backing to make it easier to exchange diffs. This will be followed by a diff which takes most of the .c files off the vendor branch in order to: - add locking - disable ALTQ3_COMPAT code (which is outdated and "un-lockable") There is work in progress to refine the configuration API. Import this "as is" now to have more exposure time before 5-STABLE. This is only the import, it will be some more days until you will actually be able to compile ALTQ support into your kernel so don't hold your breath. HEADUPs will be posted on current@ and net@ before this is actually enabled. No-objection: re(scottl), core(rwatson)
This commit is contained in:
commit
a2f5f9a397
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor-sys/altq/dist/; revision=130365 svn path=/vendor-sys/altq/20040607/; revision=130367; tag=vendor/altq/20040607
203
sys/contrib/altq/altq/altq.h
Normal file
203
sys/contrib/altq/altq/altq.h
Normal file
@ -0,0 +1,203 @@
|
||||
/* $KAME: altq.h,v 1.10 2003/07/10 12:07:47 kjc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1998-2003
|
||||
* 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_H_
|
||||
#define _ALTQ_ALTQ_H_
|
||||
|
||||
#if 1
|
||||
/*
|
||||
* allow altq-3 (altqd(8) and /dev/altq) to coexist with the new pf-based altq.
|
||||
* altq3 is mainly for research experiments. pf-based altq is for daily use.
|
||||
*/
|
||||
#define ALTQ3_COMPAT /* for compatibility with altq-3 */
|
||||
#define ALTQ3_CLFIER_COMPAT /* for compatibility with altq-3 classifier */
|
||||
#endif
|
||||
|
||||
#ifdef ALTQ3_COMPAT
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioccom.h>
|
||||
#include <sys/queue.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#ifndef IFNAMSIZ
|
||||
#define IFNAMSIZ 16
|
||||
#endif
|
||||
#endif /* ALTQ3_COMPAT */
|
||||
|
||||
/* altq discipline type */
|
||||
#define ALTQT_NONE 0 /* reserved */
|
||||
#define ALTQT_CBQ 1 /* cbq */
|
||||
#define ALTQT_WFQ 2 /* wfq */
|
||||
#define ALTQT_AFMAP 3 /* afmap */
|
||||
#define ALTQT_FIFOQ 4 /* fifoq */
|
||||
#define ALTQT_RED 5 /* red */
|
||||
#define ALTQT_RIO 6 /* rio */
|
||||
#define ALTQT_LOCALQ 7 /* local use */
|
||||
#define ALTQT_HFSC 8 /* hfsc */
|
||||
#define ALTQT_CDNR 9 /* traffic conditioner */
|
||||
#define ALTQT_BLUE 10 /* blue */
|
||||
#define ALTQT_PRIQ 11 /* priority queue */
|
||||
#define ALTQT_JOBS 12 /* JoBS */
|
||||
#define ALTQT_MAX 13 /* should be max discipline type + 1 */
|
||||
|
||||
#ifdef ALTQ3_COMPAT
|
||||
struct altqreq {
|
||||
char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */
|
||||
u_long arg; /* request-specific argument */
|
||||
};
|
||||
#endif
|
||||
|
||||
/* simple token backet meter profile */
|
||||
struct tb_profile {
|
||||
u_int rate; /* rate in bit-per-sec */
|
||||
u_int depth; /* depth in bytes */
|
||||
};
|
||||
|
||||
#ifdef ALTQ3_COMPAT
|
||||
struct tbrreq {
|
||||
char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */
|
||||
struct tb_profile tb_prof; /* token bucket profile */
|
||||
};
|
||||
|
||||
#ifdef ALTQ3_CLFIER_COMPAT
|
||||
/*
|
||||
* common network flow info structure
|
||||
*/
|
||||
struct flowinfo {
|
||||
u_char fi_len; /* total length */
|
||||
u_char fi_family; /* address family */
|
||||
u_int8_t fi_data[46]; /* actually longer; address family
|
||||
specific flow info. */
|
||||
};
|
||||
|
||||
/*
|
||||
* flow info structure for internet protocol family.
|
||||
* (currently this is the only protocol family supported)
|
||||
*/
|
||||
struct flowinfo_in {
|
||||
u_char fi_len; /* sizeof(struct flowinfo_in) */
|
||||
u_char fi_family; /* AF_INET */
|
||||
u_int8_t fi_proto; /* IPPROTO_XXX */
|
||||
u_int8_t fi_tos; /* type-of-service */
|
||||
struct in_addr fi_dst; /* dest address */
|
||||
struct in_addr fi_src; /* src address */
|
||||
u_int16_t fi_dport; /* dest port */
|
||||
u_int16_t fi_sport; /* src port */
|
||||
u_int32_t fi_gpi; /* generalized port id for ipsec */
|
||||
u_int8_t _pad[28]; /* make the size equal to
|
||||
flowinfo_in6 */
|
||||
};
|
||||
|
||||
#ifdef SIN6_LEN
|
||||
struct flowinfo_in6 {
|
||||
u_char fi6_len; /* sizeof(struct flowinfo_in6) */
|
||||
u_char fi6_family; /* AF_INET6 */
|
||||
u_int8_t fi6_proto; /* IPPROTO_XXX */
|
||||
u_int8_t fi6_tclass; /* traffic class */
|
||||
u_int32_t fi6_flowlabel; /* ipv6 flowlabel */
|
||||
u_int16_t fi6_dport; /* dest port */
|
||||
u_int16_t fi6_sport; /* src port */
|
||||
u_int32_t fi6_gpi; /* generalized port id */
|
||||
struct in6_addr fi6_dst; /* dest address */
|
||||
struct in6_addr fi6_src; /* src address */
|
||||
};
|
||||
#endif /* INET6 */
|
||||
|
||||
/*
|
||||
* flow filters for AF_INET and AF_INET6
|
||||
*/
|
||||
struct flow_filter {
|
||||
int ff_ruleno;
|
||||
struct flowinfo_in ff_flow;
|
||||
struct {
|
||||
struct in_addr mask_dst;
|
||||
struct in_addr mask_src;
|
||||
u_int8_t mask_tos;
|
||||
u_int8_t _pad[3];
|
||||
} ff_mask;
|
||||
u_int8_t _pad2[24]; /* make the size equal to flow_filter6 */
|
||||
};
|
||||
|
||||
#ifdef SIN6_LEN
|
||||
struct flow_filter6 {
|
||||
int ff_ruleno;
|
||||
struct flowinfo_in6 ff_flow6;
|
||||
struct {
|
||||
struct in6_addr mask6_dst;
|
||||
struct in6_addr mask6_src;
|
||||
u_int8_t mask6_tclass;
|
||||
u_int8_t _pad[3];
|
||||
} ff_mask6;
|
||||
};
|
||||
#endif /* INET6 */
|
||||
#endif /* ALTQ3_CLFIER_COMPAT */
|
||||
#endif /* ALTQ3_COMPAT */
|
||||
|
||||
/*
|
||||
* generic packet counter
|
||||
*/
|
||||
struct pktcntr {
|
||||
u_int64_t packets;
|
||||
u_int64_t bytes;
|
||||
};
|
||||
|
||||
#define PKTCNTR_ADD(cntr, len) \
|
||||
do { (cntr)->packets++; (cntr)->bytes += len; } while (/*CONSTCOND*/ 0)
|
||||
|
||||
#ifdef ALTQ3_COMPAT
|
||||
/*
|
||||
* altq related ioctls
|
||||
*/
|
||||
#define ALTQGTYPE _IOWR('q', 0, struct altqreq) /* get queue type */
|
||||
#if 0
|
||||
/*
|
||||
* these ioctls are currently discipline-specific but could be shared
|
||||
* in the future.
|
||||
*/
|
||||
#define ALTQATTACH _IOW('q', 1, struct altqreq) /* attach discipline */
|
||||
#define ALTQDETACH _IOW('q', 2, struct altqreq) /* detach discipline */
|
||||
#define ALTQENABLE _IOW('q', 3, struct altqreq) /* enable discipline */
|
||||
#define ALTQDISABLE _IOW('q', 4, struct altqreq) /* disable discipline*/
|
||||
#define ALTQCLEAR _IOW('q', 5, struct altqreq) /* (re)initialize */
|
||||
#define ALTQCONFIG _IOWR('q', 6, struct altqreq) /* set config params */
|
||||
#define ALTQADDCLASS _IOWR('q', 7, struct altqreq) /* add a class */
|
||||
#define ALTQMODCLASS _IOWR('q', 8, struct altqreq) /* modify a class */
|
||||
#define ALTQDELCLASS _IOWR('q', 9, struct altqreq) /* delete a class */
|
||||
#define ALTQADDFILTER _IOWR('q', 10, struct altqreq) /* add a filter */
|
||||
#define ALTQDELFILTER _IOWR('q', 11, struct altqreq) /* delete a filter */
|
||||
#define ALTQGETSTATS _IOWR('q', 12, struct altqreq) /* get statistics */
|
||||
#define ALTQGETCNTR _IOWR('q', 13, struct altqreq) /* get a pkt counter */
|
||||
#endif /* 0 */
|
||||
#define ALTQTBRSET _IOW('q', 14, struct tbrreq) /* set tb regulator */
|
||||
#define ALTQTBRGET _IOWR('q', 15, struct tbrreq) /* get tb regulator */
|
||||
#endif /* ALTQ3_COMPAT */
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <altq/altq_var.h>
|
||||
#endif
|
||||
|
||||
#endif /* _ALTQ_ALTQ_H_ */
|
1169
sys/contrib/altq/altq/altq_cbq.c
Normal file
1169
sys/contrib/altq/altq/altq_cbq.c
Normal file
File diff suppressed because it is too large
Load Diff
221
sys/contrib/altq/altq/altq_cbq.h
Normal file
221
sys/contrib/altq/altq/altq_cbq.h
Normal file
@ -0,0 +1,221 @@
|
||||
/* $KAME: altq_cbq.h,v 1.12 2003/10/03 05:05:15 kjc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) Sun Microsystems, Inc. 1993-1998 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 SMCC Technology
|
||||
* Development Group at Sun Microsystems, Inc.
|
||||
*
|
||||
* 4. The name of the Sun Microsystems, Inc nor may not be used to endorse or
|
||||
* promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* SUN MICROSYSTEMS DOES NOT CLAIM MERCHANTABILITY OF THIS SOFTWARE OR THE
|
||||
* SUITABILITY OF THIS SOFTWARE FOR ANY PARTICULAR PURPOSE. The software is
|
||||
* provided "as is" without express or implied warranty of any kind.
|
||||
*
|
||||
* These notices must be retained in any copies of any part of this software.
|
||||
*/
|
||||
|
||||
#ifndef _ALTQ_ALTQ_CBQ_H_
|
||||
#define _ALTQ_ALTQ_CBQ_H_
|
||||
|
||||
#include <altq/altq.h>
|
||||
#include <altq/altq_rmclass.h>
|
||||
#include <altq/altq_red.h>
|
||||
#include <altq/altq_rio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define NULL_CLASS_HANDLE 0
|
||||
|
||||
/* class flags should be same as class flags in rm_class.h */
|
||||
#define CBQCLF_RED 0x0001 /* use RED */
|
||||
#define CBQCLF_ECN 0x0002 /* use RED/ECN */
|
||||
#define CBQCLF_RIO 0x0004 /* use RIO */
|
||||
#define CBQCLF_FLOWVALVE 0x0008 /* use flowvalve (aka penalty-box) */
|
||||
#define CBQCLF_CLEARDSCP 0x0010 /* clear diffserv codepoint */
|
||||
#define CBQCLF_BORROW 0x0020 /* borrow from parent */
|
||||
|
||||
/* class flags only for root class */
|
||||
#define CBQCLF_WRR 0x0100 /* weighted-round robin */
|
||||
#define CBQCLF_EFFICIENT 0x0200 /* work-conserving */
|
||||
|
||||
/* class flags for special classes */
|
||||
#define CBQCLF_ROOTCLASS 0x1000 /* root class */
|
||||
#define CBQCLF_DEFCLASS 0x2000 /* default class */
|
||||
#ifdef ALTQ3_COMPAT
|
||||
#define CBQCLF_CTLCLASS 0x4000 /* control class */
|
||||
#endif
|
||||
#define CBQCLF_CLASSMASK 0xf000 /* class mask */
|
||||
|
||||
#define CBQ_MAXQSIZE 200
|
||||
#define CBQ_MAXPRI RM_MAXPRIO
|
||||
|
||||
typedef struct _cbq_class_stats_ {
|
||||
u_int32_t handle;
|
||||
u_int depth;
|
||||
|
||||
struct pktcntr xmit_cnt; /* packets sent in this class */
|
||||
struct pktcntr drop_cnt; /* dropped packets */
|
||||
u_int over; /* # times went over limit */
|
||||
u_int borrows; /* # times tried to borrow */
|
||||
u_int overactions; /* # times invoked overlimit action */
|
||||
u_int delays; /* # times invoked delay actions */
|
||||
|
||||
/* other static class parameters useful for debugging */
|
||||
int priority;
|
||||
int maxidle;
|
||||
int minidle;
|
||||
int offtime;
|
||||
int qmax;
|
||||
int ns_per_byte;
|
||||
int wrr_allot;
|
||||
|
||||
int qcnt; /* # packets in queue */
|
||||
int avgidle;
|
||||
|
||||
/* red and rio related info */
|
||||
int qtype;
|
||||
struct redstats red[3];
|
||||
} class_stats_t;
|
||||
|
||||
#ifdef ALTQ3_COMPAT
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
/* 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)
|
||||
#endif /* ALTQ3_COMPAT */
|
||||
|
||||
#ifdef _KERNEL
|
||||
/*
|
||||
* Define macros only good for kernel drivers and modules.
|
||||
*/
|
||||
#define CBQ_WATCHDOG (hz / 20)
|
||||
#define CBQ_TIMEOUT 10
|
||||
#define CBQ_LS_TIMEOUT (20 * hz / 1000)
|
||||
|
||||
#define CBQ_MAX_CLASSES 256
|
||||
|
||||
#ifdef ALTQ3_COMPAT
|
||||
#define CBQ_MAX_FILTERS 256
|
||||
|
||||
#define DISABLE 0x00
|
||||
#define ENABLE 0x01
|
||||
#endif /* ALTQ3_COMPAT */
|
||||
|
||||
/*
|
||||
* Define State structures.
|
||||
*/
|
||||
typedef struct cbqstate {
|
||||
#ifdef ALTQ3_COMPAT
|
||||
struct cbqstate *cbq_next;
|
||||
#endif
|
||||
int cbq_qlen; /* # of packets in cbq */
|
||||
struct rm_class *cbq_class_tbl[CBQ_MAX_CLASSES];
|
||||
|
||||
struct rm_ifdat ifnp;
|
||||
struct callout cbq_callout; /* for timeouts */
|
||||
#ifdef ALTQ3_CLFIER_COMPAT
|
||||
struct acc_classifier cbq_classifier;
|
||||
#endif
|
||||
} cbq_state_t;
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_ALTQ_ALTQ_CBQ_H_ */
|
1386
sys/contrib/altq/altq/altq_cdnr.c
Normal file
1386
sys/contrib/altq/altq/altq_cdnr.c
Normal file
File diff suppressed because it is too large
Load Diff
335
sys/contrib/altq/altq/altq_cdnr.h
Normal file
335
sys/contrib/altq/altq/altq_cdnr.h
Normal file
@ -0,0 +1,335 @@
|
||||
/* $KAME: altq_cdnr.h,v 1.9 2003/07/10 12:07:48 kjc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1999-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.
|
||||
*/
|
||||
|
||||
#ifndef _ALTQ_ALTQ_CDNR_H_
|
||||
#define _ALTQ_ALTQ_CDNR_H_
|
||||
|
||||
#include <altq/altq.h>
|
||||
|
||||
/*
|
||||
* traffic conditioner element types
|
||||
*/
|
||||
#define TCETYPE_NONE 0
|
||||
#define TCETYPE_TOP 1 /* top level conditioner */
|
||||
#define TCETYPE_ELEMENT 2 /* a simple tc element */
|
||||
#define TCETYPE_TBMETER 3 /* token bucket meter */
|
||||
#define TCETYPE_TRTCM 4 /* (two-rate) three color marker */
|
||||
#define TCETYPE_TSWTCM 5 /* time sliding window 3-color maker */
|
||||
|
||||
/*
|
||||
* traffic conditioner action
|
||||
*/
|
||||
struct cdnr_block;
|
||||
|
||||
struct tc_action {
|
||||
int tca_code; /* e.g., TCACODE_PASS */
|
||||
/* tca_code dependent variable */
|
||||
union {
|
||||
u_long un_value; /* template */
|
||||
u_int8_t un_dscp; /* diffserv code point */
|
||||
u_long un_handle; /* tc action handle */
|
||||
struct cdnr_block *un_next; /* next tc element block */
|
||||
} tca_un;
|
||||
};
|
||||
#define tca_value tca_un.un_value
|
||||
#define tca_dscp tca_un.un_dscp
|
||||
#define tca_handle tca_un.un_handle
|
||||
#define tca_next tca_un.un_next
|
||||
|
||||
#define TCACODE_NONE 0 /* action is not set */
|
||||
#define TCACODE_PASS 1 /* pass this packet */
|
||||
#define TCACODE_DROP 2 /* discard this packet */
|
||||
#define TCACODE_RETURN 3 /* do not process this packet */
|
||||
#define TCACODE_MARK 4 /* mark dscp */
|
||||
#define TCACODE_HANDLE 5 /* take action specified by handle */
|
||||
#define TCACODE_NEXT 6 /* take action in the next tc element */
|
||||
#define TCACODE_MAX 6
|
||||
|
||||
#define CDNR_NULL_HANDLE 0
|
||||
|
||||
struct cdnr_interface {
|
||||
char cdnr_ifname[IFNAMSIZ]; /* interface name (e.g., fxp0) */
|
||||
};
|
||||
|
||||
/* simple element operations */
|
||||
struct cdnr_add_element {
|
||||
struct cdnr_interface iface;
|
||||
struct tc_action action;
|
||||
|
||||
u_long cdnr_handle; /* return value */
|
||||
};
|
||||
|
||||
struct cdnr_delete_element {
|
||||
struct cdnr_interface iface;
|
||||
u_long cdnr_handle;
|
||||
};
|
||||
|
||||
/* token-bucket meter operations */
|
||||
struct cdnr_add_tbmeter {
|
||||
struct cdnr_interface iface;
|
||||
struct tb_profile profile;
|
||||
struct tc_action in_action;
|
||||
struct tc_action out_action;
|
||||
|
||||
u_long cdnr_handle; /* return value */
|
||||
};
|
||||
|
||||
struct cdnr_modify_tbmeter {
|
||||
struct cdnr_interface iface;
|
||||
u_long cdnr_handle;
|
||||
struct tb_profile profile;
|
||||
};
|
||||
|
||||
struct cdnr_tbmeter_stats {
|
||||
struct cdnr_interface iface;
|
||||
u_long cdnr_handle;
|
||||
struct pktcntr in_cnt;
|
||||
struct pktcntr out_cnt;
|
||||
};
|
||||
|
||||
/* two-rate three-color marker operations */
|
||||
struct cdnr_add_trtcm {
|
||||
struct cdnr_interface iface;
|
||||
struct tb_profile cmtd_profile; /* profile for committed tb */
|
||||
struct tb_profile peak_profile; /* profile for peak tb */
|
||||
struct tc_action green_action; /* action for green packets */
|
||||
struct tc_action yellow_action; /* action for yellow packets */
|
||||
struct tc_action red_action; /* action for red packets */
|
||||
int coloraware; /* color-aware/color-blind */
|
||||
|
||||
u_long cdnr_handle; /* return value */
|
||||
};
|
||||
|
||||
struct cdnr_modify_trtcm {
|
||||
struct cdnr_interface iface;
|
||||
u_long cdnr_handle;
|
||||
struct tb_profile cmtd_profile; /* profile for committed tb */
|
||||
struct tb_profile peak_profile; /* profile for peak tb */
|
||||
int coloraware; /* color-aware/color-blind */
|
||||
};
|
||||
|
||||
struct cdnr_tcm_stats {
|
||||
struct cdnr_interface iface;
|
||||
u_long cdnr_handle;
|
||||
struct pktcntr green_cnt;
|
||||
struct pktcntr yellow_cnt;
|
||||
struct pktcntr red_cnt;
|
||||
};
|
||||
|
||||
/* time sliding window three-color marker operations */
|
||||
struct cdnr_add_tswtcm {
|
||||
struct cdnr_interface iface;
|
||||
u_int32_t cmtd_rate; /* committed rate (bits/sec) */
|
||||
u_int32_t peak_rate; /* peak rate (bits/sec) */
|
||||
u_int32_t avg_interval; /* averaging interval (msec) */
|
||||
struct tc_action green_action; /* action for green packets */
|
||||
struct tc_action yellow_action; /* action for yellow packets */
|
||||
struct tc_action red_action; /* action for red packets */
|
||||
|
||||
u_long cdnr_handle; /* return value */
|
||||
};
|
||||
|
||||
struct cdnr_modify_tswtcm {
|
||||
struct cdnr_interface iface;
|
||||
u_long cdnr_handle;
|
||||
u_int32_t cmtd_rate; /* committed rate (bits/sec) */
|
||||
u_int32_t peak_rate; /* peak rate (bits/sec) */
|
||||
u_int32_t avg_interval; /* averaging interval (msec) */
|
||||
};
|
||||
|
||||
struct cdnr_add_filter {
|
||||
struct cdnr_interface iface;
|
||||
u_long cdnr_handle;
|
||||
#ifdef ALTQ3_CLFIER_COMPAT
|
||||
struct flow_filter filter;
|
||||
#endif
|
||||
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 */
|
||||
struct pktcntr tce_cnts[3]; /* tcm returns 3 counters */
|
||||
};
|
||||
|
||||
struct cdnr_get_stats {
|
||||
struct cdnr_interface iface;
|
||||
struct pktcntr cnts[TCACODE_MAX+1];
|
||||
|
||||
/* element stats */
|
||||
int nskip; /* skip # of elements */
|
||||
int nelements; /* # of element stats (WR) */
|
||||
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
|
||||
#define DSCP_CUMASK 0x03
|
||||
#define DSCP_EF 0xb8
|
||||
#define DSCP_AF11 0x28
|
||||
#define DSCP_AF12 0x30
|
||||
#define DSCP_AF13 0x38
|
||||
#define DSCP_AF21 0x48
|
||||
#define DSCP_AF22 0x50
|
||||
#define DSCP_AF23 0x58
|
||||
#define DSCP_AF31 0x68
|
||||
#define DSCP_AF32 0x70
|
||||
#define DSCP_AF33 0x78
|
||||
#define DSCP_AF41 0x88
|
||||
#define DSCP_AF42 0x90
|
||||
#define DSCP_AF43 0x98
|
||||
#define AF_CLASSMASK 0xe0
|
||||
#define AF_DROPPRECMASK 0x18
|
||||
#endif
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
/*
|
||||
* packet information passed to the input function of tc elements
|
||||
*/
|
||||
struct cdnr_pktinfo {
|
||||
int pkt_len; /* packet length */
|
||||
u_int8_t pkt_dscp; /* diffserv code point */
|
||||
};
|
||||
|
||||
/*
|
||||
* traffic conditioner control block common to all types of tc elements
|
||||
*/
|
||||
struct cdnr_block {
|
||||
LIST_ENTRY(cdnr_block) cb_next;
|
||||
int cb_len; /* size of this tc element */
|
||||
int cb_type; /* cdnr block type */
|
||||
int cb_ref; /* reference count of this element */
|
||||
u_long cb_handle; /* handle of this tc element */
|
||||
struct top_cdnr *cb_top; /* back pointer to top */
|
||||
struct tc_action cb_action; /* top level action for this tcb */
|
||||
struct tc_action *(*cb_input)(struct cdnr_block *,
|
||||
struct cdnr_pktinfo *);
|
||||
};
|
||||
|
||||
/*
|
||||
* top level traffic conditioner structure for an interface
|
||||
*/
|
||||
struct top_cdnr {
|
||||
struct cdnr_block tc_block;
|
||||
|
||||
LIST_ENTRY(top_cdnr) tc_next;
|
||||
struct ifaltq *tc_ifq;
|
||||
|
||||
LIST_HEAD(, cdnr_block) tc_elements;
|
||||
#ifdef ALTQ3_CLFIER_COMPAT
|
||||
struct acc_classifier tc_classifier;
|
||||
#endif
|
||||
struct pktcntr tc_cnts[TCACODE_MAX+1];
|
||||
};
|
||||
|
||||
/* token bucket element */
|
||||
struct tbe {
|
||||
u_int64_t rate;
|
||||
u_int64_t depth;
|
||||
|
||||
u_int64_t token;
|
||||
u_int64_t filluptime;
|
||||
u_int64_t last;
|
||||
};
|
||||
|
||||
/* token bucket meter structure */
|
||||
struct tbmeter {
|
||||
struct cdnr_block cdnrblk; /* conditioner block */
|
||||
struct tbe tb; /* token bucket */
|
||||
struct tc_action in_action; /* actions for IN/OUT */
|
||||
struct tc_action out_action; /* actions for IN/OUT */
|
||||
struct pktcntr in_cnt; /* statistics for IN/OUT */
|
||||
struct pktcntr out_cnt; /* statistics for IN/OUT */
|
||||
};
|
||||
|
||||
/* two-rate three-color marker structure */
|
||||
struct trtcm {
|
||||
struct cdnr_block cdnrblk; /* conditioner block */
|
||||
struct tbe cmtd_tb; /* committed tb profile */
|
||||
struct tbe peak_tb; /* peak tb profile */
|
||||
struct tc_action green_action;
|
||||
struct tc_action yellow_action;
|
||||
struct tc_action red_action;
|
||||
int coloraware;
|
||||
u_int8_t green_dscp;
|
||||
u_int8_t yellow_dscp;
|
||||
u_int8_t red_dscp;
|
||||
struct pktcntr green_cnt;
|
||||
struct pktcntr yellow_cnt;
|
||||
struct pktcntr red_cnt;
|
||||
};
|
||||
|
||||
/* time sliding window three-color marker structure */
|
||||
struct tswtcm {
|
||||
struct cdnr_block cdnrblk; /* conditioner block */
|
||||
|
||||
u_int32_t avg_rate; /* average rate (bytes/sec) */
|
||||
u_int64_t t_front; /* timestamp of last update */
|
||||
|
||||
u_int64_t timewin; /* average interval */
|
||||
u_int32_t cmtd_rate; /* committed target rate */
|
||||
u_int32_t peak_rate; /* peak target rate */
|
||||
struct tc_action green_action;
|
||||
struct tc_action yellow_action;
|
||||
struct tc_action red_action;
|
||||
u_int8_t green_dscp;
|
||||
u_int8_t yellow_dscp;
|
||||
u_int8_t red_dscp;
|
||||
struct pktcntr green_cnt;
|
||||
struct pktcntr yellow_cnt;
|
||||
struct pktcntr red_cnt;
|
||||
};
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _ALTQ_ALTQ_CDNR_H_ */
|
206
sys/contrib/altq/altq/altq_classq.h
Normal file
206
sys/contrib/altq/altq/altq_classq.h
Normal file
@ -0,0 +1,206 @@
|
||||
/* $KAME: altq_classq.h,v 1.6 2003/01/07 07:33:38 kjc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991-1997 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 Network Research
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* class queue definitions extracted from rm_class.h.
|
||||
*/
|
||||
#ifndef _ALTQ_ALTQ_CLASSQ_H_
|
||||
#define _ALTQ_ALTQ_CLASSQ_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Packet Queue types: RED or DROPHEAD.
|
||||
*/
|
||||
#define Q_DROPHEAD 0x00
|
||||
#define Q_RED 0x01
|
||||
#define Q_RIO 0x02
|
||||
#define Q_DROPTAIL 0x03
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
/*
|
||||
* Packet Queue structures and macros to manipulate them.
|
||||
*/
|
||||
struct _class_queue_ {
|
||||
struct mbuf *tail_; /* Tail of packet queue */
|
||||
int qlen_; /* Queue length (in number of packets) */
|
||||
int qlim_; /* Queue limit (in number of packets*) */
|
||||
int qtype_; /* Queue type */
|
||||
};
|
||||
|
||||
typedef struct _class_queue_ class_queue_t;
|
||||
|
||||
#define qtype(q) (q)->qtype_ /* Get queue type */
|
||||
#define qlimit(q) (q)->qlim_ /* Max packets to be queued */
|
||||
#define qlen(q) (q)->qlen_ /* Current queue length. */
|
||||
#define qtail(q) (q)->tail_ /* Tail of the queue */
|
||||
#define qhead(q) ((q)->tail_ ? (q)->tail_->m_nextpkt : NULL)
|
||||
|
||||
#define qempty(q) ((q)->qlen_ == 0) /* Is the queue empty?? */
|
||||
#define q_is_red(q) ((q)->qtype_ == Q_RED) /* Is the queue a red queue */
|
||||
#define q_is_rio(q) ((q)->qtype_ == Q_RIO) /* Is the queue a rio queue */
|
||||
#define q_is_red_or_rio(q) ((q)->qtype_ == Q_RED || (q)->qtype_ == Q_RIO)
|
||||
|
||||
#if !defined(__GNUC__) || defined(ALTQ_DEBUG)
|
||||
|
||||
extern void _addq(class_queue_t *, struct mbuf *);
|
||||
extern struct mbuf *_getq(class_queue_t *);
|
||||
extern struct mbuf *_getq_tail(class_queue_t *);
|
||||
extern struct mbuf *_getq_random(class_queue_t *);
|
||||
extern void _removeq(class_queue_t *, struct mbuf *);
|
||||
extern void _flushq(class_queue_t *);
|
||||
|
||||
#else /* __GNUC__ && !ALTQ_DEBUG */
|
||||
/*
|
||||
* inlined versions
|
||||
*/
|
||||
static __inline void
|
||||
_addq(class_queue_t *q, struct mbuf *m)
|
||||
{
|
||||
struct mbuf *m0;
|
||||
|
||||
if ((m0 = qtail(q)) != NULL)
|
||||
m->m_nextpkt = m0->m_nextpkt;
|
||||
else
|
||||
m0 = m;
|
||||
m0->m_nextpkt = m;
|
||||
qtail(q) = m;
|
||||
qlen(q)++;
|
||||
}
|
||||
|
||||
static __inline struct mbuf *
|
||||
_getq(class_queue_t *q)
|
||||
{
|
||||
struct mbuf *m, *m0;
|
||||
|
||||
if ((m = qtail(q)) == NULL)
|
||||
return (NULL);
|
||||
if ((m0 = m->m_nextpkt) != m)
|
||||
m->m_nextpkt = m0->m_nextpkt;
|
||||
else
|
||||
qtail(q) = NULL;
|
||||
qlen(q)--;
|
||||
m0->m_nextpkt = NULL;
|
||||
return (m0);
|
||||
}
|
||||
|
||||
/* drop a packet at the tail of the queue */
|
||||
static __inline struct mbuf *
|
||||
_getq_tail(class_queue_t *q)
|
||||
{
|
||||
struct mbuf *m, *m0, *prev;
|
||||
|
||||
if ((m = m0 = qtail(q)) == NULL)
|
||||
return NULL;
|
||||
do {
|
||||
prev = m0;
|
||||
m0 = m0->m_nextpkt;
|
||||
} while (m0 != m);
|
||||
prev->m_nextpkt = m->m_nextpkt;
|
||||
if (prev == m)
|
||||
qtail(q) = NULL;
|
||||
else
|
||||
qtail(q) = prev;
|
||||
qlen(q)--;
|
||||
m->m_nextpkt = NULL;
|
||||
return (m);
|
||||
}
|
||||
|
||||
/* randomly select a packet in the queue */
|
||||
static __inline struct mbuf *
|
||||
_getq_random(class_queue_t *q)
|
||||
{
|
||||
struct mbuf *m;
|
||||
int i, n;
|
||||
|
||||
if ((m = qtail(q)) == NULL)
|
||||
return NULL;
|
||||
if (m->m_nextpkt == m)
|
||||
qtail(q) = NULL;
|
||||
else {
|
||||
struct mbuf *prev = NULL;
|
||||
|
||||
n = random() % qlen(q) + 1;
|
||||
for (i = 0; i < n; i++) {
|
||||
prev = m;
|
||||
m = m->m_nextpkt;
|
||||
}
|
||||
prev->m_nextpkt = m->m_nextpkt;
|
||||
if (m == qtail(q))
|
||||
qtail(q) = prev;
|
||||
}
|
||||
qlen(q)--;
|
||||
m->m_nextpkt = NULL;
|
||||
return (m);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_removeq(class_queue_t *q, struct mbuf *m)
|
||||
{
|
||||
struct mbuf *m0, *prev;
|
||||
|
||||
m0 = qtail(q);
|
||||
do {
|
||||
prev = m0;
|
||||
m0 = m0->m_nextpkt;
|
||||
} while (m0 != m);
|
||||
prev->m_nextpkt = m->m_nextpkt;
|
||||
if (prev == m)
|
||||
qtail(q) = NULL;
|
||||
else if (qtail(q) == m)
|
||||
qtail(q) = prev;
|
||||
qlen(q)--;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_flushq(class_queue_t *q)
|
||||
{
|
||||
struct mbuf *m;
|
||||
|
||||
while ((m = _getq(q)) != NULL)
|
||||
m_freem(m);
|
||||
}
|
||||
|
||||
#endif /* __GNUC__ && !ALTQ_DEBUG */
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ALTQ_ALTQ_CLASSQ_H_ */
|
2256
sys/contrib/altq/altq/altq_hfsc.c
Normal file
2256
sys/contrib/altq/altq/altq_hfsc.c
Normal file
File diff suppressed because it is too large
Load Diff
320
sys/contrib/altq/altq/altq_hfsc.h
Normal file
320
sys/contrib/altq/altq/altq_hfsc.h
Normal file
@ -0,0 +1,320 @@
|
||||
/* $KAME: altq_hfsc.h,v 1.12 2003/12/05 05:40:46 kjc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997-1999 Carnegie Mellon University. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation is hereby granted (including for commercial or
|
||||
* for-profit use), provided that both the copyright notice and this
|
||||
* permission notice appear in all copies of the software, derivative
|
||||
* works, or modified versions, and any portions thereof.
|
||||
*
|
||||
* THIS SOFTWARE IS EXPERIMENTAL AND IS KNOWN TO HAVE BUGS, SOME OF
|
||||
* WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON PROVIDES THIS
|
||||
* SOFTWARE IN ITS ``AS IS'' CONDITION, 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 CARNEGIE MELLON UNIVERSITY 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.
|
||||
*
|
||||
* Carnegie Mellon encourages (but does not require) users of this
|
||||
* software to return any improvements or extensions that they make,
|
||||
* and to grant Carnegie Mellon the rights to redistribute these
|
||||
* changes without encumbrance.
|
||||
*/
|
||||
#ifndef _ALTQ_ALTQ_HFSC_H_
|
||||
#define _ALTQ_ALTQ_HFSC_H_
|
||||
|
||||
#include <altq/altq.h>
|
||||
#include <altq/altq_classq.h>
|
||||
#include <altq/altq_red.h>
|
||||
#include <altq/altq_rio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
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 */
|
||||
};
|
||||
|
||||
/* special class handles */
|
||||
#define HFSC_NULLCLASS_HANDLE 0
|
||||
#define HFSC_MAX_CLASSES 64
|
||||
|
||||
/* hfsc class flags */
|
||||
#define HFCF_RED 0x0001 /* use RED */
|
||||
#define HFCF_ECN 0x0002 /* use RED/ECN */
|
||||
#define HFCF_RIO 0x0004 /* use RIO */
|
||||
#define HFCF_CLEARDSCP 0x0010 /* clear diffserv codepoint */
|
||||
#define HFCF_DEFAULTCLASS 0x1000 /* default class */
|
||||
|
||||
/* service curve types */
|
||||
#define HFSC_REALTIMESC 1
|
||||
#define HFSC_LINKSHARINGSC 2
|
||||
#define HFSC_UPPERLIMITSC 4
|
||||
#define HFSC_DEFAULTSC (HFSC_REALTIMESC|HFSC_LINKSHARINGSC)
|
||||
|
||||
struct hfsc_classstats {
|
||||
u_int class_id;
|
||||
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
|
||||
done by real-time criteria */
|
||||
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];
|
||||
};
|
||||
|
||||
#ifdef ALTQ3_COMPAT
|
||||
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 hfsc_add_class {
|
||||
struct hfsc_interface iface;
|
||||
u_int32_t parent_handle;
|
||||
struct service_curve service_curve;
|
||||
int qlimit;
|
||||
int flags;
|
||||
|
||||
u_int32_t class_handle; /* return value */
|
||||
};
|
||||
|
||||
struct hfsc_delete_class {
|
||||
struct hfsc_interface iface;
|
||||
u_int32_t class_handle;
|
||||
};
|
||||
|
||||
struct hfsc_modify_class {
|
||||
struct hfsc_interface iface;
|
||||
u_int32_t class_handle;
|
||||
struct service_curve service_curve;
|
||||
int sctype;
|
||||
};
|
||||
|
||||
struct hfsc_add_filter {
|
||||
struct hfsc_interface iface;
|
||||
u_int32_t 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 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_int32_t machclk_freq; /* machine clock frequency */
|
||||
u_int hif_classes; /* # of classes in the tree */
|
||||
u_int hif_packets; /* # of packets in the tree */
|
||||
struct hfsc_classstats *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)
|
||||
#endif /* ALTQ3_COMPAT */
|
||||
|
||||
#ifdef _KERNEL
|
||||
/*
|
||||
* kernel internal service curve representation
|
||||
* coordinates are given by 64 bit unsigned integers.
|
||||
* x-axis: unit is clock count. for the intel x86 architecture,
|
||||
* the raw Pentium TSC (Timestamp Counter) value is used.
|
||||
* virtual time is also calculated in this time scale.
|
||||
* y-axis: unit is byte.
|
||||
*
|
||||
* the service curve parameters are converted to the internal
|
||||
* representation.
|
||||
* the slope values are scaled to avoid overflow.
|
||||
* the inverse slope values as well as the y-projection of the 1st
|
||||
* segment are kept in order to to avoid 64-bit divide operations
|
||||
* that are expensive on 32-bit architectures.
|
||||
*
|
||||
* note: Intel Pentium TSC never wraps around in several thousands of years.
|
||||
* x-axis doesn't wrap around for 1089 years with 1GHz clock.
|
||||
* y-axis doesn't wrap around for 4358 years with 1Gbps bandwidth.
|
||||
*/
|
||||
|
||||
/* kernel internal representation of a service curve */
|
||||
struct internal_sc {
|
||||
u_int64_t sm1; /* scaled slope of the 1st segment */
|
||||
u_int64_t ism1; /* scaled inverse-slope of the 1st segment */
|
||||
u_int64_t dx; /* the x-projection of the 1st segment */
|
||||
u_int64_t dy; /* the y-projection of the 1st segment */
|
||||
u_int64_t sm2; /* scaled slope of the 2nd segment */
|
||||
u_int64_t ism2; /* scaled inverse-slope of the 2nd segment */
|
||||
};
|
||||
|
||||
/* runtime service curve */
|
||||
struct runtime_sc {
|
||||
u_int64_t x; /* current starting position on x-axis */
|
||||
u_int64_t y; /* current starting position on x-axis */
|
||||
u_int64_t sm1; /* scaled slope of the 1st segment */
|
||||
u_int64_t ism1; /* scaled inverse-slope of the 1st segment */
|
||||
u_int64_t dx; /* the x-projection of the 1st segment */
|
||||
u_int64_t dy; /* the y-projection of the 1st segment */
|
||||
u_int64_t sm2; /* scaled slope of the 2nd segment */
|
||||
u_int64_t ism2; /* scaled inverse-slope of the 2nd segment */
|
||||
};
|
||||
|
||||
/* for TAILQ based ellist and actlist implementation */
|
||||
struct hfsc_class;
|
||||
typedef TAILQ_HEAD(_eligible, hfsc_class) ellist_t;
|
||||
typedef TAILQ_ENTRY(hfsc_class) elentry_t;
|
||||
typedef TAILQ_HEAD(_active, hfsc_class) actlist_t;
|
||||
typedef TAILQ_ENTRY(hfsc_class) actentry_t;
|
||||
#define ellist_first(s) TAILQ_FIRST(s)
|
||||
#define actlist_first(s) TAILQ_FIRST(s)
|
||||
#define actlist_last(s) TAILQ_LAST(s, _active)
|
||||
|
||||
struct hfsc_class {
|
||||
u_int cl_id; /* class id (just for debug) */
|
||||
u_int32_t cl_handle; /* class handle */
|
||||
struct hfsc_if *cl_hif; /* back pointer to struct hfsc_if */
|
||||
int cl_flags; /* misc flags */
|
||||
|
||||
struct hfsc_class *cl_parent; /* parent class */
|
||||
struct hfsc_class *cl_siblings; /* sibling classes */
|
||||
struct hfsc_class *cl_children; /* child classes */
|
||||
|
||||
class_queue_t *cl_q; /* class queue structure */
|
||||
struct red *cl_red; /* RED state */
|
||||
struct altq_pktattr *cl_pktattr; /* saved header used by ECN */
|
||||
|
||||
u_int64_t cl_total; /* total work in bytes */
|
||||
u_int64_t cl_cumul; /* cumulative work in bytes
|
||||
done by real-time criteria */
|
||||
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 */
|
||||
int cl_nactive; /* number of active children */
|
||||
actlist_t *cl_actc; /* active children list */
|
||||
|
||||
actentry_t cl_actlist; /* active children list entry */
|
||||
elentry_t cl_ellist; /* eligible list entry */
|
||||
|
||||
struct {
|
||||
struct pktcntr xmit_cnt;
|
||||
struct pktcntr drop_cnt;
|
||||
u_int period;
|
||||
} cl_stats;
|
||||
};
|
||||
|
||||
/*
|
||||
* hfsc interface state
|
||||
*/
|
||||
struct hfsc_if {
|
||||
struct hfsc_if *hif_next; /* interface state list */
|
||||
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 */
|
||||
u_int hif_packets; /* # of packets in the tree */
|
||||
u_int hif_classid; /* class id sequence number */
|
||||
|
||||
ellist_t *hif_eligible; /* eligible list */
|
||||
|
||||
#ifdef ALTQ3_CLFIER_COMPAT
|
||||
struct acc_classifier hif_classifier;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ALTQ_ALTQ_HFSC_H_ */
|
1036
sys/contrib/altq/altq/altq_priq.c
Normal file
1036
sys/contrib/altq/altq/altq_priq.c
Normal file
File diff suppressed because it is too large
Load Diff
170
sys/contrib/altq/altq/altq_priq.h
Normal file
170
sys/contrib/altq/altq/altq_priq.h
Normal file
@ -0,0 +1,170 @@
|
||||
/* $KAME: altq_priq.h,v 1.7 2003/10/03 05:05:15 kjc Exp $ */
|
||||
/*
|
||||
* Copyright (C) 2000-2003
|
||||
* 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_PRIQ_H_
|
||||
#define _ALTQ_ALTQ_PRIQ_H_
|
||||
|
||||
#include <altq/altq.h>
|
||||
#include <altq/altq_classq.h>
|
||||
#include <altq/altq_red.h>
|
||||
#include <altq/altq_rio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PRIQ_MAXPRI 16 /* upper limit of the number of priorities */
|
||||
|
||||
#ifdef ALTQ3_COMPAT
|
||||
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_int32_t class_handle; /* return value */
|
||||
};
|
||||
#endif /* ALTQ3_COMPAT */
|
||||
|
||||
/* priq class flags */
|
||||
#define PRCF_RED 0x0001 /* use RED */
|
||||
#define PRCF_ECN 0x0002 /* use RED/ECN */
|
||||
#define PRCF_RIO 0x0004 /* use RIO */
|
||||
#define PRCF_CLEARDSCP 0x0010 /* clear diffserv codepoint */
|
||||
#define PRCF_DEFAULTCLASS 0x1000 /* default class */
|
||||
|
||||
/* special class handles */
|
||||
#define PRIQ_NULLCLASS_HANDLE 0
|
||||
|
||||
#ifdef ALTQ3_COMPAT
|
||||
struct priq_delete_class {
|
||||
struct priq_interface iface;
|
||||
u_int32_t class_handle;
|
||||
};
|
||||
|
||||
struct priq_modify_class {
|
||||
struct priq_interface iface;
|
||||
u_int32_t class_handle;
|
||||
int pri;
|
||||
int qlimit;
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct priq_add_filter {
|
||||
struct priq_interface iface;
|
||||
u_int32_t class_handle;
|
||||
struct flow_filter filter;
|
||||
|
||||
u_long filter_handle; /* return value */
|
||||
};
|
||||
|
||||
struct priq_delete_filter {
|
||||
struct priq_interface iface;
|
||||
u_long filter_handle;
|
||||
};
|
||||
#endif /* ALTQ3_COMPAT */
|
||||
|
||||
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 */
|
||||
|
||||
/* red and rio related info */
|
||||
int qtype;
|
||||
struct redstats red[3]; /* rio has 3 red stats */
|
||||
};
|
||||
|
||||
#ifdef ALTQ3_COMPAT
|
||||
struct priq_class_stats {
|
||||
struct priq_interface iface;
|
||||
int maxpri; /* in/out */
|
||||
|
||||
struct priq_classstats *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)
|
||||
|
||||
#endif /* ALTQ3_COMPAT */
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
struct priq_class {
|
||||
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 */
|
||||
int cl_flags; /* class flags */
|
||||
struct priq_if *cl_pif; /* back pointer to pif */
|
||||
struct altq_pktattr *cl_pktattr; /* saved header used by ECN */
|
||||
|
||||
/* statistics */
|
||||
u_int cl_period; /* backlog period */
|
||||
struct pktcntr cl_xmitcnt; /* transmitted packet counter */
|
||||
struct pktcntr cl_dropcnt; /* dropped packet counter */
|
||||
};
|
||||
|
||||
/*
|
||||
* priq interface state
|
||||
*/
|
||||
struct priq_if {
|
||||
struct priq_if *pif_next; /* interface state list */
|
||||
struct ifaltq *pif_ifq; /* backpointer to ifaltq */
|
||||
u_int pif_bandwidth; /* link bandwidth in bps */
|
||||
int pif_maxpri; /* max priority in use */
|
||||
struct priq_class *pif_default; /* default class */
|
||||
struct priq_class *pif_classes[PRIQ_MAXPRI]; /* classes */
|
||||
#ifdef ALTQ3_CLFIER_COMPAT
|
||||
struct acc_classifier pif_classifier; /* classifier */
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ALTQ_ALTQ_PRIQ_H_ */
|
1492
sys/contrib/altq/altq/altq_red.c
Normal file
1492
sys/contrib/altq/altq/altq_red.c
Normal file
File diff suppressed because it is too large
Load Diff
198
sys/contrib/altq/altq/altq_red.h
Normal file
198
sys/contrib/altq/altq/altq_red.h
Normal file
@ -0,0 +1,198 @@
|
||||
/* $KAME: altq_red.h,v 1.8 2003/07/10 12:07:49 kjc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1997-2003
|
||||
* 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_RED_H_
|
||||
#define _ALTQ_ALTQ_RED_H_
|
||||
|
||||
#include <altq/altq_classq.h>
|
||||
|
||||
#ifdef ALTQ3_COMPAT
|
||||
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 */
|
||||
};
|
||||
#endif /* ALTQ3_COMPAT */
|
||||
|
||||
/* red flags */
|
||||
#define REDF_ECN4 0x01 /* use packet marking for IPv4 packets */
|
||||
#define REDF_ECN6 0x02 /* use packet marking for IPv6 packets */
|
||||
#define REDF_ECN (REDF_ECN4 | REDF_ECN6)
|
||||
#define REDF_FLOWVALVE 0x04 /* use flowvalve (aka penalty-box) */
|
||||
|
||||
/*
|
||||
* simpler versions of red parameters and statistics used by other
|
||||
* disciplines (e.g., CBQ)
|
||||
*/
|
||||
struct redparams {
|
||||
int th_min; /* red min threshold */
|
||||
int th_max; /* red max threshold */
|
||||
int inv_pmax; /* inverse of max drop probability */
|
||||
};
|
||||
|
||||
struct redstats {
|
||||
int q_avg;
|
||||
struct pktcntr xmit_cnt;
|
||||
struct pktcntr drop_cnt;
|
||||
u_int drop_forced;
|
||||
u_int drop_unforced;
|
||||
u_int marked_packets;
|
||||
};
|
||||
|
||||
#ifdef ALTQ3_COMPAT
|
||||
/*
|
||||
* 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)
|
||||
#endif /* ALTQ3_COMPAT */
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#ifdef ALTQ3_COMPAT
|
||||
struct flowvalve;
|
||||
#endif
|
||||
|
||||
/* weight table structure for idle time calibration */
|
||||
struct wtab {
|
||||
struct wtab *w_next;
|
||||
int w_weight;
|
||||
int w_param_max;
|
||||
int w_refcount;
|
||||
int32_t w_tab[32];
|
||||
};
|
||||
|
||||
typedef struct red {
|
||||
int red_pkttime; /* average packet time in micro sec
|
||||
used for idle calibration */
|
||||
int red_flags; /* red flags */
|
||||
|
||||
/* red parameters */
|
||||
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 */
|
||||
|
||||
/* variables for internal use */
|
||||
int red_wshift; /* log(red_weight) */
|
||||
int red_thmin_s; /* th_min scaled by avgshift */
|
||||
int red_thmax_s; /* th_max scaled by avgshift */
|
||||
int red_probd; /* drop probability denominator */
|
||||
|
||||
int red_avg; /* queue len avg scaled by avgshift */
|
||||
int red_count; /* packet count since last dropped/
|
||||
marked packet */
|
||||
int red_idle; /* queue was empty */
|
||||
int red_old; /* avg is above th_min */
|
||||
struct wtab *red_wtab; /* weight table */
|
||||
struct timeval red_last; /* time when the queue becomes idle */
|
||||
|
||||
#ifdef ALTQ3_COMPAT
|
||||
struct flowvalve *red_flowvalve; /* flowvalve state */
|
||||
#endif
|
||||
|
||||
struct {
|
||||
struct pktcntr xmit_cnt;
|
||||
struct pktcntr drop_cnt;
|
||||
u_int drop_forced;
|
||||
u_int drop_unforced;
|
||||
u_int marked_packets;
|
||||
} red_stats;
|
||||
} red_t;
|
||||
|
||||
#ifdef ALTQ3_COMPAT
|
||||
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;
|
||||
#endif /* ALTQ3_COMPAT */
|
||||
|
||||
/* red drop types */
|
||||
#define DTYPE_NODROP 0 /* no drop */
|
||||
#define DTYPE_FORCED 1 /* a "forced" drop */
|
||||
#define DTYPE_EARLY 2 /* an "unforced" (early) drop */
|
||||
|
||||
extern red_t *red_alloc(int, int, int, int, int, int);
|
||||
extern void red_destroy(red_t *);
|
||||
extern void red_getstats(red_t *, struct redstats *);
|
||||
extern int red_addq(red_t *, class_queue_t *, struct mbuf *,
|
||||
struct altq_pktattr *);
|
||||
extern struct mbuf *red_getq(red_t *, class_queue_t *);
|
||||
extern int drop_early(int, int, int);
|
||||
extern int mark_ecn(struct mbuf *, struct altq_pktattr *, int);
|
||||
extern struct wtab *wtab_alloc(int);
|
||||
extern int wtab_destroy(struct wtab *);
|
||||
extern int32_t pow_w(struct wtab *, int);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _ALTQ_ALTQ_RED_H_ */
|
843
sys/contrib/altq/altq/altq_rio.c
Normal file
843
sys/contrib/altq/altq/altq_rio.c
Normal file
@ -0,0 +1,843 @@
|
||||
/* $KAME: altq_rio.c,v 1.17 2003/07/10 12:07:49 kjc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1998-2003
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
#include "opt_altq.h"
|
||||
#if (__FreeBSD__ != 2)
|
||||
#include "opt_inet.h"
|
||||
#ifdef __FreeBSD__
|
||||
#include "opt_inet6.h"
|
||||
#endif
|
||||
#endif
|
||||
#endif /* __FreeBSD__ || __NetBSD__ */
|
||||
#ifdef ALTQ_RIO /* rio is enabled by ALTQ_RIO option in opt_altq.h */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/errno.h>
|
||||
#if 1 /* ALTQ3_COMPAT */
|
||||
#include <sys/proc.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/kernel.h>
|
||||
#endif
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#ifdef INET6
|
||||
#include <netinet/ip6.h>
|
||||
#endif
|
||||
|
||||
#include <net/pfvar.h>
|
||||
#include <altq/altq.h>
|
||||
#include <altq/altq_cdnr.h>
|
||||
#include <altq/altq_red.h>
|
||||
#include <altq/altq_rio.h>
|
||||
#ifdef ALTQ3_COMPAT
|
||||
#include <altq/altq_conf.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* RIO: RED with IN/OUT bit
|
||||
* described in
|
||||
* "Explicit Allocation of Best Effort Packet Delivery Service"
|
||||
* David D. Clark and Wenjia Fang, MIT Lab for Computer Science
|
||||
* http://diffserv.lcs.mit.edu/Papers/exp-alloc-ddc-wf.{ps,pdf}
|
||||
*
|
||||
* this implementation is extended to support more than 2 drop precedence
|
||||
* values as described in RFC2597 (Assured Forwarding PHB Group).
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* AF DS (differentiated service) codepoints.
|
||||
* (classes can be mapped to CBQ or H-FSC classes.)
|
||||
*
|
||||
* 0 1 2 3 4 5 6 7
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* | CLASS |DropPre| 0 | CU |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* class 1: 001
|
||||
* class 2: 010
|
||||
* class 3: 011
|
||||
* class 4: 100
|
||||
*
|
||||
* low drop prec: 01
|
||||
* medium drop prec: 10
|
||||
* high drop prec: 01
|
||||
*/
|
||||
|
||||
/* normal red parameters */
|
||||
#define W_WEIGHT 512 /* inverse of weight of EWMA (511/512) */
|
||||
/* q_weight = 0.00195 */
|
||||
|
||||
/* red parameters for a slow link */
|
||||
#define W_WEIGHT_1 128 /* inverse of weight of EWMA (127/128) */
|
||||
/* q_weight = 0.0078125 */
|
||||
|
||||
/* red parameters for a very slow link (e.g., dialup) */
|
||||
#define W_WEIGHT_2 64 /* inverse of weight of EWMA (63/64) */
|
||||
/* q_weight = 0.015625 */
|
||||
|
||||
/* fixed-point uses 12-bit decimal places */
|
||||
#define FP_SHIFT 12 /* fixed-point shift */
|
||||
|
||||
/* red parameters for drop probability */
|
||||
#define INV_P_MAX 10 /* inverse of max drop probability */
|
||||
#define TH_MIN 5 /* min threshold */
|
||||
#define TH_MAX 15 /* max threshold */
|
||||
|
||||
#define RIO_LIMIT 60 /* default max queue lenght */
|
||||
#define RIO_STATS /* collect statistics */
|
||||
|
||||
#define TV_DELTA(a, b, delta) { \
|
||||
register int xxs; \
|
||||
\
|
||||
delta = (a)->tv_usec - (b)->tv_usec; \
|
||||
if ((xxs = (a)->tv_sec - (b)->tv_sec) != 0) { \
|
||||
if (xxs < 0) { \
|
||||
delta = 60000000; \
|
||||
} else if (xxs > 4) { \
|
||||
if (xxs > 60) \
|
||||
delta = 60000000; \
|
||||
else \
|
||||
delta += xxs * 1000000; \
|
||||
} else while (xxs > 0) { \
|
||||
delta += 1000000; \
|
||||
xxs--; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#ifdef ALTQ3_COMPAT
|
||||
/* rio_list keeps all rio_queue_t's allocated. */
|
||||
static rio_queue_t *rio_list = NULL;
|
||||
#endif
|
||||
/* default rio parameter values */
|
||||
static struct redparams default_rio_params[RIO_NDROPPREC] = {
|
||||
/* th_min, th_max, inv_pmax */
|
||||
{ TH_MAX * 2 + TH_MIN, TH_MAX * 3, INV_P_MAX }, /* low drop precedence */
|
||||
{ TH_MAX + TH_MIN, TH_MAX * 2, INV_P_MAX }, /* medium drop precedence */
|
||||
{ TH_MIN, TH_MAX, INV_P_MAX } /* high drop precedence */
|
||||
};
|
||||
|
||||
/* internal function prototypes */
|
||||
static int dscp2index(u_int8_t);
|
||||
#ifdef ALTQ3_COMPAT
|
||||
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 *);
|
||||
|
||||
/*
|
||||
* rio device interface
|
||||
*/
|
||||
altqdev_decl(rio);
|
||||
|
||||
#endif /* ALTQ3_COMPAT */
|
||||
|
||||
rio_t *
|
||||
rio_alloc(int weight, struct redparams *params, int flags, int pkttime)
|
||||
{
|
||||
rio_t *rp;
|
||||
int w, i;
|
||||
int npkts_per_sec;
|
||||
|
||||
MALLOC(rp, rio_t *, sizeof(rio_t), M_DEVBUF, M_WAITOK);
|
||||
if (rp == NULL)
|
||||
return (NULL);
|
||||
bzero(rp, sizeof(rio_t));
|
||||
|
||||
rp->rio_flags = flags;
|
||||
if (pkttime == 0)
|
||||
/* default packet time: 1000 bytes / 10Mbps * 8 * 1000000 */
|
||||
rp->rio_pkttime = 800;
|
||||
else
|
||||
rp->rio_pkttime = pkttime;
|
||||
|
||||
if (weight != 0)
|
||||
rp->rio_weight = weight;
|
||||
else {
|
||||
/* use default */
|
||||
rp->rio_weight = W_WEIGHT;
|
||||
|
||||
/* when the link is very slow, adjust red parameters */
|
||||
npkts_per_sec = 1000000 / rp->rio_pkttime;
|
||||
if (npkts_per_sec < 50) {
|
||||
/* up to about 400Kbps */
|
||||
rp->rio_weight = W_WEIGHT_2;
|
||||
} else if (npkts_per_sec < 300) {
|
||||
/* up to about 2.4Mbps */
|
||||
rp->rio_weight = W_WEIGHT_1;
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate wshift. weight must be power of 2 */
|
||||
w = rp->rio_weight;
|
||||
for (i = 0; w > 1; i++)
|
||||
w = w >> 1;
|
||||
rp->rio_wshift = i;
|
||||
w = 1 << rp->rio_wshift;
|
||||
if (w != rp->rio_weight) {
|
||||
printf("invalid weight value %d for red! use %d\n",
|
||||
rp->rio_weight, w);
|
||||
rp->rio_weight = w;
|
||||
}
|
||||
|
||||
/* allocate weight table */
|
||||
rp->rio_wtab = wtab_alloc(rp->rio_weight);
|
||||
|
||||
for (i = 0; i < RIO_NDROPPREC; i++) {
|
||||
struct dropprec_state *prec = &rp->rio_precstate[i];
|
||||
|
||||
prec->avg = 0;
|
||||
prec->idle = 1;
|
||||
|
||||
if (params == NULL || params[i].inv_pmax == 0)
|
||||
prec->inv_pmax = default_rio_params[i].inv_pmax;
|
||||
else
|
||||
prec->inv_pmax = params[i].inv_pmax;
|
||||
if (params == NULL || params[i].th_min == 0)
|
||||
prec->th_min = default_rio_params[i].th_min;
|
||||
else
|
||||
prec->th_min = params[i].th_min;
|
||||
if (params == NULL || params[i].th_max == 0)
|
||||
prec->th_max = default_rio_params[i].th_max;
|
||||
else
|
||||
prec->th_max = params[i].th_max;
|
||||
|
||||
/*
|
||||
* th_min_s and th_max_s are scaled versions of th_min
|
||||
* and th_max to be compared with avg.
|
||||
*/
|
||||
prec->th_min_s = prec->th_min << (rp->rio_wshift + FP_SHIFT);
|
||||
prec->th_max_s = prec->th_max << (rp->rio_wshift + FP_SHIFT);
|
||||
|
||||
/*
|
||||
* precompute probability denominator
|
||||
* probd = (2 * (TH_MAX-TH_MIN) / pmax) in fixed-point
|
||||
*/
|
||||
prec->probd = (2 * (prec->th_max - prec->th_min)
|
||||
* prec->inv_pmax) << FP_SHIFT;
|
||||
|
||||
microtime(&prec->last);
|
||||
}
|
||||
|
||||
return (rp);
|
||||
}
|
||||
|
||||
void
|
||||
rio_destroy(rio_t *rp)
|
||||
{
|
||||
wtab_destroy(rp->rio_wtab);
|
||||
FREE(rp, M_DEVBUF);
|
||||
}
|
||||
|
||||
void
|
||||
rio_getstats(rio_t *rp, struct redstats *sp)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < RIO_NDROPPREC; i++) {
|
||||
bcopy(&rp->q_stats[i], sp, sizeof(struct redstats));
|
||||
sp->q_avg = rp->rio_precstate[i].avg >> rp->rio_wshift;
|
||||
sp++;
|
||||
}
|
||||
}
|
||||
|
||||
#if (RIO_NDROPPREC == 3)
|
||||
/*
|
||||
* internally, a drop precedence value is converted to an index
|
||||
* starting from 0.
|
||||
*/
|
||||
static int
|
||||
dscp2index(u_int8_t dscp)
|
||||
{
|
||||
int dpindex = dscp & AF_DROPPRECMASK;
|
||||
|
||||
if (dpindex == 0)
|
||||
return (0);
|
||||
return ((dpindex >> 3) - 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
/*
|
||||
* kludge: when a packet is dequeued, we need to know its drop precedence
|
||||
* in order to keep the queue length of each drop precedence.
|
||||
* use m_pkthdr.rcvif to pass this info.
|
||||
*/
|
||||
#define RIOM_SET_PRECINDEX(m, idx) \
|
||||
do { (m)->m_pkthdr.rcvif = (struct ifnet *)((long)(idx)); } while (0)
|
||||
#define RIOM_GET_PRECINDEX(m) \
|
||||
({ long idx; idx = (long)((m)->m_pkthdr.rcvif); \
|
||||
(m)->m_pkthdr.rcvif = NULL; idx; })
|
||||
#endif
|
||||
|
||||
int
|
||||
rio_addq(rio_t *rp, class_queue_t *q, struct mbuf *m,
|
||||
struct altq_pktattr *pktattr)
|
||||
{
|
||||
int avg, droptype;
|
||||
u_int8_t dsfield, odsfield;
|
||||
int dpindex, i, n, t;
|
||||
struct timeval now;
|
||||
struct dropprec_state *prec;
|
||||
|
||||
dsfield = odsfield = read_dsfield(m, pktattr);
|
||||
dpindex = dscp2index(dsfield);
|
||||
|
||||
/*
|
||||
* update avg of the precedence states whose drop precedence
|
||||
* is larger than or equal to the drop precedence of the packet
|
||||
*/
|
||||
now.tv_sec = 0;
|
||||
for (i = dpindex; i < RIO_NDROPPREC; i++) {
|
||||
prec = &rp->rio_precstate[i];
|
||||
avg = prec->avg;
|
||||
if (prec->idle) {
|
||||
prec->idle = 0;
|
||||
if (now.tv_sec == 0)
|
||||
microtime(&now);
|
||||
t = (now.tv_sec - prec->last.tv_sec);
|
||||
if (t > 60)
|
||||
avg = 0;
|
||||
else {
|
||||
t = t * 1000000 +
|
||||
(now.tv_usec - prec->last.tv_usec);
|
||||
n = t / rp->rio_pkttime;
|
||||
/* calculate (avg = (1 - Wq)^n * avg) */
|
||||
if (n > 0)
|
||||
avg = (avg >> FP_SHIFT) *
|
||||
pow_w(rp->rio_wtab, n);
|
||||
}
|
||||
}
|
||||
|
||||
/* run estimator. (avg is scaled by WEIGHT in fixed-point) */
|
||||
avg += (prec->qlen << FP_SHIFT) - (avg >> rp->rio_wshift);
|
||||
prec->avg = avg; /* save the new value */
|
||||
/*
|
||||
* count keeps a tally of arriving traffic that has not
|
||||
* been dropped.
|
||||
*/
|
||||
prec->count++;
|
||||
}
|
||||
|
||||
prec = &rp->rio_precstate[dpindex];
|
||||
avg = prec->avg;
|
||||
|
||||
/* see if we drop early */
|
||||
droptype = DTYPE_NODROP;
|
||||
if (avg >= prec->th_min_s && prec->qlen > 1) {
|
||||
if (avg >= prec->th_max_s) {
|
||||
/* avg >= th_max: forced drop */
|
||||
droptype = DTYPE_FORCED;
|
||||
} else if (prec->old == 0) {
|
||||
/* first exceeds th_min */
|
||||
prec->count = 1;
|
||||
prec->old = 1;
|
||||
} else if (drop_early((avg - prec->th_min_s) >> rp->rio_wshift,
|
||||
prec->probd, prec->count)) {
|
||||
/* unforced drop by red */
|
||||
droptype = DTYPE_EARLY;
|
||||
}
|
||||
} else {
|
||||
/* avg < th_min */
|
||||
prec->old = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 (droptype != DTYPE_NODROP) {
|
||||
/* always drop incoming packet (as opposed to randomdrop) */
|
||||
for (i = dpindex; i < RIO_NDROPPREC; i++)
|
||||
rp->rio_precstate[i].count = 0;
|
||||
#ifdef RIO_STATS
|
||||
if (droptype == DTYPE_EARLY)
|
||||
rp->q_stats[dpindex].drop_unforced++;
|
||||
else
|
||||
rp->q_stats[dpindex].drop_forced++;
|
||||
PKTCNTR_ADD(&rp->q_stats[dpindex].drop_cnt, m_pktlen(m));
|
||||
#endif
|
||||
m_freem(m);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
for (i = dpindex; i < RIO_NDROPPREC; i++)
|
||||
rp->rio_precstate[i].qlen++;
|
||||
|
||||
/* save drop precedence index in mbuf hdr */
|
||||
RIOM_SET_PRECINDEX(m, dpindex);
|
||||
|
||||
if (rp->rio_flags & RIOF_CLEARDSCP)
|
||||
dsfield &= ~DSCP_MASK;
|
||||
|
||||
if (dsfield != odsfield)
|
||||
write_dsfield(m, pktattr, dsfield);
|
||||
|
||||
_addq(q, m);
|
||||
|
||||
#ifdef RIO_STATS
|
||||
PKTCNTR_ADD(&rp->q_stats[dpindex].xmit_cnt, m_pktlen(m));
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
rio_getq(rio_t *rp, class_queue_t *q)
|
||||
{
|
||||
struct mbuf *m;
|
||||
int dpindex, i;
|
||||
|
||||
if ((m = _getq(q)) == NULL)
|
||||
return NULL;
|
||||
|
||||
dpindex = RIOM_GET_PRECINDEX(m);
|
||||
for (i = dpindex; i < RIO_NDROPPREC; i++) {
|
||||
if (--rp->rio_precstate[i].qlen == 0) {
|
||||
if (rp->rio_precstate[i].idle == 0) {
|
||||
rp->rio_precstate[i].idle = 1;
|
||||
microtime(&rp->rio_precstate[i].last);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (m);
|
||||
}
|
||||
|
||||
#ifdef ALTQ3_COMPAT
|
||||
int
|
||||
rioopen(dev, flag, fmt, p)
|
||||
dev_t dev;
|
||||
int flag, fmt;
|
||||
#if (__FreeBSD_version > 500000)
|
||||
struct thread *p;
|
||||
#else
|
||||
struct proc *p;
|
||||
#endif
|
||||
{
|
||||
/* everything will be done when the queueing scheme is attached. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rioclose(dev, flag, fmt, p)
|
||||
dev_t dev;
|
||||
int flag, fmt;
|
||||
#if (__FreeBSD_version > 500000)
|
||||
struct thread *p;
|
||||
#else
|
||||
struct proc *p;
|
||||
#endif
|
||||
{
|
||||
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;
|
||||
#if (__FreeBSD_version > 500000)
|
||||
struct thread *p;
|
||||
#else
|
||||
struct proc *p;
|
||||
#endif
|
||||
{
|
||||
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 (/*CONSTCOND*/ 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;
|
||||
}
|
||||
|
||||
#ifdef __NetBSD__
|
||||
s = splnet();
|
||||
#else
|
||||
s = splimp();
|
||||
#endif
|
||||
_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 (/*CONSTCOND*/ 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 (/*CONSTCOND*/ 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
#ifdef KLD_MODULE
|
||||
|
||||
static struct altqsw rio_sw =
|
||||
{"rio", rioopen, rioclose, rioioctl};
|
||||
|
||||
ALTQ_MODULE(altq_rio, ALTQT_RIO, &rio_sw);
|
||||
MODULE_VERSION(altq_rio, 1);
|
||||
MODULE_DEPEND(altq_rio, altq_red, 1, 1, 1);
|
||||
|
||||
#endif /* KLD_MODULE */
|
||||
#endif /* ALTQ3_COMPAT */
|
||||
|
||||
#endif /* ALTQ_RIO */
|
144
sys/contrib/altq/altq/altq_rio.h
Normal file
144
sys/contrib/altq/altq/altq_rio.h
Normal file
@ -0,0 +1,144 @@
|
||||
/* $KAME: altq_rio.h,v 1.9 2003/07/10 12:07:49 kjc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1998-2003
|
||||
* 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_RIO_H_
|
||||
#define _ALTQ_ALTQ_RIO_H_
|
||||
|
||||
#include <altq/altq_classq.h>
|
||||
|
||||
/*
|
||||
* RIO: RED with IN/OUT bit
|
||||
* (extended to support more than 2 drop precedence values)
|
||||
*/
|
||||
#define RIO_NDROPPREC 3 /* number of drop precedence values */
|
||||
|
||||
#ifdef ALTQ3_COMPAT
|
||||
struct rio_interface {
|
||||
char rio_ifname[IFNAMSIZ];
|
||||
};
|
||||
|
||||
struct rio_stats {
|
||||
struct rio_interface iface;
|
||||
int q_len[RIO_NDROPPREC];
|
||||
struct redstats q_stats[RIO_NDROPPREC];
|
||||
|
||||
/* static red parameters */
|
||||
int q_limit;
|
||||
int weight;
|
||||
int flags;
|
||||
struct redparams q_params[RIO_NDROPPREC];
|
||||
};
|
||||
|
||||
struct rio_conf {
|
||||
struct rio_interface iface;
|
||||
struct redparams q_params[RIO_NDROPPREC];
|
||||
int rio_weight; /* weight for EWMA */
|
||||
int rio_limit; /* max queue length */
|
||||
int rio_pkttime; /* average packet time in usec */
|
||||
int rio_flags; /* see below */
|
||||
};
|
||||
#endif /* ALTQ3_COMPAT */
|
||||
|
||||
/* rio flags */
|
||||
#define RIOF_ECN4 0x01 /* use packet marking for IPv4 packets */
|
||||
#define RIOF_ECN6 0x02 /* use packet marking for IPv6 packets */
|
||||
#define RIOF_ECN (RIOF_ECN4 | RIOF_ECN6)
|
||||
#define RIOF_CLEARDSCP 0x200 /* clear diffserv codepoint */
|
||||
|
||||
#ifdef ALTQ3_COMPAT
|
||||
/*
|
||||
* 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])
|
||||
#endif /* ALTQ3_COMPAT */
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
typedef struct rio {
|
||||
/* per drop precedence structure */
|
||||
struct dropprec_state {
|
||||
/* red parameters */
|
||||
int inv_pmax; /* inverse of max drop probability */
|
||||
int th_min; /* red min threshold */
|
||||
int th_max; /* red max threshold */
|
||||
|
||||
/* variables for internal use */
|
||||
int th_min_s; /* th_min scaled by avgshift */
|
||||
int th_max_s; /* th_max scaled by avgshift */
|
||||
int probd; /* drop probability denominator */
|
||||
|
||||
int qlen; /* queue length */
|
||||
int avg; /* (scaled) queue length average */
|
||||
int count; /* packet count since the last dropped/
|
||||
marked packet */
|
||||
int idle; /* queue was empty */
|
||||
int old; /* avg is above th_min */
|
||||
struct timeval last; /* timestamp when queue becomes idle */
|
||||
} rio_precstate[RIO_NDROPPREC];
|
||||
|
||||
int rio_wshift; /* log(red_weight) */
|
||||
int rio_weight; /* weight for EWMA */
|
||||
struct wtab *rio_wtab; /* weight table */
|
||||
|
||||
int rio_pkttime; /* average packet time in micro sec
|
||||
used for idle calibration */
|
||||
int rio_flags; /* rio flags */
|
||||
|
||||
u_int8_t rio_codepoint; /* codepoint value to tag packets */
|
||||
u_int8_t rio_codepointmask; /* codepoint mask bits */
|
||||
|
||||
struct redstats q_stats[RIO_NDROPPREC]; /* statistics */
|
||||
} rio_t;
|
||||
|
||||
#ifdef ALTQ3_COMPAT
|
||||
typedef struct rio_queue {
|
||||
struct rio_queue *rq_next; /* next red_state in the list */
|
||||
struct ifaltq *rq_ifq; /* backpointer to ifaltq */
|
||||
|
||||
class_queue_t *rq_q;
|
||||
|
||||
rio_t *rq_rio;
|
||||
} rio_queue_t;
|
||||
#endif /* ALTQ3_COMPAT */
|
||||
|
||||
extern rio_t *rio_alloc(int, struct redparams *, int, int);
|
||||
extern void rio_destroy(rio_t *);
|
||||
extern void rio_getstats(rio_t *, struct redstats *);
|
||||
extern int rio_addq(rio_t *, class_queue_t *, struct mbuf *,
|
||||
struct altq_pktattr *);
|
||||
extern struct mbuf *rio_getq(rio_t *, class_queue_t *);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _ALTQ_ALTQ_RIO_H_ */
|
1832
sys/contrib/altq/altq/altq_rmclass.c
Normal file
1832
sys/contrib/altq/altq/altq_rmclass.c
Normal file
File diff suppressed because it is too large
Load Diff
266
sys/contrib/altq/altq/altq_rmclass.h
Normal file
266
sys/contrib/altq/altq/altq_rmclass.h
Normal file
@ -0,0 +1,266 @@
|
||||
/* $KAME: altq_rmclass.h,v 1.10 2003/08/20 23:30:23 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991-1997 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 Network Research
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _ALTQ_ALTQ_RMCLASS_H_
|
||||
#define _ALTQ_ALTQ_RMCLASS_H_
|
||||
|
||||
#include <altq/altq_classq.h>
|
||||
|
||||
/* #pragma ident "@(#)rm_class.h 1.20 97/10/23 SMI" */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RM_MAXPRIO 8 /* Max priority */
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
typedef struct mbuf mbuf_t;
|
||||
typedef struct rm_ifdat rm_ifdat_t;
|
||||
typedef struct rm_class rm_class_t;
|
||||
|
||||
struct red;
|
||||
|
||||
/*
|
||||
* Macros for dealing with time values. We assume all times are
|
||||
* 'timevals'. `microtime' is used to get the best available clock
|
||||
* resolution. If `microtime' *doesn't* return a value that's about
|
||||
* ten times smaller than the average packet time on the fastest
|
||||
* link that will use these routines, a slightly different clock
|
||||
* scheme than this one should be used.
|
||||
* (Bias due to truncation error in this scheme will overestimate utilization
|
||||
* and discriminate against high bandwidth classes. To remove this bias an
|
||||
* integrator needs to be added. The simplest integrator uses a history of
|
||||
* 10 * avg.packet.time / min.tick.time packet completion entries. This is
|
||||
* straight forward to add but we don't want to pay the extra memory
|
||||
* traffic to maintain it if it's not necessary (occasionally a vendor
|
||||
* accidentally builds a workstation with a decent clock - e.g., Sun & HP).)
|
||||
*/
|
||||
|
||||
#define RM_GETTIME(now) microtime(&now)
|
||||
|
||||
#define TV_LT(a, b) (((a)->tv_sec < (b)->tv_sec) || \
|
||||
(((a)->tv_usec < (b)->tv_usec) && ((a)->tv_sec <= (b)->tv_sec)))
|
||||
|
||||
#define TV_DELTA(a, b, delta) { \
|
||||
register int xxs; \
|
||||
\
|
||||
delta = (a)->tv_usec - (b)->tv_usec; \
|
||||
if ((xxs = (a)->tv_sec - (b)->tv_sec)) { \
|
||||
switch (xxs) { \
|
||||
default: \
|
||||
/* if (xxs < 0) \
|
||||
printf("rm_class: bogus time values\n"); */ \
|
||||
delta = 0; \
|
||||
/* fall through */ \
|
||||
case 2: \
|
||||
delta += 1000000; \
|
||||
/* fall through */ \
|
||||
case 1: \
|
||||
delta += 1000000; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define TV_ADD_DELTA(a, delta, res) { \
|
||||
register int xxus = (a)->tv_usec + (delta); \
|
||||
\
|
||||
(res)->tv_sec = (a)->tv_sec; \
|
||||
while (xxus >= 1000000) { \
|
||||
++((res)->tv_sec); \
|
||||
xxus -= 1000000; \
|
||||
} \
|
||||
(res)->tv_usec = xxus; \
|
||||
}
|
||||
|
||||
#define RM_TIMEOUT 2 /* 1 Clock tick. */
|
||||
|
||||
#if 1
|
||||
#define RM_MAXQUEUED 1 /* this isn't used in ALTQ/CBQ */
|
||||
#else
|
||||
#define RM_MAXQUEUED 16 /* Max number of packets downstream of CBQ */
|
||||
#endif
|
||||
#define RM_MAXQUEUE 64 /* Max queue length */
|
||||
#define RM_FILTER_GAIN 5 /* log2 of gain, e.g., 5 => 31/32 */
|
||||
#define RM_POWER (1 << RM_FILTER_GAIN)
|
||||
#define RM_MAXDEPTH 32
|
||||
#define RM_NS_PER_SEC (1000000000)
|
||||
|
||||
typedef struct _rm_class_stats_ {
|
||||
u_int handle;
|
||||
u_int depth;
|
||||
|
||||
struct pktcntr xmit_cnt; /* packets sent in this class */
|
||||
struct pktcntr drop_cnt; /* dropped packets */
|
||||
u_int over; /* # times went over limit */
|
||||
u_int borrows; /* # times tried to borrow */
|
||||
u_int overactions; /* # times invoked overlimit action */
|
||||
u_int delays; /* # times invoked delay actions */
|
||||
} rm_class_stats_t;
|
||||
|
||||
/*
|
||||
* CBQ Class state structure
|
||||
*/
|
||||
struct rm_class {
|
||||
class_queue_t *q_; /* Queue of packets */
|
||||
rm_ifdat_t *ifdat_;
|
||||
int pri_; /* Class priority. */
|
||||
int depth_; /* Class depth */
|
||||
u_int ns_per_byte_; /* NanoSeconds per byte. */
|
||||
u_int maxrate_; /* Bytes per second for this class. */
|
||||
u_int allotment_; /* Fraction of link bandwidth. */
|
||||
u_int w_allotment_; /* Weighted allotment for WRR */
|
||||
int bytes_alloc_; /* Allocation for round of WRR */
|
||||
|
||||
int avgidle_;
|
||||
int maxidle_;
|
||||
int minidle_;
|
||||
int offtime_;
|
||||
int sleeping_; /* != 0 if delaying */
|
||||
int qthresh_; /* Queue threshold for formal link sharing */
|
||||
int leaf_; /* Note whether leaf class or not.*/
|
||||
|
||||
rm_class_t *children_; /* Children of this class */
|
||||
rm_class_t *next_; /* Next pointer, used if child */
|
||||
|
||||
rm_class_t *peer_; /* Peer class */
|
||||
rm_class_t *borrow_; /* Borrow class */
|
||||
rm_class_t *parent_; /* Parent class */
|
||||
|
||||
void (*overlimit)(struct rm_class *, struct rm_class *);
|
||||
void (*drop)(struct rm_class *); /* Class drop action. */
|
||||
|
||||
struct red *red_; /* RED state pointer */
|
||||
struct altq_pktattr *pktattr_; /* saved hdr used by RED/ECN */
|
||||
int flags_;
|
||||
|
||||
int last_pkttime_; /* saved pkt_time */
|
||||
struct timeval undertime_; /* time can next send */
|
||||
struct timeval last_; /* time last packet sent */
|
||||
struct timeval overtime_;
|
||||
struct callout callout_; /* for timeout() calls */
|
||||
|
||||
rm_class_stats_t stats_; /* Class Statistics */
|
||||
};
|
||||
|
||||
/*
|
||||
* CBQ Interface state
|
||||
*/
|
||||
struct rm_ifdat {
|
||||
int queued_; /* # pkts queued downstream */
|
||||
int efficient_; /* Link Efficency bit */
|
||||
int wrr_; /* Enable Weighted Round-Robin */
|
||||
u_long ns_per_byte_; /* Link byte speed. */
|
||||
int maxqueued_; /* Max packets to queue */
|
||||
int maxpkt_; /* Max packet size. */
|
||||
int qi_; /* In/out pointers for downstream */
|
||||
int qo_; /* packets */
|
||||
|
||||
/*
|
||||
* Active class state and WRR state.
|
||||
*/
|
||||
rm_class_t *active_[RM_MAXPRIO]; /* Active cl's in each pri */
|
||||
int na_[RM_MAXPRIO]; /* # of active cl's in a pri */
|
||||
int num_[RM_MAXPRIO]; /* # of cl's per pri */
|
||||
int alloc_[RM_MAXPRIO]; /* Byte Allocation */
|
||||
u_long M_[RM_MAXPRIO]; /* WRR weights. */
|
||||
|
||||
/*
|
||||
* Network Interface/Solaris Queue state pointer.
|
||||
*/
|
||||
struct ifaltq *ifq_;
|
||||
rm_class_t *default_; /* Default Pkt class, BE */
|
||||
rm_class_t *root_; /* Root Link class. */
|
||||
rm_class_t *ctl_; /* Control Traffic class. */
|
||||
void (*restart)(struct ifaltq *); /* Restart routine. */
|
||||
|
||||
/*
|
||||
* Current packet downstream packet state and dynamic state.
|
||||
*/
|
||||
rm_class_t *borrowed_[RM_MAXQUEUED]; /* Class borrowed last */
|
||||
rm_class_t *class_[RM_MAXQUEUED]; /* class sending */
|
||||
int curlen_[RM_MAXQUEUED]; /* Current pktlen */
|
||||
struct timeval now_[RM_MAXQUEUED]; /* Current packet time. */
|
||||
int is_overlimit_[RM_MAXQUEUED];/* Current packet time. */
|
||||
|
||||
int cutoff_; /* Cut-off depth for borrowing */
|
||||
|
||||
struct timeval ifnow_; /* expected xmit completion time */
|
||||
#if 1 /* ALTQ4PPP */
|
||||
int maxiftime_; /* max delay inside interface */
|
||||
#endif
|
||||
rm_class_t *pollcache_; /* cached rm_class by poll operation */
|
||||
};
|
||||
|
||||
/* flags for rmc_init and rmc_newclass */
|
||||
/* class flags */
|
||||
#define RMCF_RED 0x0001
|
||||
#define RMCF_ECN 0x0002
|
||||
#define RMCF_RIO 0x0004
|
||||
#define RMCF_FLOWVALVE 0x0008 /* use flowvalve (aka penalty-box) */
|
||||
#define RMCF_CLEARDSCP 0x0010 /* clear diffserv codepoint */
|
||||
|
||||
/* flags for rmc_init */
|
||||
#define RMCF_WRR 0x0100
|
||||
#define RMCF_EFFICIENT 0x0200
|
||||
|
||||
#define is_a_parent_class(cl) ((cl)->children_ != NULL)
|
||||
|
||||
extern rm_class_t *rmc_newclass(int, struct rm_ifdat *, u_int,
|
||||
void (*)(struct rm_class *, struct rm_class *),
|
||||
int, struct rm_class *, struct rm_class *,
|
||||
u_int, int, u_int, int, int);
|
||||
extern void rmc_delete_class(struct rm_ifdat *, struct rm_class *);
|
||||
extern int rmc_modclass(struct rm_class *, u_int, int,
|
||||
u_int, int, u_int, int);
|
||||
extern void rmc_init(struct ifaltq *, struct rm_ifdat *, u_int,
|
||||
void (*)(struct ifaltq *),
|
||||
int, int, u_int, int, u_int, int);
|
||||
extern int rmc_queue_packet(struct rm_class *, mbuf_t *);
|
||||
extern mbuf_t *rmc_dequeue_next(struct rm_ifdat *, int);
|
||||
extern void rmc_update_class_util(struct rm_ifdat *);
|
||||
extern void rmc_delay_action(struct rm_class *, struct rm_class *);
|
||||
extern void rmc_dropall(struct rm_class *);
|
||||
extern int rmc_get_weight(struct rm_ifdat *, int);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ALTQ_ALTQ_RMCLASS_H_ */
|
112
sys/contrib/altq/altq/altq_rmclass_debug.h
Normal file
112
sys/contrib/altq/altq/altq_rmclass_debug.h
Normal file
@ -0,0 +1,112 @@
|
||||
/* $KAME: altq_rmclass_debug.h,v 1.3 2002/11/29 04:36:24 kjc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) Sun Microsystems, Inc. 1998 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 SMCC Technology
|
||||
* Development Group at Sun Microsystems, Inc.
|
||||
*
|
||||
* 4. The name of the Sun Microsystems, Inc nor may not be used to endorse or
|
||||
* promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* SUN MICROSYSTEMS DOES NOT CLAIM MERCHANTABILITY OF THIS SOFTWARE OR THE
|
||||
* SUITABILITY OF THIS SOFTWARE FOR ANY PARTICULAR PURPOSE. The software is
|
||||
* provided "as is" without express or implied warranty of any kind.
|
||||
*
|
||||
* These notices must be retained in any copies of any part of this software.
|
||||
*/
|
||||
|
||||
#ifndef _ALTQ_ALTQ_RMCLASS_DEBUG_H_
|
||||
#define _ALTQ_ALTQ_RMCLASS_DEBUG_H_
|
||||
|
||||
/* #pragma ident "@(#)rm_class_debug.h 1.7 98/05/04 SMI" */
|
||||
|
||||
/*
|
||||
* Cbq debugging macros
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef CBQ_TRACE
|
||||
#ifndef NCBQTRACE
|
||||
#define NCBQTRACE (16 * 1024)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* To view the trace output, using adb, type:
|
||||
* adb -k /dev/ksyms /dev/mem <cr>, then type
|
||||
* cbqtrace_count/D to get the count, then type
|
||||
* cbqtrace_buffer,0tcount/Dp4C" "Xn
|
||||
* This will dump the trace buffer from 0 to count.
|
||||
*/
|
||||
/*
|
||||
* in ALTQ, "call cbqtrace_dump(N)" from DDB to display 20 events
|
||||
* from Nth event in the circular buffer.
|
||||
*/
|
||||
|
||||
struct cbqtrace {
|
||||
int count;
|
||||
int function; /* address of function */
|
||||
int trace_action; /* descriptive 4 characters */
|
||||
int object; /* object operated on */
|
||||
};
|
||||
|
||||
extern struct cbqtrace cbqtrace_buffer[];
|
||||
extern struct cbqtrace *cbqtrace_ptr;
|
||||
extern int cbqtrace_count;
|
||||
|
||||
#define CBQTRACEINIT() { \
|
||||
if (cbqtrace_ptr == NULL) \
|
||||
cbqtrace_ptr = cbqtrace_buffer; \
|
||||
else { \
|
||||
cbqtrace_ptr = cbqtrace_buffer; \
|
||||
bzero((void *)cbqtrace_ptr, sizeof(cbqtrace_buffer)); \
|
||||
cbqtrace_count = 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define LOCK_TRACE() splimp()
|
||||
#define UNLOCK_TRACE(x) splx(x)
|
||||
|
||||
#define CBQTRACE(func, act, obj) { \
|
||||
int __s = LOCK_TRACE(); \
|
||||
int *_p = &cbqtrace_ptr->count; \
|
||||
*_p++ = ++cbqtrace_count; \
|
||||
*_p++ = (int)(func); \
|
||||
*_p++ = (int)(act); \
|
||||
*_p++ = (int)(obj); \
|
||||
if ((struct cbqtrace *)(void *)_p >= &cbqtrace_buffer[NCBQTRACE])\
|
||||
cbqtrace_ptr = cbqtrace_buffer; \
|
||||
else \
|
||||
cbqtrace_ptr = (struct cbqtrace *)(void *)_p; \
|
||||
UNLOCK_TRACE(__s); \
|
||||
}
|
||||
#else
|
||||
|
||||
/* If no tracing, define no-ops */
|
||||
#define CBQTRACEINIT()
|
||||
#define CBQTRACE(a, b, c)
|
||||
|
||||
#endif /* !CBQ_TRACE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ALTQ_ALTQ_RMCLASS_DEBUG_H_ */
|
1901
sys/contrib/altq/altq/altq_subr.c
Normal file
1901
sys/contrib/altq/altq/altq_subr.c
Normal file
File diff suppressed because it is too large
Load Diff
264
sys/contrib/altq/altq/altq_var.h
Normal file
264
sys/contrib/altq/altq/altq_var.h
Normal file
@ -0,0 +1,264 @@
|
||||
/* $KAME: altq_var.h,v 1.16 2003/10/03 05:05:15 kjc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1998-2003
|
||||
* 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_VAR_H_
|
||||
#define _ALTQ_ALTQ_VAR_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#ifdef ALTQ3_CLFIER_COMPAT
|
||||
/*
|
||||
* 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)
|
||||
|
||||
#if (__FreeBSD_version > 500000)
|
||||
#define ACC_LOCK_INIT(ac) mtx_init(&(ac)->acc_mtx, "classifier", MTX_DEF)
|
||||
#define ACC_LOCK_DESTROY(ac) mtx_destroy(&(ac)->acc_mtx)
|
||||
#define ACC_LOCK(ac) mtx_lock(&(ac)->acc_mtx)
|
||||
#define ACC_UNLOCK(ac) mtx_unlock(&(ac)->acc_mtx)
|
||||
#else
|
||||
#define ACC_LOCK_INIT(ac)
|
||||
#define ACC_LOCK_DESTROY(ac)
|
||||
#define ACC_LOCK(ac)
|
||||
#define ACC_UNLOCK(ac)
|
||||
#endif
|
||||
|
||||
struct acc_classifier {
|
||||
u_int32_t acc_fbmask;
|
||||
LIST_HEAD(filt, acc_filter) acc_filters[ACC_FILTER_TABLESIZE];
|
||||
|
||||
#if (__FreeBSD_version > 500000)
|
||||
struct mtx acc_mtx;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* 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)
|
||||
#endif /* ALTQ3_CLFIER_COMPAT */
|
||||
|
||||
/*
|
||||
* machine dependent clock
|
||||
* a 64bit high resolution time counter.
|
||||
*/
|
||||
extern int machclk_usepcc;
|
||||
extern u_int32_t machclk_freq;
|
||||
extern u_int32_t machclk_per_tick;
|
||||
extern void init_machclk(void);
|
||||
extern u_int64_t read_machclk(void);
|
||||
|
||||
/*
|
||||
* debug support
|
||||
*/
|
||||
#ifdef ALTQ_DEBUG
|
||||
#ifdef __STDC__
|
||||
#define ASSERT(e) ((e) ? (void)0 : altq_assert(__FILE__, __LINE__, #e))
|
||||
#else /* PCC */
|
||||
#define ASSERT(e) ((e) ? (void)0 : altq_assert(__FILE__, __LINE__, "e"))
|
||||
#endif
|
||||
#else
|
||||
#define ASSERT(e) ((void)0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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>
|
||||
|
||||
#if (__FreeBSD_version > 500000)
|
||||
#define CALLOUT_INIT(c) callout_init((c), 0)
|
||||
#else
|
||||
#define CALLOUT_INIT(c) callout_init((c))
|
||||
#endif
|
||||
#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 {
|
||||
struct timeout c_to;
|
||||
};
|
||||
#define CALLOUT_INIT(c) do { bzero((c), sizeof(*(c))); } while (/*CONSTCOND*/ 0)
|
||||
#define CALLOUT_RESET(c,t,f,a) do { if (!timeout_initialized(&(c)->c_to)) \
|
||||
timeout_set(&(c)->c_to, (f), (a)); \
|
||||
timeout_add(&(c)->c_to, (t)); } while (/*CONSTCOND*/ 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 *); /* functiuon to call */
|
||||
};
|
||||
#define CALLOUT_INIT(c) do { bzero((c), sizeof(*(c))); } while (/*CONSTCOND*/ 0)
|
||||
#define CALLOUT_RESET(c,t,f,a) do { (c)->c_arg = (a); \
|
||||
(c)->c_func = (f); \
|
||||
timeout((f),(a),(t)); } while (/*CONSTCOND*/ 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)
|
||||
|
||||
struct ifnet; struct mbuf;
|
||||
struct pf_altq;
|
||||
#ifdef ALTQ3_CLFIER_COMPAT
|
||||
struct flowinfo;
|
||||
#endif
|
||||
|
||||
void *altq_lookup(char *, int);
|
||||
#ifdef ALTQ3_CLFIER_COMPAT
|
||||
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);
|
||||
#endif
|
||||
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 *);
|
||||
int tbr_set(struct ifaltq *, struct tb_profile *);
|
||||
int tbr_get(struct ifaltq *, struct tb_profile *);
|
||||
|
||||
int altq_pfattach(struct pf_altq *);
|
||||
int altq_pfdetach(struct pf_altq *);
|
||||
int altq_add(struct pf_altq *);
|
||||
int altq_remove(struct pf_altq *);
|
||||
int altq_add_queue(struct pf_altq *);
|
||||
int altq_remove_queue(struct pf_altq *);
|
||||
int altq_getqstats(struct pf_altq *, void *, int *);
|
||||
|
||||
int cbq_pfattach(struct pf_altq *);
|
||||
int cbq_add_altq(struct pf_altq *);
|
||||
int cbq_remove_altq(struct pf_altq *);
|
||||
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_ */
|
29
sys/contrib/altq/altq/altqconf.h
Normal file
29
sys/contrib/altq/altq/altqconf.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* $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 $ */
|
||||
|
||||
#if defined(_KERNEL_OPT) || defined(__OpenBSD__)
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_altq_enabled.h"
|
||||
#endif
|
||||
|
||||
#include <sys/conf.h>
|
||||
|
||||
#ifdef ALTQ
|
||||
#define NALTQ 1
|
||||
#else
|
||||
#define NALTQ 0
|
||||
#endif
|
||||
|
||||
cdev_decl(altq);
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
#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 }
|
||||
#else
|
||||
#define cdev_altq_init(x,y) cdev__oci_init(x,y)
|
||||
#endif
|
||||
#endif /* defined(_KERNEL_OPT) || defined(__OpenBSD__) */
|
184
sys/contrib/altq/altq/if_altq.h
Normal file
184
sys/contrib/altq/altq/if_altq.h
Normal file
@ -0,0 +1,184 @@
|
||||
/* $KAME: if_altq.h,v 1.11 2003/07/10 12:07:50 kjc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1997-2003
|
||||
* 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_IF_ALTQ_H_
|
||||
#define _ALTQ_IF_ALTQ_H_
|
||||
|
||||
#if (defined(__FreeBSD__) && __FreeBSD_version >= 500000)
|
||||
#include <sys/lock.h> /* XXX */
|
||||
#include <sys/mutex.h> /* XXX */
|
||||
#include <sys/event.h> /* XXX */
|
||||
#endif
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include <altq/altqconf.h>
|
||||
#endif
|
||||
|
||||
struct altq_pktattr; struct tb_regulator; struct top_cdnr;
|
||||
|
||||
/*
|
||||
* Structure defining a queue for a network interface.
|
||||
*/
|
||||
struct ifaltq {
|
||||
/* fields compatible with struct ifqueue */
|
||||
struct mbuf *ifq_head;
|
||||
struct mbuf *ifq_tail;
|
||||
int ifq_len;
|
||||
int ifq_maxlen;
|
||||
int ifq_drops;
|
||||
#if (defined(__FreeBSD__) && __FreeBSD_version >= 500000)
|
||||
struct mtx ifq_mtx;
|
||||
#endif
|
||||
|
||||
/* alternate queueing related fields */
|
||||
int altq_type; /* discipline type */
|
||||
int altq_flags; /* flags (e.g. ready, in-use) */
|
||||
void *altq_disc; /* for discipline-specific use */
|
||||
struct ifnet *altq_ifp; /* back pointer to interface */
|
||||
|
||||
int (*altq_enqueue)(struct ifaltq *, struct mbuf *,
|
||||
struct altq_pktattr *);
|
||||
struct mbuf *(*altq_dequeue)(struct ifaltq *, int);
|
||||
int (*altq_request)(struct ifaltq *, int, void *);
|
||||
|
||||
/* classifier fields */
|
||||
void *altq_clfier; /* classifier-specific use */
|
||||
void *(*altq_classify)(void *, struct mbuf *, int);
|
||||
|
||||
/* token bucket regulator */
|
||||
struct tb_regulator *altq_tbr;
|
||||
|
||||
/* input traffic conditioner (doesn't belong to the output queue...) */
|
||||
struct top_cdnr *altq_cdnr;
|
||||
};
|
||||
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
/*
|
||||
* packet attributes used by queueing disciplines.
|
||||
* pattr_class is a discipline-dependent scheduling class that is
|
||||
* set by a classifier.
|
||||
* pattr_hdr and pattr_af may be used by a discipline to access
|
||||
* the header within a mbuf. (e.g. ECN needs to update the CE bit)
|
||||
* note that pattr_hdr could be stale after m_pullup, though link
|
||||
* layer output routines usually don't use m_pullup. link-level
|
||||
* compression also invalidates these fields. thus, pattr_hdr needs
|
||||
* to be verified when a discipline touches the header.
|
||||
*/
|
||||
struct altq_pktattr {
|
||||
void *pattr_class; /* sched class set by classifier */
|
||||
int pattr_af; /* address family */
|
||||
caddr_t pattr_hdr; /* saved header position in mbuf */
|
||||
};
|
||||
|
||||
/*
|
||||
* mbuf tag to carry a queue id (and hints for ECN).
|
||||
*/
|
||||
struct altq_tag {
|
||||
u_int32_t qid; /* queue id */
|
||||
/* hints for ecn */
|
||||
int af; /* address family */
|
||||
void *hdr; /* saved header position in mbuf */
|
||||
};
|
||||
|
||||
/*
|
||||
* a token-bucket regulator limits the rate that a network driver can
|
||||
* dequeue packets from the output queue.
|
||||
* modern cards are able to buffer a large amount of packets and dequeue
|
||||
* too many packets at a time. this bursty dequeue behavior makes it
|
||||
* impossible to schedule packets by queueing disciplines.
|
||||
* a token-bucket is used to control the burst size in a device
|
||||
* independent manner.
|
||||
*/
|
||||
struct tb_regulator {
|
||||
int64_t tbr_rate; /* (scaled) token bucket rate */
|
||||
int64_t tbr_depth; /* (scaled) token bucket depth */
|
||||
|
||||
int64_t tbr_token; /* (scaled) current token */
|
||||
int64_t tbr_filluptime; /* (scaled) time to fill up bucket */
|
||||
u_int64_t tbr_last; /* last time token was updated */
|
||||
|
||||
int tbr_lastop; /* last dequeue operation type
|
||||
needed for poll-and-dequeue */
|
||||
};
|
||||
|
||||
/* if_altqflags */
|
||||
#define ALTQF_READY 0x01 /* driver supports alternate queueing */
|
||||
#define ALTQF_ENABLED 0x02 /* altq is in use */
|
||||
#define ALTQF_CLASSIFY 0x04 /* classify packets */
|
||||
#define ALTQF_CNDTNING 0x08 /* altq traffic conditioning is enabled */
|
||||
#define ALTQF_DRIVER1 0x40 /* driver specific */
|
||||
|
||||
/* if_altqflags set internally only: */
|
||||
#define ALTQF_CANTCHANGE (ALTQF_READY)
|
||||
|
||||
/* altq_dequeue 2nd arg */
|
||||
#define ALTDQ_REMOVE 1 /* dequeue mbuf from the queue */
|
||||
#define ALTDQ_POLL 2 /* don't dequeue mbuf from the queue */
|
||||
|
||||
/* altq request types (currently only purge is defined) */
|
||||
#define ALTRQ_PURGE 1 /* purge all packets */
|
||||
|
||||
#define ALTQ_IS_READY(ifq) ((ifq)->altq_flags & ALTQF_READY)
|
||||
#define ALTQ_IS_ENABLED(ifq) ((ifq)->altq_flags & ALTQF_ENABLED)
|
||||
#define ALTQ_NEEDS_CLASSIFY(ifq) ((ifq)->altq_flags & ALTQF_CLASSIFY)
|
||||
#define ALTQ_IS_CNDTNING(ifq) ((ifq)->altq_flags & ALTQF_CNDTNING)
|
||||
|
||||
#define ALTQ_SET_CNDTNING(ifq) ((ifq)->altq_flags |= ALTQF_CNDTNING)
|
||||
#define ALTQ_CLEAR_CNDTNING(ifq) ((ifq)->altq_flags &= ~ALTQF_CNDTNING)
|
||||
#define ALTQ_IS_ATTACHED(ifq) ((ifq)->altq_disc != NULL)
|
||||
|
||||
#define ALTQ_ENQUEUE(ifq, m, pa, err) \
|
||||
(err) = (*(ifq)->altq_enqueue)((ifq),(m),(pa))
|
||||
#define ALTQ_DEQUEUE(ifq, m) \
|
||||
(m) = (*(ifq)->altq_dequeue)((ifq), ALTDQ_REMOVE)
|
||||
#define ALTQ_POLL(ifq, m) \
|
||||
(m) = (*(ifq)->altq_dequeue)((ifq), ALTDQ_POLL)
|
||||
#define ALTQ_PURGE(ifq) \
|
||||
(void)(*(ifq)->altq_request)((ifq), ALTRQ_PURGE, (void *)0)
|
||||
#define ALTQ_IS_EMPTY(ifq) ((ifq)->ifq_len == 0)
|
||||
#define TBR_IS_ENABLED(ifq) ((ifq)->altq_tbr != NULL)
|
||||
|
||||
extern int altq_attach(struct ifaltq *, int, void *,
|
||||
int (*)(struct ifaltq *, struct mbuf *,
|
||||
struct altq_pktattr *),
|
||||
struct mbuf *(*)(struct ifaltq *, int),
|
||||
int (*)(struct ifaltq *, int, void *),
|
||||
void *,
|
||||
void *(*)(void *, struct mbuf *, int));
|
||||
extern int altq_detach(struct ifaltq *);
|
||||
extern int altq_enable(struct ifaltq *);
|
||||
extern int altq_disable(struct ifaltq *);
|
||||
extern struct mbuf *tbr_dequeue(struct ifaltq *, int);
|
||||
extern int (*altq_input)(struct mbuf *, int);
|
||||
#if 1 /* ALTQ3_CLFIER_COMPAT */
|
||||
void altq_etherclassify(struct ifaltq *, struct mbuf *, struct altq_pktattr *);
|
||||
#endif
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _ALTQ_IF_ALTQ_H_ */
|
Loading…
Reference in New Issue
Block a user