summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorRyan Thomas McBride <mcbride@cvs.openbsd.org>2011-07-27 00:26:11 +0000
committerRyan Thomas McBride <mcbride@cvs.openbsd.org>2011-07-27 00:26:11 +0000
commit68db64f6aa38ae259e5795c3322e6406af0b0879 (patch)
tree1efad0ea2cb6f49698ddd244204b7f56d3b084d4 /sys/net
parent05eda0b2c9cbf976e3527833943b961079ab7cb8 (diff)
Add support for weighted round-robin in load balancing pools and tables.
Diff from zinke@ with a some minor cleanup. ok henning claudio deraadt
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/pf.c12
-rw-r--r--sys/net/pf_lb.c75
-rw-r--r--sys/net/pf_table.c163
-rw-r--r--sys/net/pfvar.h24
4 files changed, 202 insertions, 72 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 8af51bcacd3..41a092e6934 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.768 2011/07/24 12:13:10 mcbride Exp $ */
+/* $OpenBSD: pf.c,v 1.769 2011/07/27 00:26:10 mcbride Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -2942,16 +2942,10 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
/* order is irrelevant */
SLIST_INSERT_HEAD(&rules, ri, entry);
pf_rule_to_actions(r, &act);
- if (pf_get_transaddr(r, pd, sns) == -1) {
+ if (pf_get_transaddr(r, pd, sns, &nr) == -1) {
REASON_SET(&reason, PFRES_MEMORY);
goto cleanup;
}
- /*
- * We need to save this rule pointer,
- * otherwise the counter decrease
- * would not work for SLB.
- */
- nr = r;
if (r->log || act.log & PF_LOG_MATCHES)
PFLOG_PACKET(kif, m, direction,
reason, r, a, ruleset, pd);
@@ -2983,7 +2977,7 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
/* apply actions for last matching pass/block rule */
pf_rule_to_actions(r, &act);
- if (pf_get_transaddr(r, pd, sns) == -1) {
+ if (pf_get_transaddr(r, pd, sns, &nr) == -1) {
REASON_SET(&reason, PFRES_MEMORY);
goto cleanup;
}
diff --git a/sys/net/pf_lb.c b/sys/net/pf_lb.c
index d4873cd8eb9..5f8e2069598 100644
--- a/sys/net/pf_lb.c
+++ b/sys/net/pf_lb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_lb.c,v 1.15 2011/07/03 23:37:55 zinke Exp $ */
+/* $OpenBSD: pf_lb.c,v 1.16 2011/07/27 00:26:10 mcbride Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -283,7 +283,8 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
struct pf_addr *raddr = &rpool->addr.v.a.addr;
struct pf_addr *rmask = &rpool->addr.v.a.mask;
struct pf_src_node k;
- u_int32_t states;
+ u_int64_t states;
+ u_int16_t weight;
if (sns[type] == NULL && rpool->opts & PF_POOL_STICKYADDR &&
(rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
@@ -401,17 +402,47 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
if (pfr_pool_get(rpool->addr.p.tbl,
&rpool->tblidx, &rpool->counter,
&raddr, &rmask, &rpool->kif,
- &rpool->states, af, NULL))
+ &rpool->states, &rpool->weight,
+ &rpool->curweight, af, NULL))
return (1);
} else if (rpool->addr.type == PF_ADDR_DYNIFTL) {
if (pfr_pool_get(rpool->addr.p.dyn->pfid_kt,
&rpool->tblidx, &rpool->counter,
&raddr, &rmask, &rpool->kif,
- &rpool->states, af, pf_islinklocal))
+ &rpool->states, &rpool->weight,
+ &rpool->curweight, af, pf_islinklocal))
return (1);
} else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af))
return (1);
+ /* iterate over table if it contains entries which are weighted */
+ if (rpool->addr.p.tbl->pfrkt_refcntcost > 0) {
+ do {
+ if (rpool->addr.type == PF_ADDR_TABLE) {
+ if (pfr_pool_get(rpool->addr.p.tbl,
+ &rpool->tblidx, &rpool->counter,
+ &raddr, &rmask, &rpool->kif,
+ &rpool->states, &rpool->weight,
+ &rpool->curweight, af, NULL))
+ return (1);
+ } else if (rpool->addr.type == PF_ADDR_DYNIFTL) {
+ if (pfr_pool_get(
+ rpool->addr.p.dyn->pfid_kt,
+ &rpool->tblidx, &rpool->counter,
+ &raddr, &rmask, &rpool->kif,
+ &rpool->states, &rpool->weight,
+ &rpool->curweight, af,
+ pf_islinklocal))
+ return (1);
+ } else if (pf_match_addr(0, raddr, rmask,
+ &rpool->counter, af))
+ return (1);
+ PF_AINC(&rpool->counter, af);
+ } while (rpool->weight < rpool->curweight);
+
+ weight = rpool->weight;
+ }
+
PF_ACPY(naddr, &rpool->counter, af);
if (init_addr != NULL && PF_AZERO(init_addr, af))
PF_ACPY(init_addr, naddr, af);
@@ -423,13 +454,15 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
if (pfr_pool_get(rpool->addr.p.tbl,
&rpool->tblidx, &rpool->counter,
&raddr, &rmask, &rpool->kif,
- &rpool->states, af, NULL))
+ &rpool->states, &rpool->weight,
+ &rpool->curweight, af, NULL))
return (1);
} else if (rpool->addr.type == PF_ADDR_DYNIFTL) {
if (pfr_pool_get(rpool->addr.p.dyn->pfid_kt,
&rpool->tblidx, &rpool->counter,
&raddr, &rmask, &rpool->kif,
- &rpool->states, af, pf_islinklocal))
+ &rpool->states, &rpool->weight,
+ &rpool->curweight, af, pf_islinklocal))
return (1);
} else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af))
return (1);
@@ -441,29 +474,31 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
PF_ACPY(naddr, &rpool->counter, af);
if (init_addr != NULL && PF_AZERO(init_addr, af))
PF_ACPY(init_addr, naddr, af);
- PF_AINC(&rpool->counter, af);
/*
* iterate *once* over whole table and find destination with
* least connection
*/
- while (pf_match_addr(1, &faddr, rmask, &rpool->counter, af) &&
- (states > 0)) {
-
+ do {
+ PF_AINC(&rpool->counter, af);
if (rpool->addr.type == PF_ADDR_TABLE) {
if (pfr_pool_get(rpool->addr.p.tbl,
&rpool->tblidx, &rpool->counter,
&raddr, &rmask, &rpool->kif,
- &rpool->states, af, NULL))
+ &rpool->states, &rpool->weight,
+ &rpool->curweight, af, NULL))
return (1);
} else if (rpool->addr.type == PF_ADDR_DYNIFTL) {
if (pfr_pool_get(rpool->addr.p.dyn->pfid_kt,
&rpool->tblidx, &rpool->counter,
&raddr, &rmask, &rpool->kif,
- &rpool->states, af, pf_islinklocal))
+ &rpool->states, &rpool->weight,
+ &rpool->curweight, af, pf_islinklocal))
return (1);
- }
-
+ } else if (pf_match_addr(0, raddr, rmask,
+ &rpool->counter, af))
+ return (1);
+
/* find lc minimum */
if (states > rpool->states) {
states = rpool->states;
@@ -473,8 +508,8 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
PF_AZERO(init_addr, af))
PF_ACPY(init_addr, naddr, af);
}
- PF_AINC(&rpool->counter, af);
- }
+ } while (pf_match_addr(1, &faddr, rmask, &rpool->counter, af) &&
+ (states > 0));
if (rpool->addr.type == PF_ADDR_TABLE) {
if (pfr_states_increase(rpool->addr.p.tbl,
@@ -519,6 +554,9 @@ 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 %d", states);
+ if ((rpool->addr.p.tbl->pfrkt_refcntcost > 0) &&
+ ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_LEASTSTATES))
+ addlog(" with weight %u", weight);
addlog("\n");
}
@@ -527,7 +565,7 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
int
pf_get_transaddr(struct pf_rule *r, struct pf_pdesc *pd,
- struct pf_src_node **sns)
+ struct pf_src_node **sns, struct pf_rule **nr)
{
struct pf_addr naddr;
u_int16_t nport = 0;
@@ -543,6 +581,7 @@ pf_get_transaddr(struct pf_rule *r, struct pf_pdesc *pd,
r->nat.proxy_port[1]);
return (-1);
}
+ *nr = r;
PF_ACPY(&pd->nsaddr, &naddr, pd->af);
pd->nsport = nport;
}
@@ -569,7 +608,7 @@ pf_get_transaddr(struct pf_rule *r, struct pf_pdesc *pd,
nport = htons((u_int16_t)tmp_nport);
} else if (r->rdr.proxy_port[0])
nport = htons(r->rdr.proxy_port[0]);
-
+ *nr = r;
PF_ACPY(&pd->ndaddr, &naddr, pd->af);
if (nport)
pd->ndport = nport;
diff --git a/sys/net/pf_table.c b/sys/net/pf_table.c
index 724ceb6e83d..17f7b786d43 100644
--- a/sys/net/pf_table.c
+++ b/sys/net/pf_table.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_table.c,v 1.92 2011/07/08 22:11:17 mikeb Exp $ */
+/* $OpenBSD: pf_table.c,v 1.93 2011/07/27 00:26:10 mcbride Exp $ */
/*
* Copyright (c) 2002 Cedric Berger
@@ -140,6 +140,7 @@ struct sockaddr_in6 pfr_sin6;
union sockaddr_union pfr_mask;
struct pf_addr pfr_ffaddr;
+int pfr_gcd(int, int);
void pfr_copyout_addr(struct pfr_addr *,
struct pfr_kentry *ke);
int pfr_validate_addr(struct pfr_addr *);
@@ -179,6 +180,8 @@ void pfr_destroy_ktables(struct pfr_ktableworkq *, int);
void pfr_destroy_ktable(struct pfr_ktable *, int);
int pfr_ktable_compare(struct pfr_ktable *,
struct pfr_ktable *);
+void pfr_ktable_winfo_update(struct pfr_ktable *,
+ struct pfr_kentry *);
struct pfr_ktable *pfr_lookup_table(struct pfr_table *);
void pfr_clean_node_mask(struct pfr_ktable *,
struct pfr_kentryworkq *);
@@ -194,6 +197,19 @@ struct pfr_ktablehead pfr_ktables;
struct pfr_table pfr_nulltable;
int pfr_ktable_cnt;
+int
+pfr_gcd(int m, int n)
+{
+ int t;
+
+ while (m > 0) {
+ t = n % m;
+ n = m;
+ m = t;
+ }
+ return (n);
+}
+
void
pfr_initialize(void)
{
@@ -476,6 +492,9 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
ad.pfra_fback = PFR_FB_ADDED;
xadd++;
}
+ if (p->pfrke_type == PFRKE_COST)
+ kt->pfrkt_refcntcost++;
+ pfr_ktable_winfo_update(kt, p);
}
_skip:
if (flags & PFR_FLAG_FEEDBACK)
@@ -804,36 +823,28 @@ pfr_create_kentry(struct pfr_addr *ad, u_int32_t flags)
{
struct pfr_kentry_all *ke;
- if (flags & PFR_TFLAG_COST) {
- switch (ad->pfra_type) {
- case PFRKE_PLAIN:
- case PFRKE_ROUTE:
- ad->pfra_type = PFRKE_COST;
- break;
- case PFRKE_COST:
- break;
- default:
- /* not compatible with PFR_FLAG_COST */
- /* XXX debug output? check earlier? */
- return (NULL);
- }
- }
-
ke = pool_get(&pfr_kentry_pl[ad->pfra_type], PR_NOWAIT | PR_ZERO);
if (ke == NULL)
return (NULL);
ke->pfrke_type = ad->pfra_type;
+ /* set weight allowing implicit weights */
+ if (ad->pfra_weight == 0)
+ ad->pfra_weight = 1;
+
switch (ke->pfrke_type) {
- case PFRKE_ROUTE:
+ case PFRKE_PLAIN:
+ break;
case PFRKE_COST:
- ke->pfrke_rkif = pfi_kif_get(ad->pfra_ifname);
+ ((struct pfr_kentry_cost *)ke)->weight = ad->pfra_weight;
+ /* FALLTHROUGH */
+ case PFRKE_ROUTE:
+ if (ad->pfra_ifname[0])
+ ke->pfrke_rkif = pfi_kif_get(ad->pfra_ifname);
if (ke->pfrke_rkif)
pfi_kif_ref(ke->pfrke_rkif, PFI_KIF_REF_ROUTE);
break;
- case PFRKE_PLAIN:
- break;
default:
panic("unknown pfrke_type %d", ke->pfrke_type);
break;
@@ -888,6 +899,9 @@ pfr_insert_kentries(struct pfr_ktable *kt,
}
p->pfrke_tzero = tzero;
++n;
+ if (p->pfrke_type == PFRKE_COST)
+ kt->pfrkt_refcntcost++;
+ pfr_ktable_winfo_update(kt, p);
YIELD(n, 1);
}
kt->pfrkt_cnt += n;
@@ -911,7 +925,10 @@ pfr_insert_kentry(struct pfr_ktable *kt, struct pfr_addr *ad, long tzero)
return (rv);
p->pfrke_tzero = tzero;
+ if (p->pfrke_type == PFRKE_COST)
+ kt->pfrkt_refcntcost++;
kt->pfrkt_cnt++;
+ pfr_ktable_winfo_update(kt, p);
return (0);
}
@@ -921,15 +938,27 @@ pfr_remove_kentries(struct pfr_ktable *kt,
struct pfr_kentryworkq *workq)
{
struct pfr_kentry *p;
+ struct pfr_kentryworkq addrq;
int n = 0;
SLIST_FOREACH(p, workq, pfrke_workq) {
pfr_unroute_kentry(kt, p);
++n;
YIELD(n, 1);
+ if (p->pfrke_type == PFRKE_COST)
+ kt->pfrkt_refcntcost--;
}
kt->pfrkt_cnt -= n;
pfr_destroy_kentries(workq);
+
+ /* update maxweight and gcd for load balancing */
+ if (kt->pfrkt_refcntcost > 0) {
+ kt->pfrkt_gcdweight = 0;
+ kt->pfrkt_maxweight = 1;
+ pfr_enqueue_addrs(kt, &addrq, NULL, 0);
+ SLIST_FOREACH(p, &addrq, pfrke_workq)
+ pfr_ktable_winfo_update(kt, p);
+ }
}
void
@@ -1071,9 +1100,11 @@ pfr_copyout_addr(struct pfr_addr *ad, struct pfr_kentry *ke)
ad->pfra_ip4addr = ke->pfrke_sa.sin.sin_addr;
else if (ad->pfra_af == AF_INET6)
ad->pfra_ip6addr = ke->pfrke_sa.sin6.sin6_addr;
+ if (ke->pfrke_counters != NULL)
+ ad->pfra_states = ke->pfrke_counters->states;
switch (ke->pfrke_type) {
case PFRKE_COST:
- ad->pfra_states = ((struct pfr_kentry_cost *)ke)->states;
+ ad->pfra_weight = ((struct pfr_kentry_cost *)ke)->weight;
/* FALLTHROUGH */
case PFRKE_ROUTE:
if (((struct pfr_kentry_route *)ke)->kif != NULL)
@@ -1591,6 +1622,9 @@ _skip:
}
SLIST_INSERT_HEAD(&addrq, p, pfrke_workq);
xaddr++;
+ if (p->pfrke_type == PFRKE_COST)
+ kt->pfrkt_refcntcost++;
+ pfr_ktable_winfo_update(kt, p);
}
if (!(flags & PFR_FLAG_DUMMY)) {
if (kt->pfrkt_shadow != NULL)
@@ -1949,6 +1983,9 @@ pfr_create_ktable(struct pfr_table *tbl, long tzero, int attachruleset,
return (NULL);
}
kt->pfrkt_tzero = tzero;
+ kt->pfrkt_refcntcost = 0;
+ kt->pfrkt_gcdweight = 0;
+ kt->pfrkt_maxweight = 1;
return (kt);
}
@@ -2142,7 +2179,7 @@ pfr_detach_table(struct pfr_ktable *kt)
int
pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter,
struct pf_addr **raddr, struct pf_addr **rmask, struct pfi_kif **kif,
- u_int32_t *states, sa_family_t af,
+ u_int64_t *states, u_int16_t *weight, int *curweight, sa_family_t af,
int (*filter)(sa_family_t, struct pf_addr *))
{
struct pfr_kentry *ke, *ke2;
@@ -2167,7 +2204,7 @@ pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter,
idx = 0;
startidx = idx;
-_next_block:
+ _next_block:
if (loop && startidx == idx) {
kt->pfrkt_nomatch++;
return (1);
@@ -2183,6 +2220,15 @@ _next_block:
idx = 0;
loop++;
}
+
+ /* Get current weight for weighted round-robin */
+ if (idx == 0 && use_counter == 1 && kt->pfrkt_refcntcost > 0) {
+ *curweight = *curweight - kt->pfrkt_gcdweight;
+
+ if (*curweight < 1)
+ *curweight = kt->pfrkt_maxweight;
+ }
+
pfr_prepare_network(&pfr_mask, af, ke->pfrke_net);
*raddr = SUNION2PF(&ke->pfrke_sa, af);
*rmask = SUNION2PF(&pfr_mask, af);
@@ -2210,14 +2256,18 @@ _next_block:
PF_ACPY(counter, addr, af);
*pidx = idx;
kt->pfrkt_match++;
+ *states = 0;
+ if (ke->pfrke_counters != NULL)
+ *states = ke->pfrke_counters->states;
switch (ke->pfrke_type) {
case PFRKE_COST:
- *states = ((struct pfr_kentry_cost *)ke)->states;
+ *weight = ((struct pfr_kentry_cost *)ke)->weight;
/* FALLTHROUGH */
case PFRKE_ROUTE:
*kif = ((struct pfr_kentry_route *)ke)->kif;
break;
default:
+ *weight = 1;
break;
}
return (0);
@@ -2238,15 +2288,19 @@ _next_block:
PF_ACPY(counter, addr, af);
*pidx = idx;
kt->pfrkt_match++;
+ *states = 0;
+ if (ke->pfrke_counters != NULL)
+ *states = ke->pfrke_counters->states;
switch (ke->pfrke_type) {
case PFRKE_COST:
- *states =
- ((struct pfr_kentry_cost *)ke)->states;
+ *weight =
+ ((struct pfr_kentry_cost *)ke)->weight;
/* FALLTHROUGH */
case PFRKE_ROUTE:
*kif = ((struct pfr_kentry_route *)ke)->kif;
break;
default:
+ *weight = 1;
break;
}
return (0);
@@ -2291,41 +2345,53 @@ pfr_kentry_byidx(struct pfr_ktable *kt, int idx, int af)
}
}
-/* added for slb counter use */
+/* Added for load balancing state counter use. */
int
pfr_states_increase(struct pfr_ktable *kt, struct pf_addr *addr, int af)
{
struct pfr_kentry *ke;
ke = pfr_kentry_byaddr(kt, addr, af, 1);
- if (ke == NULL || ke->pfrke_type != PFRKE_COST)
+ if (ke == NULL)
return (-1);
- ((struct pfr_kentry_cost *)ke)->states++;
- return (((struct pfr_kentry_cost *)ke)->states);
+ if (ke->pfrke_counters == NULL)
+ ke->pfrke_counters = pool_get(&pfr_kcounters_pl,
+ PR_NOWAIT | PR_ZERO);
+ if (ke->pfrke_counters == NULL)
+ return (-1);
+
+ ke->pfrke_counters->states++;
+ return ke->pfrke_counters->states;
}
-/* added for slb counter use */
+/* Added for load balancing state counter use. */
int
pfr_states_decrease(struct pfr_ktable *kt, struct pf_addr *addr, int af)
{
struct pfr_kentry *ke;
ke = pfr_kentry_byaddr(kt, addr, af, 1);
- if (ke == NULL || ke->pfrke_type != PFRKE_COST)
+ if (ke == NULL)
return (-1);
- if (((struct pfr_kentry_cost *)ke)->states > 0)
- ((struct pfr_kentry_cost *)ke)->states--;
+ if (ke->pfrke_counters == NULL)
+ ke->pfrke_counters = pool_get(&pfr_kcounters_pl,
+ PR_NOWAIT | PR_ZERO);
+ if (ke->pfrke_counters == NULL)
+ return (-1);
+
+ if (ke->pfrke_counters->states > 0)
+ ke->pfrke_counters->states--;
else
DPFPRINTF(LOG_DEBUG,
- "pfr_states_increase: states-- when states <= 0");
+ "pfr_states_decrease: states-- when states <= 0");
- return (((struct pfr_kentry_cost *)ke)->states);
+ return ke->pfrke_counters->states;
}
/*
- * Added for slb to find a kentry outside of the table.
+ * Added for load balancing to find a kentry outside of the table.
* We need to create a custom pfr_addr struct.
*/
struct pfr_kentry *
@@ -2376,3 +2442,26 @@ pfr_dynaddr_update(struct pfr_ktable *kt, struct pfi_dynaddr *dyn)
rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
splx(s);
}
+
+void
+pfr_ktable_winfo_update(struct pfr_ktable *kt, struct pfr_kentry *p) {
+ /*
+ * If cost flag is set,
+ * gcdweight is needed for round-robin.
+ */
+ if (kt->pfrkt_refcntcost > 0) {
+ u_int16_t weight;
+
+ weight = (p->pfrke_type == PFRKE_COST) ?
+ ((struct pfr_kentry_cost *)p)->weight : 1;
+
+ if (kt->pfrkt_gcdweight == 0)
+ kt->pfrkt_gcdweight = weight;
+
+ kt->pfrkt_gcdweight =
+ pfr_gcd(weight, kt->pfrkt_gcdweight);
+
+ if (kt->pfrkt_maxweight < weight)
+ kt->pfrkt_maxweight = weight;
+ }
+}
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index d10d2ae036f..cec2e308a77 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.340 2011/07/08 18:50:52 henning Exp $ */
+/* $OpenBSD: pfvar.h,v 1.341 2011/07/27 00:26:10 mcbride Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -393,6 +393,7 @@ struct pf_rule_addr {
u_int16_t port[2];
u_int8_t neg;
u_int8_t port_op;
+ u_int16_t weight;
};
struct pf_poolhashkey {
@@ -413,7 +414,9 @@ struct pf_pool {
char ifname[IFNAMSIZ];
struct pfi_kif *kif;
int tblidx;
- u_int32_t states;
+ u_int64_t states;
+ int curweight;
+ u_int16_t weight;
u_int16_t proxy_port[2];
u_int8_t port_op;
u_int8_t opts;
@@ -1007,11 +1010,10 @@ RB_PROTOTYPE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare);
#define PFR_TFLAG_REFERENCED 0x00000010
#define PFR_TFLAG_REFDANCHOR 0x00000020
#define PFR_TFLAG_COUNTERS 0x00000040
-#define PFR_TFLAG_COST 0x00000080
/* Adjust masks below when adding flags. */
-#define PFR_TFLAG_USRMASK 0x000000C3
+#define PFR_TFLAG_USRMASK 0x00000043
#define PFR_TFLAG_SETMASK 0x0000003C
-#define PFR_TFLAG_ALLMASK 0x000000FF
+#define PFR_TFLAG_ALLMASK 0x0000007F
struct pfr_table {
char pfrt_anchor[MAXPATHLEN];
@@ -1031,6 +1033,7 @@ struct pfr_addr {
} pfra_u;
char pfra_ifname[IFNAMSIZ];
u_int32_t pfra_states;
+ u_int16_t pfra_weight;
u_int8_t pfra_af;
u_int8_t pfra_net;
u_int8_t pfra_not;
@@ -1070,6 +1073,7 @@ struct pfr_tstats {
struct pfr_kcounters {
u_int64_t pfrkc_packets[PFR_DIR_MAX][PFR_OP_ADDR_MAX];
u_int64_t pfrkc_bytes[PFR_DIR_MAX][PFR_OP_ADDR_MAX];
+ u_int64_t states;
};
SLIST_HEAD(pfr_kentryworkq, pfr_kentry);
@@ -1121,7 +1125,7 @@ struct pfr_kentry_cost {
struct pfi_kif *kif;
/* Above overlaps with pfr_kentry route */
- u_int32_t states;
+ u_int16_t weight;
};
struct pfr_kentry_all {
@@ -1146,6 +1150,9 @@ struct pfr_ktable {
struct pf_ruleset *pfrkt_rs;
long pfrkt_larg;
int pfrkt_nflags;
+ u_int64_t pfrkt_refcntcost;
+ u_int16_t pfrkt_gcdweight;
+ u_int16_t pfrkt_maxweight;
};
#define pfrkt_t pfrkt_ts.pfrts_t
#define pfrkt_name pfrkt_t.pfrt_name
@@ -1825,7 +1832,8 @@ void pfr_update_stats(struct pfr_ktable *, struct pf_addr *, sa_family_t,
u_int64_t, int, int, int);
int pfr_pool_get(struct pfr_ktable *, int *, struct pf_addr *,
struct pf_addr **, struct pf_addr **, struct pfi_kif **,
- u_int32_t *, sa_family_t, int (*)(sa_family_t, struct pf_addr *));
+ u_int64_t *, u_int16_t *, int *,
+ sa_family_t, int (*)(sa_family_t, struct pf_addr *));
int pfr_states_increase(struct pfr_ktable *, struct pf_addr *, int);
int pfr_states_decrease(struct pfr_ktable *, struct pf_addr *, int);
struct pfr_kentry *
@@ -1961,7 +1969,7 @@ int pf_step_out_of_anchor(int *, struct pf_ruleset **,
int *);
int pf_get_transaddr(struct pf_rule *, struct pf_pdesc *,
- struct pf_src_node **);
+ struct pf_src_node **, struct pf_rule **);
int pf_map_addr(sa_family_t, struct pf_rule *,
struct pf_addr *, struct pf_addr *,