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