1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2001 Daniel Hartmeier
5 * Copyright (c) 2002,2003 Henning Brauer
6 * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.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 * Effort sponsored in part by the Defense Advanced Research Projects
34 * Agency (DARPA) and Air Force Research Laboratory, Air Force
35 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
36 *
37 *	$OpenBSD: pf_ioctl.c,v 1.213 2009/02/15 21:46:12 mbalmer Exp $
38 */
39
40#include <sys/cdefs.h>
41#include "opt_inet.h"
42#include "opt_inet6.h"
43#include "opt_bpf.h"
44#include "opt_pf.h"
45
46#include <sys/param.h>
47#include <sys/_bitset.h>
48#include <sys/bitset.h>
49#include <sys/bus.h>
50#include <sys/conf.h>
51#include <sys/endian.h>
52#include <sys/fcntl.h>
53#include <sys/filio.h>
54#include <sys/hash.h>
55#include <sys/interrupt.h>
56#include <sys/jail.h>
57#include <sys/kernel.h>
58#include <sys/kthread.h>
59#include <sys/lock.h>
60#include <sys/mbuf.h>
61#include <sys/module.h>
62#include <sys/nv.h>
63#include <sys/proc.h>
64#include <sys/sdt.h>
65#include <sys/smp.h>
66#include <sys/socket.h>
67#include <sys/sysctl.h>
68#include <sys/md5.h>
69#include <sys/ucred.h>
70
71#include <net/if.h>
72#include <net/if_var.h>
73#include <net/if_private.h>
74#include <net/vnet.h>
75#include <net/route.h>
76#include <net/pfil.h>
77#include <net/pfvar.h>
78#include <net/if_pfsync.h>
79#include <net/if_pflog.h>
80
81#include <netinet/in.h>
82#include <netinet/ip.h>
83#include <netinet/ip_var.h>
84#include <netinet6/ip6_var.h>
85#include <netinet/ip_icmp.h>
86#include <netpfil/pf/pf_nl.h>
87#include <netpfil/pf/pf_nv.h>
88
89#ifdef INET6
90#include <netinet/ip6.h>
91#endif /* INET6 */
92
93#ifdef ALTQ
94#include <net/altq/altq.h>
95#endif
96
97SDT_PROBE_DEFINE3(pf, ioctl, ioctl, error, "int", "int", "int");
98SDT_PROBE_DEFINE3(pf, ioctl, function, error, "char *", "int", "int");
99SDT_PROBE_DEFINE2(pf, ioctl, addrule, error, "int", "int");
100SDT_PROBE_DEFINE2(pf, ioctl, nvchk, error, "int", "int");
101
102static struct pf_kpool	*pf_get_kpool(const char *, u_int32_t, u_int8_t,
103			    u_int32_t, u_int8_t, u_int8_t, u_int8_t);
104
105static void		 pf_mv_kpool(struct pf_kpalist *, struct pf_kpalist *);
106static void		 pf_empty_kpool(struct pf_kpalist *);
107static int		 pfioctl(struct cdev *, u_long, caddr_t, int,
108			    struct thread *);
109static int		 pf_begin_eth(uint32_t *, const char *);
110static void		 pf_rollback_eth_cb(struct epoch_context *);
111static int		 pf_rollback_eth(uint32_t, const char *);
112static int		 pf_commit_eth(uint32_t, const char *);
113static void		 pf_free_eth_rule(struct pf_keth_rule *);
114#ifdef ALTQ
115static int		 pf_begin_altq(u_int32_t *);
116static int		 pf_rollback_altq(u_int32_t);
117static int		 pf_commit_altq(u_int32_t);
118static int		 pf_enable_altq(struct pf_altq *);
119static int		 pf_disable_altq(struct pf_altq *);
120static uint16_t		 pf_qname2qid(const char *);
121static void		 pf_qid_unref(uint16_t);
122#endif /* ALTQ */
123static int		 pf_begin_rules(u_int32_t *, int, const char *);
124static int		 pf_rollback_rules(u_int32_t, int, char *);
125static int		 pf_setup_pfsync_matching(struct pf_kruleset *);
126static void		 pf_hash_rule_rolling(MD5_CTX *, struct pf_krule *);
127static void		 pf_hash_rule(struct pf_krule *);
128static void		 pf_hash_rule_addr(MD5_CTX *, struct pf_rule_addr *);
129static int		 pf_commit_rules(u_int32_t, int, char *);
130static int		 pf_addr_setup(struct pf_kruleset *,
131			    struct pf_addr_wrap *, sa_family_t);
132static void		 pf_addr_copyout(struct pf_addr_wrap *);
133static void		 pf_src_node_copy(const struct pf_ksrc_node *,
134			    struct pf_src_node *);
135#ifdef ALTQ
136static int		 pf_export_kaltq(struct pf_altq *,
137			    struct pfioc_altq_v1 *, size_t);
138static int		 pf_import_kaltq(struct pfioc_altq_v1 *,
139			    struct pf_altq *, size_t);
140#endif /* ALTQ */
141
142VNET_DEFINE(struct pf_krule,	pf_default_rule);
143
144static __inline int             pf_krule_compare(struct pf_krule *,
145				    struct pf_krule *);
146
147RB_GENERATE(pf_krule_global, pf_krule, entry_global, pf_krule_compare);
148
149#ifdef ALTQ
150VNET_DEFINE_STATIC(int,		pf_altq_running);
151#define	V_pf_altq_running	VNET(pf_altq_running)
152#endif
153
154#define	TAGID_MAX	 50000
155struct pf_tagname {
156	TAILQ_ENTRY(pf_tagname)	namehash_entries;
157	TAILQ_ENTRY(pf_tagname)	taghash_entries;
158	char			name[PF_TAG_NAME_SIZE];
159	uint16_t		tag;
160	int			ref;
161};
162
163struct pf_tagset {
164	TAILQ_HEAD(, pf_tagname)	*namehash;
165	TAILQ_HEAD(, pf_tagname)	*taghash;
166	unsigned int			 mask;
167	uint32_t			 seed;
168	BITSET_DEFINE(, TAGID_MAX)	 avail;
169};
170
171VNET_DEFINE(struct pf_tagset, pf_tags);
172#define	V_pf_tags	VNET(pf_tags)
173static unsigned int	pf_rule_tag_hashsize;
174#define	PF_RULE_TAG_HASH_SIZE_DEFAULT	128
175SYSCTL_UINT(_net_pf, OID_AUTO, rule_tag_hashsize, CTLFLAG_RDTUN,
176    &pf_rule_tag_hashsize, PF_RULE_TAG_HASH_SIZE_DEFAULT,
177    "Size of pf(4) rule tag hashtable");
178
179#ifdef ALTQ
180VNET_DEFINE(struct pf_tagset, pf_qids);
181#define	V_pf_qids	VNET(pf_qids)
182static unsigned int	pf_queue_tag_hashsize;
183#define	PF_QUEUE_TAG_HASH_SIZE_DEFAULT	128
184SYSCTL_UINT(_net_pf, OID_AUTO, queue_tag_hashsize, CTLFLAG_RDTUN,
185    &pf_queue_tag_hashsize, PF_QUEUE_TAG_HASH_SIZE_DEFAULT,
186    "Size of pf(4) queue tag hashtable");
187#endif
188VNET_DEFINE(uma_zone_t,	 pf_tag_z);
189#define	V_pf_tag_z		 VNET(pf_tag_z)
190static MALLOC_DEFINE(M_PFALTQ, "pf_altq", "pf(4) altq configuration db");
191static MALLOC_DEFINE(M_PFRULE, "pf_rule", "pf(4) rules");
192
193#if (PF_QNAME_SIZE != PF_TAG_NAME_SIZE)
194#error PF_QNAME_SIZE must be equal to PF_TAG_NAME_SIZE
195#endif
196
197VNET_DEFINE_STATIC(bool, pf_filter_local) = false;
198#define V_pf_filter_local	VNET(pf_filter_local)
199SYSCTL_BOOL(_net_pf, OID_AUTO, filter_local, CTLFLAG_VNET | CTLFLAG_RW,
200    &VNET_NAME(pf_filter_local), false,
201    "Enable filtering for packets delivered to local network stack");
202
203#ifdef PF_DEFAULT_TO_DROP
204VNET_DEFINE_STATIC(bool, default_to_drop) = true;
205#else
206VNET_DEFINE_STATIC(bool, default_to_drop);
207#endif
208#define	V_default_to_drop VNET(default_to_drop)
209SYSCTL_BOOL(_net_pf, OID_AUTO, default_to_drop, CTLFLAG_RDTUN | CTLFLAG_VNET,
210    &VNET_NAME(default_to_drop), false,
211    "Make the default rule drop all packets.");
212
213static void		 pf_init_tagset(struct pf_tagset *, unsigned int *,
214			    unsigned int);
215static void		 pf_cleanup_tagset(struct pf_tagset *);
216static uint16_t		 tagname2hashindex(const struct pf_tagset *, const char *);
217static uint16_t		 tag2hashindex(const struct pf_tagset *, uint16_t);
218static u_int16_t	 tagname2tag(struct pf_tagset *, const char *);
219static u_int16_t	 pf_tagname2tag(const char *);
220static void		 tag_unref(struct pf_tagset *, u_int16_t);
221
222#define DPFPRINTF(n, x) if (V_pf_status.debug >= (n)) printf x
223
224struct cdev *pf_dev;
225
226/*
227 * XXX - These are new and need to be checked when moveing to a new version
228 */
229static void		 pf_clear_all_states(void);
230static int		 pf_killstates_row(struct pf_kstate_kill *,
231			    struct pf_idhash *);
232static int		 pf_killstates_nv(struct pfioc_nv *);
233static int		 pf_clearstates_nv(struct pfioc_nv *);
234static int		 pf_getstate(struct pfioc_nv *);
235static int		 pf_getstatus(struct pfioc_nv *);
236static int		 pf_clear_tables(void);
237static void		 pf_clear_srcnodes(struct pf_ksrc_node *);
238static void		 pf_kill_srcnodes(struct pfioc_src_node_kill *);
239static int		 pf_keepcounters(struct pfioc_nv *);
240static void		 pf_tbladdr_copyout(struct pf_addr_wrap *);
241
242/*
243 * Wrapper functions for pfil(9) hooks
244 */
245static pfil_return_t pf_eth_check_in(struct mbuf **m, struct ifnet *ifp,
246    int flags, void *ruleset __unused, struct inpcb *inp);
247static pfil_return_t pf_eth_check_out(struct mbuf **m, struct ifnet *ifp,
248    int flags, void *ruleset __unused, struct inpcb *inp);
249#ifdef INET
250static pfil_return_t pf_check_in(struct mbuf **m, struct ifnet *ifp,
251    int flags, void *ruleset __unused, struct inpcb *inp);
252static pfil_return_t pf_check_out(struct mbuf **m, struct ifnet *ifp,
253    int flags, void *ruleset __unused, struct inpcb *inp);
254#endif
255#ifdef INET6
256static pfil_return_t pf_check6_in(struct mbuf **m, struct ifnet *ifp,
257    int flags, void *ruleset __unused, struct inpcb *inp);
258static pfil_return_t pf_check6_out(struct mbuf **m, struct ifnet *ifp,
259    int flags, void *ruleset __unused, struct inpcb *inp);
260#endif
261
262static void		hook_pf_eth(void);
263static void		hook_pf(void);
264static void		dehook_pf_eth(void);
265static void		dehook_pf(void);
266static int		shutdown_pf(void);
267static int		pf_load(void);
268static void		pf_unload(void);
269
270static struct cdevsw pf_cdevsw = {
271	.d_ioctl =	pfioctl,
272	.d_name =	PF_NAME,
273	.d_version =	D_VERSION,
274};
275
276VNET_DEFINE_STATIC(bool, pf_pfil_hooked);
277#define V_pf_pfil_hooked	VNET(pf_pfil_hooked)
278VNET_DEFINE_STATIC(bool, pf_pfil_eth_hooked);
279#define V_pf_pfil_eth_hooked	VNET(pf_pfil_eth_hooked)
280
281/*
282 * We need a flag that is neither hooked nor running to know when
283 * the VNET is "valid".  We primarily need this to control (global)
284 * external event, e.g., eventhandlers.
285 */
286VNET_DEFINE(int, pf_vnet_active);
287#define V_pf_vnet_active	VNET(pf_vnet_active)
288
289int pf_end_threads;
290struct proc *pf_purge_proc;
291
292VNET_DEFINE(struct rmlock, pf_rules_lock);
293VNET_DEFINE_STATIC(struct sx, pf_ioctl_lock);
294#define	V_pf_ioctl_lock		VNET(pf_ioctl_lock)
295struct sx			pf_end_lock;
296
297/* pfsync */
298VNET_DEFINE(pfsync_state_import_t *, pfsync_state_import_ptr);
299VNET_DEFINE(pfsync_insert_state_t *, pfsync_insert_state_ptr);
300VNET_DEFINE(pfsync_update_state_t *, pfsync_update_state_ptr);
301VNET_DEFINE(pfsync_delete_state_t *, pfsync_delete_state_ptr);
302VNET_DEFINE(pfsync_clear_states_t *, pfsync_clear_states_ptr);
303VNET_DEFINE(pfsync_defer_t *, pfsync_defer_ptr);
304VNET_DEFINE(pflow_export_state_t *, pflow_export_state_ptr);
305pfsync_detach_ifnet_t *pfsync_detach_ifnet_ptr;
306
307/* pflog */
308pflog_packet_t			*pflog_packet_ptr = NULL;
309
310/*
311 * Copy a user-provided string, returning an error if truncation would occur.
312 * Avoid scanning past "sz" bytes in the source string since there's no
313 * guarantee that it's nul-terminated.
314 */
315static int
316pf_user_strcpy(char *dst, const char *src, size_t sz)
317{
318	if (strnlen(src, sz) == sz)
319		return (EINVAL);
320	(void)strlcpy(dst, src, sz);
321	return (0);
322}
323
324static void
325pfattach_vnet(void)
326{
327	u_int32_t *my_timeout = V_pf_default_rule.timeout;
328
329	bzero(&V_pf_status, sizeof(V_pf_status));
330
331	pf_initialize();
332	pfr_initialize();
333	pfi_initialize_vnet();
334	pf_normalize_init();
335	pf_syncookies_init();
336
337	V_pf_limits[PF_LIMIT_STATES].limit = PFSTATE_HIWAT;
338	V_pf_limits[PF_LIMIT_SRC_NODES].limit = PFSNODE_HIWAT;
339
340	RB_INIT(&V_pf_anchors);
341	pf_init_kruleset(&pf_main_ruleset);
342
343	pf_init_keth(V_pf_keth);
344
345	/* default rule should never be garbage collected */
346	V_pf_default_rule.entries.tqe_prev = &V_pf_default_rule.entries.tqe_next;
347	V_pf_default_rule.action = V_default_to_drop ? PF_DROP : PF_PASS;
348	V_pf_default_rule.nr = -1;
349	V_pf_default_rule.rtableid = -1;
350
351	pf_counter_u64_init(&V_pf_default_rule.evaluations, M_WAITOK);
352	for (int i = 0; i < 2; i++) {
353		pf_counter_u64_init(&V_pf_default_rule.packets[i], M_WAITOK);
354		pf_counter_u64_init(&V_pf_default_rule.bytes[i], M_WAITOK);
355	}
356	V_pf_default_rule.states_cur = counter_u64_alloc(M_WAITOK);
357	V_pf_default_rule.states_tot = counter_u64_alloc(M_WAITOK);
358	V_pf_default_rule.src_nodes = counter_u64_alloc(M_WAITOK);
359
360	V_pf_default_rule.timestamp = uma_zalloc_pcpu(pf_timestamp_pcpu_zone,
361	    M_WAITOK | M_ZERO);
362
363#ifdef PF_WANT_32_TO_64_COUNTER
364	V_pf_kifmarker = malloc(sizeof(*V_pf_kifmarker), PFI_MTYPE, M_WAITOK | M_ZERO);
365	V_pf_rulemarker = malloc(sizeof(*V_pf_rulemarker), M_PFRULE, M_WAITOK | M_ZERO);
366	PF_RULES_WLOCK();
367	LIST_INSERT_HEAD(&V_pf_allkiflist, V_pf_kifmarker, pfik_allkiflist);
368	LIST_INSERT_HEAD(&V_pf_allrulelist, &V_pf_default_rule, allrulelist);
369	V_pf_allrulecount++;
370	LIST_INSERT_HEAD(&V_pf_allrulelist, V_pf_rulemarker, allrulelist);
371	PF_RULES_WUNLOCK();
372#endif
373
374	/* initialize default timeouts */
375	my_timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
376	my_timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL;
377	my_timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL;
378	my_timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL;
379	my_timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL;
380	my_timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL;
381	my_timeout[PFTM_SCTP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
382	my_timeout[PFTM_SCTP_OPENING] = PFTM_TCP_OPENING_VAL;
383	my_timeout[PFTM_SCTP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL;
384	my_timeout[PFTM_SCTP_CLOSING] = PFTM_TCP_CLOSING_VAL;
385	my_timeout[PFTM_SCTP_CLOSED] = PFTM_TCP_CLOSED_VAL;
386	my_timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL;
387	my_timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL;
388	my_timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL;
389	my_timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL;
390	my_timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL;
391	my_timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL;
392	my_timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL;
393	my_timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL;
394	my_timeout[PFTM_FRAG] = PFTM_FRAG_VAL;
395	my_timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL;
396	my_timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL;
397	my_timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL;
398	my_timeout[PFTM_ADAPTIVE_START] = PFSTATE_ADAPT_START;
399	my_timeout[PFTM_ADAPTIVE_END] = PFSTATE_ADAPT_END;
400
401	V_pf_status.debug = PF_DEBUG_URGENT;
402	/*
403	 * XXX This is different than in OpenBSD where reassembly is enabled by
404	 * defult. In FreeBSD we expect people to still use scrub rules and
405	 * switch to the new syntax later. Only when they switch they must
406	 * explicitly enable reassemle. We could change the default once the
407	 * scrub rule functionality is hopefully removed some day in future.
408	 */
409	V_pf_status.reass = 0;
410
411	V_pf_pfil_hooked = false;
412	V_pf_pfil_eth_hooked = false;
413
414	/* XXX do our best to avoid a conflict */
415	V_pf_status.hostid = arc4random();
416
417	for (int i = 0; i < PFRES_MAX; i++)
418		V_pf_status.counters[i] = counter_u64_alloc(M_WAITOK);
419	for (int i = 0; i < KLCNT_MAX; i++)
420		V_pf_status.lcounters[i] = counter_u64_alloc(M_WAITOK);
421	for (int i = 0; i < FCNT_MAX; i++)
422		pf_counter_u64_init(&V_pf_status.fcounters[i], M_WAITOK);
423	for (int i = 0; i < SCNT_MAX; i++)
424		V_pf_status.scounters[i] = counter_u64_alloc(M_WAITOK);
425
426	if (swi_add(&V_pf_swi_ie, "pf send", pf_intr, curvnet, SWI_NET,
427	    INTR_MPSAFE, &V_pf_swi_cookie) != 0)
428		/* XXXGL: leaked all above. */
429		return;
430}
431
432static struct pf_kpool *
433pf_get_kpool(const char *anchor, u_int32_t ticket, u_int8_t rule_action,
434    u_int32_t rule_number, u_int8_t r_last, u_int8_t active,
435    u_int8_t check_ticket)
436{
437	struct pf_kruleset	*ruleset;
438	struct pf_krule		*rule;
439	int			 rs_num;
440
441	ruleset = pf_find_kruleset(anchor);
442	if (ruleset == NULL)
443		return (NULL);
444	rs_num = pf_get_ruleset_number(rule_action);
445	if (rs_num >= PF_RULESET_MAX)
446		return (NULL);
447	if (active) {
448		if (check_ticket && ticket !=
449		    ruleset->rules[rs_num].active.ticket)
450			return (NULL);
451		if (r_last)
452			rule = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
453			    pf_krulequeue);
454		else
455			rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
456	} else {
457		if (check_ticket && ticket !=
458		    ruleset->rules[rs_num].inactive.ticket)
459			return (NULL);
460		if (r_last)
461			rule = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,
462			    pf_krulequeue);
463		else
464			rule = TAILQ_FIRST(ruleset->rules[rs_num].inactive.ptr);
465	}
466	if (!r_last) {
467		while ((rule != NULL) && (rule->nr != rule_number))
468			rule = TAILQ_NEXT(rule, entries);
469	}
470	if (rule == NULL)
471		return (NULL);
472
473	return (&rule->rpool);
474}
475
476static void
477pf_mv_kpool(struct pf_kpalist *poola, struct pf_kpalist *poolb)
478{
479	struct pf_kpooladdr	*mv_pool_pa;
480
481	while ((mv_pool_pa = TAILQ_FIRST(poola)) != NULL) {
482		TAILQ_REMOVE(poola, mv_pool_pa, entries);
483		TAILQ_INSERT_TAIL(poolb, mv_pool_pa, entries);
484	}
485}
486
487static void
488pf_empty_kpool(struct pf_kpalist *poola)
489{
490	struct pf_kpooladdr *pa;
491
492	while ((pa = TAILQ_FIRST(poola)) != NULL) {
493		switch (pa->addr.type) {
494		case PF_ADDR_DYNIFTL:
495			pfi_dynaddr_remove(pa->addr.p.dyn);
496			break;
497		case PF_ADDR_TABLE:
498			/* XXX: this could be unfinished pooladdr on pabuf */
499			if (pa->addr.p.tbl != NULL)
500				pfr_detach_table(pa->addr.p.tbl);
501			break;
502		}
503		if (pa->kif)
504			pfi_kkif_unref(pa->kif);
505		TAILQ_REMOVE(poola, pa, entries);
506		free(pa, M_PFRULE);
507	}
508}
509
510static void
511pf_unlink_rule_locked(struct pf_krulequeue *rulequeue, struct pf_krule *rule)
512{
513
514	PF_RULES_WASSERT();
515	PF_UNLNKDRULES_ASSERT();
516
517	TAILQ_REMOVE(rulequeue, rule, entries);
518
519	rule->rule_ref |= PFRULE_REFS;
520	TAILQ_INSERT_TAIL(&V_pf_unlinked_rules, rule, entries);
521}
522
523static void
524pf_unlink_rule(struct pf_krulequeue *rulequeue, struct pf_krule *rule)
525{
526
527	PF_RULES_WASSERT();
528
529	PF_UNLNKDRULES_LOCK();
530	pf_unlink_rule_locked(rulequeue, rule);
531	PF_UNLNKDRULES_UNLOCK();
532}
533
534static void
535pf_free_eth_rule(struct pf_keth_rule *rule)
536{
537	PF_RULES_WASSERT();
538
539	if (rule == NULL)
540		return;
541
542	if (rule->tag)
543		tag_unref(&V_pf_tags, rule->tag);
544	if (rule->match_tag)
545		tag_unref(&V_pf_tags, rule->match_tag);
546#ifdef ALTQ
547	pf_qid_unref(rule->qid);
548#endif
549
550	if (rule->bridge_to)
551		pfi_kkif_unref(rule->bridge_to);
552	if (rule->kif)
553		pfi_kkif_unref(rule->kif);
554
555	if (rule->ipsrc.addr.type == PF_ADDR_TABLE)
556		pfr_detach_table(rule->ipsrc.addr.p.tbl);
557	if (rule->ipdst.addr.type == PF_ADDR_TABLE)
558		pfr_detach_table(rule->ipdst.addr.p.tbl);
559
560	counter_u64_free(rule->evaluations);
561	for (int i = 0; i < 2; i++) {
562		counter_u64_free(rule->packets[i]);
563		counter_u64_free(rule->bytes[i]);
564	}
565	uma_zfree_pcpu(pf_timestamp_pcpu_zone, rule->timestamp);
566	pf_keth_anchor_remove(rule);
567
568	free(rule, M_PFRULE);
569}
570
571void
572pf_free_rule(struct pf_krule *rule)
573{
574
575	PF_RULES_WASSERT();
576	PF_CONFIG_ASSERT();
577
578	if (rule->tag)
579		tag_unref(&V_pf_tags, rule->tag);
580	if (rule->match_tag)
581		tag_unref(&V_pf_tags, rule->match_tag);
582#ifdef ALTQ
583	if (rule->pqid != rule->qid)
584		pf_qid_unref(rule->pqid);
585	pf_qid_unref(rule->qid);
586#endif
587	switch (rule->src.addr.type) {
588	case PF_ADDR_DYNIFTL:
589		pfi_dynaddr_remove(rule->src.addr.p.dyn);
590		break;
591	case PF_ADDR_TABLE:
592		pfr_detach_table(rule->src.addr.p.tbl);
593		break;
594	}
595	switch (rule->dst.addr.type) {
596	case PF_ADDR_DYNIFTL:
597		pfi_dynaddr_remove(rule->dst.addr.p.dyn);
598		break;
599	case PF_ADDR_TABLE:
600		pfr_detach_table(rule->dst.addr.p.tbl);
601		break;
602	}
603	if (rule->overload_tbl)
604		pfr_detach_table(rule->overload_tbl);
605	if (rule->kif)
606		pfi_kkif_unref(rule->kif);
607	pf_kanchor_remove(rule);
608	pf_empty_kpool(&rule->rpool.list);
609
610	pf_krule_free(rule);
611}
612
613static void
614pf_init_tagset(struct pf_tagset *ts, unsigned int *tunable_size,
615    unsigned int default_size)
616{
617	unsigned int i;
618	unsigned int hashsize;
619
620	if (*tunable_size == 0 || !powerof2(*tunable_size))
621		*tunable_size = default_size;
622
623	hashsize = *tunable_size;
624	ts->namehash = mallocarray(hashsize, sizeof(*ts->namehash), M_PFHASH,
625	    M_WAITOK);
626	ts->taghash = mallocarray(hashsize, sizeof(*ts->taghash), M_PFHASH,
627	    M_WAITOK);
628	ts->mask = hashsize - 1;
629	ts->seed = arc4random();
630	for (i = 0; i < hashsize; i++) {
631		TAILQ_INIT(&ts->namehash[i]);
632		TAILQ_INIT(&ts->taghash[i]);
633	}
634	BIT_FILL(TAGID_MAX, &ts->avail);
635}
636
637static void
638pf_cleanup_tagset(struct pf_tagset *ts)
639{
640	unsigned int i;
641	unsigned int hashsize;
642	struct pf_tagname *t, *tmp;
643
644	/*
645	 * Only need to clean up one of the hashes as each tag is hashed
646	 * into each table.
647	 */
648	hashsize = ts->mask + 1;
649	for (i = 0; i < hashsize; i++)
650		TAILQ_FOREACH_SAFE(t, &ts->namehash[i], namehash_entries, tmp)
651			uma_zfree(V_pf_tag_z, t);
652
653	free(ts->namehash, M_PFHASH);
654	free(ts->taghash, M_PFHASH);
655}
656
657static uint16_t
658tagname2hashindex(const struct pf_tagset *ts, const char *tagname)
659{
660	size_t len;
661
662	len = strnlen(tagname, PF_TAG_NAME_SIZE - 1);
663	return (murmur3_32_hash(tagname, len, ts->seed) & ts->mask);
664}
665
666static uint16_t
667tag2hashindex(const struct pf_tagset *ts, uint16_t tag)
668{
669
670	return (tag & ts->mask);
671}
672
673static u_int16_t
674tagname2tag(struct pf_tagset *ts, const char *tagname)
675{
676	struct pf_tagname	*tag;
677	u_int32_t		 index;
678	u_int16_t		 new_tagid;
679
680	PF_RULES_WASSERT();
681
682	index = tagname2hashindex(ts, tagname);
683	TAILQ_FOREACH(tag, &ts->namehash[index], namehash_entries)
684		if (strcmp(tagname, tag->name) == 0) {
685			tag->ref++;
686			return (tag->tag);
687		}
688
689	/*
690	 * new entry
691	 *
692	 * to avoid fragmentation, we do a linear search from the beginning
693	 * and take the first free slot we find.
694	 */
695	new_tagid = BIT_FFS(TAGID_MAX, &ts->avail);
696	/*
697	 * Tags are 1-based, with valid tags in the range [1..TAGID_MAX].
698	 * BIT_FFS() returns a 1-based bit number, with 0 indicating no bits
699	 * set.  It may also return a bit number greater than TAGID_MAX due
700	 * to rounding of the number of bits in the vector up to a multiple
701	 * of the vector word size at declaration/allocation time.
702	 */
703	if ((new_tagid == 0) || (new_tagid > TAGID_MAX))
704		return (0);
705
706	/* Mark the tag as in use.  Bits are 0-based for BIT_CLR() */
707	BIT_CLR(TAGID_MAX, new_tagid - 1, &ts->avail);
708
709	/* allocate and fill new struct pf_tagname */
710	tag = uma_zalloc(V_pf_tag_z, M_NOWAIT);
711	if (tag == NULL)
712		return (0);
713	strlcpy(tag->name, tagname, sizeof(tag->name));
714	tag->tag = new_tagid;
715	tag->ref = 1;
716
717	/* Insert into namehash */
718	TAILQ_INSERT_TAIL(&ts->namehash[index], tag, namehash_entries);
719
720	/* Insert into taghash */
721	index = tag2hashindex(ts, new_tagid);
722	TAILQ_INSERT_TAIL(&ts->taghash[index], tag, taghash_entries);
723
724	return (tag->tag);
725}
726
727static void
728tag_unref(struct pf_tagset *ts, u_int16_t tag)
729{
730	struct pf_tagname	*t;
731	uint16_t		 index;
732
733	PF_RULES_WASSERT();
734
735	index = tag2hashindex(ts, tag);
736	TAILQ_FOREACH(t, &ts->taghash[index], taghash_entries)
737		if (tag == t->tag) {
738			if (--t->ref == 0) {
739				TAILQ_REMOVE(&ts->taghash[index], t,
740				    taghash_entries);
741				index = tagname2hashindex(ts, t->name);
742				TAILQ_REMOVE(&ts->namehash[index], t,
743				    namehash_entries);
744				/* Bits are 0-based for BIT_SET() */
745				BIT_SET(TAGID_MAX, tag - 1, &ts->avail);
746				uma_zfree(V_pf_tag_z, t);
747			}
748			break;
749		}
750}
751
752static uint16_t
753pf_tagname2tag(const char *tagname)
754{
755	return (tagname2tag(&V_pf_tags, tagname));
756}
757
758static int
759pf_begin_eth(uint32_t *ticket, const char *anchor)
760{
761	struct pf_keth_rule *rule, *tmp;
762	struct pf_keth_ruleset *rs;
763
764	PF_RULES_WASSERT();
765
766	rs = pf_find_or_create_keth_ruleset(anchor);
767	if (rs == NULL)
768		return (EINVAL);
769
770	/* Purge old inactive rules. */
771	TAILQ_FOREACH_SAFE(rule, rs->inactive.rules, entries,
772	    tmp) {
773		TAILQ_REMOVE(rs->inactive.rules, rule,
774		    entries);
775		pf_free_eth_rule(rule);
776	}
777
778	*ticket = ++rs->inactive.ticket;
779	rs->inactive.open = 1;
780
781	return (0);
782}
783
784static void
785pf_rollback_eth_cb(struct epoch_context *ctx)
786{
787	struct pf_keth_ruleset *rs;
788
789	rs = __containerof(ctx, struct pf_keth_ruleset, epoch_ctx);
790
791	CURVNET_SET(rs->vnet);
792
793	PF_RULES_WLOCK();
794	pf_rollback_eth(rs->inactive.ticket,
795	    rs->anchor ? rs->anchor->path : "");
796	PF_RULES_WUNLOCK();
797
798	CURVNET_RESTORE();
799}
800
801static int
802pf_rollback_eth(uint32_t ticket, const char *anchor)
803{
804	struct pf_keth_rule *rule, *tmp;
805	struct pf_keth_ruleset *rs;
806
807	PF_RULES_WASSERT();
808
809	rs = pf_find_keth_ruleset(anchor);
810	if (rs == NULL)
811		return (EINVAL);
812
813	if (!rs->inactive.open ||
814	    ticket != rs->inactive.ticket)
815		return (0);
816
817	/* Purge old inactive rules. */
818	TAILQ_FOREACH_SAFE(rule, rs->inactive.rules, entries,
819	    tmp) {
820		TAILQ_REMOVE(rs->inactive.rules, rule, entries);
821		pf_free_eth_rule(rule);
822	}
823
824	rs->inactive.open = 0;
825
826	pf_remove_if_empty_keth_ruleset(rs);
827
828	return (0);
829}
830
831#define	PF_SET_SKIP_STEPS(i)					\
832	do {							\
833		while (head[i] != cur) {			\
834			head[i]->skip[i].ptr = cur;		\
835			head[i] = TAILQ_NEXT(head[i], entries);	\
836		}						\
837	} while (0)
838
839static void
840pf_eth_calc_skip_steps(struct pf_keth_ruleq *rules)
841{
842	struct pf_keth_rule *cur, *prev, *head[PFE_SKIP_COUNT];
843	int i;
844
845	cur = TAILQ_FIRST(rules);
846	prev = cur;
847	for (i = 0; i < PFE_SKIP_COUNT; ++i)
848		head[i] = cur;
849	while (cur != NULL) {
850		if (cur->kif != prev->kif || cur->ifnot != prev->ifnot)
851			PF_SET_SKIP_STEPS(PFE_SKIP_IFP);
852		if (cur->direction != prev->direction)
853			PF_SET_SKIP_STEPS(PFE_SKIP_DIR);
854		if (cur->proto != prev->proto)
855			PF_SET_SKIP_STEPS(PFE_SKIP_PROTO);
856		if (memcmp(&cur->src, &prev->src, sizeof(cur->src)) != 0)
857			PF_SET_SKIP_STEPS(PFE_SKIP_SRC_ADDR);
858		if (memcmp(&cur->dst, &prev->dst, sizeof(cur->dst)) != 0)
859			PF_SET_SKIP_STEPS(PFE_SKIP_DST_ADDR);
860		if (cur->ipsrc.neg != prev->ipsrc.neg ||
861		    pf_addr_wrap_neq(&cur->ipsrc.addr, &prev->ipsrc.addr))
862			PF_SET_SKIP_STEPS(PFE_SKIP_SRC_IP_ADDR);
863		if (cur->ipdst.neg != prev->ipdst.neg ||
864		    pf_addr_wrap_neq(&cur->ipdst.addr, &prev->ipdst.addr))
865			PF_SET_SKIP_STEPS(PFE_SKIP_DST_IP_ADDR);
866
867		prev = cur;
868		cur = TAILQ_NEXT(cur, entries);
869	}
870	for (i = 0; i < PFE_SKIP_COUNT; ++i)
871		PF_SET_SKIP_STEPS(i);
872}
873
874static int
875pf_commit_eth(uint32_t ticket, const char *anchor)
876{
877	struct pf_keth_ruleq *rules;
878	struct pf_keth_ruleset *rs;
879
880	rs = pf_find_keth_ruleset(anchor);
881	if (rs == NULL) {
882		return (EINVAL);
883	}
884
885	if (!rs->inactive.open ||
886	    ticket != rs->inactive.ticket)
887		return (EBUSY);
888
889	PF_RULES_WASSERT();
890
891	pf_eth_calc_skip_steps(rs->inactive.rules);
892
893	rules = rs->active.rules;
894	ck_pr_store_ptr(&rs->active.rules, rs->inactive.rules);
895	rs->inactive.rules = rules;
896	rs->inactive.ticket = rs->active.ticket;
897
898	/* Clean up inactive rules (i.e. previously active rules), only when
899	 * we're sure they're no longer used. */
900	NET_EPOCH_CALL(pf_rollback_eth_cb, &rs->epoch_ctx);
901
902	return (0);
903}
904
905#ifdef ALTQ
906static uint16_t
907pf_qname2qid(const char *qname)
908{
909	return (tagname2tag(&V_pf_qids, qname));
910}
911
912static void
913pf_qid_unref(uint16_t qid)
914{
915	tag_unref(&V_pf_qids, qid);
916}
917
918static int
919pf_begin_altq(u_int32_t *ticket)
920{
921	struct pf_altq	*altq, *tmp;
922	int		 error = 0;
923
924	PF_RULES_WASSERT();
925
926	/* Purge the old altq lists */
927	TAILQ_FOREACH_SAFE(altq, V_pf_altq_ifs_inactive, entries, tmp) {
928		if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
929			/* detach and destroy the discipline */
930			error = altq_remove(altq);
931		}
932		free(altq, M_PFALTQ);
933	}
934	TAILQ_INIT(V_pf_altq_ifs_inactive);
935	TAILQ_FOREACH_SAFE(altq, V_pf_altqs_inactive, entries, tmp) {
936		pf_qid_unref(altq->qid);
937		free(altq, M_PFALTQ);
938	}
939	TAILQ_INIT(V_pf_altqs_inactive);
940	if (error)
941		return (error);
942	*ticket = ++V_ticket_altqs_inactive;
943	V_altqs_inactive_open = 1;
944	return (0);
945}
946
947static int
948pf_rollback_altq(u_int32_t ticket)
949{
950	struct pf_altq	*altq, *tmp;
951	int		 error = 0;
952
953	PF_RULES_WASSERT();
954
955	if (!V_altqs_inactive_open || ticket != V_ticket_altqs_inactive)
956		return (0);
957	/* Purge the old altq lists */
958	TAILQ_FOREACH_SAFE(altq, V_pf_altq_ifs_inactive, entries, tmp) {
959		if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
960			/* detach and destroy the discipline */
961			error = altq_remove(altq);
962		}
963		free(altq, M_PFALTQ);
964	}
965	TAILQ_INIT(V_pf_altq_ifs_inactive);
966	TAILQ_FOREACH_SAFE(altq, V_pf_altqs_inactive, entries, tmp) {
967		pf_qid_unref(altq->qid);
968		free(altq, M_PFALTQ);
969	}
970	TAILQ_INIT(V_pf_altqs_inactive);
971	V_altqs_inactive_open = 0;
972	return (error);
973}
974
975static int
976pf_commit_altq(u_int32_t ticket)
977{
978	struct pf_altqqueue	*old_altqs, *old_altq_ifs;
979	struct pf_altq		*altq, *tmp;
980	int			 err, error = 0;
981
982	PF_RULES_WASSERT();
983
984	if (!V_altqs_inactive_open || ticket != V_ticket_altqs_inactive)
985		return (EBUSY);
986
987	/* swap altqs, keep the old. */
988	old_altqs = V_pf_altqs_active;
989	old_altq_ifs = V_pf_altq_ifs_active;
990	V_pf_altqs_active = V_pf_altqs_inactive;
991	V_pf_altq_ifs_active = V_pf_altq_ifs_inactive;
992	V_pf_altqs_inactive = old_altqs;
993	V_pf_altq_ifs_inactive = old_altq_ifs;
994	V_ticket_altqs_active = V_ticket_altqs_inactive;
995
996	/* Attach new disciplines */
997	TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) {
998		if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
999			/* attach the discipline */
1000			error = altq_pfattach(altq);
1001			if (error == 0 && V_pf_altq_running)
1002				error = pf_enable_altq(altq);
1003			if (error != 0)
1004				return (error);
1005		}
1006	}
1007
1008	/* Purge the old altq lists */
1009	TAILQ_FOREACH_SAFE(altq, V_pf_altq_ifs_inactive, entries, tmp) {
1010		if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
1011			/* detach and destroy the discipline */
1012			if (V_pf_altq_running)
1013				error = pf_disable_altq(altq);
1014			err = altq_pfdetach(altq);
1015			if (err != 0 && error == 0)
1016				error = err;
1017			err = altq_remove(altq);
1018			if (err != 0 && error == 0)
1019				error = err;
1020		}
1021		free(altq, M_PFALTQ);
1022	}
1023	TAILQ_INIT(V_pf_altq_ifs_inactive);
1024	TAILQ_FOREACH_SAFE(altq, V_pf_altqs_inactive, entries, tmp) {
1025		pf_qid_unref(altq->qid);
1026		free(altq, M_PFALTQ);
1027	}
1028	TAILQ_INIT(V_pf_altqs_inactive);
1029
1030	V_altqs_inactive_open = 0;
1031	return (error);
1032}
1033
1034static int
1035pf_enable_altq(struct pf_altq *altq)
1036{
1037	struct ifnet		*ifp;
1038	struct tb_profile	 tb;
1039	int			 error = 0;
1040
1041	if ((ifp = ifunit(altq->ifname)) == NULL)
1042		return (EINVAL);
1043
1044	if (ifp->if_snd.altq_type != ALTQT_NONE)
1045		error = altq_enable(&ifp->if_snd);
1046
1047	/* set tokenbucket regulator */
1048	if (error == 0 && ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
1049		tb.rate = altq->ifbandwidth;
1050		tb.depth = altq->tbrsize;
1051		error = tbr_set(&ifp->if_snd, &tb);
1052	}
1053
1054	return (error);
1055}
1056
1057static int
1058pf_disable_altq(struct pf_altq *altq)
1059{
1060	struct ifnet		*ifp;
1061	struct tb_profile	 tb;
1062	int			 error;
1063
1064	if ((ifp = ifunit(altq->ifname)) == NULL)
1065		return (EINVAL);
1066
1067	/*
1068	 * when the discipline is no longer referenced, it was overridden
1069	 * by a new one.  if so, just return.
1070	 */
1071	if (altq->altq_disc != ifp->if_snd.altq_disc)
1072		return (0);
1073
1074	error = altq_disable(&ifp->if_snd);
1075
1076	if (error == 0) {
1077		/* clear tokenbucket regulator */
1078		tb.rate = 0;
1079		error = tbr_set(&ifp->if_snd, &tb);
1080	}
1081
1082	return (error);
1083}
1084
1085static int
1086pf_altq_ifnet_event_add(struct ifnet *ifp, int remove, u_int32_t ticket,
1087    struct pf_altq *altq)
1088{
1089	struct ifnet	*ifp1;
1090	int		 error = 0;
1091
1092	/* Deactivate the interface in question */
1093	altq->local_flags &= ~PFALTQ_FLAG_IF_REMOVED;
1094	if ((ifp1 = ifunit(altq->ifname)) == NULL ||
1095	    (remove && ifp1 == ifp)) {
1096		altq->local_flags |= PFALTQ_FLAG_IF_REMOVED;
1097	} else {
1098		error = altq_add(ifp1, altq);
1099
1100		if (ticket != V_ticket_altqs_inactive)
1101			error = EBUSY;
1102
1103		if (error)
1104			free(altq, M_PFALTQ);
1105	}
1106
1107	return (error);
1108}
1109
1110void
1111pf_altq_ifnet_event(struct ifnet *ifp, int remove)
1112{
1113	struct pf_altq	*a1, *a2, *a3;
1114	u_int32_t	 ticket;
1115	int		 error = 0;
1116
1117	/*
1118	 * No need to re-evaluate the configuration for events on interfaces
1119	 * that do not support ALTQ, as it's not possible for such
1120	 * interfaces to be part of the configuration.
1121	 */
1122	if (!ALTQ_IS_READY(&ifp->if_snd))
1123		return;
1124
1125	/* Interrupt userland queue modifications */
1126	if (V_altqs_inactive_open)
1127		pf_rollback_altq(V_ticket_altqs_inactive);
1128
1129	/* Start new altq ruleset */
1130	if (pf_begin_altq(&ticket))
1131		return;
1132
1133	/* Copy the current active set */
1134	TAILQ_FOREACH(a1, V_pf_altq_ifs_active, entries) {
1135		a2 = malloc(sizeof(*a2), M_PFALTQ, M_NOWAIT);
1136		if (a2 == NULL) {
1137			error = ENOMEM;
1138			break;
1139		}
1140		bcopy(a1, a2, sizeof(struct pf_altq));
1141
1142		error = pf_altq_ifnet_event_add(ifp, remove, ticket, a2);
1143		if (error)
1144			break;
1145
1146		TAILQ_INSERT_TAIL(V_pf_altq_ifs_inactive, a2, entries);
1147	}
1148	if (error)
1149		goto out;
1150	TAILQ_FOREACH(a1, V_pf_altqs_active, entries) {
1151		a2 = malloc(sizeof(*a2), M_PFALTQ, M_NOWAIT);
1152		if (a2 == NULL) {
1153			error = ENOMEM;
1154			break;
1155		}
1156		bcopy(a1, a2, sizeof(struct pf_altq));
1157
1158		if ((a2->qid = pf_qname2qid(a2->qname)) == 0) {
1159			error = EBUSY;
1160			free(a2, M_PFALTQ);
1161			break;
1162		}
1163		a2->altq_disc = NULL;
1164		TAILQ_FOREACH(a3, V_pf_altq_ifs_inactive, entries) {
1165			if (strncmp(a3->ifname, a2->ifname,
1166				IFNAMSIZ) == 0) {
1167				a2->altq_disc = a3->altq_disc;
1168				break;
1169			}
1170		}
1171		error = pf_altq_ifnet_event_add(ifp, remove, ticket, a2);
1172		if (error)
1173			break;
1174
1175		TAILQ_INSERT_TAIL(V_pf_altqs_inactive, a2, entries);
1176	}
1177
1178out:
1179	if (error != 0)
1180		pf_rollback_altq(ticket);
1181	else
1182		pf_commit_altq(ticket);
1183}
1184#endif /* ALTQ */
1185
1186static struct pf_krule_global *
1187pf_rule_tree_alloc(int flags)
1188{
1189	struct pf_krule_global *tree;
1190
1191	tree = malloc(sizeof(struct pf_krule_global), M_TEMP, flags);
1192	if (tree == NULL)
1193		return (NULL);
1194	RB_INIT(tree);
1195	return (tree);
1196}
1197
1198static void
1199pf_rule_tree_free(struct pf_krule_global *tree)
1200{
1201
1202	free(tree, M_TEMP);
1203}
1204
1205static int
1206pf_begin_rules(u_int32_t *ticket, int rs_num, const char *anchor)
1207{
1208	struct pf_krule_global *tree;
1209	struct pf_kruleset	*rs;
1210	struct pf_krule		*rule;
1211
1212	PF_RULES_WASSERT();
1213
1214	if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
1215		return (EINVAL);
1216	tree = pf_rule_tree_alloc(M_NOWAIT);
1217	if (tree == NULL)
1218		return (ENOMEM);
1219	rs = pf_find_or_create_kruleset(anchor);
1220	if (rs == NULL) {
1221		free(tree, M_TEMP);
1222		return (EINVAL);
1223	}
1224	pf_rule_tree_free(rs->rules[rs_num].inactive.tree);
1225	rs->rules[rs_num].inactive.tree = tree;
1226
1227	while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL) {
1228		pf_unlink_rule(rs->rules[rs_num].inactive.ptr, rule);
1229		rs->rules[rs_num].inactive.rcount--;
1230	}
1231	*ticket = ++rs->rules[rs_num].inactive.ticket;
1232	rs->rules[rs_num].inactive.open = 1;
1233	return (0);
1234}
1235
1236static int
1237pf_rollback_rules(u_int32_t ticket, int rs_num, char *anchor)
1238{
1239	struct pf_kruleset	*rs;
1240	struct pf_krule		*rule;
1241
1242	PF_RULES_WASSERT();
1243
1244	if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
1245		return (EINVAL);
1246	rs = pf_find_kruleset(anchor);
1247	if (rs == NULL || !rs->rules[rs_num].inactive.open ||
1248	    rs->rules[rs_num].inactive.ticket != ticket)
1249		return (0);
1250	while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL) {
1251		pf_unlink_rule(rs->rules[rs_num].inactive.ptr, rule);
1252		rs->rules[rs_num].inactive.rcount--;
1253	}
1254	rs->rules[rs_num].inactive.open = 0;
1255	return (0);
1256}
1257
1258#define PF_MD5_UPD(st, elm)						\
1259		MD5Update(ctx, (u_int8_t *) &(st)->elm, sizeof((st)->elm))
1260
1261#define PF_MD5_UPD_STR(st, elm)						\
1262		MD5Update(ctx, (u_int8_t *) (st)->elm, strlen((st)->elm))
1263
1264#define PF_MD5_UPD_HTONL(st, elm, stor) do {				\
1265		(stor) = htonl((st)->elm);				\
1266		MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int32_t));\
1267} while (0)
1268
1269#define PF_MD5_UPD_HTONS(st, elm, stor) do {				\
1270		(stor) = htons((st)->elm);				\
1271		MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int16_t));\
1272} while (0)
1273
1274static void
1275pf_hash_rule_addr(MD5_CTX *ctx, struct pf_rule_addr *pfr)
1276{
1277	PF_MD5_UPD(pfr, addr.type);
1278	switch (pfr->addr.type) {
1279		case PF_ADDR_DYNIFTL:
1280			PF_MD5_UPD(pfr, addr.v.ifname);
1281			PF_MD5_UPD(pfr, addr.iflags);
1282			break;
1283		case PF_ADDR_TABLE:
1284			PF_MD5_UPD(pfr, addr.v.tblname);
1285			break;
1286		case PF_ADDR_ADDRMASK:
1287			/* XXX ignore af? */
1288			PF_MD5_UPD(pfr, addr.v.a.addr.addr32);
1289			PF_MD5_UPD(pfr, addr.v.a.mask.addr32);
1290			break;
1291	}
1292
1293	PF_MD5_UPD(pfr, port[0]);
1294	PF_MD5_UPD(pfr, port[1]);
1295	PF_MD5_UPD(pfr, neg);
1296	PF_MD5_UPD(pfr, port_op);
1297}
1298
1299static void
1300pf_hash_rule_rolling(MD5_CTX *ctx, struct pf_krule *rule)
1301{
1302	u_int16_t x;
1303	u_int32_t y;
1304
1305	pf_hash_rule_addr(ctx, &rule->src);
1306	pf_hash_rule_addr(ctx, &rule->dst);
1307	for (int i = 0; i < PF_RULE_MAX_LABEL_COUNT; i++)
1308		PF_MD5_UPD_STR(rule, label[i]);
1309	PF_MD5_UPD_STR(rule, ifname);
1310	PF_MD5_UPD_STR(rule, match_tagname);
1311	PF_MD5_UPD_HTONS(rule, match_tag, x); /* dup? */
1312	PF_MD5_UPD_HTONL(rule, os_fingerprint, y);
1313	PF_MD5_UPD_HTONL(rule, prob, y);
1314	PF_MD5_UPD_HTONL(rule, uid.uid[0], y);
1315	PF_MD5_UPD_HTONL(rule, uid.uid[1], y);
1316	PF_MD5_UPD(rule, uid.op);
1317	PF_MD5_UPD_HTONL(rule, gid.gid[0], y);
1318	PF_MD5_UPD_HTONL(rule, gid.gid[1], y);
1319	PF_MD5_UPD(rule, gid.op);
1320	PF_MD5_UPD_HTONL(rule, rule_flag, y);
1321	PF_MD5_UPD(rule, action);
1322	PF_MD5_UPD(rule, direction);
1323	PF_MD5_UPD(rule, af);
1324	PF_MD5_UPD(rule, quick);
1325	PF_MD5_UPD(rule, ifnot);
1326	PF_MD5_UPD(rule, match_tag_not);
1327	PF_MD5_UPD(rule, natpass);
1328	PF_MD5_UPD(rule, keep_state);
1329	PF_MD5_UPD(rule, proto);
1330	PF_MD5_UPD(rule, type);
1331	PF_MD5_UPD(rule, code);
1332	PF_MD5_UPD(rule, flags);
1333	PF_MD5_UPD(rule, flagset);
1334	PF_MD5_UPD(rule, allow_opts);
1335	PF_MD5_UPD(rule, rt);
1336	PF_MD5_UPD(rule, tos);
1337	PF_MD5_UPD(rule, scrub_flags);
1338	PF_MD5_UPD(rule, min_ttl);
1339	PF_MD5_UPD(rule, set_tos);
1340	if (rule->anchor != NULL)
1341		PF_MD5_UPD_STR(rule, anchor->path);
1342}
1343
1344static void
1345pf_hash_rule(struct pf_krule *rule)
1346{
1347	MD5_CTX		ctx;
1348
1349	MD5Init(&ctx);
1350	pf_hash_rule_rolling(&ctx, rule);
1351	MD5Final(rule->md5sum, &ctx);
1352}
1353
1354static int
1355pf_krule_compare(struct pf_krule *a, struct pf_krule *b)
1356{
1357
1358	return (memcmp(a->md5sum, b->md5sum, PF_MD5_DIGEST_LENGTH));
1359}
1360
1361static int
1362pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
1363{
1364	struct pf_kruleset	*rs;
1365	struct pf_krule		*rule, **old_array, *old_rule;
1366	struct pf_krulequeue	*old_rules;
1367	struct pf_krule_global  *old_tree;
1368	int			 error;
1369	u_int32_t		 old_rcount;
1370
1371	PF_RULES_WASSERT();
1372
1373	if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
1374		return (EINVAL);
1375	rs = pf_find_kruleset(anchor);
1376	if (rs == NULL || !rs->rules[rs_num].inactive.open ||
1377	    ticket != rs->rules[rs_num].inactive.ticket)
1378		return (EBUSY);
1379
1380	/* Calculate checksum for the main ruleset */
1381	if (rs == &pf_main_ruleset) {
1382		error = pf_setup_pfsync_matching(rs);
1383		if (error != 0)
1384			return (error);
1385	}
1386
1387	/* Swap rules, keep the old. */
1388	old_rules = rs->rules[rs_num].active.ptr;
1389	old_rcount = rs->rules[rs_num].active.rcount;
1390	old_array = rs->rules[rs_num].active.ptr_array;
1391	old_tree = rs->rules[rs_num].active.tree;
1392
1393	rs->rules[rs_num].active.ptr =
1394	    rs->rules[rs_num].inactive.ptr;
1395	rs->rules[rs_num].active.ptr_array =
1396	    rs->rules[rs_num].inactive.ptr_array;
1397	rs->rules[rs_num].active.tree =
1398	    rs->rules[rs_num].inactive.tree;
1399	rs->rules[rs_num].active.rcount =
1400	    rs->rules[rs_num].inactive.rcount;
1401
1402	/* Attempt to preserve counter information. */
1403	if (V_pf_status.keep_counters && old_tree != NULL) {
1404		TAILQ_FOREACH(rule, rs->rules[rs_num].active.ptr,
1405		    entries) {
1406			old_rule = RB_FIND(pf_krule_global, old_tree, rule);
1407			if (old_rule == NULL) {
1408				continue;
1409			}
1410			pf_counter_u64_critical_enter();
1411			pf_counter_u64_add_protected(&rule->evaluations,
1412			    pf_counter_u64_fetch(&old_rule->evaluations));
1413			pf_counter_u64_add_protected(&rule->packets[0],
1414			    pf_counter_u64_fetch(&old_rule->packets[0]));
1415			pf_counter_u64_add_protected(&rule->packets[1],
1416			    pf_counter_u64_fetch(&old_rule->packets[1]));
1417			pf_counter_u64_add_protected(&rule->bytes[0],
1418			    pf_counter_u64_fetch(&old_rule->bytes[0]));
1419			pf_counter_u64_add_protected(&rule->bytes[1],
1420			    pf_counter_u64_fetch(&old_rule->bytes[1]));
1421			pf_counter_u64_critical_exit();
1422		}
1423	}
1424
1425	rs->rules[rs_num].inactive.ptr = old_rules;
1426	rs->rules[rs_num].inactive.ptr_array = old_array;
1427	rs->rules[rs_num].inactive.tree = NULL; /* important for pf_ioctl_addrule */
1428	rs->rules[rs_num].inactive.rcount = old_rcount;
1429
1430	rs->rules[rs_num].active.ticket =
1431	    rs->rules[rs_num].inactive.ticket;
1432	pf_calc_skip_steps(rs->rules[rs_num].active.ptr);
1433
1434	/* Purge the old rule list. */
1435	PF_UNLNKDRULES_LOCK();
1436	while ((rule = TAILQ_FIRST(old_rules)) != NULL)
1437		pf_unlink_rule_locked(old_rules, rule);
1438	PF_UNLNKDRULES_UNLOCK();
1439	if (rs->rules[rs_num].inactive.ptr_array)
1440		free(rs->rules[rs_num].inactive.ptr_array, M_TEMP);
1441	rs->rules[rs_num].inactive.ptr_array = NULL;
1442	rs->rules[rs_num].inactive.rcount = 0;
1443	rs->rules[rs_num].inactive.open = 0;
1444	pf_remove_if_empty_kruleset(rs);
1445	free(old_tree, M_TEMP);
1446
1447	return (0);
1448}
1449
1450static int
1451pf_setup_pfsync_matching(struct pf_kruleset *rs)
1452{
1453	MD5_CTX			 ctx;
1454	struct pf_krule		*rule;
1455	int			 rs_cnt;
1456	u_int8_t		 digest[PF_MD5_DIGEST_LENGTH];
1457
1458	MD5Init(&ctx);
1459	for (rs_cnt = 0; rs_cnt < PF_RULESET_MAX; rs_cnt++) {
1460		/* XXX PF_RULESET_SCRUB as well? */
1461		if (rs_cnt == PF_RULESET_SCRUB)
1462			continue;
1463
1464		if (rs->rules[rs_cnt].inactive.ptr_array)
1465			free(rs->rules[rs_cnt].inactive.ptr_array, M_TEMP);
1466		rs->rules[rs_cnt].inactive.ptr_array = NULL;
1467
1468		if (rs->rules[rs_cnt].inactive.rcount) {
1469			rs->rules[rs_cnt].inactive.ptr_array =
1470			    mallocarray(rs->rules[rs_cnt].inactive.rcount,
1471			    sizeof(struct pf_rule **),
1472			    M_TEMP, M_NOWAIT);
1473
1474			if (!rs->rules[rs_cnt].inactive.ptr_array)
1475				return (ENOMEM);
1476		}
1477
1478		TAILQ_FOREACH(rule, rs->rules[rs_cnt].inactive.ptr,
1479		    entries) {
1480			pf_hash_rule_rolling(&ctx, rule);
1481			(rs->rules[rs_cnt].inactive.ptr_array)[rule->nr] = rule;
1482		}
1483	}
1484
1485	MD5Final(digest, &ctx);
1486	memcpy(V_pf_status.pf_chksum, digest, sizeof(V_pf_status.pf_chksum));
1487	return (0);
1488}
1489
1490static int
1491pf_eth_addr_setup(struct pf_keth_ruleset *ruleset, struct pf_addr_wrap *addr)
1492{
1493	int error = 0;
1494
1495	switch (addr->type) {
1496	case PF_ADDR_TABLE:
1497		addr->p.tbl = pfr_eth_attach_table(ruleset, addr->v.tblname);
1498		if (addr->p.tbl == NULL)
1499			error = ENOMEM;
1500		break;
1501	default:
1502		error = EINVAL;
1503	}
1504
1505	return (error);
1506}
1507
1508static int
1509pf_addr_setup(struct pf_kruleset *ruleset, struct pf_addr_wrap *addr,
1510    sa_family_t af)
1511{
1512	int error = 0;
1513
1514	switch (addr->type) {
1515	case PF_ADDR_TABLE:
1516		addr->p.tbl = pfr_attach_table(ruleset, addr->v.tblname);
1517		if (addr->p.tbl == NULL)
1518			error = ENOMEM;
1519		break;
1520	case PF_ADDR_DYNIFTL:
1521		error = pfi_dynaddr_setup(addr, af);
1522		break;
1523	}
1524
1525	return (error);
1526}
1527
1528static void
1529pf_addr_copyout(struct pf_addr_wrap *addr)
1530{
1531
1532	switch (addr->type) {
1533	case PF_ADDR_DYNIFTL:
1534		pfi_dynaddr_copyout(addr);
1535		break;
1536	case PF_ADDR_TABLE:
1537		pf_tbladdr_copyout(addr);
1538		break;
1539	}
1540}
1541
1542static void
1543pf_src_node_copy(const struct pf_ksrc_node *in, struct pf_src_node *out)
1544{
1545	int	secs = time_uptime, diff;
1546
1547	bzero(out, sizeof(struct pf_src_node));
1548
1549	bcopy(&in->addr, &out->addr, sizeof(struct pf_addr));
1550	bcopy(&in->raddr, &out->raddr, sizeof(struct pf_addr));
1551
1552	if (in->rule.ptr != NULL)
1553		out->rule.nr = in->rule.ptr->nr;
1554
1555	for (int i = 0; i < 2; i++) {
1556		out->bytes[i] = counter_u64_fetch(in->bytes[i]);
1557		out->packets[i] = counter_u64_fetch(in->packets[i]);
1558	}
1559
1560	out->states = in->states;
1561	out->conn = in->conn;
1562	out->af = in->af;
1563	out->ruletype = in->ruletype;
1564
1565	out->creation = secs - in->creation;
1566	if (out->expire > secs)
1567		out->expire -= secs;
1568	else
1569		out->expire = 0;
1570
1571	/* Adjust the connection rate estimate. */
1572	diff = secs - in->conn_rate.last;
1573	if (diff >= in->conn_rate.seconds)
1574		out->conn_rate.count = 0;
1575	else
1576		out->conn_rate.count -=
1577		    in->conn_rate.count * diff /
1578		    in->conn_rate.seconds;
1579}
1580
1581#ifdef ALTQ
1582/*
1583 * Handle export of struct pf_kaltq to user binaries that may be using any
1584 * version of struct pf_altq.
1585 */
1586static int
1587pf_export_kaltq(struct pf_altq *q, struct pfioc_altq_v1 *pa, size_t ioc_size)
1588{
1589	u_int32_t version;
1590
1591	if (ioc_size == sizeof(struct pfioc_altq_v0))
1592		version = 0;
1593	else
1594		version = pa->version;
1595
1596	if (version > PFIOC_ALTQ_VERSION)
1597		return (EINVAL);
1598
1599#define ASSIGN(x) exported_q->x = q->x
1600#define COPY(x) \
1601	bcopy(&q->x, &exported_q->x, min(sizeof(q->x), sizeof(exported_q->x)))
1602#define SATU16(x) (u_int32_t)uqmin((x), USHRT_MAX)
1603#define SATU32(x) (u_int32_t)uqmin((x), UINT_MAX)
1604
1605	switch (version) {
1606	case 0: {
1607		struct pf_altq_v0 *exported_q =
1608		    &((struct pfioc_altq_v0 *)pa)->altq;
1609
1610		COPY(ifname);
1611
1612		ASSIGN(scheduler);
1613		ASSIGN(tbrsize);
1614		exported_q->tbrsize = SATU16(q->tbrsize);
1615		exported_q->ifbandwidth = SATU32(q->ifbandwidth);
1616
1617		COPY(qname);
1618		COPY(parent);
1619		ASSIGN(parent_qid);
1620		exported_q->bandwidth = SATU32(q->bandwidth);
1621		ASSIGN(priority);
1622		ASSIGN(local_flags);
1623
1624		ASSIGN(qlimit);
1625		ASSIGN(flags);
1626
1627		if (q->scheduler == ALTQT_HFSC) {
1628#define ASSIGN_OPT(x) exported_q->pq_u.hfsc_opts.x = q->pq_u.hfsc_opts.x
1629#define ASSIGN_OPT_SATU32(x) exported_q->pq_u.hfsc_opts.x = \
1630			    SATU32(q->pq_u.hfsc_opts.x)
1631
1632			ASSIGN_OPT_SATU32(rtsc_m1);
1633			ASSIGN_OPT(rtsc_d);
1634			ASSIGN_OPT_SATU32(rtsc_m2);
1635
1636			ASSIGN_OPT_SATU32(lssc_m1);
1637			ASSIGN_OPT(lssc_d);
1638			ASSIGN_OPT_SATU32(lssc_m2);
1639
1640			ASSIGN_OPT_SATU32(ulsc_m1);
1641			ASSIGN_OPT(ulsc_d);
1642			ASSIGN_OPT_SATU32(ulsc_m2);
1643
1644			ASSIGN_OPT(flags);
1645
1646#undef ASSIGN_OPT
1647#undef ASSIGN_OPT_SATU32
1648		} else
1649			COPY(pq_u);
1650
1651		ASSIGN(qid);
1652		break;
1653	}
1654	case 1:	{
1655		struct pf_altq_v1 *exported_q =
1656		    &((struct pfioc_altq_v1 *)pa)->altq;
1657
1658		COPY(ifname);
1659
1660		ASSIGN(scheduler);
1661		ASSIGN(tbrsize);
1662		ASSIGN(ifbandwidth);
1663
1664		COPY(qname);
1665		COPY(parent);
1666		ASSIGN(parent_qid);
1667		ASSIGN(bandwidth);
1668		ASSIGN(priority);
1669		ASSIGN(local_flags);
1670
1671		ASSIGN(qlimit);
1672		ASSIGN(flags);
1673		COPY(pq_u);
1674
1675		ASSIGN(qid);
1676		break;
1677	}
1678	default:
1679		panic("%s: unhandled struct pfioc_altq version", __func__);
1680		break;
1681	}
1682
1683#undef ASSIGN
1684#undef COPY
1685#undef SATU16
1686#undef SATU32
1687
1688	return (0);
1689}
1690
1691/*
1692 * Handle import to struct pf_kaltq of struct pf_altq from user binaries
1693 * that may be using any version of it.
1694 */
1695static int
1696pf_import_kaltq(struct pfioc_altq_v1 *pa, struct pf_altq *q, size_t ioc_size)
1697{
1698	u_int32_t version;
1699
1700	if (ioc_size == sizeof(struct pfioc_altq_v0))
1701		version = 0;
1702	else
1703		version = pa->version;
1704
1705	if (version > PFIOC_ALTQ_VERSION)
1706		return (EINVAL);
1707
1708#define ASSIGN(x) q->x = imported_q->x
1709#define COPY(x) \
1710	bcopy(&imported_q->x, &q->x, min(sizeof(imported_q->x), sizeof(q->x)))
1711
1712	switch (version) {
1713	case 0: {
1714		struct pf_altq_v0 *imported_q =
1715		    &((struct pfioc_altq_v0 *)pa)->altq;
1716
1717		COPY(ifname);
1718
1719		ASSIGN(scheduler);
1720		ASSIGN(tbrsize); /* 16-bit -> 32-bit */
1721		ASSIGN(ifbandwidth); /* 32-bit -> 64-bit */
1722
1723		COPY(qname);
1724		COPY(parent);
1725		ASSIGN(parent_qid);
1726		ASSIGN(bandwidth); /* 32-bit -> 64-bit */
1727		ASSIGN(priority);
1728		ASSIGN(local_flags);
1729
1730		ASSIGN(qlimit);
1731		ASSIGN(flags);
1732
1733		if (imported_q->scheduler == ALTQT_HFSC) {
1734#define ASSIGN_OPT(x) q->pq_u.hfsc_opts.x = imported_q->pq_u.hfsc_opts.x
1735
1736			/*
1737			 * The m1 and m2 parameters are being copied from
1738			 * 32-bit to 64-bit.
1739			 */
1740			ASSIGN_OPT(rtsc_m1);
1741			ASSIGN_OPT(rtsc_d);
1742			ASSIGN_OPT(rtsc_m2);
1743
1744			ASSIGN_OPT(lssc_m1);
1745			ASSIGN_OPT(lssc_d);
1746			ASSIGN_OPT(lssc_m2);
1747
1748			ASSIGN_OPT(ulsc_m1);
1749			ASSIGN_OPT(ulsc_d);
1750			ASSIGN_OPT(ulsc_m2);
1751
1752			ASSIGN_OPT(flags);
1753
1754#undef ASSIGN_OPT
1755		} else
1756			COPY(pq_u);
1757
1758		ASSIGN(qid);
1759		break;
1760	}
1761	case 1: {
1762		struct pf_altq_v1 *imported_q =
1763		    &((struct pfioc_altq_v1 *)pa)->altq;
1764
1765		COPY(ifname);
1766
1767		ASSIGN(scheduler);
1768		ASSIGN(tbrsize);
1769		ASSIGN(ifbandwidth);
1770
1771		COPY(qname);
1772		COPY(parent);
1773		ASSIGN(parent_qid);
1774		ASSIGN(bandwidth);
1775		ASSIGN(priority);
1776		ASSIGN(local_flags);
1777
1778		ASSIGN(qlimit);
1779		ASSIGN(flags);
1780		COPY(pq_u);
1781
1782		ASSIGN(qid);
1783		break;
1784	}
1785	default:
1786		panic("%s: unhandled struct pfioc_altq version", __func__);
1787		break;
1788	}
1789
1790#undef ASSIGN
1791#undef COPY
1792
1793	return (0);
1794}
1795
1796static struct pf_altq *
1797pf_altq_get_nth_active(u_int32_t n)
1798{
1799	struct pf_altq		*altq;
1800	u_int32_t		 nr;
1801
1802	nr = 0;
1803	TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) {
1804		if (nr == n)
1805			return (altq);
1806		nr++;
1807	}
1808
1809	TAILQ_FOREACH(altq, V_pf_altqs_active, entries) {
1810		if (nr == n)
1811			return (altq);
1812		nr++;
1813	}
1814
1815	return (NULL);
1816}
1817#endif /* ALTQ */
1818
1819struct pf_krule *
1820pf_krule_alloc(void)
1821{
1822	struct pf_krule *rule;
1823
1824	rule = malloc(sizeof(struct pf_krule), M_PFRULE, M_WAITOK | M_ZERO);
1825	mtx_init(&rule->rpool.mtx, "pf_krule_pool", NULL, MTX_DEF);
1826	rule->timestamp = uma_zalloc_pcpu(pf_timestamp_pcpu_zone,
1827	    M_WAITOK | M_ZERO);
1828	return (rule);
1829}
1830
1831void
1832pf_krule_free(struct pf_krule *rule)
1833{
1834#ifdef PF_WANT_32_TO_64_COUNTER
1835	bool wowned;
1836#endif
1837
1838	if (rule == NULL)
1839		return;
1840
1841#ifdef PF_WANT_32_TO_64_COUNTER
1842	if (rule->allrulelinked) {
1843		wowned = PF_RULES_WOWNED();
1844		if (!wowned)
1845			PF_RULES_WLOCK();
1846		LIST_REMOVE(rule, allrulelist);
1847		V_pf_allrulecount--;
1848		if (!wowned)
1849			PF_RULES_WUNLOCK();
1850	}
1851#endif
1852
1853	pf_counter_u64_deinit(&rule->evaluations);
1854	for (int i = 0; i < 2; i++) {
1855		pf_counter_u64_deinit(&rule->packets[i]);
1856		pf_counter_u64_deinit(&rule->bytes[i]);
1857	}
1858	counter_u64_free(rule->states_cur);
1859	counter_u64_free(rule->states_tot);
1860	counter_u64_free(rule->src_nodes);
1861	uma_zfree_pcpu(pf_timestamp_pcpu_zone, rule->timestamp);
1862
1863	mtx_destroy(&rule->rpool.mtx);
1864	free(rule, M_PFRULE);
1865}
1866
1867void
1868pf_krule_clear_counters(struct pf_krule *rule)
1869{
1870	pf_counter_u64_zero(&rule->evaluations);
1871	for (int i = 0; i < 2; i++) {
1872		pf_counter_u64_zero(&rule->packets[i]);
1873		pf_counter_u64_zero(&rule->bytes[i]);
1874	}
1875	counter_u64_zero(rule->states_tot);
1876}
1877
1878static void
1879pf_kpooladdr_to_pooladdr(const struct pf_kpooladdr *kpool,
1880    struct pf_pooladdr *pool)
1881{
1882
1883	bzero(pool, sizeof(*pool));
1884	bcopy(&kpool->addr, &pool->addr, sizeof(pool->addr));
1885	strlcpy(pool->ifname, kpool->ifname, sizeof(pool->ifname));
1886}
1887
1888static int
1889pf_pooladdr_to_kpooladdr(const struct pf_pooladdr *pool,
1890    struct pf_kpooladdr *kpool)
1891{
1892	int ret;
1893
1894	bzero(kpool, sizeof(*kpool));
1895	bcopy(&pool->addr, &kpool->addr, sizeof(kpool->addr));
1896	ret = pf_user_strcpy(kpool->ifname, pool->ifname,
1897	    sizeof(kpool->ifname));
1898	return (ret);
1899}
1900
1901static void
1902pf_pool_to_kpool(const struct pf_pool *pool, struct pf_kpool *kpool)
1903{
1904	_Static_assert(sizeof(pool->key) == sizeof(kpool->key), "");
1905	_Static_assert(sizeof(pool->counter) == sizeof(kpool->counter), "");
1906
1907	bcopy(&pool->key, &kpool->key, sizeof(kpool->key));
1908	bcopy(&pool->counter, &kpool->counter, sizeof(kpool->counter));
1909
1910	kpool->tblidx = pool->tblidx;
1911	kpool->proxy_port[0] = pool->proxy_port[0];
1912	kpool->proxy_port[1] = pool->proxy_port[1];
1913	kpool->opts = pool->opts;
1914}
1915
1916static int
1917pf_rule_to_krule(const struct pf_rule *rule, struct pf_krule *krule)
1918{
1919	int ret;
1920
1921#ifndef INET
1922	if (rule->af == AF_INET) {
1923		return (EAFNOSUPPORT);
1924	}
1925#endif /* INET */
1926#ifndef INET6
1927	if (rule->af == AF_INET6) {
1928		return (EAFNOSUPPORT);
1929	}
1930#endif /* INET6 */
1931
1932	ret = pf_check_rule_addr(&rule->src);
1933	if (ret != 0)
1934		return (ret);
1935	ret = pf_check_rule_addr(&rule->dst);
1936	if (ret != 0)
1937		return (ret);
1938
1939	bcopy(&rule->src, &krule->src, sizeof(rule->src));
1940	bcopy(&rule->dst, &krule->dst, sizeof(rule->dst));
1941
1942	ret = pf_user_strcpy(krule->label[0], rule->label, sizeof(rule->label));
1943	if (ret != 0)
1944		return (ret);
1945	ret = pf_user_strcpy(krule->ifname, rule->ifname, sizeof(rule->ifname));
1946	if (ret != 0)
1947		return (ret);
1948	ret = pf_user_strcpy(krule->qname, rule->qname, sizeof(rule->qname));
1949	if (ret != 0)
1950		return (ret);
1951	ret = pf_user_strcpy(krule->pqname, rule->pqname, sizeof(rule->pqname));
1952	if (ret != 0)
1953		return (ret);
1954	ret = pf_user_strcpy(krule->tagname, rule->tagname,
1955	    sizeof(rule->tagname));
1956	if (ret != 0)
1957		return (ret);
1958	ret = pf_user_strcpy(krule->match_tagname, rule->match_tagname,
1959	    sizeof(rule->match_tagname));
1960	if (ret != 0)
1961		return (ret);
1962	ret = pf_user_strcpy(krule->overload_tblname, rule->overload_tblname,
1963	    sizeof(rule->overload_tblname));
1964	if (ret != 0)
1965		return (ret);
1966
1967	pf_pool_to_kpool(&rule->rpool, &krule->rpool);
1968
1969	/* Don't allow userspace to set evaluations, packets or bytes. */
1970	/* kif, anchor, overload_tbl are not copied over. */
1971
1972	krule->os_fingerprint = rule->os_fingerprint;
1973
1974	krule->rtableid = rule->rtableid;
1975	/* pf_rule->timeout is smaller than pf_krule->timeout */
1976	bcopy(rule->timeout, krule->timeout, sizeof(rule->timeout));
1977	krule->max_states = rule->max_states;
1978	krule->max_src_nodes = rule->max_src_nodes;
1979	krule->max_src_states = rule->max_src_states;
1980	krule->max_src_conn = rule->max_src_conn;
1981	krule->max_src_conn_rate.limit = rule->max_src_conn_rate.limit;
1982	krule->max_src_conn_rate.seconds = rule->max_src_conn_rate.seconds;
1983	krule->qid = rule->qid;
1984	krule->pqid = rule->pqid;
1985	krule->nr = rule->nr;
1986	krule->prob = rule->prob;
1987	krule->cuid = rule->cuid;
1988	krule->cpid = rule->cpid;
1989
1990	krule->return_icmp = rule->return_icmp;
1991	krule->return_icmp6 = rule->return_icmp6;
1992	krule->max_mss = rule->max_mss;
1993	krule->tag = rule->tag;
1994	krule->match_tag = rule->match_tag;
1995	krule->scrub_flags = rule->scrub_flags;
1996
1997	bcopy(&rule->uid, &krule->uid, sizeof(krule->uid));
1998	bcopy(&rule->gid, &krule->gid, sizeof(krule->gid));
1999
2000	krule->rule_flag = rule->rule_flag;
2001	krule->action = rule->action;
2002	krule->direction = rule->direction;
2003	krule->log = rule->log;
2004	krule->logif = rule->logif;
2005	krule->quick = rule->quick;
2006	krule->ifnot = rule->ifnot;
2007	krule->match_tag_not = rule->match_tag_not;
2008	krule->natpass = rule->natpass;
2009
2010	krule->keep_state = rule->keep_state;
2011	krule->af = rule->af;
2012	krule->proto = rule->proto;
2013	krule->type = rule->type;
2014	krule->code = rule->code;
2015	krule->flags = rule->flags;
2016	krule->flagset = rule->flagset;
2017	krule->min_ttl = rule->min_ttl;
2018	krule->allow_opts = rule->allow_opts;
2019	krule->rt = rule->rt;
2020	krule->return_ttl = rule->return_ttl;
2021	krule->tos = rule->tos;
2022	krule->set_tos = rule->set_tos;
2023
2024	krule->flush = rule->flush;
2025	krule->prio = rule->prio;
2026	krule->set_prio[0] = rule->set_prio[0];
2027	krule->set_prio[1] = rule->set_prio[1];
2028
2029	bcopy(&rule->divert, &krule->divert, sizeof(krule->divert));
2030
2031	return (0);
2032}
2033
2034int
2035pf_ioctl_getrules(struct pfioc_rule *pr)
2036{
2037	struct pf_kruleset	*ruleset;
2038	struct pf_krule		*tail;
2039	int			 rs_num;
2040
2041	PF_RULES_WLOCK();
2042	ruleset = pf_find_kruleset(pr->anchor);
2043	if (ruleset == NULL) {
2044		PF_RULES_WUNLOCK();
2045		return (EINVAL);
2046	}
2047	rs_num = pf_get_ruleset_number(pr->rule.action);
2048	if (rs_num >= PF_RULESET_MAX) {
2049		PF_RULES_WUNLOCK();
2050		return (EINVAL);
2051	}
2052	tail = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
2053	    pf_krulequeue);
2054	if (tail)
2055		pr->nr = tail->nr + 1;
2056	else
2057		pr->nr = 0;
2058	pr->ticket = ruleset->rules[rs_num].active.ticket;
2059	PF_RULES_WUNLOCK();
2060
2061	return (0);
2062}
2063
2064int
2065pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket,
2066    uint32_t pool_ticket, const char *anchor, const char *anchor_call,
2067    uid_t uid, pid_t pid)
2068{
2069	struct pf_kruleset	*ruleset;
2070	struct pf_krule		*tail;
2071	struct pf_kpooladdr	*pa;
2072	struct pfi_kkif		*kif = NULL;
2073	int			 rs_num;
2074	int			 error = 0;
2075
2076	if ((rule->return_icmp >> 8) > ICMP_MAXTYPE) {
2077		error = EINVAL;
2078		goto errout_unlocked;
2079	}
2080
2081#define	ERROUT(x)	ERROUT_FUNCTION(errout, x)
2082
2083	if (rule->ifname[0])
2084		kif = pf_kkif_create(M_WAITOK);
2085	pf_counter_u64_init(&rule->evaluations, M_WAITOK);
2086	for (int i = 0; i < 2; i++) {
2087		pf_counter_u64_init(&rule->packets[i], M_WAITOK);
2088		pf_counter_u64_init(&rule->bytes[i], M_WAITOK);
2089	}
2090	rule->states_cur = counter_u64_alloc(M_WAITOK);
2091	rule->states_tot = counter_u64_alloc(M_WAITOK);
2092	rule->src_nodes = counter_u64_alloc(M_WAITOK);
2093	rule->cuid = uid;
2094	rule->cpid = pid;
2095	TAILQ_INIT(&rule->rpool.list);
2096
2097	PF_CONFIG_LOCK();
2098	PF_RULES_WLOCK();
2099#ifdef PF_WANT_32_TO_64_COUNTER
2100	LIST_INSERT_HEAD(&V_pf_allrulelist, rule, allrulelist);
2101	MPASS(!rule->allrulelinked);
2102	rule->allrulelinked = true;
2103	V_pf_allrulecount++;
2104#endif
2105	ruleset = pf_find_kruleset(anchor);
2106	if (ruleset == NULL)
2107		ERROUT(EINVAL);
2108	rs_num = pf_get_ruleset_number(rule->action);
2109	if (rs_num >= PF_RULESET_MAX)
2110		ERROUT(EINVAL);
2111	if (ticket != ruleset->rules[rs_num].inactive.ticket) {
2112		DPFPRINTF(PF_DEBUG_MISC,
2113		    ("ticket: %d != [%d]%d\n", ticket, rs_num,
2114		    ruleset->rules[rs_num].inactive.ticket));
2115		ERROUT(EBUSY);
2116	}
2117	if (pool_ticket != V_ticket_pabuf) {
2118		DPFPRINTF(PF_DEBUG_MISC,
2119		    ("pool_ticket: %d != %d\n", pool_ticket,
2120		    V_ticket_pabuf));
2121		ERROUT(EBUSY);
2122	}
2123	/*
2124	 * XXXMJG hack: there is no mechanism to ensure they started the
2125	 * transaction. Ticket checked above may happen to match by accident,
2126	 * even if nobody called DIOCXBEGIN, let alone this process.
2127	 * Partially work around it by checking if the RB tree got allocated,
2128	 * see pf_begin_rules.
2129	 */
2130	if (ruleset->rules[rs_num].inactive.tree == NULL) {
2131		ERROUT(EINVAL);
2132	}
2133
2134	tail = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,
2135	    pf_krulequeue);
2136	if (tail)
2137		rule->nr = tail->nr + 1;
2138	else
2139		rule->nr = 0;
2140	if (rule->ifname[0]) {
2141		rule->kif = pfi_kkif_attach(kif, rule->ifname);
2142		kif = NULL;
2143		pfi_kkif_ref(rule->kif);
2144	} else
2145		rule->kif = NULL;
2146
2147	if (rule->rtableid > 0 && rule->rtableid >= rt_numfibs)
2148		error = EBUSY;
2149
2150#ifdef ALTQ
2151	/* set queue IDs */
2152	if (rule->qname[0] != 0) {
2153		if ((rule->qid = pf_qname2qid(rule->qname)) == 0)
2154			error = EBUSY;
2155		else if (rule->pqname[0] != 0) {
2156			if ((rule->pqid =
2157			    pf_qname2qid(rule->pqname)) == 0)
2158				error = EBUSY;
2159		} else
2160			rule->pqid = rule->qid;
2161	}
2162#endif
2163	if (rule->tagname[0])
2164		if ((rule->tag = pf_tagname2tag(rule->tagname)) == 0)
2165			error = EBUSY;
2166	if (rule->match_tagname[0])
2167		if ((rule->match_tag =
2168		    pf_tagname2tag(rule->match_tagname)) == 0)
2169			error = EBUSY;
2170	if (rule->rt && !rule->direction)
2171		error = EINVAL;
2172	if (!rule->log)
2173		rule->logif = 0;
2174	if (rule->logif >= PFLOGIFS_MAX)
2175		error = EINVAL;
2176	if (pf_addr_setup(ruleset, &rule->src.addr, rule->af))
2177		error = ENOMEM;
2178	if (pf_addr_setup(ruleset, &rule->dst.addr, rule->af))
2179		error = ENOMEM;
2180	if (pf_kanchor_setup(rule, ruleset, anchor_call))
2181		error = EINVAL;
2182	if (rule->scrub_flags & PFSTATE_SETPRIO &&
2183	    (rule->set_prio[0] > PF_PRIO_MAX ||
2184	    rule->set_prio[1] > PF_PRIO_MAX))
2185		error = EINVAL;
2186	TAILQ_FOREACH(pa, &V_pf_pabuf, entries)
2187		if (pa->addr.type == PF_ADDR_TABLE) {
2188			pa->addr.p.tbl = pfr_attach_table(ruleset,
2189			    pa->addr.v.tblname);
2190			if (pa->addr.p.tbl == NULL)
2191				error = ENOMEM;
2192		}
2193
2194	rule->overload_tbl = NULL;
2195	if (rule->overload_tblname[0]) {
2196		if ((rule->overload_tbl = pfr_attach_table(ruleset,
2197		    rule->overload_tblname)) == NULL)
2198			error = EINVAL;
2199		else
2200			rule->overload_tbl->pfrkt_flags |=
2201			    PFR_TFLAG_ACTIVE;
2202	}
2203
2204	pf_mv_kpool(&V_pf_pabuf, &rule->rpool.list);
2205	if (((((rule->action == PF_NAT) || (rule->action == PF_RDR) ||
2206	    (rule->action == PF_BINAT)) && rule->anchor == NULL) ||
2207	    (rule->rt > PF_NOPFROUTE)) &&
2208	    (TAILQ_FIRST(&rule->rpool.list) == NULL))
2209		error = EINVAL;
2210
2211	if (error) {
2212		pf_free_rule(rule);
2213		rule = NULL;
2214		ERROUT(error);
2215	}
2216
2217	rule->rpool.cur = TAILQ_FIRST(&rule->rpool.list);
2218	TAILQ_INSERT_TAIL(ruleset->rules[rs_num].inactive.ptr,
2219	    rule, entries);
2220	ruleset->rules[rs_num].inactive.rcount++;
2221
2222	PF_RULES_WUNLOCK();
2223	pf_hash_rule(rule);
2224	if (RB_INSERT(pf_krule_global, ruleset->rules[rs_num].inactive.tree, rule) != NULL) {
2225		PF_RULES_WLOCK();
2226		TAILQ_REMOVE(ruleset->rules[rs_num].inactive.ptr, rule, entries);
2227		ruleset->rules[rs_num].inactive.rcount--;
2228		pf_free_rule(rule);
2229		rule = NULL;
2230		ERROUT(EEXIST);
2231	}
2232	PF_CONFIG_UNLOCK();
2233
2234	return (0);
2235
2236#undef ERROUT
2237errout:
2238	PF_RULES_WUNLOCK();
2239	PF_CONFIG_UNLOCK();
2240errout_unlocked:
2241	pf_kkif_free(kif);
2242	pf_krule_free(rule);
2243	return (error);
2244}
2245
2246static bool
2247pf_label_match(const struct pf_krule *rule, const char *label)
2248{
2249	int i = 0;
2250
2251	while (*rule->label[i]) {
2252		if (strcmp(rule->label[i], label) == 0)
2253			return (true);
2254		i++;
2255	}
2256
2257	return (false);
2258}
2259
2260static unsigned int
2261pf_kill_matching_state(struct pf_state_key_cmp *key, int dir)
2262{
2263	struct pf_kstate *s;
2264	int more = 0;
2265
2266	s = pf_find_state_all(key, dir, &more);
2267	if (s == NULL)
2268		return (0);
2269
2270	if (more) {
2271		PF_STATE_UNLOCK(s);
2272		return (0);
2273	}
2274
2275	pf_unlink_state(s);
2276	return (1);
2277}
2278
2279static int
2280pf_killstates_row(struct pf_kstate_kill *psk, struct pf_idhash *ih)
2281{
2282	struct pf_kstate	*s;
2283	struct pf_state_key	*sk;
2284	struct pf_addr		*srcaddr, *dstaddr;
2285	struct pf_state_key_cmp	 match_key;
2286	int			 idx, killed = 0;
2287	unsigned int		 dir;
2288	u_int16_t		 srcport, dstport;
2289	struct pfi_kkif		*kif;
2290
2291relock_DIOCKILLSTATES:
2292	PF_HASHROW_LOCK(ih);
2293	LIST_FOREACH(s, &ih->states, entry) {
2294		/* For floating states look at the original kif. */
2295		kif = s->kif == V_pfi_all ? s->orig_kif : s->kif;
2296
2297		sk = s->key[psk->psk_nat ? PF_SK_STACK : PF_SK_WIRE];
2298		if (s->direction == PF_OUT) {
2299			srcaddr = &sk->addr[1];
2300			dstaddr = &sk->addr[0];
2301			srcport = sk->port[1];
2302			dstport = sk->port[0];
2303		} else {
2304			srcaddr = &sk->addr[0];
2305			dstaddr = &sk->addr[1];
2306			srcport = sk->port[0];
2307			dstport = sk->port[1];
2308		}
2309
2310		if (psk->psk_af && sk->af != psk->psk_af)
2311			continue;
2312
2313		if (psk->psk_proto && psk->psk_proto != sk->proto)
2314			continue;
2315
2316		if (! PF_MATCHA(psk->psk_src.neg, &psk->psk_src.addr.v.a.addr,
2317		    &psk->psk_src.addr.v.a.mask, srcaddr, sk->af))
2318			continue;
2319
2320		if (! PF_MATCHA(psk->psk_dst.neg, &psk->psk_dst.addr.v.a.addr,
2321		    &psk->psk_dst.addr.v.a.mask, dstaddr, sk->af))
2322			continue;
2323
2324		if (!  PF_MATCHA(psk->psk_rt_addr.neg,
2325		    &psk->psk_rt_addr.addr.v.a.addr,
2326		    &psk->psk_rt_addr.addr.v.a.mask,
2327		    &s->rt_addr, sk->af))
2328			continue;
2329
2330		if (psk->psk_src.port_op != 0 &&
2331		    ! pf_match_port(psk->psk_src.port_op,
2332		    psk->psk_src.port[0], psk->psk_src.port[1], srcport))
2333			continue;
2334
2335		if (psk->psk_dst.port_op != 0 &&
2336		    ! pf_match_port(psk->psk_dst.port_op,
2337		    psk->psk_dst.port[0], psk->psk_dst.port[1], dstport))
2338			continue;
2339
2340		if (psk->psk_label[0] &&
2341		    ! pf_label_match(s->rule.ptr, psk->psk_label))
2342			continue;
2343
2344		if (psk->psk_ifname[0] && strcmp(psk->psk_ifname,
2345		    kif->pfik_name))
2346			continue;
2347
2348		if (psk->psk_kill_match) {
2349			/* Create the key to find matching states, with lock
2350			 * held. */
2351
2352			bzero(&match_key, sizeof(match_key));
2353
2354			if (s->direction == PF_OUT) {
2355				dir = PF_IN;
2356				idx = psk->psk_nat ? PF_SK_WIRE : PF_SK_STACK;
2357			} else {
2358				dir = PF_OUT;
2359				idx = psk->psk_nat ? PF_SK_STACK : PF_SK_WIRE;
2360			}
2361
2362			match_key.af = s->key[idx]->af;
2363			match_key.proto = s->key[idx]->proto;
2364			PF_ACPY(&match_key.addr[0],
2365			    &s->key[idx]->addr[1], match_key.af);
2366			match_key.port[0] = s->key[idx]->port[1];
2367			PF_ACPY(&match_key.addr[1],
2368			    &s->key[idx]->addr[0], match_key.af);
2369			match_key.port[1] = s->key[idx]->port[0];
2370		}
2371
2372		pf_unlink_state(s);
2373		killed++;
2374
2375		if (psk->psk_kill_match)
2376			killed += pf_kill_matching_state(&match_key, dir);
2377
2378		goto relock_DIOCKILLSTATES;
2379	}
2380	PF_HASHROW_UNLOCK(ih);
2381
2382	return (killed);
2383}
2384
2385int
2386pf_start(void)
2387{
2388	int error = 0;
2389
2390	sx_xlock(&V_pf_ioctl_lock);
2391	if (V_pf_status.running)
2392		error = EEXIST;
2393	else {
2394		hook_pf();
2395		if (! TAILQ_EMPTY(V_pf_keth->active.rules))
2396			hook_pf_eth();
2397		V_pf_status.running = 1;
2398		V_pf_status.since = time_second;
2399		new_unrhdr64(&V_pf_stateid, time_second);
2400
2401		DPFPRINTF(PF_DEBUG_MISC, ("pf: started\n"));
2402	}
2403	sx_xunlock(&V_pf_ioctl_lock);
2404
2405	return (error);
2406}
2407
2408int
2409pf_stop(void)
2410{
2411	int error = 0;
2412
2413	sx_xlock(&V_pf_ioctl_lock);
2414	if (!V_pf_status.running)
2415		error = ENOENT;
2416	else {
2417		V_pf_status.running = 0;
2418		dehook_pf();
2419		dehook_pf_eth();
2420		V_pf_status.since = time_second;
2421		DPFPRINTF(PF_DEBUG_MISC, ("pf: stopped\n"));
2422	}
2423	sx_xunlock(&V_pf_ioctl_lock);
2424
2425	return (error);
2426}
2427
2428void
2429pf_ioctl_clear_status(void)
2430{
2431	PF_RULES_WLOCK();
2432	for (int i = 0; i < PFRES_MAX; i++)
2433		counter_u64_zero(V_pf_status.counters[i]);
2434	for (int i = 0; i < FCNT_MAX; i++)
2435		pf_counter_u64_zero(&V_pf_status.fcounters[i]);
2436	for (int i = 0; i < SCNT_MAX; i++)
2437		counter_u64_zero(V_pf_status.scounters[i]);
2438	for (int i = 0; i < KLCNT_MAX; i++)
2439		counter_u64_zero(V_pf_status.lcounters[i]);
2440	V_pf_status.since = time_second;
2441	if (*V_pf_status.ifname)
2442		pfi_update_status(V_pf_status.ifname, NULL);
2443	PF_RULES_WUNLOCK();
2444}
2445
2446int
2447pf_ioctl_set_timeout(int timeout, int seconds, int *prev_seconds)
2448{
2449	uint32_t old;
2450
2451	if (timeout < 0 || timeout >= PFTM_MAX ||
2452	    seconds < 0)
2453		return (EINVAL);
2454
2455	PF_RULES_WLOCK();
2456	old = V_pf_default_rule.timeout[timeout];
2457	if (timeout == PFTM_INTERVAL && seconds == 0)
2458		seconds = 1;
2459	V_pf_default_rule.timeout[timeout] = seconds;
2460	if (timeout == PFTM_INTERVAL && seconds < old)
2461		wakeup(pf_purge_thread);
2462
2463	if (prev_seconds != NULL)
2464		*prev_seconds = old;
2465
2466	PF_RULES_WUNLOCK();
2467
2468	return (0);
2469}
2470
2471int
2472pf_ioctl_get_timeout(int timeout, int *seconds)
2473{
2474	PF_RULES_RLOCK_TRACKER;
2475
2476	if (timeout < 0 || timeout >= PFTM_MAX)
2477		return (EINVAL);
2478
2479	PF_RULES_RLOCK();
2480	*seconds = V_pf_default_rule.timeout[timeout];
2481	PF_RULES_RUNLOCK();
2482
2483	return (0);
2484}
2485
2486static int
2487pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
2488{
2489	int			 error = 0;
2490	PF_RULES_RLOCK_TRACKER;
2491
2492#define	ERROUT_IOCTL(target, x)					\
2493    do {								\
2494	    error = (x);						\
2495	    SDT_PROBE3(pf, ioctl, ioctl, error, cmd, error, __LINE__);	\
2496	    goto target;						\
2497    } while (0)
2498
2499
2500	/* XXX keep in sync with switch() below */
2501	if (securelevel_gt(td->td_ucred, 2))
2502		switch (cmd) {
2503		case DIOCGETRULES:
2504		case DIOCGETRULENV:
2505		case DIOCGETADDRS:
2506		case DIOCGETADDR:
2507		case DIOCGETSTATE:
2508		case DIOCGETSTATENV:
2509		case DIOCSETSTATUSIF:
2510		case DIOCGETSTATUSNV:
2511		case DIOCCLRSTATUS:
2512		case DIOCNATLOOK:
2513		case DIOCSETDEBUG:
2514#ifdef COMPAT_FREEBSD14
2515		case DIOCGETSTATES:
2516		case DIOCGETSTATESV2:
2517#endif
2518		case DIOCGETTIMEOUT:
2519		case DIOCCLRRULECTRS:
2520		case DIOCGETLIMIT:
2521		case DIOCGETALTQSV0:
2522		case DIOCGETALTQSV1:
2523		case DIOCGETALTQV0:
2524		case DIOCGETALTQV1:
2525		case DIOCGETQSTATSV0:
2526		case DIOCGETQSTATSV1:
2527		case DIOCGETRULESETS:
2528		case DIOCGETRULESET:
2529		case DIOCRGETTABLES:
2530		case DIOCRGETTSTATS:
2531		case DIOCRCLRTSTATS:
2532		case DIOCRCLRADDRS:
2533		case DIOCRADDADDRS:
2534		case DIOCRDELADDRS:
2535		case DIOCRSETADDRS:
2536		case DIOCRGETADDRS:
2537		case DIOCRGETASTATS:
2538		case DIOCRCLRASTATS:
2539		case DIOCRTSTADDRS:
2540		case DIOCOSFPGET:
2541		case DIOCGETSRCNODES:
2542		case DIOCCLRSRCNODES:
2543		case DIOCGETSYNCOOKIES:
2544		case DIOCIGETIFACES:
2545		case DIOCGIFSPEEDV0:
2546		case DIOCGIFSPEEDV1:
2547		case DIOCSETIFFLAG:
2548		case DIOCCLRIFFLAG:
2549		case DIOCGETETHRULES:
2550		case DIOCGETETHRULE:
2551		case DIOCGETETHRULESETS:
2552		case DIOCGETETHRULESET:
2553			break;
2554		case DIOCRCLRTABLES:
2555		case DIOCRADDTABLES:
2556		case DIOCRDELTABLES:
2557		case DIOCRSETTFLAGS:
2558			if (((struct pfioc_table *)addr)->pfrio_flags &
2559			    PFR_FLAG_DUMMY)
2560				break; /* dummy operation ok */
2561			return (EPERM);
2562		default:
2563			return (EPERM);
2564		}
2565
2566	if (!(flags & FWRITE))
2567		switch (cmd) {
2568		case DIOCGETRULES:
2569		case DIOCGETADDRS:
2570		case DIOCGETADDR:
2571		case DIOCGETSTATE:
2572		case DIOCGETSTATENV:
2573		case DIOCGETSTATUSNV:
2574#ifdef COMPAT_FREEBSD14
2575		case DIOCGETSTATES:
2576		case DIOCGETSTATESV2:
2577#endif
2578		case DIOCGETTIMEOUT:
2579		case DIOCGETLIMIT:
2580		case DIOCGETALTQSV0:
2581		case DIOCGETALTQSV1:
2582		case DIOCGETALTQV0:
2583		case DIOCGETALTQV1:
2584		case DIOCGETQSTATSV0:
2585		case DIOCGETQSTATSV1:
2586		case DIOCGETRULESETS:
2587		case DIOCGETRULESET:
2588		case DIOCNATLOOK:
2589		case DIOCRGETTABLES:
2590		case DIOCRGETTSTATS:
2591		case DIOCRGETADDRS:
2592		case DIOCRGETASTATS:
2593		case DIOCRTSTADDRS:
2594		case DIOCOSFPGET:
2595		case DIOCGETSRCNODES:
2596		case DIOCGETSYNCOOKIES:
2597		case DIOCIGETIFACES:
2598		case DIOCGIFSPEEDV1:
2599		case DIOCGIFSPEEDV0:
2600		case DIOCGETRULENV:
2601		case DIOCGETETHRULES:
2602		case DIOCGETETHRULE:
2603		case DIOCGETETHRULESETS:
2604		case DIOCGETETHRULESET:
2605			break;
2606		case DIOCRCLRTABLES:
2607		case DIOCRADDTABLES:
2608		case DIOCRDELTABLES:
2609		case DIOCRCLRTSTATS:
2610		case DIOCRCLRADDRS:
2611		case DIOCRADDADDRS:
2612		case DIOCRDELADDRS:
2613		case DIOCRSETADDRS:
2614		case DIOCRSETTFLAGS:
2615			if (((struct pfioc_table *)addr)->pfrio_flags &
2616			    PFR_FLAG_DUMMY) {
2617				flags |= FWRITE; /* need write lock for dummy */
2618				break; /* dummy operation ok */
2619			}
2620			return (EACCES);
2621		default:
2622			return (EACCES);
2623		}
2624
2625	CURVNET_SET(TD_TO_VNET(td));
2626
2627	switch (cmd) {
2628#ifdef COMPAT_FREEBSD14
2629	case DIOCSTART:
2630		error = pf_start();
2631		break;
2632
2633	case DIOCSTOP:
2634		error = pf_stop();
2635		break;
2636#endif
2637
2638	case DIOCGETETHRULES: {
2639		struct pfioc_nv		*nv = (struct pfioc_nv *)addr;
2640		nvlist_t		*nvl;
2641		void			*packed;
2642		struct pf_keth_rule	*tail;
2643		struct pf_keth_ruleset	*rs;
2644		u_int32_t		 ticket, nr;
2645		const char		*anchor = "";
2646
2647		nvl = NULL;
2648		packed = NULL;
2649
2650#define	ERROUT(x)	ERROUT_IOCTL(DIOCGETETHRULES_error, x)
2651
2652		if (nv->len > pf_ioctl_maxcount)
2653			ERROUT(ENOMEM);
2654
2655		/* Copy the request in */
2656		packed = malloc(nv->len, M_NVLIST, M_WAITOK);
2657		if (packed == NULL)
2658			ERROUT(ENOMEM);
2659
2660		error = copyin(nv->data, packed, nv->len);
2661		if (error)
2662			ERROUT(error);
2663
2664		nvl = nvlist_unpack(packed, nv->len, 0);
2665		if (nvl == NULL)
2666			ERROUT(EBADMSG);
2667
2668		if (! nvlist_exists_string(nvl, "anchor"))
2669			ERROUT(EBADMSG);
2670
2671		anchor = nvlist_get_string(nvl, "anchor");
2672
2673		rs = pf_find_keth_ruleset(anchor);
2674
2675		nvlist_destroy(nvl);
2676		nvl = NULL;
2677		free(packed, M_NVLIST);
2678		packed = NULL;
2679
2680		if (rs == NULL)
2681			ERROUT(ENOENT);
2682
2683		/* Reply */
2684		nvl = nvlist_create(0);
2685		if (nvl == NULL)
2686			ERROUT(ENOMEM);
2687
2688		PF_RULES_RLOCK();
2689
2690		ticket = rs->active.ticket;
2691		tail = TAILQ_LAST(rs->active.rules, pf_keth_ruleq);
2692		if (tail)
2693			nr = tail->nr + 1;
2694		else
2695			nr = 0;
2696
2697		PF_RULES_RUNLOCK();
2698
2699		nvlist_add_number(nvl, "ticket", ticket);
2700		nvlist_add_number(nvl, "nr", nr);
2701
2702		packed = nvlist_pack(nvl, &nv->len);
2703		if (packed == NULL)
2704			ERROUT(ENOMEM);
2705
2706		if (nv->size == 0)
2707			ERROUT(0);
2708		else if (nv->size < nv->len)
2709			ERROUT(ENOSPC);
2710
2711		error = copyout(packed, nv->data, nv->len);
2712
2713#undef ERROUT
2714DIOCGETETHRULES_error:
2715		free(packed, M_NVLIST);
2716		nvlist_destroy(nvl);
2717		break;
2718	}
2719
2720	case DIOCGETETHRULE: {
2721		struct epoch_tracker	 et;
2722		struct pfioc_nv		*nv = (struct pfioc_nv *)addr;
2723		nvlist_t		*nvl = NULL;
2724		void			*nvlpacked = NULL;
2725		struct pf_keth_rule	*rule = NULL;
2726		struct pf_keth_ruleset	*rs;
2727		u_int32_t		 ticket, nr;
2728		bool			 clear = false;
2729		const char		*anchor;
2730
2731#define ERROUT(x)	ERROUT_IOCTL(DIOCGETETHRULE_error, x)
2732
2733		if (nv->len > pf_ioctl_maxcount)
2734			ERROUT(ENOMEM);
2735
2736		nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
2737		if (nvlpacked == NULL)
2738			ERROUT(ENOMEM);
2739
2740		error = copyin(nv->data, nvlpacked, nv->len);
2741		if (error)
2742			ERROUT(error);
2743
2744		nvl = nvlist_unpack(nvlpacked, nv->len, 0);
2745		if (nvl == NULL)
2746			ERROUT(EBADMSG);
2747		if (! nvlist_exists_number(nvl, "ticket"))
2748			ERROUT(EBADMSG);
2749		ticket = nvlist_get_number(nvl, "ticket");
2750		if (! nvlist_exists_string(nvl, "anchor"))
2751			ERROUT(EBADMSG);
2752		anchor = nvlist_get_string(nvl, "anchor");
2753
2754		if (nvlist_exists_bool(nvl, "clear"))
2755			clear = nvlist_get_bool(nvl, "clear");
2756
2757		if (clear && !(flags & FWRITE))
2758			ERROUT(EACCES);
2759
2760		if (! nvlist_exists_number(nvl, "nr"))
2761			ERROUT(EBADMSG);
2762		nr = nvlist_get_number(nvl, "nr");
2763
2764		PF_RULES_RLOCK();
2765		rs = pf_find_keth_ruleset(anchor);
2766		if (rs == NULL) {
2767			PF_RULES_RUNLOCK();
2768			ERROUT(ENOENT);
2769		}
2770		if (ticket != rs->active.ticket) {
2771			PF_RULES_RUNLOCK();
2772			ERROUT(EBUSY);
2773		}
2774
2775		nvlist_destroy(nvl);
2776		nvl = NULL;
2777		free(nvlpacked, M_NVLIST);
2778		nvlpacked = NULL;
2779
2780		rule = TAILQ_FIRST(rs->active.rules);
2781		while ((rule != NULL) && (rule->nr != nr))
2782			rule = TAILQ_NEXT(rule, entries);
2783		if (rule == NULL) {
2784			PF_RULES_RUNLOCK();
2785			ERROUT(ENOENT);
2786		}
2787		/* Make sure rule can't go away. */
2788		NET_EPOCH_ENTER(et);
2789		PF_RULES_RUNLOCK();
2790		nvl = pf_keth_rule_to_nveth_rule(rule);
2791		if (pf_keth_anchor_nvcopyout(rs, rule, nvl))
2792			ERROUT(EBUSY);
2793		NET_EPOCH_EXIT(et);
2794		if (nvl == NULL)
2795			ERROUT(ENOMEM);
2796
2797		nvlpacked = nvlist_pack(nvl, &nv->len);
2798		if (nvlpacked == NULL)
2799			ERROUT(ENOMEM);
2800
2801		if (nv->size == 0)
2802			ERROUT(0);
2803		else if (nv->size < nv->len)
2804			ERROUT(ENOSPC);
2805
2806		error = copyout(nvlpacked, nv->data, nv->len);
2807		if (error == 0 && clear) {
2808			counter_u64_zero(rule->evaluations);
2809			for (int i = 0; i < 2; i++) {
2810				counter_u64_zero(rule->packets[i]);
2811				counter_u64_zero(rule->bytes[i]);
2812			}
2813		}
2814
2815#undef ERROUT
2816DIOCGETETHRULE_error:
2817		free(nvlpacked, M_NVLIST);
2818		nvlist_destroy(nvl);
2819		break;
2820	}
2821
2822	case DIOCADDETHRULE: {
2823		struct pfioc_nv		*nv = (struct pfioc_nv *)addr;
2824		nvlist_t		*nvl = NULL;
2825		void			*nvlpacked = NULL;
2826		struct pf_keth_rule	*rule = NULL, *tail = NULL;
2827		struct pf_keth_ruleset	*ruleset = NULL;
2828		struct pfi_kkif		*kif = NULL, *bridge_to_kif = NULL;
2829		const char		*anchor = "", *anchor_call = "";
2830
2831#define ERROUT(x)	ERROUT_IOCTL(DIOCADDETHRULE_error, x)
2832
2833		if (nv->len > pf_ioctl_maxcount)
2834			ERROUT(ENOMEM);
2835
2836		nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
2837		if (nvlpacked == NULL)
2838			ERROUT(ENOMEM);
2839
2840		error = copyin(nv->data, nvlpacked, nv->len);
2841		if (error)
2842			ERROUT(error);
2843
2844		nvl = nvlist_unpack(nvlpacked, nv->len, 0);
2845		if (nvl == NULL)
2846			ERROUT(EBADMSG);
2847
2848		if (! nvlist_exists_number(nvl, "ticket"))
2849			ERROUT(EBADMSG);
2850
2851		if (nvlist_exists_string(nvl, "anchor"))
2852			anchor = nvlist_get_string(nvl, "anchor");
2853		if (nvlist_exists_string(nvl, "anchor_call"))
2854			anchor_call = nvlist_get_string(nvl, "anchor_call");
2855
2856		ruleset = pf_find_keth_ruleset(anchor);
2857		if (ruleset == NULL)
2858			ERROUT(EINVAL);
2859
2860		if (nvlist_get_number(nvl, "ticket") !=
2861		    ruleset->inactive.ticket) {
2862			DPFPRINTF(PF_DEBUG_MISC,
2863			    ("ticket: %d != %d\n",
2864			    (u_int32_t)nvlist_get_number(nvl, "ticket"),
2865			    ruleset->inactive.ticket));
2866			ERROUT(EBUSY);
2867		}
2868
2869		rule = malloc(sizeof(*rule), M_PFRULE, M_WAITOK);
2870		if (rule == NULL)
2871			ERROUT(ENOMEM);
2872		rule->timestamp = NULL;
2873
2874		error = pf_nveth_rule_to_keth_rule(nvl, rule);
2875		if (error != 0)
2876			ERROUT(error);
2877
2878		if (rule->ifname[0])
2879			kif = pf_kkif_create(M_WAITOK);
2880		if (rule->bridge_to_name[0])
2881			bridge_to_kif = pf_kkif_create(M_WAITOK);
2882		rule->evaluations = counter_u64_alloc(M_WAITOK);
2883		for (int i = 0; i < 2; i++) {
2884			rule->packets[i] = counter_u64_alloc(M_WAITOK);
2885			rule->bytes[i] = counter_u64_alloc(M_WAITOK);
2886		}
2887		rule->timestamp = uma_zalloc_pcpu(pf_timestamp_pcpu_zone,
2888		    M_WAITOK | M_ZERO);
2889
2890		PF_RULES_WLOCK();
2891
2892		if (rule->ifname[0]) {
2893			rule->kif = pfi_kkif_attach(kif, rule->ifname);
2894			pfi_kkif_ref(rule->kif);
2895		} else
2896			rule->kif = NULL;
2897		if (rule->bridge_to_name[0]) {
2898			rule->bridge_to = pfi_kkif_attach(bridge_to_kif,
2899			    rule->bridge_to_name);
2900			pfi_kkif_ref(rule->bridge_to);
2901		} else
2902			rule->bridge_to = NULL;
2903
2904#ifdef ALTQ
2905		/* set queue IDs */
2906		if (rule->qname[0] != 0) {
2907			if ((rule->qid = pf_qname2qid(rule->qname)) == 0)
2908				error = EBUSY;
2909			else
2910				rule->qid = rule->qid;
2911		}
2912#endif
2913		if (rule->tagname[0])
2914			if ((rule->tag = pf_tagname2tag(rule->tagname)) == 0)
2915				error = EBUSY;
2916		if (rule->match_tagname[0])
2917			if ((rule->match_tag = pf_tagname2tag(
2918			    rule->match_tagname)) == 0)
2919				error = EBUSY;
2920
2921		if (error == 0 && rule->ipdst.addr.type == PF_ADDR_TABLE)
2922			error = pf_eth_addr_setup(ruleset, &rule->ipdst.addr);
2923		if (error == 0 && rule->ipsrc.addr.type == PF_ADDR_TABLE)
2924			error = pf_eth_addr_setup(ruleset, &rule->ipsrc.addr);
2925
2926		if (error) {
2927			pf_free_eth_rule(rule);
2928			PF_RULES_WUNLOCK();
2929			ERROUT(error);
2930		}
2931
2932		if (pf_keth_anchor_setup(rule, ruleset, anchor_call)) {
2933			pf_free_eth_rule(rule);
2934			PF_RULES_WUNLOCK();
2935			ERROUT(EINVAL);
2936		}
2937
2938		tail = TAILQ_LAST(ruleset->inactive.rules, pf_keth_ruleq);
2939		if (tail)
2940			rule->nr = tail->nr + 1;
2941		else
2942			rule->nr = 0;
2943
2944		TAILQ_INSERT_TAIL(ruleset->inactive.rules, rule, entries);
2945
2946		PF_RULES_WUNLOCK();
2947
2948#undef ERROUT
2949DIOCADDETHRULE_error:
2950		nvlist_destroy(nvl);
2951		free(nvlpacked, M_NVLIST);
2952		break;
2953	}
2954
2955	case DIOCGETETHRULESETS: {
2956		struct epoch_tracker	 et;
2957		struct pfioc_nv		*nv = (struct pfioc_nv *)addr;
2958		nvlist_t		*nvl = NULL;
2959		void			*nvlpacked = NULL;
2960		struct pf_keth_ruleset	*ruleset;
2961		struct pf_keth_anchor	*anchor;
2962		int			 nr = 0;
2963
2964#define ERROUT(x)	ERROUT_IOCTL(DIOCGETETHRULESETS_error, x)
2965
2966		if (nv->len > pf_ioctl_maxcount)
2967			ERROUT(ENOMEM);
2968
2969		nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
2970		if (nvlpacked == NULL)
2971			ERROUT(ENOMEM);
2972
2973		error = copyin(nv->data, nvlpacked, nv->len);
2974		if (error)
2975			ERROUT(error);
2976
2977		nvl = nvlist_unpack(nvlpacked, nv->len, 0);
2978		if (nvl == NULL)
2979			ERROUT(EBADMSG);
2980		if (! nvlist_exists_string(nvl, "path"))
2981			ERROUT(EBADMSG);
2982
2983		NET_EPOCH_ENTER(et);
2984
2985		if ((ruleset = pf_find_keth_ruleset(
2986		    nvlist_get_string(nvl, "path"))) == NULL) {
2987			NET_EPOCH_EXIT(et);
2988			ERROUT(ENOENT);
2989		}
2990
2991		if (ruleset->anchor == NULL) {
2992			RB_FOREACH(anchor, pf_keth_anchor_global, &V_pf_keth_anchors)
2993				if (anchor->parent == NULL)
2994					nr++;
2995		} else {
2996			RB_FOREACH(anchor, pf_keth_anchor_node,
2997			    &ruleset->anchor->children)
2998				nr++;
2999		}
3000
3001		NET_EPOCH_EXIT(et);
3002
3003		nvlist_destroy(nvl);
3004		nvl = NULL;
3005		free(nvlpacked, M_NVLIST);
3006		nvlpacked = NULL;
3007
3008		nvl = nvlist_create(0);
3009		if (nvl == NULL)
3010			ERROUT(ENOMEM);
3011
3012		nvlist_add_number(nvl, "nr", nr);
3013
3014		nvlpacked = nvlist_pack(nvl, &nv->len);
3015		if (nvlpacked == NULL)
3016			ERROUT(ENOMEM);
3017
3018		if (nv->size == 0)
3019			ERROUT(0);
3020		else if (nv->size < nv->len)
3021			ERROUT(ENOSPC);
3022
3023		error = copyout(nvlpacked, nv->data, nv->len);
3024
3025#undef ERROUT
3026DIOCGETETHRULESETS_error:
3027		free(nvlpacked, M_NVLIST);
3028		nvlist_destroy(nvl);
3029		break;
3030	}
3031
3032	case DIOCGETETHRULESET: {
3033		struct epoch_tracker	 et;
3034		struct pfioc_nv		*nv = (struct pfioc_nv *)addr;
3035		nvlist_t		*nvl = NULL;
3036		void			*nvlpacked = NULL;
3037		struct pf_keth_ruleset	*ruleset;
3038		struct pf_keth_anchor	*anchor;
3039		int			 nr = 0, req_nr = 0;
3040		bool			 found = false;
3041
3042#define ERROUT(x)	ERROUT_IOCTL(DIOCGETETHRULESET_error, x)
3043
3044		if (nv->len > pf_ioctl_maxcount)
3045			ERROUT(ENOMEM);
3046
3047		nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
3048		if (nvlpacked == NULL)
3049			ERROUT(ENOMEM);
3050
3051		error = copyin(nv->data, nvlpacked, nv->len);
3052		if (error)
3053			ERROUT(error);
3054
3055		nvl = nvlist_unpack(nvlpacked, nv->len, 0);
3056		if (nvl == NULL)
3057			ERROUT(EBADMSG);
3058		if (! nvlist_exists_string(nvl, "path"))
3059			ERROUT(EBADMSG);
3060		if (! nvlist_exists_number(nvl, "nr"))
3061			ERROUT(EBADMSG);
3062
3063		req_nr = nvlist_get_number(nvl, "nr");
3064
3065		NET_EPOCH_ENTER(et);
3066
3067		if ((ruleset = pf_find_keth_ruleset(
3068		    nvlist_get_string(nvl, "path"))) == NULL) {
3069			NET_EPOCH_EXIT(et);
3070			ERROUT(ENOENT);
3071		}
3072
3073		nvlist_destroy(nvl);
3074		nvl = NULL;
3075		free(nvlpacked, M_NVLIST);
3076		nvlpacked = NULL;
3077
3078		nvl = nvlist_create(0);
3079		if (nvl == NULL) {
3080			NET_EPOCH_EXIT(et);
3081			ERROUT(ENOMEM);
3082		}
3083
3084		if (ruleset->anchor == NULL) {
3085			RB_FOREACH(anchor, pf_keth_anchor_global,
3086			    &V_pf_keth_anchors) {
3087				if (anchor->parent == NULL && nr++ == req_nr) {
3088					found = true;
3089					break;
3090				}
3091			}
3092		} else {
3093			RB_FOREACH(anchor, pf_keth_anchor_node,
3094			     &ruleset->anchor->children) {
3095				if (nr++ == req_nr) {
3096					found = true;
3097					break;
3098				}
3099			}
3100		}
3101
3102		NET_EPOCH_EXIT(et);
3103		if (found) {
3104			nvlist_add_number(nvl, "nr", nr);
3105			nvlist_add_string(nvl, "name", anchor->name);
3106			if (ruleset->anchor)
3107				nvlist_add_string(nvl, "path",
3108				    ruleset->anchor->path);
3109			else
3110				nvlist_add_string(nvl, "path", "");
3111		} else {
3112			ERROUT(EBUSY);
3113		}
3114
3115		nvlpacked = nvlist_pack(nvl, &nv->len);
3116		if (nvlpacked == NULL)
3117			ERROUT(ENOMEM);
3118
3119		if (nv->size == 0)
3120			ERROUT(0);
3121		else if (nv->size < nv->len)
3122			ERROUT(ENOSPC);
3123
3124		error = copyout(nvlpacked, nv->data, nv->len);
3125
3126#undef ERROUT
3127DIOCGETETHRULESET_error:
3128		free(nvlpacked, M_NVLIST);
3129		nvlist_destroy(nvl);
3130		break;
3131	}
3132
3133	case DIOCADDRULENV: {
3134		struct pfioc_nv	*nv = (struct pfioc_nv *)addr;
3135		nvlist_t	*nvl = NULL;
3136		void		*nvlpacked = NULL;
3137		struct pf_krule	*rule = NULL;
3138		const char	*anchor = "", *anchor_call = "";
3139		uint32_t	 ticket = 0, pool_ticket = 0;
3140
3141#define	ERROUT(x)	ERROUT_IOCTL(DIOCADDRULENV_error, x)
3142
3143		if (nv->len > pf_ioctl_maxcount)
3144			ERROUT(ENOMEM);
3145
3146		nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
3147		error = copyin(nv->data, nvlpacked, nv->len);
3148		if (error)
3149			ERROUT(error);
3150
3151		nvl = nvlist_unpack(nvlpacked, nv->len, 0);
3152		if (nvl == NULL)
3153			ERROUT(EBADMSG);
3154
3155		if (! nvlist_exists_number(nvl, "ticket"))
3156			ERROUT(EINVAL);
3157		ticket = nvlist_get_number(nvl, "ticket");
3158
3159		if (! nvlist_exists_number(nvl, "pool_ticket"))
3160			ERROUT(EINVAL);
3161		pool_ticket = nvlist_get_number(nvl, "pool_ticket");
3162
3163		if (! nvlist_exists_nvlist(nvl, "rule"))
3164			ERROUT(EINVAL);
3165
3166		rule = pf_krule_alloc();
3167		error = pf_nvrule_to_krule(nvlist_get_nvlist(nvl, "rule"),
3168		    rule);
3169		if (error)
3170			ERROUT(error);
3171
3172		if (nvlist_exists_string(nvl, "anchor"))
3173			anchor = nvlist_get_string(nvl, "anchor");
3174		if (nvlist_exists_string(nvl, "anchor_call"))
3175			anchor_call = nvlist_get_string(nvl, "anchor_call");
3176
3177		if ((error = nvlist_error(nvl)))
3178			ERROUT(error);
3179
3180		/* Frees rule on error */
3181		error = pf_ioctl_addrule(rule, ticket, pool_ticket, anchor,
3182		    anchor_call, td->td_ucred->cr_ruid,
3183		    td->td_proc ? td->td_proc->p_pid : 0);
3184
3185		nvlist_destroy(nvl);
3186		free(nvlpacked, M_NVLIST);
3187		break;
3188#undef ERROUT
3189DIOCADDRULENV_error:
3190		pf_krule_free(rule);
3191		nvlist_destroy(nvl);
3192		free(nvlpacked, M_NVLIST);
3193
3194		break;
3195	}
3196	case DIOCADDRULE: {
3197		struct pfioc_rule	*pr = (struct pfioc_rule *)addr;
3198		struct pf_krule		*rule;
3199
3200		rule = pf_krule_alloc();
3201		error = pf_rule_to_krule(&pr->rule, rule);
3202		if (error != 0) {
3203			pf_krule_free(rule);
3204			break;
3205		}
3206
3207		pr->anchor[sizeof(pr->anchor) - 1] = 0;
3208
3209		/* Frees rule on error */
3210		error = pf_ioctl_addrule(rule, pr->ticket, pr->pool_ticket,
3211		    pr->anchor, pr->anchor_call, td->td_ucred->cr_ruid,
3212		    td->td_proc ? td->td_proc->p_pid : 0);
3213		break;
3214	}
3215
3216	case DIOCGETRULES: {
3217		struct pfioc_rule	*pr = (struct pfioc_rule *)addr;
3218
3219		pr->anchor[sizeof(pr->anchor) - 1] = 0;
3220
3221		error = pf_ioctl_getrules(pr);
3222
3223		break;
3224	}
3225
3226	case DIOCGETRULENV: {
3227		struct pfioc_nv		*nv = (struct pfioc_nv *)addr;
3228		nvlist_t		*nvrule = NULL;
3229		nvlist_t		*nvl = NULL;
3230		struct pf_kruleset	*ruleset;
3231		struct pf_krule		*rule;
3232		void			*nvlpacked = NULL;
3233		int			 rs_num, nr;
3234		bool			 clear_counter = false;
3235
3236#define	ERROUT(x)	ERROUT_IOCTL(DIOCGETRULENV_error, x)
3237
3238		if (nv->len > pf_ioctl_maxcount)
3239			ERROUT(ENOMEM);
3240
3241		/* Copy the request in */
3242		nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
3243		if (nvlpacked == NULL)
3244			ERROUT(ENOMEM);
3245
3246		error = copyin(nv->data, nvlpacked, nv->len);
3247		if (error)
3248			ERROUT(error);
3249
3250		nvl = nvlist_unpack(nvlpacked, nv->len, 0);
3251		if (nvl == NULL)
3252			ERROUT(EBADMSG);
3253
3254		if (! nvlist_exists_string(nvl, "anchor"))
3255			ERROUT(EBADMSG);
3256		if (! nvlist_exists_number(nvl, "ruleset"))
3257			ERROUT(EBADMSG);
3258		if (! nvlist_exists_number(nvl, "ticket"))
3259			ERROUT(EBADMSG);
3260		if (! nvlist_exists_number(nvl, "nr"))
3261			ERROUT(EBADMSG);
3262
3263		if (nvlist_exists_bool(nvl, "clear_counter"))
3264			clear_counter = nvlist_get_bool(nvl, "clear_counter");
3265
3266		if (clear_counter && !(flags & FWRITE))
3267			ERROUT(EACCES);
3268
3269		nr = nvlist_get_number(nvl, "nr");
3270
3271		PF_RULES_WLOCK();
3272		ruleset = pf_find_kruleset(nvlist_get_string(nvl, "anchor"));
3273		if (ruleset == NULL) {
3274			PF_RULES_WUNLOCK();
3275			ERROUT(ENOENT);
3276		}
3277
3278		rs_num = pf_get_ruleset_number(nvlist_get_number(nvl, "ruleset"));
3279		if (rs_num >= PF_RULESET_MAX) {
3280			PF_RULES_WUNLOCK();
3281			ERROUT(EINVAL);
3282		}
3283
3284		if (nvlist_get_number(nvl, "ticket") !=
3285		    ruleset->rules[rs_num].active.ticket) {
3286			PF_RULES_WUNLOCK();
3287			ERROUT(EBUSY);
3288		}
3289
3290		if ((error = nvlist_error(nvl))) {
3291			PF_RULES_WUNLOCK();
3292			ERROUT(error);
3293		}
3294
3295		rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
3296		while ((rule != NULL) && (rule->nr != nr))
3297			rule = TAILQ_NEXT(rule, entries);
3298		if (rule == NULL) {
3299			PF_RULES_WUNLOCK();
3300			ERROUT(EBUSY);
3301		}
3302
3303		nvrule = pf_krule_to_nvrule(rule);
3304
3305		nvlist_destroy(nvl);
3306		nvl = nvlist_create(0);
3307		if (nvl == NULL) {
3308			PF_RULES_WUNLOCK();
3309			ERROUT(ENOMEM);
3310		}
3311		nvlist_add_number(nvl, "nr", nr);
3312		nvlist_add_nvlist(nvl, "rule", nvrule);
3313		nvlist_destroy(nvrule);
3314		nvrule = NULL;
3315		if (pf_kanchor_nvcopyout(ruleset, rule, nvl)) {
3316			PF_RULES_WUNLOCK();
3317			ERROUT(EBUSY);
3318		}
3319
3320		free(nvlpacked, M_NVLIST);
3321		nvlpacked = nvlist_pack(nvl, &nv->len);
3322		if (nvlpacked == NULL) {
3323			PF_RULES_WUNLOCK();
3324			ERROUT(ENOMEM);
3325		}
3326
3327		if (nv->size == 0) {
3328			PF_RULES_WUNLOCK();
3329			ERROUT(0);
3330		}
3331		else if (nv->size < nv->len) {
3332			PF_RULES_WUNLOCK();
3333			ERROUT(ENOSPC);
3334		}
3335
3336		if (clear_counter)
3337			pf_krule_clear_counters(rule);
3338
3339		PF_RULES_WUNLOCK();
3340
3341		error = copyout(nvlpacked, nv->data, nv->len);
3342
3343#undef ERROUT
3344DIOCGETRULENV_error:
3345		free(nvlpacked, M_NVLIST);
3346		nvlist_destroy(nvrule);
3347		nvlist_destroy(nvl);
3348
3349		break;
3350	}
3351
3352	case DIOCCHANGERULE: {
3353		struct pfioc_rule	*pcr = (struct pfioc_rule *)addr;
3354		struct pf_kruleset	*ruleset;
3355		struct pf_krule		*oldrule = NULL, *newrule = NULL;
3356		struct pfi_kkif		*kif = NULL;
3357		struct pf_kpooladdr	*pa;
3358		u_int32_t		 nr = 0;
3359		int			 rs_num;
3360
3361		pcr->anchor[sizeof(pcr->anchor) - 1] = 0;
3362
3363		if (pcr->action < PF_CHANGE_ADD_HEAD ||
3364		    pcr->action > PF_CHANGE_GET_TICKET) {
3365			error = EINVAL;
3366			break;
3367		}
3368		if (pcr->rule.return_icmp >> 8 > ICMP_MAXTYPE) {
3369			error = EINVAL;
3370			break;
3371		}
3372
3373		if (pcr->action != PF_CHANGE_REMOVE) {
3374			newrule = pf_krule_alloc();
3375			error = pf_rule_to_krule(&pcr->rule, newrule);
3376			if (error != 0) {
3377				pf_krule_free(newrule);
3378				break;
3379			}
3380
3381			if (newrule->ifname[0])
3382				kif = pf_kkif_create(M_WAITOK);
3383			pf_counter_u64_init(&newrule->evaluations, M_WAITOK);
3384			for (int i = 0; i < 2; i++) {
3385				pf_counter_u64_init(&newrule->packets[i], M_WAITOK);
3386				pf_counter_u64_init(&newrule->bytes[i], M_WAITOK);
3387			}
3388			newrule->states_cur = counter_u64_alloc(M_WAITOK);
3389			newrule->states_tot = counter_u64_alloc(M_WAITOK);
3390			newrule->src_nodes = counter_u64_alloc(M_WAITOK);
3391			newrule->cuid = td->td_ucred->cr_ruid;
3392			newrule->cpid = td->td_proc ? td->td_proc->p_pid : 0;
3393			TAILQ_INIT(&newrule->rpool.list);
3394		}
3395#define	ERROUT(x)	ERROUT_IOCTL(DIOCCHANGERULE_error, x)
3396
3397		PF_CONFIG_LOCK();
3398		PF_RULES_WLOCK();
3399#ifdef PF_WANT_32_TO_64_COUNTER
3400		if (newrule != NULL) {
3401			LIST_INSERT_HEAD(&V_pf_allrulelist, newrule, allrulelist);
3402			newrule->allrulelinked = true;
3403			V_pf_allrulecount++;
3404		}
3405#endif
3406
3407		if (!(pcr->action == PF_CHANGE_REMOVE ||
3408		    pcr->action == PF_CHANGE_GET_TICKET) &&
3409		    pcr->pool_ticket != V_ticket_pabuf)
3410			ERROUT(EBUSY);
3411
3412		ruleset = pf_find_kruleset(pcr->anchor);
3413		if (ruleset == NULL)
3414			ERROUT(EINVAL);
3415
3416		rs_num = pf_get_ruleset_number(pcr->rule.action);
3417		if (rs_num >= PF_RULESET_MAX)
3418			ERROUT(EINVAL);
3419
3420		/*
3421		 * XXXMJG: there is no guarantee that the ruleset was
3422		 * created by the usual route of calling DIOCXBEGIN.
3423		 * As a result it is possible the rule tree will not
3424		 * be allocated yet. Hack around it by doing it here.
3425		 * Note it is fine to let the tree persist in case of
3426		 * error as it will be freed down the road on future
3427		 * updates (if need be).
3428		 */
3429		if (ruleset->rules[rs_num].active.tree == NULL) {
3430			ruleset->rules[rs_num].active.tree = pf_rule_tree_alloc(M_NOWAIT);
3431			if (ruleset->rules[rs_num].active.tree == NULL) {
3432				ERROUT(ENOMEM);
3433			}
3434		}
3435
3436		if (pcr->action == PF_CHANGE_GET_TICKET) {
3437			pcr->ticket = ++ruleset->rules[rs_num].active.ticket;
3438			ERROUT(0);
3439		} else if (pcr->ticket !=
3440			    ruleset->rules[rs_num].active.ticket)
3441				ERROUT(EINVAL);
3442
3443		if (pcr->action != PF_CHANGE_REMOVE) {
3444			if (newrule->ifname[0]) {
3445				newrule->kif = pfi_kkif_attach(kif,
3446				    newrule->ifname);
3447				kif = NULL;
3448				pfi_kkif_ref(newrule->kif);
3449			} else
3450				newrule->kif = NULL;
3451
3452			if (newrule->rtableid > 0 &&
3453			    newrule->rtableid >= rt_numfibs)
3454				error = EBUSY;
3455
3456#ifdef ALTQ
3457			/* set queue IDs */
3458			if (newrule->qname[0] != 0) {
3459				if ((newrule->qid =
3460				    pf_qname2qid(newrule->qname)) == 0)
3461					error = EBUSY;
3462				else if (newrule->pqname[0] != 0) {
3463					if ((newrule->pqid =
3464					    pf_qname2qid(newrule->pqname)) == 0)
3465						error = EBUSY;
3466				} else
3467					newrule->pqid = newrule->qid;
3468			}
3469#endif /* ALTQ */
3470			if (newrule->tagname[0])
3471				if ((newrule->tag =
3472				    pf_tagname2tag(newrule->tagname)) == 0)
3473					error = EBUSY;
3474			if (newrule->match_tagname[0])
3475				if ((newrule->match_tag = pf_tagname2tag(
3476				    newrule->match_tagname)) == 0)
3477					error = EBUSY;
3478			if (newrule->rt && !newrule->direction)
3479				error = EINVAL;
3480			if (!newrule->log)
3481				newrule->logif = 0;
3482			if (newrule->logif >= PFLOGIFS_MAX)
3483				error = EINVAL;
3484			if (pf_addr_setup(ruleset, &newrule->src.addr, newrule->af))
3485				error = ENOMEM;
3486			if (pf_addr_setup(ruleset, &newrule->dst.addr, newrule->af))
3487				error = ENOMEM;
3488			if (pf_kanchor_setup(newrule, ruleset, pcr->anchor_call))
3489				error = EINVAL;
3490			TAILQ_FOREACH(pa, &V_pf_pabuf, entries)
3491				if (pa->addr.type == PF_ADDR_TABLE) {
3492					pa->addr.p.tbl =
3493					    pfr_attach_table(ruleset,
3494					    pa->addr.v.tblname);
3495					if (pa->addr.p.tbl == NULL)
3496						error = ENOMEM;
3497				}
3498
3499			newrule->overload_tbl = NULL;
3500			if (newrule->overload_tblname[0]) {
3501				if ((newrule->overload_tbl = pfr_attach_table(
3502				    ruleset, newrule->overload_tblname)) ==
3503				    NULL)
3504					error = EINVAL;
3505				else
3506					newrule->overload_tbl->pfrkt_flags |=
3507					    PFR_TFLAG_ACTIVE;
3508			}
3509
3510			pf_mv_kpool(&V_pf_pabuf, &newrule->rpool.list);
3511			if (((((newrule->action == PF_NAT) ||
3512			    (newrule->action == PF_RDR) ||
3513			    (newrule->action == PF_BINAT) ||
3514			    (newrule->rt > PF_NOPFROUTE)) &&
3515			    !newrule->anchor)) &&
3516			    (TAILQ_FIRST(&newrule->rpool.list) == NULL))
3517				error = EINVAL;
3518
3519			if (error) {
3520				pf_free_rule(newrule);
3521				PF_RULES_WUNLOCK();
3522				PF_CONFIG_UNLOCK();
3523				break;
3524			}
3525
3526			newrule->rpool.cur = TAILQ_FIRST(&newrule->rpool.list);
3527		}
3528		pf_empty_kpool(&V_pf_pabuf);
3529
3530		if (pcr->action == PF_CHANGE_ADD_HEAD)
3531			oldrule = TAILQ_FIRST(
3532			    ruleset->rules[rs_num].active.ptr);
3533		else if (pcr->action == PF_CHANGE_ADD_TAIL)
3534			oldrule = TAILQ_LAST(
3535			    ruleset->rules[rs_num].active.ptr, pf_krulequeue);
3536		else {
3537			oldrule = TAILQ_FIRST(
3538			    ruleset->rules[rs_num].active.ptr);
3539			while ((oldrule != NULL) && (oldrule->nr != pcr->nr))
3540				oldrule = TAILQ_NEXT(oldrule, entries);
3541			if (oldrule == NULL) {
3542				if (newrule != NULL)
3543					pf_free_rule(newrule);
3544				PF_RULES_WUNLOCK();
3545				PF_CONFIG_UNLOCK();
3546				error = EINVAL;
3547				break;
3548			}
3549		}
3550
3551		if (pcr->action == PF_CHANGE_REMOVE) {
3552			pf_unlink_rule(ruleset->rules[rs_num].active.ptr,
3553			    oldrule);
3554			RB_REMOVE(pf_krule_global,
3555			    ruleset->rules[rs_num].active.tree, oldrule);
3556			ruleset->rules[rs_num].active.rcount--;
3557		} else {
3558			pf_hash_rule(newrule);
3559			if (RB_INSERT(pf_krule_global,
3560			    ruleset->rules[rs_num].active.tree, newrule) != NULL) {
3561				pf_free_rule(newrule);
3562				PF_RULES_WUNLOCK();
3563				PF_CONFIG_UNLOCK();
3564				error = EEXIST;
3565				break;
3566			}
3567
3568			if (oldrule == NULL)
3569				TAILQ_INSERT_TAIL(
3570				    ruleset->rules[rs_num].active.ptr,
3571				    newrule, entries);
3572			else if (pcr->action == PF_CHANGE_ADD_HEAD ||
3573			    pcr->action == PF_CHANGE_ADD_BEFORE)
3574				TAILQ_INSERT_BEFORE(oldrule, newrule, entries);
3575			else
3576				TAILQ_INSERT_AFTER(
3577				    ruleset->rules[rs_num].active.ptr,
3578				    oldrule, newrule, entries);
3579			ruleset->rules[rs_num].active.rcount++;
3580		}
3581
3582		nr = 0;
3583		TAILQ_FOREACH(oldrule,
3584		    ruleset->rules[rs_num].active.ptr, entries)
3585			oldrule->nr = nr++;
3586
3587		ruleset->rules[rs_num].active.ticket++;
3588
3589		pf_calc_skip_steps(ruleset->rules[rs_num].active.ptr);
3590		pf_remove_if_empty_kruleset(ruleset);
3591
3592		PF_RULES_WUNLOCK();
3593		PF_CONFIG_UNLOCK();
3594		break;
3595
3596#undef ERROUT
3597DIOCCHANGERULE_error:
3598		PF_RULES_WUNLOCK();
3599		PF_CONFIG_UNLOCK();
3600		pf_krule_free(newrule);
3601		pf_kkif_free(kif);
3602		break;
3603	}
3604
3605	case DIOCCLRSTATESNV: {
3606		error = pf_clearstates_nv((struct pfioc_nv *)addr);
3607		break;
3608	}
3609
3610	case DIOCKILLSTATESNV: {
3611		error = pf_killstates_nv((struct pfioc_nv *)addr);
3612		break;
3613	}
3614
3615	case DIOCADDSTATE: {
3616		struct pfioc_state		*ps = (struct pfioc_state *)addr;
3617		struct pfsync_state_1301	*sp = &ps->state;
3618
3619		if (sp->timeout >= PFTM_MAX) {
3620			error = EINVAL;
3621			break;
3622		}
3623		if (V_pfsync_state_import_ptr != NULL) {
3624			PF_RULES_RLOCK();
3625			error = V_pfsync_state_import_ptr(
3626			    (union pfsync_state_union *)sp, PFSYNC_SI_IOCTL,
3627			    PFSYNC_MSG_VERSION_1301);
3628			PF_RULES_RUNLOCK();
3629		} else
3630			error = EOPNOTSUPP;
3631		break;
3632	}
3633
3634	case DIOCGETSTATE: {
3635		struct pfioc_state	*ps = (struct pfioc_state *)addr;
3636		struct pf_kstate	*s;
3637
3638		s = pf_find_state_byid(ps->state.id, ps->state.creatorid);
3639		if (s == NULL) {
3640			error = ENOENT;
3641			break;
3642		}
3643
3644		pfsync_state_export((union pfsync_state_union*)&ps->state,
3645		    s, PFSYNC_MSG_VERSION_1301);
3646		PF_STATE_UNLOCK(s);
3647		break;
3648	}
3649
3650	case DIOCGETSTATENV: {
3651		error = pf_getstate((struct pfioc_nv *)addr);
3652		break;
3653	}
3654
3655#ifdef COMPAT_FREEBSD14
3656	case DIOCGETSTATES: {
3657		struct pfioc_states	*ps = (struct pfioc_states *)addr;
3658		struct pf_kstate	*s;
3659		struct pfsync_state_1301	*pstore, *p;
3660		int			 i, nr;
3661		size_t			 slice_count = 16, count;
3662		void			*out;
3663
3664		if (ps->ps_len <= 0) {
3665			nr = uma_zone_get_cur(V_pf_state_z);
3666			ps->ps_len = sizeof(struct pfsync_state_1301) * nr;
3667			break;
3668		}
3669
3670		out = ps->ps_states;
3671		pstore = mallocarray(slice_count,
3672		    sizeof(struct pfsync_state_1301), M_TEMP, M_WAITOK | M_ZERO);
3673		nr = 0;
3674
3675		for (i = 0; i <= pf_hashmask; i++) {
3676			struct pf_idhash *ih = &V_pf_idhash[i];
3677
3678DIOCGETSTATES_retry:
3679			p = pstore;
3680
3681			if (LIST_EMPTY(&ih->states))
3682				continue;
3683
3684			PF_HASHROW_LOCK(ih);
3685			count = 0;
3686			LIST_FOREACH(s, &ih->states, entry) {
3687				if (s->timeout == PFTM_UNLINKED)
3688					continue;
3689				count++;
3690			}
3691
3692			if (count > slice_count) {
3693				PF_HASHROW_UNLOCK(ih);
3694				free(pstore, M_TEMP);
3695				slice_count = count * 2;
3696				pstore = mallocarray(slice_count,
3697				    sizeof(struct pfsync_state_1301), M_TEMP,
3698				    M_WAITOK | M_ZERO);
3699				goto DIOCGETSTATES_retry;
3700			}
3701
3702			if ((nr+count) * sizeof(*p) > ps->ps_len) {
3703				PF_HASHROW_UNLOCK(ih);
3704				goto DIOCGETSTATES_full;
3705			}
3706
3707			LIST_FOREACH(s, &ih->states, entry) {
3708				if (s->timeout == PFTM_UNLINKED)
3709					continue;
3710
3711				pfsync_state_export((union pfsync_state_union*)p,
3712				    s, PFSYNC_MSG_VERSION_1301);
3713				p++;
3714				nr++;
3715			}
3716			PF_HASHROW_UNLOCK(ih);
3717			error = copyout(pstore, out,
3718			    sizeof(struct pfsync_state_1301) * count);
3719			if (error)
3720				break;
3721			out = ps->ps_states + nr;
3722		}
3723DIOCGETSTATES_full:
3724		ps->ps_len = sizeof(struct pfsync_state_1301) * nr;
3725		free(pstore, M_TEMP);
3726
3727		break;
3728	}
3729
3730	case DIOCGETSTATESV2: {
3731		struct pfioc_states_v2	*ps = (struct pfioc_states_v2 *)addr;
3732		struct pf_kstate	*s;
3733		struct pf_state_export	*pstore, *p;
3734		int i, nr;
3735		size_t slice_count = 16, count;
3736		void *out;
3737
3738		if (ps->ps_req_version > PF_STATE_VERSION) {
3739			error = ENOTSUP;
3740			break;
3741		}
3742
3743		if (ps->ps_len <= 0) {
3744			nr = uma_zone_get_cur(V_pf_state_z);
3745			ps->ps_len = sizeof(struct pf_state_export) * nr;
3746			break;
3747		}
3748
3749		out = ps->ps_states;
3750		pstore = mallocarray(slice_count,
3751		    sizeof(struct pf_state_export), M_TEMP, M_WAITOK | M_ZERO);
3752		nr = 0;
3753
3754		for (i = 0; i <= pf_hashmask; i++) {
3755			struct pf_idhash *ih = &V_pf_idhash[i];
3756
3757DIOCGETSTATESV2_retry:
3758			p = pstore;
3759
3760			if (LIST_EMPTY(&ih->states))
3761				continue;
3762
3763			PF_HASHROW_LOCK(ih);
3764			count = 0;
3765			LIST_FOREACH(s, &ih->states, entry) {
3766				if (s->timeout == PFTM_UNLINKED)
3767					continue;
3768				count++;
3769			}
3770
3771			if (count > slice_count) {
3772				PF_HASHROW_UNLOCK(ih);
3773				free(pstore, M_TEMP);
3774				slice_count = count * 2;
3775				pstore = mallocarray(slice_count,
3776				    sizeof(struct pf_state_export), M_TEMP,
3777				    M_WAITOK | M_ZERO);
3778				goto DIOCGETSTATESV2_retry;
3779			}
3780
3781			if ((nr+count) * sizeof(*p) > ps->ps_len) {
3782				PF_HASHROW_UNLOCK(ih);
3783				goto DIOCGETSTATESV2_full;
3784			}
3785
3786			LIST_FOREACH(s, &ih->states, entry) {
3787				if (s->timeout == PFTM_UNLINKED)
3788					continue;
3789
3790				pf_state_export(p, s);
3791				p++;
3792				nr++;
3793			}
3794			PF_HASHROW_UNLOCK(ih);
3795			error = copyout(pstore, out,
3796			    sizeof(struct pf_state_export) * count);
3797			if (error)
3798				break;
3799			out = ps->ps_states + nr;
3800		}
3801DIOCGETSTATESV2_full:
3802		ps->ps_len = nr * sizeof(struct pf_state_export);
3803		free(pstore, M_TEMP);
3804
3805		break;
3806	}
3807#endif
3808	case DIOCGETSTATUSNV: {
3809		error = pf_getstatus((struct pfioc_nv *)addr);
3810		break;
3811	}
3812
3813	case DIOCSETSTATUSIF: {
3814		struct pfioc_if	*pi = (struct pfioc_if *)addr;
3815
3816		if (pi->ifname[0] == 0) {
3817			bzero(V_pf_status.ifname, IFNAMSIZ);
3818			break;
3819		}
3820		PF_RULES_WLOCK();
3821		error = pf_user_strcpy(V_pf_status.ifname, pi->ifname, IFNAMSIZ);
3822		PF_RULES_WUNLOCK();
3823		break;
3824	}
3825
3826	case DIOCCLRSTATUS: {
3827		pf_ioctl_clear_status();
3828		break;
3829	}
3830
3831	case DIOCNATLOOK: {
3832		struct pfioc_natlook	*pnl = (struct pfioc_natlook *)addr;
3833		struct pf_state_key	*sk;
3834		struct pf_kstate	*state;
3835		struct pf_state_key_cmp	 key;
3836		int			 m = 0, direction = pnl->direction;
3837		int			 sidx, didx;
3838
3839		/* NATLOOK src and dst are reversed, so reverse sidx/didx */
3840		sidx = (direction == PF_IN) ? 1 : 0;
3841		didx = (direction == PF_IN) ? 0 : 1;
3842
3843		if (!pnl->proto ||
3844		    PF_AZERO(&pnl->saddr, pnl->af) ||
3845		    PF_AZERO(&pnl->daddr, pnl->af) ||
3846		    ((pnl->proto == IPPROTO_TCP ||
3847		    pnl->proto == IPPROTO_UDP) &&
3848		    (!pnl->dport || !pnl->sport)))
3849			error = EINVAL;
3850		else {
3851			bzero(&key, sizeof(key));
3852			key.af = pnl->af;
3853			key.proto = pnl->proto;
3854			PF_ACPY(&key.addr[sidx], &pnl->saddr, pnl->af);
3855			key.port[sidx] = pnl->sport;
3856			PF_ACPY(&key.addr[didx], &pnl->daddr, pnl->af);
3857			key.port[didx] = pnl->dport;
3858
3859			state = pf_find_state_all(&key, direction, &m);
3860			if (state == NULL) {
3861				error = ENOENT;
3862			} else {
3863				if (m > 1) {
3864					PF_STATE_UNLOCK(state);
3865					error = E2BIG;	/* more than one state */
3866				} else {
3867					sk = state->key[sidx];
3868					PF_ACPY(&pnl->rsaddr, &sk->addr[sidx], sk->af);
3869					pnl->rsport = sk->port[sidx];
3870					PF_ACPY(&pnl->rdaddr, &sk->addr[didx], sk->af);
3871					pnl->rdport = sk->port[didx];
3872					PF_STATE_UNLOCK(state);
3873				}
3874			}
3875		}
3876		break;
3877	}
3878
3879	case DIOCSETTIMEOUT: {
3880		struct pfioc_tm	*pt = (struct pfioc_tm *)addr;
3881
3882		error = pf_ioctl_set_timeout(pt->timeout, pt->seconds,
3883		    &pt->seconds);
3884		break;
3885	}
3886
3887	case DIOCGETTIMEOUT: {
3888		struct pfioc_tm	*pt = (struct pfioc_tm *)addr;
3889
3890		error = pf_ioctl_get_timeout(pt->timeout, &pt->seconds);
3891		break;
3892	}
3893
3894	case DIOCGETLIMIT: {
3895		struct pfioc_limit	*pl = (struct pfioc_limit *)addr;
3896
3897		if (pl->index < 0 || pl->index >= PF_LIMIT_MAX) {
3898			error = EINVAL;
3899			break;
3900		}
3901		PF_RULES_RLOCK();
3902		pl->limit = V_pf_limits[pl->index].limit;
3903		PF_RULES_RUNLOCK();
3904		break;
3905	}
3906
3907	case DIOCSETLIMIT: {
3908		struct pfioc_limit	*pl = (struct pfioc_limit *)addr;
3909		int			 old_limit;
3910
3911		PF_RULES_WLOCK();
3912		if (pl->index < 0 || pl->index >= PF_LIMIT_MAX ||
3913		    V_pf_limits[pl->index].zone == NULL) {
3914			PF_RULES_WUNLOCK();
3915			error = EINVAL;
3916			break;
3917		}
3918		uma_zone_set_max(V_pf_limits[pl->index].zone, pl->limit);
3919		old_limit = V_pf_limits[pl->index].limit;
3920		V_pf_limits[pl->index].limit = pl->limit;
3921		pl->limit = old_limit;
3922		PF_RULES_WUNLOCK();
3923		break;
3924	}
3925
3926	case DIOCSETDEBUG: {
3927		u_int32_t	*level = (u_int32_t *)addr;
3928
3929		PF_RULES_WLOCK();
3930		V_pf_status.debug = *level;
3931		PF_RULES_WUNLOCK();
3932		break;
3933	}
3934
3935	case DIOCCLRRULECTRS: {
3936		/* obsoleted by DIOCGETRULE with action=PF_GET_CLR_CNTR */
3937		struct pf_kruleset	*ruleset = &pf_main_ruleset;
3938		struct pf_krule		*rule;
3939
3940		PF_RULES_WLOCK();
3941		TAILQ_FOREACH(rule,
3942		    ruleset->rules[PF_RULESET_FILTER].active.ptr, entries) {
3943			pf_counter_u64_zero(&rule->evaluations);
3944			for (int i = 0; i < 2; i++) {
3945				pf_counter_u64_zero(&rule->packets[i]);
3946				pf_counter_u64_zero(&rule->bytes[i]);
3947			}
3948		}
3949		PF_RULES_WUNLOCK();
3950		break;
3951	}
3952
3953	case DIOCGIFSPEEDV0:
3954	case DIOCGIFSPEEDV1: {
3955		struct pf_ifspeed_v1	*psp = (struct pf_ifspeed_v1 *)addr;
3956		struct pf_ifspeed_v1	ps;
3957		struct ifnet		*ifp;
3958
3959		if (psp->ifname[0] == '\0') {
3960			error = EINVAL;
3961			break;
3962		}
3963
3964		error = pf_user_strcpy(ps.ifname, psp->ifname, IFNAMSIZ);
3965		if (error != 0)
3966			break;
3967		ifp = ifunit(ps.ifname);
3968		if (ifp != NULL) {
3969			psp->baudrate32 =
3970			    (u_int32_t)uqmin(ifp->if_baudrate, UINT_MAX);
3971			if (cmd == DIOCGIFSPEEDV1)
3972				psp->baudrate = ifp->if_baudrate;
3973		} else {
3974			error = EINVAL;
3975		}
3976		break;
3977	}
3978
3979#ifdef ALTQ
3980	case DIOCSTARTALTQ: {
3981		struct pf_altq		*altq;
3982
3983		PF_RULES_WLOCK();
3984		/* enable all altq interfaces on active list */
3985		TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) {
3986			if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
3987				error = pf_enable_altq(altq);
3988				if (error != 0)
3989					break;
3990			}
3991		}
3992		if (error == 0)
3993			V_pf_altq_running = 1;
3994		PF_RULES_WUNLOCK();
3995		DPFPRINTF(PF_DEBUG_MISC, ("altq: started\n"));
3996		break;
3997	}
3998
3999	case DIOCSTOPALTQ: {
4000		struct pf_altq		*altq;
4001
4002		PF_RULES_WLOCK();
4003		/* disable all altq interfaces on active list */
4004		TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) {
4005			if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
4006				error = pf_disable_altq(altq);
4007				if (error != 0)
4008					break;
4009			}
4010		}
4011		if (error == 0)
4012			V_pf_altq_running = 0;
4013		PF_RULES_WUNLOCK();
4014		DPFPRINTF(PF_DEBUG_MISC, ("altq: stopped\n"));
4015		break;
4016	}
4017
4018	case DIOCADDALTQV0:
4019	case DIOCADDALTQV1: {
4020		struct pfioc_altq_v1	*pa = (struct pfioc_altq_v1 *)addr;
4021		struct pf_altq		*altq, *a;
4022		struct ifnet		*ifp;
4023
4024		altq = malloc(sizeof(*altq), M_PFALTQ, M_WAITOK | M_ZERO);
4025		error = pf_import_kaltq(pa, altq, IOCPARM_LEN(cmd));
4026		if (error)
4027			break;
4028		altq->local_flags = 0;
4029
4030		PF_RULES_WLOCK();
4031		if (pa->ticket != V_ticket_altqs_inactive) {
4032			PF_RULES_WUNLOCK();
4033			free(altq, M_PFALTQ);
4034			error = EBUSY;
4035			break;
4036		}
4037
4038		/*
4039		 * if this is for a queue, find the discipline and
4040		 * copy the necessary fields
4041		 */
4042		if (altq->qname[0] != 0) {
4043			if ((altq->qid = pf_qname2qid(altq->qname)) == 0) {
4044				PF_RULES_WUNLOCK();
4045				error = EBUSY;
4046				free(altq, M_PFALTQ);
4047				break;
4048			}
4049			altq->altq_disc = NULL;
4050			TAILQ_FOREACH(a, V_pf_altq_ifs_inactive, entries) {
4051				if (strncmp(a->ifname, altq->ifname,
4052				    IFNAMSIZ) == 0) {
4053					altq->altq_disc = a->altq_disc;
4054					break;
4055				}
4056			}
4057		}
4058
4059		if ((ifp = ifunit(altq->ifname)) == NULL)
4060			altq->local_flags |= PFALTQ_FLAG_IF_REMOVED;
4061		else
4062			error = altq_add(ifp, altq);
4063
4064		if (error) {
4065			PF_RULES_WUNLOCK();
4066			free(altq, M_PFALTQ);
4067			break;
4068		}
4069
4070		if (altq->qname[0] != 0)
4071			TAILQ_INSERT_TAIL(V_pf_altqs_inactive, altq, entries);
4072		else
4073			TAILQ_INSERT_TAIL(V_pf_altq_ifs_inactive, altq, entries);
4074		/* version error check done on import above */
4075		pf_export_kaltq(altq, pa, IOCPARM_LEN(cmd));
4076		PF_RULES_WUNLOCK();
4077		break;
4078	}
4079
4080	case DIOCGETALTQSV0:
4081	case DIOCGETALTQSV1: {
4082		struct pfioc_altq_v1	*pa = (struct pfioc_altq_v1 *)addr;
4083		struct pf_altq		*altq;
4084
4085		PF_RULES_RLOCK();
4086		pa->nr = 0;
4087		TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries)
4088			pa->nr++;
4089		TAILQ_FOREACH(altq, V_pf_altqs_active, entries)
4090			pa->nr++;
4091		pa->ticket = V_ticket_altqs_active;
4092		PF_RULES_RUNLOCK();
4093		break;
4094	}
4095
4096	case DIOCGETALTQV0:
4097	case DIOCGETALTQV1: {
4098		struct pfioc_altq_v1	*pa = (struct pfioc_altq_v1 *)addr;
4099		struct pf_altq		*altq;
4100
4101		PF_RULES_RLOCK();
4102		if (pa->ticket != V_ticket_altqs_active) {
4103			PF_RULES_RUNLOCK();
4104			error = EBUSY;
4105			break;
4106		}
4107		altq = pf_altq_get_nth_active(pa->nr);
4108		if (altq == NULL) {
4109			PF_RULES_RUNLOCK();
4110			error = EBUSY;
4111			break;
4112		}
4113		pf_export_kaltq(altq, pa, IOCPARM_LEN(cmd));
4114		PF_RULES_RUNLOCK();
4115		break;
4116	}
4117
4118	case DIOCCHANGEALTQV0:
4119	case DIOCCHANGEALTQV1:
4120		/* CHANGEALTQ not supported yet! */
4121		error = ENODEV;
4122		break;
4123
4124	case DIOCGETQSTATSV0:
4125	case DIOCGETQSTATSV1: {
4126		struct pfioc_qstats_v1	*pq = (struct pfioc_qstats_v1 *)addr;
4127		struct pf_altq		*altq;
4128		int			 nbytes;
4129		u_int32_t		 version;
4130
4131		PF_RULES_RLOCK();
4132		if (pq->ticket != V_ticket_altqs_active) {
4133			PF_RULES_RUNLOCK();
4134			error = EBUSY;
4135			break;
4136		}
4137		nbytes = pq->nbytes;
4138		altq = pf_altq_get_nth_active(pq->nr);
4139		if (altq == NULL) {
4140			PF_RULES_RUNLOCK();
4141			error = EBUSY;
4142			break;
4143		}
4144
4145		if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) != 0) {
4146			PF_RULES_RUNLOCK();
4147			error = ENXIO;
4148			break;
4149		}
4150		PF_RULES_RUNLOCK();
4151		if (cmd == DIOCGETQSTATSV0)
4152			version = 0;  /* DIOCGETQSTATSV0 means stats struct v0 */
4153		else
4154			version = pq->version;
4155		error = altq_getqstats(altq, pq->buf, &nbytes, version);
4156		if (error == 0) {
4157			pq->scheduler = altq->scheduler;
4158			pq->nbytes = nbytes;
4159		}
4160		break;
4161	}
4162#endif /* ALTQ */
4163
4164	case DIOCBEGINADDRS: {
4165		struct pfioc_pooladdr	*pp = (struct pfioc_pooladdr *)addr;
4166
4167		PF_RULES_WLOCK();
4168		pf_empty_kpool(&V_pf_pabuf);
4169		pp->ticket = ++V_ticket_pabuf;
4170		PF_RULES_WUNLOCK();
4171		break;
4172	}
4173
4174	case DIOCADDADDR: {
4175		struct pfioc_pooladdr	*pp = (struct pfioc_pooladdr *)addr;
4176		struct pf_kpooladdr	*pa;
4177		struct pfi_kkif		*kif = NULL;
4178
4179#ifndef INET
4180		if (pp->af == AF_INET) {
4181			error = EAFNOSUPPORT;
4182			break;
4183		}
4184#endif /* INET */
4185#ifndef INET6
4186		if (pp->af == AF_INET6) {
4187			error = EAFNOSUPPORT;
4188			break;
4189		}
4190#endif /* INET6 */
4191		if (pp->addr.addr.type != PF_ADDR_ADDRMASK &&
4192		    pp->addr.addr.type != PF_ADDR_DYNIFTL &&
4193		    pp->addr.addr.type != PF_ADDR_TABLE) {
4194			error = EINVAL;
4195			break;
4196		}
4197		if (pp->addr.addr.p.dyn != NULL) {
4198			error = EINVAL;
4199			break;
4200		}
4201		pa = malloc(sizeof(*pa), M_PFRULE, M_WAITOK);
4202		error = pf_pooladdr_to_kpooladdr(&pp->addr, pa);
4203		if (error != 0)
4204			break;
4205		if (pa->ifname[0])
4206			kif = pf_kkif_create(M_WAITOK);
4207		PF_RULES_WLOCK();
4208		if (pp->ticket != V_ticket_pabuf) {
4209			PF_RULES_WUNLOCK();
4210			if (pa->ifname[0])
4211				pf_kkif_free(kif);
4212			free(pa, M_PFRULE);
4213			error = EBUSY;
4214			break;
4215		}
4216		if (pa->ifname[0]) {
4217			pa->kif = pfi_kkif_attach(kif, pa->ifname);
4218			kif = NULL;
4219			pfi_kkif_ref(pa->kif);
4220		} else
4221			pa->kif = NULL;
4222		if (pa->addr.type == PF_ADDR_DYNIFTL && ((error =
4223		    pfi_dynaddr_setup(&pa->addr, pp->af)) != 0)) {
4224			if (pa->ifname[0])
4225				pfi_kkif_unref(pa->kif);
4226			PF_RULES_WUNLOCK();
4227			free(pa, M_PFRULE);
4228			break;
4229		}
4230		TAILQ_INSERT_TAIL(&V_pf_pabuf, pa, entries);
4231		PF_RULES_WUNLOCK();
4232		break;
4233	}
4234
4235	case DIOCGETADDRS: {
4236		struct pfioc_pooladdr	*pp = (struct pfioc_pooladdr *)addr;
4237		struct pf_kpool		*pool;
4238		struct pf_kpooladdr	*pa;
4239
4240		pp->anchor[sizeof(pp->anchor) - 1] = 0;
4241		pp->nr = 0;
4242
4243		PF_RULES_RLOCK();
4244		pool = pf_get_kpool(pp->anchor, pp->ticket, pp->r_action,
4245		    pp->r_num, 0, 1, 0);
4246		if (pool == NULL) {
4247			PF_RULES_RUNLOCK();
4248			error = EBUSY;
4249			break;
4250		}
4251		TAILQ_FOREACH(pa, &pool->list, entries)
4252			pp->nr++;
4253		PF_RULES_RUNLOCK();
4254		break;
4255	}
4256
4257	case DIOCGETADDR: {
4258		struct pfioc_pooladdr	*pp = (struct pfioc_pooladdr *)addr;
4259		struct pf_kpool		*pool;
4260		struct pf_kpooladdr	*pa;
4261		u_int32_t		 nr = 0;
4262
4263		pp->anchor[sizeof(pp->anchor) - 1] = 0;
4264
4265		PF_RULES_RLOCK();
4266		pool = pf_get_kpool(pp->anchor, pp->ticket, pp->r_action,
4267		    pp->r_num, 0, 1, 1);
4268		if (pool == NULL) {
4269			PF_RULES_RUNLOCK();
4270			error = EBUSY;
4271			break;
4272		}
4273		pa = TAILQ_FIRST(&pool->list);
4274		while ((pa != NULL) && (nr < pp->nr)) {
4275			pa = TAILQ_NEXT(pa, entries);
4276			nr++;
4277		}
4278		if (pa == NULL) {
4279			PF_RULES_RUNLOCK();
4280			error = EBUSY;
4281			break;
4282		}
4283		pf_kpooladdr_to_pooladdr(pa, &pp->addr);
4284		pf_addr_copyout(&pp->addr.addr);
4285		PF_RULES_RUNLOCK();
4286		break;
4287	}
4288
4289	case DIOCCHANGEADDR: {
4290		struct pfioc_pooladdr	*pca = (struct pfioc_pooladdr *)addr;
4291		struct pf_kpool		*pool;
4292		struct pf_kpooladdr	*oldpa = NULL, *newpa = NULL;
4293		struct pf_kruleset	*ruleset;
4294		struct pfi_kkif		*kif = NULL;
4295
4296		pca->anchor[sizeof(pca->anchor) - 1] = 0;
4297
4298		if (pca->action < PF_CHANGE_ADD_HEAD ||
4299		    pca->action > PF_CHANGE_REMOVE) {
4300			error = EINVAL;
4301			break;
4302		}
4303		if (pca->addr.addr.type != PF_ADDR_ADDRMASK &&
4304		    pca->addr.addr.type != PF_ADDR_DYNIFTL &&
4305		    pca->addr.addr.type != PF_ADDR_TABLE) {
4306			error = EINVAL;
4307			break;
4308		}
4309		if (pca->addr.addr.p.dyn != NULL) {
4310			error = EINVAL;
4311			break;
4312		}
4313
4314		if (pca->action != PF_CHANGE_REMOVE) {
4315#ifndef INET
4316			if (pca->af == AF_INET) {
4317				error = EAFNOSUPPORT;
4318				break;
4319			}
4320#endif /* INET */
4321#ifndef INET6
4322			if (pca->af == AF_INET6) {
4323				error = EAFNOSUPPORT;
4324				break;
4325			}
4326#endif /* INET6 */
4327			newpa = malloc(sizeof(*newpa), M_PFRULE, M_WAITOK);
4328			bcopy(&pca->addr, newpa, sizeof(struct pf_pooladdr));
4329			if (newpa->ifname[0])
4330				kif = pf_kkif_create(M_WAITOK);
4331			newpa->kif = NULL;
4332		}
4333#define	ERROUT(x)	ERROUT_IOCTL(DIOCCHANGEADDR_error, x)
4334		PF_RULES_WLOCK();
4335		ruleset = pf_find_kruleset(pca->anchor);
4336		if (ruleset == NULL)
4337			ERROUT(EBUSY);
4338
4339		pool = pf_get_kpool(pca->anchor, pca->ticket, pca->r_action,
4340		    pca->r_num, pca->r_last, 1, 1);
4341		if (pool == NULL)
4342			ERROUT(EBUSY);
4343
4344		if (pca->action != PF_CHANGE_REMOVE) {
4345			if (newpa->ifname[0]) {
4346				newpa->kif = pfi_kkif_attach(kif, newpa->ifname);
4347				pfi_kkif_ref(newpa->kif);
4348				kif = NULL;
4349			}
4350
4351			switch (newpa->addr.type) {
4352			case PF_ADDR_DYNIFTL:
4353				error = pfi_dynaddr_setup(&newpa->addr,
4354				    pca->af);
4355				break;
4356			case PF_ADDR_TABLE:
4357				newpa->addr.p.tbl = pfr_attach_table(ruleset,
4358				    newpa->addr.v.tblname);
4359				if (newpa->addr.p.tbl == NULL)
4360					error = ENOMEM;
4361				break;
4362			}
4363			if (error)
4364				goto DIOCCHANGEADDR_error;
4365		}
4366
4367		switch (pca->action) {
4368		case PF_CHANGE_ADD_HEAD:
4369			oldpa = TAILQ_FIRST(&pool->list);
4370			break;
4371		case PF_CHANGE_ADD_TAIL:
4372			oldpa = TAILQ_LAST(&pool->list, pf_kpalist);
4373			break;
4374		default:
4375			oldpa = TAILQ_FIRST(&pool->list);
4376			for (int i = 0; oldpa && i < pca->nr; i++)
4377				oldpa = TAILQ_NEXT(oldpa, entries);
4378
4379			if (oldpa == NULL)
4380				ERROUT(EINVAL);
4381		}
4382
4383		if (pca->action == PF_CHANGE_REMOVE) {
4384			TAILQ_REMOVE(&pool->list, oldpa, entries);
4385			switch (oldpa->addr.type) {
4386			case PF_ADDR_DYNIFTL:
4387				pfi_dynaddr_remove(oldpa->addr.p.dyn);
4388				break;
4389			case PF_ADDR_TABLE:
4390				pfr_detach_table(oldpa->addr.p.tbl);
4391				break;
4392			}
4393			if (oldpa->kif)
4394				pfi_kkif_unref(oldpa->kif);
4395			free(oldpa, M_PFRULE);
4396		} else {
4397			if (oldpa == NULL)
4398				TAILQ_INSERT_TAIL(&pool->list, newpa, entries);
4399			else if (pca->action == PF_CHANGE_ADD_HEAD ||
4400			    pca->action == PF_CHANGE_ADD_BEFORE)
4401				TAILQ_INSERT_BEFORE(oldpa, newpa, entries);
4402			else
4403				TAILQ_INSERT_AFTER(&pool->list, oldpa,
4404				    newpa, entries);
4405		}
4406
4407		pool->cur = TAILQ_FIRST(&pool->list);
4408		PF_ACPY(&pool->counter, &pool->cur->addr.v.a.addr, pca->af);
4409		PF_RULES_WUNLOCK();
4410		break;
4411
4412#undef ERROUT
4413DIOCCHANGEADDR_error:
4414		if (newpa != NULL) {
4415			if (newpa->kif)
4416				pfi_kkif_unref(newpa->kif);
4417			free(newpa, M_PFRULE);
4418		}
4419		PF_RULES_WUNLOCK();
4420		pf_kkif_free(kif);
4421		break;
4422	}
4423
4424	case DIOCGETRULESETS: {
4425		struct pfioc_ruleset	*pr = (struct pfioc_ruleset *)addr;
4426		struct pf_kruleset	*ruleset;
4427		struct pf_kanchor	*anchor;
4428
4429		pr->path[sizeof(pr->path) - 1] = 0;
4430
4431		PF_RULES_RLOCK();
4432		if ((ruleset = pf_find_kruleset(pr->path)) == NULL) {
4433			PF_RULES_RUNLOCK();
4434			error = ENOENT;
4435			break;
4436		}
4437		pr->nr = 0;
4438		if (ruleset->anchor == NULL) {
4439			/* XXX kludge for pf_main_ruleset */
4440			RB_FOREACH(anchor, pf_kanchor_global, &V_pf_anchors)
4441				if (anchor->parent == NULL)
4442					pr->nr++;
4443		} else {
4444			RB_FOREACH(anchor, pf_kanchor_node,
4445			    &ruleset->anchor->children)
4446				pr->nr++;
4447		}
4448		PF_RULES_RUNLOCK();
4449		break;
4450	}
4451
4452	case DIOCGETRULESET: {
4453		struct pfioc_ruleset	*pr = (struct pfioc_ruleset *)addr;
4454		struct pf_kruleset	*ruleset;
4455		struct pf_kanchor	*anchor;
4456		u_int32_t		 nr = 0;
4457
4458		pr->path[sizeof(pr->path) - 1] = 0;
4459
4460		PF_RULES_RLOCK();
4461		if ((ruleset = pf_find_kruleset(pr->path)) == NULL) {
4462			PF_RULES_RUNLOCK();
4463			error = ENOENT;
4464			break;
4465		}
4466		pr->name[0] = 0;
4467		if (ruleset->anchor == NULL) {
4468			/* XXX kludge for pf_main_ruleset */
4469			RB_FOREACH(anchor, pf_kanchor_global, &V_pf_anchors)
4470				if (anchor->parent == NULL && nr++ == pr->nr) {
4471					strlcpy(pr->name, anchor->name,
4472					    sizeof(pr->name));
4473					break;
4474				}
4475		} else {
4476			RB_FOREACH(anchor, pf_kanchor_node,
4477			    &ruleset->anchor->children)
4478				if (nr++ == pr->nr) {
4479					strlcpy(pr->name, anchor->name,
4480					    sizeof(pr->name));
4481					break;
4482				}
4483		}
4484		if (!pr->name[0])
4485			error = EBUSY;
4486		PF_RULES_RUNLOCK();
4487		break;
4488	}
4489
4490	case DIOCRCLRTABLES: {
4491		struct pfioc_table *io = (struct pfioc_table *)addr;
4492
4493		if (io->pfrio_esize != 0) {
4494			error = ENODEV;
4495			break;
4496		}
4497		PF_RULES_WLOCK();
4498		error = pfr_clr_tables(&io->pfrio_table, &io->pfrio_ndel,
4499		    io->pfrio_flags | PFR_FLAG_USERIOCTL);
4500		PF_RULES_WUNLOCK();
4501		break;
4502	}
4503
4504	case DIOCRADDTABLES: {
4505		struct pfioc_table *io = (struct pfioc_table *)addr;
4506		struct pfr_table *pfrts;
4507		size_t totlen;
4508
4509		if (io->pfrio_esize != sizeof(struct pfr_table)) {
4510			error = ENODEV;
4511			break;
4512		}
4513
4514		if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount ||
4515		    WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) {
4516			error = ENOMEM;
4517			break;
4518		}
4519
4520		totlen = io->pfrio_size * sizeof(struct pfr_table);
4521		pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
4522		    M_TEMP, M_WAITOK);
4523		error = copyin(io->pfrio_buffer, pfrts, totlen);
4524		if (error) {
4525			free(pfrts, M_TEMP);
4526			break;
4527		}
4528		PF_RULES_WLOCK();
4529		error = pfr_add_tables(pfrts, io->pfrio_size,
4530		    &io->pfrio_nadd, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4531		PF_RULES_WUNLOCK();
4532		free(pfrts, M_TEMP);
4533		break;
4534	}
4535
4536	case DIOCRDELTABLES: {
4537		struct pfioc_table *io = (struct pfioc_table *)addr;
4538		struct pfr_table *pfrts;
4539		size_t totlen;
4540
4541		if (io->pfrio_esize != sizeof(struct pfr_table)) {
4542			error = ENODEV;
4543			break;
4544		}
4545
4546		if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount ||
4547		    WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) {
4548			error = ENOMEM;
4549			break;
4550		}
4551
4552		totlen = io->pfrio_size * sizeof(struct pfr_table);
4553		pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
4554		    M_TEMP, M_WAITOK);
4555		error = copyin(io->pfrio_buffer, pfrts, totlen);
4556		if (error) {
4557			free(pfrts, M_TEMP);
4558			break;
4559		}
4560		PF_RULES_WLOCK();
4561		error = pfr_del_tables(pfrts, io->pfrio_size,
4562		    &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4563		PF_RULES_WUNLOCK();
4564		free(pfrts, M_TEMP);
4565		break;
4566	}
4567
4568	case DIOCRGETTABLES: {
4569		struct pfioc_table *io = (struct pfioc_table *)addr;
4570		struct pfr_table *pfrts;
4571		size_t totlen;
4572		int n;
4573
4574		if (io->pfrio_esize != sizeof(struct pfr_table)) {
4575			error = ENODEV;
4576			break;
4577		}
4578		PF_RULES_RLOCK();
4579		n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
4580		if (n < 0) {
4581			PF_RULES_RUNLOCK();
4582			error = EINVAL;
4583			break;
4584		}
4585		io->pfrio_size = min(io->pfrio_size, n);
4586
4587		totlen = io->pfrio_size * sizeof(struct pfr_table);
4588
4589		pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
4590		    M_TEMP, M_NOWAIT | M_ZERO);
4591		if (pfrts == NULL) {
4592			error = ENOMEM;
4593			PF_RULES_RUNLOCK();
4594			break;
4595		}
4596		error = pfr_get_tables(&io->pfrio_table, pfrts,
4597		    &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4598		PF_RULES_RUNLOCK();
4599		if (error == 0)
4600			error = copyout(pfrts, io->pfrio_buffer, totlen);
4601		free(pfrts, M_TEMP);
4602		break;
4603	}
4604
4605	case DIOCRGETTSTATS: {
4606		struct pfioc_table *io = (struct pfioc_table *)addr;
4607		struct pfr_tstats *pfrtstats;
4608		size_t totlen;
4609		int n;
4610
4611		if (io->pfrio_esize != sizeof(struct pfr_tstats)) {
4612			error = ENODEV;
4613			break;
4614		}
4615		PF_TABLE_STATS_LOCK();
4616		PF_RULES_RLOCK();
4617		n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
4618		if (n < 0) {
4619			PF_RULES_RUNLOCK();
4620			PF_TABLE_STATS_UNLOCK();
4621			error = EINVAL;
4622			break;
4623		}
4624		io->pfrio_size = min(io->pfrio_size, n);
4625
4626		totlen = io->pfrio_size * sizeof(struct pfr_tstats);
4627		pfrtstats = mallocarray(io->pfrio_size,
4628		    sizeof(struct pfr_tstats), M_TEMP, M_NOWAIT | M_ZERO);
4629		if (pfrtstats == NULL) {
4630			error = ENOMEM;
4631			PF_RULES_RUNLOCK();
4632			PF_TABLE_STATS_UNLOCK();
4633			break;
4634		}
4635		error = pfr_get_tstats(&io->pfrio_table, pfrtstats,
4636		    &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4637		PF_RULES_RUNLOCK();
4638		PF_TABLE_STATS_UNLOCK();
4639		if (error == 0)
4640			error = copyout(pfrtstats, io->pfrio_buffer, totlen);
4641		free(pfrtstats, M_TEMP);
4642		break;
4643	}
4644
4645	case DIOCRCLRTSTATS: {
4646		struct pfioc_table *io = (struct pfioc_table *)addr;
4647		struct pfr_table *pfrts;
4648		size_t totlen;
4649
4650		if (io->pfrio_esize != sizeof(struct pfr_table)) {
4651			error = ENODEV;
4652			break;
4653		}
4654
4655		if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount ||
4656		    WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) {
4657			/* We used to count tables and use the minimum required
4658			 * size, so we didn't fail on overly large requests.
4659			 * Keep doing so. */
4660			io->pfrio_size = pf_ioctl_maxcount;
4661			break;
4662		}
4663
4664		totlen = io->pfrio_size * sizeof(struct pfr_table);
4665		pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
4666		    M_TEMP, M_WAITOK);
4667		error = copyin(io->pfrio_buffer, pfrts, totlen);
4668		if (error) {
4669			free(pfrts, M_TEMP);
4670			break;
4671		}
4672
4673		PF_TABLE_STATS_LOCK();
4674		PF_RULES_RLOCK();
4675		error = pfr_clr_tstats(pfrts, io->pfrio_size,
4676		    &io->pfrio_nzero, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4677		PF_RULES_RUNLOCK();
4678		PF_TABLE_STATS_UNLOCK();
4679		free(pfrts, M_TEMP);
4680		break;
4681	}
4682
4683	case DIOCRSETTFLAGS: {
4684		struct pfioc_table *io = (struct pfioc_table *)addr;
4685		struct pfr_table *pfrts;
4686		size_t totlen;
4687		int n;
4688
4689		if (io->pfrio_esize != sizeof(struct pfr_table)) {
4690			error = ENODEV;
4691			break;
4692		}
4693
4694		PF_RULES_RLOCK();
4695		n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
4696		if (n < 0) {
4697			PF_RULES_RUNLOCK();
4698			error = EINVAL;
4699			break;
4700		}
4701
4702		io->pfrio_size = min(io->pfrio_size, n);
4703		PF_RULES_RUNLOCK();
4704
4705		totlen = io->pfrio_size * sizeof(struct pfr_table);
4706		pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
4707		    M_TEMP, M_WAITOK);
4708		error = copyin(io->pfrio_buffer, pfrts, totlen);
4709		if (error) {
4710			free(pfrts, M_TEMP);
4711			break;
4712		}
4713		PF_RULES_WLOCK();
4714		error = pfr_set_tflags(pfrts, io->pfrio_size,
4715		    io->pfrio_setflag, io->pfrio_clrflag, &io->pfrio_nchange,
4716		    &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4717		PF_RULES_WUNLOCK();
4718		free(pfrts, M_TEMP);
4719		break;
4720	}
4721
4722	case DIOCRCLRADDRS: {
4723		struct pfioc_table *io = (struct pfioc_table *)addr;
4724
4725		if (io->pfrio_esize != 0) {
4726			error = ENODEV;
4727			break;
4728		}
4729		PF_RULES_WLOCK();
4730		error = pfr_clr_addrs(&io->pfrio_table, &io->pfrio_ndel,
4731		    io->pfrio_flags | PFR_FLAG_USERIOCTL);
4732		PF_RULES_WUNLOCK();
4733		break;
4734	}
4735
4736	case DIOCRADDADDRS: {
4737		struct pfioc_table *io = (struct pfioc_table *)addr;
4738		struct pfr_addr *pfras;
4739		size_t totlen;
4740
4741		if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4742			error = ENODEV;
4743			break;
4744		}
4745		if (io->pfrio_size < 0 ||
4746		    io->pfrio_size > pf_ioctl_maxcount ||
4747		    WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4748			error = EINVAL;
4749			break;
4750		}
4751		totlen = io->pfrio_size * sizeof(struct pfr_addr);
4752		pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4753		    M_TEMP, M_WAITOK);
4754		error = copyin(io->pfrio_buffer, pfras, totlen);
4755		if (error) {
4756			free(pfras, M_TEMP);
4757			break;
4758		}
4759		PF_RULES_WLOCK();
4760		error = pfr_add_addrs(&io->pfrio_table, pfras,
4761		    io->pfrio_size, &io->pfrio_nadd, io->pfrio_flags |
4762		    PFR_FLAG_USERIOCTL);
4763		PF_RULES_WUNLOCK();
4764		if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
4765			error = copyout(pfras, io->pfrio_buffer, totlen);
4766		free(pfras, M_TEMP);
4767		break;
4768	}
4769
4770	case DIOCRDELADDRS: {
4771		struct pfioc_table *io = (struct pfioc_table *)addr;
4772		struct pfr_addr *pfras;
4773		size_t totlen;
4774
4775		if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4776			error = ENODEV;
4777			break;
4778		}
4779		if (io->pfrio_size < 0 ||
4780		    io->pfrio_size > pf_ioctl_maxcount ||
4781		    WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4782			error = EINVAL;
4783			break;
4784		}
4785		totlen = io->pfrio_size * sizeof(struct pfr_addr);
4786		pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4787		    M_TEMP, M_WAITOK);
4788		error = copyin(io->pfrio_buffer, pfras, totlen);
4789		if (error) {
4790			free(pfras, M_TEMP);
4791			break;
4792		}
4793		PF_RULES_WLOCK();
4794		error = pfr_del_addrs(&io->pfrio_table, pfras,
4795		    io->pfrio_size, &io->pfrio_ndel, io->pfrio_flags |
4796		    PFR_FLAG_USERIOCTL);
4797		PF_RULES_WUNLOCK();
4798		if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
4799			error = copyout(pfras, io->pfrio_buffer, totlen);
4800		free(pfras, M_TEMP);
4801		break;
4802	}
4803
4804	case DIOCRSETADDRS: {
4805		struct pfioc_table *io = (struct pfioc_table *)addr;
4806		struct pfr_addr *pfras;
4807		size_t totlen, count;
4808
4809		if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4810			error = ENODEV;
4811			break;
4812		}
4813		if (io->pfrio_size < 0 || io->pfrio_size2 < 0) {
4814			error = EINVAL;
4815			break;
4816		}
4817		count = max(io->pfrio_size, io->pfrio_size2);
4818		if (count > pf_ioctl_maxcount ||
4819		    WOULD_OVERFLOW(count, sizeof(struct pfr_addr))) {
4820			error = EINVAL;
4821			break;
4822		}
4823		totlen = count * sizeof(struct pfr_addr);
4824		pfras = mallocarray(count, sizeof(struct pfr_addr), M_TEMP,
4825		    M_WAITOK);
4826		error = copyin(io->pfrio_buffer, pfras, totlen);
4827		if (error) {
4828			free(pfras, M_TEMP);
4829			break;
4830		}
4831		PF_RULES_WLOCK();
4832		error = pfr_set_addrs(&io->pfrio_table, pfras,
4833		    io->pfrio_size, &io->pfrio_size2, &io->pfrio_nadd,
4834		    &io->pfrio_ndel, &io->pfrio_nchange, io->pfrio_flags |
4835		    PFR_FLAG_USERIOCTL, 0);
4836		PF_RULES_WUNLOCK();
4837		if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
4838			error = copyout(pfras, io->pfrio_buffer, totlen);
4839		free(pfras, M_TEMP);
4840		break;
4841	}
4842
4843	case DIOCRGETADDRS: {
4844		struct pfioc_table *io = (struct pfioc_table *)addr;
4845		struct pfr_addr *pfras;
4846		size_t totlen;
4847
4848		if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4849			error = ENODEV;
4850			break;
4851		}
4852		if (io->pfrio_size < 0 ||
4853		    io->pfrio_size > pf_ioctl_maxcount ||
4854		    WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4855			error = EINVAL;
4856			break;
4857		}
4858		totlen = io->pfrio_size * sizeof(struct pfr_addr);
4859		pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4860		    M_TEMP, M_WAITOK | M_ZERO);
4861		PF_RULES_RLOCK();
4862		error = pfr_get_addrs(&io->pfrio_table, pfras,
4863		    &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4864		PF_RULES_RUNLOCK();
4865		if (error == 0)
4866			error = copyout(pfras, io->pfrio_buffer, totlen);
4867		free(pfras, M_TEMP);
4868		break;
4869	}
4870
4871	case DIOCRGETASTATS: {
4872		struct pfioc_table *io = (struct pfioc_table *)addr;
4873		struct pfr_astats *pfrastats;
4874		size_t totlen;
4875
4876		if (io->pfrio_esize != sizeof(struct pfr_astats)) {
4877			error = ENODEV;
4878			break;
4879		}
4880		if (io->pfrio_size < 0 ||
4881		    io->pfrio_size > pf_ioctl_maxcount ||
4882		    WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_astats))) {
4883			error = EINVAL;
4884			break;
4885		}
4886		totlen = io->pfrio_size * sizeof(struct pfr_astats);
4887		pfrastats = mallocarray(io->pfrio_size,
4888		    sizeof(struct pfr_astats), M_TEMP, M_WAITOK | M_ZERO);
4889		PF_RULES_RLOCK();
4890		error = pfr_get_astats(&io->pfrio_table, pfrastats,
4891		    &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4892		PF_RULES_RUNLOCK();
4893		if (error == 0)
4894			error = copyout(pfrastats, io->pfrio_buffer, totlen);
4895		free(pfrastats, M_TEMP);
4896		break;
4897	}
4898
4899	case DIOCRCLRASTATS: {
4900		struct pfioc_table *io = (struct pfioc_table *)addr;
4901		struct pfr_addr *pfras;
4902		size_t totlen;
4903
4904		if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4905			error = ENODEV;
4906			break;
4907		}
4908		if (io->pfrio_size < 0 ||
4909		    io->pfrio_size > pf_ioctl_maxcount ||
4910		    WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4911			error = EINVAL;
4912			break;
4913		}
4914		totlen = io->pfrio_size * sizeof(struct pfr_addr);
4915		pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4916		    M_TEMP, M_WAITOK);
4917		error = copyin(io->pfrio_buffer, pfras, totlen);
4918		if (error) {
4919			free(pfras, M_TEMP);
4920			break;
4921		}
4922		PF_RULES_WLOCK();
4923		error = pfr_clr_astats(&io->pfrio_table, pfras,
4924		    io->pfrio_size, &io->pfrio_nzero, io->pfrio_flags |
4925		    PFR_FLAG_USERIOCTL);
4926		PF_RULES_WUNLOCK();
4927		if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
4928			error = copyout(pfras, io->pfrio_buffer, totlen);
4929		free(pfras, M_TEMP);
4930		break;
4931	}
4932
4933	case DIOCRTSTADDRS: {
4934		struct pfioc_table *io = (struct pfioc_table *)addr;
4935		struct pfr_addr *pfras;
4936		size_t totlen;
4937
4938		if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4939			error = ENODEV;
4940			break;
4941		}
4942		if (io->pfrio_size < 0 ||
4943		    io->pfrio_size > pf_ioctl_maxcount ||
4944		    WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4945			error = EINVAL;
4946			break;
4947		}
4948		totlen = io->pfrio_size * sizeof(struct pfr_addr);
4949		pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4950		    M_TEMP, M_WAITOK);
4951		error = copyin(io->pfrio_buffer, pfras, totlen);
4952		if (error) {
4953			free(pfras, M_TEMP);
4954			break;
4955		}
4956		PF_RULES_RLOCK();
4957		error = pfr_tst_addrs(&io->pfrio_table, pfras,
4958		    io->pfrio_size, &io->pfrio_nmatch, io->pfrio_flags |
4959		    PFR_FLAG_USERIOCTL);
4960		PF_RULES_RUNLOCK();
4961		if (error == 0)
4962			error = copyout(pfras, io->pfrio_buffer, totlen);
4963		free(pfras, M_TEMP);
4964		break;
4965	}
4966
4967	case DIOCRINADEFINE: {
4968		struct pfioc_table *io = (struct pfioc_table *)addr;
4969		struct pfr_addr *pfras;
4970		size_t totlen;
4971
4972		if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4973			error = ENODEV;
4974			break;
4975		}
4976		if (io->pfrio_size < 0 ||
4977		    io->pfrio_size > pf_ioctl_maxcount ||
4978		    WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4979			error = EINVAL;
4980			break;
4981		}
4982		totlen = io->pfrio_size * sizeof(struct pfr_addr);
4983		pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4984		    M_TEMP, M_WAITOK);
4985		error = copyin(io->pfrio_buffer, pfras, totlen);
4986		if (error) {
4987			free(pfras, M_TEMP);
4988			break;
4989		}
4990		PF_RULES_WLOCK();
4991		error = pfr_ina_define(&io->pfrio_table, pfras,
4992		    io->pfrio_size, &io->pfrio_nadd, &io->pfrio_naddr,
4993		    io->pfrio_ticket, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4994		PF_RULES_WUNLOCK();
4995		free(pfras, M_TEMP);
4996		break;
4997	}
4998
4999	case DIOCOSFPADD: {
5000		struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
5001		PF_RULES_WLOCK();
5002		error = pf_osfp_add(io);
5003		PF_RULES_WUNLOCK();
5004		break;
5005	}
5006
5007	case DIOCOSFPGET: {
5008		struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
5009		PF_RULES_RLOCK();
5010		error = pf_osfp_get(io);
5011		PF_RULES_RUNLOCK();
5012		break;
5013	}
5014
5015	case DIOCXBEGIN: {
5016		struct pfioc_trans	*io = (struct pfioc_trans *)addr;
5017		struct pfioc_trans_e	*ioes, *ioe;
5018		size_t			 totlen;
5019		int			 i;
5020
5021		if (io->esize != sizeof(*ioe)) {
5022			error = ENODEV;
5023			break;
5024		}
5025		if (io->size < 0 ||
5026		    io->size > pf_ioctl_maxcount ||
5027		    WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
5028			error = EINVAL;
5029			break;
5030		}
5031		totlen = sizeof(struct pfioc_trans_e) * io->size;
5032		ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
5033		    M_TEMP, M_WAITOK);
5034		error = copyin(io->array, ioes, totlen);
5035		if (error) {
5036			free(ioes, M_TEMP);
5037			break;
5038		}
5039		/* Ensure there's no more ethernet rules to clean up. */
5040		NET_EPOCH_DRAIN_CALLBACKS();
5041		PF_RULES_WLOCK();
5042		for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
5043			ioe->anchor[sizeof(ioe->anchor) - 1] = '\0';
5044			switch (ioe->rs_num) {
5045			case PF_RULESET_ETH:
5046				if ((error = pf_begin_eth(&ioe->ticket, ioe->anchor))) {
5047					PF_RULES_WUNLOCK();
5048					free(ioes, M_TEMP);
5049					goto fail;
5050				}
5051				break;
5052#ifdef ALTQ
5053			case PF_RULESET_ALTQ:
5054				if (ioe->anchor[0]) {
5055					PF_RULES_WUNLOCK();
5056					free(ioes, M_TEMP);
5057					error = EINVAL;
5058					goto fail;
5059				}
5060				if ((error = pf_begin_altq(&ioe->ticket))) {
5061					PF_RULES_WUNLOCK();
5062					free(ioes, M_TEMP);
5063					goto fail;
5064				}
5065				break;
5066#endif /* ALTQ */
5067			case PF_RULESET_TABLE:
5068			    {
5069				struct pfr_table table;
5070
5071				bzero(&table, sizeof(table));
5072				strlcpy(table.pfrt_anchor, ioe->anchor,
5073				    sizeof(table.pfrt_anchor));
5074				if ((error = pfr_ina_begin(&table,
5075				    &ioe->ticket, NULL, 0))) {
5076					PF_RULES_WUNLOCK();
5077					free(ioes, M_TEMP);
5078					goto fail;
5079				}
5080				break;
5081			    }
5082			default:
5083				if ((error = pf_begin_rules(&ioe->ticket,
5084				    ioe->rs_num, ioe->anchor))) {
5085					PF_RULES_WUNLOCK();
5086					free(ioes, M_TEMP);
5087					goto fail;
5088				}
5089				break;
5090			}
5091		}
5092		PF_RULES_WUNLOCK();
5093		error = copyout(ioes, io->array, totlen);
5094		free(ioes, M_TEMP);
5095		break;
5096	}
5097
5098	case DIOCXROLLBACK: {
5099		struct pfioc_trans	*io = (struct pfioc_trans *)addr;
5100		struct pfioc_trans_e	*ioe, *ioes;
5101		size_t			 totlen;
5102		int			 i;
5103
5104		if (io->esize != sizeof(*ioe)) {
5105			error = ENODEV;
5106			break;
5107		}
5108		if (io->size < 0 ||
5109		    io->size > pf_ioctl_maxcount ||
5110		    WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
5111			error = EINVAL;
5112			break;
5113		}
5114		totlen = sizeof(struct pfioc_trans_e) * io->size;
5115		ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
5116		    M_TEMP, M_WAITOK);
5117		error = copyin(io->array, ioes, totlen);
5118		if (error) {
5119			free(ioes, M_TEMP);
5120			break;
5121		}
5122		PF_RULES_WLOCK();
5123		for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
5124			ioe->anchor[sizeof(ioe->anchor) - 1] = '\0';
5125			switch (ioe->rs_num) {
5126			case PF_RULESET_ETH:
5127				if ((error = pf_rollback_eth(ioe->ticket,
5128				    ioe->anchor))) {
5129					PF_RULES_WUNLOCK();
5130					free(ioes, M_TEMP);
5131					goto fail; /* really bad */
5132				}
5133				break;
5134#ifdef ALTQ
5135			case PF_RULESET_ALTQ:
5136				if (ioe->anchor[0]) {
5137					PF_RULES_WUNLOCK();
5138					free(ioes, M_TEMP);
5139					error = EINVAL;
5140					goto fail;
5141				}
5142				if ((error = pf_rollback_altq(ioe->ticket))) {
5143					PF_RULES_WUNLOCK();
5144					free(ioes, M_TEMP);
5145					goto fail; /* really bad */
5146				}
5147				break;
5148#endif /* ALTQ */
5149			case PF_RULESET_TABLE:
5150			    {
5151				struct pfr_table table;
5152
5153				bzero(&table, sizeof(table));
5154				strlcpy(table.pfrt_anchor, ioe->anchor,
5155				    sizeof(table.pfrt_anchor));
5156				if ((error = pfr_ina_rollback(&table,
5157				    ioe->ticket, NULL, 0))) {
5158					PF_RULES_WUNLOCK();
5159					free(ioes, M_TEMP);
5160					goto fail; /* really bad */
5161				}
5162				break;
5163			    }
5164			default:
5165				if ((error = pf_rollback_rules(ioe->ticket,
5166				    ioe->rs_num, ioe->anchor))) {
5167					PF_RULES_WUNLOCK();
5168					free(ioes, M_TEMP);
5169					goto fail; /* really bad */
5170				}
5171				break;
5172			}
5173		}
5174		PF_RULES_WUNLOCK();
5175		free(ioes, M_TEMP);
5176		break;
5177	}
5178
5179	case DIOCXCOMMIT: {
5180		struct pfioc_trans	*io = (struct pfioc_trans *)addr;
5181		struct pfioc_trans_e	*ioe, *ioes;
5182		struct pf_kruleset	*rs;
5183		struct pf_keth_ruleset	*ers;
5184		size_t			 totlen;
5185		int			 i;
5186
5187		if (io->esize != sizeof(*ioe)) {
5188			error = ENODEV;
5189			break;
5190		}
5191
5192		if (io->size < 0 ||
5193		    io->size > pf_ioctl_maxcount ||
5194		    WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
5195			error = EINVAL;
5196			break;
5197		}
5198
5199		totlen = sizeof(struct pfioc_trans_e) * io->size;
5200		ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
5201		    M_TEMP, M_WAITOK);
5202		error = copyin(io->array, ioes, totlen);
5203		if (error) {
5204			free(ioes, M_TEMP);
5205			break;
5206		}
5207		PF_RULES_WLOCK();
5208		/* First makes sure everything will succeed. */
5209		for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
5210			ioe->anchor[sizeof(ioe->anchor) - 1] = 0;
5211			switch (ioe->rs_num) {
5212			case PF_RULESET_ETH:
5213				ers = pf_find_keth_ruleset(ioe->anchor);
5214				if (ers == NULL || ioe->ticket == 0 ||
5215				    ioe->ticket != ers->inactive.ticket) {
5216					PF_RULES_WUNLOCK();
5217					free(ioes, M_TEMP);
5218					error = EINVAL;
5219					goto fail;
5220				}
5221				break;
5222#ifdef ALTQ
5223			case PF_RULESET_ALTQ:
5224				if (ioe->anchor[0]) {
5225					PF_RULES_WUNLOCK();
5226					free(ioes, M_TEMP);
5227					error = EINVAL;
5228					goto fail;
5229				}
5230				if (!V_altqs_inactive_open || ioe->ticket !=
5231				    V_ticket_altqs_inactive) {
5232					PF_RULES_WUNLOCK();
5233					free(ioes, M_TEMP);
5234					error = EBUSY;
5235					goto fail;
5236				}
5237				break;
5238#endif /* ALTQ */
5239			case PF_RULESET_TABLE:
5240				rs = pf_find_kruleset(ioe->anchor);
5241				if (rs == NULL || !rs->topen || ioe->ticket !=
5242				    rs->tticket) {
5243					PF_RULES_WUNLOCK();
5244					free(ioes, M_TEMP);
5245					error = EBUSY;
5246					goto fail;
5247				}
5248				break;
5249			default:
5250				if (ioe->rs_num < 0 || ioe->rs_num >=
5251				    PF_RULESET_MAX) {
5252					PF_RULES_WUNLOCK();
5253					free(ioes, M_TEMP);
5254					error = EINVAL;
5255					goto fail;
5256				}
5257				rs = pf_find_kruleset(ioe->anchor);
5258				if (rs == NULL ||
5259				    !rs->rules[ioe->rs_num].inactive.open ||
5260				    rs->rules[ioe->rs_num].inactive.ticket !=
5261				    ioe->ticket) {
5262					PF_RULES_WUNLOCK();
5263					free(ioes, M_TEMP);
5264					error = EBUSY;
5265					goto fail;
5266				}
5267				break;
5268			}
5269		}
5270		/* Now do the commit - no errors should happen here. */
5271		for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
5272			switch (ioe->rs_num) {
5273			case PF_RULESET_ETH:
5274				if ((error = pf_commit_eth(ioe->ticket, ioe->anchor))) {
5275					PF_RULES_WUNLOCK();
5276					free(ioes, M_TEMP);
5277					goto fail; /* really bad */
5278				}
5279				break;
5280#ifdef ALTQ
5281			case PF_RULESET_ALTQ:
5282				if ((error = pf_commit_altq(ioe->ticket))) {
5283					PF_RULES_WUNLOCK();
5284					free(ioes, M_TEMP);
5285					goto fail; /* really bad */
5286				}
5287				break;
5288#endif /* ALTQ */
5289			case PF_RULESET_TABLE:
5290			    {
5291				struct pfr_table table;
5292
5293				bzero(&table, sizeof(table));
5294				(void)strlcpy(table.pfrt_anchor, ioe->anchor,
5295				    sizeof(table.pfrt_anchor));
5296				if ((error = pfr_ina_commit(&table,
5297				    ioe->ticket, NULL, NULL, 0))) {
5298					PF_RULES_WUNLOCK();
5299					free(ioes, M_TEMP);
5300					goto fail; /* really bad */
5301				}
5302				break;
5303			    }
5304			default:
5305				if ((error = pf_commit_rules(ioe->ticket,
5306				    ioe->rs_num, ioe->anchor))) {
5307					PF_RULES_WUNLOCK();
5308					free(ioes, M_TEMP);
5309					goto fail; /* really bad */
5310				}
5311				break;
5312			}
5313		}
5314		PF_RULES_WUNLOCK();
5315
5316		/* Only hook into EtherNet taffic if we've got rules for it. */
5317		if (! TAILQ_EMPTY(V_pf_keth->active.rules))
5318			hook_pf_eth();
5319		else
5320			dehook_pf_eth();
5321
5322		free(ioes, M_TEMP);
5323		break;
5324	}
5325
5326	case DIOCGETSRCNODES: {
5327		struct pfioc_src_nodes	*psn = (struct pfioc_src_nodes *)addr;
5328		struct pf_srchash	*sh;
5329		struct pf_ksrc_node	*n;
5330		struct pf_src_node	*p, *pstore;
5331		uint32_t		 i, nr = 0;
5332
5333		for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask;
5334				i++, sh++) {
5335			PF_HASHROW_LOCK(sh);
5336			LIST_FOREACH(n, &sh->nodes, entry)
5337				nr++;
5338			PF_HASHROW_UNLOCK(sh);
5339		}
5340
5341		psn->psn_len = min(psn->psn_len,
5342		    sizeof(struct pf_src_node) * nr);
5343
5344		if (psn->psn_len == 0) {
5345			psn->psn_len = sizeof(struct pf_src_node) * nr;
5346			break;
5347		}
5348
5349		nr = 0;
5350
5351		p = pstore = malloc(psn->psn_len, M_TEMP, M_WAITOK | M_ZERO);
5352		for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask;
5353		    i++, sh++) {
5354		    PF_HASHROW_LOCK(sh);
5355		    LIST_FOREACH(n, &sh->nodes, entry) {
5356
5357			if ((nr + 1) * sizeof(*p) > (unsigned)psn->psn_len)
5358				break;
5359
5360			pf_src_node_copy(n, p);
5361
5362			p++;
5363			nr++;
5364		    }
5365		    PF_HASHROW_UNLOCK(sh);
5366		}
5367		error = copyout(pstore, psn->psn_src_nodes,
5368		    sizeof(struct pf_src_node) * nr);
5369		if (error) {
5370			free(pstore, M_TEMP);
5371			break;
5372		}
5373		psn->psn_len = sizeof(struct pf_src_node) * nr;
5374		free(pstore, M_TEMP);
5375		break;
5376	}
5377
5378	case DIOCCLRSRCNODES: {
5379		pf_clear_srcnodes(NULL);
5380		pf_purge_expired_src_nodes();
5381		break;
5382	}
5383
5384	case DIOCKILLSRCNODES:
5385		pf_kill_srcnodes((struct pfioc_src_node_kill *)addr);
5386		break;
5387
5388#ifdef COMPAT_FREEBSD13
5389	case DIOCKEEPCOUNTERS_FREEBSD13:
5390#endif
5391	case DIOCKEEPCOUNTERS:
5392		error = pf_keepcounters((struct pfioc_nv *)addr);
5393		break;
5394
5395	case DIOCGETSYNCOOKIES:
5396		error = pf_get_syncookies((struct pfioc_nv *)addr);
5397		break;
5398
5399	case DIOCSETSYNCOOKIES:
5400		error = pf_set_syncookies((struct pfioc_nv *)addr);
5401		break;
5402
5403	case DIOCSETHOSTID: {
5404		u_int32_t	*hostid = (u_int32_t *)addr;
5405
5406		PF_RULES_WLOCK();
5407		if (*hostid == 0)
5408			V_pf_status.hostid = arc4random();
5409		else
5410			V_pf_status.hostid = *hostid;
5411		PF_RULES_WUNLOCK();
5412		break;
5413	}
5414
5415	case DIOCOSFPFLUSH:
5416		PF_RULES_WLOCK();
5417		pf_osfp_flush();
5418		PF_RULES_WUNLOCK();
5419		break;
5420
5421	case DIOCIGETIFACES: {
5422		struct pfioc_iface *io = (struct pfioc_iface *)addr;
5423		struct pfi_kif *ifstore;
5424		size_t bufsiz;
5425
5426		if (io->pfiio_esize != sizeof(struct pfi_kif)) {
5427			error = ENODEV;
5428			break;
5429		}
5430
5431		if (io->pfiio_size < 0 ||
5432		    io->pfiio_size > pf_ioctl_maxcount ||
5433		    WOULD_OVERFLOW(io->pfiio_size, sizeof(struct pfi_kif))) {
5434			error = EINVAL;
5435			break;
5436		}
5437
5438		io->pfiio_name[sizeof(io->pfiio_name) - 1] = '\0';
5439
5440		bufsiz = io->pfiio_size * sizeof(struct pfi_kif);
5441		ifstore = mallocarray(io->pfiio_size, sizeof(struct pfi_kif),
5442		    M_TEMP, M_WAITOK | M_ZERO);
5443
5444		PF_RULES_RLOCK();
5445		pfi_get_ifaces(io->pfiio_name, ifstore, &io->pfiio_size);
5446		PF_RULES_RUNLOCK();
5447		error = copyout(ifstore, io->pfiio_buffer, bufsiz);
5448		free(ifstore, M_TEMP);
5449		break;
5450	}
5451
5452	case DIOCSETIFFLAG: {
5453		struct pfioc_iface *io = (struct pfioc_iface *)addr;
5454
5455		io->pfiio_name[sizeof(io->pfiio_name) - 1] = '\0';
5456
5457		PF_RULES_WLOCK();
5458		error = pfi_set_flags(io->pfiio_name, io->pfiio_flags);
5459		PF_RULES_WUNLOCK();
5460		break;
5461	}
5462
5463	case DIOCCLRIFFLAG: {
5464		struct pfioc_iface *io = (struct pfioc_iface *)addr;
5465
5466		io->pfiio_name[sizeof(io->pfiio_name) - 1] = '\0';
5467
5468		PF_RULES_WLOCK();
5469		error = pfi_clear_flags(io->pfiio_name, io->pfiio_flags);
5470		PF_RULES_WUNLOCK();
5471		break;
5472	}
5473
5474	case DIOCSETREASS: {
5475		u_int32_t	*reass = (u_int32_t *)addr;
5476
5477		V_pf_status.reass = *reass & (PF_REASS_ENABLED|PF_REASS_NODF);
5478		/* Removal of DF flag without reassembly enabled is not a
5479		 * valid combination. Disable reassembly in such case. */
5480		if (!(V_pf_status.reass & PF_REASS_ENABLED))
5481			V_pf_status.reass = 0;
5482		break;
5483	}
5484
5485	default:
5486		error = ENODEV;
5487		break;
5488	}
5489fail:
5490	CURVNET_RESTORE();
5491
5492#undef ERROUT_IOCTL
5493
5494	return (error);
5495}
5496
5497void
5498pfsync_state_export(union pfsync_state_union *sp, struct pf_kstate *st, int msg_version)
5499{
5500	bzero(sp, sizeof(union pfsync_state_union));
5501
5502	/* copy from state key */
5503	sp->pfs_1301.key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
5504	sp->pfs_1301.key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1];
5505	sp->pfs_1301.key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0];
5506	sp->pfs_1301.key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1];
5507	sp->pfs_1301.key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0];
5508	sp->pfs_1301.key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1];
5509	sp->pfs_1301.key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0];
5510	sp->pfs_1301.key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1];
5511	sp->pfs_1301.proto = st->key[PF_SK_WIRE]->proto;
5512	sp->pfs_1301.af = st->key[PF_SK_WIRE]->af;
5513
5514	/* copy from state */
5515	strlcpy(sp->pfs_1301.ifname, st->kif->pfik_name, sizeof(sp->pfs_1301.ifname));
5516	bcopy(&st->rt_addr, &sp->pfs_1301.rt_addr, sizeof(sp->pfs_1301.rt_addr));
5517	sp->pfs_1301.creation = htonl(time_uptime - (st->creation / 1000));
5518	sp->pfs_1301.expire = pf_state_expires(st);
5519	if (sp->pfs_1301.expire <= time_uptime)
5520		sp->pfs_1301.expire = htonl(0);
5521	else
5522		sp->pfs_1301.expire = htonl(sp->pfs_1301.expire - time_uptime);
5523
5524	sp->pfs_1301.direction = st->direction;
5525	sp->pfs_1301.log = st->act.log;
5526	sp->pfs_1301.timeout = st->timeout;
5527
5528	switch (msg_version) {
5529		case PFSYNC_MSG_VERSION_1301:
5530			sp->pfs_1301.state_flags = st->state_flags;
5531			break;
5532		case PFSYNC_MSG_VERSION_1400:
5533			sp->pfs_1400.state_flags = htons(st->state_flags);
5534			sp->pfs_1400.qid = htons(st->act.qid);
5535			sp->pfs_1400.pqid = htons(st->act.pqid);
5536			sp->pfs_1400.dnpipe = htons(st->act.dnpipe);
5537			sp->pfs_1400.dnrpipe = htons(st->act.dnrpipe);
5538			sp->pfs_1400.rtableid = htonl(st->act.rtableid);
5539			sp->pfs_1400.min_ttl = st->act.min_ttl;
5540			sp->pfs_1400.set_tos = st->act.set_tos;
5541			sp->pfs_1400.max_mss = htons(st->act.max_mss);
5542			sp->pfs_1400.set_prio[0] = st->act.set_prio[0];
5543			sp->pfs_1400.set_prio[1] = st->act.set_prio[1];
5544			sp->pfs_1400.rt = st->rt;
5545			if (st->rt_kif)
5546				strlcpy(sp->pfs_1400.rt_ifname,
5547				    st->rt_kif->pfik_name,
5548				    sizeof(sp->pfs_1400.rt_ifname));
5549			break;
5550		default:
5551			panic("%s: Unsupported pfsync_msg_version %d",
5552			    __func__, msg_version);
5553	}
5554
5555	if (st->src_node)
5556		sp->pfs_1301.sync_flags |= PFSYNC_FLAG_SRCNODE;
5557	if (st->nat_src_node)
5558		sp->pfs_1301.sync_flags |= PFSYNC_FLAG_NATSRCNODE;
5559
5560	sp->pfs_1301.id = st->id;
5561	sp->pfs_1301.creatorid = st->creatorid;
5562	pf_state_peer_hton(&st->src, &sp->pfs_1301.src);
5563	pf_state_peer_hton(&st->dst, &sp->pfs_1301.dst);
5564
5565	if (st->rule.ptr == NULL)
5566		sp->pfs_1301.rule = htonl(-1);
5567	else
5568		sp->pfs_1301.rule = htonl(st->rule.ptr->nr);
5569	if (st->anchor.ptr == NULL)
5570		sp->pfs_1301.anchor = htonl(-1);
5571	else
5572		sp->pfs_1301.anchor = htonl(st->anchor.ptr->nr);
5573	if (st->nat_rule.ptr == NULL)
5574		sp->pfs_1301.nat_rule = htonl(-1);
5575	else
5576		sp->pfs_1301.nat_rule = htonl(st->nat_rule.ptr->nr);
5577
5578	pf_state_counter_hton(st->packets[0], sp->pfs_1301.packets[0]);
5579	pf_state_counter_hton(st->packets[1], sp->pfs_1301.packets[1]);
5580	pf_state_counter_hton(st->bytes[0], sp->pfs_1301.bytes[0]);
5581	pf_state_counter_hton(st->bytes[1], sp->pfs_1301.bytes[1]);
5582}
5583
5584void
5585pf_state_export(struct pf_state_export *sp, struct pf_kstate *st)
5586{
5587	bzero(sp, sizeof(*sp));
5588
5589	sp->version = PF_STATE_VERSION;
5590
5591	/* copy from state key */
5592	sp->key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
5593	sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1];
5594	sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0];
5595	sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1];
5596	sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0];
5597	sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1];
5598	sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0];
5599	sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1];
5600	sp->proto = st->key[PF_SK_WIRE]->proto;
5601	sp->af = st->key[PF_SK_WIRE]->af;
5602
5603	/* copy from state */
5604	strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname));
5605	strlcpy(sp->orig_ifname, st->orig_kif->pfik_name,
5606	    sizeof(sp->orig_ifname));
5607	bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr));
5608	sp->creation = htonl(time_uptime - (st->creation / 1000));
5609	sp->expire = pf_state_expires(st);
5610	if (sp->expire <= time_uptime)
5611		sp->expire = htonl(0);
5612	else
5613		sp->expire = htonl(sp->expire - time_uptime);
5614
5615	sp->direction = st->direction;
5616	sp->log = st->act.log;
5617	sp->timeout = st->timeout;
5618	/* 8 bits for the old libpfctl, 16 bits for the new libpfctl */
5619	sp->state_flags_compat = st->state_flags;
5620	sp->state_flags = htons(st->state_flags);
5621	if (st->src_node)
5622		sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
5623	if (st->nat_src_node)
5624		sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE;
5625
5626	sp->id = st->id;
5627	sp->creatorid = st->creatorid;
5628	pf_state_peer_hton(&st->src, &sp->src);
5629	pf_state_peer_hton(&st->dst, &sp->dst);
5630
5631	if (st->rule.ptr == NULL)
5632		sp->rule = htonl(-1);
5633	else
5634		sp->rule = htonl(st->rule.ptr->nr);
5635	if (st->anchor.ptr == NULL)
5636		sp->anchor = htonl(-1);
5637	else
5638		sp->anchor = htonl(st->anchor.ptr->nr);
5639	if (st->nat_rule.ptr == NULL)
5640		sp->nat_rule = htonl(-1);
5641	else
5642		sp->nat_rule = htonl(st->nat_rule.ptr->nr);
5643
5644	sp->packets[0] = st->packets[0];
5645	sp->packets[1] = st->packets[1];
5646	sp->bytes[0] = st->bytes[0];
5647	sp->bytes[1] = st->bytes[1];
5648
5649	sp->qid = htons(st->act.qid);
5650	sp->pqid = htons(st->act.pqid);
5651	sp->dnpipe = htons(st->act.dnpipe);
5652	sp->dnrpipe = htons(st->act.dnrpipe);
5653	sp->rtableid = htonl(st->act.rtableid);
5654	sp->min_ttl = st->act.min_ttl;
5655	sp->set_tos = st->act.set_tos;
5656	sp->max_mss = htons(st->act.max_mss);
5657	sp->rt = st->rt;
5658	if (st->rt_kif)
5659		strlcpy(sp->rt_ifname, st->rt_kif->pfik_name,
5660		    sizeof(sp->rt_ifname));
5661	sp->set_prio[0] = st->act.set_prio[0];
5662	sp->set_prio[1] = st->act.set_prio[1];
5663
5664}
5665
5666static void
5667pf_tbladdr_copyout(struct pf_addr_wrap *aw)
5668{
5669	struct pfr_ktable *kt;
5670
5671	KASSERT(aw->type == PF_ADDR_TABLE, ("%s: type %u", __func__, aw->type));
5672
5673	kt = aw->p.tbl;
5674	if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
5675		kt = kt->pfrkt_root;
5676	aw->p.tbl = NULL;
5677	aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ?
5678		kt->pfrkt_cnt : -1;
5679}
5680
5681static int
5682pf_add_status_counters(nvlist_t *nvl, const char *name, counter_u64_t *counters,
5683    size_t number, char **names)
5684{
5685	nvlist_t        *nvc;
5686
5687	nvc = nvlist_create(0);
5688	if (nvc == NULL)
5689		return (ENOMEM);
5690
5691	for (int i = 0; i < number; i++) {
5692		nvlist_append_number_array(nvc, "counters",
5693		    counter_u64_fetch(counters[i]));
5694		nvlist_append_string_array(nvc, "names",
5695		    names[i]);
5696		nvlist_append_number_array(nvc, "ids",
5697		    i);
5698	}
5699	nvlist_add_nvlist(nvl, name, nvc);
5700	nvlist_destroy(nvc);
5701
5702	return (0);
5703}
5704
5705static int
5706pf_getstatus(struct pfioc_nv *nv)
5707{
5708	nvlist_t        *nvl = NULL, *nvc = NULL;
5709	void            *nvlpacked = NULL;
5710	int              error;
5711	struct pf_status s;
5712	char *pf_reasons[PFRES_MAX+1] = PFRES_NAMES;
5713	char *pf_lcounter[KLCNT_MAX+1] = KLCNT_NAMES;
5714	char *pf_fcounter[FCNT_MAX+1] = FCNT_NAMES;
5715	PF_RULES_RLOCK_TRACKER;
5716
5717#define ERROUT(x)      ERROUT_FUNCTION(errout, x)
5718
5719	PF_RULES_RLOCK();
5720
5721	nvl = nvlist_create(0);
5722	if (nvl == NULL)
5723		ERROUT(ENOMEM);
5724
5725	nvlist_add_bool(nvl, "running", V_pf_status.running);
5726	nvlist_add_number(nvl, "since", V_pf_status.since);
5727	nvlist_add_number(nvl, "debug", V_pf_status.debug);
5728	nvlist_add_number(nvl, "hostid", V_pf_status.hostid);
5729	nvlist_add_number(nvl, "states", V_pf_status.states);
5730	nvlist_add_number(nvl, "src_nodes", V_pf_status.src_nodes);
5731	nvlist_add_number(nvl, "reass", V_pf_status.reass);
5732	nvlist_add_bool(nvl, "syncookies_active",
5733	    V_pf_status.syncookies_active);
5734	nvlist_add_number(nvl, "halfopen_states", V_pf_status.states_halfopen);
5735
5736	/* counters */
5737	error = pf_add_status_counters(nvl, "counters", V_pf_status.counters,
5738	    PFRES_MAX, pf_reasons);
5739	if (error != 0)
5740		ERROUT(error);
5741
5742	/* lcounters */
5743	error = pf_add_status_counters(nvl, "lcounters", V_pf_status.lcounters,
5744	    KLCNT_MAX, pf_lcounter);
5745	if (error != 0)
5746		ERROUT(error);
5747
5748	/* fcounters */
5749	nvc = nvlist_create(0);
5750	if (nvc == NULL)
5751		ERROUT(ENOMEM);
5752
5753	for (int i = 0; i < FCNT_MAX; i++) {
5754		nvlist_append_number_array(nvc, "counters",
5755		    pf_counter_u64_fetch(&V_pf_status.fcounters[i]));
5756		nvlist_append_string_array(nvc, "names",
5757		    pf_fcounter[i]);
5758		nvlist_append_number_array(nvc, "ids",
5759		    i);
5760	}
5761	nvlist_add_nvlist(nvl, "fcounters", nvc);
5762	nvlist_destroy(nvc);
5763	nvc = NULL;
5764
5765	/* scounters */
5766	error = pf_add_status_counters(nvl, "scounters", V_pf_status.scounters,
5767	    SCNT_MAX, pf_fcounter);
5768	if (error != 0)
5769		ERROUT(error);
5770
5771	nvlist_add_string(nvl, "ifname", V_pf_status.ifname);
5772	nvlist_add_binary(nvl, "chksum", V_pf_status.pf_chksum,
5773	    PF_MD5_DIGEST_LENGTH);
5774
5775	pfi_update_status(V_pf_status.ifname, &s);
5776
5777	/* pcounters / bcounters */
5778	for (int i = 0; i < 2; i++) {
5779		for (int j = 0; j < 2; j++) {
5780			for (int k = 0; k < 2; k++) {
5781				nvlist_append_number_array(nvl, "pcounters",
5782				    s.pcounters[i][j][k]);
5783			}
5784			nvlist_append_number_array(nvl, "bcounters",
5785			    s.bcounters[i][j]);
5786		}
5787	}
5788
5789	nvlpacked = nvlist_pack(nvl, &nv->len);
5790	if (nvlpacked == NULL)
5791		ERROUT(ENOMEM);
5792
5793	if (nv->size == 0)
5794		ERROUT(0);
5795	else if (nv->size < nv->len)
5796		ERROUT(ENOSPC);
5797
5798	PF_RULES_RUNLOCK();
5799	error = copyout(nvlpacked, nv->data, nv->len);
5800	goto done;
5801
5802#undef ERROUT
5803errout:
5804	PF_RULES_RUNLOCK();
5805done:
5806	free(nvlpacked, M_NVLIST);
5807	nvlist_destroy(nvc);
5808	nvlist_destroy(nvl);
5809
5810	return (error);
5811}
5812
5813/*
5814 * XXX - Check for version mismatch!!!
5815 */
5816static void
5817pf_clear_all_states(void)
5818{
5819	struct epoch_tracker	 et;
5820	struct pf_kstate	*s;
5821	u_int i;
5822
5823	NET_EPOCH_ENTER(et);
5824	for (i = 0; i <= pf_hashmask; i++) {
5825		struct pf_idhash *ih = &V_pf_idhash[i];
5826relock:
5827		PF_HASHROW_LOCK(ih);
5828		LIST_FOREACH(s, &ih->states, entry) {
5829			s->timeout = PFTM_PURGE;
5830			/* Don't send out individual delete messages. */
5831			s->state_flags |= PFSTATE_NOSYNC;
5832			pf_unlink_state(s);
5833			goto relock;
5834		}
5835		PF_HASHROW_UNLOCK(ih);
5836	}
5837	NET_EPOCH_EXIT(et);
5838}
5839
5840static int
5841pf_clear_tables(void)
5842{
5843	struct pfioc_table io;
5844	int error;
5845
5846	bzero(&io, sizeof(io));
5847	io.pfrio_flags |= PFR_FLAG_ALLRSETS;
5848
5849	error = pfr_clr_tables(&io.pfrio_table, &io.pfrio_ndel,
5850	    io.pfrio_flags);
5851
5852	return (error);
5853}
5854
5855static void
5856pf_clear_srcnodes(struct pf_ksrc_node *n)
5857{
5858	struct pf_kstate *s;
5859	int i;
5860
5861	for (i = 0; i <= pf_hashmask; i++) {
5862		struct pf_idhash *ih = &V_pf_idhash[i];
5863
5864		PF_HASHROW_LOCK(ih);
5865		LIST_FOREACH(s, &ih->states, entry) {
5866			if (n == NULL || n == s->src_node)
5867				s->src_node = NULL;
5868			if (n == NULL || n == s->nat_src_node)
5869				s->nat_src_node = NULL;
5870		}
5871		PF_HASHROW_UNLOCK(ih);
5872	}
5873
5874	if (n == NULL) {
5875		struct pf_srchash *sh;
5876
5877		for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask;
5878		    i++, sh++) {
5879			PF_HASHROW_LOCK(sh);
5880			LIST_FOREACH(n, &sh->nodes, entry) {
5881				n->expire = 1;
5882				n->states = 0;
5883			}
5884			PF_HASHROW_UNLOCK(sh);
5885		}
5886	} else {
5887		/* XXX: hash slot should already be locked here. */
5888		n->expire = 1;
5889		n->states = 0;
5890	}
5891}
5892
5893static void
5894pf_kill_srcnodes(struct pfioc_src_node_kill *psnk)
5895{
5896	struct pf_ksrc_node_list	 kill;
5897
5898	LIST_INIT(&kill);
5899	for (int i = 0; i <= pf_srchashmask; i++) {
5900		struct pf_srchash *sh = &V_pf_srchash[i];
5901		struct pf_ksrc_node *sn, *tmp;
5902
5903		PF_HASHROW_LOCK(sh);
5904		LIST_FOREACH_SAFE(sn, &sh->nodes, entry, tmp)
5905			if (PF_MATCHA(psnk->psnk_src.neg,
5906			      &psnk->psnk_src.addr.v.a.addr,
5907			      &psnk->psnk_src.addr.v.a.mask,
5908			      &sn->addr, sn->af) &&
5909			    PF_MATCHA(psnk->psnk_dst.neg,
5910			      &psnk->psnk_dst.addr.v.a.addr,
5911			      &psnk->psnk_dst.addr.v.a.mask,
5912			      &sn->raddr, sn->af)) {
5913				pf_unlink_src_node(sn);
5914				LIST_INSERT_HEAD(&kill, sn, entry);
5915				sn->expire = 1;
5916			}
5917		PF_HASHROW_UNLOCK(sh);
5918	}
5919
5920	for (int i = 0; i <= pf_hashmask; i++) {
5921		struct pf_idhash *ih = &V_pf_idhash[i];
5922		struct pf_kstate *s;
5923
5924		PF_HASHROW_LOCK(ih);
5925		LIST_FOREACH(s, &ih->states, entry) {
5926			if (s->src_node && s->src_node->expire == 1)
5927				s->src_node = NULL;
5928			if (s->nat_src_node && s->nat_src_node->expire == 1)
5929				s->nat_src_node = NULL;
5930		}
5931		PF_HASHROW_UNLOCK(ih);
5932	}
5933
5934	psnk->psnk_killed = pf_free_src_nodes(&kill);
5935}
5936
5937static int
5938pf_keepcounters(struct pfioc_nv *nv)
5939{
5940	nvlist_t	*nvl = NULL;
5941	void		*nvlpacked = NULL;
5942	int		 error = 0;
5943
5944#define	ERROUT(x)	ERROUT_FUNCTION(on_error, x)
5945
5946	if (nv->len > pf_ioctl_maxcount)
5947		ERROUT(ENOMEM);
5948
5949	nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
5950	if (nvlpacked == NULL)
5951		ERROUT(ENOMEM);
5952
5953	error = copyin(nv->data, nvlpacked, nv->len);
5954	if (error)
5955		ERROUT(error);
5956
5957	nvl = nvlist_unpack(nvlpacked, nv->len, 0);
5958	if (nvl == NULL)
5959		ERROUT(EBADMSG);
5960
5961	if (! nvlist_exists_bool(nvl, "keep_counters"))
5962		ERROUT(EBADMSG);
5963
5964	V_pf_status.keep_counters = nvlist_get_bool(nvl, "keep_counters");
5965
5966on_error:
5967	nvlist_destroy(nvl);
5968	free(nvlpacked, M_NVLIST);
5969	return (error);
5970}
5971
5972unsigned int
5973pf_clear_states(const struct pf_kstate_kill *kill)
5974{
5975	struct pf_state_key_cmp	 match_key;
5976	struct pf_kstate	*s;
5977	struct pfi_kkif	*kif;
5978	int		 idx;
5979	unsigned int	 killed = 0, dir;
5980
5981	NET_EPOCH_ASSERT();
5982
5983	for (unsigned int i = 0; i <= pf_hashmask; i++) {
5984		struct pf_idhash *ih = &V_pf_idhash[i];
5985
5986relock_DIOCCLRSTATES:
5987		PF_HASHROW_LOCK(ih);
5988		LIST_FOREACH(s, &ih->states, entry) {
5989			/* For floating states look at the original kif. */
5990			kif = s->kif == V_pfi_all ? s->orig_kif : s->kif;
5991
5992			if (kill->psk_ifname[0] &&
5993			    strcmp(kill->psk_ifname,
5994			    kif->pfik_name))
5995				continue;
5996
5997			if (kill->psk_kill_match) {
5998				bzero(&match_key, sizeof(match_key));
5999
6000				if (s->direction == PF_OUT) {
6001					dir = PF_IN;
6002					idx = PF_SK_STACK;
6003				} else {
6004					dir = PF_OUT;
6005					idx = PF_SK_WIRE;
6006				}
6007
6008				match_key.af = s->key[idx]->af;
6009				match_key.proto = s->key[idx]->proto;
6010				PF_ACPY(&match_key.addr[0],
6011				    &s->key[idx]->addr[1], match_key.af);
6012				match_key.port[0] = s->key[idx]->port[1];
6013				PF_ACPY(&match_key.addr[1],
6014				    &s->key[idx]->addr[0], match_key.af);
6015				match_key.port[1] = s->key[idx]->port[0];
6016			}
6017
6018			/*
6019			 * Don't send out individual
6020			 * delete messages.
6021			 */
6022			s->state_flags |= PFSTATE_NOSYNC;
6023			pf_unlink_state(s);
6024			killed++;
6025
6026			if (kill->psk_kill_match)
6027				killed += pf_kill_matching_state(&match_key,
6028				    dir);
6029
6030			goto relock_DIOCCLRSTATES;
6031		}
6032		PF_HASHROW_UNLOCK(ih);
6033	}
6034
6035	if (V_pfsync_clear_states_ptr != NULL)
6036		V_pfsync_clear_states_ptr(V_pf_status.hostid, kill->psk_ifname);
6037
6038	return (killed);
6039}
6040
6041void
6042pf_killstates(struct pf_kstate_kill *kill, unsigned int *killed)
6043{
6044	struct pf_kstate	*s;
6045
6046	NET_EPOCH_ASSERT();
6047	if (kill->psk_pfcmp.id) {
6048		if (kill->psk_pfcmp.creatorid == 0)
6049			kill->psk_pfcmp.creatorid = V_pf_status.hostid;
6050		if ((s = pf_find_state_byid(kill->psk_pfcmp.id,
6051		    kill->psk_pfcmp.creatorid))) {
6052			pf_unlink_state(s);
6053			*killed = 1;
6054		}
6055		return;
6056	}
6057
6058	for (unsigned int i = 0; i <= pf_hashmask; i++)
6059		*killed += pf_killstates_row(kill, &V_pf_idhash[i]);
6060}
6061
6062static int
6063pf_killstates_nv(struct pfioc_nv *nv)
6064{
6065	struct pf_kstate_kill	 kill;
6066	struct epoch_tracker	 et;
6067	nvlist_t		*nvl = NULL;
6068	void			*nvlpacked = NULL;
6069	int			 error = 0;
6070	unsigned int		 killed = 0;
6071
6072#define ERROUT(x)	ERROUT_FUNCTION(on_error, x)
6073
6074	if (nv->len > pf_ioctl_maxcount)
6075		ERROUT(ENOMEM);
6076
6077	nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
6078	if (nvlpacked == NULL)
6079		ERROUT(ENOMEM);
6080
6081	error = copyin(nv->data, nvlpacked, nv->len);
6082	if (error)
6083		ERROUT(error);
6084
6085	nvl = nvlist_unpack(nvlpacked, nv->len, 0);
6086	if (nvl == NULL)
6087		ERROUT(EBADMSG);
6088
6089	error = pf_nvstate_kill_to_kstate_kill(nvl, &kill);
6090	if (error)
6091		ERROUT(error);
6092
6093	NET_EPOCH_ENTER(et);
6094	pf_killstates(&kill, &killed);
6095	NET_EPOCH_EXIT(et);
6096
6097	free(nvlpacked, M_NVLIST);
6098	nvlpacked = NULL;
6099	nvlist_destroy(nvl);
6100	nvl = nvlist_create(0);
6101	if (nvl == NULL)
6102		ERROUT(ENOMEM);
6103
6104	nvlist_add_number(nvl, "killed", killed);
6105
6106	nvlpacked = nvlist_pack(nvl, &nv->len);
6107	if (nvlpacked == NULL)
6108		ERROUT(ENOMEM);
6109
6110	if (nv->size == 0)
6111		ERROUT(0);
6112	else if (nv->size < nv->len)
6113		ERROUT(ENOSPC);
6114
6115	error = copyout(nvlpacked, nv->data, nv->len);
6116
6117on_error:
6118	nvlist_destroy(nvl);
6119	free(nvlpacked, M_NVLIST);
6120	return (error);
6121}
6122
6123static int
6124pf_clearstates_nv(struct pfioc_nv *nv)
6125{
6126	struct pf_kstate_kill	 kill;
6127	struct epoch_tracker	 et;
6128	nvlist_t		*nvl = NULL;
6129	void			*nvlpacked = NULL;
6130	int			 error = 0;
6131	unsigned int		 killed;
6132
6133#define ERROUT(x)	ERROUT_FUNCTION(on_error, x)
6134
6135	if (nv->len > pf_ioctl_maxcount)
6136		ERROUT(ENOMEM);
6137
6138	nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
6139	if (nvlpacked == NULL)
6140		ERROUT(ENOMEM);
6141
6142	error = copyin(nv->data, nvlpacked, nv->len);
6143	if (error)
6144		ERROUT(error);
6145
6146	nvl = nvlist_unpack(nvlpacked, nv->len, 0);
6147	if (nvl == NULL)
6148		ERROUT(EBADMSG);
6149
6150	error = pf_nvstate_kill_to_kstate_kill(nvl, &kill);
6151	if (error)
6152		ERROUT(error);
6153
6154	NET_EPOCH_ENTER(et);
6155	killed = pf_clear_states(&kill);
6156	NET_EPOCH_EXIT(et);
6157
6158	free(nvlpacked, M_NVLIST);
6159	nvlpacked = NULL;
6160	nvlist_destroy(nvl);
6161	nvl = nvlist_create(0);
6162	if (nvl == NULL)
6163		ERROUT(ENOMEM);
6164
6165	nvlist_add_number(nvl, "killed", killed);
6166
6167	nvlpacked = nvlist_pack(nvl, &nv->len);
6168	if (nvlpacked == NULL)
6169		ERROUT(ENOMEM);
6170
6171	if (nv->size == 0)
6172		ERROUT(0);
6173	else if (nv->size < nv->len)
6174		ERROUT(ENOSPC);
6175
6176	error = copyout(nvlpacked, nv->data, nv->len);
6177
6178#undef ERROUT
6179on_error:
6180	nvlist_destroy(nvl);
6181	free(nvlpacked, M_NVLIST);
6182	return (error);
6183}
6184
6185static int
6186pf_getstate(struct pfioc_nv *nv)
6187{
6188	nvlist_t		*nvl = NULL, *nvls;
6189	void			*nvlpacked = NULL;
6190	struct pf_kstate	*s = NULL;
6191	int			 error = 0;
6192	uint64_t		 id, creatorid;
6193
6194#define ERROUT(x)	ERROUT_FUNCTION(errout, x)
6195
6196	if (nv->len > pf_ioctl_maxcount)
6197		ERROUT(ENOMEM);
6198
6199	nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
6200	if (nvlpacked == NULL)
6201		ERROUT(ENOMEM);
6202
6203	error = copyin(nv->data, nvlpacked, nv->len);
6204	if (error)
6205		ERROUT(error);
6206
6207	nvl = nvlist_unpack(nvlpacked, nv->len, 0);
6208	if (nvl == NULL)
6209		ERROUT(EBADMSG);
6210
6211	PFNV_CHK(pf_nvuint64(nvl, "id", &id));
6212	PFNV_CHK(pf_nvuint64(nvl, "creatorid", &creatorid));
6213
6214	s = pf_find_state_byid(id, creatorid);
6215	if (s == NULL)
6216		ERROUT(ENOENT);
6217
6218	free(nvlpacked, M_NVLIST);
6219	nvlpacked = NULL;
6220	nvlist_destroy(nvl);
6221	nvl = nvlist_create(0);
6222	if (nvl == NULL)
6223		ERROUT(ENOMEM);
6224
6225	nvls = pf_state_to_nvstate(s);
6226	if (nvls == NULL)
6227		ERROUT(ENOMEM);
6228
6229	nvlist_add_nvlist(nvl, "state", nvls);
6230	nvlist_destroy(nvls);
6231
6232	nvlpacked = nvlist_pack(nvl, &nv->len);
6233	if (nvlpacked == NULL)
6234		ERROUT(ENOMEM);
6235
6236	if (nv->size == 0)
6237		ERROUT(0);
6238	else if (nv->size < nv->len)
6239		ERROUT(ENOSPC);
6240
6241	error = copyout(nvlpacked, nv->data, nv->len);
6242
6243#undef ERROUT
6244errout:
6245	if (s != NULL)
6246		PF_STATE_UNLOCK(s);
6247	free(nvlpacked, M_NVLIST);
6248	nvlist_destroy(nvl);
6249	return (error);
6250}
6251
6252/*
6253 * XXX - Check for version mismatch!!!
6254 */
6255
6256/*
6257 * Duplicate pfctl -Fa operation to get rid of as much as we can.
6258 */
6259static int
6260shutdown_pf(void)
6261{
6262	int error = 0;
6263	u_int32_t t[5];
6264	char nn = '\0';
6265	struct pf_kanchor *anchor;
6266	struct pf_keth_anchor *eth_anchor;
6267	int rs_num;
6268
6269	do {
6270		/* Unlink rules of all user defined anchors */
6271		RB_FOREACH(anchor, pf_kanchor_global, &V_pf_anchors) {
6272			/* Wildcard based anchors may not have a respective
6273			 * explicit anchor rule or they may be left empty
6274			 * without rules. It leads to anchor.refcnt=0, and the
6275			 * rest of the logic does not expect it. */
6276			if (anchor->refcnt == 0)
6277				anchor->refcnt = 1;
6278			for (rs_num = 0; rs_num < PF_RULESET_MAX; ++rs_num) {
6279				if ((error = pf_begin_rules(&t[rs_num], rs_num,
6280				    anchor->path)) != 0) {
6281					DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: "
6282					    "anchor.path=%s rs_num=%d\n",
6283					    anchor->path, rs_num));
6284					goto error;	/* XXX: rollback? */
6285				}
6286			}
6287			for (rs_num = 0; rs_num < PF_RULESET_MAX; ++rs_num) {
6288				error = pf_commit_rules(t[rs_num], rs_num,
6289				    anchor->path);
6290				MPASS(error == 0);
6291			}
6292		}
6293
6294		/* Unlink rules of all user defined ether anchors */
6295		RB_FOREACH(eth_anchor, pf_keth_anchor_global,
6296		    &V_pf_keth_anchors) {
6297			/* Wildcard based anchors may not have a respective
6298			 * explicit anchor rule or they may be left empty
6299			 * without rules. It leads to anchor.refcnt=0, and the
6300			 * rest of the logic does not expect it. */
6301			if (eth_anchor->refcnt == 0)
6302				eth_anchor->refcnt = 1;
6303			if ((error = pf_begin_eth(&t[0], eth_anchor->path))
6304			    != 0) {
6305				DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: eth "
6306				    "anchor.path=%s\n", eth_anchor->path));
6307				goto error;
6308			}
6309			error = pf_commit_eth(t[0], eth_anchor->path);
6310			MPASS(error == 0);
6311		}
6312
6313		if ((error = pf_begin_rules(&t[0], PF_RULESET_SCRUB, &nn))
6314		    != 0) {
6315			DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: SCRUB\n"));
6316			break;
6317		}
6318		if ((error = pf_begin_rules(&t[1], PF_RULESET_FILTER, &nn))
6319		    != 0) {
6320			DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: FILTER\n"));
6321			break;		/* XXX: rollback? */
6322		}
6323		if ((error = pf_begin_rules(&t[2], PF_RULESET_NAT, &nn))
6324		    != 0) {
6325			DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: NAT\n"));
6326			break;		/* XXX: rollback? */
6327		}
6328		if ((error = pf_begin_rules(&t[3], PF_RULESET_BINAT, &nn))
6329		    != 0) {
6330			DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: BINAT\n"));
6331			break;		/* XXX: rollback? */
6332		}
6333		if ((error = pf_begin_rules(&t[4], PF_RULESET_RDR, &nn))
6334		    != 0) {
6335			DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: RDR\n"));
6336			break;		/* XXX: rollback? */
6337		}
6338
6339		error = pf_commit_rules(t[0], PF_RULESET_SCRUB, &nn);
6340		MPASS(error == 0);
6341		error = pf_commit_rules(t[1], PF_RULESET_FILTER, &nn);
6342		MPASS(error == 0);
6343		error = pf_commit_rules(t[2], PF_RULESET_NAT, &nn);
6344		MPASS(error == 0);
6345		error = pf_commit_rules(t[3], PF_RULESET_BINAT, &nn);
6346		MPASS(error == 0);
6347		error = pf_commit_rules(t[4], PF_RULESET_RDR, &nn);
6348		MPASS(error == 0);
6349
6350		if ((error = pf_clear_tables()) != 0)
6351			break;
6352
6353		if ((error = pf_begin_eth(&t[0], &nn)) != 0) {
6354			DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: eth\n"));
6355			break;
6356		}
6357		error = pf_commit_eth(t[0], &nn);
6358		MPASS(error == 0);
6359
6360#ifdef ALTQ
6361		if ((error = pf_begin_altq(&t[0])) != 0) {
6362			DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: ALTQ\n"));
6363			break;
6364		}
6365		pf_commit_altq(t[0]);
6366#endif
6367
6368		pf_clear_all_states();
6369
6370		pf_clear_srcnodes(NULL);
6371
6372		/* status does not use malloced mem so no need to cleanup */
6373		/* fingerprints and interfaces have their own cleanup code */
6374	} while(0);
6375
6376error:
6377	return (error);
6378}
6379
6380static pfil_return_t
6381pf_check_return(int chk, struct mbuf **m)
6382{
6383
6384	switch (chk) {
6385	case PF_PASS:
6386		if (*m == NULL)
6387			return (PFIL_CONSUMED);
6388		else
6389			return (PFIL_PASS);
6390		break;
6391	default:
6392		if (*m != NULL) {
6393			m_freem(*m);
6394			*m = NULL;
6395		}
6396		return (PFIL_DROPPED);
6397	}
6398}
6399
6400static pfil_return_t
6401pf_eth_check_in(struct mbuf **m, struct ifnet *ifp, int flags,
6402    void *ruleset __unused, struct inpcb *inp)
6403{
6404	int chk;
6405
6406	chk = pf_test_eth(PF_IN, flags, ifp, m, inp);
6407
6408	return (pf_check_return(chk, m));
6409}
6410
6411static pfil_return_t
6412pf_eth_check_out(struct mbuf **m, struct ifnet *ifp, int flags,
6413    void *ruleset __unused, struct inpcb *inp)
6414{
6415	int chk;
6416
6417	chk = pf_test_eth(PF_OUT, flags, ifp, m, inp);
6418
6419	return (pf_check_return(chk, m));
6420}
6421
6422#ifdef INET
6423static pfil_return_t
6424pf_check_in(struct mbuf **m, struct ifnet *ifp, int flags,
6425    void *ruleset __unused, struct inpcb *inp)
6426{
6427	int chk;
6428
6429	chk = pf_test(PF_IN, flags, ifp, m, inp, NULL);
6430
6431	return (pf_check_return(chk, m));
6432}
6433
6434static pfil_return_t
6435pf_check_out(struct mbuf **m, struct ifnet *ifp, int flags,
6436    void *ruleset __unused,  struct inpcb *inp)
6437{
6438	int chk;
6439
6440	chk = pf_test(PF_OUT, flags, ifp, m, inp, NULL);
6441
6442	return (pf_check_return(chk, m));
6443}
6444#endif
6445
6446#ifdef INET6
6447static pfil_return_t
6448pf_check6_in(struct mbuf **m, struct ifnet *ifp, int flags,
6449    void *ruleset __unused,  struct inpcb *inp)
6450{
6451	int chk;
6452
6453	/*
6454	 * In case of loopback traffic IPv6 uses the real interface in
6455	 * order to support scoped addresses. In order to support stateful
6456	 * filtering we have change this to lo0 as it is the case in IPv4.
6457	 */
6458	CURVNET_SET(ifp->if_vnet);
6459	chk = pf_test6(PF_IN, flags, (*m)->m_flags & M_LOOP ? V_loif : ifp,
6460	    m, inp, NULL);
6461	CURVNET_RESTORE();
6462
6463	return (pf_check_return(chk, m));
6464}
6465
6466static pfil_return_t
6467pf_check6_out(struct mbuf **m, struct ifnet *ifp, int flags,
6468    void *ruleset __unused,  struct inpcb *inp)
6469{
6470	int chk;
6471
6472	CURVNET_SET(ifp->if_vnet);
6473	chk = pf_test6(PF_OUT, flags, ifp, m, inp, NULL);
6474	CURVNET_RESTORE();
6475
6476	return (pf_check_return(chk, m));
6477}
6478#endif /* INET6 */
6479
6480VNET_DEFINE_STATIC(pfil_hook_t, pf_eth_in_hook);
6481VNET_DEFINE_STATIC(pfil_hook_t, pf_eth_out_hook);
6482#define	V_pf_eth_in_hook	VNET(pf_eth_in_hook)
6483#define	V_pf_eth_out_hook	VNET(pf_eth_out_hook)
6484
6485#ifdef INET
6486VNET_DEFINE_STATIC(pfil_hook_t, pf_ip4_in_hook);
6487VNET_DEFINE_STATIC(pfil_hook_t, pf_ip4_out_hook);
6488#define	V_pf_ip4_in_hook	VNET(pf_ip4_in_hook)
6489#define	V_pf_ip4_out_hook	VNET(pf_ip4_out_hook)
6490#endif
6491#ifdef INET6
6492VNET_DEFINE_STATIC(pfil_hook_t, pf_ip6_in_hook);
6493VNET_DEFINE_STATIC(pfil_hook_t, pf_ip6_out_hook);
6494#define	V_pf_ip6_in_hook	VNET(pf_ip6_in_hook)
6495#define	V_pf_ip6_out_hook	VNET(pf_ip6_out_hook)
6496#endif
6497
6498static void
6499hook_pf_eth(void)
6500{
6501	struct pfil_hook_args pha = {
6502		.pa_version = PFIL_VERSION,
6503		.pa_modname = "pf",
6504		.pa_type = PFIL_TYPE_ETHERNET,
6505	};
6506	struct pfil_link_args pla = {
6507		.pa_version = PFIL_VERSION,
6508	};
6509	int ret __diagused;
6510
6511	if (atomic_load_bool(&V_pf_pfil_eth_hooked))
6512		return;
6513
6514	pha.pa_mbuf_chk = pf_eth_check_in;
6515	pha.pa_flags = PFIL_IN;
6516	pha.pa_rulname = "eth-in";
6517	V_pf_eth_in_hook = pfil_add_hook(&pha);
6518	pla.pa_flags = PFIL_IN | PFIL_HEADPTR | PFIL_HOOKPTR;
6519	pla.pa_head = V_link_pfil_head;
6520	pla.pa_hook = V_pf_eth_in_hook;
6521	ret = pfil_link(&pla);
6522	MPASS(ret == 0);
6523	pha.pa_mbuf_chk = pf_eth_check_out;
6524	pha.pa_flags = PFIL_OUT;
6525	pha.pa_rulname = "eth-out";
6526	V_pf_eth_out_hook = pfil_add_hook(&pha);
6527	pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
6528	pla.pa_head = V_link_pfil_head;
6529	pla.pa_hook = V_pf_eth_out_hook;
6530	ret = pfil_link(&pla);
6531	MPASS(ret == 0);
6532
6533	atomic_store_bool(&V_pf_pfil_eth_hooked, true);
6534}
6535
6536static void
6537hook_pf(void)
6538{
6539	struct pfil_hook_args pha = {
6540		.pa_version = PFIL_VERSION,
6541		.pa_modname = "pf",
6542	};
6543	struct pfil_link_args pla = {
6544		.pa_version = PFIL_VERSION,
6545	};
6546	int ret __diagused;
6547
6548	if (atomic_load_bool(&V_pf_pfil_hooked))
6549		return;
6550
6551#ifdef INET
6552	pha.pa_type = PFIL_TYPE_IP4;
6553	pha.pa_mbuf_chk = pf_check_in;
6554	pha.pa_flags = PFIL_IN;
6555	pha.pa_rulname = "default-in";
6556	V_pf_ip4_in_hook = pfil_add_hook(&pha);
6557	pla.pa_flags = PFIL_IN | PFIL_HEADPTR | PFIL_HOOKPTR;
6558	pla.pa_head = V_inet_pfil_head;
6559	pla.pa_hook = V_pf_ip4_in_hook;
6560	ret = pfil_link(&pla);
6561	MPASS(ret == 0);
6562	pha.pa_mbuf_chk = pf_check_out;
6563	pha.pa_flags = PFIL_OUT;
6564	pha.pa_rulname = "default-out";
6565	V_pf_ip4_out_hook = pfil_add_hook(&pha);
6566	pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
6567	pla.pa_head = V_inet_pfil_head;
6568	pla.pa_hook = V_pf_ip4_out_hook;
6569	ret = pfil_link(&pla);
6570	MPASS(ret == 0);
6571	if (V_pf_filter_local) {
6572		pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
6573		pla.pa_head = V_inet_local_pfil_head;
6574		pla.pa_hook = V_pf_ip4_out_hook;
6575		ret = pfil_link(&pla);
6576		MPASS(ret == 0);
6577	}
6578#endif
6579#ifdef INET6
6580	pha.pa_type = PFIL_TYPE_IP6;
6581	pha.pa_mbuf_chk = pf_check6_in;
6582	pha.pa_flags = PFIL_IN;
6583	pha.pa_rulname = "default-in6";
6584	V_pf_ip6_in_hook = pfil_add_hook(&pha);
6585	pla.pa_flags = PFIL_IN | PFIL_HEADPTR | PFIL_HOOKPTR;
6586	pla.pa_head = V_inet6_pfil_head;
6587	pla.pa_hook = V_pf_ip6_in_hook;
6588	ret = pfil_link(&pla);
6589	MPASS(ret == 0);
6590	pha.pa_mbuf_chk = pf_check6_out;
6591	pha.pa_rulname = "default-out6";
6592	pha.pa_flags = PFIL_OUT;
6593	V_pf_ip6_out_hook = pfil_add_hook(&pha);
6594	pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
6595	pla.pa_head = V_inet6_pfil_head;
6596	pla.pa_hook = V_pf_ip6_out_hook;
6597	ret = pfil_link(&pla);
6598	MPASS(ret == 0);
6599	if (V_pf_filter_local) {
6600		pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
6601		pla.pa_head = V_inet6_local_pfil_head;
6602		pla.pa_hook = V_pf_ip6_out_hook;
6603		ret = pfil_link(&pla);
6604		MPASS(ret == 0);
6605	}
6606#endif
6607
6608	atomic_store_bool(&V_pf_pfil_hooked, true);
6609}
6610
6611static void
6612dehook_pf_eth(void)
6613{
6614
6615	if (!atomic_load_bool(&V_pf_pfil_eth_hooked))
6616		return;
6617
6618	pfil_remove_hook(V_pf_eth_in_hook);
6619	pfil_remove_hook(V_pf_eth_out_hook);
6620
6621	atomic_store_bool(&V_pf_pfil_eth_hooked, false);
6622}
6623
6624static void
6625dehook_pf(void)
6626{
6627
6628	if (!atomic_load_bool(&V_pf_pfil_hooked))
6629		return;
6630
6631#ifdef INET
6632	pfil_remove_hook(V_pf_ip4_in_hook);
6633	pfil_remove_hook(V_pf_ip4_out_hook);
6634#endif
6635#ifdef INET6
6636	pfil_remove_hook(V_pf_ip6_in_hook);
6637	pfil_remove_hook(V_pf_ip6_out_hook);
6638#endif
6639
6640	atomic_store_bool(&V_pf_pfil_hooked, false);
6641}
6642
6643static void
6644pf_load_vnet(void)
6645{
6646	V_pf_tag_z = uma_zcreate("pf tags", sizeof(struct pf_tagname),
6647	    NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
6648
6649	rm_init_flags(&V_pf_rules_lock, "pf rulesets", RM_RECURSE);
6650	sx_init(&V_pf_ioctl_lock, "pf ioctl");
6651
6652	pf_init_tagset(&V_pf_tags, &pf_rule_tag_hashsize,
6653	    PF_RULE_TAG_HASH_SIZE_DEFAULT);
6654#ifdef ALTQ
6655	pf_init_tagset(&V_pf_qids, &pf_queue_tag_hashsize,
6656	    PF_QUEUE_TAG_HASH_SIZE_DEFAULT);
6657#endif
6658
6659	V_pf_keth = &V_pf_main_keth_anchor.ruleset;
6660
6661	pfattach_vnet();
6662	V_pf_vnet_active = 1;
6663}
6664
6665static int
6666pf_load(void)
6667{
6668	int error;
6669
6670	sx_init(&pf_end_lock, "pf end thread");
6671
6672	pf_mtag_initialize();
6673
6674	pf_dev = make_dev(&pf_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, PF_NAME);
6675	if (pf_dev == NULL)
6676		return (ENOMEM);
6677
6678	pf_end_threads = 0;
6679	error = kproc_create(pf_purge_thread, NULL, &pf_purge_proc, 0, 0, "pf purge");
6680	if (error != 0)
6681		return (error);
6682
6683	pfi_initialize();
6684
6685	return (0);
6686}
6687
6688static void
6689pf_unload_vnet(void)
6690{
6691	int ret __diagused;
6692
6693	V_pf_vnet_active = 0;
6694	V_pf_status.running = 0;
6695	dehook_pf();
6696	dehook_pf_eth();
6697
6698	PF_RULES_WLOCK();
6699	pf_syncookies_cleanup();
6700	shutdown_pf();
6701	PF_RULES_WUNLOCK();
6702
6703	/* Make sure we've cleaned up ethernet rules before we continue. */
6704	NET_EPOCH_DRAIN_CALLBACKS();
6705
6706	ret = swi_remove(V_pf_swi_cookie);
6707	MPASS(ret == 0);
6708	ret = intr_event_destroy(V_pf_swi_ie);
6709	MPASS(ret == 0);
6710
6711	pf_unload_vnet_purge();
6712
6713	pf_normalize_cleanup();
6714	PF_RULES_WLOCK();
6715	pfi_cleanup_vnet();
6716	PF_RULES_WUNLOCK();
6717	pfr_cleanup();
6718	pf_osfp_flush();
6719	pf_cleanup();
6720	if (IS_DEFAULT_VNET(curvnet))
6721		pf_mtag_cleanup();
6722
6723	pf_cleanup_tagset(&V_pf_tags);
6724#ifdef ALTQ
6725	pf_cleanup_tagset(&V_pf_qids);
6726#endif
6727	uma_zdestroy(V_pf_tag_z);
6728
6729#ifdef PF_WANT_32_TO_64_COUNTER
6730	PF_RULES_WLOCK();
6731	LIST_REMOVE(V_pf_kifmarker, pfik_allkiflist);
6732
6733	MPASS(LIST_EMPTY(&V_pf_allkiflist));
6734	MPASS(V_pf_allkifcount == 0);
6735
6736	LIST_REMOVE(&V_pf_default_rule, allrulelist);
6737	V_pf_allrulecount--;
6738	LIST_REMOVE(V_pf_rulemarker, allrulelist);
6739
6740	MPASS(LIST_EMPTY(&V_pf_allrulelist));
6741	MPASS(V_pf_allrulecount == 0);
6742
6743	PF_RULES_WUNLOCK();
6744
6745	free(V_pf_kifmarker, PFI_MTYPE);
6746	free(V_pf_rulemarker, M_PFRULE);
6747#endif
6748
6749	/* Free counters last as we updated them during shutdown. */
6750	pf_counter_u64_deinit(&V_pf_default_rule.evaluations);
6751	for (int i = 0; i < 2; i++) {
6752		pf_counter_u64_deinit(&V_pf_default_rule.packets[i]);
6753		pf_counter_u64_deinit(&V_pf_default_rule.bytes[i]);
6754	}
6755	counter_u64_free(V_pf_default_rule.states_cur);
6756	counter_u64_free(V_pf_default_rule.states_tot);
6757	counter_u64_free(V_pf_default_rule.src_nodes);
6758	uma_zfree_pcpu(pf_timestamp_pcpu_zone, V_pf_default_rule.timestamp);
6759
6760	for (int i = 0; i < PFRES_MAX; i++)
6761		counter_u64_free(V_pf_status.counters[i]);
6762	for (int i = 0; i < KLCNT_MAX; i++)
6763		counter_u64_free(V_pf_status.lcounters[i]);
6764	for (int i = 0; i < FCNT_MAX; i++)
6765		pf_counter_u64_deinit(&V_pf_status.fcounters[i]);
6766	for (int i = 0; i < SCNT_MAX; i++)
6767		counter_u64_free(V_pf_status.scounters[i]);
6768
6769	rm_destroy(&V_pf_rules_lock);
6770	sx_destroy(&V_pf_ioctl_lock);
6771}
6772
6773static void
6774pf_unload(void)
6775{
6776
6777	sx_xlock(&pf_end_lock);
6778	pf_end_threads = 1;
6779	while (pf_end_threads < 2) {
6780		wakeup_one(pf_purge_thread);
6781		sx_sleep(pf_purge_proc, &pf_end_lock, 0, "pftmo", 0);
6782	}
6783	sx_xunlock(&pf_end_lock);
6784
6785	pf_nl_unregister();
6786
6787	if (pf_dev != NULL)
6788		destroy_dev(pf_dev);
6789
6790	pfi_cleanup();
6791
6792	sx_destroy(&pf_end_lock);
6793}
6794
6795static void
6796vnet_pf_init(void *unused __unused)
6797{
6798
6799	pf_load_vnet();
6800}
6801VNET_SYSINIT(vnet_pf_init, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
6802    vnet_pf_init, NULL);
6803
6804static void
6805vnet_pf_uninit(const void *unused __unused)
6806{
6807
6808	pf_unload_vnet();
6809}
6810SYSUNINIT(pf_unload, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND, pf_unload, NULL);
6811VNET_SYSUNINIT(vnet_pf_uninit, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
6812    vnet_pf_uninit, NULL);
6813
6814static int
6815pf_modevent(module_t mod, int type, void *data)
6816{
6817	int error = 0;
6818
6819	switch(type) {
6820	case MOD_LOAD:
6821		error = pf_load();
6822		pf_nl_register();
6823		break;
6824	case MOD_UNLOAD:
6825		/* Handled in SYSUNINIT(pf_unload) to ensure it's done after
6826		 * the vnet_pf_uninit()s */
6827		break;
6828	default:
6829		error = EINVAL;
6830		break;
6831	}
6832
6833	return (error);
6834}
6835
6836static moduledata_t pf_mod = {
6837	"pf",
6838	pf_modevent,
6839	0
6840};
6841
6842DECLARE_MODULE(pf, pf_mod, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND);
6843MODULE_DEPEND(pf, netlink, 1, 1, 1);
6844MODULE_VERSION(pf, PF_MODVER);
6845