From 3260ae00be831075207f009f13a3df951c81a123 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Fri, 22 Nov 2013 19:02:22 +0000 Subject: Add missing 'extern'. --- sys/net/pfvar.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sys/net/pfvar.h') diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 06db6cc4d685..645209232651 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1574,8 +1574,8 @@ pf_release_state(struct pf_state *s) extern struct pf_state *pf_find_state_byid(uint64_t, uint32_t); extern struct pf_state *pf_find_state_all(struct pf_state_key_cmp *, u_int, int *); -struct pf_src_node *pf_find_src_node(struct pf_addr *, struct pf_rule *, - sa_family_t, int); +extern struct pf_src_node *pf_find_src_node(struct pf_addr *, + struct pf_rule *, sa_family_t, int); extern void pf_print_state(struct pf_state *); extern void pf_print_flags(u_int8_t); extern u_int16_t pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t, -- cgit v1.2.3 From d77c1b3269b9d7dd340d36191bf42126af488557 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Fri, 22 Nov 2013 19:16:34 +0000 Subject: To support upcoming changes change internal API for source node handling: - Removed pf_remove_src_node(). - Introduce pf_unlink_src_node() and pf_unlink_src_node_locked(). These function do not proceed with freeing of a node, just disconnect it from storage. - New function pf_free_src_nodes() works on a list of previously disconnected nodes and frees them. - Utilize new API in pf_purge_expired_src_nodes(). In collaboration with: Kajetan Staszkiewicz Sponsored by: InnoGames GmbH Sponsored by: Nginx, Inc. --- sys/net/pfvar.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'sys/net/pfvar.h') diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 645209232651..28b313e26f65 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1467,8 +1467,9 @@ struct pf_ifspeed { #define DIOCGIFSPEED _IOWR('D', 92, struct pf_ifspeed) #ifdef _KERNEL +LIST_HEAD(pf_src_node_list, pf_src_node); struct pf_srchash { - LIST_HEAD(, pf_src_node) nodes; + struct pf_src_node_list nodes; struct mtx lock; }; @@ -1576,6 +1577,9 @@ extern struct pf_state *pf_find_state_all(struct pf_state_key_cmp *, u_int, int *); extern struct pf_src_node *pf_find_src_node(struct pf_addr *, struct pf_rule *, sa_family_t, int); +extern void pf_unlink_src_node(struct pf_src_node *); +extern void pf_unlink_src_node_locked(struct pf_src_node *); +extern u_int pf_free_src_nodes(struct pf_src_node_list *); extern void pf_print_state(struct pf_state *); extern void pf_print_flags(u_int8_t); extern u_int16_t pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t, -- cgit v1.2.3 From 603819bc74a6b69d7dccc8c5a32900f2085028d7 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Sat, 8 Feb 2014 09:56:26 +0000 Subject: Remove never set flag FL_OVERWRITE. The only place where it was checked led to lock/critnest leak. --- sys/net/pfvar.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'sys/net/pfvar.h') diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 28b313e26f65..6d3e4761ad50 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1580,8 +1580,6 @@ extern struct pf_src_node *pf_find_src_node(struct pf_addr *, extern void pf_unlink_src_node(struct pf_src_node *); extern void pf_unlink_src_node_locked(struct pf_src_node *); extern u_int pf_free_src_nodes(struct pf_src_node_list *); -extern void pf_print_state(struct pf_state *); -extern void pf_print_flags(u_int8_t); extern u_int16_t pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t, u_int8_t); @@ -1744,8 +1742,6 @@ int pf_osfp_get(struct pf_osfp_ioctl *); int pf_osfp_match(struct pf_osfp_enlist *, pf_osfp_t); #ifdef _KERNEL -void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t); - void pf_step_into_anchor(struct pf_anchor_stackframe *, int *, struct pf_ruleset **, int, struct pf_rule **, struct pf_rule **, int *); -- cgit v1.2.3 From 07d9bc074069503a28448ddbf8518327a22e5c1d Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Sat, 8 Feb 2014 09:57:52 +0000 Subject: Revert accidentially leaked changes in r261627. --- sys/net/pfvar.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sys/net/pfvar.h') diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 6d3e4761ad50..28b313e26f65 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1580,6 +1580,8 @@ extern struct pf_src_node *pf_find_src_node(struct pf_addr *, extern void pf_unlink_src_node(struct pf_src_node *); extern void pf_unlink_src_node_locked(struct pf_src_node *); extern u_int pf_free_src_nodes(struct pf_src_node_list *); +extern void pf_print_state(struct pf_state *); +extern void pf_print_flags(u_int8_t); extern u_int16_t pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t, u_int8_t); @@ -1742,6 +1744,8 @@ int pf_osfp_get(struct pf_osfp_ioctl *); int pf_osfp_match(struct pf_osfp_enlist *, pf_osfp_t); #ifdef _KERNEL +void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t); + void pf_step_into_anchor(struct pf_anchor_stackframe *, int *, struct pf_ruleset **, int, struct pf_rule **, struct pf_rule **, int *); -- cgit v1.2.3 From 48278b884656bf960d81fd9556f1203b176749e2 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Fri, 14 Feb 2014 10:05:21 +0000 Subject: Once pf became not covered by a single mutex, many counters in it became race prone. Some just gather statistics, but some are later used in different calculations. A real problem was the race provoked underflow of the states_cur counter on a rule. Once it goes below zero, it wraps to UINT32_MAX. Later this value is used in pf_state_expires() and any state created by this rule is immediately expired. Thus, make fields states_cur, states_tot and src_nodes of struct pf_rule be counter(9)s. Thanks to Dennis for providing me shell access to problematic box and his help with reproducing, debugging and investigating the problem. Thanks to: Dennis Yusupoff Also reported by: dumbbell, pgj, Rambler Sponsored by: Nginx, Inc. --- sys/net/pfvar.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'sys/net/pfvar.h') diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 28b313e26f65..2068325b6cf3 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -512,13 +513,9 @@ struct pf_rule { int rtableid; u_int32_t timeout[PFTM_MAX]; - u_int32_t states_cur; - u_int32_t states_tot; u_int32_t max_states; - u_int32_t src_nodes; u_int32_t max_src_nodes; u_int32_t max_src_states; - u_int32_t spare1; /* netgraph */ u_int32_t max_src_conn; struct { u_int32_t limit; @@ -532,6 +529,10 @@ struct pf_rule { uid_t cuid; pid_t cpid; + counter_u64_t states_cur; + counter_u64_t states_tot; + counter_u64_t src_nodes; + u_int16_t return_icmp; u_int16_t return_icmp6; u_int16_t max_mss; -- cgit v1.2.3