]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/netpfil/pf/pf_ioctl.c
zfs: merge OpenZFS master-bf156c966
[FreeBSD/FreeBSD.git] / sys / netpfil / pf / pf_ioctl.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2001 Daniel Hartmeier
5  * Copyright (c) 2002,2003 Henning Brauer
6  * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.org>
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  *    - Redistributions of source code must retain the above copyright
14  *      notice, this list of conditions and the following disclaimer.
15  *    - Redistributions in binary form must reproduce the above
16  *      copyright notice, this list of conditions and the following
17  *      disclaimer in the documentation and/or other materials provided
18  *      with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Effort sponsored in part by the Defense Advanced Research Projects
34  * Agency (DARPA) and Air Force Research Laboratory, Air Force
35  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
36  *
37  *      $OpenBSD: pf_ioctl.c,v 1.213 2009/02/15 21:46:12 mbalmer Exp $
38  */
39
40 #include <sys/cdefs.h>
41 __FBSDID("$FreeBSD$");
42
43 #include "opt_inet.h"
44 #include "opt_inet6.h"
45 #include "opt_bpf.h"
46 #include "opt_pf.h"
47
48 #include <sys/param.h>
49 #include <sys/_bitset.h>
50 #include <sys/bitset.h>
51 #include <sys/bus.h>
52 #include <sys/conf.h>
53 #include <sys/endian.h>
54 #include <sys/fcntl.h>
55 #include <sys/filio.h>
56 #include <sys/hash.h>
57 #include <sys/interrupt.h>
58 #include <sys/jail.h>
59 #include <sys/kernel.h>
60 #include <sys/kthread.h>
61 #include <sys/lock.h>
62 #include <sys/mbuf.h>
63 #include <sys/module.h>
64 #include <sys/proc.h>
65 #include <sys/smp.h>
66 #include <sys/socket.h>
67 #include <sys/sysctl.h>
68 #include <sys/md5.h>
69 #include <sys/ucred.h>
70
71 #include <net/if.h>
72 #include <net/if_var.h>
73 #include <net/vnet.h>
74 #include <net/route.h>
75 #include <net/pfil.h>
76 #include <net/pfvar.h>
77 #include <net/if_pfsync.h>
78 #include <net/if_pflog.h>
79
80 #include <netinet/in.h>
81 #include <netinet/ip.h>
82 #include <netinet/ip_var.h>
83 #include <netinet6/ip6_var.h>
84 #include <netinet/ip_icmp.h>
85
86 #ifdef INET6
87 #include <netinet/ip6.h>
88 #endif /* INET6 */
89
90 #ifdef ALTQ
91 #include <net/altq/altq.h>
92 #endif
93
94 static struct pf_kpool  *pf_get_kpool(char *, u_int32_t, u_int8_t, u_int32_t,
95                             u_int8_t, u_int8_t, u_int8_t);
96
97 static void              pf_mv_kpool(struct pf_kpalist *, struct pf_kpalist *);
98 static void              pf_empty_kpool(struct pf_kpalist *);
99 static int               pfioctl(struct cdev *, u_long, caddr_t, int,
100                             struct thread *);
101 #ifdef ALTQ
102 static int               pf_begin_altq(u_int32_t *);
103 static int               pf_rollback_altq(u_int32_t);
104 static int               pf_commit_altq(u_int32_t);
105 static int               pf_enable_altq(struct pf_altq *);
106 static int               pf_disable_altq(struct pf_altq *);
107 static u_int32_t         pf_qname2qid(char *);
108 static void              pf_qid_unref(u_int32_t);
109 #endif /* ALTQ */
110 static int               pf_begin_rules(u_int32_t *, int, const char *);
111 static int               pf_rollback_rules(u_int32_t, int, char *);
112 static int               pf_setup_pfsync_matching(struct pf_kruleset *);
113 static void              pf_hash_rule(MD5_CTX *, struct pf_krule *);
114 static void              pf_hash_rule_addr(MD5_CTX *, struct pf_rule_addr *);
115 static int               pf_commit_rules(u_int32_t, int, char *);
116 static int               pf_addr_setup(struct pf_kruleset *,
117                             struct pf_addr_wrap *, sa_family_t);
118 static void              pf_addr_copyout(struct pf_addr_wrap *);
119 static void              pf_src_node_copy(const struct pf_ksrc_node *,
120                             struct pf_src_node *);
121 #ifdef ALTQ
122 static int               pf_export_kaltq(struct pf_altq *,
123                             struct pfioc_altq_v1 *, size_t);
124 static int               pf_import_kaltq(struct pfioc_altq_v1 *,
125                             struct pf_altq *, size_t);
126 #endif /* ALTQ */
127
128 VNET_DEFINE(struct pf_krule,    pf_default_rule);
129
130 #ifdef ALTQ
131 VNET_DEFINE_STATIC(int,         pf_altq_running);
132 #define V_pf_altq_running       VNET(pf_altq_running)
133 #endif
134
135 #define TAGID_MAX        50000
136 struct pf_tagname {
137         TAILQ_ENTRY(pf_tagname) namehash_entries;
138         TAILQ_ENTRY(pf_tagname) taghash_entries;
139         char                    name[PF_TAG_NAME_SIZE];
140         uint16_t                tag;
141         int                     ref;
142 };
143
144 struct pf_tagset {
145         TAILQ_HEAD(, pf_tagname)        *namehash;
146         TAILQ_HEAD(, pf_tagname)        *taghash;
147         unsigned int                     mask;
148         uint32_t                         seed;
149         BITSET_DEFINE(, TAGID_MAX)       avail;
150 };
151
152 VNET_DEFINE(struct pf_tagset, pf_tags);
153 #define V_pf_tags       VNET(pf_tags)
154 static unsigned int     pf_rule_tag_hashsize;
155 #define PF_RULE_TAG_HASH_SIZE_DEFAULT   128
156 SYSCTL_UINT(_net_pf, OID_AUTO, rule_tag_hashsize, CTLFLAG_RDTUN,
157     &pf_rule_tag_hashsize, PF_RULE_TAG_HASH_SIZE_DEFAULT,
158     "Size of pf(4) rule tag hashtable");
159
160 #ifdef ALTQ
161 VNET_DEFINE(struct pf_tagset, pf_qids);
162 #define V_pf_qids       VNET(pf_qids)
163 static unsigned int     pf_queue_tag_hashsize;
164 #define PF_QUEUE_TAG_HASH_SIZE_DEFAULT  128
165 SYSCTL_UINT(_net_pf, OID_AUTO, queue_tag_hashsize, CTLFLAG_RDTUN,
166     &pf_queue_tag_hashsize, PF_QUEUE_TAG_HASH_SIZE_DEFAULT,
167     "Size of pf(4) queue tag hashtable");
168 #endif
169 VNET_DEFINE(uma_zone_t,  pf_tag_z);
170 #define V_pf_tag_z               VNET(pf_tag_z)
171 static MALLOC_DEFINE(M_PFALTQ, "pf_altq", "pf(4) altq configuration db");
172 static MALLOC_DEFINE(M_PFRULE, "pf_rule", "pf(4) rules");
173
174 #if (PF_QNAME_SIZE != PF_TAG_NAME_SIZE)
175 #error PF_QNAME_SIZE must be equal to PF_TAG_NAME_SIZE
176 #endif
177
178 static void              pf_init_tagset(struct pf_tagset *, unsigned int *,
179                             unsigned int);
180 static void              pf_cleanup_tagset(struct pf_tagset *);
181 static uint16_t          tagname2hashindex(const struct pf_tagset *, const char *);
182 static uint16_t          tag2hashindex(const struct pf_tagset *, uint16_t);
183 static u_int16_t         tagname2tag(struct pf_tagset *, char *);
184 static u_int16_t         pf_tagname2tag(char *);
185 static void              tag_unref(struct pf_tagset *, u_int16_t);
186
187 #define DPFPRINTF(n, x) if (V_pf_status.debug >= (n)) printf x
188
189 struct cdev *pf_dev;
190
191 /*
192  * XXX - These are new and need to be checked when moveing to a new version
193  */
194 static void              pf_clear_states(void);
195 static int               pf_clear_tables(void);
196 static void              pf_clear_srcnodes(struct pf_ksrc_node *);
197 static void              pf_kill_srcnodes(struct pfioc_src_node_kill *);
198 static void              pf_tbladdr_copyout(struct pf_addr_wrap *);
199
200 /*
201  * Wrapper functions for pfil(9) hooks
202  */
203 #ifdef INET
204 static pfil_return_t pf_check_in(struct mbuf **m, struct ifnet *ifp,
205     int flags, void *ruleset __unused, struct inpcb *inp);
206 static pfil_return_t pf_check_out(struct mbuf **m, struct ifnet *ifp,
207     int flags, void *ruleset __unused, struct inpcb *inp);
208 #endif
209 #ifdef INET6
210 static pfil_return_t pf_check6_in(struct mbuf **m, struct ifnet *ifp,
211     int flags, void *ruleset __unused, struct inpcb *inp);
212 static pfil_return_t pf_check6_out(struct mbuf **m, struct ifnet *ifp,
213     int flags, void *ruleset __unused, struct inpcb *inp);
214 #endif
215
216 static void             hook_pf(void);
217 static void             dehook_pf(void);
218 static int              shutdown_pf(void);
219 static int              pf_load(void);
220 static void             pf_unload(void);
221
222 static struct cdevsw pf_cdevsw = {
223         .d_ioctl =      pfioctl,
224         .d_name =       PF_NAME,
225         .d_version =    D_VERSION,
226 };
227
228 volatile VNET_DEFINE_STATIC(int, pf_pfil_hooked);
229 #define V_pf_pfil_hooked        VNET(pf_pfil_hooked)
230
231 /*
232  * We need a flag that is neither hooked nor running to know when
233  * the VNET is "valid".  We primarily need this to control (global)
234  * external event, e.g., eventhandlers.
235  */
236 VNET_DEFINE(int, pf_vnet_active);
237 #define V_pf_vnet_active        VNET(pf_vnet_active)
238
239 int pf_end_threads;
240 struct proc *pf_purge_proc;
241
242 struct rmlock                   pf_rules_lock;
243 struct sx                       pf_ioctl_lock;
244 struct sx                       pf_end_lock;
245
246 /* pfsync */
247 VNET_DEFINE(pfsync_state_import_t *, pfsync_state_import_ptr);
248 VNET_DEFINE(pfsync_insert_state_t *, pfsync_insert_state_ptr);
249 VNET_DEFINE(pfsync_update_state_t *, pfsync_update_state_ptr);
250 VNET_DEFINE(pfsync_delete_state_t *, pfsync_delete_state_ptr);
251 VNET_DEFINE(pfsync_clear_states_t *, pfsync_clear_states_ptr);
252 VNET_DEFINE(pfsync_defer_t *, pfsync_defer_ptr);
253 pfsync_detach_ifnet_t *pfsync_detach_ifnet_ptr;
254
255 /* pflog */
256 pflog_packet_t                  *pflog_packet_ptr = NULL;
257
258 extern u_long   pf_ioctl_maxcount;
259
260 static void
261 pfattach_vnet(void)
262 {
263         u_int32_t *my_timeout = V_pf_default_rule.timeout;
264
265         pf_initialize();
266         pfr_initialize();
267         pfi_initialize_vnet();
268         pf_normalize_init();
269
270         V_pf_limits[PF_LIMIT_STATES].limit = PFSTATE_HIWAT;
271         V_pf_limits[PF_LIMIT_SRC_NODES].limit = PFSNODE_HIWAT;
272
273         RB_INIT(&V_pf_anchors);
274         pf_init_kruleset(&pf_main_ruleset);
275
276         /* default rule should never be garbage collected */
277         V_pf_default_rule.entries.tqe_prev = &V_pf_default_rule.entries.tqe_next;
278 #ifdef PF_DEFAULT_TO_DROP
279         V_pf_default_rule.action = PF_DROP;
280 #else
281         V_pf_default_rule.action = PF_PASS;
282 #endif
283         V_pf_default_rule.nr = -1;
284         V_pf_default_rule.rtableid = -1;
285
286         V_pf_default_rule.evaluations = counter_u64_alloc(M_WAITOK);
287         for (int i = 0; i < 2; i++) {
288                 V_pf_default_rule.packets[i] = counter_u64_alloc(M_WAITOK);
289                 V_pf_default_rule.bytes[i] = counter_u64_alloc(M_WAITOK);
290         }
291         V_pf_default_rule.states_cur = counter_u64_alloc(M_WAITOK);
292         V_pf_default_rule.states_tot = counter_u64_alloc(M_WAITOK);
293         V_pf_default_rule.src_nodes = counter_u64_alloc(M_WAITOK);
294
295         /* initialize default timeouts */
296         my_timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
297         my_timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL;
298         my_timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL;
299         my_timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL;
300         my_timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL;
301         my_timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL;
302         my_timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL;
303         my_timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL;
304         my_timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL;
305         my_timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL;
306         my_timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL;
307         my_timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL;
308         my_timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL;
309         my_timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL;
310         my_timeout[PFTM_FRAG] = PFTM_FRAG_VAL;
311         my_timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL;
312         my_timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL;
313         my_timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL;
314         my_timeout[PFTM_ADAPTIVE_START] = PFSTATE_ADAPT_START;
315         my_timeout[PFTM_ADAPTIVE_END] = PFSTATE_ADAPT_END;
316
317         bzero(&V_pf_status, sizeof(V_pf_status));
318         V_pf_status.debug = PF_DEBUG_URGENT;
319
320         V_pf_pfil_hooked = 0;
321
322         /* XXX do our best to avoid a conflict */
323         V_pf_status.hostid = arc4random();
324
325         for (int i = 0; i < PFRES_MAX; i++)
326                 V_pf_status.counters[i] = counter_u64_alloc(M_WAITOK);
327         for (int i = 0; i < LCNT_MAX; i++)
328                 V_pf_status.lcounters[i] = counter_u64_alloc(M_WAITOK);
329         for (int i = 0; i < FCNT_MAX; i++)
330                 V_pf_status.fcounters[i] = counter_u64_alloc(M_WAITOK);
331         for (int i = 0; i < SCNT_MAX; i++)
332                 V_pf_status.scounters[i] = counter_u64_alloc(M_WAITOK);
333
334         if (swi_add(NULL, "pf send", pf_intr, curvnet, SWI_NET,
335             INTR_MPSAFE, &V_pf_swi_cookie) != 0)
336                 /* XXXGL: leaked all above. */
337                 return;
338 }
339
340 static struct pf_kpool *
341 pf_get_kpool(char *anchor, u_int32_t ticket, u_int8_t rule_action,
342     u_int32_t rule_number, u_int8_t r_last, u_int8_t active,
343     u_int8_t check_ticket)
344 {
345         struct pf_kruleset      *ruleset;
346         struct pf_krule         *rule;
347         int                      rs_num;
348
349         ruleset = pf_find_kruleset(anchor);
350         if (ruleset == NULL)
351                 return (NULL);
352         rs_num = pf_get_ruleset_number(rule_action);
353         if (rs_num >= PF_RULESET_MAX)
354                 return (NULL);
355         if (active) {
356                 if (check_ticket && ticket !=
357                     ruleset->rules[rs_num].active.ticket)
358                         return (NULL);
359                 if (r_last)
360                         rule = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
361                             pf_krulequeue);
362                 else
363                         rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
364         } else {
365                 if (check_ticket && ticket !=
366                     ruleset->rules[rs_num].inactive.ticket)
367                         return (NULL);
368                 if (r_last)
369                         rule = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,
370                             pf_krulequeue);
371                 else
372                         rule = TAILQ_FIRST(ruleset->rules[rs_num].inactive.ptr);
373         }
374         if (!r_last) {
375                 while ((rule != NULL) && (rule->nr != rule_number))
376                         rule = TAILQ_NEXT(rule, entries);
377         }
378         if (rule == NULL)
379                 return (NULL);
380
381         return (&rule->rpool);
382 }
383
384 static void
385 pf_mv_kpool(struct pf_kpalist *poola, struct pf_kpalist *poolb)
386 {
387         struct pf_kpooladdr     *mv_pool_pa;
388
389         while ((mv_pool_pa = TAILQ_FIRST(poola)) != NULL) {
390                 TAILQ_REMOVE(poola, mv_pool_pa, entries);
391                 TAILQ_INSERT_TAIL(poolb, mv_pool_pa, entries);
392         }
393 }
394
395 static void
396 pf_empty_kpool(struct pf_kpalist *poola)
397 {
398         struct pf_kpooladdr *pa;
399
400         while ((pa = TAILQ_FIRST(poola)) != NULL) {
401                 switch (pa->addr.type) {
402                 case PF_ADDR_DYNIFTL:
403                         pfi_dynaddr_remove(pa->addr.p.dyn);
404                         break;
405                 case PF_ADDR_TABLE:
406                         /* XXX: this could be unfinished pooladdr on pabuf */
407                         if (pa->addr.p.tbl != NULL)
408                                 pfr_detach_table(pa->addr.p.tbl);
409                         break;
410                 }
411                 if (pa->kif)
412                         pfi_kkif_unref(pa->kif);
413                 TAILQ_REMOVE(poola, pa, entries);
414                 free(pa, M_PFRULE);
415         }
416 }
417
418 static void
419 pf_unlink_rule(struct pf_krulequeue *rulequeue, struct pf_krule *rule)
420 {
421
422         PF_RULES_WASSERT();
423
424         TAILQ_REMOVE(rulequeue, rule, entries);
425
426         PF_UNLNKDRULES_LOCK();
427         rule->rule_flag |= PFRULE_REFS;
428         TAILQ_INSERT_TAIL(&V_pf_unlinked_rules, rule, entries);
429         PF_UNLNKDRULES_UNLOCK();
430 }
431
432 void
433 pf_free_rule(struct pf_krule *rule)
434 {
435
436         PF_RULES_WASSERT();
437
438         if (rule->tag)
439                 tag_unref(&V_pf_tags, rule->tag);
440         if (rule->match_tag)
441                 tag_unref(&V_pf_tags, rule->match_tag);
442 #ifdef ALTQ
443         if (rule->pqid != rule->qid)
444                 pf_qid_unref(rule->pqid);
445         pf_qid_unref(rule->qid);
446 #endif
447         switch (rule->src.addr.type) {
448         case PF_ADDR_DYNIFTL:
449                 pfi_dynaddr_remove(rule->src.addr.p.dyn);
450                 break;
451         case PF_ADDR_TABLE:
452                 pfr_detach_table(rule->src.addr.p.tbl);
453                 break;
454         }
455         switch (rule->dst.addr.type) {
456         case PF_ADDR_DYNIFTL:
457                 pfi_dynaddr_remove(rule->dst.addr.p.dyn);
458                 break;
459         case PF_ADDR_TABLE:
460                 pfr_detach_table(rule->dst.addr.p.tbl);
461                 break;
462         }
463         if (rule->overload_tbl)
464                 pfr_detach_table(rule->overload_tbl);
465         if (rule->kif)
466                 pfi_kkif_unref(rule->kif);
467         pf_kanchor_remove(rule);
468         pf_empty_kpool(&rule->rpool.list);
469         counter_u64_free(rule->evaluations);
470         for (int i = 0; i < 2; i++) {
471                 counter_u64_free(rule->packets[i]);
472                 counter_u64_free(rule->bytes[i]);
473         }
474         counter_u64_free(rule->states_cur);
475         counter_u64_free(rule->states_tot);
476         counter_u64_free(rule->src_nodes);
477         free(rule, M_PFRULE);
478 }
479
480 static void
481 pf_init_tagset(struct pf_tagset *ts, unsigned int *tunable_size,
482     unsigned int default_size)
483 {
484         unsigned int i;
485         unsigned int hashsize;
486
487         if (*tunable_size == 0 || !powerof2(*tunable_size))
488                 *tunable_size = default_size;
489
490         hashsize = *tunable_size;
491         ts->namehash = mallocarray(hashsize, sizeof(*ts->namehash), M_PFHASH,
492             M_WAITOK);
493         ts->taghash = mallocarray(hashsize, sizeof(*ts->taghash), M_PFHASH,
494             M_WAITOK);
495         ts->mask = hashsize - 1;
496         ts->seed = arc4random();
497         for (i = 0; i < hashsize; i++) {
498                 TAILQ_INIT(&ts->namehash[i]);
499                 TAILQ_INIT(&ts->taghash[i]);
500         }
501         BIT_FILL(TAGID_MAX, &ts->avail);
502 }
503
504 static void
505 pf_cleanup_tagset(struct pf_tagset *ts)
506 {
507         unsigned int i;
508         unsigned int hashsize;
509         struct pf_tagname *t, *tmp;
510
511         /*
512          * Only need to clean up one of the hashes as each tag is hashed
513          * into each table.
514          */
515         hashsize = ts->mask + 1;
516         for (i = 0; i < hashsize; i++)
517                 TAILQ_FOREACH_SAFE(t, &ts->namehash[i], namehash_entries, tmp)
518                         uma_zfree(V_pf_tag_z, t);
519
520         free(ts->namehash, M_PFHASH);
521         free(ts->taghash, M_PFHASH);
522 }
523
524 static uint16_t
525 tagname2hashindex(const struct pf_tagset *ts, const char *tagname)
526 {
527         size_t len;
528
529         len = strnlen(tagname, PF_TAG_NAME_SIZE - 1);
530         return (murmur3_32_hash(tagname, len, ts->seed) & ts->mask);
531 }
532
533 static uint16_t
534 tag2hashindex(const struct pf_tagset *ts, uint16_t tag)
535 {
536
537         return (tag & ts->mask);
538 }
539
540 static u_int16_t
541 tagname2tag(struct pf_tagset *ts, char *tagname)
542 {
543         struct pf_tagname       *tag;
544         u_int32_t                index;
545         u_int16_t                new_tagid;
546
547         PF_RULES_WASSERT();
548
549         index = tagname2hashindex(ts, tagname);
550         TAILQ_FOREACH(tag, &ts->namehash[index], namehash_entries)
551                 if (strcmp(tagname, tag->name) == 0) {
552                         tag->ref++;
553                         return (tag->tag);
554                 }
555
556         /*
557          * new entry
558          *
559          * to avoid fragmentation, we do a linear search from the beginning
560          * and take the first free slot we find.
561          */
562         new_tagid = BIT_FFS(TAGID_MAX, &ts->avail);
563         /*
564          * Tags are 1-based, with valid tags in the range [1..TAGID_MAX].
565          * BIT_FFS() returns a 1-based bit number, with 0 indicating no bits
566          * set.  It may also return a bit number greater than TAGID_MAX due
567          * to rounding of the number of bits in the vector up to a multiple
568          * of the vector word size at declaration/allocation time.
569          */
570         if ((new_tagid == 0) || (new_tagid > TAGID_MAX))
571                 return (0);
572
573         /* Mark the tag as in use.  Bits are 0-based for BIT_CLR() */
574         BIT_CLR(TAGID_MAX, new_tagid - 1, &ts->avail);
575
576         /* allocate and fill new struct pf_tagname */
577         tag = uma_zalloc(V_pf_tag_z, M_NOWAIT);
578         if (tag == NULL)
579                 return (0);
580         strlcpy(tag->name, tagname, sizeof(tag->name));
581         tag->tag = new_tagid;
582         tag->ref = 1;
583
584         /* Insert into namehash */
585         TAILQ_INSERT_TAIL(&ts->namehash[index], tag, namehash_entries);
586
587         /* Insert into taghash */
588         index = tag2hashindex(ts, new_tagid);
589         TAILQ_INSERT_TAIL(&ts->taghash[index], tag, taghash_entries);
590
591         return (tag->tag);
592 }
593
594 static void
595 tag_unref(struct pf_tagset *ts, u_int16_t tag)
596 {
597         struct pf_tagname       *t;
598         uint16_t                 index;
599
600         PF_RULES_WASSERT();
601
602         index = tag2hashindex(ts, tag);
603         TAILQ_FOREACH(t, &ts->taghash[index], taghash_entries)
604                 if (tag == t->tag) {
605                         if (--t->ref == 0) {
606                                 TAILQ_REMOVE(&ts->taghash[index], t,
607                                     taghash_entries);
608                                 index = tagname2hashindex(ts, t->name);
609                                 TAILQ_REMOVE(&ts->namehash[index], t,
610                                     namehash_entries);
611                                 /* Bits are 0-based for BIT_SET() */
612                                 BIT_SET(TAGID_MAX, tag - 1, &ts->avail);
613                                 uma_zfree(V_pf_tag_z, t);
614                         }
615                         break;
616                 }
617 }
618
619 static u_int16_t
620 pf_tagname2tag(char *tagname)
621 {
622         return (tagname2tag(&V_pf_tags, tagname));
623 }
624
625 #ifdef ALTQ
626 static u_int32_t
627 pf_qname2qid(char *qname)
628 {
629         return ((u_int32_t)tagname2tag(&V_pf_qids, qname));
630 }
631
632 static void
633 pf_qid_unref(u_int32_t qid)
634 {
635         tag_unref(&V_pf_qids, (u_int16_t)qid);
636 }
637
638 static int
639 pf_begin_altq(u_int32_t *ticket)
640 {
641         struct pf_altq  *altq, *tmp;
642         int              error = 0;
643
644         PF_RULES_WASSERT();
645
646         /* Purge the old altq lists */
647         TAILQ_FOREACH_SAFE(altq, V_pf_altq_ifs_inactive, entries, tmp) {
648                 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
649                         /* detach and destroy the discipline */
650                         error = altq_remove(altq);
651                 }
652                 free(altq, M_PFALTQ);
653         }
654         TAILQ_INIT(V_pf_altq_ifs_inactive);
655         TAILQ_FOREACH_SAFE(altq, V_pf_altqs_inactive, entries, tmp) {
656                 pf_qid_unref(altq->qid);
657                 free(altq, M_PFALTQ);
658         }
659         TAILQ_INIT(V_pf_altqs_inactive);
660         if (error)
661                 return (error);
662         *ticket = ++V_ticket_altqs_inactive;
663         V_altqs_inactive_open = 1;
664         return (0);
665 }
666
667 static int
668 pf_rollback_altq(u_int32_t ticket)
669 {
670         struct pf_altq  *altq, *tmp;
671         int              error = 0;
672
673         PF_RULES_WASSERT();
674
675         if (!V_altqs_inactive_open || ticket != V_ticket_altqs_inactive)
676                 return (0);
677         /* Purge the old altq lists */
678         TAILQ_FOREACH_SAFE(altq, V_pf_altq_ifs_inactive, entries, tmp) {
679                 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
680                         /* detach and destroy the discipline */
681                         error = altq_remove(altq);
682                 }
683                 free(altq, M_PFALTQ);
684         }
685         TAILQ_INIT(V_pf_altq_ifs_inactive);
686         TAILQ_FOREACH_SAFE(altq, V_pf_altqs_inactive, entries, tmp) {
687                 pf_qid_unref(altq->qid);
688                 free(altq, M_PFALTQ);
689         }
690         TAILQ_INIT(V_pf_altqs_inactive);
691         V_altqs_inactive_open = 0;
692         return (error);
693 }
694
695 static int
696 pf_commit_altq(u_int32_t ticket)
697 {
698         struct pf_altqqueue     *old_altqs, *old_altq_ifs;
699         struct pf_altq          *altq, *tmp;
700         int                      err, error = 0;
701
702         PF_RULES_WASSERT();
703
704         if (!V_altqs_inactive_open || ticket != V_ticket_altqs_inactive)
705                 return (EBUSY);
706
707         /* swap altqs, keep the old. */
708         old_altqs = V_pf_altqs_active;
709         old_altq_ifs = V_pf_altq_ifs_active;
710         V_pf_altqs_active = V_pf_altqs_inactive;
711         V_pf_altq_ifs_active = V_pf_altq_ifs_inactive;
712         V_pf_altqs_inactive = old_altqs;
713         V_pf_altq_ifs_inactive = old_altq_ifs;
714         V_ticket_altqs_active = V_ticket_altqs_inactive;
715
716         /* Attach new disciplines */
717         TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) {
718                 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
719                         /* attach the discipline */
720                         error = altq_pfattach(altq);
721                         if (error == 0 && V_pf_altq_running)
722                                 error = pf_enable_altq(altq);
723                         if (error != 0)
724                                 return (error);
725                 }
726         }
727
728         /* Purge the old altq lists */
729         TAILQ_FOREACH_SAFE(altq, V_pf_altq_ifs_inactive, entries, tmp) {
730                 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
731                         /* detach and destroy the discipline */
732                         if (V_pf_altq_running)
733                                 error = pf_disable_altq(altq);
734                         err = altq_pfdetach(altq);
735                         if (err != 0 && error == 0)
736                                 error = err;
737                         err = altq_remove(altq);
738                         if (err != 0 && error == 0)
739                                 error = err;
740                 }
741                 free(altq, M_PFALTQ);
742         }
743         TAILQ_INIT(V_pf_altq_ifs_inactive);
744         TAILQ_FOREACH_SAFE(altq, V_pf_altqs_inactive, entries, tmp) {
745                 pf_qid_unref(altq->qid);
746                 free(altq, M_PFALTQ);
747         }
748         TAILQ_INIT(V_pf_altqs_inactive);
749
750         V_altqs_inactive_open = 0;
751         return (error);
752 }
753
754 static int
755 pf_enable_altq(struct pf_altq *altq)
756 {
757         struct ifnet            *ifp;
758         struct tb_profile        tb;
759         int                      error = 0;
760
761         if ((ifp = ifunit(altq->ifname)) == NULL)
762                 return (EINVAL);
763
764         if (ifp->if_snd.altq_type != ALTQT_NONE)
765                 error = altq_enable(&ifp->if_snd);
766
767         /* set tokenbucket regulator */
768         if (error == 0 && ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
769                 tb.rate = altq->ifbandwidth;
770                 tb.depth = altq->tbrsize;
771                 error = tbr_set(&ifp->if_snd, &tb);
772         }
773
774         return (error);
775 }
776
777 static int
778 pf_disable_altq(struct pf_altq *altq)
779 {
780         struct ifnet            *ifp;
781         struct tb_profile        tb;
782         int                      error;
783
784         if ((ifp = ifunit(altq->ifname)) == NULL)
785                 return (EINVAL);
786
787         /*
788          * when the discipline is no longer referenced, it was overridden
789          * by a new one.  if so, just return.
790          */
791         if (altq->altq_disc != ifp->if_snd.altq_disc)
792                 return (0);
793
794         error = altq_disable(&ifp->if_snd);
795
796         if (error == 0) {
797                 /* clear tokenbucket regulator */
798                 tb.rate = 0;
799                 error = tbr_set(&ifp->if_snd, &tb);
800         }
801
802         return (error);
803 }
804
805 static int
806 pf_altq_ifnet_event_add(struct ifnet *ifp, int remove, u_int32_t ticket,
807     struct pf_altq *altq)
808 {
809         struct ifnet    *ifp1;
810         int              error = 0;
811
812         /* Deactivate the interface in question */
813         altq->local_flags &= ~PFALTQ_FLAG_IF_REMOVED;
814         if ((ifp1 = ifunit(altq->ifname)) == NULL ||
815             (remove && ifp1 == ifp)) {
816                 altq->local_flags |= PFALTQ_FLAG_IF_REMOVED;
817         } else {
818                 error = altq_add(ifp1, altq);
819
820                 if (ticket != V_ticket_altqs_inactive)
821                         error = EBUSY;
822
823                 if (error)
824                         free(altq, M_PFALTQ);
825         }
826
827         return (error);
828 }
829
830 void
831 pf_altq_ifnet_event(struct ifnet *ifp, int remove)
832 {
833         struct pf_altq  *a1, *a2, *a3;
834         u_int32_t        ticket;
835         int              error = 0;
836
837         /*
838          * No need to re-evaluate the configuration for events on interfaces
839          * that do not support ALTQ, as it's not possible for such
840          * interfaces to be part of the configuration.
841          */
842         if (!ALTQ_IS_READY(&ifp->if_snd))
843                 return;
844
845         /* Interrupt userland queue modifications */
846         if (V_altqs_inactive_open)
847                 pf_rollback_altq(V_ticket_altqs_inactive);
848
849         /* Start new altq ruleset */
850         if (pf_begin_altq(&ticket))
851                 return;
852
853         /* Copy the current active set */
854         TAILQ_FOREACH(a1, V_pf_altq_ifs_active, entries) {
855                 a2 = malloc(sizeof(*a2), M_PFALTQ, M_NOWAIT);
856                 if (a2 == NULL) {
857                         error = ENOMEM;
858                         break;
859                 }
860                 bcopy(a1, a2, sizeof(struct pf_altq));
861
862                 error = pf_altq_ifnet_event_add(ifp, remove, ticket, a2);
863                 if (error)
864                         break;
865
866                 TAILQ_INSERT_TAIL(V_pf_altq_ifs_inactive, a2, entries);
867         }
868         if (error)
869                 goto out;
870         TAILQ_FOREACH(a1, V_pf_altqs_active, entries) {
871                 a2 = malloc(sizeof(*a2), M_PFALTQ, M_NOWAIT);
872                 if (a2 == NULL) {
873                         error = ENOMEM;
874                         break;
875                 }
876                 bcopy(a1, a2, sizeof(struct pf_altq));
877
878                 if ((a2->qid = pf_qname2qid(a2->qname)) == 0) {
879                         error = EBUSY;
880                         free(a2, M_PFALTQ);
881                         break;
882                 }
883                 a2->altq_disc = NULL;
884                 TAILQ_FOREACH(a3, V_pf_altq_ifs_inactive, entries) {
885                         if (strncmp(a3->ifname, a2->ifname,
886                                 IFNAMSIZ) == 0) {
887                                 a2->altq_disc = a3->altq_disc;
888                                 break;
889                         }
890                 }
891                 error = pf_altq_ifnet_event_add(ifp, remove, ticket, a2);
892                 if (error)
893                         break;
894
895                 TAILQ_INSERT_TAIL(V_pf_altqs_inactive, a2, entries);
896         }
897
898 out:
899         if (error != 0)
900                 pf_rollback_altq(ticket);
901         else
902                 pf_commit_altq(ticket);
903 }
904 #endif /* ALTQ */
905
906 static int
907 pf_begin_rules(u_int32_t *ticket, int rs_num, const char *anchor)
908 {
909         struct pf_kruleset      *rs;
910         struct pf_krule         *rule;
911
912         PF_RULES_WASSERT();
913
914         if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
915                 return (EINVAL);
916         rs = pf_find_or_create_kruleset(anchor);
917         if (rs == NULL)
918                 return (EINVAL);
919         while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL) {
920                 pf_unlink_rule(rs->rules[rs_num].inactive.ptr, rule);
921                 rs->rules[rs_num].inactive.rcount--;
922         }
923         *ticket = ++rs->rules[rs_num].inactive.ticket;
924         rs->rules[rs_num].inactive.open = 1;
925         return (0);
926 }
927
928 static int
929 pf_rollback_rules(u_int32_t ticket, int rs_num, char *anchor)
930 {
931         struct pf_kruleset      *rs;
932         struct pf_krule         *rule;
933
934         PF_RULES_WASSERT();
935
936         if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
937                 return (EINVAL);
938         rs = pf_find_kruleset(anchor);
939         if (rs == NULL || !rs->rules[rs_num].inactive.open ||
940             rs->rules[rs_num].inactive.ticket != ticket)
941                 return (0);
942         while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL) {
943                 pf_unlink_rule(rs->rules[rs_num].inactive.ptr, rule);
944                 rs->rules[rs_num].inactive.rcount--;
945         }
946         rs->rules[rs_num].inactive.open = 0;
947         return (0);
948 }
949
950 #define PF_MD5_UPD(st, elm)                                             \
951                 MD5Update(ctx, (u_int8_t *) &(st)->elm, sizeof((st)->elm))
952
953 #define PF_MD5_UPD_STR(st, elm)                                         \
954                 MD5Update(ctx, (u_int8_t *) (st)->elm, strlen((st)->elm))
955
956 #define PF_MD5_UPD_HTONL(st, elm, stor) do {                            \
957                 (stor) = htonl((st)->elm);                              \
958                 MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int32_t));\
959 } while (0)
960
961 #define PF_MD5_UPD_HTONS(st, elm, stor) do {                            \
962                 (stor) = htons((st)->elm);                              \
963                 MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int16_t));\
964 } while (0)
965
966 static void
967 pf_hash_rule_addr(MD5_CTX *ctx, struct pf_rule_addr *pfr)
968 {
969         PF_MD5_UPD(pfr, addr.type);
970         switch (pfr->addr.type) {
971                 case PF_ADDR_DYNIFTL:
972                         PF_MD5_UPD(pfr, addr.v.ifname);
973                         PF_MD5_UPD(pfr, addr.iflags);
974                         break;
975                 case PF_ADDR_TABLE:
976                         PF_MD5_UPD(pfr, addr.v.tblname);
977                         break;
978                 case PF_ADDR_ADDRMASK:
979                         /* XXX ignore af? */
980                         PF_MD5_UPD(pfr, addr.v.a.addr.addr32);
981                         PF_MD5_UPD(pfr, addr.v.a.mask.addr32);
982                         break;
983         }
984
985         PF_MD5_UPD(pfr, port[0]);
986         PF_MD5_UPD(pfr, port[1]);
987         PF_MD5_UPD(pfr, neg);
988         PF_MD5_UPD(pfr, port_op);
989 }
990
991 static void
992 pf_hash_rule(MD5_CTX *ctx, struct pf_krule *rule)
993 {
994         u_int16_t x;
995         u_int32_t y;
996
997         pf_hash_rule_addr(ctx, &rule->src);
998         pf_hash_rule_addr(ctx, &rule->dst);
999         PF_MD5_UPD_STR(rule, label);
1000         PF_MD5_UPD_STR(rule, ifname);
1001         PF_MD5_UPD_STR(rule, match_tagname);
1002         PF_MD5_UPD_HTONS(rule, match_tag, x); /* dup? */
1003         PF_MD5_UPD_HTONL(rule, os_fingerprint, y);
1004         PF_MD5_UPD_HTONL(rule, prob, y);
1005         PF_MD5_UPD_HTONL(rule, uid.uid[0], y);
1006         PF_MD5_UPD_HTONL(rule, uid.uid[1], y);
1007         PF_MD5_UPD(rule, uid.op);
1008         PF_MD5_UPD_HTONL(rule, gid.gid[0], y);
1009         PF_MD5_UPD_HTONL(rule, gid.gid[1], y);
1010         PF_MD5_UPD(rule, gid.op);
1011         PF_MD5_UPD_HTONL(rule, rule_flag, y);
1012         PF_MD5_UPD(rule, action);
1013         PF_MD5_UPD(rule, direction);
1014         PF_MD5_UPD(rule, af);
1015         PF_MD5_UPD(rule, quick);
1016         PF_MD5_UPD(rule, ifnot);
1017         PF_MD5_UPD(rule, match_tag_not);
1018         PF_MD5_UPD(rule, natpass);
1019         PF_MD5_UPD(rule, keep_state);
1020         PF_MD5_UPD(rule, proto);
1021         PF_MD5_UPD(rule, type);
1022         PF_MD5_UPD(rule, code);
1023         PF_MD5_UPD(rule, flags);
1024         PF_MD5_UPD(rule, flagset);
1025         PF_MD5_UPD(rule, allow_opts);
1026         PF_MD5_UPD(rule, rt);
1027         PF_MD5_UPD(rule, tos);
1028 }
1029
1030 static int
1031 pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
1032 {
1033         struct pf_kruleset      *rs;
1034         struct pf_krule         *rule, **old_array;
1035         struct pf_krulequeue    *old_rules;
1036         int                      error;
1037         u_int32_t                old_rcount;
1038
1039         PF_RULES_WASSERT();
1040
1041         if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
1042                 return (EINVAL);
1043         rs = pf_find_kruleset(anchor);
1044         if (rs == NULL || !rs->rules[rs_num].inactive.open ||
1045             ticket != rs->rules[rs_num].inactive.ticket)
1046                 return (EBUSY);
1047
1048         /* Calculate checksum for the main ruleset */
1049         if (rs == &pf_main_ruleset) {
1050                 error = pf_setup_pfsync_matching(rs);
1051                 if (error != 0)
1052                         return (error);
1053         }
1054
1055         /* Swap rules, keep the old. */
1056         old_rules = rs->rules[rs_num].active.ptr;
1057         old_rcount = rs->rules[rs_num].active.rcount;
1058         old_array = rs->rules[rs_num].active.ptr_array;
1059
1060         rs->rules[rs_num].active.ptr =
1061             rs->rules[rs_num].inactive.ptr;
1062         rs->rules[rs_num].active.ptr_array =
1063             rs->rules[rs_num].inactive.ptr_array;
1064         rs->rules[rs_num].active.rcount =
1065             rs->rules[rs_num].inactive.rcount;
1066         rs->rules[rs_num].inactive.ptr = old_rules;
1067         rs->rules[rs_num].inactive.ptr_array = old_array;
1068         rs->rules[rs_num].inactive.rcount = old_rcount;
1069
1070         rs->rules[rs_num].active.ticket =
1071             rs->rules[rs_num].inactive.ticket;
1072         pf_calc_skip_steps(rs->rules[rs_num].active.ptr);
1073
1074         /* Purge the old rule list. */
1075         while ((rule = TAILQ_FIRST(old_rules)) != NULL)
1076                 pf_unlink_rule(old_rules, rule);
1077         if (rs->rules[rs_num].inactive.ptr_array)
1078                 free(rs->rules[rs_num].inactive.ptr_array, M_TEMP);
1079         rs->rules[rs_num].inactive.ptr_array = NULL;
1080         rs->rules[rs_num].inactive.rcount = 0;
1081         rs->rules[rs_num].inactive.open = 0;
1082         pf_remove_if_empty_kruleset(rs);
1083
1084         return (0);
1085 }
1086
1087 static int
1088 pf_setup_pfsync_matching(struct pf_kruleset *rs)
1089 {
1090         MD5_CTX                  ctx;
1091         struct pf_krule         *rule;
1092         int                      rs_cnt;
1093         u_int8_t                 digest[PF_MD5_DIGEST_LENGTH];
1094
1095         MD5Init(&ctx);
1096         for (rs_cnt = 0; rs_cnt < PF_RULESET_MAX; rs_cnt++) {
1097                 /* XXX PF_RULESET_SCRUB as well? */
1098                 if (rs_cnt == PF_RULESET_SCRUB)
1099                         continue;
1100
1101                 if (rs->rules[rs_cnt].inactive.ptr_array)
1102                         free(rs->rules[rs_cnt].inactive.ptr_array, M_TEMP);
1103                 rs->rules[rs_cnt].inactive.ptr_array = NULL;
1104
1105                 if (rs->rules[rs_cnt].inactive.rcount) {
1106                         rs->rules[rs_cnt].inactive.ptr_array =
1107                             malloc(sizeof(caddr_t) *
1108                             rs->rules[rs_cnt].inactive.rcount,
1109                             M_TEMP, M_NOWAIT);
1110
1111                         if (!rs->rules[rs_cnt].inactive.ptr_array)
1112                                 return (ENOMEM);
1113                 }
1114
1115                 TAILQ_FOREACH(rule, rs->rules[rs_cnt].inactive.ptr,
1116                     entries) {
1117                         pf_hash_rule(&ctx, rule);
1118                         (rs->rules[rs_cnt].inactive.ptr_array)[rule->nr] = rule;
1119                 }
1120         }
1121
1122         MD5Final(digest, &ctx);
1123         memcpy(V_pf_status.pf_chksum, digest, sizeof(V_pf_status.pf_chksum));
1124         return (0);
1125 }
1126
1127 static int
1128 pf_addr_setup(struct pf_kruleset *ruleset, struct pf_addr_wrap *addr,
1129     sa_family_t af)
1130 {
1131         int error = 0;
1132
1133         switch (addr->type) {
1134         case PF_ADDR_TABLE:
1135                 addr->p.tbl = pfr_attach_table(ruleset, addr->v.tblname);
1136                 if (addr->p.tbl == NULL)
1137                         error = ENOMEM;
1138                 break;
1139         case PF_ADDR_DYNIFTL:
1140                 error = pfi_dynaddr_setup(addr, af);
1141                 break;
1142         }
1143
1144         return (error);
1145 }
1146
1147 static void
1148 pf_addr_copyout(struct pf_addr_wrap *addr)
1149 {
1150
1151         switch (addr->type) {
1152         case PF_ADDR_DYNIFTL:
1153                 pfi_dynaddr_copyout(addr);
1154                 break;
1155         case PF_ADDR_TABLE:
1156                 pf_tbladdr_copyout(addr);
1157                 break;
1158         }
1159 }
1160
1161 static void
1162 pf_src_node_copy(const struct pf_ksrc_node *in, struct pf_src_node *out)
1163 {
1164         int     secs = time_uptime, diff;
1165
1166         bzero(out, sizeof(struct pf_src_node));
1167
1168         bcopy(&in->addr, &out->addr, sizeof(struct pf_addr));
1169         bcopy(&in->raddr, &out->raddr, sizeof(struct pf_addr));
1170
1171         if (in->rule.ptr != NULL)
1172                 out->rule.nr = in->rule.ptr->nr;
1173
1174         for (int i = 0; i < 2; i++) {
1175                 out->bytes[i] = counter_u64_fetch(in->bytes[i]);
1176                 out->packets[i] = counter_u64_fetch(in->packets[i]);
1177         }
1178
1179         out->states = in->states;
1180         out->conn = in->conn;
1181         out->af = in->af;
1182         out->ruletype = in->ruletype;
1183
1184         out->creation = secs - in->creation;
1185         if (out->expire > secs)
1186                 out->expire -= secs;
1187         else
1188                 out->expire = 0;
1189
1190         /* Adjust the connection rate estimate. */
1191         diff = secs - in->conn_rate.last;
1192         if (diff >= in->conn_rate.seconds)
1193                 out->conn_rate.count = 0;
1194         else
1195                 out->conn_rate.count -=
1196                     in->conn_rate.count * diff /
1197                     in->conn_rate.seconds;
1198 }
1199
1200 #ifdef ALTQ
1201 /*
1202  * Handle export of struct pf_kaltq to user binaries that may be using any
1203  * version of struct pf_altq.
1204  */
1205 static int
1206 pf_export_kaltq(struct pf_altq *q, struct pfioc_altq_v1 *pa, size_t ioc_size)
1207 {
1208         u_int32_t version;
1209
1210         if (ioc_size == sizeof(struct pfioc_altq_v0))
1211                 version = 0;
1212         else
1213                 version = pa->version;
1214
1215         if (version > PFIOC_ALTQ_VERSION)
1216                 return (EINVAL);
1217
1218 #define ASSIGN(x) exported_q->x = q->x
1219 #define COPY(x) \
1220         bcopy(&q->x, &exported_q->x, min(sizeof(q->x), sizeof(exported_q->x)))
1221 #define SATU16(x) (u_int32_t)uqmin((x), USHRT_MAX)
1222 #define SATU32(x) (u_int32_t)uqmin((x), UINT_MAX)
1223
1224         switch (version) {
1225         case 0: {
1226                 struct pf_altq_v0 *exported_q =
1227                     &((struct pfioc_altq_v0 *)pa)->altq;
1228
1229                 COPY(ifname);
1230
1231                 ASSIGN(scheduler);
1232                 ASSIGN(tbrsize);
1233                 exported_q->tbrsize = SATU16(q->tbrsize);
1234                 exported_q->ifbandwidth = SATU32(q->ifbandwidth);
1235
1236                 COPY(qname);
1237                 COPY(parent);
1238                 ASSIGN(parent_qid);
1239                 exported_q->bandwidth = SATU32(q->bandwidth);
1240                 ASSIGN(priority);
1241                 ASSIGN(local_flags);
1242
1243                 ASSIGN(qlimit);
1244                 ASSIGN(flags);
1245
1246                 if (q->scheduler == ALTQT_HFSC) {
1247 #define ASSIGN_OPT(x) exported_q->pq_u.hfsc_opts.x = q->pq_u.hfsc_opts.x
1248 #define ASSIGN_OPT_SATU32(x) exported_q->pq_u.hfsc_opts.x = \
1249                             SATU32(q->pq_u.hfsc_opts.x)
1250                         
1251                         ASSIGN_OPT_SATU32(rtsc_m1);
1252                         ASSIGN_OPT(rtsc_d);
1253                         ASSIGN_OPT_SATU32(rtsc_m2);
1254
1255                         ASSIGN_OPT_SATU32(lssc_m1);
1256                         ASSIGN_OPT(lssc_d);
1257                         ASSIGN_OPT_SATU32(lssc_m2);
1258
1259                         ASSIGN_OPT_SATU32(ulsc_m1);
1260                         ASSIGN_OPT(ulsc_d);
1261                         ASSIGN_OPT_SATU32(ulsc_m2);
1262
1263                         ASSIGN_OPT(flags);
1264                         
1265 #undef ASSIGN_OPT
1266 #undef ASSIGN_OPT_SATU32
1267                 } else
1268                         COPY(pq_u);
1269
1270                 ASSIGN(qid);
1271                 break;
1272         }
1273         case 1: {
1274                 struct pf_altq_v1 *exported_q =
1275                     &((struct pfioc_altq_v1 *)pa)->altq;
1276
1277                 COPY(ifname);
1278
1279                 ASSIGN(scheduler);
1280                 ASSIGN(tbrsize);
1281                 ASSIGN(ifbandwidth);
1282
1283                 COPY(qname);
1284                 COPY(parent);
1285                 ASSIGN(parent_qid);
1286                 ASSIGN(bandwidth);
1287                 ASSIGN(priority);
1288                 ASSIGN(local_flags);
1289
1290                 ASSIGN(qlimit);
1291                 ASSIGN(flags);
1292                 COPY(pq_u);
1293
1294                 ASSIGN(qid);
1295                 break;
1296         }
1297         default:
1298                 panic("%s: unhandled struct pfioc_altq version", __func__);
1299                 break;
1300         }
1301
1302 #undef ASSIGN
1303 #undef COPY
1304 #undef SATU16
1305 #undef SATU32
1306
1307         return (0);
1308 }
1309
1310 /*
1311  * Handle import to struct pf_kaltq of struct pf_altq from user binaries
1312  * that may be using any version of it.
1313  */
1314 static int
1315 pf_import_kaltq(struct pfioc_altq_v1 *pa, struct pf_altq *q, size_t ioc_size)
1316 {
1317         u_int32_t version;
1318
1319         if (ioc_size == sizeof(struct pfioc_altq_v0))
1320                 version = 0;
1321         else
1322                 version = pa->version;
1323
1324         if (version > PFIOC_ALTQ_VERSION)
1325                 return (EINVAL);
1326
1327 #define ASSIGN(x) q->x = imported_q->x
1328 #define COPY(x) \
1329         bcopy(&imported_q->x, &q->x, min(sizeof(imported_q->x), sizeof(q->x)))
1330
1331         switch (version) {
1332         case 0: {
1333                 struct pf_altq_v0 *imported_q =
1334                     &((struct pfioc_altq_v0 *)pa)->altq;
1335
1336                 COPY(ifname);
1337
1338                 ASSIGN(scheduler);
1339                 ASSIGN(tbrsize); /* 16-bit -> 32-bit */
1340                 ASSIGN(ifbandwidth); /* 32-bit -> 64-bit */
1341
1342                 COPY(qname);
1343                 COPY(parent);
1344                 ASSIGN(parent_qid);
1345                 ASSIGN(bandwidth); /* 32-bit -> 64-bit */
1346                 ASSIGN(priority);
1347                 ASSIGN(local_flags);
1348
1349                 ASSIGN(qlimit);
1350                 ASSIGN(flags);
1351
1352                 if (imported_q->scheduler == ALTQT_HFSC) {
1353 #define ASSIGN_OPT(x) q->pq_u.hfsc_opts.x = imported_q->pq_u.hfsc_opts.x
1354
1355                         /*
1356                          * The m1 and m2 parameters are being copied from
1357                          * 32-bit to 64-bit.
1358                          */
1359                         ASSIGN_OPT(rtsc_m1);
1360                         ASSIGN_OPT(rtsc_d);
1361                         ASSIGN_OPT(rtsc_m2);
1362
1363                         ASSIGN_OPT(lssc_m1);
1364                         ASSIGN_OPT(lssc_d);
1365                         ASSIGN_OPT(lssc_m2);
1366
1367                         ASSIGN_OPT(ulsc_m1);
1368                         ASSIGN_OPT(ulsc_d);
1369                         ASSIGN_OPT(ulsc_m2);
1370
1371                         ASSIGN_OPT(flags);
1372                         
1373 #undef ASSIGN_OPT
1374                 } else
1375                         COPY(pq_u);
1376
1377                 ASSIGN(qid);
1378                 break;
1379         }
1380         case 1: {
1381                 struct pf_altq_v1 *imported_q =
1382                     &((struct pfioc_altq_v1 *)pa)->altq;
1383
1384                 COPY(ifname);
1385
1386                 ASSIGN(scheduler);
1387                 ASSIGN(tbrsize);
1388                 ASSIGN(ifbandwidth);
1389
1390                 COPY(qname);
1391                 COPY(parent);
1392                 ASSIGN(parent_qid);
1393                 ASSIGN(bandwidth);
1394                 ASSIGN(priority);
1395                 ASSIGN(local_flags);
1396
1397                 ASSIGN(qlimit);
1398                 ASSIGN(flags);
1399                 COPY(pq_u);
1400
1401                 ASSIGN(qid);
1402                 break;
1403         }
1404         default:        
1405                 panic("%s: unhandled struct pfioc_altq version", __func__);
1406                 break;
1407         }
1408
1409 #undef ASSIGN
1410 #undef COPY
1411
1412         return (0);
1413 }
1414
1415 static struct pf_altq *
1416 pf_altq_get_nth_active(u_int32_t n)
1417 {
1418         struct pf_altq          *altq;
1419         u_int32_t                nr;
1420
1421         nr = 0;
1422         TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) {
1423                 if (nr == n)
1424                         return (altq);
1425                 nr++;
1426         }
1427
1428         TAILQ_FOREACH(altq, V_pf_altqs_active, entries) {
1429                 if (nr == n)
1430                         return (altq);
1431                 nr++;
1432         }
1433
1434         return (NULL);
1435 }
1436 #endif /* ALTQ */
1437
1438 static void
1439 pf_kpooladdr_to_pooladdr(const struct pf_kpooladdr *kpool,
1440     struct pf_pooladdr *pool)
1441 {
1442
1443         bzero(pool, sizeof(*pool));
1444         bcopy(&kpool->addr, &pool->addr, sizeof(pool->addr));
1445         strlcpy(pool->ifname, kpool->ifname, sizeof(pool->ifname));
1446 }
1447
1448 static void
1449 pf_pooladdr_to_kpooladdr(const struct pf_pooladdr *pool,
1450     struct pf_kpooladdr *kpool)
1451 {
1452
1453         bzero(kpool, sizeof(*kpool));
1454         bcopy(&pool->addr, &kpool->addr, sizeof(kpool->addr));
1455         strlcpy(kpool->ifname, pool->ifname, sizeof(kpool->ifname));
1456 }
1457
1458 static void
1459 pf_krule_to_rule(const struct pf_krule *krule, struct pf_rule *rule)
1460 {
1461
1462         bzero(rule, sizeof(*rule));
1463
1464         bcopy(&krule->src, &rule->src, sizeof(rule->src));
1465         bcopy(&krule->dst, &rule->dst, sizeof(rule->dst));
1466
1467         for (int i = 0; i < PF_SKIP_COUNT; ++i) {
1468                 if (rule->skip[i].ptr == NULL)
1469                         rule->skip[i].nr = -1;
1470                 else
1471                         rule->skip[i].nr = krule->skip[i].ptr->nr;
1472         }
1473
1474         strlcpy(rule->label, krule->label, sizeof(rule->label));
1475         strlcpy(rule->ifname, krule->ifname, sizeof(rule->ifname));
1476         strlcpy(rule->qname, krule->qname, sizeof(rule->qname));
1477         strlcpy(rule->pqname, krule->pqname, sizeof(rule->pqname));
1478         strlcpy(rule->tagname, krule->tagname, sizeof(rule->tagname));
1479         strlcpy(rule->match_tagname, krule->match_tagname,
1480             sizeof(rule->match_tagname));
1481         strlcpy(rule->overload_tblname, krule->overload_tblname,
1482             sizeof(rule->overload_tblname));
1483
1484         bcopy(&krule->rpool, &rule->rpool, sizeof(krule->rpool));
1485
1486         rule->evaluations = counter_u64_fetch(krule->evaluations);
1487         for (int i = 0; i < 2; i++) {
1488                 rule->packets[i] = counter_u64_fetch(krule->packets[i]);
1489                 rule->bytes[i] = counter_u64_fetch(krule->bytes[i]);
1490         }
1491
1492         /* kif, anchor, overload_tbl are not copied over. */
1493
1494         rule->os_fingerprint = krule->os_fingerprint;
1495
1496         rule->rtableid = krule->rtableid;
1497         bcopy(krule->timeout, rule->timeout, sizeof(krule->timeout));
1498         rule->max_states = krule->max_states;
1499         rule->max_src_nodes = krule->max_src_nodes;
1500         rule->max_src_states = krule->max_src_states;
1501         rule->max_src_conn = krule->max_src_conn;
1502         rule->max_src_conn_rate.limit = krule->max_src_conn_rate.limit;
1503         rule->max_src_conn_rate.seconds = krule->max_src_conn_rate.seconds;
1504         rule->qid = krule->qid;
1505         rule->pqid = krule->pqid;
1506         rule->rt_listid = krule->rt_listid;
1507         rule->nr = krule->nr;
1508         rule->prob = krule->prob;
1509         rule->cuid = krule->cuid;
1510         rule->cpid = krule->cpid;
1511
1512         rule->return_icmp = krule->return_icmp;
1513         rule->return_icmp6 = krule->return_icmp6;
1514         rule->max_mss = krule->max_mss;
1515         rule->tag = krule->tag;
1516         rule->match_tag = krule->match_tag;
1517         rule->scrub_flags = krule->scrub_flags;
1518
1519         bcopy(&krule->uid, &rule->uid, sizeof(krule->uid));
1520         bcopy(&krule->gid, &rule->gid, sizeof(krule->gid));
1521
1522         rule->rule_flag = krule->rule_flag;
1523         rule->action = krule->action;
1524         rule->direction = krule->direction;
1525         rule->log = krule->log;
1526         rule->logif = krule->logif;
1527         rule->quick = krule->quick;
1528         rule->ifnot = krule->ifnot;
1529         rule->match_tag_not = krule->match_tag_not;
1530         rule->natpass = krule->natpass;
1531
1532         rule->keep_state = krule->keep_state;
1533         rule->af = krule->af;
1534         rule->proto = krule->proto;
1535         rule->type = krule->type;
1536         rule->code = krule->code;
1537         rule->flags = krule->flags;
1538         rule->flagset = krule->flagset;
1539         rule->min_ttl = krule->min_ttl;
1540         rule->allow_opts = krule->allow_opts;
1541         rule->rt = krule->rt;
1542         rule->return_ttl = krule->return_ttl;
1543         rule->tos = krule->tos;
1544         rule->set_tos = krule->set_tos;
1545         rule->anchor_relative = krule->anchor_relative;
1546         rule->anchor_wildcard = krule->anchor_wildcard;
1547
1548         rule->flush = krule->flush;
1549         rule->prio = krule->prio;
1550         rule->set_prio[0] = krule->set_prio[0];
1551         rule->set_prio[1] = krule->set_prio[1];
1552
1553         bcopy(&krule->divert, &rule->divert, sizeof(krule->divert));
1554
1555         rule->u_states_cur = counter_u64_fetch(krule->states_cur);
1556         rule->u_states_tot = counter_u64_fetch(krule->states_tot);
1557         rule->u_src_nodes = counter_u64_fetch(krule->src_nodes);
1558 }
1559
1560 static int
1561 pf_check_rule_addr(const struct pf_rule_addr *addr)
1562 {
1563
1564         switch (addr->addr.type) {
1565         case PF_ADDR_ADDRMASK:
1566         case PF_ADDR_NOROUTE:
1567         case PF_ADDR_DYNIFTL:
1568         case PF_ADDR_TABLE:
1569         case PF_ADDR_URPFFAILED:
1570         case PF_ADDR_RANGE:
1571                 break;
1572         default:
1573                 return (EINVAL);
1574         }
1575
1576         if (addr->addr.p.dyn != NULL) {
1577                 return (EINVAL);
1578         }
1579
1580         return (0);
1581 }
1582
1583 static int
1584 pf_rule_to_krule(const struct pf_rule *rule, struct pf_krule *krule)
1585 {
1586         int ret;
1587
1588 #ifndef INET
1589         if (rule->af == AF_INET) {
1590                 return (EAFNOSUPPORT);
1591         }
1592 #endif /* INET */
1593 #ifndef INET6
1594         if (rule->af == AF_INET6) {
1595                 return (EAFNOSUPPORT);
1596         }
1597 #endif /* INET6 */
1598
1599         ret = pf_check_rule_addr(&rule->src);
1600         if (ret != 0)
1601                 return (ret);
1602         ret = pf_check_rule_addr(&rule->dst);
1603         if (ret != 0)
1604                 return (ret);
1605
1606         bzero(krule, sizeof(*krule));
1607
1608         bcopy(&rule->src, &krule->src, sizeof(rule->src));
1609         bcopy(&rule->dst, &krule->dst, sizeof(rule->dst));
1610
1611         strlcpy(krule->label, rule->label, sizeof(rule->label));
1612         strlcpy(krule->ifname, rule->ifname, sizeof(rule->ifname));
1613         strlcpy(krule->qname, rule->qname, sizeof(rule->qname));
1614         strlcpy(krule->pqname, rule->pqname, sizeof(rule->pqname));
1615         strlcpy(krule->tagname, rule->tagname, sizeof(rule->tagname));
1616         strlcpy(krule->match_tagname, rule->match_tagname,
1617             sizeof(rule->match_tagname));
1618         strlcpy(krule->overload_tblname, rule->overload_tblname,
1619             sizeof(rule->overload_tblname));
1620
1621         bcopy(&rule->rpool, &krule->rpool, sizeof(krule->rpool));
1622
1623         /* Don't allow userspace to set evaulations, packets or bytes. */
1624         /* kif, anchor, overload_tbl are not copied over. */
1625
1626         krule->os_fingerprint = rule->os_fingerprint;
1627
1628         krule->rtableid = rule->rtableid;
1629         bcopy(rule->timeout, krule->timeout, sizeof(krule->timeout));
1630         krule->max_states = rule->max_states;
1631         krule->max_src_nodes = rule->max_src_nodes;
1632         krule->max_src_states = rule->max_src_states;
1633         krule->max_src_conn = rule->max_src_conn;
1634         krule->max_src_conn_rate.limit = rule->max_src_conn_rate.limit;
1635         krule->max_src_conn_rate.seconds = rule->max_src_conn_rate.seconds;
1636         krule->qid = rule->qid;
1637         krule->pqid = rule->pqid;
1638         krule->rt_listid = rule->rt_listid;
1639         krule->nr = rule->nr;
1640         krule->prob = rule->prob;
1641         krule->cuid = rule->cuid;
1642         krule->cpid = rule->cpid;
1643
1644         krule->return_icmp = rule->return_icmp;
1645         krule->return_icmp6 = rule->return_icmp6;
1646         krule->max_mss = rule->max_mss;
1647         krule->tag = rule->tag;
1648         krule->match_tag = rule->match_tag;
1649         krule->scrub_flags = rule->scrub_flags;
1650
1651         bcopy(&rule->uid, &krule->uid, sizeof(krule->uid));
1652         bcopy(&rule->gid, &krule->gid, sizeof(krule->gid));
1653
1654         krule->rule_flag = rule->rule_flag;
1655         krule->action = rule->action;
1656         krule->direction = rule->direction;
1657         krule->log = rule->log;
1658         krule->logif = rule->logif;
1659         krule->quick = rule->quick;
1660         krule->ifnot = rule->ifnot;
1661         krule->match_tag_not = rule->match_tag_not;
1662         krule->natpass = rule->natpass;
1663
1664         krule->keep_state = rule->keep_state;
1665         krule->af = rule->af;
1666         krule->proto = rule->proto;
1667         krule->type = rule->type;
1668         krule->code = rule->code;
1669         krule->flags = rule->flags;
1670         krule->flagset = rule->flagset;
1671         krule->min_ttl = rule->min_ttl;
1672         krule->allow_opts = rule->allow_opts;
1673         krule->rt = rule->rt;
1674         krule->return_ttl = rule->return_ttl;
1675         krule->tos = rule->tos;
1676         krule->set_tos = rule->set_tos;
1677         krule->anchor_relative = rule->anchor_relative;
1678         krule->anchor_wildcard = rule->anchor_wildcard;
1679
1680         krule->flush = rule->flush;
1681         krule->prio = rule->prio;
1682         krule->set_prio[0] = rule->set_prio[0];
1683         krule->set_prio[1] = rule->set_prio[1];
1684
1685         bcopy(&rule->divert, &krule->divert, sizeof(krule->divert));
1686
1687         return (0);
1688 }
1689
1690 static int
1691 pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
1692 {
1693         int                      error = 0;
1694         PF_RULES_RLOCK_TRACKER;
1695
1696         /* XXX keep in sync with switch() below */
1697         if (securelevel_gt(td->td_ucred, 2))
1698                 switch (cmd) {
1699                 case DIOCGETRULES:
1700                 case DIOCGETRULE:
1701                 case DIOCGETADDRS:
1702                 case DIOCGETADDR:
1703                 case DIOCGETSTATE:
1704                 case DIOCSETSTATUSIF:
1705                 case DIOCGETSTATUS:
1706                 case DIOCCLRSTATUS:
1707                 case DIOCNATLOOK:
1708                 case DIOCSETDEBUG:
1709                 case DIOCGETSTATES:
1710                 case DIOCGETTIMEOUT:
1711                 case DIOCCLRRULECTRS:
1712                 case DIOCGETLIMIT:
1713                 case DIOCGETALTQSV0:
1714                 case DIOCGETALTQSV1:
1715                 case DIOCGETALTQV0:
1716                 case DIOCGETALTQV1:
1717                 case DIOCGETQSTATSV0:
1718                 case DIOCGETQSTATSV1:
1719                 case DIOCGETRULESETS:
1720                 case DIOCGETRULESET:
1721                 case DIOCRGETTABLES:
1722                 case DIOCRGETTSTATS:
1723                 case DIOCRCLRTSTATS:
1724                 case DIOCRCLRADDRS:
1725                 case DIOCRADDADDRS:
1726                 case DIOCRDELADDRS:
1727                 case DIOCRSETADDRS:
1728                 case DIOCRGETADDRS:
1729                 case DIOCRGETASTATS:
1730                 case DIOCRCLRASTATS:
1731                 case DIOCRTSTADDRS:
1732                 case DIOCOSFPGET:
1733                 case DIOCGETSRCNODES:
1734                 case DIOCCLRSRCNODES:
1735                 case DIOCIGETIFACES:
1736                 case DIOCGIFSPEEDV0:
1737                 case DIOCGIFSPEEDV1:
1738                 case DIOCSETIFFLAG:
1739                 case DIOCCLRIFFLAG:
1740                         break;
1741                 case DIOCRCLRTABLES:
1742                 case DIOCRADDTABLES:
1743                 case DIOCRDELTABLES:
1744                 case DIOCRSETTFLAGS:
1745                         if (((struct pfioc_table *)addr)->pfrio_flags &
1746                             PFR_FLAG_DUMMY)
1747                                 break; /* dummy operation ok */
1748                         return (EPERM);
1749                 default:
1750                         return (EPERM);
1751                 }
1752
1753         if (!(flags & FWRITE))
1754                 switch (cmd) {
1755                 case DIOCGETRULES:
1756                 case DIOCGETADDRS:
1757                 case DIOCGETADDR:
1758                 case DIOCGETSTATE:
1759                 case DIOCGETSTATUS:
1760                 case DIOCGETSTATES:
1761                 case DIOCGETTIMEOUT:
1762                 case DIOCGETLIMIT:
1763                 case DIOCGETALTQSV0:
1764                 case DIOCGETALTQSV1:
1765                 case DIOCGETALTQV0:
1766                 case DIOCGETALTQV1:
1767                 case DIOCGETQSTATSV0:
1768                 case DIOCGETQSTATSV1:
1769                 case DIOCGETRULESETS:
1770                 case DIOCGETRULESET:
1771                 case DIOCNATLOOK:
1772                 case DIOCRGETTABLES:
1773                 case DIOCRGETTSTATS:
1774                 case DIOCRGETADDRS:
1775                 case DIOCRGETASTATS:
1776                 case DIOCRTSTADDRS:
1777                 case DIOCOSFPGET:
1778                 case DIOCGETSRCNODES:
1779                 case DIOCIGETIFACES:
1780                 case DIOCGIFSPEEDV1:
1781                 case DIOCGIFSPEEDV0:
1782                         break;
1783                 case DIOCRCLRTABLES:
1784                 case DIOCRADDTABLES:
1785                 case DIOCRDELTABLES:
1786                 case DIOCRCLRTSTATS:
1787                 case DIOCRCLRADDRS:
1788                 case DIOCRADDADDRS:
1789                 case DIOCRDELADDRS:
1790                 case DIOCRSETADDRS:
1791                 case DIOCRSETTFLAGS:
1792                         if (((struct pfioc_table *)addr)->pfrio_flags &
1793                             PFR_FLAG_DUMMY) {
1794                                 flags |= FWRITE; /* need write lock for dummy */
1795                                 break; /* dummy operation ok */
1796                         }
1797                         return (EACCES);
1798                 case DIOCGETRULE:
1799                         if (((struct pfioc_rule *)addr)->action ==
1800                             PF_GET_CLR_CNTR)
1801                                 return (EACCES);
1802                         break;
1803                 default:
1804                         return (EACCES);
1805                 }
1806
1807         CURVNET_SET(TD_TO_VNET(td));
1808
1809         switch (cmd) {
1810         case DIOCSTART:
1811                 sx_xlock(&pf_ioctl_lock);
1812                 if (V_pf_status.running)
1813                         error = EEXIST;
1814                 else {
1815                         int cpu;
1816
1817                         hook_pf();
1818                         V_pf_status.running = 1;
1819                         V_pf_status.since = time_second;
1820
1821                         CPU_FOREACH(cpu)
1822                                 V_pf_stateid[cpu] = time_second;
1823
1824                         DPFPRINTF(PF_DEBUG_MISC, ("pf: started\n"));
1825                 }
1826                 break;
1827
1828         case DIOCSTOP:
1829                 sx_xlock(&pf_ioctl_lock);
1830                 if (!V_pf_status.running)
1831                         error = ENOENT;
1832                 else {
1833                         V_pf_status.running = 0;
1834                         dehook_pf();
1835                         V_pf_status.since = time_second;
1836                         DPFPRINTF(PF_DEBUG_MISC, ("pf: stopped\n"));
1837                 }
1838                 break;
1839
1840         case DIOCADDRULE: {
1841                 struct pfioc_rule       *pr = (struct pfioc_rule *)addr;
1842                 struct pf_kruleset      *ruleset;
1843                 struct pf_krule         *rule, *tail;
1844                 struct pf_kpooladdr     *pa;
1845                 struct pfi_kkif         *kif = NULL;
1846                 int                      rs_num;
1847
1848                 if (pr->rule.return_icmp >> 8 > ICMP_MAXTYPE) {
1849                         error = EINVAL;
1850                         break;
1851                 }
1852
1853                 rule = malloc(sizeof(*rule), M_PFRULE, M_WAITOK);
1854                 error = pf_rule_to_krule(&pr->rule, rule);
1855                 if (error != 0) {
1856                         free(rule, M_PFRULE);
1857                         break;
1858                 }
1859
1860                 if (rule->ifname[0])
1861                         kif = pf_kkif_create(M_WAITOK);
1862                 rule->evaluations = counter_u64_alloc(M_WAITOK);
1863                 for (int i = 0; i < 2; i++) {
1864                         rule->packets[i] = counter_u64_alloc(M_WAITOK);
1865                         rule->bytes[i] = counter_u64_alloc(M_WAITOK);
1866                 }
1867                 rule->states_cur = counter_u64_alloc(M_WAITOK);
1868                 rule->states_tot = counter_u64_alloc(M_WAITOK);
1869                 rule->src_nodes = counter_u64_alloc(M_WAITOK);
1870                 rule->cuid = td->td_ucred->cr_ruid;
1871                 rule->cpid = td->td_proc ? td->td_proc->p_pid : 0;
1872                 TAILQ_INIT(&rule->rpool.list);
1873 #define ERROUT(x)       { error = (x); goto DIOCADDRULE_error; }
1874
1875                 PF_RULES_WLOCK();
1876                 pr->anchor[sizeof(pr->anchor) - 1] = 0;
1877                 ruleset = pf_find_kruleset(pr->anchor);
1878                 if (ruleset == NULL)
1879                         ERROUT(EINVAL);
1880                 rs_num = pf_get_ruleset_number(pr->rule.action);
1881                 if (rs_num >= PF_RULESET_MAX)
1882                         ERROUT(EINVAL);
1883                 if (pr->ticket != ruleset->rules[rs_num].inactive.ticket) {
1884                         DPFPRINTF(PF_DEBUG_MISC,
1885                             ("ticket: %d != [%d]%d\n", pr->ticket, rs_num,
1886                             ruleset->rules[rs_num].inactive.ticket));
1887                         ERROUT(EBUSY);
1888                 }
1889                 if (pr->pool_ticket != V_ticket_pabuf) {
1890                         DPFPRINTF(PF_DEBUG_MISC,
1891                             ("pool_ticket: %d != %d\n", pr->pool_ticket,
1892                             V_ticket_pabuf));
1893                         ERROUT(EBUSY);
1894                 }
1895
1896                 tail = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,
1897                     pf_krulequeue);
1898                 if (tail)
1899                         rule->nr = tail->nr + 1;
1900                 else
1901                         rule->nr = 0;
1902                 if (rule->ifname[0]) {
1903                         rule->kif = pfi_kkif_attach(kif, rule->ifname);
1904                         pfi_kkif_ref(rule->kif);
1905                 } else
1906                         rule->kif = NULL;
1907
1908                 if (rule->rtableid > 0 && rule->rtableid >= rt_numfibs)
1909                         error = EBUSY;
1910
1911 #ifdef ALTQ
1912                 /* set queue IDs */
1913                 if (rule->qname[0] != 0) {
1914                         if ((rule->qid = pf_qname2qid(rule->qname)) == 0)
1915                                 error = EBUSY;
1916                         else if (rule->pqname[0] != 0) {
1917                                 if ((rule->pqid =
1918                                     pf_qname2qid(rule->pqname)) == 0)
1919                                         error = EBUSY;
1920                         } else
1921                                 rule->pqid = rule->qid;
1922                 }
1923 #endif
1924                 if (rule->tagname[0])
1925                         if ((rule->tag = pf_tagname2tag(rule->tagname)) == 0)
1926                                 error = EBUSY;
1927                 if (rule->match_tagname[0])
1928                         if ((rule->match_tag =
1929                             pf_tagname2tag(rule->match_tagname)) == 0)
1930                                 error = EBUSY;
1931                 if (rule->rt && !rule->direction)
1932                         error = EINVAL;
1933                 if (!rule->log)
1934                         rule->logif = 0;
1935                 if (rule->logif >= PFLOGIFS_MAX)
1936                         error = EINVAL;
1937                 if (pf_addr_setup(ruleset, &rule->src.addr, rule->af))
1938                         error = ENOMEM;
1939                 if (pf_addr_setup(ruleset, &rule->dst.addr, rule->af))
1940                         error = ENOMEM;
1941                 if (pf_kanchor_setup(rule, ruleset, pr->anchor_call))
1942                         error = EINVAL;
1943                 if (rule->scrub_flags & PFSTATE_SETPRIO &&
1944                     (rule->set_prio[0] > PF_PRIO_MAX ||
1945                     rule->set_prio[1] > PF_PRIO_MAX))
1946                         error = EINVAL;
1947                 TAILQ_FOREACH(pa, &V_pf_pabuf, entries)
1948                         if (pa->addr.type == PF_ADDR_TABLE) {
1949                                 pa->addr.p.tbl = pfr_attach_table(ruleset,
1950                                     pa->addr.v.tblname);
1951                                 if (pa->addr.p.tbl == NULL)
1952                                         error = ENOMEM;
1953                         }
1954
1955                 rule->overload_tbl = NULL;
1956                 if (rule->overload_tblname[0]) {
1957                         if ((rule->overload_tbl = pfr_attach_table(ruleset,
1958                             rule->overload_tblname)) == NULL)
1959                                 error = EINVAL;
1960                         else
1961                                 rule->overload_tbl->pfrkt_flags |=
1962                                     PFR_TFLAG_ACTIVE;
1963                 }
1964
1965                 pf_mv_kpool(&V_pf_pabuf, &rule->rpool.list);
1966                 if (((((rule->action == PF_NAT) || (rule->action == PF_RDR) ||
1967                     (rule->action == PF_BINAT)) && rule->anchor == NULL) ||
1968                     (rule->rt > PF_NOPFROUTE)) &&
1969                     (TAILQ_FIRST(&rule->rpool.list) == NULL))
1970                         error = EINVAL;
1971
1972                 if (error) {
1973                         pf_free_rule(rule);
1974                         PF_RULES_WUNLOCK();
1975                         break;
1976                 }
1977
1978                 rule->rpool.cur = TAILQ_FIRST(&rule->rpool.list);
1979                 counter_u64_zero(rule->evaluations);
1980                 for (int i = 0; i < 2; i++) {
1981                         counter_u64_zero(rule->packets[i]);
1982                         counter_u64_zero(rule->bytes[i]);
1983                 }
1984                 TAILQ_INSERT_TAIL(ruleset->rules[rs_num].inactive.ptr,
1985                     rule, entries);
1986                 ruleset->rules[rs_num].inactive.rcount++;
1987                 PF_RULES_WUNLOCK();
1988                 break;
1989
1990 #undef ERROUT
1991 DIOCADDRULE_error:
1992                 PF_RULES_WUNLOCK();
1993                 counter_u64_free(rule->evaluations);
1994                 for (int i = 0; i < 2; i++) {
1995                         counter_u64_free(rule->packets[i]);
1996                         counter_u64_free(rule->bytes[i]);
1997                 }
1998                 counter_u64_free(rule->states_cur);
1999                 counter_u64_free(rule->states_tot);
2000                 counter_u64_free(rule->src_nodes);
2001                 free(rule, M_PFRULE);
2002                 if (kif)
2003                         pf_kkif_free(kif);
2004                 break;
2005         }
2006
2007         case DIOCGETRULES: {
2008                 struct pfioc_rule       *pr = (struct pfioc_rule *)addr;
2009                 struct pf_kruleset      *ruleset;
2010                 struct pf_krule         *tail;
2011                 int                      rs_num;
2012
2013                 PF_RULES_WLOCK();
2014                 pr->anchor[sizeof(pr->anchor) - 1] = 0;
2015                 ruleset = pf_find_kruleset(pr->anchor);
2016                 if (ruleset == NULL) {
2017                         PF_RULES_WUNLOCK();
2018                         error = EINVAL;
2019                         break;
2020                 }
2021                 rs_num = pf_get_ruleset_number(pr->rule.action);
2022                 if (rs_num >= PF_RULESET_MAX) {
2023                         PF_RULES_WUNLOCK();
2024                         error = EINVAL;
2025                         break;
2026                 }
2027                 tail = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
2028                     pf_krulequeue);
2029                 if (tail)
2030                         pr->nr = tail->nr + 1;
2031                 else
2032                         pr->nr = 0;
2033                 pr->ticket = ruleset->rules[rs_num].active.ticket;
2034                 PF_RULES_WUNLOCK();
2035                 break;
2036         }
2037
2038         case DIOCGETRULE: {
2039                 struct pfioc_rule       *pr = (struct pfioc_rule *)addr;
2040                 struct pf_kruleset      *ruleset;
2041                 struct pf_krule         *rule;
2042                 int                      rs_num;
2043
2044                 PF_RULES_WLOCK();
2045                 pr->anchor[sizeof(pr->anchor) - 1] = 0;
2046                 ruleset = pf_find_kruleset(pr->anchor);
2047                 if (ruleset == NULL) {
2048                         PF_RULES_WUNLOCK();
2049                         error = EINVAL;
2050                         break;
2051                 }
2052                 rs_num = pf_get_ruleset_number(pr->rule.action);
2053                 if (rs_num >= PF_RULESET_MAX) {
2054                         PF_RULES_WUNLOCK();
2055                         error = EINVAL;
2056                         break;
2057                 }
2058                 if (pr->ticket != ruleset->rules[rs_num].active.ticket) {
2059                         PF_RULES_WUNLOCK();
2060                         error = EBUSY;
2061                         break;
2062                 }
2063                 rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
2064                 while ((rule != NULL) && (rule->nr != pr->nr))
2065                         rule = TAILQ_NEXT(rule, entries);
2066                 if (rule == NULL) {
2067                         PF_RULES_WUNLOCK();
2068                         error = EBUSY;
2069                         break;
2070                 }
2071
2072                 pf_krule_to_rule(rule, &pr->rule);
2073
2074                 if (pf_kanchor_copyout(ruleset, rule, pr)) {
2075                         PF_RULES_WUNLOCK();
2076                         error = EBUSY;
2077                         break;
2078                 }
2079                 pf_addr_copyout(&pr->rule.src.addr);
2080                 pf_addr_copyout(&pr->rule.dst.addr);
2081
2082                 if (pr->action == PF_GET_CLR_CNTR) {
2083                         counter_u64_zero(rule->evaluations);
2084                         for (int i = 0; i < 2; i++) {
2085                                 counter_u64_zero(rule->packets[i]);
2086                                 counter_u64_zero(rule->bytes[i]);
2087                         }
2088                         counter_u64_zero(rule->states_tot);
2089                 }
2090                 PF_RULES_WUNLOCK();
2091                 break;
2092         }
2093
2094         case DIOCCHANGERULE: {
2095                 struct pfioc_rule       *pcr = (struct pfioc_rule *)addr;
2096                 struct pf_kruleset      *ruleset;
2097                 struct pf_krule         *oldrule = NULL, *newrule = NULL;
2098                 struct pfi_kkif         *kif = NULL;
2099                 struct pf_kpooladdr     *pa;
2100                 u_int32_t                nr = 0;
2101                 int                      rs_num;
2102
2103                 if (pcr->action < PF_CHANGE_ADD_HEAD ||
2104                     pcr->action > PF_CHANGE_GET_TICKET) {
2105                         error = EINVAL;
2106                         break;
2107                 }
2108                 if (pcr->rule.return_icmp >> 8 > ICMP_MAXTYPE) {
2109                         error = EINVAL;
2110                         break;
2111                 }
2112
2113                 if (pcr->action != PF_CHANGE_REMOVE) {
2114                         newrule = malloc(sizeof(*newrule), M_PFRULE, M_WAITOK);
2115                         error = pf_rule_to_krule(&pcr->rule, newrule);
2116                         if (error != 0) {
2117                                 free(newrule, M_PFRULE);
2118                                 break;
2119                         }
2120
2121                         if (newrule->ifname[0])
2122                                 kif = pf_kkif_create(M_WAITOK);
2123                         newrule->evaluations = counter_u64_alloc(M_WAITOK);
2124                         for (int i = 0; i < 2; i++) {
2125                                 newrule->packets[i] =
2126                                     counter_u64_alloc(M_WAITOK);
2127                                 newrule->bytes[i] =
2128                                     counter_u64_alloc(M_WAITOK);
2129                         }
2130                         newrule->states_cur = counter_u64_alloc(M_WAITOK);
2131                         newrule->states_tot = counter_u64_alloc(M_WAITOK);
2132                         newrule->src_nodes = counter_u64_alloc(M_WAITOK);
2133                         newrule->cuid = td->td_ucred->cr_ruid;
2134                         newrule->cpid = td->td_proc ? td->td_proc->p_pid : 0;
2135                         TAILQ_INIT(&newrule->rpool.list);
2136                 }
2137 #define ERROUT(x)       { error = (x); goto DIOCCHANGERULE_error; }
2138
2139                 PF_RULES_WLOCK();
2140                 if (!(pcr->action == PF_CHANGE_REMOVE ||
2141                     pcr->action == PF_CHANGE_GET_TICKET) &&
2142                     pcr->pool_ticket != V_ticket_pabuf)
2143                         ERROUT(EBUSY);
2144
2145                 ruleset = pf_find_kruleset(pcr->anchor);
2146                 if (ruleset == NULL)
2147                         ERROUT(EINVAL);
2148
2149                 rs_num = pf_get_ruleset_number(pcr->rule.action);
2150                 if (rs_num >= PF_RULESET_MAX)
2151                         ERROUT(EINVAL);
2152
2153                 if (pcr->action == PF_CHANGE_GET_TICKET) {
2154                         pcr->ticket = ++ruleset->rules[rs_num].active.ticket;
2155                         ERROUT(0);
2156                 } else if (pcr->ticket !=
2157                             ruleset->rules[rs_num].active.ticket)
2158                                 ERROUT(EINVAL);
2159
2160                 if (pcr->action != PF_CHANGE_REMOVE) {
2161                         if (newrule->ifname[0]) {
2162                                 newrule->kif = pfi_kkif_attach(kif,
2163                                     newrule->ifname);
2164                                 pfi_kkif_ref(newrule->kif);
2165                         } else
2166                                 newrule->kif = NULL;
2167
2168                         if (newrule->rtableid > 0 &&
2169                             newrule->rtableid >= rt_numfibs)
2170                                 error = EBUSY;
2171
2172 #ifdef ALTQ
2173                         /* set queue IDs */
2174                         if (newrule->qname[0] != 0) {
2175                                 if ((newrule->qid =
2176                                     pf_qname2qid(newrule->qname)) == 0)
2177                                         error = EBUSY;
2178                                 else if (newrule->pqname[0] != 0) {
2179                                         if ((newrule->pqid =
2180                                             pf_qname2qid(newrule->pqname)) == 0)
2181                                                 error = EBUSY;
2182                                 } else
2183                                         newrule->pqid = newrule->qid;
2184                         }
2185 #endif /* ALTQ */
2186                         if (newrule->tagname[0])
2187                                 if ((newrule->tag =
2188                                     pf_tagname2tag(newrule->tagname)) == 0)
2189                                         error = EBUSY;
2190                         if (newrule->match_tagname[0])
2191                                 if ((newrule->match_tag = pf_tagname2tag(
2192                                     newrule->match_tagname)) == 0)
2193                                         error = EBUSY;
2194                         if (newrule->rt && !newrule->direction)
2195                                 error = EINVAL;
2196                         if (!newrule->log)
2197                                 newrule->logif = 0;
2198                         if (newrule->logif >= PFLOGIFS_MAX)
2199                                 error = EINVAL;
2200                         if (pf_addr_setup(ruleset, &newrule->src.addr, newrule->af))
2201                                 error = ENOMEM;
2202                         if (pf_addr_setup(ruleset, &newrule->dst.addr, newrule->af))
2203                                 error = ENOMEM;
2204                         if (pf_kanchor_setup(newrule, ruleset, pcr->anchor_call))
2205                                 error = EINVAL;
2206                         TAILQ_FOREACH(pa, &V_pf_pabuf, entries)
2207                                 if (pa->addr.type == PF_ADDR_TABLE) {
2208                                         pa->addr.p.tbl =
2209                                             pfr_attach_table(ruleset,
2210                                             pa->addr.v.tblname);
2211                                         if (pa->addr.p.tbl == NULL)
2212                                                 error = ENOMEM;
2213                                 }
2214
2215                         newrule->overload_tbl = NULL;
2216                         if (newrule->overload_tblname[0]) {
2217                                 if ((newrule->overload_tbl = pfr_attach_table(
2218                                     ruleset, newrule->overload_tblname)) ==
2219                                     NULL)
2220                                         error = EINVAL;
2221                                 else
2222                                         newrule->overload_tbl->pfrkt_flags |=
2223                                             PFR_TFLAG_ACTIVE;
2224                         }
2225
2226                         pf_mv_kpool(&V_pf_pabuf, &newrule->rpool.list);
2227                         if (((((newrule->action == PF_NAT) ||
2228                             (newrule->action == PF_RDR) ||
2229                             (newrule->action == PF_BINAT) ||
2230                             (newrule->rt > PF_NOPFROUTE)) &&
2231                             !newrule->anchor)) &&
2232                             (TAILQ_FIRST(&newrule->rpool.list) == NULL))
2233                                 error = EINVAL;
2234
2235                         if (error) {
2236                                 pf_free_rule(newrule);
2237                                 PF_RULES_WUNLOCK();
2238                                 break;
2239                         }
2240
2241                         newrule->rpool.cur = TAILQ_FIRST(&newrule->rpool.list);
2242                 }
2243                 pf_empty_kpool(&V_pf_pabuf);
2244
2245                 if (pcr->action == PF_CHANGE_ADD_HEAD)
2246                         oldrule = TAILQ_FIRST(
2247                             ruleset->rules[rs_num].active.ptr);
2248                 else if (pcr->action == PF_CHANGE_ADD_TAIL)
2249                         oldrule = TAILQ_LAST(
2250                             ruleset->rules[rs_num].active.ptr, pf_krulequeue);
2251                 else {
2252                         oldrule = TAILQ_FIRST(
2253                             ruleset->rules[rs_num].active.ptr);
2254                         while ((oldrule != NULL) && (oldrule->nr != pcr->nr))
2255                                 oldrule = TAILQ_NEXT(oldrule, entries);
2256                         if (oldrule == NULL) {
2257                                 if (newrule != NULL)
2258                                         pf_free_rule(newrule);
2259                                 PF_RULES_WUNLOCK();
2260                                 error = EINVAL;
2261                                 break;
2262                         }
2263                 }
2264
2265                 if (pcr->action == PF_CHANGE_REMOVE) {
2266                         pf_unlink_rule(ruleset->rules[rs_num].active.ptr,
2267                             oldrule);
2268                         ruleset->rules[rs_num].active.rcount--;
2269                 } else {
2270                         if (oldrule == NULL)
2271                                 TAILQ_INSERT_TAIL(
2272                                     ruleset->rules[rs_num].active.ptr,
2273                                     newrule, entries);
2274                         else if (pcr->action == PF_CHANGE_ADD_HEAD ||
2275                             pcr->action == PF_CHANGE_ADD_BEFORE)
2276                                 TAILQ_INSERT_BEFORE(oldrule, newrule, entries);
2277                         else
2278                                 TAILQ_INSERT_AFTER(
2279                                     ruleset->rules[rs_num].active.ptr,
2280                                     oldrule, newrule, entries);
2281                         ruleset->rules[rs_num].active.rcount++;
2282                 }
2283
2284                 nr = 0;
2285                 TAILQ_FOREACH(oldrule,
2286                     ruleset->rules[rs_num].active.ptr, entries)
2287                         oldrule->nr = nr++;
2288
2289                 ruleset->rules[rs_num].active.ticket++;
2290
2291                 pf_calc_skip_steps(ruleset->rules[rs_num].active.ptr);
2292                 pf_remove_if_empty_kruleset(ruleset);
2293
2294                 PF_RULES_WUNLOCK();
2295                 break;
2296
2297 #undef ERROUT
2298 DIOCCHANGERULE_error:
2299                 PF_RULES_WUNLOCK();
2300                 if (newrule != NULL) {
2301                         counter_u64_free(newrule->evaluations);
2302                         for (int i = 0; i < 2; i++) {
2303                                 counter_u64_free(newrule->packets[i]);
2304                                 counter_u64_free(newrule->bytes[i]);
2305                         }
2306                         counter_u64_free(newrule->states_cur);
2307                         counter_u64_free(newrule->states_tot);
2308                         counter_u64_free(newrule->src_nodes);
2309                         free(newrule, M_PFRULE);
2310                 }
2311                 if (kif != NULL)
2312                         pf_kkif_free(kif);
2313                 break;
2314         }
2315
2316         case DIOCCLRSTATES: {
2317                 struct pf_state         *s;
2318                 struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr;
2319                 u_int                    i, killed = 0;
2320
2321                 for (i = 0; i <= pf_hashmask; i++) {
2322                         struct pf_idhash *ih = &V_pf_idhash[i];
2323
2324 relock_DIOCCLRSTATES:
2325                         PF_HASHROW_LOCK(ih);
2326                         LIST_FOREACH(s, &ih->states, entry)
2327                                 if (!psk->psk_ifname[0] ||
2328                                     !strcmp(psk->psk_ifname,
2329                                     s->kif->pfik_name)) {
2330                                         /*
2331                                          * Don't send out individual
2332                                          * delete messages.
2333                                          */
2334                                         s->state_flags |= PFSTATE_NOSYNC;
2335                                         pf_unlink_state(s, PF_ENTER_LOCKED);
2336                                         killed++;
2337                                         goto relock_DIOCCLRSTATES;
2338                                 }
2339                         PF_HASHROW_UNLOCK(ih);
2340                 }
2341                 psk->psk_killed = killed;
2342                 if (V_pfsync_clear_states_ptr != NULL)
2343                         V_pfsync_clear_states_ptr(V_pf_status.hostid, psk->psk_ifname);
2344                 break;
2345         }
2346
2347         case DIOCKILLSTATES: {
2348                 struct pf_state         *s;
2349                 struct pf_state_key     *sk;
2350                 struct pf_addr          *srcaddr, *dstaddr;
2351                 u_int16_t                srcport, dstport;
2352                 struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr;
2353                 u_int                    i, killed = 0;
2354
2355                 if (psk->psk_pfcmp.id) {
2356                         if (psk->psk_pfcmp.creatorid == 0)
2357                                 psk->psk_pfcmp.creatorid = V_pf_status.hostid;
2358                         if ((s = pf_find_state_byid(psk->psk_pfcmp.id,
2359                             psk->psk_pfcmp.creatorid))) {
2360                                 pf_unlink_state(s, PF_ENTER_LOCKED);
2361                                 psk->psk_killed = 1;
2362                         }
2363                         break;
2364                 }
2365
2366                 for (i = 0; i <= pf_hashmask; i++) {
2367                         struct pf_idhash *ih = &V_pf_idhash[i];
2368
2369 relock_DIOCKILLSTATES:
2370                         PF_HASHROW_LOCK(ih);
2371                         LIST_FOREACH(s, &ih->states, entry) {
2372                                 sk = s->key[PF_SK_WIRE];
2373                                 if (s->direction == PF_OUT) {
2374                                         srcaddr = &sk->addr[1];
2375                                         dstaddr = &sk->addr[0];
2376                                         srcport = sk->port[1];
2377                                         dstport = sk->port[0];
2378                                 } else {
2379                                         srcaddr = &sk->addr[0];
2380                                         dstaddr = &sk->addr[1];
2381                                         srcport = sk->port[0];
2382                                         dstport = sk->port[1];
2383                                 }
2384
2385                                 if ((!psk->psk_af || sk->af == psk->psk_af)
2386                                     && (!psk->psk_proto || psk->psk_proto ==
2387                                     sk->proto) &&
2388                                     PF_MATCHA(psk->psk_src.neg,
2389                                     &psk->psk_src.addr.v.a.addr,
2390                                     &psk->psk_src.addr.v.a.mask,
2391                                     srcaddr, sk->af) &&
2392                                     PF_MATCHA(psk->psk_dst.neg,
2393                                     &psk->psk_dst.addr.v.a.addr,
2394                                     &psk->psk_dst.addr.v.a.mask,
2395                                     dstaddr, sk->af) &&
2396                                     (psk->psk_src.port_op == 0 ||
2397                                     pf_match_port(psk->psk_src.port_op,
2398                                     psk->psk_src.port[0], psk->psk_src.port[1],
2399                                     srcport)) &&
2400                                     (psk->psk_dst.port_op == 0 ||
2401                                     pf_match_port(psk->psk_dst.port_op,
2402                                     psk->psk_dst.port[0], psk->psk_dst.port[1],
2403                                     dstport)) &&
2404                                     (!psk->psk_label[0] ||
2405                                     (s->rule.ptr->label[0] &&
2406                                     !strcmp(psk->psk_label,
2407                                     s->rule.ptr->label))) &&
2408                                     (!psk->psk_ifname[0] ||
2409                                     !strcmp(psk->psk_ifname,
2410                                     s->kif->pfik_name))) {
2411                                         pf_unlink_state(s, PF_ENTER_LOCKED);
2412                                         killed++;
2413                                         goto relock_DIOCKILLSTATES;
2414                                 }
2415                         }
2416                         PF_HASHROW_UNLOCK(ih);
2417                 }
2418                 psk->psk_killed = killed;
2419                 break;
2420         }
2421
2422         case DIOCADDSTATE: {
2423                 struct pfioc_state      *ps = (struct pfioc_state *)addr;
2424                 struct pfsync_state     *sp = &ps->state;
2425
2426                 if (sp->timeout >= PFTM_MAX) {
2427                         error = EINVAL;
2428                         break;
2429                 }
2430                 if (V_pfsync_state_import_ptr != NULL) {
2431                         PF_RULES_RLOCK();
2432                         error = V_pfsync_state_import_ptr(sp, PFSYNC_SI_IOCTL);
2433                         PF_RULES_RUNLOCK();
2434                 } else
2435                         error = EOPNOTSUPP;
2436                 break;
2437         }
2438
2439         case DIOCGETSTATE: {
2440                 struct pfioc_state      *ps = (struct pfioc_state *)addr;
2441                 struct pf_state         *s;
2442
2443                 s = pf_find_state_byid(ps->state.id, ps->state.creatorid);
2444                 if (s == NULL) {
2445                         error = ENOENT;
2446                         break;
2447                 }
2448
2449                 pfsync_state_export(&ps->state, s);
2450                 PF_STATE_UNLOCK(s);
2451                 break;
2452         }
2453
2454         case DIOCGETSTATES: {
2455                 struct pfioc_states     *ps = (struct pfioc_states *)addr;
2456                 struct pf_state         *s;
2457                 struct pfsync_state     *pstore, *p;
2458                 int i, nr;
2459
2460                 if (ps->ps_len <= 0) {
2461                         nr = uma_zone_get_cur(V_pf_state_z);
2462                         ps->ps_len = sizeof(struct pfsync_state) * nr;
2463                         break;
2464                 }
2465
2466                 p = pstore = malloc(ps->ps_len, M_TEMP, M_WAITOK | M_ZERO);
2467                 nr = 0;
2468
2469                 for (i = 0; i <= pf_hashmask; i++) {
2470                         struct pf_idhash *ih = &V_pf_idhash[i];
2471
2472                         PF_HASHROW_LOCK(ih);
2473                         LIST_FOREACH(s, &ih->states, entry) {
2474                                 if (s->timeout == PFTM_UNLINKED)
2475                                         continue;
2476
2477                                 if ((nr+1) * sizeof(*p) > ps->ps_len) {
2478                                         PF_HASHROW_UNLOCK(ih);
2479                                         goto DIOCGETSTATES_full;
2480                                 }
2481                                 pfsync_state_export(p, s);
2482                                 p++;
2483                                 nr++;
2484                         }
2485                         PF_HASHROW_UNLOCK(ih);
2486                 }
2487 DIOCGETSTATES_full:
2488                 error = copyout(pstore, ps->ps_states,
2489                     sizeof(struct pfsync_state) * nr);
2490                 if (error) {
2491                         free(pstore, M_TEMP);
2492                         break;
2493                 }
2494                 ps->ps_len = sizeof(struct pfsync_state) * nr;
2495                 free(pstore, M_TEMP);
2496
2497                 break;
2498         }
2499
2500         case DIOCGETSTATUS: {
2501                 struct pf_status *s = (struct pf_status *)addr;
2502
2503                 PF_RULES_RLOCK();
2504                 s->running = V_pf_status.running;
2505                 s->since   = V_pf_status.since;
2506                 s->debug   = V_pf_status.debug;
2507                 s->hostid  = V_pf_status.hostid;
2508                 s->states  = V_pf_status.states;
2509                 s->src_nodes = V_pf_status.src_nodes;
2510
2511                 for (int i = 0; i < PFRES_MAX; i++)
2512                         s->counters[i] =
2513                             counter_u64_fetch(V_pf_status.counters[i]);
2514                 for (int i = 0; i < LCNT_MAX; i++)
2515                         s->lcounters[i] =
2516                             counter_u64_fetch(V_pf_status.lcounters[i]);
2517                 for (int i = 0; i < FCNT_MAX; i++)
2518                         s->fcounters[i] =
2519                             counter_u64_fetch(V_pf_status.fcounters[i]);
2520                 for (int i = 0; i < SCNT_MAX; i++)
2521                         s->scounters[i] =
2522                             counter_u64_fetch(V_pf_status.scounters[i]);
2523
2524                 bcopy(V_pf_status.ifname, s->ifname, IFNAMSIZ);
2525                 bcopy(V_pf_status.pf_chksum, s->pf_chksum,
2526                     PF_MD5_DIGEST_LENGTH);
2527
2528                 pfi_update_status(s->ifname, s);
2529                 PF_RULES_RUNLOCK();
2530                 break;
2531         }
2532
2533         case DIOCSETSTATUSIF: {
2534                 struct pfioc_if *pi = (struct pfioc_if *)addr;
2535
2536                 if (pi->ifname[0] == 0) {
2537                         bzero(V_pf_status.ifname, IFNAMSIZ);
2538                         break;
2539                 }
2540                 PF_RULES_WLOCK();
2541                 strlcpy(V_pf_status.ifname, pi->ifname, IFNAMSIZ);
2542                 PF_RULES_WUNLOCK();
2543                 break;
2544         }
2545
2546         case DIOCCLRSTATUS: {
2547                 PF_RULES_WLOCK();
2548                 for (int i = 0; i < PFRES_MAX; i++)
2549                         counter_u64_zero(V_pf_status.counters[i]);
2550                 for (int i = 0; i < FCNT_MAX; i++)
2551                         counter_u64_zero(V_pf_status.fcounters[i]);
2552                 for (int i = 0; i < SCNT_MAX; i++)
2553                         counter_u64_zero(V_pf_status.scounters[i]);
2554                 for (int i = 0; i < LCNT_MAX; i++)
2555                         counter_u64_zero(V_pf_status.lcounters[i]);
2556                 V_pf_status.since = time_second;
2557                 if (*V_pf_status.ifname)
2558                         pfi_update_status(V_pf_status.ifname, NULL);
2559                 PF_RULES_WUNLOCK();
2560                 break;
2561         }
2562
2563         case DIOCNATLOOK: {
2564                 struct pfioc_natlook    *pnl = (struct pfioc_natlook *)addr;
2565                 struct pf_state_key     *sk;
2566                 struct pf_state         *state;
2567                 struct pf_state_key_cmp  key;
2568                 int                      m = 0, direction = pnl->direction;
2569                 int                      sidx, didx;
2570
2571                 /* NATLOOK src and dst are reversed, so reverse sidx/didx */
2572                 sidx = (direction == PF_IN) ? 1 : 0;
2573                 didx = (direction == PF_IN) ? 0 : 1;
2574
2575                 if (!pnl->proto ||
2576                     PF_AZERO(&pnl->saddr, pnl->af) ||
2577                     PF_AZERO(&pnl->daddr, pnl->af) ||
2578                     ((pnl->proto == IPPROTO_TCP ||
2579                     pnl->proto == IPPROTO_UDP) &&
2580                     (!pnl->dport || !pnl->sport)))
2581                         error = EINVAL;
2582                 else {
2583                         bzero(&key, sizeof(key));
2584                         key.af = pnl->af;
2585                         key.proto = pnl->proto;
2586                         PF_ACPY(&key.addr[sidx], &pnl->saddr, pnl->af);
2587                         key.port[sidx] = pnl->sport;
2588                         PF_ACPY(&key.addr[didx], &pnl->daddr, pnl->af);
2589                         key.port[didx] = pnl->dport;
2590
2591                         state = pf_find_state_all(&key, direction, &m);
2592
2593                         if (m > 1)
2594                                 error = E2BIG;  /* more than one state */
2595                         else if (state != NULL) {
2596                                 /* XXXGL: not locked read */
2597                                 sk = state->key[sidx];
2598                                 PF_ACPY(&pnl->rsaddr, &sk->addr[sidx], sk->af);
2599                                 pnl->rsport = sk->port[sidx];
2600                                 PF_ACPY(&pnl->rdaddr, &sk->addr[didx], sk->af);
2601                                 pnl->rdport = sk->port[didx];
2602                         } else
2603                                 error = ENOENT;
2604                 }
2605                 break;
2606         }
2607
2608         case DIOCSETTIMEOUT: {
2609                 struct pfioc_tm *pt = (struct pfioc_tm *)addr;
2610                 int              old;
2611
2612                 if (pt->timeout < 0 || pt->timeout >= PFTM_MAX ||
2613                     pt->seconds < 0) {
2614                         error = EINVAL;
2615                         break;
2616                 }
2617                 PF_RULES_WLOCK();
2618                 old = V_pf_default_rule.timeout[pt->timeout];
2619                 if (pt->timeout == PFTM_INTERVAL && pt->seconds == 0)
2620                         pt->seconds = 1;
2621                 V_pf_default_rule.timeout[pt->timeout] = pt->seconds;
2622                 if (pt->timeout == PFTM_INTERVAL && pt->seconds < old)
2623                         wakeup(pf_purge_thread);
2624                 pt->seconds = old;
2625                 PF_RULES_WUNLOCK();
2626                 break;
2627         }
2628
2629         case DIOCGETTIMEOUT: {
2630                 struct pfioc_tm *pt = (struct pfioc_tm *)addr;
2631
2632                 if (pt->timeout < 0 || pt->timeout >= PFTM_MAX) {
2633                         error = EINVAL;
2634                         break;
2635                 }
2636                 PF_RULES_RLOCK();
2637                 pt->seconds = V_pf_default_rule.timeout[pt->timeout];
2638                 PF_RULES_RUNLOCK();
2639                 break;
2640         }
2641
2642         case DIOCGETLIMIT: {
2643                 struct pfioc_limit      *pl = (struct pfioc_limit *)addr;
2644
2645                 if (pl->index < 0 || pl->index >= PF_LIMIT_MAX) {
2646                         error = EINVAL;
2647                         break;
2648                 }
2649                 PF_RULES_RLOCK();
2650                 pl->limit = V_pf_limits[pl->index].limit;
2651                 PF_RULES_RUNLOCK();
2652                 break;
2653         }
2654
2655         case DIOCSETLIMIT: {
2656                 struct pfioc_limit      *pl = (struct pfioc_limit *)addr;
2657                 int                      old_limit;
2658
2659                 PF_RULES_WLOCK();
2660                 if (pl->index < 0 || pl->index >= PF_LIMIT_MAX ||
2661                     V_pf_limits[pl->index].zone == NULL) {
2662                         PF_RULES_WUNLOCK();
2663                         error = EINVAL;
2664                         break;
2665                 }
2666                 uma_zone_set_max(V_pf_limits[pl->index].zone, pl->limit);
2667                 old_limit = V_pf_limits[pl->index].limit;
2668                 V_pf_limits[pl->index].limit = pl->limit;
2669                 pl->limit = old_limit;
2670                 PF_RULES_WUNLOCK();
2671                 break;
2672         }
2673
2674         case DIOCSETDEBUG: {
2675                 u_int32_t       *level = (u_int32_t *)addr;
2676
2677                 PF_RULES_WLOCK();
2678                 V_pf_status.debug = *level;
2679                 PF_RULES_WUNLOCK();
2680                 break;
2681         }
2682
2683         case DIOCCLRRULECTRS: {
2684                 /* obsoleted by DIOCGETRULE with action=PF_GET_CLR_CNTR */
2685                 struct pf_kruleset      *ruleset = &pf_main_ruleset;
2686                 struct pf_krule         *rule;
2687
2688                 PF_RULES_WLOCK();
2689                 TAILQ_FOREACH(rule,
2690                     ruleset->rules[PF_RULESET_FILTER].active.ptr, entries) {
2691                         counter_u64_zero(rule->evaluations);
2692                         for (int i = 0; i < 2; i++) {
2693                                 counter_u64_zero(rule->packets[i]);
2694                                 counter_u64_zero(rule->bytes[i]);
2695                         }
2696                 }
2697                 PF_RULES_WUNLOCK();
2698                 break;
2699         }
2700
2701         case DIOCGIFSPEEDV0:
2702         case DIOCGIFSPEEDV1: {
2703                 struct pf_ifspeed_v1    *psp = (struct pf_ifspeed_v1 *)addr;
2704                 struct pf_ifspeed_v1    ps;
2705                 struct ifnet            *ifp;
2706
2707                 if (psp->ifname[0] != 0) {
2708                         /* Can we completely trust user-land? */
2709                         strlcpy(ps.ifname, psp->ifname, IFNAMSIZ);
2710                         ifp = ifunit(ps.ifname);
2711                         if (ifp != NULL) {
2712                                 psp->baudrate32 =
2713                                     (u_int32_t)uqmin(ifp->if_baudrate, UINT_MAX);
2714                                 if (cmd == DIOCGIFSPEEDV1)
2715                                         psp->baudrate = ifp->if_baudrate;
2716                         } else
2717                                 error = EINVAL;
2718                 } else
2719                         error = EINVAL;
2720                 break;
2721         }
2722
2723 #ifdef ALTQ
2724         case DIOCSTARTALTQ: {
2725                 struct pf_altq          *altq;
2726
2727                 PF_RULES_WLOCK();
2728                 /* enable all altq interfaces on active list */
2729                 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) {
2730                         if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
2731                                 error = pf_enable_altq(altq);
2732                                 if (error != 0)
2733                                         break;
2734                         }
2735                 }
2736                 if (error == 0)
2737                         V_pf_altq_running = 1;
2738                 PF_RULES_WUNLOCK();
2739                 DPFPRINTF(PF_DEBUG_MISC, ("altq: started\n"));
2740                 break;
2741         }
2742
2743         case DIOCSTOPALTQ: {
2744                 struct pf_altq          *altq;
2745
2746                 PF_RULES_WLOCK();
2747                 /* disable all altq interfaces on active list */
2748                 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) {
2749                         if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
2750                                 error = pf_disable_altq(altq);
2751                                 if (error != 0)
2752                                         break;
2753                         }
2754                 }
2755                 if (error == 0)
2756                         V_pf_altq_running = 0;
2757                 PF_RULES_WUNLOCK();
2758                 DPFPRINTF(PF_DEBUG_MISC, ("altq: stopped\n"));
2759                 break;
2760         }
2761
2762         case DIOCADDALTQV0:
2763         case DIOCADDALTQV1: {
2764                 struct pfioc_altq_v1    *pa = (struct pfioc_altq_v1 *)addr;
2765                 struct pf_altq          *altq, *a;
2766                 struct ifnet            *ifp;
2767
2768                 altq = malloc(sizeof(*altq), M_PFALTQ, M_WAITOK | M_ZERO);
2769                 error = pf_import_kaltq(pa, altq, IOCPARM_LEN(cmd));
2770                 if (error)
2771                         break;
2772                 altq->local_flags = 0;
2773
2774                 PF_RULES_WLOCK();
2775                 if (pa->ticket != V_ticket_altqs_inactive) {
2776                         PF_RULES_WUNLOCK();
2777                         free(altq, M_PFALTQ);
2778                         error = EBUSY;
2779                         break;
2780                 }
2781
2782                 /*
2783                  * if this is for a queue, find the discipline and
2784                  * copy the necessary fields
2785                  */
2786                 if (altq->qname[0] != 0) {
2787                         if ((altq->qid = pf_qname2qid(altq->qname)) == 0) {
2788                                 PF_RULES_WUNLOCK();
2789                                 error = EBUSY;
2790                                 free(altq, M_PFALTQ);
2791                                 break;
2792                         }
2793                         altq->altq_disc = NULL;
2794                         TAILQ_FOREACH(a, V_pf_altq_ifs_inactive, entries) {
2795                                 if (strncmp(a->ifname, altq->ifname,
2796                                     IFNAMSIZ) == 0) {
2797                                         altq->altq_disc = a->altq_disc;
2798                                         break;
2799                                 }
2800                         }
2801                 }
2802
2803                 if ((ifp = ifunit(altq->ifname)) == NULL)
2804                         altq->local_flags |= PFALTQ_FLAG_IF_REMOVED;
2805                 else
2806                         error = altq_add(ifp, altq);
2807
2808                 if (error) {
2809                         PF_RULES_WUNLOCK();
2810                         free(altq, M_PFALTQ);
2811                         break;
2812                 }
2813
2814                 if (altq->qname[0] != 0)
2815                         TAILQ_INSERT_TAIL(V_pf_altqs_inactive, altq, entries);
2816                 else
2817                         TAILQ_INSERT_TAIL(V_pf_altq_ifs_inactive, altq, entries);
2818                 /* version error check done on import above */
2819                 pf_export_kaltq(altq, pa, IOCPARM_LEN(cmd));
2820                 PF_RULES_WUNLOCK();
2821                 break;
2822         }
2823
2824         case DIOCGETALTQSV0:
2825         case DIOCGETALTQSV1: {
2826                 struct pfioc_altq_v1    *pa = (struct pfioc_altq_v1 *)addr;
2827                 struct pf_altq          *altq;
2828
2829                 PF_RULES_RLOCK();
2830                 pa->nr = 0;
2831                 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries)
2832                         pa->nr++;
2833                 TAILQ_FOREACH(altq, V_pf_altqs_active, entries)
2834                         pa->nr++;
2835                 pa->ticket = V_ticket_altqs_active;
2836                 PF_RULES_RUNLOCK();
2837                 break;
2838         }
2839
2840         case DIOCGETALTQV0:
2841         case DIOCGETALTQV1: {
2842                 struct pfioc_altq_v1    *pa = (struct pfioc_altq_v1 *)addr;
2843                 struct pf_altq          *altq;
2844
2845                 PF_RULES_RLOCK();
2846                 if (pa->ticket != V_ticket_altqs_active) {
2847                         PF_RULES_RUNLOCK();
2848                         error = EBUSY;
2849                         break;
2850                 }
2851                 altq = pf_altq_get_nth_active(pa->nr);
2852                 if (altq == NULL) {
2853                         PF_RULES_RUNLOCK();
2854                         error = EBUSY;
2855                         break;
2856                 }
2857                 pf_export_kaltq(altq, pa, IOCPARM_LEN(cmd));
2858                 PF_RULES_RUNLOCK();
2859                 break;
2860         }
2861
2862         case DIOCCHANGEALTQV0:
2863         case DIOCCHANGEALTQV1:
2864                 /* CHANGEALTQ not supported yet! */
2865                 error = ENODEV;
2866                 break;
2867
2868         case DIOCGETQSTATSV0:
2869         case DIOCGETQSTATSV1: {
2870                 struct pfioc_qstats_v1  *pq = (struct pfioc_qstats_v1 *)addr;
2871                 struct pf_altq          *altq;
2872                 int                      nbytes;
2873                 u_int32_t                version;
2874
2875                 PF_RULES_RLOCK();
2876                 if (pq->ticket != V_ticket_altqs_active) {
2877                         PF_RULES_RUNLOCK();
2878                         error = EBUSY;
2879                         break;
2880                 }
2881                 nbytes = pq->nbytes;
2882                 altq = pf_altq_get_nth_active(pq->nr);
2883                 if (altq == NULL) {
2884                         PF_RULES_RUNLOCK();
2885                         error = EBUSY;
2886                         break;
2887                 }
2888
2889                 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) != 0) {
2890                         PF_RULES_RUNLOCK();
2891                         error = ENXIO;
2892                         break;
2893                 }
2894                 PF_RULES_RUNLOCK();
2895                 if (cmd == DIOCGETQSTATSV0)
2896                         version = 0;  /* DIOCGETQSTATSV0 means stats struct v0 */
2897                 else
2898                         version = pq->version;
2899                 error = altq_getqstats(altq, pq->buf, &nbytes, version);
2900                 if (error == 0) {
2901                         pq->scheduler = altq->scheduler;
2902                         pq->nbytes = nbytes;
2903                 }
2904                 break;
2905         }
2906 #endif /* ALTQ */
2907
2908         case DIOCBEGINADDRS: {
2909                 struct pfioc_pooladdr   *pp = (struct pfioc_pooladdr *)addr;
2910
2911                 PF_RULES_WLOCK();
2912                 pf_empty_kpool(&V_pf_pabuf);
2913                 pp->ticket = ++V_ticket_pabuf;
2914                 PF_RULES_WUNLOCK();
2915                 break;
2916         }
2917
2918         case DIOCADDADDR: {
2919                 struct pfioc_pooladdr   *pp = (struct pfioc_pooladdr *)addr;
2920                 struct pf_kpooladdr     *pa;
2921                 struct pfi_kkif         *kif = NULL;
2922
2923 #ifndef INET
2924                 if (pp->af == AF_INET) {
2925                         error = EAFNOSUPPORT;
2926                         break;
2927                 }
2928 #endif /* INET */
2929 #ifndef INET6
2930                 if (pp->af == AF_INET6) {
2931                         error = EAFNOSUPPORT;
2932                         break;
2933                 }
2934 #endif /* INET6 */
2935                 if (pp->addr.addr.type != PF_ADDR_ADDRMASK &&
2936                     pp->addr.addr.type != PF_ADDR_DYNIFTL &&
2937                     pp->addr.addr.type != PF_ADDR_TABLE) {
2938                         error = EINVAL;
2939                         break;
2940                 }
2941                 if (pp->addr.addr.p.dyn != NULL) {
2942                         error = EINVAL;
2943                         break;
2944                 }
2945                 pa = malloc(sizeof(*pa), M_PFRULE, M_WAITOK);
2946                 pf_pooladdr_to_kpooladdr(&pp->addr, pa);
2947                 if (pa->ifname[0])
2948                         kif = pf_kkif_create(M_WAITOK);
2949                 PF_RULES_WLOCK();
2950                 if (pp->ticket != V_ticket_pabuf) {
2951                         PF_RULES_WUNLOCK();
2952                         if (pa->ifname[0])
2953                                 pf_kkif_free(kif);
2954                         free(pa, M_PFRULE);
2955                         error = EBUSY;
2956                         break;
2957                 }
2958                 if (pa->ifname[0]) {
2959                         pa->kif = pfi_kkif_attach(kif, pa->ifname);
2960                         pfi_kkif_ref(pa->kif);
2961                 } else
2962                         pa->kif = NULL;
2963                 if (pa->addr.type == PF_ADDR_DYNIFTL && ((error =
2964                     pfi_dynaddr_setup(&pa->addr, pp->af)) != 0)) {
2965                         if (pa->ifname[0])
2966                                 pfi_kkif_unref(pa->kif);
2967                         PF_RULES_WUNLOCK();
2968                         free(pa, M_PFRULE);
2969                         break;
2970                 }
2971                 TAILQ_INSERT_TAIL(&V_pf_pabuf, pa, entries);
2972                 PF_RULES_WUNLOCK();
2973                 break;
2974         }
2975
2976         case DIOCGETADDRS: {
2977                 struct pfioc_pooladdr   *pp = (struct pfioc_pooladdr *)addr;
2978                 struct pf_kpool         *pool;
2979                 struct pf_kpooladdr     *pa;
2980
2981                 PF_RULES_RLOCK();
2982                 pp->nr = 0;
2983                 pool = pf_get_kpool(pp->anchor, pp->ticket, pp->r_action,
2984                     pp->r_num, 0, 1, 0);
2985                 if (pool == NULL) {
2986                         PF_RULES_RUNLOCK();
2987                         error = EBUSY;
2988                         break;
2989                 }
2990                 TAILQ_FOREACH(pa, &pool->list, entries)
2991                         pp->nr++;
2992                 PF_RULES_RUNLOCK();
2993                 break;
2994         }
2995
2996         case DIOCGETADDR: {
2997                 struct pfioc_pooladdr   *pp = (struct pfioc_pooladdr *)addr;
2998                 struct pf_kpool         *pool;
2999                 struct pf_kpooladdr     *pa;
3000                 u_int32_t                nr = 0;
3001
3002                 PF_RULES_RLOCK();
3003                 pool = pf_get_kpool(pp->anchor, pp->ticket, pp->r_action,
3004                     pp->r_num, 0, 1, 1);
3005                 if (pool == NULL) {
3006                         PF_RULES_RUNLOCK();
3007                         error = EBUSY;
3008                         break;
3009                 }
3010                 pa = TAILQ_FIRST(&pool->list);
3011                 while ((pa != NULL) && (nr < pp->nr)) {
3012                         pa = TAILQ_NEXT(pa, entries);
3013                         nr++;
3014                 }
3015                 if (pa == NULL) {
3016                         PF_RULES_RUNLOCK();
3017                         error = EBUSY;
3018                         break;
3019                 }
3020                 pf_kpooladdr_to_pooladdr(pa, &pp->addr);
3021                 pf_addr_copyout(&pp->addr.addr);
3022                 PF_RULES_RUNLOCK();
3023                 break;
3024         }
3025
3026         case DIOCCHANGEADDR: {
3027                 struct pfioc_pooladdr   *pca = (struct pfioc_pooladdr *)addr;
3028                 struct pf_kpool         *pool;
3029                 struct pf_kpooladdr     *oldpa = NULL, *newpa = NULL;
3030                 struct pf_kruleset      *ruleset;
3031                 struct pfi_kkif         *kif = NULL;
3032
3033                 if (pca->action < PF_CHANGE_ADD_HEAD ||
3034                     pca->action > PF_CHANGE_REMOVE) {
3035                         error = EINVAL;
3036                         break;
3037                 }
3038                 if (pca->addr.addr.type != PF_ADDR_ADDRMASK &&
3039                     pca->addr.addr.type != PF_ADDR_DYNIFTL &&
3040                     pca->addr.addr.type != PF_ADDR_TABLE) {
3041                         error = EINVAL;
3042                         break;
3043                 }
3044                 if (pca->addr.addr.p.dyn != NULL) {
3045                         error = EINVAL;
3046                         break;
3047                 }
3048
3049                 if (pca->action != PF_CHANGE_REMOVE) {
3050 #ifndef INET
3051                         if (pca->af == AF_INET) {
3052                                 error = EAFNOSUPPORT;
3053                                 break;
3054                         }
3055 #endif /* INET */
3056 #ifndef INET6
3057                         if (pca->af == AF_INET6) {
3058                                 error = EAFNOSUPPORT;
3059                                 break;
3060                         }
3061 #endif /* INET6 */
3062                         newpa = malloc(sizeof(*newpa), M_PFRULE, M_WAITOK);
3063                         bcopy(&pca->addr, newpa, sizeof(struct pf_pooladdr));
3064                         if (newpa->ifname[0])
3065                                 kif = pf_kkif_create(M_WAITOK);
3066                         newpa->kif = NULL;
3067                 }
3068 #define ERROUT(x)       { error = (x); goto DIOCCHANGEADDR_error; }
3069                 PF_RULES_WLOCK();
3070                 ruleset = pf_find_kruleset(pca->anchor);
3071                 if (ruleset == NULL)
3072                         ERROUT(EBUSY);
3073
3074                 pool = pf_get_kpool(pca->anchor, pca->ticket, pca->r_action,
3075                     pca->r_num, pca->r_last, 1, 1);
3076                 if (pool == NULL)
3077                         ERROUT(EBUSY);
3078
3079                 if (pca->action != PF_CHANGE_REMOVE) {
3080                         if (newpa->ifname[0]) {
3081                                 newpa->kif = pfi_kkif_attach(kif, newpa->ifname);
3082                                 pfi_kkif_ref(newpa->kif);
3083                                 kif = NULL;
3084                         }
3085
3086                         switch (newpa->addr.type) {
3087                         case PF_ADDR_DYNIFTL:
3088                                 error = pfi_dynaddr_setup(&newpa->addr,
3089                                     pca->af);
3090                                 break;
3091                         case PF_ADDR_TABLE:
3092                                 newpa->addr.p.tbl = pfr_attach_table(ruleset,
3093                                     newpa->addr.v.tblname);
3094                                 if (newpa->addr.p.tbl == NULL)
3095                                         error = ENOMEM;
3096                                 break;
3097                         }
3098                         if (error)
3099                                 goto DIOCCHANGEADDR_error;
3100                 }
3101
3102                 switch (pca->action) {
3103                 case PF_CHANGE_ADD_HEAD:
3104                         oldpa = TAILQ_FIRST(&pool->list);
3105                         break;
3106                 case PF_CHANGE_ADD_TAIL:
3107                         oldpa = TAILQ_LAST(&pool->list, pf_kpalist);
3108                         break;
3109                 default:
3110                         oldpa = TAILQ_FIRST(&pool->list);
3111                         for (int i = 0; oldpa && i < pca->nr; i++)
3112                                 oldpa = TAILQ_NEXT(oldpa, entries);
3113
3114                         if (oldpa == NULL)
3115                                 ERROUT(EINVAL);
3116                 }
3117
3118                 if (pca->action == PF_CHANGE_REMOVE) {
3119                         TAILQ_REMOVE(&pool->list, oldpa, entries);
3120                         switch (oldpa->addr.type) {
3121                         case PF_ADDR_DYNIFTL:
3122                                 pfi_dynaddr_remove(oldpa->addr.p.dyn);
3123                                 break;
3124                         case PF_ADDR_TABLE:
3125                                 pfr_detach_table(oldpa->addr.p.tbl);
3126                                 break;
3127                         }
3128                         if (oldpa->kif)
3129                                 pfi_kkif_unref(oldpa->kif);
3130                         free(oldpa, M_PFRULE);
3131                 } else {
3132                         if (oldpa == NULL)
3133                                 TAILQ_INSERT_TAIL(&pool->list, newpa, entries);
3134                         else if (pca->action == PF_CHANGE_ADD_HEAD ||
3135                             pca->action == PF_CHANGE_ADD_BEFORE)
3136                                 TAILQ_INSERT_BEFORE(oldpa, newpa, entries);
3137                         else
3138                                 TAILQ_INSERT_AFTER(&pool->list, oldpa,
3139                                     newpa, entries);
3140                 }
3141
3142                 pool->cur = TAILQ_FIRST(&pool->list);
3143                 PF_ACPY(&pool->counter, &pool->cur->addr.v.a.addr, pca->af);
3144                 PF_RULES_WUNLOCK();
3145                 break;
3146
3147 #undef ERROUT
3148 DIOCCHANGEADDR_error:
3149                 if (newpa != NULL) {
3150                         if (newpa->kif)
3151                                 pfi_kkif_unref(newpa->kif);
3152                         free(newpa, M_PFRULE);
3153                 }
3154                 PF_RULES_WUNLOCK();
3155                 if (kif != NULL)
3156                         pf_kkif_free(kif);
3157                 break;
3158         }
3159
3160         case DIOCGETRULESETS: {
3161                 struct pfioc_ruleset    *pr = (struct pfioc_ruleset *)addr;
3162                 struct pf_kruleset      *ruleset;
3163                 struct pf_kanchor       *anchor;
3164
3165                 PF_RULES_RLOCK();
3166                 pr->path[sizeof(pr->path) - 1] = 0;
3167                 if ((ruleset = pf_find_kruleset(pr->path)) == NULL) {
3168                         PF_RULES_RUNLOCK();
3169                         error = ENOENT;
3170                         break;
3171                 }
3172                 pr->nr = 0;
3173                 if (ruleset->anchor == NULL) {
3174                         /* XXX kludge for pf_main_ruleset */
3175                         RB_FOREACH(anchor, pf_kanchor_global, &V_pf_anchors)
3176                                 if (anchor->parent == NULL)
3177                                         pr->nr++;
3178                 } else {
3179                         RB_FOREACH(anchor, pf_kanchor_node,
3180                             &ruleset->anchor->children)
3181                                 pr->nr++;
3182                 }
3183                 PF_RULES_RUNLOCK();
3184                 break;
3185         }
3186
3187         case DIOCGETRULESET: {
3188                 struct pfioc_ruleset    *pr = (struct pfioc_ruleset *)addr;
3189                 struct pf_kruleset      *ruleset;
3190                 struct pf_kanchor       *anchor;
3191                 u_int32_t                nr = 0;
3192
3193                 PF_RULES_RLOCK();
3194                 pr->path[sizeof(pr->path) - 1] = 0;
3195                 if ((ruleset = pf_find_kruleset(pr->path)) == NULL) {
3196                         PF_RULES_RUNLOCK();
3197                         error = ENOENT;
3198                         break;
3199                 }
3200                 pr->name[0] = 0;
3201                 if (ruleset->anchor == NULL) {
3202                         /* XXX kludge for pf_main_ruleset */
3203                         RB_FOREACH(anchor, pf_kanchor_global, &V_pf_anchors)
3204                                 if (anchor->parent == NULL && nr++ == pr->nr) {
3205                                         strlcpy(pr->name, anchor->name,
3206                                             sizeof(pr->name));
3207                                         break;
3208                                 }
3209                 } else {
3210                         RB_FOREACH(anchor, pf_kanchor_node,
3211                             &ruleset->anchor->children)
3212                                 if (nr++ == pr->nr) {
3213                                         strlcpy(pr->name, anchor->name,
3214                                             sizeof(pr->name));
3215                                         break;
3216                                 }
3217                 }
3218                 if (!pr->name[0])
3219                         error = EBUSY;
3220                 PF_RULES_RUNLOCK();
3221                 break;
3222         }
3223
3224         case DIOCRCLRTABLES: {
3225                 struct pfioc_table *io = (struct pfioc_table *)addr;
3226
3227                 if (io->pfrio_esize != 0) {
3228                         error = ENODEV;
3229                         break;
3230                 }
3231                 PF_RULES_WLOCK();
3232                 error = pfr_clr_tables(&io->pfrio_table, &io->pfrio_ndel,
3233                     io->pfrio_flags | PFR_FLAG_USERIOCTL);
3234                 PF_RULES_WUNLOCK();
3235                 break;
3236         }
3237
3238         case DIOCRADDTABLES: {
3239                 struct pfioc_table *io = (struct pfioc_table *)addr;
3240                 struct pfr_table *pfrts;
3241                 size_t totlen;
3242
3243                 if (io->pfrio_esize != sizeof(struct pfr_table)) {
3244                         error = ENODEV;
3245                         break;
3246                 }
3247
3248                 if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount ||
3249                     WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) {
3250                         error = ENOMEM;
3251                         break;
3252                 }
3253
3254                 totlen = io->pfrio_size * sizeof(struct pfr_table);
3255                 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
3256                     M_TEMP, M_WAITOK);
3257                 error = copyin(io->pfrio_buffer, pfrts, totlen);
3258                 if (error) {
3259                         free(pfrts, M_TEMP);
3260                         break;
3261                 }
3262                 PF_RULES_WLOCK();
3263                 error = pfr_add_tables(pfrts, io->pfrio_size,
3264                     &io->pfrio_nadd, io->pfrio_flags | PFR_FLAG_USERIOCTL);
3265                 PF_RULES_WUNLOCK();
3266                 free(pfrts, M_TEMP);
3267                 break;
3268         }
3269
3270         case DIOCRDELTABLES: {
3271                 struct pfioc_table *io = (struct pfioc_table *)addr;
3272                 struct pfr_table *pfrts;
3273                 size_t totlen;
3274
3275                 if (io->pfrio_esize != sizeof(struct pfr_table)) {
3276                         error = ENODEV;
3277                         break;
3278                 }
3279
3280                 if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount ||
3281                     WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) {
3282                         error = ENOMEM;
3283                         break;
3284                 }
3285
3286                 totlen = io->pfrio_size * sizeof(struct pfr_table);
3287                 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
3288                     M_TEMP, M_WAITOK);
3289                 error = copyin(io->pfrio_buffer, pfrts, totlen);
3290                 if (error) {
3291                         free(pfrts, M_TEMP);
3292                         break;
3293                 }
3294                 PF_RULES_WLOCK();
3295                 error = pfr_del_tables(pfrts, io->pfrio_size,
3296                     &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
3297                 PF_RULES_WUNLOCK();
3298                 free(pfrts, M_TEMP);
3299                 break;
3300         }
3301
3302         case DIOCRGETTABLES: {
3303                 struct pfioc_table *io = (struct pfioc_table *)addr;
3304                 struct pfr_table *pfrts;
3305                 size_t totlen;
3306                 int n;
3307
3308                 if (io->pfrio_esize != sizeof(struct pfr_table)) {
3309                         error = ENODEV;
3310                         break;
3311                 }
3312                 PF_RULES_RLOCK();
3313                 n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
3314                 if (n < 0) {
3315                         PF_RULES_RUNLOCK();
3316                         error = EINVAL;
3317                         break;
3318                 }
3319                 io->pfrio_size = min(io->pfrio_size, n);
3320
3321                 totlen = io->pfrio_size * sizeof(struct pfr_table);
3322
3323                 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
3324                     M_TEMP, M_NOWAIT);
3325                 if (pfrts == NULL) {
3326                         error = ENOMEM;
3327                         PF_RULES_RUNLOCK();
3328                         break;
3329                 }
3330                 error = pfr_get_tables(&io->pfrio_table, pfrts,
3331                     &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
3332                 PF_RULES_RUNLOCK();
3333                 if (error == 0)
3334                         error = copyout(pfrts, io->pfrio_buffer, totlen);
3335                 free(pfrts, M_TEMP);
3336                 break;
3337         }
3338
3339         case DIOCRGETTSTATS: {
3340                 struct pfioc_table *io = (struct pfioc_table *)addr;
3341                 struct pfr_tstats *pfrtstats;
3342                 size_t totlen;
3343                 int n;
3344
3345                 if (io->pfrio_esize != sizeof(struct pfr_tstats)) {
3346                         error = ENODEV;
3347                         break;
3348                 }
3349                 PF_RULES_WLOCK();
3350                 n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
3351                 if (n < 0) {
3352                         PF_RULES_WUNLOCK();
3353                         error = EINVAL;
3354                         break;
3355                 }
3356                 io->pfrio_size = min(io->pfrio_size, n);
3357
3358                 totlen = io->pfrio_size * sizeof(struct pfr_tstats);
3359                 pfrtstats = mallocarray(io->pfrio_size,
3360                     sizeof(struct pfr_tstats), M_TEMP, M_NOWAIT);
3361                 if (pfrtstats == NULL) {
3362                         error = ENOMEM;
3363                         PF_RULES_WUNLOCK();
3364                         break;
3365                 }
3366                 error = pfr_get_tstats(&io->pfrio_table, pfrtstats,
3367                     &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
3368                 PF_RULES_WUNLOCK();
3369                 if (error == 0)
3370                         error = copyout(pfrtstats, io->pfrio_buffer, totlen);
3371                 free(pfrtstats, M_TEMP);
3372                 break;
3373         }
3374
3375         case DIOCRCLRTSTATS: {
3376                 struct pfioc_table *io = (struct pfioc_table *)addr;
3377                 struct pfr_table *pfrts;
3378                 size_t totlen;
3379
3380                 if (io->pfrio_esize != sizeof(struct pfr_table)) {
3381                         error = ENODEV;
3382                         break;
3383                 }
3384
3385                 if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount ||
3386                     WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) {
3387                         /* We used to count tables and use the minimum required
3388                          * size, so we didn't fail on overly large requests.
3389                          * Keep doing so. */
3390                         io->pfrio_size = pf_ioctl_maxcount;
3391                         break;
3392                 }
3393
3394                 totlen = io->pfrio_size * sizeof(struct pfr_table);
3395                 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
3396                     M_TEMP, M_NOWAIT);
3397                 if (pfrts == NULL) {
3398                         error = ENOMEM;
3399                         break;
3400                 }
3401                 error = copyin(io->pfrio_buffer, pfrts, totlen);
3402                 if (error) {
3403                         free(pfrts, M_TEMP);
3404                         break;
3405                 }
3406
3407                 PF_RULES_WLOCK();
3408                 error = pfr_clr_tstats(pfrts, io->pfrio_size,
3409                     &io->pfrio_nzero, io->pfrio_flags | PFR_FLAG_USERIOCTL);
3410                 PF_RULES_WUNLOCK();
3411                 free(pfrts, M_TEMP);
3412                 break;
3413         }
3414
3415         case DIOCRSETTFLAGS: {
3416                 struct pfioc_table *io = (struct pfioc_table *)addr;
3417                 struct pfr_table *pfrts;
3418                 size_t totlen;
3419                 int n;
3420
3421                 if (io->pfrio_esize != sizeof(struct pfr_table)) {
3422                         error = ENODEV;
3423                         break;
3424                 }
3425
3426                 PF_RULES_RLOCK();
3427                 n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
3428                 if (n < 0) {
3429                         PF_RULES_RUNLOCK();
3430                         error = EINVAL;
3431                         break;
3432                 }
3433
3434                 io->pfrio_size = min(io->pfrio_size, n);
3435                 PF_RULES_RUNLOCK();
3436
3437                 totlen = io->pfrio_size * sizeof(struct pfr_table);
3438                 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
3439                     M_TEMP, M_WAITOK);
3440                 error = copyin(io->pfrio_buffer, pfrts, totlen);
3441                 if (error) {
3442                         free(pfrts, M_TEMP);
3443                         break;
3444                 }
3445                 PF_RULES_WLOCK();
3446                 error = pfr_set_tflags(pfrts, io->pfrio_size,
3447                     io->pfrio_setflag, io->pfrio_clrflag, &io->pfrio_nchange,
3448                     &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
3449                 PF_RULES_WUNLOCK();
3450                 free(pfrts, M_TEMP);
3451                 break;
3452         }
3453
3454         case DIOCRCLRADDRS: {
3455                 struct pfioc_table *io = (struct pfioc_table *)addr;
3456
3457                 if (io->pfrio_esize != 0) {
3458                         error = ENODEV;
3459                         break;
3460                 }
3461                 PF_RULES_WLOCK();
3462                 error = pfr_clr_addrs(&io->pfrio_table, &io->pfrio_ndel,
3463                     io->pfrio_flags | PFR_FLAG_USERIOCTL);
3464                 PF_RULES_WUNLOCK();
3465                 break;
3466         }
3467
3468         case DIOCRADDADDRS: {
3469                 struct pfioc_table *io = (struct pfioc_table *)addr;
3470                 struct pfr_addr *pfras;
3471                 size_t totlen;
3472
3473                 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
3474                         error = ENODEV;
3475                         break;
3476                 }
3477                 if (io->pfrio_size < 0 ||
3478                     io->pfrio_size > pf_ioctl_maxcount ||
3479                     WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
3480                         error = EINVAL;
3481                         break;
3482                 }
3483                 totlen = io->pfrio_size * sizeof(struct pfr_addr);
3484                 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
3485                     M_TEMP, M_NOWAIT);
3486                 if (! pfras) {
3487                         error = ENOMEM;
3488                         break;
3489                 }
3490                 error = copyin(io->pfrio_buffer, pfras, totlen);
3491                 if (error) {
3492                         free(pfras, M_TEMP);
3493                         break;
3494                 }
3495                 PF_RULES_WLOCK();
3496                 error = pfr_add_addrs(&io->pfrio_table, pfras,
3497                     io->pfrio_size, &io->pfrio_nadd, io->pfrio_flags |
3498                     PFR_FLAG_USERIOCTL);
3499                 PF_RULES_WUNLOCK();
3500                 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
3501                         error = copyout(pfras, io->pfrio_buffer, totlen);
3502                 free(pfras, M_TEMP);
3503                 break;
3504         }
3505
3506         case DIOCRDELADDRS: {
3507                 struct pfioc_table *io = (struct pfioc_table *)addr;
3508                 struct pfr_addr *pfras;
3509                 size_t totlen;
3510
3511                 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
3512                         error = ENODEV;
3513                         break;
3514                 }
3515                 if (io->pfrio_size < 0 ||
3516                     io->pfrio_size > pf_ioctl_maxcount ||
3517                     WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
3518                         error = EINVAL;
3519                         break;
3520                 }
3521                 totlen = io->pfrio_size * sizeof(struct pfr_addr);
3522                 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
3523                     M_TEMP, M_NOWAIT);
3524                 if (! pfras) {
3525                         error = ENOMEM;
3526                         break;
3527                 }
3528                 error = copyin(io->pfrio_buffer, pfras, totlen);
3529                 if (error) {
3530                         free(pfras, M_TEMP);
3531                         break;
3532                 }
3533                 PF_RULES_WLOCK();
3534                 error = pfr_del_addrs(&io->pfrio_table, pfras,
3535                     io->pfrio_size, &io->pfrio_ndel, io->pfrio_flags |
3536                     PFR_FLAG_USERIOCTL);
3537                 PF_RULES_WUNLOCK();
3538                 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
3539                         error = copyout(pfras, io->pfrio_buffer, totlen);
3540                 free(pfras, M_TEMP);
3541                 break;
3542         }
3543
3544         case DIOCRSETADDRS: {
3545                 struct pfioc_table *io = (struct pfioc_table *)addr;
3546                 struct pfr_addr *pfras;
3547                 size_t totlen, count;
3548
3549                 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
3550                         error = ENODEV;
3551                         break;
3552                 }
3553                 if (io->pfrio_size < 0 || io->pfrio_size2 < 0) {
3554                         error = EINVAL;
3555                         break;
3556                 }
3557                 count = max(io->pfrio_size, io->pfrio_size2);
3558                 if (count > pf_ioctl_maxcount ||
3559                     WOULD_OVERFLOW(count, sizeof(struct pfr_addr))) {
3560                         error = EINVAL;
3561                         break;
3562                 }
3563                 totlen = count * sizeof(struct pfr_addr);
3564                 pfras = mallocarray(count, sizeof(struct pfr_addr), M_TEMP,
3565                     M_NOWAIT);
3566                 if (! pfras) {
3567                         error = ENOMEM;
3568                         break;
3569                 }
3570                 error = copyin(io->pfrio_buffer, pfras, totlen);
3571                 if (error) {
3572                         free(pfras, M_TEMP);
3573                         break;
3574                 }
3575                 PF_RULES_WLOCK();
3576                 error = pfr_set_addrs(&io->pfrio_table, pfras,
3577                     io->pfrio_size, &io->pfrio_size2, &io->pfrio_nadd,
3578                     &io->pfrio_ndel, &io->pfrio_nchange, io->pfrio_flags |
3579                     PFR_FLAG_USERIOCTL, 0);
3580                 PF_RULES_WUNLOCK();
3581                 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
3582                         error = copyout(pfras, io->pfrio_buffer, totlen);
3583                 free(pfras, M_TEMP);
3584                 break;
3585         }
3586
3587         case DIOCRGETADDRS: {
3588                 struct pfioc_table *io = (struct pfioc_table *)addr;
3589                 struct pfr_addr *pfras;
3590                 size_t totlen;
3591
3592                 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
3593                         error = ENODEV;
3594                         break;
3595                 }
3596                 if (io->pfrio_size < 0 ||
3597                     io->pfrio_size > pf_ioctl_maxcount ||
3598                     WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
3599                         error = EINVAL;
3600                         break;
3601                 }
3602                 totlen = io->pfrio_size * sizeof(struct pfr_addr);
3603                 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
3604                     M_TEMP, M_NOWAIT);
3605                 if (! pfras) {
3606                         error = ENOMEM;
3607                         break;
3608                 }
3609                 PF_RULES_RLOCK();
3610                 error = pfr_get_addrs(&io->pfrio_table, pfras,
3611                     &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
3612                 PF_RULES_RUNLOCK();
3613                 if (error == 0)
3614                         error = copyout(pfras, io->pfrio_buffer, totlen);
3615                 free(pfras, M_TEMP);
3616                 break;
3617         }
3618
3619         case DIOCRGETASTATS: {
3620                 struct pfioc_table *io = (struct pfioc_table *)addr;
3621                 struct pfr_astats *pfrastats;
3622                 size_t totlen;
3623
3624                 if (io->pfrio_esize != sizeof(struct pfr_astats)) {
3625                         error = ENODEV;
3626                         break;
3627                 }
3628                 if (io->pfrio_size < 0 ||
3629                     io->pfrio_size > pf_ioctl_maxcount ||
3630                     WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_astats))) {
3631                         error = EINVAL;
3632                         break;
3633                 }
3634                 totlen = io->pfrio_size * sizeof(struct pfr_astats);
3635                 pfrastats = mallocarray(io->pfrio_size,
3636                     sizeof(struct pfr_astats), M_TEMP, M_NOWAIT);
3637                 if (! pfrastats) {
3638                         error = ENOMEM;
3639                         break;
3640                 }
3641                 PF_RULES_RLOCK();
3642                 error = pfr_get_astats(&io->pfrio_table, pfrastats,
3643                     &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
3644                 PF_RULES_RUNLOCK();
3645                 if (error == 0)
3646                         error = copyout(pfrastats, io->pfrio_buffer, totlen);
3647                 free(pfrastats, M_TEMP);
3648                 break;
3649         }
3650
3651         case DIOCRCLRASTATS: {
3652                 struct pfioc_table *io = (struct pfioc_table *)addr;
3653                 struct pfr_addr *pfras;
3654                 size_t totlen;
3655
3656                 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
3657                         error = ENODEV;
3658                         break;
3659                 }
3660                 if (io->pfrio_size < 0 ||
3661                     io->pfrio_size > pf_ioctl_maxcount ||
3662                     WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
3663                         error = EINVAL;
3664                         break;
3665                 }
3666                 totlen = io->pfrio_size * sizeof(struct pfr_addr);
3667                 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
3668                     M_TEMP, M_NOWAIT);
3669                 if (! pfras) {
3670                         error = ENOMEM;
3671                         break;
3672                 }
3673                 error = copyin(io->pfrio_buffer, pfras, totlen);
3674                 if (error) {
3675                         free(pfras, M_TEMP);
3676                         break;
3677                 }
3678                 PF_RULES_WLOCK();
3679                 error = pfr_clr_astats(&io->pfrio_table, pfras,
3680                     io->pfrio_size, &io->pfrio_nzero, io->pfrio_flags |
3681                     PFR_FLAG_USERIOCTL);
3682                 PF_RULES_WUNLOCK();
3683                 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
3684                         error = copyout(pfras, io->pfrio_buffer, totlen);
3685                 free(pfras, M_TEMP);
3686                 break;
3687         }
3688
3689         case DIOCRTSTADDRS: {
3690                 struct pfioc_table *io = (struct pfioc_table *)addr;
3691                 struct pfr_addr *pfras;
3692                 size_t totlen;
3693
3694                 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
3695                         error = ENODEV;
3696                         break;
3697                 }
3698                 if (io->pfrio_size < 0 ||
3699                     io->pfrio_size > pf_ioctl_maxcount ||
3700                     WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
3701                         error = EINVAL;
3702                         break;
3703                 }
3704                 totlen = io->pfrio_size * sizeof(struct pfr_addr);
3705                 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
3706                     M_TEMP, M_NOWAIT);
3707                 if (! pfras) {
3708                         error = ENOMEM;
3709                         break;
3710                 }
3711                 error = copyin(io->pfrio_buffer, pfras, totlen);
3712                 if (error) {
3713                         free(pfras, M_TEMP);
3714                         break;
3715                 }
3716                 PF_RULES_RLOCK();
3717                 error = pfr_tst_addrs(&io->pfrio_table, pfras,
3718                     io->pfrio_size, &io->pfrio_nmatch, io->pfrio_flags |
3719                     PFR_FLAG_USERIOCTL);
3720                 PF_RULES_RUNLOCK();
3721                 if (error == 0)
3722                         error = copyout(pfras, io->pfrio_buffer, totlen);
3723                 free(pfras, M_TEMP);
3724                 break;
3725         }
3726
3727         case DIOCRINADEFINE: {
3728                 struct pfioc_table *io = (struct pfioc_table *)addr;
3729                 struct pfr_addr *pfras;
3730                 size_t totlen;
3731
3732                 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
3733                         error = ENODEV;
3734                         break;
3735                 }
3736                 if (io->pfrio_size < 0 ||
3737                     io->pfrio_size > pf_ioctl_maxcount ||
3738                     WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
3739                         error = EINVAL;
3740                         break;
3741                 }
3742                 totlen = io->pfrio_size * sizeof(struct pfr_addr);
3743                 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
3744                     M_TEMP, M_NOWAIT);
3745                 if (! pfras) {
3746                         error = ENOMEM;
3747                         break;
3748                 }
3749                 error = copyin(io->pfrio_buffer, pfras, totlen);
3750                 if (error) {
3751                         free(pfras, M_TEMP);
3752                         break;
3753                 }
3754                 PF_RULES_WLOCK();
3755                 error = pfr_ina_define(&io->pfrio_table, pfras,
3756                     io->pfrio_size, &io->pfrio_nadd, &io->pfrio_naddr,
3757                     io->pfrio_ticket, io->pfrio_flags | PFR_FLAG_USERIOCTL);
3758                 PF_RULES_WUNLOCK();
3759                 free(pfras, M_TEMP);
3760                 break;
3761         }
3762
3763         case DIOCOSFPADD: {
3764                 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
3765                 PF_RULES_WLOCK();
3766                 error = pf_osfp_add(io);
3767                 PF_RULES_WUNLOCK();
3768                 break;
3769         }
3770
3771         case DIOCOSFPGET: {
3772                 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
3773                 PF_RULES_RLOCK();
3774                 error = pf_osfp_get(io);
3775                 PF_RULES_RUNLOCK();
3776                 break;
3777         }
3778
3779         case DIOCXBEGIN: {
3780                 struct pfioc_trans      *io = (struct pfioc_trans *)addr;
3781                 struct pfioc_trans_e    *ioes, *ioe;
3782                 size_t                   totlen;
3783                 int                      i;
3784
3785                 if (io->esize != sizeof(*ioe)) {
3786                         error = ENODEV;
3787                         break;
3788                 }
3789                 if (io->size < 0 ||
3790                     io->size > pf_ioctl_maxcount ||
3791                     WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
3792                         error = EINVAL;
3793                         break;
3794                 }
3795                 totlen = sizeof(struct pfioc_trans_e) * io->size;
3796                 ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
3797                     M_TEMP, M_NOWAIT);
3798                 if (! ioes) {
3799                         error = ENOMEM;
3800                         break;
3801                 }
3802                 error = copyin(io->array, ioes, totlen);
3803                 if (error) {
3804                         free(ioes, M_TEMP);
3805                         break;
3806                 }
3807                 PF_RULES_WLOCK();
3808                 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
3809                         switch (ioe->rs_num) {
3810 #ifdef ALTQ
3811                         case PF_RULESET_ALTQ:
3812                                 if (ioe->anchor[0]) {
3813                                         PF_RULES_WUNLOCK();
3814                                         free(ioes, M_TEMP);
3815                                         error = EINVAL;
3816                                         goto fail;
3817                                 }
3818                                 if ((error = pf_begin_altq(&ioe->ticket))) {
3819                                         PF_RULES_WUNLOCK();
3820                                         free(ioes, M_TEMP);
3821                                         goto fail;
3822                                 }
3823                                 break;
3824 #endif /* ALTQ */
3825                         case PF_RULESET_TABLE:
3826                             {
3827                                 struct pfr_table table;
3828
3829                                 bzero(&table, sizeof(table));
3830                                 strlcpy(table.pfrt_anchor, ioe->anchor,
3831                                     sizeof(table.pfrt_anchor));
3832                                 if ((error = pfr_ina_begin(&table,
3833                                     &ioe->ticket, NULL, 0))) {
3834                                         PF_RULES_WUNLOCK();
3835                                         free(ioes, M_TEMP);
3836                                         goto fail;
3837                                 }
3838                                 break;
3839                             }
3840                         default:
3841                                 if ((error = pf_begin_rules(&ioe->ticket,
3842                                     ioe->rs_num, ioe->anchor))) {
3843                                         PF_RULES_WUNLOCK();
3844                                         free(ioes, M_TEMP);
3845                                         goto fail;
3846                                 }
3847                                 break;
3848                         }
3849                 }
3850                 PF_RULES_WUNLOCK();
3851                 error = copyout(ioes, io->array, totlen);
3852                 free(ioes, M_TEMP);
3853                 break;
3854         }
3855
3856         case DIOCXROLLBACK: {
3857                 struct pfioc_trans      *io = (struct pfioc_trans *)addr;
3858                 struct pfioc_trans_e    *ioe, *ioes;
3859                 size_t                   totlen;
3860                 int                      i;
3861
3862                 if (io->esize != sizeof(*ioe)) {
3863                         error = ENODEV;
3864                         break;
3865                 }
3866                 if (io->size < 0 ||
3867                     io->size > pf_ioctl_maxcount ||
3868                     WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
3869                         error = EINVAL;
3870                         break;
3871                 }
3872                 totlen = sizeof(struct pfioc_trans_e) * io->size;
3873                 ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
3874                     M_TEMP, M_NOWAIT);
3875                 if (! ioes) {
3876                         error = ENOMEM;
3877                         break;
3878                 }
3879                 error = copyin(io->array, ioes, totlen);
3880                 if (error) {
3881                         free(ioes, M_TEMP);
3882                         break;
3883                 }
3884                 PF_RULES_WLOCK();
3885                 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
3886                         switch (ioe->rs_num) {
3887 #ifdef ALTQ
3888                         case PF_RULESET_ALTQ:
3889                                 if (ioe->anchor[0]) {
3890                                         PF_RULES_WUNLOCK();
3891                                         free(ioes, M_TEMP);
3892                                         error = EINVAL;
3893                                         goto fail;
3894                                 }
3895                                 if ((error = pf_rollback_altq(ioe->ticket))) {
3896                                         PF_RULES_WUNLOCK();
3897                                         free(ioes, M_TEMP);
3898                                         goto fail; /* really bad */
3899                                 }
3900                                 break;
3901 #endif /* ALTQ */
3902                         case PF_RULESET_TABLE:
3903                             {
3904                                 struct pfr_table table;
3905
3906                                 bzero(&table, sizeof(table));
3907                                 strlcpy(table.pfrt_anchor, ioe->anchor,
3908                                     sizeof(table.pfrt_anchor));
3909                                 if ((error = pfr_ina_rollback(&table,
3910                                     ioe->ticket, NULL, 0))) {
3911                                         PF_RULES_WUNLOCK();
3912                                         free(ioes, M_TEMP);
3913                                         goto fail; /* really bad */
3914                                 }
3915                                 break;
3916                             }
3917                         default:
3918                                 if ((error = pf_rollback_rules(ioe->ticket,
3919                                     ioe->rs_num, ioe->anchor))) {
3920                                         PF_RULES_WUNLOCK();
3921                                         free(ioes, M_TEMP);
3922                                         goto fail; /* really bad */
3923                                 }
3924                                 break;
3925                         }
3926                 }
3927                 PF_RULES_WUNLOCK();
3928                 free(ioes, M_TEMP);
3929                 break;
3930         }
3931
3932         case DIOCXCOMMIT: {
3933                 struct pfioc_trans      *io = (struct pfioc_trans *)addr;
3934                 struct pfioc_trans_e    *ioe, *ioes;
3935                 struct pf_kruleset      *rs;
3936                 size_t                   totlen;
3937                 int                      i;
3938
3939                 if (io->esize != sizeof(*ioe)) {
3940                         error = ENODEV;
3941                         break;
3942                 }
3943
3944                 if (io->size < 0 ||
3945                     io->size > pf_ioctl_maxcount ||
3946                     WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
3947                         error = EINVAL;
3948                         break;
3949                 }
3950
3951                 totlen = sizeof(struct pfioc_trans_e) * io->size;
3952                 ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
3953                     M_TEMP, M_NOWAIT);
3954                 if (ioes == NULL) {
3955                         error = ENOMEM;
3956                         break;
3957                 }
3958                 error = copyin(io->array, ioes, totlen);
3959                 if (error) {
3960                         free(ioes, M_TEMP);
3961                         break;
3962                 }
3963                 PF_RULES_WLOCK();
3964                 /* First makes sure everything will succeed. */
3965                 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
3966                         switch (ioe->rs_num) {
3967 #ifdef ALTQ
3968                         case PF_RULESET_ALTQ:
3969                                 if (ioe->anchor[0]) {
3970                                         PF_RULES_WUNLOCK();
3971                                         free(ioes, M_TEMP);
3972                                         error = EINVAL;
3973                                         goto fail;
3974                                 }
3975                                 if (!V_altqs_inactive_open || ioe->ticket !=
3976                                     V_ticket_altqs_inactive) {
3977                                         PF_RULES_WUNLOCK();
3978                                         free(ioes, M_TEMP);
3979                                         error = EBUSY;
3980                                         goto fail;
3981                                 }
3982                                 break;
3983 #endif /* ALTQ */
3984                         case PF_RULESET_TABLE:
3985                                 rs = pf_find_kruleset(ioe->anchor);
3986                                 if (rs == NULL || !rs->topen || ioe->ticket !=
3987                                     rs->tticket) {
3988                                         PF_RULES_WUNLOCK();
3989                                         free(ioes, M_TEMP);
3990                                         error = EBUSY;
3991                                         goto fail;
3992                                 }
3993                                 break;
3994                         default:
3995                                 if (ioe->rs_num < 0 || ioe->rs_num >=
3996                                     PF_RULESET_MAX) {
3997                                         PF_RULES_WUNLOCK();
3998                                         free(ioes, M_TEMP);
3999                                         error = EINVAL;
4000                                         goto fail;
4001                                 }
4002                                 rs = pf_find_kruleset(ioe->anchor);
4003                                 if (rs == NULL ||
4004                                     !rs->rules[ioe->rs_num].inactive.open ||
4005                                     rs->rules[ioe->rs_num].inactive.ticket !=
4006                                     ioe->ticket) {
4007                                         PF_RULES_WUNLOCK();
4008                                         free(ioes, M_TEMP);
4009                                         error = EBUSY;
4010                                         goto fail;
4011                                 }
4012                                 break;
4013                         }
4014                 }
4015                 /* Now do the commit - no errors should happen here. */
4016                 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
4017                         switch (ioe->rs_num) {
4018 #ifdef ALTQ
4019                         case PF_RULESET_ALTQ:
4020                                 if ((error = pf_commit_altq(ioe->ticket))) {
4021                                         PF_RULES_WUNLOCK();
4022                                         free(ioes, M_TEMP);
4023                                         goto fail; /* really bad */
4024                                 }
4025                                 break;
4026 #endif /* ALTQ */
4027                         case PF_RULESET_TABLE:
4028                             {
4029                                 struct pfr_table table;
4030
4031                                 bzero(&table, sizeof(table));
4032                                 strlcpy(table.pfrt_anchor, ioe->anchor,
4033                                     sizeof(table.pfrt_anchor));
4034                                 if ((error = pfr_ina_commit(&table,
4035                                     ioe->ticket, NULL, NULL, 0))) {
4036                                         PF_RULES_WUNLOCK();
4037                                         free(ioes, M_TEMP);
4038                                         goto fail; /* really bad */
4039                                 }
4040                                 break;
4041                             }
4042                         default:
4043                                 if ((error = pf_commit_rules(ioe->ticket,
4044                                     ioe->rs_num, ioe->anchor))) {
4045                                         PF_RULES_WUNLOCK();
4046                                         free(ioes, M_TEMP);
4047                                         goto fail; /* really bad */
4048                                 }
4049                                 break;
4050                         }
4051                 }
4052                 PF_RULES_WUNLOCK();
4053                 free(ioes, M_TEMP);
4054                 break;
4055         }
4056
4057         case DIOCGETSRCNODES: {
4058                 struct pfioc_src_nodes  *psn = (struct pfioc_src_nodes *)addr;
4059                 struct pf_srchash       *sh;
4060                 struct pf_ksrc_node     *n;
4061                 struct pf_src_node      *p, *pstore;
4062                 uint32_t                 i, nr = 0;
4063
4064                 for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask;
4065                                 i++, sh++) {
4066                         PF_HASHROW_LOCK(sh);
4067                         LIST_FOREACH(n, &sh->nodes, entry)
4068                                 nr++;
4069                         PF_HASHROW_UNLOCK(sh);
4070                 }
4071
4072                 psn->psn_len = min(psn->psn_len,
4073                     sizeof(struct pf_src_node) * nr);
4074
4075                 if (psn->psn_len == 0) {
4076                         psn->psn_len = sizeof(struct pf_src_node) * nr;
4077                         break;
4078                 }
4079
4080                 nr = 0;
4081
4082                 p = pstore = malloc(psn->psn_len, M_TEMP, M_WAITOK | M_ZERO);
4083                 for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask;
4084                     i++, sh++) {
4085                     PF_HASHROW_LOCK(sh);
4086                     LIST_FOREACH(n, &sh->nodes, entry) {
4087
4088                         if ((nr + 1) * sizeof(*p) > (unsigned)psn->psn_len)
4089                                 break;
4090
4091                         pf_src_node_copy(n, p);
4092
4093                         p++;
4094                         nr++;
4095                     }
4096                     PF_HASHROW_UNLOCK(sh);
4097                 }
4098                 error = copyout(pstore, psn->psn_src_nodes,
4099                     sizeof(struct pf_src_node) * nr);
4100                 if (error) {
4101                         free(pstore, M_TEMP);
4102                         break;
4103                 }
4104                 psn->psn_len = sizeof(struct pf_src_node) * nr;
4105                 free(pstore, M_TEMP);
4106                 break;
4107         }
4108
4109         case DIOCCLRSRCNODES: {
4110                 pf_clear_srcnodes(NULL);
4111                 pf_purge_expired_src_nodes();
4112                 break;
4113         }
4114
4115         case DIOCKILLSRCNODES:
4116                 pf_kill_srcnodes((struct pfioc_src_node_kill *)addr);
4117                 break;
4118
4119         case DIOCSETHOSTID: {
4120                 u_int32_t       *hostid = (u_int32_t *)addr;
4121
4122                 PF_RULES_WLOCK();
4123                 if (*hostid == 0)
4124                         V_pf_status.hostid = arc4random();
4125                 else
4126                         V_pf_status.hostid = *hostid;
4127                 PF_RULES_WUNLOCK();
4128                 break;
4129         }
4130
4131         case DIOCOSFPFLUSH:
4132                 PF_RULES_WLOCK();
4133                 pf_osfp_flush();
4134                 PF_RULES_WUNLOCK();
4135                 break;
4136
4137         case DIOCIGETIFACES: {
4138                 struct pfioc_iface *io = (struct pfioc_iface *)addr;
4139                 struct pfi_kif *ifstore;
4140                 size_t bufsiz;
4141
4142                 if (io->pfiio_esize != sizeof(struct pfi_kif)) {
4143                         error = ENODEV;
4144                         break;
4145                 }
4146
4147                 if (io->pfiio_size < 0 ||
4148                     io->pfiio_size > pf_ioctl_maxcount ||
4149                     WOULD_OVERFLOW(io->pfiio_size, sizeof(struct pfi_kif))) {
4150                         error = EINVAL;
4151                         break;
4152                 }
4153
4154                 bufsiz = io->pfiio_size * sizeof(struct pfi_kif);
4155                 ifstore = mallocarray(io->pfiio_size, sizeof(struct pfi_kif),
4156                     M_TEMP, M_NOWAIT);
4157                 if (ifstore == NULL) {
4158                         error = ENOMEM;
4159                         break;
4160                 }
4161
4162                 PF_RULES_RLOCK();
4163                 pfi_get_ifaces(io->pfiio_name, ifstore, &io->pfiio_size);
4164                 PF_RULES_RUNLOCK();
4165                 error = copyout(ifstore, io->pfiio_buffer, bufsiz);
4166                 free(ifstore, M_TEMP);
4167                 break;
4168         }
4169
4170         case DIOCSETIFFLAG: {
4171                 struct pfioc_iface *io = (struct pfioc_iface *)addr;
4172
4173                 PF_RULES_WLOCK();
4174                 error = pfi_set_flags(io->pfiio_name, io->pfiio_flags);
4175                 PF_RULES_WUNLOCK();
4176                 break;
4177         }
4178
4179         case DIOCCLRIFFLAG: {
4180                 struct pfioc_iface *io = (struct pfioc_iface *)addr;
4181
4182                 PF_RULES_WLOCK();
4183                 error = pfi_clear_flags(io->pfiio_name, io->pfiio_flags);
4184                 PF_RULES_WUNLOCK();
4185                 break;
4186         }
4187
4188         default:
4189                 error = ENODEV;
4190                 break;
4191         }
4192 fail:
4193         if (sx_xlocked(&pf_ioctl_lock))
4194                 sx_xunlock(&pf_ioctl_lock);
4195         CURVNET_RESTORE();
4196
4197         return (error);
4198 }
4199
4200 void
4201 pfsync_state_export(struct pfsync_state *sp, struct pf_state *st)
4202 {
4203         bzero(sp, sizeof(struct pfsync_state));
4204
4205         /* copy from state key */
4206         sp->key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
4207         sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1];
4208         sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0];
4209         sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1];
4210         sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0];
4211         sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1];
4212         sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0];
4213         sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1];
4214         sp->proto = st->key[PF_SK_WIRE]->proto;
4215         sp->af = st->key[PF_SK_WIRE]->af;
4216
4217         /* copy from state */
4218         strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname));
4219         bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr));
4220         sp->creation = htonl(time_uptime - st->creation);
4221         sp->expire = pf_state_expires(st);
4222         if (sp->expire <= time_uptime)
4223                 sp->expire = htonl(0);
4224         else
4225                 sp->expire = htonl(sp->expire - time_uptime);
4226
4227         sp->direction = st->direction;
4228         sp->log = st->log;
4229         sp->timeout = st->timeout;
4230         sp->state_flags = st->state_flags;
4231         if (st->src_node)
4232                 sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
4233         if (st->nat_src_node)
4234                 sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE;
4235
4236         sp->id = st->id;
4237         sp->creatorid = st->creatorid;
4238         pf_state_peer_hton(&st->src, &sp->src);
4239         pf_state_peer_hton(&st->dst, &sp->dst);
4240
4241         if (st->rule.ptr == NULL)
4242                 sp->rule = htonl(-1);
4243         else
4244                 sp->rule = htonl(st->rule.ptr->nr);
4245         if (st->anchor.ptr == NULL)
4246                 sp->anchor = htonl(-1);
4247         else
4248                 sp->anchor = htonl(st->anchor.ptr->nr);
4249         if (st->nat_rule.ptr == NULL)
4250                 sp->nat_rule = htonl(-1);
4251         else
4252                 sp->nat_rule = htonl(st->nat_rule.ptr->nr);
4253
4254         pf_state_counter_hton(counter_u64_fetch(st->packets[0]),
4255             sp->packets[0]);
4256         pf_state_counter_hton(counter_u64_fetch(st->packets[1]),
4257             sp->packets[1]);
4258         pf_state_counter_hton(counter_u64_fetch(st->bytes[0]), sp->bytes[0]);
4259         pf_state_counter_hton(counter_u64_fetch(st->bytes[1]), sp->bytes[1]);
4260
4261 }
4262
4263 static void
4264 pf_tbladdr_copyout(struct pf_addr_wrap *aw)
4265 {
4266         struct pfr_ktable *kt;
4267
4268         KASSERT(aw->type == PF_ADDR_TABLE, ("%s: type %u", __func__, aw->type));
4269
4270         kt = aw->p.tbl;
4271         if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
4272                 kt = kt->pfrkt_root;
4273         aw->p.tbl = NULL;
4274         aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ?
4275                 kt->pfrkt_cnt : -1;
4276 }
4277
4278 /*
4279  * XXX - Check for version missmatch!!!
4280  */
4281 static void
4282 pf_clear_states(void)
4283 {
4284         struct pf_state *s;
4285         u_int i;
4286
4287         for (i = 0; i <= pf_hashmask; i++) {
4288                 struct pf_idhash *ih = &V_pf_idhash[i];
4289 relock:
4290                 PF_HASHROW_LOCK(ih);
4291                 LIST_FOREACH(s, &ih->states, entry) {
4292                         s->timeout = PFTM_PURGE;
4293                         /* Don't send out individual delete messages. */
4294                         s->state_flags |= PFSTATE_NOSYNC;
4295                         pf_unlink_state(s, PF_ENTER_LOCKED);
4296                         goto relock;
4297                 }
4298                 PF_HASHROW_UNLOCK(ih);
4299         }
4300 }
4301
4302 static int
4303 pf_clear_tables(void)
4304 {
4305         struct pfioc_table io;
4306         int error;
4307
4308         bzero(&io, sizeof(io));
4309
4310         error = pfr_clr_tables(&io.pfrio_table, &io.pfrio_ndel,
4311             io.pfrio_flags);
4312
4313         return (error);
4314 }
4315
4316 static void
4317 pf_clear_srcnodes(struct pf_ksrc_node *n)
4318 {
4319         struct pf_state *s;
4320         int i;
4321
4322         for (i = 0; i <= pf_hashmask; i++) {
4323                 struct pf_idhash *ih = &V_pf_idhash[i];
4324
4325                 PF_HASHROW_LOCK(ih);
4326                 LIST_FOREACH(s, &ih->states, entry) {
4327                         if (n == NULL || n == s->src_node)
4328                                 s->src_node = NULL;
4329                         if (n == NULL || n == s->nat_src_node)
4330                                 s->nat_src_node = NULL;
4331                 }
4332                 PF_HASHROW_UNLOCK(ih);
4333         }
4334
4335         if (n == NULL) {
4336                 struct pf_srchash *sh;
4337
4338                 for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask;
4339                     i++, sh++) {
4340                         PF_HASHROW_LOCK(sh);
4341                         LIST_FOREACH(n, &sh->nodes, entry) {
4342                                 n->expire = 1;
4343                                 n->states = 0;
4344                         }
4345                         PF_HASHROW_UNLOCK(sh);
4346                 }
4347         } else {
4348                 /* XXX: hash slot should already be locked here. */
4349                 n->expire = 1;
4350                 n->states = 0;
4351         }
4352 }
4353
4354 static void
4355 pf_kill_srcnodes(struct pfioc_src_node_kill *psnk)
4356 {
4357         struct pf_ksrc_node_list         kill;
4358
4359         LIST_INIT(&kill);
4360         for (int i = 0; i <= pf_srchashmask; i++) {
4361                 struct pf_srchash *sh = &V_pf_srchash[i];
4362                 struct pf_ksrc_node *sn, *tmp;
4363
4364                 PF_HASHROW_LOCK(sh);
4365                 LIST_FOREACH_SAFE(sn, &sh->nodes, entry, tmp)
4366                         if (PF_MATCHA(psnk->psnk_src.neg,
4367                               &psnk->psnk_src.addr.v.a.addr,
4368                               &psnk->psnk_src.addr.v.a.mask,
4369                               &sn->addr, sn->af) &&
4370                             PF_MATCHA(psnk->psnk_dst.neg,
4371                               &psnk->psnk_dst.addr.v.a.addr,
4372                               &psnk->psnk_dst.addr.v.a.mask,
4373                               &sn->raddr, sn->af)) {
4374                                 pf_unlink_src_node(sn);
4375                                 LIST_INSERT_HEAD(&kill, sn, entry);
4376                                 sn->expire = 1;
4377                         }
4378                 PF_HASHROW_UNLOCK(sh);
4379         }
4380
4381         for (int i = 0; i <= pf_hashmask; i++) {
4382                 struct pf_idhash *ih = &V_pf_idhash[i];
4383                 struct pf_state *s;
4384
4385                 PF_HASHROW_LOCK(ih);
4386                 LIST_FOREACH(s, &ih->states, entry) {
4387                         if (s->src_node && s->src_node->expire == 1)
4388                                 s->src_node = NULL;
4389                         if (s->nat_src_node && s->nat_src_node->expire == 1)
4390                                 s->nat_src_node = NULL;
4391                 }
4392                 PF_HASHROW_UNLOCK(ih);
4393         }
4394
4395         psnk->psnk_killed = pf_free_src_nodes(&kill);
4396 }
4397
4398 /*
4399  * XXX - Check for version missmatch!!!
4400  */
4401
4402 /*
4403  * Duplicate pfctl -Fa operation to get rid of as much as we can.
4404  */
4405 static int
4406 shutdown_pf(void)
4407 {
4408         int error = 0;
4409         u_int32_t t[5];
4410         char nn = '\0';
4411
4412         do {
4413                 if ((error = pf_begin_rules(&t[0], PF_RULESET_SCRUB, &nn))
4414                     != 0) {
4415                         DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: SCRUB\n"));
4416                         break;
4417                 }
4418                 if ((error = pf_begin_rules(&t[1], PF_RULESET_FILTER, &nn))
4419                     != 0) {
4420                         DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: FILTER\n"));
4421                         break;          /* XXX: rollback? */
4422                 }
4423                 if ((error = pf_begin_rules(&t[2], PF_RULESET_NAT, &nn))
4424                     != 0) {
4425                         DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: NAT\n"));
4426                         break;          /* XXX: rollback? */
4427                 }
4428                 if ((error = pf_begin_rules(&t[3], PF_RULESET_BINAT, &nn))
4429                     != 0) {
4430                         DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: BINAT\n"));
4431                         break;          /* XXX: rollback? */
4432                 }
4433                 if ((error = pf_begin_rules(&t[4], PF_RULESET_RDR, &nn))
4434                     != 0) {
4435                         DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: RDR\n"));
4436                         break;          /* XXX: rollback? */
4437                 }
4438
4439                 /* XXX: these should always succeed here */
4440                 pf_commit_rules(t[0], PF_RULESET_SCRUB, &nn);
4441                 pf_commit_rules(t[1], PF_RULESET_FILTER, &nn);
4442                 pf_commit_rules(t[2], PF_RULESET_NAT, &nn);
4443                 pf_commit_rules(t[3], PF_RULESET_BINAT, &nn);
4444                 pf_commit_rules(t[4], PF_RULESET_RDR, &nn);
4445
4446                 if ((error = pf_clear_tables()) != 0)
4447                         break;
4448
4449 #ifdef ALTQ
4450                 if ((error = pf_begin_altq(&t[0])) != 0) {
4451                         DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: ALTQ\n"));
4452                         break;
4453                 }
4454                 pf_commit_altq(t[0]);
4455 #endif
4456
4457                 pf_clear_states();
4458
4459                 pf_clear_srcnodes(NULL);
4460
4461                 /* status does not use malloced mem so no need to cleanup */
4462                 /* fingerprints and interfaces have their own cleanup code */
4463         } while(0);
4464
4465         return (error);
4466 }
4467
4468 static pfil_return_t
4469 pf_check_return(int chk, struct mbuf **m)
4470 {
4471
4472         switch (chk) {
4473         case PF_PASS:
4474                 if (*m == NULL)
4475                         return (PFIL_CONSUMED);
4476                 else
4477                         return (PFIL_PASS);
4478                 break;
4479         default:
4480                 if (*m != NULL) {
4481                         m_freem(*m);
4482                         *m = NULL;
4483                 }
4484                 return (PFIL_DROPPED);
4485         }
4486 }
4487
4488 #ifdef INET
4489 static pfil_return_t
4490 pf_check_in(struct mbuf **m, struct ifnet *ifp, int flags,
4491     void *ruleset __unused, struct inpcb *inp)
4492 {
4493         int chk;
4494
4495         chk = pf_test(PF_IN, flags, ifp, m, inp);
4496
4497         return (pf_check_return(chk, m));
4498 }
4499
4500 static pfil_return_t
4501 pf_check_out(struct mbuf **m, struct ifnet *ifp, int flags,
4502     void *ruleset __unused,  struct inpcb *inp)
4503 {
4504         int chk;
4505
4506         chk = pf_test(PF_OUT, flags, ifp, m, inp);
4507
4508         return (pf_check_return(chk, m));
4509 }
4510 #endif
4511
4512 #ifdef INET6
4513 static pfil_return_t
4514 pf_check6_in(struct mbuf **m, struct ifnet *ifp, int flags,
4515     void *ruleset __unused,  struct inpcb *inp)
4516 {
4517         int chk;
4518
4519         /*
4520          * In case of loopback traffic IPv6 uses the real interface in
4521          * order to support scoped addresses. In order to support stateful
4522          * filtering we have change this to lo0 as it is the case in IPv4.
4523          */
4524         CURVNET_SET(ifp->if_vnet);
4525         chk = pf_test6(PF_IN, flags, (*m)->m_flags & M_LOOP ? V_loif : ifp, m, inp);
4526         CURVNET_RESTORE();
4527
4528         return (pf_check_return(chk, m));
4529 }
4530
4531 static pfil_return_t
4532 pf_check6_out(struct mbuf **m, struct ifnet *ifp, int flags,
4533     void *ruleset __unused,  struct inpcb *inp)
4534 {
4535         int chk;
4536
4537         CURVNET_SET(ifp->if_vnet);
4538         chk = pf_test6(PF_OUT, flags, ifp, m, inp);
4539         CURVNET_RESTORE();
4540
4541         return (pf_check_return(chk, m));
4542 }
4543 #endif /* INET6 */
4544
4545 #ifdef INET
4546 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip4_in_hook);
4547 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip4_out_hook);
4548 #define V_pf_ip4_in_hook        VNET(pf_ip4_in_hook)
4549 #define V_pf_ip4_out_hook       VNET(pf_ip4_out_hook)
4550 #endif
4551 #ifdef INET6
4552 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip6_in_hook);
4553 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip6_out_hook);
4554 #define V_pf_ip6_in_hook        VNET(pf_ip6_in_hook)
4555 #define V_pf_ip6_out_hook       VNET(pf_ip6_out_hook)
4556 #endif
4557
4558 static void
4559 hook_pf(void)
4560 {
4561         struct pfil_hook_args pha;
4562         struct pfil_link_args pla;
4563         int ret;
4564
4565         if (V_pf_pfil_hooked)
4566                 return;
4567
4568         pha.pa_version = PFIL_VERSION;
4569         pha.pa_modname = "pf";
4570         pha.pa_ruleset = NULL;
4571
4572         pla.pa_version = PFIL_VERSION;
4573
4574 #ifdef INET
4575         pha.pa_type = PFIL_TYPE_IP4;
4576         pha.pa_func = pf_check_in;
4577         pha.pa_flags = PFIL_IN;
4578         pha.pa_rulname = "default-in";
4579         V_pf_ip4_in_hook = pfil_add_hook(&pha);
4580         pla.pa_flags = PFIL_IN | PFIL_HEADPTR | PFIL_HOOKPTR;
4581         pla.pa_head = V_inet_pfil_head;
4582         pla.pa_hook = V_pf_ip4_in_hook;
4583         ret = pfil_link(&pla);
4584         MPASS(ret == 0);
4585         pha.pa_func = pf_check_out;
4586         pha.pa_flags = PFIL_OUT;
4587         pha.pa_rulname = "default-out";
4588         V_pf_ip4_out_hook = pfil_add_hook(&pha);
4589         pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
4590         pla.pa_head = V_inet_pfil_head;
4591         pla.pa_hook = V_pf_ip4_out_hook;
4592         ret = pfil_link(&pla);
4593         MPASS(ret == 0);
4594 #endif
4595 #ifdef INET6
4596         pha.pa_type = PFIL_TYPE_IP6;
4597         pha.pa_func = pf_check6_in;
4598         pha.pa_flags = PFIL_IN;
4599         pha.pa_rulname = "default-in6";
4600         V_pf_ip6_in_hook = pfil_add_hook(&pha);
4601         pla.pa_flags = PFIL_IN | PFIL_HEADPTR | PFIL_HOOKPTR;
4602         pla.pa_head = V_inet6_pfil_head;
4603         pla.pa_hook = V_pf_ip6_in_hook;
4604         ret = pfil_link(&pla);
4605         MPASS(ret == 0);
4606         pha.pa_func = pf_check6_out;
4607         pha.pa_rulname = "default-out6";
4608         pha.pa_flags = PFIL_OUT;
4609         V_pf_ip6_out_hook = pfil_add_hook(&pha);
4610         pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
4611         pla.pa_head = V_inet6_pfil_head;
4612         pla.pa_hook = V_pf_ip6_out_hook;
4613         ret = pfil_link(&pla);
4614         MPASS(ret == 0);
4615 #endif
4616
4617         V_pf_pfil_hooked = 1;
4618 }
4619
4620 static void
4621 dehook_pf(void)
4622 {
4623
4624         if (V_pf_pfil_hooked == 0)
4625                 return;
4626
4627 #ifdef INET
4628         pfil_remove_hook(V_pf_ip4_in_hook);
4629         pfil_remove_hook(V_pf_ip4_out_hook);
4630 #endif
4631 #ifdef INET6
4632         pfil_remove_hook(V_pf_ip6_in_hook);
4633         pfil_remove_hook(V_pf_ip6_out_hook);
4634 #endif
4635
4636         V_pf_pfil_hooked = 0;
4637 }
4638
4639 static void
4640 pf_load_vnet(void)
4641 {
4642         V_pf_tag_z = uma_zcreate("pf tags", sizeof(struct pf_tagname),
4643             NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
4644
4645         pf_init_tagset(&V_pf_tags, &pf_rule_tag_hashsize,
4646             PF_RULE_TAG_HASH_SIZE_DEFAULT);
4647 #ifdef ALTQ
4648         pf_init_tagset(&V_pf_qids, &pf_queue_tag_hashsize,
4649             PF_QUEUE_TAG_HASH_SIZE_DEFAULT);
4650 #endif
4651
4652         pfattach_vnet();
4653         V_pf_vnet_active = 1;
4654 }
4655
4656 static int
4657 pf_load(void)
4658 {
4659         int error;
4660
4661         rm_init(&pf_rules_lock, "pf rulesets");
4662         sx_init(&pf_ioctl_lock, "pf ioctl");
4663         sx_init(&pf_end_lock, "pf end thread");
4664
4665         pf_mtag_initialize();
4666
4667         pf_dev = make_dev(&pf_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, PF_NAME);
4668         if (pf_dev == NULL)
4669                 return (ENOMEM);
4670
4671         pf_end_threads = 0;
4672         error = kproc_create(pf_purge_thread, NULL, &pf_purge_proc, 0, 0, "pf purge");
4673         if (error != 0)
4674                 return (error);
4675
4676         pfi_initialize();
4677
4678         return (0);
4679 }
4680
4681 static void
4682 pf_unload_vnet(void)
4683 {
4684
4685         V_pf_vnet_active = 0;
4686         V_pf_status.running = 0;
4687         dehook_pf();
4688
4689         PF_RULES_WLOCK();
4690         shutdown_pf();
4691         PF_RULES_WUNLOCK();
4692
4693         swi_remove(V_pf_swi_cookie);
4694
4695         pf_unload_vnet_purge();
4696
4697         pf_normalize_cleanup();
4698         PF_RULES_WLOCK();
4699         pfi_cleanup_vnet();
4700         PF_RULES_WUNLOCK();
4701         pfr_cleanup();
4702         pf_osfp_flush();
4703         pf_cleanup();
4704         if (IS_DEFAULT_VNET(curvnet))
4705                 pf_mtag_cleanup();
4706
4707         pf_cleanup_tagset(&V_pf_tags);
4708 #ifdef ALTQ
4709         pf_cleanup_tagset(&V_pf_qids);
4710 #endif
4711         uma_zdestroy(V_pf_tag_z);
4712
4713         /* Free counters last as we updated them during shutdown. */
4714         counter_u64_free(V_pf_default_rule.evaluations);
4715         for (int i = 0; i < 2; i++) {
4716                 counter_u64_free(V_pf_default_rule.packets[i]);
4717                 counter_u64_free(V_pf_default_rule.bytes[i]);
4718         }
4719         counter_u64_free(V_pf_default_rule.states_cur);
4720         counter_u64_free(V_pf_default_rule.states_tot);
4721         counter_u64_free(V_pf_default_rule.src_nodes);
4722
4723         for (int i = 0; i < PFRES_MAX; i++)
4724                 counter_u64_free(V_pf_status.counters[i]);
4725         for (int i = 0; i < LCNT_MAX; i++)
4726                 counter_u64_free(V_pf_status.lcounters[i]);
4727         for (int i = 0; i < FCNT_MAX; i++)
4728                 counter_u64_free(V_pf_status.fcounters[i]);
4729         for (int i = 0; i < SCNT_MAX; i++)
4730                 counter_u64_free(V_pf_status.scounters[i]);
4731 }
4732
4733 static void
4734 pf_unload(void)
4735 {
4736
4737         sx_xlock(&pf_end_lock);
4738         pf_end_threads = 1;
4739         while (pf_end_threads < 2) {
4740                 wakeup_one(pf_purge_thread);
4741                 sx_sleep(pf_purge_proc, &pf_end_lock, 0, "pftmo", 0);
4742         }
4743         sx_xunlock(&pf_end_lock);
4744
4745         if (pf_dev != NULL)
4746                 destroy_dev(pf_dev);
4747
4748         pfi_cleanup();
4749
4750         rm_destroy(&pf_rules_lock);
4751         sx_destroy(&pf_ioctl_lock);
4752         sx_destroy(&pf_end_lock);
4753 }
4754
4755 static void
4756 vnet_pf_init(void *unused __unused)
4757 {
4758
4759         pf_load_vnet();
4760 }
4761 VNET_SYSINIT(vnet_pf_init, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD, 
4762     vnet_pf_init, NULL);
4763
4764 static void
4765 vnet_pf_uninit(const void *unused __unused)
4766 {
4767
4768         pf_unload_vnet();
4769
4770 SYSUNINIT(pf_unload, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND, pf_unload, NULL);
4771 VNET_SYSUNINIT(vnet_pf_uninit, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
4772     vnet_pf_uninit, NULL);
4773
4774 static int
4775 pf_modevent(module_t mod, int type, void *data)
4776 {
4777         int error = 0;
4778
4779         switch(type) {
4780         case MOD_LOAD:
4781                 error = pf_load();
4782                 break;
4783         case MOD_UNLOAD:
4784                 /* Handled in SYSUNINIT(pf_unload) to ensure it's done after
4785                  * the vnet_pf_uninit()s */
4786                 break;
4787         default:
4788                 error = EINVAL;
4789                 break;
4790         }
4791
4792         return (error);
4793 }
4794
4795 static moduledata_t pf_mod = {
4796         "pf",
4797         pf_modevent,
4798         0
4799 };
4800
4801 DECLARE_MODULE(pf, pf_mod, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND);
4802 MODULE_VERSION(pf, PF_MODVER);