xref: /openbsd-src/sys/net/pf_ioctl.c (revision 78fec973f57e9fc9edd564490c79661460ad807b)
1 /*	$OpenBSD: pf_ioctl.c,v 1.382 2022/06/26 11:37:08 mbuhl Exp $ */
2 
3 /*
4  * Copyright (c) 2001 Daniel Hartmeier
5  * Copyright (c) 2002 - 2018 Henning Brauer <henning@openbsd.org>
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  *    - Redistributions of source code must retain the above copyright
13  *      notice, this list of conditions and the following disclaimer.
14  *    - Redistributions in binary form must reproduce the above
15  *      copyright notice, this list of conditions and the following
16  *      disclaimer in the documentation and/or other materials provided
17  *      with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  * Effort sponsored in part by the Defense Advanced Research Projects
33  * Agency (DARPA) and Air Force Research Laboratory, Air Force
34  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
35  *
36  */
37 
38 #include "pfsync.h"
39 #include "pflog.h"
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/sysctl.h>
44 #include <sys/mbuf.h>
45 #include <sys/filio.h>
46 #include <sys/fcntl.h>
47 #include <sys/socket.h>
48 #include <sys/socketvar.h>
49 #include <sys/kernel.h>
50 #include <sys/time.h>
51 #include <sys/timeout.h>
52 #include <sys/pool.h>
53 #include <sys/malloc.h>
54 #include <sys/proc.h>
55 #include <sys/rwlock.h>
56 #include <sys/syslog.h>
57 #include <uvm/uvm_extern.h>
58 
59 #include <crypto/md5.h>
60 
61 #include <net/if.h>
62 #include <net/if_var.h>
63 #include <net/route.h>
64 #include <net/hfsc.h>
65 #include <net/fq_codel.h>
66 
67 #include <netinet/in.h>
68 #include <netinet/ip.h>
69 #include <netinet/in_pcb.h>
70 #include <netinet/ip_var.h>
71 #include <netinet/ip_icmp.h>
72 #include <netinet/tcp.h>
73 #include <netinet/udp.h>
74 
75 #ifdef INET6
76 #include <netinet/ip6.h>
77 #include <netinet/icmp6.h>
78 #endif /* INET6 */
79 
80 #include <net/pfvar.h>
81 #include <net/pfvar_priv.h>
82 
83 #if NPFSYNC > 0
84 #include <netinet/ip_ipsp.h>
85 #include <net/if_pfsync.h>
86 #endif /* NPFSYNC > 0 */
87 
88 struct pool		 pf_tag_pl;
89 
90 void			 pfattach(int);
91 void			 pf_thread_create(void *);
92 int			 pfopen(dev_t, int, int, struct proc *);
93 int			 pfclose(dev_t, int, int, struct proc *);
94 int			 pfioctl(dev_t, u_long, caddr_t, int, struct proc *);
95 int			 pf_begin_rules(u_int32_t *, const char *);
96 void			 pf_rollback_rules(u_int32_t, char *);
97 void			 pf_remove_queues(void);
98 int			 pf_commit_queues(void);
99 void			 pf_free_queues(struct pf_queuehead *);
100 void			 pf_calc_chksum(struct pf_ruleset *);
101 void			 pf_hash_rule(MD5_CTX *, struct pf_rule *);
102 void			 pf_hash_rule_addr(MD5_CTX *, struct pf_rule_addr *);
103 int			 pf_commit_rules(u_int32_t, char *);
104 int			 pf_addr_setup(struct pf_ruleset *,
105 			    struct pf_addr_wrap *, sa_family_t);
106 struct pfi_kif		*pf_kif_setup(struct pfi_kif *);
107 void			 pf_addr_copyout(struct pf_addr_wrap *);
108 void			 pf_trans_set_commit(void);
109 void			 pf_pool_copyin(struct pf_pool *, struct pf_pool *);
110 int			 pf_validate_range(u_int8_t, u_int16_t[2], int);
111 int			 pf_rule_copyin(struct pf_rule *, struct pf_rule *);
112 int			 pf_rule_checkaf(struct pf_rule *);
113 u_int16_t		 pf_qname2qid(char *, int);
114 void			 pf_qid2qname(u_int16_t, char *);
115 void			 pf_qid_unref(u_int16_t);
116 int			 pf_states_clr(struct pfioc_state_kill *);
117 int			 pf_states_get(struct pfioc_states *);
118 
119 struct pf_rule		 pf_default_rule, pf_default_rule_new;
120 
121 struct {
122 	char		statusif[IFNAMSIZ];
123 	u_int32_t	debug;
124 	u_int32_t	hostid;
125 	u_int32_t	reass;
126 	u_int32_t	mask;
127 } pf_trans_set;
128 
129 #define	PF_ORDER_HOST	0
130 #define	PF_ORDER_NET	1
131 
132 #define	PF_TSET_STATUSIF	0x01
133 #define	PF_TSET_DEBUG		0x02
134 #define	PF_TSET_HOSTID		0x04
135 #define	PF_TSET_REASS		0x08
136 
137 #define	TAGID_MAX	 50000
138 TAILQ_HEAD(pf_tags, pf_tagname)	pf_tags = TAILQ_HEAD_INITIALIZER(pf_tags),
139 				pf_qids = TAILQ_HEAD_INITIALIZER(pf_qids);
140 
141 /*
142  * pf_lock protects consistency of PF data structures, which don't have
143  * their dedicated lock yet. The pf_lock currently protects:
144  *	- rules,
145  *	- radix tables,
146  *	- source nodes
147  * All callers must grab pf_lock exclusively.
148  *
149  * pf_state_lock protects consistency of state table. Packets, which do state
150  * look up grab the lock as readers. If packet must create state, then it must
151  * grab the lock as writer. Whenever packet creates state it grabs pf_lock
152  * first then it locks pf_state_lock as the writer.
153  */
154 struct rwlock		 pf_lock = RWLOCK_INITIALIZER("pf_lock");
155 struct rwlock		 pf_state_lock = RWLOCK_INITIALIZER("pf_state_lock");
156 struct rwlock		 pfioctl_rw = RWLOCK_INITIALIZER("pfioctl_rw");
157 
158 #if (PF_QNAME_SIZE != PF_TAG_NAME_SIZE)
159 #error PF_QNAME_SIZE must be equal to PF_TAG_NAME_SIZE
160 #endif
161 u_int16_t		 tagname2tag(struct pf_tags *, char *, int);
162 void			 tag2tagname(struct pf_tags *, u_int16_t, char *);
163 void			 tag_unref(struct pf_tags *, u_int16_t);
164 int			 pf_rtlabel_add(struct pf_addr_wrap *);
165 void			 pf_rtlabel_remove(struct pf_addr_wrap *);
166 void			 pf_rtlabel_copyout(struct pf_addr_wrap *);
167 
168 
169 void
170 pfattach(int num)
171 {
172 	u_int32_t *timeout = pf_default_rule.timeout;
173 
174 	pool_init(&pf_rule_pl, sizeof(struct pf_rule), 0,
175 	    IPL_SOFTNET, 0, "pfrule", NULL);
176 	pool_init(&pf_src_tree_pl, sizeof(struct pf_src_node), 0,
177 	    IPL_SOFTNET, 0, "pfsrctr", NULL);
178 	pool_init(&pf_sn_item_pl, sizeof(struct pf_sn_item), 0,
179 	    IPL_SOFTNET, 0, "pfsnitem", NULL);
180 	pool_init(&pf_state_pl, sizeof(struct pf_state), 0,
181 	    IPL_SOFTNET, 0, "pfstate", NULL);
182 	pool_init(&pf_state_key_pl, sizeof(struct pf_state_key), 0,
183 	    IPL_SOFTNET, 0, "pfstkey", NULL);
184 	pool_init(&pf_state_item_pl, sizeof(struct pf_state_item), 0,
185 	    IPL_SOFTNET, 0, "pfstitem", NULL);
186 	pool_init(&pf_rule_item_pl, sizeof(struct pf_rule_item), 0,
187 	    IPL_SOFTNET, 0, "pfruleitem", NULL);
188 	pool_init(&pf_queue_pl, sizeof(struct pf_queuespec), 0,
189 	    IPL_SOFTNET, 0, "pfqueue", NULL);
190 	pool_init(&pf_tag_pl, sizeof(struct pf_tagname), 0,
191 	    IPL_SOFTNET, 0, "pftag", NULL);
192 	pool_init(&pf_pktdelay_pl, sizeof(struct pf_pktdelay), 0,
193 	    IPL_SOFTNET, 0, "pfpktdelay", NULL);
194 
195 	hfsc_initialize();
196 	pfr_initialize();
197 	pfi_initialize();
198 	pf_osfp_initialize();
199 	pf_syncookies_init();
200 
201 	pool_sethardlimit(pf_pool_limits[PF_LIMIT_STATES].pp,
202 	    pf_pool_limits[PF_LIMIT_STATES].limit, NULL, 0);
203 
204 	if (physmem <= atop(100*1024*1024))
205 		pf_pool_limits[PF_LIMIT_TABLE_ENTRIES].limit =
206 		    PFR_KENTRY_HIWAT_SMALL;
207 
208 	RB_INIT(&tree_src_tracking);
209 	RB_INIT(&pf_anchors);
210 	pf_init_ruleset(&pf_main_ruleset);
211 	TAILQ_INIT(&pf_queues[0]);
212 	TAILQ_INIT(&pf_queues[1]);
213 	pf_queues_active = &pf_queues[0];
214 	pf_queues_inactive = &pf_queues[1];
215 
216 	/* default rule should never be garbage collected */
217 	pf_default_rule.entries.tqe_prev = &pf_default_rule.entries.tqe_next;
218 	pf_default_rule.action = PF_PASS;
219 	pf_default_rule.nr = (u_int32_t)-1;
220 	pf_default_rule.rtableid = -1;
221 
222 	/* initialize default timeouts */
223 	timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
224 	timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL;
225 	timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL;
226 	timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL;
227 	timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL;
228 	timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL;
229 	timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL;
230 	timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL;
231 	timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL;
232 	timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL;
233 	timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL;
234 	timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL;
235 	timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL;
236 	timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL;
237 	timeout[PFTM_FRAG] = PFTM_FRAG_VAL;
238 	timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL;
239 	timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL;
240 	timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL;
241 	timeout[PFTM_ADAPTIVE_START] = PFSTATE_ADAPT_START;
242 	timeout[PFTM_ADAPTIVE_END] = PFSTATE_ADAPT_END;
243 
244 	pf_default_rule.src.addr.type =  PF_ADDR_ADDRMASK;
245 	pf_default_rule.dst.addr.type =  PF_ADDR_ADDRMASK;
246 	pf_default_rule.rdr.addr.type =  PF_ADDR_NONE;
247 	pf_default_rule.nat.addr.type =  PF_ADDR_NONE;
248 	pf_default_rule.route.addr.type =  PF_ADDR_NONE;
249 
250 	pf_normalize_init();
251 	memset(&pf_status, 0, sizeof(pf_status));
252 	pf_status.debug = LOG_ERR;
253 	pf_status.reass = PF_REASS_ENABLED;
254 
255 	/* XXX do our best to avoid a conflict */
256 	pf_status.hostid = arc4random();
257 
258 	pf_default_rule_new = pf_default_rule;
259 }
260 
261 int
262 pfopen(dev_t dev, int flags, int fmt, struct proc *p)
263 {
264 	if (minor(dev) >= 1)
265 		return (ENXIO);
266 	return (0);
267 }
268 
269 int
270 pfclose(dev_t dev, int flags, int fmt, struct proc *p)
271 {
272 	if (minor(dev) >= 1)
273 		return (ENXIO);
274 	return (0);
275 }
276 
277 void
278 pf_rule_free(struct pf_rule *rule)
279 {
280 	if (rule == NULL)
281 		return;
282 
283 	pfi_kif_free(rule->kif);
284 	pfi_kif_free(rule->rcv_kif);
285 	pfi_kif_free(rule->rdr.kif);
286 	pfi_kif_free(rule->nat.kif);
287 	pfi_kif_free(rule->route.kif);
288 
289 	pool_put(&pf_rule_pl, rule);
290 }
291 
292 void
293 pf_rm_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule)
294 {
295 	if (rulequeue != NULL) {
296 		if (rule->states_cur == 0 && rule->src_nodes == 0) {
297 			/*
298 			 * XXX - we need to remove the table *before* detaching
299 			 * the rule to make sure the table code does not delete
300 			 * the anchor under our feet.
301 			 */
302 			pf_tbladdr_remove(&rule->src.addr);
303 			pf_tbladdr_remove(&rule->dst.addr);
304 			pf_tbladdr_remove(&rule->rdr.addr);
305 			pf_tbladdr_remove(&rule->nat.addr);
306 			pf_tbladdr_remove(&rule->route.addr);
307 			if (rule->overload_tbl)
308 				pfr_detach_table(rule->overload_tbl);
309 		}
310 		TAILQ_REMOVE(rulequeue, rule, entries);
311 		rule->entries.tqe_prev = NULL;
312 		rule->nr = (u_int32_t)-1;
313 	}
314 
315 	if (rule->states_cur > 0 || rule->src_nodes > 0 ||
316 	    rule->entries.tqe_prev != NULL)
317 		return;
318 	pf_tag_unref(rule->tag);
319 	pf_tag_unref(rule->match_tag);
320 	pf_rtlabel_remove(&rule->src.addr);
321 	pf_rtlabel_remove(&rule->dst.addr);
322 	pfi_dynaddr_remove(&rule->src.addr);
323 	pfi_dynaddr_remove(&rule->dst.addr);
324 	pfi_dynaddr_remove(&rule->rdr.addr);
325 	pfi_dynaddr_remove(&rule->nat.addr);
326 	pfi_dynaddr_remove(&rule->route.addr);
327 	if (rulequeue == NULL) {
328 		pf_tbladdr_remove(&rule->src.addr);
329 		pf_tbladdr_remove(&rule->dst.addr);
330 		pf_tbladdr_remove(&rule->rdr.addr);
331 		pf_tbladdr_remove(&rule->nat.addr);
332 		pf_tbladdr_remove(&rule->route.addr);
333 		if (rule->overload_tbl)
334 			pfr_detach_table(rule->overload_tbl);
335 	}
336 	pfi_kif_unref(rule->rcv_kif, PFI_KIF_REF_RULE);
337 	pfi_kif_unref(rule->kif, PFI_KIF_REF_RULE);
338 	pfi_kif_unref(rule->rdr.kif, PFI_KIF_REF_RULE);
339 	pfi_kif_unref(rule->nat.kif, PFI_KIF_REF_RULE);
340 	pfi_kif_unref(rule->route.kif, PFI_KIF_REF_RULE);
341 	pf_remove_anchor(rule);
342 	pool_put(&pf_rule_pl, rule);
343 }
344 
345 void
346 pf_purge_rule(struct pf_rule *rule)
347 {
348 	u_int32_t		 nr = 0;
349 	struct pf_ruleset	*ruleset;
350 
351 	KASSERT((rule != NULL) && (rule->ruleset != NULL));
352 	ruleset = rule->ruleset;
353 
354 	pf_rm_rule(ruleset->rules.active.ptr, rule);
355 	ruleset->rules.active.rcount--;
356 	TAILQ_FOREACH(rule, ruleset->rules.active.ptr, entries)
357 		rule->nr = nr++;
358 	ruleset->rules.active.ticket++;
359 	pf_calc_skip_steps(ruleset->rules.active.ptr);
360 	pf_remove_if_empty_ruleset(ruleset);
361 
362 	if (ruleset == &pf_main_ruleset)
363 		pf_calc_chksum(ruleset);
364 }
365 
366 u_int16_t
367 tagname2tag(struct pf_tags *head, char *tagname, int create)
368 {
369 	struct pf_tagname	*tag, *p = NULL;
370 	u_int16_t		 new_tagid = 1;
371 
372 	TAILQ_FOREACH(tag, head, entries)
373 		if (strcmp(tagname, tag->name) == 0) {
374 			tag->ref++;
375 			return (tag->tag);
376 		}
377 
378 	if (!create)
379 		return (0);
380 
381 	/*
382 	 * to avoid fragmentation, we do a linear search from the beginning
383 	 * and take the first free slot we find. if there is none or the list
384 	 * is empty, append a new entry at the end.
385 	 */
386 
387 	/* new entry */
388 	TAILQ_FOREACH(p, head, entries) {
389 		if (p->tag != new_tagid)
390 			break;
391 		new_tagid = p->tag + 1;
392 	}
393 
394 	if (new_tagid > TAGID_MAX)
395 		return (0);
396 
397 	/* allocate and fill new struct pf_tagname */
398 	tag = pool_get(&pf_tag_pl, PR_NOWAIT | PR_ZERO);
399 	if (tag == NULL)
400 		return (0);
401 	strlcpy(tag->name, tagname, sizeof(tag->name));
402 	tag->tag = new_tagid;
403 	tag->ref++;
404 
405 	if (p != NULL)	/* insert new entry before p */
406 		TAILQ_INSERT_BEFORE(p, tag, entries);
407 	else	/* either list empty or no free slot in between */
408 		TAILQ_INSERT_TAIL(head, tag, entries);
409 
410 	return (tag->tag);
411 }
412 
413 void
414 tag2tagname(struct pf_tags *head, u_int16_t tagid, char *p)
415 {
416 	struct pf_tagname	*tag;
417 
418 	TAILQ_FOREACH(tag, head, entries)
419 		if (tag->tag == tagid) {
420 			strlcpy(p, tag->name, PF_TAG_NAME_SIZE);
421 			return;
422 		}
423 }
424 
425 void
426 tag_unref(struct pf_tags *head, u_int16_t tag)
427 {
428 	struct pf_tagname	*p, *next;
429 
430 	if (tag == 0)
431 		return;
432 
433 	TAILQ_FOREACH_SAFE(p, head, entries, next) {
434 		if (tag == p->tag) {
435 			if (--p->ref == 0) {
436 				TAILQ_REMOVE(head, p, entries);
437 				pool_put(&pf_tag_pl, p);
438 			}
439 			break;
440 		}
441 	}
442 }
443 
444 u_int16_t
445 pf_tagname2tag(char *tagname, int create)
446 {
447 	return (tagname2tag(&pf_tags, tagname, create));
448 }
449 
450 void
451 pf_tag2tagname(u_int16_t tagid, char *p)
452 {
453 	tag2tagname(&pf_tags, tagid, p);
454 }
455 
456 void
457 pf_tag_ref(u_int16_t tag)
458 {
459 	struct pf_tagname *t;
460 
461 	TAILQ_FOREACH(t, &pf_tags, entries)
462 		if (t->tag == tag)
463 			break;
464 	if (t != NULL)
465 		t->ref++;
466 }
467 
468 void
469 pf_tag_unref(u_int16_t tag)
470 {
471 	tag_unref(&pf_tags, tag);
472 }
473 
474 int
475 pf_rtlabel_add(struct pf_addr_wrap *a)
476 {
477 	if (a->type == PF_ADDR_RTLABEL &&
478 	    (a->v.rtlabel = rtlabel_name2id(a->v.rtlabelname)) == 0)
479 		return (-1);
480 	return (0);
481 }
482 
483 void
484 pf_rtlabel_remove(struct pf_addr_wrap *a)
485 {
486 	if (a->type == PF_ADDR_RTLABEL)
487 		rtlabel_unref(a->v.rtlabel);
488 }
489 
490 void
491 pf_rtlabel_copyout(struct pf_addr_wrap *a)
492 {
493 	const char	*name;
494 
495 	if (a->type == PF_ADDR_RTLABEL && a->v.rtlabel) {
496 		if ((name = rtlabel_id2name(a->v.rtlabel)) == NULL)
497 			strlcpy(a->v.rtlabelname, "?",
498 			    sizeof(a->v.rtlabelname));
499 		else
500 			strlcpy(a->v.rtlabelname, name,
501 			    sizeof(a->v.rtlabelname));
502 	}
503 }
504 
505 u_int16_t
506 pf_qname2qid(char *qname, int create)
507 {
508 	return (tagname2tag(&pf_qids, qname, create));
509 }
510 
511 void
512 pf_qid2qname(u_int16_t qid, char *p)
513 {
514 	tag2tagname(&pf_qids, qid, p);
515 }
516 
517 void
518 pf_qid_unref(u_int16_t qid)
519 {
520 	tag_unref(&pf_qids, (u_int16_t)qid);
521 }
522 
523 int
524 pf_begin_rules(u_int32_t *ticket, const char *anchor)
525 {
526 	struct pf_ruleset	*rs;
527 	struct pf_rule		*rule;
528 
529 	if ((rs = pf_find_or_create_ruleset(anchor)) == NULL)
530 		return (EINVAL);
531 	while ((rule = TAILQ_FIRST(rs->rules.inactive.ptr)) != NULL) {
532 		pf_rm_rule(rs->rules.inactive.ptr, rule);
533 		rs->rules.inactive.rcount--;
534 	}
535 	*ticket = ++rs->rules.inactive.ticket;
536 	rs->rules.inactive.open = 1;
537 	return (0);
538 }
539 
540 void
541 pf_rollback_rules(u_int32_t ticket, char *anchor)
542 {
543 	struct pf_ruleset	*rs;
544 	struct pf_rule		*rule;
545 
546 	rs = pf_find_ruleset(anchor);
547 	if (rs == NULL || !rs->rules.inactive.open ||
548 	    rs->rules.inactive.ticket != ticket)
549 		return;
550 	while ((rule = TAILQ_FIRST(rs->rules.inactive.ptr)) != NULL) {
551 		pf_rm_rule(rs->rules.inactive.ptr, rule);
552 		rs->rules.inactive.rcount--;
553 	}
554 	rs->rules.inactive.open = 0;
555 
556 	/* queue defs only in the main ruleset */
557 	if (anchor[0])
558 		return;
559 
560 	pf_free_queues(pf_queues_inactive);
561 }
562 
563 void
564 pf_free_queues(struct pf_queuehead *where)
565 {
566 	struct pf_queuespec	*q, *qtmp;
567 
568 	TAILQ_FOREACH_SAFE(q, where, entries, qtmp) {
569 		TAILQ_REMOVE(where, q, entries);
570 		pfi_kif_unref(q->kif, PFI_KIF_REF_RULE);
571 		pool_put(&pf_queue_pl, q);
572 	}
573 }
574 
575 void
576 pf_remove_queues(void)
577 {
578 	struct pf_queuespec	*q;
579 	struct ifnet		*ifp;
580 
581 	/* put back interfaces in normal queueing mode */
582 	TAILQ_FOREACH(q, pf_queues_active, entries) {
583 		if (q->parent_qid != 0)
584 			continue;
585 
586 		ifp = q->kif->pfik_ifp;
587 		if (ifp == NULL)
588 			continue;
589 
590 		ifq_attach(&ifp->if_snd, ifq_priq_ops, NULL);
591 	}
592 }
593 
594 struct pf_queue_if {
595 	struct ifnet		*ifp;
596 	const struct ifq_ops	*ifqops;
597 	const struct pfq_ops	*pfqops;
598 	void			*disc;
599 	struct pf_queue_if	*next;
600 };
601 
602 static inline struct pf_queue_if *
603 pf_ifp2q(struct pf_queue_if *list, struct ifnet *ifp)
604 {
605 	struct pf_queue_if *qif = list;
606 
607 	while (qif != NULL) {
608 		if (qif->ifp == ifp)
609 			return (qif);
610 
611 		qif = qif->next;
612 	}
613 
614 	return (qif);
615 }
616 
617 int
618 pf_create_queues(void)
619 {
620 	struct pf_queuespec	*q;
621 	struct ifnet		*ifp;
622 	struct pf_queue_if		*list = NULL, *qif;
623 	int			 error;
624 
625 	/*
626 	 * Find root queues and allocate traffic conditioner
627 	 * private data for these interfaces
628 	 */
629 	TAILQ_FOREACH(q, pf_queues_active, entries) {
630 		if (q->parent_qid != 0)
631 			continue;
632 
633 		ifp = q->kif->pfik_ifp;
634 		if (ifp == NULL)
635 			continue;
636 
637 		qif = malloc(sizeof(*qif), M_TEMP, M_WAITOK);
638 		qif->ifp = ifp;
639 
640 		if (q->flags & PFQS_ROOTCLASS) {
641 			qif->ifqops = ifq_hfsc_ops;
642 			qif->pfqops = pfq_hfsc_ops;
643 		} else {
644 			qif->ifqops = ifq_fqcodel_ops;
645 			qif->pfqops = pfq_fqcodel_ops;
646 		}
647 
648 		qif->disc = qif->pfqops->pfq_alloc(ifp);
649 
650 		qif->next = list;
651 		list = qif;
652 	}
653 
654 	/* and now everything */
655 	TAILQ_FOREACH(q, pf_queues_active, entries) {
656 		ifp = q->kif->pfik_ifp;
657 		if (ifp == NULL)
658 			continue;
659 
660 		qif = pf_ifp2q(list, ifp);
661 		KASSERT(qif != NULL);
662 
663 		error = qif->pfqops->pfq_addqueue(qif->disc, q);
664 		if (error != 0)
665 			goto error;
666 	}
667 
668 	/* find root queues in old list to disable them if necessary */
669 	TAILQ_FOREACH(q, pf_queues_inactive, entries) {
670 		if (q->parent_qid != 0)
671 			continue;
672 
673 		ifp = q->kif->pfik_ifp;
674 		if (ifp == NULL)
675 			continue;
676 
677 		qif = pf_ifp2q(list, ifp);
678 		if (qif != NULL)
679 			continue;
680 
681 		ifq_attach(&ifp->if_snd, ifq_priq_ops, NULL);
682 	}
683 
684 	/* commit the new queues */
685 	while (list != NULL) {
686 		qif = list;
687 		list = qif->next;
688 
689 		ifp = qif->ifp;
690 
691 		ifq_attach(&ifp->if_snd, qif->ifqops, qif->disc);
692 		free(qif, M_TEMP, sizeof(*qif));
693 	}
694 
695 	return (0);
696 
697 error:
698 	while (list != NULL) {
699 		qif = list;
700 		list = qif->next;
701 
702 		qif->pfqops->pfq_free(qif->disc);
703 		free(qif, M_TEMP, sizeof(*qif));
704 	}
705 
706 	return (error);
707 }
708 
709 int
710 pf_commit_queues(void)
711 {
712 	struct pf_queuehead	*qswap;
713 	int error;
714 
715 	/* swap */
716 	qswap = pf_queues_active;
717 	pf_queues_active = pf_queues_inactive;
718 	pf_queues_inactive = qswap;
719 
720 	error = pf_create_queues();
721 	if (error != 0) {
722 		pf_queues_inactive = pf_queues_active;
723 		pf_queues_active = qswap;
724 		return (error);
725 	}
726 
727 	pf_free_queues(pf_queues_inactive);
728 
729 	return (0);
730 }
731 
732 const struct pfq_ops *
733 pf_queue_manager(struct pf_queuespec *q)
734 {
735 	if (q->flags & PFQS_FLOWQUEUE)
736 		return pfq_fqcodel_ops;
737 	return (/* pfq_default_ops */ NULL);
738 }
739 
740 #define PF_MD5_UPD(st, elm)						\
741 		MD5Update(ctx, (u_int8_t *) &(st)->elm, sizeof((st)->elm))
742 
743 #define PF_MD5_UPD_STR(st, elm)						\
744 		MD5Update(ctx, (u_int8_t *) (st)->elm, strlen((st)->elm))
745 
746 #define PF_MD5_UPD_HTONL(st, elm, stor) do {				\
747 		(stor) = htonl((st)->elm);				\
748 		MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int32_t));\
749 } while (0)
750 
751 #define PF_MD5_UPD_HTONS(st, elm, stor) do {				\
752 		(stor) = htons((st)->elm);				\
753 		MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int16_t));\
754 } while (0)
755 
756 void
757 pf_hash_rule_addr(MD5_CTX *ctx, struct pf_rule_addr *pfr)
758 {
759 	PF_MD5_UPD(pfr, addr.type);
760 	switch (pfr->addr.type) {
761 		case PF_ADDR_DYNIFTL:
762 			PF_MD5_UPD(pfr, addr.v.ifname);
763 			PF_MD5_UPD(pfr, addr.iflags);
764 			break;
765 		case PF_ADDR_TABLE:
766 			if (strncmp(pfr->addr.v.tblname, PF_OPTIMIZER_TABLE_PFX,
767 			    strlen(PF_OPTIMIZER_TABLE_PFX)))
768 				PF_MD5_UPD(pfr, addr.v.tblname);
769 			break;
770 		case PF_ADDR_ADDRMASK:
771 			/* XXX ignore af? */
772 			PF_MD5_UPD(pfr, addr.v.a.addr.addr32);
773 			PF_MD5_UPD(pfr, addr.v.a.mask.addr32);
774 			break;
775 		case PF_ADDR_RTLABEL:
776 			PF_MD5_UPD(pfr, addr.v.rtlabelname);
777 			break;
778 	}
779 
780 	PF_MD5_UPD(pfr, port[0]);
781 	PF_MD5_UPD(pfr, port[1]);
782 	PF_MD5_UPD(pfr, neg);
783 	PF_MD5_UPD(pfr, port_op);
784 }
785 
786 void
787 pf_hash_rule(MD5_CTX *ctx, struct pf_rule *rule)
788 {
789 	u_int16_t x;
790 	u_int32_t y;
791 
792 	pf_hash_rule_addr(ctx, &rule->src);
793 	pf_hash_rule_addr(ctx, &rule->dst);
794 	PF_MD5_UPD_STR(rule, label);
795 	PF_MD5_UPD_STR(rule, ifname);
796 	PF_MD5_UPD_STR(rule, rcv_ifname);
797 	PF_MD5_UPD_STR(rule, match_tagname);
798 	PF_MD5_UPD_HTONS(rule, match_tag, x); /* dup? */
799 	PF_MD5_UPD_HTONL(rule, os_fingerprint, y);
800 	PF_MD5_UPD_HTONL(rule, prob, y);
801 	PF_MD5_UPD_HTONL(rule, uid.uid[0], y);
802 	PF_MD5_UPD_HTONL(rule, uid.uid[1], y);
803 	PF_MD5_UPD(rule, uid.op);
804 	PF_MD5_UPD_HTONL(rule, gid.gid[0], y);
805 	PF_MD5_UPD_HTONL(rule, gid.gid[1], y);
806 	PF_MD5_UPD(rule, gid.op);
807 	PF_MD5_UPD_HTONL(rule, rule_flag, y);
808 	PF_MD5_UPD(rule, action);
809 	PF_MD5_UPD(rule, direction);
810 	PF_MD5_UPD(rule, af);
811 	PF_MD5_UPD(rule, quick);
812 	PF_MD5_UPD(rule, ifnot);
813 	PF_MD5_UPD(rule, rcvifnot);
814 	PF_MD5_UPD(rule, match_tag_not);
815 	PF_MD5_UPD(rule, keep_state);
816 	PF_MD5_UPD(rule, proto);
817 	PF_MD5_UPD(rule, type);
818 	PF_MD5_UPD(rule, code);
819 	PF_MD5_UPD(rule, flags);
820 	PF_MD5_UPD(rule, flagset);
821 	PF_MD5_UPD(rule, allow_opts);
822 	PF_MD5_UPD(rule, rt);
823 	PF_MD5_UPD(rule, tos);
824 }
825 
826 int
827 pf_commit_rules(u_int32_t ticket, char *anchor)
828 {
829 	struct pf_ruleset	*rs;
830 	struct pf_rule		*rule;
831 	struct pf_rulequeue	*old_rules;
832 	u_int32_t		 old_rcount;
833 
834 	/* Make sure any expired rules get removed from active rules first. */
835 	pf_purge_expired_rules();
836 
837 	rs = pf_find_ruleset(anchor);
838 	if (rs == NULL || !rs->rules.inactive.open ||
839 	    ticket != rs->rules.inactive.ticket)
840 		return (EBUSY);
841 
842 	if (rs == &pf_main_ruleset)
843 		pf_calc_chksum(rs);
844 
845 	/* Swap rules, keep the old. */
846 	old_rules = rs->rules.active.ptr;
847 	old_rcount = rs->rules.active.rcount;
848 
849 	rs->rules.active.ptr = rs->rules.inactive.ptr;
850 	rs->rules.active.rcount = rs->rules.inactive.rcount;
851 	rs->rules.inactive.ptr = old_rules;
852 	rs->rules.inactive.rcount = old_rcount;
853 
854 	rs->rules.active.ticket = rs->rules.inactive.ticket;
855 	pf_calc_skip_steps(rs->rules.active.ptr);
856 
857 
858 	/* Purge the old rule list. */
859 	while ((rule = TAILQ_FIRST(old_rules)) != NULL)
860 		pf_rm_rule(old_rules, rule);
861 	rs->rules.inactive.rcount = 0;
862 	rs->rules.inactive.open = 0;
863 	pf_remove_if_empty_ruleset(rs);
864 
865 	/* queue defs only in the main ruleset */
866 	if (anchor[0])
867 		return (0);
868 	return (pf_commit_queues());
869 }
870 
871 void
872 pf_calc_chksum(struct pf_ruleset *rs)
873 {
874 	MD5_CTX			 ctx;
875 	struct pf_rule		*rule;
876 	u_int8_t		 digest[PF_MD5_DIGEST_LENGTH];
877 
878 	MD5Init(&ctx);
879 
880 	if (rs->rules.inactive.rcount) {
881 		TAILQ_FOREACH(rule, rs->rules.inactive.ptr, entries) {
882 			pf_hash_rule(&ctx, rule);
883 		}
884 	}
885 
886 	MD5Final(digest, &ctx);
887 	memcpy(pf_status.pf_chksum, digest, sizeof(pf_status.pf_chksum));
888 }
889 
890 int
891 pf_addr_setup(struct pf_ruleset *ruleset, struct pf_addr_wrap *addr,
892     sa_family_t af)
893 {
894 	if (pfi_dynaddr_setup(addr, af, PR_WAITOK) ||
895 	    pf_tbladdr_setup(ruleset, addr, PR_WAITOK) ||
896 	    pf_rtlabel_add(addr))
897 		return (EINVAL);
898 
899 	return (0);
900 }
901 
902 struct pfi_kif *
903 pf_kif_setup(struct pfi_kif *kif_buf)
904 {
905 	struct pfi_kif *kif;
906 
907 	if (kif_buf == NULL)
908 		return (NULL);
909 
910 	KASSERT(kif_buf->pfik_name[0] != '\0');
911 
912 	kif = pfi_kif_get(kif_buf->pfik_name, &kif_buf);
913 	if (kif_buf != NULL)
914 		pfi_kif_free(kif_buf);
915 	pfi_kif_ref(kif, PFI_KIF_REF_RULE);
916 
917 	return (kif);
918 }
919 
920 void
921 pf_addr_copyout(struct pf_addr_wrap *addr)
922 {
923 	pfi_dynaddr_copyout(addr);
924 	pf_tbladdr_copyout(addr);
925 	pf_rtlabel_copyout(addr);
926 }
927 
928 int
929 pf_states_clr(struct pfioc_state_kill *psk)
930 {
931 	struct pf_state		*s, *nexts;
932 	struct pf_state		*head, *tail;
933 	u_int			 killed = 0;
934 	int			 error;
935 
936 	NET_LOCK();
937 
938 	/* lock against the gc removing an item from the list */
939 	error = rw_enter(&pf_state_list.pfs_rwl, RW_READ|RW_INTR);
940 	if (error != 0)
941 		goto unlock;
942 
943 	/* get a snapshot view of the ends of the list to traverse between */
944 	mtx_enter(&pf_state_list.pfs_mtx);
945 	head = TAILQ_FIRST(&pf_state_list.pfs_list);
946 	tail = TAILQ_LAST(&pf_state_list.pfs_list, pf_state_queue);
947 	mtx_leave(&pf_state_list.pfs_mtx);
948 
949 	s = NULL;
950 	nexts = head;
951 
952 	PF_LOCK();
953 	PF_STATE_ENTER_WRITE();
954 
955 	while (s != tail) {
956 		s = nexts;
957 		nexts = TAILQ_NEXT(s, entry_list);
958 
959 		if (s->timeout == PFTM_UNLINKED)
960 			continue;
961 
962 		if (!psk->psk_ifname[0] || !strcmp(psk->psk_ifname,
963 		    s->kif->pfik_name)) {
964 #if NPFSYNC > 0
965 			/* don't send out individual delete messages */
966 			SET(s->state_flags, PFSTATE_NOSYNC);
967 #endif	/* NPFSYNC > 0 */
968 			pf_remove_state(s);
969 			killed++;
970 		}
971 	}
972 
973 	PF_STATE_EXIT_WRITE();
974 #if NPFSYNC > 0
975 	pfsync_clear_states(pf_status.hostid, psk->psk_ifname);
976 #endif	/* NPFSYNC > 0 */
977 	PF_UNLOCK();
978 	rw_exit(&pf_state_list.pfs_rwl);
979 
980 	psk->psk_killed = killed;
981 unlock:
982 	NET_UNLOCK();
983 
984 	return (error);
985 }
986 
987 int
988 pf_states_get(struct pfioc_states *ps)
989 {
990 	struct pf_state		*head, *tail;
991 	struct pf_state		*next, *state;
992 	struct pfsync_state	*p, pstore;
993 	u_int32_t		 nr = 0;
994 	int			 error;
995 
996 	if (ps->ps_len == 0) {
997 		nr = pf_status.states;
998 		ps->ps_len = sizeof(struct pfsync_state) * nr;
999 		return (0);
1000 	}
1001 
1002 	p = ps->ps_states;
1003 
1004 	/* lock against the gc removing an item from the list */
1005 	error = rw_enter(&pf_state_list.pfs_rwl, RW_READ|RW_INTR);
1006 	if (error != 0)
1007 		return (error);
1008 
1009 	/* get a snapshot view of the ends of the list to traverse between */
1010 	mtx_enter(&pf_state_list.pfs_mtx);
1011 	head = TAILQ_FIRST(&pf_state_list.pfs_list);
1012 	tail = TAILQ_LAST(&pf_state_list.pfs_list, pf_state_queue);
1013 	mtx_leave(&pf_state_list.pfs_mtx);
1014 
1015 	state = NULL;
1016 	next = head;
1017 
1018 	while (state != tail) {
1019 		state = next;
1020 		next = TAILQ_NEXT(state, entry_list);
1021 
1022 		if (state->timeout == PFTM_UNLINKED)
1023 			continue;
1024 
1025 		if ((nr+1) * sizeof(*p) > ps->ps_len)
1026 			break;
1027 
1028 		pf_state_export(&pstore, state);
1029 		error = copyout(&pstore, p, sizeof(*p));
1030 		if (error)
1031 			goto fail;
1032 
1033 		p++;
1034 		nr++;
1035 	}
1036 	ps->ps_len = sizeof(struct pfsync_state) * nr;
1037 
1038 fail:
1039 	rw_exit(&pf_state_list.pfs_rwl);
1040 
1041 	return (error);
1042 }
1043 
1044 int
1045 pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
1046 {
1047 	int			 error = 0;
1048 
1049 	/* XXX keep in sync with switch() below */
1050 	if (securelevel > 1)
1051 		switch (cmd) {
1052 		case DIOCGETRULES:
1053 		case DIOCGETRULE:
1054 		case DIOCGETSTATE:
1055 		case DIOCSETSTATUSIF:
1056 		case DIOCGETSTATUS:
1057 		case DIOCCLRSTATUS:
1058 		case DIOCNATLOOK:
1059 		case DIOCSETDEBUG:
1060 		case DIOCGETSTATES:
1061 		case DIOCGETTIMEOUT:
1062 		case DIOCGETLIMIT:
1063 		case DIOCGETRULESETS:
1064 		case DIOCGETRULESET:
1065 		case DIOCGETQUEUES:
1066 		case DIOCGETQUEUE:
1067 		case DIOCGETQSTATS:
1068 		case DIOCRGETTABLES:
1069 		case DIOCRGETTSTATS:
1070 		case DIOCRCLRTSTATS:
1071 		case DIOCRCLRADDRS:
1072 		case DIOCRADDADDRS:
1073 		case DIOCRDELADDRS:
1074 		case DIOCRSETADDRS:
1075 		case DIOCRGETADDRS:
1076 		case DIOCRGETASTATS:
1077 		case DIOCRCLRASTATS:
1078 		case DIOCRTSTADDRS:
1079 		case DIOCOSFPGET:
1080 		case DIOCGETSRCNODES:
1081 		case DIOCCLRSRCNODES:
1082 		case DIOCIGETIFACES:
1083 		case DIOCSETIFFLAG:
1084 		case DIOCCLRIFFLAG:
1085 		case DIOCGETSYNFLWATS:
1086 			break;
1087 		case DIOCRCLRTABLES:
1088 		case DIOCRADDTABLES:
1089 		case DIOCRDELTABLES:
1090 		case DIOCRSETTFLAGS:
1091 			if (((struct pfioc_table *)addr)->pfrio_flags &
1092 			    PFR_FLAG_DUMMY)
1093 				break; /* dummy operation ok */
1094 			return (EPERM);
1095 		default:
1096 			return (EPERM);
1097 		}
1098 
1099 	if (!(flags & FWRITE))
1100 		switch (cmd) {
1101 		case DIOCGETRULES:
1102 		case DIOCGETSTATE:
1103 		case DIOCGETSTATUS:
1104 		case DIOCGETSTATES:
1105 		case DIOCGETTIMEOUT:
1106 		case DIOCGETLIMIT:
1107 		case DIOCGETRULESETS:
1108 		case DIOCGETRULESET:
1109 		case DIOCGETQUEUES:
1110 		case DIOCGETQUEUE:
1111 		case DIOCGETQSTATS:
1112 		case DIOCNATLOOK:
1113 		case DIOCRGETTABLES:
1114 		case DIOCRGETTSTATS:
1115 		case DIOCRGETADDRS:
1116 		case DIOCRGETASTATS:
1117 		case DIOCRTSTADDRS:
1118 		case DIOCOSFPGET:
1119 		case DIOCGETSRCNODES:
1120 		case DIOCIGETIFACES:
1121 		case DIOCGETSYNFLWATS:
1122 			break;
1123 		case DIOCRCLRTABLES:
1124 		case DIOCRADDTABLES:
1125 		case DIOCRDELTABLES:
1126 		case DIOCRCLRTSTATS:
1127 		case DIOCRCLRADDRS:
1128 		case DIOCRADDADDRS:
1129 		case DIOCRDELADDRS:
1130 		case DIOCRSETADDRS:
1131 		case DIOCRSETTFLAGS:
1132 			if (((struct pfioc_table *)addr)->pfrio_flags &
1133 			    PFR_FLAG_DUMMY) {
1134 				flags |= FWRITE; /* need write lock for dummy */
1135 				break; /* dummy operation ok */
1136 			}
1137 			return (EACCES);
1138 		case DIOCGETRULE:
1139 			if (((struct pfioc_rule *)addr)->action ==
1140 			    PF_GET_CLR_CNTR)
1141 				return (EACCES);
1142 			break;
1143 		default:
1144 			return (EACCES);
1145 		}
1146 
1147 	if (flags & FWRITE)
1148 		rw_enter_write(&pfioctl_rw);
1149 	else
1150 		rw_enter_read(&pfioctl_rw);
1151 
1152 	switch (cmd) {
1153 
1154 	case DIOCSTART:
1155 		NET_LOCK();
1156 		PF_LOCK();
1157 		if (pf_status.running)
1158 			error = EEXIST;
1159 		else {
1160 			pf_status.running = 1;
1161 			pf_status.since = getuptime();
1162 			if (pf_status.stateid == 0) {
1163 				pf_status.stateid = gettime();
1164 				pf_status.stateid = pf_status.stateid << 32;
1165 			}
1166 			timeout_add_sec(&pf_purge_to, 1);
1167 			pf_create_queues();
1168 			DPFPRINTF(LOG_NOTICE, "pf: started");
1169 		}
1170 		PF_UNLOCK();
1171 		NET_UNLOCK();
1172 		break;
1173 
1174 	case DIOCSTOP:
1175 		NET_LOCK();
1176 		PF_LOCK();
1177 		if (!pf_status.running)
1178 			error = ENOENT;
1179 		else {
1180 			pf_status.running = 0;
1181 			pf_status.since = getuptime();
1182 			pf_remove_queues();
1183 			DPFPRINTF(LOG_NOTICE, "pf: stopped");
1184 		}
1185 		PF_UNLOCK();
1186 		NET_UNLOCK();
1187 		break;
1188 
1189 	case DIOCGETQUEUES: {
1190 		struct pfioc_queue	*pq = (struct pfioc_queue *)addr;
1191 		struct pf_queuespec	*qs;
1192 		u_int32_t		 nr = 0;
1193 
1194 		NET_LOCK();
1195 		PF_LOCK();
1196 		pq->ticket = pf_main_ruleset.rules.active.ticket;
1197 
1198 		/* save state to not run over them all each time? */
1199 		qs = TAILQ_FIRST(pf_queues_active);
1200 		while (qs != NULL) {
1201 			qs = TAILQ_NEXT(qs, entries);
1202 			nr++;
1203 		}
1204 		pq->nr = nr;
1205 		PF_UNLOCK();
1206 		NET_UNLOCK();
1207 		break;
1208 	}
1209 
1210 	case DIOCGETQUEUE: {
1211 		struct pfioc_queue	*pq = (struct pfioc_queue *)addr;
1212 		struct pf_queuespec	*qs;
1213 		u_int32_t		 nr = 0;
1214 
1215 		NET_LOCK();
1216 		PF_LOCK();
1217 		if (pq->ticket != pf_main_ruleset.rules.active.ticket) {
1218 			error = EBUSY;
1219 			PF_UNLOCK();
1220 			NET_UNLOCK();
1221 			goto fail;
1222 		}
1223 
1224 		/* save state to not run over them all each time? */
1225 		qs = TAILQ_FIRST(pf_queues_active);
1226 		while ((qs != NULL) && (nr++ < pq->nr))
1227 			qs = TAILQ_NEXT(qs, entries);
1228 		if (qs == NULL) {
1229 			error = EBUSY;
1230 			PF_UNLOCK();
1231 			NET_UNLOCK();
1232 			goto fail;
1233 		}
1234 		memcpy(&pq->queue, qs, sizeof(pq->queue));
1235 		PF_UNLOCK();
1236 		NET_UNLOCK();
1237 		break;
1238 	}
1239 
1240 	case DIOCGETQSTATS: {
1241 		struct pfioc_qstats	*pq = (struct pfioc_qstats *)addr;
1242 		struct pf_queuespec	*qs;
1243 		u_int32_t		 nr;
1244 		int			 nbytes;
1245 
1246 		NET_LOCK();
1247 		PF_LOCK();
1248 		if (pq->ticket != pf_main_ruleset.rules.active.ticket) {
1249 			error = EBUSY;
1250 			PF_UNLOCK();
1251 			NET_UNLOCK();
1252 			goto fail;
1253 		}
1254 		nbytes = pq->nbytes;
1255 		nr = 0;
1256 
1257 		/* save state to not run over them all each time? */
1258 		qs = TAILQ_FIRST(pf_queues_active);
1259 		while ((qs != NULL) && (nr++ < pq->nr))
1260 			qs = TAILQ_NEXT(qs, entries);
1261 		if (qs == NULL) {
1262 			error = EBUSY;
1263 			PF_UNLOCK();
1264 			NET_UNLOCK();
1265 			goto fail;
1266 		}
1267 		memcpy(&pq->queue, qs, sizeof(pq->queue));
1268 		/* It's a root flow queue but is not an HFSC root class */
1269 		if ((qs->flags & PFQS_FLOWQUEUE) && qs->parent_qid == 0 &&
1270 		    !(qs->flags & PFQS_ROOTCLASS))
1271 			error = pfq_fqcodel_ops->pfq_qstats(qs, pq->buf,
1272 			    &nbytes);
1273 		else
1274 			error = pfq_hfsc_ops->pfq_qstats(qs, pq->buf,
1275 			    &nbytes);
1276 		if (error == 0)
1277 			pq->nbytes = nbytes;
1278 		PF_UNLOCK();
1279 		NET_UNLOCK();
1280 		break;
1281 	}
1282 
1283 	case DIOCADDQUEUE: {
1284 		struct pfioc_queue	*q = (struct pfioc_queue *)addr;
1285 		struct pf_queuespec	*qs;
1286 
1287 		qs = pool_get(&pf_queue_pl, PR_WAITOK|PR_LIMITFAIL|PR_ZERO);
1288 		if (qs == NULL) {
1289 			error = ENOMEM;
1290 			goto fail;
1291 		}
1292 
1293 		NET_LOCK();
1294 		PF_LOCK();
1295 		if (q->ticket != pf_main_ruleset.rules.inactive.ticket) {
1296 			error = EBUSY;
1297 			PF_UNLOCK();
1298 			NET_UNLOCK();
1299 			pool_put(&pf_queue_pl, qs);
1300 			goto fail;
1301 		}
1302 		memcpy(qs, &q->queue, sizeof(*qs));
1303 		qs->qid = pf_qname2qid(qs->qname, 1);
1304 		if (qs->qid == 0) {
1305 			error = EBUSY;
1306 			PF_UNLOCK();
1307 			NET_UNLOCK();
1308 			pool_put(&pf_queue_pl, qs);
1309 			goto fail;
1310 		}
1311 		if (qs->parent[0] && (qs->parent_qid =
1312 		    pf_qname2qid(qs->parent, 0)) == 0) {
1313 			error = ESRCH;
1314 			PF_UNLOCK();
1315 			NET_UNLOCK();
1316 			pool_put(&pf_queue_pl, qs);
1317 			goto fail;
1318 		}
1319 		qs->kif = pfi_kif_get(qs->ifname, NULL);
1320 		if (qs->kif == NULL) {
1321 			error = ESRCH;
1322 			PF_UNLOCK();
1323 			NET_UNLOCK();
1324 			pool_put(&pf_queue_pl, qs);
1325 			goto fail;
1326 		}
1327 		/* XXX resolve bw percentage specs */
1328 		pfi_kif_ref(qs->kif, PFI_KIF_REF_RULE);
1329 
1330 		TAILQ_INSERT_TAIL(pf_queues_inactive, qs, entries);
1331 		PF_UNLOCK();
1332 		NET_UNLOCK();
1333 
1334 		break;
1335 	}
1336 
1337 	case DIOCADDRULE: {
1338 		struct pfioc_rule	*pr = (struct pfioc_rule *)addr;
1339 		struct pf_ruleset	*ruleset;
1340 		struct pf_rule		*rule, *tail;
1341 
1342 		rule = pool_get(&pf_rule_pl, PR_WAITOK|PR_LIMITFAIL|PR_ZERO);
1343 		if (rule == NULL) {
1344 			error = ENOMEM;
1345 			goto fail;
1346 		}
1347 
1348 		if ((error = pf_rule_copyin(&pr->rule, rule))) {
1349 			pf_rule_free(rule);
1350 			rule = NULL;
1351 			goto fail;
1352 		}
1353 
1354 		if (pr->rule.return_icmp >> 8 > ICMP_MAXTYPE) {
1355 			error = EINVAL;
1356 			pf_rule_free(rule);
1357 			rule = NULL;
1358 			goto fail;
1359 		}
1360 		if ((error = pf_rule_checkaf(rule))) {
1361 			pf_rule_free(rule);
1362 			rule = NULL;
1363 			goto fail;
1364 		}
1365 		if (rule->src.addr.type == PF_ADDR_NONE ||
1366 		    rule->dst.addr.type == PF_ADDR_NONE) {
1367 			error = EINVAL;
1368 			pf_rule_free(rule);
1369 			rule = NULL;
1370 			goto fail;
1371 		}
1372 
1373 		if (rule->rt && !rule->direction) {
1374 			error = EINVAL;
1375 			pf_rule_free(rule);
1376 			rule = NULL;
1377 			goto fail;
1378 		}
1379 
1380 		NET_LOCK();
1381 		PF_LOCK();
1382 		pr->anchor[sizeof(pr->anchor) - 1] = '\0';
1383 		ruleset = pf_find_ruleset(pr->anchor);
1384 		if (ruleset == NULL) {
1385 			error = EINVAL;
1386 			PF_UNLOCK();
1387 			NET_UNLOCK();
1388 			pf_rule_free(rule);
1389 			goto fail;
1390 		}
1391 		if (pr->ticket != ruleset->rules.inactive.ticket) {
1392 			error = EBUSY;
1393 			PF_UNLOCK();
1394 			NET_UNLOCK();
1395 			pf_rule_free(rule);
1396 			goto fail;
1397 		}
1398 		rule->cuid = p->p_ucred->cr_ruid;
1399 		rule->cpid = p->p_p->ps_pid;
1400 
1401 		tail = TAILQ_LAST(ruleset->rules.inactive.ptr,
1402 		    pf_rulequeue);
1403 		if (tail)
1404 			rule->nr = tail->nr + 1;
1405 		else
1406 			rule->nr = 0;
1407 
1408 		rule->kif = pf_kif_setup(rule->kif);
1409 		rule->rcv_kif = pf_kif_setup(rule->rcv_kif);
1410 		rule->rdr.kif = pf_kif_setup(rule->rdr.kif);
1411 		rule->nat.kif = pf_kif_setup(rule->nat.kif);
1412 		rule->route.kif = pf_kif_setup(rule->route.kif);
1413 
1414 		if (rule->overload_tblname[0]) {
1415 			if ((rule->overload_tbl = pfr_attach_table(ruleset,
1416 			    rule->overload_tblname, PR_WAITOK)) == NULL)
1417 				error = EINVAL;
1418 			else
1419 				rule->overload_tbl->pfrkt_flags |= PFR_TFLAG_ACTIVE;
1420 		}
1421 
1422 		if (pf_addr_setup(ruleset, &rule->src.addr, rule->af))
1423 			error = EINVAL;
1424 		if (pf_addr_setup(ruleset, &rule->dst.addr, rule->af))
1425 			error = EINVAL;
1426 		if (pf_addr_setup(ruleset, &rule->rdr.addr, rule->af))
1427 			error = EINVAL;
1428 		if (pf_addr_setup(ruleset, &rule->nat.addr, rule->af))
1429 			error = EINVAL;
1430 		if (pf_addr_setup(ruleset, &rule->route.addr, rule->af))
1431 			error = EINVAL;
1432 		if (pf_anchor_setup(rule, ruleset, pr->anchor_call))
1433 			error = EINVAL;
1434 
1435 		if (error) {
1436 			pf_rm_rule(NULL, rule);
1437 			PF_UNLOCK();
1438 			NET_UNLOCK();
1439 			goto fail;
1440 		}
1441 		TAILQ_INSERT_TAIL(ruleset->rules.inactive.ptr,
1442 		    rule, entries);
1443 		rule->ruleset = ruleset;
1444 		ruleset->rules.inactive.rcount++;
1445 		PF_UNLOCK();
1446 		NET_UNLOCK();
1447 		break;
1448 	}
1449 
1450 	case DIOCGETRULES: {
1451 		struct pfioc_rule	*pr = (struct pfioc_rule *)addr;
1452 		struct pf_ruleset	*ruleset;
1453 		struct pf_rule		*tail;
1454 
1455 		NET_LOCK();
1456 		PF_LOCK();
1457 		pr->anchor[sizeof(pr->anchor) - 1] = '\0';
1458 		ruleset = pf_find_ruleset(pr->anchor);
1459 		if (ruleset == NULL) {
1460 			error = EINVAL;
1461 			PF_UNLOCK();
1462 			NET_UNLOCK();
1463 			goto fail;
1464 		}
1465 		tail = TAILQ_LAST(ruleset->rules.active.ptr, pf_rulequeue);
1466 		if (tail)
1467 			pr->nr = tail->nr + 1;
1468 		else
1469 			pr->nr = 0;
1470 		pr->ticket = ruleset->rules.active.ticket;
1471 		PF_UNLOCK();
1472 		NET_UNLOCK();
1473 		break;
1474 	}
1475 
1476 	case DIOCGETRULE: {
1477 		struct pfioc_rule	*pr = (struct pfioc_rule *)addr;
1478 		struct pf_ruleset	*ruleset;
1479 		struct pf_rule		*rule;
1480 		int			 i;
1481 
1482 		NET_LOCK();
1483 		PF_LOCK();
1484 		pr->anchor[sizeof(pr->anchor) - 1] = '\0';
1485 		ruleset = pf_find_ruleset(pr->anchor);
1486 		if (ruleset == NULL) {
1487 			error = EINVAL;
1488 			PF_UNLOCK();
1489 			NET_UNLOCK();
1490 			goto fail;
1491 		}
1492 		if (pr->ticket != ruleset->rules.active.ticket) {
1493 			error = EBUSY;
1494 			PF_UNLOCK();
1495 			NET_UNLOCK();
1496 			goto fail;
1497 		}
1498 		rule = TAILQ_FIRST(ruleset->rules.active.ptr);
1499 		while ((rule != NULL) && (rule->nr != pr->nr))
1500 			rule = TAILQ_NEXT(rule, entries);
1501 		if (rule == NULL) {
1502 			error = EBUSY;
1503 			PF_UNLOCK();
1504 			NET_UNLOCK();
1505 			goto fail;
1506 		}
1507 		memcpy(&pr->rule, rule, sizeof(struct pf_rule));
1508 		memset(&pr->rule.entries, 0, sizeof(pr->rule.entries));
1509 		pr->rule.kif = NULL;
1510 		pr->rule.nat.kif = NULL;
1511 		pr->rule.rdr.kif = NULL;
1512 		pr->rule.route.kif = NULL;
1513 		pr->rule.rcv_kif = NULL;
1514 		pr->rule.anchor = NULL;
1515 		pr->rule.overload_tbl = NULL;
1516 		pr->rule.pktrate.limit /= PF_THRESHOLD_MULT;
1517 		memset(&pr->rule.gcle, 0, sizeof(pr->rule.gcle));
1518 		pr->rule.ruleset = NULL;
1519 		if (pf_anchor_copyout(ruleset, rule, pr)) {
1520 			error = EBUSY;
1521 			PF_UNLOCK();
1522 			NET_UNLOCK();
1523 			goto fail;
1524 		}
1525 		pf_addr_copyout(&pr->rule.src.addr);
1526 		pf_addr_copyout(&pr->rule.dst.addr);
1527 		pf_addr_copyout(&pr->rule.rdr.addr);
1528 		pf_addr_copyout(&pr->rule.nat.addr);
1529 		pf_addr_copyout(&pr->rule.route.addr);
1530 		for (i = 0; i < PF_SKIP_COUNT; ++i)
1531 			if (rule->skip[i].ptr == NULL)
1532 				pr->rule.skip[i].nr = (u_int32_t)-1;
1533 			else
1534 				pr->rule.skip[i].nr =
1535 				    rule->skip[i].ptr->nr;
1536 
1537 		if (pr->action == PF_GET_CLR_CNTR) {
1538 			rule->evaluations = 0;
1539 			rule->packets[0] = rule->packets[1] = 0;
1540 			rule->bytes[0] = rule->bytes[1] = 0;
1541 			rule->states_tot = 0;
1542 		}
1543 		PF_UNLOCK();
1544 		NET_UNLOCK();
1545 		break;
1546 	}
1547 
1548 	case DIOCCHANGERULE: {
1549 		struct pfioc_rule	*pcr = (struct pfioc_rule *)addr;
1550 		struct pf_ruleset	*ruleset;
1551 		struct pf_rule		*oldrule = NULL, *newrule = NULL;
1552 		u_int32_t		 nr = 0;
1553 
1554 		if (pcr->action < PF_CHANGE_ADD_HEAD ||
1555 		    pcr->action > PF_CHANGE_GET_TICKET) {
1556 			error = EINVAL;
1557 			goto fail;
1558 		}
1559 
1560 		if (pcr->action == PF_CHANGE_GET_TICKET) {
1561 			NET_LOCK();
1562 			PF_LOCK();
1563 
1564 			ruleset = pf_find_ruleset(pcr->anchor);
1565 			if (ruleset == NULL)
1566 				error = EINVAL;
1567 			else
1568 				pcr->ticket = ++ruleset->rules.active.ticket;
1569 
1570 			PF_UNLOCK();
1571 			NET_UNLOCK();
1572 			goto fail;
1573 		}
1574 
1575 		if (pcr->action != PF_CHANGE_REMOVE) {
1576 			newrule = pool_get(&pf_rule_pl,
1577 			    PR_WAITOK|PR_LIMITFAIL|PR_ZERO);
1578 			if (newrule == NULL) {
1579 				error = ENOMEM;
1580 				goto fail;
1581 			}
1582 
1583 			if (pcr->rule.return_icmp >> 8 > ICMP_MAXTYPE) {
1584 				error = EINVAL;
1585 				pool_put(&pf_rule_pl, newrule);
1586 				goto fail;
1587 			}
1588 			error = pf_rule_copyin(&pcr->rule, newrule);
1589 			if (error != 0) {
1590 				pf_rule_free(newrule);
1591 				newrule = NULL;
1592 				goto fail;
1593 			}
1594 			if ((error = pf_rule_checkaf(newrule))) {
1595 				pf_rule_free(newrule);
1596 				newrule = NULL;
1597 				goto fail;
1598 			}
1599 			if (newrule->rt && !newrule->direction) {
1600 				pf_rule_free(newrule);
1601 				error = EINVAL;
1602 				newrule = NULL;
1603 				goto fail;
1604 			}
1605 		}
1606 
1607 		NET_LOCK();
1608 		PF_LOCK();
1609 		ruleset = pf_find_ruleset(pcr->anchor);
1610 		if (ruleset == NULL) {
1611 			error = EINVAL;
1612 			PF_UNLOCK();
1613 			NET_UNLOCK();
1614 			pf_rule_free(newrule);
1615 			goto fail;
1616 		}
1617 
1618 		if (pcr->ticket != ruleset->rules.active.ticket) {
1619 			error = EINVAL;
1620 			PF_UNLOCK();
1621 			NET_UNLOCK();
1622 			pf_rule_free(newrule);
1623 			goto fail;
1624 		}
1625 
1626 		if (pcr->action != PF_CHANGE_REMOVE) {
1627 			KASSERT(newrule != NULL);
1628 			newrule->cuid = p->p_ucred->cr_ruid;
1629 			newrule->cpid = p->p_p->ps_pid;
1630 
1631 			newrule->kif = pf_kif_setup(newrule->kif);
1632 			newrule->rcv_kif = pf_kif_setup(newrule->rcv_kif);
1633 			newrule->rdr.kif = pf_kif_setup(newrule->rdr.kif);
1634 			newrule->nat.kif = pf_kif_setup(newrule->nat.kif);
1635 			newrule->route.kif = pf_kif_setup(newrule->route.kif);
1636 
1637 			if (newrule->overload_tblname[0]) {
1638 				newrule->overload_tbl = pfr_attach_table(
1639 				    ruleset, newrule->overload_tblname,
1640 				    PR_WAITOK);
1641 				if (newrule->overload_tbl == NULL)
1642 					error = EINVAL;
1643 				else
1644 					newrule->overload_tbl->pfrkt_flags |=
1645 					    PFR_TFLAG_ACTIVE;
1646 			}
1647 
1648 			if (pf_addr_setup(ruleset, &newrule->src.addr,
1649 			    newrule->af))
1650 				error = EINVAL;
1651 			if (pf_addr_setup(ruleset, &newrule->dst.addr,
1652 			    newrule->af))
1653 				error = EINVAL;
1654 			if (pf_addr_setup(ruleset, &newrule->rdr.addr,
1655 			    newrule->af))
1656 				error = EINVAL;
1657 			if (pf_addr_setup(ruleset, &newrule->nat.addr,
1658 			    newrule->af))
1659 				error = EINVAL;
1660 			if (pf_addr_setup(ruleset, &newrule->route.addr,
1661 			    newrule->af))
1662 				error = EINVAL;
1663 			if (pf_anchor_setup(newrule, ruleset, pcr->anchor_call))
1664 				error = EINVAL;
1665 
1666 			if (error) {
1667 				pf_rm_rule(NULL, newrule);
1668 				PF_UNLOCK();
1669 				NET_UNLOCK();
1670 				goto fail;
1671 			}
1672 		}
1673 
1674 		if (pcr->action == PF_CHANGE_ADD_HEAD)
1675 			oldrule = TAILQ_FIRST(ruleset->rules.active.ptr);
1676 		else if (pcr->action == PF_CHANGE_ADD_TAIL)
1677 			oldrule = TAILQ_LAST(ruleset->rules.active.ptr,
1678 			    pf_rulequeue);
1679 		else {
1680 			oldrule = TAILQ_FIRST(ruleset->rules.active.ptr);
1681 			while ((oldrule != NULL) && (oldrule->nr != pcr->nr))
1682 				oldrule = TAILQ_NEXT(oldrule, entries);
1683 			if (oldrule == NULL) {
1684 				if (newrule != NULL)
1685 					pf_rm_rule(NULL, newrule);
1686 				error = EINVAL;
1687 				PF_UNLOCK();
1688 				NET_UNLOCK();
1689 				goto fail;
1690 			}
1691 		}
1692 
1693 		if (pcr->action == PF_CHANGE_REMOVE) {
1694 			pf_rm_rule(ruleset->rules.active.ptr, oldrule);
1695 			ruleset->rules.active.rcount--;
1696 		} else {
1697 			if (oldrule == NULL)
1698 				TAILQ_INSERT_TAIL(
1699 				    ruleset->rules.active.ptr,
1700 				    newrule, entries);
1701 			else if (pcr->action == PF_CHANGE_ADD_HEAD ||
1702 			    pcr->action == PF_CHANGE_ADD_BEFORE)
1703 				TAILQ_INSERT_BEFORE(oldrule, newrule, entries);
1704 			else
1705 				TAILQ_INSERT_AFTER(
1706 				    ruleset->rules.active.ptr,
1707 				    oldrule, newrule, entries);
1708 			ruleset->rules.active.rcount++;
1709 			newrule->ruleset = ruleset;
1710 		}
1711 
1712 		nr = 0;
1713 		TAILQ_FOREACH(oldrule, ruleset->rules.active.ptr, entries)
1714 			oldrule->nr = nr++;
1715 
1716 		ruleset->rules.active.ticket++;
1717 
1718 		pf_calc_skip_steps(ruleset->rules.active.ptr);
1719 		pf_remove_if_empty_ruleset(ruleset);
1720 
1721 		PF_UNLOCK();
1722 		NET_UNLOCK();
1723 		break;
1724 	}
1725 
1726 	case DIOCCLRSTATES:
1727 		error = pf_states_clr((struct pfioc_state_kill *)addr);
1728 		break;
1729 
1730 	case DIOCKILLSTATES: {
1731 		struct pf_state		*s, *nexts;
1732 		struct pf_state_item	*si, *sit;
1733 		struct pf_state_key	*sk, key;
1734 		struct pf_addr		*srcaddr, *dstaddr;
1735 		u_int16_t		 srcport, dstport;
1736 		struct pfioc_state_kill	*psk = (struct pfioc_state_kill *)addr;
1737 		u_int			 i, killed = 0;
1738 		const int		 dirs[] = { PF_IN, PF_OUT };
1739 		int			 sidx, didx;
1740 
1741 		if (psk->psk_pfcmp.id) {
1742 			if (psk->psk_pfcmp.creatorid == 0)
1743 				psk->psk_pfcmp.creatorid = pf_status.hostid;
1744 			NET_LOCK();
1745 			PF_LOCK();
1746 			PF_STATE_ENTER_WRITE();
1747 			if ((s = pf_find_state_byid(&psk->psk_pfcmp))) {
1748 				pf_remove_state(s);
1749 				psk->psk_killed = 1;
1750 			}
1751 			PF_STATE_EXIT_WRITE();
1752 			PF_UNLOCK();
1753 			NET_UNLOCK();
1754 			goto fail;
1755 		}
1756 
1757 		if (psk->psk_af && psk->psk_proto &&
1758 		    psk->psk_src.port_op == PF_OP_EQ &&
1759 		    psk->psk_dst.port_op == PF_OP_EQ) {
1760 
1761 			key.af = psk->psk_af;
1762 			key.proto = psk->psk_proto;
1763 			key.rdomain = psk->psk_rdomain;
1764 
1765 			NET_LOCK();
1766 			PF_LOCK();
1767 			PF_STATE_ENTER_WRITE();
1768 			for (i = 0; i < nitems(dirs); i++) {
1769 				if (dirs[i] == PF_IN) {
1770 					sidx = 0;
1771 					didx = 1;
1772 				} else {
1773 					sidx = 1;
1774 					didx = 0;
1775 				}
1776 				pf_addrcpy(&key.addr[sidx],
1777 				    &psk->psk_src.addr.v.a.addr, key.af);
1778 				pf_addrcpy(&key.addr[didx],
1779 				    &psk->psk_dst.addr.v.a.addr, key.af);
1780 				key.port[sidx] = psk->psk_src.port[0];
1781 				key.port[didx] = psk->psk_dst.port[0];
1782 
1783 				sk = RB_FIND(pf_state_tree, &pf_statetbl, &key);
1784 				if (sk == NULL)
1785 					continue;
1786 
1787 				TAILQ_FOREACH_SAFE(si, &sk->states, entry, sit)
1788 					if (((si->s->key[PF_SK_WIRE]->af ==
1789 					    si->s->key[PF_SK_STACK]->af &&
1790 					    sk == (dirs[i] == PF_IN ?
1791 					    si->s->key[PF_SK_WIRE] :
1792 					    si->s->key[PF_SK_STACK])) ||
1793 					    (si->s->key[PF_SK_WIRE]->af !=
1794 					    si->s->key[PF_SK_STACK]->af &&
1795 					    dirs[i] == PF_IN &&
1796 					    (sk == si->s->key[PF_SK_STACK] ||
1797 					    sk == si->s->key[PF_SK_WIRE]))) &&
1798 					    (!psk->psk_ifname[0] ||
1799 					    (si->s->kif != pfi_all &&
1800 					    !strcmp(psk->psk_ifname,
1801 					    si->s->kif->pfik_name)))) {
1802 						pf_remove_state(si->s);
1803 						killed++;
1804 					}
1805 			}
1806 			if (killed)
1807 				psk->psk_killed = killed;
1808 			PF_STATE_EXIT_WRITE();
1809 			PF_UNLOCK();
1810 			NET_UNLOCK();
1811 			goto fail;
1812 		}
1813 
1814 		NET_LOCK();
1815 		PF_LOCK();
1816 		PF_STATE_ENTER_WRITE();
1817 		for (s = RB_MIN(pf_state_tree_id, &tree_id); s;
1818 		    s = nexts) {
1819 			nexts = RB_NEXT(pf_state_tree_id, &tree_id, s);
1820 
1821 			if (s->direction == PF_OUT) {
1822 				sk = s->key[PF_SK_STACK];
1823 				srcaddr = &sk->addr[1];
1824 				dstaddr = &sk->addr[0];
1825 				srcport = sk->port[1];
1826 				dstport = sk->port[0];
1827 			} else {
1828 				sk = s->key[PF_SK_WIRE];
1829 				srcaddr = &sk->addr[0];
1830 				dstaddr = &sk->addr[1];
1831 				srcport = sk->port[0];
1832 				dstport = sk->port[1];
1833 			}
1834 			if ((!psk->psk_af || sk->af == psk->psk_af)
1835 			    && (!psk->psk_proto || psk->psk_proto ==
1836 			    sk->proto) && psk->psk_rdomain == sk->rdomain &&
1837 			    pf_match_addr(psk->psk_src.neg,
1838 			    &psk->psk_src.addr.v.a.addr,
1839 			    &psk->psk_src.addr.v.a.mask,
1840 			    srcaddr, sk->af) &&
1841 			    pf_match_addr(psk->psk_dst.neg,
1842 			    &psk->psk_dst.addr.v.a.addr,
1843 			    &psk->psk_dst.addr.v.a.mask,
1844 			    dstaddr, sk->af) &&
1845 			    (psk->psk_src.port_op == 0 ||
1846 			    pf_match_port(psk->psk_src.port_op,
1847 			    psk->psk_src.port[0], psk->psk_src.port[1],
1848 			    srcport)) &&
1849 			    (psk->psk_dst.port_op == 0 ||
1850 			    pf_match_port(psk->psk_dst.port_op,
1851 			    psk->psk_dst.port[0], psk->psk_dst.port[1],
1852 			    dstport)) &&
1853 			    (!psk->psk_label[0] || (s->rule.ptr->label[0] &&
1854 			    !strcmp(psk->psk_label, s->rule.ptr->label))) &&
1855 			    (!psk->psk_ifname[0] || !strcmp(psk->psk_ifname,
1856 			    s->kif->pfik_name))) {
1857 				pf_remove_state(s);
1858 				killed++;
1859 			}
1860 		}
1861 		psk->psk_killed = killed;
1862 		PF_STATE_EXIT_WRITE();
1863 		PF_UNLOCK();
1864 		NET_UNLOCK();
1865 		break;
1866 	}
1867 
1868 #if NPFSYNC > 0
1869 	case DIOCADDSTATE: {
1870 		struct pfioc_state	*ps = (struct pfioc_state *)addr;
1871 		struct pfsync_state	*sp = &ps->state;
1872 
1873 		if (sp->timeout >= PFTM_MAX) {
1874 			error = EINVAL;
1875 			goto fail;
1876 		}
1877 		NET_LOCK();
1878 		PF_LOCK();
1879 		error = pfsync_state_import(sp, PFSYNC_SI_IOCTL);
1880 		PF_UNLOCK();
1881 		NET_UNLOCK();
1882 		break;
1883 	}
1884 #endif	/* NPFSYNC > 0 */
1885 
1886 	case DIOCGETSTATE: {
1887 		struct pfioc_state	*ps = (struct pfioc_state *)addr;
1888 		struct pf_state		*s;
1889 		struct pf_state_cmp	 id_key;
1890 
1891 		memset(&id_key, 0, sizeof(id_key));
1892 		id_key.id = ps->state.id;
1893 		id_key.creatorid = ps->state.creatorid;
1894 
1895 		NET_LOCK();
1896 		PF_STATE_ENTER_READ();
1897 		s = pf_find_state_byid(&id_key);
1898 		s = pf_state_ref(s);
1899 		PF_STATE_EXIT_READ();
1900 		NET_UNLOCK();
1901 		if (s == NULL) {
1902 			error = ENOENT;
1903 			goto fail;
1904 		}
1905 
1906 		pf_state_export(&ps->state, s);
1907 		pf_state_unref(s);
1908 		break;
1909 	}
1910 
1911 	case DIOCGETSTATES:
1912 		error = pf_states_get((struct pfioc_states *)addr);
1913 		break;
1914 
1915 	case DIOCGETSTATUS: {
1916 		struct pf_status *s = (struct pf_status *)addr;
1917 		NET_LOCK();
1918 		PF_LOCK();
1919 		memcpy(s, &pf_status, sizeof(struct pf_status));
1920 		pfi_update_status(s->ifname, s);
1921 		PF_UNLOCK();
1922 		NET_UNLOCK();
1923 		break;
1924 	}
1925 
1926 	case DIOCSETSTATUSIF: {
1927 		struct pfioc_iface	*pi = (struct pfioc_iface *)addr;
1928 
1929 		NET_LOCK();
1930 		PF_LOCK();
1931 		if (pi->pfiio_name[0] == 0) {
1932 			memset(pf_status.ifname, 0, IFNAMSIZ);
1933 			PF_UNLOCK();
1934 			NET_UNLOCK();
1935 			goto fail;
1936 		}
1937 		strlcpy(pf_trans_set.statusif, pi->pfiio_name, IFNAMSIZ);
1938 		pf_trans_set.mask |= PF_TSET_STATUSIF;
1939 		PF_UNLOCK();
1940 		NET_UNLOCK();
1941 		break;
1942 	}
1943 
1944 	case DIOCCLRSTATUS: {
1945 		struct pfioc_iface	*pi = (struct pfioc_iface *)addr;
1946 
1947 		NET_LOCK();
1948 		PF_LOCK();
1949 		/* if ifname is specified, clear counters there only */
1950 		if (pi->pfiio_name[0]) {
1951 			pfi_update_status(pi->pfiio_name, NULL);
1952 			PF_UNLOCK();
1953 			NET_UNLOCK();
1954 			goto fail;
1955 		}
1956 
1957 		memset(pf_status.counters, 0, sizeof(pf_status.counters));
1958 		memset(pf_status.fcounters, 0, sizeof(pf_status.fcounters));
1959 		memset(pf_status.scounters, 0, sizeof(pf_status.scounters));
1960 		pf_status.since = getuptime();
1961 
1962 		PF_UNLOCK();
1963 		NET_UNLOCK();
1964 		break;
1965 	}
1966 
1967 	case DIOCNATLOOK: {
1968 		struct pfioc_natlook	*pnl = (struct pfioc_natlook *)addr;
1969 		struct pf_state_key	*sk;
1970 		struct pf_state		*state;
1971 		struct pf_state_key_cmp	 key;
1972 		int			 m = 0, direction = pnl->direction;
1973 		int			 sidx, didx;
1974 
1975 		switch (pnl->af) {
1976 		case AF_INET:
1977 			break;
1978 #ifdef INET6
1979 		case AF_INET6:
1980 			break;
1981 #endif /* INET6 */
1982 		default:
1983 			error = EAFNOSUPPORT;
1984 			goto fail;
1985 		}
1986 
1987 		/* NATLOOK src and dst are reversed, so reverse sidx/didx */
1988 		sidx = (direction == PF_IN) ? 1 : 0;
1989 		didx = (direction == PF_IN) ? 0 : 1;
1990 
1991 		if (!pnl->proto ||
1992 		    PF_AZERO(&pnl->saddr, pnl->af) ||
1993 		    PF_AZERO(&pnl->daddr, pnl->af) ||
1994 		    ((pnl->proto == IPPROTO_TCP ||
1995 		    pnl->proto == IPPROTO_UDP) &&
1996 		    (!pnl->dport || !pnl->sport)) ||
1997 		    pnl->rdomain > RT_TABLEID_MAX)
1998 			error = EINVAL;
1999 		else {
2000 			key.af = pnl->af;
2001 			key.proto = pnl->proto;
2002 			key.rdomain = pnl->rdomain;
2003 			pf_addrcpy(&key.addr[sidx], &pnl->saddr, pnl->af);
2004 			key.port[sidx] = pnl->sport;
2005 			pf_addrcpy(&key.addr[didx], &pnl->daddr, pnl->af);
2006 			key.port[didx] = pnl->dport;
2007 
2008 			NET_LOCK();
2009 			PF_STATE_ENTER_READ();
2010 			state = pf_find_state_all(&key, direction, &m);
2011 			state = pf_state_ref(state);
2012 			PF_STATE_EXIT_READ();
2013 			NET_UNLOCK();
2014 
2015 			if (m > 1)
2016 				error = E2BIG;	/* more than one state */
2017 			else if (state != NULL) {
2018 				sk = state->key[sidx];
2019 				pf_addrcpy(&pnl->rsaddr, &sk->addr[sidx],
2020 				    sk->af);
2021 				pnl->rsport = sk->port[sidx];
2022 				pf_addrcpy(&pnl->rdaddr, &sk->addr[didx],
2023 				    sk->af);
2024 				pnl->rdport = sk->port[didx];
2025 				pnl->rrdomain = sk->rdomain;
2026 			} else
2027 				error = ENOENT;
2028 			pf_state_unref(state);
2029 		}
2030 		break;
2031 	}
2032 
2033 	case DIOCSETTIMEOUT: {
2034 		struct pfioc_tm	*pt = (struct pfioc_tm *)addr;
2035 
2036 		if (pt->timeout < 0 || pt->timeout >= PFTM_MAX ||
2037 		    pt->seconds < 0) {
2038 			error = EINVAL;
2039 			goto fail;
2040 		}
2041 		NET_LOCK();
2042 		PF_LOCK();
2043 		if (pt->timeout == PFTM_INTERVAL && pt->seconds == 0)
2044 			pt->seconds = 1;
2045 		pf_default_rule_new.timeout[pt->timeout] = pt->seconds;
2046 		pt->seconds = pf_default_rule.timeout[pt->timeout];
2047 		PF_UNLOCK();
2048 		NET_UNLOCK();
2049 		break;
2050 	}
2051 
2052 	case DIOCGETTIMEOUT: {
2053 		struct pfioc_tm	*pt = (struct pfioc_tm *)addr;
2054 
2055 		if (pt->timeout < 0 || pt->timeout >= PFTM_MAX) {
2056 			error = EINVAL;
2057 			goto fail;
2058 		}
2059 		NET_LOCK();
2060 		PF_LOCK();
2061 		pt->seconds = pf_default_rule.timeout[pt->timeout];
2062 		PF_UNLOCK();
2063 		NET_UNLOCK();
2064 		break;
2065 	}
2066 
2067 	case DIOCGETLIMIT: {
2068 		struct pfioc_limit	*pl = (struct pfioc_limit *)addr;
2069 
2070 		if (pl->index < 0 || pl->index >= PF_LIMIT_MAX) {
2071 			error = EINVAL;
2072 			goto fail;
2073 		}
2074 		NET_LOCK();
2075 		PF_LOCK();
2076 		pl->limit = pf_pool_limits[pl->index].limit;
2077 		PF_UNLOCK();
2078 		NET_UNLOCK();
2079 		break;
2080 	}
2081 
2082 	case DIOCSETLIMIT: {
2083 		struct pfioc_limit	*pl = (struct pfioc_limit *)addr;
2084 
2085 		NET_LOCK();
2086 		PF_LOCK();
2087 		if (pl->index < 0 || pl->index >= PF_LIMIT_MAX ||
2088 		    pf_pool_limits[pl->index].pp == NULL) {
2089 			error = EINVAL;
2090 			PF_UNLOCK();
2091 			NET_UNLOCK();
2092 			goto fail;
2093 		}
2094 		if (((struct pool *)pf_pool_limits[pl->index].pp)->pr_nout >
2095 		    pl->limit) {
2096 			error = EBUSY;
2097 			PF_UNLOCK();
2098 			NET_UNLOCK();
2099 			goto fail;
2100 		}
2101 		/* Fragments reference mbuf clusters. */
2102 		if (pl->index == PF_LIMIT_FRAGS && pl->limit > nmbclust) {
2103 			error = EINVAL;
2104 			PF_UNLOCK();
2105 			NET_UNLOCK();
2106 			goto fail;
2107 		}
2108 
2109 		pf_pool_limits[pl->index].limit_new = pl->limit;
2110 		pl->limit = pf_pool_limits[pl->index].limit;
2111 		PF_UNLOCK();
2112 		NET_UNLOCK();
2113 		break;
2114 	}
2115 
2116 	case DIOCSETDEBUG: {
2117 		u_int32_t	*level = (u_int32_t *)addr;
2118 
2119 		NET_LOCK();
2120 		PF_LOCK();
2121 		pf_trans_set.debug = *level;
2122 		pf_trans_set.mask |= PF_TSET_DEBUG;
2123 		PF_UNLOCK();
2124 		NET_UNLOCK();
2125 		break;
2126 	}
2127 
2128 	case DIOCGETRULESETS: {
2129 		struct pfioc_ruleset	*pr = (struct pfioc_ruleset *)addr;
2130 		struct pf_ruleset	*ruleset;
2131 		struct pf_anchor	*anchor;
2132 
2133 		NET_LOCK();
2134 		PF_LOCK();
2135 		pr->path[sizeof(pr->path) - 1] = '\0';
2136 		if ((ruleset = pf_find_ruleset(pr->path)) == NULL) {
2137 			error = EINVAL;
2138 			PF_UNLOCK();
2139 			NET_UNLOCK();
2140 			goto fail;
2141 		}
2142 		pr->nr = 0;
2143 		if (ruleset == &pf_main_ruleset) {
2144 			/* XXX kludge for pf_main_ruleset */
2145 			RB_FOREACH(anchor, pf_anchor_global, &pf_anchors)
2146 				if (anchor->parent == NULL)
2147 					pr->nr++;
2148 		} else {
2149 			RB_FOREACH(anchor, pf_anchor_node,
2150 			    &ruleset->anchor->children)
2151 				pr->nr++;
2152 		}
2153 		PF_UNLOCK();
2154 		NET_UNLOCK();
2155 		break;
2156 	}
2157 
2158 	case DIOCGETRULESET: {
2159 		struct pfioc_ruleset	*pr = (struct pfioc_ruleset *)addr;
2160 		struct pf_ruleset	*ruleset;
2161 		struct pf_anchor	*anchor;
2162 		u_int32_t		 nr = 0;
2163 
2164 		NET_LOCK();
2165 		PF_LOCK();
2166 		pr->path[sizeof(pr->path) - 1] = '\0';
2167 		if ((ruleset = pf_find_ruleset(pr->path)) == NULL) {
2168 			error = EINVAL;
2169 			PF_UNLOCK();
2170 			NET_UNLOCK();
2171 			goto fail;
2172 		}
2173 		pr->name[0] = '\0';
2174 		if (ruleset == &pf_main_ruleset) {
2175 			/* XXX kludge for pf_main_ruleset */
2176 			RB_FOREACH(anchor, pf_anchor_global, &pf_anchors)
2177 				if (anchor->parent == NULL && nr++ == pr->nr) {
2178 					strlcpy(pr->name, anchor->name,
2179 					    sizeof(pr->name));
2180 					break;
2181 				}
2182 		} else {
2183 			RB_FOREACH(anchor, pf_anchor_node,
2184 			    &ruleset->anchor->children)
2185 				if (nr++ == pr->nr) {
2186 					strlcpy(pr->name, anchor->name,
2187 					    sizeof(pr->name));
2188 					break;
2189 				}
2190 		}
2191 		PF_UNLOCK();
2192 		NET_UNLOCK();
2193 		if (!pr->name[0])
2194 			error = EBUSY;
2195 		break;
2196 	}
2197 
2198 	case DIOCRCLRTABLES: {
2199 		struct pfioc_table *io = (struct pfioc_table *)addr;
2200 
2201 		if (io->pfrio_esize != 0) {
2202 			error = ENODEV;
2203 			goto fail;
2204 		}
2205 		NET_LOCK();
2206 		PF_LOCK();
2207 		error = pfr_clr_tables(&io->pfrio_table, &io->pfrio_ndel,
2208 		    io->pfrio_flags | PFR_FLAG_USERIOCTL);
2209 		PF_UNLOCK();
2210 		NET_UNLOCK();
2211 		break;
2212 	}
2213 
2214 	case DIOCRADDTABLES: {
2215 		struct pfioc_table *io = (struct pfioc_table *)addr;
2216 
2217 		if (io->pfrio_esize != sizeof(struct pfr_table)) {
2218 			error = ENODEV;
2219 			goto fail;
2220 		}
2221 		error = pfr_add_tables(io->pfrio_buffer, io->pfrio_size,
2222 		    &io->pfrio_nadd, io->pfrio_flags | PFR_FLAG_USERIOCTL);
2223 		break;
2224 	}
2225 
2226 	case DIOCRDELTABLES: {
2227 		struct pfioc_table *io = (struct pfioc_table *)addr;
2228 
2229 		if (io->pfrio_esize != sizeof(struct pfr_table)) {
2230 			error = ENODEV;
2231 			goto fail;
2232 		}
2233 		NET_LOCK();
2234 		PF_LOCK();
2235 		error = pfr_del_tables(io->pfrio_buffer, io->pfrio_size,
2236 		    &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
2237 		PF_UNLOCK();
2238 		NET_UNLOCK();
2239 		break;
2240 	}
2241 
2242 	case DIOCRGETTABLES: {
2243 		struct pfioc_table *io = (struct pfioc_table *)addr;
2244 
2245 		if (io->pfrio_esize != sizeof(struct pfr_table)) {
2246 			error = ENODEV;
2247 			goto fail;
2248 		}
2249 		NET_LOCK();
2250 		PF_LOCK();
2251 		error = pfr_get_tables(&io->pfrio_table, io->pfrio_buffer,
2252 		    &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
2253 		PF_UNLOCK();
2254 		NET_UNLOCK();
2255 		break;
2256 	}
2257 
2258 	case DIOCRGETTSTATS: {
2259 		struct pfioc_table *io = (struct pfioc_table *)addr;
2260 
2261 		if (io->pfrio_esize != sizeof(struct pfr_tstats)) {
2262 			error = ENODEV;
2263 			goto fail;
2264 		}
2265 		NET_LOCK();
2266 		PF_LOCK();
2267 		error = pfr_get_tstats(&io->pfrio_table, io->pfrio_buffer,
2268 		    &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
2269 		PF_UNLOCK();
2270 		NET_UNLOCK();
2271 		break;
2272 	}
2273 
2274 	case DIOCRCLRTSTATS: {
2275 		struct pfioc_table *io = (struct pfioc_table *)addr;
2276 
2277 		if (io->pfrio_esize != sizeof(struct pfr_table)) {
2278 			error = ENODEV;
2279 			goto fail;
2280 		}
2281 		NET_LOCK();
2282 		PF_LOCK();
2283 		error = pfr_clr_tstats(io->pfrio_buffer, io->pfrio_size,
2284 		    &io->pfrio_nzero, io->pfrio_flags | PFR_FLAG_USERIOCTL);
2285 		PF_UNLOCK();
2286 		NET_UNLOCK();
2287 		break;
2288 	}
2289 
2290 	case DIOCRSETTFLAGS: {
2291 		struct pfioc_table *io = (struct pfioc_table *)addr;
2292 
2293 		if (io->pfrio_esize != sizeof(struct pfr_table)) {
2294 			error = ENODEV;
2295 			goto fail;
2296 		}
2297 		NET_LOCK();
2298 		PF_LOCK();
2299 		error = pfr_set_tflags(io->pfrio_buffer, io->pfrio_size,
2300 		    io->pfrio_setflag, io->pfrio_clrflag, &io->pfrio_nchange,
2301 		    &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
2302 		PF_UNLOCK();
2303 		NET_UNLOCK();
2304 		break;
2305 	}
2306 
2307 	case DIOCRCLRADDRS: {
2308 		struct pfioc_table *io = (struct pfioc_table *)addr;
2309 
2310 		if (io->pfrio_esize != 0) {
2311 			error = ENODEV;
2312 			goto fail;
2313 		}
2314 		NET_LOCK();
2315 		PF_LOCK();
2316 		error = pfr_clr_addrs(&io->pfrio_table, &io->pfrio_ndel,
2317 		    io->pfrio_flags | PFR_FLAG_USERIOCTL);
2318 		PF_UNLOCK();
2319 		NET_UNLOCK();
2320 		break;
2321 	}
2322 
2323 	case DIOCRADDADDRS: {
2324 		struct pfioc_table *io = (struct pfioc_table *)addr;
2325 
2326 		if (io->pfrio_esize != sizeof(struct pfr_addr)) {
2327 			error = ENODEV;
2328 			goto fail;
2329 		}
2330 		error = pfr_add_addrs(&io->pfrio_table, io->pfrio_buffer,
2331 		    io->pfrio_size, &io->pfrio_nadd, io->pfrio_flags |
2332 		    PFR_FLAG_USERIOCTL);
2333 		break;
2334 	}
2335 
2336 	case DIOCRDELADDRS: {
2337 		struct pfioc_table *io = (struct pfioc_table *)addr;
2338 
2339 		if (io->pfrio_esize != sizeof(struct pfr_addr)) {
2340 			error = ENODEV;
2341 			goto fail;
2342 		}
2343 		NET_LOCK();
2344 		PF_LOCK();
2345 		error = pfr_del_addrs(&io->pfrio_table, io->pfrio_buffer,
2346 		    io->pfrio_size, &io->pfrio_ndel, io->pfrio_flags |
2347 		    PFR_FLAG_USERIOCTL);
2348 		PF_UNLOCK();
2349 		NET_UNLOCK();
2350 		break;
2351 	}
2352 
2353 	case DIOCRSETADDRS: {
2354 		struct pfioc_table *io = (struct pfioc_table *)addr;
2355 
2356 		if (io->pfrio_esize != sizeof(struct pfr_addr)) {
2357 			error = ENODEV;
2358 			goto fail;
2359 		}
2360 		NET_LOCK();
2361 		PF_LOCK();
2362 		error = pfr_set_addrs(&io->pfrio_table, io->pfrio_buffer,
2363 		    io->pfrio_size, &io->pfrio_size2, &io->pfrio_nadd,
2364 		    &io->pfrio_ndel, &io->pfrio_nchange, io->pfrio_flags |
2365 		    PFR_FLAG_USERIOCTL, 0);
2366 		PF_UNLOCK();
2367 		NET_UNLOCK();
2368 		break;
2369 	}
2370 
2371 	case DIOCRGETADDRS: {
2372 		struct pfioc_table *io = (struct pfioc_table *)addr;
2373 
2374 		if (io->pfrio_esize != sizeof(struct pfr_addr)) {
2375 			error = ENODEV;
2376 			goto fail;
2377 		}
2378 		NET_LOCK();
2379 		PF_LOCK();
2380 		error = pfr_get_addrs(&io->pfrio_table, io->pfrio_buffer,
2381 		    &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
2382 		PF_UNLOCK();
2383 		NET_UNLOCK();
2384 		break;
2385 	}
2386 
2387 	case DIOCRGETASTATS: {
2388 		struct pfioc_table *io = (struct pfioc_table *)addr;
2389 
2390 		if (io->pfrio_esize != sizeof(struct pfr_astats)) {
2391 			error = ENODEV;
2392 			goto fail;
2393 		}
2394 		NET_LOCK();
2395 		PF_LOCK();
2396 		error = pfr_get_astats(&io->pfrio_table, io->pfrio_buffer,
2397 		    &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
2398 		PF_UNLOCK();
2399 		NET_UNLOCK();
2400 		break;
2401 	}
2402 
2403 	case DIOCRCLRASTATS: {
2404 		struct pfioc_table *io = (struct pfioc_table *)addr;
2405 
2406 		if (io->pfrio_esize != sizeof(struct pfr_addr)) {
2407 			error = ENODEV;
2408 			goto fail;
2409 		}
2410 		NET_LOCK();
2411 		PF_LOCK();
2412 		error = pfr_clr_astats(&io->pfrio_table, io->pfrio_buffer,
2413 		    io->pfrio_size, &io->pfrio_nzero, io->pfrio_flags |
2414 		    PFR_FLAG_USERIOCTL);
2415 		PF_UNLOCK();
2416 		NET_UNLOCK();
2417 		break;
2418 	}
2419 
2420 	case DIOCRTSTADDRS: {
2421 		struct pfioc_table *io = (struct pfioc_table *)addr;
2422 
2423 		if (io->pfrio_esize != sizeof(struct pfr_addr)) {
2424 			error = ENODEV;
2425 			goto fail;
2426 		}
2427 		NET_LOCK();
2428 		PF_LOCK();
2429 		error = pfr_tst_addrs(&io->pfrio_table, io->pfrio_buffer,
2430 		    io->pfrio_size, &io->pfrio_nmatch, io->pfrio_flags |
2431 		    PFR_FLAG_USERIOCTL);
2432 		PF_UNLOCK();
2433 		NET_UNLOCK();
2434 		break;
2435 	}
2436 
2437 	case DIOCRINADEFINE: {
2438 		struct pfioc_table *io = (struct pfioc_table *)addr;
2439 
2440 		if (io->pfrio_esize != sizeof(struct pfr_addr)) {
2441 			error = ENODEV;
2442 			goto fail;
2443 		}
2444 		NET_LOCK();
2445 		PF_LOCK();
2446 		error = pfr_ina_define(&io->pfrio_table, io->pfrio_buffer,
2447 		    io->pfrio_size, &io->pfrio_nadd, &io->pfrio_naddr,
2448 		    io->pfrio_ticket, io->pfrio_flags | PFR_FLAG_USERIOCTL);
2449 		PF_UNLOCK();
2450 		NET_UNLOCK();
2451 		break;
2452 	}
2453 
2454 	case DIOCOSFPADD: {
2455 		struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
2456 		error = pf_osfp_add(io);
2457 		break;
2458 	}
2459 
2460 	case DIOCOSFPGET: {
2461 		struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
2462 		error = pf_osfp_get(io);
2463 		break;
2464 	}
2465 
2466 	case DIOCXBEGIN: {
2467 		struct pfioc_trans	*io = (struct pfioc_trans *)addr;
2468 		struct pfioc_trans_e	*ioe;
2469 		struct pfr_table	*table;
2470 		int			 i;
2471 
2472 		if (io->esize != sizeof(*ioe)) {
2473 			error = ENODEV;
2474 			goto fail;
2475 		}
2476 		ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK);
2477 		table = malloc(sizeof(*table), M_TEMP, M_WAITOK);
2478 		NET_LOCK();
2479 		PF_LOCK();
2480 		pf_default_rule_new = pf_default_rule;
2481 		PF_UNLOCK();
2482 		NET_UNLOCK();
2483 		memset(&pf_trans_set, 0, sizeof(pf_trans_set));
2484 		for (i = 0; i < io->size; i++) {
2485 			if (copyin(io->array+i, ioe, sizeof(*ioe))) {
2486 				free(table, M_TEMP, sizeof(*table));
2487 				free(ioe, M_TEMP, sizeof(*ioe));
2488 				error = EFAULT;
2489 				goto fail;
2490 			}
2491 			if (strnlen(ioe->anchor, sizeof(ioe->anchor)) ==
2492 			    sizeof(ioe->anchor)) {
2493 				free(table, M_TEMP, sizeof(*table));
2494 				free(ioe, M_TEMP, sizeof(*ioe));
2495 				error = ENAMETOOLONG;
2496 				goto fail;
2497 			}
2498 			NET_LOCK();
2499 			PF_LOCK();
2500 			switch (ioe->type) {
2501 			case PF_TRANS_TABLE:
2502 				memset(table, 0, sizeof(*table));
2503 				strlcpy(table->pfrt_anchor, ioe->anchor,
2504 				    sizeof(table->pfrt_anchor));
2505 				if ((error = pfr_ina_begin(table,
2506 				    &ioe->ticket, NULL, 0))) {
2507 					PF_UNLOCK();
2508 					NET_UNLOCK();
2509 					free(table, M_TEMP, sizeof(*table));
2510 					free(ioe, M_TEMP, sizeof(*ioe));
2511 					goto fail;
2512 				}
2513 				break;
2514 			case PF_TRANS_RULESET:
2515 				if ((error = pf_begin_rules(&ioe->ticket,
2516 				    ioe->anchor))) {
2517 					PF_UNLOCK();
2518 					NET_UNLOCK();
2519 					free(table, M_TEMP, sizeof(*table));
2520 					free(ioe, M_TEMP, sizeof(*ioe));
2521 					goto fail;
2522 				}
2523 				break;
2524 			default:
2525 				PF_UNLOCK();
2526 				NET_UNLOCK();
2527 				free(table, M_TEMP, sizeof(*table));
2528 				free(ioe, M_TEMP, sizeof(*ioe));
2529 				error = EINVAL;
2530 				goto fail;
2531 			}
2532 			PF_UNLOCK();
2533 			NET_UNLOCK();
2534 			if (copyout(ioe, io->array+i, sizeof(io->array[i]))) {
2535 				free(table, M_TEMP, sizeof(*table));
2536 				free(ioe, M_TEMP, sizeof(*ioe));
2537 				error = EFAULT;
2538 				goto fail;
2539 			}
2540 		}
2541 		free(table, M_TEMP, sizeof(*table));
2542 		free(ioe, M_TEMP, sizeof(*ioe));
2543 		break;
2544 	}
2545 
2546 	case DIOCXROLLBACK: {
2547 		struct pfioc_trans	*io = (struct pfioc_trans *)addr;
2548 		struct pfioc_trans_e	*ioe;
2549 		struct pfr_table	*table;
2550 		int			 i;
2551 
2552 		if (io->esize != sizeof(*ioe)) {
2553 			error = ENODEV;
2554 			goto fail;
2555 		}
2556 		ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK);
2557 		table = malloc(sizeof(*table), M_TEMP, M_WAITOK);
2558 		for (i = 0; i < io->size; i++) {
2559 			if (copyin(io->array+i, ioe, sizeof(*ioe))) {
2560 				free(table, M_TEMP, sizeof(*table));
2561 				free(ioe, M_TEMP, sizeof(*ioe));
2562 				error = EFAULT;
2563 				goto fail;
2564 			}
2565 			if (strnlen(ioe->anchor, sizeof(ioe->anchor)) ==
2566 			    sizeof(ioe->anchor)) {
2567 				free(table, M_TEMP, sizeof(*table));
2568 				free(ioe, M_TEMP, sizeof(*ioe));
2569 				error = ENAMETOOLONG;
2570 				goto fail;
2571 			}
2572 			NET_LOCK();
2573 			PF_LOCK();
2574 			switch (ioe->type) {
2575 			case PF_TRANS_TABLE:
2576 				memset(table, 0, sizeof(*table));
2577 				strlcpy(table->pfrt_anchor, ioe->anchor,
2578 				    sizeof(table->pfrt_anchor));
2579 				if ((error = pfr_ina_rollback(table,
2580 				    ioe->ticket, NULL, 0))) {
2581 					PF_UNLOCK();
2582 					NET_UNLOCK();
2583 					free(table, M_TEMP, sizeof(*table));
2584 					free(ioe, M_TEMP, sizeof(*ioe));
2585 					goto fail; /* really bad */
2586 				}
2587 				break;
2588 			case PF_TRANS_RULESET:
2589 				pf_rollback_rules(ioe->ticket, ioe->anchor);
2590 				break;
2591 			default:
2592 				PF_UNLOCK();
2593 				NET_UNLOCK();
2594 				free(table, M_TEMP, sizeof(*table));
2595 				free(ioe, M_TEMP, sizeof(*ioe));
2596 				error = EINVAL;
2597 				goto fail; /* really bad */
2598 			}
2599 			PF_UNLOCK();
2600 			NET_UNLOCK();
2601 		}
2602 		free(table, M_TEMP, sizeof(*table));
2603 		free(ioe, M_TEMP, sizeof(*ioe));
2604 		break;
2605 	}
2606 
2607 	case DIOCXCOMMIT: {
2608 		struct pfioc_trans	*io = (struct pfioc_trans *)addr;
2609 		struct pfioc_trans_e	*ioe;
2610 		struct pfr_table	*table;
2611 		struct pf_ruleset	*rs;
2612 		int			 i;
2613 
2614 		if (io->esize != sizeof(*ioe)) {
2615 			error = ENODEV;
2616 			goto fail;
2617 		}
2618 		ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK);
2619 		table = malloc(sizeof(*table), M_TEMP, M_WAITOK);
2620 		NET_LOCK();
2621 		PF_LOCK();
2622 		/* first makes sure everything will succeed */
2623 		for (i = 0; i < io->size; i++) {
2624 			if (copyin(io->array+i, ioe, sizeof(*ioe))) {
2625 				PF_UNLOCK();
2626 				NET_UNLOCK();
2627 				free(table, M_TEMP, sizeof(*table));
2628 				free(ioe, M_TEMP, sizeof(*ioe));
2629 				error = EFAULT;
2630 				goto fail;
2631 			}
2632 			if (strnlen(ioe->anchor, sizeof(ioe->anchor)) ==
2633 			    sizeof(ioe->anchor)) {
2634 				PF_UNLOCK();
2635 				NET_UNLOCK();
2636 				free(table, M_TEMP, sizeof(*table));
2637 				free(ioe, M_TEMP, sizeof(*ioe));
2638 				error = ENAMETOOLONG;
2639 				goto fail;
2640 			}
2641 			switch (ioe->type) {
2642 			case PF_TRANS_TABLE:
2643 				rs = pf_find_ruleset(ioe->anchor);
2644 				if (rs == NULL || !rs->topen || ioe->ticket !=
2645 				     rs->tticket) {
2646 					PF_UNLOCK();
2647 					NET_UNLOCK();
2648 					free(table, M_TEMP, sizeof(*table));
2649 					free(ioe, M_TEMP, sizeof(*ioe));
2650 					error = EBUSY;
2651 					goto fail;
2652 				}
2653 				break;
2654 			case PF_TRANS_RULESET:
2655 				rs = pf_find_ruleset(ioe->anchor);
2656 				if (rs == NULL ||
2657 				    !rs->rules.inactive.open ||
2658 				    rs->rules.inactive.ticket !=
2659 				    ioe->ticket) {
2660 					PF_UNLOCK();
2661 					NET_UNLOCK();
2662 					free(table, M_TEMP, sizeof(*table));
2663 					free(ioe, M_TEMP, sizeof(*ioe));
2664 					error = EBUSY;
2665 					goto fail;
2666 				}
2667 				break;
2668 			default:
2669 				PF_UNLOCK();
2670 				NET_UNLOCK();
2671 				free(table, M_TEMP, sizeof(*table));
2672 				free(ioe, M_TEMP, sizeof(*ioe));
2673 				error = EINVAL;
2674 				goto fail;
2675 			}
2676 		}
2677 
2678 		/*
2679 		 * Checked already in DIOCSETLIMIT, but check again as the
2680 		 * situation might have changed.
2681 		 */
2682 		for (i = 0; i < PF_LIMIT_MAX; i++) {
2683 			if (((struct pool *)pf_pool_limits[i].pp)->pr_nout >
2684 			    pf_pool_limits[i].limit_new) {
2685 				PF_UNLOCK();
2686 				NET_UNLOCK();
2687 				free(table, M_TEMP, sizeof(*table));
2688 				free(ioe, M_TEMP, sizeof(*ioe));
2689 				error = EBUSY;
2690 				goto fail;
2691 			}
2692 		}
2693 		/* now do the commit - no errors should happen here */
2694 		for (i = 0; i < io->size; i++) {
2695 			if (copyin(io->array+i, ioe, sizeof(*ioe))) {
2696 				PF_UNLOCK();
2697 				NET_UNLOCK();
2698 				free(table, M_TEMP, sizeof(*table));
2699 				free(ioe, M_TEMP, sizeof(*ioe));
2700 				error = EFAULT;
2701 				goto fail;
2702 			}
2703 			if (strnlen(ioe->anchor, sizeof(ioe->anchor)) ==
2704 			    sizeof(ioe->anchor)) {
2705 				PF_UNLOCK();
2706 				NET_UNLOCK();
2707 				free(table, M_TEMP, sizeof(*table));
2708 				free(ioe, M_TEMP, sizeof(*ioe));
2709 				error = ENAMETOOLONG;
2710 				goto fail;
2711 			}
2712 			switch (ioe->type) {
2713 			case PF_TRANS_TABLE:
2714 				memset(table, 0, sizeof(*table));
2715 				strlcpy(table->pfrt_anchor, ioe->anchor,
2716 				    sizeof(table->pfrt_anchor));
2717 				if ((error = pfr_ina_commit(table, ioe->ticket,
2718 				    NULL, NULL, 0))) {
2719 					PF_UNLOCK();
2720 					NET_UNLOCK();
2721 					free(table, M_TEMP, sizeof(*table));
2722 					free(ioe, M_TEMP, sizeof(*ioe));
2723 					goto fail; /* really bad */
2724 				}
2725 				break;
2726 			case PF_TRANS_RULESET:
2727 				if ((error = pf_commit_rules(ioe->ticket,
2728 				    ioe->anchor))) {
2729 					PF_UNLOCK();
2730 					NET_UNLOCK();
2731 					free(table, M_TEMP, sizeof(*table));
2732 					free(ioe, M_TEMP, sizeof(*ioe));
2733 					goto fail; /* really bad */
2734 				}
2735 				break;
2736 			default:
2737 				PF_UNLOCK();
2738 				NET_UNLOCK();
2739 				free(table, M_TEMP, sizeof(*table));
2740 				free(ioe, M_TEMP, sizeof(*ioe));
2741 				error = EINVAL;
2742 				goto fail; /* really bad */
2743 			}
2744 		}
2745 		for (i = 0; i < PF_LIMIT_MAX; i++) {
2746 			if (pf_pool_limits[i].limit_new !=
2747 			    pf_pool_limits[i].limit &&
2748 			    pool_sethardlimit(pf_pool_limits[i].pp,
2749 			    pf_pool_limits[i].limit_new, NULL, 0) != 0) {
2750 				PF_UNLOCK();
2751 				NET_UNLOCK();
2752 				free(table, M_TEMP, sizeof(*table));
2753 				free(ioe, M_TEMP, sizeof(*ioe));
2754 				error = EBUSY;
2755 				goto fail; /* really bad */
2756 			}
2757 			pf_pool_limits[i].limit = pf_pool_limits[i].limit_new;
2758 		}
2759 		for (i = 0; i < PFTM_MAX; i++) {
2760 			int old = pf_default_rule.timeout[i];
2761 
2762 			pf_default_rule.timeout[i] =
2763 			    pf_default_rule_new.timeout[i];
2764 			if (pf_default_rule.timeout[i] == PFTM_INTERVAL &&
2765 			    pf_default_rule.timeout[i] < old)
2766 				task_add(net_tq(0), &pf_purge_task);
2767 		}
2768 		pfi_xcommit();
2769 		pf_trans_set_commit();
2770 		PF_UNLOCK();
2771 		NET_UNLOCK();
2772 		free(table, M_TEMP, sizeof(*table));
2773 		free(ioe, M_TEMP, sizeof(*ioe));
2774 		break;
2775 	}
2776 
2777 	case DIOCGETSRCNODES: {
2778 		struct pfioc_src_nodes	*psn = (struct pfioc_src_nodes *)addr;
2779 		struct pf_src_node	*n, *p, *pstore;
2780 		u_int32_t		 nr = 0;
2781 		size_t			 space = psn->psn_len;
2782 
2783 		pstore = malloc(sizeof(*pstore), M_TEMP, M_WAITOK);
2784 
2785 		NET_LOCK();
2786 		PF_LOCK();
2787 		if (space == 0) {
2788 			RB_FOREACH(n, pf_src_tree, &tree_src_tracking)
2789 				nr++;
2790 			psn->psn_len = sizeof(struct pf_src_node) * nr;
2791 			PF_UNLOCK();
2792 			NET_UNLOCK();
2793 			free(pstore, M_TEMP, sizeof(*pstore));
2794 			goto fail;
2795 		}
2796 
2797 		p = psn->psn_src_nodes;
2798 		RB_FOREACH(n, pf_src_tree, &tree_src_tracking) {
2799 			int	secs = getuptime(), diff;
2800 
2801 			if ((nr + 1) * sizeof(*p) > psn->psn_len)
2802 				break;
2803 
2804 			memcpy(pstore, n, sizeof(*pstore));
2805 			memset(&pstore->entry, 0, sizeof(pstore->entry));
2806 			pstore->rule.ptr = NULL;
2807 			pstore->kif = NULL;
2808 			pstore->rule.nr = n->rule.ptr->nr;
2809 			pstore->creation = secs - pstore->creation;
2810 			if (pstore->expire > secs)
2811 				pstore->expire -= secs;
2812 			else
2813 				pstore->expire = 0;
2814 
2815 			/* adjust the connection rate estimate */
2816 			diff = secs - n->conn_rate.last;
2817 			if (diff >= n->conn_rate.seconds)
2818 				pstore->conn_rate.count = 0;
2819 			else
2820 				pstore->conn_rate.count -=
2821 				    n->conn_rate.count * diff /
2822 				    n->conn_rate.seconds;
2823 
2824 			error = copyout(pstore, p, sizeof(*p));
2825 			if (error) {
2826 				PF_UNLOCK();
2827 				NET_UNLOCK();
2828 				free(pstore, M_TEMP, sizeof(*pstore));
2829 				goto fail;
2830 			}
2831 			p++;
2832 			nr++;
2833 		}
2834 		psn->psn_len = sizeof(struct pf_src_node) * nr;
2835 
2836 		PF_UNLOCK();
2837 		NET_UNLOCK();
2838 		free(pstore, M_TEMP, sizeof(*pstore));
2839 		break;
2840 	}
2841 
2842 	case DIOCCLRSRCNODES: {
2843 		struct pf_src_node	*n;
2844 		struct pf_state		*state;
2845 
2846 		NET_LOCK();
2847 		PF_LOCK();
2848 		PF_STATE_ENTER_WRITE();
2849 		RB_FOREACH(state, pf_state_tree_id, &tree_id)
2850 			pf_src_tree_remove_state(state);
2851 		PF_STATE_EXIT_WRITE();
2852 		RB_FOREACH(n, pf_src_tree, &tree_src_tracking)
2853 			n->expire = 1;
2854 		pf_purge_expired_src_nodes();
2855 		PF_UNLOCK();
2856 		NET_UNLOCK();
2857 		break;
2858 	}
2859 
2860 	case DIOCKILLSRCNODES: {
2861 		struct pf_src_node	*sn;
2862 		struct pf_state		*s;
2863 		struct pfioc_src_node_kill *psnk =
2864 		    (struct pfioc_src_node_kill *)addr;
2865 		u_int			killed = 0;
2866 
2867 		NET_LOCK();
2868 		PF_LOCK();
2869 		RB_FOREACH(sn, pf_src_tree, &tree_src_tracking) {
2870 			if (pf_match_addr(psnk->psnk_src.neg,
2871 				&psnk->psnk_src.addr.v.a.addr,
2872 				&psnk->psnk_src.addr.v.a.mask,
2873 				&sn->addr, sn->af) &&
2874 			    pf_match_addr(psnk->psnk_dst.neg,
2875 				&psnk->psnk_dst.addr.v.a.addr,
2876 				&psnk->psnk_dst.addr.v.a.mask,
2877 				&sn->raddr, sn->af)) {
2878 				/* Handle state to src_node linkage */
2879 				if (sn->states != 0) {
2880 					PF_ASSERT_LOCKED();
2881 					PF_STATE_ENTER_WRITE();
2882 					RB_FOREACH(s, pf_state_tree_id,
2883 					   &tree_id)
2884 						pf_state_rm_src_node(s, sn);
2885 					PF_STATE_EXIT_WRITE();
2886 				}
2887 				sn->expire = 1;
2888 				killed++;
2889 			}
2890 		}
2891 
2892 		if (killed > 0)
2893 			pf_purge_expired_src_nodes();
2894 
2895 		psnk->psnk_killed = killed;
2896 		PF_UNLOCK();
2897 		NET_UNLOCK();
2898 		break;
2899 	}
2900 
2901 	case DIOCSETHOSTID: {
2902 		u_int32_t	*hostid = (u_int32_t *)addr;
2903 
2904 		NET_LOCK();
2905 		PF_LOCK();
2906 		if (*hostid == 0)
2907 			pf_trans_set.hostid = arc4random();
2908 		else
2909 			pf_trans_set.hostid = *hostid;
2910 		pf_trans_set.mask |= PF_TSET_HOSTID;
2911 		PF_UNLOCK();
2912 		NET_UNLOCK();
2913 		break;
2914 	}
2915 
2916 	case DIOCOSFPFLUSH:
2917 		pf_osfp_flush();
2918 		break;
2919 
2920 	case DIOCIGETIFACES: {
2921 		struct pfioc_iface	*io = (struct pfioc_iface *)addr;
2922 		struct pfi_kif		*kif_buf;
2923 		int			 apfiio_size = io->pfiio_size;
2924 
2925 		if (io->pfiio_esize != sizeof(struct pfi_kif)) {
2926 			error = ENODEV;
2927 			goto fail;
2928 		}
2929 
2930 		if ((kif_buf = mallocarray(sizeof(*kif_buf), apfiio_size,
2931 		    M_TEMP, M_WAITOK|M_CANFAIL)) == NULL) {
2932 			error = EINVAL;
2933 			goto fail;
2934 		}
2935 
2936 		NET_LOCK();
2937 		PF_LOCK();
2938 		pfi_get_ifaces(io->pfiio_name, kif_buf, &io->pfiio_size);
2939 		PF_UNLOCK();
2940 		NET_UNLOCK();
2941 		if (copyout(kif_buf, io->pfiio_buffer, sizeof(*kif_buf) *
2942 		    io->pfiio_size))
2943 			error = EFAULT;
2944 		free(kif_buf, M_TEMP, sizeof(*kif_buf) * apfiio_size);
2945 		break;
2946 	}
2947 
2948 	case DIOCSETIFFLAG: {
2949 		struct pfioc_iface *io = (struct pfioc_iface *)addr;
2950 
2951 		if (io == NULL) {
2952 			error = EINVAL;
2953 			goto fail;
2954 		}
2955 
2956 		NET_LOCK();
2957 		PF_LOCK();
2958 		error = pfi_set_flags(io->pfiio_name, io->pfiio_flags);
2959 		PF_UNLOCK();
2960 		NET_UNLOCK();
2961 		break;
2962 	}
2963 
2964 	case DIOCCLRIFFLAG: {
2965 		struct pfioc_iface *io = (struct pfioc_iface *)addr;
2966 
2967 		if (io == NULL) {
2968 			error = EINVAL;
2969 			goto fail;
2970 		}
2971 
2972 		NET_LOCK();
2973 		PF_LOCK();
2974 		error = pfi_clear_flags(io->pfiio_name, io->pfiio_flags);
2975 		PF_UNLOCK();
2976 		NET_UNLOCK();
2977 		break;
2978 	}
2979 
2980 	case DIOCSETREASS: {
2981 		u_int32_t	*reass = (u_int32_t *)addr;
2982 
2983 		NET_LOCK();
2984 		PF_LOCK();
2985 		pf_trans_set.reass = *reass;
2986 		pf_trans_set.mask |= PF_TSET_REASS;
2987 		PF_UNLOCK();
2988 		NET_UNLOCK();
2989 		break;
2990 	}
2991 
2992 	case DIOCSETSYNFLWATS: {
2993 		struct pfioc_synflwats *io = (struct pfioc_synflwats *)addr;
2994 
2995 		NET_LOCK();
2996 		PF_LOCK();
2997 		error = pf_syncookies_setwats(io->hiwat, io->lowat);
2998 		PF_UNLOCK();
2999 		NET_UNLOCK();
3000 		break;
3001 	}
3002 
3003 	case DIOCGETSYNFLWATS: {
3004 		struct pfioc_synflwats *io = (struct pfioc_synflwats *)addr;
3005 
3006 		NET_LOCK();
3007 		PF_LOCK();
3008 		error = pf_syncookies_getwats(io);
3009 		PF_UNLOCK();
3010 		NET_UNLOCK();
3011 		break;
3012 	}
3013 
3014 	case DIOCSETSYNCOOKIES: {
3015 		u_int8_t	*mode = (u_int8_t *)addr;
3016 
3017 		NET_LOCK();
3018 		PF_LOCK();
3019 		error = pf_syncookies_setmode(*mode);
3020 		PF_UNLOCK();
3021 		NET_UNLOCK();
3022 		break;
3023 	}
3024 
3025 	default:
3026 		error = ENODEV;
3027 		break;
3028 	}
3029 fail:
3030 	if (flags & FWRITE)
3031 		rw_exit_write(&pfioctl_rw);
3032 	else
3033 		rw_exit_read(&pfioctl_rw);
3034 
3035 	return (error);
3036 }
3037 
3038 void
3039 pf_trans_set_commit(void)
3040 {
3041 	if (pf_trans_set.mask & PF_TSET_STATUSIF)
3042 		strlcpy(pf_status.ifname, pf_trans_set.statusif, IFNAMSIZ);
3043 	if (pf_trans_set.mask & PF_TSET_DEBUG)
3044 		pf_status.debug = pf_trans_set.debug;
3045 	if (pf_trans_set.mask & PF_TSET_HOSTID)
3046 		pf_status.hostid = pf_trans_set.hostid;
3047 	if (pf_trans_set.mask & PF_TSET_REASS)
3048 		pf_status.reass = pf_trans_set.reass;
3049 }
3050 
3051 void
3052 pf_pool_copyin(struct pf_pool *from, struct pf_pool *to)
3053 {
3054 	memmove(to, from, sizeof(*to));
3055 	to->kif = NULL;
3056 	to->addr.p.tbl = NULL;
3057 }
3058 
3059 int
3060 pf_validate_range(u_int8_t op, u_int16_t port[2], int order)
3061 {
3062 	u_int16_t a = (order == PF_ORDER_NET) ? ntohs(port[0]) : port[0];
3063 	u_int16_t b = (order == PF_ORDER_NET) ? ntohs(port[1]) : port[1];
3064 
3065 	if ((op == PF_OP_RRG && a > b) ||  /* 34:12,  i.e. none */
3066 	    (op == PF_OP_IRG && a >= b) || /* 34><12, i.e. none */
3067 	    (op == PF_OP_XRG && a > b))    /* 34<>22, i.e. all */
3068 		return 1;
3069 	return 0;
3070 }
3071 
3072 int
3073 pf_rule_copyin(struct pf_rule *from, struct pf_rule *to)
3074 {
3075 	int i;
3076 
3077 	if (from->scrub_flags & PFSTATE_SETPRIO &&
3078 	    (from->set_prio[0] > IFQ_MAXPRIO ||
3079 	    from->set_prio[1] > IFQ_MAXPRIO))
3080 		return (EINVAL);
3081 
3082 	to->src = from->src;
3083 	to->src.addr.p.tbl = NULL;
3084 	to->dst = from->dst;
3085 	to->dst.addr.p.tbl = NULL;
3086 
3087 	if (pf_validate_range(to->src.port_op, to->src.port, PF_ORDER_NET))
3088 		return (EINVAL);
3089 	if (pf_validate_range(to->dst.port_op, to->dst.port, PF_ORDER_NET))
3090 		return (EINVAL);
3091 
3092 	/* XXX union skip[] */
3093 
3094 	strlcpy(to->label, from->label, sizeof(to->label));
3095 	strlcpy(to->ifname, from->ifname, sizeof(to->ifname));
3096 	strlcpy(to->rcv_ifname, from->rcv_ifname, sizeof(to->rcv_ifname));
3097 	strlcpy(to->qname, from->qname, sizeof(to->qname));
3098 	strlcpy(to->pqname, from->pqname, sizeof(to->pqname));
3099 	strlcpy(to->tagname, from->tagname, sizeof(to->tagname));
3100 	strlcpy(to->match_tagname, from->match_tagname,
3101 	    sizeof(to->match_tagname));
3102 	strlcpy(to->overload_tblname, from->overload_tblname,
3103 	    sizeof(to->overload_tblname));
3104 
3105 	pf_pool_copyin(&from->nat, &to->nat);
3106 	pf_pool_copyin(&from->rdr, &to->rdr);
3107 	pf_pool_copyin(&from->route, &to->route);
3108 
3109 	if (pf_validate_range(to->rdr.port_op, to->rdr.proxy_port,
3110 	    PF_ORDER_HOST))
3111 		return (EINVAL);
3112 
3113 	to->kif = (to->ifname[0]) ?
3114 	    pfi_kif_alloc(to->ifname, M_WAITOK) : NULL;
3115 	to->rcv_kif = (to->rcv_ifname[0]) ?
3116 	    pfi_kif_alloc(to->rcv_ifname, M_WAITOK) : NULL;
3117 	to->rdr.kif = (to->rdr.ifname[0]) ?
3118 	    pfi_kif_alloc(to->rdr.ifname, M_WAITOK) : NULL;
3119 	to->nat.kif = (to->nat.ifname[0]) ?
3120 	    pfi_kif_alloc(to->nat.ifname, M_WAITOK) : NULL;
3121 	to->route.kif = (to->route.ifname[0]) ?
3122 	    pfi_kif_alloc(to->route.ifname, M_WAITOK) : NULL;
3123 
3124 	to->os_fingerprint = from->os_fingerprint;
3125 
3126 	to->rtableid = from->rtableid;
3127 	if (to->rtableid >= 0 && !rtable_exists(to->rtableid))
3128 		return (EBUSY);
3129 	to->onrdomain = from->onrdomain;
3130 	if (to->onrdomain != -1 && (to->onrdomain < 0 ||
3131 	    to->onrdomain > RT_TABLEID_MAX))
3132 		return (EINVAL);
3133 
3134 	for (i = 0; i < PFTM_MAX; i++)
3135 		to->timeout[i] = from->timeout[i];
3136 	to->states_tot = from->states_tot;
3137 	to->max_states = from->max_states;
3138 	to->max_src_nodes = from->max_src_nodes;
3139 	to->max_src_states = from->max_src_states;
3140 	to->max_src_conn = from->max_src_conn;
3141 	to->max_src_conn_rate.limit = from->max_src_conn_rate.limit;
3142 	to->max_src_conn_rate.seconds = from->max_src_conn_rate.seconds;
3143 	pf_init_threshold(&to->pktrate, from->pktrate.limit,
3144 	    from->pktrate.seconds);
3145 
3146 	if (to->qname[0] != 0) {
3147 		if ((to->qid = pf_qname2qid(to->qname, 0)) == 0)
3148 			return (EBUSY);
3149 		if (to->pqname[0] != 0) {
3150 			if ((to->pqid = pf_qname2qid(to->pqname, 0)) == 0)
3151 				return (EBUSY);
3152 		} else
3153 			to->pqid = to->qid;
3154 	}
3155 	to->rt_listid = from->rt_listid;
3156 	to->prob = from->prob;
3157 	to->return_icmp = from->return_icmp;
3158 	to->return_icmp6 = from->return_icmp6;
3159 	to->max_mss = from->max_mss;
3160 	if (to->tagname[0])
3161 		if ((to->tag = pf_tagname2tag(to->tagname, 1)) == 0)
3162 			return (EBUSY);
3163 	if (to->match_tagname[0])
3164 		if ((to->match_tag = pf_tagname2tag(to->match_tagname, 1)) == 0)
3165 			return (EBUSY);
3166 	to->scrub_flags = from->scrub_flags;
3167 	to->delay = from->delay;
3168 	to->uid = from->uid;
3169 	to->gid = from->gid;
3170 	to->rule_flag = from->rule_flag;
3171 	to->action = from->action;
3172 	to->direction = from->direction;
3173 	to->log = from->log;
3174 	to->logif = from->logif;
3175 #if NPFLOG > 0
3176 	if (!to->log)
3177 		to->logif = 0;
3178 #endif	/* NPFLOG > 0 */
3179 	to->quick = from->quick;
3180 	to->ifnot = from->ifnot;
3181 	to->rcvifnot = from->rcvifnot;
3182 	to->match_tag_not = from->match_tag_not;
3183 	to->keep_state = from->keep_state;
3184 	to->af = from->af;
3185 	to->naf = from->naf;
3186 	to->proto = from->proto;
3187 	to->type = from->type;
3188 	to->code = from->code;
3189 	to->flags = from->flags;
3190 	to->flagset = from->flagset;
3191 	to->min_ttl = from->min_ttl;
3192 	to->allow_opts = from->allow_opts;
3193 	to->rt = from->rt;
3194 	to->return_ttl = from->return_ttl;
3195 	to->tos = from->tos;
3196 	to->set_tos = from->set_tos;
3197 	to->anchor_relative = from->anchor_relative; /* XXX */
3198 	to->anchor_wildcard = from->anchor_wildcard; /* XXX */
3199 	to->flush = from->flush;
3200 	to->divert.addr = from->divert.addr;
3201 	to->divert.port = from->divert.port;
3202 	to->divert.type = from->divert.type;
3203 	to->prio = from->prio;
3204 	to->set_prio[0] = from->set_prio[0];
3205 	to->set_prio[1] = from->set_prio[1];
3206 
3207 	return (0);
3208 }
3209 
3210 int
3211 pf_rule_checkaf(struct pf_rule *r)
3212 {
3213 	switch (r->af) {
3214 	case 0:
3215 		if (r->rule_flag & PFRULE_AFTO)
3216 			return (EPFNOSUPPORT);
3217 		break;
3218 	case AF_INET:
3219 		if ((r->rule_flag & PFRULE_AFTO) && r->naf != AF_INET6)
3220 			return (EPFNOSUPPORT);
3221 		break;
3222 #ifdef INET6
3223 	case AF_INET6:
3224 		if ((r->rule_flag & PFRULE_AFTO) && r->naf != AF_INET)
3225 			return (EPFNOSUPPORT);
3226 		break;
3227 #endif /* INET6 */
3228 	default:
3229 		return (EPFNOSUPPORT);
3230 	}
3231 
3232 	if ((r->rule_flag & PFRULE_AFTO) == 0 && r->naf != 0)
3233 		return (EPFNOSUPPORT);
3234 
3235 	return (0);
3236 }
3237 
3238 int
3239 pf_sysctl(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
3240 {
3241 	struct pf_status	pfs;
3242 
3243 	NET_RLOCK_IN_IOCTL();
3244 	PF_LOCK();
3245 	memcpy(&pfs, &pf_status, sizeof(struct pf_status));
3246 	pfi_update_status(pfs.ifname, &pfs);
3247 	PF_UNLOCK();
3248 	NET_RUNLOCK_IN_IOCTL();
3249 
3250 	return sysctl_rdstruct(oldp, oldlenp, newp, &pfs, sizeof(pfs));
3251 }
3252