diff options
author | Joerg Zinke <zinke@cvs.openbsd.org> | 2011-07-03 23:37:56 +0000 |
---|---|---|
committer | Joerg Zinke <zinke@cvs.openbsd.org> | 2011-07-03 23:37:56 +0000 |
commit | c22be30ebe7d9c8ce80dfe223351edaf2c035c33 (patch) | |
tree | 6f0a3aeb262e5e409f9d53b6db53c04ed76b9253 /sbin | |
parent | 8c4fabd58502851b921aa22c22ff07c9d5e3769a (diff) |
bring in least-states load balancing algorithm
ok mcbride@ henning@
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/pfctl/parse.y | 57 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_optimize.c | 4 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_parser.c | 7 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_parser.h | 3 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_table.c | 10 |
5 files changed, 57 insertions, 24 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index 5a2e36a373a..9fac047d119 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.599 2011/04/06 13:19:55 claudio Exp $ */ +/* $OpenBSD: parse.y,v 1.600 2011/07/03 23:37:55 zinke Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -459,7 +459,7 @@ int parseport(char *, struct range *r, int); %token SET OPTIMIZATION TIMEOUT LIMIT LOGINTERFACE BLOCKPOLICY RANDOMID %token REQUIREORDER SYNPROXY FINGERPRINTS NOSYNC DEBUG SKIP HOSTID %token ANTISPOOF FOR INCLUDE MATCHES -%token BITMASK RANDOM SOURCEHASH ROUNDROBIN STATICPORT PROBABILITY +%token BITMASK RANDOM SOURCEHASH ROUNDROBIN LEASTSTATES STATICPORT PROBABILITY %token ALTQ CBQ PRIQ HFSC BANDWIDTH TBRSIZE LINKSHARE REALTIME UPPERLIMIT %token QUEUE PRIORITY QLIMIT RTABLE RDOMAIN %token LOAD RULESET_OPTIMIZATION @@ -1230,6 +1230,8 @@ table_opt : STRING { table_opts.flags |= PFR_TFLAG_PERSIST; else if (!strcmp($1, "counters")) table_opts.flags |= PFR_TFLAG_COUNTERS; + else if (!strcmp($1, "cost")) + table_opts.flags |= PFR_TFLAG_COST; else { yyerror("invalid table option '%s'", $1); free($1); @@ -2035,24 +2037,32 @@ pfrule : action dir logquick interface af proto fromto $8.route.host->addr.type == PF_ADDR_TABLE || DYNIF_MULTIADDR($8.route.host->addr))) r.route.opts |= PF_POOL_ROUNDROBIN; - if ((r.route.opts & PF_POOL_TYPEMASK) != - PF_POOL_ROUNDROBIN && + if (((r.route.opts & PF_POOL_TYPEMASK) != + PF_POOL_ROUNDROBIN) && + ((r.route.opts & PF_POOL_TYPEMASK) != + PF_POOL_LEASTSTATES) && disallow_table($8.route.host, "tables are only " - "supported in round-robin routing pools")) + "supported in round-robin or " + "least-states routing pools")) YYERROR; - if ((r.route.opts & PF_POOL_TYPEMASK) != - PF_POOL_ROUNDROBIN && + if (((r.route.opts & PF_POOL_TYPEMASK) != + PF_POOL_ROUNDROBIN) && + ((r.route.opts & PF_POOL_TYPEMASK) != + PF_POOL_LEASTSTATES) && disallow_alias($8.route.host, "interface (%s) " - "is only supported in round-robin " - "routing pools")) + "is only supported in round-robin or " + "least-states routing pools")) YYERROR; if ($8.route.host->next != NULL) { - if ((r.route.opts & PF_POOL_TYPEMASK) != - PF_POOL_ROUNDROBIN) { + if (((r.route.opts & PF_POOL_TYPEMASK) != + PF_POOL_ROUNDROBIN) && + ((r.route.opts & PF_POOL_TYPEMASK) != + PF_POOL_LEASTSTATES)) { yyerror("r.route.opts must " - "be PF_POOL_ROUNDROBIN"); + "be PF_POOL_ROUNDROBIN " + "or PF_POOL_LEASTSTATES"); YYERROR; } } @@ -2297,6 +2307,8 @@ filter_opt : USER uids { filter_opts.route.host = $2; filter_opts.route.rt = PF_ROUTETO; filter_opts.route.pool_opts = $3.type | $3.opts; + memcpy(&filter_opts.rroute.pool_opts, &$3, + sizeof(filter_opts.rroute.pool_opts)); if ($3.key != NULL) filter_opts.route.key = $3.key; } @@ -3715,6 +3727,13 @@ pool_opt : BITMASK { } pool_opts.type = PF_POOL_ROUNDROBIN; } + | LEASTSTATES { + if (pool_opts.type) { + yyerror("pool type cannot be redefined"); + YYERROR; + } + pool_opts.type = PF_POOL_LEASTSTATES; + } | STATICPORT { if (pool_opts.staticport) { yyerror("static-port cannot be redefined"); @@ -4544,7 +4563,6 @@ collapse_redirspec(struct pf_pool *rpool, struct pf_rule *r, struct pf_rule_addr ra; int i = 0; - if (!rs || !rs->rdr || rs->rdr->host == NULL) { rpool->addr.type = PF_ADDR_NONE; return (0); @@ -4579,8 +4597,10 @@ collapse_redirspec(struct pf_pool *rpool, struct pf_rule *r, return (0); } else { /* more than one address */ if (rs->pool_opts.type && - rs->pool_opts.type != PF_POOL_ROUNDROBIN) { - yyerror("only round-robin valid for multiple " + (rs->pool_opts.type != PF_POOL_ROUNDROBIN) && + (rs->pool_opts.type != PF_POOL_LEASTSTATES)) { + yyerror("only round-robin or " + "least-states valid for multiple " "translation or routing addresses"); return (1); } @@ -4605,6 +4625,9 @@ collapse_redirspec(struct pf_pool *rpool, struct pf_rule *r, } } if (tbl) { + if (rs->pool_opts.type == PF_POOL_LEASTSTATES) + tbl->pt_flags |= PFR_TFLAG_COST; + if ((pf->opts & PF_OPT_NOACTION) == 0 && pf_opt_create_table(pf, tbl)) return (1); @@ -4612,7 +4635,8 @@ collapse_redirspec(struct pf_pool *rpool, struct pf_rule *r, pf->tdirty = 1; if (pf->opts & PF_OPT_VERBOSE) - print_tabledef(tbl->pt_name, PFR_TFLAG_CONST, + print_tabledef(tbl->pt_name, + PFR_TFLAG_CONST | tbl->pt_flags, 1, &tbl->pt_nodes); memset(&rpool->addr, 0, sizeof(rpool->addr)); @@ -5080,6 +5104,7 @@ lookup(char *s) { "inet6", INET6}, { "keep", KEEP}, { "label", LABEL}, + { "least-states", LEASTSTATES}, { "limit", LIMIT}, { "linkshare", LINKSHARE}, { "load", LOAD}, diff --git a/sbin/pfctl/pfctl_optimize.c b/sbin/pfctl/pfctl_optimize.c index 45f1bb747c8..fbea5cd90dd 100644 --- a/sbin/pfctl/pfctl_optimize.c +++ b/sbin/pfctl/pfctl_optimize.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_optimize.c,v 1.26 2011/04/06 13:19:55 claudio Exp $ */ +/* $OpenBSD: pfctl_optimize.c,v 1.27 2011/07/03 23:37:55 zinke Exp $ */ /* * Copyright (c) 2004 Mike Frantzen <frantzen@openbsd.org> @@ -1305,7 +1305,7 @@ again: } tablenum++; - if (pfctl_define_table(tbl->pt_name, PFR_TFLAG_CONST, 1, + if (pfctl_define_table(tbl->pt_name, PFR_TFLAG_CONST | tbl->pt_flags, 1, pf->astack[0]->name, tbl->pt_buf, pf->astack[0]->ruleset.tticket)) { warn("failed to create table %s in %s", tbl->pt_name, pf->astack[0]->name); diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c index f6c5c7f16eb..df4e6602443 100644 --- a/sbin/pfctl/pfctl_parser.c +++ b/sbin/pfctl/pfctl_parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_parser.c,v 1.275 2011/04/06 13:19:55 claudio Exp $ */ +/* $OpenBSD: pfctl_parser.c,v 1.276 2011/07/03 23:37:55 zinke Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -489,6 +489,9 @@ print_pool(struct pf_pool *pool, u_int16_t p1, u_int16_t p2, case PF_POOL_ROUNDROBIN: printf(" round-robin"); break; + case PF_POOL_LEASTSTATES: + printf(" least-states"); + break; } if (pool->opts & PF_POOL_STICKYADDR) printf(" sticky-address"); @@ -1081,6 +1084,8 @@ print_tabledef(const char *name, int flags, int addrs, printf(" persist"); if (flags & PFR_TFLAG_COUNTERS) printf(" counters"); + if (flags & PFR_TFLAG_COST) + printf(" cost"); SIMPLEQ_FOREACH(ti, nodes, entries) { if (ti->file) { printf(" file \"%s\"", ti->file); diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h index 8131ac6bbc0..7d27dba9cf1 100644 --- a/sbin/pfctl/pfctl_parser.h +++ b/sbin/pfctl/pfctl_parser.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_parser.h,v 1.95 2011/04/06 13:19:55 claudio Exp $ */ +/* $OpenBSD: pfctl_parser.h,v 1.96 2011/07/03 23:37:55 zinke Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -172,6 +172,7 @@ struct pf_opt_tbl { char pt_name[PF_TABLE_NAME_SIZE]; int pt_rulecount; int pt_generated; + u_int32_t pt_flags; struct node_tinithead pt_nodes; struct pfr_buffer *pt_buf; }; diff --git a/sbin/pfctl/pfctl_table.c b/sbin/pfctl/pfctl_table.c index a20c89cfb5c..bbdc4e660db 100644 --- a/sbin/pfctl/pfctl_table.c +++ b/sbin/pfctl/pfctl_table.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_table.c,v 1.69 2010/01/12 03:20:51 mcbride Exp $ */ +/* $OpenBSD: pfctl_table.c,v 1.70 2011/07/03 23:37:55 zinke Exp $ */ /* * Copyright (c) 2002 Cedric Berger @@ -478,14 +478,16 @@ print_astats(struct pfr_astats *as, int dns) int dir, op; print_addrx(&as->pfras_a, NULL, dns); - printf("\tCleared: %s", ctime(&time)); + printf("\tCleared: %s", ctime(&time)); + if (as->pfras_a.pfra_type == PFRKE_COST) + printf("\tActive States: %d\n", as->pfras_a.pfra_states); if (as->pfras_a.pfra_fback == PFR_FB_NOCOUNT) return; if (as->pfras_a.pfra_ifname[0]) - printf("\tInterface: %s\n", as->pfras_a.pfra_ifname); + printf("\tInterface: %s\n", as->pfras_a.pfra_ifname); for (dir = 0; dir < PFR_DIR_MAX; dir++) for (op = 0; op < PFR_OP_ADDR_MAX; op++) - printf("\t%-12s [ Packets: %-18llu Bytes: %-18llu ]\n", + printf("\t%-19s [ Packets: %-18llu Bytes: %-18llu ]\n", stats_text[dir][op], (unsigned long long)as->pfras_packets[dir][op], (unsigned long long)as->pfras_bytes[dir][op]); |