summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorJoerg Zinke <zinke@cvs.openbsd.org>2011-07-03 23:37:56 +0000
committerJoerg Zinke <zinke@cvs.openbsd.org>2011-07-03 23:37:56 +0000
commitc22be30ebe7d9c8ce80dfe223351edaf2c035c33 (patch)
tree6f0a3aeb262e5e409f9d53b6db53c04ed76b9253 /sbin
parent8c4fabd58502851b921aa22c22ff07c9d5e3769a (diff)
bring in least-states load balancing algorithm
ok mcbride@ henning@
Diffstat (limited to 'sbin')
-rw-r--r--sbin/pfctl/parse.y57
-rw-r--r--sbin/pfctl/pfctl_optimize.c4
-rw-r--r--sbin/pfctl/pfctl_parser.c7
-rw-r--r--sbin/pfctl/pfctl_parser.h3
-rw-r--r--sbin/pfctl/pfctl_table.c10
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]);