From: henning Date: Sat, 19 Apr 2014 14:22:32 +0000 (+0000) Subject: remove altq bits here, too X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=12aebd241ea5dcdd934b75bcdf55510ac2e7297d;p=openbsd remove altq bits here, too (i was convinced i committed that yesterday already, hrm) --- diff --git a/sbin/pfctl/Makefile b/sbin/pfctl/Makefile index aee713b8afe..489dcb310e4 100644 --- a/sbin/pfctl/Makefile +++ b/sbin/pfctl/Makefile @@ -1,8 +1,8 @@ -# $OpenBSD: Makefile,v 1.20 2013/10/12 12:16:10 henning Exp $ +# $OpenBSD: Makefile,v 1.21 2014/04/19 14:22:32 henning Exp $ PROG= pfctl -SRCS= pfctl.c parse.y pfctl_parser.c pf_print_state.c pfctl_altq.c -SRCS+= pfctl_osfp.c pfctl_radix.c pfctl_table.c pfctl_qstats.c +SRCS= pfctl.c parse.y pfctl_parser.c pf_print_state.c +SRCS+= pfctl_osfp.c pfctl_radix.c pfctl_table.c SRCS+= pfctl_optimize.c pf_ruleset.c pfctl_queue.c CFLAGS+= -Wall -Wmissing-prototypes -Wno-uninitialized CFLAGS+= -Wstrict-prototypes -I${.CURDIR} diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index 07b78055f1e..257aee4d70a 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.631 2014/01/22 00:21:16 henning Exp $ */ +/* $OpenBSD: parse.y,v 1.632 2014/04/19 14:22:32 henning Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -39,10 +39,6 @@ #include #include #include -#include -#include -#include -#include #include #include @@ -320,20 +316,6 @@ struct queue_opts { u_int qlimit; } queue_opts; -struct oldqueue_opts { - int marker; -#define OQOM_BWSPEC 0x01 -#define OQOM_SCHEDULER 0x02 -#define OQOM_PRIORITY 0x04 -#define OQOM_TBRSIZE 0x08 -#define OQOM_QLIMIT 0x10 - struct node_queue_bw queue_bwspec; - struct node_queue_opt scheduler; - int priority; - int tbrsize; - int qlimit; -} oldqueue_opts; - struct table_opts { int flags; int init_addr; @@ -371,12 +353,6 @@ void expand_rule(struct pf_rule *, int, struct node_if *, struct node_gid *, struct node_if *, struct node_icmp *, const char *); int expand_queue(char *, struct node_if *, struct queue_opts *); -int expand_altq(struct pf_altq *, struct node_if *, - struct node_queue *, struct node_queue_bw bwspec, - struct node_queue_opt *); -int expand_oldqueue(struct pf_altq *, struct node_if *, - struct node_queue *, struct node_queue_bw, - struct node_queue_opt *); int expand_skip_interface(struct node_if *); int getservice(char *); @@ -450,7 +426,6 @@ typedef struct { struct filter_opts filter_opts; struct antispoof_opts antispoof_opts; struct queue_opts queue_opts; - struct oldqueue_opts oldqueue_opts; struct scrub_opts scrub_opts; struct table_opts table_opts; struct pool_opts pool_opts; @@ -479,9 +454,8 @@ int parseport(char *, struct range *r, int); %token SYNPROXY FINGERPRINTS NOSYNC DEBUG SKIP HOSTID %token ANTISPOOF FOR INCLUDE MATCHES %token BITMASK RANDOM SOURCEHASH ROUNDROBIN LEASTSTATES STATICPORT PROBABILITY -%token WEIGHT -%token ALTQ CBQ PRIQ HFSC BANDWIDTH TBRSIZE LINKSHARE REALTIME UPPERLIMIT -%token QUEUE OLDQUEUE PRIORITY QLIMIT RTABLE RDOMAIN MINIMUM BURST PARENT +%token WEIGHT BANDWIDTH +%token QUEUE PRIORITY QLIMIT RTABLE RDOMAIN MINIMUM BURST PARENT %token LOAD RULESET_OPTIMIZATION RTABLE RDOMAIN PRIO ONCE DEFAULT %token STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE %token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY PFLOW @@ -525,18 +499,12 @@ int parseport(char *, struct range *r, int); %type logquick quick log logopts logopt %type antispoof_ifspc antispoof_iflst antispoof_if %type qname -%type qassign qassign_list qassign_item -%type scheduler -%type cbqflags_list cbqflags_item -%type priqflags_list priqflags_item -%type hfscopts_list hfscopts_item hfsc_opts %type bandwidth %type filter_opts filter_opt filter_opts_l %type filter_sets filter_set filter_sets_l %type antispoof_opts antispoof_opt antispoof_opts_l %type queue_opts queue_opt queue_opts_l optscs %type scspec -%type oldqueue_opts oldqueue_opt oldqueue_opts_l %type scrub_opts scrub_opt scrub_opts_l %type table_opts table_opt table_opts_l %type pool_opts pool_opt pool_opts_l @@ -550,8 +518,6 @@ ruleset : /* empty */ | ruleset anchorrule '\n' | ruleset loadrule '\n' | ruleset queuespec '\n' - | ruleset altqif '\n' - | ruleset oldqueuespec '\n' | ruleset varset '\n' | ruleset antispoof '\n' | ruleset tabledef '\n' @@ -1416,135 +1382,6 @@ scspec : bandwidth { } ; -altqif : ALTQ interface oldqueue_opts QUEUE qassign { - struct pf_altq a; - - memset(&a, 0, sizeof(a)); - if ($3.scheduler.qtype == ALTQT_NONE) { - yyerror("no scheduler specified!"); - YYERROR; - } - a.scheduler = $3.scheduler.qtype; - a.qlimit = $3.qlimit; - a.tbrsize = $3.tbrsize; - if ($5 == NULL) { - yyerror("no child queues specified"); - YYERROR; - } - if (expand_altq(&a, $2, $5, $3.queue_bwspec, - &$3.scheduler)) - YYERROR; - } - ; - -oldqueuespec : OLDQUEUE STRING interface oldqueue_opts qassign { - struct pf_altq a; - - memset(&a, 0, sizeof(a)); - if (strlcpy(a.qname, $2, sizeof(a.qname)) >= - sizeof(a.qname)) { - yyerror("queue name too long (max " - "%d chars)", PF_QNAME_SIZE-1); - free($2); - YYERROR; - } - free($2); - if ($4.tbrsize) { - yyerror("cannot specify tbrsize for queue"); - YYERROR; - } - if ($4.priority > 255) { - yyerror("priority out of range: max 255"); - YYERROR; - } - a.priority = $4.priority; - a.qlimit = $4.qlimit; - a.scheduler = $4.scheduler.qtype; - if (expand_oldqueue(&a, $3, $5, $4.queue_bwspec, - &$4.scheduler)) { - yyerror("errors in queue definition"); - YYERROR; - } - } - ; - -oldqueue_opts : { - bzero(&oldqueue_opts, sizeof oldqueue_opts); - oldqueue_opts.priority = DEFAULT_PRIORITY; - oldqueue_opts.qlimit = DEFAULT_QLIMIT; - oldqueue_opts.scheduler.qtype = ALTQT_NONE; - oldqueue_opts.queue_bwspec.bw_percent = 100; - } - oldqueue_opts_l - { $$ = oldqueue_opts; } - | /* empty */ { - bzero(&oldqueue_opts, sizeof oldqueue_opts); - oldqueue_opts.priority = DEFAULT_PRIORITY; - oldqueue_opts.qlimit = DEFAULT_QLIMIT; - oldqueue_opts.scheduler.qtype = ALTQT_NONE; - oldqueue_opts.queue_bwspec.bw_percent = 100; - $$ = oldqueue_opts; - } - ; - -oldqueue_opts_l : oldqueue_opts_l oldqueue_opt - | oldqueue_opt - ; - -oldqueue_opt : BANDWIDTH bandwidth { - if (oldqueue_opts.marker & OQOM_BWSPEC) { - yyerror("bandwidth cannot be respecified"); - YYERROR; - } - oldqueue_opts.marker |= OQOM_BWSPEC; - oldqueue_opts.queue_bwspec = $2; - } - | PRIORITY NUMBER { - if (oldqueue_opts.marker & OQOM_PRIORITY) { - yyerror("priority cannot be respecified"); - YYERROR; - } - if ($2 < 0 || $2 > 255) { - yyerror("priority out of range: max 255"); - YYERROR; - } - oldqueue_opts.marker |= OQOM_PRIORITY; - oldqueue_opts.priority = $2; - } - | QLIMIT NUMBER { - if (oldqueue_opts.marker & OQOM_QLIMIT) { - yyerror("qlimit cannot be respecified"); - YYERROR; - } - if ($2 < 0 || $2 > 65535) { - yyerror("qlimit out of range: max 65535"); - YYERROR; - } - oldqueue_opts.marker |= OQOM_QLIMIT; - oldqueue_opts.qlimit = $2; - } - | scheduler { - if (oldqueue_opts.marker & OQOM_SCHEDULER) { - yyerror("scheduler cannot be respecified"); - YYERROR; - } - oldqueue_opts.marker |= OQOM_SCHEDULER; - oldqueue_opts.scheduler = $1; - } - | TBRSIZE NUMBER { - if (oldqueue_opts.marker & OQOM_TBRSIZE) { - yyerror("tbrsize cannot be respecified"); - YYERROR; - } - if ($2 < 0 || $2 > 65535) { - yyerror("tbrsize too big: max 65535"); - YYERROR; - } - oldqueue_opts.marker |= OQOM_TBRSIZE; - oldqueue_opts.tbrsize = $2; - } - ; - bandwidth : STRING { double bps; char *cp; @@ -1598,207 +1435,6 @@ bandwidth : STRING { } ; -scheduler : CBQ { - $$.qtype = ALTQT_CBQ; - $$.data.cbq_opts.flags = 0; - } - | CBQ '(' cbqflags_list ')' { - $$.qtype = ALTQT_CBQ; - $$.data.cbq_opts.flags = $3; - } - | PRIQ { - $$.qtype = ALTQT_PRIQ; - $$.data.priq_opts.flags = 0; - } - | PRIQ '(' priqflags_list ')' { - $$.qtype = ALTQT_PRIQ; - $$.data.priq_opts.flags = $3; - } - | HFSC { - $$.qtype = ALTQT_HFSC; - bzero(&$$.data.hfsc_opts, - sizeof(struct node_hfsc_opts)); - } - | HFSC '(' hfsc_opts ')' { - $$.qtype = ALTQT_HFSC; - $$.data.hfsc_opts = $3; - } - ; - -cbqflags_list : cbqflags_item { $$ |= $1; } - | cbqflags_list comma cbqflags_item { $$ |= $3; } - ; - -cbqflags_item : DEFAULT { - $$ = CBQCLF_DEFCLASS; - } - | STRING { - if (!strcmp($1, "borrow")) - $$ = CBQCLF_BORROW; - else if (!strcmp($1, "red")) - $$ = CBQCLF_RED; - else if (!strcmp($1, "ecn")) - $$ = CBQCLF_RED|CBQCLF_ECN; - else { - yyerror("unknown cbq flag \"%s\"", $1); - free($1); - YYERROR; - } - free($1); - } - ; - -priqflags_list : priqflags_item { $$ |= $1; } - | priqflags_list comma priqflags_item { $$ |= $3; } - ; - -priqflags_item : DEFAULT { - $$ = PRCF_DEFAULTCLASS; - } - | STRING { - if (!strcmp($1, "red")) - $$ = PRCF_RED; - else if (!strcmp($1, "ecn")) - $$ = PRCF_RED|PRCF_ECN; - else { - yyerror("unknown priq flag \"%s\"", $1); - free($1); - YYERROR; - } - free($1); - } - ; - -hfsc_opts : { - bzero(&hfsc_opts, - sizeof(struct node_hfsc_opts)); - } - hfscopts_list { - $$ = hfsc_opts; - } - ; - -hfscopts_list : hfscopts_item - | hfscopts_list comma hfscopts_item - ; - -hfscopts_item : LINKSHARE bandwidth { - if (hfsc_opts.linkshare.used) { - yyerror("linkshare already specified"); - YYERROR; - } - hfsc_opts.linkshare.m2 = $2; - hfsc_opts.linkshare.used = 1; - } - | LINKSHARE '(' bandwidth comma NUMBER comma bandwidth ')' - { - if ($5 < 0 || $5 > INT_MAX) { - yyerror("timing in curve out of range"); - YYERROR; - } - if (hfsc_opts.linkshare.used) { - yyerror("linkshare already specified"); - YYERROR; - } - hfsc_opts.linkshare.m1 = $3; - hfsc_opts.linkshare.d = $5; - hfsc_opts.linkshare.m2 = $7; - hfsc_opts.linkshare.used = 1; - } - | REALTIME bandwidth { - if (hfsc_opts.realtime.used) { - yyerror("realtime already specified"); - YYERROR; - } - hfsc_opts.realtime.m2 = $2; - hfsc_opts.realtime.used = 1; - } - | REALTIME '(' bandwidth comma NUMBER comma bandwidth ')' - { - if ($5 < 0 || $5 > INT_MAX) { - yyerror("timing in curve out of range"); - YYERROR; - } - if (hfsc_opts.realtime.used) { - yyerror("realtime already specified"); - YYERROR; - } - hfsc_opts.realtime.m1 = $3; - hfsc_opts.realtime.d = $5; - hfsc_opts.realtime.m2 = $7; - hfsc_opts.realtime.used = 1; - } - | UPPERLIMIT bandwidth { - if (hfsc_opts.upperlimit.used) { - yyerror("upperlimit already specified"); - YYERROR; - } - hfsc_opts.upperlimit.m2 = $2; - hfsc_opts.upperlimit.used = 1; - } - | UPPERLIMIT '(' bandwidth comma NUMBER comma bandwidth ')' - { - if ($5 < 0 || $5 > INT_MAX) { - yyerror("timing in curve out of range"); - YYERROR; - } - if (hfsc_opts.upperlimit.used) { - yyerror("upperlimit already specified"); - YYERROR; - } - hfsc_opts.upperlimit.m1 = $3; - hfsc_opts.upperlimit.d = $5; - hfsc_opts.upperlimit.m2 = $7; - hfsc_opts.upperlimit.used = 1; - } - | DEFAULT { - hfsc_opts.flags |= HFCF_DEFAULTCLASS; - } - | STRING { - if (!strcmp($1, "red")) - hfsc_opts.flags |= HFCF_RED; - else if (!strcmp($1, "ecn")) - hfsc_opts.flags |= HFCF_RED|HFCF_ECN; - else { - yyerror("unknown hfsc flag \"%s\"", $1); - free($1); - YYERROR; - } - free($1); - } - ; - -qassign : /* empty */ { $$ = NULL; } - | qassign_item { $$ = $1; } - | '{' optnl qassign_list '}' { $$ = $3; } - ; - -qassign_list : qassign_item optnl { $$ = $1; } - | qassign_list comma qassign_item optnl { - $1->tail->next = $3; - $1->tail = $3; - $$ = $1; - } - ; - -qassign_item : STRING { - $$ = calloc(1, sizeof(struct node_queue)); - if ($$ == NULL) - err(1, "qassign_item: calloc"); - if (strlcpy($$->queue, $1, sizeof($$->queue)) >= - sizeof($$->queue)) { - yyerror("queue name '%s' too long (max " - "%d chars)", $1, sizeof($$->queue)-1); - free($1); - free($$); - YYERROR; - } - free($1); - $$->next = NULL; - $$->tail = $$; - } - ; - pfrule : action dir logquick interface af proto fromto filter_opts { @@ -4596,112 +4232,6 @@ expand_label(char *label, size_t len, const char *ifname, sa_family_t af, expand_label_nr("$nr", label, len); } -int -expand_altq(struct pf_altq *a, struct node_if *interfaces, - struct node_queue *nqueues, struct node_queue_bw bwspec, - struct node_queue_opt *opts) -{ - struct pf_altq pa, pb; - char qname[PF_QNAME_SIZE]; - struct node_queue *n; - struct node_queue_bw bw; - int errs = 0; - - LOOP_THROUGH(struct node_if, interface, interfaces, - memcpy(&pa, a, sizeof(struct pf_altq)); - if (strlcpy(pa.ifname, interface->ifname, - sizeof(pa.ifname)) >= sizeof(pa.ifname)) - errx(1, "expand_altq: strlcpy"); - - if (interface->not) { - yyerror("altq on ! is not supported"); - errs++; - } else if (interface->use_rdomain) { - yyerror("altq on rdomain is not supported"); - errs++; - } else { - if (eval_pfaltq(pf, &pa, &bwspec, opts)) - errs++; - else - if (pfctl_add_altq(pf, &pa)) - errs++; - - if (pf->opts & PF_OPT_VERBOSE) { - print_altq(&pf->paltq->altq, 0, - &bwspec, opts); - if (nqueues && nqueues->tail) { - printf("queue { "); - LOOP_THROUGH(struct node_queue, queue, - nqueues, - printf("%s ", - queue->queue); - ); - printf("}"); - } - printf("\n"); - } - - if (pa.scheduler == ALTQT_CBQ || - pa.scheduler == ALTQT_HFSC) { - /* now create a root queue */ - memset(&pb, 0, sizeof(struct pf_altq)); - if (strlcpy(qname, "root_", sizeof(qname)) >= - sizeof(qname)) - errx(1, "expand_altq: strlcpy"); - if (strlcat(qname, interface->ifname, - sizeof(qname)) >= sizeof(qname)) - errx(1, "expand_altq: strlcat"); - if (strlcpy(pb.qname, qname, - sizeof(pb.qname)) >= sizeof(pb.qname)) - errx(1, "expand_altq: strlcpy"); - if (strlcpy(pb.ifname, interface->ifname, - sizeof(pb.ifname)) >= sizeof(pb.ifname)) - errx(1, "expand_altq: strlcpy"); - pb.qlimit = pa.qlimit; - pb.scheduler = pa.scheduler; - bw.bw_absolute = pa.ifbandwidth; - bw.bw_percent = 0; - if (eval_pfqueue(pf, &pb, &bw, opts)) - errs++; - else - if (pfctl_add_altq(pf, &pb)) - errs++; - } - - LOOP_THROUGH(struct node_queue, queue, nqueues, - n = calloc(1, sizeof(struct node_queue)); - if (n == NULL) - err(1, "expand_altq: calloc"); - if (pa.scheduler == ALTQT_CBQ || - pa.scheduler == ALTQT_HFSC) - if (strlcpy(n->parent, qname, - sizeof(n->parent)) >= - sizeof(n->parent)) - errx(1, "expand_altq: strlcpy"); - if (strlcpy(n->queue, queue->queue, - sizeof(n->queue)) >= sizeof(n->queue)) - errx(1, "expand_altq: strlcpy"); - if (strlcpy(n->ifname, interface->ifname, - sizeof(n->ifname)) >= sizeof(n->ifname)) - errx(1, "expand_altq: strlcpy"); - n->scheduler = pa.scheduler; - n->next = NULL; - n->tail = n; - if (oqueues == NULL) - oqueues = n; - else { - oqueues->tail->next = n; - oqueues->tail = n; - } - ); - } - ); - FREE_LIST(struct node_if, interfaces); - FREE_LIST(struct node_queue, nqueues); - - return (errs); -} - int expand_queue(char *qname, struct node_if *interfaces, struct queue_opts *opts) { @@ -4755,143 +4285,6 @@ expand_queue(char *qname, struct node_if *interfaces, struct queue_opts *opts) return (0); } -int -expand_oldqueue(struct pf_altq *a, struct node_if *interfaces, - struct node_queue *nqueues, struct node_queue_bw bwspec, - struct node_queue_opt *opts) -{ - struct node_queue *n, *nq; - struct pf_altq pa; - u_int8_t found = 0; - u_int8_t errs = 0; - - if (oqueues == NULL) { - yyerror("queue %s has no parent", a->qname); - FREE_LIST(struct node_queue, nqueues); - return (1); - } - - LOOP_THROUGH(struct node_if, interface, interfaces, - LOOP_THROUGH(struct node_queue, tqueue, oqueues, - if (!strncmp(a->qname, tqueue->queue, PF_QNAME_SIZE) && - (interface->ifname[0] == 0 || - (!interface->not && !strncmp(interface->ifname, - tqueue->ifname, IFNAMSIZ)) || - (interface->not && strncmp(interface->ifname, - tqueue->ifname, IFNAMSIZ)))) { - /* found ourself in queues */ - found++; - - memcpy(&pa, a, sizeof(struct pf_altq)); - - if (pa.scheduler != ALTQT_NONE && - pa.scheduler != tqueue->scheduler) { - yyerror("exactly one scheduler type " - "per interface allowed"); - return (1); - } - pa.scheduler = tqueue->scheduler; - - /* scheduler dependent error checking */ - switch (pa.scheduler) { - case ALTQT_PRIQ: - if (nqueues != NULL) { - yyerror("priq queues cannot " - "have child queues"); - return (1); - } - if (bwspec.bw_absolute > 0 || - bwspec.bw_percent < 100) { - yyerror("priq doesn't take " - "bandwidth"); - return (1); - } - break; - default: - break; - } - - if (strlcpy(pa.ifname, tqueue->ifname, - sizeof(pa.ifname)) >= sizeof(pa.ifname)) - errx(1, "expand_queue: strlcpy"); - if (strlcpy(pa.parent, tqueue->parent, - sizeof(pa.parent)) >= sizeof(pa.parent)) - errx(1, "expand_queue: strlcpy"); - - if (eval_pfqueue(pf, &pa, &bwspec, opts)) - errs++; - else - if (pfctl_add_altq(pf, &pa)) - errs++; - - for (nq = nqueues; nq != NULL; nq = nq->next) { - if (!strcmp(a->qname, nq->queue)) { - yyerror("queue cannot have " - "itself as child"); - errs++; - continue; - } - n = calloc(1, - sizeof(struct node_queue)); - if (n == NULL) - err(1, "expand_queue: calloc"); - if (strlcpy(n->parent, a->qname, - sizeof(n->parent)) >= - sizeof(n->parent)) - errx(1, "expand_queue strlcpy"); - if (strlcpy(n->queue, nq->queue, - sizeof(n->queue)) >= - sizeof(n->queue)) - errx(1, "expand_queue strlcpy"); - if (strlcpy(n->ifname, tqueue->ifname, - sizeof(n->ifname)) >= - sizeof(n->ifname)) - errx(1, "expand_queue strlcpy"); - n->scheduler = tqueue->scheduler; - n->next = NULL; - n->tail = n; - if (oqueues == NULL) - oqueues = n; - else { - oqueues->tail->next = n; - oqueues->tail = n; - } - } - if ((pf->opts & PF_OPT_VERBOSE) && ( - (found == 1 && interface->ifname[0] == 0) || - (found > 0 && interface->ifname[0] != 0))) { - print_queue(&pf->paltq->altq, 0, - &bwspec, interface->ifname[0] != 0, - opts); - if (nqueues && nqueues->tail) { - printf("{ "); - LOOP_THROUGH(struct node_queue, - queue, nqueues, - printf("%s ", - queue->queue); - ); - printf("}"); - } - printf("\n"); - } - } - ); - ); - - FREE_LIST(struct node_queue, nqueues); - FREE_LIST(struct node_if, interfaces); - - if (!found) { - yyerror("queue %s has no parent", a->qname); - errs++; - } - - if (errs) - return (1); - else - return (0); -} - int collapse_redirspec(struct pf_pool *rpool, struct pf_rule *r, struct redirspec *rs, u_int8_t allow_if) @@ -5405,7 +4798,6 @@ lookup(char *s) { "af-to", AFTO}, { "all", ALL}, { "allow-opts", ALLOWOPTS}, - { "altq", ALTQ}, { "anchor", ANCHOR}, { "antispoof", ANTISPOOF}, { "any", ANY}, @@ -5415,7 +4807,6 @@ lookup(char *s) { "block", BLOCK}, { "block-policy", BLOCKPOLICY}, { "burst", BURST}, - { "cbq", CBQ}, { "code", CODE}, { "debug", DEBUG}, { "default", DEFAULT}, @@ -5434,7 +4825,6 @@ lookup(char *s) { "from", FROM}, { "global", GLOBAL}, { "group", GROUP}, - { "hfsc", HFSC}, { "hostid", HOSTID}, { "icmp-type", ICMPTYPE}, { "icmp6-type", ICMP6TYPE}, @@ -5447,7 +4837,6 @@ lookup(char *s) { "label", LABEL}, { "least-states", LEASTSTATES}, { "limit", LIMIT}, - { "linkshare", LINKSHARE}, { "load", LOAD}, { "log", LOG}, { "loginterface", LOGINTERFACE}, @@ -5467,7 +4856,6 @@ lookup(char *s) { "no-df", NODF}, { "no-route", NOROUTE}, { "no-sync", NOSYNC}, - { "oldqueue", OLDQUEUE}, { "on", ON}, { "once", ONCE}, { "optimization", OPTIMIZATION}, @@ -5479,8 +4867,6 @@ lookup(char *s) { "pflow", PFLOW}, { "port", PORT}, { "prio", PRIO}, - { "priority", PRIORITY}, - { "priq", PRIQ}, { "probability", PROBABILITY}, { "proto", PROTO}, { "qlimit", QLIMIT}, @@ -5490,7 +4876,6 @@ lookup(char *s) { "random-id", RANDOMID}, { "rdomain", RDOMAIN}, { "rdr-to", RDRTO}, - { "realtime", REALTIME}, { "reassemble", REASSEMBLE}, { "received-on", RECEIVEDON}, { "reply-to", REPLYTO}, @@ -5519,12 +4904,10 @@ lookup(char *s) { "table", TABLE}, { "tag", TAG}, { "tagged", TAGGED}, - { "tbrsize", TBRSIZE}, { "timeout", TIMEOUT}, { "to", TO}, { "tos", TOS}, { "ttl", TTL}, - { "upperlimit", UPPERLIMIT}, { "urpf-failed", URPFFAILED}, { "user", USER}, { "weight", WEIGHT}, diff --git a/sbin/pfctl/pfctl.8 b/sbin/pfctl/pfctl.8 index cca91458862..66bcb4d697d 100644 --- a/sbin/pfctl/pfctl.8 +++ b/sbin/pfctl/pfctl.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pfctl.8,v 1.163 2013/07/21 17:22:49 jmc Exp $ +.\" $OpenBSD: pfctl.8,v 1.164 2014/04/19 14:22:32 henning Exp $ .\" .\" Copyright (c) 2001 Kjell Wooding. All rights reserved. .\" @@ -24,7 +24,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: July 21 2013 $ +.Dd $Mdocdate: April 19 2014 $ .Dt PFCTL 8 .Os .Sh NAME @@ -183,8 +183,6 @@ Flush the filter parameters specified by (may be abbreviated): .Pp .Bl -tag -width xxxxxxxxxxxx -compact -.It Fl F Cm queue -Flush the queue rules. .It Fl F Cm rules Flush the filter rules. .It Fl F Cm states @@ -333,7 +331,7 @@ Show the filter parameters specified by .Pp .Bl -tag -width xxxxxxxxxxxxxx -compact .It Fl s Cm queue -Show the currently loaded queue rules. +Show the currently loaded queue definitions. When used together with .Fl v , per-queue statistics are also shown. diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index 64c1e0aed40..37b2db0415a 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl.c,v 1.324 2014/04/11 02:56:41 jsg Exp $ */ +/* $OpenBSD: pfctl.c,v 1.325 2014/04/19 14:22:32 henning Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -40,7 +40,6 @@ #include #include #include -#include #include #include @@ -65,7 +64,6 @@ int pfctl_disable(int, int); int pfctl_clear_stats(int, const char *, int); int pfctl_clear_interface_flags(int, int); int pfctl_clear_rules(int, int, char *); -int pfctl_clear_altq(int, int); int pfctl_clear_src_nodes(int, int); int pfctl_clear_states(int, const char *, int); void pfctl_addrprefix(char *, struct pf_addr *); @@ -90,7 +88,6 @@ int pfctl_show_status(int, int); int pfctl_show_timeouts(int, int); int pfctl_show_limits(int, int); void pfctl_debug(int, u_int32_t, int); -int pfctl_test_altqsupport(int, int); int pfctl_show_anchors(int, int, char *); int pfctl_ruleset_trans(struct pfctl *, char *, struct pf_anchor *); u_int pfctl_find_childqs(struct pfctl_qsitem *); @@ -121,8 +118,6 @@ int src_node_killers; char *src_node_kill[2]; int state_killers; char *state_kill[2]; -int loadaltq = 1; -int altqsupport; int dev = -1; int first_title = 1; @@ -207,8 +202,7 @@ static const struct { }; static const char *clearopt_list[] = { - "queue", "rules", "Sources", - "states", "info", "Tables", "osfp", "all", NULL + "rules", "Sources", "states", "info", "Tables", "osfp", "all", NULL }; static const char *showopt_list[] = { @@ -261,10 +255,6 @@ pfctl_enable(int dev, int opts) if ((opts & PF_OPT_QUIET) == 0) fprintf(stderr, "pf enabled\n"); - if (altqsupport && ioctl(dev, DIOCSTARTALTQ)) - if (errno != EEXIST) - err(1, "DIOCSTARTALTQ"); - return (0); } @@ -280,10 +270,6 @@ pfctl_disable(int dev, int opts) if ((opts & PF_OPT_QUIET) == 0) fprintf(stderr, "pf disabled\n"); - if (altqsupport && ioctl(dev, DIOCSTOPALTQ)) - if (errno != ENOENT) - err(1, "DIOCSTOPALTQ"); - return (0); } @@ -341,23 +327,6 @@ pfctl_clear_rules(int dev, int opts, char *anchorname) return (0); } -int -pfctl_clear_altq(int dev, int opts) -{ - struct pfr_buffer t; - if (!altqsupport) - return (-1); - memset(&t, 0, sizeof(t)); - t.pfrb_type = PFRB_TRANS; - if (pfctl_add_trans(&t, PF_TRANS_ALTQ, "") || - pfctl_trans(dev, &t, DIOCXBEGIN, 0) || - pfctl_trans(dev, &t, DIOCXCOMMIT, 0)) - err(1, "pfctl_clear_altq"); - if ((opts & PF_OPT_QUIET) == 0) - fprintf(stderr, "altq cleared\n"); - return (0); -} - int pfctl_clear_src_nodes(int dev, int opts) { @@ -1125,10 +1094,6 @@ pfctl_ruleset_trans(struct pfctl *pf, char *path, struct pf_anchor *a) { int osize = pf->trans->pfrb_size; - if (a == pf->astack[0] && (altqsupport && loadaltq)) { - if (pfctl_add_trans(pf->trans, PF_TRANS_ALTQ, path)) - return (2); - } if (pfctl_add_trans(pf->trans, PF_TRANS_RULESET, path)) return (3); if (pfctl_add_trans(pf->trans, PF_TRANS_TABLE, path)) @@ -1439,27 +1404,6 @@ pfctl_load_rule(struct pfctl *pf, char *path, struct pf_rule *r, int depth) return (0); } -int -pfctl_add_altq(struct pfctl *pf, struct pf_altq *a) -{ - if (altqsupport) { - memcpy(&pf->paltq->altq, a, sizeof(struct pf_altq)); - if ((pf->opts & PF_OPT_NOACTION) == 0) { - if (ioctl(pf->dev, DIOCADDALTQ, pf->paltq)) { - if (errno == ENXIO) - errx(1, "qtype not configured"); - else if (errno == ENODEV) - errx(1, "%s: driver does not support " - "altq", a->ifname); - else - err(1, "DIOCADDALTQ"); - } - } - pfaltq_store(&pf->paltq->altq); - } - return (0); -} - int pfctl_rules(int dev, char *filename, int opts, int optimize, char *anchorname, struct pfr_buffer *trans) @@ -1468,7 +1412,6 @@ pfctl_rules(int dev, char *filename, int opts, int optimize, #define ERRX(x) do { warnx(x); goto _error; } while(0) struct pfr_buffer *t, buf; - struct pfioc_altq pa; struct pfctl pf; struct pf_ruleset *rs; struct pfr_table trs; @@ -1490,7 +1433,6 @@ pfctl_rules(int dev, char *filename, int opts, int optimize, osize = t->pfrb_size; } - memset(&pa, 0, sizeof(pa)); memset(&pf, 0, sizeof(pf)); memset(&trs, 0, sizeof(trs)); if ((path = calloc(1, MAXPATHLEN)) == NULL) @@ -1501,8 +1443,6 @@ pfctl_rules(int dev, char *filename, int opts, int optimize, pf.dev = dev; pf.opts = opts; pf.optimize = optimize; - if (anchorname[0]) - loadaltq = 0; /* non-brace anchor, create without resolving the path */ if ((pf.anchor = calloc(1, sizeof(*pf.anchor))) == NULL) @@ -1520,7 +1460,6 @@ pfctl_rules(int dev, char *filename, int opts, int optimize, pf.astack[0] = pf.anchor; pf.asd = 0; - pf.paltq = &pa; pf.trans = t; pfctl_init_options(&pf); @@ -1532,9 +1471,6 @@ pfctl_rules(int dev, char *filename, int opts, int optimize, */ if (pfctl_ruleset_trans(&pf, anchorname, pf.anchor)) ERRX("pfctl_rules"); - if (altqsupport && loadaltq) - pa.ticket = - pfctl_get_ticket(t, PF_TRANS_ALTQ, anchorname); pf.astack[0]->ruleset.tticket = pfctl_get_ticket(t, PF_TRANS_TABLE, anchorname); } @@ -1565,9 +1501,6 @@ pfctl_rules(int dev, char *filename, int opts, int optimize, free(path); path = NULL; - if (altqsupport && loadaltq && check_commit_altq(dev, opts) != 0) - ERRX("errors in altq config"); - /* process "load anchor" directives */ if (!anchorname[0]) if (pfctl_load_anchors(dev, &pf, t) == -1) @@ -2004,23 +1937,6 @@ pfctl_debug(int dev, u_int32_t level, int opts) loglevel_to_string(level)); } -int -pfctl_test_altqsupport(int dev, int opts) -{ - struct pfioc_altq pa; - - if (ioctl(dev, DIOCGETALTQS, &pa)) { - if (errno == ENODEV) { - if (!(opts & PF_OPT_QUIET)) - fprintf(stderr, "No ALTQ support in kernel\n" - "ALTQ related functions disabled\n"); - return (0); - } else - err(1, "DIOCGETALTQS"); - } - return (1); -} - int pfctl_show_anchors(int dev, int opts, char *anchorname) { @@ -2335,7 +2251,6 @@ main(int argc, char *argv[]) dev = open(pf_device, mode); if (dev == -1) err(1, "%s", pf_device); - altqsupport = pfctl_test_altqsupport(dev, opts); } else { dev = open(pf_device, O_RDONLY); if (dev >= 0) @@ -2343,7 +2258,6 @@ main(int argc, char *argv[]) /* turn off options */ opts &= ~ (PF_OPT_DISABLE | PF_OPT_ENABLE); clearopt = showopt = debugopt = NULL; - altqsupport = 1; } if (opts & PF_OPT_DISABLE) @@ -2368,8 +2282,6 @@ main(int argc, char *argv[]) case 'q': pfctl_show_queues(dev, ifaceopt, opts, opts & PF_OPT_VERBOSE2); - pfctl_show_altq(dev, ifaceopt, opts, - opts & PF_OPT_VERBOSE2); break; case 's': pfctl_show_states(dev, ifaceopt, opts); @@ -2392,7 +2304,6 @@ main(int argc, char *argv[]) pfctl_show_rules(dev, path, opts, 0, anchorname, 0, 0, -1); - pfctl_show_altq(dev, ifaceopt, opts, 0); pfctl_show_states(dev, ifaceopt, opts); pfctl_show_src_nodes(dev, opts); pfctl_show_status(dev, opts); @@ -2429,9 +2340,6 @@ main(int argc, char *argv[]) case 'r': pfctl_clear_rules(dev, opts, anchorname); break; - case 'q': - pfctl_clear_altq(dev, opts); - break; case 's': pfctl_clear_states(dev, ifaceopt, opts); break; @@ -2450,7 +2358,6 @@ main(int argc, char *argv[]) /* NOTREACHED */ } if (!*anchorname) { - pfctl_clear_altq(dev, opts); pfctl_clear_states(dev, ifaceopt, opts); pfctl_clear_src_nodes(dev, opts); pfctl_clear_stats(dev, ifaceopt, opts); diff --git a/sbin/pfctl/pfctl.h b/sbin/pfctl/pfctl.h index 828609face7..39a45d3571d 100644 --- a/sbin/pfctl/pfctl.h +++ b/sbin/pfctl/pfctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl.h,v 1.51 2013/10/12 12:16:11 henning Exp $ */ +/* $OpenBSD: pfctl.h,v 1.52 2014/04/19 14:22:32 henning Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -79,7 +79,6 @@ int pfctl_clear_tables(const char *, int); int pfctl_show_tables(const char *, int); int pfctl_command_tables(int, char *[], char *, const char *, char *, const char *, int); -int pfctl_show_altq(int, const char *, int, int); void warn_namespace_collision(const char *); int pfctl_show_ifaces(const char *, int); FILE *pfctl_fopen(const char *, const char *); @@ -100,11 +99,6 @@ struct segment { double x, y, d, m; }; -int check_commit_altq(int, int); -void pfaltq_store(struct pf_altq *); -struct pf_altq *pfaltq_lookup(const char *); -char *rate2str(double); - void print_addr(struct pf_addr_wrap *, sa_family_t, int); void print_host(struct pf_addr *, u_int16_t p, sa_family_t, u_int16_t, const char *, int); void print_seq(struct pfsync_state_peer *); diff --git a/sbin/pfctl/pfctl_altq.c b/sbin/pfctl/pfctl_altq.c deleted file mode 100644 index 4e32053e5dc..00000000000 --- a/sbin/pfctl/pfctl_altq.c +++ /dev/null @@ -1,1205 +0,0 @@ -/* $OpenBSD: pfctl_altq.c,v 1.101 2014/01/19 04:14:34 claudio Exp $ */ - -/* - * Copyright (c) 2002 - * Sony Computer Science Laboratories Inc. - * Copyright (c) 2002, 2003 Henning Brauer - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "pfctl_parser.h" -#include "pfctl.h" - -#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; - -struct pf_altq *qname_to_pfaltq(const char *, const char *); -u_int32_t qname_to_qid(const char *); - -static int eval_pfqueue_cbq(struct pfctl *, struct pf_altq *); -static int cbq_compute_idletime(struct pfctl *, struct pf_altq *); -static int check_commit_cbq(int, int, struct pf_altq *); -static int print_cbq_opts(const struct pf_altq *); - -static int eval_pfqueue_priq(struct pfctl *, struct pf_altq *); -static int check_commit_priq(int, int, struct pf_altq *); -static int print_priq_opts(const struct pf_altq *); - -static int eval_pfqueue_hfsc(struct pfctl *, struct pf_altq *); -static int check_commit_hfsc(int, int, struct pf_altq *); -static int print_hfsc_opts(const struct pf_altq *, - const struct node_queue_opt *); - -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); - -u_int32_t getifspeed(char *); -u_long getifmtu(char *); -int eval_queue_opts(struct pf_altq *, struct node_queue_opt *, - u_int32_t); -u_int32_t eval_bwspec(struct node_queue_bw *, u_int32_t); -void print_hfsc_sc(const char *, u_int, u_int, u_int, - const struct node_hfsc_sc *); - -void -pfaltq_store(struct pf_altq *a) -{ - struct pf_altq *altq; - - if ((altq = malloc(sizeof(*altq))) == NULL) - err(1, "malloc"); - memcpy(altq, a, sizeof(struct pf_altq)); - TAILQ_INSERT_TAIL(&altqs, altq, entries); -} - -struct pf_altq * -pfaltq_lookup(const char *ifname) -{ - struct pf_altq *altq; - - TAILQ_FOREACH(altq, &altqs, entries) { - if (strncmp(ifname, altq->ifname, IFNAMSIZ) == 0 && - altq->qname[0] == 0) - return (altq); - } - return (NULL); -} - -struct pf_altq * -qname_to_pfaltq(const char *qname, const char *ifname) -{ - struct pf_altq *altq; - - TAILQ_FOREACH(altq, &altqs, entries) { - if (strncmp(ifname, altq->ifname, IFNAMSIZ) == 0 && - strncmp(qname, altq->qname, PF_QNAME_SIZE) == 0) - return (altq); - } - return (NULL); -} - -u_int32_t -qname_to_qid(const char *qname) -{ - struct pf_altq *altq; - - /* - * We guarantee that same named queues on different interfaces - * have the same qid, so we do NOT need to limit matching on - * one interface! - */ - - TAILQ_FOREACH(altq, &altqs, entries) { - if (strncmp(qname, altq->qname, PF_QNAME_SIZE) == 0) - return (altq->qid); - } - return (0); -} - -void -print_altq(const struct pf_altq *a, unsigned int level, - struct node_queue_bw *bw, struct node_queue_opt *qopts) -{ - if (a->qname[0] != 0) { - print_queue(a, level, bw, 1, qopts); - return; - } - - printf("altq on %s ", a->ifname); - - switch (a->scheduler) { - case ALTQT_CBQ: - if (!print_cbq_opts(a)) - printf("cbq "); - break; - case ALTQT_PRIQ: - if (!print_priq_opts(a)) - printf("priq "); - break; - case ALTQT_HFSC: - if (!print_hfsc_opts(a, qopts)) - printf("hfsc "); - break; - } - - if (bw != NULL && bw->bw_percent > 0) { - if (bw->bw_percent < 100) - printf("bandwidth %u%% ", bw->bw_percent); - } else - printf("bandwidth %s ", rate2str((double)a->ifbandwidth)); - - if (a->qlimit != DEFAULT_QLIMIT) - printf("qlimit %u ", a->qlimit); - printf("tbrsize %u ", a->tbrsize); -} - -void -print_queue(const struct pf_altq *a, unsigned int level, - struct node_queue_bw *bw, int print_interface, - struct node_queue_opt *qopts) -{ - unsigned int i; - - printf("oldqueue "); - for (i = 0; i < level; ++i) - printf(" "); - printf("%s ", a->qname); - if (print_interface) - printf("on %s ", a->ifname); - if (a->scheduler == ALTQT_CBQ || a->scheduler == ALTQT_HFSC) { - if (bw != NULL && bw->bw_percent > 0) { - if (bw->bw_percent < 100) - printf("bandwidth %u%% ", bw->bw_percent); - } else - printf("bandwidth %s ", rate2str((double)a->bandwidth)); - } - if (a->priority != DEFAULT_PRIORITY) - printf("priority %u ", a->priority); - if (a->qlimit != DEFAULT_QLIMIT) - printf("qlimit %u ", a->qlimit); - switch (a->scheduler) { - case ALTQT_CBQ: - print_cbq_opts(a); - break; - case ALTQT_PRIQ: - print_priq_opts(a); - break; - case ALTQT_HFSC: - print_hfsc_opts(a, qopts); - break; - } -} - -/* - * eval_pfaltq computes the discipline parameters. - */ -int -eval_pfaltq(struct pfctl *pf, struct pf_altq *pa, struct node_queue_bw *bw, - struct node_queue_opt *opts) -{ - u_int rate, size, errors = 0; - - if (bw->bw_absolute > 0) - pa->ifbandwidth = bw->bw_absolute; - else - if ((rate = getifspeed(pa->ifname)) == 0) { - fprintf(stderr, "interface %s does not know its bandwidth, " - "please specify an absolute bandwidth\n", - pa->ifname); - errors++; - } else if ((pa->ifbandwidth = eval_bwspec(bw, rate)) == 0) - pa->ifbandwidth = rate; - - errors += eval_queue_opts(pa, opts, pa->ifbandwidth); - - /* if tbrsize is not specified, use heuristics */ - if (pa->tbrsize == 0) { - rate = pa->ifbandwidth; - if (rate <= 1 * 1000 * 1000) - size = 1; - else if (rate <= 10 * 1000 * 1000) - size = 4; - else if (rate <= 200 * 1000 * 1000) - size = 8; - else - size = 24; - - if ((pf->opts & PF_OPT_NOACTION) == 0) - size = size * getifmtu(pa->ifname); - else - size = size * 1500; - - if (size > 0xffff) - size = 0xffff; - pa->tbrsize = size; - } - 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; - } - } - } - return (error); -} - -/* - * eval_pfqueue computes the queue parameters. - */ -int -eval_pfqueue(struct pfctl *pf, struct pf_altq *pa, struct node_queue_bw *bw, - struct node_queue_opt *opts) -{ - /* should be merged with expand_queue */ - struct pf_altq *if_pa, *parent, *altq; - u_int32_t bwsum; - int error = 0; - - /* find the corresponding interface and copy fields used by queues */ - if ((if_pa = pfaltq_lookup(pa->ifname)) == NULL) { - fprintf(stderr, "altq not defined on %s\n", pa->ifname); - return (1); - } - pa->scheduler = if_pa->scheduler; - pa->ifbandwidth = if_pa->ifbandwidth; - - if (qname_to_pfaltq(pa->qname, pa->ifname) != NULL) { - fprintf(stderr, "queue %s already exists on interface %s\n", - pa->qname, pa->ifname); - return (1); - } - pa->qid = qname_to_qid(pa->qname); - - parent = NULL; - if (pa->parent[0] != 0) { - parent = qname_to_pfaltq(pa->parent, pa->ifname); - if (parent == NULL) { - fprintf(stderr, "parent %s not found for %s\n", - pa->parent, pa->qname); - return (1); - } - pa->parent_qid = parent->qid; - } - if (pa->qlimit == 0) - pa->qlimit = DEFAULT_QLIMIT; - - if (pa->scheduler == ALTQT_CBQ || pa->scheduler == ALTQT_HFSC) { - pa->bandwidth = eval_bwspec(bw, - parent == NULL ? 0 : parent->bandwidth); - - if (pa->bandwidth > pa->ifbandwidth) { - fprintf(stderr, "bandwidth for %s higher than " - "interface\n", pa->qname); - return (1); - } - /* check the sum of the child bandwidth is under parent's */ - if (parent != NULL) { - if (pa->bandwidth > parent->bandwidth) { - warnx("bandwidth for %s higher than parent", - pa->qname); - return (1); - } - bwsum = 0; - TAILQ_FOREACH(altq, &altqs, entries) { - if (strncmp(altq->ifname, pa->ifname, - IFNAMSIZ) == 0 && - altq->qname[0] != 0 && - strncmp(altq->parent, pa->parent, - PF_QNAME_SIZE) == 0) - bwsum += altq->bandwidth; - } - bwsum += pa->bandwidth; - if (bwsum > parent->bandwidth) { - warnx("the sum of the child bandwidth higher" - " than parent \"%s\"", parent->qname); - } - } - } - - if (eval_queue_opts(pa, opts, parent == NULL? 0 : parent->bandwidth)) - return (1); - - switch (pa->scheduler) { - 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; - } - return (error); -} - -/* - * CBQ support functions - */ -#define RM_FILTER_GAIN 5 /* log2 of gain, e.g., 5 => 31/32 */ -#define RM_NS_PER_SEC (1000000000) - -static int -eval_pfqueue_cbq(struct pfctl *pf, struct pf_altq *pa) -{ - struct cbq_opts *opts; - u_int ifmtu; - - if (pa->priority >= CBQ_MAXPRI) { - warnx("priority out of range: max %d", CBQ_MAXPRI - 1); - return (-1); - } - - if ((pf->opts & PF_OPT_NOACTION) == 0) - ifmtu = getifmtu(pa->ifname); - else - ifmtu = 1500; - - opts = &pa->pq_u.cbq_opts; - - if (opts->pktsize == 0) { /* use default */ - opts->pktsize = ifmtu; - if (opts->pktsize > 2048) /* do what TCP does */ - opts->pktsize &= ~2048; - } else if (opts->pktsize > ifmtu) - opts->pktsize = ifmtu; - if (opts->maxpktsize == 0) /* use default */ - opts->maxpktsize = ifmtu; - else if (opts->maxpktsize > ifmtu) - opts->pktsize = ifmtu; - - if (opts->pktsize > opts->maxpktsize) - opts->pktsize = opts->maxpktsize; - - if (pa->parent[0] == 0) - opts->flags |= (CBQCLF_ROOTCLASS | CBQCLF_WRR); - - cbq_compute_idletime(pf, pa); - return (0); -} - -/* - * compute ns_per_byte, maxidle, minidle, and offtime - */ -static int -cbq_compute_idletime(struct pfctl *pf, struct pf_altq *pa) -{ - struct cbq_opts *opts; - double maxidle_s, maxidle, minidle; - double offtime, nsPerByte, ifnsPerByte, ptime, cptime; - double z, g, f, gton, gtom; - u_int minburst, maxburst; - - opts = &pa->pq_u.cbq_opts; - ifnsPerByte = (1.0 / (double)pa->ifbandwidth) * RM_NS_PER_SEC * 8; - minburst = opts->minburst; - maxburst = opts->maxburst; - - if (pa->bandwidth == 0) - f = 0.0001; /* small enough? */ - else - f = ((double) pa->bandwidth / (double) pa->ifbandwidth); - - nsPerByte = ifnsPerByte / f; - ptime = (double)opts->pktsize * ifnsPerByte; - cptime = ptime * (1.0 - f) / f; - - if (nsPerByte * (double)opts->maxpktsize > (double)INT_MAX) { - /* - * this causes integer overflow in kernel! - * (bandwidth < 6Kbps when max_pkt_size=1500) - */ - if (pa->bandwidth != 0 && (pf->opts & PF_OPT_QUIET) == 0) - warnx("queue bandwidth must be larger than %s", - rate2str(ifnsPerByte * (double)opts->maxpktsize / - (double)INT_MAX * (double)pa->ifbandwidth)); - fprintf(stderr, "cbq: queue %s is too slow!\n", pa->qname); - nsPerByte = (double)(INT_MAX / opts->maxpktsize); - } - - if (maxburst == 0) { /* use default */ - if (cptime > 10.0 * 1000000) - maxburst = 4; - else - maxburst = 16; - } - if (minburst == 0) /* use default */ - minburst = 2; - if (minburst > maxburst) - minburst = maxburst; - - z = (double)(1 << RM_FILTER_GAIN); - g = (1.0 - 1.0 / z); - gton = pow(g, (double)maxburst); - gtom = pow(g, (double)(minburst-1)); - maxidle = ((1.0 / f - 1.0) * ((1.0 - gton) / gton)); - maxidle_s = (1.0 - g); - if (maxidle > maxidle_s) - maxidle = ptime * maxidle; - else - maxidle = ptime * maxidle_s; - offtime = cptime * (1.0 + 1.0/(1.0 - g) * (1.0 - gtom) / gtom); - minidle = -((double)opts->maxpktsize * (double)nsPerByte); - - /* scale parameters */ - maxidle = ((maxidle * 8.0) / nsPerByte) * - pow(2.0, (double)RM_FILTER_GAIN); - offtime = (offtime * 8.0) / nsPerByte * - pow(2.0, (double)RM_FILTER_GAIN); - minidle = ((minidle * 8.0) / nsPerByte) * - pow(2.0, (double)RM_FILTER_GAIN); - - maxidle = maxidle / 1000.0; - offtime = offtime / 1000.0; - minidle = minidle / 1000.0; - - opts->minburst = minburst; - opts->maxburst = maxburst; - opts->ns_per_byte = (u_int)nsPerByte; - opts->maxidle = (u_int)fabs(maxidle); - opts->minidle = (int)minidle; - opts->offtime = (u_int)fabs(offtime); - - return (0); -} - -static int -check_commit_cbq(int dev, int opts, struct pf_altq *pa) -{ - struct pf_altq *altq; - int root_class, default_class; - int error = 0; - - /* - * check if cbq has one root queue and one default queue - * for this interface - */ - root_class = 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->pq_u.cbq_opts.flags & CBQCLF_ROOTCLASS) - root_class++; - if (altq->pq_u.cbq_opts.flags & CBQCLF_DEFCLASS) - default_class++; - } - if (root_class != 1) { - warnx("should have one root queue on %s", pa->ifname); - error++; - } - if (default_class != 1) { - warnx("should have one default queue on %s", pa->ifname); - error++; - } - return (error); -} - -static int -print_cbq_opts(const struct pf_altq *a) -{ - const struct cbq_opts *opts; - - opts = &a->pq_u.cbq_opts; - if (opts->flags) { - printf("cbq("); - if (opts->flags & CBQCLF_RED) - printf(" red"); - if (opts->flags & CBQCLF_ECN) - printf(" ecn"); - if (opts->flags & CBQCLF_BORROW) - printf(" borrow"); - if (opts->flags & CBQCLF_WRR) - printf(" wrr"); - if (opts->flags & CBQCLF_ROOTCLASS) - printf(" root"); - if (opts->flags & CBQCLF_DEFCLASS) - printf(" default"); - printf(" ) "); - - return (1); - } else - return (0); -} - -/* - * PRIQ support functions - */ -static int -eval_pfqueue_priq(struct pfctl *pf, struct pf_altq *pa) -{ - struct pf_altq *altq; - - 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->priority == pa->priority) { - warnx("%s and %s have the same priority", - altq->qname, pa->qname); - return (-1); - } - } - - 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->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 int -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_DEFAULTCLASS) - printf(" default"); - printf(" ) "); - - return (1); - } else - return (0); -} - -/* - * 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; - - opts = &pa->pq_u.hfsc_opts; - - if (pa->parent[0] == 0) { - /* root queue */ - opts->lssc_m1 = pa->ifbandwidth; - opts->lssc_m2 = pa->ifbandwidth; - opts->lssc_d = 0; - return (0); - } - - 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->lssc_m1 < opts->lssc_m2 && opts->lssc_m1 != 0) || - (opts->ulsc_m1 < opts->ulsc_m2 && opts->ulsc_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 linkshare 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 linkshare 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) { - /* add this queue to the sum */ - sc.m1 = opts->rtsc_m1; - sc.d = opts->rtsc_d; - sc.m2 = opts->rtsc_m2; - gsc_add_sc(&rtsc, &sc); - /* compare the sum with 80% of the interface */ - sc.m1 = 0; - sc.d = 0; - sc.m2 = pa->ifbandwidth / 100 * 80; - if (!is_gsc_under_sc(&rtsc, &sc)) { - warnx("real-time sc exceeds 80%% of the interface " - "bandwidth (%s)", rate2str((double)sc.m2)); - goto err_ret; - } - } - - /* check the linkshare service curve. */ - if (opts->lssc_m2 != 0) { - /* add this queue to the child sum */ - sc.m1 = opts->lssc_m1; - sc.d = opts->lssc_d; - sc.m2 = opts->lssc_m2; - gsc_add_sc(&lssc, &sc); - /* compare the sum of the children with parent's sc */ - 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("linkshare 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); - return (1); - } - /* 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 int -print_hfsc_opts(const struct pf_altq *a, const struct node_queue_opt *qopts) -{ - const struct hfsc_opts *opts; - const struct node_hfsc_sc *rtsc, *lssc, *ulsc; - - opts = &a->pq_u.hfsc_opts; - if (qopts == NULL) - rtsc = lssc = ulsc = NULL; - else { - rtsc = &qopts->data.hfsc_opts.realtime; - lssc = &qopts->data.hfsc_opts.linkshare; - ulsc = &qopts->data.hfsc_opts.upperlimit; - } - - if (opts->flags || opts->rtsc_m2 != 0 || opts->ulsc_m2 != 0 || - (opts->lssc_m2 != 0 && (opts->lssc_m2 != a->bandwidth || - opts->lssc_d != 0))) { - printf("hfsc("); - if (opts->flags & HFCF_RED) - printf(" red"); - if (opts->flags & HFCF_ECN) - printf(" ecn"); - if (opts->flags & HFCF_DEFAULTCLASS) - printf(" default"); - if (opts->rtsc_m2 != 0) - print_hfsc_sc("realtime", opts->rtsc_m1, opts->rtsc_d, - opts->rtsc_m2, rtsc); - if (opts->lssc_m2 != 0 && (opts->lssc_m2 != a->bandwidth || - opts->lssc_d != 0)) - print_hfsc_sc("linkshare", opts->lssc_m1, opts->lssc_d, - opts->lssc_m2, lssc); - if (opts->ulsc_m2 != 0) - print_hfsc_sc("upperlimit", opts->ulsc_m1, opts->ulsc_d, - opts->ulsc_m2, ulsc); - printf(" ) "); - - return (1); - } else - return (0); -} - -/* - * admission control using generalized service curve - */ - -/* add a new service curve to a generalized 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, 0.0, (double)sc->d, (double)sc->m1); - gsc_add_seg(gsc, (double)sc->d, 0.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); -} - -/* - * misc utilities - */ -#define R2S_BUFS 8 -#define RATESTR_MAX 16 - -char * -rate2str(double rate) -{ - char *buf; - static char r2sbuf[R2S_BUFS][RATESTR_MAX]; /* ring bufer */ - static int idx = 0; - int i; - static const char unit[] = " KMG"; - - buf = r2sbuf[idx++]; - if (idx == R2S_BUFS) - idx = 0; - - for (i = 0; rate >= 1000 && i <= 3; i++) - rate /= 1000; - - if ((int)(rate * 100) % 100) - snprintf(buf, RATESTR_MAX, "%.2f%cb", rate, unit[i]); - else - snprintf(buf, RATESTR_MAX, "%d%cb", (int)rate, unit[i]); - - return (buf); -} - -u_int32_t -getifspeed(char *ifname) -{ - int s; - struct ifreq ifr; - struct if_data ifrdat; - - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) - err(1, "socket"); - bzero(&ifr, sizeof(ifr)); - if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)) >= - sizeof(ifr.ifr_name)) - errx(1, "getifspeed: strlcpy"); - ifr.ifr_data = (caddr_t)&ifrdat; - if (ioctl(s, SIOCGIFDATA, (caddr_t)&ifr) == -1) - err(1, "SIOCGIFDATA"); - if (close(s)) - err(1, "close"); - return ((u_int32_t)ifrdat.ifi_baudrate); -} - -u_long -getifmtu(char *ifname) -{ - int s; - struct ifreq ifr; - - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) - err(1, "socket"); - bzero(&ifr, sizeof(ifr)); - if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)) >= - sizeof(ifr.ifr_name)) - errx(1, "getifmtu: strlcpy"); - if (ioctl(s, SIOCGIFMTU, (caddr_t)&ifr) == -1) - err(1, "SIOCGIFMTU"); - if (close(s)) - err(1, "close"); - if (ifr.ifr_mtu > 0) - return (ifr.ifr_mtu); - else { - warnx("could not get mtu for %s, assuming 1500", ifname); - return (1500); - } -} - -int -eval_queue_opts(struct pf_altq *pa, struct node_queue_opt *opts, - u_int32_t ref_bw) -{ - int errors = 0; - - switch (pa->scheduler) { - case ALTQT_CBQ: - pa->pq_u.cbq_opts = opts->data.cbq_opts; - break; - case ALTQT_PRIQ: - pa->pq_u.priq_opts = opts->data.priq_opts; - break; - case ALTQT_HFSC: - pa->pq_u.hfsc_opts.flags = opts->data.hfsc_opts.flags; - if (opts->data.hfsc_opts.linkshare.used) { - pa->pq_u.hfsc_opts.lssc_m1 = - eval_bwspec(&opts->data.hfsc_opts.linkshare.m1, - ref_bw); - pa->pq_u.hfsc_opts.lssc_m2 = - eval_bwspec(&opts->data.hfsc_opts.linkshare.m2, - ref_bw); - pa->pq_u.hfsc_opts.lssc_d = - opts->data.hfsc_opts.linkshare.d; - } - if (opts->data.hfsc_opts.realtime.used) { - pa->pq_u.hfsc_opts.rtsc_m1 = - eval_bwspec(&opts->data.hfsc_opts.realtime.m1, - ref_bw); - pa->pq_u.hfsc_opts.rtsc_m2 = - eval_bwspec(&opts->data.hfsc_opts.realtime.m2, - ref_bw); - pa->pq_u.hfsc_opts.rtsc_d = - opts->data.hfsc_opts.realtime.d; - } - if (opts->data.hfsc_opts.upperlimit.used) { - pa->pq_u.hfsc_opts.ulsc_m1 = - eval_bwspec(&opts->data.hfsc_opts.upperlimit.m1, - ref_bw); - pa->pq_u.hfsc_opts.ulsc_m2 = - eval_bwspec(&opts->data.hfsc_opts.upperlimit.m2, - ref_bw); - pa->pq_u.hfsc_opts.ulsc_d = - opts->data.hfsc_opts.upperlimit.d; - } - break; - default: - warnx("eval_queue_opts: unknown scheduler type %u", - opts->qtype); - errors++; - break; - } - - return (errors); -} - -u_int32_t -eval_bwspec(struct node_queue_bw *bw, u_int32_t ref_bw) -{ - if (bw->bw_absolute > 0) - return (bw->bw_absolute); - - if (bw->bw_percent > 0) - return (ref_bw / 100 * bw->bw_percent); - - return (0); -} - -void -print_hfsc_sc(const char *scname, u_int m1, u_int d, u_int m2, - const struct node_hfsc_sc *sc) -{ - printf(" %s", scname); - - if (d != 0) { - printf("("); - if (sc != NULL && sc->m1.bw_percent > 0) - printf("%u%%", sc->m1.bw_percent); - else - printf("%s", rate2str((double)m1)); - printf(" %u", d); - } - - if (sc != NULL && sc->m2.bw_percent > 0) - printf(" %u%%", sc->m2.bw_percent); - else - printf(" %s", rate2str((double)m2)); - - if (d != 0) - printf(")"); -} diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h index 1bd2a649e96..9762c9b66a7 100644 --- a/sbin/pfctl/pfctl_parser.h +++ b/sbin/pfctl/pfctl_parser.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_parser.h,v 1.101 2013/10/12 12:16:12 henning Exp $ */ +/* $OpenBSD: pfctl_parser.h,v 1.102 2014/04/19 14:22:32 henning Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -79,7 +79,6 @@ struct pfctl { int tdirty; /* kernel dirty */ #define PFCTL_ANCHOR_STACK_DEPTH 64 struct pf_anchor *astack[PFCTL_ANCHOR_STACK_DEPTH]; - struct pfioc_altq *paltq; struct pfioc_queue *pqueue; struct pfr_buffer *trans; struct pf_anchor *anchor, *alast; @@ -200,7 +199,6 @@ int add_opt_table(struct pfctl *, struct pf_opt_tbl **, sa_family_t, struct pf_rule_addr *, char *); int pfctl_add_rule(struct pfctl *, struct pf_rule *, const char *); -int pfctl_add_altq(struct pfctl *, struct pf_altq *); int pfctl_add_pool(struct pfctl *, struct pf_pool *, sa_family_t, int); void pfctl_move_pool(struct pf_pool *, struct pf_pool *); void pfctl_clear_pool(struct pf_pool *); @@ -228,16 +226,6 @@ void print_tabledef(const char *, int, int, struct node_tinithead *); void print_status(struct pf_status *, int); void print_queuespec(struct pf_queuespec *); -int eval_pfaltq(struct pfctl *, struct pf_altq *, struct node_queue_bw *, - struct node_queue_opt *); -int eval_pfqueue(struct pfctl *, struct pf_altq *, struct node_queue_bw *, - struct node_queue_opt *); - -void print_altq(const struct pf_altq *, unsigned, struct node_queue_bw *, - struct node_queue_opt *); -void print_queue(const struct pf_altq *, unsigned, struct node_queue_bw *, - int, struct node_queue_opt *); - int pfctl_define_table(char *, int, int, const char *, struct pfr_buffer *, u_int32_t); @@ -248,7 +236,6 @@ int pfctl_load_fingerprints(int, int); char *pfctl_lookup_fingerprint(pf_osfp_t, char *, size_t); void pfctl_show_fingerprints(int); - struct icmptypeent { const char *name; u_int8_t type; diff --git a/sbin/pfctl/pfctl_qstats.c b/sbin/pfctl/pfctl_qstats.c deleted file mode 100644 index c2cf2b6e868..00000000000 --- a/sbin/pfctl/pfctl_qstats.c +++ /dev/null @@ -1,416 +0,0 @@ -/* $OpenBSD: pfctl_qstats.c,v 1.33 2013/10/12 12:16:12 henning Exp $ */ - -/* - * Copyright (c) 2003 - 2013 Henning Brauer - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "pfctl.h" -#include "pfctl_parser.h" - -union class_stats { - class_stats_t cbq_stats; - struct priq_classstats priq_stats; - struct hfsc_classstats hfsc_stats; -}; - -#define AVGN_MAX 8 -#define STAT_INTERVAL 5 - -struct queue_stats { - union class_stats data; - int avgn; - double avg_bytes; - double avg_packets; - u_int64_t prev_bytes; - u_int64_t prev_packets; -}; - -struct pf_altq_node { - struct pf_altq altq; - struct pf_altq_node *next; - struct pf_altq_node *children; - struct queue_stats qstats; -}; - -int pfctl_update_altqstats(int, struct pf_altq_node **); -void pfctl_insert_altq_node(struct pf_altq_node **, - const struct pf_altq, const struct queue_stats); -struct pf_altq_node *pfctl_find_altq_node(struct pf_altq_node *, - const char *, const char *); -void pfctl_print_altq_node(int, const struct pf_altq_node *, - unsigned, int); -void print_cbqstats(struct queue_stats); -void print_priqstats(struct queue_stats); -void print_hfscstats(struct queue_stats); -void pfctl_free_altq_node(struct pf_altq_node *); -void pfctl_print_altq_nodestat(int, - const struct pf_altq_node *); - -void altq_update_avg(struct pf_altq_node *); - -int -pfctl_show_altq(int dev, const char *iface, int opts, int verbose2) -{ - struct pf_altq_node *root = NULL, *node; - int nodes, dotitle = (opts & PF_OPT_SHOWALL); - - - if ((nodes = pfctl_update_altqstats(dev, &root)) < 0) - return (-1); - - if (nodes == 0) - printf("No altq queue in use\n"); - for (node = root; node != NULL; node = node->next) { - if (iface != NULL && strcmp(node->altq.ifname, iface)) - continue; - if (dotitle) { - pfctl_print_title("ALTQ:"); - dotitle = 0; - } - pfctl_print_altq_node(dev, node, 0, opts); - } - - while (verbose2 && nodes > 0) { - printf("\n"); - fflush(stdout); - sleep(STAT_INTERVAL); - if ((nodes = pfctl_update_altqstats(dev, &root)) == -1) - return (-1); - for (node = root; node != NULL; node = node->next) { - if (iface != NULL && strcmp(node->altq.ifname, iface)) - continue; - pfctl_print_altq_node(dev, node, 0, opts); - } - } - pfctl_free_altq_node(root); - return (0); -} - -int -pfctl_update_altqstats(int dev, struct pf_altq_node **root) -{ - struct pf_altq_node *node; - struct pfioc_altq pa; - struct pfioc_altqstats pq; - u_int32_t mnr, nr; - struct queue_stats qstats; - static u_int32_t last_ticket; - - memset(&pa, 0, sizeof(pa)); - memset(&pq, 0, sizeof(pq)); - memset(&qstats, 0, sizeof(qstats)); - if (ioctl(dev, DIOCGETALTQS, &pa)) { - warn("DIOCGETALTQS"); - return (-1); - } - - /* if a new set is found, start over */ - if (pa.ticket != last_ticket && *root != NULL) { - pfctl_free_altq_node(*root); - *root = NULL; - } - last_ticket = pa.ticket; - - mnr = pa.nr; - for (nr = 0; nr < mnr; ++nr) { - pa.nr = nr; - if (ioctl(dev, DIOCGETALTQ, &pa)) { - warn("DIOCGETALTQ"); - return (-1); - } - if (pa.altq.qid > 0) { - pq.nr = nr; - pq.ticket = pa.ticket; - pq.buf = &qstats.data; - pq.nbytes = sizeof(qstats.data); - if (ioctl(dev, DIOCGETALTQSTATS, &pq)) { - warn("DIOCGETALTQSTATS"); - return (-1); - } - if ((node = pfctl_find_altq_node(*root, pa.altq.qname, - pa.altq.ifname)) != NULL) { - memcpy(&node->qstats.data, &qstats.data, - sizeof(qstats.data)); - altq_update_avg(node); - } else { - pfctl_insert_altq_node(root, pa.altq, qstats); - } - } - } - return (mnr); -} - -void -pfctl_insert_altq_node(struct pf_altq_node **root, - const struct pf_altq altq, const struct queue_stats qstats) -{ - struct pf_altq_node *node; - - node = calloc(1, sizeof(struct pf_altq_node)); - if (node == NULL) - err(1, "pfctl_insert_altq_node: calloc"); - memcpy(&node->altq, &altq, sizeof(struct pf_altq)); - memcpy(&node->qstats, &qstats, sizeof(qstats)); - node->next = node->children = NULL; - - if (*root == NULL) - *root = node; - else if (!altq.parent[0]) { - struct pf_altq_node *prev = *root; - - while (prev->next != NULL) - prev = prev->next; - prev->next = node; - } else { - struct pf_altq_node *parent; - - parent = pfctl_find_altq_node(*root, altq.parent, altq.ifname); - if (parent == NULL) - errx(1, "parent %s not found", altq.parent); - if (parent->children == NULL) - parent->children = node; - else { - struct pf_altq_node *prev = parent->children; - - while (prev->next != NULL) - prev = prev->next; - prev->next = node; - } - } - altq_update_avg(node); -} - -struct pf_altq_node * -pfctl_find_altq_node(struct pf_altq_node *root, const char *qname, - const char *ifname) -{ - struct pf_altq_node *node, *child; - - for (node = root; node != NULL; node = node->next) { - if (!strcmp(node->altq.qname, qname) - && !(strcmp(node->altq.ifname, ifname))) - return (node); - if (node->children != NULL) { - child = pfctl_find_altq_node(node->children, qname, - ifname); - if (child != NULL) - return (child); - } - } - return (NULL); -} - -void -pfctl_print_altq_node(int dev, const struct pf_altq_node *node, - unsigned int level, int opts) -{ - const struct pf_altq_node *child; - - if (node == NULL) - return; - - print_altq(&node->altq, level, NULL, NULL); - - if (node->children != NULL) { - printf("{"); - for (child = node->children; child != NULL; - child = child->next) { - printf("%s", child->altq.qname); - if (child->next != NULL) - printf(", "); - } - printf("}"); - } - printf("\n"); - - if (opts & PF_OPT_VERBOSE) - pfctl_print_altq_nodestat(dev, node); - - if (opts & PF_OPT_DEBUG) - printf(" [ qid=%u ifname=%s ifbandwidth=%s ]\n", - node->altq.qid, node->altq.ifname, - rate2str((double)(node->altq.ifbandwidth))); - - for (child = node->children; child != NULL; - child = child->next) - pfctl_print_altq_node(dev, child, level + 1, opts); -} - -void -pfctl_print_altq_nodestat(int dev, const struct pf_altq_node *a) -{ - if (a->altq.qid == 0) - return; - - switch (a->altq.scheduler) { - case ALTQT_CBQ: - print_cbqstats(a->qstats); - break; - case ALTQT_PRIQ: - print_priqstats(a->qstats); - break; - case ALTQT_HFSC: - print_hfscstats(a->qstats); - break; - } -} - -void -print_cbqstats(struct queue_stats cur) -{ - printf(" [ pkts: %10llu bytes: %10llu " - "dropped pkts: %6llu bytes: %6llu ]\n", - (unsigned long long)cur.data.cbq_stats.xmit_cnt.packets, - (unsigned long long)cur.data.cbq_stats.xmit_cnt.bytes, - (unsigned long long)cur.data.cbq_stats.drop_cnt.packets, - (unsigned long long)cur.data.cbq_stats.drop_cnt.bytes); - printf(" [ qlength: %3d/%3d borrows: %6u suspends: %6u ]\n", - cur.data.cbq_stats.qcnt, cur.data.cbq_stats.qmax, - cur.data.cbq_stats.borrows, cur.data.cbq_stats.delays); - - if (cur.avgn < 2) - return; - - printf(" [ measured: %7.1f packets/s, %s/s ]\n", - cur.avg_packets / STAT_INTERVAL, - rate2str((8 * cur.avg_bytes) / STAT_INTERVAL)); -} - -void -print_priqstats(struct queue_stats cur) -{ - printf(" [ pkts: %10llu bytes: %10llu " - "dropped pkts: %6llu bytes: %6llu ]\n", - (unsigned long long)cur.data.priq_stats.xmitcnt.packets, - (unsigned long long)cur.data.priq_stats.xmitcnt.bytes, - (unsigned long long)cur.data.priq_stats.dropcnt.packets, - (unsigned long long)cur.data.priq_stats.dropcnt.bytes); - printf(" [ qlength: %3d/%3d ]\n", - cur.data.priq_stats.qlength, cur.data.priq_stats.qlimit); - - if (cur.avgn < 2) - return; - - printf(" [ measured: %7.1f packets/s, %s/s ]\n", - cur.avg_packets / STAT_INTERVAL, - rate2str((8 * cur.avg_bytes) / STAT_INTERVAL)); -} - -void -print_hfscstats(struct queue_stats cur) -{ - printf(" [ pkts: %10llu bytes: %10llu " - "dropped pkts: %6llu bytes: %6llu ]\n", - (unsigned long long)cur.data.hfsc_stats.xmit_cnt.packets, - (unsigned long long)cur.data.hfsc_stats.xmit_cnt.bytes, - (unsigned long long)cur.data.hfsc_stats.drop_cnt.packets, - (unsigned long long)cur.data.hfsc_stats.drop_cnt.bytes); - printf(" [ qlength: %3d/%3d ]\n", - cur.data.hfsc_stats.qlength, cur.data.hfsc_stats.qlimit); - - if (cur.avgn < 2) - return; - - printf(" [ measured: %7.1f packets/s, %s/s ]\n", - cur.avg_packets / STAT_INTERVAL, - rate2str((8 * cur.avg_bytes) / STAT_INTERVAL)); -} - -void -pfctl_free_altq_node(struct pf_altq_node *node) -{ - while (node != NULL) { - struct pf_altq_node *prev; - - if (node->children != NULL) - pfctl_free_altq_node(node->children); - prev = node; - node = node->next; - free(prev); - } -} - -void -altq_update_avg(struct pf_altq_node *a) -{ - struct queue_stats *qs; - u_int64_t b, p; - int n; - - if (a->altq.qid == 0) - return; - - qs = &a->qstats; - n = qs->avgn; - - switch (a->altq.scheduler) { - case ALTQT_CBQ: - b = qs->data.cbq_stats.xmit_cnt.bytes; - p = qs->data.cbq_stats.xmit_cnt.packets; - break; - case ALTQT_PRIQ: - b = qs->data.priq_stats.xmitcnt.bytes; - p = qs->data.priq_stats.xmitcnt.packets; - break; - case ALTQT_HFSC: - b = qs->data.hfsc_stats.xmit_cnt.bytes; - p = qs->data.hfsc_stats.xmit_cnt.packets; - break; - default: - b = 0; - p = 0; - break; - } - - if (n == 0) { - qs->prev_bytes = b; - qs->prev_packets = p; - qs->avgn++; - return; - } - - if (b >= qs->prev_bytes) - qs->avg_bytes = ((qs->avg_bytes * (n - 1)) + - (b - qs->prev_bytes)) / n; - - if (p >= qs->prev_packets) - qs->avg_packets = ((qs->avg_packets * (n - 1)) + - (p - qs->prev_packets)) / n; - - qs->prev_bytes = b; - qs->prev_packets = p; - if (n < AVGN_MAX) - qs->avgn++; -} diff --git a/sbin/pfctl/pfctl_queue.c b/sbin/pfctl/pfctl_queue.c index 5d11e61a22d..3b5a47d114b 100644 --- a/sbin/pfctl/pfctl_queue.c +++ b/sbin/pfctl/pfctl_queue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_queue.c,v 1.1 2013/10/12 12:16:12 henning Exp $ */ +/* $OpenBSD: pfctl_queue.c,v 1.2 2014/04/19 14:22:32 henning Exp $ */ /* * Copyright (c) 2003 - 2013 Henning Brauer @@ -66,6 +66,7 @@ void pfctl_free_queue_node(struct pfctl_queue_node *); void pfctl_print_queue_nodestat(int, const struct pfctl_queue_node *); void update_avg(struct queue_stats *); +char *rate2str(double); int pfctl_show_queues(int dev, const char *iface, int opts, int verbose2) @@ -235,3 +236,30 @@ update_avg(struct queue_stats *s) if (s->avgn < AVGN_MAX) s->avgn++; } + +#define R2S_BUFS 8 +#define RATESTR_MAX 16 + +char * +rate2str(double rate) +{ + char *buf; + static char r2sbuf[R2S_BUFS][RATESTR_MAX]; /* ring bufer */ + static int idx = 0; + int i; + static const char unit[] = " KMG"; + + buf = r2sbuf[idx++]; + if (idx == R2S_BUFS) + idx = 0; + + for (i = 0; rate >= 1000 && i <= 3; i++) + rate /= 1000; + + if ((int)(rate * 100) % 100) + snprintf(buf, RATESTR_MAX, "%.2f%cb", rate, unit[i]); + else + snprintf(buf, RATESTR_MAX, "%d%cb", (int)rate, unit[i]); + + return (buf); +}