xref: /openbsd/sys/net/pfvar_priv.h (revision 19e99d06)
1*19e99d06Sbluhm /*	$OpenBSD: pfvar_priv.h,v 1.36 2024/04/22 13:30:22 bluhm Exp $	*/
2ab417b3aSbluhm 
3ab417b3aSbluhm /*
4ab417b3aSbluhm  * Copyright (c) 2001 Daniel Hartmeier
5ab417b3aSbluhm  * Copyright (c) 2002 - 2013 Henning Brauer <henning@openbsd.org>
6ab417b3aSbluhm  * Copyright (c) 2016 Alexander Bluhm <bluhm@openbsd.org>
7ab417b3aSbluhm  * All rights reserved.
8ab417b3aSbluhm  *
9ab417b3aSbluhm  * Redistribution and use in source and binary forms, with or without
10ab417b3aSbluhm  * modification, are permitted provided that the following conditions
11ab417b3aSbluhm  * are met:
12ab417b3aSbluhm  *
13ab417b3aSbluhm  *    - Redistributions of source code must retain the above copyright
14ab417b3aSbluhm  *      notice, this list of conditions and the following disclaimer.
15ab417b3aSbluhm  *    - Redistributions in binary form must reproduce the above
16ab417b3aSbluhm  *      copyright notice, this list of conditions and the following
17ab417b3aSbluhm  *      disclaimer in the documentation and/or other materials provided
18ab417b3aSbluhm  *      with the distribution.
19ab417b3aSbluhm  *
20ab417b3aSbluhm  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21ab417b3aSbluhm  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22ab417b3aSbluhm  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23ab417b3aSbluhm  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24ab417b3aSbluhm  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25ab417b3aSbluhm  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26ab417b3aSbluhm  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27ab417b3aSbluhm  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28ab417b3aSbluhm  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29ab417b3aSbluhm  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30ab417b3aSbluhm  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31ab417b3aSbluhm  * POSSIBILITY OF SUCH DAMAGE.
32ab417b3aSbluhm  *
33ab417b3aSbluhm  */
34ab417b3aSbluhm 
35ab417b3aSbluhm #ifndef _NET_PFVAR_PRIV_H_
36ab417b3aSbluhm #define _NET_PFVAR_PRIV_H_
37ab417b3aSbluhm 
38ab417b3aSbluhm #ifdef _KERNEL
39ab417b3aSbluhm 
40956659a2Ssashan #include <sys/rwlock.h>
413f1b5c31Sdlg #include <sys/mutex.h>
42acafb14eSsashan #include <sys/percpu.h>
433f1b5c31Sdlg 
44034f31ceSbluhm /*
45034f31ceSbluhm  * Locks used to protect struct members in this file:
46034f31ceSbluhm  *	L	pf_inp_mtx		link pf to inp mutex
47034f31ceSbluhm  */
48034f31ceSbluhm 
49cc90b7e6Sdlg struct pfsync_deferral;
50cc90b7e6Sdlg 
51cc90b7e6Sdlg /*
52cc90b7e6Sdlg  * pf state items - links from pf_state_key to pf_states
53cc90b7e6Sdlg  */
54cc90b7e6Sdlg 
55d956567bSdlg struct pf_state_item {
5635751c74Sdlg 	TAILQ_ENTRY(pf_state_item)
5735751c74Sdlg 				 si_entry;
5835751c74Sdlg 	struct pf_state		*si_st;
59d956567bSdlg };
60d956567bSdlg 
61d956567bSdlg TAILQ_HEAD(pf_statelisthead, pf_state_item);
62d956567bSdlg 
63cc90b7e6Sdlg /*
64cc90b7e6Sdlg  * pf state keys - look up states by address
65cc90b7e6Sdlg  */
66cc90b7e6Sdlg 
67d956567bSdlg struct pf_state_key {
68d956567bSdlg 	struct pf_addr	 addr[2];
69d956567bSdlg 	u_int16_t	 port[2];
70d956567bSdlg 	u_int16_t	 rdomain;
71ad6271c5Sdlg 	u_int16_t	 hash;
72d956567bSdlg 	sa_family_t	 af;
73d956567bSdlg 	u_int8_t	 proto;
74d956567bSdlg 
7535751c74Sdlg 	RB_ENTRY(pf_state_key)	 sk_entry;
7635751c74Sdlg 	struct pf_statelisthead	 sk_states;
7735751c74Sdlg 	struct pf_state_key	*sk_reverse;
78034f31ceSbluhm 	struct inpcb		*sk_inp;	/* [L] */
7935751c74Sdlg 	pf_refcnt_t		 sk_refcnt;
8035751c74Sdlg 	u_int8_t		 sk_removed;
81d956567bSdlg };
82211190b8Sdlg 
83211190b8Sdlg RBT_HEAD(pf_state_tree, pf_state_key);
84211190b8Sdlg RBT_PROTOTYPE(pf_state_tree, pf_state_key, sk_entry, pf_state_compare_key);
85211190b8Sdlg 
86d956567bSdlg #define PF_REVERSED_KEY(key, family)				\
87d956567bSdlg 	((key[PF_SK_WIRE]->af != key[PF_SK_STACK]->af) &&	\
88d956567bSdlg 	 (key[PF_SK_WIRE]->af != (family)))
89d956567bSdlg 
904d847e65Sdlg /*
91cc90b7e6Sdlg  * pf state
92cc90b7e6Sdlg  *
934d847e65Sdlg  * Protection/ownership of pf_state members:
94437c6c3fSdlg  *	I	immutable after pf_state_insert()
953eb75377Sdlg  *	M	pf_state mtx
964d847e65Sdlg  *	P	PF_STATE_LOCK
97cc90b7e6Sdlg  *	S	pfsync
984d847e65Sdlg  *	L	pf_state_list
994d847e65Sdlg  *	g	pf_purge gc
1004d847e65Sdlg  */
1014d847e65Sdlg 
102bd25c300Sdlg struct pf_state {
103cefd7618Sdlg 	u_int64_t		 id;		/* [I] */
104cefd7618Sdlg 	u_int32_t		 creatorid;	/* [I] */
105cefd7618Sdlg 	u_int8_t		 direction;	/* [I] */
106bd25c300Sdlg 	u_int8_t		 pad[3];
107bd25c300Sdlg 
108cefd7618Sdlg 	TAILQ_ENTRY(pf_state)	 sync_list;	/* [S] */
109cc90b7e6Sdlg 	struct pfsync_deferral	*sync_defer;	/* [S] */
110cefd7618Sdlg 	TAILQ_ENTRY(pf_state)	 entry_list;	/* [L] */
111cefd7618Sdlg 	SLIST_ENTRY(pf_state)	 gc_list;	/* [g] */
112cefd7618Sdlg 	RB_ENTRY(pf_state)	 entry_id;	/* [P] */
113bcbed442Sdlg 	struct pf_state_peer	 src;
114bd25c300Sdlg 	struct pf_state_peer	 dst;
115cefd7618Sdlg 	struct pf_rule_slist	 match_rules;	/* [I] */
116cefd7618Sdlg 	union pf_rule_ptr	 rule;		/* [I] */
117cefd7618Sdlg 	union pf_rule_ptr	 anchor;	/* [I] */
118cefd7618Sdlg 	union pf_rule_ptr	 natrule;	/* [I] */
119cefd7618Sdlg 	struct pf_addr		 rt_addr;	/* [I] */
120cefd7618Sdlg 	struct pf_sn_head	 src_nodes;	/* [I] */
121437c6c3fSdlg 	struct pf_state_key	*key[2];	/* [I] stack and wire */
122cefd7618Sdlg 	struct pfi_kif		*kif;		/* [I] */
1233eb75377Sdlg 	struct mutex		 mtx;
1243eb75377Sdlg 	pf_refcnt_t		 refcnt;
125bd25c300Sdlg 	u_int64_t		 packets[2];
126bd25c300Sdlg 	u_int64_t		 bytes[2];
127cefd7618Sdlg 	int32_t			 creation;	/* [I] */
128bd25c300Sdlg 	int32_t			 expire;
129cc90b7e6Sdlg 	int32_t			 pfsync_time;	/* [S] */
130cc90b7e6Sdlg 	int			 rtableid[2];	/* [I] stack and wire */
131cefd7618Sdlg 	u_int16_t		 qid;		/* [I] */
132cefd7618Sdlg 	u_int16_t		 pqid;		/* [I] */
133cefd7618Sdlg 	u_int16_t		 tag;		/* [I] */
134cc90b7e6Sdlg 	u_int16_t		 state_flags;	/* [M] */
135cefd7618Sdlg 	u_int8_t		 log;		/* [I] */
136bd25c300Sdlg 	u_int8_t		 timeout;
137cc90b7e6Sdlg 	u_int8_t		 sync_state;	/* [S] PFSYNC_S_x */
138cc90b7e6Sdlg 	u_int8_t		 sync_updates;	/* [S] */
139cefd7618Sdlg 	u_int8_t		 min_ttl;	/* [I] */
140cefd7618Sdlg 	u_int8_t		 set_tos;	/* [I] */
141cefd7618Sdlg 	u_int8_t		 set_prio[2];	/* [I] */
142cefd7618Sdlg 	u_int16_t		 max_mss;	/* [I] */
143cefd7618Sdlg 	u_int16_t		 if_index_in;	/* [I] */
144cefd7618Sdlg 	u_int16_t		 if_index_out;	/* [I] */
145cefd7618Sdlg 	u_int16_t		 delay;		/* [I] */
146cefd7618Sdlg 	u_int8_t		 rt;		/* [I] */
147bd25c300Sdlg };
148bd25c300Sdlg 
149e9311d0bSdlg RBT_HEAD(pf_state_tree_id, pf_state);
150e9311d0bSdlg RBT_PROTOTYPE(pf_state_tree_id, pf_state, entry_id, pf_state_compare_id);
151e9311d0bSdlg extern struct pf_state_tree_id tree_id;
152e9311d0bSdlg 
1533f1b5c31Sdlg /*
1543f1b5c31Sdlg  * states are linked into a global list to support the following
1553f1b5c31Sdlg  * functionality:
1563f1b5c31Sdlg  *
1573f1b5c31Sdlg  * - garbage collection
1583f1b5c31Sdlg  * - pfsync bulk send operations
1593f1b5c31Sdlg  * - bulk state fetches via the DIOCGETSTATES ioctl
1603f1b5c31Sdlg  * - bulk state clearing via the DIOCCLRSTATES ioctl
1613f1b5c31Sdlg  *
1623f1b5c31Sdlg  * states are inserted into the global pf_state_list once it has also
1633f1b5c31Sdlg  * been successfully added to the various trees that make up the state
1643f1b5c31Sdlg  * table. states are only removed from the pf_state_list by the garbage
1653f1b5c31Sdlg  * collection process.
16608f32a0cSdlg  *
1673f1b5c31Sdlg  * the pf_state_list head and tail pointers (ie, the pfs_list TAILQ_HEAD
1683f1b5c31Sdlg  * structure) and the pointers between the entries on the pf_state_list
1693f1b5c31Sdlg  * are locked separately. at a high level, this allows for insertion
1703f1b5c31Sdlg  * of new states into the pf_state_list while other contexts (eg, the
1713f1b5c31Sdlg  * ioctls) are traversing the state items in the list. for garbage
1723f1b5c31Sdlg  * collection to remove items from the pf_state_list, it has to exclude
1733f1b5c31Sdlg  * both modifications to the list head and tail pointers, and traversal
1743f1b5c31Sdlg  * of the links between the states.
1753f1b5c31Sdlg  *
1763f1b5c31Sdlg  * the head and tail pointers are protected by a mutex. the pointers
1773f1b5c31Sdlg  * between states are protected by an rwlock.
1783f1b5c31Sdlg  *
1793f1b5c31Sdlg  * because insertions are only made to the end of the list, if we get
1803f1b5c31Sdlg  * a snapshot of the head and tail of the list and prevent modifications
1813f1b5c31Sdlg  * to the links between states, we can safely traverse between the
1823f1b5c31Sdlg  * head and tail entries. subsequent insertions can add entries after
1833f1b5c31Sdlg  * our view of the tail, but we don't look past our view.
1843f1b5c31Sdlg  *
1853f1b5c31Sdlg  * if both locks must be taken, the rwlock protecting the links between
1863f1b5c31Sdlg  * states is taken before the mutex protecting the head and tail
1873f1b5c31Sdlg  * pointer.
1883f1b5c31Sdlg  *
1893f1b5c31Sdlg  * insertion into the list follows this pattern:
1903f1b5c31Sdlg  *
1913f1b5c31Sdlg  *	// serialise list head/tail modifications
1923f1b5c31Sdlg  *	mtx_enter(&pf_state_list.pfs_mtx);
1933f1b5c31Sdlg  *	TAILQ_INSERT_TAIL(&pf_state_list.pfs_list, state, entry_list);
1943f1b5c31Sdlg  *	mtx_leave(&pf_state_list.pfs_mtx);
1953f1b5c31Sdlg  *
1963f1b5c31Sdlg  * traversal of the list:
1973f1b5c31Sdlg  *
1983f1b5c31Sdlg  *	// lock against the gc removing an item from the list
1993f1b5c31Sdlg  *	rw_enter_read(&pf_state_list.pfs_rwl);
2003f1b5c31Sdlg  *
2013f1b5c31Sdlg  *	// get a snapshot view of the ends of the list
2023f1b5c31Sdlg  *	mtx_enter(&pf_state_list.pfs_mtx);
2033f1b5c31Sdlg  *	head = TAILQ_FIRST(&pf_state_list.pfs_list);
2043f1b5c31Sdlg  *	tail = TAILQ_LAST(&pf_state_list.pfs_list, pf_state_queue);
2053f1b5c31Sdlg  *	mtx_leave(&pf_state_list.pfs_mtx);
2063f1b5c31Sdlg  *
2073f1b5c31Sdlg  *	state = NULL;
2083f1b5c31Sdlg  *	next = head;
2093f1b5c31Sdlg  *
2103f1b5c31Sdlg  *	while (state != tail) {
2113f1b5c31Sdlg  *		state = next;
2123f1b5c31Sdlg  *		next = TAILQ_NEXT(state, entry_list);
2133f1b5c31Sdlg  *
2143f1b5c31Sdlg  *		// look at the state
2153f1b5c31Sdlg  *	}
2163f1b5c31Sdlg  *
2173f1b5c31Sdlg  *	rw_exit_read(&pf_state_list.pfs_rwl);
2183f1b5c31Sdlg  *
2193f1b5c31Sdlg  * removing an item from the list:
2203f1b5c31Sdlg  *
2213f1b5c31Sdlg  *	// wait for iterators (readers) to get out
2223f1b5c31Sdlg  *	rw_enter_write(&pf_state_list.pfs_rwl);
2233f1b5c31Sdlg  *
2243f1b5c31Sdlg  *	// serialise list head/tail modifications
2253f1b5c31Sdlg  *	mtx_enter(&pf_state_list.pfs_mtx);
2263f1b5c31Sdlg  *	TAILQ_REMOVE(&pf_state_list.pfs_list, state, entry_list);
2273f1b5c31Sdlg  *	mtx_leave(&pf_state_list.pfs_mtx);
2283f1b5c31Sdlg  *
2293f1b5c31Sdlg  *	rw_exit_write(&pf_state_list.pfs_rwl);
2303f1b5c31Sdlg  *
2313f1b5c31Sdlg  * the lock ordering for pf_state_list locks and the rest of the pf
2323f1b5c31Sdlg  * locks are:
2333f1b5c31Sdlg  *
2343f1b5c31Sdlg  * 1. KERNEL_LOCK
2353f1b5c31Sdlg  * 2. NET_LOCK
2363f1b5c31Sdlg  * 3. pf_state_list.pfs_rwl
2373f1b5c31Sdlg  * 4. PF_LOCK
2383f1b5c31Sdlg  * 5. PF_STATE_LOCK
2393f1b5c31Sdlg  * 6. pf_state_list.pfs_mtx
2403f1b5c31Sdlg  */
2413f1b5c31Sdlg 
2423f1b5c31Sdlg struct pf_state_list {
2433f1b5c31Sdlg 	/* the list of states in the system */
2443f1b5c31Sdlg 	struct pf_state_queue		pfs_list;
2453f1b5c31Sdlg 
2463f1b5c31Sdlg 	/* serialise pfs_list head/tail access */
2473f1b5c31Sdlg 	struct mutex			pfs_mtx;
2483f1b5c31Sdlg 
2493f1b5c31Sdlg 	/* serialise access to pointers between pfs_list entries */
2503f1b5c31Sdlg 	struct rwlock			pfs_rwl;
2513f1b5c31Sdlg };
2523f1b5c31Sdlg 
2533f1b5c31Sdlg #define PF_STATE_LIST_INITIALIZER(_pfs) {				\
2543f1b5c31Sdlg 	.pfs_list	= TAILQ_HEAD_INITIALIZER(_pfs.pfs_list),	\
2553f1b5c31Sdlg 	.pfs_mtx	= MUTEX_INITIALIZER(IPL_SOFTNET),		\
2563f1b5c31Sdlg 	.pfs_rwl	= RWLOCK_INITIALIZER("pfstates"),		\
2573f1b5c31Sdlg }
258956659a2Ssashan 
259956659a2Ssashan extern struct rwlock pf_lock;
260956659a2Ssashan 
261ab417b3aSbluhm struct pf_pdesc {
262ab417b3aSbluhm 	struct {
263ab417b3aSbluhm 		int	 done;
264ab417b3aSbluhm 		uid_t	 uid;
265ab417b3aSbluhm 		gid_t	 gid;
266ab417b3aSbluhm 		pid_t	 pid;
267ab417b3aSbluhm 	}		 lookup;
268ab417b3aSbluhm 	u_int64_t	 tot_len;	/* Make Mickey money */
269ab417b3aSbluhm 
270ab417b3aSbluhm 	struct pf_addr	 nsaddr;	/* src address after NAT */
271ab417b3aSbluhm 	struct pf_addr	 ndaddr;	/* dst address after NAT */
272ab417b3aSbluhm 
273ab417b3aSbluhm 	struct pfi_kif	*kif;		/* incoming interface */
274ab417b3aSbluhm 	struct mbuf	*m;		/* mbuf containing the packet */
275ab417b3aSbluhm 	struct pf_addr	*src;		/* src address */
276ab417b3aSbluhm 	struct pf_addr	*dst;		/* dst address */
277ab417b3aSbluhm 	u_int16_t	*pcksum;	/* proto cksum */
278ab417b3aSbluhm 	u_int16_t	*sport;
279ab417b3aSbluhm 	u_int16_t	*dport;
280ab417b3aSbluhm 	u_int16_t	 osport;
281ab417b3aSbluhm 	u_int16_t	 odport;
282ad6271c5Sdlg 	u_int16_t	 hash;
283ab417b3aSbluhm 	u_int16_t	 nsport;	/* src port after NAT */
284ab417b3aSbluhm 	u_int16_t	 ndport;	/* dst port after NAT */
285ab417b3aSbluhm 
286ab417b3aSbluhm 	u_int32_t	 off;		/* protocol header offset */
287ab417b3aSbluhm 	u_int32_t	 hdrlen;	/* protocol header length */
288ab417b3aSbluhm 	u_int32_t	 p_len;		/* length of protocol payload */
289df8d9afdSjsg 	u_int32_t	 extoff;	/* extension header offset */
290ab417b3aSbluhm 	u_int32_t	 fragoff;	/* fragment header offset */
291ab417b3aSbluhm 	u_int32_t	 jumbolen;	/* length from v6 jumbo header */
292ab417b3aSbluhm 	u_int32_t	 badopts;	/* v4 options or v6 routing headers */
293214dd828Sbluhm #define PF_OPT_OTHER		0x0001
294214dd828Sbluhm #define PF_OPT_JUMBO		0x0002
295214dd828Sbluhm #define PF_OPT_ROUTER_ALERT	0x0004
296ab417b3aSbluhm 
297ab417b3aSbluhm 	u_int16_t	 rdomain;	/* original routing domain */
298ab417b3aSbluhm 	u_int16_t	 virtual_proto;
299ab417b3aSbluhm #define PF_VPROTO_FRAGMENT	256
300ab417b3aSbluhm 	sa_family_t	 af;
301ab417b3aSbluhm 	sa_family_t	 naf;
302ab417b3aSbluhm 	u_int8_t	 proto;
303ab417b3aSbluhm 	u_int8_t	 tos;
304ab417b3aSbluhm 	u_int8_t	 ttl;
305ab417b3aSbluhm 	u_int8_t	 dir;		/* direction */
306ab417b3aSbluhm 	u_int8_t	 sidx;		/* key index for source */
307ab417b3aSbluhm 	u_int8_t	 didx;		/* key index for destination */
308ab417b3aSbluhm 	u_int8_t	 destchg;	/* flag set when destination changed */
309ab417b3aSbluhm 	u_int8_t	 pflog;		/* flags for packet logging */
310266d31c5Sprocter 	union {
311266d31c5Sprocter 		struct tcphdr			tcp;
312266d31c5Sprocter 		struct udphdr			udp;
313266d31c5Sprocter 		struct icmp			icmp;
314266d31c5Sprocter #ifdef INET6
315266d31c5Sprocter 		struct icmp6_hdr		icmp6;
316266d31c5Sprocter 		struct mld_hdr			mld;
317266d31c5Sprocter 		struct nd_neighbor_solicit	nd_ns;
318266d31c5Sprocter #endif /* INET6 */
319266d31c5Sprocter 	} hdr;
320ab417b3aSbluhm };
321ab417b3aSbluhm 
322acafb14eSsashan struct pf_anchor_stackframe {
323acafb14eSsashan 	struct pf_ruleset	*sf_rs;
324acafb14eSsashan 	union {
325acafb14eSsashan 		struct pf_rule			*u_r;
326acafb14eSsashan 		struct pf_anchor_stackframe	*u_stack_top;
327acafb14eSsashan 	} u;
328acafb14eSsashan 	struct pf_anchor	*sf_child;
329acafb14eSsashan 	int			 sf_jump_target;
330acafb14eSsashan };
331acafb14eSsashan #define sf_r		u.u_r
332acafb14eSsashan #define sf_stack_top	u.u_stack_top
333acafb14eSsashan enum {
334acafb14eSsashan 	PF_NEXT_RULE,
335acafb14eSsashan 	PF_NEXT_CHILD
336acafb14eSsashan };
337acafb14eSsashan 
338acafb14eSsashan extern struct cpumem *pf_anchor_stack;
339acafb14eSsashan 
340072583c9Ssashan enum pf_trans_type {
341072583c9Ssashan 	PF_TRANS_NONE,
342072583c9Ssashan 	PF_TRANS_GETRULE,
343072583c9Ssashan 	PF_TRANS_MAX
344072583c9Ssashan };
345072583c9Ssashan 
346072583c9Ssashan struct pf_trans {
347072583c9Ssashan 	LIST_ENTRY(pf_trans)	pft_entry;
348072583c9Ssashan 	uint32_t		pft_unit;		/* process id */
349072583c9Ssashan 	uint64_t		pft_ticket;
350072583c9Ssashan 	enum pf_trans_type	pft_type;
351072583c9Ssashan 	union {
352072583c9Ssashan 		struct {
353072583c9Ssashan 			u_int32_t		 gr_version;
354072583c9Ssashan 			struct pf_anchor	*gr_anchor;
355072583c9Ssashan 			struct pf_rule		*gr_rule;
356072583c9Ssashan 		} u_getrule;
357072583c9Ssashan 	} u;
358072583c9Ssashan };
359072583c9Ssashan 
360072583c9Ssashan #define pftgr_version	u.u_getrule.gr_version
361072583c9Ssashan #define pftgr_anchor	u.u_getrule.gr_anchor
362072583c9Ssashan #define pftgr_rule	u.u_getrule.gr_rule
363072583c9Ssashan 
364cc90b7e6Sdlg extern struct timeout	pf_purge_states_to;
365d7a877acSmpi extern struct task	pf_purge_task;
366d7a877acSmpi extern struct timeout	pf_purge_to;
367d7a877acSmpi 
368ddb22b95Ssashan struct pf_state		*pf_state_ref(struct pf_state *);
369ddb22b95Ssashan void			 pf_state_unref(struct pf_state *);
370ddb22b95Ssashan 
371956659a2Ssashan extern struct rwlock	pf_lock;
372ddb22b95Ssashan extern struct rwlock	pf_state_lock;
373*19e99d06Sbluhm extern struct mutex	pf_frag_mtx;
374034f31ceSbluhm extern struct mutex	pf_inp_mtx;
375956659a2Ssashan 
376956659a2Ssashan #define PF_LOCK()		do {			\
377956659a2Ssashan 		rw_enter_write(&pf_lock);		\
378956659a2Ssashan 	} while (0)
379956659a2Ssashan 
380956659a2Ssashan #define PF_UNLOCK()		do {			\
381956659a2Ssashan 		PF_ASSERT_LOCKED();			\
382956659a2Ssashan 		rw_exit_write(&pf_lock);		\
383956659a2Ssashan 	} while (0)
384956659a2Ssashan 
385956659a2Ssashan #define PF_ASSERT_LOCKED()	do {			\
386956659a2Ssashan 		if (rw_status(&pf_lock) != RW_WRITE)	\
387956659a2Ssashan 			splassert_fail(RW_WRITE,	\
388956659a2Ssashan 			    rw_status(&pf_lock),__func__);\
389956659a2Ssashan 	} while (0)
390956659a2Ssashan 
391956659a2Ssashan #define PF_ASSERT_UNLOCKED()	do {			\
392956659a2Ssashan 		if (rw_status(&pf_lock) == RW_WRITE)	\
393956659a2Ssashan 			splassert_fail(0, rw_status(&pf_lock), __func__);\
394956659a2Ssashan 	} while (0)
395ddb22b95Ssashan 
396ddb22b95Ssashan #define PF_STATE_ENTER_READ()	do {			\
397ddb22b95Ssashan 		rw_enter_read(&pf_state_lock);		\
398ddb22b95Ssashan 	} while (0)
399ddb22b95Ssashan 
400ddb22b95Ssashan #define PF_STATE_EXIT_READ()	do {			\
401ddb22b95Ssashan 		rw_exit_read(&pf_state_lock);		\
402ddb22b95Ssashan 	} while (0)
403ddb22b95Ssashan 
404ddb22b95Ssashan #define PF_STATE_ENTER_WRITE()	do {			\
405ddb22b95Ssashan 		rw_enter_write(&pf_state_lock);		\
406ddb22b95Ssashan 	} while (0)
407ddb22b95Ssashan 
408ddb22b95Ssashan #define PF_STATE_EXIT_WRITE()	do {			\
409c7049310Sbluhm 		PF_STATE_ASSERT_LOCKED();		\
410ddb22b95Ssashan 		rw_exit_write(&pf_state_lock);		\
411ddb22b95Ssashan 	} while (0)
412ddb22b95Ssashan 
413c7049310Sbluhm #define PF_STATE_ASSERT_LOCKED()	do {		\
414ddb22b95Ssashan 		if (rw_status(&pf_state_lock) != RW_WRITE)\
415ddb22b95Ssashan 			splassert_fail(RW_WRITE,	\
416ddb22b95Ssashan 			    rw_status(&pf_state_lock), __func__);\
417ddb22b95Ssashan 	} while (0)
418ddb22b95Ssashan 
419*19e99d06Sbluhm #define PF_FRAG_LOCK()		mtx_enter(&pf_frag_mtx)
420*19e99d06Sbluhm #define PF_FRAG_UNLOCK()	mtx_leave(&pf_frag_mtx)
421*19e99d06Sbluhm 
4224103306eSdlg /* for copies to/from network byte order */
4234103306eSdlg void			pf_state_peer_hton(const struct pf_state_peer *,
4244103306eSdlg 			    struct pfsync_state_peer *);
4254103306eSdlg void			pf_state_peer_ntoh(const struct pfsync_state_peer *,
4264103306eSdlg 			    struct pf_state_peer *);
427e8d81675Ssashan u_int16_t		pf_pkt_hash(sa_family_t, uint8_t,
428e8d81675Ssashan 			    const struct pf_addr *, const struct pf_addr *,
429e8d81675Ssashan 			    uint16_t, uint16_t);
4304103306eSdlg 
431ab417b3aSbluhm #endif /* _KERNEL */
432ab417b3aSbluhm 
433ab417b3aSbluhm #endif /* _NET_PFVAR_PRIV_H_ */
434