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