diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -615,8 +615,8 @@ struct pf_addr raddr; union pf_rule_ptr rule; struct pfi_kif *kif; - u_int64_t bytes[2]; - u_int64_t packets[2]; + counter_u64_t bytes[2]; + counter_u64_t packets[2]; u_int32_t states; u_int32_t conn; struct pf_threshold conn_rate; 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 @@ -702,6 +702,19 @@ return (n); } +static void +pf_free_src_node(struct pf_ksrc_node *sn) +{ + + for (int i = 0; i < 2; i++) { + if (sn->bytes[i]) + counter_u64_free(sn->bytes[i]); + if (sn->packets[i]) + counter_u64_free(sn->packets[i]); + } + uma_zfree(V_pf_sources_z, sn); +} + static int pf_insert_src_node(struct pf_ksrc_node **sn, struct pf_rule *rule, struct pf_addr *src, sa_family_t af) @@ -730,6 +743,17 @@ return (-1); } + for (int i = 0; i < 2; i++) { + (*sn)->bytes[i] = counter_u64_alloc(M_NOWAIT); + (*sn)->packets[i] = counter_u64_alloc(M_NOWAIT); + + if ((*sn)->bytes[i] == NULL || (*sn)->packets[i] == NULL) { + pf_free_src_node(*sn); + PF_HASHROW_UNLOCK(sh); + return (-1); + } + } + pf_init_threshold(&(*sn)->conn_rate, rule->max_src_conn_rate.limit, rule->max_src_conn_rate.seconds); @@ -773,7 +797,7 @@ u_int count = 0; LIST_FOREACH_SAFE(sn, head, entry, tmp) { - uma_zfree(V_pf_sources_z, sn); + pf_free_src_node(sn); count++; } @@ -6189,12 +6213,16 @@ s->nat_rule.ptr->bytes[dirndx] += pd.tot_len; } if (s->src_node != NULL) { - s->src_node->packets[dirndx]++; - s->src_node->bytes[dirndx] += pd.tot_len; + counter_u64_add(s->src_node->packets[dirndx], + 1); + counter_u64_add(s->src_node->bytes[dirndx], + pd.tot_len); } if (s->nat_src_node != NULL) { - s->nat_src_node->packets[dirndx]++; - s->nat_src_node->bytes[dirndx] += pd.tot_len; + counter_u64_add(s->nat_src_node->packets[dirndx], + 1); + counter_u64_add(s->nat_src_node->bytes[dirndx], + pd.tot_len); } dirndx = (dir == s->direction) ? 0 : 1; counter_u64_add(s->packets[dirndx], 1); @@ -6585,12 +6613,16 @@ s->nat_rule.ptr->bytes[dirndx] += pd.tot_len; } if (s->src_node != NULL) { - s->src_node->packets[dirndx]++; - s->src_node->bytes[dirndx] += pd.tot_len; + counter_u64_add(s->src_node->packets[dirndx], + 1); + counter_u64_add(s->src_node->bytes[dirndx], + pd.tot_len); } if (s->nat_src_node != NULL) { - s->nat_src_node->packets[dirndx]++; - s->nat_src_node->bytes[dirndx] += pd.tot_len; + counter_u64_add(s->nat_src_node->packets[dirndx], + 1); + counter_u64_add(s->nat_src_node->bytes[dirndx], + pd.tot_len); } dirndx = (dir == s->direction) ? 0 : 1; counter_u64_add(s->packets[dirndx], 1); diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -1161,8 +1161,11 @@ if (in->rule.ptr != NULL) out->rule.nr = in->rule.ptr->nr; - bcopy(&in->bytes, &out->bytes, sizeof(u_int64_t) * 2); - bcopy(&in->packets, &out->packets, sizeof(u_int64_t) * 2); + for (int i = 0; i < 2; i++) { + out->bytes[i] = counter_u64_fetch(in->bytes[i]); + out->packets[i] = counter_u64_fetch(in->packets[i]); + } + out->states = in->states; out->conn = in->conn; out->af = in->af;