1/* $OpenBSD: pfvar_priv.h,v 1.42 2026/02/05 03:26:00 dlg Exp $ */
2
3/*
4 * Copyright (c) 2001 Daniel Hartmeier
5 * Copyright (c) 2002 - 2013 Henning Brauer <henning@openbsd.org>
6 * Copyright (c) 2016 Alexander Bluhm <bluhm@openbsd.org>
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * - Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35#ifndef _NET_PFVAR_PRIV_H_
36#define _NET_PFVAR_PRIV_H_
37
38#ifdef _KERNEL
39
40#include <sys/rwlock.h>
41#include <sys/mutex.h>
42#include <sys/pclock.h>
43#include <sys/percpu.h>
44
45/*
46 * Locks used to protect struct members in this file:
47 * L pf_inp_mtx link pf to inp mutex
48 */
49
50struct pfsync_deferral;
51struct kstat;
52
53/*
54 * PF state links
55 *
56 * This is used to augment a struct pf_state so it can be
57 * tracked/referenced by the state and source address limiter things.
58 * Each limiter maintains a list of the states they "own", and these
59 * state links are what the limiters use to wire a state into their
60 * lists.
61 *
62 * Without PF state links, the pf_state struct would have to grow
63 * a lot to support a feature that may not be used.
64 *
65 * pfl_entry is used by the pools to add states to their list.
66 * pfl_state allows the pools to get from their list of states to
67 * the states themselves.
68 *
69 * pfl_link allows operations on states (well, delete) to be able
70 * to quickly locate the pf_state_link struct so they can be unwired
71 * from the pools.
72 */
73
74#define PF_STATE_LINK_TYPE_STATELIM 1
75#define PF_STATE_LINK_TYPE_SOURCELIM 2
76
77struct pf_state_link {
78 /* used by source/state pools to get to states */
79 TAILQ_ENTRY(pf_state_link) pfl_link;
80
81 /* used by pf_state to get to source/state pools */
82 SLIST_ENTRY(pf_state_link) pfl_linkage;
83
84 struct pf_state *pfl_state;
85 unsigned int pfl_type;
86};
87
88TAILQ_HEAD(pf_state_link_list, pf_state_link);
89SLIST_HEAD(pf_state_linkage, pf_state_link);
90
91/*
92 * pf state items - links from pf_state_key to pf_states
93 */
94
95struct pf_state_item {
96 TAILQ_ENTRY(pf_state_item)
97 si_entry;
98 struct pf_state *si_st;
99};
100
101TAILQ_HEAD(pf_statelisthead, pf_state_item);
102
103/*
104 * pf state keys - look up states by address
105 */
106
107struct pf_state_key {
108 struct pf_addr addr[2];
109 u_int16_t port[2];
110 u_int16_t rdomain;
111 u_int16_t hash;
112 sa_family_t af;
113 u_int8_t proto;
114
115 RBT_ENTRY(pf_state_key) sk_entry;
116 struct pf_statelisthead sk_states;
117 struct pf_state_key *sk_reverse;
118 struct inpcb *sk_inp; /* [L] */
119 pf_refcnt_t sk_refcnt;
120 u_int8_t sk_removed;
121};
122
123RBT_HEAD(pf_state_tree, pf_state_key);
124RBT_PROTOTYPE(pf_state_tree, pf_state_key, sk_entry, pf_state_compare_key);
125
126#define PF_REVERSED_KEY(key, family) \
127 ((key[PF_SK_WIRE]->af != key[PF_SK_STACK]->af) && \
128 (key[PF_SK_WIRE]->af != (family)))
129
130/*
131 * pf state
132 *
133 * Protection/ownership of pf_state members:
134 * I immutable after pf_state_insert()
135 * M pf_state mtx
136 * P PF_STATE_LOCK
137 * S pfsync
138 * L pf_state_list
139 * g pf_purge gc
140 */
141
142struct pf_state {
143 u_int64_t id; /* [I] */
144 u_int32_t creatorid; /* [I] */
145 u_int8_t direction; /* [I] */
146 u_int8_t pad[3];
147
148 TAILQ_ENTRY(pf_state) sync_list; /* [S] */
149 struct pfsync_deferral *sync_defer; /* [S] */
150 TAILQ_ENTRY(pf_state) entry_list; /* [L] */
151 SLIST_ENTRY(pf_state) gc_list; /* [g] */
152 RBT_ENTRY(pf_state) entry_id; /* [P] */
153 struct pf_state_peer src;
154 struct pf_state_peer dst;
155 struct pf_rule_slist match_rules; /* [I] */
156 union pf_rule_ptr rule; /* [I] */
157 union pf_rule_ptr anchor; /* [I] */
158 union pf_rule_ptr natrule; /* [I] */
159 struct pf_addr rt_addr; /* [I] */
160 struct pf_sn_head src_nodes; /* [I] */
161 struct pf_state_key *key[2]; /* [I] stack and wire */
162 struct pfi_kif *kif; /* [I] */
163 struct mutex mtx;
164 pf_refcnt_t refcnt;
165 u_int64_t packets[2];
166 u_int64_t bytes[2];
167 int32_t creation; /* [I] */
168 int32_t expire;
169 int32_t pfsync_time; /* [S] */
170 int rtableid[2]; /* [I] stack and wire */
171 u_int16_t qid; /* [I] */
172 u_int16_t pqid; /* [I] */
173 u_int16_t tag; /* [I] */
174 u_int16_t state_flags; /* [M] */
175 u_int8_t log; /* [I] */
176 u_int8_t timeout;
177 u_int8_t sync_state; /* [S] PFSYNC_S_x */
178 u_int8_t sync_updates; /* [S] */
179 u_int8_t min_ttl; /* [I] */
180 u_int8_t set_tos; /* [I] */
181 u_int8_t set_prio[2]; /* [I] */
182 u_int16_t max_mss; /* [I] */
183 u_int16_t if_index_in; /* [I] */
184 u_int16_t if_index_out; /* [I] */
185 u_int16_t delay; /* [I] */
186 u_int8_t rt; /* [I] */
187 uint8_t statelim;
188 uint8_t sourcelim;
189 struct pf_state_linkage linkage;
190};
191
192RBT_HEAD(pf_state_tree_id, pf_state);
193RBT_PROTOTYPE(pf_state_tree_id, pf_state, entry_id, pf_state_compare_id);
194extern struct pf_state_tree_id tree_id;
195
196/*
197 * states are linked into a global list to support the following
198 * functionality:
199 *
200 * - garbage collection
201 * - pfsync bulk send operations
202 * - bulk state fetches via the DIOCGETSTATES ioctl
203 * - bulk state clearing via the DIOCCLRSTATES ioctl
204 *
205 * states are inserted into the global pf_state_list once it has also
206 * been successfully added to the various trees that make up the state
207 * table. states are only removed from the pf_state_list by the garbage
208 * collection process.
209 *
210 * the pf_state_list head and tail pointers (ie, the pfs_list TAILQ_HEAD
211 * structure) and the pointers between the entries on the pf_state_list
212 * are locked separately. at a high level, this allows for insertion
213 * of new states into the pf_state_list while other contexts (eg, the
214 * ioctls) are traversing the state items in the list. for garbage
215 * collection to remove items from the pf_state_list, it has to exclude
216 * both modifications to the list head and tail pointers, and traversal
217 * of the links between the states.
218 *
219 * the head and tail pointers are protected by a mutex. the pointers
220 * between states are protected by an rwlock.
221 *
222 * because insertions are only made to the end of the list, if we get
223 * a snapshot of the head and tail of the list and prevent modifications
224 * to the links between states, we can safely traverse between the
225 * head and tail entries. subsequent insertions can add entries after
226 * our view of the tail, but we don't look past our view.
227 *
228 * if both locks must be taken, the rwlock protecting the links between
229 * states is taken before the mutex protecting the head and tail
230 * pointer.
231 *
232 * insertion into the list follows this pattern:
233 *
234 * // serialise list head/tail modifications
235 * mtx_enter(&pf_state_list.pfs_mtx);
236 * TAILQ_INSERT_TAIL(&pf_state_list.pfs_list, state, entry_list);
237 * mtx_leave(&pf_state_list.pfs_mtx);
238 *
239 * traversal of the list:
240 *
241 * // lock against the gc removing an item from the list
242 * rw_enter_read(&pf_state_list.pfs_rwl);
243 *
244 * // get a snapshot view of the ends of the list
245 * mtx_enter(&pf_state_list.pfs_mtx);
246 * head = TAILQ_FIRST(&pf_state_list.pfs_list);
247 * tail = TAILQ_LAST(&pf_state_list.pfs_list, pf_state_queue);
248 * mtx_leave(&pf_state_list.pfs_mtx);
249 *
250 * state = NULL;
251 * next = head;
252 *
253 * while (state != tail) {
254 * state = next;
255 * next = TAILQ_NEXT(state, entry_list);
256 *
257 * // look at the state
258 * }
259 *
260 * rw_exit_read(&pf_state_list.pfs_rwl);
261 *
262 * removing an item from the list:
263 *
264 * // wait for iterators (readers) to get out
265 * rw_enter_write(&pf_state_list.pfs_rwl);
266 *
267 * // serialise list head/tail modifications
268 * mtx_enter(&pf_state_list.pfs_mtx);
269 * TAILQ_REMOVE(&pf_state_list.pfs_list, state, entry_list);
270 * mtx_leave(&pf_state_list.pfs_mtx);
271 *
272 * rw_exit_write(&pf_state_list.pfs_rwl);
273 *
274 * the lock ordering for pf_state_list locks and the rest of the pf
275 * locks are:
276 *
277 * 1. KERNEL_LOCK
278 * 2. NET_LOCK
279 * 3. pf_state_list.pfs_rwl
280 * 4. PF_LOCK
281 * 5. PF_STATE_LOCK
282 * 6. pf_state_list.pfs_mtx
283 */
284
285struct pf_state_list {
286 /* the list of states in the system */
287 struct pf_state_queue pfs_list;
288
289 /* serialise pfs_list head/tail access */
290 struct mutex pfs_mtx;
291
292 /* serialise access to pointers between pfs_list entries */
293 struct rwlock pfs_rwl;
294};
295
296#define PF_STATE_LIST_INITIALIZER(_pfs) { \
297 .pfs_list = TAILQ_HEAD_INITIALIZER(_pfs.pfs_list), \
298 .pfs_mtx = MUTEX_INITIALIZER(IPL_SOFTNET), \
299 .pfs_rwl = RWLOCK_INITIALIZER("pfstates"), \
300}
301
302/*
303 * State limiter
304 */
305
306struct pf_statelim {
307 RBT_ENTRY(pf_statelim) pfstlim_id_tree;
308 RBT_ENTRY(pf_statelim) pfstlim_nm_tree;
309 TAILQ_ENTRY(pf_statelim) pfstlim_list;
310 struct kstat *pfstlim_ks;
311
312 uint32_t pfstlim_id;
313 char pfstlim_nm[PF_STATELIM_NAME_LEN];
314
315 /* config */
316
317 unsigned int pfstlim_limit;
318 struct {
319 unsigned int limit;
320 unsigned int seconds;
321 } pfstlim_rate;
322
323 /* run state */
324 struct pc_lock pfstlim_lock;
325
326 /* rate limiter */
327 uint64_t pfstlim_rate_ts;
328 uint64_t pfstlim_rate_token;
329 uint64_t pfstlim_rate_bucket;
330
331 unsigned int pfstlim_inuse;
332 struct pf_state_link_list pfstlim_states;
333
334 /* counters */
335
336 struct {
337 uint64_t admitted;
338 uint64_t hardlimited;
339 uint64_t ratelimited;
340 } pfstlim_counters;
341
342 struct {
343 time_t created;
344 time_t updated;
345 time_t cleared;
346 } pfstlim_timestamps;
347};
348
349RBT_HEAD(pf_statelim_id_tree, pf_statelim);
350RBT_PROTOTYPE(pf_statelim_id_tree, pf_statelim, pfstlim_id_tree, cmp);
351
352RBT_HEAD(pf_statelim_nm_tree, pf_statelim);
353RBT_PROTOTYPE(pf_statelim_nm_tree, pf_statelim, pfstlim_nm_tree, cmp);
354
355TAILQ_HEAD(pf_statelim_list, pf_statelim);
356
357extern struct pf_statelim_id_tree pf_statelim_id_tree_active;
358extern struct pf_statelim_list pf_statelim_list_active;
359
360extern struct pf_statelim_id_tree pf_statelim_id_tree_inactive;
361extern struct pf_statelim_nm_tree pf_statelim_nm_tree_inactive;
362extern struct pf_statelim_list pf_statelim_list_inactive;
363
364static inline unsigned int
365pf_statelim_enter(struct pf_statelim *pfstlim)
366{
367 return (pc_sprod_enter(&pfstlim->pfstlim_lock));
368}
369
370static inline void
371pf_statelim_leave(struct pf_statelim *pfstlim, unsigned int gen)
372{
373 pc_sprod_leave(&pfstlim->pfstlim_lock, gen);
374}
375
376/*
377 * Source address pools
378 */
379
380struct pf_sourcelim;
381
382struct pf_source {
383 RBT_ENTRY(pf_source) pfsr_tree;
384 RBT_ENTRY(pf_source) pfsr_ioc_tree;
385 struct pf_sourcelim *pfsr_parent;
386
387 sa_family_t pfsr_af;
388 u_int16_t pfsr_rdomain;
389 struct pf_addr pfsr_addr;
390
391 /* run state */
392
393 unsigned int pfsr_inuse;
394 unsigned int pfsr_intable;
395 struct pf_state_link_list pfsr_states;
396 time_t pfsr_empty_ts;
397 TAILQ_ENTRY(pf_source) pfsr_empty_gc;
398
399 /* rate limiter */
400 uint64_t pfsr_rate_ts;
401
402 struct {
403 uint64_t admitted;
404 uint64_t hardlimited;
405 uint64_t ratelimited;
406 } pfsr_counters;
407};
408
409RBT_HEAD(pf_source_tree, pf_source);
410RBT_PROTOTYPE(pf_source_tree, pf_source, pfsr_tree, cmp);
411
412RBT_HEAD(pf_source_ioc_tree, pf_source);
413RBT_PROTOTYPE(pf_source_ioc_tree, pf_source, pfsr_ioc_tree, cmp);
414
415TAILQ_HEAD(pf_source_list, pf_source);
416
417struct pf_sourcelim {
418 RBT_ENTRY(pf_sourcelim) pfsrlim_id_tree;
419 RBT_ENTRY(pf_sourcelim) pfsrlim_nm_tree;
420 TAILQ_ENTRY(pf_sourcelim) pfsrlim_list;
421 struct kstat *pfsrlim_ks;
422
423 uint32_t pfsrlim_id;
424 char pfsrlim_nm[PF_SOURCELIM_NAME_LEN];
425 unsigned int pfsrlim_disabled;
426
427 /* config */
428
429 unsigned int pfsrlim_entries;
430 unsigned int pfsrlim_limit;
431 unsigned int pfsrlim_ipv4_prefix;
432 unsigned int pfsrlim_ipv6_prefix;
433
434 struct {
435 unsigned int limit;
436 unsigned int seconds;
437 } pfsrlim_rate;
438
439 struct {
440 char name[PF_TABLE_NAME_SIZE];
441 unsigned int hwm;
442 unsigned int lwm;
443 struct pfr_ktable *table;
444 } pfsrlim_overload;
445
446 /* run state */
447 struct pc_lock pfsrlim_lock;
448
449 struct pf_addr pfsrlim_ipv4_mask;
450 struct pf_addr pfsrlim_ipv6_mask;
451
452 uint64_t pfsrlim_rate_token;
453 uint64_t pfsrlim_rate_bucket;
454
455 /* number of pf_sources */
456 unsigned int pfsrlim_nsources;
457 struct pf_source_tree pfsrlim_sources;
458 struct pf_source_ioc_tree pfsrlim_ioc_sources;
459
460 struct {
461 /* number of times pf_source was allocated */
462 uint64_t addrallocs;
463 /* state was rejected because the address limit was hit */
464 uint64_t addrlimited;
465 /* no memory to create address thing */
466 uint64_t addrnomem;
467
468 /* sum of pf_source inuse gauges */
469 uint64_t inuse;
470 /* sum of pf_source admitted counters */
471 uint64_t admitted;
472 /* sum of pf_source hardlimited counters */
473 uint64_t hardlimited;
474 /* sum of pf_source ratelimited counters */
475 uint64_t ratelimited;
476 } pfsrlim_counters;
477};
478
479RBT_HEAD(pf_sourcelim_id_tree, pf_sourcelim);
480RBT_PROTOTYPE(pf_sourcelim_id_tree, pf_sourcelim, pfsrlim_id_tree, cmp);
481
482RBT_HEAD(pf_sourcelim_nm_tree, pf_sourcelim);
483RBT_PROTOTYPE(pf_sourcelim_nm_tree, pf_sourcelim, pfsrlim_nm_tree, cmp);
484
485TAILQ_HEAD(pf_sourcelim_list, pf_sourcelim);
486
487extern struct pf_sourcelim_id_tree pf_sourcelim_id_tree_active;
488extern struct pf_sourcelim_list pf_sourcelim_list_active;
489
490extern struct pf_sourcelim_id_tree pf_sourcelim_id_tree_inactive;
491extern struct pf_sourcelim_nm_tree pf_sourcelim_nm_tree_inactive;
492extern struct pf_sourcelim_list pf_sourcelim_list_inactive;
493
494static inline unsigned int
495pf_sourcelim_enter(struct pf_sourcelim *pfsrlim)
496{
497 return (pc_sprod_enter(&pfsrlim->pfsrlim_lock));
498}
499
500static inline void
501pf_sourcelim_leave(struct pf_sourcelim *pfsrlim, unsigned int gen)
502{
503 pc_sprod_leave(&pfsrlim->pfsrlim_lock, gen);
504}
505
506/*
507 * pf internals
508 */
509
510extern struct rwlock pf_lock;
511
512struct pf_pdesc {
513 struct {
514 int done;
515 uid_t uid;
516 gid_t gid;
517 pid_t pid;
518 } lookup;
519 u_int64_t tot_len; /* Make Mickey money */
520
521 struct pf_addr nsaddr; /* src address after NAT */
522 struct pf_addr ndaddr; /* dst address after NAT */
523
524 struct pfi_kif *kif; /* incoming interface */
525 struct mbuf *m; /* mbuf containing the packet */
526 struct pf_addr *src; /* src address */
527 struct pf_addr *dst; /* dst address */
528 u_int16_t *pcksum; /* proto cksum */
529 u_int16_t *sport;
530 u_int16_t *dport;
531 u_int16_t osport;
532 u_int16_t odport;
533 u_int16_t hash;
534 u_int16_t nsport; /* src port after NAT */
535 u_int16_t ndport; /* dst port after NAT */
536
537 u_int32_t off; /* protocol header offset */
538 u_int32_t hdrlen; /* protocol header length */
539 u_int32_t p_len; /* length of protocol payload */
540 u_int32_t extoff; /* extension header offset */
541 u_int32_t fragoff; /* fragment header offset */
542 u_int32_t jumbolen; /* length from v6 jumbo header */
543 u_int32_t badopts; /* v4 options or v6 routing headers */
544#define PF_OPT_OTHER 0x0001
545#define PF_OPT_JUMBO 0x0002
546#define PF_OPT_ROUTER_ALERT 0x0004
547
548 u_int16_t rdomain; /* original routing domain */
549 u_int16_t virtual_proto;
550#define PF_VPROTO_FRAGMENT 256
551 sa_family_t af;
552 sa_family_t naf;
553 u_int8_t proto;
554 u_int8_t tos;
555 u_int8_t ttl;
556 u_int8_t dir; /* direction */
557 u_int8_t sidx; /* key index for source */
558 u_int8_t didx; /* key index for destination */
559 u_int8_t destchg; /* flag set when destination changed */
560 u_int8_t pflog; /* flags for packet logging */
561 union {
562 struct tcphdr tcp;
563 struct udphdr udp;
564 struct icmp icmp;
565#ifdef INET6
566 struct icmp6_hdr icmp6;
567 struct mld_hdr mld;
568 struct nd_neighbor_solicit nd_ns;
569#endif /* INET6 */
570 } hdr;
571};
572
573struct pf_anchor_stackframe {
574 struct pf_ruleset *sf_rs;
575 struct pf_rule *sf_anchor;
576 union {
577 struct pf_rule *u_r;
578 struct pf_anchor_stackframe *u_stack_top;
579 } u;
580 struct pf_anchor *sf_child;
581 int sf_jump_target;
582};
583#define sf_r u.u_r
584#define sf_stack_top u.u_stack_top
585enum {
586 PF_NEXT_RULE,
587 PF_NEXT_CHILD
588};
589
590extern struct cpumem *pf_anchor_stack;
591
592enum pf_trans_type {
593 PF_TRANS_NONE,
594 PF_TRANS_GETRULE,
595 PF_TRANS_MAX
596};
597
598struct pf_trans {
599 LIST_ENTRY(pf_trans) pft_entry;
600 uint32_t pft_unit; /* process id */
601 uint64_t pft_ticket;
602 enum pf_trans_type pft_type;
603 union {
604 struct {
605 u_int32_t gr_version;
606 struct pf_anchor *gr_anchor;
607 struct pf_rule *gr_rule;
608 } u_getrule;
609 } u;
610};
611
612#define pftgr_version u.u_getrule.gr_version
613#define pftgr_anchor u.u_getrule.gr_anchor
614#define pftgr_rule u.u_getrule.gr_rule
615
616extern struct timeout pf_purge_states_to;
617extern struct task pf_purge_task;
618extern struct timeout pf_purge_to;
619
620struct pf_state *pf_state_ref(struct pf_state *);
621void pf_state_unref(struct pf_state *);
622
623extern struct rwlock pf_lock;
624extern struct rwlock pf_state_lock;
625extern struct mutex pf_frag_mtx;
626extern struct mutex pf_inp_mtx;
627
628#define PF_LOCK() do { \
629 rw_enter_write(&pf_lock); \
630 } while (0)
631
632#define PF_UNLOCK() do { \
633 PF_ASSERT_LOCKED(); \
634 rw_exit_write(&pf_lock); \
635 } while (0)
636
637#define PF_ASSERT_LOCKED() do { \
638 if (rw_status(&pf_lock) != RW_WRITE) \
639 splassert_fail(RW_WRITE, \
640 rw_status(&pf_lock),__func__);\
641 } while (0)
642
643#define PF_ASSERT_UNLOCKED() do { \
644 if (rw_status(&pf_lock) == RW_WRITE) \
645 splassert_fail(0, rw_status(&pf_lock), __func__);\
646 } while (0)
647
648#define PF_STATE_ENTER_READ() do { \
649 rw_enter_read(&pf_state_lock); \
650 } while (0)
651
652#define PF_STATE_EXIT_READ() do { \
653 rw_exit_read(&pf_state_lock); \
654 } while (0)
655
656#define PF_STATE_ENTER_WRITE() do { \
657 rw_enter_write(&pf_state_lock); \
658 } while (0)
659
660#define PF_STATE_EXIT_WRITE() do { \
661 PF_STATE_ASSERT_LOCKED(); \
662 rw_exit_write(&pf_state_lock); \
663 } while (0)
664
665#define PF_STATE_ASSERT_LOCKED() do { \
666 if (rw_status(&pf_state_lock) != RW_WRITE)\
667 splassert_fail(RW_WRITE, \
668 rw_status(&pf_state_lock), __func__);\
669 } while (0)
670
671#define PF_FRAG_LOCK() mtx_enter(&pf_frag_mtx)
672#define PF_FRAG_UNLOCK() mtx_leave(&pf_frag_mtx)
673
674/* for copies to/from network byte order */
675void pf_state_peer_hton(const struct pf_state_peer *,
676 struct pfsync_state_peer *);
677void pf_state_peer_ntoh(const struct pfsync_state_peer *,
678 struct pf_state_peer *);
679u_int16_t pf_pkt_hash(sa_family_t, uint8_t,
680 const struct pf_addr *, const struct pf_addr *,
681 uint16_t, uint16_t);
682
683void pf_status_init(void);
684void pf_status_clear(void);
685void pf_status_read(struct pf_status *);
686
687#endif /* _KERNEL */
688
689#endif /* _NET_PFVAR_PRIV_H_ */