diff options
author | Ryan Thomas McBride <mcbride@cvs.openbsd.org> | 2011-07-27 00:26:11 +0000 |
---|---|---|
committer | Ryan Thomas McBride <mcbride@cvs.openbsd.org> | 2011-07-27 00:26:11 +0000 |
commit | 68db64f6aa38ae259e5795c3322e6406af0b0879 (patch) | |
tree | 1efad0ea2cb6f49698ddd244204b7f56d3b084d4 /sys/net | |
parent | 05eda0b2c9cbf976e3527833943b961079ab7cb8 (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.c | 12 | ||||
-rw-r--r-- | sys/net/pf_lb.c | 75 | ||||
-rw-r--r-- | sys/net/pf_table.c | 163 | ||||
-rw-r--r-- | sys/net/pfvar.h | 24 |
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 *, |