summaryrefslogtreecommitdiffstats
path: root/sys/net/pf_table.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net/pf_table.c')
-rw-r--r--sys/net/pf_table.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/sys/net/pf_table.c b/sys/net/pf_table.c
index c6f6f74ecc7..724ceb6e83d 100644
--- a/sys/net/pf_table.c
+++ b/sys/net/pf_table.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_table.c,v 1.91 2011/07/03 23:37:55 zinke Exp $ */
+/* $OpenBSD: pf_table.c,v 1.92 2011/07/08 22:11:17 mikeb Exp $ */
/*
* Copyright (c) 2002 Cedric Berger
@@ -2148,7 +2148,7 @@ pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter,
struct pfr_kentry *ke, *ke2;
struct pf_addr *addr;
union sockaddr_union mask;
- int idx = -1, use_counter = 0;
+ int startidx, idx = -1, loop = 0, use_counter = 0;
if (af == AF_INET)
addr = (struct pf_addr *)&pfr_sin.sin_addr;
@@ -2165,23 +2165,29 @@ pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter,
use_counter = 1;
if (idx < 0)
idx = 0;
+ startidx = idx;
_next_block:
+ if (loop && startidx == idx) {
+ kt->pfrkt_nomatch++;
+ return (1);
+ }
+
ke = pfr_kentry_byidx(kt, idx, af);
if (ke == NULL) {
/* we don't have this idx, try looping */
- idx = 0;
- ke = pfr_kentry_byidx(kt, idx, af);
- if (ke == NULL) {
+ if (loop || (ke = pfr_kentry_byidx(kt, 0, af)) == NULL) {
kt->pfrkt_nomatch++;
return (1);
}
+ idx = 0;
+ loop++;
}
pfr_prepare_network(&pfr_mask, af, ke->pfrke_net);
*raddr = SUNION2PF(&ke->pfrke_sa, af);
*rmask = SUNION2PF(&pfr_mask, af);
- if (use_counter) {
+ if (use_counter && !PF_AZERO(counter, af)) {
/* is supplied address within block? */
if (!PF_MATCHA(0, *raddr, *rmask, counter, af)) {
/* no, go to next block in table */