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