summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorJoerg Zinke <zinke@cvs.openbsd.org>2012-07-09 15:20:58 +0000
committerJoerg Zinke <zinke@cvs.openbsd.org>2012-07-09 15:20:58 +0000
commit5b4f8f5fd9354911af9e8882726a56aedfd6d6f9 (patch)
tree14110098c249c48d5045f36e6230ad1c32256ff3 /sys/net
parent408ba7d2761195e2126b2fb29eea2077c9f5ce85 (diff)
Enable support for the 'weight' keyword in the 'least-states'
load balancing case, this allows Weighted Least States (WLS). Everything prepared on c2k11 with help from mcbride@. This finally makes PF ready for the cloud. ok henning@ mikeb@ pyr@
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/pf_lb.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/sys/net/pf_lb.c b/sys/net/pf_lb.c
index a88bce0f669..8f52fc6594f 100644
--- a/sys/net/pf_lb.c
+++ b/sys/net/pf_lb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_lb.c,v 1.20 2012/02/03 01:57:51 bluhm Exp $ */
+/* $OpenBSD: pf_lb.c,v 1.21 2012/07/09 15:20:57 zinke Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -52,6 +52,7 @@
#include <sys/proc.h>
#include <sys/rwlock.h>
#include <sys/syslog.h>
+#include <sys/stdint.h>
#include <crypto/md5.h>
@@ -287,6 +288,8 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
struct pf_src_node k;
u_int64_t states;
u_int16_t weight;
+ u_int64_t load;
+ u_int64_t cload;
if (sns[type] == NULL && rpool->opts & PF_POOL_STICKYADDR &&
(rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
@@ -477,6 +480,15 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
return (1);
states = rpool->states;
+ weight = rpool->weight;
+
+ if ((rpool->addr.type == PF_ADDR_TABLE &&
+ rpool->addr.p.tbl->pfrkt_refcntcost > 0) ||
+ (rpool->addr.type == PF_ADDR_DYNIFTL &&
+ rpool->addr.p.dyn->pfid_kt->pfrkt_refcntcost > 0))
+ load = ((UINT16_MAX * rpool->states) / rpool->weight);
+ else
+ load = states;
PF_ACPY(&faddr, &rpool->counter, af);
@@ -507,10 +519,21 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
} else if (pf_match_addr(0, raddr, rmask,
&rpool->counter, af))
return (1);
-
+
+ if ((rpool->addr.type == PF_ADDR_TABLE &&
+ rpool->addr.p.tbl->pfrkt_refcntcost > 0) ||
+ (rpool->addr.type == PF_ADDR_DYNIFTL &&
+ rpool->addr.p.dyn->pfid_kt->pfrkt_refcntcost > 0))
+ cload = ((UINT16_MAX * rpool->states)
+ / rpool->weight);
+ else
+ cload = rpool->states;
+
/* find lc minimum */
- if (states > rpool->states) {
+ if (cload < load) {
states = rpool->states;
+ weight = rpool->weight;
+ load = cload;
PF_ACPY(naddr, &rpool->counter, af);
if (init_addr != NULL &&
@@ -563,11 +586,10 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
if ((rpool->opts & PF_POOL_TYPEMASK) ==
PF_POOL_LEASTSTATES)
addlog(" with state count %llu", states);
- if (((rpool->addr.type == PF_ADDR_TABLE &&
+ if ((rpool->addr.type == PF_ADDR_TABLE &&
rpool->addr.p.tbl->pfrkt_refcntcost > 0) ||
(rpool->addr.type == PF_ADDR_DYNIFTL &&
- rpool->addr.p.dyn->pfid_kt->pfrkt_refcntcost > 0)) &&
- ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_LEASTSTATES))
+ rpool->addr.p.dyn->pfid_kt->pfrkt_refcntcost > 0))
addlog(" with weight %u", weight);
addlog("\n");
}