]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/netpfil/pf/pf_ioctl.c
pf: Handle errors returned by pf_killstates()
[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_kstate *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_kstate        *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_kstate        *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_kstate        *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_kstate        *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_TABLE_STATS_LOCK();
3729                 PF_RULES_RLOCK();
3730                 n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
3731                 if (n < 0) {
3732                         PF_RULES_RUNLOCK();
3733                         PF_TABLE_STATS_UNLOCK();
3734                         error = EINVAL;
3735                         break;
3736                 }
3737                 io->pfrio_size = min(io->pfrio_size, n);
3738
3739                 totlen = io->pfrio_size * sizeof(struct pfr_tstats);
3740                 pfrtstats = mallocarray(io->pfrio_size,
3741                     sizeof(struct pfr_tstats), M_TEMP, M_NOWAIT);
3742                 if (pfrtstats == NULL) {
3743                         error = ENOMEM;
3744                         PF_RULES_RUNLOCK();
3745                         PF_TABLE_STATS_UNLOCK();
3746                         break;
3747                 }
3748                 error = pfr_get_tstats(&io->pfrio_table, pfrtstats,
3749                     &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
3750                 PF_RULES_RUNLOCK();
3751                 PF_TABLE_STATS_UNLOCK();
3752                 if (error == 0)
3753                         error = copyout(pfrtstats, io->pfrio_buffer, totlen);
3754                 free(pfrtstats, M_TEMP);
3755                 break;
3756         }
3757
3758         case DIOCRCLRTSTATS: {
3759                 struct pfioc_table *io = (struct pfioc_table *)addr;
3760                 struct pfr_table *pfrts;
3761                 size_t totlen;
3762
3763                 if (io->pfrio_esize != sizeof(struct pfr_table)) {
3764                         error = ENODEV;
3765                         break;
3766                 }
3767
3768                 if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount ||
3769                     WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) {
3770                         /* We used to count tables and use the minimum required
3771                          * size, so we didn't fail on overly large requests.
3772                          * Keep doing so. */
3773                         io->pfrio_size = pf_ioctl_maxcount;
3774                         break;
3775                 }
3776
3777                 totlen = io->pfrio_size * sizeof(struct pfr_table);
3778                 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
3779                     M_TEMP, M_WAITOK);
3780                 error = copyin(io->pfrio_buffer, pfrts, totlen);
3781                 if (error) {
3782                         free(pfrts, M_TEMP);
3783                         break;
3784                 }
3785
3786                 PF_TABLE_STATS_LOCK();
3787                 PF_RULES_RLOCK();
3788                 error = pfr_clr_tstats(pfrts, io->pfrio_size,
3789                     &io->pfrio_nzero, io->pfrio_flags | PFR_FLAG_USERIOCTL);
3790                 PF_RULES_RUNLOCK();
3791                 PF_TABLE_STATS_UNLOCK();
3792                 free(pfrts, M_TEMP);
3793                 break;
3794         }
3795
3796         case DIOCRSETTFLAGS: {
3797                 struct pfioc_table *io = (struct pfioc_table *)addr;
3798                 struct pfr_table *pfrts;
3799                 size_t totlen;
3800                 int n;
3801
3802                 if (io->pfrio_esize != sizeof(struct pfr_table)) {
3803                         error = ENODEV;
3804                         break;
3805                 }
3806
3807                 PF_RULES_RLOCK();
3808                 n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
3809                 if (n < 0) {
3810                         PF_RULES_RUNLOCK();
3811                         error = EINVAL;
3812                         break;
3813                 }
3814
3815                 io->pfrio_size = min(io->pfrio_size, n);
3816                 PF_RULES_RUNLOCK();
3817
3818                 totlen = io->pfrio_size * sizeof(struct pfr_table);
3819                 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
3820                     M_TEMP, M_WAITOK);
3821                 error = copyin(io->pfrio_buffer, pfrts, totlen);
3822                 if (error) {
3823                         free(pfrts, M_TEMP);
3824                         break;
3825                 }
3826                 PF_RULES_WLOCK();
3827                 error = pfr_set_tflags(pfrts, io->pfrio_size,
3828                     io->pfrio_setflag, io->pfrio_clrflag, &io->pfrio_nchange,
3829                     &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
3830                 PF_RULES_WUNLOCK();
3831                 free(pfrts, M_TEMP);
3832                 break;
3833         }
3834
3835         case DIOCRCLRADDRS: {
3836                 struct pfioc_table *io = (struct pfioc_table *)addr;
3837
3838                 if (io->pfrio_esize != 0) {
3839                         error = ENODEV;
3840                         break;
3841                 }
3842                 PF_RULES_WLOCK();
3843                 error = pfr_clr_addrs(&io->pfrio_table, &io->pfrio_ndel,
3844                     io->pfrio_flags | PFR_FLAG_USERIOCTL);
3845                 PF_RULES_WUNLOCK();
3846                 break;
3847         }
3848
3849         case DIOCRADDADDRS: {
3850                 struct pfioc_table *io = (struct pfioc_table *)addr;
3851                 struct pfr_addr *pfras;
3852                 size_t totlen;
3853
3854                 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
3855                         error = ENODEV;
3856                         break;
3857                 }
3858                 if (io->pfrio_size < 0 ||
3859                     io->pfrio_size > pf_ioctl_maxcount ||
3860                     WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
3861                         error = EINVAL;
3862                         break;
3863                 }
3864                 totlen = io->pfrio_size * sizeof(struct pfr_addr);
3865                 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
3866                     M_TEMP, M_WAITOK);
3867                 error = copyin(io->pfrio_buffer, pfras, totlen);
3868                 if (error) {
3869                         free(pfras, M_TEMP);
3870                         break;
3871                 }
3872                 PF_RULES_WLOCK();
3873                 error = pfr_add_addrs(&io->pfrio_table, pfras,
3874                     io->pfrio_size, &io->pfrio_nadd, io->pfrio_flags |
3875                     PFR_FLAG_USERIOCTL);
3876                 PF_RULES_WUNLOCK();
3877                 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
3878                         error = copyout(pfras, io->pfrio_buffer, totlen);
3879                 free(pfras, M_TEMP);
3880                 break;
3881         }
3882
3883         case DIOCRDELADDRS: {
3884                 struct pfioc_table *io = (struct pfioc_table *)addr;
3885                 struct pfr_addr *pfras;
3886                 size_t totlen;
3887
3888                 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
3889                         error = ENODEV;
3890                         break;
3891                 }
3892                 if (io->pfrio_size < 0 ||
3893                     io->pfrio_size > pf_ioctl_maxcount ||
3894                     WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
3895                         error = EINVAL;
3896                         break;
3897                 }
3898                 totlen = io->pfrio_size * sizeof(struct pfr_addr);
3899                 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
3900                     M_TEMP, M_WAITOK);
3901                 error = copyin(io->pfrio_buffer, pfras, totlen);
3902                 if (error) {
3903                         free(pfras, M_TEMP);
3904                         break;
3905                 }
3906                 PF_RULES_WLOCK();
3907                 error = pfr_del_addrs(&io->pfrio_table, pfras,
3908                     io->pfrio_size, &io->pfrio_ndel, io->pfrio_flags |
3909                     PFR_FLAG_USERIOCTL);
3910                 PF_RULES_WUNLOCK();
3911                 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
3912                         error = copyout(pfras, io->pfrio_buffer, totlen);
3913                 free(pfras, M_TEMP);
3914                 break;
3915         }
3916
3917         case DIOCRSETADDRS: {
3918                 struct pfioc_table *io = (struct pfioc_table *)addr;
3919                 struct pfr_addr *pfras;
3920                 size_t totlen, count;
3921
3922                 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
3923                         error = ENODEV;
3924                         break;
3925                 }
3926                 if (io->pfrio_size < 0 || io->pfrio_size2 < 0) {
3927                         error = EINVAL;
3928                         break;
3929                 }
3930                 count = max(io->pfrio_size, io->pfrio_size2);
3931                 if (count > pf_ioctl_maxcount ||
3932                     WOULD_OVERFLOW(count, sizeof(struct pfr_addr))) {
3933                         error = EINVAL;
3934                         break;
3935                 }
3936                 totlen = count * sizeof(struct pfr_addr);
3937                 pfras = mallocarray(count, sizeof(struct pfr_addr), M_TEMP,
3938                     M_WAITOK);
3939                 error = copyin(io->pfrio_buffer, pfras, totlen);
3940                 if (error) {
3941                         free(pfras, M_TEMP);
3942                         break;
3943                 }
3944                 PF_RULES_WLOCK();
3945                 error = pfr_set_addrs(&io->pfrio_table, pfras,
3946                     io->pfrio_size, &io->pfrio_size2, &io->pfrio_nadd,
3947                     &io->pfrio_ndel, &io->pfrio_nchange, io->pfrio_flags |
3948                     PFR_FLAG_USERIOCTL, 0);
3949                 PF_RULES_WUNLOCK();
3950                 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
3951                         error = copyout(pfras, io->pfrio_buffer, totlen);
3952                 free(pfras, M_TEMP);
3953                 break;
3954         }
3955
3956         case DIOCRGETADDRS: {
3957                 struct pfioc_table *io = (struct pfioc_table *)addr;
3958                 struct pfr_addr *pfras;
3959                 size_t totlen;
3960
3961                 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
3962                         error = ENODEV;
3963                         break;
3964                 }
3965                 if (io->pfrio_size < 0 ||
3966                     io->pfrio_size > pf_ioctl_maxcount ||
3967                     WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
3968                         error = EINVAL;
3969                         break;
3970                 }
3971                 totlen = io->pfrio_size * sizeof(struct pfr_addr);
3972                 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
3973                     M_TEMP, M_WAITOK);
3974                 PF_RULES_RLOCK();
3975                 error = pfr_get_addrs(&io->pfrio_table, pfras,
3976                     &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
3977                 PF_RULES_RUNLOCK();
3978                 if (error == 0)
3979                         error = copyout(pfras, io->pfrio_buffer, totlen);
3980                 free(pfras, M_TEMP);
3981                 break;
3982         }
3983
3984         case DIOCRGETASTATS: {
3985                 struct pfioc_table *io = (struct pfioc_table *)addr;
3986                 struct pfr_astats *pfrastats;
3987                 size_t totlen;
3988
3989                 if (io->pfrio_esize != sizeof(struct pfr_astats)) {
3990                         error = ENODEV;
3991                         break;
3992                 }
3993                 if (io->pfrio_size < 0 ||
3994                     io->pfrio_size > pf_ioctl_maxcount ||
3995                     WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_astats))) {
3996                         error = EINVAL;
3997                         break;
3998                 }
3999                 totlen = io->pfrio_size * sizeof(struct pfr_astats);
4000                 pfrastats = mallocarray(io->pfrio_size,
4001                     sizeof(struct pfr_astats), M_TEMP, M_WAITOK);
4002                 PF_RULES_RLOCK();
4003                 error = pfr_get_astats(&io->pfrio_table, pfrastats,
4004                     &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4005                 PF_RULES_RUNLOCK();
4006                 if (error == 0)
4007                         error = copyout(pfrastats, io->pfrio_buffer, totlen);
4008                 free(pfrastats, M_TEMP);
4009                 break;
4010         }
4011
4012         case DIOCRCLRASTATS: {
4013                 struct pfioc_table *io = (struct pfioc_table *)addr;
4014                 struct pfr_addr *pfras;
4015                 size_t totlen;
4016
4017                 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4018                         error = ENODEV;
4019                         break;
4020                 }
4021                 if (io->pfrio_size < 0 ||
4022                     io->pfrio_size > pf_ioctl_maxcount ||
4023                     WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4024                         error = EINVAL;
4025                         break;
4026                 }
4027                 totlen = io->pfrio_size * sizeof(struct pfr_addr);
4028                 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4029                     M_TEMP, M_WAITOK);
4030                 error = copyin(io->pfrio_buffer, pfras, totlen);
4031                 if (error) {
4032                         free(pfras, M_TEMP);
4033                         break;
4034                 }
4035                 PF_RULES_WLOCK();
4036                 error = pfr_clr_astats(&io->pfrio_table, pfras,
4037                     io->pfrio_size, &io->pfrio_nzero, io->pfrio_flags |
4038                     PFR_FLAG_USERIOCTL);
4039                 PF_RULES_WUNLOCK();
4040                 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
4041                         error = copyout(pfras, io->pfrio_buffer, totlen);
4042                 free(pfras, M_TEMP);
4043                 break;
4044         }
4045
4046         case DIOCRTSTADDRS: {
4047                 struct pfioc_table *io = (struct pfioc_table *)addr;
4048                 struct pfr_addr *pfras;
4049                 size_t totlen;
4050
4051                 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4052                         error = ENODEV;
4053                         break;
4054                 }
4055                 if (io->pfrio_size < 0 ||
4056                     io->pfrio_size > pf_ioctl_maxcount ||
4057                     WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4058                         error = EINVAL;
4059                         break;
4060                 }
4061                 totlen = io->pfrio_size * sizeof(struct pfr_addr);
4062                 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4063                     M_TEMP, M_WAITOK);
4064                 error = copyin(io->pfrio_buffer, pfras, totlen);
4065                 if (error) {
4066                         free(pfras, M_TEMP);
4067                         break;
4068                 }
4069                 PF_RULES_RLOCK();
4070                 error = pfr_tst_addrs(&io->pfrio_table, pfras,
4071                     io->pfrio_size, &io->pfrio_nmatch, io->pfrio_flags |
4072                     PFR_FLAG_USERIOCTL);
4073                 PF_RULES_RUNLOCK();
4074                 if (error == 0)
4075                         error = copyout(pfras, io->pfrio_buffer, totlen);
4076                 free(pfras, M_TEMP);
4077                 break;
4078         }
4079
4080         case DIOCRINADEFINE: {
4081                 struct pfioc_table *io = (struct pfioc_table *)addr;
4082                 struct pfr_addr *pfras;
4083                 size_t totlen;
4084
4085                 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4086                         error = ENODEV;
4087                         break;
4088                 }
4089                 if (io->pfrio_size < 0 ||
4090                     io->pfrio_size > pf_ioctl_maxcount ||
4091                     WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4092                         error = EINVAL;
4093                         break;
4094                 }
4095                 totlen = io->pfrio_size * sizeof(struct pfr_addr);
4096                 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4097                     M_TEMP, M_WAITOK);
4098                 error = copyin(io->pfrio_buffer, pfras, totlen);
4099                 if (error) {
4100                         free(pfras, M_TEMP);
4101                         break;
4102                 }
4103                 PF_RULES_WLOCK();
4104                 error = pfr_ina_define(&io->pfrio_table, pfras,
4105                     io->pfrio_size, &io->pfrio_nadd, &io->pfrio_naddr,
4106                     io->pfrio_ticket, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4107                 PF_RULES_WUNLOCK();
4108                 free(pfras, M_TEMP);
4109                 break;
4110         }
4111
4112         case DIOCOSFPADD: {
4113                 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
4114                 PF_RULES_WLOCK();
4115                 error = pf_osfp_add(io);
4116                 PF_RULES_WUNLOCK();
4117                 break;
4118         }
4119
4120         case DIOCOSFPGET: {
4121                 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
4122                 PF_RULES_RLOCK();
4123                 error = pf_osfp_get(io);
4124                 PF_RULES_RUNLOCK();
4125                 break;
4126         }
4127
4128         case DIOCXBEGIN: {
4129                 struct pfioc_trans      *io = (struct pfioc_trans *)addr;
4130                 struct pfioc_trans_e    *ioes, *ioe;
4131                 size_t                   totlen;
4132                 int                      i;
4133
4134                 if (io->esize != sizeof(*ioe)) {
4135                         error = ENODEV;
4136                         break;
4137                 }
4138                 if (io->size < 0 ||
4139                     io->size > pf_ioctl_maxcount ||
4140                     WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
4141                         error = EINVAL;
4142                         break;
4143                 }
4144                 totlen = sizeof(struct pfioc_trans_e) * io->size;
4145                 ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
4146                     M_TEMP, M_WAITOK);
4147                 error = copyin(io->array, ioes, totlen);
4148                 if (error) {
4149                         free(ioes, M_TEMP);
4150                         break;
4151                 }
4152                 PF_RULES_WLOCK();
4153                 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
4154                         switch (ioe->rs_num) {
4155 #ifdef ALTQ
4156                         case PF_RULESET_ALTQ:
4157                                 if (ioe->anchor[0]) {
4158                                         PF_RULES_WUNLOCK();
4159                                         free(ioes, M_TEMP);
4160                                         error = EINVAL;
4161                                         goto fail;
4162                                 }
4163                                 if ((error = pf_begin_altq(&ioe->ticket))) {
4164                                         PF_RULES_WUNLOCK();
4165                                         free(ioes, M_TEMP);
4166                                         goto fail;
4167                                 }
4168                                 break;
4169 #endif /* ALTQ */
4170                         case PF_RULESET_TABLE:
4171                             {
4172                                 struct pfr_table table;
4173
4174                                 bzero(&table, sizeof(table));
4175                                 strlcpy(table.pfrt_anchor, ioe->anchor,
4176                                     sizeof(table.pfrt_anchor));
4177                                 if ((error = pfr_ina_begin(&table,
4178                                     &ioe->ticket, NULL, 0))) {
4179                                         PF_RULES_WUNLOCK();
4180                                         free(ioes, M_TEMP);
4181                                         goto fail;
4182                                 }
4183                                 break;
4184                             }
4185                         default:
4186                                 if ((error = pf_begin_rules(&ioe->ticket,
4187                                     ioe->rs_num, ioe->anchor))) {
4188                                         PF_RULES_WUNLOCK();
4189                                         free(ioes, M_TEMP);
4190                                         goto fail;
4191                                 }
4192                                 break;
4193                         }
4194                 }
4195                 PF_RULES_WUNLOCK();
4196                 error = copyout(ioes, io->array, totlen);
4197                 free(ioes, M_TEMP);
4198                 break;
4199         }
4200
4201         case DIOCXROLLBACK: {
4202                 struct pfioc_trans      *io = (struct pfioc_trans *)addr;
4203                 struct pfioc_trans_e    *ioe, *ioes;
4204                 size_t                   totlen;
4205                 int                      i;
4206
4207                 if (io->esize != sizeof(*ioe)) {
4208                         error = ENODEV;
4209                         break;
4210                 }
4211                 if (io->size < 0 ||
4212                     io->size > pf_ioctl_maxcount ||
4213                     WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
4214                         error = EINVAL;
4215                         break;
4216                 }
4217                 totlen = sizeof(struct pfioc_trans_e) * io->size;
4218                 ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
4219                     M_TEMP, M_WAITOK);
4220                 error = copyin(io->array, ioes, totlen);
4221                 if (error) {
4222                         free(ioes, M_TEMP);
4223                         break;
4224                 }
4225                 PF_RULES_WLOCK();
4226                 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
4227                         switch (ioe->rs_num) {
4228 #ifdef ALTQ
4229                         case PF_RULESET_ALTQ:
4230                                 if (ioe->anchor[0]) {
4231                                         PF_RULES_WUNLOCK();
4232                                         free(ioes, M_TEMP);
4233                                         error = EINVAL;
4234                                         goto fail;
4235                                 }
4236                                 if ((error = pf_rollback_altq(ioe->ticket))) {
4237                                         PF_RULES_WUNLOCK();
4238                                         free(ioes, M_TEMP);
4239                                         goto fail; /* really bad */
4240                                 }
4241                                 break;
4242 #endif /* ALTQ */
4243                         case PF_RULESET_TABLE:
4244                             {
4245                                 struct pfr_table table;
4246
4247                                 bzero(&table, sizeof(table));
4248                                 strlcpy(table.pfrt_anchor, ioe->anchor,
4249                                     sizeof(table.pfrt_anchor));
4250                                 if ((error = pfr_ina_rollback(&table,
4251                                     ioe->ticket, NULL, 0))) {
4252                                         PF_RULES_WUNLOCK();
4253                                         free(ioes, M_TEMP);
4254                                         goto fail; /* really bad */
4255                                 }
4256                                 break;
4257                             }
4258                         default:
4259                                 if ((error = pf_rollback_rules(ioe->ticket,
4260                                     ioe->rs_num, ioe->anchor))) {
4261                                         PF_RULES_WUNLOCK();
4262                                         free(ioes, M_TEMP);
4263                                         goto fail; /* really bad */
4264                                 }
4265                                 break;
4266                         }
4267                 }
4268                 PF_RULES_WUNLOCK();
4269                 free(ioes, M_TEMP);
4270                 break;
4271         }
4272
4273         case DIOCXCOMMIT: {
4274                 struct pfioc_trans      *io = (struct pfioc_trans *)addr;
4275                 struct pfioc_trans_e    *ioe, *ioes;
4276                 struct pf_kruleset      *rs;
4277                 size_t                   totlen;
4278                 int                      i;
4279
4280                 if (io->esize != sizeof(*ioe)) {
4281                         error = ENODEV;
4282                         break;
4283                 }
4284
4285                 if (io->size < 0 ||
4286                     io->size > pf_ioctl_maxcount ||
4287                     WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
4288                         error = EINVAL;
4289                         break;
4290                 }
4291
4292                 totlen = sizeof(struct pfioc_trans_e) * io->size;
4293                 ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
4294                     M_TEMP, M_WAITOK);
4295                 error = copyin(io->array, ioes, totlen);
4296                 if (error) {
4297                         free(ioes, M_TEMP);
4298                         break;
4299                 }
4300                 PF_RULES_WLOCK();
4301                 /* First makes sure everything will succeed. */
4302                 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
4303                         switch (ioe->rs_num) {
4304 #ifdef ALTQ
4305                         case PF_RULESET_ALTQ:
4306                                 if (ioe->anchor[0]) {
4307                                         PF_RULES_WUNLOCK();
4308                                         free(ioes, M_TEMP);
4309                                         error = EINVAL;
4310                                         goto fail;
4311                                 }
4312                                 if (!V_altqs_inactive_open || ioe->ticket !=
4313                                     V_ticket_altqs_inactive) {
4314                                         PF_RULES_WUNLOCK();
4315                                         free(ioes, M_TEMP);
4316                                         error = EBUSY;
4317                                         goto fail;
4318                                 }
4319                                 break;
4320 #endif /* ALTQ */
4321                         case PF_RULESET_TABLE:
4322                                 rs = pf_find_kruleset(ioe->anchor);
4323                                 if (rs == NULL || !rs->topen || ioe->ticket !=
4324                                     rs->tticket) {
4325                                         PF_RULES_WUNLOCK();
4326                                         free(ioes, M_TEMP);
4327                                         error = EBUSY;
4328                                         goto fail;
4329                                 }
4330                                 break;
4331                         default:
4332                                 if (ioe->rs_num < 0 || ioe->rs_num >=
4333                                     PF_RULESET_MAX) {
4334                                         PF_RULES_WUNLOCK();
4335                                         free(ioes, M_TEMP);
4336                                         error = EINVAL;
4337                                         goto fail;
4338                                 }
4339                                 rs = pf_find_kruleset(ioe->anchor);
4340                                 if (rs == NULL ||
4341                                     !rs->rules[ioe->rs_num].inactive.open ||
4342                                     rs->rules[ioe->rs_num].inactive.ticket !=
4343                                     ioe->ticket) {
4344                                         PF_RULES_WUNLOCK();
4345                                         free(ioes, M_TEMP);
4346                                         error = EBUSY;
4347                                         goto fail;
4348                                 }
4349                                 break;
4350                         }
4351                 }
4352                 /* Now do the commit - no errors should happen here. */
4353                 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
4354                         switch (ioe->rs_num) {
4355 #ifdef ALTQ
4356                         case PF_RULESET_ALTQ:
4357                                 if ((error = pf_commit_altq(ioe->ticket))) {
4358                                         PF_RULES_WUNLOCK();
4359                                         free(ioes, M_TEMP);
4360                                         goto fail; /* really bad */
4361                                 }
4362                                 break;
4363 #endif /* ALTQ */
4364                         case PF_RULESET_TABLE:
4365                             {
4366                                 struct pfr_table table;
4367
4368                                 bzero(&table, sizeof(table));
4369                                 strlcpy(table.pfrt_anchor, ioe->anchor,
4370                                     sizeof(table.pfrt_anchor));
4371                                 if ((error = pfr_ina_commit(&table,
4372                                     ioe->ticket, NULL, NULL, 0))) {
4373                                         PF_RULES_WUNLOCK();
4374                                         free(ioes, M_TEMP);
4375                                         goto fail; /* really bad */
4376                                 }
4377                                 break;
4378                             }
4379                         default:
4380                                 if ((error = pf_commit_rules(ioe->ticket,
4381                                     ioe->rs_num, ioe->anchor))) {
4382                                         PF_RULES_WUNLOCK();
4383                                         free(ioes, M_TEMP);
4384                                         goto fail; /* really bad */
4385                                 }
4386                                 break;
4387                         }
4388                 }
4389                 PF_RULES_WUNLOCK();
4390                 free(ioes, M_TEMP);
4391                 break;
4392         }
4393
4394         case DIOCGETSRCNODES: {
4395                 struct pfioc_src_nodes  *psn = (struct pfioc_src_nodes *)addr;
4396                 struct pf_srchash       *sh;
4397                 struct pf_ksrc_node     *n;
4398                 struct pf_src_node      *p, *pstore;
4399                 uint32_t                 i, nr = 0;
4400
4401                 for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask;
4402                                 i++, sh++) {
4403                         PF_HASHROW_LOCK(sh);
4404                         LIST_FOREACH(n, &sh->nodes, entry)
4405                                 nr++;
4406                         PF_HASHROW_UNLOCK(sh);
4407                 }
4408
4409                 psn->psn_len = min(psn->psn_len,
4410                     sizeof(struct pf_src_node) * nr);
4411
4412                 if (psn->psn_len == 0) {
4413                         psn->psn_len = sizeof(struct pf_src_node) * nr;
4414                         break;
4415                 }
4416
4417                 nr = 0;
4418
4419                 p = pstore = malloc(psn->psn_len, M_TEMP, M_WAITOK | M_ZERO);
4420                 for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask;
4421                     i++, sh++) {
4422                     PF_HASHROW_LOCK(sh);
4423                     LIST_FOREACH(n, &sh->nodes, entry) {
4424
4425                         if ((nr + 1) * sizeof(*p) > (unsigned)psn->psn_len)
4426                                 break;
4427
4428                         pf_src_node_copy(n, p);
4429
4430                         p++;
4431                         nr++;
4432                     }
4433                     PF_HASHROW_UNLOCK(sh);
4434                 }
4435                 error = copyout(pstore, psn->psn_src_nodes,
4436                     sizeof(struct pf_src_node) * nr);
4437                 if (error) {
4438                         free(pstore, M_TEMP);
4439                         break;
4440                 }
4441                 psn->psn_len = sizeof(struct pf_src_node) * nr;
4442                 free(pstore, M_TEMP);
4443                 break;
4444         }
4445
4446         case DIOCCLRSRCNODES: {
4447                 pf_clear_srcnodes(NULL);
4448                 pf_purge_expired_src_nodes();
4449                 break;
4450         }
4451
4452         case DIOCKILLSRCNODES:
4453                 pf_kill_srcnodes((struct pfioc_src_node_kill *)addr);
4454                 break;
4455
4456         case DIOCKEEPCOUNTERS:
4457                 error = pf_keepcounters((struct pfioc_nv *)addr);
4458                 break;
4459
4460         case DIOCSETHOSTID: {
4461                 u_int32_t       *hostid = (u_int32_t *)addr;
4462
4463                 PF_RULES_WLOCK();
4464                 if (*hostid == 0)
4465                         V_pf_status.hostid = arc4random();
4466                 else
4467                         V_pf_status.hostid = *hostid;
4468                 PF_RULES_WUNLOCK();
4469                 break;
4470         }
4471
4472         case DIOCOSFPFLUSH:
4473                 PF_RULES_WLOCK();
4474                 pf_osfp_flush();
4475                 PF_RULES_WUNLOCK();
4476                 break;
4477
4478         case DIOCIGETIFACES: {
4479                 struct pfioc_iface *io = (struct pfioc_iface *)addr;
4480                 struct pfi_kif *ifstore;
4481                 size_t bufsiz;
4482
4483                 if (io->pfiio_esize != sizeof(struct pfi_kif)) {
4484                         error = ENODEV;
4485                         break;
4486                 }
4487
4488                 if (io->pfiio_size < 0 ||
4489                     io->pfiio_size > pf_ioctl_maxcount ||
4490                     WOULD_OVERFLOW(io->pfiio_size, sizeof(struct pfi_kif))) {
4491                         error = EINVAL;
4492                         break;
4493                 }
4494
4495                 bufsiz = io->pfiio_size * sizeof(struct pfi_kif);
4496                 ifstore = mallocarray(io->pfiio_size, sizeof(struct pfi_kif),
4497                     M_TEMP, M_WAITOK);
4498
4499                 PF_RULES_RLOCK();
4500                 pfi_get_ifaces(io->pfiio_name, ifstore, &io->pfiio_size);
4501                 PF_RULES_RUNLOCK();
4502                 error = copyout(ifstore, io->pfiio_buffer, bufsiz);
4503                 free(ifstore, M_TEMP);
4504                 break;
4505         }
4506
4507         case DIOCSETIFFLAG: {
4508                 struct pfioc_iface *io = (struct pfioc_iface *)addr;
4509
4510                 PF_RULES_WLOCK();
4511                 error = pfi_set_flags(io->pfiio_name, io->pfiio_flags);
4512                 PF_RULES_WUNLOCK();
4513                 break;
4514         }
4515
4516         case DIOCCLRIFFLAG: {
4517                 struct pfioc_iface *io = (struct pfioc_iface *)addr;
4518
4519                 PF_RULES_WLOCK();
4520                 error = pfi_clear_flags(io->pfiio_name, io->pfiio_flags);
4521                 PF_RULES_WUNLOCK();
4522                 break;
4523         }
4524
4525         default:
4526                 error = ENODEV;
4527                 break;
4528         }
4529 fail:
4530         if (sx_xlocked(&pf_ioctl_lock))
4531                 sx_xunlock(&pf_ioctl_lock);
4532         CURVNET_RESTORE();
4533
4534 #undef ERROUT_IOCTL
4535
4536         return (error);
4537 }
4538
4539 void
4540 pfsync_state_export(struct pfsync_state *sp, struct pf_kstate *st)
4541 {
4542         bzero(sp, sizeof(struct pfsync_state));
4543
4544         /* copy from state key */
4545         sp->key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
4546         sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1];
4547         sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0];
4548         sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1];
4549         sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0];
4550         sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1];
4551         sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0];
4552         sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1];
4553         sp->proto = st->key[PF_SK_WIRE]->proto;
4554         sp->af = st->key[PF_SK_WIRE]->af;
4555
4556         /* copy from state */
4557         strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname));
4558         bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr));
4559         sp->creation = htonl(time_uptime - st->creation);
4560         sp->expire = pf_state_expires(st);
4561         if (sp->expire <= time_uptime)
4562                 sp->expire = htonl(0);
4563         else
4564                 sp->expire = htonl(sp->expire - time_uptime);
4565
4566         sp->direction = st->direction;
4567         sp->log = st->log;
4568         sp->timeout = st->timeout;
4569         sp->state_flags = st->state_flags;
4570         if (st->src_node)
4571                 sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
4572         if (st->nat_src_node)
4573                 sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE;
4574
4575         sp->id = st->id;
4576         sp->creatorid = st->creatorid;
4577         pf_state_peer_hton(&st->src, &sp->src);
4578         pf_state_peer_hton(&st->dst, &sp->dst);
4579
4580         if (st->rule.ptr == NULL)
4581                 sp->rule = htonl(-1);
4582         else
4583                 sp->rule = htonl(st->rule.ptr->nr);
4584         if (st->anchor.ptr == NULL)
4585                 sp->anchor = htonl(-1);
4586         else
4587                 sp->anchor = htonl(st->anchor.ptr->nr);
4588         if (st->nat_rule.ptr == NULL)
4589                 sp->nat_rule = htonl(-1);
4590         else
4591                 sp->nat_rule = htonl(st->nat_rule.ptr->nr);
4592
4593         pf_state_counter_hton(st->packets[0], sp->packets[0]);
4594         pf_state_counter_hton(st->packets[1], sp->packets[1]);
4595         pf_state_counter_hton(st->bytes[0], sp->bytes[0]);
4596         pf_state_counter_hton(st->bytes[1], sp->bytes[1]);
4597
4598 }
4599
4600 static void
4601 pf_tbladdr_copyout(struct pf_addr_wrap *aw)
4602 {
4603         struct pfr_ktable *kt;
4604
4605         KASSERT(aw->type == PF_ADDR_TABLE, ("%s: type %u", __func__, aw->type));
4606
4607         kt = aw->p.tbl;
4608         if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
4609                 kt = kt->pfrkt_root;
4610         aw->p.tbl = NULL;
4611         aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ?
4612                 kt->pfrkt_cnt : -1;
4613 }
4614
4615 /*
4616  * XXX - Check for version missmatch!!!
4617  */
4618 static void
4619 pf_clear_all_states(void)
4620 {
4621         struct pf_kstate        *s;
4622         u_int i;
4623
4624         for (i = 0; i <= pf_hashmask; i++) {
4625                 struct pf_idhash *ih = &V_pf_idhash[i];
4626 relock:
4627                 PF_HASHROW_LOCK(ih);
4628                 LIST_FOREACH(s, &ih->states, entry) {
4629                         s->timeout = PFTM_PURGE;
4630                         /* Don't send out individual delete messages. */
4631                         s->state_flags |= PFSTATE_NOSYNC;
4632                         pf_unlink_state(s, PF_ENTER_LOCKED);
4633                         goto relock;
4634                 }
4635                 PF_HASHROW_UNLOCK(ih);
4636         }
4637 }
4638
4639 static int
4640 pf_clear_tables(void)
4641 {
4642         struct pfioc_table io;
4643         int error;
4644
4645         bzero(&io, sizeof(io));
4646
4647         error = pfr_clr_tables(&io.pfrio_table, &io.pfrio_ndel,
4648             io.pfrio_flags);
4649
4650         return (error);
4651 }
4652
4653 static void
4654 pf_clear_srcnodes(struct pf_ksrc_node *n)
4655 {
4656         struct pf_kstate *s;
4657         int i;
4658
4659         for (i = 0; i <= pf_hashmask; i++) {
4660                 struct pf_idhash *ih = &V_pf_idhash[i];
4661
4662                 PF_HASHROW_LOCK(ih);
4663                 LIST_FOREACH(s, &ih->states, entry) {
4664                         if (n == NULL || n == s->src_node)
4665                                 s->src_node = NULL;
4666                         if (n == NULL || n == s->nat_src_node)
4667                                 s->nat_src_node = NULL;
4668                 }
4669                 PF_HASHROW_UNLOCK(ih);
4670         }
4671
4672         if (n == NULL) {
4673                 struct pf_srchash *sh;
4674
4675                 for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask;
4676                     i++, sh++) {
4677                         PF_HASHROW_LOCK(sh);
4678                         LIST_FOREACH(n, &sh->nodes, entry) {
4679                                 n->expire = 1;
4680                                 n->states = 0;
4681                         }
4682                         PF_HASHROW_UNLOCK(sh);
4683                 }
4684         } else {
4685                 /* XXX: hash slot should already be locked here. */
4686                 n->expire = 1;
4687                 n->states = 0;
4688         }
4689 }
4690
4691 static void
4692 pf_kill_srcnodes(struct pfioc_src_node_kill *psnk)
4693 {
4694         struct pf_ksrc_node_list         kill;
4695
4696         LIST_INIT(&kill);
4697         for (int i = 0; i <= pf_srchashmask; i++) {
4698                 struct pf_srchash *sh = &V_pf_srchash[i];
4699                 struct pf_ksrc_node *sn, *tmp;
4700
4701                 PF_HASHROW_LOCK(sh);
4702                 LIST_FOREACH_SAFE(sn, &sh->nodes, entry, tmp)
4703                         if (PF_MATCHA(psnk->psnk_src.neg,
4704                               &psnk->psnk_src.addr.v.a.addr,
4705                               &psnk->psnk_src.addr.v.a.mask,
4706                               &sn->addr, sn->af) &&
4707                             PF_MATCHA(psnk->psnk_dst.neg,
4708                               &psnk->psnk_dst.addr.v.a.addr,
4709                               &psnk->psnk_dst.addr.v.a.mask,
4710                               &sn->raddr, sn->af)) {
4711                                 pf_unlink_src_node(sn);
4712                                 LIST_INSERT_HEAD(&kill, sn, entry);
4713                                 sn->expire = 1;
4714                         }
4715                 PF_HASHROW_UNLOCK(sh);
4716         }
4717
4718         for (int i = 0; i <= pf_hashmask; i++) {
4719                 struct pf_idhash *ih = &V_pf_idhash[i];
4720                 struct pf_kstate *s;
4721
4722                 PF_HASHROW_LOCK(ih);
4723                 LIST_FOREACH(s, &ih->states, entry) {
4724                         if (s->src_node && s->src_node->expire == 1)
4725                                 s->src_node = NULL;
4726                         if (s->nat_src_node && s->nat_src_node->expire == 1)
4727                                 s->nat_src_node = NULL;
4728                 }
4729                 PF_HASHROW_UNLOCK(ih);
4730         }
4731
4732         psnk->psnk_killed = pf_free_src_nodes(&kill);
4733 }
4734
4735 static int
4736 pf_keepcounters(struct pfioc_nv *nv)
4737 {
4738         nvlist_t        *nvl = NULL;
4739         void            *nvlpacked = NULL;
4740         int              error = 0;
4741
4742 #define ERROUT(x)       ERROUT_FUNCTION(on_error, x)
4743
4744         if (nv->len > pf_ioctl_maxcount)
4745                 ERROUT(ENOMEM);
4746
4747         nvlpacked = malloc(nv->len, M_TEMP, M_WAITOK);
4748         if (nvlpacked == NULL)
4749                 ERROUT(ENOMEM);
4750
4751         error = copyin(nv->data, nvlpacked, nv->len);
4752         if (error)
4753                 ERROUT(error);
4754
4755         nvl = nvlist_unpack(nvlpacked, nv->len, 0);
4756         if (nvl == NULL)
4757                 ERROUT(EBADMSG);
4758
4759         if (! nvlist_exists_bool(nvl, "keep_counters"))
4760                 ERROUT(EBADMSG);
4761
4762         V_pf_status.keep_counters = nvlist_get_bool(nvl, "keep_counters");
4763
4764 on_error:
4765         nvlist_destroy(nvl);
4766         free(nvlpacked, M_TEMP);
4767         return (error);
4768 }
4769
4770 static unsigned int
4771 pf_clear_states(const struct pf_kstate_kill *kill)
4772 {
4773         struct pf_state_key_cmp  match_key;
4774         struct pf_kstate        *s;
4775         struct pfi_kkif *kif;
4776         int              idx;
4777         unsigned int     killed = 0, dir;
4778
4779         for (unsigned int i = 0; i <= pf_hashmask; i++) {
4780                 struct pf_idhash *ih = &V_pf_idhash[i];
4781
4782 relock_DIOCCLRSTATES:
4783                 PF_HASHROW_LOCK(ih);
4784                 LIST_FOREACH(s, &ih->states, entry) {
4785                         /* For floating states look at the original kif. */
4786                         kif = s->kif == V_pfi_all ? s->orig_kif : s->kif;
4787
4788                         if (kill->psk_ifname[0] &&
4789                             strcmp(kill->psk_ifname,
4790                             kif->pfik_name))
4791                                 continue;
4792
4793                         if (kill->psk_kill_match) {
4794                                 bzero(&match_key, sizeof(match_key));
4795
4796                                 if (s->direction == PF_OUT) {
4797                                         dir = PF_IN;
4798                                         idx = PF_SK_STACK;
4799                                 } else {
4800                                         dir = PF_OUT;
4801                                         idx = PF_SK_WIRE;
4802                                 }
4803
4804                                 match_key.af = s->key[idx]->af;
4805                                 match_key.proto = s->key[idx]->proto;
4806                                 PF_ACPY(&match_key.addr[0],
4807                                     &s->key[idx]->addr[1], match_key.af);
4808                                 match_key.port[0] = s->key[idx]->port[1];
4809                                 PF_ACPY(&match_key.addr[1],
4810                                     &s->key[idx]->addr[0], match_key.af);
4811                                 match_key.port[1] = s->key[idx]->port[0];
4812                         }
4813
4814                         /*
4815                          * Don't send out individual
4816                          * delete messages.
4817                          */
4818                         s->state_flags |= PFSTATE_NOSYNC;
4819                         pf_unlink_state(s, PF_ENTER_LOCKED);
4820                         killed++;
4821
4822                         if (kill->psk_kill_match)
4823                                 killed += pf_kill_matching_state(&match_key,
4824                                     dir);
4825
4826                         goto relock_DIOCCLRSTATES;
4827                 }
4828                 PF_HASHROW_UNLOCK(ih);
4829         }
4830
4831         if (V_pfsync_clear_states_ptr != NULL)
4832                 V_pfsync_clear_states_ptr(V_pf_status.hostid, kill->psk_ifname);
4833
4834         return (killed);
4835 }
4836
4837 static int
4838 pf_killstates(struct pf_kstate_kill *kill, unsigned int *killed)
4839 {
4840         struct pf_kstate        *s;
4841
4842         if (kill->psk_pfcmp.id) {
4843                 if (kill->psk_pfcmp.creatorid == 0)
4844                         kill->psk_pfcmp.creatorid = V_pf_status.hostid;
4845                 if ((s = pf_find_state_byid(kill->psk_pfcmp.id,
4846                     kill->psk_pfcmp.creatorid))) {
4847                         pf_unlink_state(s, PF_ENTER_LOCKED);
4848                         *killed = 1;
4849                 }
4850                 return (0);
4851         }
4852
4853         for (unsigned int i = 0; i <= pf_hashmask; i++)
4854                 *killed += pf_killstates_row(kill, &V_pf_idhash[i]);
4855
4856         return (0);
4857 }
4858
4859 static int
4860 pf_killstates_nv(struct pfioc_nv *nv)
4861 {
4862         struct pf_kstate_kill    kill;
4863         nvlist_t                *nvl = NULL;
4864         void                    *nvlpacked = NULL;
4865         int                      error = 0;
4866         unsigned int             killed = 0;
4867
4868 #define ERROUT(x)       ERROUT_FUNCTION(on_error, x)
4869
4870         if (nv->len > pf_ioctl_maxcount)
4871                 ERROUT(ENOMEM);
4872
4873         nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
4874         if (nvlpacked == NULL)
4875                 ERROUT(ENOMEM);
4876
4877         error = copyin(nv->data, nvlpacked, nv->len);
4878         if (error)
4879                 ERROUT(error);
4880
4881         nvl = nvlist_unpack(nvlpacked, nv->len, 0);
4882         if (nvl == NULL)
4883                 ERROUT(EBADMSG);
4884
4885         error = pf_nvstate_kill_to_kstate_kill(nvl, &kill);
4886         if (error)
4887                 ERROUT(error);
4888
4889         error = pf_killstates(&kill, &killed);
4890         if (error)
4891                 ERROUT(error);
4892
4893         free(nvlpacked, M_NVLIST);
4894         nvlpacked = NULL;
4895         nvlist_destroy(nvl);
4896         nvl = nvlist_create(0);
4897         if (nvl == NULL)
4898                 ERROUT(ENOMEM);
4899
4900         nvlist_add_number(nvl, "killed", killed);
4901
4902         nvlpacked = nvlist_pack(nvl, &nv->len);
4903         if (nvlpacked == NULL)
4904                 ERROUT(ENOMEM);
4905
4906         if (nv->size == 0)
4907                 ERROUT(0);
4908         else if (nv->size < nv->len)
4909                 ERROUT(ENOSPC);
4910
4911         error = copyout(nvlpacked, nv->data, nv->len);
4912
4913 on_error:
4914         nvlist_destroy(nvl);
4915         free(nvlpacked, M_NVLIST);
4916         return (error);
4917 }
4918
4919 static int
4920 pf_clearstates_nv(struct pfioc_nv *nv)
4921 {
4922         struct pf_kstate_kill    kill;
4923         nvlist_t                *nvl = NULL;
4924         void                    *nvlpacked = NULL;
4925         int                      error = 0;
4926         unsigned int             killed;
4927
4928 #define ERROUT(x)       ERROUT_FUNCTION(on_error, x)
4929
4930         if (nv->len > pf_ioctl_maxcount)
4931                 ERROUT(ENOMEM);
4932
4933         nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
4934         if (nvlpacked == NULL)
4935                 ERROUT(ENOMEM);
4936
4937         error = copyin(nv->data, nvlpacked, nv->len);
4938         if (error)
4939                 ERROUT(error);
4940
4941         nvl = nvlist_unpack(nvlpacked, nv->len, 0);
4942         if (nvl == NULL)
4943                 ERROUT(EBADMSG);
4944
4945         error = pf_nvstate_kill_to_kstate_kill(nvl, &kill);
4946         if (error)
4947                 ERROUT(error);
4948
4949         killed = pf_clear_states(&kill);
4950
4951         free(nvlpacked, M_NVLIST);
4952         nvlpacked = NULL;
4953         nvlist_destroy(nvl);
4954         nvl = nvlist_create(0);
4955         if (nvl == NULL)
4956                 ERROUT(ENOMEM);
4957
4958         nvlist_add_number(nvl, "killed", killed);
4959
4960         nvlpacked = nvlist_pack(nvl, &nv->len);
4961         if (nvlpacked == NULL)
4962                 ERROUT(ENOMEM);
4963
4964         if (nv->size == 0)
4965                 ERROUT(0);
4966         else if (nv->size < nv->len)
4967                 ERROUT(ENOSPC);
4968
4969         error = copyout(nvlpacked, nv->data, nv->len);
4970
4971 #undef ERROUT
4972 on_error:
4973         nvlist_destroy(nvl);
4974         free(nvlpacked, M_NVLIST);
4975         return (error);
4976 }
4977
4978 static int
4979 pf_getstate(struct pfioc_nv *nv)
4980 {
4981         nvlist_t                *nvl = NULL, *nvls;
4982         void                    *nvlpacked = NULL;
4983         struct pf_kstate        *s = NULL;
4984         int                      error = 0;
4985         uint64_t                 id, creatorid;
4986
4987 #define ERROUT(x)       ERROUT_FUNCTION(errout, x)
4988
4989         if (nv->len > pf_ioctl_maxcount)
4990                 ERROUT(ENOMEM);
4991
4992         nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
4993         if (nvlpacked == NULL)
4994                 ERROUT(ENOMEM);
4995
4996         error = copyin(nv->data, nvlpacked, nv->len);
4997         if (error)
4998                 ERROUT(error);
4999
5000         nvl = nvlist_unpack(nvlpacked, nv->len, 0);
5001         if (nvl == NULL)
5002                 ERROUT(EBADMSG);
5003
5004         PFNV_CHK(pf_nvuint64(nvl, "id", &id));
5005         PFNV_CHK(pf_nvuint64(nvl, "creatorid", &creatorid));
5006
5007         s = pf_find_state_byid(id, creatorid);
5008         if (s == NULL)
5009                 ERROUT(ENOENT);
5010
5011         free(nvlpacked, M_NVLIST);
5012         nvlpacked = NULL;
5013         nvlist_destroy(nvl);
5014         nvl = nvlist_create(0);
5015         if (nvl == NULL)
5016                 ERROUT(ENOMEM);
5017
5018         nvls = pf_state_to_nvstate(s);
5019         if (nvls == NULL)
5020                 ERROUT(ENOMEM);
5021
5022         nvlist_add_nvlist(nvl, "state", nvls);
5023         nvlist_destroy(nvls);
5024
5025         nvlpacked = nvlist_pack(nvl, &nv->len);
5026         if (nvlpacked == NULL)
5027                 ERROUT(ENOMEM);
5028
5029         if (nv->size == 0)
5030                 ERROUT(0);
5031         else if (nv->size < nv->len)
5032                 ERROUT(ENOSPC);
5033
5034         error = copyout(nvlpacked, nv->data, nv->len);
5035
5036 #undef ERROUT
5037 errout:
5038         if (s != NULL)
5039                 PF_STATE_UNLOCK(s);
5040         free(nvlpacked, M_NVLIST);
5041         nvlist_destroy(nvl);
5042         return (error);
5043 }
5044
5045 static int
5046 pf_getstates(struct pfioc_nv *nv)
5047 {
5048         nvlist_t                *nvl = NULL, *nvls;
5049         void                    *nvlpacked = NULL;
5050         struct pf_kstate        *s = NULL;
5051         int                      error = 0;
5052         uint64_t                 count = 0;
5053
5054 #define ERROUT(x)       ERROUT_FUNCTION(errout, x)
5055
5056         nvl = nvlist_create(0);
5057         if (nvl == NULL)
5058                 ERROUT(ENOMEM);
5059
5060         nvlist_add_number(nvl, "count", uma_zone_get_cur(V_pf_state_z));
5061
5062         for (int i = 0; i < pf_hashmask; i++) {
5063                 struct pf_idhash *ih = &V_pf_idhash[i];
5064
5065                 /* Avoid taking the lock if there are no states in the row. */
5066                 if (LIST_EMPTY(&ih->states))
5067                         continue;
5068
5069                 PF_HASHROW_LOCK(ih);
5070                 LIST_FOREACH(s, &ih->states, entry) {
5071                         if (s->timeout == PFTM_UNLINKED)
5072                                 continue;
5073
5074                         if (SIGPENDING(curthread)) {
5075                                 PF_HASHROW_UNLOCK(ih);
5076                                 ERROUT(EINTR);
5077                         }
5078
5079                         nvls = pf_state_to_nvstate(s);
5080                         if (nvls == NULL) {
5081                                 PF_HASHROW_UNLOCK(ih);
5082                                 ERROUT(ENOMEM);
5083                         }
5084                         if ((nvlist_size(nvl) + nvlist_size(nvls)) > nv->size) {
5085                                 /* We've run out of room for more states. */
5086                                 nvlist_destroy(nvls);
5087                                 PF_HASHROW_UNLOCK(ih);
5088                                 goto DIOCGETSTATESNV_full;
5089                         }
5090                         nvlist_append_nvlist_array(nvl, "states", nvls);
5091                         nvlist_destroy(nvls);
5092                         count++;
5093                 }
5094                 PF_HASHROW_UNLOCK(ih);
5095         }
5096
5097         /* We've managed to put them all the available space. Let's make sure
5098          * 'count' matches our array (that's racy, because we don't hold a lock
5099          * over all states, only over each row individually. */
5100         (void)nvlist_take_number(nvl, "count");
5101         nvlist_add_number(nvl, "count", count);
5102
5103 DIOCGETSTATESNV_full:
5104
5105         nvlpacked = nvlist_pack(nvl, &nv->len);
5106         if (nvlpacked == NULL)
5107                 ERROUT(ENOMEM);
5108
5109         if (nv->size == 0)
5110                 ERROUT(0);
5111         else if (nv->size < nv->len)
5112                 ERROUT(ENOSPC);
5113
5114         error = copyout(nvlpacked, nv->data, nv->len);
5115
5116 #undef ERROUT
5117 errout:
5118         free(nvlpacked, M_NVLIST);
5119         nvlist_destroy(nvl);
5120         return (error);
5121 }
5122
5123 /*
5124  * XXX - Check for version missmatch!!!
5125  */
5126
5127 /*
5128  * Duplicate pfctl -Fa operation to get rid of as much as we can.
5129  */
5130 static int
5131 shutdown_pf(void)
5132 {
5133         int error = 0;
5134         u_int32_t t[5];
5135         char nn = '\0';
5136
5137         do {
5138                 if ((error = pf_begin_rules(&t[0], PF_RULESET_SCRUB, &nn))
5139                     != 0) {
5140                         DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: SCRUB\n"));
5141                         break;
5142                 }
5143                 if ((error = pf_begin_rules(&t[1], PF_RULESET_FILTER, &nn))
5144                     != 0) {
5145                         DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: FILTER\n"));
5146                         break;          /* XXX: rollback? */
5147                 }
5148                 if ((error = pf_begin_rules(&t[2], PF_RULESET_NAT, &nn))
5149                     != 0) {
5150                         DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: NAT\n"));
5151                         break;          /* XXX: rollback? */
5152                 }
5153                 if ((error = pf_begin_rules(&t[3], PF_RULESET_BINAT, &nn))
5154                     != 0) {
5155                         DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: BINAT\n"));
5156                         break;          /* XXX: rollback? */
5157                 }
5158                 if ((error = pf_begin_rules(&t[4], PF_RULESET_RDR, &nn))
5159                     != 0) {
5160                         DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: RDR\n"));
5161                         break;          /* XXX: rollback? */
5162                 }
5163
5164                 /* XXX: these should always succeed here */
5165                 pf_commit_rules(t[0], PF_RULESET_SCRUB, &nn);
5166                 pf_commit_rules(t[1], PF_RULESET_FILTER, &nn);
5167                 pf_commit_rules(t[2], PF_RULESET_NAT, &nn);
5168                 pf_commit_rules(t[3], PF_RULESET_BINAT, &nn);
5169                 pf_commit_rules(t[4], PF_RULESET_RDR, &nn);
5170
5171                 if ((error = pf_clear_tables()) != 0)
5172                         break;
5173
5174 #ifdef ALTQ
5175                 if ((error = pf_begin_altq(&t[0])) != 0) {
5176                         DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: ALTQ\n"));
5177                         break;
5178                 }
5179                 pf_commit_altq(t[0]);
5180 #endif
5181
5182                 pf_clear_all_states();
5183
5184                 pf_clear_srcnodes(NULL);
5185
5186                 /* status does not use malloced mem so no need to cleanup */
5187                 /* fingerprints and interfaces have their own cleanup code */
5188         } while(0);
5189
5190         return (error);
5191 }
5192
5193 static pfil_return_t
5194 pf_check_return(int chk, struct mbuf **m)
5195 {
5196
5197         switch (chk) {
5198         case PF_PASS:
5199                 if (*m == NULL)
5200                         return (PFIL_CONSUMED);
5201                 else
5202                         return (PFIL_PASS);
5203                 break;
5204         default:
5205                 if (*m != NULL) {
5206                         m_freem(*m);
5207                         *m = NULL;
5208                 }
5209                 return (PFIL_DROPPED);
5210         }
5211 }
5212
5213 #ifdef INET
5214 static pfil_return_t
5215 pf_check_in(struct mbuf **m, struct ifnet *ifp, int flags,
5216     void *ruleset __unused, struct inpcb *inp)
5217 {
5218         int chk;
5219
5220         chk = pf_test(PF_IN, flags, ifp, m, inp);
5221
5222         return (pf_check_return(chk, m));
5223 }
5224
5225 static pfil_return_t
5226 pf_check_out(struct mbuf **m, struct ifnet *ifp, int flags,
5227     void *ruleset __unused,  struct inpcb *inp)
5228 {
5229         int chk;
5230
5231         chk = pf_test(PF_OUT, flags, ifp, m, inp);
5232
5233         return (pf_check_return(chk, m));
5234 }
5235 #endif
5236
5237 #ifdef INET6
5238 static pfil_return_t
5239 pf_check6_in(struct mbuf **m, struct ifnet *ifp, int flags,
5240     void *ruleset __unused,  struct inpcb *inp)
5241 {
5242         int chk;
5243
5244         /*
5245          * In case of loopback traffic IPv6 uses the real interface in
5246          * order to support scoped addresses. In order to support stateful
5247          * filtering we have change this to lo0 as it is the case in IPv4.
5248          */
5249         CURVNET_SET(ifp->if_vnet);
5250         chk = pf_test6(PF_IN, flags, (*m)->m_flags & M_LOOP ? V_loif : ifp, m, inp);
5251         CURVNET_RESTORE();
5252
5253         return (pf_check_return(chk, m));
5254 }
5255
5256 static pfil_return_t
5257 pf_check6_out(struct mbuf **m, struct ifnet *ifp, int flags,
5258     void *ruleset __unused,  struct inpcb *inp)
5259 {
5260         int chk;
5261
5262         CURVNET_SET(ifp->if_vnet);
5263         chk = pf_test6(PF_OUT, flags, ifp, m, inp);
5264         CURVNET_RESTORE();
5265
5266         return (pf_check_return(chk, m));
5267 }
5268 #endif /* INET6 */
5269
5270 #ifdef INET
5271 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip4_in_hook);
5272 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip4_out_hook);
5273 #define V_pf_ip4_in_hook        VNET(pf_ip4_in_hook)
5274 #define V_pf_ip4_out_hook       VNET(pf_ip4_out_hook)
5275 #endif
5276 #ifdef INET6
5277 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip6_in_hook);
5278 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip6_out_hook);
5279 #define V_pf_ip6_in_hook        VNET(pf_ip6_in_hook)
5280 #define V_pf_ip6_out_hook       VNET(pf_ip6_out_hook)
5281 #endif
5282
5283 static void
5284 hook_pf(void)
5285 {
5286         struct pfil_hook_args pha;
5287         struct pfil_link_args pla;
5288         int ret;
5289
5290         if (V_pf_pfil_hooked)
5291                 return;
5292
5293         pha.pa_version = PFIL_VERSION;
5294         pha.pa_modname = "pf";
5295         pha.pa_ruleset = NULL;
5296
5297         pla.pa_version = PFIL_VERSION;
5298
5299 #ifdef INET
5300         pha.pa_type = PFIL_TYPE_IP4;
5301         pha.pa_func = pf_check_in;
5302         pha.pa_flags = PFIL_IN;
5303         pha.pa_rulname = "default-in";
5304         V_pf_ip4_in_hook = pfil_add_hook(&pha);
5305         pla.pa_flags = PFIL_IN | PFIL_HEADPTR | PFIL_HOOKPTR;
5306         pla.pa_head = V_inet_pfil_head;
5307         pla.pa_hook = V_pf_ip4_in_hook;
5308         ret = pfil_link(&pla);
5309         MPASS(ret == 0);
5310         pha.pa_func = pf_check_out;
5311         pha.pa_flags = PFIL_OUT;
5312         pha.pa_rulname = "default-out";
5313         V_pf_ip4_out_hook = pfil_add_hook(&pha);
5314         pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
5315         pla.pa_head = V_inet_pfil_head;
5316         pla.pa_hook = V_pf_ip4_out_hook;
5317         ret = pfil_link(&pla);
5318         MPASS(ret == 0);
5319 #endif
5320 #ifdef INET6
5321         pha.pa_type = PFIL_TYPE_IP6;
5322         pha.pa_func = pf_check6_in;
5323         pha.pa_flags = PFIL_IN;
5324         pha.pa_rulname = "default-in6";
5325         V_pf_ip6_in_hook = pfil_add_hook(&pha);
5326         pla.pa_flags = PFIL_IN | PFIL_HEADPTR | PFIL_HOOKPTR;
5327         pla.pa_head = V_inet6_pfil_head;
5328         pla.pa_hook = V_pf_ip6_in_hook;
5329         ret = pfil_link(&pla);
5330         MPASS(ret == 0);
5331         pha.pa_func = pf_check6_out;
5332         pha.pa_rulname = "default-out6";
5333         pha.pa_flags = PFIL_OUT;
5334         V_pf_ip6_out_hook = pfil_add_hook(&pha);
5335         pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
5336         pla.pa_head = V_inet6_pfil_head;
5337         pla.pa_hook = V_pf_ip6_out_hook;
5338         ret = pfil_link(&pla);
5339         MPASS(ret == 0);
5340 #endif
5341
5342         V_pf_pfil_hooked = 1;
5343 }
5344
5345 static void
5346 dehook_pf(void)
5347 {
5348
5349         if (V_pf_pfil_hooked == 0)
5350                 return;
5351
5352 #ifdef INET
5353         pfil_remove_hook(V_pf_ip4_in_hook);
5354         pfil_remove_hook(V_pf_ip4_out_hook);
5355 #endif
5356 #ifdef INET6
5357         pfil_remove_hook(V_pf_ip6_in_hook);
5358         pfil_remove_hook(V_pf_ip6_out_hook);
5359 #endif
5360
5361         V_pf_pfil_hooked = 0;
5362 }
5363
5364 static void
5365 pf_load_vnet(void)
5366 {
5367         V_pf_tag_z = uma_zcreate("pf tags", sizeof(struct pf_tagname),
5368             NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
5369
5370         pf_init_tagset(&V_pf_tags, &pf_rule_tag_hashsize,
5371             PF_RULE_TAG_HASH_SIZE_DEFAULT);
5372 #ifdef ALTQ
5373         pf_init_tagset(&V_pf_qids, &pf_queue_tag_hashsize,
5374             PF_QUEUE_TAG_HASH_SIZE_DEFAULT);
5375 #endif
5376
5377         pfattach_vnet();
5378         V_pf_vnet_active = 1;
5379 }
5380
5381 static int
5382 pf_load(void)
5383 {
5384         int error;
5385
5386         rm_init(&pf_rules_lock, "pf rulesets");
5387         sx_init(&pf_ioctl_lock, "pf ioctl");
5388         sx_init(&pf_end_lock, "pf end thread");
5389
5390         pf_mtag_initialize();
5391
5392         pf_dev = make_dev(&pf_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, PF_NAME);
5393         if (pf_dev == NULL)
5394                 return (ENOMEM);
5395
5396         pf_end_threads = 0;
5397         error = kproc_create(pf_purge_thread, NULL, &pf_purge_proc, 0, 0, "pf purge");
5398         if (error != 0)
5399                 return (error);
5400
5401         pfi_initialize();
5402
5403         return (0);
5404 }
5405
5406 static void
5407 pf_unload_vnet(void)
5408 {
5409         int ret;
5410
5411         V_pf_vnet_active = 0;
5412         V_pf_status.running = 0;
5413         dehook_pf();
5414
5415         PF_RULES_WLOCK();
5416         shutdown_pf();
5417         PF_RULES_WUNLOCK();
5418
5419         ret = swi_remove(V_pf_swi_cookie);
5420         MPASS(ret == 0);
5421         ret = intr_event_destroy(V_pf_swi_ie);
5422         MPASS(ret == 0);
5423
5424         pf_unload_vnet_purge();
5425
5426         pf_normalize_cleanup();
5427         PF_RULES_WLOCK();
5428         pfi_cleanup_vnet();
5429         PF_RULES_WUNLOCK();
5430         pfr_cleanup();
5431         pf_osfp_flush();
5432         pf_cleanup();
5433         if (IS_DEFAULT_VNET(curvnet))
5434                 pf_mtag_cleanup();
5435
5436         pf_cleanup_tagset(&V_pf_tags);
5437 #ifdef ALTQ
5438         pf_cleanup_tagset(&V_pf_qids);
5439 #endif
5440         uma_zdestroy(V_pf_tag_z);
5441
5442         /* Free counters last as we updated them during shutdown. */
5443         counter_u64_free(V_pf_default_rule.evaluations);
5444         for (int i = 0; i < 2; i++) {
5445                 counter_u64_free(V_pf_default_rule.packets[i]);
5446                 counter_u64_free(V_pf_default_rule.bytes[i]);
5447         }
5448         counter_u64_free(V_pf_default_rule.states_cur);
5449         counter_u64_free(V_pf_default_rule.states_tot);
5450         counter_u64_free(V_pf_default_rule.src_nodes);
5451
5452         for (int i = 0; i < PFRES_MAX; i++)
5453                 counter_u64_free(V_pf_status.counters[i]);
5454         for (int i = 0; i < LCNT_MAX; i++)
5455                 counter_u64_free(V_pf_status.lcounters[i]);
5456         for (int i = 0; i < FCNT_MAX; i++)
5457                 counter_u64_free(V_pf_status.fcounters[i]);
5458         for (int i = 0; i < SCNT_MAX; i++)
5459                 counter_u64_free(V_pf_status.scounters[i]);
5460 }
5461
5462 static void
5463 pf_unload(void)
5464 {
5465
5466         sx_xlock(&pf_end_lock);
5467         pf_end_threads = 1;
5468         while (pf_end_threads < 2) {
5469                 wakeup_one(pf_purge_thread);
5470                 sx_sleep(pf_purge_proc, &pf_end_lock, 0, "pftmo", 0);
5471         }
5472         sx_xunlock(&pf_end_lock);
5473
5474         if (pf_dev != NULL)
5475                 destroy_dev(pf_dev);
5476
5477         pfi_cleanup();
5478
5479         rm_destroy(&pf_rules_lock);
5480         sx_destroy(&pf_ioctl_lock);
5481         sx_destroy(&pf_end_lock);
5482 }
5483
5484 static void
5485 vnet_pf_init(void *unused __unused)
5486 {
5487
5488         pf_load_vnet();
5489 }
5490 VNET_SYSINIT(vnet_pf_init, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD, 
5491     vnet_pf_init, NULL);
5492
5493 static void
5494 vnet_pf_uninit(const void *unused __unused)
5495 {
5496
5497         pf_unload_vnet();
5498
5499 SYSUNINIT(pf_unload, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND, pf_unload, NULL);
5500 VNET_SYSUNINIT(vnet_pf_uninit, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
5501     vnet_pf_uninit, NULL);
5502
5503 static int
5504 pf_modevent(module_t mod, int type, void *data)
5505 {
5506         int error = 0;
5507
5508         switch(type) {
5509         case MOD_LOAD:
5510                 error = pf_load();
5511                 break;
5512         case MOD_UNLOAD:
5513                 /* Handled in SYSUNINIT(pf_unload) to ensure it's done after
5514                  * the vnet_pf_uninit()s */
5515                 break;
5516         default:
5517                 error = EINVAL;
5518                 break;
5519         }
5520
5521         return (error);
5522 }
5523
5524 static moduledata_t pf_mod = {
5525         "pf",
5526         pf_modevent,
5527         0
5528 };
5529
5530 DECLARE_MODULE(pf, pf_mod, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND);
5531 MODULE_VERSION(pf, PF_MODVER);