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