1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2001 Daniel Hartmeier 5 * Copyright (c) 2002,2003 Henning Brauer 6 * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.org> 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * - Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * - Redistributions in binary form must reproduce the above 16 * copyright notice, this list of conditions and the following 17 * disclaimer in the documentation and/or other materials provided 18 * with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 * 33 * Effort sponsored in part by the Defense Advanced Research Projects 34 * Agency (DARPA) and Air Force Research Laboratory, Air Force 35 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 36 * 37 * $OpenBSD: pf_ioctl.c,v 1.213 2009/02/15 21:46:12 mbalmer Exp $ 38 */ 39 40 #include <sys/cdefs.h> 41 #include "opt_inet.h" 42 #include "opt_inet6.h" 43 #include "opt_bpf.h" 44 #include "opt_pf.h" 45 46 #include <sys/param.h> 47 #include <sys/_bitset.h> 48 #include <sys/bitset.h> 49 #include <sys/bus.h> 50 #include <sys/conf.h> 51 #include <sys/endian.h> 52 #include <sys/fcntl.h> 53 #include <sys/filio.h> 54 #include <sys/hash.h> 55 #include <sys/interrupt.h> 56 #include <sys/jail.h> 57 #include <sys/kernel.h> 58 #include <sys/kthread.h> 59 #include <sys/lock.h> 60 #include <sys/mbuf.h> 61 #include <sys/module.h> 62 #include <sys/nv.h> 63 #include <sys/proc.h> 64 #include <sys/sdt.h> 65 #include <sys/smp.h> 66 #include <sys/socket.h> 67 #include <sys/sysctl.h> 68 #include <sys/md5.h> 69 #include <sys/ucred.h> 70 71 #include <net/if.h> 72 #include <net/if_var.h> 73 #include <net/if_private.h> 74 #include <net/vnet.h> 75 #include <net/route.h> 76 #include <net/pfil.h> 77 #include <net/pfvar.h> 78 #include <net/if_pfsync.h> 79 #include <net/if_pflog.h> 80 81 #include <netinet/in.h> 82 #include <netinet/ip.h> 83 #include <netinet/ip_var.h> 84 #include <netinet6/ip6_var.h> 85 #include <netinet/ip_icmp.h> 86 #include <netpfil/pf/pf_nl.h> 87 #include <netpfil/pf/pf_nv.h> 88 89 #ifdef INET6 90 #include <netinet/ip6.h> 91 #endif /* INET6 */ 92 93 #ifdef ALTQ 94 #include <net/altq/altq.h> 95 #endif 96 97 SDT_PROBE_DEFINE3(pf, ioctl, ioctl, error, "int", "int", "int"); 98 SDT_PROBE_DEFINE3(pf, ioctl, function, error, "char *", "int", "int"); 99 SDT_PROBE_DEFINE2(pf, ioctl, addrule, error, "int", "int"); 100 SDT_PROBE_DEFINE2(pf, ioctl, nvchk, error, "int", "int"); 101 102 static struct pf_kpool *pf_get_kpool(const char *, u_int32_t, u_int8_t, 103 u_int32_t, u_int8_t, u_int8_t, u_int8_t, int); 104 105 static void pf_mv_kpool(struct pf_kpalist *, struct pf_kpalist *); 106 static void pf_empty_kpool(struct pf_kpalist *); 107 static int pfioctl(struct cdev *, u_long, caddr_t, int, 108 struct thread *); 109 static int pf_begin_eth(uint32_t *, const char *); 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 *); 113 #ifdef ALTQ 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 void pf_qid_unref(uint16_t); 120 #endif /* ALTQ */ 121 static int pf_begin_rules(u_int32_t *, int, const char *); 122 static int pf_rollback_rules(u_int32_t, int, char *); 123 static int pf_setup_pfsync_matching(struct pf_kruleset *); 124 static void pf_hash_rule_rolling(MD5_CTX *, struct pf_krule *); 125 static void pf_hash_rule(struct pf_krule *); 126 static void pf_hash_rule_addr(MD5_CTX *, struct pf_rule_addr *); 127 static int pf_commit_rules(u_int32_t, int, char *); 128 static int pf_addr_setup(struct pf_kruleset *, 129 struct pf_addr_wrap *, sa_family_t); 130 static void pf_src_node_copy(const struct pf_ksrc_node *, 131 struct pf_src_node *); 132 #ifdef ALTQ 133 static int pf_export_kaltq(struct pf_altq *, 134 struct pfioc_altq_v1 *, size_t); 135 static int pf_import_kaltq(struct pfioc_altq_v1 *, 136 struct pf_altq *, size_t); 137 #endif /* ALTQ */ 138 139 static void pf_statelim_commit(void); 140 static void pf_statelim_rollback(void); 141 static int pf_sourcelim_check(void); 142 static void pf_sourcelim_commit(void); 143 static void pf_sourcelim_rollback(void); 144 145 VNET_DEFINE(struct pf_krule, pf_default_rule); 146 147 static __inline int pf_krule_compare(struct pf_krule *, 148 struct pf_krule *); 149 150 RB_GENERATE(pf_krule_global, pf_krule, entry_global, pf_krule_compare); 151 152 #ifdef ALTQ 153 VNET_DEFINE_STATIC(int, pf_altq_running); 154 #define V_pf_altq_running VNET(pf_altq_running) 155 #endif 156 157 #define TAGID_MAX 50000 158 struct pf_tagname { 159 TAILQ_ENTRY(pf_tagname) namehash_entries; 160 TAILQ_ENTRY(pf_tagname) taghash_entries; 161 char name[PF_TAG_NAME_SIZE]; 162 uint16_t tag; 163 int ref; 164 }; 165 166 struct pf_tagset { 167 TAILQ_HEAD(, pf_tagname) *namehash; 168 TAILQ_HEAD(, pf_tagname) *taghash; 169 unsigned int mask; 170 uint32_t seed; 171 BITSET_DEFINE(, TAGID_MAX) avail; 172 }; 173 174 VNET_DEFINE(struct pf_tagset, pf_tags); 175 #define V_pf_tags VNET(pf_tags) 176 static unsigned int pf_rule_tag_hashsize; 177 #define PF_RULE_TAG_HASH_SIZE_DEFAULT 128 178 SYSCTL_UINT(_net_pf, OID_AUTO, rule_tag_hashsize, CTLFLAG_RDTUN, 179 &pf_rule_tag_hashsize, PF_RULE_TAG_HASH_SIZE_DEFAULT, 180 "Size of pf(4) rule tag hashtable"); 181 182 #ifdef ALTQ 183 VNET_DEFINE(struct pf_tagset, pf_qids); 184 #define V_pf_qids VNET(pf_qids) 185 static unsigned int pf_queue_tag_hashsize; 186 #define PF_QUEUE_TAG_HASH_SIZE_DEFAULT 128 187 SYSCTL_UINT(_net_pf, OID_AUTO, queue_tag_hashsize, CTLFLAG_RDTUN, 188 &pf_queue_tag_hashsize, PF_QUEUE_TAG_HASH_SIZE_DEFAULT, 189 "Size of pf(4) queue tag hashtable"); 190 #endif 191 VNET_DEFINE(uma_zone_t, pf_tag_z); 192 #define V_pf_tag_z VNET(pf_tag_z) 193 static MALLOC_DEFINE(M_PFALTQ, "pf_altq", "pf(4) altq configuration db"); 194 static MALLOC_DEFINE(M_PFRULE, "pf_rule", "pf(4) rules"); 195 MALLOC_DEFINE(M_PF, "pf", "pf(4)"); 196 MALLOC_DEFINE(M_PF_STATE_LIM, "pf_state_lim", "pf(4) state limiter"); 197 198 #if (PF_QNAME_SIZE != PF_TAG_NAME_SIZE) 199 #error PF_QNAME_SIZE must be equal to PF_TAG_NAME_SIZE 200 #endif 201 202 VNET_DEFINE_STATIC(bool, pf_filter_local) = false; 203 #define V_pf_filter_local VNET(pf_filter_local) 204 SYSCTL_BOOL(_net_pf, OID_AUTO, filter_local, CTLFLAG_VNET | CTLFLAG_RW, 205 &VNET_NAME(pf_filter_local), false, 206 "Enable filtering for packets delivered to local network stack"); 207 208 #ifdef PF_DEFAULT_TO_DROP 209 VNET_DEFINE_STATIC(bool, default_to_drop) = true; 210 #else 211 VNET_DEFINE_STATIC(bool, default_to_drop); 212 #endif 213 #define V_default_to_drop VNET(default_to_drop) 214 SYSCTL_BOOL(_net_pf, OID_AUTO, default_to_drop, CTLFLAG_RDTUN | CTLFLAG_VNET, 215 &VNET_NAME(default_to_drop), false, 216 "Make the default rule drop all packets."); 217 218 static void pf_init_tagset(struct pf_tagset *, unsigned int *, 219 unsigned int); 220 static void pf_cleanup_tagset(struct pf_tagset *); 221 static uint16_t tagname2hashindex(const struct pf_tagset *, const char *); 222 static uint16_t tag2hashindex(const struct pf_tagset *, uint16_t); 223 static u_int16_t tagname2tag(struct pf_tagset *, const char *, bool); 224 static void tag_unref(struct pf_tagset *, u_int16_t); 225 226 struct cdev *pf_dev; 227 228 /* 229 * XXX - These are new and need to be checked when moveing to a new version 230 */ 231 static void pf_clear_all_states(void); 232 static int pf_killstates_row(struct pf_kstate_kill *, 233 struct pf_idhash *); 234 static int pf_killstates_nv(struct pfioc_nv *); 235 static int pf_clearstates_nv(struct pfioc_nv *); 236 static int pf_getstate(struct pfioc_nv *); 237 static int pf_getstatus(struct pfioc_nv *); 238 static int pf_clear_tables(void); 239 static void pf_kill_srcnodes(struct pfioc_src_node_kill *); 240 static int pf_keepcounters(struct pfioc_nv *); 241 static void pf_tbladdr_copyout(struct pf_addr_wrap *); 242 243 /* 244 * Wrapper functions for pfil(9) hooks 245 */ 246 static pfil_return_t pf_eth_check_in(struct mbuf **m, struct ifnet *ifp, 247 int flags, void *ruleset __unused, struct inpcb *inp); 248 static pfil_return_t pf_eth_check_out(struct mbuf **m, struct ifnet *ifp, 249 int flags, void *ruleset __unused, struct inpcb *inp); 250 #ifdef INET 251 static pfil_return_t pf_check_in(struct mbuf **m, struct ifnet *ifp, 252 int flags, void *ruleset __unused, struct inpcb *inp); 253 static pfil_return_t pf_check_out(struct mbuf **m, struct ifnet *ifp, 254 int flags, void *ruleset __unused, struct inpcb *inp); 255 #endif 256 #ifdef INET6 257 static pfil_return_t pf_check6_in(struct mbuf **m, struct ifnet *ifp, 258 int flags, void *ruleset __unused, struct inpcb *inp); 259 static pfil_return_t pf_check6_out(struct mbuf **m, struct ifnet *ifp, 260 int flags, void *ruleset __unused, struct inpcb *inp); 261 #endif 262 263 static void hook_pf_eth(void); 264 static void hook_pf(void); 265 static void dehook_pf_eth(void); 266 static void dehook_pf(void); 267 static int shutdown_pf(void); 268 static int pf_load(void); 269 static void pf_unload(void *); 270 271 static struct cdevsw pf_cdevsw = { 272 .d_ioctl = pfioctl, 273 .d_name = PF_NAME, 274 .d_version = D_VERSION, 275 }; 276 277 VNET_DEFINE_STATIC(bool, pf_pfil_hooked); 278 #define V_pf_pfil_hooked VNET(pf_pfil_hooked) 279 VNET_DEFINE_STATIC(bool, pf_pfil_eth_hooked); 280 #define V_pf_pfil_eth_hooked VNET(pf_pfil_eth_hooked) 281 282 /* 283 * We need a flag that is neither hooked nor running to know when 284 * the VNET is "valid". We primarily need this to control (global) 285 * external event, e.g., eventhandlers. 286 */ 287 VNET_DEFINE(int, pf_vnet_active); 288 #define V_pf_vnet_active VNET(pf_vnet_active) 289 290 int pf_end_threads; 291 struct proc *pf_purge_proc; 292 293 VNET_DEFINE(struct rmlock, pf_rules_lock); 294 VNET_DEFINE(struct rmlock, pf_tags_lock); 295 VNET_DEFINE_STATIC(struct sx, pf_ioctl_lock); 296 #define V_pf_ioctl_lock VNET(pf_ioctl_lock) 297 struct sx pf_end_lock; 298 299 /* pfsync */ 300 VNET_DEFINE(pfsync_state_import_t *, pfsync_state_import_ptr); 301 VNET_DEFINE(pfsync_insert_state_t *, pfsync_insert_state_ptr); 302 VNET_DEFINE(pfsync_update_state_t *, pfsync_update_state_ptr); 303 VNET_DEFINE(pfsync_delete_state_t *, pfsync_delete_state_ptr); 304 VNET_DEFINE(pfsync_clear_states_t *, pfsync_clear_states_ptr); 305 VNET_DEFINE(pfsync_defer_t *, pfsync_defer_ptr); 306 VNET_DEFINE(pflow_export_state_t *, pflow_export_state_ptr); 307 pfsync_detach_ifnet_t *pfsync_detach_ifnet_ptr; 308 309 /* pflog */ 310 pflog_packet_t *pflog_packet_ptr = NULL; 311 312 /* 313 * Copy a user-provided string, returning an error if truncation would occur. 314 * Avoid scanning past "sz" bytes in the source string since there's no 315 * guarantee that it's nul-terminated. 316 */ 317 static int 318 pf_user_strcpy(char *dst, const char *src, size_t sz) 319 { 320 if (strnlen(src, sz) == sz) 321 return (EINVAL); 322 (void)strlcpy(dst, src, sz); 323 return (0); 324 } 325 326 static void 327 pfattach_vnet(void) 328 { 329 u_int32_t *my_timeout = V_pf_default_rule.timeout; 330 331 bzero(&V_pf_status, sizeof(V_pf_status)); 332 333 pf_initialize(); 334 pfr_initialize(); 335 pfi_initialize_vnet(); 336 pf_normalize_init(); 337 pf_syncookies_init(); 338 339 V_pf_limits[PF_LIMIT_STATES].limit = PFSTATE_HIWAT; 340 V_pf_limits[PF_LIMIT_SRC_NODES].limit = PFSNODE_HIWAT; 341 V_pf_limits[PF_LIMIT_ANCHORS].limit = PF_ANCHOR_HIWAT; 342 V_pf_limits[PF_LIMIT_ETH_ANCHORS].limit = PF_ANCHOR_HIWAT; 343 344 RB_INIT(&V_pf_anchors); 345 pf_init_kruleset(&pf_main_ruleset); 346 347 pf_init_keth(V_pf_keth); 348 349 /* default rule should never be garbage collected */ 350 V_pf_default_rule.entries.tqe_prev = &V_pf_default_rule.entries.tqe_next; 351 V_pf_default_rule.action = V_default_to_drop ? PF_DROP : PF_PASS; 352 V_pf_default_rule.nr = (uint32_t)-1; 353 V_pf_default_rule.rtableid = -1; 354 355 pf_counter_u64_init(&V_pf_default_rule.evaluations, M_WAITOK); 356 for (int i = 0; i < 2; i++) { 357 pf_counter_u64_init(&V_pf_default_rule.packets[i], M_WAITOK); 358 pf_counter_u64_init(&V_pf_default_rule.bytes[i], M_WAITOK); 359 } 360 V_pf_default_rule.states_cur = counter_u64_alloc(M_WAITOK); 361 V_pf_default_rule.states_tot = counter_u64_alloc(M_WAITOK); 362 for (pf_sn_types_t sn_type = 0; sn_type<PF_SN_MAX; sn_type++) 363 V_pf_default_rule.src_nodes[sn_type] = counter_u64_alloc(M_WAITOK); 364 365 V_pf_default_rule.timestamp = uma_zalloc_pcpu(pf_timestamp_pcpu_zone, 366 M_WAITOK | M_ZERO); 367 368 #ifdef PF_WANT_32_TO_64_COUNTER 369 V_pf_kifmarker = malloc(sizeof(*V_pf_kifmarker), PFI_MTYPE, M_WAITOK | M_ZERO); 370 V_pf_rulemarker = malloc(sizeof(*V_pf_rulemarker), M_PFRULE, M_WAITOK | M_ZERO); 371 PF_RULES_WLOCK(); 372 LIST_INSERT_HEAD(&V_pf_allkiflist, V_pf_kifmarker, pfik_allkiflist); 373 LIST_INSERT_HEAD(&V_pf_allrulelist, &V_pf_default_rule, allrulelist); 374 V_pf_allrulecount++; 375 LIST_INSERT_HEAD(&V_pf_allrulelist, V_pf_rulemarker, allrulelist); 376 PF_RULES_WUNLOCK(); 377 #endif 378 379 /* initialize default timeouts */ 380 my_timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL; 381 my_timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL; 382 my_timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL; 383 my_timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL; 384 my_timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL; 385 my_timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL; 386 my_timeout[PFTM_SCTP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL; 387 my_timeout[PFTM_SCTP_OPENING] = PFTM_TCP_OPENING_VAL; 388 my_timeout[PFTM_SCTP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL; 389 my_timeout[PFTM_SCTP_CLOSING] = PFTM_TCP_CLOSING_VAL; 390 my_timeout[PFTM_SCTP_CLOSED] = PFTM_TCP_CLOSED_VAL; 391 my_timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL; 392 my_timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL; 393 my_timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL; 394 my_timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL; 395 my_timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL; 396 my_timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL; 397 my_timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL; 398 my_timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL; 399 my_timeout[PFTM_FRAG] = PFTM_FRAG_VAL; 400 my_timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL; 401 my_timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL; 402 my_timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL; 403 my_timeout[PFTM_ADAPTIVE_START] = PFSTATE_ADAPT_START; 404 my_timeout[PFTM_ADAPTIVE_END] = PFSTATE_ADAPT_END; 405 406 V_pf_status.debug = PF_DEBUG_URGENT; 407 /* 408 * XXX This is different than in OpenBSD where reassembly is enabled by 409 * defult. In FreeBSD we expect people to still use scrub rules and 410 * switch to the new syntax later. Only when they switch they must 411 * explicitly enable reassemle. We could change the default once the 412 * scrub rule functionality is hopefully removed some day in future. 413 */ 414 V_pf_status.reass = 0; 415 416 V_pf_pfil_hooked = false; 417 V_pf_pfil_eth_hooked = false; 418 419 /* XXX do our best to avoid a conflict */ 420 V_pf_status.hostid = arc4random(); 421 422 for (int i = 0; i < PFRES_MAX; i++) 423 V_pf_status.counters[i] = counter_u64_alloc(M_WAITOK); 424 for (int i = 0; i < KLCNT_MAX; i++) 425 V_pf_status.lcounters[i] = counter_u64_alloc(M_WAITOK); 426 for (int i = 0; i < FCNT_MAX; i++) 427 pf_counter_u64_init(&V_pf_status.fcounters[i], M_WAITOK); 428 for (int i = 0; i < SCNT_MAX; i++) 429 V_pf_status.scounters[i] = counter_u64_alloc(M_WAITOK); 430 for (int i = 0; i < NCNT_MAX; i++) 431 V_pf_status.ncounters[i] = counter_u64_alloc(M_WAITOK); 432 433 if (swi_add(&V_pf_swi_ie, "pf send", pf_intr, curvnet, SWI_NET, 434 INTR_MPSAFE, &V_pf_swi_cookie) != 0) 435 /* XXXGL: leaked all above. */ 436 return; 437 } 438 439 static struct pf_kpool * 440 pf_get_kpool(const char *anchor, u_int32_t ticket, u_int8_t rule_action, 441 u_int32_t rule_number, u_int8_t r_last, u_int8_t active, 442 u_int8_t check_ticket, int which) 443 { 444 struct pf_kruleset *ruleset; 445 struct pf_krule *rule; 446 int rs_num; 447 448 MPASS(which == PF_RDR || which == PF_NAT || which == PF_RT); 449 450 ruleset = pf_find_kruleset(anchor); 451 if (ruleset == NULL) 452 return (NULL); 453 rs_num = pf_get_ruleset_number(rule_action); 454 if (rs_num >= PF_RULESET_MAX) 455 return (NULL); 456 if (active) { 457 if (check_ticket && ticket != 458 ruleset->rules[rs_num].active.ticket) 459 return (NULL); 460 if (r_last) 461 rule = TAILQ_LAST(ruleset->rules[rs_num].active.ptr, 462 pf_krulequeue); 463 else 464 rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr); 465 } else { 466 if (check_ticket && ticket != 467 ruleset->rules[rs_num].inactive.ticket) 468 return (NULL); 469 if (r_last) 470 rule = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr, 471 pf_krulequeue); 472 else 473 rule = TAILQ_FIRST(ruleset->rules[rs_num].inactive.ptr); 474 } 475 if (!r_last) { 476 while ((rule != NULL) && (rule->nr != rule_number)) 477 rule = TAILQ_NEXT(rule, entries); 478 } 479 if (rule == NULL) 480 return (NULL); 481 482 switch (which) { 483 case PF_RDR: 484 return (&rule->rdr); 485 case PF_NAT: 486 return (&rule->nat); 487 case PF_RT: 488 return (&rule->route); 489 default: 490 panic("Unknow pool type %d", which); 491 } 492 } 493 494 static void 495 pf_mv_kpool(struct pf_kpalist *poola, struct pf_kpalist *poolb) 496 { 497 struct pf_kpooladdr *mv_pool_pa; 498 499 while ((mv_pool_pa = TAILQ_FIRST(poola)) != NULL) { 500 TAILQ_REMOVE(poola, mv_pool_pa, entries); 501 TAILQ_INSERT_TAIL(poolb, mv_pool_pa, entries); 502 } 503 } 504 505 static void 506 pf_empty_kpool(struct pf_kpalist *poola) 507 { 508 struct pf_kpooladdr *pa; 509 510 while ((pa = TAILQ_FIRST(poola)) != NULL) { 511 switch (pa->addr.type) { 512 case PF_ADDR_DYNIFTL: 513 pfi_dynaddr_remove(pa->addr.p.dyn); 514 break; 515 case PF_ADDR_TABLE: 516 /* XXX: this could be unfinished pooladdr on pabuf */ 517 if (pa->addr.p.tbl != NULL) 518 pfr_detach_table(pa->addr.p.tbl); 519 break; 520 } 521 if (pa->kif) 522 pfi_kkif_unref(pa->kif); 523 TAILQ_REMOVE(poola, pa, entries); 524 free(pa, M_PFRULE); 525 } 526 } 527 528 static void 529 pf_unlink_rule_locked(struct pf_krulequeue *rulequeue, struct pf_krule *rule) 530 { 531 532 PF_RULES_WASSERT(); 533 PF_UNLNKDRULES_ASSERT(); 534 535 TAILQ_REMOVE(rulequeue, rule, entries); 536 537 rule->rule_ref |= PFRULE_REFS; 538 TAILQ_INSERT_TAIL(&V_pf_unlinked_rules, rule, entries); 539 } 540 541 static void 542 pf_unlink_rule(struct pf_krulequeue *rulequeue, struct pf_krule *rule) 543 { 544 545 PF_RULES_WASSERT(); 546 547 PF_UNLNKDRULES_LOCK(); 548 pf_unlink_rule_locked(rulequeue, rule); 549 PF_UNLNKDRULES_UNLOCK(); 550 } 551 552 static void 553 pf_free_eth_rule(struct pf_keth_rule *rule) 554 { 555 PF_RULES_WASSERT(); 556 557 if (rule == NULL) 558 return; 559 560 if (rule->tag) 561 tag_unref(&V_pf_tags, rule->tag); 562 if (rule->match_tag) 563 tag_unref(&V_pf_tags, rule->match_tag); 564 #ifdef ALTQ 565 pf_qid_unref(rule->qid); 566 #endif 567 568 if (rule->bridge_to) 569 pfi_kkif_unref(rule->bridge_to); 570 if (rule->kif) 571 pfi_kkif_unref(rule->kif); 572 573 if (rule->ipsrc.addr.type == PF_ADDR_TABLE) 574 pfr_detach_table(rule->ipsrc.addr.p.tbl); 575 if (rule->ipdst.addr.type == PF_ADDR_TABLE) 576 pfr_detach_table(rule->ipdst.addr.p.tbl); 577 578 counter_u64_free(rule->evaluations); 579 for (int i = 0; i < 2; i++) { 580 counter_u64_free(rule->packets[i]); 581 counter_u64_free(rule->bytes[i]); 582 } 583 uma_zfree_pcpu(pf_timestamp_pcpu_zone, rule->timestamp); 584 pf_keth_anchor_remove(rule); 585 586 free(rule, M_PFRULE); 587 } 588 589 void 590 pf_free_rule(struct pf_krule *rule) 591 { 592 593 PF_RULES_WASSERT(); 594 PF_CONFIG_ASSERT(); 595 596 if (rule->tag) 597 tag_unref(&V_pf_tags, rule->tag); 598 if (rule->match_tag) 599 tag_unref(&V_pf_tags, rule->match_tag); 600 #ifdef ALTQ 601 if (rule->pqid != rule->qid) 602 pf_qid_unref(rule->pqid); 603 pf_qid_unref(rule->qid); 604 #endif 605 switch (rule->src.addr.type) { 606 case PF_ADDR_DYNIFTL: 607 pfi_dynaddr_remove(rule->src.addr.p.dyn); 608 break; 609 case PF_ADDR_TABLE: 610 pfr_detach_table(rule->src.addr.p.tbl); 611 break; 612 } 613 switch (rule->dst.addr.type) { 614 case PF_ADDR_DYNIFTL: 615 pfi_dynaddr_remove(rule->dst.addr.p.dyn); 616 break; 617 case PF_ADDR_TABLE: 618 pfr_detach_table(rule->dst.addr.p.tbl); 619 break; 620 } 621 if (rule->overload_tbl) 622 pfr_detach_table(rule->overload_tbl); 623 if (rule->kif) 624 pfi_kkif_unref(rule->kif); 625 if (rule->rcv_kif) 626 pfi_kkif_unref(rule->rcv_kif); 627 pf_remove_kanchor(rule); 628 pf_empty_kpool(&rule->rdr.list); 629 pf_empty_kpool(&rule->nat.list); 630 pf_empty_kpool(&rule->route.list); 631 632 pf_krule_free(rule); 633 } 634 635 static void 636 pf_init_tagset(struct pf_tagset *ts, unsigned int *tunable_size, 637 unsigned int default_size) 638 { 639 unsigned int i; 640 unsigned int hashsize; 641 642 if (*tunable_size == 0 || !powerof2(*tunable_size)) 643 *tunable_size = default_size; 644 645 hashsize = *tunable_size; 646 ts->namehash = mallocarray(hashsize, sizeof(*ts->namehash), M_PFHASH, 647 M_WAITOK); 648 ts->taghash = mallocarray(hashsize, sizeof(*ts->taghash), M_PFHASH, 649 M_WAITOK); 650 ts->mask = hashsize - 1; 651 ts->seed = arc4random(); 652 for (i = 0; i < hashsize; i++) { 653 TAILQ_INIT(&ts->namehash[i]); 654 TAILQ_INIT(&ts->taghash[i]); 655 } 656 BIT_FILL(TAGID_MAX, &ts->avail); 657 } 658 659 static void 660 pf_cleanup_tagset(struct pf_tagset *ts) 661 { 662 unsigned int i; 663 unsigned int hashsize; 664 struct pf_tagname *t, *tmp; 665 666 /* 667 * Only need to clean up one of the hashes as each tag is hashed 668 * into each table. 669 */ 670 hashsize = ts->mask + 1; 671 for (i = 0; i < hashsize; i++) 672 TAILQ_FOREACH_SAFE(t, &ts->namehash[i], namehash_entries, tmp) 673 uma_zfree(V_pf_tag_z, t); 674 675 free(ts->namehash, M_PFHASH); 676 free(ts->taghash, M_PFHASH); 677 } 678 679 static uint16_t 680 tagname2hashindex(const struct pf_tagset *ts, const char *tagname) 681 { 682 size_t len; 683 684 len = strnlen(tagname, PF_TAG_NAME_SIZE - 1); 685 return (murmur3_32_hash(tagname, len, ts->seed) & ts->mask); 686 } 687 688 static uint16_t 689 tag2hashindex(const struct pf_tagset *ts, uint16_t tag) 690 { 691 692 return (tag & ts->mask); 693 } 694 695 static u_int16_t 696 tagname2tag(struct pf_tagset *ts, const char *tagname, bool add_new) 697 { 698 struct pf_tagname *tag; 699 u_int32_t index; 700 u_int16_t new_tagid; 701 702 PF_TAGS_RLOCK_TRACKER; 703 704 PF_TAGS_RLOCK(); 705 706 index = tagname2hashindex(ts, tagname); 707 TAILQ_FOREACH(tag, &ts->namehash[index], namehash_entries) 708 if (strcmp(tagname, tag->name) == 0) { 709 tag->ref++; 710 new_tagid = tag->tag; 711 PF_TAGS_RUNLOCK(); 712 return (new_tagid); 713 } 714 715 /* 716 * When used for pfsync with queues we must not create new entries. 717 * Pf tags can be created just fine by this function, but queues 718 * require additional configuration. If they are missing on the target 719 * system we just ignore them 720 */ 721 if (add_new == false) { 722 printf("%s: Not creating a new tag\n", __func__); 723 PF_TAGS_RUNLOCK(); 724 return (0); 725 } 726 727 /* 728 * If a new entry must be created do it under a write lock. 729 * But first search again, somebody could have created the tag 730 * between unlocking the read lock and locking the write lock. 731 */ 732 PF_TAGS_RUNLOCK(); 733 PF_TAGS_WLOCK(); 734 TAILQ_FOREACH(tag, &ts->namehash[index], namehash_entries) 735 if (strcmp(tagname, tag->name) == 0) { 736 tag->ref++; 737 new_tagid = tag->tag; 738 PF_TAGS_WUNLOCK(); 739 return (new_tagid); 740 } 741 742 /* 743 * new entry 744 * 745 * to avoid fragmentation, we do a linear search from the beginning 746 * and take the first free slot we find. 747 */ 748 new_tagid = BIT_FFS(TAGID_MAX, &ts->avail); 749 /* 750 * Tags are 1-based, with valid tags in the range [1..TAGID_MAX]. 751 * BIT_FFS() returns a 1-based bit number, with 0 indicating no bits 752 * set. It may also return a bit number greater than TAGID_MAX due 753 * to rounding of the number of bits in the vector up to a multiple 754 * of the vector word size at declaration/allocation time. 755 */ 756 if ((new_tagid == 0) || (new_tagid > TAGID_MAX)) { 757 PF_TAGS_WUNLOCK(); 758 return (0); 759 } 760 761 /* Mark the tag as in use. Bits are 0-based for BIT_CLR() */ 762 BIT_CLR(TAGID_MAX, new_tagid - 1, &ts->avail); 763 764 /* allocate and fill new struct pf_tagname */ 765 tag = uma_zalloc(V_pf_tag_z, M_NOWAIT); 766 if (tag == NULL) { 767 PF_TAGS_WUNLOCK(); 768 return (0); 769 } 770 strlcpy(tag->name, tagname, sizeof(tag->name)); 771 tag->tag = new_tagid; 772 tag->ref = 1; 773 774 /* Insert into namehash */ 775 TAILQ_INSERT_TAIL(&ts->namehash[index], tag, namehash_entries); 776 777 /* Insert into taghash */ 778 index = tag2hashindex(ts, new_tagid); 779 TAILQ_INSERT_TAIL(&ts->taghash[index], tag, taghash_entries); 780 781 PF_TAGS_WUNLOCK(); 782 return (new_tagid); 783 } 784 785 static char * 786 tag2tagname(struct pf_tagset *ts, u_int16_t tag) 787 { 788 struct pf_tagname *t; 789 uint16_t index; 790 791 PF_TAGS_RLOCK_TRACKER; 792 793 PF_TAGS_RLOCK(); 794 795 index = tag2hashindex(ts, tag); 796 TAILQ_FOREACH(t, &ts->taghash[index], taghash_entries) 797 if (tag == t->tag) { 798 PF_TAGS_RUNLOCK(); 799 return (t->name); 800 } 801 802 PF_TAGS_RUNLOCK(); 803 return (NULL); 804 } 805 806 static void 807 tag_unref(struct pf_tagset *ts, u_int16_t tag) 808 { 809 struct pf_tagname *t; 810 uint16_t index; 811 812 PF_TAGS_WLOCK(); 813 814 index = tag2hashindex(ts, tag); 815 TAILQ_FOREACH(t, &ts->taghash[index], taghash_entries) 816 if (tag == t->tag) { 817 if (--t->ref == 0) { 818 TAILQ_REMOVE(&ts->taghash[index], t, 819 taghash_entries); 820 index = tagname2hashindex(ts, t->name); 821 TAILQ_REMOVE(&ts->namehash[index], t, 822 namehash_entries); 823 /* Bits are 0-based for BIT_SET() */ 824 BIT_SET(TAGID_MAX, tag - 1, &ts->avail); 825 uma_zfree(V_pf_tag_z, t); 826 } 827 break; 828 } 829 830 PF_TAGS_WUNLOCK(); 831 } 832 833 uint16_t 834 pf_tagname2tag(const char *tagname) 835 { 836 return (tagname2tag(&V_pf_tags, tagname, true)); 837 } 838 839 static const char * 840 pf_tag2tagname(uint16_t tag) 841 { 842 return (tag2tagname(&V_pf_tags, tag)); 843 } 844 845 static int 846 pf_begin_eth(uint32_t *ticket, const char *anchor) 847 { 848 struct pf_keth_rule *rule, *tmp; 849 struct pf_keth_ruleset *rs; 850 851 PF_RULES_WASSERT(); 852 853 rs = pf_find_or_create_keth_ruleset(anchor); 854 if (rs == NULL) 855 return (EINVAL); 856 857 /* Purge old inactive rules. */ 858 TAILQ_FOREACH_SAFE(rule, rs->inactive.rules, entries, 859 tmp) { 860 TAILQ_REMOVE(rs->inactive.rules, rule, 861 entries); 862 pf_free_eth_rule(rule); 863 } 864 865 *ticket = ++rs->inactive.ticket; 866 rs->inactive.open = 1; 867 868 return (0); 869 } 870 871 static int 872 pf_rollback_eth(uint32_t ticket, const char *anchor) 873 { 874 struct pf_keth_rule *rule, *tmp; 875 struct pf_keth_ruleset *rs; 876 877 PF_RULES_WASSERT(); 878 879 rs = pf_find_keth_ruleset(anchor); 880 if (rs == NULL) 881 return (EINVAL); 882 883 if (!rs->inactive.open || 884 ticket != rs->inactive.ticket) 885 return (0); 886 887 /* Purge old inactive rules. */ 888 TAILQ_FOREACH_SAFE(rule, rs->inactive.rules, entries, 889 tmp) { 890 TAILQ_REMOVE(rs->inactive.rules, rule, entries); 891 pf_free_eth_rule(rule); 892 } 893 894 rs->inactive.open = 0; 895 896 pf_remove_if_empty_keth_ruleset(rs); 897 898 return (0); 899 } 900 901 #define PF_SET_SKIP_STEPS(i) \ 902 do { \ 903 while (head[i] != cur) { \ 904 head[i]->skip[i].ptr = cur; \ 905 head[i] = TAILQ_NEXT(head[i], entries); \ 906 } \ 907 } while (0) 908 909 static void 910 pf_eth_calc_skip_steps(struct pf_keth_ruleq *rules) 911 { 912 struct pf_keth_rule *cur, *prev, *head[PFE_SKIP_COUNT]; 913 int i; 914 915 cur = TAILQ_FIRST(rules); 916 prev = cur; 917 for (i = 0; i < PFE_SKIP_COUNT; ++i) 918 head[i] = cur; 919 while (cur != NULL) { 920 if (cur->kif != prev->kif || cur->ifnot != prev->ifnot) 921 PF_SET_SKIP_STEPS(PFE_SKIP_IFP); 922 if (cur->direction != prev->direction) 923 PF_SET_SKIP_STEPS(PFE_SKIP_DIR); 924 if (cur->proto != prev->proto) 925 PF_SET_SKIP_STEPS(PFE_SKIP_PROTO); 926 if (memcmp(&cur->src, &prev->src, sizeof(cur->src)) != 0) 927 PF_SET_SKIP_STEPS(PFE_SKIP_SRC_ADDR); 928 if (memcmp(&cur->dst, &prev->dst, sizeof(cur->dst)) != 0) 929 PF_SET_SKIP_STEPS(PFE_SKIP_DST_ADDR); 930 if (cur->ipsrc.neg != prev->ipsrc.neg || 931 pf_addr_wrap_neq(&cur->ipsrc.addr, &prev->ipsrc.addr)) 932 PF_SET_SKIP_STEPS(PFE_SKIP_SRC_IP_ADDR); 933 if (cur->ipdst.neg != prev->ipdst.neg || 934 pf_addr_wrap_neq(&cur->ipdst.addr, &prev->ipdst.addr)) 935 PF_SET_SKIP_STEPS(PFE_SKIP_DST_IP_ADDR); 936 937 prev = cur; 938 cur = TAILQ_NEXT(cur, entries); 939 } 940 for (i = 0; i < PFE_SKIP_COUNT; ++i) 941 PF_SET_SKIP_STEPS(i); 942 } 943 944 static int 945 pf_commit_eth(uint32_t ticket, const char *anchor) 946 { 947 struct pf_keth_ruleq *rules; 948 struct pf_keth_ruleset *rs; 949 950 rs = pf_find_keth_ruleset(anchor); 951 if (rs == NULL) { 952 return (EINVAL); 953 } 954 955 if (!rs->inactive.open || 956 ticket != rs->inactive.ticket) 957 return (EBUSY); 958 959 PF_RULES_WASSERT(); 960 961 pf_eth_calc_skip_steps(rs->inactive.rules); 962 963 rules = rs->active.rules; 964 atomic_store_ptr(&rs->active.rules, rs->inactive.rules); 965 rs->inactive.rules = rules; 966 rs->inactive.ticket = rs->active.ticket; 967 968 return (pf_rollback_eth(rs->inactive.ticket, 969 rs->anchor ? rs->anchor->path : "")); 970 } 971 972 #ifdef ALTQ 973 uint16_t 974 pf_qname2qid(const char *qname, bool add_new) 975 { 976 return (tagname2tag(&V_pf_qids, qname, add_new)); 977 } 978 979 static void 980 pf_qid_unref(uint16_t qid) 981 { 982 tag_unref(&V_pf_qids, qid); 983 } 984 985 static int 986 pf_begin_altq(u_int32_t *ticket) 987 { 988 struct pf_altq *altq, *tmp; 989 int error = 0; 990 991 PF_RULES_WASSERT(); 992 993 /* Purge the old altq lists */ 994 TAILQ_FOREACH_SAFE(altq, V_pf_altq_ifs_inactive, entries, tmp) { 995 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) { 996 /* detach and destroy the discipline */ 997 error = altq_remove(altq); 998 } 999 free(altq, M_PFALTQ); 1000 } 1001 TAILQ_INIT(V_pf_altq_ifs_inactive); 1002 TAILQ_FOREACH_SAFE(altq, V_pf_altqs_inactive, entries, tmp) { 1003 pf_qid_unref(altq->qid); 1004 free(altq, M_PFALTQ); 1005 } 1006 TAILQ_INIT(V_pf_altqs_inactive); 1007 if (error) 1008 return (error); 1009 *ticket = ++V_ticket_altqs_inactive; 1010 V_altqs_inactive_open = 1; 1011 return (0); 1012 } 1013 1014 static int 1015 pf_rollback_altq(u_int32_t ticket) 1016 { 1017 struct pf_altq *altq, *tmp; 1018 int error = 0; 1019 1020 PF_RULES_WASSERT(); 1021 1022 if (!V_altqs_inactive_open || ticket != V_ticket_altqs_inactive) 1023 return (0); 1024 /* Purge the old altq lists */ 1025 TAILQ_FOREACH_SAFE(altq, V_pf_altq_ifs_inactive, entries, tmp) { 1026 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) { 1027 /* detach and destroy the discipline */ 1028 error = altq_remove(altq); 1029 } 1030 free(altq, M_PFALTQ); 1031 } 1032 TAILQ_INIT(V_pf_altq_ifs_inactive); 1033 TAILQ_FOREACH_SAFE(altq, V_pf_altqs_inactive, entries, tmp) { 1034 pf_qid_unref(altq->qid); 1035 free(altq, M_PFALTQ); 1036 } 1037 TAILQ_INIT(V_pf_altqs_inactive); 1038 V_altqs_inactive_open = 0; 1039 return (error); 1040 } 1041 1042 static int 1043 pf_commit_altq(u_int32_t ticket) 1044 { 1045 struct pf_altqqueue *old_altqs, *old_altq_ifs; 1046 struct pf_altq *altq, *tmp; 1047 int err, error = 0; 1048 1049 PF_RULES_WASSERT(); 1050 1051 if (!V_altqs_inactive_open || ticket != V_ticket_altqs_inactive) 1052 return (EBUSY); 1053 1054 /* swap altqs, keep the old. */ 1055 old_altqs = V_pf_altqs_active; 1056 old_altq_ifs = V_pf_altq_ifs_active; 1057 V_pf_altqs_active = V_pf_altqs_inactive; 1058 V_pf_altq_ifs_active = V_pf_altq_ifs_inactive; 1059 V_pf_altqs_inactive = old_altqs; 1060 V_pf_altq_ifs_inactive = old_altq_ifs; 1061 V_ticket_altqs_active = V_ticket_altqs_inactive; 1062 1063 /* Attach new disciplines */ 1064 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) { 1065 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) { 1066 /* attach the discipline */ 1067 error = altq_pfattach(altq); 1068 if (error == 0 && V_pf_altq_running) 1069 error = pf_enable_altq(altq); 1070 if (error != 0) 1071 return (error); 1072 } 1073 } 1074 1075 /* Purge the old altq lists */ 1076 TAILQ_FOREACH_SAFE(altq, V_pf_altq_ifs_inactive, entries, tmp) { 1077 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) { 1078 /* detach and destroy the discipline */ 1079 if (V_pf_altq_running) 1080 error = pf_disable_altq(altq); 1081 err = altq_pfdetach(altq); 1082 if (err != 0 && error == 0) 1083 error = err; 1084 err = altq_remove(altq); 1085 if (err != 0 && error == 0) 1086 error = err; 1087 } 1088 free(altq, M_PFALTQ); 1089 } 1090 TAILQ_INIT(V_pf_altq_ifs_inactive); 1091 TAILQ_FOREACH_SAFE(altq, V_pf_altqs_inactive, entries, tmp) { 1092 pf_qid_unref(altq->qid); 1093 free(altq, M_PFALTQ); 1094 } 1095 TAILQ_INIT(V_pf_altqs_inactive); 1096 1097 V_altqs_inactive_open = 0; 1098 return (error); 1099 } 1100 1101 static int 1102 pf_enable_altq(struct pf_altq *altq) 1103 { 1104 struct ifnet *ifp; 1105 struct tb_profile tb; 1106 int error = 0; 1107 1108 if ((ifp = ifunit(altq->ifname)) == NULL) 1109 return (EINVAL); 1110 1111 if (ifp->if_snd.altq_type != ALTQT_NONE) 1112 error = altq_enable(&ifp->if_snd); 1113 1114 /* set tokenbucket regulator */ 1115 if (error == 0 && ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) { 1116 tb.rate = altq->ifbandwidth; 1117 tb.depth = altq->tbrsize; 1118 error = tbr_set(&ifp->if_snd, &tb); 1119 } 1120 1121 return (error); 1122 } 1123 1124 static int 1125 pf_disable_altq(struct pf_altq *altq) 1126 { 1127 struct ifnet *ifp; 1128 struct tb_profile tb; 1129 int error; 1130 1131 if ((ifp = ifunit(altq->ifname)) == NULL) 1132 return (EINVAL); 1133 1134 /* 1135 * when the discipline is no longer referenced, it was overridden 1136 * by a new one. if so, just return. 1137 */ 1138 if (altq->altq_disc != ifp->if_snd.altq_disc) 1139 return (0); 1140 1141 error = altq_disable(&ifp->if_snd); 1142 1143 if (error == 0) { 1144 /* clear tokenbucket regulator */ 1145 tb.rate = 0; 1146 error = tbr_set(&ifp->if_snd, &tb); 1147 } 1148 1149 return (error); 1150 } 1151 1152 static int 1153 pf_altq_ifnet_event_add(struct ifnet *ifp, int remove, u_int32_t ticket, 1154 struct pf_altq *altq) 1155 { 1156 struct ifnet *ifp1; 1157 int error = 0; 1158 1159 /* Deactivate the interface in question */ 1160 altq->local_flags &= ~PFALTQ_FLAG_IF_REMOVED; 1161 if ((ifp1 = ifunit(altq->ifname)) == NULL || 1162 (remove && ifp1 == ifp)) { 1163 altq->local_flags |= PFALTQ_FLAG_IF_REMOVED; 1164 } else { 1165 error = altq_add(ifp1, altq); 1166 1167 if (ticket != V_ticket_altqs_inactive) 1168 error = EBUSY; 1169 1170 if (error) 1171 free(altq, M_PFALTQ); 1172 } 1173 1174 return (error); 1175 } 1176 1177 void 1178 pf_altq_ifnet_event(struct ifnet *ifp, int remove) 1179 { 1180 struct pf_altq *a1, *a2, *a3; 1181 u_int32_t ticket; 1182 int error = 0; 1183 1184 /* 1185 * No need to re-evaluate the configuration for events on interfaces 1186 * that do not support ALTQ, as it's not possible for such 1187 * interfaces to be part of the configuration. 1188 */ 1189 if (!ALTQ_IS_READY(&ifp->if_snd)) 1190 return; 1191 1192 /* Interrupt userland queue modifications */ 1193 if (V_altqs_inactive_open) 1194 pf_rollback_altq(V_ticket_altqs_inactive); 1195 1196 /* Start new altq ruleset */ 1197 if (pf_begin_altq(&ticket)) 1198 return; 1199 1200 /* Copy the current active set */ 1201 TAILQ_FOREACH(a1, V_pf_altq_ifs_active, entries) { 1202 a2 = malloc(sizeof(*a2), M_PFALTQ, M_NOWAIT); 1203 if (a2 == NULL) { 1204 error = ENOMEM; 1205 break; 1206 } 1207 bcopy(a1, a2, sizeof(struct pf_altq)); 1208 1209 error = pf_altq_ifnet_event_add(ifp, remove, ticket, a2); 1210 if (error) 1211 break; 1212 1213 TAILQ_INSERT_TAIL(V_pf_altq_ifs_inactive, a2, entries); 1214 } 1215 if (error) 1216 goto out; 1217 TAILQ_FOREACH(a1, V_pf_altqs_active, entries) { 1218 a2 = malloc(sizeof(*a2), M_PFALTQ, M_NOWAIT); 1219 if (a2 == NULL) { 1220 error = ENOMEM; 1221 break; 1222 } 1223 bcopy(a1, a2, sizeof(struct pf_altq)); 1224 1225 if ((a2->qid = pf_qname2qid(a2->qname, true)) == 0) { 1226 error = EBUSY; 1227 free(a2, M_PFALTQ); 1228 break; 1229 } 1230 a2->altq_disc = NULL; 1231 TAILQ_FOREACH(a3, V_pf_altq_ifs_inactive, entries) { 1232 if (strncmp(a3->ifname, a2->ifname, 1233 IFNAMSIZ) == 0) { 1234 a2->altq_disc = a3->altq_disc; 1235 break; 1236 } 1237 } 1238 error = pf_altq_ifnet_event_add(ifp, remove, ticket, a2); 1239 if (error) 1240 break; 1241 1242 TAILQ_INSERT_TAIL(V_pf_altqs_inactive, a2, entries); 1243 } 1244 1245 out: 1246 if (error != 0) 1247 pf_rollback_altq(ticket); 1248 else 1249 pf_commit_altq(ticket); 1250 } 1251 #endif /* ALTQ */ 1252 1253 static struct pf_krule_global * 1254 pf_rule_tree_alloc(int flags) 1255 { 1256 struct pf_krule_global *tree; 1257 1258 tree = malloc(sizeof(struct pf_krule_global), M_PF, flags); 1259 if (tree == NULL) 1260 return (NULL); 1261 RB_INIT(tree); 1262 return (tree); 1263 } 1264 1265 void 1266 pf_rule_tree_free(struct pf_krule_global *tree) 1267 { 1268 1269 free(tree, M_PF); 1270 } 1271 1272 static int 1273 pf_begin_rules(u_int32_t *ticket, int rs_num, const char *anchor) 1274 { 1275 struct pf_krule_global *tree; 1276 struct pf_kruleset *rs; 1277 struct pf_krule *rule; 1278 1279 PF_RULES_WASSERT(); 1280 1281 if (rs_num < 0 || rs_num >= PF_RULESET_MAX) 1282 return (EINVAL); 1283 tree = pf_rule_tree_alloc(M_NOWAIT); 1284 if (tree == NULL) 1285 return (ENOMEM); 1286 rs = pf_find_or_create_kruleset(anchor); 1287 if (rs == NULL) { 1288 pf_rule_tree_free(tree); 1289 return (EINVAL); 1290 } 1291 pf_rule_tree_free(rs->rules[rs_num].inactive.tree); 1292 rs->rules[rs_num].inactive.tree = tree; 1293 1294 while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL) { 1295 pf_unlink_rule(rs->rules[rs_num].inactive.ptr, rule); 1296 rs->rules[rs_num].inactive.rcount--; 1297 } 1298 *ticket = ++rs->rules[rs_num].inactive.ticket; 1299 rs->rules[rs_num].inactive.open = 1; 1300 return (0); 1301 } 1302 1303 static int 1304 pf_rollback_rules(u_int32_t ticket, int rs_num, char *anchor) 1305 { 1306 struct pf_kruleset *rs; 1307 struct pf_krule *rule; 1308 1309 PF_RULES_WASSERT(); 1310 1311 if (rs_num < 0 || rs_num >= PF_RULESET_MAX) 1312 return (EINVAL); 1313 rs = pf_find_kruleset(anchor); 1314 if (rs == NULL || !rs->rules[rs_num].inactive.open || 1315 rs->rules[rs_num].inactive.ticket != ticket) 1316 return (0); 1317 while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL) { 1318 pf_unlink_rule(rs->rules[rs_num].inactive.ptr, rule); 1319 rs->rules[rs_num].inactive.rcount--; 1320 } 1321 rs->rules[rs_num].inactive.open = 0; 1322 1323 if (anchor[0]) 1324 return (0); 1325 1326 pf_statelim_rollback(); 1327 pf_sourcelim_rollback(); 1328 return (0); 1329 } 1330 1331 #define PF_MD5_UPD(st, elm) \ 1332 MD5Update(ctx, (u_int8_t *) &(st)->elm, sizeof((st)->elm)) 1333 1334 #define PF_MD5_UPD_STR(st, elm) \ 1335 MD5Update(ctx, (u_int8_t *) (st)->elm, strlen((st)->elm)) 1336 1337 #define PF_MD5_UPD_HTONL(st, elm, stor) do { \ 1338 (stor) = htonl((st)->elm); \ 1339 MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int32_t));\ 1340 } while (0) 1341 1342 #define PF_MD5_UPD_HTONS(st, elm, stor) do { \ 1343 (stor) = htons((st)->elm); \ 1344 MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int16_t));\ 1345 } while (0) 1346 1347 static void 1348 pf_hash_rule_addr(MD5_CTX *ctx, struct pf_rule_addr *pfr) 1349 { 1350 PF_MD5_UPD(pfr, addr.type); 1351 switch (pfr->addr.type) { 1352 case PF_ADDR_DYNIFTL: 1353 PF_MD5_UPD(pfr, addr.v.ifname); 1354 PF_MD5_UPD(pfr, addr.iflags); 1355 break; 1356 case PF_ADDR_TABLE: 1357 PF_MD5_UPD(pfr, addr.v.tblname); 1358 break; 1359 case PF_ADDR_ADDRMASK: 1360 case PF_ADDR_RANGE: 1361 /* XXX ignore af? */ 1362 PF_MD5_UPD(pfr, addr.v.a.addr.addr32); 1363 PF_MD5_UPD(pfr, addr.v.a.mask.addr32); 1364 break; 1365 case PF_ADDR_NONE: 1366 case PF_ADDR_NOROUTE: 1367 case PF_ADDR_URPFFAILED: 1368 /* These do not use any address data. */ 1369 break; 1370 default: 1371 panic("Unknown address type %d", pfr->addr.type); 1372 } 1373 1374 PF_MD5_UPD(pfr, port[0]); 1375 PF_MD5_UPD(pfr, port[1]); 1376 PF_MD5_UPD(pfr, neg); 1377 PF_MD5_UPD(pfr, port_op); 1378 } 1379 1380 static void 1381 pf_hash_pool(MD5_CTX *ctx, struct pf_kpool *pool) 1382 { 1383 struct pf_addr_wrap addr; 1384 uint16_t x; 1385 int y; 1386 1387 if (pool->cur) { 1388 /* Leave out the pointer to the kernel's dynaddr or table. */ 1389 bcopy(&pool->cur->addr, &addr, sizeof(addr)); 1390 bzero(&addr.p, sizeof(addr.p)); 1391 MD5Update(ctx, (u_int8_t *)&addr, sizeof(addr)); 1392 PF_MD5_UPD_STR(pool, cur->ifname); 1393 PF_MD5_UPD(pool, cur->af); 1394 } 1395 PF_MD5_UPD(pool, key); 1396 PF_MD5_UPD(pool, counter); 1397 1398 PF_MD5_UPD(pool, mape.offset); 1399 PF_MD5_UPD(pool, mape.psidlen); 1400 PF_MD5_UPD_HTONS(pool, mape.psid, x); 1401 PF_MD5_UPD_HTONL(pool, tblidx, y); 1402 PF_MD5_UPD_HTONS(pool, proxy_port[0], x); 1403 PF_MD5_UPD_HTONS(pool, proxy_port[1], x); 1404 PF_MD5_UPD(pool, opts); 1405 PF_MD5_UPD(pool, ipv6_nexthop_af); 1406 } 1407 1408 static void 1409 pf_hash_rule_rolling(MD5_CTX *ctx, struct pf_krule *rule) 1410 { 1411 u_int16_t x; 1412 u_int32_t y; 1413 1414 pf_hash_rule_addr(ctx, &rule->src); 1415 pf_hash_rule_addr(ctx, &rule->dst); 1416 for (int i = 0; i < PF_RULE_MAX_LABEL_COUNT; i++) 1417 PF_MD5_UPD_STR(rule, label[i]); 1418 PF_MD5_UPD_HTONL(rule, ridentifier, y); 1419 PF_MD5_UPD_STR(rule, ifname); 1420 PF_MD5_UPD_STR(rule, rcv_ifname); 1421 PF_MD5_UPD_STR(rule, qname); 1422 PF_MD5_UPD_STR(rule, pqname); 1423 PF_MD5_UPD_STR(rule, tagname); 1424 PF_MD5_UPD_STR(rule, match_tagname); 1425 1426 PF_MD5_UPD_STR(rule, overload_tblname); 1427 1428 pf_hash_pool(ctx, &rule->nat); 1429 pf_hash_pool(ctx, &rule->rdr); 1430 pf_hash_pool(ctx, &rule->route); 1431 PF_MD5_UPD_HTONL(rule, pktrate.limit, y); 1432 PF_MD5_UPD_HTONL(rule, pktrate.seconds, y); 1433 1434 PF_MD5_UPD_HTONL(rule, os_fingerprint, y); 1435 1436 PF_MD5_UPD_HTONL(rule, rtableid, y); 1437 for (int i = 0; i < PFTM_MAX; i++) 1438 PF_MD5_UPD_HTONL(rule, timeout[i], y); 1439 PF_MD5_UPD_HTONL(rule, max_states, y); 1440 PF_MD5_UPD_HTONL(rule, max_src_nodes, y); 1441 PF_MD5_UPD_HTONL(rule, max_src_states, y); 1442 PF_MD5_UPD_HTONL(rule, max_src_conn, y); 1443 PF_MD5_UPD_HTONL(rule, max_src_conn_rate.limit, y); 1444 PF_MD5_UPD_HTONL(rule, max_src_conn_rate.seconds, y); 1445 PF_MD5_UPD_HTONS(rule, max_pkt_size, y); 1446 PF_MD5_UPD_HTONS(rule, qid, x); 1447 PF_MD5_UPD_HTONS(rule, pqid, x); 1448 PF_MD5_UPD_HTONS(rule, dnpipe, x); 1449 PF_MD5_UPD_HTONS(rule, dnrpipe, x); 1450 PF_MD5_UPD_HTONL(rule, free_flags, y); 1451 PF_MD5_UPD_HTONL(rule, prob, y); 1452 1453 PF_MD5_UPD_HTONS(rule, return_icmp, x); 1454 PF_MD5_UPD_HTONS(rule, return_icmp6, x); 1455 PF_MD5_UPD_HTONS(rule, max_mss, x); 1456 PF_MD5_UPD_HTONS(rule, tag, x); /* dup? */ 1457 PF_MD5_UPD_HTONS(rule, match_tag, x); /* dup? */ 1458 PF_MD5_UPD_HTONS(rule, scrub_flags, x); 1459 1460 PF_MD5_UPD(rule, uid.op); 1461 PF_MD5_UPD_HTONL(rule, uid.uid[0], y); 1462 PF_MD5_UPD_HTONL(rule, uid.uid[1], y); 1463 PF_MD5_UPD(rule, gid.op); 1464 PF_MD5_UPD_HTONL(rule, gid.gid[0], y); 1465 PF_MD5_UPD_HTONL(rule, gid.gid[1], y); 1466 1467 PF_MD5_UPD_HTONL(rule, rule_flag, y); 1468 PF_MD5_UPD_HTONL(rule, rule_ref, y); 1469 PF_MD5_UPD(rule, action); 1470 PF_MD5_UPD(rule, direction); 1471 PF_MD5_UPD(rule, log); 1472 PF_MD5_UPD(rule, logif); 1473 PF_MD5_UPD(rule, quick); 1474 PF_MD5_UPD(rule, ifnot); 1475 PF_MD5_UPD(rule, match_tag_not); 1476 PF_MD5_UPD(rule, natpass); 1477 1478 PF_MD5_UPD(rule, keep_state); 1479 PF_MD5_UPD(rule, af); 1480 PF_MD5_UPD(rule, proto); 1481 PF_MD5_UPD_HTONS(rule, type, x); 1482 PF_MD5_UPD_HTONS(rule, code, x); 1483 PF_MD5_UPD(rule, flags); 1484 PF_MD5_UPD(rule, flagset); 1485 PF_MD5_UPD(rule, min_ttl); 1486 PF_MD5_UPD(rule, allow_opts); 1487 PF_MD5_UPD(rule, rt); 1488 PF_MD5_UPD(rule, return_ttl); 1489 PF_MD5_UPD(rule, tos); 1490 PF_MD5_UPD(rule, set_tos); 1491 PF_MD5_UPD(rule, anchor_relative); 1492 PF_MD5_UPD(rule, anchor_wildcard); 1493 1494 PF_MD5_UPD(rule, flush); 1495 PF_MD5_UPD(rule, prio); 1496 PF_MD5_UPD(rule, set_prio[0]); 1497 PF_MD5_UPD(rule, set_prio[1]); 1498 PF_MD5_UPD(rule, naf); 1499 PF_MD5_UPD(rule, rcvifnot); 1500 PF_MD5_UPD(rule, statelim.id); 1501 PF_MD5_UPD_HTONL(rule, statelim.limiter_action, y); 1502 PF_MD5_UPD(rule, sourcelim.id); 1503 PF_MD5_UPD_HTONL(rule, sourcelim.limiter_action, y); 1504 1505 PF_MD5_UPD(rule, divert.addr); 1506 PF_MD5_UPD_HTONS(rule, divert.port, x); 1507 1508 if (rule->anchor != NULL) 1509 PF_MD5_UPD_STR(rule, anchor->path); 1510 } 1511 1512 static void 1513 pf_hash_rule(struct pf_krule *rule) 1514 { 1515 MD5_CTX ctx; 1516 1517 MD5Init(&ctx); 1518 pf_hash_rule_rolling(&ctx, rule); 1519 MD5Final(rule->md5sum, &ctx); 1520 } 1521 1522 static int 1523 pf_krule_compare(struct pf_krule *a, struct pf_krule *b) 1524 { 1525 1526 return (memcmp(a->md5sum, b->md5sum, PF_MD5_DIGEST_LENGTH)); 1527 } 1528 1529 static int 1530 pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor) 1531 { 1532 struct pf_kruleset *rs; 1533 struct pf_krule *rule, *old_rule; 1534 struct pf_krulequeue *old_rules; 1535 struct pf_krule_global *old_tree; 1536 int error; 1537 u_int32_t old_rcount; 1538 bool is_main_ruleset = anchor[0] == '\0'; 1539 1540 PF_RULES_WASSERT(); 1541 1542 if (rs_num < 0 || rs_num >= PF_RULESET_MAX) 1543 return (EINVAL); 1544 rs = pf_find_kruleset(anchor); 1545 if (rs == NULL || !rs->rules[rs_num].inactive.open || 1546 ticket != rs->rules[rs_num].inactive.ticket) 1547 return (EBUSY); 1548 1549 /* Calculate checksum for the main ruleset */ 1550 if (rs == &pf_main_ruleset) { 1551 error = pf_sourcelim_check(); 1552 if (error != 0) 1553 return (error); 1554 error = pf_setup_pfsync_matching(rs); 1555 if (error != 0) 1556 return (error); 1557 } 1558 1559 /* Swap rules, keep the old. */ 1560 old_rules = rs->rules[rs_num].active.ptr; 1561 old_rcount = rs->rules[rs_num].active.rcount; 1562 old_tree = rs->rules[rs_num].active.tree; 1563 1564 rs->rules[rs_num].active.ptr = 1565 rs->rules[rs_num].inactive.ptr; 1566 rs->rules[rs_num].active.tree = 1567 rs->rules[rs_num].inactive.tree; 1568 rs->rules[rs_num].active.rcount = 1569 rs->rules[rs_num].inactive.rcount; 1570 1571 /* Attempt to preserve counter information. */ 1572 if (V_pf_status.keep_counters && old_tree != NULL) { 1573 TAILQ_FOREACH(rule, rs->rules[rs_num].active.ptr, 1574 entries) { 1575 old_rule = RB_FIND(pf_krule_global, old_tree, rule); 1576 if (old_rule == NULL) { 1577 continue; 1578 } 1579 pf_counter_u64_critical_enter(); 1580 pf_counter_u64_rollup_protected(&rule->evaluations, 1581 pf_counter_u64_fetch(&old_rule->evaluations)); 1582 pf_counter_u64_rollup_protected(&rule->packets[0], 1583 pf_counter_u64_fetch(&old_rule->packets[0])); 1584 pf_counter_u64_rollup_protected(&rule->packets[1], 1585 pf_counter_u64_fetch(&old_rule->packets[1])); 1586 pf_counter_u64_rollup_protected(&rule->bytes[0], 1587 pf_counter_u64_fetch(&old_rule->bytes[0])); 1588 pf_counter_u64_rollup_protected(&rule->bytes[1], 1589 pf_counter_u64_fetch(&old_rule->bytes[1])); 1590 pf_counter_u64_critical_exit(); 1591 } 1592 } 1593 1594 rs->rules[rs_num].inactive.ptr = old_rules; 1595 rs->rules[rs_num].inactive.tree = NULL; /* important for pf_ioctl_addrule */ 1596 rs->rules[rs_num].inactive.rcount = old_rcount; 1597 1598 rs->rules[rs_num].active.ticket = 1599 rs->rules[rs_num].inactive.ticket; 1600 pf_calc_skip_steps(rs->rules[rs_num].active.ptr); 1601 1602 /* Purge the old rule list. */ 1603 PF_UNLNKDRULES_LOCK(); 1604 while ((rule = TAILQ_FIRST(old_rules)) != NULL) 1605 pf_unlink_rule_locked(old_rules, rule); 1606 PF_UNLNKDRULES_UNLOCK(); 1607 rs->rules[rs_num].inactive.rcount = 0; 1608 rs->rules[rs_num].inactive.open = 0; 1609 pf_remove_if_empty_kruleset(rs); 1610 pf_rule_tree_free(old_tree); 1611 1612 /* statelim/sourcelim/queue defs only in the main ruleset */ 1613 if (! is_main_ruleset || rs_num != PF_RULESET_FILTER) 1614 return (0); 1615 1616 pf_statelim_commit(); 1617 pf_sourcelim_commit(); 1618 1619 return (0); 1620 } 1621 1622 static int 1623 pf_setup_pfsync_matching(struct pf_kruleset *rs) 1624 { 1625 MD5_CTX ctx; 1626 struct pf_krule *rule; 1627 int rs_cnt; 1628 u_int8_t digest[PF_MD5_DIGEST_LENGTH]; 1629 1630 MD5Init(&ctx); 1631 for (rs_cnt = 0; rs_cnt < PF_RULESET_MAX; rs_cnt++) { 1632 /* XXX PF_RULESET_SCRUB as well? */ 1633 if (rs_cnt == PF_RULESET_SCRUB) 1634 continue; 1635 1636 if (rs->rules[rs_cnt].inactive.rcount) { 1637 TAILQ_FOREACH(rule, rs->rules[rs_cnt].inactive.ptr, 1638 entries) { 1639 pf_hash_rule_rolling(&ctx, rule); 1640 } 1641 } 1642 } 1643 1644 MD5Final(digest, &ctx); 1645 memcpy(V_pf_status.pf_chksum, digest, sizeof(V_pf_status.pf_chksum)); 1646 return (0); 1647 } 1648 1649 static int 1650 pf_eth_addr_setup(struct pf_keth_ruleset *ruleset, struct pf_addr_wrap *addr) 1651 { 1652 int error = 0; 1653 1654 switch (addr->type) { 1655 case PF_ADDR_TABLE: 1656 addr->p.tbl = pfr_eth_attach_table(ruleset, addr->v.tblname); 1657 if (addr->p.tbl == NULL) 1658 error = ENOMEM; 1659 break; 1660 default: 1661 error = EINVAL; 1662 } 1663 1664 return (error); 1665 } 1666 1667 static int 1668 pf_addr_setup(struct pf_kruleset *ruleset, struct pf_addr_wrap *addr, 1669 sa_family_t af) 1670 { 1671 int error = 0; 1672 1673 switch (addr->type) { 1674 case PF_ADDR_TABLE: 1675 addr->p.tbl = pfr_attach_table(ruleset, addr->v.tblname); 1676 if (addr->p.tbl == NULL) 1677 error = ENOMEM; 1678 break; 1679 case PF_ADDR_DYNIFTL: 1680 error = pfi_dynaddr_setup(addr, af); 1681 break; 1682 } 1683 1684 return (error); 1685 } 1686 1687 void 1688 pf_addr_copyout(struct pf_addr_wrap *addr) 1689 { 1690 1691 switch (addr->type) { 1692 case PF_ADDR_DYNIFTL: 1693 pfi_dynaddr_copyout(addr); 1694 break; 1695 case PF_ADDR_TABLE: 1696 pf_tbladdr_copyout(addr); 1697 break; 1698 } 1699 } 1700 1701 int 1702 pf_statelim_add(const struct pfioc_statelim *ioc) 1703 { 1704 struct pf_statelim *pfstlim; 1705 int error; 1706 size_t namelen; 1707 1708 if (ioc->id < PF_STATELIM_ID_MIN || 1709 ioc->id > PF_STATELIM_ID_MAX) 1710 return (EINVAL); 1711 1712 if (ioc->limit < PF_STATELIM_LIMIT_MIN || 1713 ioc->limit > PF_STATELIM_LIMIT_MAX) 1714 return (EINVAL); 1715 1716 if ((ioc->rate.limit == 0) != (ioc->rate.seconds == 0)) 1717 return (EINVAL); 1718 1719 namelen = strnlen(ioc->name, sizeof(ioc->name)); 1720 /* is the name from userland nul terminated? */ 1721 if (namelen == sizeof(ioc->name)) 1722 return (EINVAL); 1723 1724 pfstlim = malloc(sizeof(*pfstlim), M_PF_STATE_LIM, M_WAITOK | M_ZERO); 1725 if (pfstlim == NULL) 1726 return (ENOMEM); 1727 1728 pfstlim->pfstlim_id = ioc->id; 1729 if (strlcpy(pfstlim->pfstlim_nm, ioc->name, 1730 sizeof(pfstlim->pfstlim_nm)) >= sizeof(pfstlim->pfstlim_nm)) { 1731 error = EINVAL; 1732 goto free; 1733 } 1734 pfstlim->pfstlim_limit = ioc->limit; 1735 pfstlim->pfstlim_rate.limit = ioc->rate.limit; 1736 pfstlim->pfstlim_rate.seconds = ioc->rate.seconds; 1737 1738 if (pfstlim->pfstlim_rate.limit) { 1739 uint64_t bucket = SEC_TO_NSEC(pfstlim->pfstlim_rate.seconds); 1740 struct timespec ts; 1741 1742 getnanouptime(&ts); 1743 1744 pfstlim->pfstlim_rate_ts = SEC_TO_NSEC(ts.tv_sec) + ts.tv_nsec - 1745 bucket; 1746 pfstlim->pfstlim_rate_token = bucket / 1747 pfstlim->pfstlim_rate.limit; 1748 pfstlim->pfstlim_rate_bucket = bucket; 1749 } 1750 1751 TAILQ_INIT(&pfstlim->pfstlim_states); 1752 mtx_init(&pfstlim->pfstlim_lock, "pf state limit", NULL, MTX_DEF); 1753 1754 PF_RULES_WLOCK(); 1755 if (ioc->ticket != pf_main_ruleset.rules[PF_RULESET_FILTER].inactive.ticket) { 1756 error = EBUSY; 1757 goto unlock; 1758 } 1759 1760 if (RB_INSERT(pf_statelim_id_tree, &V_pf_statelim_id_tree_inactive, 1761 pfstlim) != NULL) { 1762 error = EBUSY; 1763 goto unlock; 1764 } 1765 1766 if (RB_INSERT(pf_statelim_nm_tree, &V_pf_statelim_nm_tree_inactive, 1767 pfstlim) != NULL) { 1768 RB_REMOVE(pf_statelim_id_tree, &V_pf_statelim_id_tree_inactive, 1769 pfstlim); 1770 error = EBUSY; 1771 goto unlock; 1772 } 1773 1774 TAILQ_INSERT_HEAD(&V_pf_statelim_list_inactive, pfstlim, pfstlim_list); 1775 1776 PF_RULES_WUNLOCK(); 1777 1778 return (0); 1779 1780 unlock: 1781 PF_RULES_WUNLOCK(); 1782 1783 free: 1784 free(pfstlim, M_PF_STATE_LIM); 1785 1786 return (error); 1787 } 1788 1789 static void 1790 pf_statelim_unlink(struct pf_statelim *pfstlim, 1791 struct pf_state_link_list *garbage) 1792 { 1793 struct pf_state_link *pfl; 1794 1795 1796 /* unwire the links */ 1797 TAILQ_FOREACH(pfl, &pfstlim->pfstlim_states, pfl_link) { 1798 struct pf_kstate *s = pfl->pfl_state; 1799 1800 /* if !rmst */ 1801 PF_STATE_LOCK(s); 1802 s->statelim = 0; 1803 SLIST_REMOVE(&s->linkage, pfl, pf_state_link, pfl_linkage); 1804 PF_STATE_UNLOCK(s); 1805 } 1806 1807 /* take the list away */ 1808 TAILQ_CONCAT(garbage, &pfstlim->pfstlim_states, pfl_link); 1809 pfstlim->pfstlim_inuse = 0; 1810 } 1811 1812 void 1813 pf_statelim_commit(void) 1814 { 1815 struct pf_statelim *pfstlim, *npfstlim, *opfstlim; 1816 struct pf_statelim_list l = TAILQ_HEAD_INITIALIZER(l); 1817 struct pf_state_link_list garbage = TAILQ_HEAD_INITIALIZER(garbage); 1818 struct pf_state_link *pfl, *npfl; 1819 1820 PF_RULES_WASSERT(); 1821 1822 /* merge the new statelims into the current set */ 1823 1824 /* start with an empty active list */ 1825 TAILQ_CONCAT(&l, &V_pf_statelim_list_active, pfstlim_list); 1826 1827 /* beware, the inactive bits gets messed up here */ 1828 1829 /* try putting pending statelims into the active tree */ 1830 TAILQ_FOREACH_SAFE(pfstlim, &V_pf_statelim_list_inactive, pfstlim_list, 1831 npfstlim) { 1832 opfstlim = RB_INSERT(pf_statelim_id_tree, 1833 &V_pf_statelim_id_tree_active, pfstlim); 1834 if (opfstlim != NULL) { 1835 /* this statelim already exists, merge */ 1836 opfstlim->pfstlim_limit = pfstlim->pfstlim_limit; 1837 opfstlim->pfstlim_rate.limit = 1838 pfstlim->pfstlim_rate.limit; 1839 opfstlim->pfstlim_rate.seconds = 1840 pfstlim->pfstlim_rate.seconds; 1841 1842 opfstlim->pfstlim_rate_ts = pfstlim->pfstlim_rate_ts; 1843 opfstlim->pfstlim_rate_token = 1844 pfstlim->pfstlim_rate_token; 1845 opfstlim->pfstlim_rate_bucket = 1846 pfstlim->pfstlim_rate_bucket; 1847 1848 memcpy(opfstlim->pfstlim_nm, pfstlim->pfstlim_nm, 1849 sizeof(opfstlim->pfstlim_nm)); 1850 1851 /* use the existing statelim instead */ 1852 free(pfstlim, M_PF_STATE_LIM); 1853 TAILQ_REMOVE(&l, opfstlim, pfstlim_list); 1854 pfstlim = opfstlim; 1855 } 1856 1857 TAILQ_INSERT_TAIL(&V_pf_statelim_list_active, pfstlim, 1858 pfstlim_list); 1859 } 1860 1861 /* clean up the now unused statelims from the old set */ 1862 TAILQ_FOREACH_SAFE(pfstlim, &l, pfstlim_list, npfstlim) { 1863 pf_statelim_unlink(pfstlim, &garbage); 1864 1865 RB_REMOVE(pf_statelim_id_tree, &V_pf_statelim_id_tree_active, 1866 pfstlim); 1867 1868 free(pfstlim, M_PF_STATE_LIM); 1869 } 1870 1871 /* fix up the inactive tree */ 1872 RB_INIT(&V_pf_statelim_id_tree_inactive); 1873 RB_INIT(&V_pf_statelim_nm_tree_inactive); 1874 TAILQ_INIT(&V_pf_statelim_list_inactive); 1875 1876 TAILQ_FOREACH_SAFE(pfl, &garbage, pfl_link, npfl) 1877 free(pfl, M_PF_STATE_LINK); 1878 } 1879 1880 static void 1881 pf_sourcelim_unlink(struct pf_sourcelim *pfsrlim, 1882 struct pf_state_link_list *garbage) 1883 { 1884 extern struct pf_source_list pf_source_gc; 1885 struct pf_source *pfsr; 1886 struct pf_state_link *pfl; 1887 1888 PF_RULES_WASSERT(); 1889 1890 while ((pfsr = RB_ROOT(&pfsrlim->pfsrlim_sources)) != NULL) { 1891 RB_REMOVE(pf_source_tree, &pfsrlim->pfsrlim_sources, pfsr); 1892 RB_REMOVE(pf_source_ioc_tree, &pfsrlim->pfsrlim_ioc_sources, 1893 pfsr); 1894 if (pfsr->pfsr_inuse == 0) 1895 TAILQ_REMOVE(&pf_source_gc, pfsr, pfsr_empty_gc); 1896 1897 /* unwire the links */ 1898 TAILQ_FOREACH(pfl, &pfsr->pfsr_states, pfl_link) { 1899 struct pf_kstate *s = pfl->pfl_state; 1900 1901 PF_STATE_LOCK(s); 1902 /* if !rmst */ 1903 s->sourcelim = 0; 1904 SLIST_REMOVE(&s->linkage, pfl, pf_state_link, 1905 pfl_linkage); 1906 PF_STATE_UNLOCK(s); 1907 } 1908 1909 /* take the list away */ 1910 TAILQ_CONCAT(garbage, &pfsr->pfsr_states, pfl_link); 1911 1912 free(pfsr, M_PF_SOURCE_LIM); 1913 } 1914 } 1915 1916 int 1917 pf_sourcelim_check(void) 1918 { 1919 struct pf_sourcelim *pfsrlim, *npfsrlim; 1920 1921 PF_RULES_WASSERT(); 1922 1923 /* check if we can merge */ 1924 1925 TAILQ_FOREACH(pfsrlim, &V_pf_sourcelim_list_inactive, pfsrlim_list) { 1926 npfsrlim = RB_FIND(pf_sourcelim_id_tree, 1927 &V_pf_sourcelim_id_tree_active, pfsrlim); 1928 1929 /* new config, no conflict */ 1930 if (npfsrlim == NULL) 1931 continue; 1932 1933 /* nothing is tracked at the moment, no conflict */ 1934 if (RB_EMPTY(&npfsrlim->pfsrlim_sources)) 1935 continue; 1936 1937 if (strcmp(npfsrlim->pfsrlim_overload.name, 1938 pfsrlim->pfsrlim_overload.name) != 0) 1939 return (EBUSY); 1940 1941 /* 1942 * we should allow the prefixlens to get shorter 1943 * and merge pf_source entries. 1944 */ 1945 1946 if ((npfsrlim->pfsrlim_ipv4_prefix != 1947 pfsrlim->pfsrlim_ipv4_prefix) || 1948 (npfsrlim->pfsrlim_ipv6_prefix != 1949 pfsrlim->pfsrlim_ipv6_prefix)) 1950 return (EBUSY); 1951 } 1952 1953 return (0); 1954 } 1955 1956 void 1957 pf_sourcelim_commit(void) 1958 { 1959 struct pf_sourcelim *pfsrlim, *npfsrlim, *opfsrlim; 1960 struct pf_sourcelim_list l = TAILQ_HEAD_INITIALIZER(l); 1961 struct pf_state_link_list garbage = TAILQ_HEAD_INITIALIZER(garbage); 1962 struct pf_state_link *pfl, *npfl; 1963 1964 PF_RULES_WASSERT(); 1965 1966 /* merge the new sourcelims into the current set */ 1967 1968 /* start with an empty active list */ 1969 TAILQ_CONCAT(&l, &V_pf_sourcelim_list_active, pfsrlim_list); 1970 1971 /* beware, the inactive bits gets messed up here */ 1972 1973 /* try putting pending sourcelims into the active tree */ 1974 TAILQ_FOREACH_SAFE(pfsrlim, &V_pf_sourcelim_list_inactive, pfsrlim_list, 1975 npfsrlim) { 1976 opfsrlim = RB_INSERT(pf_sourcelim_id_tree, 1977 &V_pf_sourcelim_id_tree_active, pfsrlim); 1978 if (opfsrlim != NULL) { 1979 /* this sourcelim already exists, merge */ 1980 opfsrlim->pfsrlim_entries = pfsrlim->pfsrlim_entries; 1981 opfsrlim->pfsrlim_limit = pfsrlim->pfsrlim_limit; 1982 opfsrlim->pfsrlim_ipv4_prefix = 1983 pfsrlim->pfsrlim_ipv4_prefix; 1984 opfsrlim->pfsrlim_ipv6_prefix = 1985 pfsrlim->pfsrlim_ipv6_prefix; 1986 opfsrlim->pfsrlim_rate.limit = 1987 pfsrlim->pfsrlim_rate.limit; 1988 opfsrlim->pfsrlim_rate.seconds = 1989 pfsrlim->pfsrlim_rate.seconds; 1990 1991 opfsrlim->pfsrlim_ipv4_mask = 1992 pfsrlim->pfsrlim_ipv4_mask; 1993 opfsrlim->pfsrlim_ipv6_mask = 1994 pfsrlim->pfsrlim_ipv6_mask; 1995 1996 /* keep the existing pfstlim_rate_ts */ 1997 1998 opfsrlim->pfsrlim_rate_token = 1999 pfsrlim->pfsrlim_rate_token; 2000 opfsrlim->pfsrlim_rate_bucket = 2001 pfsrlim->pfsrlim_rate_bucket; 2002 2003 if (opfsrlim->pfsrlim_overload.table != NULL) { 2004 pfr_detach_table( 2005 opfsrlim->pfsrlim_overload.table); 2006 } 2007 2008 strlcpy(opfsrlim->pfsrlim_overload.name, 2009 pfsrlim->pfsrlim_overload.name, 2010 sizeof(opfsrlim->pfsrlim_overload.name)); 2011 opfsrlim->pfsrlim_overload.hwm = 2012 pfsrlim->pfsrlim_overload.hwm; 2013 opfsrlim->pfsrlim_overload.lwm = 2014 pfsrlim->pfsrlim_overload.lwm; 2015 opfsrlim->pfsrlim_overload.table = 2016 pfsrlim->pfsrlim_overload.table, 2017 2018 memcpy(opfsrlim->pfsrlim_nm, pfsrlim->pfsrlim_nm, 2019 sizeof(opfsrlim->pfsrlim_nm)); 2020 2021 /* use the existing sourcelim instead */ 2022 free(pfsrlim, M_PF_SOURCE_LIM); 2023 TAILQ_REMOVE(&l, opfsrlim, pfsrlim_list); 2024 pfsrlim = opfsrlim; 2025 } 2026 2027 TAILQ_INSERT_TAIL(&V_pf_sourcelim_list_active, pfsrlim, 2028 pfsrlim_list); 2029 } 2030 2031 /* clean up the now unused sourcelims from the old set */ 2032 TAILQ_FOREACH_SAFE(pfsrlim, &l, pfsrlim_list, npfsrlim) { 2033 pf_sourcelim_unlink(pfsrlim, &garbage); 2034 2035 RB_REMOVE(pf_sourcelim_id_tree, &V_pf_sourcelim_id_tree_active, 2036 pfsrlim); 2037 2038 if (pfsrlim->pfsrlim_overload.table != NULL) 2039 pfr_detach_table(pfsrlim->pfsrlim_overload.table); 2040 2041 free(pfsrlim, M_PF_SOURCE_LIM); 2042 } 2043 2044 /* fix up the inactive tree */ 2045 RB_INIT(&V_pf_sourcelim_id_tree_inactive); 2046 RB_INIT(&V_pf_sourcelim_nm_tree_inactive); 2047 TAILQ_INIT(&V_pf_sourcelim_list_inactive); 2048 2049 TAILQ_FOREACH_SAFE(pfl, &garbage, pfl_link, npfl) 2050 free(pfl, M_PF_STATE_LINK); 2051 } 2052 2053 void 2054 pf_statelim_rollback(void) 2055 { 2056 struct pf_statelim *pfstlim, *npfstlim; 2057 2058 PF_RULES_WASSERT(); 2059 2060 TAILQ_FOREACH_SAFE(pfstlim, &V_pf_statelim_list_inactive, pfstlim_list, 2061 npfstlim) 2062 free(pfstlim, M_PF_STATE_LIM); 2063 2064 TAILQ_INIT(&V_pf_statelim_list_inactive); 2065 RB_INIT(&V_pf_statelim_id_tree_inactive); 2066 RB_INIT(&V_pf_statelim_nm_tree_inactive); 2067 } 2068 2069 struct pf_statelim * 2070 pf_statelim_rb_find(struct pf_statelim_id_tree *tree, struct pf_statelim *key) 2071 { 2072 PF_RULES_ASSERT(); 2073 2074 return (RB_FIND(pf_statelim_id_tree, tree, key)); 2075 } 2076 2077 struct pf_statelim * 2078 pf_statelim_rb_nfind(struct pf_statelim_id_tree *tree, struct pf_statelim *key) 2079 { 2080 PF_RULES_ASSERT(); 2081 2082 return (RB_NFIND(pf_statelim_id_tree, tree, key)); 2083 } 2084 2085 int 2086 pf_statelim_get(struct pfioc_statelim *ioc, 2087 struct pf_statelim *(*rbt_op)(struct pf_statelim_id_tree *, 2088 struct pf_statelim *)) 2089 { 2090 struct pf_statelim key = { .pfstlim_id = ioc->id }; 2091 struct pf_statelim *pfstlim; 2092 int error = 0; 2093 PF_RULES_RLOCK_TRACKER; 2094 2095 PF_RULES_RLOCK(); 2096 2097 pfstlim = (*rbt_op)(&V_pf_statelim_id_tree_active, &key); 2098 if (pfstlim == NULL) { 2099 error = ENOENT; 2100 goto unlock; 2101 } 2102 2103 ioc->id = pfstlim->pfstlim_id; 2104 ioc->limit = pfstlim->pfstlim_limit; 2105 ioc->rate.limit = pfstlim->pfstlim_rate.limit; 2106 ioc->rate.seconds = pfstlim->pfstlim_rate.seconds; 2107 CTASSERT(sizeof(ioc->name) == sizeof(pfstlim->pfstlim_nm)); 2108 memcpy(ioc->name, pfstlim->pfstlim_nm, sizeof(ioc->name)); 2109 2110 ioc->inuse = pfstlim->pfstlim_inuse; 2111 ioc->admitted = pfstlim->pfstlim_counters.admitted; 2112 ioc->hardlimited = pfstlim->pfstlim_counters.hardlimited; 2113 ioc->ratelimited = pfstlim->pfstlim_counters.ratelimited; 2114 2115 unlock: 2116 PF_RULES_RUNLOCK(); 2117 2118 return (error); 2119 } 2120 2121 int 2122 pf_sourcelim_add(const struct pfioc_sourcelim *ioc) 2123 { 2124 struct pf_sourcelim *pfsrlim; 2125 int error; 2126 size_t namelen, tablelen; 2127 unsigned int prefix; 2128 size_t i; 2129 2130 if (ioc->id < PF_SOURCELIM_ID_MIN || 2131 ioc->id > PF_SOURCELIM_ID_MAX) 2132 return (EINVAL); 2133 2134 if (ioc->entries < 1) 2135 return (EINVAL); 2136 2137 if (ioc->limit < 1) 2138 return (EINVAL); 2139 2140 if ((ioc->rate.limit == 0) != (ioc->rate.seconds == 0)) 2141 return (EINVAL); 2142 2143 if (ioc->inet_prefix > 32) 2144 return (EINVAL); 2145 if (ioc->inet6_prefix > 128) 2146 return (EINVAL); 2147 2148 namelen = strnlen(ioc->name, sizeof(ioc->name)); 2149 /* is the name from userland nul terminated? */ 2150 if (namelen == sizeof(ioc->name)) 2151 return (EINVAL); 2152 2153 tablelen = strnlen(ioc->overload_tblname, 2154 sizeof(ioc->overload_tblname)); 2155 /* is the name from userland nul terminated? */ 2156 if (tablelen == sizeof(ioc->overload_tblname)) 2157 return (EINVAL); 2158 if (tablelen != 0) { 2159 if (ioc->overload_hwm == 0) 2160 return (EINVAL); 2161 2162 if (ioc->overload_hwm < ioc->overload_lwm) 2163 return (EINVAL); 2164 } 2165 2166 pfsrlim = malloc(sizeof(*pfsrlim), M_PF_SOURCE_LIM, M_WAITOK | M_ZERO); 2167 if (pfsrlim == NULL) 2168 return (ENOMEM); 2169 2170 pfsrlim->pfsrlim_id = ioc->id; 2171 pfsrlim->pfsrlim_entries = ioc->entries; 2172 pfsrlim->pfsrlim_limit = ioc->limit; 2173 pfsrlim->pfsrlim_ipv4_prefix = ioc->inet_prefix; 2174 pfsrlim->pfsrlim_ipv6_prefix = ioc->inet6_prefix; 2175 pfsrlim->pfsrlim_rate.limit = ioc->rate.limit; 2176 pfsrlim->pfsrlim_rate.seconds = ioc->rate.seconds; 2177 if (strlcpy(pfsrlim->pfsrlim_overload.name, ioc->overload_tblname, 2178 sizeof(pfsrlim->pfsrlim_overload.name)) >= 2179 sizeof(pfsrlim->pfsrlim_overload.name)) { 2180 error = EINVAL; 2181 goto free; 2182 } 2183 pfsrlim->pfsrlim_overload.hwm = ioc->overload_hwm; 2184 pfsrlim->pfsrlim_overload.lwm = ioc->overload_lwm; 2185 if (strlcpy(pfsrlim->pfsrlim_nm, ioc->name, 2186 sizeof(pfsrlim->pfsrlim_nm)) >= sizeof(pfsrlim->pfsrlim_nm)) { 2187 error = EINVAL; 2188 goto free; 2189 } 2190 2191 if (pfsrlim->pfsrlim_rate.limit) { 2192 uint64_t bucket = pfsrlim->pfsrlim_rate.seconds * 1000000000ULL; 2193 2194 pfsrlim->pfsrlim_rate_token = bucket / 2195 pfsrlim->pfsrlim_rate.limit; 2196 pfsrlim->pfsrlim_rate_bucket = bucket; 2197 } 2198 2199 pfsrlim->pfsrlim_ipv4_mask.v4.s_addr = htonl( 2200 0xffffffff << (32 - pfsrlim->pfsrlim_ipv4_prefix)); 2201 2202 prefix = pfsrlim->pfsrlim_ipv6_prefix; 2203 for (i = 0; i < nitems(pfsrlim->pfsrlim_ipv6_mask.addr32); i++) { 2204 if (prefix == 0) { 2205 /* the memory is already zeroed */ 2206 break; 2207 } 2208 if (prefix < 32) { 2209 pfsrlim->pfsrlim_ipv6_mask.addr32[i] = htonl( 2210 0xffffffff << (32 - prefix)); 2211 break; 2212 } 2213 2214 pfsrlim->pfsrlim_ipv6_mask.addr32[i] = htonl(0xffffffff); 2215 prefix -= 32; 2216 } 2217 2218 RB_INIT(&pfsrlim->pfsrlim_sources); 2219 mtx_init(&pfsrlim->pfsrlim_lock, "pf source limit", NULL, MTX_DEF); 2220 2221 PF_RULES_WLOCK(); 2222 if (ioc->ticket != pf_main_ruleset.rules[PF_RULESET_FILTER].inactive.ticket) { 2223 error = EBUSY; 2224 goto unlock; 2225 } 2226 2227 if (pfsrlim->pfsrlim_overload.name[0] != '\0') { 2228 pfsrlim->pfsrlim_overload.table = pfr_attach_table( 2229 &pf_main_ruleset, pfsrlim->pfsrlim_overload.name); 2230 if (pfsrlim->pfsrlim_overload.table == NULL) { 2231 error = EINVAL; 2232 goto unlock; 2233 } 2234 } 2235 2236 if (RB_INSERT(pf_sourcelim_id_tree, &V_pf_sourcelim_id_tree_inactive, 2237 pfsrlim) != NULL) { 2238 error = EBUSY; 2239 goto unlock; 2240 } 2241 2242 if (RB_INSERT(pf_sourcelim_nm_tree, &V_pf_sourcelim_nm_tree_inactive, 2243 pfsrlim) != NULL) { 2244 RB_REMOVE(pf_sourcelim_id_tree, &V_pf_sourcelim_id_tree_inactive, 2245 pfsrlim); 2246 error = EBUSY; 2247 goto unlock; 2248 } 2249 2250 TAILQ_INSERT_HEAD(&V_pf_sourcelim_list_inactive, pfsrlim, pfsrlim_list); 2251 2252 PF_RULES_WUNLOCK(); 2253 2254 return (0); 2255 2256 unlock: 2257 if (pfsrlim->pfsrlim_overload.table != NULL) 2258 pfr_detach_table(pfsrlim->pfsrlim_overload.table); 2259 PF_RULES_WUNLOCK(); 2260 2261 free: 2262 free(pfsrlim, M_PF_SOURCE_LIM); 2263 2264 return (error); 2265 } 2266 2267 void 2268 pf_sourcelim_rollback(void) 2269 { 2270 struct pf_sourcelim *pfsrlim, *npfsrlim; 2271 2272 PF_RULES_WASSERT(); 2273 2274 TAILQ_FOREACH_SAFE(pfsrlim, &V_pf_sourcelim_list_inactive, pfsrlim_list, 2275 npfsrlim) { 2276 if (pfsrlim->pfsrlim_overload.table != NULL) 2277 pfr_detach_table(pfsrlim->pfsrlim_overload.table); 2278 2279 free(pfsrlim, M_PF_SOURCE_LIM); 2280 } 2281 2282 TAILQ_INIT(&V_pf_sourcelim_list_inactive); 2283 RB_INIT(&V_pf_sourcelim_id_tree_inactive); 2284 RB_INIT(&V_pf_sourcelim_nm_tree_inactive); 2285 } 2286 2287 struct pf_sourcelim * 2288 pf_sourcelim_rb_find(struct pf_sourcelim_id_tree *tree, 2289 struct pf_sourcelim *key) 2290 { 2291 PF_RULES_ASSERT(); 2292 return (RB_FIND(pf_sourcelim_id_tree, tree, key)); 2293 } 2294 2295 struct pf_sourcelim * 2296 pf_sourcelim_rb_nfind(struct pf_sourcelim_id_tree *tree, 2297 struct pf_sourcelim *key) 2298 { 2299 PF_RULES_ASSERT(); 2300 return (RB_NFIND(pf_sourcelim_id_tree, tree, key)); 2301 } 2302 2303 int 2304 pf_sourcelim_get(struct pfioc_sourcelim *ioc, 2305 struct pf_sourcelim *(*rbt_op)(struct pf_sourcelim_id_tree *, 2306 struct pf_sourcelim *)) 2307 { 2308 struct pf_sourcelim key = { .pfsrlim_id = ioc->id }; 2309 struct pf_sourcelim *pfsrlim; 2310 int error = 0; 2311 PF_RULES_RLOCK_TRACKER; 2312 2313 PF_RULES_RLOCK(); 2314 2315 pfsrlim = (*rbt_op)(&V_pf_sourcelim_id_tree_active, &key); 2316 if (pfsrlim == NULL) { 2317 error = ESRCH; 2318 goto unlock; 2319 } 2320 2321 ioc->id = pfsrlim->pfsrlim_id; 2322 ioc->entries = pfsrlim->pfsrlim_entries; 2323 ioc->limit = pfsrlim->pfsrlim_limit; 2324 ioc->inet_prefix = pfsrlim->pfsrlim_ipv4_prefix; 2325 ioc->inet6_prefix = pfsrlim->pfsrlim_ipv6_prefix; 2326 ioc->rate.limit = pfsrlim->pfsrlim_rate.limit; 2327 ioc->rate.seconds = pfsrlim->pfsrlim_rate.seconds; 2328 2329 CTASSERT(sizeof(ioc->overload_tblname) == 2330 sizeof(pfsrlim->pfsrlim_overload.name)); 2331 memcpy(ioc->overload_tblname, pfsrlim->pfsrlim_overload.name, 2332 sizeof(pfsrlim->pfsrlim_overload.name)); 2333 ioc->overload_hwm = pfsrlim->pfsrlim_overload.hwm; 2334 ioc->overload_lwm = pfsrlim->pfsrlim_overload.lwm; 2335 2336 CTASSERT(sizeof(ioc->name) == sizeof(pfsrlim->pfsrlim_nm)); 2337 memcpy(ioc->name, pfsrlim->pfsrlim_nm, sizeof(ioc->name)); 2338 /* XXX overload table thing */ 2339 2340 ioc->nentries = pfsrlim->pfsrlim_nsources; 2341 2342 ioc->inuse = pfsrlim->pfsrlim_counters.inuse; 2343 ioc->addrallocs = pfsrlim->pfsrlim_counters.addrallocs; 2344 ioc->addrnomem = pfsrlim->pfsrlim_counters.addrnomem; 2345 ioc->admitted = pfsrlim->pfsrlim_counters.admitted; 2346 ioc->addrlimited = pfsrlim->pfsrlim_counters.addrlimited; 2347 ioc->hardlimited = pfsrlim->pfsrlim_counters.hardlimited; 2348 ioc->ratelimited = pfsrlim->pfsrlim_counters.ratelimited; 2349 2350 unlock: 2351 PF_RULES_RUNLOCK(); 2352 2353 return (error); 2354 } 2355 2356 struct pf_source * 2357 pf_source_rb_find(struct pf_source_ioc_tree *tree, 2358 struct pf_source *key) 2359 { 2360 PF_RULES_ASSERT(); 2361 2362 return (RB_FIND(pf_source_ioc_tree, tree, key)); 2363 } 2364 2365 struct pf_source * 2366 pf_source_rb_nfind(struct pf_source_ioc_tree *tree, 2367 struct pf_source *key) 2368 { 2369 PF_RULES_ASSERT(); 2370 2371 return (RB_NFIND(pf_source_ioc_tree, tree, key)); 2372 } 2373 2374 int 2375 pf_source_clr(struct pfioc_source_kill *ioc) 2376 { 2377 extern struct pf_source_list pf_source_gc; 2378 struct pf_sourcelim plkey = { 2379 .pfsrlim_id = ioc->id, 2380 }; 2381 struct pf_source skey = { 2382 .pfsr_af = ioc->af, 2383 .pfsr_rdomain = ioc->rdomain, 2384 .pfsr_addr = ioc->addr, 2385 }; 2386 struct pf_sourcelim *pfsrlim; 2387 struct pf_source *pfsr; 2388 struct pf_state_link *pfl, *npfl; 2389 int error = 0; 2390 unsigned int gen; 2391 2392 if (ioc->rmstates) { 2393 /* XXX userland wants the states removed too */ 2394 return (EOPNOTSUPP); 2395 } 2396 2397 PF_RULES_WLOCK(); 2398 2399 pfsrlim = pf_sourcelim_rb_find(&V_pf_sourcelim_id_tree_active, &plkey); 2400 if (pfsrlim == NULL) { 2401 error = ESRCH; 2402 goto unlock; 2403 } 2404 2405 pfsr = pf_source_rb_find(&pfsrlim->pfsrlim_ioc_sources, &skey); 2406 if (pfsr == NULL) { 2407 error = ENOENT; 2408 goto unlock; 2409 } 2410 2411 RB_REMOVE(pf_source_tree, &pfsrlim->pfsrlim_sources, pfsr); 2412 RB_REMOVE(pf_source_ioc_tree, &pfsrlim->pfsrlim_ioc_sources, pfsr); 2413 if (pfsr->pfsr_inuse == 0) 2414 TAILQ_REMOVE(&pf_source_gc, pfsr, pfsr_empty_gc); 2415 2416 gen = pf_sourcelim_enter(pfsrlim); 2417 pfsrlim->pfsrlim_nsources--; 2418 pfsrlim->pfsrlim_counters.inuse -= pfsr->pfsr_inuse; 2419 pf_sourcelim_leave(pfsrlim, gen); 2420 2421 /* unwire the links */ 2422 TAILQ_FOREACH(pfl, &pfsr->pfsr_states, pfl_link) { 2423 struct pf_kstate *st = pfl->pfl_state; 2424 2425 /* if !rmst */ 2426 st->sourcelim = 0; 2427 SLIST_REMOVE(&st->linkage, pfl, pf_state_link, pfl_linkage); 2428 } 2429 2430 PF_RULES_WUNLOCK(); 2431 2432 TAILQ_FOREACH_SAFE(pfl, &pfsr->pfsr_states, pfl_link, npfl) 2433 free(pfl, M_PF_STATE_LINK); 2434 2435 free(pfsr, M_PF_SOURCE_LIM); 2436 2437 return (0); 2438 2439 unlock: 2440 PF_RULES_WUNLOCK(); 2441 2442 return (error); 2443 } 2444 2445 static void 2446 pf_src_node_copy(const struct pf_ksrc_node *in, struct pf_src_node *out) 2447 { 2448 int secs = time_uptime; 2449 2450 bzero(out, sizeof(struct pf_src_node)); 2451 2452 bcopy(&in->addr, &out->addr, sizeof(struct pf_addr)); 2453 bcopy(&in->raddr, &out->raddr, sizeof(struct pf_addr)); 2454 2455 if (in->rule != NULL) 2456 out->rule.nr = in->rule->nr; 2457 2458 for (int i = 0; i < 2; i++) { 2459 out->bytes[i] = counter_u64_fetch(in->bytes[i]); 2460 out->packets[i] = counter_u64_fetch(in->packets[i]); 2461 } 2462 2463 out->states = in->states; 2464 out->conn = in->conn; 2465 out->af = in->af; 2466 out->ruletype = in->ruletype; 2467 2468 out->creation = secs - in->creation; 2469 if (out->expire > secs) 2470 out->expire -= secs; 2471 else 2472 out->expire = 0; 2473 2474 /* Adjust the connection rate estimate. */ 2475 out->conn_rate.limit = in->conn_rate.limit; 2476 out->conn_rate.seconds = in->conn_rate.seconds; 2477 /* If there's no limit there's no counter_rate. */ 2478 if (in->conn_rate.cr != NULL) 2479 out->conn_rate.count = counter_rate_get(in->conn_rate.cr); 2480 } 2481 2482 #ifdef ALTQ 2483 /* 2484 * Handle export of struct pf_kaltq to user binaries that may be using any 2485 * version of struct pf_altq. 2486 */ 2487 static int 2488 pf_export_kaltq(struct pf_altq *q, struct pfioc_altq_v1 *pa, size_t ioc_size) 2489 { 2490 u_int32_t version; 2491 2492 if (ioc_size == sizeof(struct pfioc_altq_v0)) 2493 version = 0; 2494 else 2495 version = pa->version; 2496 2497 if (version > PFIOC_ALTQ_VERSION) 2498 return (EINVAL); 2499 2500 #define ASSIGN(x) exported_q->x = q->x 2501 #define COPY(x) \ 2502 bcopy(&q->x, &exported_q->x, min(sizeof(q->x), sizeof(exported_q->x))) 2503 #define SATU16(x) (u_int32_t)uqmin((x), USHRT_MAX) 2504 #define SATU32(x) (u_int32_t)uqmin((x), UINT_MAX) 2505 2506 switch (version) { 2507 case 0: { 2508 struct pf_altq_v0 *exported_q = 2509 &((struct pfioc_altq_v0 *)pa)->altq; 2510 2511 COPY(ifname); 2512 2513 ASSIGN(scheduler); 2514 ASSIGN(tbrsize); 2515 exported_q->tbrsize = SATU16(q->tbrsize); 2516 exported_q->ifbandwidth = SATU32(q->ifbandwidth); 2517 2518 COPY(qname); 2519 COPY(parent); 2520 ASSIGN(parent_qid); 2521 exported_q->bandwidth = SATU32(q->bandwidth); 2522 ASSIGN(priority); 2523 ASSIGN(local_flags); 2524 2525 ASSIGN(qlimit); 2526 ASSIGN(flags); 2527 2528 if (q->scheduler == ALTQT_HFSC) { 2529 #define ASSIGN_OPT(x) exported_q->pq_u.hfsc_opts.x = q->pq_u.hfsc_opts.x 2530 #define ASSIGN_OPT_SATU32(x) exported_q->pq_u.hfsc_opts.x = \ 2531 SATU32(q->pq_u.hfsc_opts.x) 2532 2533 ASSIGN_OPT_SATU32(rtsc_m1); 2534 ASSIGN_OPT(rtsc_d); 2535 ASSIGN_OPT_SATU32(rtsc_m2); 2536 2537 ASSIGN_OPT_SATU32(lssc_m1); 2538 ASSIGN_OPT(lssc_d); 2539 ASSIGN_OPT_SATU32(lssc_m2); 2540 2541 ASSIGN_OPT_SATU32(ulsc_m1); 2542 ASSIGN_OPT(ulsc_d); 2543 ASSIGN_OPT_SATU32(ulsc_m2); 2544 2545 ASSIGN_OPT(flags); 2546 2547 #undef ASSIGN_OPT 2548 #undef ASSIGN_OPT_SATU32 2549 } else 2550 COPY(pq_u); 2551 2552 ASSIGN(qid); 2553 break; 2554 } 2555 case 1: { 2556 struct pf_altq_v1 *exported_q = 2557 &((struct pfioc_altq_v1 *)pa)->altq; 2558 2559 COPY(ifname); 2560 2561 ASSIGN(scheduler); 2562 ASSIGN(tbrsize); 2563 ASSIGN(ifbandwidth); 2564 2565 COPY(qname); 2566 COPY(parent); 2567 ASSIGN(parent_qid); 2568 ASSIGN(bandwidth); 2569 ASSIGN(priority); 2570 ASSIGN(local_flags); 2571 2572 ASSIGN(qlimit); 2573 ASSIGN(flags); 2574 COPY(pq_u); 2575 2576 ASSIGN(qid); 2577 break; 2578 } 2579 default: 2580 panic("%s: unhandled struct pfioc_altq version", __func__); 2581 break; 2582 } 2583 2584 #undef ASSIGN 2585 #undef COPY 2586 #undef SATU16 2587 #undef SATU32 2588 2589 return (0); 2590 } 2591 2592 /* 2593 * Handle import to struct pf_kaltq of struct pf_altq from user binaries 2594 * that may be using any version of it. 2595 */ 2596 static int 2597 pf_import_kaltq(struct pfioc_altq_v1 *pa, struct pf_altq *q, size_t ioc_size) 2598 { 2599 u_int32_t version; 2600 2601 if (ioc_size == sizeof(struct pfioc_altq_v0)) 2602 version = 0; 2603 else 2604 version = pa->version; 2605 2606 if (version > PFIOC_ALTQ_VERSION) 2607 return (EINVAL); 2608 2609 #define ASSIGN(x) q->x = imported_q->x 2610 #define COPY(x) \ 2611 bcopy(&imported_q->x, &q->x, min(sizeof(imported_q->x), sizeof(q->x))) 2612 2613 switch (version) { 2614 case 0: { 2615 struct pf_altq_v0 *imported_q = 2616 &((struct pfioc_altq_v0 *)pa)->altq; 2617 2618 COPY(ifname); 2619 2620 ASSIGN(scheduler); 2621 ASSIGN(tbrsize); /* 16-bit -> 32-bit */ 2622 ASSIGN(ifbandwidth); /* 32-bit -> 64-bit */ 2623 2624 COPY(qname); 2625 COPY(parent); 2626 ASSIGN(parent_qid); 2627 ASSIGN(bandwidth); /* 32-bit -> 64-bit */ 2628 ASSIGN(priority); 2629 ASSIGN(local_flags); 2630 2631 ASSIGN(qlimit); 2632 ASSIGN(flags); 2633 2634 if (imported_q->scheduler == ALTQT_HFSC) { 2635 #define ASSIGN_OPT(x) q->pq_u.hfsc_opts.x = imported_q->pq_u.hfsc_opts.x 2636 2637 /* 2638 * The m1 and m2 parameters are being copied from 2639 * 32-bit to 64-bit. 2640 */ 2641 ASSIGN_OPT(rtsc_m1); 2642 ASSIGN_OPT(rtsc_d); 2643 ASSIGN_OPT(rtsc_m2); 2644 2645 ASSIGN_OPT(lssc_m1); 2646 ASSIGN_OPT(lssc_d); 2647 ASSIGN_OPT(lssc_m2); 2648 2649 ASSIGN_OPT(ulsc_m1); 2650 ASSIGN_OPT(ulsc_d); 2651 ASSIGN_OPT(ulsc_m2); 2652 2653 ASSIGN_OPT(flags); 2654 2655 #undef ASSIGN_OPT 2656 } else 2657 COPY(pq_u); 2658 2659 ASSIGN(qid); 2660 break; 2661 } 2662 case 1: { 2663 struct pf_altq_v1 *imported_q = 2664 &((struct pfioc_altq_v1 *)pa)->altq; 2665 2666 COPY(ifname); 2667 2668 ASSIGN(scheduler); 2669 ASSIGN(tbrsize); 2670 ASSIGN(ifbandwidth); 2671 2672 COPY(qname); 2673 COPY(parent); 2674 ASSIGN(parent_qid); 2675 ASSIGN(bandwidth); 2676 ASSIGN(priority); 2677 ASSIGN(local_flags); 2678 2679 ASSIGN(qlimit); 2680 ASSIGN(flags); 2681 COPY(pq_u); 2682 2683 ASSIGN(qid); 2684 break; 2685 } 2686 default: 2687 panic("%s: unhandled struct pfioc_altq version", __func__); 2688 break; 2689 } 2690 2691 #undef ASSIGN 2692 #undef COPY 2693 2694 return (0); 2695 } 2696 2697 static struct pf_altq * 2698 pf_altq_get_nth_active(u_int32_t n) 2699 { 2700 struct pf_altq *altq; 2701 u_int32_t nr; 2702 2703 nr = 0; 2704 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) { 2705 if (nr == n) 2706 return (altq); 2707 nr++; 2708 } 2709 2710 TAILQ_FOREACH(altq, V_pf_altqs_active, entries) { 2711 if (nr == n) 2712 return (altq); 2713 nr++; 2714 } 2715 2716 return (NULL); 2717 } 2718 #endif /* ALTQ */ 2719 2720 struct pf_krule * 2721 pf_krule_alloc(void) 2722 { 2723 struct pf_krule *rule; 2724 2725 rule = malloc(sizeof(struct pf_krule), M_PFRULE, M_WAITOK | M_ZERO); 2726 mtx_init(&rule->nat.mtx, "pf_krule_nat_pool", NULL, MTX_DEF); 2727 mtx_init(&rule->rdr.mtx, "pf_krule_rdr_pool", NULL, MTX_DEF); 2728 mtx_init(&rule->route.mtx, "pf_krule_route_pool", NULL, MTX_DEF); 2729 rule->timestamp = uma_zalloc_pcpu(pf_timestamp_pcpu_zone, 2730 M_WAITOK | M_ZERO); 2731 return (rule); 2732 } 2733 2734 void 2735 pf_krule_free(struct pf_krule *rule) 2736 { 2737 #ifdef PF_WANT_32_TO_64_COUNTER 2738 bool wowned; 2739 #endif 2740 2741 if (rule == NULL) 2742 return; 2743 2744 #ifdef PF_WANT_32_TO_64_COUNTER 2745 if (rule->allrulelinked) { 2746 wowned = PF_RULES_WOWNED(); 2747 if (!wowned) 2748 PF_RULES_WLOCK(); 2749 LIST_REMOVE(rule, allrulelist); 2750 V_pf_allrulecount--; 2751 if (!wowned) 2752 PF_RULES_WUNLOCK(); 2753 } 2754 #endif 2755 2756 pf_counter_u64_deinit(&rule->evaluations); 2757 for (int i = 0; i < 2; i++) { 2758 pf_counter_u64_deinit(&rule->packets[i]); 2759 pf_counter_u64_deinit(&rule->bytes[i]); 2760 } 2761 counter_u64_free(rule->states_cur); 2762 counter_u64_free(rule->states_tot); 2763 for (pf_sn_types_t sn_type=0; sn_type<PF_SN_MAX; sn_type++) 2764 counter_u64_free(rule->src_nodes[sn_type]); 2765 counter_rate_free(rule->pktrate.cr); 2766 uma_zfree_pcpu(pf_timestamp_pcpu_zone, rule->timestamp); 2767 2768 mtx_destroy(&rule->nat.mtx); 2769 mtx_destroy(&rule->rdr.mtx); 2770 mtx_destroy(&rule->route.mtx); 2771 free(rule, M_PFRULE); 2772 } 2773 2774 void 2775 pf_krule_clear_counters(struct pf_krule *rule) 2776 { 2777 pf_counter_u64_zero(&rule->evaluations); 2778 for (int i = 0; i < 2; i++) { 2779 pf_counter_u64_zero(&rule->packets[i]); 2780 pf_counter_u64_zero(&rule->bytes[i]); 2781 } 2782 counter_u64_zero(rule->states_tot); 2783 } 2784 2785 static void 2786 pf_kpooladdr_to_pooladdr(const struct pf_kpooladdr *kpool, 2787 struct pf_pooladdr *pool) 2788 { 2789 2790 bzero(pool, sizeof(*pool)); 2791 bcopy(&kpool->addr, &pool->addr, sizeof(pool->addr)); 2792 strlcpy(pool->ifname, kpool->ifname, sizeof(pool->ifname)); 2793 } 2794 2795 static int 2796 pf_pooladdr_to_kpooladdr(const struct pf_pooladdr *pool, 2797 struct pf_kpooladdr *kpool) 2798 { 2799 int ret; 2800 2801 bzero(kpool, sizeof(*kpool)); 2802 bcopy(&pool->addr, &kpool->addr, sizeof(kpool->addr)); 2803 ret = pf_user_strcpy(kpool->ifname, pool->ifname, 2804 sizeof(kpool->ifname)); 2805 return (ret); 2806 } 2807 2808 static void 2809 pf_pool_to_kpool(const struct pf_pool *pool, struct pf_kpool *kpool) 2810 { 2811 _Static_assert(sizeof(pool->key) == sizeof(kpool->key), ""); 2812 _Static_assert(sizeof(pool->counter) == sizeof(kpool->counter), ""); 2813 2814 bcopy(&pool->key, &kpool->key, sizeof(kpool->key)); 2815 bcopy(&pool->counter, &kpool->counter, sizeof(kpool->counter)); 2816 2817 kpool->tblidx = pool->tblidx; 2818 kpool->proxy_port[0] = pool->proxy_port[0]; 2819 kpool->proxy_port[1] = pool->proxy_port[1]; 2820 kpool->opts = pool->opts; 2821 } 2822 2823 static int 2824 pf_rule_to_krule(const struct pf_rule *rule, struct pf_krule *krule) 2825 { 2826 int ret; 2827 2828 #ifndef INET 2829 if (rule->af == AF_INET) { 2830 return (EAFNOSUPPORT); 2831 } 2832 #endif /* INET */ 2833 #ifndef INET6 2834 if (rule->af == AF_INET6) { 2835 return (EAFNOSUPPORT); 2836 } 2837 #endif /* INET6 */ 2838 2839 ret = pf_check_rule_addr(&rule->src); 2840 if (ret != 0) 2841 return (ret); 2842 ret = pf_check_rule_addr(&rule->dst); 2843 if (ret != 0) 2844 return (ret); 2845 2846 bcopy(&rule->src, &krule->src, sizeof(rule->src)); 2847 bcopy(&rule->dst, &krule->dst, sizeof(rule->dst)); 2848 2849 ret = pf_user_strcpy(krule->label[0], rule->label, sizeof(rule->label)); 2850 if (ret != 0) 2851 return (ret); 2852 ret = pf_user_strcpy(krule->ifname, rule->ifname, sizeof(rule->ifname)); 2853 if (ret != 0) 2854 return (ret); 2855 ret = pf_user_strcpy(krule->qname, rule->qname, sizeof(rule->qname)); 2856 if (ret != 0) 2857 return (ret); 2858 ret = pf_user_strcpy(krule->pqname, rule->pqname, sizeof(rule->pqname)); 2859 if (ret != 0) 2860 return (ret); 2861 ret = pf_user_strcpy(krule->tagname, rule->tagname, 2862 sizeof(rule->tagname)); 2863 if (ret != 0) 2864 return (ret); 2865 ret = pf_user_strcpy(krule->match_tagname, rule->match_tagname, 2866 sizeof(rule->match_tagname)); 2867 if (ret != 0) 2868 return (ret); 2869 ret = pf_user_strcpy(krule->overload_tblname, rule->overload_tblname, 2870 sizeof(rule->overload_tblname)); 2871 if (ret != 0) 2872 return (ret); 2873 2874 pf_pool_to_kpool(&rule->rpool, &krule->rdr); 2875 2876 /* Don't allow userspace to set evaluations, packets or bytes. */ 2877 /* kif, anchor, overload_tbl are not copied over. */ 2878 2879 krule->os_fingerprint = rule->os_fingerprint; 2880 2881 krule->rtableid = rule->rtableid; 2882 /* pf_rule->timeout is smaller than pf_krule->timeout */ 2883 bcopy(rule->timeout, krule->timeout, sizeof(rule->timeout)); 2884 krule->max_states = rule->max_states; 2885 krule->max_src_nodes = rule->max_src_nodes; 2886 krule->max_src_states = rule->max_src_states; 2887 krule->max_src_conn = rule->max_src_conn; 2888 krule->max_src_conn_rate.limit = rule->max_src_conn_rate.limit; 2889 krule->max_src_conn_rate.seconds = rule->max_src_conn_rate.seconds; 2890 krule->qid = rule->qid; 2891 krule->pqid = rule->pqid; 2892 krule->nr = rule->nr; 2893 krule->prob = rule->prob; 2894 krule->cuid = rule->cuid; 2895 krule->cpid = rule->cpid; 2896 2897 krule->return_icmp = rule->return_icmp; 2898 krule->return_icmp6 = rule->return_icmp6; 2899 krule->max_mss = rule->max_mss; 2900 krule->tag = rule->tag; 2901 krule->match_tag = rule->match_tag; 2902 krule->scrub_flags = rule->scrub_flags; 2903 2904 bcopy(&rule->uid, &krule->uid, sizeof(krule->uid)); 2905 bcopy(&rule->gid, &krule->gid, sizeof(krule->gid)); 2906 2907 krule->rule_flag = rule->rule_flag; 2908 krule->action = rule->action; 2909 krule->direction = rule->direction; 2910 krule->log = rule->log; 2911 krule->logif = rule->logif; 2912 krule->quick = rule->quick; 2913 krule->ifnot = rule->ifnot; 2914 krule->match_tag_not = rule->match_tag_not; 2915 krule->natpass = rule->natpass; 2916 2917 krule->keep_state = rule->keep_state; 2918 krule->af = rule->af; 2919 krule->proto = rule->proto; 2920 krule->type = rule->type; 2921 krule->code = rule->code; 2922 krule->flags = rule->flags; 2923 krule->flagset = rule->flagset; 2924 krule->min_ttl = rule->min_ttl; 2925 krule->allow_opts = rule->allow_opts; 2926 krule->rt = rule->rt; 2927 krule->return_ttl = rule->return_ttl; 2928 krule->tos = rule->tos; 2929 krule->set_tos = rule->set_tos; 2930 2931 krule->flush = rule->flush; 2932 krule->prio = rule->prio; 2933 krule->set_prio[0] = rule->set_prio[0]; 2934 krule->set_prio[1] = rule->set_prio[1]; 2935 2936 bcopy(&rule->divert, &krule->divert, sizeof(krule->divert)); 2937 2938 return (0); 2939 } 2940 2941 int 2942 pf_ioctl_getrules(struct pfioc_rule *pr) 2943 { 2944 PF_RULES_RLOCK_TRACKER; 2945 struct pf_kruleset *ruleset; 2946 struct pf_krule *tail; 2947 int rs_num; 2948 2949 PF_RULES_RLOCK(); 2950 ruleset = pf_find_kruleset(pr->anchor); 2951 if (ruleset == NULL) { 2952 PF_RULES_RUNLOCK(); 2953 return (EINVAL); 2954 } 2955 rs_num = pf_get_ruleset_number(pr->rule.action); 2956 if (rs_num >= PF_RULESET_MAX) { 2957 PF_RULES_RUNLOCK(); 2958 return (EINVAL); 2959 } 2960 tail = TAILQ_LAST(ruleset->rules[rs_num].active.ptr, 2961 pf_krulequeue); 2962 if (tail) 2963 pr->nr = tail->nr + 1; 2964 else 2965 pr->nr = 0; 2966 pr->ticket = ruleset->rules[rs_num].active.ticket; 2967 PF_RULES_RUNLOCK(); 2968 2969 return (0); 2970 } 2971 2972 static int 2973 pf_rule_checkaf(struct pf_krule *r) 2974 { 2975 switch (r->af) { 2976 case 0: 2977 if (r->rule_flag & PFRULE_AFTO) 2978 return (EPFNOSUPPORT); 2979 break; 2980 case AF_INET: 2981 if ((r->rule_flag & PFRULE_AFTO) && r->naf != AF_INET6) 2982 return (EPFNOSUPPORT); 2983 break; 2984 #ifdef INET6 2985 case AF_INET6: 2986 if ((r->rule_flag & PFRULE_AFTO) && r->naf != AF_INET) 2987 return (EPFNOSUPPORT); 2988 break; 2989 #endif /* INET6 */ 2990 default: 2991 return (EPFNOSUPPORT); 2992 } 2993 2994 if ((r->rule_flag & PFRULE_AFTO) == 0 && r->naf != 0) 2995 return (EPFNOSUPPORT); 2996 2997 return (0); 2998 } 2999 3000 static int 3001 pf_validate_range(uint8_t op, uint16_t port[2]) 3002 { 3003 uint16_t a = ntohs(port[0]); 3004 uint16_t b = ntohs(port[1]); 3005 3006 if ((op == PF_OP_RRG && a > b) || /* 34:12, i.e. none */ 3007 (op == PF_OP_IRG && a >= b) || /* 34><12, i.e. none */ 3008 (op == PF_OP_XRG && a > b)) /* 34<>22, i.e. all */ 3009 return 1; 3010 return 0; 3011 } 3012 3013 static int 3014 pf_chk_limiter_action(int limiter_action) 3015 { 3016 int rv; 3017 3018 switch (limiter_action) { 3019 case PF_LIMITER_NOMATCH: 3020 case PF_LIMITER_BLOCK: 3021 rv = 0; 3022 break; 3023 default: 3024 rv = 1; 3025 } 3026 3027 return (rv); 3028 } 3029 3030 int 3031 pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket, 3032 uint32_t pool_ticket, const char *anchor, const char *anchor_call, 3033 uid_t uid, pid_t pid) 3034 { 3035 struct pf_kruleset *ruleset; 3036 struct pf_krule *tail; 3037 struct pf_kpooladdr *pa; 3038 struct pfi_kkif *kif = NULL, *rcv_kif = NULL; 3039 int rs_num; 3040 int error = 0; 3041 3042 #define ERROUT(x) ERROUT_FUNCTION(errout, x) 3043 #define ERROUT_UNLOCKED(x) ERROUT_FUNCTION(errout_unlocked, x) 3044 3045 if ((rule->return_icmp >> 8) > ICMP_MAXTYPE) 3046 ERROUT_UNLOCKED(EINVAL); 3047 3048 if ((error = pf_rule_checkaf(rule))) 3049 ERROUT_UNLOCKED(error); 3050 if (pf_validate_range(rule->src.port_op, rule->src.port)) 3051 ERROUT_UNLOCKED(EINVAL); 3052 if (pf_validate_range(rule->dst.port_op, rule->dst.port)) 3053 ERROUT_UNLOCKED(EINVAL); 3054 if (pf_chk_limiter_action(rule->statelim.limiter_action) || 3055 pf_chk_limiter_action(rule->sourcelim.limiter_action)) 3056 ERROUT_UNLOCKED(EINVAL); 3057 3058 if (rule->ifname[0]) 3059 kif = pf_kkif_create(M_WAITOK); 3060 if (rule->rcv_ifname[0]) 3061 rcv_kif = pf_kkif_create(M_WAITOK); 3062 pf_counter_u64_init(&rule->evaluations, M_WAITOK); 3063 for (int i = 0; i < 2; i++) { 3064 pf_counter_u64_init(&rule->packets[i], M_WAITOK); 3065 pf_counter_u64_init(&rule->bytes[i], M_WAITOK); 3066 } 3067 rule->states_cur = counter_u64_alloc(M_WAITOK); 3068 rule->states_tot = counter_u64_alloc(M_WAITOK); 3069 for (pf_sn_types_t sn_type=0; sn_type<PF_SN_MAX; sn_type++) 3070 rule->src_nodes[sn_type] = counter_u64_alloc(M_WAITOK); 3071 rule->cuid = uid; 3072 rule->cpid = pid; 3073 TAILQ_INIT(&rule->rdr.list); 3074 TAILQ_INIT(&rule->nat.list); 3075 TAILQ_INIT(&rule->route.list); 3076 3077 PF_CONFIG_LOCK(); 3078 PF_RULES_WLOCK(); 3079 #ifdef PF_WANT_32_TO_64_COUNTER 3080 LIST_INSERT_HEAD(&V_pf_allrulelist, rule, allrulelist); 3081 MPASS(!rule->allrulelinked); 3082 rule->allrulelinked = true; 3083 V_pf_allrulecount++; 3084 #endif 3085 ruleset = pf_find_kruleset(anchor); 3086 if (ruleset == NULL) 3087 ERROUT(EINVAL); 3088 rs_num = pf_get_ruleset_number(rule->action); 3089 if (rs_num >= PF_RULESET_MAX) 3090 ERROUT(EINVAL); 3091 if (ticket != ruleset->rules[rs_num].inactive.ticket) { 3092 DPFPRINTF(PF_DEBUG_MISC, 3093 "ticket: %d != [%d]%d", ticket, rs_num, 3094 ruleset->rules[rs_num].inactive.ticket); 3095 ERROUT(EBUSY); 3096 } 3097 if (pool_ticket != V_ticket_pabuf) { 3098 DPFPRINTF(PF_DEBUG_MISC, 3099 "pool_ticket: %d != %d", pool_ticket, 3100 V_ticket_pabuf); 3101 ERROUT(EBUSY); 3102 } 3103 /* 3104 * XXXMJG hack: there is no mechanism to ensure they started the 3105 * transaction. Ticket checked above may happen to match by accident, 3106 * even if nobody called DIOCXBEGIN, let alone this process. 3107 * Partially work around it by checking if the RB tree got allocated, 3108 * see pf_begin_rules. 3109 */ 3110 if (ruleset->rules[rs_num].inactive.tree == NULL) { 3111 ERROUT(EINVAL); 3112 } 3113 3114 tail = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr, 3115 pf_krulequeue); 3116 if (tail) 3117 rule->nr = tail->nr + 1; 3118 else 3119 rule->nr = 0; 3120 if (rule->ifname[0]) { 3121 rule->kif = pfi_kkif_attach(kif, rule->ifname); 3122 kif = NULL; 3123 pfi_kkif_ref(rule->kif); 3124 } else 3125 rule->kif = NULL; 3126 3127 if (rule->rcv_ifname[0]) { 3128 rule->rcv_kif = pfi_kkif_attach(rcv_kif, rule->rcv_ifname); 3129 rcv_kif = NULL; 3130 pfi_kkif_ref(rule->rcv_kif); 3131 } else 3132 rule->rcv_kif = NULL; 3133 3134 if (rule->rtableid > 0 && rule->rtableid >= rt_numfibs) 3135 ERROUT(EBUSY); 3136 #ifdef ALTQ 3137 /* set queue IDs */ 3138 if (rule->qname[0] != 0) { 3139 if ((rule->qid = pf_qname2qid(rule->qname, true)) == 0) 3140 ERROUT(EBUSY); 3141 else if (rule->pqname[0] != 0) { 3142 if ((rule->pqid = 3143 pf_qname2qid(rule->pqname, true)) == 0) 3144 ERROUT(EBUSY); 3145 } else 3146 rule->pqid = rule->qid; 3147 } 3148 #endif 3149 if (rule->tagname[0]) 3150 if ((rule->tag = pf_tagname2tag(rule->tagname)) == 0) 3151 ERROUT(EBUSY); 3152 if (rule->match_tagname[0]) 3153 if ((rule->match_tag = 3154 pf_tagname2tag(rule->match_tagname)) == 0) 3155 ERROUT(EBUSY); 3156 if (rule->rt && !rule->direction) 3157 ERROUT(EINVAL); 3158 if (!rule->log) 3159 rule->logif = 0; 3160 if (! pf_init_threshold(&rule->pktrate, rule->pktrate.limit, 3161 rule->pktrate.seconds)) 3162 ERROUT(ENOMEM); 3163 if (pf_addr_setup(ruleset, &rule->src.addr, rule->af)) 3164 ERROUT(ENOMEM); 3165 if (pf_addr_setup(ruleset, &rule->dst.addr, rule->af)) 3166 ERROUT(ENOMEM); 3167 if (pf_kanchor_setup(rule, ruleset, anchor_call)) 3168 ERROUT(EINVAL); 3169 if (rule->scrub_flags & PFSTATE_SETPRIO && 3170 (rule->set_prio[0] > PF_PRIO_MAX || 3171 rule->set_prio[1] > PF_PRIO_MAX)) 3172 ERROUT(EINVAL); 3173 for (int i = 0; i < 3; i++) { 3174 TAILQ_FOREACH(pa, &V_pf_pabuf[i], entries) 3175 if (pa->addr.type == PF_ADDR_TABLE) { 3176 pa->addr.p.tbl = pfr_attach_table(ruleset, 3177 pa->addr.v.tblname); 3178 if (pa->addr.p.tbl == NULL) 3179 ERROUT(ENOMEM); 3180 } 3181 } 3182 3183 rule->overload_tbl = NULL; 3184 if (rule->overload_tblname[0]) { 3185 if ((rule->overload_tbl = pfr_attach_table(ruleset, 3186 rule->overload_tblname)) == NULL) 3187 ERROUT(EINVAL); 3188 else 3189 rule->overload_tbl->pfrkt_flags |= 3190 PFR_TFLAG_ACTIVE; 3191 } 3192 3193 pf_mv_kpool(&V_pf_pabuf[0], &rule->nat.list); 3194 3195 /* 3196 * Old version of pfctl provide route redirection pools in single 3197 * common redirection pool rdr. New versions use rdr only for 3198 * rdr-to rules. 3199 */ 3200 if (rule->rt > PF_NOPFROUTE && TAILQ_EMPTY(&V_pf_pabuf[2])) { 3201 pf_mv_kpool(&V_pf_pabuf[1], &rule->route.list); 3202 } else { 3203 pf_mv_kpool(&V_pf_pabuf[1], &rule->rdr.list); 3204 pf_mv_kpool(&V_pf_pabuf[2], &rule->route.list); 3205 } 3206 3207 if (((rule->action == PF_NAT) || (rule->action == PF_RDR) || 3208 (rule->action == PF_BINAT)) && rule->anchor == NULL && 3209 TAILQ_FIRST(&rule->rdr.list) == NULL) { 3210 ERROUT(EINVAL); 3211 } 3212 3213 if (rule->rt > PF_NOPFROUTE && (TAILQ_FIRST(&rule->route.list) == NULL)) { 3214 ERROUT(EINVAL); 3215 } 3216 3217 if (rule->action == PF_PASS && (rule->rdr.opts & PF_POOL_STICKYADDR || 3218 rule->nat.opts & PF_POOL_STICKYADDR) && !rule->keep_state) { 3219 ERROUT(EINVAL); 3220 } 3221 3222 MPASS(error == 0); 3223 3224 rule->nat.cur = TAILQ_FIRST(&rule->nat.list); 3225 rule->rdr.cur = TAILQ_FIRST(&rule->rdr.list); 3226 rule->route.cur = TAILQ_FIRST(&rule->route.list); 3227 rule->route.ipv6_nexthop_af = AF_INET6; 3228 TAILQ_INSERT_TAIL(ruleset->rules[rs_num].inactive.ptr, 3229 rule, entries); 3230 ruleset->rules[rs_num].inactive.rcount++; 3231 3232 PF_RULES_WUNLOCK(); 3233 pf_hash_rule(rule); 3234 /** 3235 * Note: rule hashes may collide. Accept this, because the worst that can 3236 * happen is that we get counter preservation wrong. 3237 * Failing to insert here would be worse. 3238 **/ 3239 RB_INSERT(pf_krule_global, ruleset->rules[rs_num].inactive.tree, rule); 3240 PF_CONFIG_UNLOCK(); 3241 3242 return (0); 3243 3244 #undef ERROUT 3245 #undef ERROUT_UNLOCKED 3246 errout: 3247 PF_RULES_WUNLOCK(); 3248 PF_CONFIG_UNLOCK(); 3249 errout_unlocked: 3250 pf_kkif_free(rcv_kif); 3251 pf_kkif_free(kif); 3252 pf_krule_free(rule); 3253 return (error); 3254 } 3255 3256 static bool 3257 pf_label_match(const struct pf_krule *rule, const char *label) 3258 { 3259 int i = 0; 3260 3261 while (*rule->label[i]) { 3262 if (strcmp(rule->label[i], label) == 0) 3263 return (true); 3264 i++; 3265 } 3266 3267 return (false); 3268 } 3269 3270 static unsigned int 3271 pf_kill_matching_state(struct pf_state_key_cmp *key, int dir) 3272 { 3273 struct pf_kstate *s; 3274 int more = 0; 3275 3276 s = pf_find_state_all(key, dir, &more); 3277 if (s == NULL) 3278 return (0); 3279 3280 if (more) { 3281 PF_STATE_UNLOCK(s); 3282 return (0); 3283 } 3284 3285 pf_remove_state(s); 3286 return (1); 3287 } 3288 3289 static int 3290 pf_killstates_row(struct pf_kstate_kill *psk, struct pf_idhash *ih) 3291 { 3292 struct pf_kstate *s; 3293 struct pf_state_key *sk; 3294 struct pf_addr *srcaddr, *dstaddr; 3295 struct pf_state_key_cmp match_key; 3296 int idx, killed = 0; 3297 unsigned int dir; 3298 u_int16_t srcport, dstport; 3299 struct pfi_kkif *kif; 3300 3301 relock_DIOCKILLSTATES: 3302 PF_HASHROW_LOCK(ih); 3303 LIST_FOREACH(s, &ih->states, entry) { 3304 /* For floating states look at the original kif. */ 3305 kif = s->kif == V_pfi_all ? s->orig_kif : s->kif; 3306 3307 sk = s->key[psk->psk_nat ? PF_SK_STACK : PF_SK_WIRE]; 3308 if (s->direction == PF_OUT) { 3309 srcaddr = &sk->addr[1]; 3310 dstaddr = &sk->addr[0]; 3311 srcport = sk->port[1]; 3312 dstport = sk->port[0]; 3313 } else { 3314 srcaddr = &sk->addr[0]; 3315 dstaddr = &sk->addr[1]; 3316 srcport = sk->port[0]; 3317 dstport = sk->port[1]; 3318 } 3319 3320 if (psk->psk_af && sk->af != psk->psk_af) 3321 continue; 3322 3323 if (psk->psk_proto && psk->psk_proto != sk->proto) 3324 continue; 3325 3326 if (! pf_match_addr(psk->psk_src.neg, 3327 &psk->psk_src.addr.v.a.addr, 3328 &psk->psk_src.addr.v.a.mask, srcaddr, sk->af)) 3329 continue; 3330 3331 if (! pf_match_addr(psk->psk_dst.neg, 3332 &psk->psk_dst.addr.v.a.addr, 3333 &psk->psk_dst.addr.v.a.mask, dstaddr, sk->af)) 3334 continue; 3335 3336 if (! pf_match_addr(psk->psk_rt_addr.neg, 3337 &psk->psk_rt_addr.addr.v.a.addr, 3338 &psk->psk_rt_addr.addr.v.a.mask, 3339 &s->act.rt_addr, sk->af)) 3340 continue; 3341 3342 if (psk->psk_src.port_op != 0 && 3343 ! pf_match_port(psk->psk_src.port_op, 3344 psk->psk_src.port[0], psk->psk_src.port[1], srcport)) 3345 continue; 3346 3347 if (psk->psk_dst.port_op != 0 && 3348 ! pf_match_port(psk->psk_dst.port_op, 3349 psk->psk_dst.port[0], psk->psk_dst.port[1], dstport)) 3350 continue; 3351 3352 if (psk->psk_label[0] && 3353 ! pf_label_match(s->rule, psk->psk_label)) 3354 continue; 3355 3356 if (psk->psk_ifname[0] && strcmp(psk->psk_ifname, 3357 kif->pfik_name)) 3358 continue; 3359 3360 if (psk->psk_kill_match) { 3361 /* Create the key to find matching states, with lock 3362 * held. */ 3363 3364 bzero(&match_key, sizeof(match_key)); 3365 3366 if (s->direction == PF_OUT) { 3367 dir = PF_IN; 3368 idx = psk->psk_nat ? PF_SK_WIRE : PF_SK_STACK; 3369 } else { 3370 dir = PF_OUT; 3371 idx = psk->psk_nat ? PF_SK_STACK : PF_SK_WIRE; 3372 } 3373 3374 match_key.af = s->key[idx]->af; 3375 match_key.proto = s->key[idx]->proto; 3376 pf_addrcpy(&match_key.addr[0], 3377 &s->key[idx]->addr[1], match_key.af); 3378 match_key.port[0] = s->key[idx]->port[1]; 3379 pf_addrcpy(&match_key.addr[1], 3380 &s->key[idx]->addr[0], match_key.af); 3381 match_key.port[1] = s->key[idx]->port[0]; 3382 } 3383 3384 pf_remove_state(s); 3385 killed++; 3386 3387 if (psk->psk_kill_match) 3388 killed += pf_kill_matching_state(&match_key, dir); 3389 3390 goto relock_DIOCKILLSTATES; 3391 } 3392 PF_HASHROW_UNLOCK(ih); 3393 3394 return (killed); 3395 } 3396 3397 int 3398 pf_start(void) 3399 { 3400 int error = 0; 3401 3402 sx_xlock(&V_pf_ioctl_lock); 3403 if (V_pf_status.running) 3404 error = EEXIST; 3405 else { 3406 hook_pf(); 3407 if (! TAILQ_EMPTY(V_pf_keth->active.rules)) 3408 hook_pf_eth(); 3409 V_pf_status.running = 1; 3410 V_pf_status.since = time_uptime; 3411 new_unrhdr64(&V_pf_stateid, time_second); 3412 3413 DPFPRINTF(PF_DEBUG_MISC, "pf: started"); 3414 } 3415 sx_xunlock(&V_pf_ioctl_lock); 3416 3417 return (error); 3418 } 3419 3420 int 3421 pf_stop(void) 3422 { 3423 int error = 0; 3424 3425 sx_xlock(&V_pf_ioctl_lock); 3426 if (!V_pf_status.running) 3427 error = ENOENT; 3428 else { 3429 V_pf_status.running = 0; 3430 dehook_pf(); 3431 dehook_pf_eth(); 3432 V_pf_status.since = time_uptime; 3433 DPFPRINTF(PF_DEBUG_MISC, "pf: stopped"); 3434 } 3435 sx_xunlock(&V_pf_ioctl_lock); 3436 3437 return (error); 3438 } 3439 3440 void 3441 pf_ioctl_clear_status(void) 3442 { 3443 PF_RULES_WLOCK(); 3444 for (int i = 0; i < PFRES_MAX; i++) 3445 counter_u64_zero(V_pf_status.counters[i]); 3446 for (int i = 0; i < FCNT_MAX; i++) 3447 pf_counter_u64_zero(&V_pf_status.fcounters[i]); 3448 for (int i = 0; i < SCNT_MAX; i++) 3449 counter_u64_zero(V_pf_status.scounters[i]); 3450 for (int i = 0; i < NCNT_MAX; i++) 3451 counter_u64_zero(V_pf_status.ncounters[i]); 3452 for (int i = 0; i < KLCNT_MAX; i++) 3453 counter_u64_zero(V_pf_status.lcounters[i]); 3454 V_pf_status.since = time_uptime; 3455 if (*V_pf_status.ifname) 3456 pfi_update_status(V_pf_status.ifname, NULL); 3457 PF_RULES_WUNLOCK(); 3458 } 3459 3460 int 3461 pf_ioctl_set_timeout(int timeout, int seconds, int *prev_seconds) 3462 { 3463 uint32_t old; 3464 3465 if (timeout < 0 || timeout >= PFTM_MAX || 3466 seconds < 0) 3467 return (EINVAL); 3468 3469 PF_RULES_WLOCK(); 3470 old = V_pf_default_rule.timeout[timeout]; 3471 if (timeout == PFTM_INTERVAL && seconds == 0) 3472 seconds = 1; 3473 V_pf_default_rule.timeout[timeout] = seconds; 3474 if (timeout == PFTM_INTERVAL && seconds < old) 3475 wakeup(pf_purge_thread); 3476 3477 if (prev_seconds != NULL) 3478 *prev_seconds = old; 3479 3480 PF_RULES_WUNLOCK(); 3481 3482 return (0); 3483 } 3484 3485 int 3486 pf_ioctl_get_timeout(int timeout, int *seconds) 3487 { 3488 PF_RULES_RLOCK_TRACKER; 3489 3490 if (timeout < 0 || timeout >= PFTM_MAX) 3491 return (EINVAL); 3492 3493 PF_RULES_RLOCK(); 3494 *seconds = V_pf_default_rule.timeout[timeout]; 3495 PF_RULES_RUNLOCK(); 3496 3497 return (0); 3498 } 3499 3500 int 3501 pf_ioctl_set_limit(int index, unsigned int limit, unsigned int *old_limit) 3502 { 3503 3504 PF_RULES_WLOCK(); 3505 if (index < 0 || index >= PF_LIMIT_MAX || 3506 V_pf_limits[index].zone == NULL) { 3507 PF_RULES_WUNLOCK(); 3508 return (EINVAL); 3509 } 3510 uma_zone_set_max(V_pf_limits[index].zone, 3511 limit == 0 ? INT_MAX : limit); 3512 if (old_limit != NULL) 3513 *old_limit = V_pf_limits[index].limit; 3514 V_pf_limits[index].limit = limit; 3515 PF_RULES_WUNLOCK(); 3516 3517 return (0); 3518 } 3519 3520 int 3521 pf_ioctl_get_limit(int index, unsigned int *limit) 3522 { 3523 PF_RULES_RLOCK_TRACKER; 3524 3525 if (index < 0 || index >= PF_LIMIT_MAX) 3526 return (EINVAL); 3527 3528 PF_RULES_RLOCK(); 3529 *limit = V_pf_limits[index].limit; 3530 PF_RULES_RUNLOCK(); 3531 3532 return (0); 3533 } 3534 3535 int 3536 pf_ioctl_begin_addrs(uint32_t *ticket) 3537 { 3538 PF_RULES_WLOCK(); 3539 pf_empty_kpool(&V_pf_pabuf[0]); 3540 pf_empty_kpool(&V_pf_pabuf[1]); 3541 pf_empty_kpool(&V_pf_pabuf[2]); 3542 *ticket = ++V_ticket_pabuf; 3543 PF_RULES_WUNLOCK(); 3544 3545 return (0); 3546 } 3547 3548 int 3549 pf_ioctl_add_addr(struct pf_nl_pooladdr *pp) 3550 { 3551 struct pf_kpooladdr *pa = NULL; 3552 struct pfi_kkif *kif = NULL; 3553 int error; 3554 3555 if (pp->which != PF_RDR && pp->which != PF_NAT && 3556 pp->which != PF_RT) 3557 return (EINVAL); 3558 3559 switch (pp->af) { 3560 #ifdef INET 3561 case AF_INET: 3562 /* FALLTHROUGH */ 3563 #endif /* INET */ 3564 #ifdef INET6 3565 case AF_INET6: 3566 /* FALLTHROUGH */ 3567 #endif /* INET6 */ 3568 case AF_UNSPEC: 3569 break; 3570 default: 3571 return (EAFNOSUPPORT); 3572 } 3573 3574 if (pp->addr.addr.type != PF_ADDR_ADDRMASK && 3575 pp->addr.addr.type != PF_ADDR_DYNIFTL && 3576 pp->addr.addr.type != PF_ADDR_TABLE) 3577 return (EINVAL); 3578 3579 if (pp->addr.addr.p.dyn != NULL) 3580 return (EINVAL); 3581 3582 pa = malloc(sizeof(*pa), M_PFRULE, M_WAITOK); 3583 error = pf_pooladdr_to_kpooladdr(&pp->addr, pa); 3584 if (error != 0) 3585 goto out; 3586 if (pa->ifname[0]) 3587 kif = pf_kkif_create(M_WAITOK); 3588 PF_RULES_WLOCK(); 3589 if (pp->ticket != V_ticket_pabuf) { 3590 PF_RULES_WUNLOCK(); 3591 if (pa->ifname[0]) 3592 pf_kkif_free(kif); 3593 error = EBUSY; 3594 goto out; 3595 } 3596 if (pa->ifname[0]) { 3597 pa->kif = pfi_kkif_attach(kif, pa->ifname); 3598 kif = NULL; 3599 pfi_kkif_ref(pa->kif); 3600 } else 3601 pa->kif = NULL; 3602 if (pa->addr.type == PF_ADDR_DYNIFTL && ((error = 3603 pfi_dynaddr_setup(&pa->addr, pp->af)) != 0)) { 3604 if (pa->ifname[0]) 3605 pfi_kkif_unref(pa->kif); 3606 PF_RULES_WUNLOCK(); 3607 goto out; 3608 } 3609 pa->af = pp->af; 3610 switch (pp->which) { 3611 case PF_NAT: 3612 TAILQ_INSERT_TAIL(&V_pf_pabuf[0], pa, entries); 3613 break; 3614 case PF_RDR: 3615 TAILQ_INSERT_TAIL(&V_pf_pabuf[1], pa, entries); 3616 break; 3617 case PF_RT: 3618 TAILQ_INSERT_TAIL(&V_pf_pabuf[2], pa, entries); 3619 break; 3620 } 3621 PF_RULES_WUNLOCK(); 3622 3623 return (0); 3624 3625 out: 3626 free(pa, M_PFRULE); 3627 return (error); 3628 } 3629 3630 int 3631 pf_ioctl_get_addrs(struct pf_nl_pooladdr *pp) 3632 { 3633 struct pf_kpool *pool; 3634 struct pf_kpooladdr *pa; 3635 3636 PF_RULES_RLOCK_TRACKER; 3637 3638 if (pp->which != PF_RDR && pp->which != PF_NAT && 3639 pp->which != PF_RT) 3640 return (EINVAL); 3641 3642 pp->anchor[sizeof(pp->anchor) - 1] = 0; 3643 pp->nr = 0; 3644 3645 PF_RULES_RLOCK(); 3646 pool = pf_get_kpool(pp->anchor, pp->ticket, pp->r_action, 3647 pp->r_num, 0, 1, 0, pp->which); 3648 if (pool == NULL) { 3649 PF_RULES_RUNLOCK(); 3650 return (EBUSY); 3651 } 3652 TAILQ_FOREACH(pa, &pool->list, entries) 3653 pp->nr++; 3654 PF_RULES_RUNLOCK(); 3655 3656 return (0); 3657 } 3658 3659 int 3660 pf_ioctl_get_addr(struct pf_nl_pooladdr *pp) 3661 { 3662 struct pf_kpool *pool; 3663 struct pf_kpooladdr *pa; 3664 u_int32_t nr = 0; 3665 3666 if (pp->which != PF_RDR && pp->which != PF_NAT && 3667 pp->which != PF_RT) 3668 return (EINVAL); 3669 3670 PF_RULES_RLOCK_TRACKER; 3671 3672 pp->anchor[sizeof(pp->anchor) - 1] = '\0'; 3673 3674 PF_RULES_RLOCK(); 3675 pool = pf_get_kpool(pp->anchor, pp->ticket, pp->r_action, 3676 pp->r_num, 0, 1, 1, pp->which); 3677 if (pool == NULL) { 3678 PF_RULES_RUNLOCK(); 3679 return (EBUSY); 3680 } 3681 pa = TAILQ_FIRST(&pool->list); 3682 while ((pa != NULL) && (nr < pp->nr)) { 3683 pa = TAILQ_NEXT(pa, entries); 3684 nr++; 3685 } 3686 if (pa == NULL) { 3687 PF_RULES_RUNLOCK(); 3688 return (EBUSY); 3689 } 3690 pf_kpooladdr_to_pooladdr(pa, &pp->addr); 3691 pp->af = pa->af; 3692 pf_addr_copyout(&pp->addr.addr); 3693 PF_RULES_RUNLOCK(); 3694 3695 return (0); 3696 } 3697 3698 int 3699 pf_ioctl_get_rulesets(struct pfioc_ruleset *pr) 3700 { 3701 struct pf_kruleset *ruleset; 3702 struct pf_kanchor *anchor; 3703 3704 PF_RULES_RLOCK_TRACKER; 3705 3706 pr->path[sizeof(pr->path) - 1] = '\0'; 3707 3708 PF_RULES_RLOCK(); 3709 if ((ruleset = pf_find_kruleset(pr->path)) == NULL) { 3710 PF_RULES_RUNLOCK(); 3711 return (ENOENT); 3712 } 3713 pr->nr = 0; 3714 if (ruleset == &pf_main_ruleset) { 3715 /* XXX kludge for pf_main_ruleset */ 3716 RB_FOREACH(anchor, pf_kanchor_global, &V_pf_anchors) 3717 if (anchor->parent == NULL) 3718 pr->nr++; 3719 } else { 3720 RB_FOREACH(anchor, pf_kanchor_node, 3721 &ruleset->anchor->children) 3722 pr->nr++; 3723 } 3724 PF_RULES_RUNLOCK(); 3725 3726 return (0); 3727 } 3728 3729 int 3730 pf_ioctl_get_ruleset(struct pfioc_ruleset *pr) 3731 { 3732 struct pf_kruleset *ruleset; 3733 struct pf_kanchor *anchor; 3734 u_int32_t nr = 0; 3735 int error = 0; 3736 3737 PF_RULES_RLOCK_TRACKER; 3738 3739 PF_RULES_RLOCK(); 3740 if ((ruleset = pf_find_kruleset(pr->path)) == NULL) { 3741 PF_RULES_RUNLOCK(); 3742 return (ENOENT); 3743 } 3744 3745 pr->name[0] = '\0'; 3746 if (ruleset == &pf_main_ruleset) { 3747 /* XXX kludge for pf_main_ruleset */ 3748 RB_FOREACH(anchor, pf_kanchor_global, &V_pf_anchors) 3749 if (anchor->parent == NULL && nr++ == pr->nr) { 3750 strlcpy(pr->name, anchor->name, 3751 sizeof(pr->name)); 3752 break; 3753 } 3754 } else { 3755 RB_FOREACH(anchor, pf_kanchor_node, 3756 &ruleset->anchor->children) 3757 if (nr++ == pr->nr) { 3758 strlcpy(pr->name, anchor->name, 3759 sizeof(pr->name)); 3760 break; 3761 } 3762 } 3763 if (!pr->name[0]) 3764 error = EBUSY; 3765 PF_RULES_RUNLOCK(); 3766 3767 return (error); 3768 } 3769 3770 int 3771 pf_ioctl_natlook(struct pfioc_natlook *pnl) 3772 { 3773 struct pf_state_key *sk; 3774 struct pf_kstate *state; 3775 struct pf_state_key_cmp key; 3776 int m = 0, direction = pnl->direction; 3777 int sidx, didx; 3778 3779 /* NATLOOK src and dst are reversed, so reverse sidx/didx */ 3780 sidx = (direction == PF_IN) ? 1 : 0; 3781 didx = (direction == PF_IN) ? 0 : 1; 3782 3783 if (!pnl->proto || 3784 PF_AZERO(&pnl->saddr, pnl->af) || 3785 PF_AZERO(&pnl->daddr, pnl->af) || 3786 ((pnl->proto == IPPROTO_TCP || 3787 pnl->proto == IPPROTO_UDP) && 3788 (!pnl->dport || !pnl->sport))) 3789 return (EINVAL); 3790 3791 switch (pnl->direction) { 3792 case PF_IN: 3793 case PF_OUT: 3794 case PF_INOUT: 3795 break; 3796 default: 3797 return (EINVAL); 3798 } 3799 3800 switch (pnl->af) { 3801 #ifdef INET 3802 case AF_INET: 3803 break; 3804 #endif /* INET */ 3805 #ifdef INET6 3806 case AF_INET6: 3807 break; 3808 #endif /* INET6 */ 3809 default: 3810 return (EAFNOSUPPORT); 3811 } 3812 3813 bzero(&key, sizeof(key)); 3814 key.af = pnl->af; 3815 key.proto = pnl->proto; 3816 pf_addrcpy(&key.addr[sidx], &pnl->saddr, pnl->af); 3817 key.port[sidx] = pnl->sport; 3818 pf_addrcpy(&key.addr[didx], &pnl->daddr, pnl->af); 3819 key.port[didx] = pnl->dport; 3820 3821 state = pf_find_state_all(&key, direction, &m); 3822 if (state == NULL) 3823 return (ENOENT); 3824 3825 if (m > 1) { 3826 PF_STATE_UNLOCK(state); 3827 return (E2BIG); /* more than one state */ 3828 } 3829 3830 sk = state->key[sidx]; 3831 pf_addrcpy(&pnl->rsaddr, 3832 &sk->addr[sidx], sk->af); 3833 pnl->rsport = sk->port[sidx]; 3834 pf_addrcpy(&pnl->rdaddr, 3835 &sk->addr[didx], sk->af); 3836 pnl->rdport = sk->port[didx]; 3837 PF_STATE_UNLOCK(state); 3838 3839 return (0); 3840 } 3841 3842 static int 3843 pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td) 3844 { 3845 int error = 0; 3846 PF_RULES_RLOCK_TRACKER; 3847 3848 #define ERROUT_IOCTL(target, x) \ 3849 do { \ 3850 error = (x); \ 3851 SDT_PROBE3(pf, ioctl, ioctl, error, cmd, error, __LINE__); \ 3852 goto target; \ 3853 } while (0) 3854 3855 3856 /* XXX keep in sync with switch() below */ 3857 if (securelevel_gt(td->td_ucred, 2)) 3858 switch (cmd) { 3859 case DIOCGETRULES: 3860 case DIOCGETRULENV: 3861 case DIOCGETADDRS: 3862 case DIOCGETADDR: 3863 case DIOCGETSTATE: 3864 case DIOCGETSTATENV: 3865 case DIOCSETSTATUSIF: 3866 case DIOCGETSTATUSNV: 3867 case DIOCCLRSTATUS: 3868 case DIOCNATLOOK: 3869 case DIOCSETDEBUG: 3870 #ifdef COMPAT_FREEBSD14 3871 case DIOCGETSTATES: 3872 case DIOCGETSTATESV2: 3873 #endif 3874 case DIOCGETTIMEOUT: 3875 case DIOCCLRRULECTRS: 3876 case DIOCGETLIMIT: 3877 case DIOCGETALTQSV0: 3878 case DIOCGETALTQSV1: 3879 case DIOCGETALTQV0: 3880 case DIOCGETALTQV1: 3881 case DIOCGETQSTATSV0: 3882 case DIOCGETQSTATSV1: 3883 case DIOCGETRULESETS: 3884 case DIOCGETRULESET: 3885 case DIOCRGETTABLES: 3886 case DIOCRGETTSTATS: 3887 case DIOCRCLRTSTATS: 3888 case DIOCRCLRADDRS: 3889 case DIOCRADDADDRS: 3890 case DIOCRDELADDRS: 3891 case DIOCRSETADDRS: 3892 case DIOCRGETADDRS: 3893 case DIOCRGETASTATS: 3894 case DIOCRCLRASTATS: 3895 case DIOCRTSTADDRS: 3896 case DIOCOSFPGET: 3897 case DIOCGETSRCNODES: 3898 case DIOCCLRSRCNODES: 3899 case DIOCGETSYNCOOKIES: 3900 case DIOCIGETIFACES: 3901 case DIOCGIFSPEEDV0: 3902 case DIOCGIFSPEEDV1: 3903 case DIOCGETETHRULES: 3904 case DIOCGETETHRULE: 3905 case DIOCGETETHRULESETS: 3906 case DIOCGETETHRULESET: 3907 break; 3908 case DIOCRCLRTABLES: 3909 case DIOCRADDTABLES: 3910 case DIOCRDELTABLES: 3911 case DIOCRSETTFLAGS: 3912 if (((struct pfioc_table *)addr)->pfrio_flags & 3913 PFR_FLAG_DUMMY) 3914 break; /* dummy operation ok */ 3915 return (EPERM); 3916 default: 3917 return (EPERM); 3918 } 3919 3920 if (!(flags & FWRITE)) 3921 switch (cmd) { 3922 case DIOCGETRULES: 3923 case DIOCGETADDRS: 3924 case DIOCGETADDR: 3925 case DIOCGETSTATE: 3926 case DIOCGETSTATENV: 3927 case DIOCGETSTATUSNV: 3928 #ifdef COMPAT_FREEBSD14 3929 case DIOCGETSTATES: 3930 case DIOCGETSTATESV2: 3931 #endif 3932 case DIOCGETTIMEOUT: 3933 case DIOCGETLIMIT: 3934 case DIOCGETALTQSV0: 3935 case DIOCGETALTQSV1: 3936 case DIOCGETALTQV0: 3937 case DIOCGETALTQV1: 3938 case DIOCGETQSTATSV0: 3939 case DIOCGETQSTATSV1: 3940 case DIOCGETRULESETS: 3941 case DIOCGETRULESET: 3942 case DIOCNATLOOK: 3943 case DIOCRGETTABLES: 3944 case DIOCRGETTSTATS: 3945 case DIOCRGETADDRS: 3946 case DIOCRGETASTATS: 3947 case DIOCRTSTADDRS: 3948 case DIOCOSFPGET: 3949 case DIOCGETSRCNODES: 3950 case DIOCGETSYNCOOKIES: 3951 case DIOCIGETIFACES: 3952 case DIOCGIFSPEEDV1: 3953 case DIOCGIFSPEEDV0: 3954 case DIOCGETRULENV: 3955 case DIOCGETETHRULES: 3956 case DIOCGETETHRULE: 3957 case DIOCGETETHRULESETS: 3958 case DIOCGETETHRULESET: 3959 break; 3960 case DIOCRCLRTABLES: 3961 case DIOCRADDTABLES: 3962 case DIOCRDELTABLES: 3963 case DIOCRCLRTSTATS: 3964 case DIOCRCLRADDRS: 3965 case DIOCRADDADDRS: 3966 case DIOCRDELADDRS: 3967 case DIOCRSETADDRS: 3968 case DIOCRSETTFLAGS: 3969 if (((struct pfioc_table *)addr)->pfrio_flags & 3970 PFR_FLAG_DUMMY) { 3971 flags |= FWRITE; /* need write lock for dummy */ 3972 break; /* dummy operation ok */ 3973 } 3974 return (EACCES); 3975 default: 3976 return (EACCES); 3977 } 3978 3979 CURVNET_SET(TD_TO_VNET(td)); 3980 3981 switch (cmd) { 3982 #ifdef COMPAT_FREEBSD14 3983 case DIOCSTART: 3984 error = pf_start(); 3985 break; 3986 3987 case DIOCSTOP: 3988 error = pf_stop(); 3989 break; 3990 #endif 3991 3992 case DIOCGETETHRULES: { 3993 struct pfioc_nv *nv = (struct pfioc_nv *)addr; 3994 nvlist_t *nvl; 3995 void *packed; 3996 struct pf_keth_rule *tail; 3997 struct pf_keth_ruleset *rs; 3998 u_int32_t ticket, nr; 3999 const char *anchor = ""; 4000 4001 nvl = NULL; 4002 packed = NULL; 4003 4004 #define ERROUT(x) ERROUT_IOCTL(DIOCGETETHRULES_error, x) 4005 4006 if (nv->len > pf_ioctl_maxcount) 4007 ERROUT(ENOMEM); 4008 4009 /* Copy the request in */ 4010 packed = malloc(nv->len, M_NVLIST, M_WAITOK); 4011 error = copyin(nv->data, packed, nv->len); 4012 if (error) 4013 ERROUT(error); 4014 4015 nvl = nvlist_unpack(packed, nv->len, 0); 4016 if (nvl == NULL) 4017 ERROUT(EBADMSG); 4018 4019 if (! nvlist_exists_string(nvl, "anchor")) 4020 ERROUT(EBADMSG); 4021 4022 anchor = nvlist_get_string(nvl, "anchor"); 4023 4024 rs = pf_find_keth_ruleset(anchor); 4025 4026 nvlist_destroy(nvl); 4027 nvl = NULL; 4028 free(packed, M_NVLIST); 4029 packed = NULL; 4030 4031 if (rs == NULL) 4032 ERROUT(ENOENT); 4033 4034 /* Reply */ 4035 nvl = nvlist_create(0); 4036 if (nvl == NULL) 4037 ERROUT(ENOMEM); 4038 4039 PF_RULES_RLOCK(); 4040 4041 ticket = rs->active.ticket; 4042 tail = TAILQ_LAST(rs->active.rules, pf_keth_ruleq); 4043 if (tail) 4044 nr = tail->nr + 1; 4045 else 4046 nr = 0; 4047 4048 PF_RULES_RUNLOCK(); 4049 4050 nvlist_add_number(nvl, "ticket", ticket); 4051 nvlist_add_number(nvl, "nr", nr); 4052 4053 packed = nvlist_pack(nvl, &nv->len); 4054 if (packed == NULL) 4055 ERROUT(ENOMEM); 4056 4057 if (nv->size == 0) 4058 ERROUT(0); 4059 else if (nv->size < nv->len) 4060 ERROUT(ENOSPC); 4061 4062 error = copyout(packed, nv->data, nv->len); 4063 4064 #undef ERROUT 4065 DIOCGETETHRULES_error: 4066 free(packed, M_NVLIST); 4067 nvlist_destroy(nvl); 4068 break; 4069 } 4070 4071 case DIOCGETETHRULE: { 4072 struct epoch_tracker et; 4073 struct pfioc_nv *nv = (struct pfioc_nv *)addr; 4074 nvlist_t *nvl = NULL; 4075 void *nvlpacked = NULL; 4076 struct pf_keth_rule *rule = NULL; 4077 struct pf_keth_ruleset *rs; 4078 u_int32_t ticket, nr; 4079 bool clear = false; 4080 const char *anchor; 4081 4082 #define ERROUT(x) ERROUT_IOCTL(DIOCGETETHRULE_error, x) 4083 4084 if (nv->len > pf_ioctl_maxcount) 4085 ERROUT(ENOMEM); 4086 4087 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK); 4088 error = copyin(nv->data, nvlpacked, nv->len); 4089 if (error) 4090 ERROUT(error); 4091 4092 nvl = nvlist_unpack(nvlpacked, nv->len, 0); 4093 if (nvl == NULL) 4094 ERROUT(EBADMSG); 4095 if (! nvlist_exists_number(nvl, "ticket")) 4096 ERROUT(EBADMSG); 4097 ticket = nvlist_get_number(nvl, "ticket"); 4098 if (! nvlist_exists_string(nvl, "anchor")) 4099 ERROUT(EBADMSG); 4100 anchor = nvlist_get_string(nvl, "anchor"); 4101 4102 if (nvlist_exists_bool(nvl, "clear")) 4103 clear = nvlist_get_bool(nvl, "clear"); 4104 4105 if (clear && !(flags & FWRITE)) 4106 ERROUT(EACCES); 4107 4108 if (! nvlist_exists_number(nvl, "nr")) 4109 ERROUT(EBADMSG); 4110 nr = nvlist_get_number(nvl, "nr"); 4111 4112 PF_RULES_RLOCK(); 4113 rs = pf_find_keth_ruleset(anchor); 4114 if (rs == NULL) { 4115 PF_RULES_RUNLOCK(); 4116 ERROUT(ENOENT); 4117 } 4118 if (ticket != rs->active.ticket) { 4119 PF_RULES_RUNLOCK(); 4120 ERROUT(EBUSY); 4121 } 4122 4123 nvlist_destroy(nvl); 4124 nvl = NULL; 4125 free(nvlpacked, M_NVLIST); 4126 nvlpacked = NULL; 4127 4128 rule = TAILQ_FIRST(rs->active.rules); 4129 while ((rule != NULL) && (rule->nr != nr)) 4130 rule = TAILQ_NEXT(rule, entries); 4131 if (rule == NULL) { 4132 PF_RULES_RUNLOCK(); 4133 ERROUT(ENOENT); 4134 } 4135 /* Make sure rule can't go away. */ 4136 NET_EPOCH_ENTER(et); 4137 PF_RULES_RUNLOCK(); 4138 nvl = pf_keth_rule_to_nveth_rule(rule); 4139 if (pf_keth_anchor_nvcopyout(rs, rule, nvl)) { 4140 NET_EPOCH_EXIT(et); 4141 ERROUT(EBUSY); 4142 } 4143 NET_EPOCH_EXIT(et); 4144 if (nvl == NULL) 4145 ERROUT(ENOMEM); 4146 4147 nvlpacked = nvlist_pack(nvl, &nv->len); 4148 if (nvlpacked == NULL) 4149 ERROUT(ENOMEM); 4150 4151 if (nv->size == 0) 4152 ERROUT(0); 4153 else if (nv->size < nv->len) 4154 ERROUT(ENOSPC); 4155 4156 error = copyout(nvlpacked, nv->data, nv->len); 4157 if (error == 0 && clear) { 4158 counter_u64_zero(rule->evaluations); 4159 for (int i = 0; i < 2; i++) { 4160 counter_u64_zero(rule->packets[i]); 4161 counter_u64_zero(rule->bytes[i]); 4162 } 4163 } 4164 4165 #undef ERROUT 4166 DIOCGETETHRULE_error: 4167 free(nvlpacked, M_NVLIST); 4168 nvlist_destroy(nvl); 4169 break; 4170 } 4171 4172 case DIOCADDETHRULE: { 4173 struct pfioc_nv *nv = (struct pfioc_nv *)addr; 4174 nvlist_t *nvl = NULL; 4175 void *nvlpacked = NULL; 4176 struct pf_keth_rule *rule = NULL, *tail = NULL; 4177 struct pf_keth_ruleset *ruleset = NULL; 4178 struct pfi_kkif *kif = NULL, *bridge_to_kif = NULL; 4179 const char *anchor = "", *anchor_call = ""; 4180 4181 #define ERROUT(x) ERROUT_IOCTL(DIOCADDETHRULE_error, x) 4182 4183 if (nv->len > pf_ioctl_maxcount) 4184 ERROUT(ENOMEM); 4185 4186 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK); 4187 error = copyin(nv->data, nvlpacked, nv->len); 4188 if (error) 4189 ERROUT(error); 4190 4191 nvl = nvlist_unpack(nvlpacked, nv->len, 0); 4192 if (nvl == NULL) 4193 ERROUT(EBADMSG); 4194 4195 if (! nvlist_exists_number(nvl, "ticket")) 4196 ERROUT(EBADMSG); 4197 4198 if (nvlist_exists_string(nvl, "anchor")) 4199 anchor = nvlist_get_string(nvl, "anchor"); 4200 if (nvlist_exists_string(nvl, "anchor_call")) 4201 anchor_call = nvlist_get_string(nvl, "anchor_call"); 4202 4203 ruleset = pf_find_keth_ruleset(anchor); 4204 if (ruleset == NULL) 4205 ERROUT(EINVAL); 4206 4207 if (nvlist_get_number(nvl, "ticket") != 4208 ruleset->inactive.ticket) { 4209 DPFPRINTF(PF_DEBUG_MISC, 4210 "ticket: %d != %d", 4211 (u_int32_t)nvlist_get_number(nvl, "ticket"), 4212 ruleset->inactive.ticket); 4213 ERROUT(EBUSY); 4214 } 4215 4216 rule = malloc(sizeof(*rule), M_PFRULE, M_WAITOK); 4217 rule->timestamp = NULL; 4218 4219 error = pf_nveth_rule_to_keth_rule(nvl, rule); 4220 if (error != 0) 4221 ERROUT(error); 4222 4223 if (rule->ifname[0]) 4224 kif = pf_kkif_create(M_WAITOK); 4225 if (rule->bridge_to_name[0]) 4226 bridge_to_kif = pf_kkif_create(M_WAITOK); 4227 rule->evaluations = counter_u64_alloc(M_WAITOK); 4228 for (int i = 0; i < 2; i++) { 4229 rule->packets[i] = counter_u64_alloc(M_WAITOK); 4230 rule->bytes[i] = counter_u64_alloc(M_WAITOK); 4231 } 4232 rule->timestamp = uma_zalloc_pcpu(pf_timestamp_pcpu_zone, 4233 M_WAITOK | M_ZERO); 4234 4235 PF_RULES_WLOCK(); 4236 4237 if (rule->ifname[0]) { 4238 rule->kif = pfi_kkif_attach(kif, rule->ifname); 4239 pfi_kkif_ref(rule->kif); 4240 } else 4241 rule->kif = NULL; 4242 if (rule->bridge_to_name[0]) { 4243 rule->bridge_to = pfi_kkif_attach(bridge_to_kif, 4244 rule->bridge_to_name); 4245 pfi_kkif_ref(rule->bridge_to); 4246 } else 4247 rule->bridge_to = NULL; 4248 4249 #ifdef ALTQ 4250 /* set queue IDs */ 4251 if (rule->qname[0] != 0) { 4252 if ((rule->qid = pf_qname2qid(rule->qname, true)) == 0) 4253 error = EBUSY; 4254 else 4255 rule->qid = rule->qid; 4256 } 4257 #endif 4258 if (rule->tagname[0]) 4259 if ((rule->tag = pf_tagname2tag(rule->tagname)) == 0) 4260 error = EBUSY; 4261 if (rule->match_tagname[0]) 4262 if ((rule->match_tag = pf_tagname2tag( 4263 rule->match_tagname)) == 0) 4264 error = EBUSY; 4265 4266 if (error == 0 && rule->ipdst.addr.type == PF_ADDR_TABLE) 4267 error = pf_eth_addr_setup(ruleset, &rule->ipdst.addr); 4268 if (error == 0 && rule->ipsrc.addr.type == PF_ADDR_TABLE) 4269 error = pf_eth_addr_setup(ruleset, &rule->ipsrc.addr); 4270 4271 if (error) { 4272 pf_free_eth_rule(rule); 4273 PF_RULES_WUNLOCK(); 4274 ERROUT(error); 4275 } 4276 4277 if (pf_keth_anchor_setup(rule, ruleset, anchor_call)) { 4278 pf_free_eth_rule(rule); 4279 PF_RULES_WUNLOCK(); 4280 ERROUT(EINVAL); 4281 } 4282 4283 tail = TAILQ_LAST(ruleset->inactive.rules, pf_keth_ruleq); 4284 if (tail) 4285 rule->nr = tail->nr + 1; 4286 else 4287 rule->nr = 0; 4288 4289 TAILQ_INSERT_TAIL(ruleset->inactive.rules, rule, entries); 4290 4291 PF_RULES_WUNLOCK(); 4292 4293 #undef ERROUT 4294 DIOCADDETHRULE_error: 4295 nvlist_destroy(nvl); 4296 free(nvlpacked, M_NVLIST); 4297 break; 4298 } 4299 4300 case DIOCGETETHRULESETS: { 4301 struct epoch_tracker et; 4302 struct pfioc_nv *nv = (struct pfioc_nv *)addr; 4303 nvlist_t *nvl = NULL; 4304 void *nvlpacked = NULL; 4305 struct pf_keth_ruleset *ruleset; 4306 struct pf_keth_anchor *anchor; 4307 int nr = 0; 4308 4309 #define ERROUT(x) ERROUT_IOCTL(DIOCGETETHRULESETS_error, x) 4310 4311 if (nv->len > pf_ioctl_maxcount) 4312 ERROUT(ENOMEM); 4313 4314 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK); 4315 error = copyin(nv->data, nvlpacked, nv->len); 4316 if (error) 4317 ERROUT(error); 4318 4319 nvl = nvlist_unpack(nvlpacked, nv->len, 0); 4320 if (nvl == NULL) 4321 ERROUT(EBADMSG); 4322 if (! nvlist_exists_string(nvl, "path")) 4323 ERROUT(EBADMSG); 4324 4325 NET_EPOCH_ENTER(et); 4326 4327 if ((ruleset = pf_find_keth_ruleset( 4328 nvlist_get_string(nvl, "path"))) == NULL) { 4329 NET_EPOCH_EXIT(et); 4330 ERROUT(ENOENT); 4331 } 4332 4333 if (ruleset->anchor == NULL) { 4334 RB_FOREACH(anchor, pf_keth_anchor_global, &V_pf_keth_anchors) 4335 if (anchor->parent == NULL) 4336 nr++; 4337 } else { 4338 RB_FOREACH(anchor, pf_keth_anchor_node, 4339 &ruleset->anchor->children) 4340 nr++; 4341 } 4342 4343 NET_EPOCH_EXIT(et); 4344 4345 nvlist_destroy(nvl); 4346 nvl = NULL; 4347 free(nvlpacked, M_NVLIST); 4348 nvlpacked = NULL; 4349 4350 nvl = nvlist_create(0); 4351 if (nvl == NULL) 4352 ERROUT(ENOMEM); 4353 4354 nvlist_add_number(nvl, "nr", nr); 4355 4356 nvlpacked = nvlist_pack(nvl, &nv->len); 4357 if (nvlpacked == NULL) 4358 ERROUT(ENOMEM); 4359 4360 if (nv->size == 0) 4361 ERROUT(0); 4362 else if (nv->size < nv->len) 4363 ERROUT(ENOSPC); 4364 4365 error = copyout(nvlpacked, nv->data, nv->len); 4366 4367 #undef ERROUT 4368 DIOCGETETHRULESETS_error: 4369 free(nvlpacked, M_NVLIST); 4370 nvlist_destroy(nvl); 4371 break; 4372 } 4373 4374 case DIOCGETETHRULESET: { 4375 struct epoch_tracker et; 4376 struct pfioc_nv *nv = (struct pfioc_nv *)addr; 4377 nvlist_t *nvl = NULL; 4378 void *nvlpacked = NULL; 4379 struct pf_keth_ruleset *ruleset; 4380 struct pf_keth_anchor *anchor; 4381 int nr = 0, req_nr = 0; 4382 bool found = false; 4383 4384 #define ERROUT(x) ERROUT_IOCTL(DIOCGETETHRULESET_error, x) 4385 4386 if (nv->len > pf_ioctl_maxcount) 4387 ERROUT(ENOMEM); 4388 4389 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK); 4390 error = copyin(nv->data, nvlpacked, nv->len); 4391 if (error) 4392 ERROUT(error); 4393 4394 nvl = nvlist_unpack(nvlpacked, nv->len, 0); 4395 if (nvl == NULL) 4396 ERROUT(EBADMSG); 4397 if (! nvlist_exists_string(nvl, "path")) 4398 ERROUT(EBADMSG); 4399 if (! nvlist_exists_number(nvl, "nr")) 4400 ERROUT(EBADMSG); 4401 4402 req_nr = nvlist_get_number(nvl, "nr"); 4403 4404 NET_EPOCH_ENTER(et); 4405 4406 if ((ruleset = pf_find_keth_ruleset( 4407 nvlist_get_string(nvl, "path"))) == NULL) { 4408 NET_EPOCH_EXIT(et); 4409 ERROUT(ENOENT); 4410 } 4411 4412 nvlist_destroy(nvl); 4413 nvl = NULL; 4414 free(nvlpacked, M_NVLIST); 4415 nvlpacked = NULL; 4416 4417 nvl = nvlist_create(0); 4418 if (nvl == NULL) { 4419 NET_EPOCH_EXIT(et); 4420 ERROUT(ENOMEM); 4421 } 4422 4423 if (ruleset->anchor == NULL) { 4424 RB_FOREACH(anchor, pf_keth_anchor_global, 4425 &V_pf_keth_anchors) { 4426 if (anchor->parent == NULL && nr++ == req_nr) { 4427 found = true; 4428 break; 4429 } 4430 } 4431 } else { 4432 RB_FOREACH(anchor, pf_keth_anchor_node, 4433 &ruleset->anchor->children) { 4434 if (nr++ == req_nr) { 4435 found = true; 4436 break; 4437 } 4438 } 4439 } 4440 4441 NET_EPOCH_EXIT(et); 4442 if (found) { 4443 nvlist_add_number(nvl, "nr", nr); 4444 nvlist_add_string(nvl, "name", anchor->name); 4445 if (ruleset->anchor) 4446 nvlist_add_string(nvl, "path", 4447 ruleset->anchor->path); 4448 else 4449 nvlist_add_string(nvl, "path", ""); 4450 } else { 4451 ERROUT(EBUSY); 4452 } 4453 4454 nvlpacked = nvlist_pack(nvl, &nv->len); 4455 if (nvlpacked == NULL) 4456 ERROUT(ENOMEM); 4457 4458 if (nv->size == 0) 4459 ERROUT(0); 4460 else if (nv->size < nv->len) 4461 ERROUT(ENOSPC); 4462 4463 error = copyout(nvlpacked, nv->data, nv->len); 4464 4465 #undef ERROUT 4466 DIOCGETETHRULESET_error: 4467 free(nvlpacked, M_NVLIST); 4468 nvlist_destroy(nvl); 4469 break; 4470 } 4471 4472 case DIOCADDRULENV: { 4473 struct pfioc_nv *nv = (struct pfioc_nv *)addr; 4474 nvlist_t *nvl = NULL; 4475 void *nvlpacked = NULL; 4476 struct pf_krule *rule = NULL; 4477 const char *anchor = "", *anchor_call = ""; 4478 uint32_t ticket = 0, pool_ticket = 0; 4479 4480 #define ERROUT(x) ERROUT_IOCTL(DIOCADDRULENV_error, x) 4481 4482 if (nv->len > pf_ioctl_maxcount) 4483 ERROUT(ENOMEM); 4484 4485 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK); 4486 error = copyin(nv->data, nvlpacked, nv->len); 4487 if (error) 4488 ERROUT(error); 4489 4490 nvl = nvlist_unpack(nvlpacked, nv->len, 0); 4491 if (nvl == NULL) 4492 ERROUT(EBADMSG); 4493 4494 if (! nvlist_exists_number(nvl, "ticket")) 4495 ERROUT(EINVAL); 4496 ticket = nvlist_get_number(nvl, "ticket"); 4497 4498 if (! nvlist_exists_number(nvl, "pool_ticket")) 4499 ERROUT(EINVAL); 4500 pool_ticket = nvlist_get_number(nvl, "pool_ticket"); 4501 4502 if (! nvlist_exists_nvlist(nvl, "rule")) 4503 ERROUT(EINVAL); 4504 4505 rule = pf_krule_alloc(); 4506 error = pf_nvrule_to_krule(nvlist_get_nvlist(nvl, "rule"), 4507 rule); 4508 if (error) 4509 ERROUT(error); 4510 4511 if (nvlist_exists_string(nvl, "anchor")) 4512 anchor = nvlist_get_string(nvl, "anchor"); 4513 if (nvlist_exists_string(nvl, "anchor_call")) 4514 anchor_call = nvlist_get_string(nvl, "anchor_call"); 4515 4516 if ((error = nvlist_error(nvl))) 4517 ERROUT(error); 4518 4519 /* Frees rule on error */ 4520 error = pf_ioctl_addrule(rule, ticket, pool_ticket, anchor, 4521 anchor_call, td->td_ucred->cr_ruid, 4522 td->td_proc ? td->td_proc->p_pid : 0); 4523 4524 nvlist_destroy(nvl); 4525 free(nvlpacked, M_NVLIST); 4526 break; 4527 #undef ERROUT 4528 DIOCADDRULENV_error: 4529 pf_krule_free(rule); 4530 nvlist_destroy(nvl); 4531 free(nvlpacked, M_NVLIST); 4532 4533 break; 4534 } 4535 case DIOCADDRULE: { 4536 struct pfioc_rule *pr = (struct pfioc_rule *)addr; 4537 struct pf_krule *rule; 4538 4539 rule = pf_krule_alloc(); 4540 error = pf_rule_to_krule(&pr->rule, rule); 4541 if (error != 0) { 4542 pf_krule_free(rule); 4543 goto fail; 4544 } 4545 4546 pr->anchor[sizeof(pr->anchor) - 1] = '\0'; 4547 4548 /* Frees rule on error */ 4549 error = pf_ioctl_addrule(rule, pr->ticket, pr->pool_ticket, 4550 pr->anchor, pr->anchor_call, td->td_ucred->cr_ruid, 4551 td->td_proc ? td->td_proc->p_pid : 0); 4552 break; 4553 } 4554 4555 case DIOCGETRULES: { 4556 struct pfioc_rule *pr = (struct pfioc_rule *)addr; 4557 4558 pr->anchor[sizeof(pr->anchor) - 1] = '\0'; 4559 4560 error = pf_ioctl_getrules(pr); 4561 4562 break; 4563 } 4564 4565 case DIOCGETRULENV: { 4566 PF_RULES_RLOCK_TRACKER; 4567 struct pfioc_nv *nv = (struct pfioc_nv *)addr; 4568 nvlist_t *nvrule = NULL; 4569 nvlist_t *nvl = NULL; 4570 struct pf_kruleset *ruleset; 4571 struct pf_krule *rule; 4572 void *nvlpacked = NULL; 4573 int rs_num, nr; 4574 bool clear_counter = false; 4575 4576 #define ERROUT(x) ERROUT_IOCTL(DIOCGETRULENV_error, x) 4577 #define ERROUT_LOCKED(x) do { \ 4578 if (clear_counter) \ 4579 PF_RULES_WUNLOCK(); \ 4580 else \ 4581 PF_RULES_RUNLOCK(); \ 4582 ERROUT(x); \ 4583 } while (0) 4584 4585 if (nv->len > pf_ioctl_maxcount) 4586 ERROUT(ENOMEM); 4587 4588 /* Copy the request in */ 4589 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK); 4590 error = copyin(nv->data, nvlpacked, nv->len); 4591 if (error) 4592 ERROUT(error); 4593 4594 nvl = nvlist_unpack(nvlpacked, nv->len, 0); 4595 if (nvl == NULL) 4596 ERROUT(EBADMSG); 4597 4598 if (! nvlist_exists_string(nvl, "anchor")) 4599 ERROUT(EBADMSG); 4600 if (! nvlist_exists_number(nvl, "ruleset")) 4601 ERROUT(EBADMSG); 4602 if (! nvlist_exists_number(nvl, "ticket")) 4603 ERROUT(EBADMSG); 4604 if (! nvlist_exists_number(nvl, "nr")) 4605 ERROUT(EBADMSG); 4606 4607 if (nvlist_exists_bool(nvl, "clear_counter")) 4608 clear_counter = nvlist_get_bool(nvl, "clear_counter"); 4609 4610 if (clear_counter && !(flags & FWRITE)) 4611 ERROUT(EACCES); 4612 4613 nr = nvlist_get_number(nvl, "nr"); 4614 4615 if (clear_counter) 4616 PF_RULES_WLOCK(); 4617 else 4618 PF_RULES_RLOCK(); 4619 ruleset = pf_find_kruleset(nvlist_get_string(nvl, "anchor")); 4620 if (ruleset == NULL) 4621 ERROUT_LOCKED(ENOENT); 4622 4623 rs_num = pf_get_ruleset_number(nvlist_get_number(nvl, "ruleset")); 4624 if (rs_num >= PF_RULESET_MAX) 4625 ERROUT_LOCKED(EINVAL); 4626 4627 if (nvlist_get_number(nvl, "ticket") != 4628 ruleset->rules[rs_num].active.ticket) 4629 ERROUT_LOCKED(EBUSY); 4630 4631 if ((error = nvlist_error(nvl))) 4632 ERROUT_LOCKED(error); 4633 4634 rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr); 4635 while ((rule != NULL) && (rule->nr != nr)) 4636 rule = TAILQ_NEXT(rule, entries); 4637 if (rule == NULL) 4638 ERROUT_LOCKED(EBUSY); 4639 4640 nvrule = pf_krule_to_nvrule(rule); 4641 4642 nvlist_destroy(nvl); 4643 nvl = nvlist_create(0); 4644 if (nvl == NULL) 4645 ERROUT_LOCKED(ENOMEM); 4646 nvlist_add_number(nvl, "nr", nr); 4647 nvlist_add_nvlist(nvl, "rule", nvrule); 4648 nvlist_destroy(nvrule); 4649 nvrule = NULL; 4650 if (pf_kanchor_nvcopyout(ruleset, rule, nvl)) 4651 ERROUT_LOCKED(EBUSY); 4652 4653 free(nvlpacked, M_NVLIST); 4654 nvlpacked = nvlist_pack(nvl, &nv->len); 4655 if (nvlpacked == NULL) 4656 ERROUT_LOCKED(ENOMEM); 4657 4658 if (nv->size == 0) 4659 ERROUT_LOCKED(0); 4660 else if (nv->size < nv->len) 4661 ERROUT_LOCKED(ENOSPC); 4662 4663 if (clear_counter) { 4664 pf_krule_clear_counters(rule); 4665 PF_RULES_WUNLOCK(); 4666 } else { 4667 PF_RULES_RUNLOCK(); 4668 } 4669 4670 error = copyout(nvlpacked, nv->data, nv->len); 4671 4672 #undef ERROUT_LOCKED 4673 #undef ERROUT 4674 DIOCGETRULENV_error: 4675 free(nvlpacked, M_NVLIST); 4676 nvlist_destroy(nvrule); 4677 nvlist_destroy(nvl); 4678 4679 break; 4680 } 4681 4682 case DIOCCHANGERULE: { 4683 struct pfioc_rule *pcr = (struct pfioc_rule *)addr; 4684 struct pf_kruleset *ruleset; 4685 struct pf_krule *oldrule = NULL, *newrule = NULL; 4686 struct pfi_kkif *kif = NULL; 4687 struct pf_kpooladdr *pa; 4688 u_int32_t nr = 0; 4689 int rs_num; 4690 4691 pcr->anchor[sizeof(pcr->anchor) - 1] = '\0'; 4692 4693 if (pcr->action < PF_CHANGE_ADD_HEAD || 4694 pcr->action > PF_CHANGE_GET_TICKET) { 4695 error = EINVAL; 4696 goto fail; 4697 } 4698 if (pcr->rule.return_icmp >> 8 > ICMP_MAXTYPE) { 4699 error = EINVAL; 4700 goto fail; 4701 } 4702 4703 if (pcr->action != PF_CHANGE_REMOVE) { 4704 newrule = pf_krule_alloc(); 4705 error = pf_rule_to_krule(&pcr->rule, newrule); 4706 if (error != 0) { 4707 pf_krule_free(newrule); 4708 goto fail; 4709 } 4710 4711 if ((error = pf_rule_checkaf(newrule))) { 4712 pf_krule_free(newrule); 4713 goto fail; 4714 } 4715 if (newrule->ifname[0]) 4716 kif = pf_kkif_create(M_WAITOK); 4717 pf_counter_u64_init(&newrule->evaluations, M_WAITOK); 4718 for (int i = 0; i < 2; i++) { 4719 pf_counter_u64_init(&newrule->packets[i], M_WAITOK); 4720 pf_counter_u64_init(&newrule->bytes[i], M_WAITOK); 4721 } 4722 newrule->states_cur = counter_u64_alloc(M_WAITOK); 4723 newrule->states_tot = counter_u64_alloc(M_WAITOK); 4724 for (pf_sn_types_t sn_type=0; sn_type<PF_SN_MAX; sn_type++) 4725 newrule->src_nodes[sn_type] = counter_u64_alloc(M_WAITOK); 4726 newrule->cuid = td->td_ucred->cr_ruid; 4727 newrule->cpid = td->td_proc ? td->td_proc->p_pid : 0; 4728 TAILQ_INIT(&newrule->nat.list); 4729 TAILQ_INIT(&newrule->rdr.list); 4730 TAILQ_INIT(&newrule->route.list); 4731 } 4732 #define ERROUT(x) ERROUT_IOCTL(DIOCCHANGERULE_error, x) 4733 4734 PF_CONFIG_LOCK(); 4735 PF_RULES_WLOCK(); 4736 #ifdef PF_WANT_32_TO_64_COUNTER 4737 if (newrule != NULL) { 4738 LIST_INSERT_HEAD(&V_pf_allrulelist, newrule, allrulelist); 4739 newrule->allrulelinked = true; 4740 V_pf_allrulecount++; 4741 } 4742 #endif 4743 4744 if (!(pcr->action == PF_CHANGE_REMOVE || 4745 pcr->action == PF_CHANGE_GET_TICKET) && 4746 pcr->pool_ticket != V_ticket_pabuf) 4747 ERROUT(EBUSY); 4748 4749 ruleset = pf_find_kruleset(pcr->anchor); 4750 if (ruleset == NULL) 4751 ERROUT(EINVAL); 4752 4753 rs_num = pf_get_ruleset_number(pcr->rule.action); 4754 if (rs_num >= PF_RULESET_MAX) 4755 ERROUT(EINVAL); 4756 4757 /* 4758 * XXXMJG: there is no guarantee that the ruleset was 4759 * created by the usual route of calling DIOCXBEGIN. 4760 * As a result it is possible the rule tree will not 4761 * be allocated yet. Hack around it by doing it here. 4762 * Note it is fine to let the tree persist in case of 4763 * error as it will be freed down the road on future 4764 * updates (if need be). 4765 */ 4766 if (ruleset->rules[rs_num].active.tree == NULL) { 4767 ruleset->rules[rs_num].active.tree = pf_rule_tree_alloc(M_NOWAIT); 4768 if (ruleset->rules[rs_num].active.tree == NULL) { 4769 ERROUT(ENOMEM); 4770 } 4771 } 4772 4773 if (pcr->action == PF_CHANGE_GET_TICKET) { 4774 pcr->ticket = ++ruleset->rules[rs_num].active.ticket; 4775 ERROUT(0); 4776 } else if (pcr->ticket != 4777 ruleset->rules[rs_num].active.ticket) 4778 ERROUT(EINVAL); 4779 4780 if (pcr->action != PF_CHANGE_REMOVE) { 4781 if (newrule->ifname[0]) { 4782 newrule->kif = pfi_kkif_attach(kif, 4783 newrule->ifname); 4784 kif = NULL; 4785 pfi_kkif_ref(newrule->kif); 4786 } else 4787 newrule->kif = NULL; 4788 4789 if (newrule->rtableid > 0 && 4790 newrule->rtableid >= rt_numfibs) 4791 error = EBUSY; 4792 4793 #ifdef ALTQ 4794 /* set queue IDs */ 4795 if (newrule->qname[0] != 0) { 4796 if ((newrule->qid = 4797 pf_qname2qid(newrule->qname, true)) == 0) 4798 error = EBUSY; 4799 else if (newrule->pqname[0] != 0) { 4800 if ((newrule->pqid = 4801 pf_qname2qid(newrule->pqname, true)) == 0) 4802 error = EBUSY; 4803 } else 4804 newrule->pqid = newrule->qid; 4805 } 4806 #endif /* ALTQ */ 4807 if (newrule->tagname[0]) 4808 if ((newrule->tag = 4809 pf_tagname2tag(newrule->tagname)) == 0) 4810 error = EBUSY; 4811 if (newrule->match_tagname[0]) 4812 if ((newrule->match_tag = pf_tagname2tag( 4813 newrule->match_tagname)) == 0) 4814 error = EBUSY; 4815 if (newrule->rt && !newrule->direction) 4816 error = EINVAL; 4817 if (!newrule->log) 4818 newrule->logif = 0; 4819 if (pf_addr_setup(ruleset, &newrule->src.addr, newrule->af)) 4820 error = ENOMEM; 4821 if (pf_addr_setup(ruleset, &newrule->dst.addr, newrule->af)) 4822 error = ENOMEM; 4823 if (pf_kanchor_setup(newrule, ruleset, pcr->anchor_call)) 4824 error = EINVAL; 4825 for (int i = 0; i < 3; i++) { 4826 TAILQ_FOREACH(pa, &V_pf_pabuf[i], entries) 4827 if (pa->addr.type == PF_ADDR_TABLE) { 4828 pa->addr.p.tbl = 4829 pfr_attach_table(ruleset, 4830 pa->addr.v.tblname); 4831 if (pa->addr.p.tbl == NULL) 4832 error = ENOMEM; 4833 } 4834 } 4835 4836 newrule->overload_tbl = NULL; 4837 if (newrule->overload_tblname[0]) { 4838 if ((newrule->overload_tbl = pfr_attach_table( 4839 ruleset, newrule->overload_tblname)) == 4840 NULL) 4841 error = EINVAL; 4842 else 4843 newrule->overload_tbl->pfrkt_flags |= 4844 PFR_TFLAG_ACTIVE; 4845 } 4846 4847 pf_mv_kpool(&V_pf_pabuf[0], &newrule->nat.list); 4848 pf_mv_kpool(&V_pf_pabuf[1], &newrule->rdr.list); 4849 pf_mv_kpool(&V_pf_pabuf[2], &newrule->route.list); 4850 if (((((newrule->action == PF_NAT) || 4851 (newrule->action == PF_RDR) || 4852 (newrule->action == PF_BINAT) || 4853 (newrule->rt > PF_NOPFROUTE)) && 4854 !newrule->anchor)) && 4855 (TAILQ_FIRST(&newrule->rdr.list) == NULL)) 4856 error = EINVAL; 4857 4858 if (error) { 4859 pf_free_rule(newrule); 4860 PF_RULES_WUNLOCK(); 4861 PF_CONFIG_UNLOCK(); 4862 goto fail; 4863 } 4864 4865 newrule->nat.cur = TAILQ_FIRST(&newrule->nat.list); 4866 newrule->rdr.cur = TAILQ_FIRST(&newrule->rdr.list); 4867 } 4868 pf_empty_kpool(&V_pf_pabuf[0]); 4869 pf_empty_kpool(&V_pf_pabuf[1]); 4870 pf_empty_kpool(&V_pf_pabuf[2]); 4871 4872 if (pcr->action == PF_CHANGE_ADD_HEAD) 4873 oldrule = TAILQ_FIRST( 4874 ruleset->rules[rs_num].active.ptr); 4875 else if (pcr->action == PF_CHANGE_ADD_TAIL) 4876 oldrule = TAILQ_LAST( 4877 ruleset->rules[rs_num].active.ptr, pf_krulequeue); 4878 else { 4879 oldrule = TAILQ_FIRST( 4880 ruleset->rules[rs_num].active.ptr); 4881 while ((oldrule != NULL) && (oldrule->nr != pcr->nr)) 4882 oldrule = TAILQ_NEXT(oldrule, entries); 4883 if (oldrule == NULL) { 4884 if (newrule != NULL) 4885 pf_free_rule(newrule); 4886 PF_RULES_WUNLOCK(); 4887 PF_CONFIG_UNLOCK(); 4888 error = EINVAL; 4889 goto fail; 4890 } 4891 } 4892 4893 if (pcr->action == PF_CHANGE_REMOVE) { 4894 pf_unlink_rule(ruleset->rules[rs_num].active.ptr, 4895 oldrule); 4896 RB_REMOVE(pf_krule_global, 4897 ruleset->rules[rs_num].active.tree, oldrule); 4898 ruleset->rules[rs_num].active.rcount--; 4899 } else { 4900 pf_hash_rule(newrule); 4901 RB_INSERT(pf_krule_global, 4902 ruleset->rules[rs_num].active.tree, newrule); 4903 4904 if (oldrule == NULL) 4905 TAILQ_INSERT_TAIL( 4906 ruleset->rules[rs_num].active.ptr, 4907 newrule, entries); 4908 else if (pcr->action == PF_CHANGE_ADD_HEAD || 4909 pcr->action == PF_CHANGE_ADD_BEFORE) 4910 TAILQ_INSERT_BEFORE(oldrule, newrule, entries); 4911 else 4912 TAILQ_INSERT_AFTER( 4913 ruleset->rules[rs_num].active.ptr, 4914 oldrule, newrule, entries); 4915 ruleset->rules[rs_num].active.rcount++; 4916 } 4917 4918 nr = 0; 4919 TAILQ_FOREACH(oldrule, 4920 ruleset->rules[rs_num].active.ptr, entries) 4921 oldrule->nr = nr++; 4922 4923 ruleset->rules[rs_num].active.ticket++; 4924 4925 pf_calc_skip_steps(ruleset->rules[rs_num].active.ptr); 4926 pf_remove_if_empty_kruleset(ruleset); 4927 4928 PF_RULES_WUNLOCK(); 4929 PF_CONFIG_UNLOCK(); 4930 break; 4931 4932 #undef ERROUT 4933 DIOCCHANGERULE_error: 4934 PF_RULES_WUNLOCK(); 4935 PF_CONFIG_UNLOCK(); 4936 pf_krule_free(newrule); 4937 pf_kkif_free(kif); 4938 break; 4939 } 4940 4941 case DIOCCLRSTATESNV: { 4942 error = pf_clearstates_nv((struct pfioc_nv *)addr); 4943 break; 4944 } 4945 4946 case DIOCKILLSTATESNV: { 4947 error = pf_killstates_nv((struct pfioc_nv *)addr); 4948 break; 4949 } 4950 4951 case DIOCADDSTATE: { 4952 struct pfioc_state *ps = (struct pfioc_state *)addr; 4953 struct pfsync_state_1301 *sp = &ps->state; 4954 4955 if (sp->timeout >= PFTM_MAX) { 4956 error = EINVAL; 4957 goto fail; 4958 } 4959 if (V_pfsync_state_import_ptr != NULL) { 4960 PF_RULES_RLOCK(); 4961 error = V_pfsync_state_import_ptr( 4962 (union pfsync_state_union *)sp, PFSYNC_SI_IOCTL, 4963 PFSYNC_MSG_VERSION_1301); 4964 PF_RULES_RUNLOCK(); 4965 } else 4966 error = EOPNOTSUPP; 4967 break; 4968 } 4969 4970 case DIOCGETSTATE: { 4971 struct pfioc_state *ps = (struct pfioc_state *)addr; 4972 struct pf_kstate *s; 4973 4974 s = pf_find_state_byid(ps->state.id, ps->state.creatorid); 4975 if (s == NULL) { 4976 error = ENOENT; 4977 goto fail; 4978 } 4979 4980 pfsync_state_export_1301(&ps->state, s); 4981 PF_STATE_UNLOCK(s); 4982 break; 4983 } 4984 4985 case DIOCGETSTATENV: { 4986 error = pf_getstate((struct pfioc_nv *)addr); 4987 break; 4988 } 4989 4990 #ifdef COMPAT_FREEBSD14 4991 case DIOCGETSTATES: { 4992 struct pfioc_states *ps = (struct pfioc_states *)addr; 4993 struct pf_kstate *s; 4994 struct pfsync_state_1301 *pstore, *p; 4995 int i, nr; 4996 size_t slice_count = 16, count; 4997 void *out; 4998 4999 if (ps->ps_len <= 0) { 5000 nr = uma_zone_get_cur(V_pf_state_z); 5001 ps->ps_len = sizeof(struct pfsync_state_1301) * nr; 5002 break; 5003 } 5004 5005 out = ps->ps_states; 5006 pstore = mallocarray(slice_count, 5007 sizeof(struct pfsync_state_1301), M_PF, M_WAITOK | M_ZERO); 5008 nr = 0; 5009 5010 for (i = 0; i <= V_pf_hashmask; i++) { 5011 struct pf_idhash *ih = &V_pf_idhash[i]; 5012 5013 DIOCGETSTATES_retry: 5014 p = pstore; 5015 5016 if (LIST_EMPTY(&ih->states)) 5017 continue; 5018 5019 PF_HASHROW_LOCK(ih); 5020 count = 0; 5021 LIST_FOREACH(s, &ih->states, entry) { 5022 if (s->timeout == PFTM_UNLINKED) 5023 continue; 5024 count++; 5025 } 5026 5027 if (count > slice_count) { 5028 PF_HASHROW_UNLOCK(ih); 5029 free(pstore, M_PF); 5030 slice_count = count * 2; 5031 pstore = mallocarray(slice_count, 5032 sizeof(struct pfsync_state_1301), M_PF, 5033 M_WAITOK | M_ZERO); 5034 goto DIOCGETSTATES_retry; 5035 } 5036 5037 if ((nr+count) * sizeof(*p) > ps->ps_len) { 5038 PF_HASHROW_UNLOCK(ih); 5039 goto DIOCGETSTATES_full; 5040 } 5041 5042 LIST_FOREACH(s, &ih->states, entry) { 5043 if (s->timeout == PFTM_UNLINKED) 5044 continue; 5045 5046 pfsync_state_export_1301(p, s); 5047 p++; 5048 nr++; 5049 } 5050 PF_HASHROW_UNLOCK(ih); 5051 error = copyout(pstore, out, 5052 sizeof(struct pfsync_state_1301) * count); 5053 if (error) { 5054 free(pstore, M_PF); 5055 goto fail; 5056 } 5057 out = ps->ps_states + nr; 5058 } 5059 DIOCGETSTATES_full: 5060 ps->ps_len = sizeof(struct pfsync_state_1301) * nr; 5061 free(pstore, M_PF); 5062 5063 break; 5064 } 5065 5066 case DIOCGETSTATESV2: { 5067 struct pfioc_states_v2 *ps = (struct pfioc_states_v2 *)addr; 5068 struct pf_kstate *s; 5069 struct pf_state_export *pstore, *p; 5070 int i, nr; 5071 size_t slice_count = 16, count; 5072 void *out; 5073 5074 if (ps->ps_req_version > PF_STATE_VERSION) { 5075 error = ENOTSUP; 5076 goto fail; 5077 } 5078 5079 if (ps->ps_len <= 0) { 5080 nr = uma_zone_get_cur(V_pf_state_z); 5081 ps->ps_len = sizeof(struct pf_state_export) * nr; 5082 break; 5083 } 5084 5085 out = ps->ps_states; 5086 pstore = mallocarray(slice_count, 5087 sizeof(struct pf_state_export), M_PF, M_WAITOK | M_ZERO); 5088 nr = 0; 5089 5090 for (i = 0; i <= V_pf_hashmask; i++) { 5091 struct pf_idhash *ih = &V_pf_idhash[i]; 5092 5093 DIOCGETSTATESV2_retry: 5094 p = pstore; 5095 5096 if (LIST_EMPTY(&ih->states)) 5097 continue; 5098 5099 PF_HASHROW_LOCK(ih); 5100 count = 0; 5101 LIST_FOREACH(s, &ih->states, entry) { 5102 if (s->timeout == PFTM_UNLINKED) 5103 continue; 5104 count++; 5105 } 5106 5107 if (count > slice_count) { 5108 PF_HASHROW_UNLOCK(ih); 5109 free(pstore, M_PF); 5110 slice_count = count * 2; 5111 pstore = mallocarray(slice_count, 5112 sizeof(struct pf_state_export), M_PF, 5113 M_WAITOK | M_ZERO); 5114 goto DIOCGETSTATESV2_retry; 5115 } 5116 5117 if ((nr+count) * sizeof(*p) > ps->ps_len) { 5118 PF_HASHROW_UNLOCK(ih); 5119 goto DIOCGETSTATESV2_full; 5120 } 5121 5122 LIST_FOREACH(s, &ih->states, entry) { 5123 if (s->timeout == PFTM_UNLINKED) 5124 continue; 5125 5126 pf_state_export(p, s); 5127 p++; 5128 nr++; 5129 } 5130 PF_HASHROW_UNLOCK(ih); 5131 error = copyout(pstore, out, 5132 sizeof(struct pf_state_export) * count); 5133 if (error) { 5134 free(pstore, M_PF); 5135 goto fail; 5136 } 5137 out = ps->ps_states + nr; 5138 } 5139 DIOCGETSTATESV2_full: 5140 ps->ps_len = nr * sizeof(struct pf_state_export); 5141 free(pstore, M_PF); 5142 5143 break; 5144 } 5145 #endif 5146 case DIOCGETSTATUSNV: { 5147 error = pf_getstatus((struct pfioc_nv *)addr); 5148 break; 5149 } 5150 5151 case DIOCSETSTATUSIF: { 5152 struct pfioc_if *pi = (struct pfioc_if *)addr; 5153 5154 if (pi->ifname[0] == 0) { 5155 bzero(V_pf_status.ifname, IFNAMSIZ); 5156 break; 5157 } 5158 PF_RULES_WLOCK(); 5159 error = pf_user_strcpy(V_pf_status.ifname, pi->ifname, IFNAMSIZ); 5160 PF_RULES_WUNLOCK(); 5161 break; 5162 } 5163 5164 case DIOCCLRSTATUS: { 5165 pf_ioctl_clear_status(); 5166 break; 5167 } 5168 5169 case DIOCNATLOOK: { 5170 struct pfioc_natlook *pnl = (struct pfioc_natlook *)addr; 5171 5172 error = pf_ioctl_natlook(pnl); 5173 break; 5174 } 5175 5176 case DIOCSETTIMEOUT: { 5177 struct pfioc_tm *pt = (struct pfioc_tm *)addr; 5178 5179 error = pf_ioctl_set_timeout(pt->timeout, pt->seconds, 5180 &pt->seconds); 5181 break; 5182 } 5183 5184 case DIOCGETTIMEOUT: { 5185 struct pfioc_tm *pt = (struct pfioc_tm *)addr; 5186 5187 error = pf_ioctl_get_timeout(pt->timeout, &pt->seconds); 5188 break; 5189 } 5190 5191 case DIOCGETLIMIT: { 5192 struct pfioc_limit *pl = (struct pfioc_limit *)addr; 5193 5194 error = pf_ioctl_get_limit(pl->index, &pl->limit); 5195 break; 5196 } 5197 5198 case DIOCSETLIMIT: { 5199 struct pfioc_limit *pl = (struct pfioc_limit *)addr; 5200 unsigned int old_limit; 5201 5202 error = pf_ioctl_set_limit(pl->index, pl->limit, &old_limit); 5203 pl->limit = old_limit; 5204 break; 5205 } 5206 5207 case DIOCSETDEBUG: { 5208 u_int32_t *level = (u_int32_t *)addr; 5209 5210 PF_RULES_WLOCK(); 5211 V_pf_status.debug = *level; 5212 PF_RULES_WUNLOCK(); 5213 break; 5214 } 5215 5216 case DIOCCLRRULECTRS: { 5217 /* obsoleted by DIOCGETRULE with action=PF_GET_CLR_CNTR */ 5218 struct pf_kruleset *ruleset = &pf_main_ruleset; 5219 struct pf_krule *rule; 5220 5221 PF_RULES_WLOCK(); 5222 TAILQ_FOREACH(rule, 5223 ruleset->rules[PF_RULESET_FILTER].active.ptr, entries) { 5224 pf_counter_u64_zero(&rule->evaluations); 5225 for (int i = 0; i < 2; i++) { 5226 pf_counter_u64_zero(&rule->packets[i]); 5227 pf_counter_u64_zero(&rule->bytes[i]); 5228 } 5229 } 5230 PF_RULES_WUNLOCK(); 5231 break; 5232 } 5233 5234 case DIOCGIFSPEEDV0: 5235 case DIOCGIFSPEEDV1: { 5236 struct pf_ifspeed_v1 *psp = (struct pf_ifspeed_v1 *)addr; 5237 struct pf_ifspeed_v1 ps; 5238 struct ifnet *ifp; 5239 5240 if (psp->ifname[0] == '\0') { 5241 error = EINVAL; 5242 goto fail; 5243 } 5244 5245 error = pf_user_strcpy(ps.ifname, psp->ifname, IFNAMSIZ); 5246 if (error != 0) 5247 goto fail; 5248 ifp = ifunit(ps.ifname); 5249 if (ifp != NULL) { 5250 psp->baudrate32 = 5251 (u_int32_t)uqmin(ifp->if_baudrate, UINT_MAX); 5252 if (cmd == DIOCGIFSPEEDV1) 5253 psp->baudrate = ifp->if_baudrate; 5254 } else { 5255 error = EINVAL; 5256 } 5257 break; 5258 } 5259 5260 #ifdef ALTQ 5261 case DIOCSTARTALTQ: { 5262 struct pf_altq *altq; 5263 5264 PF_RULES_WLOCK(); 5265 /* enable all altq interfaces on active list */ 5266 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) { 5267 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) { 5268 error = pf_enable_altq(altq); 5269 if (error != 0) 5270 break; 5271 } 5272 } 5273 if (error == 0) 5274 V_pf_altq_running = 1; 5275 PF_RULES_WUNLOCK(); 5276 DPFPRINTF(PF_DEBUG_MISC, "altq: started"); 5277 break; 5278 } 5279 5280 case DIOCSTOPALTQ: { 5281 struct pf_altq *altq; 5282 5283 PF_RULES_WLOCK(); 5284 /* disable all altq interfaces on active list */ 5285 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) { 5286 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) { 5287 error = pf_disable_altq(altq); 5288 if (error != 0) 5289 break; 5290 } 5291 } 5292 if (error == 0) 5293 V_pf_altq_running = 0; 5294 PF_RULES_WUNLOCK(); 5295 DPFPRINTF(PF_DEBUG_MISC, "altq: stopped"); 5296 break; 5297 } 5298 5299 case DIOCADDALTQV0: 5300 case DIOCADDALTQV1: { 5301 struct pfioc_altq_v1 *pa = (struct pfioc_altq_v1 *)addr; 5302 struct pf_altq *altq, *a; 5303 struct ifnet *ifp; 5304 5305 altq = malloc(sizeof(*altq), M_PFALTQ, M_WAITOK | M_ZERO); 5306 error = pf_import_kaltq(pa, altq, IOCPARM_LEN(cmd)); 5307 if (error) 5308 goto fail; 5309 altq->local_flags = 0; 5310 5311 PF_RULES_WLOCK(); 5312 if (pa->ticket != V_ticket_altqs_inactive) { 5313 PF_RULES_WUNLOCK(); 5314 free(altq, M_PFALTQ); 5315 error = EBUSY; 5316 goto fail; 5317 } 5318 5319 /* 5320 * if this is for a queue, find the discipline and 5321 * copy the necessary fields 5322 */ 5323 if (altq->qname[0] != 0) { 5324 if ((altq->qid = pf_qname2qid(altq->qname, true)) == 0) { 5325 PF_RULES_WUNLOCK(); 5326 error = EBUSY; 5327 free(altq, M_PFALTQ); 5328 goto fail; 5329 } 5330 altq->altq_disc = NULL; 5331 TAILQ_FOREACH(a, V_pf_altq_ifs_inactive, entries) { 5332 if (strncmp(a->ifname, altq->ifname, 5333 IFNAMSIZ) == 0) { 5334 altq->altq_disc = a->altq_disc; 5335 break; 5336 } 5337 } 5338 } 5339 5340 if ((ifp = ifunit(altq->ifname)) == NULL) 5341 altq->local_flags |= PFALTQ_FLAG_IF_REMOVED; 5342 else 5343 error = altq_add(ifp, altq); 5344 5345 if (error) { 5346 PF_RULES_WUNLOCK(); 5347 free(altq, M_PFALTQ); 5348 goto fail; 5349 } 5350 5351 if (altq->qname[0] != 0) 5352 TAILQ_INSERT_TAIL(V_pf_altqs_inactive, altq, entries); 5353 else 5354 TAILQ_INSERT_TAIL(V_pf_altq_ifs_inactive, altq, entries); 5355 /* version error check done on import above */ 5356 pf_export_kaltq(altq, pa, IOCPARM_LEN(cmd)); 5357 PF_RULES_WUNLOCK(); 5358 break; 5359 } 5360 5361 case DIOCGETALTQSV0: 5362 case DIOCGETALTQSV1: { 5363 struct pfioc_altq_v1 *pa = (struct pfioc_altq_v1 *)addr; 5364 struct pf_altq *altq; 5365 5366 PF_RULES_RLOCK(); 5367 pa->nr = 0; 5368 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) 5369 pa->nr++; 5370 TAILQ_FOREACH(altq, V_pf_altqs_active, entries) 5371 pa->nr++; 5372 pa->ticket = V_ticket_altqs_active; 5373 PF_RULES_RUNLOCK(); 5374 break; 5375 } 5376 5377 case DIOCGETALTQV0: 5378 case DIOCGETALTQV1: { 5379 struct pfioc_altq_v1 *pa = (struct pfioc_altq_v1 *)addr; 5380 struct pf_altq *altq; 5381 5382 PF_RULES_RLOCK(); 5383 if (pa->ticket != V_ticket_altqs_active) { 5384 PF_RULES_RUNLOCK(); 5385 error = EBUSY; 5386 goto fail; 5387 } 5388 altq = pf_altq_get_nth_active(pa->nr); 5389 if (altq == NULL) { 5390 PF_RULES_RUNLOCK(); 5391 error = EBUSY; 5392 goto fail; 5393 } 5394 pf_export_kaltq(altq, pa, IOCPARM_LEN(cmd)); 5395 PF_RULES_RUNLOCK(); 5396 break; 5397 } 5398 5399 case DIOCCHANGEALTQV0: 5400 case DIOCCHANGEALTQV1: 5401 /* CHANGEALTQ not supported yet! */ 5402 error = ENODEV; 5403 break; 5404 5405 case DIOCGETQSTATSV0: 5406 case DIOCGETQSTATSV1: { 5407 struct pfioc_qstats_v1 *pq = (struct pfioc_qstats_v1 *)addr; 5408 struct pf_altq *altq; 5409 int nbytes; 5410 u_int32_t version; 5411 5412 PF_RULES_RLOCK(); 5413 if (pq->ticket != V_ticket_altqs_active) { 5414 PF_RULES_RUNLOCK(); 5415 error = EBUSY; 5416 goto fail; 5417 } 5418 nbytes = pq->nbytes; 5419 altq = pf_altq_get_nth_active(pq->nr); 5420 if (altq == NULL) { 5421 PF_RULES_RUNLOCK(); 5422 error = EBUSY; 5423 goto fail; 5424 } 5425 5426 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) != 0) { 5427 PF_RULES_RUNLOCK(); 5428 error = ENXIO; 5429 goto fail; 5430 } 5431 PF_RULES_RUNLOCK(); 5432 if (cmd == DIOCGETQSTATSV0) 5433 version = 0; /* DIOCGETQSTATSV0 means stats struct v0 */ 5434 else 5435 version = pq->version; 5436 error = altq_getqstats(altq, pq->buf, &nbytes, version); 5437 if (error == 0) { 5438 pq->scheduler = altq->scheduler; 5439 pq->nbytes = nbytes; 5440 } 5441 break; 5442 } 5443 #endif /* ALTQ */ 5444 5445 case DIOCBEGINADDRS: { 5446 struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr; 5447 5448 error = pf_ioctl_begin_addrs(&pp->ticket); 5449 break; 5450 } 5451 5452 case DIOCADDADDR: { 5453 struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr; 5454 struct pf_nl_pooladdr npp = {}; 5455 5456 npp.which = PF_RDR; 5457 memcpy(&npp, pp, sizeof(*pp)); 5458 error = pf_ioctl_add_addr(&npp); 5459 break; 5460 } 5461 5462 case DIOCGETADDRS: { 5463 struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr; 5464 struct pf_nl_pooladdr npp = {}; 5465 5466 npp.which = PF_RDR; 5467 memcpy(&npp, pp, sizeof(*pp)); 5468 error = pf_ioctl_get_addrs(&npp); 5469 memcpy(pp, &npp, sizeof(*pp)); 5470 5471 break; 5472 } 5473 5474 case DIOCGETADDR: { 5475 struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr; 5476 struct pf_nl_pooladdr npp = {}; 5477 5478 npp.which = PF_RDR; 5479 memcpy(&npp, pp, sizeof(*pp)); 5480 error = pf_ioctl_get_addr(&npp); 5481 memcpy(pp, &npp, sizeof(*pp)); 5482 5483 break; 5484 } 5485 5486 case DIOCCHANGEADDR: { 5487 struct pfioc_pooladdr *pca = (struct pfioc_pooladdr *)addr; 5488 struct pf_kpool *pool; 5489 struct pf_kpooladdr *oldpa = NULL, *newpa = NULL; 5490 struct pf_kruleset *ruleset; 5491 struct pfi_kkif *kif = NULL; 5492 5493 pca->anchor[sizeof(pca->anchor) - 1] = '\0'; 5494 5495 if (pca->action < PF_CHANGE_ADD_HEAD || 5496 pca->action > PF_CHANGE_REMOVE) { 5497 error = EINVAL; 5498 goto fail; 5499 } 5500 if (pca->addr.addr.type != PF_ADDR_ADDRMASK && 5501 pca->addr.addr.type != PF_ADDR_DYNIFTL && 5502 pca->addr.addr.type != PF_ADDR_TABLE) { 5503 error = EINVAL; 5504 goto fail; 5505 } 5506 if (pca->addr.addr.p.dyn != NULL) { 5507 error = EINVAL; 5508 goto fail; 5509 } 5510 5511 if (pca->action != PF_CHANGE_REMOVE) { 5512 #ifndef INET 5513 if (pca->af == AF_INET) { 5514 error = EAFNOSUPPORT; 5515 goto fail; 5516 } 5517 #endif /* INET */ 5518 #ifndef INET6 5519 if (pca->af == AF_INET6) { 5520 error = EAFNOSUPPORT; 5521 goto fail; 5522 } 5523 #endif /* INET6 */ 5524 newpa = malloc(sizeof(*newpa), M_PFRULE, M_WAITOK); 5525 bcopy(&pca->addr, newpa, sizeof(struct pf_pooladdr)); 5526 if (newpa->ifname[0]) 5527 kif = pf_kkif_create(M_WAITOK); 5528 newpa->kif = NULL; 5529 } 5530 #define ERROUT(x) ERROUT_IOCTL(DIOCCHANGEADDR_error, x) 5531 PF_RULES_WLOCK(); 5532 ruleset = pf_find_kruleset(pca->anchor); 5533 if (ruleset == NULL) 5534 ERROUT(EBUSY); 5535 5536 pool = pf_get_kpool(pca->anchor, pca->ticket, pca->r_action, 5537 pca->r_num, pca->r_last, 1, 1, PF_RDR); 5538 if (pool == NULL) 5539 ERROUT(EBUSY); 5540 5541 if (pca->action != PF_CHANGE_REMOVE) { 5542 if (newpa->ifname[0]) { 5543 newpa->kif = pfi_kkif_attach(kif, newpa->ifname); 5544 pfi_kkif_ref(newpa->kif); 5545 kif = NULL; 5546 } 5547 5548 switch (newpa->addr.type) { 5549 case PF_ADDR_DYNIFTL: 5550 error = pfi_dynaddr_setup(&newpa->addr, 5551 pca->af); 5552 break; 5553 case PF_ADDR_TABLE: 5554 newpa->addr.p.tbl = pfr_attach_table(ruleset, 5555 newpa->addr.v.tblname); 5556 if (newpa->addr.p.tbl == NULL) 5557 error = ENOMEM; 5558 break; 5559 } 5560 if (error) 5561 goto DIOCCHANGEADDR_error; 5562 } 5563 5564 switch (pca->action) { 5565 case PF_CHANGE_ADD_HEAD: 5566 oldpa = TAILQ_FIRST(&pool->list); 5567 break; 5568 case PF_CHANGE_ADD_TAIL: 5569 oldpa = TAILQ_LAST(&pool->list, pf_kpalist); 5570 break; 5571 default: 5572 oldpa = TAILQ_FIRST(&pool->list); 5573 for (int i = 0; oldpa && i < pca->nr; i++) 5574 oldpa = TAILQ_NEXT(oldpa, entries); 5575 5576 if (oldpa == NULL) 5577 ERROUT(EINVAL); 5578 } 5579 5580 if (pca->action == PF_CHANGE_REMOVE) { 5581 TAILQ_REMOVE(&pool->list, oldpa, entries); 5582 switch (oldpa->addr.type) { 5583 case PF_ADDR_DYNIFTL: 5584 pfi_dynaddr_remove(oldpa->addr.p.dyn); 5585 break; 5586 case PF_ADDR_TABLE: 5587 pfr_detach_table(oldpa->addr.p.tbl); 5588 break; 5589 } 5590 if (oldpa->kif) 5591 pfi_kkif_unref(oldpa->kif); 5592 free(oldpa, M_PFRULE); 5593 } else { 5594 if (oldpa == NULL) 5595 TAILQ_INSERT_TAIL(&pool->list, newpa, entries); 5596 else if (pca->action == PF_CHANGE_ADD_HEAD || 5597 pca->action == PF_CHANGE_ADD_BEFORE) 5598 TAILQ_INSERT_BEFORE(oldpa, newpa, entries); 5599 else 5600 TAILQ_INSERT_AFTER(&pool->list, oldpa, 5601 newpa, entries); 5602 } 5603 5604 pool->cur = TAILQ_FIRST(&pool->list); 5605 pf_addrcpy(&pool->counter, &pool->cur->addr.v.a.addr, pca->af); 5606 PF_RULES_WUNLOCK(); 5607 break; 5608 5609 #undef ERROUT 5610 DIOCCHANGEADDR_error: 5611 if (newpa != NULL) { 5612 if (newpa->kif) 5613 pfi_kkif_unref(newpa->kif); 5614 free(newpa, M_PFRULE); 5615 } 5616 PF_RULES_WUNLOCK(); 5617 pf_kkif_free(kif); 5618 break; 5619 } 5620 5621 case DIOCGETRULESETS: { 5622 struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr; 5623 5624 pr->path[sizeof(pr->path) - 1] = '\0'; 5625 5626 error = pf_ioctl_get_rulesets(pr); 5627 break; 5628 } 5629 5630 case DIOCGETRULESET: { 5631 struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr; 5632 5633 pr->path[sizeof(pr->path) - 1] = '\0'; 5634 5635 error = pf_ioctl_get_ruleset(pr); 5636 break; 5637 } 5638 5639 case DIOCRCLRTABLES: { 5640 struct pfioc_table *io = (struct pfioc_table *)addr; 5641 5642 if (io->pfrio_esize != 0) { 5643 error = ENODEV; 5644 goto fail; 5645 } 5646 if (strnlen(io->pfrio_table.pfrt_anchor, MAXPATHLEN) 5647 == MAXPATHLEN) { 5648 error = EINVAL; 5649 goto fail; 5650 } 5651 if (strnlen(io->pfrio_table.pfrt_name, PF_TABLE_NAME_SIZE) 5652 == PF_TABLE_NAME_SIZE) { 5653 error = EINVAL; 5654 goto fail; 5655 } 5656 5657 PF_RULES_WLOCK(); 5658 error = pfr_clr_tables(&io->pfrio_table, &io->pfrio_ndel, 5659 io->pfrio_flags | PFR_FLAG_USERIOCTL); 5660 PF_RULES_WUNLOCK(); 5661 break; 5662 } 5663 5664 case DIOCRADDTABLES: { 5665 struct pfioc_table *io = (struct pfioc_table *)addr; 5666 struct pfr_table *pfrts; 5667 size_t totlen; 5668 5669 if (io->pfrio_esize != sizeof(struct pfr_table)) { 5670 error = ENODEV; 5671 goto fail; 5672 } 5673 5674 if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount || 5675 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) { 5676 error = ENOMEM; 5677 goto fail; 5678 } 5679 5680 totlen = io->pfrio_size * sizeof(struct pfr_table); 5681 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table), 5682 M_PF, M_WAITOK); 5683 error = copyin(io->pfrio_buffer, pfrts, totlen); 5684 if (error) { 5685 free(pfrts, M_PF); 5686 goto fail; 5687 } 5688 PF_RULES_WLOCK(); 5689 error = pfr_add_tables(pfrts, io->pfrio_size, 5690 &io->pfrio_nadd, io->pfrio_flags | PFR_FLAG_USERIOCTL); 5691 PF_RULES_WUNLOCK(); 5692 free(pfrts, M_PF); 5693 break; 5694 } 5695 5696 case DIOCRDELTABLES: { 5697 struct pfioc_table *io = (struct pfioc_table *)addr; 5698 struct pfr_table *pfrts; 5699 size_t totlen; 5700 5701 if (io->pfrio_esize != sizeof(struct pfr_table)) { 5702 error = ENODEV; 5703 goto fail; 5704 } 5705 5706 if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount || 5707 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) { 5708 error = ENOMEM; 5709 goto fail; 5710 } 5711 5712 totlen = io->pfrio_size * sizeof(struct pfr_table); 5713 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table), 5714 M_PF, M_WAITOK); 5715 error = copyin(io->pfrio_buffer, pfrts, totlen); 5716 if (error) { 5717 free(pfrts, M_PF); 5718 goto fail; 5719 } 5720 PF_RULES_WLOCK(); 5721 error = pfr_del_tables(pfrts, io->pfrio_size, 5722 &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL); 5723 PF_RULES_WUNLOCK(); 5724 free(pfrts, M_PF); 5725 break; 5726 } 5727 5728 case DIOCRGETTABLES: { 5729 struct pfioc_table *io = (struct pfioc_table *)addr; 5730 struct pfr_table *pfrts; 5731 size_t totlen; 5732 int n; 5733 5734 if (io->pfrio_esize != sizeof(struct pfr_table)) { 5735 error = ENODEV; 5736 goto fail; 5737 } 5738 PF_RULES_RLOCK(); 5739 n = pfr_table_count(&io->pfrio_table, io->pfrio_flags); 5740 if (n < 0) { 5741 PF_RULES_RUNLOCK(); 5742 error = EINVAL; 5743 goto fail; 5744 } 5745 io->pfrio_size = min(io->pfrio_size, n); 5746 5747 totlen = io->pfrio_size * sizeof(struct pfr_table); 5748 5749 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table), 5750 M_PF, M_NOWAIT | M_ZERO); 5751 if (pfrts == NULL) { 5752 error = ENOMEM; 5753 PF_RULES_RUNLOCK(); 5754 goto fail; 5755 } 5756 error = pfr_get_tables(&io->pfrio_table, pfrts, 5757 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); 5758 PF_RULES_RUNLOCK(); 5759 if (error == 0) 5760 error = copyout(pfrts, io->pfrio_buffer, totlen); 5761 free(pfrts, M_PF); 5762 break; 5763 } 5764 5765 case DIOCRGETTSTATS: { 5766 struct pfioc_table *io = (struct pfioc_table *)addr; 5767 struct pfr_tstats *pfrtstats; 5768 size_t totlen; 5769 int n; 5770 5771 if (io->pfrio_esize != sizeof(struct pfr_tstats)) { 5772 error = ENODEV; 5773 goto fail; 5774 } 5775 PF_TABLE_STATS_LOCK(); 5776 PF_RULES_RLOCK(); 5777 n = pfr_table_count(&io->pfrio_table, io->pfrio_flags); 5778 if (n < 0) { 5779 PF_RULES_RUNLOCK(); 5780 PF_TABLE_STATS_UNLOCK(); 5781 error = EINVAL; 5782 goto fail; 5783 } 5784 io->pfrio_size = min(io->pfrio_size, n); 5785 5786 totlen = io->pfrio_size * sizeof(struct pfr_tstats); 5787 pfrtstats = mallocarray(io->pfrio_size, 5788 sizeof(struct pfr_tstats), M_PF, M_NOWAIT | M_ZERO); 5789 if (pfrtstats == NULL) { 5790 error = ENOMEM; 5791 PF_RULES_RUNLOCK(); 5792 PF_TABLE_STATS_UNLOCK(); 5793 goto fail; 5794 } 5795 error = pfr_get_tstats(&io->pfrio_table, pfrtstats, 5796 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); 5797 PF_RULES_RUNLOCK(); 5798 PF_TABLE_STATS_UNLOCK(); 5799 if (error == 0) 5800 error = copyout(pfrtstats, io->pfrio_buffer, totlen); 5801 free(pfrtstats, M_PF); 5802 break; 5803 } 5804 5805 case DIOCRCLRTSTATS: { 5806 struct pfioc_table *io = (struct pfioc_table *)addr; 5807 struct pfr_table *pfrts; 5808 size_t totlen; 5809 5810 if (io->pfrio_esize != sizeof(struct pfr_table)) { 5811 error = ENODEV; 5812 goto fail; 5813 } 5814 5815 if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount || 5816 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) { 5817 /* We used to count tables and use the minimum required 5818 * size, so we didn't fail on overly large requests. 5819 * Keep doing so. */ 5820 io->pfrio_size = pf_ioctl_maxcount; 5821 goto fail; 5822 } 5823 5824 totlen = io->pfrio_size * sizeof(struct pfr_table); 5825 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table), 5826 M_PF, M_WAITOK); 5827 error = copyin(io->pfrio_buffer, pfrts, totlen); 5828 if (error) { 5829 free(pfrts, M_PF); 5830 goto fail; 5831 } 5832 5833 PF_TABLE_STATS_LOCK(); 5834 PF_RULES_RLOCK(); 5835 error = pfr_clr_tstats(pfrts, io->pfrio_size, 5836 &io->pfrio_nzero, io->pfrio_flags | PFR_FLAG_USERIOCTL); 5837 PF_RULES_RUNLOCK(); 5838 PF_TABLE_STATS_UNLOCK(); 5839 free(pfrts, M_PF); 5840 break; 5841 } 5842 5843 case DIOCRSETTFLAGS: { 5844 struct pfioc_table *io = (struct pfioc_table *)addr; 5845 struct pfr_table *pfrts; 5846 size_t totlen; 5847 int n; 5848 5849 if (io->pfrio_esize != sizeof(struct pfr_table)) { 5850 error = ENODEV; 5851 goto fail; 5852 } 5853 5854 PF_RULES_RLOCK(); 5855 n = pfr_table_count(&io->pfrio_table, io->pfrio_flags); 5856 if (n < 0) { 5857 PF_RULES_RUNLOCK(); 5858 error = EINVAL; 5859 goto fail; 5860 } 5861 5862 io->pfrio_size = min(io->pfrio_size, n); 5863 PF_RULES_RUNLOCK(); 5864 5865 totlen = io->pfrio_size * sizeof(struct pfr_table); 5866 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table), 5867 M_PF, M_WAITOK); 5868 error = copyin(io->pfrio_buffer, pfrts, totlen); 5869 if (error) { 5870 free(pfrts, M_PF); 5871 goto fail; 5872 } 5873 PF_RULES_WLOCK(); 5874 error = pfr_set_tflags(pfrts, io->pfrio_size, 5875 io->pfrio_setflag, io->pfrio_clrflag, &io->pfrio_nchange, 5876 &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL); 5877 PF_RULES_WUNLOCK(); 5878 free(pfrts, M_PF); 5879 break; 5880 } 5881 5882 case DIOCRCLRADDRS: { 5883 struct pfioc_table *io = (struct pfioc_table *)addr; 5884 5885 if (io->pfrio_esize != 0) { 5886 error = ENODEV; 5887 goto fail; 5888 } 5889 PF_RULES_WLOCK(); 5890 error = pfr_clr_addrs(&io->pfrio_table, &io->pfrio_ndel, 5891 io->pfrio_flags | PFR_FLAG_USERIOCTL); 5892 PF_RULES_WUNLOCK(); 5893 break; 5894 } 5895 5896 case DIOCRADDADDRS: { 5897 struct pfioc_table *io = (struct pfioc_table *)addr; 5898 struct pfr_addr *pfras; 5899 size_t totlen; 5900 5901 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 5902 error = ENODEV; 5903 goto fail; 5904 } 5905 if (io->pfrio_size < 0 || 5906 io->pfrio_size > pf_ioctl_maxcount || 5907 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) { 5908 error = EINVAL; 5909 goto fail; 5910 } 5911 totlen = io->pfrio_size * sizeof(struct pfr_addr); 5912 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr), 5913 M_PF, M_WAITOK); 5914 error = copyin(io->pfrio_buffer, pfras, totlen); 5915 if (error) { 5916 free(pfras, M_PF); 5917 goto fail; 5918 } 5919 PF_RULES_WLOCK(); 5920 io->pfrio_nadd = 0; 5921 error = pfr_add_addrs(&io->pfrio_table, pfras, 5922 io->pfrio_size, &io->pfrio_nadd, io->pfrio_flags | 5923 PFR_FLAG_USERIOCTL); 5924 PF_RULES_WUNLOCK(); 5925 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK) 5926 error = copyout(pfras, io->pfrio_buffer, totlen); 5927 free(pfras, M_PF); 5928 break; 5929 } 5930 5931 case DIOCRDELADDRS: { 5932 struct pfioc_table *io = (struct pfioc_table *)addr; 5933 struct pfr_addr *pfras; 5934 size_t totlen; 5935 5936 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 5937 error = ENODEV; 5938 goto fail; 5939 } 5940 if (io->pfrio_size < 0 || 5941 io->pfrio_size > pf_ioctl_maxcount || 5942 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) { 5943 error = EINVAL; 5944 goto fail; 5945 } 5946 totlen = io->pfrio_size * sizeof(struct pfr_addr); 5947 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr), 5948 M_PF, M_WAITOK); 5949 error = copyin(io->pfrio_buffer, pfras, totlen); 5950 if (error) { 5951 free(pfras, M_PF); 5952 goto fail; 5953 } 5954 PF_RULES_WLOCK(); 5955 error = pfr_del_addrs(&io->pfrio_table, pfras, 5956 io->pfrio_size, &io->pfrio_ndel, io->pfrio_flags | 5957 PFR_FLAG_USERIOCTL); 5958 PF_RULES_WUNLOCK(); 5959 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK) 5960 error = copyout(pfras, io->pfrio_buffer, totlen); 5961 free(pfras, M_PF); 5962 break; 5963 } 5964 5965 case DIOCRSETADDRS: { 5966 struct pfioc_table *io = (struct pfioc_table *)addr; 5967 struct pfr_addr *pfras; 5968 size_t totlen, count; 5969 5970 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 5971 error = ENODEV; 5972 goto fail; 5973 } 5974 if (io->pfrio_size < 0 || io->pfrio_size2 < 0) { 5975 error = EINVAL; 5976 goto fail; 5977 } 5978 count = max(io->pfrio_size, io->pfrio_size2); 5979 if (count > pf_ioctl_maxcount || 5980 WOULD_OVERFLOW(count, sizeof(struct pfr_addr))) { 5981 error = EINVAL; 5982 goto fail; 5983 } 5984 totlen = count * sizeof(struct pfr_addr); 5985 pfras = mallocarray(count, sizeof(struct pfr_addr), M_PF, 5986 M_WAITOK); 5987 error = copyin(io->pfrio_buffer, pfras, totlen); 5988 if (error) { 5989 free(pfras, M_PF); 5990 goto fail; 5991 } 5992 PF_RULES_WLOCK(); 5993 error = pfr_set_addrs(&io->pfrio_table, pfras, 5994 io->pfrio_size, &io->pfrio_size2, &io->pfrio_nadd, 5995 &io->pfrio_ndel, &io->pfrio_nchange, io->pfrio_flags | 5996 PFR_FLAG_START | PFR_FLAG_DONE | PFR_FLAG_USERIOCTL, 0); 5997 PF_RULES_WUNLOCK(); 5998 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK) 5999 error = copyout(pfras, io->pfrio_buffer, totlen); 6000 free(pfras, M_PF); 6001 break; 6002 } 6003 6004 case DIOCRGETADDRS: { 6005 struct pfioc_table *io = (struct pfioc_table *)addr; 6006 struct pfr_addr *pfras; 6007 size_t totlen; 6008 6009 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 6010 error = ENODEV; 6011 goto fail; 6012 } 6013 if (io->pfrio_size < 0 || 6014 io->pfrio_size > pf_ioctl_maxcount || 6015 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) { 6016 error = EINVAL; 6017 goto fail; 6018 } 6019 totlen = io->pfrio_size * sizeof(struct pfr_addr); 6020 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr), 6021 M_PF, M_WAITOK | M_ZERO); 6022 PF_RULES_RLOCK(); 6023 error = pfr_get_addrs(&io->pfrio_table, pfras, 6024 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); 6025 PF_RULES_RUNLOCK(); 6026 if (error == 0) 6027 error = copyout(pfras, io->pfrio_buffer, totlen); 6028 free(pfras, M_PF); 6029 break; 6030 } 6031 6032 case DIOCRGETASTATS: { 6033 struct pfioc_table *io = (struct pfioc_table *)addr; 6034 struct pfr_astats *pfrastats; 6035 size_t totlen; 6036 6037 if (io->pfrio_esize != sizeof(struct pfr_astats)) { 6038 error = ENODEV; 6039 goto fail; 6040 } 6041 if (io->pfrio_size < 0 || 6042 io->pfrio_size > pf_ioctl_maxcount || 6043 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_astats))) { 6044 error = EINVAL; 6045 goto fail; 6046 } 6047 totlen = io->pfrio_size * sizeof(struct pfr_astats); 6048 pfrastats = mallocarray(io->pfrio_size, 6049 sizeof(struct pfr_astats), M_PF, M_WAITOK | M_ZERO); 6050 PF_RULES_RLOCK(); 6051 error = pfr_get_astats(&io->pfrio_table, pfrastats, 6052 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); 6053 PF_RULES_RUNLOCK(); 6054 if (error == 0) 6055 error = copyout(pfrastats, io->pfrio_buffer, totlen); 6056 free(pfrastats, M_PF); 6057 break; 6058 } 6059 6060 case DIOCRCLRASTATS: { 6061 struct pfioc_table *io = (struct pfioc_table *)addr; 6062 struct pfr_addr *pfras; 6063 size_t totlen; 6064 6065 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 6066 error = ENODEV; 6067 goto fail; 6068 } 6069 if (io->pfrio_size < 0 || 6070 io->pfrio_size > pf_ioctl_maxcount || 6071 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) { 6072 error = EINVAL; 6073 goto fail; 6074 } 6075 totlen = io->pfrio_size * sizeof(struct pfr_addr); 6076 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr), 6077 M_PF, M_WAITOK); 6078 error = copyin(io->pfrio_buffer, pfras, totlen); 6079 if (error) { 6080 free(pfras, M_PF); 6081 goto fail; 6082 } 6083 PF_RULES_WLOCK(); 6084 error = pfr_clr_astats(&io->pfrio_table, pfras, 6085 io->pfrio_size, &io->pfrio_nzero, io->pfrio_flags | 6086 PFR_FLAG_USERIOCTL); 6087 PF_RULES_WUNLOCK(); 6088 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK) 6089 error = copyout(pfras, io->pfrio_buffer, totlen); 6090 free(pfras, M_PF); 6091 break; 6092 } 6093 6094 case DIOCRTSTADDRS: { 6095 struct pfioc_table *io = (struct pfioc_table *)addr; 6096 struct pfr_addr *pfras; 6097 size_t totlen; 6098 6099 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 6100 error = ENODEV; 6101 goto fail; 6102 } 6103 if (io->pfrio_size < 0 || 6104 io->pfrio_size > pf_ioctl_maxcount || 6105 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) { 6106 error = EINVAL; 6107 goto fail; 6108 } 6109 totlen = io->pfrio_size * sizeof(struct pfr_addr); 6110 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr), 6111 M_PF, M_WAITOK); 6112 error = copyin(io->pfrio_buffer, pfras, totlen); 6113 if (error) { 6114 free(pfras, M_PF); 6115 goto fail; 6116 } 6117 PF_RULES_RLOCK(); 6118 error = pfr_tst_addrs(&io->pfrio_table, pfras, 6119 io->pfrio_size, &io->pfrio_nmatch, io->pfrio_flags | 6120 PFR_FLAG_USERIOCTL); 6121 PF_RULES_RUNLOCK(); 6122 if (error == 0) 6123 error = copyout(pfras, io->pfrio_buffer, totlen); 6124 free(pfras, M_PF); 6125 break; 6126 } 6127 6128 case DIOCRINADEFINE: { 6129 struct pfioc_table *io = (struct pfioc_table *)addr; 6130 struct pfr_addr *pfras; 6131 size_t totlen; 6132 6133 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 6134 error = ENODEV; 6135 goto fail; 6136 } 6137 if (io->pfrio_size < 0 || 6138 io->pfrio_size > pf_ioctl_maxcount || 6139 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) { 6140 error = EINVAL; 6141 goto fail; 6142 } 6143 totlen = io->pfrio_size * sizeof(struct pfr_addr); 6144 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr), 6145 M_PF, M_WAITOK); 6146 error = copyin(io->pfrio_buffer, pfras, totlen); 6147 if (error) { 6148 free(pfras, M_PF); 6149 goto fail; 6150 } 6151 PF_RULES_WLOCK(); 6152 error = pfr_ina_define(&io->pfrio_table, pfras, 6153 io->pfrio_size, &io->pfrio_nadd, &io->pfrio_naddr, 6154 io->pfrio_ticket, io->pfrio_flags | PFR_FLAG_USERIOCTL); 6155 PF_RULES_WUNLOCK(); 6156 free(pfras, M_PF); 6157 break; 6158 } 6159 6160 case DIOCOSFPADD: { 6161 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr; 6162 PF_RULES_WLOCK(); 6163 error = pf_osfp_add(io); 6164 PF_RULES_WUNLOCK(); 6165 break; 6166 } 6167 6168 case DIOCOSFPGET: { 6169 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr; 6170 PF_RULES_RLOCK(); 6171 error = pf_osfp_get(io); 6172 PF_RULES_RUNLOCK(); 6173 break; 6174 } 6175 6176 case DIOCXBEGIN: { 6177 struct pfioc_trans *io = (struct pfioc_trans *)addr; 6178 struct pfioc_trans_e *ioes, *ioe; 6179 size_t totlen; 6180 int i; 6181 6182 if (io->esize != sizeof(*ioe)) { 6183 error = ENODEV; 6184 goto fail; 6185 } 6186 if (io->size < 0 || 6187 io->size > pf_ioctl_maxcount || 6188 WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) { 6189 error = EINVAL; 6190 goto fail; 6191 } 6192 totlen = sizeof(struct pfioc_trans_e) * io->size; 6193 ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e), 6194 M_PF, M_WAITOK); 6195 error = copyin(io->array, ioes, totlen); 6196 if (error) { 6197 free(ioes, M_PF); 6198 goto fail; 6199 } 6200 PF_RULES_WLOCK(); 6201 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) { 6202 ioe->anchor[sizeof(ioe->anchor) - 1] = '\0'; 6203 switch (ioe->rs_num) { 6204 case PF_RULESET_ETH: 6205 if ((error = pf_begin_eth(&ioe->ticket, ioe->anchor))) { 6206 PF_RULES_WUNLOCK(); 6207 free(ioes, M_PF); 6208 goto fail; 6209 } 6210 break; 6211 #ifdef ALTQ 6212 case PF_RULESET_ALTQ: 6213 if (ioe->anchor[0]) { 6214 PF_RULES_WUNLOCK(); 6215 free(ioes, M_PF); 6216 error = EINVAL; 6217 goto fail; 6218 } 6219 if ((error = pf_begin_altq(&ioe->ticket))) { 6220 PF_RULES_WUNLOCK(); 6221 free(ioes, M_PF); 6222 goto fail; 6223 } 6224 break; 6225 #endif /* ALTQ */ 6226 case PF_RULESET_TABLE: 6227 { 6228 struct pfr_table table; 6229 6230 bzero(&table, sizeof(table)); 6231 strlcpy(table.pfrt_anchor, ioe->anchor, 6232 sizeof(table.pfrt_anchor)); 6233 if ((error = pfr_ina_begin(&table, 6234 &ioe->ticket, NULL, 0))) { 6235 PF_RULES_WUNLOCK(); 6236 free(ioes, M_PF); 6237 goto fail; 6238 } 6239 break; 6240 } 6241 default: 6242 if ((error = pf_begin_rules(&ioe->ticket, 6243 ioe->rs_num, ioe->anchor))) { 6244 PF_RULES_WUNLOCK(); 6245 free(ioes, M_PF); 6246 goto fail; 6247 } 6248 break; 6249 } 6250 } 6251 PF_RULES_WUNLOCK(); 6252 error = copyout(ioes, io->array, totlen); 6253 free(ioes, M_PF); 6254 break; 6255 } 6256 6257 case DIOCXROLLBACK: { 6258 struct pfioc_trans *io = (struct pfioc_trans *)addr; 6259 struct pfioc_trans_e *ioe, *ioes; 6260 size_t totlen; 6261 int i; 6262 6263 if (io->esize != sizeof(*ioe)) { 6264 error = ENODEV; 6265 goto fail; 6266 } 6267 if (io->size < 0 || 6268 io->size > pf_ioctl_maxcount || 6269 WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) { 6270 error = EINVAL; 6271 goto fail; 6272 } 6273 totlen = sizeof(struct pfioc_trans_e) * io->size; 6274 ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e), 6275 M_PF, M_WAITOK); 6276 error = copyin(io->array, ioes, totlen); 6277 if (error) { 6278 free(ioes, M_PF); 6279 goto fail; 6280 } 6281 PF_RULES_WLOCK(); 6282 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) { 6283 ioe->anchor[sizeof(ioe->anchor) - 1] = '\0'; 6284 switch (ioe->rs_num) { 6285 case PF_RULESET_ETH: 6286 if ((error = pf_rollback_eth(ioe->ticket, 6287 ioe->anchor))) { 6288 PF_RULES_WUNLOCK(); 6289 free(ioes, M_PF); 6290 goto fail; /* really bad */ 6291 } 6292 break; 6293 #ifdef ALTQ 6294 case PF_RULESET_ALTQ: 6295 if (ioe->anchor[0]) { 6296 PF_RULES_WUNLOCK(); 6297 free(ioes, M_PF); 6298 error = EINVAL; 6299 goto fail; 6300 } 6301 if ((error = pf_rollback_altq(ioe->ticket))) { 6302 PF_RULES_WUNLOCK(); 6303 free(ioes, M_PF); 6304 goto fail; /* really bad */ 6305 } 6306 break; 6307 #endif /* ALTQ */ 6308 case PF_RULESET_TABLE: 6309 { 6310 struct pfr_table table; 6311 6312 bzero(&table, sizeof(table)); 6313 strlcpy(table.pfrt_anchor, ioe->anchor, 6314 sizeof(table.pfrt_anchor)); 6315 if ((error = pfr_ina_rollback(&table, 6316 ioe->ticket, NULL, 0))) { 6317 PF_RULES_WUNLOCK(); 6318 free(ioes, M_PF); 6319 goto fail; /* really bad */ 6320 } 6321 break; 6322 } 6323 default: 6324 if ((error = pf_rollback_rules(ioe->ticket, 6325 ioe->rs_num, ioe->anchor))) { 6326 PF_RULES_WUNLOCK(); 6327 free(ioes, M_PF); 6328 goto fail; /* really bad */ 6329 } 6330 break; 6331 } 6332 } 6333 PF_RULES_WUNLOCK(); 6334 free(ioes, M_PF); 6335 break; 6336 } 6337 6338 case DIOCXCOMMIT: { 6339 struct pfioc_trans *io = (struct pfioc_trans *)addr; 6340 struct pfioc_trans_e *ioe, *ioes; 6341 struct pf_kruleset *rs; 6342 struct pf_keth_ruleset *ers; 6343 size_t totlen; 6344 int i; 6345 6346 if (io->esize != sizeof(*ioe)) { 6347 error = ENODEV; 6348 goto fail; 6349 } 6350 6351 if (io->size < 0 || 6352 io->size > pf_ioctl_maxcount || 6353 WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) { 6354 error = EINVAL; 6355 goto fail; 6356 } 6357 6358 totlen = sizeof(struct pfioc_trans_e) * io->size; 6359 ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e), 6360 M_PF, M_WAITOK); 6361 error = copyin(io->array, ioes, totlen); 6362 if (error) { 6363 free(ioes, M_PF); 6364 goto fail; 6365 } 6366 PF_RULES_WLOCK(); 6367 /* First makes sure everything will succeed. */ 6368 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) { 6369 ioe->anchor[sizeof(ioe->anchor) - 1] = '\0'; 6370 switch (ioe->rs_num) { 6371 case PF_RULESET_ETH: 6372 ers = pf_find_keth_ruleset(ioe->anchor); 6373 if (ers == NULL || ioe->ticket == 0 || 6374 ioe->ticket != ers->inactive.ticket) { 6375 PF_RULES_WUNLOCK(); 6376 free(ioes, M_PF); 6377 error = EINVAL; 6378 goto fail; 6379 } 6380 break; 6381 #ifdef ALTQ 6382 case PF_RULESET_ALTQ: 6383 if (ioe->anchor[0]) { 6384 PF_RULES_WUNLOCK(); 6385 free(ioes, M_PF); 6386 error = EINVAL; 6387 goto fail; 6388 } 6389 if (!V_altqs_inactive_open || ioe->ticket != 6390 V_ticket_altqs_inactive) { 6391 PF_RULES_WUNLOCK(); 6392 free(ioes, M_PF); 6393 error = EBUSY; 6394 goto fail; 6395 } 6396 break; 6397 #endif /* ALTQ */ 6398 case PF_RULESET_TABLE: 6399 rs = pf_find_kruleset(ioe->anchor); 6400 if (rs == NULL || !rs->topen || ioe->ticket != 6401 rs->tticket) { 6402 PF_RULES_WUNLOCK(); 6403 free(ioes, M_PF); 6404 error = EBUSY; 6405 goto fail; 6406 } 6407 break; 6408 default: 6409 if (ioe->rs_num < 0 || ioe->rs_num >= 6410 PF_RULESET_MAX) { 6411 PF_RULES_WUNLOCK(); 6412 free(ioes, M_PF); 6413 error = EINVAL; 6414 goto fail; 6415 } 6416 rs = pf_find_kruleset(ioe->anchor); 6417 if (rs == NULL || 6418 !rs->rules[ioe->rs_num].inactive.open || 6419 rs->rules[ioe->rs_num].inactive.ticket != 6420 ioe->ticket) { 6421 PF_RULES_WUNLOCK(); 6422 free(ioes, M_PF); 6423 error = EBUSY; 6424 goto fail; 6425 } 6426 break; 6427 } 6428 } 6429 /* Now do the commit - no errors should happen here. */ 6430 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) { 6431 switch (ioe->rs_num) { 6432 case PF_RULESET_ETH: 6433 if ((error = pf_commit_eth(ioe->ticket, ioe->anchor))) { 6434 PF_RULES_WUNLOCK(); 6435 free(ioes, M_PF); 6436 goto fail; /* really bad */ 6437 } 6438 break; 6439 #ifdef ALTQ 6440 case PF_RULESET_ALTQ: 6441 if ((error = pf_commit_altq(ioe->ticket))) { 6442 PF_RULES_WUNLOCK(); 6443 free(ioes, M_PF); 6444 goto fail; /* really bad */ 6445 } 6446 break; 6447 #endif /* ALTQ */ 6448 case PF_RULESET_TABLE: 6449 { 6450 struct pfr_table table; 6451 6452 bzero(&table, sizeof(table)); 6453 (void)strlcpy(table.pfrt_anchor, ioe->anchor, 6454 sizeof(table.pfrt_anchor)); 6455 if ((error = pfr_ina_commit(&table, 6456 ioe->ticket, NULL, NULL, 0))) { 6457 PF_RULES_WUNLOCK(); 6458 free(ioes, M_PF); 6459 goto fail; /* really bad */ 6460 } 6461 break; 6462 } 6463 default: 6464 if ((error = pf_commit_rules(ioe->ticket, 6465 ioe->rs_num, ioe->anchor))) { 6466 PF_RULES_WUNLOCK(); 6467 free(ioes, M_PF); 6468 goto fail; /* really bad */ 6469 } 6470 break; 6471 } 6472 } 6473 PF_RULES_WUNLOCK(); 6474 6475 /* Only hook into EtherNet taffic if we've got rules for it. */ 6476 if (! TAILQ_EMPTY(V_pf_keth->active.rules)) 6477 hook_pf_eth(); 6478 else 6479 dehook_pf_eth(); 6480 6481 free(ioes, M_PF); 6482 break; 6483 } 6484 6485 case DIOCGETSRCNODES: { 6486 struct pfioc_src_nodes *psn = (struct pfioc_src_nodes *)addr; 6487 struct pf_srchash *sh; 6488 struct pf_ksrc_node *n; 6489 struct pf_src_node *p, *pstore; 6490 uint32_t i, nr = 0; 6491 6492 for (i = 0, sh = V_pf_srchash; i <= V_pf_srchashmask; 6493 i++, sh++) { 6494 PF_HASHROW_LOCK(sh); 6495 LIST_FOREACH(n, &sh->nodes, entry) 6496 nr++; 6497 PF_HASHROW_UNLOCK(sh); 6498 } 6499 6500 psn->psn_len = min(psn->psn_len, 6501 sizeof(struct pf_src_node) * nr); 6502 6503 if (psn->psn_len == 0) { 6504 psn->psn_len = sizeof(struct pf_src_node) * nr; 6505 goto fail; 6506 } 6507 6508 nr = 0; 6509 6510 p = pstore = malloc(psn->psn_len, M_PF, M_WAITOK | M_ZERO); 6511 for (i = 0, sh = V_pf_srchash; i <= V_pf_srchashmask; 6512 i++, sh++) { 6513 PF_HASHROW_LOCK(sh); 6514 LIST_FOREACH(n, &sh->nodes, entry) { 6515 6516 if ((nr + 1) * sizeof(*p) > (unsigned)psn->psn_len) 6517 break; 6518 6519 pf_src_node_copy(n, p); 6520 6521 p++; 6522 nr++; 6523 } 6524 PF_HASHROW_UNLOCK(sh); 6525 } 6526 error = copyout(pstore, psn->psn_src_nodes, 6527 sizeof(struct pf_src_node) * nr); 6528 if (error) { 6529 free(pstore, M_PF); 6530 goto fail; 6531 } 6532 psn->psn_len = sizeof(struct pf_src_node) * nr; 6533 free(pstore, M_PF); 6534 break; 6535 } 6536 6537 case DIOCCLRSRCNODES: { 6538 pf_kill_srcnodes(NULL); 6539 break; 6540 } 6541 6542 case DIOCKILLSRCNODES: 6543 pf_kill_srcnodes((struct pfioc_src_node_kill *)addr); 6544 break; 6545 6546 #ifdef COMPAT_FREEBSD13 6547 case DIOCKEEPCOUNTERS_FREEBSD13: 6548 #endif 6549 case DIOCKEEPCOUNTERS: 6550 error = pf_keepcounters((struct pfioc_nv *)addr); 6551 break; 6552 6553 case DIOCGETSYNCOOKIES: 6554 error = pf_get_syncookies((struct pfioc_nv *)addr); 6555 break; 6556 6557 case DIOCSETSYNCOOKIES: 6558 error = pf_set_syncookies((struct pfioc_nv *)addr); 6559 break; 6560 6561 case DIOCSETHOSTID: { 6562 u_int32_t *hostid = (u_int32_t *)addr; 6563 6564 PF_RULES_WLOCK(); 6565 if (*hostid == 0) 6566 V_pf_status.hostid = arc4random(); 6567 else 6568 V_pf_status.hostid = *hostid; 6569 PF_RULES_WUNLOCK(); 6570 break; 6571 } 6572 6573 case DIOCOSFPFLUSH: 6574 PF_RULES_WLOCK(); 6575 pf_osfp_flush(); 6576 PF_RULES_WUNLOCK(); 6577 break; 6578 6579 case DIOCIGETIFACES: { 6580 struct pfioc_iface *io = (struct pfioc_iface *)addr; 6581 struct pfi_kif *ifstore; 6582 size_t bufsiz; 6583 6584 if (io->pfiio_esize != sizeof(struct pfi_kif)) { 6585 error = ENODEV; 6586 goto fail; 6587 } 6588 6589 if (io->pfiio_size < 0 || 6590 io->pfiio_size > pf_ioctl_maxcount || 6591 WOULD_OVERFLOW(io->pfiio_size, sizeof(struct pfi_kif))) { 6592 error = EINVAL; 6593 goto fail; 6594 } 6595 6596 io->pfiio_name[sizeof(io->pfiio_name) - 1] = '\0'; 6597 6598 bufsiz = io->pfiio_size * sizeof(struct pfi_kif); 6599 ifstore = mallocarray(io->pfiio_size, sizeof(struct pfi_kif), 6600 M_PF, M_WAITOK | M_ZERO); 6601 6602 PF_RULES_RLOCK(); 6603 pfi_get_ifaces(io->pfiio_name, ifstore, &io->pfiio_size); 6604 PF_RULES_RUNLOCK(); 6605 error = copyout(ifstore, io->pfiio_buffer, bufsiz); 6606 free(ifstore, M_PF); 6607 break; 6608 } 6609 6610 case DIOCSETIFFLAG: { 6611 struct pfioc_iface *io = (struct pfioc_iface *)addr; 6612 6613 io->pfiio_name[sizeof(io->pfiio_name) - 1] = '\0'; 6614 6615 PF_RULES_WLOCK(); 6616 error = pfi_set_flags(io->pfiio_name, io->pfiio_flags); 6617 PF_RULES_WUNLOCK(); 6618 break; 6619 } 6620 6621 case DIOCCLRIFFLAG: { 6622 struct pfioc_iface *io = (struct pfioc_iface *)addr; 6623 6624 io->pfiio_name[sizeof(io->pfiio_name) - 1] = '\0'; 6625 6626 PF_RULES_WLOCK(); 6627 error = pfi_clear_flags(io->pfiio_name, io->pfiio_flags); 6628 PF_RULES_WUNLOCK(); 6629 break; 6630 } 6631 6632 case DIOCSETREASS: { 6633 u_int32_t *reass = (u_int32_t *)addr; 6634 u_int32_t flags; 6635 6636 flags = *reass & (PF_REASS_ENABLED|PF_REASS_NODF); 6637 /* Removal of DF flag without reassembly enabled is not a 6638 * valid combination. Disable reassembly in such case. */ 6639 if (!(flags & PF_REASS_ENABLED)) 6640 flags = 0; 6641 PF_RULES_WLOCK(); 6642 V_pf_status.reass = flags; 6643 PF_RULES_WUNLOCK(); 6644 break; 6645 } 6646 6647 default: 6648 error = ENODEV; 6649 break; 6650 } 6651 fail: 6652 CURVNET_RESTORE(); 6653 6654 #undef ERROUT_IOCTL 6655 6656 return (error); 6657 } 6658 6659 static void 6660 pfsync_state_export(union pfsync_state_union *sp, struct pf_kstate *st, int msg_version) 6661 { 6662 const char *tagname; 6663 6664 /* copy from state key */ 6665 sp->pfs_1301.key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0]; 6666 sp->pfs_1301.key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1]; 6667 sp->pfs_1301.key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0]; 6668 sp->pfs_1301.key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1]; 6669 sp->pfs_1301.key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0]; 6670 sp->pfs_1301.key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1]; 6671 sp->pfs_1301.key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0]; 6672 sp->pfs_1301.key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1]; 6673 6674 /* copy from state */ 6675 strlcpy(sp->pfs_1301.ifname, st->kif->pfik_name, sizeof(sp->pfs_1301.ifname)); 6676 bcopy(&st->act.rt_addr, &sp->pfs_1301.rt_addr, sizeof(sp->pfs_1301.rt_addr)); 6677 sp->pfs_1301.creation = htonl(time_uptime - (st->creation / 1000)); 6678 sp->pfs_1301.expire = pf_state_expires(st); 6679 if (sp->pfs_1301.expire <= time_uptime) 6680 sp->pfs_1301.expire = htonl(0); 6681 else 6682 sp->pfs_1301.expire = htonl(sp->pfs_1301.expire - time_uptime); 6683 6684 switch (msg_version) { 6685 case PFSYNC_MSG_VERSION_1301: 6686 sp->pfs_1301.state_flags = st->state_flags; 6687 sp->pfs_1301.direction = st->direction; 6688 sp->pfs_1301.log = st->act.log; 6689 sp->pfs_1301.timeout = st->timeout; 6690 sp->pfs_1301.proto = st->key[PF_SK_WIRE]->proto; 6691 sp->pfs_1301.af = st->key[PF_SK_WIRE]->af; 6692 /* 6693 * XXX Why do we bother pfsyncing source node information if source 6694 * nodes are not synced? Showing users that there is source tracking 6695 * when there is none seems useless. 6696 */ 6697 if (st->sns[PF_SN_LIMIT] != NULL) 6698 sp->pfs_1301.sync_flags |= PFSYNC_FLAG_SRCNODE; 6699 if (st->sns[PF_SN_NAT] != NULL || st->sns[PF_SN_ROUTE]) 6700 sp->pfs_1301.sync_flags |= PFSYNC_FLAG_NATSRCNODE; 6701 break; 6702 case PFSYNC_MSG_VERSION_1400: 6703 sp->pfs_1400.state_flags = htons(st->state_flags); 6704 sp->pfs_1400.direction = st->direction; 6705 sp->pfs_1400.log = st->act.log; 6706 sp->pfs_1400.timeout = st->timeout; 6707 sp->pfs_1400.proto = st->key[PF_SK_WIRE]->proto; 6708 sp->pfs_1400.af = st->key[PF_SK_WIRE]->af; 6709 sp->pfs_1400.qid = htons(st->act.qid); 6710 sp->pfs_1400.pqid = htons(st->act.pqid); 6711 sp->pfs_1400.dnpipe = htons(st->act.dnpipe); 6712 sp->pfs_1400.dnrpipe = htons(st->act.dnrpipe); 6713 sp->pfs_1400.rtableid = htonl(st->act.rtableid); 6714 sp->pfs_1400.min_ttl = st->act.min_ttl; 6715 sp->pfs_1400.set_tos = st->act.set_tos; 6716 sp->pfs_1400.max_mss = htons(st->act.max_mss); 6717 sp->pfs_1400.set_prio[0] = st->act.set_prio[0]; 6718 sp->pfs_1400.set_prio[1] = st->act.set_prio[1]; 6719 sp->pfs_1400.rt = st->act.rt; 6720 if (st->act.rt_kif) 6721 strlcpy(sp->pfs_1400.rt_ifname, 6722 st->act.rt_kif->pfik_name, 6723 sizeof(sp->pfs_1400.rt_ifname)); 6724 /* 6725 * XXX Why do we bother pfsyncing source node information if source 6726 * nodes are not synced? Showing users that there is source tracking 6727 * when there is none seems useless. 6728 */ 6729 if (st->sns[PF_SN_LIMIT] != NULL) 6730 sp->pfs_1400.sync_flags |= PFSYNC_FLAG_SRCNODE; 6731 if (st->sns[PF_SN_NAT] != NULL || st->sns[PF_SN_ROUTE]) 6732 sp->pfs_1400.sync_flags |= PFSYNC_FLAG_NATSRCNODE; 6733 break; 6734 case PFSYNC_MSG_VERSION_1500: 6735 sp->pfs_1500.state_flags = htons(st->state_flags); 6736 sp->pfs_1500.direction = st->direction; 6737 sp->pfs_1500.log = st->act.log; 6738 sp->pfs_1500.timeout = st->timeout; 6739 sp->pfs_1500.wire_proto = st->key[PF_SK_WIRE]->proto; 6740 sp->pfs_1500.wire_af = st->key[PF_SK_WIRE]->af; 6741 sp->pfs_1500.stack_proto = st->key[PF_SK_STACK]->proto; 6742 sp->pfs_1500.stack_af = st->key[PF_SK_STACK]->af; 6743 sp->pfs_1500.qid = htons(st->act.qid); 6744 sp->pfs_1500.pqid = htons(st->act.pqid); 6745 sp->pfs_1500.dnpipe = htons(st->act.dnpipe); 6746 sp->pfs_1500.dnrpipe = htons(st->act.dnrpipe); 6747 sp->pfs_1500.rtableid = htonl(st->act.rtableid); 6748 sp->pfs_1500.min_ttl = st->act.min_ttl; 6749 sp->pfs_1500.set_tos = st->act.set_tos; 6750 sp->pfs_1500.max_mss = htons(st->act.max_mss); 6751 sp->pfs_1500.set_prio[0] = st->act.set_prio[0]; 6752 sp->pfs_1500.set_prio[1] = st->act.set_prio[1]; 6753 sp->pfs_1500.rt = st->act.rt; 6754 sp->pfs_1500.rt_af = st->act.rt_af; 6755 if (st->act.rt_kif) 6756 strlcpy(sp->pfs_1500.rt_ifname, 6757 st->act.rt_kif->pfik_name, 6758 sizeof(sp->pfs_1500.rt_ifname)); 6759 strlcpy(sp->pfs_1500.orig_ifname, 6760 st->orig_kif->pfik_name, 6761 sizeof(sp->pfs_1500.orig_ifname)); 6762 if ((tagname = pf_tag2tagname(st->tag)) != NULL) 6763 strlcpy(sp->pfs_1500.tagname, tagname, 6764 sizeof(sp->pfs_1500.tagname)); 6765 break; 6766 default: 6767 panic("%s: Unsupported pfsync_msg_version %d", 6768 __func__, msg_version); 6769 } 6770 6771 sp->pfs_1301.id = st->id; 6772 sp->pfs_1301.creatorid = st->creatorid; 6773 pf_state_peer_hton(&st->src, &sp->pfs_1301.src); 6774 pf_state_peer_hton(&st->dst, &sp->pfs_1301.dst); 6775 6776 if (st->rule == NULL) 6777 sp->pfs_1301.rule = htonl(-1); 6778 else 6779 sp->pfs_1301.rule = htonl(st->rule->nr); 6780 if (st->anchor == NULL) 6781 sp->pfs_1301.anchor = htonl(-1); 6782 else 6783 sp->pfs_1301.anchor = htonl(st->anchor->nr); 6784 if (st->nat_rule == NULL) 6785 sp->pfs_1301.nat_rule = htonl(-1); 6786 else 6787 sp->pfs_1301.nat_rule = htonl(st->nat_rule->nr); 6788 6789 pf_state_counter_hton(st->packets[0], sp->pfs_1301.packets[0]); 6790 pf_state_counter_hton(st->packets[1], sp->pfs_1301.packets[1]); 6791 pf_state_counter_hton(st->bytes[0], sp->pfs_1301.bytes[0]); 6792 pf_state_counter_hton(st->bytes[1], sp->pfs_1301.bytes[1]); 6793 } 6794 6795 void 6796 pfsync_state_export_1301(struct pfsync_state_1301 *sp, struct pf_kstate *st) 6797 { 6798 bzero(sp, sizeof(*sp)); 6799 pfsync_state_export((union pfsync_state_union *)sp, st, 6800 PFSYNC_MSG_VERSION_1301); 6801 } 6802 6803 void 6804 pfsync_state_export_1400(struct pfsync_state_1400 *sp, struct pf_kstate *st) 6805 { 6806 bzero(sp, sizeof(*sp)); 6807 pfsync_state_export((union pfsync_state_union *)sp, st, 6808 PFSYNC_MSG_VERSION_1400); 6809 } 6810 6811 void 6812 pfsync_state_export_1500(struct pfsync_state_1500 *sp, struct pf_kstate *st) 6813 { 6814 bzero(sp, sizeof(*sp)); 6815 pfsync_state_export((union pfsync_state_union *)sp, st, 6816 PFSYNC_MSG_VERSION_1500); 6817 } 6818 6819 void 6820 pf_state_export(struct pf_state_export *sp, struct pf_kstate *st) 6821 { 6822 bzero(sp, sizeof(*sp)); 6823 6824 sp->version = PF_STATE_VERSION; 6825 6826 /* copy from state key */ 6827 sp->key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0]; 6828 sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1]; 6829 sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0]; 6830 sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1]; 6831 sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0]; 6832 sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1]; 6833 sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0]; 6834 sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1]; 6835 sp->proto = st->key[PF_SK_WIRE]->proto; 6836 sp->af = st->key[PF_SK_WIRE]->af; 6837 6838 /* copy from state */ 6839 strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname)); 6840 strlcpy(sp->orig_ifname, st->orig_kif->pfik_name, 6841 sizeof(sp->orig_ifname)); 6842 memcpy(&sp->rt_addr, &st->act.rt_addr, sizeof(sp->rt_addr)); 6843 sp->creation = htonl(time_uptime - (st->creation / 1000)); 6844 sp->expire = pf_state_expires(st); 6845 if (sp->expire <= time_uptime) 6846 sp->expire = htonl(0); 6847 else 6848 sp->expire = htonl(sp->expire - time_uptime); 6849 6850 sp->direction = st->direction; 6851 sp->log = st->act.log; 6852 sp->timeout = st->timeout; 6853 /* 8 bits for the old libpfctl, 16 bits for the new libpfctl */ 6854 sp->state_flags_compat = st->state_flags; 6855 sp->state_flags = htons(st->state_flags); 6856 if (st->sns[PF_SN_LIMIT] != NULL) 6857 sp->sync_flags |= PFSYNC_FLAG_SRCNODE; 6858 if (st->sns[PF_SN_NAT] != NULL || st->sns[PF_SN_ROUTE] != NULL) 6859 sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE; 6860 sp->id = st->id; 6861 sp->creatorid = st->creatorid; 6862 pf_state_peer_hton(&st->src, &sp->src); 6863 pf_state_peer_hton(&st->dst, &sp->dst); 6864 6865 if (st->rule == NULL) 6866 sp->rule = htonl(-1); 6867 else 6868 sp->rule = htonl(st->rule->nr); 6869 if (st->anchor == NULL) 6870 sp->anchor = htonl(-1); 6871 else 6872 sp->anchor = htonl(st->anchor->nr); 6873 if (st->nat_rule == NULL) 6874 sp->nat_rule = htonl(-1); 6875 else 6876 sp->nat_rule = htonl(st->nat_rule->nr); 6877 6878 sp->packets[0] = st->packets[0]; 6879 sp->packets[1] = st->packets[1]; 6880 sp->bytes[0] = st->bytes[0]; 6881 sp->bytes[1] = st->bytes[1]; 6882 6883 sp->qid = htons(st->act.qid); 6884 sp->pqid = htons(st->act.pqid); 6885 sp->dnpipe = htons(st->act.dnpipe); 6886 sp->dnrpipe = htons(st->act.dnrpipe); 6887 sp->rtableid = htonl(st->act.rtableid); 6888 sp->min_ttl = st->act.min_ttl; 6889 sp->set_tos = st->act.set_tos; 6890 sp->max_mss = htons(st->act.max_mss); 6891 sp->rt = st->act.rt; 6892 if (st->act.rt_kif) 6893 strlcpy(sp->rt_ifname, st->act.rt_kif->pfik_name, 6894 sizeof(sp->rt_ifname)); 6895 sp->set_prio[0] = st->act.set_prio[0]; 6896 sp->set_prio[1] = st->act.set_prio[1]; 6897 6898 } 6899 6900 static void 6901 pf_tbladdr_copyout(struct pf_addr_wrap *aw) 6902 { 6903 struct pfr_ktable *kt; 6904 6905 KASSERT(aw->type == PF_ADDR_TABLE, ("%s: type %u", __func__, aw->type)); 6906 6907 kt = aw->p.tbl; 6908 if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL) 6909 kt = kt->pfrkt_root; 6910 aw->p.tbl = NULL; 6911 aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ? 6912 kt->pfrkt_cnt : -1; 6913 } 6914 6915 static int 6916 pf_add_status_counters(nvlist_t *nvl, const char *name, counter_u64_t *counters, 6917 size_t number, char **names) 6918 { 6919 nvlist_t *nvc; 6920 6921 nvc = nvlist_create(0); 6922 if (nvc == NULL) 6923 return (ENOMEM); 6924 6925 for (int i = 0; i < number; i++) { 6926 nvlist_append_number_array(nvc, "counters", 6927 counter_u64_fetch(counters[i])); 6928 nvlist_append_string_array(nvc, "names", 6929 names[i]); 6930 nvlist_append_number_array(nvc, "ids", 6931 i); 6932 } 6933 nvlist_add_nvlist(nvl, name, nvc); 6934 nvlist_destroy(nvc); 6935 6936 return (0); 6937 } 6938 6939 static int 6940 pf_getstatus(struct pfioc_nv *nv) 6941 { 6942 nvlist_t *nvl = NULL, *nvc = NULL; 6943 void *nvlpacked = NULL; 6944 int error; 6945 struct pf_status s; 6946 char *pf_reasons[PFRES_MAX+1] = PFRES_NAMES; 6947 char *pf_lcounter[KLCNT_MAX+1] = KLCNT_NAMES; 6948 char *pf_fcounter[FCNT_MAX+1] = FCNT_NAMES; 6949 time_t since; 6950 6951 PF_RULES_RLOCK_TRACKER; 6952 6953 #define ERROUT(x) ERROUT_FUNCTION(errout, x) 6954 6955 PF_RULES_RLOCK(); 6956 6957 nvl = nvlist_create(0); 6958 if (nvl == NULL) 6959 ERROUT(ENOMEM); 6960 6961 since = time_second - (time_uptime - V_pf_status.since); 6962 6963 nvlist_add_bool(nvl, "running", V_pf_status.running); 6964 nvlist_add_number(nvl, "since", since); 6965 nvlist_add_number(nvl, "debug", V_pf_status.debug); 6966 nvlist_add_number(nvl, "hostid", V_pf_status.hostid); 6967 nvlist_add_number(nvl, "states", V_pf_status.states); 6968 nvlist_add_number(nvl, "src_nodes", V_pf_status.src_nodes); 6969 nvlist_add_number(nvl, "reass", V_pf_status.reass); 6970 nvlist_add_bool(nvl, "syncookies_active", 6971 V_pf_status.syncookies_active); 6972 nvlist_add_number(nvl, "halfopen_states", V_pf_status.states_halfopen); 6973 6974 /* counters */ 6975 error = pf_add_status_counters(nvl, "counters", V_pf_status.counters, 6976 PFRES_MAX, pf_reasons); 6977 if (error != 0) 6978 ERROUT(error); 6979 6980 /* lcounters */ 6981 error = pf_add_status_counters(nvl, "lcounters", V_pf_status.lcounters, 6982 KLCNT_MAX, pf_lcounter); 6983 if (error != 0) 6984 ERROUT(error); 6985 6986 /* fcounters */ 6987 nvc = nvlist_create(0); 6988 if (nvc == NULL) 6989 ERROUT(ENOMEM); 6990 6991 for (int i = 0; i < FCNT_MAX; i++) { 6992 nvlist_append_number_array(nvc, "counters", 6993 pf_counter_u64_fetch(&V_pf_status.fcounters[i])); 6994 nvlist_append_string_array(nvc, "names", 6995 pf_fcounter[i]); 6996 nvlist_append_number_array(nvc, "ids", 6997 i); 6998 } 6999 nvlist_add_nvlist(nvl, "fcounters", nvc); 7000 nvlist_destroy(nvc); 7001 nvc = NULL; 7002 7003 /* scounters */ 7004 error = pf_add_status_counters(nvl, "scounters", V_pf_status.scounters, 7005 SCNT_MAX, pf_fcounter); 7006 if (error != 0) 7007 ERROUT(error); 7008 7009 nvlist_add_string(nvl, "ifname", V_pf_status.ifname); 7010 nvlist_add_binary(nvl, "chksum", V_pf_status.pf_chksum, 7011 PF_MD5_DIGEST_LENGTH); 7012 7013 pfi_update_status(V_pf_status.ifname, &s); 7014 7015 /* pcounters / bcounters */ 7016 for (int i = 0; i < 2; i++) { 7017 for (int j = 0; j < 2; j++) { 7018 for (int k = 0; k < 2; k++) { 7019 nvlist_append_number_array(nvl, "pcounters", 7020 s.pcounters[i][j][k]); 7021 } 7022 nvlist_append_number_array(nvl, "bcounters", 7023 s.bcounters[i][j]); 7024 } 7025 } 7026 7027 nvlpacked = nvlist_pack(nvl, &nv->len); 7028 if (nvlpacked == NULL) 7029 ERROUT(ENOMEM); 7030 7031 if (nv->size == 0) 7032 ERROUT(0); 7033 else if (nv->size < nv->len) 7034 ERROUT(ENOSPC); 7035 7036 PF_RULES_RUNLOCK(); 7037 error = copyout(nvlpacked, nv->data, nv->len); 7038 goto done; 7039 7040 #undef ERROUT 7041 errout: 7042 PF_RULES_RUNLOCK(); 7043 done: 7044 free(nvlpacked, M_NVLIST); 7045 nvlist_destroy(nvc); 7046 nvlist_destroy(nvl); 7047 7048 return (error); 7049 } 7050 7051 /* 7052 * XXX - Check for version mismatch!!! 7053 */ 7054 static void 7055 pf_clear_all_states(void) 7056 { 7057 struct epoch_tracker et; 7058 struct pf_kstate *s; 7059 u_int i; 7060 7061 NET_EPOCH_ENTER(et); 7062 for (i = 0; i <= V_pf_hashmask; i++) { 7063 struct pf_idhash *ih = &V_pf_idhash[i]; 7064 relock: 7065 PF_HASHROW_LOCK(ih); 7066 LIST_FOREACH(s, &ih->states, entry) { 7067 s->timeout = PFTM_PURGE; 7068 /* Don't send out individual delete messages. */ 7069 s->state_flags |= PFSTATE_NOSYNC; 7070 pf_remove_state(s); 7071 goto relock; 7072 } 7073 PF_HASHROW_UNLOCK(ih); 7074 } 7075 NET_EPOCH_EXIT(et); 7076 } 7077 7078 static int 7079 pf_clear_tables(void) 7080 { 7081 struct pfioc_table io; 7082 int error; 7083 7084 bzero(&io, sizeof(io)); 7085 io.pfrio_flags |= PFR_FLAG_ALLRSETS; 7086 7087 error = pfr_clr_tables(&io.pfrio_table, &io.pfrio_ndel, 7088 io.pfrio_flags); 7089 7090 return (error); 7091 } 7092 7093 static void 7094 pf_kill_srcnodes(struct pfioc_src_node_kill *psnk) 7095 { 7096 struct pf_ksrc_node_list kill; 7097 u_int killed; 7098 7099 LIST_INIT(&kill); 7100 for (int i = 0; i <= V_pf_srchashmask; i++) { 7101 struct pf_srchash *sh = &V_pf_srchash[i]; 7102 struct pf_ksrc_node *sn, *tmp; 7103 7104 PF_HASHROW_LOCK(sh); 7105 LIST_FOREACH_SAFE(sn, &sh->nodes, entry, tmp) 7106 if (psnk == NULL || 7107 (pf_match_addr(psnk->psnk_src.neg, 7108 &psnk->psnk_src.addr.v.a.addr, 7109 &psnk->psnk_src.addr.v.a.mask, 7110 &sn->addr, sn->af) && 7111 pf_match_addr(psnk->psnk_dst.neg, 7112 &psnk->psnk_dst.addr.v.a.addr, 7113 &psnk->psnk_dst.addr.v.a.mask, 7114 &sn->raddr, sn->af))) { 7115 pf_unlink_src_node(sn); 7116 LIST_INSERT_HEAD(&kill, sn, entry); 7117 sn->expire = 1; 7118 } 7119 PF_HASHROW_UNLOCK(sh); 7120 } 7121 7122 for (int i = 0; i <= V_pf_hashmask; i++) { 7123 struct pf_idhash *ih = &V_pf_idhash[i]; 7124 struct pf_kstate *s; 7125 7126 PF_HASHROW_LOCK(ih); 7127 LIST_FOREACH(s, &ih->states, entry) { 7128 for(pf_sn_types_t sn_type=0; sn_type<PF_SN_MAX; 7129 sn_type++) { 7130 if (s->sns[sn_type] && 7131 s->sns[sn_type]->expire == 1) { 7132 s->sns[sn_type] = NULL; 7133 } 7134 } 7135 } 7136 PF_HASHROW_UNLOCK(ih); 7137 } 7138 7139 killed = pf_free_src_nodes(&kill); 7140 7141 if (psnk != NULL) 7142 psnk->psnk_killed = killed; 7143 } 7144 7145 static int 7146 pf_keepcounters(struct pfioc_nv *nv) 7147 { 7148 nvlist_t *nvl = NULL; 7149 void *nvlpacked = NULL; 7150 int error = 0; 7151 7152 #define ERROUT(x) ERROUT_FUNCTION(on_error, x) 7153 7154 if (nv->len > pf_ioctl_maxcount) 7155 ERROUT(ENOMEM); 7156 7157 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK); 7158 error = copyin(nv->data, nvlpacked, nv->len); 7159 if (error) 7160 ERROUT(error); 7161 7162 nvl = nvlist_unpack(nvlpacked, nv->len, 0); 7163 if (nvl == NULL) 7164 ERROUT(EBADMSG); 7165 7166 if (! nvlist_exists_bool(nvl, "keep_counters")) 7167 ERROUT(EBADMSG); 7168 7169 V_pf_status.keep_counters = nvlist_get_bool(nvl, "keep_counters"); 7170 7171 on_error: 7172 nvlist_destroy(nvl); 7173 free(nvlpacked, M_NVLIST); 7174 return (error); 7175 } 7176 7177 unsigned int 7178 pf_clear_states(const struct pf_kstate_kill *kill) 7179 { 7180 struct pf_state_key_cmp match_key; 7181 struct pf_kstate *s; 7182 struct pfi_kkif *kif; 7183 int idx; 7184 unsigned int killed = 0, dir; 7185 7186 NET_EPOCH_ASSERT(); 7187 7188 for (unsigned int i = 0; i <= V_pf_hashmask; i++) { 7189 struct pf_idhash *ih = &V_pf_idhash[i]; 7190 7191 relock_DIOCCLRSTATES: 7192 PF_HASHROW_LOCK(ih); 7193 LIST_FOREACH(s, &ih->states, entry) { 7194 /* For floating states look at the original kif. */ 7195 kif = s->kif == V_pfi_all ? s->orig_kif : s->kif; 7196 7197 if (kill->psk_ifname[0] && 7198 strcmp(kill->psk_ifname, 7199 kif->pfik_name)) 7200 continue; 7201 7202 if (kill->psk_kill_match) { 7203 bzero(&match_key, sizeof(match_key)); 7204 7205 if (s->direction == PF_OUT) { 7206 dir = PF_IN; 7207 idx = PF_SK_STACK; 7208 } else { 7209 dir = PF_OUT; 7210 idx = PF_SK_WIRE; 7211 } 7212 7213 match_key.af = s->key[idx]->af; 7214 match_key.proto = s->key[idx]->proto; 7215 pf_addrcpy(&match_key.addr[0], 7216 &s->key[idx]->addr[1], match_key.af); 7217 match_key.port[0] = s->key[idx]->port[1]; 7218 pf_addrcpy(&match_key.addr[1], 7219 &s->key[idx]->addr[0], match_key.af); 7220 match_key.port[1] = s->key[idx]->port[0]; 7221 } 7222 7223 /* 7224 * Don't send out individual 7225 * delete messages. 7226 */ 7227 s->state_flags |= PFSTATE_NOSYNC; 7228 pf_remove_state(s); 7229 killed++; 7230 7231 if (kill->psk_kill_match) 7232 killed += pf_kill_matching_state(&match_key, 7233 dir); 7234 7235 goto relock_DIOCCLRSTATES; 7236 } 7237 PF_HASHROW_UNLOCK(ih); 7238 } 7239 7240 if (V_pfsync_clear_states_ptr != NULL) 7241 V_pfsync_clear_states_ptr(V_pf_status.hostid, kill->psk_ifname); 7242 7243 return (killed); 7244 } 7245 7246 void 7247 pf_killstates(struct pf_kstate_kill *kill, unsigned int *killed) 7248 { 7249 struct pf_kstate *s; 7250 7251 NET_EPOCH_ASSERT(); 7252 if (kill->psk_pfcmp.id) { 7253 if (kill->psk_pfcmp.creatorid == 0) 7254 kill->psk_pfcmp.creatorid = V_pf_status.hostid; 7255 if ((s = pf_find_state_byid(kill->psk_pfcmp.id, 7256 kill->psk_pfcmp.creatorid))) { 7257 pf_remove_state(s); 7258 *killed = 1; 7259 } 7260 return; 7261 } 7262 7263 for (unsigned int i = 0; i <= V_pf_hashmask; i++) 7264 *killed += pf_killstates_row(kill, &V_pf_idhash[i]); 7265 } 7266 7267 static int 7268 pf_killstates_nv(struct pfioc_nv *nv) 7269 { 7270 struct pf_kstate_kill kill; 7271 struct epoch_tracker et; 7272 nvlist_t *nvl = NULL; 7273 void *nvlpacked = NULL; 7274 int error = 0; 7275 unsigned int killed = 0; 7276 7277 #define ERROUT(x) ERROUT_FUNCTION(on_error, x) 7278 7279 if (nv->len > pf_ioctl_maxcount) 7280 ERROUT(ENOMEM); 7281 7282 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK); 7283 error = copyin(nv->data, nvlpacked, nv->len); 7284 if (error) 7285 ERROUT(error); 7286 7287 nvl = nvlist_unpack(nvlpacked, nv->len, 0); 7288 if (nvl == NULL) 7289 ERROUT(EBADMSG); 7290 7291 error = pf_nvstate_kill_to_kstate_kill(nvl, &kill); 7292 if (error) 7293 ERROUT(error); 7294 7295 NET_EPOCH_ENTER(et); 7296 pf_killstates(&kill, &killed); 7297 NET_EPOCH_EXIT(et); 7298 7299 free(nvlpacked, M_NVLIST); 7300 nvlpacked = NULL; 7301 nvlist_destroy(nvl); 7302 nvl = nvlist_create(0); 7303 if (nvl == NULL) 7304 ERROUT(ENOMEM); 7305 7306 nvlist_add_number(nvl, "killed", killed); 7307 7308 nvlpacked = nvlist_pack(nvl, &nv->len); 7309 if (nvlpacked == NULL) 7310 ERROUT(ENOMEM); 7311 7312 if (nv->size == 0) 7313 ERROUT(0); 7314 else if (nv->size < nv->len) 7315 ERROUT(ENOSPC); 7316 7317 error = copyout(nvlpacked, nv->data, nv->len); 7318 7319 on_error: 7320 nvlist_destroy(nvl); 7321 free(nvlpacked, M_NVLIST); 7322 return (error); 7323 } 7324 7325 static int 7326 pf_clearstates_nv(struct pfioc_nv *nv) 7327 { 7328 struct pf_kstate_kill kill; 7329 struct epoch_tracker et; 7330 nvlist_t *nvl = NULL; 7331 void *nvlpacked = NULL; 7332 int error = 0; 7333 unsigned int killed; 7334 7335 #define ERROUT(x) ERROUT_FUNCTION(on_error, x) 7336 7337 if (nv->len > pf_ioctl_maxcount) 7338 ERROUT(ENOMEM); 7339 7340 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK); 7341 error = copyin(nv->data, nvlpacked, nv->len); 7342 if (error) 7343 ERROUT(error); 7344 7345 nvl = nvlist_unpack(nvlpacked, nv->len, 0); 7346 if (nvl == NULL) 7347 ERROUT(EBADMSG); 7348 7349 error = pf_nvstate_kill_to_kstate_kill(nvl, &kill); 7350 if (error) 7351 ERROUT(error); 7352 7353 NET_EPOCH_ENTER(et); 7354 killed = pf_clear_states(&kill); 7355 NET_EPOCH_EXIT(et); 7356 7357 free(nvlpacked, M_NVLIST); 7358 nvlpacked = NULL; 7359 nvlist_destroy(nvl); 7360 nvl = nvlist_create(0); 7361 if (nvl == NULL) 7362 ERROUT(ENOMEM); 7363 7364 nvlist_add_number(nvl, "killed", killed); 7365 7366 nvlpacked = nvlist_pack(nvl, &nv->len); 7367 if (nvlpacked == NULL) 7368 ERROUT(ENOMEM); 7369 7370 if (nv->size == 0) 7371 ERROUT(0); 7372 else if (nv->size < nv->len) 7373 ERROUT(ENOSPC); 7374 7375 error = copyout(nvlpacked, nv->data, nv->len); 7376 7377 #undef ERROUT 7378 on_error: 7379 nvlist_destroy(nvl); 7380 free(nvlpacked, M_NVLIST); 7381 return (error); 7382 } 7383 7384 static int 7385 pf_getstate(struct pfioc_nv *nv) 7386 { 7387 nvlist_t *nvl = NULL, *nvls; 7388 void *nvlpacked = NULL; 7389 struct pf_kstate *s = NULL; 7390 int error = 0; 7391 uint64_t id, creatorid; 7392 7393 #define ERROUT(x) ERROUT_FUNCTION(errout, x) 7394 7395 if (nv->len > pf_ioctl_maxcount) 7396 ERROUT(ENOMEM); 7397 7398 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK); 7399 error = copyin(nv->data, nvlpacked, nv->len); 7400 if (error) 7401 ERROUT(error); 7402 7403 nvl = nvlist_unpack(nvlpacked, nv->len, 0); 7404 if (nvl == NULL) 7405 ERROUT(EBADMSG); 7406 7407 PFNV_CHK(pf_nvuint64(nvl, "id", &id)); 7408 PFNV_CHK(pf_nvuint64(nvl, "creatorid", &creatorid)); 7409 7410 s = pf_find_state_byid(id, creatorid); 7411 if (s == NULL) 7412 ERROUT(ENOENT); 7413 7414 free(nvlpacked, M_NVLIST); 7415 nvlpacked = NULL; 7416 nvlist_destroy(nvl); 7417 nvl = nvlist_create(0); 7418 if (nvl == NULL) 7419 ERROUT(ENOMEM); 7420 7421 nvls = pf_state_to_nvstate(s); 7422 if (nvls == NULL) 7423 ERROUT(ENOMEM); 7424 7425 nvlist_add_nvlist(nvl, "state", nvls); 7426 nvlist_destroy(nvls); 7427 7428 nvlpacked = nvlist_pack(nvl, &nv->len); 7429 if (nvlpacked == NULL) 7430 ERROUT(ENOMEM); 7431 7432 if (nv->size == 0) 7433 ERROUT(0); 7434 else if (nv->size < nv->len) 7435 ERROUT(ENOSPC); 7436 7437 error = copyout(nvlpacked, nv->data, nv->len); 7438 7439 #undef ERROUT 7440 errout: 7441 if (s != NULL) 7442 PF_STATE_UNLOCK(s); 7443 free(nvlpacked, M_NVLIST); 7444 nvlist_destroy(nvl); 7445 return (error); 7446 } 7447 7448 /* 7449 * XXX - Check for version mismatch!!! 7450 */ 7451 7452 /* 7453 * Duplicate pfctl -Fa operation to get rid of as much as we can. 7454 */ 7455 static int 7456 shutdown_pf(void) 7457 { 7458 int error = 0; 7459 u_int32_t t[5]; 7460 char nn = '\0'; 7461 struct pf_kanchor *anchor, *tmp_anchor; 7462 struct pf_keth_anchor *eth_anchor, *tmp_eth_anchor; 7463 int rs_num; 7464 7465 do { 7466 /* Unlink rules of all user defined anchors */ 7467 RB_FOREACH_SAFE(anchor, pf_kanchor_global, &V_pf_anchors, 7468 tmp_anchor) { 7469 for (rs_num = 0; rs_num < PF_RULESET_MAX; ++rs_num) { 7470 if ((error = pf_begin_rules(&t[rs_num], rs_num, 7471 anchor->path)) != 0) { 7472 DPFPRINTF(PF_DEBUG_MISC, "%s: " 7473 "anchor.path=%s rs_num=%d", 7474 __func__, anchor->path, rs_num); 7475 goto error; /* XXX: rollback? */ 7476 } 7477 } 7478 for (rs_num = 0; rs_num < PF_RULESET_MAX; ++rs_num) { 7479 error = pf_commit_rules(t[rs_num], rs_num, 7480 anchor->path); 7481 MPASS(error == 0); 7482 } 7483 } 7484 7485 /* Unlink rules of all user defined ether anchors */ 7486 RB_FOREACH_SAFE(eth_anchor, pf_keth_anchor_global, 7487 &V_pf_keth_anchors, tmp_eth_anchor) { 7488 if ((error = pf_begin_eth(&t[0], eth_anchor->path)) 7489 != 0) { 7490 DPFPRINTF(PF_DEBUG_MISC, "%s: eth " 7491 "anchor.path=%s", __func__, 7492 eth_anchor->path); 7493 goto error; 7494 } 7495 error = pf_commit_eth(t[0], eth_anchor->path); 7496 MPASS(error == 0); 7497 } 7498 7499 if ((error = pf_begin_rules(&t[0], PF_RULESET_SCRUB, &nn)) 7500 != 0) { 7501 DPFPRINTF(PF_DEBUG_MISC, "%s: SCRUB", __func__); 7502 break; 7503 } 7504 if ((error = pf_begin_rules(&t[1], PF_RULESET_FILTER, &nn)) 7505 != 0) { 7506 DPFPRINTF(PF_DEBUG_MISC, "%s: FILTER", __func__); 7507 break; /* XXX: rollback? */ 7508 } 7509 if ((error = pf_begin_rules(&t[2], PF_RULESET_NAT, &nn)) 7510 != 0) { 7511 DPFPRINTF(PF_DEBUG_MISC, "%s: NAT", __func__); 7512 break; /* XXX: rollback? */ 7513 } 7514 if ((error = pf_begin_rules(&t[3], PF_RULESET_BINAT, &nn)) 7515 != 0) { 7516 DPFPRINTF(PF_DEBUG_MISC, "%s: BINAT", __func__); 7517 break; /* XXX: rollback? */ 7518 } 7519 if ((error = pf_begin_rules(&t[4], PF_RULESET_RDR, &nn)) 7520 != 0) { 7521 DPFPRINTF(PF_DEBUG_MISC, "%s: RDR", __func__); 7522 break; /* XXX: rollback? */ 7523 } 7524 7525 error = pf_commit_rules(t[0], PF_RULESET_SCRUB, &nn); 7526 MPASS(error == 0); 7527 error = pf_commit_rules(t[1], PF_RULESET_FILTER, &nn); 7528 MPASS(error == 0); 7529 error = pf_commit_rules(t[2], PF_RULESET_NAT, &nn); 7530 MPASS(error == 0); 7531 error = pf_commit_rules(t[3], PF_RULESET_BINAT, &nn); 7532 MPASS(error == 0); 7533 error = pf_commit_rules(t[4], PF_RULESET_RDR, &nn); 7534 MPASS(error == 0); 7535 7536 if ((error = pf_clear_tables()) != 0) 7537 break; 7538 7539 if ((error = pf_begin_eth(&t[0], &nn)) != 0) { 7540 DPFPRINTF(PF_DEBUG_MISC, "%s: eth", __func__); 7541 break; 7542 } 7543 error = pf_commit_eth(t[0], &nn); 7544 MPASS(error == 0); 7545 7546 #ifdef ALTQ 7547 if ((error = pf_begin_altq(&t[0])) != 0) { 7548 DPFPRINTF(PF_DEBUG_MISC, "%s: ALTQ", __func__); 7549 break; 7550 } 7551 pf_commit_altq(t[0]); 7552 #endif 7553 7554 pf_clear_all_states(); 7555 7556 pf_kill_srcnodes(NULL); 7557 7558 for (int i = 0; i < PF_RULESET_MAX; i++) { 7559 pf_rule_tree_free(pf_main_ruleset.rules[i].active.tree); 7560 pf_rule_tree_free(pf_main_ruleset.rules[i].inactive.tree); 7561 } 7562 7563 /* status does not use malloced mem so no need to cleanup */ 7564 /* fingerprints and interfaces have their own cleanup code */ 7565 } while(0); 7566 7567 error: 7568 return (error); 7569 } 7570 7571 static pfil_return_t 7572 pf_check_return(int chk, struct mbuf **m) 7573 { 7574 7575 switch (chk) { 7576 case PF_PASS: 7577 if (*m == NULL) 7578 return (PFIL_CONSUMED); 7579 else 7580 return (PFIL_PASS); 7581 break; 7582 default: 7583 if (*m != NULL) { 7584 m_freem(*m); 7585 *m = NULL; 7586 } 7587 return (PFIL_DROPPED); 7588 } 7589 } 7590 7591 static pfil_return_t 7592 pf_eth_check_in(struct mbuf **m, struct ifnet *ifp, int flags, 7593 void *ruleset __unused, struct inpcb *inp) 7594 { 7595 int chk; 7596 7597 CURVNET_ASSERT_SET(); 7598 7599 chk = pf_test_eth(PF_IN, flags, ifp, m, inp); 7600 7601 return (pf_check_return(chk, m)); 7602 } 7603 7604 static pfil_return_t 7605 pf_eth_check_out(struct mbuf **m, struct ifnet *ifp, int flags, 7606 void *ruleset __unused, struct inpcb *inp) 7607 { 7608 int chk; 7609 7610 CURVNET_ASSERT_SET(); 7611 7612 chk = pf_test_eth(PF_OUT, flags, ifp, m, inp); 7613 7614 return (pf_check_return(chk, m)); 7615 } 7616 7617 #ifdef INET 7618 static pfil_return_t 7619 pf_check_in(struct mbuf **m, struct ifnet *ifp, int flags, 7620 void *ruleset __unused, struct inpcb *inp) 7621 { 7622 int chk; 7623 7624 CURVNET_ASSERT_SET(); 7625 7626 chk = pf_test(AF_INET, PF_IN, flags, ifp, m, inp, NULL); 7627 7628 return (pf_check_return(chk, m)); 7629 } 7630 7631 static pfil_return_t 7632 pf_check_out(struct mbuf **m, struct ifnet *ifp, int flags, 7633 void *ruleset __unused, struct inpcb *inp) 7634 { 7635 int chk; 7636 7637 CURVNET_ASSERT_SET(); 7638 7639 chk = pf_test(AF_INET, PF_OUT, flags, ifp, m, inp, NULL); 7640 7641 return (pf_check_return(chk, m)); 7642 } 7643 #endif 7644 7645 #ifdef INET6 7646 static pfil_return_t 7647 pf_check6_in(struct mbuf **m, struct ifnet *ifp, int flags, 7648 void *ruleset __unused, struct inpcb *inp) 7649 { 7650 int chk; 7651 7652 CURVNET_ASSERT_SET(); 7653 7654 /* 7655 * In case of loopback traffic IPv6 uses the real interface in 7656 * order to support scoped addresses. In order to support stateful 7657 * filtering we have change this to lo0 as it is the case in IPv4. 7658 */ 7659 chk = pf_test(AF_INET6, PF_IN, flags, (*m)->m_flags & M_LOOP ? V_loif : ifp, 7660 m, inp, NULL); 7661 7662 return (pf_check_return(chk, m)); 7663 } 7664 7665 static pfil_return_t 7666 pf_check6_out(struct mbuf **m, struct ifnet *ifp, int flags, 7667 void *ruleset __unused, struct inpcb *inp) 7668 { 7669 int chk; 7670 7671 CURVNET_ASSERT_SET(); 7672 7673 chk = pf_test(AF_INET6, PF_OUT, flags, ifp, m, inp, NULL); 7674 7675 return (pf_check_return(chk, m)); 7676 } 7677 #endif /* INET6 */ 7678 7679 VNET_DEFINE_STATIC(pfil_hook_t, pf_eth_in_hook); 7680 VNET_DEFINE_STATIC(pfil_hook_t, pf_eth_out_hook); 7681 #define V_pf_eth_in_hook VNET(pf_eth_in_hook) 7682 #define V_pf_eth_out_hook VNET(pf_eth_out_hook) 7683 7684 #ifdef INET 7685 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip4_in_hook); 7686 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip4_out_hook); 7687 #define V_pf_ip4_in_hook VNET(pf_ip4_in_hook) 7688 #define V_pf_ip4_out_hook VNET(pf_ip4_out_hook) 7689 #endif 7690 #ifdef INET6 7691 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip6_in_hook); 7692 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip6_out_hook); 7693 #define V_pf_ip6_in_hook VNET(pf_ip6_in_hook) 7694 #define V_pf_ip6_out_hook VNET(pf_ip6_out_hook) 7695 #endif 7696 7697 static void 7698 hook_pf_eth(void) 7699 { 7700 struct pfil_hook_args pha = { 7701 .pa_version = PFIL_VERSION, 7702 .pa_modname = "pf", 7703 .pa_type = PFIL_TYPE_ETHERNET, 7704 }; 7705 struct pfil_link_args pla = { 7706 .pa_version = PFIL_VERSION, 7707 }; 7708 int ret __diagused; 7709 7710 if (atomic_load_bool(&V_pf_pfil_eth_hooked)) 7711 return; 7712 7713 pha.pa_mbuf_chk = pf_eth_check_in; 7714 pha.pa_flags = PFIL_IN; 7715 pha.pa_rulname = "eth-in"; 7716 V_pf_eth_in_hook = pfil_add_hook(&pha); 7717 pla.pa_flags = PFIL_IN | PFIL_HEADPTR | PFIL_HOOKPTR; 7718 pla.pa_head = V_link_pfil_head; 7719 pla.pa_hook = V_pf_eth_in_hook; 7720 ret = pfil_link(&pla); 7721 MPASS(ret == 0); 7722 pha.pa_mbuf_chk = pf_eth_check_out; 7723 pha.pa_flags = PFIL_OUT; 7724 pha.pa_rulname = "eth-out"; 7725 V_pf_eth_out_hook = pfil_add_hook(&pha); 7726 pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR; 7727 pla.pa_head = V_link_pfil_head; 7728 pla.pa_hook = V_pf_eth_out_hook; 7729 ret = pfil_link(&pla); 7730 MPASS(ret == 0); 7731 7732 atomic_store_bool(&V_pf_pfil_eth_hooked, true); 7733 } 7734 7735 static void 7736 hook_pf(void) 7737 { 7738 struct pfil_hook_args pha = { 7739 .pa_version = PFIL_VERSION, 7740 .pa_modname = "pf", 7741 }; 7742 struct pfil_link_args pla = { 7743 .pa_version = PFIL_VERSION, 7744 }; 7745 int ret __diagused; 7746 7747 if (atomic_load_bool(&V_pf_pfil_hooked)) 7748 return; 7749 7750 #ifdef INET 7751 pha.pa_type = PFIL_TYPE_IP4; 7752 pha.pa_mbuf_chk = pf_check_in; 7753 pha.pa_flags = PFIL_IN; 7754 pha.pa_rulname = "default-in"; 7755 V_pf_ip4_in_hook = pfil_add_hook(&pha); 7756 pla.pa_flags = PFIL_IN | PFIL_HEADPTR | PFIL_HOOKPTR; 7757 pla.pa_head = V_inet_pfil_head; 7758 pla.pa_hook = V_pf_ip4_in_hook; 7759 ret = pfil_link(&pla); 7760 MPASS(ret == 0); 7761 pha.pa_mbuf_chk = pf_check_out; 7762 pha.pa_flags = PFIL_OUT; 7763 pha.pa_rulname = "default-out"; 7764 V_pf_ip4_out_hook = pfil_add_hook(&pha); 7765 pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR; 7766 pla.pa_head = V_inet_pfil_head; 7767 pla.pa_hook = V_pf_ip4_out_hook; 7768 ret = pfil_link(&pla); 7769 MPASS(ret == 0); 7770 if (V_pf_filter_local) { 7771 pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR; 7772 pla.pa_head = V_inet_local_pfil_head; 7773 pla.pa_hook = V_pf_ip4_out_hook; 7774 ret = pfil_link(&pla); 7775 MPASS(ret == 0); 7776 } 7777 #endif 7778 #ifdef INET6 7779 pha.pa_type = PFIL_TYPE_IP6; 7780 pha.pa_mbuf_chk = pf_check6_in; 7781 pha.pa_flags = PFIL_IN; 7782 pha.pa_rulname = "default-in6"; 7783 V_pf_ip6_in_hook = pfil_add_hook(&pha); 7784 pla.pa_flags = PFIL_IN | PFIL_HEADPTR | PFIL_HOOKPTR; 7785 pla.pa_head = V_inet6_pfil_head; 7786 pla.pa_hook = V_pf_ip6_in_hook; 7787 ret = pfil_link(&pla); 7788 MPASS(ret == 0); 7789 pha.pa_mbuf_chk = pf_check6_out; 7790 pha.pa_rulname = "default-out6"; 7791 pha.pa_flags = PFIL_OUT; 7792 V_pf_ip6_out_hook = pfil_add_hook(&pha); 7793 pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR; 7794 pla.pa_head = V_inet6_pfil_head; 7795 pla.pa_hook = V_pf_ip6_out_hook; 7796 ret = pfil_link(&pla); 7797 MPASS(ret == 0); 7798 if (V_pf_filter_local) { 7799 pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR; 7800 pla.pa_head = V_inet6_local_pfil_head; 7801 pla.pa_hook = V_pf_ip6_out_hook; 7802 ret = pfil_link(&pla); 7803 MPASS(ret == 0); 7804 } 7805 #endif 7806 7807 atomic_store_bool(&V_pf_pfil_hooked, true); 7808 } 7809 7810 static void 7811 dehook_pf_eth(void) 7812 { 7813 7814 if (!atomic_load_bool(&V_pf_pfil_eth_hooked)) 7815 return; 7816 7817 pfil_remove_hook(V_pf_eth_in_hook); 7818 pfil_remove_hook(V_pf_eth_out_hook); 7819 7820 atomic_store_bool(&V_pf_pfil_eth_hooked, false); 7821 } 7822 7823 static void 7824 dehook_pf(void) 7825 { 7826 7827 if (!atomic_load_bool(&V_pf_pfil_hooked)) 7828 return; 7829 7830 #ifdef INET 7831 pfil_remove_hook(V_pf_ip4_in_hook); 7832 pfil_remove_hook(V_pf_ip4_out_hook); 7833 #endif 7834 #ifdef INET6 7835 pfil_remove_hook(V_pf_ip6_in_hook); 7836 pfil_remove_hook(V_pf_ip6_out_hook); 7837 #endif 7838 7839 atomic_store_bool(&V_pf_pfil_hooked, false); 7840 } 7841 7842 static void 7843 pf_load_vnet(void) 7844 { 7845 V_pf_tag_z = uma_zcreate("pf tags", sizeof(struct pf_tagname), 7846 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); 7847 7848 rm_init_flags(&V_pf_rules_lock, "pf rulesets", RM_RECURSE); 7849 rm_init_flags(&V_pf_tags_lock, "pf tags and queues", RM_RECURSE); 7850 sx_init(&V_pf_ioctl_lock, "pf ioctl"); 7851 7852 pf_init_tagset(&V_pf_tags, &pf_rule_tag_hashsize, 7853 PF_RULE_TAG_HASH_SIZE_DEFAULT); 7854 #ifdef ALTQ 7855 pf_init_tagset(&V_pf_qids, &pf_queue_tag_hashsize, 7856 PF_QUEUE_TAG_HASH_SIZE_DEFAULT); 7857 #endif 7858 7859 V_pf_keth = &V_pf_main_keth_anchor.ruleset; 7860 7861 pfattach_vnet(); 7862 V_pf_vnet_active = 1; 7863 } 7864 7865 static int 7866 pf_load(void) 7867 { 7868 int error; 7869 7870 sx_init(&pf_end_lock, "pf end thread"); 7871 7872 pf_mtag_initialize(); 7873 7874 pf_dev = make_dev(&pf_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, PF_NAME); 7875 if (pf_dev == NULL) 7876 return (ENOMEM); 7877 7878 pf_end_threads = 0; 7879 error = kproc_create(pf_purge_thread, NULL, &pf_purge_proc, 0, 0, "pf purge"); 7880 if (error != 0) 7881 return (error); 7882 7883 pfi_initialize(); 7884 7885 return (0); 7886 } 7887 7888 static void 7889 pf_unload_vnet(void) 7890 { 7891 int ret __diagused; 7892 7893 V_pf_vnet_active = 0; 7894 V_pf_status.running = 0; 7895 dehook_pf(); 7896 dehook_pf_eth(); 7897 7898 PF_RULES_WLOCK(); 7899 pf_syncookies_cleanup(); 7900 shutdown_pf(); 7901 PF_RULES_WUNLOCK(); 7902 7903 ret = swi_remove(V_pf_swi_cookie); 7904 MPASS(ret == 0); 7905 ret = intr_event_destroy(V_pf_swi_ie); 7906 MPASS(ret == 0); 7907 7908 pf_unload_vnet_purge(); 7909 7910 pf_normalize_cleanup(); 7911 PF_RULES_WLOCK(); 7912 pfi_cleanup_vnet(); 7913 PF_RULES_WUNLOCK(); 7914 pfr_cleanup(); 7915 pf_osfp_flush(); 7916 pf_cleanup(); 7917 if (IS_DEFAULT_VNET(curvnet)) 7918 pf_mtag_cleanup(); 7919 7920 pf_cleanup_tagset(&V_pf_tags); 7921 #ifdef ALTQ 7922 pf_cleanup_tagset(&V_pf_qids); 7923 #endif 7924 uma_zdestroy(V_pf_tag_z); 7925 7926 #ifdef PF_WANT_32_TO_64_COUNTER 7927 PF_RULES_WLOCK(); 7928 LIST_REMOVE(V_pf_kifmarker, pfik_allkiflist); 7929 7930 MPASS(LIST_EMPTY(&V_pf_allkiflist)); 7931 MPASS(V_pf_allkifcount == 0); 7932 7933 LIST_REMOVE(&V_pf_default_rule, allrulelist); 7934 V_pf_allrulecount--; 7935 LIST_REMOVE(V_pf_rulemarker, allrulelist); 7936 7937 MPASS(LIST_EMPTY(&V_pf_allrulelist)); 7938 MPASS(V_pf_allrulecount == 0); 7939 7940 PF_RULES_WUNLOCK(); 7941 7942 free(V_pf_kifmarker, PFI_MTYPE); 7943 free(V_pf_rulemarker, M_PFRULE); 7944 #endif 7945 7946 /* Free counters last as we updated them during shutdown. */ 7947 pf_counter_u64_deinit(&V_pf_default_rule.evaluations); 7948 for (int i = 0; i < 2; i++) { 7949 pf_counter_u64_deinit(&V_pf_default_rule.packets[i]); 7950 pf_counter_u64_deinit(&V_pf_default_rule.bytes[i]); 7951 } 7952 counter_u64_free(V_pf_default_rule.states_cur); 7953 counter_u64_free(V_pf_default_rule.states_tot); 7954 for (pf_sn_types_t sn_type=0; sn_type<PF_SN_MAX; sn_type++) 7955 counter_u64_free(V_pf_default_rule.src_nodes[sn_type]); 7956 uma_zfree_pcpu(pf_timestamp_pcpu_zone, V_pf_default_rule.timestamp); 7957 7958 for (int i = 0; i < PFRES_MAX; i++) 7959 counter_u64_free(V_pf_status.counters[i]); 7960 for (int i = 0; i < KLCNT_MAX; i++) 7961 counter_u64_free(V_pf_status.lcounters[i]); 7962 for (int i = 0; i < FCNT_MAX; i++) 7963 pf_counter_u64_deinit(&V_pf_status.fcounters[i]); 7964 for (int i = 0; i < SCNT_MAX; i++) 7965 counter_u64_free(V_pf_status.scounters[i]); 7966 for (int i = 0; i < NCNT_MAX; i++) 7967 counter_u64_free(V_pf_status.ncounters[i]); 7968 7969 rm_destroy(&V_pf_rules_lock); 7970 sx_destroy(&V_pf_ioctl_lock); 7971 } 7972 7973 static void 7974 pf_unload(void *dummy __unused) 7975 { 7976 7977 sx_xlock(&pf_end_lock); 7978 pf_end_threads = 1; 7979 while (pf_end_threads < 2) { 7980 wakeup_one(pf_purge_thread); 7981 sx_sleep(pf_purge_proc, &pf_end_lock, 0, "pftmo", 0); 7982 } 7983 sx_xunlock(&pf_end_lock); 7984 7985 if (pf_dev != NULL) 7986 destroy_dev(pf_dev); 7987 7988 pfi_cleanup(); 7989 7990 sx_destroy(&pf_end_lock); 7991 } 7992 7993 static void 7994 vnet_pf_init(void *unused __unused) 7995 { 7996 7997 pf_load_vnet(); 7998 } 7999 VNET_SYSINIT(vnet_pf_init, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD, 8000 vnet_pf_init, NULL); 8001 8002 static void 8003 vnet_pf_uninit(const void *unused __unused) 8004 { 8005 8006 pf_unload_vnet(); 8007 } 8008 SYSUNINIT(pf_unload, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND, pf_unload, NULL); 8009 VNET_SYSUNINIT(vnet_pf_uninit, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD, 8010 vnet_pf_uninit, NULL); 8011 8012 /* 8013 * The netlink handlers use the per-vnet state: register them after 8014 * vnet_pf_init() and unregister them before vnet_pf_uninit(). 8015 */ 8016 static void 8017 pf_nl_init(void *unused __unused) 8018 { 8019 8020 pf_nl_register(); 8021 } 8022 SYSINIT(pf_nl, SI_SUB_PROTO_FIREWALL, SI_ORDER_FOURTH, pf_nl_init, NULL); 8023 8024 static void 8025 pf_nl_uninit(void *unused __unused) 8026 { 8027 8028 pf_nl_unregister(); 8029 } 8030 SYSUNINIT(pf_nl, SI_SUB_PROTO_FIREWALL, SI_ORDER_FOURTH, pf_nl_uninit, NULL); 8031 8032 static int 8033 pf_modevent(module_t mod, int type, void *data) 8034 { 8035 int error = 0; 8036 8037 switch(type) { 8038 case MOD_LOAD: 8039 error = pf_load(); 8040 break; 8041 case MOD_UNLOAD: 8042 /* Handled in SYSUNINIT(pf_unload) to ensure it's done after 8043 * the vnet_pf_uninit()s */ 8044 break; 8045 default: 8046 error = EINVAL; 8047 break; 8048 } 8049 8050 return (error); 8051 } 8052 8053 static moduledata_t pf_mod = { 8054 "pf", 8055 pf_modevent, 8056 0 8057 }; 8058 8059 DECLARE_MODULE(pf, pf_mod, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND); 8060 MODULE_DEPEND(pf, netlink, 1, 1, 1); 8061 MODULE_DEPEND(pf, crypto, 1, 1, 1); 8062 MODULE_VERSION(pf, PF_MODVER); 8063