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