pf: switch kif counters to pf_counter_u64

Reviewed by:	kp
Sponsored by:	Rubicon Communications, LLC ("Netgate")
This commit is contained in:
Mateusz Guzik 2021-07-23 12:29:46 +02:00
parent fc4c42ce0b
commit d40d4b3ed7
4 changed files with 126 additions and 21 deletions

View File

@ -1258,14 +1258,17 @@ struct pfi_kkif {
} _pfik_glue;
#define pfik_tree _pfik_glue._pfik_tree
#define pfik_list _pfik_glue._pfik_list
counter_u64_t pfik_packets[2][2][2];
counter_u64_t pfik_bytes[2][2][2];
struct pf_counter_u64 pfik_packets[2][2][2];
struct pf_counter_u64 pfik_bytes[2][2][2];
u_int32_t pfik_tzero;
u_int pfik_flags;
struct ifnet *pfik_ifp;
struct ifg_group *pfik_group;
u_int pfik_rulerefs;
TAILQ_HEAD(, pfi_dynaddr) pfik_dynaddrs;
#ifdef PF_WANT_32_TO_64_COUNTER
LIST_ENTRY(pfi_kkif) pfik_allkiflist;
#endif
};
#endif
@ -1851,6 +1854,16 @@ VNET_DECLARE(struct pf_altqqueue *, pf_altq_ifs_inactive);
VNET_DECLARE(struct pf_krulequeue, pf_unlinked_rules);
#define V_pf_unlinked_rules VNET(pf_unlinked_rules)
#ifdef PF_WANT_32_TO_64_COUNTER
LIST_HEAD(allkiflist_head, pfi_kkif);
VNET_DECLARE(struct allkiflist_head, pf_allkiflist);
#define V_pf_allkiflist VNET(pf_allkiflist)
VNET_DECLARE(size_t, pf_allkifcount);
#define V_pf_allkifcount VNET(pf_allkifcount)
VNET_DECLARE(struct pfi_kkif *, pf_kifmarker);
#define V_pf_kifmarker VNET(pf_kifmarker)
#endif
void pf_initialize(void);
void pf_mtag_initialize(void);
void pf_mtag_cleanup(void);

View File

@ -1532,6 +1532,48 @@ pf_status_counter_u64_periodic(void)
}
}
static void
pf_kif_counter_u64_periodic(void)
{
struct pfi_kkif *kif;
size_t r, run;
PF_RULES_RASSERT();
if (__predict_false(V_pf_allkifcount == 0)) {
return;
}
if ((V_pf_counter_periodic_iter % (pf_purge_thread_period * 10 * 300)) != 0) {
return;
}
run = V_pf_allkifcount / 10;
if (run < 5)
run = 5;
for (r = 0; r < run; r++) {
kif = LIST_NEXT(V_pf_kifmarker, pfik_allkiflist);
if (kif == NULL) {
LIST_REMOVE(V_pf_kifmarker, pfik_allkiflist);
LIST_INSERT_HEAD(&V_pf_allkiflist, V_pf_kifmarker, pfik_allkiflist);
break;
}
LIST_REMOVE(V_pf_kifmarker, pfik_allkiflist);
LIST_INSERT_AFTER(kif, V_pf_kifmarker, pfik_allkiflist);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 2; k++) {
pf_counter_u64_periodic(&kif->pfik_packets[i][j][k]);
pf_counter_u64_periodic(&kif->pfik_bytes[i][j][k]);
}
}
}
}
}
static void
pf_counter_u64_periodic_main(void)
{
@ -1542,6 +1584,7 @@ pf_counter_u64_periodic_main(void)
PF_RULES_RLOCK();
pf_counter_u64_critical_enter();
pf_status_counter_u64_periodic();
pf_kif_counter_u64_periodic();
pf_counter_u64_critical_exit();
PF_RULES_RUNLOCK();
}
@ -6402,9 +6445,9 @@ pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *
(s == NULL));
}
counter_u64_add(kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS],
pf_counter_u64_add(&kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS],
pd.tot_len);
counter_u64_add(kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS],
pf_counter_u64_add(&kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS],
1);
if (action == PF_PASS || r->action == PF_DROP) {
@ -6807,9 +6850,9 @@ pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb
&pd, (s == NULL));
}
counter_u64_add(kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS],
pf_counter_u64_add(&kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS],
pd.tot_len);
counter_u64_add(kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS],
pf_counter_u64_add(&kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS],
1);
if (action == PF_PASS || r->action == PF_DROP) {

View File

@ -69,6 +69,12 @@ VNET_DEFINE_STATIC(int, pfi_buffer_max);
#define V_pfi_buffer_cnt VNET(pfi_buffer_cnt)
#define V_pfi_buffer_max VNET(pfi_buffer_max)
#ifdef PF_WANT_32_TO_64_COUNTER
VNET_DEFINE(struct allkiflist_head, pf_allkiflist);
VNET_DEFINE(size_t, pf_allkifcount);
VNET_DEFINE(struct pfi_kkif *, pf_kifmarker);
#endif
eventhandler_tag pfi_attach_cookie;
eventhandler_tag pfi_detach_cookie;
eventhandler_tag pfi_attach_group_cookie;
@ -222,6 +228,9 @@ struct pfi_kkif*
pf_kkif_create(int flags)
{
struct pfi_kkif *kif;
#ifdef PF_WANT_32_TO_64_COUNTER
bool wowned;
#endif
kif = malloc(sizeof(*kif), PFI_MTYPE, flags | M_ZERO);
if (! kif)
@ -230,13 +239,12 @@ pf_kkif_create(int flags)
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 2; k++) {
kif->pfik_packets[i][j][k] =
counter_u64_alloc(flags);
kif->pfik_bytes[i][j][k] =
counter_u64_alloc(flags);
if (pf_counter_u64_init(&kif->pfik_packets[i][j][k], flags) != 0) {
pf_kkif_free(kif);
return (NULL);
}
if (! kif->pfik_packets[i][j][k] ||
! kif->pfik_bytes[i][j][k]) {
if (pf_counter_u64_init(&kif->pfik_bytes[i][j][k], flags) != 0) {
pf_kkif_free(kif);
return (NULL);
}
@ -244,20 +252,44 @@ pf_kkif_create(int flags)
}
}
#ifdef PF_WANT_32_TO_64_COUNTER
wowned = PF_RULES_WOWNED();
if (!wowned)
PF_RULES_WLOCK();
LIST_INSERT_HEAD(&V_pf_allkiflist, kif, pfik_allkiflist);
V_pf_allkifcount++;
if (!wowned)
PF_RULES_WUNLOCK();
#endif
return (kif);
}
void
pf_kkif_free(struct pfi_kkif *kif)
{
#ifdef PF_WANT_32_TO_64_COUNTER
bool wowned;
#endif
if (! kif)
return;
#ifdef PF_WANT_32_TO_64_COUNTER
wowned = PF_RULES_WOWNED();
if (!wowned)
PF_RULES_WLOCK();
LIST_REMOVE(kif, pfik_allkiflist);
V_pf_allkifcount--;
if (!wowned)
PF_RULES_WUNLOCK();
#endif
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 2; k++) {
counter_u64_free(kif->pfik_packets[i][j][k]);
counter_u64_free(kif->pfik_bytes[i][j][k]);
pf_counter_u64_deinit(&kif->pfik_packets[i][j][k]);
pf_counter_u64_deinit(&kif->pfik_bytes[i][j][k]);
}
}
}
@ -272,8 +304,8 @@ pf_kkif_zero(struct pfi_kkif *kif)
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 2; k++) {
counter_u64_zero(kif->pfik_packets[i][j][k]);
counter_u64_zero(kif->pfik_bytes[i][j][k]);
pf_counter_u64_zero(&kif->pfik_packets[i][j][k]);
pf_counter_u64_zero(&kif->pfik_bytes[i][j][k]);
}
}
}
@ -805,15 +837,15 @@ pfi_update_status(const char *name, struct pf_status *pfs)
for (j = 0; j < 2; j++)
for (k = 0; k < 2; k++) {
pfs->pcounters[i][j][k] +=
counter_u64_fetch(p->pfik_packets[i][j][k]);
pf_counter_u64_fetch(&p->pfik_packets[i][j][k]);
pfs->bcounters[i][j] +=
counter_u64_fetch(p->pfik_bytes[i][j][k]);
pf_counter_u64_fetch(&p->pfik_bytes[i][j][k]);
}
}
}
static void
pf_kkif_to_kif(const struct pfi_kkif *kkif, struct pfi_kif *kif)
pf_kkif_to_kif(struct pfi_kkif *kkif, struct pfi_kif *kif)
{
bzero(kif, sizeof(*kif));
@ -822,9 +854,9 @@ pf_kkif_to_kif(const struct pfi_kkif *kkif, struct pfi_kif *kif)
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 2; k++) {
kif->pfik_packets[i][j][k] =
counter_u64_fetch(kkif->pfik_packets[i][j][k]);
pf_counter_u64_fetch(&kkif->pfik_packets[i][j][k]);
kif->pfik_bytes[i][j][k] =
counter_u64_fetch(kkif->pfik_bytes[i][j][k]);
pf_counter_u64_fetch(&kkif->pfik_bytes[i][j][k]);
}
}
}

View File

@ -319,6 +319,13 @@ pfattach_vnet(void)
V_pf_default_rule.states_tot = counter_u64_alloc(M_WAITOK);
V_pf_default_rule.src_nodes = counter_u64_alloc(M_WAITOK);
#ifdef PF_WANT_32_TO_64_COUNTER
V_pf_kifmarker = malloc(sizeof(*V_pf_kifmarker), PFI_MTYPE, M_WAITOK | M_ZERO);
PF_RULES_WLOCK();
LIST_INSERT_HEAD(&V_pf_allkiflist, V_pf_kifmarker, pfik_allkiflist);
PF_RULES_WUNLOCK();
#endif
/* initialize default timeouts */
my_timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
my_timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL;
@ -5600,6 +5607,16 @@ pf_unload_vnet(void)
#endif
uma_zdestroy(V_pf_tag_z);
#ifdef PF_WANT_32_TO_64_COUNTER
PF_RULES_WLOCK();
LIST_REMOVE(V_pf_kifmarker, pfik_allkiflist);
PF_RULES_WUNLOCK();
free(V_pf_kifmarker, PFI_MTYPE);
MPASS(LIST_EMPTY(&V_pf_allkiflist));
MPASS(V_pf_allkifcount == 0);
#endif
/* Free counters last as we updated them during shutdown. */
counter_u64_free(V_pf_default_rule.evaluations);
for (int i = 0; i < 2; i++) {