pf: batch critical section for several counters

Reviewed by:	kp
Sponsored by:	Rubicon Communications, LLC ("Netgate")
This commit is contained in:
Mateusz Guzik 2021-07-24 09:47:40 +02:00
parent 02cf67ccf6
commit 87c010e6e3
3 changed files with 47 additions and 31 deletions

View File

@ -3776,8 +3776,10 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, int direction,
rtableid = r->rtableid;
if (r->anchor == NULL) {
if (r->action == PF_MATCH) {
pf_counter_u64_add(&r->packets[direction == PF_OUT], 1);
pf_counter_u64_add(&r->bytes[direction == PF_OUT], pd->tot_len);
pf_counter_u64_critical_enter();
pf_counter_u64_add_protected(&r->packets[direction == PF_OUT], 1);
pf_counter_u64_add_protected(&r->bytes[direction == PF_OUT], pd->tot_len);
pf_counter_u64_critical_exit();
pf_rule_to_actions(r, &pd->act);
if (r->log)
PFLOG_PACKET(kif, m, af,
@ -4190,8 +4192,10 @@ pf_test_fragment(struct pf_krule **rm, int direction, struct pfi_kkif *kif,
else {
if (r->anchor == NULL) {
if (r->action == PF_MATCH) {
pf_counter_u64_add(&r->packets[direction == PF_OUT], 1);
pf_counter_u64_add(&r->bytes[direction == PF_OUT], pd->tot_len);
pf_counter_u64_critical_enter();
pf_counter_u64_add_protected(&r->packets[direction == PF_OUT], 1);
pf_counter_u64_add_protected(&r->bytes[direction == PF_OUT], pd->tot_len);
pf_counter_u64_critical_exit();
pf_rule_to_actions(r, &pd->act);
if (r->log)
PFLOG_PACKET(kif, m, af,
@ -6489,24 +6493,25 @@ pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *
(s == NULL));
}
pf_counter_u64_add(&kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS],
pf_counter_u64_critical_enter();
pf_counter_u64_add_protected(&kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS],
pd.tot_len);
pf_counter_u64_add(&kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS],
pf_counter_u64_add_protected(&kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS],
1);
if (action == PF_PASS || r->action == PF_DROP) {
dirndx = (dir == PF_OUT);
pf_counter_u64_add(&r->packets[dirndx], 1);
pf_counter_u64_add(&r->bytes[dirndx], pd.tot_len);
pf_counter_u64_add_protected(&r->packets[dirndx], 1);
pf_counter_u64_add_protected(&r->bytes[dirndx], pd.tot_len);
if (a != NULL) {
pf_counter_u64_add(&a->packets[dirndx], 1);
pf_counter_u64_add(&a->bytes[dirndx], pd.tot_len);
pf_counter_u64_add_protected(&a->packets[dirndx], 1);
pf_counter_u64_add_protected(&a->bytes[dirndx], pd.tot_len);
}
if (s != NULL) {
if (s->nat_rule.ptr != NULL) {
pf_counter_u64_add(&s->nat_rule.ptr->packets[dirndx],
pf_counter_u64_add_protected(&s->nat_rule.ptr->packets[dirndx],
1);
pf_counter_u64_add(&s->nat_rule.ptr->bytes[dirndx],
pf_counter_u64_add_protected(&s->nat_rule.ptr->bytes[dirndx],
pd.tot_len);
}
if (s->src_node != NULL) {
@ -6544,6 +6549,7 @@ pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *
pd.af, pd.tot_len, dir == PF_OUT,
r->action == PF_PASS, tr->dst.neg);
}
pf_counter_u64_critical_exit();
switch (action) {
case PF_SYNPROXY_DROP:
@ -6894,24 +6900,25 @@ pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb
&pd, (s == NULL));
}
pf_counter_u64_add(&kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS],
pf_counter_u64_critical_enter();
pf_counter_u64_add_protected(&kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS],
pd.tot_len);
pf_counter_u64_add(&kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS],
pf_counter_u64_add_protected(&kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS],
1);
if (action == PF_PASS || r->action == PF_DROP) {
dirndx = (dir == PF_OUT);
pf_counter_u64_add(&r->packets[dirndx], 1);
pf_counter_u64_add(&r->bytes[dirndx], pd.tot_len);
pf_counter_u64_add_protected(&r->packets[dirndx], 1);
pf_counter_u64_add_protected(&r->bytes[dirndx], pd.tot_len);
if (a != NULL) {
pf_counter_u64_add(&a->packets[dirndx], 1);
pf_counter_u64_add(&a->bytes[dirndx], pd.tot_len);
pf_counter_u64_add_protected(&a->packets[dirndx], 1);
pf_counter_u64_add_protected(&a->bytes[dirndx], pd.tot_len);
}
if (s != NULL) {
if (s->nat_rule.ptr != NULL) {
pf_counter_u64_add(&s->nat_rule.ptr->packets[dirndx],
pf_counter_u64_add_protected(&s->nat_rule.ptr->packets[dirndx],
1);
pf_counter_u64_add(&s->nat_rule.ptr->bytes[dirndx],
pf_counter_u64_add_protected(&s->nat_rule.ptr->bytes[dirndx],
pd.tot_len);
}
if (s->src_node != NULL) {
@ -6947,6 +6954,7 @@ pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb
pd.af, pd.tot_len, dir == PF_OUT,
r->action == PF_PASS, tr->dst.neg);
}
pf_counter_u64_critical_exit();
switch (action) {
case PF_SYNPROXY_DROP:

View File

@ -1120,16 +1120,18 @@ pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
while ((tail != NULL) && ! pf_krule_compare(tail, rule))
tail = TAILQ_NEXT(tail, entries);
if (tail != NULL) {
pf_counter_u64_add(&rule->evaluations,
pf_counter_u64_critical_enter();
pf_counter_u64_add_protected(&rule->evaluations,
pf_counter_u64_fetch(&tail->evaluations));
pf_counter_u64_add(&rule->packets[0],
pf_counter_u64_add_protected(&rule->packets[0],
pf_counter_u64_fetch(&tail->packets[0]));
pf_counter_u64_add(&rule->packets[1],
pf_counter_u64_add_protected(&rule->packets[1],
pf_counter_u64_fetch(&tail->packets[1]));
pf_counter_u64_add(&rule->bytes[0],
pf_counter_u64_add_protected(&rule->bytes[0],
pf_counter_u64_fetch(&tail->bytes[0]));
pf_counter_u64_add(&rule->bytes[1],
pf_counter_u64_add_protected(&rule->bytes[1],
pf_counter_u64_fetch(&tail->bytes[1]));
pf_counter_u64_critical_exit();
}
}
}

View File

@ -1066,8 +1066,10 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kkif *kif, u_short *reason
if (r == NULL || r->action == PF_NOSCRUB)
return (PF_PASS);
pf_counter_u64_add(&r->packets[dir == PF_OUT], 1);
pf_counter_u64_add(&r->bytes[dir == PF_OUT], pd->tot_len);
pf_counter_u64_critical_enter();
pf_counter_u64_add_protected(&r->packets[dir == PF_OUT], 1);
pf_counter_u64_add_protected(&r->bytes[dir == PF_OUT], pd->tot_len);
pf_counter_u64_critical_exit();
/* Check for illegal packets */
if (hlen < (int)sizeof(struct ip)) {
@ -1207,8 +1209,10 @@ pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kkif *kif,
if (r == NULL || r->action == PF_NOSCRUB)
return (PF_PASS);
pf_counter_u64_add(&r->packets[dir == PF_OUT], 1);
pf_counter_u64_add(&r->bytes[dir == PF_OUT], pd->tot_len);
pf_counter_u64_critical_enter();
pf_counter_u64_add_protected(&r->packets[dir == PF_OUT], 1);
pf_counter_u64_add_protected(&r->bytes[dir == PF_OUT], pd->tot_len);
pf_counter_u64_critical_exit();
/* Check for illegal packets */
if (sizeof(struct ip6_hdr) + IPV6_MAXPACKET < m->m_pkthdr.len)
@ -1368,8 +1372,10 @@ pf_normalize_tcp(int dir, struct pfi_kkif *kif, struct mbuf *m, int ipoff,
if (rm == NULL || rm->action == PF_NOSCRUB)
return (PF_PASS);
pf_counter_u64_add(&r->packets[dir == PF_OUT], 1);
pf_counter_u64_add(&r->bytes[dir == PF_OUT], pd->tot_len);
pf_counter_u64_critical_enter();
pf_counter_u64_add_protected(&r->packets[dir == PF_OUT], 1);
pf_counter_u64_add_protected(&r->bytes[dir == PF_OUT], pd->tot_len);
pf_counter_u64_critical_exit();
if (rm->rule_flag & PFRULE_REASSEMBLE_TCP)
pd->flags |= PFDESC_TCP_NORM;