Page MenuHomeFreeBSD

D39940.diff
No OneTemporary

D39940.diff

diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2403,7 +2403,7 @@
struct pf_keth_rule **, struct pf_keth_rule **,
int *);
-int pf_map_addr(u_int8_t, struct pf_krule *,
+u_short pf_map_addr(u_int8_t, struct pf_krule *,
struct pf_addr *, struct pf_addr *,
struct pf_addr *, struct pf_ksrc_node **);
struct pf_krule *pf_get_translation(struct pf_pdesc *, struct mbuf *,
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -329,7 +329,7 @@
struct pf_state_key_cmp *, u_int);
static int pf_src_connlimit(struct pf_kstate **);
static void pf_overload_task(void *v, int pending);
-static int pf_insert_src_node(struct pf_ksrc_node **,
+static u_short pf_insert_src_node(struct pf_ksrc_node **,
struct pf_krule *, struct pf_addr *, sa_family_t);
static u_int pf_purge_expired_states(u_int, int);
static void pf_purge_unlinked_rules(void);
@@ -865,11 +865,12 @@
uma_zfree(V_pf_sources_z, sn);
}
-static int
+static u_short
pf_insert_src_node(struct pf_ksrc_node **sn, struct pf_krule *rule,
struct pf_addr *src, sa_family_t af)
{
- struct pf_srchash *sh = NULL;
+ u_short reason = 0;
+ struct pf_srchash *sh = NULL;
KASSERT((rule->rule_flag & PFRULE_SRCTRACK ||
rule->rpool.opts & PF_POOL_STICKYADDR),
@@ -881,15 +882,19 @@
if (*sn == NULL) {
PF_HASHROW_ASSERT(sh);
- if (!rule->max_src_nodes ||
- counter_u64_fetch(rule->src_nodes) < rule->max_src_nodes)
- (*sn) = uma_zalloc(V_pf_sources_z, M_NOWAIT | M_ZERO);
- else
- counter_u64_add(V_pf_status.lcounters[LCNT_SRCNODES],
- 1);
+ if (rule->max_src_nodes &&
+ counter_u64_fetch(rule->src_nodes) >= rule->max_src_nodes) {
+ counter_u64_add(V_pf_status.lcounters[LCNT_SRCNODES], 1);
+ PF_HASHROW_UNLOCK(sh);
+ reason = PFRES_SRCLIMIT;
+ goto done;
+ }
+
+ (*sn) = uma_zalloc(V_pf_sources_z, M_NOWAIT | M_ZERO);
if ((*sn) == NULL) {
PF_HASHROW_UNLOCK(sh);
- return (-1);
+ reason = PFRES_MEMORY;
+ goto done;
}
for (int i = 0; i < 2; i++) {
@@ -899,7 +904,8 @@
if ((*sn)->bytes[i] == NULL || (*sn)->packets[i] == NULL) {
pf_free_src_node(*sn);
PF_HASHROW_UNLOCK(sh);
- return (-1);
+ reason = PFRES_MEMORY;
+ goto done;
}
}
@@ -926,10 +932,12 @@
(*sn)->states >= rule->max_src_states) {
counter_u64_add(V_pf_status.lcounters[LCNT_SRCSTATES],
1);
- return (-1);
+ reason = PFRES_SRCLIMIT;
+ goto done;
}
}
- return (0);
+done:
+ return (reason);
}
void
@@ -4581,7 +4589,7 @@
struct pf_ksrc_node *sn = NULL;
struct tcphdr *th = &pd->hdr.tcp;
u_int16_t mss = V_tcp_mssdflt;
- u_short reason;
+ u_short reason, sn_reason;
/* check maximums */
if (r->max_states &&
@@ -4593,14 +4601,15 @@
/* src node for filter rule */
if ((r->rule_flag & PFRULE_SRCTRACK ||
r->rpool.opts & PF_POOL_STICKYADDR) &&
- pf_insert_src_node(&sn, r, pd->src, pd->af) != 0) {
- REASON_SET(&reason, PFRES_SRCLIMIT);
+ (sn_reason = pf_insert_src_node(&sn, r, pd->src, pd->af)) != 0) {
+ REASON_SET(&reason, sn_reason);
goto csfailed;
}
/* src node for translation rule */
if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
- pf_insert_src_node(&nsn, nr, &sk->addr[pd->sidx], pd->af)) {
- REASON_SET(&reason, PFRES_SRCLIMIT);
+ (sn_reason = pf_insert_src_node(&nsn, nr, &sk->addr[pd->sidx],
+ pd->af)) != 0 ) {
+ REASON_SET(&reason, sn_reason);
goto csfailed;
}
s = pf_alloc_state(M_NOWAIT);
@@ -4689,8 +4698,9 @@
}
if (r->rt) {
- if (pf_map_addr(pd->af, r, pd->src, &s->rt_addr, NULL, &sn)) {
- REASON_SET(&reason, PFRES_MAPFAILED);
+ /* pf_map_addr increases the reason counters */
+ if ((reason = pf_map_addr(pd->af, r, pd->src, &s->rt_addr, NULL,
+ &sn)) != 0) {
pf_src_tree_remove_state(s);
s->timeout = PFTM_UNLINKED;
STATE_DEC_COUNTERS(s);
diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c
--- a/sys/netpfil/pf/pf_lb.c
+++ b/sys/netpfil/pf/pf_lb.c
@@ -342,10 +342,11 @@
return (1);
}
-int
+u_short
pf_map_addr(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr,
struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_ksrc_node **sn)
{
+ u_short reason = 0;
struct pf_kpool *rpool = &r->rpool;
struct pf_addr *raddr = NULL, *rmask = NULL;
struct pf_srchash *sh = NULL;
@@ -364,8 +365,10 @@
/* If the supplied address is the same as the current one we've
* been asked before, so tell the caller that there's no other
* address to be had. */
- if (PF_AEQ(naddr, &(*sn)->raddr, af))
- return (1);
+ if (PF_AEQ(naddr, &(*sn)->raddr, af)) {
+ reason = PFRES_MAPFAILED;
+ goto done;
+ }
PF_ACPY(naddr, &(*sn)->raddr, af);
if (V_pf_status.debug >= PF_DEBUG_NOISY) {
@@ -375,15 +378,15 @@
pf_print_host(naddr, 0, af);
printf("\n");
}
- return (0);
+ goto done;
}
mtx_lock(&rpool->mtx);
/* Find the route using chosen algorithm. Store the found route
in src_node if it was given or found. */
if (rpool->cur->addr.type == PF_ADDR_NOROUTE) {
- mtx_unlock(&rpool->mtx);
- return (1);
+ reason = PFRES_MAPFAILED;
+ goto done_pool_mtx;
}
if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
switch (af) {
@@ -392,8 +395,8 @@
if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 &&
(rpool->opts & PF_POOL_TYPEMASK) !=
PF_POOL_ROUNDROBIN) {
- mtx_unlock(&rpool->mtx);
- return (1);
+ reason = PFRES_MAPFAILED;
+ goto done_pool_mtx;
}
raddr = &rpool->cur->addr.p.dyn->pfid_addr4;
rmask = &rpool->cur->addr.p.dyn->pfid_mask4;
@@ -404,8 +407,8 @@
if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 &&
(rpool->opts & PF_POOL_TYPEMASK) !=
PF_POOL_ROUNDROBIN) {
- mtx_unlock(&rpool->mtx);
- return (1);
+ reason = PFRES_MAPFAILED;
+ goto done_pool_mtx;
}
raddr = &rpool->cur->addr.p.dyn->pfid_addr6;
rmask = &rpool->cur->addr.p.dyn->pfid_mask6;
@@ -414,8 +417,8 @@
}
} else if (rpool->cur->addr.type == PF_ADDR_TABLE) {
if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN) {
- mtx_unlock(&rpool->mtx);
- return (1); /* unsupported */
+ reason = PFRES_MAPFAILED;
+ goto done_pool_mtx; /* unsupported */
}
} else {
raddr = &rpool->cur->addr.v.a.addr;
@@ -503,8 +506,8 @@
/* table contains no address of type 'af' */
if (rpool->cur != acur)
goto try_next;
- mtx_unlock(&rpool->mtx);
- return (1);
+ reason = PFRES_MAPFAILED;
+ goto done_pool_mtx;
}
} else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
rpool->tblidx = -1;
@@ -513,8 +516,8 @@
/* table contains no address of type 'af' */
if (rpool->cur != acur)
goto try_next;
- mtx_unlock(&rpool->mtx);
- return (1);
+ reason = PFRES_MAPFAILED;
+ goto done_pool_mtx;
}
} else {
raddr = &rpool->cur->addr.v.a.addr;
@@ -533,8 +536,6 @@
if (*sn != NULL)
PF_ACPY(&(*sn)->raddr, naddr, af);
- mtx_unlock(&rpool->mtx);
-
if (V_pf_status.debug >= PF_DEBUG_NOISY &&
(rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
printf("pf_map_addr: selected address ");
@@ -542,7 +543,15 @@
printf("\n");
}
- return (0);
+done_pool_mtx:
+ mtx_unlock(&rpool->mtx);
+
+done:
+ if (reason) {
+ counter_u64_add(V_pf_status.counters[reason], 1);
+ }
+
+ return (reason);
}
struct pf_krule *

File Metadata

Mime Type
text/plain
Expires
Sun, Sep 29, 3:21 AM (21 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
13094237
Default Alt Text
D39940.diff (7 KB)

Event Timeline