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