2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2001 Daniel Hartmeier
5 * Copyright (c) 2002,2003 Henning Brauer
6 * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.org>
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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.
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.
37 * $OpenBSD: pf_ioctl.c,v 1.213 2009/02/15 21:46:12 mbalmer Exp $
40 #include <sys/cdefs.h>
42 #include "opt_inet6.h"
46 #include <sys/param.h>
47 #include <sys/_bitset.h>
48 #include <sys/bitset.h>
51 #include <sys/endian.h>
52 #include <sys/fcntl.h>
53 #include <sys/filio.h>
55 #include <sys/interrupt.h>
57 #include <sys/kernel.h>
58 #include <sys/kthread.h>
61 #include <sys/module.h>
66 #include <sys/socket.h>
67 #include <sys/sysctl.h>
69 #include <sys/ucred.h>
72 #include <net/if_var.h>
73 #include <net/if_private.h>
75 #include <net/route.h>
77 #include <net/pfvar.h>
78 #include <net/if_pfsync.h>
79 #include <net/if_pflog.h>
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>
89 #include <netinet/ip6.h>
93 #include <net/altq/altq.h>
96 SDT_PROBE_DEFINE3(pf, ioctl, ioctl, error, "int", "int", "int");
97 SDT_PROBE_DEFINE3(pf, ioctl, function, error, "char *", "int", "int");
98 SDT_PROBE_DEFINE2(pf, ioctl, addrule, error, "int", "int");
99 SDT_PROBE_DEFINE2(pf, ioctl, nvchk, error, "int", "int");
101 static struct pf_kpool *pf_get_kpool(const char *, u_int32_t, u_int8_t,
102 u_int32_t, u_int8_t, u_int8_t, u_int8_t);
104 static void pf_mv_kpool(struct pf_kpalist *, struct pf_kpalist *);
105 static void pf_empty_kpool(struct pf_kpalist *);
106 static int pfioctl(struct cdev *, u_long, caddr_t, int,
108 static int pf_begin_eth(uint32_t *, const char *);
109 static void pf_rollback_eth_cb(struct epoch_context *);
110 static int pf_rollback_eth(uint32_t, const char *);
111 static int pf_commit_eth(uint32_t, const char *);
112 static void pf_free_eth_rule(struct pf_keth_rule *);
114 static int pf_begin_altq(u_int32_t *);
115 static int pf_rollback_altq(u_int32_t);
116 static int pf_commit_altq(u_int32_t);
117 static int pf_enable_altq(struct pf_altq *);
118 static int pf_disable_altq(struct pf_altq *);
119 static uint16_t pf_qname2qid(const char *);
120 static void pf_qid_unref(uint16_t);
122 static int pf_begin_rules(u_int32_t *, int, const char *);
123 static int pf_rollback_rules(u_int32_t, int, char *);
124 static int pf_setup_pfsync_matching(struct pf_kruleset *);
125 static void pf_hash_rule_rolling(MD5_CTX *, struct pf_krule *);
126 static void pf_hash_rule(struct pf_krule *);
127 static void pf_hash_rule_addr(MD5_CTX *, struct pf_rule_addr *);
128 static int pf_commit_rules(u_int32_t, int, char *);
129 static int pf_addr_setup(struct pf_kruleset *,
130 struct pf_addr_wrap *, sa_family_t);
131 static void pf_addr_copyout(struct pf_addr_wrap *);
132 static void pf_src_node_copy(const struct pf_ksrc_node *,
133 struct pf_src_node *);
135 static int pf_export_kaltq(struct pf_altq *,
136 struct pfioc_altq_v1 *, size_t);
137 static int pf_import_kaltq(struct pfioc_altq_v1 *,
138 struct pf_altq *, size_t);
141 VNET_DEFINE(struct pf_krule, pf_default_rule);
143 static __inline int pf_krule_compare(struct pf_krule *,
146 RB_GENERATE(pf_krule_global, pf_krule, entry_global, pf_krule_compare);
149 VNET_DEFINE_STATIC(int, pf_altq_running);
150 #define V_pf_altq_running VNET(pf_altq_running)
153 #define TAGID_MAX 50000
155 TAILQ_ENTRY(pf_tagname) namehash_entries;
156 TAILQ_ENTRY(pf_tagname) taghash_entries;
157 char name[PF_TAG_NAME_SIZE];
163 TAILQ_HEAD(, pf_tagname) *namehash;
164 TAILQ_HEAD(, pf_tagname) *taghash;
167 BITSET_DEFINE(, TAGID_MAX) avail;
170 VNET_DEFINE(struct pf_tagset, pf_tags);
171 #define V_pf_tags VNET(pf_tags)
172 static unsigned int pf_rule_tag_hashsize;
173 #define PF_RULE_TAG_HASH_SIZE_DEFAULT 128
174 SYSCTL_UINT(_net_pf, OID_AUTO, rule_tag_hashsize, CTLFLAG_RDTUN,
175 &pf_rule_tag_hashsize, PF_RULE_TAG_HASH_SIZE_DEFAULT,
176 "Size of pf(4) rule tag hashtable");
179 VNET_DEFINE(struct pf_tagset, pf_qids);
180 #define V_pf_qids VNET(pf_qids)
181 static unsigned int pf_queue_tag_hashsize;
182 #define PF_QUEUE_TAG_HASH_SIZE_DEFAULT 128
183 SYSCTL_UINT(_net_pf, OID_AUTO, queue_tag_hashsize, CTLFLAG_RDTUN,
184 &pf_queue_tag_hashsize, PF_QUEUE_TAG_HASH_SIZE_DEFAULT,
185 "Size of pf(4) queue tag hashtable");
187 VNET_DEFINE(uma_zone_t, pf_tag_z);
188 #define V_pf_tag_z VNET(pf_tag_z)
189 static MALLOC_DEFINE(M_PFALTQ, "pf_altq", "pf(4) altq configuration db");
190 static MALLOC_DEFINE(M_PFRULE, "pf_rule", "pf(4) rules");
192 #if (PF_QNAME_SIZE != PF_TAG_NAME_SIZE)
193 #error PF_QNAME_SIZE must be equal to PF_TAG_NAME_SIZE
196 VNET_DEFINE_STATIC(bool, pf_filter_local) = false;
197 #define V_pf_filter_local VNET(pf_filter_local)
198 SYSCTL_BOOL(_net_pf, OID_AUTO, filter_local, CTLFLAG_VNET | CTLFLAG_RW,
199 &VNET_NAME(pf_filter_local), false,
200 "Enable filtering for packets delivered to local network stack");
202 static void pf_init_tagset(struct pf_tagset *, unsigned int *,
204 static void pf_cleanup_tagset(struct pf_tagset *);
205 static uint16_t tagname2hashindex(const struct pf_tagset *, const char *);
206 static uint16_t tag2hashindex(const struct pf_tagset *, uint16_t);
207 static u_int16_t tagname2tag(struct pf_tagset *, const char *);
208 static u_int16_t pf_tagname2tag(const char *);
209 static void tag_unref(struct pf_tagset *, u_int16_t);
211 #define DPFPRINTF(n, x) if (V_pf_status.debug >= (n)) printf x
216 * XXX - These are new and need to be checked when moveing to a new version
218 static void pf_clear_all_states(void);
219 static unsigned int pf_clear_states(const struct pf_kstate_kill *);
220 static void pf_killstates(struct pf_kstate_kill *,
222 static int pf_killstates_row(struct pf_kstate_kill *,
224 static int pf_killstates_nv(struct pfioc_nv *);
225 static int pf_clearstates_nv(struct pfioc_nv *);
226 static int pf_getstate(struct pfioc_nv *);
227 static int pf_getstatus(struct pfioc_nv *);
228 static int pf_clear_tables(void);
229 static void pf_clear_srcnodes(struct pf_ksrc_node *);
230 static void pf_kill_srcnodes(struct pfioc_src_node_kill *);
231 static int pf_keepcounters(struct pfioc_nv *);
232 static void pf_tbladdr_copyout(struct pf_addr_wrap *);
235 * Wrapper functions for pfil(9) hooks
237 static pfil_return_t pf_eth_check_in(struct mbuf **m, struct ifnet *ifp,
238 int flags, void *ruleset __unused, struct inpcb *inp);
239 static pfil_return_t pf_eth_check_out(struct mbuf **m, struct ifnet *ifp,
240 int flags, void *ruleset __unused, struct inpcb *inp);
242 static pfil_return_t pf_check_in(struct mbuf **m, struct ifnet *ifp,
243 int flags, void *ruleset __unused, struct inpcb *inp);
244 static pfil_return_t pf_check_out(struct mbuf **m, struct ifnet *ifp,
245 int flags, void *ruleset __unused, struct inpcb *inp);
248 static pfil_return_t pf_check6_in(struct mbuf **m, struct ifnet *ifp,
249 int flags, void *ruleset __unused, struct inpcb *inp);
250 static pfil_return_t pf_check6_out(struct mbuf **m, struct ifnet *ifp,
251 int flags, void *ruleset __unused, struct inpcb *inp);
254 static void hook_pf_eth(void);
255 static void hook_pf(void);
256 static void dehook_pf_eth(void);
257 static void dehook_pf(void);
258 static int shutdown_pf(void);
259 static int pf_load(void);
260 static void pf_unload(void);
262 static struct cdevsw pf_cdevsw = {
265 .d_version = D_VERSION,
268 VNET_DEFINE_STATIC(bool, pf_pfil_hooked);
269 #define V_pf_pfil_hooked VNET(pf_pfil_hooked)
270 VNET_DEFINE_STATIC(bool, pf_pfil_eth_hooked);
271 #define V_pf_pfil_eth_hooked VNET(pf_pfil_eth_hooked)
274 * We need a flag that is neither hooked nor running to know when
275 * the VNET is "valid". We primarily need this to control (global)
276 * external event, e.g., eventhandlers.
278 VNET_DEFINE(int, pf_vnet_active);
279 #define V_pf_vnet_active VNET(pf_vnet_active)
282 struct proc *pf_purge_proc;
284 VNET_DEFINE(struct rmlock, pf_rules_lock);
285 VNET_DEFINE_STATIC(struct sx, pf_ioctl_lock);
286 #define V_pf_ioctl_lock VNET(pf_ioctl_lock)
287 struct sx pf_end_lock;
290 VNET_DEFINE(pfsync_state_import_t *, pfsync_state_import_ptr);
291 VNET_DEFINE(pfsync_insert_state_t *, pfsync_insert_state_ptr);
292 VNET_DEFINE(pfsync_update_state_t *, pfsync_update_state_ptr);
293 VNET_DEFINE(pfsync_delete_state_t *, pfsync_delete_state_ptr);
294 VNET_DEFINE(pfsync_clear_states_t *, pfsync_clear_states_ptr);
295 VNET_DEFINE(pfsync_defer_t *, pfsync_defer_ptr);
296 pfsync_detach_ifnet_t *pfsync_detach_ifnet_ptr;
299 pflog_packet_t *pflog_packet_ptr = NULL;
302 * Copy a user-provided string, returning an error if truncation would occur.
303 * Avoid scanning past "sz" bytes in the source string since there's no
304 * guarantee that it's nul-terminated.
307 pf_user_strcpy(char *dst, const char *src, size_t sz)
309 if (strnlen(src, sz) == sz)
311 (void)strlcpy(dst, src, sz);
318 u_int32_t *my_timeout = V_pf_default_rule.timeout;
320 bzero(&V_pf_status, sizeof(V_pf_status));
324 pfi_initialize_vnet();
326 pf_syncookies_init();
328 V_pf_limits[PF_LIMIT_STATES].limit = PFSTATE_HIWAT;
329 V_pf_limits[PF_LIMIT_SRC_NODES].limit = PFSNODE_HIWAT;
331 RB_INIT(&V_pf_anchors);
332 pf_init_kruleset(&pf_main_ruleset);
334 pf_init_keth(V_pf_keth);
336 /* default rule should never be garbage collected */
337 V_pf_default_rule.entries.tqe_prev = &V_pf_default_rule.entries.tqe_next;
338 #ifdef PF_DEFAULT_TO_DROP
339 V_pf_default_rule.action = PF_DROP;
341 V_pf_default_rule.action = PF_PASS;
343 V_pf_default_rule.nr = -1;
344 V_pf_default_rule.rtableid = -1;
346 pf_counter_u64_init(&V_pf_default_rule.evaluations, M_WAITOK);
347 for (int i = 0; i < 2; i++) {
348 pf_counter_u64_init(&V_pf_default_rule.packets[i], M_WAITOK);
349 pf_counter_u64_init(&V_pf_default_rule.bytes[i], M_WAITOK);
351 V_pf_default_rule.states_cur = counter_u64_alloc(M_WAITOK);
352 V_pf_default_rule.states_tot = counter_u64_alloc(M_WAITOK);
353 V_pf_default_rule.src_nodes = counter_u64_alloc(M_WAITOK);
355 V_pf_default_rule.timestamp = uma_zalloc_pcpu(pf_timestamp_pcpu_zone,
358 #ifdef PF_WANT_32_TO_64_COUNTER
359 V_pf_kifmarker = malloc(sizeof(*V_pf_kifmarker), PFI_MTYPE, M_WAITOK | M_ZERO);
360 V_pf_rulemarker = malloc(sizeof(*V_pf_rulemarker), M_PFRULE, M_WAITOK | M_ZERO);
362 LIST_INSERT_HEAD(&V_pf_allkiflist, V_pf_kifmarker, pfik_allkiflist);
363 LIST_INSERT_HEAD(&V_pf_allrulelist, &V_pf_default_rule, allrulelist);
365 LIST_INSERT_HEAD(&V_pf_allrulelist, V_pf_rulemarker, allrulelist);
369 /* initialize default timeouts */
370 my_timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
371 my_timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL;
372 my_timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL;
373 my_timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL;
374 my_timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL;
375 my_timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL;
376 my_timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL;
377 my_timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL;
378 my_timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL;
379 my_timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL;
380 my_timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL;
381 my_timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL;
382 my_timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL;
383 my_timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL;
384 my_timeout[PFTM_FRAG] = PFTM_FRAG_VAL;
385 my_timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL;
386 my_timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL;
387 my_timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL;
388 my_timeout[PFTM_ADAPTIVE_START] = PFSTATE_ADAPT_START;
389 my_timeout[PFTM_ADAPTIVE_END] = PFSTATE_ADAPT_END;
391 V_pf_status.debug = PF_DEBUG_URGENT;
393 * XXX This is different than in OpenBSD where reassembly is enabled by
394 * defult. In FreeBSD we expect people to still use scrub rules and
395 * switch to the new syntax later. Only when they switch they must
396 * explicitly enable reassemle. We could change the default once the
397 * scrub rule functionality is hopefully removed some day in future.
399 V_pf_status.reass = 0;
401 V_pf_pfil_hooked = false;
402 V_pf_pfil_eth_hooked = false;
404 /* XXX do our best to avoid a conflict */
405 V_pf_status.hostid = arc4random();
407 for (int i = 0; i < PFRES_MAX; i++)
408 V_pf_status.counters[i] = counter_u64_alloc(M_WAITOK);
409 for (int i = 0; i < KLCNT_MAX; i++)
410 V_pf_status.lcounters[i] = counter_u64_alloc(M_WAITOK);
411 for (int i = 0; i < FCNT_MAX; i++)
412 pf_counter_u64_init(&V_pf_status.fcounters[i], M_WAITOK);
413 for (int i = 0; i < SCNT_MAX; i++)
414 V_pf_status.scounters[i] = counter_u64_alloc(M_WAITOK);
416 if (swi_add(&V_pf_swi_ie, "pf send", pf_intr, curvnet, SWI_NET,
417 INTR_MPSAFE, &V_pf_swi_cookie) != 0)
418 /* XXXGL: leaked all above. */
422 static struct pf_kpool *
423 pf_get_kpool(const char *anchor, u_int32_t ticket, u_int8_t rule_action,
424 u_int32_t rule_number, u_int8_t r_last, u_int8_t active,
425 u_int8_t check_ticket)
427 struct pf_kruleset *ruleset;
428 struct pf_krule *rule;
431 ruleset = pf_find_kruleset(anchor);
434 rs_num = pf_get_ruleset_number(rule_action);
435 if (rs_num >= PF_RULESET_MAX)
438 if (check_ticket && ticket !=
439 ruleset->rules[rs_num].active.ticket)
442 rule = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
445 rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
447 if (check_ticket && ticket !=
448 ruleset->rules[rs_num].inactive.ticket)
451 rule = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,
454 rule = TAILQ_FIRST(ruleset->rules[rs_num].inactive.ptr);
457 while ((rule != NULL) && (rule->nr != rule_number))
458 rule = TAILQ_NEXT(rule, entries);
463 return (&rule->rpool);
467 pf_mv_kpool(struct pf_kpalist *poola, struct pf_kpalist *poolb)
469 struct pf_kpooladdr *mv_pool_pa;
471 while ((mv_pool_pa = TAILQ_FIRST(poola)) != NULL) {
472 TAILQ_REMOVE(poola, mv_pool_pa, entries);
473 TAILQ_INSERT_TAIL(poolb, mv_pool_pa, entries);
478 pf_empty_kpool(struct pf_kpalist *poola)
480 struct pf_kpooladdr *pa;
482 while ((pa = TAILQ_FIRST(poola)) != NULL) {
483 switch (pa->addr.type) {
484 case PF_ADDR_DYNIFTL:
485 pfi_dynaddr_remove(pa->addr.p.dyn);
488 /* XXX: this could be unfinished pooladdr on pabuf */
489 if (pa->addr.p.tbl != NULL)
490 pfr_detach_table(pa->addr.p.tbl);
494 pfi_kkif_unref(pa->kif);
495 TAILQ_REMOVE(poola, pa, entries);
501 pf_unlink_rule_locked(struct pf_krulequeue *rulequeue, struct pf_krule *rule)
505 PF_UNLNKDRULES_ASSERT();
507 TAILQ_REMOVE(rulequeue, rule, entries);
509 rule->rule_ref |= PFRULE_REFS;
510 TAILQ_INSERT_TAIL(&V_pf_unlinked_rules, rule, entries);
514 pf_unlink_rule(struct pf_krulequeue *rulequeue, struct pf_krule *rule)
519 PF_UNLNKDRULES_LOCK();
520 pf_unlink_rule_locked(rulequeue, rule);
521 PF_UNLNKDRULES_UNLOCK();
525 pf_free_eth_rule(struct pf_keth_rule *rule)
533 tag_unref(&V_pf_tags, rule->tag);
535 tag_unref(&V_pf_tags, rule->match_tag);
537 pf_qid_unref(rule->qid);
541 pfi_kkif_unref(rule->bridge_to);
543 pfi_kkif_unref(rule->kif);
545 if (rule->ipsrc.addr.type == PF_ADDR_TABLE)
546 pfr_detach_table(rule->ipsrc.addr.p.tbl);
547 if (rule->ipdst.addr.type == PF_ADDR_TABLE)
548 pfr_detach_table(rule->ipdst.addr.p.tbl);
550 counter_u64_free(rule->evaluations);
551 for (int i = 0; i < 2; i++) {
552 counter_u64_free(rule->packets[i]);
553 counter_u64_free(rule->bytes[i]);
555 uma_zfree_pcpu(pf_timestamp_pcpu_zone, rule->timestamp);
556 pf_keth_anchor_remove(rule);
558 free(rule, M_PFRULE);
562 pf_free_rule(struct pf_krule *rule)
569 tag_unref(&V_pf_tags, rule->tag);
571 tag_unref(&V_pf_tags, rule->match_tag);
573 if (rule->pqid != rule->qid)
574 pf_qid_unref(rule->pqid);
575 pf_qid_unref(rule->qid);
577 switch (rule->src.addr.type) {
578 case PF_ADDR_DYNIFTL:
579 pfi_dynaddr_remove(rule->src.addr.p.dyn);
582 pfr_detach_table(rule->src.addr.p.tbl);
585 switch (rule->dst.addr.type) {
586 case PF_ADDR_DYNIFTL:
587 pfi_dynaddr_remove(rule->dst.addr.p.dyn);
590 pfr_detach_table(rule->dst.addr.p.tbl);
593 if (rule->overload_tbl)
594 pfr_detach_table(rule->overload_tbl);
596 pfi_kkif_unref(rule->kif);
597 pf_kanchor_remove(rule);
598 pf_empty_kpool(&rule->rpool.list);
604 pf_init_tagset(struct pf_tagset *ts, unsigned int *tunable_size,
605 unsigned int default_size)
608 unsigned int hashsize;
610 if (*tunable_size == 0 || !powerof2(*tunable_size))
611 *tunable_size = default_size;
613 hashsize = *tunable_size;
614 ts->namehash = mallocarray(hashsize, sizeof(*ts->namehash), M_PFHASH,
616 ts->taghash = mallocarray(hashsize, sizeof(*ts->taghash), M_PFHASH,
618 ts->mask = hashsize - 1;
619 ts->seed = arc4random();
620 for (i = 0; i < hashsize; i++) {
621 TAILQ_INIT(&ts->namehash[i]);
622 TAILQ_INIT(&ts->taghash[i]);
624 BIT_FILL(TAGID_MAX, &ts->avail);
628 pf_cleanup_tagset(struct pf_tagset *ts)
631 unsigned int hashsize;
632 struct pf_tagname *t, *tmp;
635 * Only need to clean up one of the hashes as each tag is hashed
638 hashsize = ts->mask + 1;
639 for (i = 0; i < hashsize; i++)
640 TAILQ_FOREACH_SAFE(t, &ts->namehash[i], namehash_entries, tmp)
641 uma_zfree(V_pf_tag_z, t);
643 free(ts->namehash, M_PFHASH);
644 free(ts->taghash, M_PFHASH);
648 tagname2hashindex(const struct pf_tagset *ts, const char *tagname)
652 len = strnlen(tagname, PF_TAG_NAME_SIZE - 1);
653 return (murmur3_32_hash(tagname, len, ts->seed) & ts->mask);
657 tag2hashindex(const struct pf_tagset *ts, uint16_t tag)
660 return (tag & ts->mask);
664 tagname2tag(struct pf_tagset *ts, const char *tagname)
666 struct pf_tagname *tag;
672 index = tagname2hashindex(ts, tagname);
673 TAILQ_FOREACH(tag, &ts->namehash[index], namehash_entries)
674 if (strcmp(tagname, tag->name) == 0) {
682 * to avoid fragmentation, we do a linear search from the beginning
683 * and take the first free slot we find.
685 new_tagid = BIT_FFS(TAGID_MAX, &ts->avail);
687 * Tags are 1-based, with valid tags in the range [1..TAGID_MAX].
688 * BIT_FFS() returns a 1-based bit number, with 0 indicating no bits
689 * set. It may also return a bit number greater than TAGID_MAX due
690 * to rounding of the number of bits in the vector up to a multiple
691 * of the vector word size at declaration/allocation time.
693 if ((new_tagid == 0) || (new_tagid > TAGID_MAX))
696 /* Mark the tag as in use. Bits are 0-based for BIT_CLR() */
697 BIT_CLR(TAGID_MAX, new_tagid - 1, &ts->avail);
699 /* allocate and fill new struct pf_tagname */
700 tag = uma_zalloc(V_pf_tag_z, M_NOWAIT);
703 strlcpy(tag->name, tagname, sizeof(tag->name));
704 tag->tag = new_tagid;
707 /* Insert into namehash */
708 TAILQ_INSERT_TAIL(&ts->namehash[index], tag, namehash_entries);
710 /* Insert into taghash */
711 index = tag2hashindex(ts, new_tagid);
712 TAILQ_INSERT_TAIL(&ts->taghash[index], tag, taghash_entries);
718 tag_unref(struct pf_tagset *ts, u_int16_t tag)
720 struct pf_tagname *t;
725 index = tag2hashindex(ts, tag);
726 TAILQ_FOREACH(t, &ts->taghash[index], taghash_entries)
729 TAILQ_REMOVE(&ts->taghash[index], t,
731 index = tagname2hashindex(ts, t->name);
732 TAILQ_REMOVE(&ts->namehash[index], t,
734 /* Bits are 0-based for BIT_SET() */
735 BIT_SET(TAGID_MAX, tag - 1, &ts->avail);
736 uma_zfree(V_pf_tag_z, t);
743 pf_tagname2tag(const char *tagname)
745 return (tagname2tag(&V_pf_tags, tagname));
749 pf_begin_eth(uint32_t *ticket, const char *anchor)
751 struct pf_keth_rule *rule, *tmp;
752 struct pf_keth_ruleset *rs;
756 rs = pf_find_or_create_keth_ruleset(anchor);
760 /* Purge old inactive rules. */
761 TAILQ_FOREACH_SAFE(rule, rs->inactive.rules, entries,
763 TAILQ_REMOVE(rs->inactive.rules, rule,
765 pf_free_eth_rule(rule);
768 *ticket = ++rs->inactive.ticket;
769 rs->inactive.open = 1;
775 pf_rollback_eth_cb(struct epoch_context *ctx)
777 struct pf_keth_ruleset *rs;
779 rs = __containerof(ctx, struct pf_keth_ruleset, epoch_ctx);
781 CURVNET_SET(rs->vnet);
784 pf_rollback_eth(rs->inactive.ticket,
785 rs->anchor ? rs->anchor->path : "");
792 pf_rollback_eth(uint32_t ticket, const char *anchor)
794 struct pf_keth_rule *rule, *tmp;
795 struct pf_keth_ruleset *rs;
799 rs = pf_find_keth_ruleset(anchor);
803 if (!rs->inactive.open ||
804 ticket != rs->inactive.ticket)
807 /* Purge old inactive rules. */
808 TAILQ_FOREACH_SAFE(rule, rs->inactive.rules, entries,
810 TAILQ_REMOVE(rs->inactive.rules, rule, entries);
811 pf_free_eth_rule(rule);
814 rs->inactive.open = 0;
816 pf_remove_if_empty_keth_ruleset(rs);
821 #define PF_SET_SKIP_STEPS(i) \
823 while (head[i] != cur) { \
824 head[i]->skip[i].ptr = cur; \
825 head[i] = TAILQ_NEXT(head[i], entries); \
830 pf_eth_calc_skip_steps(struct pf_keth_ruleq *rules)
832 struct pf_keth_rule *cur, *prev, *head[PFE_SKIP_COUNT];
835 cur = TAILQ_FIRST(rules);
837 for (i = 0; i < PFE_SKIP_COUNT; ++i)
839 while (cur != NULL) {
840 if (cur->kif != prev->kif || cur->ifnot != prev->ifnot)
841 PF_SET_SKIP_STEPS(PFE_SKIP_IFP);
842 if (cur->direction != prev->direction)
843 PF_SET_SKIP_STEPS(PFE_SKIP_DIR);
844 if (cur->proto != prev->proto)
845 PF_SET_SKIP_STEPS(PFE_SKIP_PROTO);
846 if (memcmp(&cur->src, &prev->src, sizeof(cur->src)) != 0)
847 PF_SET_SKIP_STEPS(PFE_SKIP_SRC_ADDR);
848 if (memcmp(&cur->dst, &prev->dst, sizeof(cur->dst)) != 0)
849 PF_SET_SKIP_STEPS(PFE_SKIP_DST_ADDR);
850 if (cur->ipsrc.neg != prev->ipsrc.neg ||
851 pf_addr_wrap_neq(&cur->ipsrc.addr, &prev->ipsrc.addr))
852 PF_SET_SKIP_STEPS(PFE_SKIP_SRC_IP_ADDR);
853 if (cur->ipdst.neg != prev->ipdst.neg ||
854 pf_addr_wrap_neq(&cur->ipdst.addr, &prev->ipdst.addr))
855 PF_SET_SKIP_STEPS(PFE_SKIP_DST_IP_ADDR);
858 cur = TAILQ_NEXT(cur, entries);
860 for (i = 0; i < PFE_SKIP_COUNT; ++i)
861 PF_SET_SKIP_STEPS(i);
865 pf_commit_eth(uint32_t ticket, const char *anchor)
867 struct pf_keth_ruleq *rules;
868 struct pf_keth_ruleset *rs;
870 rs = pf_find_keth_ruleset(anchor);
875 if (!rs->inactive.open ||
876 ticket != rs->inactive.ticket)
881 pf_eth_calc_skip_steps(rs->inactive.rules);
883 rules = rs->active.rules;
884 ck_pr_store_ptr(&rs->active.rules, rs->inactive.rules);
885 rs->inactive.rules = rules;
886 rs->inactive.ticket = rs->active.ticket;
888 /* Clean up inactive rules (i.e. previously active rules), only when
889 * we're sure they're no longer used. */
890 NET_EPOCH_CALL(pf_rollback_eth_cb, &rs->epoch_ctx);
897 pf_qname2qid(const char *qname)
899 return (tagname2tag(&V_pf_qids, qname));
903 pf_qid_unref(uint16_t qid)
905 tag_unref(&V_pf_qids, qid);
909 pf_begin_altq(u_int32_t *ticket)
911 struct pf_altq *altq, *tmp;
916 /* Purge the old altq lists */
917 TAILQ_FOREACH_SAFE(altq, V_pf_altq_ifs_inactive, entries, tmp) {
918 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
919 /* detach and destroy the discipline */
920 error = altq_remove(altq);
922 free(altq, M_PFALTQ);
924 TAILQ_INIT(V_pf_altq_ifs_inactive);
925 TAILQ_FOREACH_SAFE(altq, V_pf_altqs_inactive, entries, tmp) {
926 pf_qid_unref(altq->qid);
927 free(altq, M_PFALTQ);
929 TAILQ_INIT(V_pf_altqs_inactive);
932 *ticket = ++V_ticket_altqs_inactive;
933 V_altqs_inactive_open = 1;
938 pf_rollback_altq(u_int32_t ticket)
940 struct pf_altq *altq, *tmp;
945 if (!V_altqs_inactive_open || ticket != V_ticket_altqs_inactive)
947 /* Purge the old altq lists */
948 TAILQ_FOREACH_SAFE(altq, V_pf_altq_ifs_inactive, entries, tmp) {
949 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
950 /* detach and destroy the discipline */
951 error = altq_remove(altq);
953 free(altq, M_PFALTQ);
955 TAILQ_INIT(V_pf_altq_ifs_inactive);
956 TAILQ_FOREACH_SAFE(altq, V_pf_altqs_inactive, entries, tmp) {
957 pf_qid_unref(altq->qid);
958 free(altq, M_PFALTQ);
960 TAILQ_INIT(V_pf_altqs_inactive);
961 V_altqs_inactive_open = 0;
966 pf_commit_altq(u_int32_t ticket)
968 struct pf_altqqueue *old_altqs, *old_altq_ifs;
969 struct pf_altq *altq, *tmp;
974 if (!V_altqs_inactive_open || ticket != V_ticket_altqs_inactive)
977 /* swap altqs, keep the old. */
978 old_altqs = V_pf_altqs_active;
979 old_altq_ifs = V_pf_altq_ifs_active;
980 V_pf_altqs_active = V_pf_altqs_inactive;
981 V_pf_altq_ifs_active = V_pf_altq_ifs_inactive;
982 V_pf_altqs_inactive = old_altqs;
983 V_pf_altq_ifs_inactive = old_altq_ifs;
984 V_ticket_altqs_active = V_ticket_altqs_inactive;
986 /* Attach new disciplines */
987 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) {
988 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
989 /* attach the discipline */
990 error = altq_pfattach(altq);
991 if (error == 0 && V_pf_altq_running)
992 error = pf_enable_altq(altq);
998 /* Purge the old altq lists */
999 TAILQ_FOREACH_SAFE(altq, V_pf_altq_ifs_inactive, entries, tmp) {
1000 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
1001 /* detach and destroy the discipline */
1002 if (V_pf_altq_running)
1003 error = pf_disable_altq(altq);
1004 err = altq_pfdetach(altq);
1005 if (err != 0 && error == 0)
1007 err = altq_remove(altq);
1008 if (err != 0 && error == 0)
1011 free(altq, M_PFALTQ);
1013 TAILQ_INIT(V_pf_altq_ifs_inactive);
1014 TAILQ_FOREACH_SAFE(altq, V_pf_altqs_inactive, entries, tmp) {
1015 pf_qid_unref(altq->qid);
1016 free(altq, M_PFALTQ);
1018 TAILQ_INIT(V_pf_altqs_inactive);
1020 V_altqs_inactive_open = 0;
1025 pf_enable_altq(struct pf_altq *altq)
1028 struct tb_profile tb;
1031 if ((ifp = ifunit(altq->ifname)) == NULL)
1034 if (ifp->if_snd.altq_type != ALTQT_NONE)
1035 error = altq_enable(&ifp->if_snd);
1037 /* set tokenbucket regulator */
1038 if (error == 0 && ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
1039 tb.rate = altq->ifbandwidth;
1040 tb.depth = altq->tbrsize;
1041 error = tbr_set(&ifp->if_snd, &tb);
1048 pf_disable_altq(struct pf_altq *altq)
1051 struct tb_profile tb;
1054 if ((ifp = ifunit(altq->ifname)) == NULL)
1058 * when the discipline is no longer referenced, it was overridden
1059 * by a new one. if so, just return.
1061 if (altq->altq_disc != ifp->if_snd.altq_disc)
1064 error = altq_disable(&ifp->if_snd);
1067 /* clear tokenbucket regulator */
1069 error = tbr_set(&ifp->if_snd, &tb);
1076 pf_altq_ifnet_event_add(struct ifnet *ifp, int remove, u_int32_t ticket,
1077 struct pf_altq *altq)
1082 /* Deactivate the interface in question */
1083 altq->local_flags &= ~PFALTQ_FLAG_IF_REMOVED;
1084 if ((ifp1 = ifunit(altq->ifname)) == NULL ||
1085 (remove && ifp1 == ifp)) {
1086 altq->local_flags |= PFALTQ_FLAG_IF_REMOVED;
1088 error = altq_add(ifp1, altq);
1090 if (ticket != V_ticket_altqs_inactive)
1094 free(altq, M_PFALTQ);
1101 pf_altq_ifnet_event(struct ifnet *ifp, int remove)
1103 struct pf_altq *a1, *a2, *a3;
1108 * No need to re-evaluate the configuration for events on interfaces
1109 * that do not support ALTQ, as it's not possible for such
1110 * interfaces to be part of the configuration.
1112 if (!ALTQ_IS_READY(&ifp->if_snd))
1115 /* Interrupt userland queue modifications */
1116 if (V_altqs_inactive_open)
1117 pf_rollback_altq(V_ticket_altqs_inactive);
1119 /* Start new altq ruleset */
1120 if (pf_begin_altq(&ticket))
1123 /* Copy the current active set */
1124 TAILQ_FOREACH(a1, V_pf_altq_ifs_active, entries) {
1125 a2 = malloc(sizeof(*a2), M_PFALTQ, M_NOWAIT);
1130 bcopy(a1, a2, sizeof(struct pf_altq));
1132 error = pf_altq_ifnet_event_add(ifp, remove, ticket, a2);
1136 TAILQ_INSERT_TAIL(V_pf_altq_ifs_inactive, a2, entries);
1140 TAILQ_FOREACH(a1, V_pf_altqs_active, entries) {
1141 a2 = malloc(sizeof(*a2), M_PFALTQ, M_NOWAIT);
1146 bcopy(a1, a2, sizeof(struct pf_altq));
1148 if ((a2->qid = pf_qname2qid(a2->qname)) == 0) {
1153 a2->altq_disc = NULL;
1154 TAILQ_FOREACH(a3, V_pf_altq_ifs_inactive, entries) {
1155 if (strncmp(a3->ifname, a2->ifname,
1157 a2->altq_disc = a3->altq_disc;
1161 error = pf_altq_ifnet_event_add(ifp, remove, ticket, a2);
1165 TAILQ_INSERT_TAIL(V_pf_altqs_inactive, a2, entries);
1170 pf_rollback_altq(ticket);
1172 pf_commit_altq(ticket);
1176 static struct pf_krule_global *
1177 pf_rule_tree_alloc(int flags)
1179 struct pf_krule_global *tree;
1181 tree = malloc(sizeof(struct pf_krule_global), M_TEMP, flags);
1189 pf_rule_tree_free(struct pf_krule_global *tree)
1196 pf_begin_rules(u_int32_t *ticket, int rs_num, const char *anchor)
1198 struct pf_krule_global *tree;
1199 struct pf_kruleset *rs;
1200 struct pf_krule *rule;
1204 if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
1206 tree = pf_rule_tree_alloc(M_NOWAIT);
1209 rs = pf_find_or_create_kruleset(anchor);
1214 pf_rule_tree_free(rs->rules[rs_num].inactive.tree);
1215 rs->rules[rs_num].inactive.tree = tree;
1217 while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL) {
1218 pf_unlink_rule(rs->rules[rs_num].inactive.ptr, rule);
1219 rs->rules[rs_num].inactive.rcount--;
1221 *ticket = ++rs->rules[rs_num].inactive.ticket;
1222 rs->rules[rs_num].inactive.open = 1;
1227 pf_rollback_rules(u_int32_t ticket, int rs_num, char *anchor)
1229 struct pf_kruleset *rs;
1230 struct pf_krule *rule;
1234 if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
1236 rs = pf_find_kruleset(anchor);
1237 if (rs == NULL || !rs->rules[rs_num].inactive.open ||
1238 rs->rules[rs_num].inactive.ticket != ticket)
1240 while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL) {
1241 pf_unlink_rule(rs->rules[rs_num].inactive.ptr, rule);
1242 rs->rules[rs_num].inactive.rcount--;
1244 rs->rules[rs_num].inactive.open = 0;
1248 #define PF_MD5_UPD(st, elm) \
1249 MD5Update(ctx, (u_int8_t *) &(st)->elm, sizeof((st)->elm))
1251 #define PF_MD5_UPD_STR(st, elm) \
1252 MD5Update(ctx, (u_int8_t *) (st)->elm, strlen((st)->elm))
1254 #define PF_MD5_UPD_HTONL(st, elm, stor) do { \
1255 (stor) = htonl((st)->elm); \
1256 MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int32_t));\
1259 #define PF_MD5_UPD_HTONS(st, elm, stor) do { \
1260 (stor) = htons((st)->elm); \
1261 MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int16_t));\
1265 pf_hash_rule_addr(MD5_CTX *ctx, struct pf_rule_addr *pfr)
1267 PF_MD5_UPD(pfr, addr.type);
1268 switch (pfr->addr.type) {
1269 case PF_ADDR_DYNIFTL:
1270 PF_MD5_UPD(pfr, addr.v.ifname);
1271 PF_MD5_UPD(pfr, addr.iflags);
1274 PF_MD5_UPD(pfr, addr.v.tblname);
1276 case PF_ADDR_ADDRMASK:
1277 /* XXX ignore af? */
1278 PF_MD5_UPD(pfr, addr.v.a.addr.addr32);
1279 PF_MD5_UPD(pfr, addr.v.a.mask.addr32);
1283 PF_MD5_UPD(pfr, port[0]);
1284 PF_MD5_UPD(pfr, port[1]);
1285 PF_MD5_UPD(pfr, neg);
1286 PF_MD5_UPD(pfr, port_op);
1290 pf_hash_rule_rolling(MD5_CTX *ctx, struct pf_krule *rule)
1295 pf_hash_rule_addr(ctx, &rule->src);
1296 pf_hash_rule_addr(ctx, &rule->dst);
1297 for (int i = 0; i < PF_RULE_MAX_LABEL_COUNT; i++)
1298 PF_MD5_UPD_STR(rule, label[i]);
1299 PF_MD5_UPD_STR(rule, ifname);
1300 PF_MD5_UPD_STR(rule, match_tagname);
1301 PF_MD5_UPD_HTONS(rule, match_tag, x); /* dup? */
1302 PF_MD5_UPD_HTONL(rule, os_fingerprint, y);
1303 PF_MD5_UPD_HTONL(rule, prob, y);
1304 PF_MD5_UPD_HTONL(rule, uid.uid[0], y);
1305 PF_MD5_UPD_HTONL(rule, uid.uid[1], y);
1306 PF_MD5_UPD(rule, uid.op);
1307 PF_MD5_UPD_HTONL(rule, gid.gid[0], y);
1308 PF_MD5_UPD_HTONL(rule, gid.gid[1], y);
1309 PF_MD5_UPD(rule, gid.op);
1310 PF_MD5_UPD_HTONL(rule, rule_flag, y);
1311 PF_MD5_UPD(rule, action);
1312 PF_MD5_UPD(rule, direction);
1313 PF_MD5_UPD(rule, af);
1314 PF_MD5_UPD(rule, quick);
1315 PF_MD5_UPD(rule, ifnot);
1316 PF_MD5_UPD(rule, match_tag_not);
1317 PF_MD5_UPD(rule, natpass);
1318 PF_MD5_UPD(rule, keep_state);
1319 PF_MD5_UPD(rule, proto);
1320 PF_MD5_UPD(rule, type);
1321 PF_MD5_UPD(rule, code);
1322 PF_MD5_UPD(rule, flags);
1323 PF_MD5_UPD(rule, flagset);
1324 PF_MD5_UPD(rule, allow_opts);
1325 PF_MD5_UPD(rule, rt);
1326 PF_MD5_UPD(rule, tos);
1327 PF_MD5_UPD(rule, scrub_flags);
1328 PF_MD5_UPD(rule, min_ttl);
1329 PF_MD5_UPD(rule, set_tos);
1330 if (rule->anchor != NULL)
1331 PF_MD5_UPD_STR(rule, anchor->path);
1335 pf_hash_rule(struct pf_krule *rule)
1340 pf_hash_rule_rolling(&ctx, rule);
1341 MD5Final(rule->md5sum, &ctx);
1345 pf_krule_compare(struct pf_krule *a, struct pf_krule *b)
1348 return (memcmp(a->md5sum, b->md5sum, PF_MD5_DIGEST_LENGTH));
1352 pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
1354 struct pf_kruleset *rs;
1355 struct pf_krule *rule, **old_array, *old_rule;
1356 struct pf_krulequeue *old_rules;
1357 struct pf_krule_global *old_tree;
1359 u_int32_t old_rcount;
1363 if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
1365 rs = pf_find_kruleset(anchor);
1366 if (rs == NULL || !rs->rules[rs_num].inactive.open ||
1367 ticket != rs->rules[rs_num].inactive.ticket)
1370 /* Calculate checksum for the main ruleset */
1371 if (rs == &pf_main_ruleset) {
1372 error = pf_setup_pfsync_matching(rs);
1377 /* Swap rules, keep the old. */
1378 old_rules = rs->rules[rs_num].active.ptr;
1379 old_rcount = rs->rules[rs_num].active.rcount;
1380 old_array = rs->rules[rs_num].active.ptr_array;
1381 old_tree = rs->rules[rs_num].active.tree;
1383 rs->rules[rs_num].active.ptr =
1384 rs->rules[rs_num].inactive.ptr;
1385 rs->rules[rs_num].active.ptr_array =
1386 rs->rules[rs_num].inactive.ptr_array;
1387 rs->rules[rs_num].active.tree =
1388 rs->rules[rs_num].inactive.tree;
1389 rs->rules[rs_num].active.rcount =
1390 rs->rules[rs_num].inactive.rcount;
1392 /* Attempt to preserve counter information. */
1393 if (V_pf_status.keep_counters && old_tree != NULL) {
1394 TAILQ_FOREACH(rule, rs->rules[rs_num].active.ptr,
1396 old_rule = RB_FIND(pf_krule_global, old_tree, rule);
1397 if (old_rule == NULL) {
1400 pf_counter_u64_critical_enter();
1401 pf_counter_u64_add_protected(&rule->evaluations,
1402 pf_counter_u64_fetch(&old_rule->evaluations));
1403 pf_counter_u64_add_protected(&rule->packets[0],
1404 pf_counter_u64_fetch(&old_rule->packets[0]));
1405 pf_counter_u64_add_protected(&rule->packets[1],
1406 pf_counter_u64_fetch(&old_rule->packets[1]));
1407 pf_counter_u64_add_protected(&rule->bytes[0],
1408 pf_counter_u64_fetch(&old_rule->bytes[0]));
1409 pf_counter_u64_add_protected(&rule->bytes[1],
1410 pf_counter_u64_fetch(&old_rule->bytes[1]));
1411 pf_counter_u64_critical_exit();
1415 rs->rules[rs_num].inactive.ptr = old_rules;
1416 rs->rules[rs_num].inactive.ptr_array = old_array;
1417 rs->rules[rs_num].inactive.tree = NULL; /* important for pf_ioctl_addrule */
1418 rs->rules[rs_num].inactive.rcount = old_rcount;
1420 rs->rules[rs_num].active.ticket =
1421 rs->rules[rs_num].inactive.ticket;
1422 pf_calc_skip_steps(rs->rules[rs_num].active.ptr);
1424 /* Purge the old rule list. */
1425 PF_UNLNKDRULES_LOCK();
1426 while ((rule = TAILQ_FIRST(old_rules)) != NULL)
1427 pf_unlink_rule_locked(old_rules, rule);
1428 PF_UNLNKDRULES_UNLOCK();
1429 if (rs->rules[rs_num].inactive.ptr_array)
1430 free(rs->rules[rs_num].inactive.ptr_array, M_TEMP);
1431 rs->rules[rs_num].inactive.ptr_array = NULL;
1432 rs->rules[rs_num].inactive.rcount = 0;
1433 rs->rules[rs_num].inactive.open = 0;
1434 pf_remove_if_empty_kruleset(rs);
1435 free(old_tree, M_TEMP);
1441 pf_setup_pfsync_matching(struct pf_kruleset *rs)
1444 struct pf_krule *rule;
1446 u_int8_t digest[PF_MD5_DIGEST_LENGTH];
1449 for (rs_cnt = 0; rs_cnt < PF_RULESET_MAX; rs_cnt++) {
1450 /* XXX PF_RULESET_SCRUB as well? */
1451 if (rs_cnt == PF_RULESET_SCRUB)
1454 if (rs->rules[rs_cnt].inactive.ptr_array)
1455 free(rs->rules[rs_cnt].inactive.ptr_array, M_TEMP);
1456 rs->rules[rs_cnt].inactive.ptr_array = NULL;
1458 if (rs->rules[rs_cnt].inactive.rcount) {
1459 rs->rules[rs_cnt].inactive.ptr_array =
1460 mallocarray(rs->rules[rs_cnt].inactive.rcount,
1461 sizeof(struct pf_rule **),
1464 if (!rs->rules[rs_cnt].inactive.ptr_array)
1468 TAILQ_FOREACH(rule, rs->rules[rs_cnt].inactive.ptr,
1470 pf_hash_rule_rolling(&ctx, rule);
1471 (rs->rules[rs_cnt].inactive.ptr_array)[rule->nr] = rule;
1475 MD5Final(digest, &ctx);
1476 memcpy(V_pf_status.pf_chksum, digest, sizeof(V_pf_status.pf_chksum));
1481 pf_eth_addr_setup(struct pf_keth_ruleset *ruleset, struct pf_addr_wrap *addr)
1485 switch (addr->type) {
1487 addr->p.tbl = pfr_eth_attach_table(ruleset, addr->v.tblname);
1488 if (addr->p.tbl == NULL)
1499 pf_addr_setup(struct pf_kruleset *ruleset, struct pf_addr_wrap *addr,
1504 switch (addr->type) {
1506 addr->p.tbl = pfr_attach_table(ruleset, addr->v.tblname);
1507 if (addr->p.tbl == NULL)
1510 case PF_ADDR_DYNIFTL:
1511 error = pfi_dynaddr_setup(addr, af);
1519 pf_addr_copyout(struct pf_addr_wrap *addr)
1522 switch (addr->type) {
1523 case PF_ADDR_DYNIFTL:
1524 pfi_dynaddr_copyout(addr);
1527 pf_tbladdr_copyout(addr);
1533 pf_src_node_copy(const struct pf_ksrc_node *in, struct pf_src_node *out)
1535 int secs = time_uptime, diff;
1537 bzero(out, sizeof(struct pf_src_node));
1539 bcopy(&in->addr, &out->addr, sizeof(struct pf_addr));
1540 bcopy(&in->raddr, &out->raddr, sizeof(struct pf_addr));
1542 if (in->rule.ptr != NULL)
1543 out->rule.nr = in->rule.ptr->nr;
1545 for (int i = 0; i < 2; i++) {
1546 out->bytes[i] = counter_u64_fetch(in->bytes[i]);
1547 out->packets[i] = counter_u64_fetch(in->packets[i]);
1550 out->states = in->states;
1551 out->conn = in->conn;
1553 out->ruletype = in->ruletype;
1555 out->creation = secs - in->creation;
1556 if (out->expire > secs)
1557 out->expire -= secs;
1561 /* Adjust the connection rate estimate. */
1562 diff = secs - in->conn_rate.last;
1563 if (diff >= in->conn_rate.seconds)
1564 out->conn_rate.count = 0;
1566 out->conn_rate.count -=
1567 in->conn_rate.count * diff /
1568 in->conn_rate.seconds;
1573 * Handle export of struct pf_kaltq to user binaries that may be using any
1574 * version of struct pf_altq.
1577 pf_export_kaltq(struct pf_altq *q, struct pfioc_altq_v1 *pa, size_t ioc_size)
1581 if (ioc_size == sizeof(struct pfioc_altq_v0))
1584 version = pa->version;
1586 if (version > PFIOC_ALTQ_VERSION)
1589 #define ASSIGN(x) exported_q->x = q->x
1591 bcopy(&q->x, &exported_q->x, min(sizeof(q->x), sizeof(exported_q->x)))
1592 #define SATU16(x) (u_int32_t)uqmin((x), USHRT_MAX)
1593 #define SATU32(x) (u_int32_t)uqmin((x), UINT_MAX)
1597 struct pf_altq_v0 *exported_q =
1598 &((struct pfioc_altq_v0 *)pa)->altq;
1604 exported_q->tbrsize = SATU16(q->tbrsize);
1605 exported_q->ifbandwidth = SATU32(q->ifbandwidth);
1610 exported_q->bandwidth = SATU32(q->bandwidth);
1612 ASSIGN(local_flags);
1617 if (q->scheduler == ALTQT_HFSC) {
1618 #define ASSIGN_OPT(x) exported_q->pq_u.hfsc_opts.x = q->pq_u.hfsc_opts.x
1619 #define ASSIGN_OPT_SATU32(x) exported_q->pq_u.hfsc_opts.x = \
1620 SATU32(q->pq_u.hfsc_opts.x)
1622 ASSIGN_OPT_SATU32(rtsc_m1);
1624 ASSIGN_OPT_SATU32(rtsc_m2);
1626 ASSIGN_OPT_SATU32(lssc_m1);
1628 ASSIGN_OPT_SATU32(lssc_m2);
1630 ASSIGN_OPT_SATU32(ulsc_m1);
1632 ASSIGN_OPT_SATU32(ulsc_m2);
1637 #undef ASSIGN_OPT_SATU32
1645 struct pf_altq_v1 *exported_q =
1646 &((struct pfioc_altq_v1 *)pa)->altq;
1652 ASSIGN(ifbandwidth);
1659 ASSIGN(local_flags);
1669 panic("%s: unhandled struct pfioc_altq version", __func__);
1682 * Handle import to struct pf_kaltq of struct pf_altq from user binaries
1683 * that may be using any version of it.
1686 pf_import_kaltq(struct pfioc_altq_v1 *pa, struct pf_altq *q, size_t ioc_size)
1690 if (ioc_size == sizeof(struct pfioc_altq_v0))
1693 version = pa->version;
1695 if (version > PFIOC_ALTQ_VERSION)
1698 #define ASSIGN(x) q->x = imported_q->x
1700 bcopy(&imported_q->x, &q->x, min(sizeof(imported_q->x), sizeof(q->x)))
1704 struct pf_altq_v0 *imported_q =
1705 &((struct pfioc_altq_v0 *)pa)->altq;
1710 ASSIGN(tbrsize); /* 16-bit -> 32-bit */
1711 ASSIGN(ifbandwidth); /* 32-bit -> 64-bit */
1716 ASSIGN(bandwidth); /* 32-bit -> 64-bit */
1718 ASSIGN(local_flags);
1723 if (imported_q->scheduler == ALTQT_HFSC) {
1724 #define ASSIGN_OPT(x) q->pq_u.hfsc_opts.x = imported_q->pq_u.hfsc_opts.x
1727 * The m1 and m2 parameters are being copied from
1730 ASSIGN_OPT(rtsc_m1);
1732 ASSIGN_OPT(rtsc_m2);
1734 ASSIGN_OPT(lssc_m1);
1736 ASSIGN_OPT(lssc_m2);
1738 ASSIGN_OPT(ulsc_m1);
1740 ASSIGN_OPT(ulsc_m2);
1752 struct pf_altq_v1 *imported_q =
1753 &((struct pfioc_altq_v1 *)pa)->altq;
1759 ASSIGN(ifbandwidth);
1766 ASSIGN(local_flags);
1776 panic("%s: unhandled struct pfioc_altq version", __func__);
1786 static struct pf_altq *
1787 pf_altq_get_nth_active(u_int32_t n)
1789 struct pf_altq *altq;
1793 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) {
1799 TAILQ_FOREACH(altq, V_pf_altqs_active, entries) {
1810 pf_krule_alloc(void)
1812 struct pf_krule *rule;
1814 rule = malloc(sizeof(struct pf_krule), M_PFRULE, M_WAITOK | M_ZERO);
1815 mtx_init(&rule->rpool.mtx, "pf_krule_pool", NULL, MTX_DEF);
1816 rule->timestamp = uma_zalloc_pcpu(pf_timestamp_pcpu_zone,
1822 pf_krule_free(struct pf_krule *rule)
1824 #ifdef PF_WANT_32_TO_64_COUNTER
1831 #ifdef PF_WANT_32_TO_64_COUNTER
1832 if (rule->allrulelinked) {
1833 wowned = PF_RULES_WOWNED();
1836 LIST_REMOVE(rule, allrulelist);
1837 V_pf_allrulecount--;
1843 pf_counter_u64_deinit(&rule->evaluations);
1844 for (int i = 0; i < 2; i++) {
1845 pf_counter_u64_deinit(&rule->packets[i]);
1846 pf_counter_u64_deinit(&rule->bytes[i]);
1848 counter_u64_free(rule->states_cur);
1849 counter_u64_free(rule->states_tot);
1850 counter_u64_free(rule->src_nodes);
1851 uma_zfree_pcpu(pf_timestamp_pcpu_zone, rule->timestamp);
1853 mtx_destroy(&rule->rpool.mtx);
1854 free(rule, M_PFRULE);
1858 pf_kpooladdr_to_pooladdr(const struct pf_kpooladdr *kpool,
1859 struct pf_pooladdr *pool)
1862 bzero(pool, sizeof(*pool));
1863 bcopy(&kpool->addr, &pool->addr, sizeof(pool->addr));
1864 strlcpy(pool->ifname, kpool->ifname, sizeof(pool->ifname));
1868 pf_pooladdr_to_kpooladdr(const struct pf_pooladdr *pool,
1869 struct pf_kpooladdr *kpool)
1873 bzero(kpool, sizeof(*kpool));
1874 bcopy(&pool->addr, &kpool->addr, sizeof(kpool->addr));
1875 ret = pf_user_strcpy(kpool->ifname, pool->ifname,
1876 sizeof(kpool->ifname));
1881 pf_pool_to_kpool(const struct pf_pool *pool, struct pf_kpool *kpool)
1883 _Static_assert(sizeof(pool->key) == sizeof(kpool->key), "");
1884 _Static_assert(sizeof(pool->counter) == sizeof(kpool->counter), "");
1886 bcopy(&pool->key, &kpool->key, sizeof(kpool->key));
1887 bcopy(&pool->counter, &kpool->counter, sizeof(kpool->counter));
1889 kpool->tblidx = pool->tblidx;
1890 kpool->proxy_port[0] = pool->proxy_port[0];
1891 kpool->proxy_port[1] = pool->proxy_port[1];
1892 kpool->opts = pool->opts;
1896 pf_rule_to_krule(const struct pf_rule *rule, struct pf_krule *krule)
1901 if (rule->af == AF_INET) {
1902 return (EAFNOSUPPORT);
1906 if (rule->af == AF_INET6) {
1907 return (EAFNOSUPPORT);
1911 ret = pf_check_rule_addr(&rule->src);
1914 ret = pf_check_rule_addr(&rule->dst);
1918 bcopy(&rule->src, &krule->src, sizeof(rule->src));
1919 bcopy(&rule->dst, &krule->dst, sizeof(rule->dst));
1921 ret = pf_user_strcpy(krule->label[0], rule->label, sizeof(rule->label));
1924 ret = pf_user_strcpy(krule->ifname, rule->ifname, sizeof(rule->ifname));
1927 ret = pf_user_strcpy(krule->qname, rule->qname, sizeof(rule->qname));
1930 ret = pf_user_strcpy(krule->pqname, rule->pqname, sizeof(rule->pqname));
1933 ret = pf_user_strcpy(krule->tagname, rule->tagname,
1934 sizeof(rule->tagname));
1937 ret = pf_user_strcpy(krule->match_tagname, rule->match_tagname,
1938 sizeof(rule->match_tagname));
1941 ret = pf_user_strcpy(krule->overload_tblname, rule->overload_tblname,
1942 sizeof(rule->overload_tblname));
1946 pf_pool_to_kpool(&rule->rpool, &krule->rpool);
1948 /* Don't allow userspace to set evaluations, packets or bytes. */
1949 /* kif, anchor, overload_tbl are not copied over. */
1951 krule->os_fingerprint = rule->os_fingerprint;
1953 krule->rtableid = rule->rtableid;
1954 bcopy(rule->timeout, krule->timeout, sizeof(krule->timeout));
1955 krule->max_states = rule->max_states;
1956 krule->max_src_nodes = rule->max_src_nodes;
1957 krule->max_src_states = rule->max_src_states;
1958 krule->max_src_conn = rule->max_src_conn;
1959 krule->max_src_conn_rate.limit = rule->max_src_conn_rate.limit;
1960 krule->max_src_conn_rate.seconds = rule->max_src_conn_rate.seconds;
1961 krule->qid = rule->qid;
1962 krule->pqid = rule->pqid;
1963 krule->nr = rule->nr;
1964 krule->prob = rule->prob;
1965 krule->cuid = rule->cuid;
1966 krule->cpid = rule->cpid;
1968 krule->return_icmp = rule->return_icmp;
1969 krule->return_icmp6 = rule->return_icmp6;
1970 krule->max_mss = rule->max_mss;
1971 krule->tag = rule->tag;
1972 krule->match_tag = rule->match_tag;
1973 krule->scrub_flags = rule->scrub_flags;
1975 bcopy(&rule->uid, &krule->uid, sizeof(krule->uid));
1976 bcopy(&rule->gid, &krule->gid, sizeof(krule->gid));
1978 krule->rule_flag = rule->rule_flag;
1979 krule->action = rule->action;
1980 krule->direction = rule->direction;
1981 krule->log = rule->log;
1982 krule->logif = rule->logif;
1983 krule->quick = rule->quick;
1984 krule->ifnot = rule->ifnot;
1985 krule->match_tag_not = rule->match_tag_not;
1986 krule->natpass = rule->natpass;
1988 krule->keep_state = rule->keep_state;
1989 krule->af = rule->af;
1990 krule->proto = rule->proto;
1991 krule->type = rule->type;
1992 krule->code = rule->code;
1993 krule->flags = rule->flags;
1994 krule->flagset = rule->flagset;
1995 krule->min_ttl = rule->min_ttl;
1996 krule->allow_opts = rule->allow_opts;
1997 krule->rt = rule->rt;
1998 krule->return_ttl = rule->return_ttl;
1999 krule->tos = rule->tos;
2000 krule->set_tos = rule->set_tos;
2002 krule->flush = rule->flush;
2003 krule->prio = rule->prio;
2004 krule->set_prio[0] = rule->set_prio[0];
2005 krule->set_prio[1] = rule->set_prio[1];
2007 bcopy(&rule->divert, &krule->divert, sizeof(krule->divert));
2013 pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket,
2014 uint32_t pool_ticket, const char *anchor, const char *anchor_call,
2017 struct pf_kruleset *ruleset;
2018 struct pf_krule *tail;
2019 struct pf_kpooladdr *pa;
2020 struct pfi_kkif *kif = NULL;
2024 if ((rule->return_icmp >> 8) > ICMP_MAXTYPE) {
2026 goto errout_unlocked;
2029 #define ERROUT(x) ERROUT_FUNCTION(errout, x)
2031 if (rule->ifname[0])
2032 kif = pf_kkif_create(M_WAITOK);
2033 pf_counter_u64_init(&rule->evaluations, M_WAITOK);
2034 for (int i = 0; i < 2; i++) {
2035 pf_counter_u64_init(&rule->packets[i], M_WAITOK);
2036 pf_counter_u64_init(&rule->bytes[i], M_WAITOK);
2038 rule->states_cur = counter_u64_alloc(M_WAITOK);
2039 rule->states_tot = counter_u64_alloc(M_WAITOK);
2040 rule->src_nodes = counter_u64_alloc(M_WAITOK);
2041 rule->cuid = td->td_ucred->cr_ruid;
2042 rule->cpid = td->td_proc ? td->td_proc->p_pid : 0;
2043 TAILQ_INIT(&rule->rpool.list);
2047 #ifdef PF_WANT_32_TO_64_COUNTER
2048 LIST_INSERT_HEAD(&V_pf_allrulelist, rule, allrulelist);
2049 MPASS(!rule->allrulelinked);
2050 rule->allrulelinked = true;
2051 V_pf_allrulecount++;
2053 ruleset = pf_find_kruleset(anchor);
2054 if (ruleset == NULL)
2056 rs_num = pf_get_ruleset_number(rule->action);
2057 if (rs_num >= PF_RULESET_MAX)
2059 if (ticket != ruleset->rules[rs_num].inactive.ticket) {
2060 DPFPRINTF(PF_DEBUG_MISC,
2061 ("ticket: %d != [%d]%d\n", ticket, rs_num,
2062 ruleset->rules[rs_num].inactive.ticket));
2065 if (pool_ticket != V_ticket_pabuf) {
2066 DPFPRINTF(PF_DEBUG_MISC,
2067 ("pool_ticket: %d != %d\n", pool_ticket,
2072 * XXXMJG hack: there is no mechanism to ensure they started the
2073 * transaction. Ticket checked above may happen to match by accident,
2074 * even if nobody called DIOCXBEGIN, let alone this process.
2075 * Partially work around it by checking if the RB tree got allocated,
2076 * see pf_begin_rules.
2078 if (ruleset->rules[rs_num].inactive.tree == NULL) {
2082 tail = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,
2085 rule->nr = tail->nr + 1;
2088 if (rule->ifname[0]) {
2089 rule->kif = pfi_kkif_attach(kif, rule->ifname);
2091 pfi_kkif_ref(rule->kif);
2095 if (rule->rtableid > 0 && rule->rtableid >= rt_numfibs)
2100 if (rule->qname[0] != 0) {
2101 if ((rule->qid = pf_qname2qid(rule->qname)) == 0)
2103 else if (rule->pqname[0] != 0) {
2105 pf_qname2qid(rule->pqname)) == 0)
2108 rule->pqid = rule->qid;
2111 if (rule->tagname[0])
2112 if ((rule->tag = pf_tagname2tag(rule->tagname)) == 0)
2114 if (rule->match_tagname[0])
2115 if ((rule->match_tag =
2116 pf_tagname2tag(rule->match_tagname)) == 0)
2118 if (rule->rt && !rule->direction)
2122 if (rule->logif >= PFLOGIFS_MAX)
2124 if (pf_addr_setup(ruleset, &rule->src.addr, rule->af))
2126 if (pf_addr_setup(ruleset, &rule->dst.addr, rule->af))
2128 if (pf_kanchor_setup(rule, ruleset, anchor_call))
2130 if (rule->scrub_flags & PFSTATE_SETPRIO &&
2131 (rule->set_prio[0] > PF_PRIO_MAX ||
2132 rule->set_prio[1] > PF_PRIO_MAX))
2134 TAILQ_FOREACH(pa, &V_pf_pabuf, entries)
2135 if (pa->addr.type == PF_ADDR_TABLE) {
2136 pa->addr.p.tbl = pfr_attach_table(ruleset,
2137 pa->addr.v.tblname);
2138 if (pa->addr.p.tbl == NULL)
2142 rule->overload_tbl = NULL;
2143 if (rule->overload_tblname[0]) {
2144 if ((rule->overload_tbl = pfr_attach_table(ruleset,
2145 rule->overload_tblname)) == NULL)
2148 rule->overload_tbl->pfrkt_flags |=
2152 pf_mv_kpool(&V_pf_pabuf, &rule->rpool.list);
2153 if (((((rule->action == PF_NAT) || (rule->action == PF_RDR) ||
2154 (rule->action == PF_BINAT)) && rule->anchor == NULL) ||
2155 (rule->rt > PF_NOPFROUTE)) &&
2156 (TAILQ_FIRST(&rule->rpool.list) == NULL))
2165 rule->rpool.cur = TAILQ_FIRST(&rule->rpool.list);
2166 TAILQ_INSERT_TAIL(ruleset->rules[rs_num].inactive.ptr,
2168 ruleset->rules[rs_num].inactive.rcount++;
2172 if (RB_INSERT(pf_krule_global, ruleset->rules[rs_num].inactive.tree, rule) != NULL) {
2174 TAILQ_REMOVE(ruleset->rules[rs_num].inactive.ptr, rule, entries);
2175 ruleset->rules[rs_num].inactive.rcount--;
2190 pf_krule_free(rule);
2195 pf_label_match(const struct pf_krule *rule, const char *label)
2199 while (*rule->label[i]) {
2200 if (strcmp(rule->label[i], label) == 0)
2209 pf_kill_matching_state(struct pf_state_key_cmp *key, int dir)
2211 struct pf_kstate *s;
2214 s = pf_find_state_all(key, dir, &more);
2228 pf_killstates_row(struct pf_kstate_kill *psk, struct pf_idhash *ih)
2230 struct pf_kstate *s;
2231 struct pf_state_key *sk;
2232 struct pf_addr *srcaddr, *dstaddr;
2233 struct pf_state_key_cmp match_key;
2234 int idx, killed = 0;
2236 u_int16_t srcport, dstport;
2237 struct pfi_kkif *kif;
2239 relock_DIOCKILLSTATES:
2240 PF_HASHROW_LOCK(ih);
2241 LIST_FOREACH(s, &ih->states, entry) {
2242 /* For floating states look at the original kif. */
2243 kif = s->kif == V_pfi_all ? s->orig_kif : s->kif;
2245 sk = s->key[PF_SK_WIRE];
2246 if (s->direction == PF_OUT) {
2247 srcaddr = &sk->addr[1];
2248 dstaddr = &sk->addr[0];
2249 srcport = sk->port[1];
2250 dstport = sk->port[0];
2252 srcaddr = &sk->addr[0];
2253 dstaddr = &sk->addr[1];
2254 srcport = sk->port[0];
2255 dstport = sk->port[1];
2258 if (psk->psk_af && sk->af != psk->psk_af)
2261 if (psk->psk_proto && psk->psk_proto != sk->proto)
2264 if (! PF_MATCHA(psk->psk_src.neg, &psk->psk_src.addr.v.a.addr,
2265 &psk->psk_src.addr.v.a.mask, srcaddr, sk->af))
2268 if (! PF_MATCHA(psk->psk_dst.neg, &psk->psk_dst.addr.v.a.addr,
2269 &psk->psk_dst.addr.v.a.mask, dstaddr, sk->af))
2272 if (! PF_MATCHA(psk->psk_rt_addr.neg,
2273 &psk->psk_rt_addr.addr.v.a.addr,
2274 &psk->psk_rt_addr.addr.v.a.mask,
2275 &s->rt_addr, sk->af))
2278 if (psk->psk_src.port_op != 0 &&
2279 ! pf_match_port(psk->psk_src.port_op,
2280 psk->psk_src.port[0], psk->psk_src.port[1], srcport))
2283 if (psk->psk_dst.port_op != 0 &&
2284 ! pf_match_port(psk->psk_dst.port_op,
2285 psk->psk_dst.port[0], psk->psk_dst.port[1], dstport))
2288 if (psk->psk_label[0] &&
2289 ! pf_label_match(s->rule.ptr, psk->psk_label))
2292 if (psk->psk_ifname[0] && strcmp(psk->psk_ifname,
2296 if (psk->psk_kill_match) {
2297 /* Create the key to find matching states, with lock
2300 bzero(&match_key, sizeof(match_key));
2302 if (s->direction == PF_OUT) {
2310 match_key.af = s->key[idx]->af;
2311 match_key.proto = s->key[idx]->proto;
2312 PF_ACPY(&match_key.addr[0],
2313 &s->key[idx]->addr[1], match_key.af);
2314 match_key.port[0] = s->key[idx]->port[1];
2315 PF_ACPY(&match_key.addr[1],
2316 &s->key[idx]->addr[0], match_key.af);
2317 match_key.port[1] = s->key[idx]->port[0];
2323 if (psk->psk_kill_match)
2324 killed += pf_kill_matching_state(&match_key, dir);
2326 goto relock_DIOCKILLSTATES;
2328 PF_HASHROW_UNLOCK(ih);
2334 pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
2337 PF_RULES_RLOCK_TRACKER;
2339 #define ERROUT_IOCTL(target, x) \
2342 SDT_PROBE3(pf, ioctl, ioctl, error, cmd, error, __LINE__); \
2347 /* XXX keep in sync with switch() below */
2348 if (securelevel_gt(td->td_ucred, 2))
2355 case DIOCGETSTATENV:
2356 case DIOCSETSTATUSIF:
2357 case DIOCGETSTATUSNV:
2362 case DIOCGETSTATESV2:
2363 case DIOCGETTIMEOUT:
2364 case DIOCCLRRULECTRS:
2366 case DIOCGETALTQSV0:
2367 case DIOCGETALTQSV1:
2370 case DIOCGETQSTATSV0:
2371 case DIOCGETQSTATSV1:
2372 case DIOCGETRULESETS:
2373 case DIOCGETRULESET:
2374 case DIOCRGETTABLES:
2375 case DIOCRGETTSTATS:
2376 case DIOCRCLRTSTATS:
2382 case DIOCRGETASTATS:
2383 case DIOCRCLRASTATS:
2386 case DIOCGETSRCNODES:
2387 case DIOCCLRSRCNODES:
2388 case DIOCGETSYNCOOKIES:
2389 case DIOCIGETIFACES:
2390 case DIOCGIFSPEEDV0:
2391 case DIOCGIFSPEEDV1:
2394 case DIOCGETETHRULES:
2395 case DIOCGETETHRULE:
2396 case DIOCGETETHRULESETS:
2397 case DIOCGETETHRULESET:
2399 case DIOCRCLRTABLES:
2400 case DIOCRADDTABLES:
2401 case DIOCRDELTABLES:
2402 case DIOCRSETTFLAGS:
2403 if (((struct pfioc_table *)addr)->pfrio_flags &
2405 break; /* dummy operation ok */
2411 if (!(flags & FWRITE))
2417 case DIOCGETSTATENV:
2418 case DIOCGETSTATUSNV:
2420 case DIOCGETSTATESV2:
2421 case DIOCGETTIMEOUT:
2423 case DIOCGETALTQSV0:
2424 case DIOCGETALTQSV1:
2427 case DIOCGETQSTATSV0:
2428 case DIOCGETQSTATSV1:
2429 case DIOCGETRULESETS:
2430 case DIOCGETRULESET:
2432 case DIOCRGETTABLES:
2433 case DIOCRGETTSTATS:
2435 case DIOCRGETASTATS:
2438 case DIOCGETSRCNODES:
2439 case DIOCGETSYNCOOKIES:
2440 case DIOCIGETIFACES:
2441 case DIOCGIFSPEEDV1:
2442 case DIOCGIFSPEEDV0:
2444 case DIOCGETETHRULES:
2445 case DIOCGETETHRULE:
2446 case DIOCGETETHRULESETS:
2447 case DIOCGETETHRULESET:
2449 case DIOCRCLRTABLES:
2450 case DIOCRADDTABLES:
2451 case DIOCRDELTABLES:
2452 case DIOCRCLRTSTATS:
2457 case DIOCRSETTFLAGS:
2458 if (((struct pfioc_table *)addr)->pfrio_flags &
2460 flags |= FWRITE; /* need write lock for dummy */
2461 break; /* dummy operation ok */
2468 CURVNET_SET(TD_TO_VNET(td));
2472 sx_xlock(&V_pf_ioctl_lock);
2473 if (V_pf_status.running)
2477 if (! TAILQ_EMPTY(V_pf_keth->active.rules))
2479 V_pf_status.running = 1;
2480 V_pf_status.since = time_second;
2481 new_unrhdr64(&V_pf_stateid, time_second);
2483 DPFPRINTF(PF_DEBUG_MISC, ("pf: started\n"));
2488 sx_xlock(&V_pf_ioctl_lock);
2489 if (!V_pf_status.running)
2492 V_pf_status.running = 0;
2495 V_pf_status.since = time_second;
2496 DPFPRINTF(PF_DEBUG_MISC, ("pf: stopped\n"));
2500 case DIOCGETETHRULES: {
2501 struct pfioc_nv *nv = (struct pfioc_nv *)addr;
2504 struct pf_keth_rule *tail;
2505 struct pf_keth_ruleset *rs;
2506 u_int32_t ticket, nr;
2507 const char *anchor = "";
2512 #define ERROUT(x) ERROUT_IOCTL(DIOCGETETHRULES_error, x)
2514 if (nv->len > pf_ioctl_maxcount)
2517 /* Copy the request in */
2518 packed = malloc(nv->len, M_NVLIST, M_WAITOK);
2522 error = copyin(nv->data, packed, nv->len);
2526 nvl = nvlist_unpack(packed, nv->len, 0);
2530 if (! nvlist_exists_string(nvl, "anchor"))
2533 anchor = nvlist_get_string(nvl, "anchor");
2535 rs = pf_find_keth_ruleset(anchor);
2537 nvlist_destroy(nvl);
2539 free(packed, M_NVLIST);
2546 nvl = nvlist_create(0);
2552 ticket = rs->active.ticket;
2553 tail = TAILQ_LAST(rs->active.rules, pf_keth_ruleq);
2561 nvlist_add_number(nvl, "ticket", ticket);
2562 nvlist_add_number(nvl, "nr", nr);
2564 packed = nvlist_pack(nvl, &nv->len);
2570 else if (nv->size < nv->len)
2573 error = copyout(packed, nv->data, nv->len);
2576 DIOCGETETHRULES_error:
2577 free(packed, M_NVLIST);
2578 nvlist_destroy(nvl);
2582 case DIOCGETETHRULE: {
2583 struct epoch_tracker et;
2584 struct pfioc_nv *nv = (struct pfioc_nv *)addr;
2585 nvlist_t *nvl = NULL;
2586 void *nvlpacked = NULL;
2587 struct pf_keth_rule *rule = NULL;
2588 struct pf_keth_ruleset *rs;
2589 u_int32_t ticket, nr;
2593 #define ERROUT(x) ERROUT_IOCTL(DIOCGETETHRULE_error, x)
2595 if (nv->len > pf_ioctl_maxcount)
2598 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
2599 if (nvlpacked == NULL)
2602 error = copyin(nv->data, nvlpacked, nv->len);
2606 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
2609 if (! nvlist_exists_number(nvl, "ticket"))
2611 ticket = nvlist_get_number(nvl, "ticket");
2612 if (! nvlist_exists_string(nvl, "anchor"))
2614 anchor = nvlist_get_string(nvl, "anchor");
2616 if (nvlist_exists_bool(nvl, "clear"))
2617 clear = nvlist_get_bool(nvl, "clear");
2619 if (clear && !(flags & FWRITE))
2622 if (! nvlist_exists_number(nvl, "nr"))
2624 nr = nvlist_get_number(nvl, "nr");
2627 rs = pf_find_keth_ruleset(anchor);
2632 if (ticket != rs->active.ticket) {
2637 nvlist_destroy(nvl);
2639 free(nvlpacked, M_NVLIST);
2642 rule = TAILQ_FIRST(rs->active.rules);
2643 while ((rule != NULL) && (rule->nr != nr))
2644 rule = TAILQ_NEXT(rule, entries);
2649 /* Make sure rule can't go away. */
2650 NET_EPOCH_ENTER(et);
2652 nvl = pf_keth_rule_to_nveth_rule(rule);
2653 if (pf_keth_anchor_nvcopyout(rs, rule, nvl))
2659 nvlpacked = nvlist_pack(nvl, &nv->len);
2660 if (nvlpacked == NULL)
2665 else if (nv->size < nv->len)
2668 error = copyout(nvlpacked, nv->data, nv->len);
2669 if (error == 0 && clear) {
2670 counter_u64_zero(rule->evaluations);
2671 for (int i = 0; i < 2; i++) {
2672 counter_u64_zero(rule->packets[i]);
2673 counter_u64_zero(rule->bytes[i]);
2678 DIOCGETETHRULE_error:
2679 free(nvlpacked, M_NVLIST);
2680 nvlist_destroy(nvl);
2684 case DIOCADDETHRULE: {
2685 struct pfioc_nv *nv = (struct pfioc_nv *)addr;
2686 nvlist_t *nvl = NULL;
2687 void *nvlpacked = NULL;
2688 struct pf_keth_rule *rule = NULL, *tail = NULL;
2689 struct pf_keth_ruleset *ruleset = NULL;
2690 struct pfi_kkif *kif = NULL, *bridge_to_kif = NULL;
2691 const char *anchor = "", *anchor_call = "";
2693 #define ERROUT(x) ERROUT_IOCTL(DIOCADDETHRULE_error, x)
2695 if (nv->len > pf_ioctl_maxcount)
2698 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
2699 if (nvlpacked == NULL)
2702 error = copyin(nv->data, nvlpacked, nv->len);
2706 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
2710 if (! nvlist_exists_number(nvl, "ticket"))
2713 if (nvlist_exists_string(nvl, "anchor"))
2714 anchor = nvlist_get_string(nvl, "anchor");
2715 if (nvlist_exists_string(nvl, "anchor_call"))
2716 anchor_call = nvlist_get_string(nvl, "anchor_call");
2718 ruleset = pf_find_keth_ruleset(anchor);
2719 if (ruleset == NULL)
2722 if (nvlist_get_number(nvl, "ticket") !=
2723 ruleset->inactive.ticket) {
2724 DPFPRINTF(PF_DEBUG_MISC,
2725 ("ticket: %d != %d\n",
2726 (u_int32_t)nvlist_get_number(nvl, "ticket"),
2727 ruleset->inactive.ticket));
2731 rule = malloc(sizeof(*rule), M_PFRULE, M_WAITOK);
2734 rule->timestamp = NULL;
2736 error = pf_nveth_rule_to_keth_rule(nvl, rule);
2740 if (rule->ifname[0])
2741 kif = pf_kkif_create(M_WAITOK);
2742 if (rule->bridge_to_name[0])
2743 bridge_to_kif = pf_kkif_create(M_WAITOK);
2744 rule->evaluations = counter_u64_alloc(M_WAITOK);
2745 for (int i = 0; i < 2; i++) {
2746 rule->packets[i] = counter_u64_alloc(M_WAITOK);
2747 rule->bytes[i] = counter_u64_alloc(M_WAITOK);
2749 rule->timestamp = uma_zalloc_pcpu(pf_timestamp_pcpu_zone,
2754 if (rule->ifname[0]) {
2755 rule->kif = pfi_kkif_attach(kif, rule->ifname);
2756 pfi_kkif_ref(rule->kif);
2759 if (rule->bridge_to_name[0]) {
2760 rule->bridge_to = pfi_kkif_attach(bridge_to_kif,
2761 rule->bridge_to_name);
2762 pfi_kkif_ref(rule->bridge_to);
2764 rule->bridge_to = NULL;
2768 if (rule->qname[0] != 0) {
2769 if ((rule->qid = pf_qname2qid(rule->qname)) == 0)
2772 rule->qid = rule->qid;
2775 if (rule->tagname[0])
2776 if ((rule->tag = pf_tagname2tag(rule->tagname)) == 0)
2778 if (rule->match_tagname[0])
2779 if ((rule->match_tag = pf_tagname2tag(
2780 rule->match_tagname)) == 0)
2783 if (error == 0 && rule->ipdst.addr.type == PF_ADDR_TABLE)
2784 error = pf_eth_addr_setup(ruleset, &rule->ipdst.addr);
2785 if (error == 0 && rule->ipsrc.addr.type == PF_ADDR_TABLE)
2786 error = pf_eth_addr_setup(ruleset, &rule->ipsrc.addr);
2789 pf_free_eth_rule(rule);
2794 if (pf_keth_anchor_setup(rule, ruleset, anchor_call)) {
2795 pf_free_eth_rule(rule);
2800 tail = TAILQ_LAST(ruleset->inactive.rules, pf_keth_ruleq);
2802 rule->nr = tail->nr + 1;
2806 TAILQ_INSERT_TAIL(ruleset->inactive.rules, rule, entries);
2811 DIOCADDETHRULE_error:
2812 nvlist_destroy(nvl);
2813 free(nvlpacked, M_NVLIST);
2817 case DIOCGETETHRULESETS: {
2818 struct epoch_tracker et;
2819 struct pfioc_nv *nv = (struct pfioc_nv *)addr;
2820 nvlist_t *nvl = NULL;
2821 void *nvlpacked = NULL;
2822 struct pf_keth_ruleset *ruleset;
2823 struct pf_keth_anchor *anchor;
2826 #define ERROUT(x) ERROUT_IOCTL(DIOCGETETHRULESETS_error, x)
2828 if (nv->len > pf_ioctl_maxcount)
2831 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
2832 if (nvlpacked == NULL)
2835 error = copyin(nv->data, nvlpacked, nv->len);
2839 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
2842 if (! nvlist_exists_string(nvl, "path"))
2845 NET_EPOCH_ENTER(et);
2847 if ((ruleset = pf_find_keth_ruleset(
2848 nvlist_get_string(nvl, "path"))) == NULL) {
2853 if (ruleset->anchor == NULL) {
2854 RB_FOREACH(anchor, pf_keth_anchor_global, &V_pf_keth_anchors)
2855 if (anchor->parent == NULL)
2858 RB_FOREACH(anchor, pf_keth_anchor_node,
2859 &ruleset->anchor->children)
2865 nvlist_destroy(nvl);
2867 free(nvlpacked, M_NVLIST);
2870 nvl = nvlist_create(0);
2874 nvlist_add_number(nvl, "nr", nr);
2876 nvlpacked = nvlist_pack(nvl, &nv->len);
2877 if (nvlpacked == NULL)
2882 else if (nv->size < nv->len)
2885 error = copyout(nvlpacked, nv->data, nv->len);
2888 DIOCGETETHRULESETS_error:
2889 free(nvlpacked, M_NVLIST);
2890 nvlist_destroy(nvl);
2894 case DIOCGETETHRULESET: {
2895 struct epoch_tracker et;
2896 struct pfioc_nv *nv = (struct pfioc_nv *)addr;
2897 nvlist_t *nvl = NULL;
2898 void *nvlpacked = NULL;
2899 struct pf_keth_ruleset *ruleset;
2900 struct pf_keth_anchor *anchor;
2901 int nr = 0, req_nr = 0;
2904 #define ERROUT(x) ERROUT_IOCTL(DIOCGETETHRULESET_error, x)
2906 if (nv->len > pf_ioctl_maxcount)
2909 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
2910 if (nvlpacked == NULL)
2913 error = copyin(nv->data, nvlpacked, nv->len);
2917 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
2920 if (! nvlist_exists_string(nvl, "path"))
2922 if (! nvlist_exists_number(nvl, "nr"))
2925 req_nr = nvlist_get_number(nvl, "nr");
2927 NET_EPOCH_ENTER(et);
2929 if ((ruleset = pf_find_keth_ruleset(
2930 nvlist_get_string(nvl, "path"))) == NULL) {
2935 nvlist_destroy(nvl);
2937 free(nvlpacked, M_NVLIST);
2940 nvl = nvlist_create(0);
2946 if (ruleset->anchor == NULL) {
2947 RB_FOREACH(anchor, pf_keth_anchor_global,
2948 &V_pf_keth_anchors) {
2949 if (anchor->parent == NULL && nr++ == req_nr) {
2955 RB_FOREACH(anchor, pf_keth_anchor_node,
2956 &ruleset->anchor->children) {
2957 if (nr++ == req_nr) {
2966 nvlist_add_number(nvl, "nr", nr);
2967 nvlist_add_string(nvl, "name", anchor->name);
2968 if (ruleset->anchor)
2969 nvlist_add_string(nvl, "path",
2970 ruleset->anchor->path);
2972 nvlist_add_string(nvl, "path", "");
2977 nvlpacked = nvlist_pack(nvl, &nv->len);
2978 if (nvlpacked == NULL)
2983 else if (nv->size < nv->len)
2986 error = copyout(nvlpacked, nv->data, nv->len);
2989 DIOCGETETHRULESET_error:
2990 free(nvlpacked, M_NVLIST);
2991 nvlist_destroy(nvl);
2995 case DIOCADDRULENV: {
2996 struct pfioc_nv *nv = (struct pfioc_nv *)addr;
2997 nvlist_t *nvl = NULL;
2998 void *nvlpacked = NULL;
2999 struct pf_krule *rule = NULL;
3000 const char *anchor = "", *anchor_call = "";
3001 uint32_t ticket = 0, pool_ticket = 0;
3003 #define ERROUT(x) ERROUT_IOCTL(DIOCADDRULENV_error, x)
3005 if (nv->len > pf_ioctl_maxcount)
3008 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
3009 error = copyin(nv->data, nvlpacked, nv->len);
3013 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
3017 if (! nvlist_exists_number(nvl, "ticket"))
3019 ticket = nvlist_get_number(nvl, "ticket");
3021 if (! nvlist_exists_number(nvl, "pool_ticket"))
3023 pool_ticket = nvlist_get_number(nvl, "pool_ticket");
3025 if (! nvlist_exists_nvlist(nvl, "rule"))
3028 rule = pf_krule_alloc();
3029 error = pf_nvrule_to_krule(nvlist_get_nvlist(nvl, "rule"),
3034 if (nvlist_exists_string(nvl, "anchor"))
3035 anchor = nvlist_get_string(nvl, "anchor");
3036 if (nvlist_exists_string(nvl, "anchor_call"))
3037 anchor_call = nvlist_get_string(nvl, "anchor_call");
3039 if ((error = nvlist_error(nvl)))
3042 /* Frees rule on error */
3043 error = pf_ioctl_addrule(rule, ticket, pool_ticket, anchor,
3046 nvlist_destroy(nvl);
3047 free(nvlpacked, M_NVLIST);
3050 DIOCADDRULENV_error:
3051 pf_krule_free(rule);
3052 nvlist_destroy(nvl);
3053 free(nvlpacked, M_NVLIST);
3058 struct pfioc_rule *pr = (struct pfioc_rule *)addr;
3059 struct pf_krule *rule;
3061 rule = pf_krule_alloc();
3062 error = pf_rule_to_krule(&pr->rule, rule);
3064 pf_krule_free(rule);
3068 pr->anchor[sizeof(pr->anchor) - 1] = 0;
3070 /* Frees rule on error */
3071 error = pf_ioctl_addrule(rule, pr->ticket, pr->pool_ticket,
3072 pr->anchor, pr->anchor_call, td);
3076 case DIOCGETRULES: {
3077 struct pfioc_rule *pr = (struct pfioc_rule *)addr;
3078 struct pf_kruleset *ruleset;
3079 struct pf_krule *tail;
3082 pr->anchor[sizeof(pr->anchor) - 1] = 0;
3085 ruleset = pf_find_kruleset(pr->anchor);
3086 if (ruleset == NULL) {
3091 rs_num = pf_get_ruleset_number(pr->rule.action);
3092 if (rs_num >= PF_RULESET_MAX) {
3097 tail = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
3100 pr->nr = tail->nr + 1;
3103 pr->ticket = ruleset->rules[rs_num].active.ticket;
3108 case DIOCGETRULENV: {
3109 struct pfioc_nv *nv = (struct pfioc_nv *)addr;
3110 nvlist_t *nvrule = NULL;
3111 nvlist_t *nvl = NULL;
3112 struct pf_kruleset *ruleset;
3113 struct pf_krule *rule;
3114 void *nvlpacked = NULL;
3116 bool clear_counter = false;
3118 #define ERROUT(x) ERROUT_IOCTL(DIOCGETRULENV_error, x)
3120 if (nv->len > pf_ioctl_maxcount)
3123 /* Copy the request in */
3124 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
3125 if (nvlpacked == NULL)
3128 error = copyin(nv->data, nvlpacked, nv->len);
3132 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
3136 if (! nvlist_exists_string(nvl, "anchor"))
3138 if (! nvlist_exists_number(nvl, "ruleset"))
3140 if (! nvlist_exists_number(nvl, "ticket"))
3142 if (! nvlist_exists_number(nvl, "nr"))
3145 if (nvlist_exists_bool(nvl, "clear_counter"))
3146 clear_counter = nvlist_get_bool(nvl, "clear_counter");
3148 if (clear_counter && !(flags & FWRITE))
3151 nr = nvlist_get_number(nvl, "nr");
3154 ruleset = pf_find_kruleset(nvlist_get_string(nvl, "anchor"));
3155 if (ruleset == NULL) {
3160 rs_num = pf_get_ruleset_number(nvlist_get_number(nvl, "ruleset"));
3161 if (rs_num >= PF_RULESET_MAX) {
3166 if (nvlist_get_number(nvl, "ticket") !=
3167 ruleset->rules[rs_num].active.ticket) {
3172 if ((error = nvlist_error(nvl))) {
3177 rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
3178 while ((rule != NULL) && (rule->nr != nr))
3179 rule = TAILQ_NEXT(rule, entries);
3185 nvrule = pf_krule_to_nvrule(rule);
3187 nvlist_destroy(nvl);
3188 nvl = nvlist_create(0);
3193 nvlist_add_number(nvl, "nr", nr);
3194 nvlist_add_nvlist(nvl, "rule", nvrule);
3195 nvlist_destroy(nvrule);
3197 if (pf_kanchor_nvcopyout(ruleset, rule, nvl)) {
3202 free(nvlpacked, M_NVLIST);
3203 nvlpacked = nvlist_pack(nvl, &nv->len);
3204 if (nvlpacked == NULL) {
3209 if (nv->size == 0) {
3213 else if (nv->size < nv->len) {
3218 if (clear_counter) {
3219 pf_counter_u64_zero(&rule->evaluations);
3220 for (int i = 0; i < 2; i++) {
3221 pf_counter_u64_zero(&rule->packets[i]);
3222 pf_counter_u64_zero(&rule->bytes[i]);
3224 counter_u64_zero(rule->states_tot);
3228 error = copyout(nvlpacked, nv->data, nv->len);
3231 DIOCGETRULENV_error:
3232 free(nvlpacked, M_NVLIST);
3233 nvlist_destroy(nvrule);
3234 nvlist_destroy(nvl);
3239 case DIOCCHANGERULE: {
3240 struct pfioc_rule *pcr = (struct pfioc_rule *)addr;
3241 struct pf_kruleset *ruleset;
3242 struct pf_krule *oldrule = NULL, *newrule = NULL;
3243 struct pfi_kkif *kif = NULL;
3244 struct pf_kpooladdr *pa;
3248 pcr->anchor[sizeof(pcr->anchor) - 1] = 0;
3250 if (pcr->action < PF_CHANGE_ADD_HEAD ||
3251 pcr->action > PF_CHANGE_GET_TICKET) {
3255 if (pcr->rule.return_icmp >> 8 > ICMP_MAXTYPE) {
3260 if (pcr->action != PF_CHANGE_REMOVE) {
3261 newrule = pf_krule_alloc();
3262 error = pf_rule_to_krule(&pcr->rule, newrule);
3264 pf_krule_free(newrule);
3268 if (newrule->ifname[0])
3269 kif = pf_kkif_create(M_WAITOK);
3270 pf_counter_u64_init(&newrule->evaluations, M_WAITOK);
3271 for (int i = 0; i < 2; i++) {
3272 pf_counter_u64_init(&newrule->packets[i], M_WAITOK);
3273 pf_counter_u64_init(&newrule->bytes[i], M_WAITOK);
3275 newrule->states_cur = counter_u64_alloc(M_WAITOK);
3276 newrule->states_tot = counter_u64_alloc(M_WAITOK);
3277 newrule->src_nodes = counter_u64_alloc(M_WAITOK);
3278 newrule->cuid = td->td_ucred->cr_ruid;
3279 newrule->cpid = td->td_proc ? td->td_proc->p_pid : 0;
3280 TAILQ_INIT(&newrule->rpool.list);
3282 #define ERROUT(x) ERROUT_IOCTL(DIOCCHANGERULE_error, x)
3286 #ifdef PF_WANT_32_TO_64_COUNTER
3287 if (newrule != NULL) {
3288 LIST_INSERT_HEAD(&V_pf_allrulelist, newrule, allrulelist);
3289 newrule->allrulelinked = true;
3290 V_pf_allrulecount++;
3294 if (!(pcr->action == PF_CHANGE_REMOVE ||
3295 pcr->action == PF_CHANGE_GET_TICKET) &&
3296 pcr->pool_ticket != V_ticket_pabuf)
3299 ruleset = pf_find_kruleset(pcr->anchor);
3300 if (ruleset == NULL)
3303 rs_num = pf_get_ruleset_number(pcr->rule.action);
3304 if (rs_num >= PF_RULESET_MAX)
3308 * XXXMJG: there is no guarantee that the ruleset was
3309 * created by the usual route of calling DIOCXBEGIN.
3310 * As a result it is possible the rule tree will not
3311 * be allocated yet. Hack around it by doing it here.
3312 * Note it is fine to let the tree persist in case of
3313 * error as it will be freed down the road on future
3314 * updates (if need be).
3316 if (ruleset->rules[rs_num].active.tree == NULL) {
3317 ruleset->rules[rs_num].active.tree = pf_rule_tree_alloc(M_NOWAIT);
3318 if (ruleset->rules[rs_num].active.tree == NULL) {
3323 if (pcr->action == PF_CHANGE_GET_TICKET) {
3324 pcr->ticket = ++ruleset->rules[rs_num].active.ticket;
3326 } else if (pcr->ticket !=
3327 ruleset->rules[rs_num].active.ticket)
3330 if (pcr->action != PF_CHANGE_REMOVE) {
3331 if (newrule->ifname[0]) {
3332 newrule->kif = pfi_kkif_attach(kif,
3335 pfi_kkif_ref(newrule->kif);
3337 newrule->kif = NULL;
3339 if (newrule->rtableid > 0 &&
3340 newrule->rtableid >= rt_numfibs)
3345 if (newrule->qname[0] != 0) {
3347 pf_qname2qid(newrule->qname)) == 0)
3349 else if (newrule->pqname[0] != 0) {
3350 if ((newrule->pqid =
3351 pf_qname2qid(newrule->pqname)) == 0)
3354 newrule->pqid = newrule->qid;
3357 if (newrule->tagname[0])
3359 pf_tagname2tag(newrule->tagname)) == 0)
3361 if (newrule->match_tagname[0])
3362 if ((newrule->match_tag = pf_tagname2tag(
3363 newrule->match_tagname)) == 0)
3365 if (newrule->rt && !newrule->direction)
3369 if (newrule->logif >= PFLOGIFS_MAX)
3371 if (pf_addr_setup(ruleset, &newrule->src.addr, newrule->af))
3373 if (pf_addr_setup(ruleset, &newrule->dst.addr, newrule->af))
3375 if (pf_kanchor_setup(newrule, ruleset, pcr->anchor_call))
3377 TAILQ_FOREACH(pa, &V_pf_pabuf, entries)
3378 if (pa->addr.type == PF_ADDR_TABLE) {
3380 pfr_attach_table(ruleset,
3381 pa->addr.v.tblname);
3382 if (pa->addr.p.tbl == NULL)
3386 newrule->overload_tbl = NULL;
3387 if (newrule->overload_tblname[0]) {
3388 if ((newrule->overload_tbl = pfr_attach_table(
3389 ruleset, newrule->overload_tblname)) ==
3393 newrule->overload_tbl->pfrkt_flags |=
3397 pf_mv_kpool(&V_pf_pabuf, &newrule->rpool.list);
3398 if (((((newrule->action == PF_NAT) ||
3399 (newrule->action == PF_RDR) ||
3400 (newrule->action == PF_BINAT) ||
3401 (newrule->rt > PF_NOPFROUTE)) &&
3402 !newrule->anchor)) &&
3403 (TAILQ_FIRST(&newrule->rpool.list) == NULL))
3407 pf_free_rule(newrule);
3413 newrule->rpool.cur = TAILQ_FIRST(&newrule->rpool.list);
3415 pf_empty_kpool(&V_pf_pabuf);
3417 if (pcr->action == PF_CHANGE_ADD_HEAD)
3418 oldrule = TAILQ_FIRST(
3419 ruleset->rules[rs_num].active.ptr);
3420 else if (pcr->action == PF_CHANGE_ADD_TAIL)
3421 oldrule = TAILQ_LAST(
3422 ruleset->rules[rs_num].active.ptr, pf_krulequeue);
3424 oldrule = TAILQ_FIRST(
3425 ruleset->rules[rs_num].active.ptr);
3426 while ((oldrule != NULL) && (oldrule->nr != pcr->nr))
3427 oldrule = TAILQ_NEXT(oldrule, entries);
3428 if (oldrule == NULL) {
3429 if (newrule != NULL)
3430 pf_free_rule(newrule);
3438 if (pcr->action == PF_CHANGE_REMOVE) {
3439 pf_unlink_rule(ruleset->rules[rs_num].active.ptr,
3441 RB_REMOVE(pf_krule_global,
3442 ruleset->rules[rs_num].active.tree, oldrule);
3443 ruleset->rules[rs_num].active.rcount--;
3445 pf_hash_rule(newrule);
3446 if (RB_INSERT(pf_krule_global,
3447 ruleset->rules[rs_num].active.tree, newrule) != NULL) {
3448 pf_free_rule(newrule);
3455 if (oldrule == NULL)
3457 ruleset->rules[rs_num].active.ptr,
3459 else if (pcr->action == PF_CHANGE_ADD_HEAD ||
3460 pcr->action == PF_CHANGE_ADD_BEFORE)
3461 TAILQ_INSERT_BEFORE(oldrule, newrule, entries);
3464 ruleset->rules[rs_num].active.ptr,
3465 oldrule, newrule, entries);
3466 ruleset->rules[rs_num].active.rcount++;
3470 TAILQ_FOREACH(oldrule,
3471 ruleset->rules[rs_num].active.ptr, entries)
3474 ruleset->rules[rs_num].active.ticket++;
3476 pf_calc_skip_steps(ruleset->rules[rs_num].active.ptr);
3477 pf_remove_if_empty_kruleset(ruleset);
3484 DIOCCHANGERULE_error:
3487 pf_krule_free(newrule);
3492 case DIOCCLRSTATESNV: {
3493 error = pf_clearstates_nv((struct pfioc_nv *)addr);
3497 case DIOCKILLSTATESNV: {
3498 error = pf_killstates_nv((struct pfioc_nv *)addr);
3502 case DIOCADDSTATE: {
3503 struct pfioc_state *ps = (struct pfioc_state *)addr;
3504 struct pfsync_state_1301 *sp = &ps->state;
3506 if (sp->timeout >= PFTM_MAX) {
3510 if (V_pfsync_state_import_ptr != NULL) {
3512 error = V_pfsync_state_import_ptr(
3513 (union pfsync_state_union *)sp, PFSYNC_SI_IOCTL,
3514 PFSYNC_MSG_VERSION_1301);
3521 case DIOCGETSTATE: {
3522 struct pfioc_state *ps = (struct pfioc_state *)addr;
3523 struct pf_kstate *s;
3525 s = pf_find_state_byid(ps->state.id, ps->state.creatorid);
3531 pfsync_state_export((union pfsync_state_union*)&ps->state,
3532 s, PFSYNC_MSG_VERSION_1301);
3537 case DIOCGETSTATENV: {
3538 error = pf_getstate((struct pfioc_nv *)addr);
3542 case DIOCGETSTATES: {
3543 struct pfioc_states *ps = (struct pfioc_states *)addr;
3544 struct pf_kstate *s;
3545 struct pfsync_state_1301 *pstore, *p;
3547 size_t slice_count = 16, count;
3550 if (ps->ps_len <= 0) {
3551 nr = uma_zone_get_cur(V_pf_state_z);
3552 ps->ps_len = sizeof(struct pfsync_state_1301) * nr;
3556 out = ps->ps_states;
3557 pstore = mallocarray(slice_count,
3558 sizeof(struct pfsync_state_1301), M_TEMP, M_WAITOK | M_ZERO);
3561 for (i = 0; i <= pf_hashmask; i++) {
3562 struct pf_idhash *ih = &V_pf_idhash[i];
3564 DIOCGETSTATES_retry:
3567 if (LIST_EMPTY(&ih->states))
3570 PF_HASHROW_LOCK(ih);
3572 LIST_FOREACH(s, &ih->states, entry) {
3573 if (s->timeout == PFTM_UNLINKED)
3578 if (count > slice_count) {
3579 PF_HASHROW_UNLOCK(ih);
3580 free(pstore, M_TEMP);
3581 slice_count = count * 2;
3582 pstore = mallocarray(slice_count,
3583 sizeof(struct pfsync_state_1301), M_TEMP,
3585 goto DIOCGETSTATES_retry;
3588 if ((nr+count) * sizeof(*p) > ps->ps_len) {
3589 PF_HASHROW_UNLOCK(ih);
3590 goto DIOCGETSTATES_full;
3593 LIST_FOREACH(s, &ih->states, entry) {
3594 if (s->timeout == PFTM_UNLINKED)
3597 pfsync_state_export((union pfsync_state_union*)p,
3598 s, PFSYNC_MSG_VERSION_1301);
3602 PF_HASHROW_UNLOCK(ih);
3603 error = copyout(pstore, out,
3604 sizeof(struct pfsync_state_1301) * count);
3607 out = ps->ps_states + nr;
3610 ps->ps_len = sizeof(struct pfsync_state_1301) * nr;
3611 free(pstore, M_TEMP);
3616 case DIOCGETSTATESV2: {
3617 struct pfioc_states_v2 *ps = (struct pfioc_states_v2 *)addr;
3618 struct pf_kstate *s;
3619 struct pf_state_export *pstore, *p;
3621 size_t slice_count = 16, count;
3624 if (ps->ps_req_version > PF_STATE_VERSION) {
3629 if (ps->ps_len <= 0) {
3630 nr = uma_zone_get_cur(V_pf_state_z);
3631 ps->ps_len = sizeof(struct pf_state_export) * nr;
3635 out = ps->ps_states;
3636 pstore = mallocarray(slice_count,
3637 sizeof(struct pf_state_export), M_TEMP, M_WAITOK | M_ZERO);
3640 for (i = 0; i <= pf_hashmask; i++) {
3641 struct pf_idhash *ih = &V_pf_idhash[i];
3643 DIOCGETSTATESV2_retry:
3646 if (LIST_EMPTY(&ih->states))
3649 PF_HASHROW_LOCK(ih);
3651 LIST_FOREACH(s, &ih->states, entry) {
3652 if (s->timeout == PFTM_UNLINKED)
3657 if (count > slice_count) {
3658 PF_HASHROW_UNLOCK(ih);
3659 free(pstore, M_TEMP);
3660 slice_count = count * 2;
3661 pstore = mallocarray(slice_count,
3662 sizeof(struct pf_state_export), M_TEMP,
3664 goto DIOCGETSTATESV2_retry;
3667 if ((nr+count) * sizeof(*p) > ps->ps_len) {
3668 PF_HASHROW_UNLOCK(ih);
3669 goto DIOCGETSTATESV2_full;
3672 LIST_FOREACH(s, &ih->states, entry) {
3673 if (s->timeout == PFTM_UNLINKED)
3676 pf_state_export(p, s);
3680 PF_HASHROW_UNLOCK(ih);
3681 error = copyout(pstore, out,
3682 sizeof(struct pf_state_export) * count);
3685 out = ps->ps_states + nr;
3687 DIOCGETSTATESV2_full:
3688 ps->ps_len = nr * sizeof(struct pf_state_export);
3689 free(pstore, M_TEMP);
3694 case DIOCGETSTATUSNV: {
3695 error = pf_getstatus((struct pfioc_nv *)addr);
3699 case DIOCSETSTATUSIF: {
3700 struct pfioc_if *pi = (struct pfioc_if *)addr;
3702 if (pi->ifname[0] == 0) {
3703 bzero(V_pf_status.ifname, IFNAMSIZ);
3707 error = pf_user_strcpy(V_pf_status.ifname, pi->ifname, IFNAMSIZ);
3712 case DIOCCLRSTATUS: {
3714 for (int i = 0; i < PFRES_MAX; i++)
3715 counter_u64_zero(V_pf_status.counters[i]);
3716 for (int i = 0; i < FCNT_MAX; i++)
3717 pf_counter_u64_zero(&V_pf_status.fcounters[i]);
3718 for (int i = 0; i < SCNT_MAX; i++)
3719 counter_u64_zero(V_pf_status.scounters[i]);
3720 for (int i = 0; i < KLCNT_MAX; i++)
3721 counter_u64_zero(V_pf_status.lcounters[i]);
3722 V_pf_status.since = time_second;
3723 if (*V_pf_status.ifname)
3724 pfi_update_status(V_pf_status.ifname, NULL);
3730 struct pfioc_natlook *pnl = (struct pfioc_natlook *)addr;
3731 struct pf_state_key *sk;
3732 struct pf_kstate *state;
3733 struct pf_state_key_cmp key;
3734 int m = 0, direction = pnl->direction;
3737 /* NATLOOK src and dst are reversed, so reverse sidx/didx */
3738 sidx = (direction == PF_IN) ? 1 : 0;
3739 didx = (direction == PF_IN) ? 0 : 1;
3742 PF_AZERO(&pnl->saddr, pnl->af) ||
3743 PF_AZERO(&pnl->daddr, pnl->af) ||
3744 ((pnl->proto == IPPROTO_TCP ||
3745 pnl->proto == IPPROTO_UDP) &&
3746 (!pnl->dport || !pnl->sport)))
3749 bzero(&key, sizeof(key));
3751 key.proto = pnl->proto;
3752 PF_ACPY(&key.addr[sidx], &pnl->saddr, pnl->af);
3753 key.port[sidx] = pnl->sport;
3754 PF_ACPY(&key.addr[didx], &pnl->daddr, pnl->af);
3755 key.port[didx] = pnl->dport;
3757 state = pf_find_state_all(&key, direction, &m);
3758 if (state == NULL) {
3762 PF_STATE_UNLOCK(state);
3763 error = E2BIG; /* more than one state */
3765 sk = state->key[sidx];
3766 PF_ACPY(&pnl->rsaddr, &sk->addr[sidx], sk->af);
3767 pnl->rsport = sk->port[sidx];
3768 PF_ACPY(&pnl->rdaddr, &sk->addr[didx], sk->af);
3769 pnl->rdport = sk->port[didx];
3770 PF_STATE_UNLOCK(state);
3777 case DIOCSETTIMEOUT: {
3778 struct pfioc_tm *pt = (struct pfioc_tm *)addr;
3781 if (pt->timeout < 0 || pt->timeout >= PFTM_MAX ||
3787 old = V_pf_default_rule.timeout[pt->timeout];
3788 if (pt->timeout == PFTM_INTERVAL && pt->seconds == 0)
3790 V_pf_default_rule.timeout[pt->timeout] = pt->seconds;
3791 if (pt->timeout == PFTM_INTERVAL && pt->seconds < old)
3792 wakeup(pf_purge_thread);
3798 case DIOCGETTIMEOUT: {
3799 struct pfioc_tm *pt = (struct pfioc_tm *)addr;
3801 if (pt->timeout < 0 || pt->timeout >= PFTM_MAX) {
3806 pt->seconds = V_pf_default_rule.timeout[pt->timeout];
3811 case DIOCGETLIMIT: {
3812 struct pfioc_limit *pl = (struct pfioc_limit *)addr;
3814 if (pl->index < 0 || pl->index >= PF_LIMIT_MAX) {
3819 pl->limit = V_pf_limits[pl->index].limit;
3824 case DIOCSETLIMIT: {
3825 struct pfioc_limit *pl = (struct pfioc_limit *)addr;
3829 if (pl->index < 0 || pl->index >= PF_LIMIT_MAX ||
3830 V_pf_limits[pl->index].zone == NULL) {
3835 uma_zone_set_max(V_pf_limits[pl->index].zone, pl->limit);
3836 old_limit = V_pf_limits[pl->index].limit;
3837 V_pf_limits[pl->index].limit = pl->limit;
3838 pl->limit = old_limit;
3843 case DIOCSETDEBUG: {
3844 u_int32_t *level = (u_int32_t *)addr;
3847 V_pf_status.debug = *level;
3852 case DIOCCLRRULECTRS: {
3853 /* obsoleted by DIOCGETRULE with action=PF_GET_CLR_CNTR */
3854 struct pf_kruleset *ruleset = &pf_main_ruleset;
3855 struct pf_krule *rule;
3859 ruleset->rules[PF_RULESET_FILTER].active.ptr, entries) {
3860 pf_counter_u64_zero(&rule->evaluations);
3861 for (int i = 0; i < 2; i++) {
3862 pf_counter_u64_zero(&rule->packets[i]);
3863 pf_counter_u64_zero(&rule->bytes[i]);
3870 case DIOCGIFSPEEDV0:
3871 case DIOCGIFSPEEDV1: {
3872 struct pf_ifspeed_v1 *psp = (struct pf_ifspeed_v1 *)addr;
3873 struct pf_ifspeed_v1 ps;
3876 if (psp->ifname[0] == '\0') {
3881 error = pf_user_strcpy(ps.ifname, psp->ifname, IFNAMSIZ);
3884 ifp = ifunit(ps.ifname);
3887 (u_int32_t)uqmin(ifp->if_baudrate, UINT_MAX);
3888 if (cmd == DIOCGIFSPEEDV1)
3889 psp->baudrate = ifp->if_baudrate;
3897 case DIOCSTARTALTQ: {
3898 struct pf_altq *altq;
3901 /* enable all altq interfaces on active list */
3902 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) {
3903 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
3904 error = pf_enable_altq(altq);
3910 V_pf_altq_running = 1;
3912 DPFPRINTF(PF_DEBUG_MISC, ("altq: started\n"));
3916 case DIOCSTOPALTQ: {
3917 struct pf_altq *altq;
3920 /* disable all altq interfaces on active list */
3921 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) {
3922 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
3923 error = pf_disable_altq(altq);
3929 V_pf_altq_running = 0;
3931 DPFPRINTF(PF_DEBUG_MISC, ("altq: stopped\n"));
3936 case DIOCADDALTQV1: {
3937 struct pfioc_altq_v1 *pa = (struct pfioc_altq_v1 *)addr;
3938 struct pf_altq *altq, *a;
3941 altq = malloc(sizeof(*altq), M_PFALTQ, M_WAITOK | M_ZERO);
3942 error = pf_import_kaltq(pa, altq, IOCPARM_LEN(cmd));
3945 altq->local_flags = 0;
3948 if (pa->ticket != V_ticket_altqs_inactive) {
3950 free(altq, M_PFALTQ);
3956 * if this is for a queue, find the discipline and
3957 * copy the necessary fields
3959 if (altq->qname[0] != 0) {
3960 if ((altq->qid = pf_qname2qid(altq->qname)) == 0) {
3963 free(altq, M_PFALTQ);
3966 altq->altq_disc = NULL;
3967 TAILQ_FOREACH(a, V_pf_altq_ifs_inactive, entries) {
3968 if (strncmp(a->ifname, altq->ifname,
3970 altq->altq_disc = a->altq_disc;
3976 if ((ifp = ifunit(altq->ifname)) == NULL)
3977 altq->local_flags |= PFALTQ_FLAG_IF_REMOVED;
3979 error = altq_add(ifp, altq);
3983 free(altq, M_PFALTQ);
3987 if (altq->qname[0] != 0)
3988 TAILQ_INSERT_TAIL(V_pf_altqs_inactive, altq, entries);
3990 TAILQ_INSERT_TAIL(V_pf_altq_ifs_inactive, altq, entries);
3991 /* version error check done on import above */
3992 pf_export_kaltq(altq, pa, IOCPARM_LEN(cmd));
3997 case DIOCGETALTQSV0:
3998 case DIOCGETALTQSV1: {
3999 struct pfioc_altq_v1 *pa = (struct pfioc_altq_v1 *)addr;
4000 struct pf_altq *altq;
4004 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries)
4006 TAILQ_FOREACH(altq, V_pf_altqs_active, entries)
4008 pa->ticket = V_ticket_altqs_active;
4014 case DIOCGETALTQV1: {
4015 struct pfioc_altq_v1 *pa = (struct pfioc_altq_v1 *)addr;
4016 struct pf_altq *altq;
4019 if (pa->ticket != V_ticket_altqs_active) {
4024 altq = pf_altq_get_nth_active(pa->nr);
4030 pf_export_kaltq(altq, pa, IOCPARM_LEN(cmd));
4035 case DIOCCHANGEALTQV0:
4036 case DIOCCHANGEALTQV1:
4037 /* CHANGEALTQ not supported yet! */
4041 case DIOCGETQSTATSV0:
4042 case DIOCGETQSTATSV1: {
4043 struct pfioc_qstats_v1 *pq = (struct pfioc_qstats_v1 *)addr;
4044 struct pf_altq *altq;
4049 if (pq->ticket != V_ticket_altqs_active) {
4054 nbytes = pq->nbytes;
4055 altq = pf_altq_get_nth_active(pq->nr);
4062 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) != 0) {
4068 if (cmd == DIOCGETQSTATSV0)
4069 version = 0; /* DIOCGETQSTATSV0 means stats struct v0 */
4071 version = pq->version;
4072 error = altq_getqstats(altq, pq->buf, &nbytes, version);
4074 pq->scheduler = altq->scheduler;
4075 pq->nbytes = nbytes;
4081 case DIOCBEGINADDRS: {
4082 struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
4085 pf_empty_kpool(&V_pf_pabuf);
4086 pp->ticket = ++V_ticket_pabuf;
4092 struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
4093 struct pf_kpooladdr *pa;
4094 struct pfi_kkif *kif = NULL;
4097 if (pp->af == AF_INET) {
4098 error = EAFNOSUPPORT;
4103 if (pp->af == AF_INET6) {
4104 error = EAFNOSUPPORT;
4108 if (pp->addr.addr.type != PF_ADDR_ADDRMASK &&
4109 pp->addr.addr.type != PF_ADDR_DYNIFTL &&
4110 pp->addr.addr.type != PF_ADDR_TABLE) {
4114 if (pp->addr.addr.p.dyn != NULL) {
4118 pa = malloc(sizeof(*pa), M_PFRULE, M_WAITOK);
4119 error = pf_pooladdr_to_kpooladdr(&pp->addr, pa);
4123 kif = pf_kkif_create(M_WAITOK);
4125 if (pp->ticket != V_ticket_pabuf) {
4133 if (pa->ifname[0]) {
4134 pa->kif = pfi_kkif_attach(kif, pa->ifname);
4136 pfi_kkif_ref(pa->kif);
4139 if (pa->addr.type == PF_ADDR_DYNIFTL && ((error =
4140 pfi_dynaddr_setup(&pa->addr, pp->af)) != 0)) {
4142 pfi_kkif_unref(pa->kif);
4147 TAILQ_INSERT_TAIL(&V_pf_pabuf, pa, entries);
4152 case DIOCGETADDRS: {
4153 struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
4154 struct pf_kpool *pool;
4155 struct pf_kpooladdr *pa;
4157 pp->anchor[sizeof(pp->anchor) - 1] = 0;
4161 pool = pf_get_kpool(pp->anchor, pp->ticket, pp->r_action,
4162 pp->r_num, 0, 1, 0);
4168 TAILQ_FOREACH(pa, &pool->list, entries)
4175 struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
4176 struct pf_kpool *pool;
4177 struct pf_kpooladdr *pa;
4180 pp->anchor[sizeof(pp->anchor) - 1] = 0;
4183 pool = pf_get_kpool(pp->anchor, pp->ticket, pp->r_action,
4184 pp->r_num, 0, 1, 1);
4190 pa = TAILQ_FIRST(&pool->list);
4191 while ((pa != NULL) && (nr < pp->nr)) {
4192 pa = TAILQ_NEXT(pa, entries);
4200 pf_kpooladdr_to_pooladdr(pa, &pp->addr);
4201 pf_addr_copyout(&pp->addr.addr);
4206 case DIOCCHANGEADDR: {
4207 struct pfioc_pooladdr *pca = (struct pfioc_pooladdr *)addr;
4208 struct pf_kpool *pool;
4209 struct pf_kpooladdr *oldpa = NULL, *newpa = NULL;
4210 struct pf_kruleset *ruleset;
4211 struct pfi_kkif *kif = NULL;
4213 pca->anchor[sizeof(pca->anchor) - 1] = 0;
4215 if (pca->action < PF_CHANGE_ADD_HEAD ||
4216 pca->action > PF_CHANGE_REMOVE) {
4220 if (pca->addr.addr.type != PF_ADDR_ADDRMASK &&
4221 pca->addr.addr.type != PF_ADDR_DYNIFTL &&
4222 pca->addr.addr.type != PF_ADDR_TABLE) {
4226 if (pca->addr.addr.p.dyn != NULL) {
4231 if (pca->action != PF_CHANGE_REMOVE) {
4233 if (pca->af == AF_INET) {
4234 error = EAFNOSUPPORT;
4239 if (pca->af == AF_INET6) {
4240 error = EAFNOSUPPORT;
4244 newpa = malloc(sizeof(*newpa), M_PFRULE, M_WAITOK);
4245 bcopy(&pca->addr, newpa, sizeof(struct pf_pooladdr));
4246 if (newpa->ifname[0])
4247 kif = pf_kkif_create(M_WAITOK);
4250 #define ERROUT(x) ERROUT_IOCTL(DIOCCHANGEADDR_error, x)
4252 ruleset = pf_find_kruleset(pca->anchor);
4253 if (ruleset == NULL)
4256 pool = pf_get_kpool(pca->anchor, pca->ticket, pca->r_action,
4257 pca->r_num, pca->r_last, 1, 1);
4261 if (pca->action != PF_CHANGE_REMOVE) {
4262 if (newpa->ifname[0]) {
4263 newpa->kif = pfi_kkif_attach(kif, newpa->ifname);
4264 pfi_kkif_ref(newpa->kif);
4268 switch (newpa->addr.type) {
4269 case PF_ADDR_DYNIFTL:
4270 error = pfi_dynaddr_setup(&newpa->addr,
4274 newpa->addr.p.tbl = pfr_attach_table(ruleset,
4275 newpa->addr.v.tblname);
4276 if (newpa->addr.p.tbl == NULL)
4281 goto DIOCCHANGEADDR_error;
4284 switch (pca->action) {
4285 case PF_CHANGE_ADD_HEAD:
4286 oldpa = TAILQ_FIRST(&pool->list);
4288 case PF_CHANGE_ADD_TAIL:
4289 oldpa = TAILQ_LAST(&pool->list, pf_kpalist);
4292 oldpa = TAILQ_FIRST(&pool->list);
4293 for (int i = 0; oldpa && i < pca->nr; i++)
4294 oldpa = TAILQ_NEXT(oldpa, entries);
4300 if (pca->action == PF_CHANGE_REMOVE) {
4301 TAILQ_REMOVE(&pool->list, oldpa, entries);
4302 switch (oldpa->addr.type) {
4303 case PF_ADDR_DYNIFTL:
4304 pfi_dynaddr_remove(oldpa->addr.p.dyn);
4307 pfr_detach_table(oldpa->addr.p.tbl);
4311 pfi_kkif_unref(oldpa->kif);
4312 free(oldpa, M_PFRULE);
4315 TAILQ_INSERT_TAIL(&pool->list, newpa, entries);
4316 else if (pca->action == PF_CHANGE_ADD_HEAD ||
4317 pca->action == PF_CHANGE_ADD_BEFORE)
4318 TAILQ_INSERT_BEFORE(oldpa, newpa, entries);
4320 TAILQ_INSERT_AFTER(&pool->list, oldpa,
4324 pool->cur = TAILQ_FIRST(&pool->list);
4325 PF_ACPY(&pool->counter, &pool->cur->addr.v.a.addr, pca->af);
4330 DIOCCHANGEADDR_error:
4331 if (newpa != NULL) {
4333 pfi_kkif_unref(newpa->kif);
4334 free(newpa, M_PFRULE);
4341 case DIOCGETRULESETS: {
4342 struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr;
4343 struct pf_kruleset *ruleset;
4344 struct pf_kanchor *anchor;
4346 pr->path[sizeof(pr->path) - 1] = 0;
4349 if ((ruleset = pf_find_kruleset(pr->path)) == NULL) {
4355 if (ruleset->anchor == NULL) {
4356 /* XXX kludge for pf_main_ruleset */
4357 RB_FOREACH(anchor, pf_kanchor_global, &V_pf_anchors)
4358 if (anchor->parent == NULL)
4361 RB_FOREACH(anchor, pf_kanchor_node,
4362 &ruleset->anchor->children)
4369 case DIOCGETRULESET: {
4370 struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr;
4371 struct pf_kruleset *ruleset;
4372 struct pf_kanchor *anchor;
4375 pr->path[sizeof(pr->path) - 1] = 0;
4378 if ((ruleset = pf_find_kruleset(pr->path)) == NULL) {
4384 if (ruleset->anchor == NULL) {
4385 /* XXX kludge for pf_main_ruleset */
4386 RB_FOREACH(anchor, pf_kanchor_global, &V_pf_anchors)
4387 if (anchor->parent == NULL && nr++ == pr->nr) {
4388 strlcpy(pr->name, anchor->name,
4393 RB_FOREACH(anchor, pf_kanchor_node,
4394 &ruleset->anchor->children)
4395 if (nr++ == pr->nr) {
4396 strlcpy(pr->name, anchor->name,
4407 case DIOCRCLRTABLES: {
4408 struct pfioc_table *io = (struct pfioc_table *)addr;
4410 if (io->pfrio_esize != 0) {
4415 error = pfr_clr_tables(&io->pfrio_table, &io->pfrio_ndel,
4416 io->pfrio_flags | PFR_FLAG_USERIOCTL);
4421 case DIOCRADDTABLES: {
4422 struct pfioc_table *io = (struct pfioc_table *)addr;
4423 struct pfr_table *pfrts;
4426 if (io->pfrio_esize != sizeof(struct pfr_table)) {
4431 if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount ||
4432 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) {
4437 totlen = io->pfrio_size * sizeof(struct pfr_table);
4438 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
4440 error = copyin(io->pfrio_buffer, pfrts, totlen);
4442 free(pfrts, M_TEMP);
4446 error = pfr_add_tables(pfrts, io->pfrio_size,
4447 &io->pfrio_nadd, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4449 free(pfrts, M_TEMP);
4453 case DIOCRDELTABLES: {
4454 struct pfioc_table *io = (struct pfioc_table *)addr;
4455 struct pfr_table *pfrts;
4458 if (io->pfrio_esize != sizeof(struct pfr_table)) {
4463 if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount ||
4464 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) {
4469 totlen = io->pfrio_size * sizeof(struct pfr_table);
4470 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
4472 error = copyin(io->pfrio_buffer, pfrts, totlen);
4474 free(pfrts, M_TEMP);
4478 error = pfr_del_tables(pfrts, io->pfrio_size,
4479 &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4481 free(pfrts, M_TEMP);
4485 case DIOCRGETTABLES: {
4486 struct pfioc_table *io = (struct pfioc_table *)addr;
4487 struct pfr_table *pfrts;
4491 if (io->pfrio_esize != sizeof(struct pfr_table)) {
4496 n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
4502 io->pfrio_size = min(io->pfrio_size, n);
4504 totlen = io->pfrio_size * sizeof(struct pfr_table);
4506 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
4507 M_TEMP, M_NOWAIT | M_ZERO);
4508 if (pfrts == NULL) {
4513 error = pfr_get_tables(&io->pfrio_table, pfrts,
4514 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4517 error = copyout(pfrts, io->pfrio_buffer, totlen);
4518 free(pfrts, M_TEMP);
4522 case DIOCRGETTSTATS: {
4523 struct pfioc_table *io = (struct pfioc_table *)addr;
4524 struct pfr_tstats *pfrtstats;
4528 if (io->pfrio_esize != sizeof(struct pfr_tstats)) {
4532 PF_TABLE_STATS_LOCK();
4534 n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
4537 PF_TABLE_STATS_UNLOCK();
4541 io->pfrio_size = min(io->pfrio_size, n);
4543 totlen = io->pfrio_size * sizeof(struct pfr_tstats);
4544 pfrtstats = mallocarray(io->pfrio_size,
4545 sizeof(struct pfr_tstats), M_TEMP, M_NOWAIT | M_ZERO);
4546 if (pfrtstats == NULL) {
4549 PF_TABLE_STATS_UNLOCK();
4552 error = pfr_get_tstats(&io->pfrio_table, pfrtstats,
4553 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4555 PF_TABLE_STATS_UNLOCK();
4557 error = copyout(pfrtstats, io->pfrio_buffer, totlen);
4558 free(pfrtstats, M_TEMP);
4562 case DIOCRCLRTSTATS: {
4563 struct pfioc_table *io = (struct pfioc_table *)addr;
4564 struct pfr_table *pfrts;
4567 if (io->pfrio_esize != sizeof(struct pfr_table)) {
4572 if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount ||
4573 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) {
4574 /* We used to count tables and use the minimum required
4575 * size, so we didn't fail on overly large requests.
4577 io->pfrio_size = pf_ioctl_maxcount;
4581 totlen = io->pfrio_size * sizeof(struct pfr_table);
4582 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
4584 error = copyin(io->pfrio_buffer, pfrts, totlen);
4586 free(pfrts, M_TEMP);
4590 PF_TABLE_STATS_LOCK();
4592 error = pfr_clr_tstats(pfrts, io->pfrio_size,
4593 &io->pfrio_nzero, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4595 PF_TABLE_STATS_UNLOCK();
4596 free(pfrts, M_TEMP);
4600 case DIOCRSETTFLAGS: {
4601 struct pfioc_table *io = (struct pfioc_table *)addr;
4602 struct pfr_table *pfrts;
4606 if (io->pfrio_esize != sizeof(struct pfr_table)) {
4612 n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
4619 io->pfrio_size = min(io->pfrio_size, n);
4622 totlen = io->pfrio_size * sizeof(struct pfr_table);
4623 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
4625 error = copyin(io->pfrio_buffer, pfrts, totlen);
4627 free(pfrts, M_TEMP);
4631 error = pfr_set_tflags(pfrts, io->pfrio_size,
4632 io->pfrio_setflag, io->pfrio_clrflag, &io->pfrio_nchange,
4633 &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4635 free(pfrts, M_TEMP);
4639 case DIOCRCLRADDRS: {
4640 struct pfioc_table *io = (struct pfioc_table *)addr;
4642 if (io->pfrio_esize != 0) {
4647 error = pfr_clr_addrs(&io->pfrio_table, &io->pfrio_ndel,
4648 io->pfrio_flags | PFR_FLAG_USERIOCTL);
4653 case DIOCRADDADDRS: {
4654 struct pfioc_table *io = (struct pfioc_table *)addr;
4655 struct pfr_addr *pfras;
4658 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4662 if (io->pfrio_size < 0 ||
4663 io->pfrio_size > pf_ioctl_maxcount ||
4664 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4668 totlen = io->pfrio_size * sizeof(struct pfr_addr);
4669 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4671 error = copyin(io->pfrio_buffer, pfras, totlen);
4673 free(pfras, M_TEMP);
4677 error = pfr_add_addrs(&io->pfrio_table, pfras,
4678 io->pfrio_size, &io->pfrio_nadd, io->pfrio_flags |
4679 PFR_FLAG_USERIOCTL);
4681 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
4682 error = copyout(pfras, io->pfrio_buffer, totlen);
4683 free(pfras, M_TEMP);
4687 case DIOCRDELADDRS: {
4688 struct pfioc_table *io = (struct pfioc_table *)addr;
4689 struct pfr_addr *pfras;
4692 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4696 if (io->pfrio_size < 0 ||
4697 io->pfrio_size > pf_ioctl_maxcount ||
4698 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4702 totlen = io->pfrio_size * sizeof(struct pfr_addr);
4703 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4705 error = copyin(io->pfrio_buffer, pfras, totlen);
4707 free(pfras, M_TEMP);
4711 error = pfr_del_addrs(&io->pfrio_table, pfras,
4712 io->pfrio_size, &io->pfrio_ndel, io->pfrio_flags |
4713 PFR_FLAG_USERIOCTL);
4715 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
4716 error = copyout(pfras, io->pfrio_buffer, totlen);
4717 free(pfras, M_TEMP);
4721 case DIOCRSETADDRS: {
4722 struct pfioc_table *io = (struct pfioc_table *)addr;
4723 struct pfr_addr *pfras;
4724 size_t totlen, count;
4726 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4730 if (io->pfrio_size < 0 || io->pfrio_size2 < 0) {
4734 count = max(io->pfrio_size, io->pfrio_size2);
4735 if (count > pf_ioctl_maxcount ||
4736 WOULD_OVERFLOW(count, sizeof(struct pfr_addr))) {
4740 totlen = count * sizeof(struct pfr_addr);
4741 pfras = mallocarray(count, sizeof(struct pfr_addr), M_TEMP,
4743 error = copyin(io->pfrio_buffer, pfras, totlen);
4745 free(pfras, M_TEMP);
4749 error = pfr_set_addrs(&io->pfrio_table, pfras,
4750 io->pfrio_size, &io->pfrio_size2, &io->pfrio_nadd,
4751 &io->pfrio_ndel, &io->pfrio_nchange, io->pfrio_flags |
4752 PFR_FLAG_USERIOCTL, 0);
4754 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
4755 error = copyout(pfras, io->pfrio_buffer, totlen);
4756 free(pfras, M_TEMP);
4760 case DIOCRGETADDRS: {
4761 struct pfioc_table *io = (struct pfioc_table *)addr;
4762 struct pfr_addr *pfras;
4765 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4769 if (io->pfrio_size < 0 ||
4770 io->pfrio_size > pf_ioctl_maxcount ||
4771 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4775 totlen = io->pfrio_size * sizeof(struct pfr_addr);
4776 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4777 M_TEMP, M_WAITOK | M_ZERO);
4779 error = pfr_get_addrs(&io->pfrio_table, pfras,
4780 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4783 error = copyout(pfras, io->pfrio_buffer, totlen);
4784 free(pfras, M_TEMP);
4788 case DIOCRGETASTATS: {
4789 struct pfioc_table *io = (struct pfioc_table *)addr;
4790 struct pfr_astats *pfrastats;
4793 if (io->pfrio_esize != sizeof(struct pfr_astats)) {
4797 if (io->pfrio_size < 0 ||
4798 io->pfrio_size > pf_ioctl_maxcount ||
4799 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_astats))) {
4803 totlen = io->pfrio_size * sizeof(struct pfr_astats);
4804 pfrastats = mallocarray(io->pfrio_size,
4805 sizeof(struct pfr_astats), M_TEMP, M_WAITOK | M_ZERO);
4807 error = pfr_get_astats(&io->pfrio_table, pfrastats,
4808 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4811 error = copyout(pfrastats, io->pfrio_buffer, totlen);
4812 free(pfrastats, M_TEMP);
4816 case DIOCRCLRASTATS: {
4817 struct pfioc_table *io = (struct pfioc_table *)addr;
4818 struct pfr_addr *pfras;
4821 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4825 if (io->pfrio_size < 0 ||
4826 io->pfrio_size > pf_ioctl_maxcount ||
4827 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4831 totlen = io->pfrio_size * sizeof(struct pfr_addr);
4832 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4834 error = copyin(io->pfrio_buffer, pfras, totlen);
4836 free(pfras, M_TEMP);
4840 error = pfr_clr_astats(&io->pfrio_table, pfras,
4841 io->pfrio_size, &io->pfrio_nzero, io->pfrio_flags |
4842 PFR_FLAG_USERIOCTL);
4844 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
4845 error = copyout(pfras, io->pfrio_buffer, totlen);
4846 free(pfras, M_TEMP);
4850 case DIOCRTSTADDRS: {
4851 struct pfioc_table *io = (struct pfioc_table *)addr;
4852 struct pfr_addr *pfras;
4855 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4859 if (io->pfrio_size < 0 ||
4860 io->pfrio_size > pf_ioctl_maxcount ||
4861 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4865 totlen = io->pfrio_size * sizeof(struct pfr_addr);
4866 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4868 error = copyin(io->pfrio_buffer, pfras, totlen);
4870 free(pfras, M_TEMP);
4874 error = pfr_tst_addrs(&io->pfrio_table, pfras,
4875 io->pfrio_size, &io->pfrio_nmatch, io->pfrio_flags |
4876 PFR_FLAG_USERIOCTL);
4879 error = copyout(pfras, io->pfrio_buffer, totlen);
4880 free(pfras, M_TEMP);
4884 case DIOCRINADEFINE: {
4885 struct pfioc_table *io = (struct pfioc_table *)addr;
4886 struct pfr_addr *pfras;
4889 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
4893 if (io->pfrio_size < 0 ||
4894 io->pfrio_size > pf_ioctl_maxcount ||
4895 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
4899 totlen = io->pfrio_size * sizeof(struct pfr_addr);
4900 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
4902 error = copyin(io->pfrio_buffer, pfras, totlen);
4904 free(pfras, M_TEMP);
4908 error = pfr_ina_define(&io->pfrio_table, pfras,
4909 io->pfrio_size, &io->pfrio_nadd, &io->pfrio_naddr,
4910 io->pfrio_ticket, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4912 free(pfras, M_TEMP);
4917 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
4919 error = pf_osfp_add(io);
4925 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
4927 error = pf_osfp_get(io);
4933 struct pfioc_trans *io = (struct pfioc_trans *)addr;
4934 struct pfioc_trans_e *ioes, *ioe;
4938 if (io->esize != sizeof(*ioe)) {
4943 io->size > pf_ioctl_maxcount ||
4944 WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
4948 totlen = sizeof(struct pfioc_trans_e) * io->size;
4949 ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
4951 error = copyin(io->array, ioes, totlen);
4956 /* Ensure there's no more ethernet rules to clean up. */
4957 NET_EPOCH_DRAIN_CALLBACKS();
4959 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
4960 ioe->anchor[sizeof(ioe->anchor) - 1] = '\0';
4961 switch (ioe->rs_num) {
4962 case PF_RULESET_ETH:
4963 if ((error = pf_begin_eth(&ioe->ticket, ioe->anchor))) {
4970 case PF_RULESET_ALTQ:
4971 if (ioe->anchor[0]) {
4977 if ((error = pf_begin_altq(&ioe->ticket))) {
4984 case PF_RULESET_TABLE:
4986 struct pfr_table table;
4988 bzero(&table, sizeof(table));
4989 strlcpy(table.pfrt_anchor, ioe->anchor,
4990 sizeof(table.pfrt_anchor));
4991 if ((error = pfr_ina_begin(&table,
4992 &ioe->ticket, NULL, 0))) {
5000 if ((error = pf_begin_rules(&ioe->ticket,
5001 ioe->rs_num, ioe->anchor))) {
5010 error = copyout(ioes, io->array, totlen);
5015 case DIOCXROLLBACK: {
5016 struct pfioc_trans *io = (struct pfioc_trans *)addr;
5017 struct pfioc_trans_e *ioe, *ioes;
5021 if (io->esize != sizeof(*ioe)) {
5026 io->size > pf_ioctl_maxcount ||
5027 WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
5031 totlen = sizeof(struct pfioc_trans_e) * io->size;
5032 ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
5034 error = copyin(io->array, ioes, totlen);
5040 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
5041 ioe->anchor[sizeof(ioe->anchor) - 1] = '\0';
5042 switch (ioe->rs_num) {
5043 case PF_RULESET_ETH:
5044 if ((error = pf_rollback_eth(ioe->ticket,
5048 goto fail; /* really bad */
5052 case PF_RULESET_ALTQ:
5053 if (ioe->anchor[0]) {
5059 if ((error = pf_rollback_altq(ioe->ticket))) {
5062 goto fail; /* really bad */
5066 case PF_RULESET_TABLE:
5068 struct pfr_table table;
5070 bzero(&table, sizeof(table));
5071 strlcpy(table.pfrt_anchor, ioe->anchor,
5072 sizeof(table.pfrt_anchor));
5073 if ((error = pfr_ina_rollback(&table,
5074 ioe->ticket, NULL, 0))) {
5077 goto fail; /* really bad */
5082 if ((error = pf_rollback_rules(ioe->ticket,
5083 ioe->rs_num, ioe->anchor))) {
5086 goto fail; /* really bad */
5097 struct pfioc_trans *io = (struct pfioc_trans *)addr;
5098 struct pfioc_trans_e *ioe, *ioes;
5099 struct pf_kruleset *rs;
5100 struct pf_keth_ruleset *ers;
5104 if (io->esize != sizeof(*ioe)) {
5110 io->size > pf_ioctl_maxcount ||
5111 WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
5116 totlen = sizeof(struct pfioc_trans_e) * io->size;
5117 ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
5119 error = copyin(io->array, ioes, totlen);
5125 /* First makes sure everything will succeed. */
5126 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
5127 ioe->anchor[sizeof(ioe->anchor) - 1] = 0;
5128 switch (ioe->rs_num) {
5129 case PF_RULESET_ETH:
5130 ers = pf_find_keth_ruleset(ioe->anchor);
5131 if (ers == NULL || ioe->ticket == 0 ||
5132 ioe->ticket != ers->inactive.ticket) {
5140 case PF_RULESET_ALTQ:
5141 if (ioe->anchor[0]) {
5147 if (!V_altqs_inactive_open || ioe->ticket !=
5148 V_ticket_altqs_inactive) {
5156 case PF_RULESET_TABLE:
5157 rs = pf_find_kruleset(ioe->anchor);
5158 if (rs == NULL || !rs->topen || ioe->ticket !=
5167 if (ioe->rs_num < 0 || ioe->rs_num >=
5174 rs = pf_find_kruleset(ioe->anchor);
5176 !rs->rules[ioe->rs_num].inactive.open ||
5177 rs->rules[ioe->rs_num].inactive.ticket !=
5187 /* Now do the commit - no errors should happen here. */
5188 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
5189 switch (ioe->rs_num) {
5190 case PF_RULESET_ETH:
5191 if ((error = pf_commit_eth(ioe->ticket, ioe->anchor))) {
5194 goto fail; /* really bad */
5198 case PF_RULESET_ALTQ:
5199 if ((error = pf_commit_altq(ioe->ticket))) {
5202 goto fail; /* really bad */
5206 case PF_RULESET_TABLE:
5208 struct pfr_table table;
5210 bzero(&table, sizeof(table));
5211 (void)strlcpy(table.pfrt_anchor, ioe->anchor,
5212 sizeof(table.pfrt_anchor));
5213 if ((error = pfr_ina_commit(&table,
5214 ioe->ticket, NULL, NULL, 0))) {
5217 goto fail; /* really bad */
5222 if ((error = pf_commit_rules(ioe->ticket,
5223 ioe->rs_num, ioe->anchor))) {
5226 goto fail; /* really bad */
5233 /* Only hook into EtherNet taffic if we've got rules for it. */
5234 if (! TAILQ_EMPTY(V_pf_keth->active.rules))
5243 case DIOCGETSRCNODES: {
5244 struct pfioc_src_nodes *psn = (struct pfioc_src_nodes *)addr;
5245 struct pf_srchash *sh;
5246 struct pf_ksrc_node *n;
5247 struct pf_src_node *p, *pstore;
5250 for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask;
5252 PF_HASHROW_LOCK(sh);
5253 LIST_FOREACH(n, &sh->nodes, entry)
5255 PF_HASHROW_UNLOCK(sh);
5258 psn->psn_len = min(psn->psn_len,
5259 sizeof(struct pf_src_node) * nr);
5261 if (psn->psn_len == 0) {
5262 psn->psn_len = sizeof(struct pf_src_node) * nr;
5268 p = pstore = malloc(psn->psn_len, M_TEMP, M_WAITOK | M_ZERO);
5269 for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask;
5271 PF_HASHROW_LOCK(sh);
5272 LIST_FOREACH(n, &sh->nodes, entry) {
5274 if ((nr + 1) * sizeof(*p) > (unsigned)psn->psn_len)
5277 pf_src_node_copy(n, p);
5282 PF_HASHROW_UNLOCK(sh);
5284 error = copyout(pstore, psn->psn_src_nodes,
5285 sizeof(struct pf_src_node) * nr);
5287 free(pstore, M_TEMP);
5290 psn->psn_len = sizeof(struct pf_src_node) * nr;
5291 free(pstore, M_TEMP);
5295 case DIOCCLRSRCNODES: {
5296 pf_clear_srcnodes(NULL);
5297 pf_purge_expired_src_nodes();
5301 case DIOCKILLSRCNODES:
5302 pf_kill_srcnodes((struct pfioc_src_node_kill *)addr);
5305 #ifdef COMPAT_FREEBSD13
5306 case DIOCKEEPCOUNTERS_FREEBSD13:
5308 case DIOCKEEPCOUNTERS:
5309 error = pf_keepcounters((struct pfioc_nv *)addr);
5312 case DIOCGETSYNCOOKIES:
5313 error = pf_get_syncookies((struct pfioc_nv *)addr);
5316 case DIOCSETSYNCOOKIES:
5317 error = pf_set_syncookies((struct pfioc_nv *)addr);
5320 case DIOCSETHOSTID: {
5321 u_int32_t *hostid = (u_int32_t *)addr;
5325 V_pf_status.hostid = arc4random();
5327 V_pf_status.hostid = *hostid;
5338 case DIOCIGETIFACES: {
5339 struct pfioc_iface *io = (struct pfioc_iface *)addr;
5340 struct pfi_kif *ifstore;
5343 if (io->pfiio_esize != sizeof(struct pfi_kif)) {
5348 if (io->pfiio_size < 0 ||
5349 io->pfiio_size > pf_ioctl_maxcount ||
5350 WOULD_OVERFLOW(io->pfiio_size, sizeof(struct pfi_kif))) {
5355 io->pfiio_name[sizeof(io->pfiio_name) - 1] = '\0';
5357 bufsiz = io->pfiio_size * sizeof(struct pfi_kif);
5358 ifstore = mallocarray(io->pfiio_size, sizeof(struct pfi_kif),
5359 M_TEMP, M_WAITOK | M_ZERO);
5362 pfi_get_ifaces(io->pfiio_name, ifstore, &io->pfiio_size);
5364 error = copyout(ifstore, io->pfiio_buffer, bufsiz);
5365 free(ifstore, M_TEMP);
5369 case DIOCSETIFFLAG: {
5370 struct pfioc_iface *io = (struct pfioc_iface *)addr;
5372 io->pfiio_name[sizeof(io->pfiio_name) - 1] = '\0';
5375 error = pfi_set_flags(io->pfiio_name, io->pfiio_flags);
5380 case DIOCCLRIFFLAG: {
5381 struct pfioc_iface *io = (struct pfioc_iface *)addr;
5383 io->pfiio_name[sizeof(io->pfiio_name) - 1] = '\0';
5386 error = pfi_clear_flags(io->pfiio_name, io->pfiio_flags);
5391 case DIOCSETREASS: {
5392 u_int32_t *reass = (u_int32_t *)addr;
5394 V_pf_status.reass = *reass & (PF_REASS_ENABLED|PF_REASS_NODF);
5395 /* Removal of DF flag without reassembly enabled is not a
5396 * valid combination. Disable reassembly in such case. */
5397 if (!(V_pf_status.reass & PF_REASS_ENABLED))
5398 V_pf_status.reass = 0;
5407 if (sx_xlocked(&V_pf_ioctl_lock))
5408 sx_xunlock(&V_pf_ioctl_lock);
5417 pfsync_state_export(union pfsync_state_union *sp, struct pf_kstate *st, int msg_version)
5419 bzero(sp, sizeof(union pfsync_state_union));
5421 /* copy from state key */
5422 sp->pfs_1301.key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
5423 sp->pfs_1301.key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1];
5424 sp->pfs_1301.key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0];
5425 sp->pfs_1301.key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1];
5426 sp->pfs_1301.key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0];
5427 sp->pfs_1301.key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1];
5428 sp->pfs_1301.key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0];
5429 sp->pfs_1301.key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1];
5430 sp->pfs_1301.proto = st->key[PF_SK_WIRE]->proto;
5431 sp->pfs_1301.af = st->key[PF_SK_WIRE]->af;
5433 /* copy from state */
5434 strlcpy(sp->pfs_1301.ifname, st->kif->pfik_name, sizeof(sp->pfs_1301.ifname));
5435 bcopy(&st->rt_addr, &sp->pfs_1301.rt_addr, sizeof(sp->pfs_1301.rt_addr));
5436 sp->pfs_1301.creation = htonl(time_uptime - st->creation);
5437 sp->pfs_1301.expire = pf_state_expires(st);
5438 if (sp->pfs_1301.expire <= time_uptime)
5439 sp->pfs_1301.expire = htonl(0);
5441 sp->pfs_1301.expire = htonl(sp->pfs_1301.expire - time_uptime);
5443 sp->pfs_1301.direction = st->direction;
5444 sp->pfs_1301.log = st->act.log;
5445 sp->pfs_1301.timeout = st->timeout;
5447 switch (msg_version) {
5448 case PFSYNC_MSG_VERSION_1301:
5449 sp->pfs_1301.state_flags = st->state_flags;
5451 case PFSYNC_MSG_VERSION_1400:
5452 sp->pfs_1400.state_flags = htons(st->state_flags);
5453 sp->pfs_1400.qid = htons(st->act.qid);
5454 sp->pfs_1400.pqid = htons(st->act.pqid);
5455 sp->pfs_1400.dnpipe = htons(st->act.dnpipe);
5456 sp->pfs_1400.dnrpipe = htons(st->act.dnrpipe);
5457 sp->pfs_1400.rtableid = htonl(st->act.rtableid);
5458 sp->pfs_1400.min_ttl = st->act.min_ttl;
5459 sp->pfs_1400.set_tos = st->act.set_tos;
5460 sp->pfs_1400.max_mss = htons(st->act.max_mss);
5461 sp->pfs_1400.set_prio[0] = st->act.set_prio[0];
5462 sp->pfs_1400.set_prio[1] = st->act.set_prio[1];
5463 sp->pfs_1400.rt = st->rt;
5465 strlcpy(sp->pfs_1400.rt_ifname,
5466 st->rt_kif->pfik_name,
5467 sizeof(sp->pfs_1400.rt_ifname));
5470 panic("%s: Unsupported pfsync_msg_version %d",
5471 __func__, msg_version);
5475 sp->pfs_1301.sync_flags |= PFSYNC_FLAG_SRCNODE;
5476 if (st->nat_src_node)
5477 sp->pfs_1301.sync_flags |= PFSYNC_FLAG_NATSRCNODE;
5479 sp->pfs_1301.id = st->id;
5480 sp->pfs_1301.creatorid = st->creatorid;
5481 pf_state_peer_hton(&st->src, &sp->pfs_1301.src);
5482 pf_state_peer_hton(&st->dst, &sp->pfs_1301.dst);
5484 if (st->rule.ptr == NULL)
5485 sp->pfs_1301.rule = htonl(-1);
5487 sp->pfs_1301.rule = htonl(st->rule.ptr->nr);
5488 if (st->anchor.ptr == NULL)
5489 sp->pfs_1301.anchor = htonl(-1);
5491 sp->pfs_1301.anchor = htonl(st->anchor.ptr->nr);
5492 if (st->nat_rule.ptr == NULL)
5493 sp->pfs_1301.nat_rule = htonl(-1);
5495 sp->pfs_1301.nat_rule = htonl(st->nat_rule.ptr->nr);
5497 pf_state_counter_hton(st->packets[0], sp->pfs_1301.packets[0]);
5498 pf_state_counter_hton(st->packets[1], sp->pfs_1301.packets[1]);
5499 pf_state_counter_hton(st->bytes[0], sp->pfs_1301.bytes[0]);
5500 pf_state_counter_hton(st->bytes[1], sp->pfs_1301.bytes[1]);
5504 pf_state_export(struct pf_state_export *sp, struct pf_kstate *st)
5506 bzero(sp, sizeof(*sp));
5508 sp->version = PF_STATE_VERSION;
5510 /* copy from state key */
5511 sp->key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
5512 sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1];
5513 sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0];
5514 sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1];
5515 sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0];
5516 sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1];
5517 sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0];
5518 sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1];
5519 sp->proto = st->key[PF_SK_WIRE]->proto;
5520 sp->af = st->key[PF_SK_WIRE]->af;
5522 /* copy from state */
5523 strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname));
5524 strlcpy(sp->orig_ifname, st->orig_kif->pfik_name,
5525 sizeof(sp->orig_ifname));
5526 bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr));
5527 sp->creation = htonl(time_uptime - st->creation);
5528 sp->expire = pf_state_expires(st);
5529 if (sp->expire <= time_uptime)
5530 sp->expire = htonl(0);
5532 sp->expire = htonl(sp->expire - time_uptime);
5534 sp->direction = st->direction;
5535 sp->log = st->act.log;
5536 sp->timeout = st->timeout;
5537 /* 8 bits for the old libpfctl, 16 bits for the new libpfctl */
5538 sp->state_flags_compat = st->state_flags;
5539 sp->state_flags = htons(st->state_flags);
5541 sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
5542 if (st->nat_src_node)
5543 sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE;
5546 sp->creatorid = st->creatorid;
5547 pf_state_peer_hton(&st->src, &sp->src);
5548 pf_state_peer_hton(&st->dst, &sp->dst);
5550 if (st->rule.ptr == NULL)
5551 sp->rule = htonl(-1);
5553 sp->rule = htonl(st->rule.ptr->nr);
5554 if (st->anchor.ptr == NULL)
5555 sp->anchor = htonl(-1);
5557 sp->anchor = htonl(st->anchor.ptr->nr);
5558 if (st->nat_rule.ptr == NULL)
5559 sp->nat_rule = htonl(-1);
5561 sp->nat_rule = htonl(st->nat_rule.ptr->nr);
5563 sp->packets[0] = st->packets[0];
5564 sp->packets[1] = st->packets[1];
5565 sp->bytes[0] = st->bytes[0];
5566 sp->bytes[1] = st->bytes[1];
5568 sp->qid = htons(st->act.qid);
5569 sp->pqid = htons(st->act.pqid);
5570 sp->dnpipe = htons(st->act.dnpipe);
5571 sp->dnrpipe = htons(st->act.dnrpipe);
5572 sp->rtableid = htonl(st->act.rtableid);
5573 sp->min_ttl = st->act.min_ttl;
5574 sp->set_tos = st->act.set_tos;
5575 sp->max_mss = htons(st->act.max_mss);
5578 strlcpy(sp->rt_ifname, st->rt_kif->pfik_name,
5579 sizeof(sp->rt_ifname));
5580 sp->set_prio[0] = st->act.set_prio[0];
5581 sp->set_prio[1] = st->act.set_prio[1];
5586 pf_tbladdr_copyout(struct pf_addr_wrap *aw)
5588 struct pfr_ktable *kt;
5590 KASSERT(aw->type == PF_ADDR_TABLE, ("%s: type %u", __func__, aw->type));
5593 if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
5594 kt = kt->pfrkt_root;
5596 aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ?
5601 pf_add_status_counters(nvlist_t *nvl, const char *name, counter_u64_t *counters,
5602 size_t number, char **names)
5606 nvc = nvlist_create(0);
5610 for (int i = 0; i < number; i++) {
5611 nvlist_append_number_array(nvc, "counters",
5612 counter_u64_fetch(counters[i]));
5613 nvlist_append_string_array(nvc, "names",
5615 nvlist_append_number_array(nvc, "ids",
5618 nvlist_add_nvlist(nvl, name, nvc);
5619 nvlist_destroy(nvc);
5625 pf_getstatus(struct pfioc_nv *nv)
5627 nvlist_t *nvl = NULL, *nvc = NULL;
5628 void *nvlpacked = NULL;
5631 char *pf_reasons[PFRES_MAX+1] = PFRES_NAMES;
5632 char *pf_lcounter[KLCNT_MAX+1] = KLCNT_NAMES;
5633 char *pf_fcounter[FCNT_MAX+1] = FCNT_NAMES;
5634 PF_RULES_RLOCK_TRACKER;
5636 #define ERROUT(x) ERROUT_FUNCTION(errout, x)
5640 nvl = nvlist_create(0);
5644 nvlist_add_bool(nvl, "running", V_pf_status.running);
5645 nvlist_add_number(nvl, "since", V_pf_status.since);
5646 nvlist_add_number(nvl, "debug", V_pf_status.debug);
5647 nvlist_add_number(nvl, "hostid", V_pf_status.hostid);
5648 nvlist_add_number(nvl, "states", V_pf_status.states);
5649 nvlist_add_number(nvl, "src_nodes", V_pf_status.src_nodes);
5650 nvlist_add_number(nvl, "reass", V_pf_status.reass);
5651 nvlist_add_bool(nvl, "syncookies_active",
5652 V_pf_status.syncookies_active);
5655 error = pf_add_status_counters(nvl, "counters", V_pf_status.counters,
5656 PFRES_MAX, pf_reasons);
5661 error = pf_add_status_counters(nvl, "lcounters", V_pf_status.lcounters,
5662 KLCNT_MAX, pf_lcounter);
5667 nvc = nvlist_create(0);
5671 for (int i = 0; i < FCNT_MAX; i++) {
5672 nvlist_append_number_array(nvc, "counters",
5673 pf_counter_u64_fetch(&V_pf_status.fcounters[i]));
5674 nvlist_append_string_array(nvc, "names",
5676 nvlist_append_number_array(nvc, "ids",
5679 nvlist_add_nvlist(nvl, "fcounters", nvc);
5680 nvlist_destroy(nvc);
5684 error = pf_add_status_counters(nvl, "scounters", V_pf_status.scounters,
5685 SCNT_MAX, pf_fcounter);
5689 nvlist_add_string(nvl, "ifname", V_pf_status.ifname);
5690 nvlist_add_binary(nvl, "chksum", V_pf_status.pf_chksum,
5691 PF_MD5_DIGEST_LENGTH);
5693 pfi_update_status(V_pf_status.ifname, &s);
5695 /* pcounters / bcounters */
5696 for (int i = 0; i < 2; i++) {
5697 for (int j = 0; j < 2; j++) {
5698 for (int k = 0; k < 2; k++) {
5699 nvlist_append_number_array(nvl, "pcounters",
5700 s.pcounters[i][j][k]);
5702 nvlist_append_number_array(nvl, "bcounters",
5707 nvlpacked = nvlist_pack(nvl, &nv->len);
5708 if (nvlpacked == NULL)
5713 else if (nv->size < nv->len)
5717 error = copyout(nvlpacked, nv->data, nv->len);
5724 free(nvlpacked, M_NVLIST);
5725 nvlist_destroy(nvc);
5726 nvlist_destroy(nvl);
5732 * XXX - Check for version mismatch!!!
5735 pf_clear_all_states(void)
5737 struct pf_kstate *s;
5740 for (i = 0; i <= pf_hashmask; i++) {
5741 struct pf_idhash *ih = &V_pf_idhash[i];
5743 PF_HASHROW_LOCK(ih);
5744 LIST_FOREACH(s, &ih->states, entry) {
5745 s->timeout = PFTM_PURGE;
5746 /* Don't send out individual delete messages. */
5747 s->state_flags |= PFSTATE_NOSYNC;
5751 PF_HASHROW_UNLOCK(ih);
5756 pf_clear_tables(void)
5758 struct pfioc_table io;
5761 bzero(&io, sizeof(io));
5763 error = pfr_clr_tables(&io.pfrio_table, &io.pfrio_ndel,
5770 pf_clear_srcnodes(struct pf_ksrc_node *n)
5772 struct pf_kstate *s;
5775 for (i = 0; i <= pf_hashmask; i++) {
5776 struct pf_idhash *ih = &V_pf_idhash[i];
5778 PF_HASHROW_LOCK(ih);
5779 LIST_FOREACH(s, &ih->states, entry) {
5780 if (n == NULL || n == s->src_node)
5782 if (n == NULL || n == s->nat_src_node)
5783 s->nat_src_node = NULL;
5785 PF_HASHROW_UNLOCK(ih);
5789 struct pf_srchash *sh;
5791 for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask;
5793 PF_HASHROW_LOCK(sh);
5794 LIST_FOREACH(n, &sh->nodes, entry) {
5798 PF_HASHROW_UNLOCK(sh);
5801 /* XXX: hash slot should already be locked here. */
5808 pf_kill_srcnodes(struct pfioc_src_node_kill *psnk)
5810 struct pf_ksrc_node_list kill;
5813 for (int i = 0; i <= pf_srchashmask; i++) {
5814 struct pf_srchash *sh = &V_pf_srchash[i];
5815 struct pf_ksrc_node *sn, *tmp;
5817 PF_HASHROW_LOCK(sh);
5818 LIST_FOREACH_SAFE(sn, &sh->nodes, entry, tmp)
5819 if (PF_MATCHA(psnk->psnk_src.neg,
5820 &psnk->psnk_src.addr.v.a.addr,
5821 &psnk->psnk_src.addr.v.a.mask,
5822 &sn->addr, sn->af) &&
5823 PF_MATCHA(psnk->psnk_dst.neg,
5824 &psnk->psnk_dst.addr.v.a.addr,
5825 &psnk->psnk_dst.addr.v.a.mask,
5826 &sn->raddr, sn->af)) {
5827 pf_unlink_src_node(sn);
5828 LIST_INSERT_HEAD(&kill, sn, entry);
5831 PF_HASHROW_UNLOCK(sh);
5834 for (int i = 0; i <= pf_hashmask; i++) {
5835 struct pf_idhash *ih = &V_pf_idhash[i];
5836 struct pf_kstate *s;
5838 PF_HASHROW_LOCK(ih);
5839 LIST_FOREACH(s, &ih->states, entry) {
5840 if (s->src_node && s->src_node->expire == 1)
5842 if (s->nat_src_node && s->nat_src_node->expire == 1)
5843 s->nat_src_node = NULL;
5845 PF_HASHROW_UNLOCK(ih);
5848 psnk->psnk_killed = pf_free_src_nodes(&kill);
5852 pf_keepcounters(struct pfioc_nv *nv)
5854 nvlist_t *nvl = NULL;
5855 void *nvlpacked = NULL;
5858 #define ERROUT(x) ERROUT_FUNCTION(on_error, x)
5860 if (nv->len > pf_ioctl_maxcount)
5863 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
5864 if (nvlpacked == NULL)
5867 error = copyin(nv->data, nvlpacked, nv->len);
5871 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
5875 if (! nvlist_exists_bool(nvl, "keep_counters"))
5878 V_pf_status.keep_counters = nvlist_get_bool(nvl, "keep_counters");
5881 nvlist_destroy(nvl);
5882 free(nvlpacked, M_NVLIST);
5887 pf_clear_states(const struct pf_kstate_kill *kill)
5889 struct pf_state_key_cmp match_key;
5890 struct pf_kstate *s;
5891 struct pfi_kkif *kif;
5893 unsigned int killed = 0, dir;
5895 for (unsigned int i = 0; i <= pf_hashmask; i++) {
5896 struct pf_idhash *ih = &V_pf_idhash[i];
5898 relock_DIOCCLRSTATES:
5899 PF_HASHROW_LOCK(ih);
5900 LIST_FOREACH(s, &ih->states, entry) {
5901 /* For floating states look at the original kif. */
5902 kif = s->kif == V_pfi_all ? s->orig_kif : s->kif;
5904 if (kill->psk_ifname[0] &&
5905 strcmp(kill->psk_ifname,
5909 if (kill->psk_kill_match) {
5910 bzero(&match_key, sizeof(match_key));
5912 if (s->direction == PF_OUT) {
5920 match_key.af = s->key[idx]->af;
5921 match_key.proto = s->key[idx]->proto;
5922 PF_ACPY(&match_key.addr[0],
5923 &s->key[idx]->addr[1], match_key.af);
5924 match_key.port[0] = s->key[idx]->port[1];
5925 PF_ACPY(&match_key.addr[1],
5926 &s->key[idx]->addr[0], match_key.af);
5927 match_key.port[1] = s->key[idx]->port[0];
5931 * Don't send out individual
5934 s->state_flags |= PFSTATE_NOSYNC;
5938 if (kill->psk_kill_match)
5939 killed += pf_kill_matching_state(&match_key,
5942 goto relock_DIOCCLRSTATES;
5944 PF_HASHROW_UNLOCK(ih);
5947 if (V_pfsync_clear_states_ptr != NULL)
5948 V_pfsync_clear_states_ptr(V_pf_status.hostid, kill->psk_ifname);
5954 pf_killstates(struct pf_kstate_kill *kill, unsigned int *killed)
5956 struct pf_kstate *s;
5958 if (kill->psk_pfcmp.id) {
5959 if (kill->psk_pfcmp.creatorid == 0)
5960 kill->psk_pfcmp.creatorid = V_pf_status.hostid;
5961 if ((s = pf_find_state_byid(kill->psk_pfcmp.id,
5962 kill->psk_pfcmp.creatorid))) {
5969 for (unsigned int i = 0; i <= pf_hashmask; i++)
5970 *killed += pf_killstates_row(kill, &V_pf_idhash[i]);
5976 pf_killstates_nv(struct pfioc_nv *nv)
5978 struct pf_kstate_kill kill;
5979 nvlist_t *nvl = NULL;
5980 void *nvlpacked = NULL;
5982 unsigned int killed = 0;
5984 #define ERROUT(x) ERROUT_FUNCTION(on_error, x)
5986 if (nv->len > pf_ioctl_maxcount)
5989 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
5990 if (nvlpacked == NULL)
5993 error = copyin(nv->data, nvlpacked, nv->len);
5997 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
6001 error = pf_nvstate_kill_to_kstate_kill(nvl, &kill);
6005 pf_killstates(&kill, &killed);
6007 free(nvlpacked, M_NVLIST);
6009 nvlist_destroy(nvl);
6010 nvl = nvlist_create(0);
6014 nvlist_add_number(nvl, "killed", killed);
6016 nvlpacked = nvlist_pack(nvl, &nv->len);
6017 if (nvlpacked == NULL)
6022 else if (nv->size < nv->len)
6025 error = copyout(nvlpacked, nv->data, nv->len);
6028 nvlist_destroy(nvl);
6029 free(nvlpacked, M_NVLIST);
6034 pf_clearstates_nv(struct pfioc_nv *nv)
6036 struct pf_kstate_kill kill;
6037 nvlist_t *nvl = NULL;
6038 void *nvlpacked = NULL;
6040 unsigned int killed;
6042 #define ERROUT(x) ERROUT_FUNCTION(on_error, x)
6044 if (nv->len > pf_ioctl_maxcount)
6047 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
6048 if (nvlpacked == NULL)
6051 error = copyin(nv->data, nvlpacked, nv->len);
6055 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
6059 error = pf_nvstate_kill_to_kstate_kill(nvl, &kill);
6063 killed = pf_clear_states(&kill);
6065 free(nvlpacked, M_NVLIST);
6067 nvlist_destroy(nvl);
6068 nvl = nvlist_create(0);
6072 nvlist_add_number(nvl, "killed", killed);
6074 nvlpacked = nvlist_pack(nvl, &nv->len);
6075 if (nvlpacked == NULL)
6080 else if (nv->size < nv->len)
6083 error = copyout(nvlpacked, nv->data, nv->len);
6087 nvlist_destroy(nvl);
6088 free(nvlpacked, M_NVLIST);
6093 pf_getstate(struct pfioc_nv *nv)
6095 nvlist_t *nvl = NULL, *nvls;
6096 void *nvlpacked = NULL;
6097 struct pf_kstate *s = NULL;
6099 uint64_t id, creatorid;
6101 #define ERROUT(x) ERROUT_FUNCTION(errout, x)
6103 if (nv->len > pf_ioctl_maxcount)
6106 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
6107 if (nvlpacked == NULL)
6110 error = copyin(nv->data, nvlpacked, nv->len);
6114 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
6118 PFNV_CHK(pf_nvuint64(nvl, "id", &id));
6119 PFNV_CHK(pf_nvuint64(nvl, "creatorid", &creatorid));
6121 s = pf_find_state_byid(id, creatorid);
6125 free(nvlpacked, M_NVLIST);
6127 nvlist_destroy(nvl);
6128 nvl = nvlist_create(0);
6132 nvls = pf_state_to_nvstate(s);
6136 nvlist_add_nvlist(nvl, "state", nvls);
6137 nvlist_destroy(nvls);
6139 nvlpacked = nvlist_pack(nvl, &nv->len);
6140 if (nvlpacked == NULL)
6145 else if (nv->size < nv->len)
6148 error = copyout(nvlpacked, nv->data, nv->len);
6154 free(nvlpacked, M_NVLIST);
6155 nvlist_destroy(nvl);
6160 * XXX - Check for version mismatch!!!
6164 * Duplicate pfctl -Fa operation to get rid of as much as we can.
6174 if ((error = pf_begin_rules(&t[0], PF_RULESET_SCRUB, &nn))
6176 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: SCRUB\n"));
6179 if ((error = pf_begin_rules(&t[1], PF_RULESET_FILTER, &nn))
6181 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: FILTER\n"));
6182 break; /* XXX: rollback? */
6184 if ((error = pf_begin_rules(&t[2], PF_RULESET_NAT, &nn))
6186 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: NAT\n"));
6187 break; /* XXX: rollback? */
6189 if ((error = pf_begin_rules(&t[3], PF_RULESET_BINAT, &nn))
6191 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: BINAT\n"));
6192 break; /* XXX: rollback? */
6194 if ((error = pf_begin_rules(&t[4], PF_RULESET_RDR, &nn))
6196 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: RDR\n"));
6197 break; /* XXX: rollback? */
6200 /* XXX: these should always succeed here */
6201 pf_commit_rules(t[0], PF_RULESET_SCRUB, &nn);
6202 pf_commit_rules(t[1], PF_RULESET_FILTER, &nn);
6203 pf_commit_rules(t[2], PF_RULESET_NAT, &nn);
6204 pf_commit_rules(t[3], PF_RULESET_BINAT, &nn);
6205 pf_commit_rules(t[4], PF_RULESET_RDR, &nn);
6207 if ((error = pf_clear_tables()) != 0)
6210 if ((error = pf_begin_eth(&t[0], &nn)) != 0) {
6211 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: eth\n"));
6214 pf_commit_eth(t[0], &nn);
6217 if ((error = pf_begin_altq(&t[0])) != 0) {
6218 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: ALTQ\n"));
6221 pf_commit_altq(t[0]);
6224 pf_clear_all_states();
6226 pf_clear_srcnodes(NULL);
6228 /* status does not use malloced mem so no need to cleanup */
6229 /* fingerprints and interfaces have their own cleanup code */
6235 static pfil_return_t
6236 pf_check_return(int chk, struct mbuf **m)
6242 return (PFIL_CONSUMED);
6251 return (PFIL_DROPPED);
6255 static pfil_return_t
6256 pf_eth_check_in(struct mbuf **m, struct ifnet *ifp, int flags,
6257 void *ruleset __unused, struct inpcb *inp)
6261 chk = pf_test_eth(PF_IN, flags, ifp, m, inp);
6263 return (pf_check_return(chk, m));
6266 static pfil_return_t
6267 pf_eth_check_out(struct mbuf **m, struct ifnet *ifp, int flags,
6268 void *ruleset __unused, struct inpcb *inp)
6272 chk = pf_test_eth(PF_OUT, flags, ifp, m, inp);
6274 return (pf_check_return(chk, m));
6278 static pfil_return_t
6279 pf_check_in(struct mbuf **m, struct ifnet *ifp, int flags,
6280 void *ruleset __unused, struct inpcb *inp)
6284 chk = pf_test(PF_IN, flags, ifp, m, inp, NULL);
6286 return (pf_check_return(chk, m));
6289 static pfil_return_t
6290 pf_check_out(struct mbuf **m, struct ifnet *ifp, int flags,
6291 void *ruleset __unused, struct inpcb *inp)
6295 chk = pf_test(PF_OUT, flags, ifp, m, inp, NULL);
6297 return (pf_check_return(chk, m));
6302 static pfil_return_t
6303 pf_check6_in(struct mbuf **m, struct ifnet *ifp, int flags,
6304 void *ruleset __unused, struct inpcb *inp)
6309 * In case of loopback traffic IPv6 uses the real interface in
6310 * order to support scoped addresses. In order to support stateful
6311 * filtering we have change this to lo0 as it is the case in IPv4.
6313 CURVNET_SET(ifp->if_vnet);
6314 chk = pf_test6(PF_IN, flags, (*m)->m_flags & M_LOOP ? V_loif : ifp,
6318 return (pf_check_return(chk, m));
6321 static pfil_return_t
6322 pf_check6_out(struct mbuf **m, struct ifnet *ifp, int flags,
6323 void *ruleset __unused, struct inpcb *inp)
6327 CURVNET_SET(ifp->if_vnet);
6328 chk = pf_test6(PF_OUT, flags, ifp, m, inp, NULL);
6331 return (pf_check_return(chk, m));
6335 VNET_DEFINE_STATIC(pfil_hook_t, pf_eth_in_hook);
6336 VNET_DEFINE_STATIC(pfil_hook_t, pf_eth_out_hook);
6337 #define V_pf_eth_in_hook VNET(pf_eth_in_hook)
6338 #define V_pf_eth_out_hook VNET(pf_eth_out_hook)
6341 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip4_in_hook);
6342 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip4_out_hook);
6343 #define V_pf_ip4_in_hook VNET(pf_ip4_in_hook)
6344 #define V_pf_ip4_out_hook VNET(pf_ip4_out_hook)
6347 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip6_in_hook);
6348 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip6_out_hook);
6349 #define V_pf_ip6_in_hook VNET(pf_ip6_in_hook)
6350 #define V_pf_ip6_out_hook VNET(pf_ip6_out_hook)
6356 struct pfil_hook_args pha = {
6357 .pa_version = PFIL_VERSION,
6359 .pa_type = PFIL_TYPE_ETHERNET,
6361 struct pfil_link_args pla = {
6362 .pa_version = PFIL_VERSION,
6366 if (atomic_load_bool(&V_pf_pfil_eth_hooked))
6369 pha.pa_mbuf_chk = pf_eth_check_in;
6370 pha.pa_flags = PFIL_IN;
6371 pha.pa_rulname = "eth-in";
6372 V_pf_eth_in_hook = pfil_add_hook(&pha);
6373 pla.pa_flags = PFIL_IN | PFIL_HEADPTR | PFIL_HOOKPTR;
6374 pla.pa_head = V_link_pfil_head;
6375 pla.pa_hook = V_pf_eth_in_hook;
6376 ret = pfil_link(&pla);
6378 pha.pa_mbuf_chk = pf_eth_check_out;
6379 pha.pa_flags = PFIL_OUT;
6380 pha.pa_rulname = "eth-out";
6381 V_pf_eth_out_hook = pfil_add_hook(&pha);
6382 pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
6383 pla.pa_head = V_link_pfil_head;
6384 pla.pa_hook = V_pf_eth_out_hook;
6385 ret = pfil_link(&pla);
6388 atomic_store_bool(&V_pf_pfil_eth_hooked, true);
6394 struct pfil_hook_args pha = {
6395 .pa_version = PFIL_VERSION,
6398 struct pfil_link_args pla = {
6399 .pa_version = PFIL_VERSION,
6403 if (atomic_load_bool(&V_pf_pfil_hooked))
6407 pha.pa_type = PFIL_TYPE_IP4;
6408 pha.pa_mbuf_chk = pf_check_in;
6409 pha.pa_flags = PFIL_IN;
6410 pha.pa_rulname = "default-in";
6411 V_pf_ip4_in_hook = pfil_add_hook(&pha);
6412 pla.pa_flags = PFIL_IN | PFIL_HEADPTR | PFIL_HOOKPTR;
6413 pla.pa_head = V_inet_pfil_head;
6414 pla.pa_hook = V_pf_ip4_in_hook;
6415 ret = pfil_link(&pla);
6417 pha.pa_mbuf_chk = pf_check_out;
6418 pha.pa_flags = PFIL_OUT;
6419 pha.pa_rulname = "default-out";
6420 V_pf_ip4_out_hook = pfil_add_hook(&pha);
6421 pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
6422 pla.pa_head = V_inet_pfil_head;
6423 pla.pa_hook = V_pf_ip4_out_hook;
6424 ret = pfil_link(&pla);
6426 if (V_pf_filter_local) {
6427 pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
6428 pla.pa_head = V_inet_local_pfil_head;
6429 pla.pa_hook = V_pf_ip4_out_hook;
6430 ret = pfil_link(&pla);
6435 pha.pa_type = PFIL_TYPE_IP6;
6436 pha.pa_mbuf_chk = pf_check6_in;
6437 pha.pa_flags = PFIL_IN;
6438 pha.pa_rulname = "default-in6";
6439 V_pf_ip6_in_hook = pfil_add_hook(&pha);
6440 pla.pa_flags = PFIL_IN | PFIL_HEADPTR | PFIL_HOOKPTR;
6441 pla.pa_head = V_inet6_pfil_head;
6442 pla.pa_hook = V_pf_ip6_in_hook;
6443 ret = pfil_link(&pla);
6445 pha.pa_mbuf_chk = pf_check6_out;
6446 pha.pa_rulname = "default-out6";
6447 pha.pa_flags = PFIL_OUT;
6448 V_pf_ip6_out_hook = pfil_add_hook(&pha);
6449 pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
6450 pla.pa_head = V_inet6_pfil_head;
6451 pla.pa_hook = V_pf_ip6_out_hook;
6452 ret = pfil_link(&pla);
6454 if (V_pf_filter_local) {
6455 pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
6456 pla.pa_head = V_inet6_local_pfil_head;
6457 pla.pa_hook = V_pf_ip6_out_hook;
6458 ret = pfil_link(&pla);
6463 atomic_store_bool(&V_pf_pfil_hooked, true);
6470 if (!atomic_load_bool(&V_pf_pfil_eth_hooked))
6473 pfil_remove_hook(V_pf_eth_in_hook);
6474 pfil_remove_hook(V_pf_eth_out_hook);
6476 atomic_store_bool(&V_pf_pfil_eth_hooked, false);
6483 if (!atomic_load_bool(&V_pf_pfil_hooked))
6487 pfil_remove_hook(V_pf_ip4_in_hook);
6488 pfil_remove_hook(V_pf_ip4_out_hook);
6491 pfil_remove_hook(V_pf_ip6_in_hook);
6492 pfil_remove_hook(V_pf_ip6_out_hook);
6495 atomic_store_bool(&V_pf_pfil_hooked, false);
6501 V_pf_tag_z = uma_zcreate("pf tags", sizeof(struct pf_tagname),
6502 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
6504 rm_init_flags(&V_pf_rules_lock, "pf rulesets", RM_RECURSE);
6505 sx_init(&V_pf_ioctl_lock, "pf ioctl");
6507 pf_init_tagset(&V_pf_tags, &pf_rule_tag_hashsize,
6508 PF_RULE_TAG_HASH_SIZE_DEFAULT);
6510 pf_init_tagset(&V_pf_qids, &pf_queue_tag_hashsize,
6511 PF_QUEUE_TAG_HASH_SIZE_DEFAULT);
6514 V_pf_keth = &V_pf_main_keth_anchor.ruleset;
6517 V_pf_vnet_active = 1;
6525 sx_init(&pf_end_lock, "pf end thread");
6527 pf_mtag_initialize();
6529 pf_dev = make_dev(&pf_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, PF_NAME);
6534 error = kproc_create(pf_purge_thread, NULL, &pf_purge_proc, 0, 0, "pf purge");
6544 pf_unload_vnet(void)
6548 V_pf_vnet_active = 0;
6549 V_pf_status.running = 0;
6554 pf_syncookies_cleanup();
6558 /* Make sure we've cleaned up ethernet rules before we continue. */
6559 NET_EPOCH_DRAIN_CALLBACKS();
6561 ret = swi_remove(V_pf_swi_cookie);
6563 ret = intr_event_destroy(V_pf_swi_ie);
6566 pf_unload_vnet_purge();
6568 pf_normalize_cleanup();
6575 if (IS_DEFAULT_VNET(curvnet))
6578 pf_cleanup_tagset(&V_pf_tags);
6580 pf_cleanup_tagset(&V_pf_qids);
6582 uma_zdestroy(V_pf_tag_z);
6584 #ifdef PF_WANT_32_TO_64_COUNTER
6586 LIST_REMOVE(V_pf_kifmarker, pfik_allkiflist);
6588 MPASS(LIST_EMPTY(&V_pf_allkiflist));
6589 MPASS(V_pf_allkifcount == 0);
6591 LIST_REMOVE(&V_pf_default_rule, allrulelist);
6592 V_pf_allrulecount--;
6593 LIST_REMOVE(V_pf_rulemarker, allrulelist);
6596 * There are known pf rule leaks when running the test suite.
6599 MPASS(LIST_EMPTY(&V_pf_allrulelist));
6600 MPASS(V_pf_allrulecount == 0);
6605 free(V_pf_kifmarker, PFI_MTYPE);
6606 free(V_pf_rulemarker, M_PFRULE);
6609 /* Free counters last as we updated them during shutdown. */
6610 pf_counter_u64_deinit(&V_pf_default_rule.evaluations);
6611 for (int i = 0; i < 2; i++) {
6612 pf_counter_u64_deinit(&V_pf_default_rule.packets[i]);
6613 pf_counter_u64_deinit(&V_pf_default_rule.bytes[i]);
6615 counter_u64_free(V_pf_default_rule.states_cur);
6616 counter_u64_free(V_pf_default_rule.states_tot);
6617 counter_u64_free(V_pf_default_rule.src_nodes);
6618 uma_zfree_pcpu(pf_timestamp_pcpu_zone, V_pf_default_rule.timestamp);
6620 for (int i = 0; i < PFRES_MAX; i++)
6621 counter_u64_free(V_pf_status.counters[i]);
6622 for (int i = 0; i < KLCNT_MAX; i++)
6623 counter_u64_free(V_pf_status.lcounters[i]);
6624 for (int i = 0; i < FCNT_MAX; i++)
6625 pf_counter_u64_deinit(&V_pf_status.fcounters[i]);
6626 for (int i = 0; i < SCNT_MAX; i++)
6627 counter_u64_free(V_pf_status.scounters[i]);
6629 rm_destroy(&V_pf_rules_lock);
6630 sx_destroy(&V_pf_ioctl_lock);
6637 sx_xlock(&pf_end_lock);
6639 while (pf_end_threads < 2) {
6640 wakeup_one(pf_purge_thread);
6641 sx_sleep(pf_purge_proc, &pf_end_lock, 0, "pftmo", 0);
6643 sx_xunlock(&pf_end_lock);
6646 destroy_dev(pf_dev);
6650 sx_destroy(&pf_end_lock);
6654 vnet_pf_init(void *unused __unused)
6659 VNET_SYSINIT(vnet_pf_init, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
6660 vnet_pf_init, NULL);
6663 vnet_pf_uninit(const void *unused __unused)
6668 SYSUNINIT(pf_unload, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND, pf_unload, NULL);
6669 VNET_SYSUNINIT(vnet_pf_uninit, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
6670 vnet_pf_uninit, NULL);
6673 pf_modevent(module_t mod, int type, void *data)
6682 /* Handled in SYSUNINIT(pf_unload) to ensure it's done after
6683 * the vnet_pf_uninit()s */
6693 static moduledata_t pf_mod = {
6699 DECLARE_MODULE(pf, pf_mod, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND);
6700 MODULE_VERSION(pf, PF_MODVER);