diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2002-12-17 11:29:05 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2002-12-17 11:29:05 +0000 |
commit | ee72705e45d656d7a03fc939ed8c048a5da8d278 (patch) | |
tree | e2986f5e5fff0b12da445260fd88dc8dc288f683 /sbin | |
parent | eabd589313a494f3fbab881f2e89403b80c181be (diff) |
PRIQ and HFSC support functions, not yet used.
mostly from kjc@ with adjustments by me.
ok theo ryan daniel
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/pfctl/parse.y | 6 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_altq.c | 554 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_altq.h | 59 |
3 files changed, 558 insertions, 61 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index 494d6c31435..3a758e938f3 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.256 2002/12/16 23:36:14 henning Exp $ */ +/* $OpenBSD: parse.y,v 1.257 2002/12/17 11:29:04 henning Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -36,6 +36,10 @@ #include <netinet/icmp6.h> #include <net/pfvar.h> #include <arpa/inet.h> +#include <altq/altq.h> +#include <altq/altq_cbq.h> +#include <altq/altq_priq.h> +#include <altq/altq_hfsc.h> #include <stdio.h> #include <stdlib.h> diff --git a/sbin/pfctl/pfctl_altq.c b/sbin/pfctl/pfctl_altq.c index 59420645420..e35b34a10ec 100644 --- a/sbin/pfctl/pfctl_altq.c +++ b/sbin/pfctl/pfctl_altq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_altq.c,v 1.23 2002/12/17 01:15:59 henning Exp $ */ +/* $OpenBSD: pfctl_altq.c,v 1.24 2002/12/17 11:29:04 henning Exp $ */ /* * Copyright (C) 2002 @@ -45,20 +45,43 @@ #include <altq/altq.h> #include <altq/altq_cbq.h> +#include <altq/altq_priq.h> +#include <altq/altq_hfsc.h> #include "pfctl_parser.h" #include "pfctl_altq.h" -static int eval_pfqueue_cbq(struct pfctl *pf, struct pf_altq *); -static int cbq_compute_idletime(struct pfctl *, struct pf_altq *); -static int check_commit_cbq(int, int, struct pf_altq *); -static void print_cbq_opts(const struct pf_altq *); +#define is_sc_null(sc) (((sc) == NULL) || ((sc)->m1 == 0 && (sc)->m2 == 0)) + +TAILQ_HEAD(altqs, pf_altq) altqs = TAILQ_HEAD_INITIALIZER(altqs); +LIST_HEAD(gen_sc, segment) rtsc, lssc; + +static int eval_pfqueue_cbq(struct pfctl *pf, struct pf_altq *); +static int cbq_compute_idletime(struct pfctl *, struct pf_altq *); +static int check_commit_cbq(int, int, struct pf_altq *); +static void print_cbq_opts(const struct pf_altq *); + +static int eval_pfqueue_priq(struct pfctl *pf, struct pf_altq *); +static int check_commit_priq(int, int, struct pf_altq *); +static void print_priq_opts(const struct pf_altq *); + +static int eval_pfqueue_hfsc(struct pfctl *pf, struct pf_altq *); +static int check_commit_hfsc(int, int, struct pf_altq *); +static void print_hfsc_opts(const struct pf_altq *); + +static void gsc_add_sc(struct gen_sc *, struct service_curve *); +static int is_gsc_under_sc(struct gen_sc *, + struct service_curve *); +static void gsc_destroy(struct gen_sc *); +static struct segment *gsc_getentry(struct gen_sc *, double); +static int gsc_add_seg(struct gen_sc *, double, double, double, + double); +static double sc_x2y(struct service_curve *, double); + static char *rate2str(double); u_int32_t getifspeed(char *); u_long getifmtu(char *); -TAILQ_HEAD(altqs, pf_altq) altqs = TAILQ_HEAD_INITIALIZER(altqs); - void pfaltq_store(struct pf_altq *a) { @@ -152,6 +175,17 @@ print_altq(const struct pf_altq *a, unsigned level) print_cbq_opts(a); if (!a->pq_u.cbq_opts.flags) printf("cbq "); + break; + case ALTQT_PRIQ: + print_priq_opts(a); + if (!a->pq_u.priq_opts.flags) + printf("priq "); + break; + case ALTQT_HFSC: + print_hfsc_opts(a); + if (!a->pq_u.hfsc_opts.flags) + printf("hfsc "); + break; } printf("bandwidth %s ", rate2str((double)a->ifbandwidth)); @@ -178,9 +212,18 @@ print_queue(const struct pf_altq *a, unsigned level) case ALTQT_CBQ: print_cbq_opts(a); break; + case ALTQT_PRIQ: + print_priq_opts(a); + break; + case ALTQT_HFSC: + print_hfsc_opts(a); + break; } } +/* + * eval_pfaltq computes the discipline parameters. + */ int eval_pfaltq(struct pfctl *pf, struct pf_altq *pa, u_int32_t bw_absolute, u_int16_t bw_percent) @@ -218,18 +261,28 @@ eval_pfaltq(struct pfctl *pf, struct pf_altq *pa, u_int32_t bw_absolute, return (errors); } +/* + * check_commit_altq does consistency check for each interface + */ int check_commit_altq(int dev, int opts) { struct pf_altq *altq; int error = 0; + /* call the discipline check for each interface. */ TAILQ_FOREACH(altq, &altqs, entries) { if (altq->qname[0] == 0) { switch (altq->scheduler) { case ALTQT_CBQ: error = check_commit_cbq(dev, opts, altq); break; + case ALTQT_PRIQ: + error = check_commit_priq(dev, opts, altq); + break; + case ALTQT_HFSC: + error = check_commit_hfsc(dev, opts, altq); + break; default: break; } @@ -238,6 +291,9 @@ check_commit_altq(int dev, int opts) return (error); } +/* + * eval_pfqueue computes the queue parameters. + */ int eval_pfqueue(struct pfctl *pf, struct pf_altq *pa, u_int32_t bw_absolute, u_int16_t bw_percent) @@ -281,6 +337,12 @@ eval_pfqueue(struct pfctl *pf, struct pf_altq *pa, u_int32_t bw_absolute, case ALTQT_CBQ: error = eval_pfqueue_cbq(pf, pa); break; + case ALTQT_PRIQ: + error = eval_pfqueue_priq(pf, pa); + break; + case ALTQT_HFSC: + error = eval_pfqueue_hfsc(pf, pa); + break; default: break; } @@ -316,11 +378,10 @@ eval_pfqueue_cbq(struct pfctl *pf, struct pf_altq *pa) if (opts->pktsize > opts->maxpktsize) opts->pktsize = opts->maxpktsize; - if (pa->parent[0] == 0 || strcasecmp("NULL", pa->parent) == 0) + if (pa->parent[0] == 0) opts->flags |= (CBQCLF_ROOTCLASS | CBQCLF_WRR); cbq_compute_idletime(pf, pa); - return (0); } @@ -357,6 +418,7 @@ cbq_compute_idletime(struct pfctl *pf, struct pf_altq *pa) * (bandwidth < 6Kbps when max_pkt_size=1500) */ if (pa->bandwidth != 0 && (pf->opts & PF_OPT_QUIET) == 0) + warnx("queue bandwidth must be larger than 6Kb"); fprintf(stderr, "cbq: queue %s is too slow!\n", pa->qname); nsPerByte = (double)(INT_MAX / opts->maxpktsize); @@ -416,7 +478,7 @@ check_commit_cbq(int dev, int opts, struct pf_altq *pa) int error = 0; /* - * check if cbq has one root class and one default class + * check if cbq has one root queue and one default queue * for this interface */ root_class = default_class = 0; @@ -482,6 +544,477 @@ print_cbq_opts(const struct pf_altq *a) } } +/* + * PRIQ support functions + */ +static int +eval_pfqueue_priq(struct pfctl *pf, struct pf_altq *pa) +{ + struct pf_altq *altq; + + if (pa->parent[0] == 0) + /* this is for dummy root */ + return (0); + + if (pa->priority >= PRIQ_MAXPRI) { + warnx("priority out of range: max %d", PRIQ_MAXPRI - 1); + return (-1); + } + /* the priority should be unique for the interface */ + TAILQ_FOREACH(altq, &altqs, entries) { + if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) == 0 && + altq->qname[0] != 0 && altq->parent[0] != 0 && + altq->priority == pa->priority) { + warnx("%s and %s have the same priority", + altq->qname, pa->qname); + return (-1); + } + } + + if (pa->bandwidth != pa->ifbandwidth) + warnx("priq does not have a bandwidth parameter -- ignored"); + + return (0); +} + +static int +check_commit_priq(int dev, int opts, struct pf_altq *pa) +{ + struct pf_altq *altq; + int default_class; + int error = 0; + + /* + * check if priq has one default class for this interface + */ + default_class = 0; + TAILQ_FOREACH(altq, &altqs, entries) { + if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) != 0) + continue; + if (altq->qname[0] == 0) /* this is for interface */ + continue; + if (altq->parent[0] == 0) /* dummy root */ + continue; + if (altq->pq_u.priq_opts.flags & PRCF_DEFAULTCLASS) + default_class++; + } + if (default_class != 1) { + warnx("should have one default queue on %s", pa->ifname); + error++; + } + return (error); +} + +static void +print_priq_opts(const struct pf_altq *a) +{ + const struct priq_opts *opts; + + opts = &a->pq_u.priq_opts; + + if (opts->flags) { + printf("priq("); + if (opts->flags & PRCF_RED) + printf(" red"); + if (opts->flags & PRCF_ECN) + printf(" ecn"); + if (opts->flags & PRCF_RIO) + printf(" rio"); + if (opts->flags & PRCF_CLEARDSCP) + printf(" cleardscp"); + if (opts->flags & PRCF_DEFAULTCLASS) + printf(" default"); + printf(" ) "); + } +} + +/* + * HFSC support functions + */ +static int +eval_pfqueue_hfsc(struct pfctl *pf, struct pf_altq *pa) +{ + struct pf_altq *altq, *parent; + struct hfsc_opts *opts; + struct service_curve sc; + + if (pa->parent[0] == 0) { + /* this is for dummy root */ + pa->qid = HFSC_ROOTCLASS_HANDLE; + pa->pq_u.hfsc_opts.lssc_m2 = pa->ifbandwidth; + return (0); + } + + opts = &pa->pq_u.hfsc_opts; + LIST_INIT(&rtsc); + LIST_INIT(&lssc); + + /* if link_share is not specified, use bandwidth */ + if (opts->lssc_m2 == 0) + opts->lssc_m2 = pa->bandwidth; + + if ((opts->rtsc_m1 > 0 && opts->rtsc_m2 == 0) || + (opts->lssc_m1 > 0 && opts->lssc_m2 == 0) || + (opts->ulsc_m1 > 0 && opts->ulsc_m2 == 0)) { + warnx("m2 is zero for %s", pa->qname); + return (-1); + } + + if ((opts->rtsc_m1 < opts->rtsc_m2 && opts->rtsc_m1 != 0) || + (opts->rtsc_m1 < opts->rtsc_m2 && opts->rtsc_m1 != 0) || + (opts->rtsc_m1 < opts->rtsc_m2 && opts->rtsc_m1 != 0)) { + warnx("m1 must be zero for convex curve: %s", pa->qname); + return (-1); + } + + /* + * admission control: + * for the real-time service curve, the sum of the service curves + * should not exceed 80% of the interface bandwidth. 20% is reserved + * not to over-commit the actual interface bandwidth. + * for the link-sharing service curve, the sum of the child service + * curve should not exceed the parent service curve. + * for the upper-limit service curve, the assigned bandwidth should + * be smaller than the interface bandwidth, and the upper-limit should + * be larger than the real-time service curve when both are defined. + */ + parent = qname_to_pfaltq(pa->parent, pa->ifname); + if (parent == NULL) + errx(1, "parent %s not found for %s", pa->parent, pa->qname); + + TAILQ_FOREACH(altq, &altqs, entries) { + if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) != 0) + continue; + if (altq->qname[0] == 0) /* this is for interface */ + continue; + + /* if the class has a real-time service curve, add it. */ + if (opts->rtsc_m2 != 0 && altq->pq_u.hfsc_opts.rtsc_m2 != 0) { + sc.m1 = altq->pq_u.hfsc_opts.rtsc_m1; + sc.d = altq->pq_u.hfsc_opts.rtsc_d; + sc.m2 = altq->pq_u.hfsc_opts.rtsc_m2; + gsc_add_sc(&rtsc, &sc); + } + + if (strncmp(altq->parent, pa->parent, PF_QNAME_SIZE) != 0) + continue; + + /* if the class has a link-sharing service curve, add it. */ + if (opts->lssc_m2 != 0 && altq->pq_u.hfsc_opts.lssc_m2 != 0) { + sc.m1 = altq->pq_u.hfsc_opts.lssc_m1; + sc.d = altq->pq_u.hfsc_opts.lssc_d; + sc.m2 = altq->pq_u.hfsc_opts.lssc_m2; + gsc_add_sc(&lssc, &sc); + } + } + + /* check the real-time service curve. reserve 20% of interface bw */ + if (opts->rtsc_m2 != 0) { + sc.m1 = 0; + sc.d = 0; + sc.m2 = pa->ifbandwidth / 100 * 80; + if (!is_gsc_under_sc(&rtsc, &sc)) { + warnx("real-time sc exceeds the interface bandwidth"); + goto err_ret; + } + } + + /* check the link-sharing service curve. */ + if (opts->lssc_m2 != 0) { + sc.m1 = parent->pq_u.hfsc_opts.lssc_m1; + sc.d = parent->pq_u.hfsc_opts.lssc_d; + sc.m2 = parent->pq_u.hfsc_opts.lssc_m2; + if (!is_gsc_under_sc(&lssc, &sc)) { + warnx("link-sharing sc exceeds parent's sc"); + goto err_ret; + } + } + + /* check the upper-limit service curve. */ + if (opts->ulsc_m2 != 0) { + if (opts->ulsc_m1 > pa->ifbandwidth || + opts->ulsc_m2 > pa->ifbandwidth) { + warnx("upper-limit larger than interface bandwidth"); + goto err_ret; + } + if (opts->rtsc_m2 != 0 && opts->rtsc_m2 > opts->ulsc_m2) { + warnx("upper-limit sc smaller than real-time sc"); + goto err_ret; + } + } + + gsc_destroy(&rtsc); + gsc_destroy(&lssc); + + return (0); + +err_ret: + gsc_destroy(&rtsc); + gsc_destroy(&lssc); + return (-1); +} + +static int +check_commit_hfsc(int dev, int opts, struct pf_altq *pa) +{ + struct pf_altq *altq, *def = NULL; + int default_class; + int error = 0; + + /* check if hfsc has one default queue for this interface */ + default_class = 0; + TAILQ_FOREACH(altq, &altqs, entries) { + if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) != 0) + continue; + if (altq->qname[0] == 0) /* this is for interface */ + continue; + if (altq->parent[0] == 0) /* dummy root */ + continue; + if (altq->pq_u.hfsc_opts.flags & HFCF_DEFAULTCLASS) { + default_class++; + def = altq; + } + } + if (default_class != 1) { + warnx("should have one default queue on %s", pa->ifname); + error++; + } + /* make sure the default queue is a leaf */ + TAILQ_FOREACH(altq, &altqs, entries) { + if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) != 0) + continue; + if (altq->qname[0] == 0) /* this is for interface */ + continue; + if (strncmp(altq->parent, def->qname, PF_QNAME_SIZE) == 0) { + warnx("default queue is not a leaf"); + error++; + } + } + return (error); +} + +static void +print_hfsc_opts(const struct pf_altq *a) +{ + const struct hfsc_opts *opts; + + opts = &a->pq_u.hfsc_opts; + + printf("hfsc("); + if (opts->flags & HFCF_RED) + printf(" red"); + if (opts->flags & HFCF_ECN) + printf(" ecn"); + if (opts->flags & HFCF_RIO) + printf(" rio"); + if (opts->flags & HFCF_CLEARDSCP) + printf(" cleardscp"); + if (opts->flags & HFCF_DEFAULTCLASS) + printf(" default"); + if (opts->rtsc_m2 != 0) { + if (opts->rtsc_d != 0) + printf(" realtime(%s %ums %s)", + rate2str((double)opts->rtsc_m1), opts->rtsc_d, + rate2str((double)opts->rtsc_m2)); + else + printf(" realtime %s", + rate2str((double)opts->rtsc_m2)); + } + if (opts->lssc_m2 != 0) { + if (opts->lssc_d != 0) + printf(" linkshare(%s %ums %s)", + rate2str((double)opts->lssc_m1), opts->lssc_d, + rate2str((double)opts->lssc_m2)); + else + printf(" linkshare %s", + rate2str((double)opts->lssc_m2)); + } + if (opts->ulsc_m2 != 0) { + if (opts->ulsc_d != 0) + printf(" upperlimit(%s %ums %s)", + rate2str((double)opts->ulsc_m1), opts->ulsc_d, + rate2str((double)opts->ulsc_m2)); + else + printf(" upperlimit(%s)", + rate2str((double)opts->ulsc_m2)); + } + printf(" ) "); +} + +/* + * admission control using generalized service curve + */ +#define INFINITY HUGE_VAL /* positive infinity defined in <math.h> */ + +/* add a new service curve to a generilized service curve */ +static void +gsc_add_sc(struct gen_sc *gsc, struct service_curve *sc) +{ + if (is_sc_null(sc)) + return; + if (sc->d != 0) + gsc_add_seg(gsc, 0, 0, (double)sc->d, (double)sc->m1); + gsc_add_seg(gsc, (double)sc->d, 0, INFINITY, (double)sc->m2); +} + +/* + * check whether all points of a generalized service curve have + * their y-coordinates no larger than a given two-piece linear + * service curve. + */ +static int +is_gsc_under_sc(struct gen_sc *gsc, struct service_curve *sc) +{ + struct segment *s, *last, *end; + double y; + + if (is_sc_null(sc)) { + if (LIST_EMPTY(gsc)) + return (1); + LIST_FOREACH(s, gsc, _next) { + if (s->m != 0) + return (0); + } + return (1); + } + /* + * gsc has a dummy entry at the end with x = INFINITY. + * loop through up to this dummy entry. + */ + end = gsc_getentry(gsc, INFINITY); + if (end == NULL) + return (1); + last = NULL; + for (s = LIST_FIRST(gsc); s != end; s = LIST_NEXT(s, _next)) { + if (s->y > sc_x2y(sc, s->x)) + return (0); + last = s; + } + /* last now holds the real last segment */ + if (last == NULL) + return (1); + if (last->m > sc->m2) + return (0); + if (last->x < sc->d && last->m > sc->m1) { + y = last->y + (sc->d - last->x) * last->m; + if (y > sc_x2y(sc, sc->d)) + return (0); + } + return (1); +} + +static void +gsc_destroy(struct gen_sc *gsc) +{ + struct segment *s; + + while ((s = LIST_FIRST(gsc)) != NULL) { + LIST_REMOVE(s, _next); + free(s); + } +} + +/* + * return a segment entry starting at x. + * if gsc has no entry starting at x, a new entry is created at x. + */ +static struct segment * +gsc_getentry(struct gen_sc *gsc, double x) +{ + struct segment *new, *prev, *s; + + prev = NULL; + LIST_FOREACH(s, gsc, _next) { + if (s->x == x) + return (s); /* matching entry found */ + else if (s->x < x) + prev = s; + else + break; + } + + /* we have to create a new entry */ + if ((new = calloc(1, sizeof(struct segment))) == NULL) + return (NULL); + + new->x = x; + if (x == INFINITY || s == NULL) + new->d = 0; + else if (s->x == INFINITY) + new->d = INFINITY; + else + new->d = s->x - x; + if (prev == NULL) { + /* insert the new entry at the head of the list */ + new->y = 0; + new->m = 0; + LIST_INSERT_HEAD(gsc, new, _next); + } else { + /* + * the start point intersects with the segment pointed by + * prev. divide prev into 2 segments + */ + if (x == INFINITY) { + prev->d = INFINITY; + if (prev->m == 0) + new->y = prev->y; + else + new->y = INFINITY; + } else { + prev->d = x - prev->x; + new->y = prev->d * prev->m + prev->y; + } + new->m = prev->m; + LIST_INSERT_AFTER(prev, new, _next); + } + return (new); +} + +/* add a segment to a generalized service curve */ +static int +gsc_add_seg(struct gen_sc *gsc, double x, double y, double d, double m) +{ + struct segment *start, *end, *s; + double x2; + + if (d == INFINITY) + x2 = INFINITY; + else + x2 = x + d; + start = gsc_getentry(gsc, x); + end = gsc_getentry(gsc, x2); + if (start == NULL || end == NULL) + return (-1); + + for (s = start; s != end; s = LIST_NEXT(s, _next)) { + s->m += m; + s->y += y + (s->x - x) * m; + } + + end = gsc_getentry(gsc, INFINITY); + for (; s != end; s = LIST_NEXT(s, _next)) { + s->y += m * d; + } + + return (0); +} + +/* get y-projection of a service curve */ +static double +sc_x2y(struct service_curve *sc, double x) +{ + double y; + + if (x <= (double)sc->d) + /* y belongs to the 1st segment */ + y = x * (double)sc->m1; + else + /* y belongs to the 2nd segment */ + y = (double)sc->d * (double)sc->m1 + + (x - (double)sc->d) * (double)sc->m2; + return (y); +} + void pfctl_insert_altq_node(struct pf_altq_node **root, const struct pf_altq altq) @@ -589,6 +1122,7 @@ pfctl_free_altq_node(struct pf_altq_node *node) */ #define R2S_BUFS 8 #define RATESTR_MAX 16 + static char * rate2str(double rate) { diff --git a/sbin/pfctl/pfctl_altq.h b/sbin/pfctl/pfctl_altq.h index 71794b42872..86d4acef44f 100644 --- a/sbin/pfctl/pfctl_altq.h +++ b/sbin/pfctl/pfctl_altq.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_altq.h,v 1.6 2002/12/07 19:52:33 henning Exp $ */ +/* $OpenBSD: pfctl_altq.h,v 1.7 2002/12/17 11:29:04 henning Exp $ */ /* * Copyright (C) 2002 @@ -27,60 +27,19 @@ * SUCH DAMAGE. */ -/* - * misc defines needed by pfctl(8) for altq - * (copied from altq headers until we find a better way...) - */ -#ifndef ALTQT_NONE -/* 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_MAX 12 /* should be max discipline type + 1 */ -#endif - -#ifndef CBQCLF_RED -/* class flags shoud be same as class flags in rm_class.h */ -#define CBQCLF_RED 0x0001 /* use RED */ -#define CBQCLF_ECN 0x0002 /* use RED/ECN */ -#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 */ -#define CBQCLF_CTLCLASS 0x4000 /* control class */ -#define CBQCLF_CLASSMASK 0xf000 /* class mask */ -#endif - -#ifndef REDF_ECN4 -/* red flags */ -#define REDF_ECN4 0x01 /* use packet marking for IPv4 pkts */ -#define REDF_ECN6 0x02 /* use packet marking for IPv6 pkts */ -#define REDF_ECN (REDF_ECN4 | REDF_ECN6) -#define REDF_FLOWVALVE 0x04 /* use flowvalve (aka penalty-box) */ -#endif - #ifndef DEFAULT_PRIORITY #define DEFAULT_PRIORITY 1 #define DEFAULT_QLIMIT 50 #endif +/* + * generalized service curve used for admission control + */ +struct segment { + LIST_ENTRY(segment) _next; + double x, y, d, m; +}; + struct pf_altq_node { struct pf_altq altq; struct pf_altq_node *next; |