1 /* $OpenBSD: pf_ioctl.c,v 1.405 2023/05/26 12:13:26 kn Exp $ */ 2 3 /* 4 * Copyright (c) 2001 Daniel Hartmeier 5 * Copyright (c) 2002 - 2018 Henning Brauer <henning@openbsd.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * - Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * - Redistributions in binary form must reproduce the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer in the documentation and/or other materials provided 17 * with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 23 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 * 32 * Effort sponsored in part by the Defense Advanced Research Projects 33 * Agency (DARPA) and Air Force Research Laboratory, Air Force 34 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 35 * 36 */ 37 38 #include "pfsync.h" 39 #include "pflog.h" 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/sysctl.h> 44 #include <sys/mbuf.h> 45 #include <sys/filio.h> 46 #include <sys/fcntl.h> 47 #include <sys/socket.h> 48 #include <sys/socketvar.h> 49 #include <sys/kernel.h> 50 #include <sys/time.h> 51 #include <sys/timeout.h> 52 #include <sys/pool.h> 53 #include <sys/malloc.h> 54 #include <sys/proc.h> 55 #include <sys/rwlock.h> 56 #include <sys/syslog.h> 57 #include <sys/specdev.h> 58 #include <uvm/uvm_extern.h> 59 60 #include <crypto/md5.h> 61 62 #include <net/if.h> 63 #include <net/if_var.h> 64 #include <net/route.h> 65 #include <net/hfsc.h> 66 #include <net/fq_codel.h> 67 68 #include <netinet/in.h> 69 #include <netinet/ip.h> 70 #include <netinet/in_pcb.h> 71 #include <netinet/ip_var.h> 72 #include <netinet/ip_icmp.h> 73 #include <netinet/tcp.h> 74 #include <netinet/udp.h> 75 76 #ifdef INET6 77 #include <netinet/ip6.h> 78 #include <netinet/icmp6.h> 79 #endif /* INET6 */ 80 81 #include <net/pfvar.h> 82 #include <net/pfvar_priv.h> 83 84 #if NPFSYNC > 0 85 #include <netinet/ip_ipsp.h> 86 #include <net/if_pfsync.h> 87 #endif /* NPFSYNC > 0 */ 88 89 struct pool pf_tag_pl; 90 91 void pfattach(int); 92 void pf_thread_create(void *); 93 int pfopen(dev_t, int, int, struct proc *); 94 int pfclose(dev_t, int, int, struct proc *); 95 int pfioctl(dev_t, u_long, caddr_t, int, struct proc *); 96 int pf_begin_rules(u_int32_t *, const char *); 97 void pf_rollback_rules(u_int32_t, char *); 98 void pf_remove_queues(void); 99 int pf_commit_queues(void); 100 void pf_free_queues(struct pf_queuehead *); 101 void pf_calc_chksum(struct pf_ruleset *); 102 void pf_hash_rule(MD5_CTX *, struct pf_rule *); 103 void pf_hash_rule_addr(MD5_CTX *, struct pf_rule_addr *); 104 int pf_commit_rules(u_int32_t, char *); 105 int pf_addr_setup(struct pf_ruleset *, 106 struct pf_addr_wrap *, sa_family_t); 107 struct pfi_kif *pf_kif_setup(struct pfi_kif *); 108 void pf_addr_copyout(struct pf_addr_wrap *); 109 void pf_trans_set_commit(void); 110 void pf_pool_copyin(struct pf_pool *, struct pf_pool *); 111 int pf_validate_range(u_int8_t, u_int16_t[2], int); 112 int pf_rule_copyin(struct pf_rule *, struct pf_rule *); 113 int pf_rule_checkaf(struct pf_rule *); 114 u_int16_t pf_qname2qid(char *, int); 115 void pf_qid2qname(u_int16_t, char *); 116 void pf_qid_unref(u_int16_t); 117 int pf_states_clr(struct pfioc_state_kill *); 118 int pf_states_get(struct pfioc_states *); 119 120 struct pf_trans *pf_open_trans(uint32_t); 121 struct pf_trans *pf_find_trans(uint32_t, uint64_t); 122 void pf_free_trans(struct pf_trans *); 123 void pf_rollback_trans(struct pf_trans *); 124 125 void pf_init_tgetrule(struct pf_trans *, 126 struct pf_anchor *, uint32_t, struct pf_rule *); 127 void pf_cleanup_tgetrule(struct pf_trans *t); 128 129 struct pf_rule pf_default_rule, pf_default_rule_new; 130 131 struct { 132 char statusif[IFNAMSIZ]; 133 u_int32_t debug; 134 u_int32_t hostid; 135 u_int32_t reass; 136 u_int32_t mask; 137 } pf_trans_set; 138 139 #define PF_ORDER_HOST 0 140 #define PF_ORDER_NET 1 141 142 #define PF_TSET_STATUSIF 0x01 143 #define PF_TSET_DEBUG 0x02 144 #define PF_TSET_HOSTID 0x04 145 #define PF_TSET_REASS 0x08 146 147 #define TAGID_MAX 50000 148 TAILQ_HEAD(pf_tags, pf_tagname) pf_tags = TAILQ_HEAD_INITIALIZER(pf_tags), 149 pf_qids = TAILQ_HEAD_INITIALIZER(pf_qids); 150 151 /* 152 * pf_lock protects consistency of PF data structures, which don't have 153 * their dedicated lock yet. The pf_lock currently protects: 154 * - rules, 155 * - radix tables, 156 * - source nodes 157 * All callers must grab pf_lock exclusively. 158 * 159 * pf_state_lock protects consistency of state table. Packets, which do state 160 * look up grab the lock as readers. If packet must create state, then it must 161 * grab the lock as writer. Whenever packet creates state it grabs pf_lock 162 * first then it locks pf_state_lock as the writer. 163 */ 164 struct rwlock pf_lock = RWLOCK_INITIALIZER("pf_lock"); 165 struct rwlock pf_state_lock = RWLOCK_INITIALIZER("pf_state_lock"); 166 struct rwlock pfioctl_rw = RWLOCK_INITIALIZER("pfioctl_rw"); 167 168 struct cpumem *pf_anchor_stack; 169 170 #if (PF_QNAME_SIZE != PF_TAG_NAME_SIZE) 171 #error PF_QNAME_SIZE must be equal to PF_TAG_NAME_SIZE 172 #endif 173 u_int16_t tagname2tag(struct pf_tags *, char *, int); 174 void tag2tagname(struct pf_tags *, u_int16_t, char *); 175 void tag_unref(struct pf_tags *, u_int16_t); 176 int pf_rtlabel_add(struct pf_addr_wrap *); 177 void pf_rtlabel_remove(struct pf_addr_wrap *); 178 void pf_rtlabel_copyout(struct pf_addr_wrap *); 179 180 uint64_t trans_ticket = 1; 181 LIST_HEAD(, pf_trans) pf_ioctl_trans = LIST_HEAD_INITIALIZER(pf_trans); 182 183 void 184 pfattach(int num) 185 { 186 u_int32_t *timeout = pf_default_rule.timeout; 187 struct pf_anchor_stackframe *sf; 188 struct cpumem_iter cmi; 189 190 pool_init(&pf_rule_pl, sizeof(struct pf_rule), 0, 191 IPL_SOFTNET, 0, "pfrule", NULL); 192 pool_init(&pf_src_tree_pl, sizeof(struct pf_src_node), 0, 193 IPL_SOFTNET, 0, "pfsrctr", NULL); 194 pool_init(&pf_sn_item_pl, sizeof(struct pf_sn_item), 0, 195 IPL_SOFTNET, 0, "pfsnitem", NULL); 196 pool_init(&pf_state_pl, sizeof(struct pf_state), 0, 197 IPL_SOFTNET, 0, "pfstate", NULL); 198 pool_init(&pf_state_key_pl, sizeof(struct pf_state_key), 0, 199 IPL_SOFTNET, 0, "pfstkey", NULL); 200 pool_init(&pf_state_item_pl, sizeof(struct pf_state_item), 0, 201 IPL_SOFTNET, 0, "pfstitem", NULL); 202 pool_init(&pf_rule_item_pl, sizeof(struct pf_rule_item), 0, 203 IPL_SOFTNET, 0, "pfruleitem", NULL); 204 pool_init(&pf_queue_pl, sizeof(struct pf_queuespec), 0, 205 IPL_SOFTNET, 0, "pfqueue", NULL); 206 pool_init(&pf_tag_pl, sizeof(struct pf_tagname), 0, 207 IPL_SOFTNET, 0, "pftag", NULL); 208 pool_init(&pf_pktdelay_pl, sizeof(struct pf_pktdelay), 0, 209 IPL_SOFTNET, 0, "pfpktdelay", NULL); 210 pool_init(&pf_anchor_pl, sizeof(struct pf_anchor), 0, 211 IPL_SOFTNET, 0, "pfanchor", NULL); 212 213 hfsc_initialize(); 214 pfr_initialize(); 215 pfi_initialize(); 216 pf_osfp_initialize(); 217 pf_syncookies_init(); 218 219 pool_sethardlimit(pf_pool_limits[PF_LIMIT_STATES].pp, 220 pf_pool_limits[PF_LIMIT_STATES].limit, NULL, 0); 221 pool_sethardlimit(pf_pool_limits[PF_LIMIT_ANCHORS].pp, 222 pf_pool_limits[PF_LIMIT_ANCHORS].limit, NULL, 0); 223 224 if (physmem <= atop(100*1024*1024)) 225 pf_pool_limits[PF_LIMIT_TABLE_ENTRIES].limit = 226 PFR_KENTRY_HIWAT_SMALL; 227 228 RB_INIT(&tree_src_tracking); 229 RB_INIT(&pf_anchors); 230 pf_init_ruleset(&pf_main_ruleset); 231 TAILQ_INIT(&pf_queues[0]); 232 TAILQ_INIT(&pf_queues[1]); 233 pf_queues_active = &pf_queues[0]; 234 pf_queues_inactive = &pf_queues[1]; 235 236 /* default rule should never be garbage collected */ 237 pf_default_rule.entries.tqe_prev = &pf_default_rule.entries.tqe_next; 238 pf_default_rule.action = PF_PASS; 239 pf_default_rule.nr = (u_int32_t)-1; 240 pf_default_rule.rtableid = -1; 241 242 /* initialize default timeouts */ 243 timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL; 244 timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL; 245 timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL; 246 timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL; 247 timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL; 248 timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL; 249 timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL; 250 timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL; 251 timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL; 252 timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL; 253 timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL; 254 timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL; 255 timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL; 256 timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL; 257 timeout[PFTM_FRAG] = PFTM_FRAG_VAL; 258 timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL; 259 timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL; 260 timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL; 261 timeout[PFTM_ADAPTIVE_START] = PFSTATE_ADAPT_START; 262 timeout[PFTM_ADAPTIVE_END] = PFSTATE_ADAPT_END; 263 264 pf_default_rule.src.addr.type = PF_ADDR_ADDRMASK; 265 pf_default_rule.dst.addr.type = PF_ADDR_ADDRMASK; 266 pf_default_rule.rdr.addr.type = PF_ADDR_NONE; 267 pf_default_rule.nat.addr.type = PF_ADDR_NONE; 268 pf_default_rule.route.addr.type = PF_ADDR_NONE; 269 270 pf_normalize_init(); 271 memset(&pf_status, 0, sizeof(pf_status)); 272 pf_status.debug = LOG_ERR; 273 pf_status.reass = PF_REASS_ENABLED; 274 275 /* XXX do our best to avoid a conflict */ 276 pf_status.hostid = arc4random(); 277 278 pf_default_rule_new = pf_default_rule; 279 280 /* 281 * we waste two stack frames as meta-data. 282 * frame[0] always presents a top, which can not be used for data 283 * frame[PF_ANCHOR_STACK_MAX] denotes a bottom of the stack and keeps 284 * the pointer to currently used stack frame. 285 */ 286 pf_anchor_stack = cpumem_malloc( 287 sizeof(struct pf_anchor_stackframe) * (PF_ANCHOR_STACK_MAX + 2), 288 M_WAITOK|M_ZERO); 289 CPUMEM_FOREACH(sf, &cmi, pf_anchor_stack) 290 sf[PF_ANCHOR_STACK_MAX].sf_stack_top = &sf[0]; 291 } 292 293 int 294 pfopen(dev_t dev, int flags, int fmt, struct proc *p) 295 { 296 int unit = minor(dev); 297 298 if (unit & ((1 << CLONE_SHIFT) - 1)) 299 return (ENXIO); 300 301 return (0); 302 } 303 304 int 305 pfclose(dev_t dev, int flags, int fmt, struct proc *p) 306 { 307 struct pf_trans *w, *s; 308 LIST_HEAD(, pf_trans) tmp_list; 309 uint32_t unit = minor(dev); 310 311 LIST_INIT(&tmp_list); 312 rw_enter_write(&pfioctl_rw); 313 LIST_FOREACH_SAFE(w, &pf_ioctl_trans, pft_entry, s) { 314 if (w->pft_unit == unit) { 315 LIST_REMOVE(w, pft_entry); 316 LIST_INSERT_HEAD(&tmp_list, w, pft_entry); 317 } 318 } 319 rw_exit_write(&pfioctl_rw); 320 321 while ((w = LIST_FIRST(&tmp_list)) != NULL) { 322 LIST_REMOVE(w, pft_entry); 323 pf_free_trans(w); 324 } 325 326 return (0); 327 } 328 329 void 330 pf_rule_free(struct pf_rule *rule) 331 { 332 if (rule == NULL) 333 return; 334 335 pfi_kif_free(rule->kif); 336 pfi_kif_free(rule->rcv_kif); 337 pfi_kif_free(rule->rdr.kif); 338 pfi_kif_free(rule->nat.kif); 339 pfi_kif_free(rule->route.kif); 340 341 pool_put(&pf_rule_pl, rule); 342 } 343 344 void 345 pf_rm_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule) 346 { 347 if (rulequeue != NULL) { 348 if (rule->states_cur == 0 && rule->src_nodes == 0) { 349 /* 350 * XXX - we need to remove the table *before* detaching 351 * the rule to make sure the table code does not delete 352 * the anchor under our feet. 353 */ 354 pf_tbladdr_remove(&rule->src.addr); 355 pf_tbladdr_remove(&rule->dst.addr); 356 pf_tbladdr_remove(&rule->rdr.addr); 357 pf_tbladdr_remove(&rule->nat.addr); 358 pf_tbladdr_remove(&rule->route.addr); 359 if (rule->overload_tbl) 360 pfr_detach_table(rule->overload_tbl); 361 } 362 TAILQ_REMOVE(rulequeue, rule, entries); 363 rule->entries.tqe_prev = NULL; 364 rule->nr = (u_int32_t)-1; 365 } 366 367 if (rule->states_cur > 0 || rule->src_nodes > 0 || 368 rule->entries.tqe_prev != NULL) 369 return; 370 pf_tag_unref(rule->tag); 371 pf_tag_unref(rule->match_tag); 372 pf_rtlabel_remove(&rule->src.addr); 373 pf_rtlabel_remove(&rule->dst.addr); 374 pfi_dynaddr_remove(&rule->src.addr); 375 pfi_dynaddr_remove(&rule->dst.addr); 376 pfi_dynaddr_remove(&rule->rdr.addr); 377 pfi_dynaddr_remove(&rule->nat.addr); 378 pfi_dynaddr_remove(&rule->route.addr); 379 if (rulequeue == NULL) { 380 pf_tbladdr_remove(&rule->src.addr); 381 pf_tbladdr_remove(&rule->dst.addr); 382 pf_tbladdr_remove(&rule->rdr.addr); 383 pf_tbladdr_remove(&rule->nat.addr); 384 pf_tbladdr_remove(&rule->route.addr); 385 if (rule->overload_tbl) 386 pfr_detach_table(rule->overload_tbl); 387 } 388 pfi_kif_unref(rule->rcv_kif, PFI_KIF_REF_RULE); 389 pfi_kif_unref(rule->kif, PFI_KIF_REF_RULE); 390 pfi_kif_unref(rule->rdr.kif, PFI_KIF_REF_RULE); 391 pfi_kif_unref(rule->nat.kif, PFI_KIF_REF_RULE); 392 pfi_kif_unref(rule->route.kif, PFI_KIF_REF_RULE); 393 pf_remove_anchor(rule); 394 pool_put(&pf_rule_pl, rule); 395 } 396 397 u_int16_t 398 tagname2tag(struct pf_tags *head, char *tagname, int create) 399 { 400 struct pf_tagname *tag, *p = NULL; 401 u_int16_t new_tagid = 1; 402 403 TAILQ_FOREACH(tag, head, entries) 404 if (strcmp(tagname, tag->name) == 0) { 405 tag->ref++; 406 return (tag->tag); 407 } 408 409 if (!create) 410 return (0); 411 412 /* 413 * to avoid fragmentation, we do a linear search from the beginning 414 * and take the first free slot we find. if there is none or the list 415 * is empty, append a new entry at the end. 416 */ 417 418 /* new entry */ 419 TAILQ_FOREACH(p, head, entries) { 420 if (p->tag != new_tagid) 421 break; 422 new_tagid = p->tag + 1; 423 } 424 425 if (new_tagid > TAGID_MAX) 426 return (0); 427 428 /* allocate and fill new struct pf_tagname */ 429 tag = pool_get(&pf_tag_pl, PR_NOWAIT | PR_ZERO); 430 if (tag == NULL) 431 return (0); 432 strlcpy(tag->name, tagname, sizeof(tag->name)); 433 tag->tag = new_tagid; 434 tag->ref++; 435 436 if (p != NULL) /* insert new entry before p */ 437 TAILQ_INSERT_BEFORE(p, tag, entries); 438 else /* either list empty or no free slot in between */ 439 TAILQ_INSERT_TAIL(head, tag, entries); 440 441 return (tag->tag); 442 } 443 444 void 445 tag2tagname(struct pf_tags *head, u_int16_t tagid, char *p) 446 { 447 struct pf_tagname *tag; 448 449 TAILQ_FOREACH(tag, head, entries) 450 if (tag->tag == tagid) { 451 strlcpy(p, tag->name, PF_TAG_NAME_SIZE); 452 return; 453 } 454 } 455 456 void 457 tag_unref(struct pf_tags *head, u_int16_t tag) 458 { 459 struct pf_tagname *p, *next; 460 461 if (tag == 0) 462 return; 463 464 TAILQ_FOREACH_SAFE(p, head, entries, next) { 465 if (tag == p->tag) { 466 if (--p->ref == 0) { 467 TAILQ_REMOVE(head, p, entries); 468 pool_put(&pf_tag_pl, p); 469 } 470 break; 471 } 472 } 473 } 474 475 u_int16_t 476 pf_tagname2tag(char *tagname, int create) 477 { 478 return (tagname2tag(&pf_tags, tagname, create)); 479 } 480 481 void 482 pf_tag2tagname(u_int16_t tagid, char *p) 483 { 484 tag2tagname(&pf_tags, tagid, p); 485 } 486 487 void 488 pf_tag_ref(u_int16_t tag) 489 { 490 struct pf_tagname *t; 491 492 TAILQ_FOREACH(t, &pf_tags, entries) 493 if (t->tag == tag) 494 break; 495 if (t != NULL) 496 t->ref++; 497 } 498 499 void 500 pf_tag_unref(u_int16_t tag) 501 { 502 tag_unref(&pf_tags, tag); 503 } 504 505 int 506 pf_rtlabel_add(struct pf_addr_wrap *a) 507 { 508 if (a->type == PF_ADDR_RTLABEL && 509 (a->v.rtlabel = rtlabel_name2id(a->v.rtlabelname)) == 0) 510 return (-1); 511 return (0); 512 } 513 514 void 515 pf_rtlabel_remove(struct pf_addr_wrap *a) 516 { 517 if (a->type == PF_ADDR_RTLABEL) 518 rtlabel_unref(a->v.rtlabel); 519 } 520 521 void 522 pf_rtlabel_copyout(struct pf_addr_wrap *a) 523 { 524 if (a->type == PF_ADDR_RTLABEL && a->v.rtlabel) { 525 if (rtlabel_id2name(a->v.rtlabel, a->v.rtlabelname, 526 sizeof(a->v.rtlabelname)) == NULL) 527 strlcpy(a->v.rtlabelname, "?", 528 sizeof(a->v.rtlabelname)); 529 } 530 } 531 532 u_int16_t 533 pf_qname2qid(char *qname, int create) 534 { 535 return (tagname2tag(&pf_qids, qname, create)); 536 } 537 538 void 539 pf_qid2qname(u_int16_t qid, char *p) 540 { 541 tag2tagname(&pf_qids, qid, p); 542 } 543 544 void 545 pf_qid_unref(u_int16_t qid) 546 { 547 tag_unref(&pf_qids, (u_int16_t)qid); 548 } 549 550 int 551 pf_begin_rules(u_int32_t *version, const char *anchor) 552 { 553 struct pf_ruleset *rs; 554 struct pf_rule *rule; 555 556 if ((rs = pf_find_or_create_ruleset(anchor)) == NULL) 557 return (EINVAL); 558 while ((rule = TAILQ_FIRST(rs->rules.inactive.ptr)) != NULL) { 559 pf_rm_rule(rs->rules.inactive.ptr, rule); 560 rs->rules.inactive.rcount--; 561 } 562 *version = ++rs->rules.inactive.version; 563 rs->rules.inactive.open = 1; 564 return (0); 565 } 566 567 void 568 pf_rollback_rules(u_int32_t version, char *anchor) 569 { 570 struct pf_ruleset *rs; 571 struct pf_rule *rule; 572 573 rs = pf_find_ruleset(anchor); 574 if (rs == NULL || !rs->rules.inactive.open || 575 rs->rules.inactive.version != version) 576 return; 577 while ((rule = TAILQ_FIRST(rs->rules.inactive.ptr)) != NULL) { 578 pf_rm_rule(rs->rules.inactive.ptr, rule); 579 rs->rules.inactive.rcount--; 580 } 581 rs->rules.inactive.open = 0; 582 583 /* queue defs only in the main ruleset */ 584 if (anchor[0]) 585 return; 586 587 pf_free_queues(pf_queues_inactive); 588 } 589 590 void 591 pf_free_queues(struct pf_queuehead *where) 592 { 593 struct pf_queuespec *q, *qtmp; 594 595 TAILQ_FOREACH_SAFE(q, where, entries, qtmp) { 596 TAILQ_REMOVE(where, q, entries); 597 pfi_kif_unref(q->kif, PFI_KIF_REF_RULE); 598 pool_put(&pf_queue_pl, q); 599 } 600 } 601 602 void 603 pf_remove_queues(void) 604 { 605 struct pf_queuespec *q; 606 struct ifnet *ifp; 607 608 /* put back interfaces in normal queueing mode */ 609 TAILQ_FOREACH(q, pf_queues_active, entries) { 610 if (q->parent_qid != 0) 611 continue; 612 613 ifp = q->kif->pfik_ifp; 614 if (ifp == NULL) 615 continue; 616 617 ifq_attach(&ifp->if_snd, ifq_priq_ops, NULL); 618 } 619 } 620 621 struct pf_queue_if { 622 struct ifnet *ifp; 623 const struct ifq_ops *ifqops; 624 const struct pfq_ops *pfqops; 625 void *disc; 626 struct pf_queue_if *next; 627 }; 628 629 static inline struct pf_queue_if * 630 pf_ifp2q(struct pf_queue_if *list, struct ifnet *ifp) 631 { 632 struct pf_queue_if *qif = list; 633 634 while (qif != NULL) { 635 if (qif->ifp == ifp) 636 return (qif); 637 638 qif = qif->next; 639 } 640 641 return (qif); 642 } 643 644 int 645 pf_create_queues(void) 646 { 647 struct pf_queuespec *q; 648 struct ifnet *ifp; 649 struct pf_queue_if *list = NULL, *qif; 650 int error; 651 652 /* 653 * Find root queues and allocate traffic conditioner 654 * private data for these interfaces 655 */ 656 TAILQ_FOREACH(q, pf_queues_active, entries) { 657 if (q->parent_qid != 0) 658 continue; 659 660 ifp = q->kif->pfik_ifp; 661 if (ifp == NULL) 662 continue; 663 664 qif = malloc(sizeof(*qif), M_TEMP, M_WAITOK); 665 qif->ifp = ifp; 666 667 if (q->flags & PFQS_ROOTCLASS) { 668 qif->ifqops = ifq_hfsc_ops; 669 qif->pfqops = pfq_hfsc_ops; 670 } else { 671 qif->ifqops = ifq_fqcodel_ops; 672 qif->pfqops = pfq_fqcodel_ops; 673 } 674 675 qif->disc = qif->pfqops->pfq_alloc(ifp); 676 677 qif->next = list; 678 list = qif; 679 } 680 681 /* and now everything */ 682 TAILQ_FOREACH(q, pf_queues_active, entries) { 683 ifp = q->kif->pfik_ifp; 684 if (ifp == NULL) 685 continue; 686 687 qif = pf_ifp2q(list, ifp); 688 KASSERT(qif != NULL); 689 690 error = qif->pfqops->pfq_addqueue(qif->disc, q); 691 if (error != 0) 692 goto error; 693 } 694 695 /* find root queues in old list to disable them if necessary */ 696 TAILQ_FOREACH(q, pf_queues_inactive, entries) { 697 if (q->parent_qid != 0) 698 continue; 699 700 ifp = q->kif->pfik_ifp; 701 if (ifp == NULL) 702 continue; 703 704 qif = pf_ifp2q(list, ifp); 705 if (qif != NULL) 706 continue; 707 708 ifq_attach(&ifp->if_snd, ifq_priq_ops, NULL); 709 } 710 711 /* commit the new queues */ 712 while (list != NULL) { 713 qif = list; 714 list = qif->next; 715 716 ifp = qif->ifp; 717 718 ifq_attach(&ifp->if_snd, qif->ifqops, qif->disc); 719 free(qif, M_TEMP, sizeof(*qif)); 720 } 721 722 return (0); 723 724 error: 725 while (list != NULL) { 726 qif = list; 727 list = qif->next; 728 729 qif->pfqops->pfq_free(qif->disc); 730 free(qif, M_TEMP, sizeof(*qif)); 731 } 732 733 return (error); 734 } 735 736 int 737 pf_commit_queues(void) 738 { 739 struct pf_queuehead *qswap; 740 int error; 741 742 /* swap */ 743 qswap = pf_queues_active; 744 pf_queues_active = pf_queues_inactive; 745 pf_queues_inactive = qswap; 746 747 error = pf_create_queues(); 748 if (error != 0) { 749 pf_queues_inactive = pf_queues_active; 750 pf_queues_active = qswap; 751 return (error); 752 } 753 754 pf_free_queues(pf_queues_inactive); 755 756 return (0); 757 } 758 759 const struct pfq_ops * 760 pf_queue_manager(struct pf_queuespec *q) 761 { 762 if (q->flags & PFQS_FLOWQUEUE) 763 return pfq_fqcodel_ops; 764 return (/* pfq_default_ops */ NULL); 765 } 766 767 #define PF_MD5_UPD(st, elm) \ 768 MD5Update(ctx, (u_int8_t *) &(st)->elm, sizeof((st)->elm)) 769 770 #define PF_MD5_UPD_STR(st, elm) \ 771 MD5Update(ctx, (u_int8_t *) (st)->elm, strlen((st)->elm)) 772 773 #define PF_MD5_UPD_HTONL(st, elm, stor) do { \ 774 (stor) = htonl((st)->elm); \ 775 MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int32_t));\ 776 } while (0) 777 778 #define PF_MD5_UPD_HTONS(st, elm, stor) do { \ 779 (stor) = htons((st)->elm); \ 780 MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int16_t));\ 781 } while (0) 782 783 void 784 pf_hash_rule_addr(MD5_CTX *ctx, struct pf_rule_addr *pfr) 785 { 786 PF_MD5_UPD(pfr, addr.type); 787 switch (pfr->addr.type) { 788 case PF_ADDR_DYNIFTL: 789 PF_MD5_UPD(pfr, addr.v.ifname); 790 PF_MD5_UPD(pfr, addr.iflags); 791 break; 792 case PF_ADDR_TABLE: 793 if (strncmp(pfr->addr.v.tblname, PF_OPTIMIZER_TABLE_PFX, 794 strlen(PF_OPTIMIZER_TABLE_PFX))) 795 PF_MD5_UPD(pfr, addr.v.tblname); 796 break; 797 case PF_ADDR_ADDRMASK: 798 /* XXX ignore af? */ 799 PF_MD5_UPD(pfr, addr.v.a.addr.addr32); 800 PF_MD5_UPD(pfr, addr.v.a.mask.addr32); 801 break; 802 case PF_ADDR_RTLABEL: 803 PF_MD5_UPD(pfr, addr.v.rtlabelname); 804 break; 805 } 806 807 PF_MD5_UPD(pfr, port[0]); 808 PF_MD5_UPD(pfr, port[1]); 809 PF_MD5_UPD(pfr, neg); 810 PF_MD5_UPD(pfr, port_op); 811 } 812 813 void 814 pf_hash_rule(MD5_CTX *ctx, struct pf_rule *rule) 815 { 816 u_int16_t x; 817 u_int32_t y; 818 819 pf_hash_rule_addr(ctx, &rule->src); 820 pf_hash_rule_addr(ctx, &rule->dst); 821 PF_MD5_UPD_STR(rule, label); 822 PF_MD5_UPD_STR(rule, ifname); 823 PF_MD5_UPD_STR(rule, rcv_ifname); 824 PF_MD5_UPD_STR(rule, match_tagname); 825 PF_MD5_UPD_HTONS(rule, match_tag, x); /* dup? */ 826 PF_MD5_UPD_HTONL(rule, os_fingerprint, y); 827 PF_MD5_UPD_HTONL(rule, prob, y); 828 PF_MD5_UPD_HTONL(rule, uid.uid[0], y); 829 PF_MD5_UPD_HTONL(rule, uid.uid[1], y); 830 PF_MD5_UPD(rule, uid.op); 831 PF_MD5_UPD_HTONL(rule, gid.gid[0], y); 832 PF_MD5_UPD_HTONL(rule, gid.gid[1], y); 833 PF_MD5_UPD(rule, gid.op); 834 PF_MD5_UPD_HTONL(rule, rule_flag, y); 835 PF_MD5_UPD(rule, action); 836 PF_MD5_UPD(rule, direction); 837 PF_MD5_UPD(rule, af); 838 PF_MD5_UPD(rule, quick); 839 PF_MD5_UPD(rule, ifnot); 840 PF_MD5_UPD(rule, rcvifnot); 841 PF_MD5_UPD(rule, match_tag_not); 842 PF_MD5_UPD(rule, keep_state); 843 PF_MD5_UPD(rule, proto); 844 PF_MD5_UPD(rule, type); 845 PF_MD5_UPD(rule, code); 846 PF_MD5_UPD(rule, flags); 847 PF_MD5_UPD(rule, flagset); 848 PF_MD5_UPD(rule, allow_opts); 849 PF_MD5_UPD(rule, rt); 850 PF_MD5_UPD(rule, tos); 851 } 852 853 int 854 pf_commit_rules(u_int32_t version, char *anchor) 855 { 856 struct pf_ruleset *rs; 857 struct pf_rule *rule; 858 struct pf_rulequeue *old_rules; 859 u_int32_t old_rcount; 860 861 PF_ASSERT_LOCKED(); 862 863 rs = pf_find_ruleset(anchor); 864 if (rs == NULL || !rs->rules.inactive.open || 865 version != rs->rules.inactive.version) 866 return (EBUSY); 867 868 if (rs == &pf_main_ruleset) 869 pf_calc_chksum(rs); 870 871 /* Swap rules, keep the old. */ 872 old_rules = rs->rules.active.ptr; 873 old_rcount = rs->rules.active.rcount; 874 875 rs->rules.active.ptr = rs->rules.inactive.ptr; 876 rs->rules.active.rcount = rs->rules.inactive.rcount; 877 rs->rules.inactive.ptr = old_rules; 878 rs->rules.inactive.rcount = old_rcount; 879 880 rs->rules.active.version = rs->rules.inactive.version; 881 pf_calc_skip_steps(rs->rules.active.ptr); 882 883 884 /* Purge the old rule list. */ 885 while ((rule = TAILQ_FIRST(old_rules)) != NULL) 886 pf_rm_rule(old_rules, rule); 887 rs->rules.inactive.rcount = 0; 888 rs->rules.inactive.open = 0; 889 pf_remove_if_empty_ruleset(rs); 890 891 /* queue defs only in the main ruleset */ 892 if (anchor[0]) 893 return (0); 894 return (pf_commit_queues()); 895 } 896 897 void 898 pf_calc_chksum(struct pf_ruleset *rs) 899 { 900 MD5_CTX ctx; 901 struct pf_rule *rule; 902 u_int8_t digest[PF_MD5_DIGEST_LENGTH]; 903 904 MD5Init(&ctx); 905 906 if (rs->rules.inactive.rcount) { 907 TAILQ_FOREACH(rule, rs->rules.inactive.ptr, entries) { 908 pf_hash_rule(&ctx, rule); 909 } 910 } 911 912 MD5Final(digest, &ctx); 913 memcpy(pf_status.pf_chksum, digest, sizeof(pf_status.pf_chksum)); 914 } 915 916 int 917 pf_addr_setup(struct pf_ruleset *ruleset, struct pf_addr_wrap *addr, 918 sa_family_t af) 919 { 920 if (pfi_dynaddr_setup(addr, af, PR_WAITOK) || 921 pf_tbladdr_setup(ruleset, addr, PR_WAITOK) || 922 pf_rtlabel_add(addr)) 923 return (EINVAL); 924 925 return (0); 926 } 927 928 struct pfi_kif * 929 pf_kif_setup(struct pfi_kif *kif_buf) 930 { 931 struct pfi_kif *kif; 932 933 if (kif_buf == NULL) 934 return (NULL); 935 936 KASSERT(kif_buf->pfik_name[0] != '\0'); 937 938 kif = pfi_kif_get(kif_buf->pfik_name, &kif_buf); 939 if (kif_buf != NULL) 940 pfi_kif_free(kif_buf); 941 pfi_kif_ref(kif, PFI_KIF_REF_RULE); 942 943 return (kif); 944 } 945 946 void 947 pf_addr_copyout(struct pf_addr_wrap *addr) 948 { 949 pfi_dynaddr_copyout(addr); 950 pf_tbladdr_copyout(addr); 951 pf_rtlabel_copyout(addr); 952 } 953 954 int 955 pf_states_clr(struct pfioc_state_kill *psk) 956 { 957 struct pf_state *st, *nextst; 958 struct pf_state *head, *tail; 959 u_int killed = 0; 960 int error; 961 962 NET_LOCK(); 963 964 /* lock against the gc removing an item from the list */ 965 error = rw_enter(&pf_state_list.pfs_rwl, RW_READ|RW_INTR); 966 if (error != 0) 967 goto unlock; 968 969 /* get a snapshot view of the ends of the list to traverse between */ 970 mtx_enter(&pf_state_list.pfs_mtx); 971 head = TAILQ_FIRST(&pf_state_list.pfs_list); 972 tail = TAILQ_LAST(&pf_state_list.pfs_list, pf_state_queue); 973 mtx_leave(&pf_state_list.pfs_mtx); 974 975 st = NULL; 976 nextst = head; 977 978 PF_LOCK(); 979 PF_STATE_ENTER_WRITE(); 980 981 while (st != tail) { 982 st = nextst; 983 nextst = TAILQ_NEXT(st, entry_list); 984 985 if (st->timeout == PFTM_UNLINKED) 986 continue; 987 988 if (!psk->psk_ifname[0] || !strcmp(psk->psk_ifname, 989 st->kif->pfik_name)) { 990 #if NPFSYNC > 0 991 /* don't send out individual delete messages */ 992 SET(st->state_flags, PFSTATE_NOSYNC); 993 #endif /* NPFSYNC > 0 */ 994 pf_remove_state(st); 995 killed++; 996 } 997 } 998 999 PF_STATE_EXIT_WRITE(); 1000 #if NPFSYNC > 0 1001 pfsync_clear_states(pf_status.hostid, psk->psk_ifname); 1002 #endif /* NPFSYNC > 0 */ 1003 PF_UNLOCK(); 1004 rw_exit(&pf_state_list.pfs_rwl); 1005 1006 psk->psk_killed = killed; 1007 unlock: 1008 NET_UNLOCK(); 1009 1010 return (error); 1011 } 1012 1013 int 1014 pf_states_get(struct pfioc_states *ps) 1015 { 1016 struct pf_state *st, *nextst; 1017 struct pf_state *head, *tail; 1018 struct pfsync_state *p, pstore; 1019 u_int32_t nr = 0; 1020 int error; 1021 1022 if (ps->ps_len == 0) { 1023 nr = pf_status.states; 1024 ps->ps_len = sizeof(struct pfsync_state) * nr; 1025 return (0); 1026 } 1027 1028 p = ps->ps_states; 1029 1030 /* lock against the gc removing an item from the list */ 1031 error = rw_enter(&pf_state_list.pfs_rwl, RW_READ|RW_INTR); 1032 if (error != 0) 1033 return (error); 1034 1035 /* get a snapshot view of the ends of the list to traverse between */ 1036 mtx_enter(&pf_state_list.pfs_mtx); 1037 head = TAILQ_FIRST(&pf_state_list.pfs_list); 1038 tail = TAILQ_LAST(&pf_state_list.pfs_list, pf_state_queue); 1039 mtx_leave(&pf_state_list.pfs_mtx); 1040 1041 st = NULL; 1042 nextst = head; 1043 1044 while (st != tail) { 1045 st = nextst; 1046 nextst = TAILQ_NEXT(st, entry_list); 1047 1048 if (st->timeout == PFTM_UNLINKED) 1049 continue; 1050 1051 if ((nr+1) * sizeof(*p) > ps->ps_len) 1052 break; 1053 1054 pf_state_export(&pstore, st); 1055 error = copyout(&pstore, p, sizeof(*p)); 1056 if (error) 1057 goto fail; 1058 1059 p++; 1060 nr++; 1061 } 1062 ps->ps_len = sizeof(struct pfsync_state) * nr; 1063 1064 fail: 1065 rw_exit(&pf_state_list.pfs_rwl); 1066 1067 return (error); 1068 } 1069 1070 int 1071 pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) 1072 { 1073 int error = 0; 1074 1075 /* XXX keep in sync with switch() below */ 1076 if (securelevel > 1) 1077 switch (cmd) { 1078 case DIOCGETRULES: 1079 case DIOCGETRULE: 1080 case DIOCGETSTATE: 1081 case DIOCSETSTATUSIF: 1082 case DIOCGETSTATUS: 1083 case DIOCCLRSTATUS: 1084 case DIOCNATLOOK: 1085 case DIOCSETDEBUG: 1086 case DIOCGETSTATES: 1087 case DIOCGETTIMEOUT: 1088 case DIOCGETLIMIT: 1089 case DIOCGETRULESETS: 1090 case DIOCGETRULESET: 1091 case DIOCGETQUEUES: 1092 case DIOCGETQUEUE: 1093 case DIOCGETQSTATS: 1094 case DIOCRGETTABLES: 1095 case DIOCRGETTSTATS: 1096 case DIOCRCLRTSTATS: 1097 case DIOCRCLRADDRS: 1098 case DIOCRADDADDRS: 1099 case DIOCRDELADDRS: 1100 case DIOCRSETADDRS: 1101 case DIOCRGETADDRS: 1102 case DIOCRGETASTATS: 1103 case DIOCRCLRASTATS: 1104 case DIOCRTSTADDRS: 1105 case DIOCOSFPGET: 1106 case DIOCGETSRCNODES: 1107 case DIOCCLRSRCNODES: 1108 case DIOCIGETIFACES: 1109 case DIOCSETIFFLAG: 1110 case DIOCCLRIFFLAG: 1111 case DIOCGETSYNFLWATS: 1112 break; 1113 case DIOCRCLRTABLES: 1114 case DIOCRADDTABLES: 1115 case DIOCRDELTABLES: 1116 case DIOCRSETTFLAGS: 1117 if (((struct pfioc_table *)addr)->pfrio_flags & 1118 PFR_FLAG_DUMMY) 1119 break; /* dummy operation ok */ 1120 return (EPERM); 1121 default: 1122 return (EPERM); 1123 } 1124 1125 if (!(flags & FWRITE)) 1126 switch (cmd) { 1127 case DIOCGETRULES: 1128 case DIOCGETSTATE: 1129 case DIOCGETSTATUS: 1130 case DIOCGETSTATES: 1131 case DIOCGETTIMEOUT: 1132 case DIOCGETLIMIT: 1133 case DIOCGETRULESETS: 1134 case DIOCGETRULESET: 1135 case DIOCGETQUEUES: 1136 case DIOCGETQUEUE: 1137 case DIOCGETQSTATS: 1138 case DIOCNATLOOK: 1139 case DIOCRGETTABLES: 1140 case DIOCRGETTSTATS: 1141 case DIOCRGETADDRS: 1142 case DIOCRGETASTATS: 1143 case DIOCRTSTADDRS: 1144 case DIOCOSFPGET: 1145 case DIOCGETSRCNODES: 1146 case DIOCIGETIFACES: 1147 case DIOCGETSYNFLWATS: 1148 break; 1149 case DIOCRCLRTABLES: 1150 case DIOCRADDTABLES: 1151 case DIOCRDELTABLES: 1152 case DIOCRCLRTSTATS: 1153 case DIOCRCLRADDRS: 1154 case DIOCRADDADDRS: 1155 case DIOCRDELADDRS: 1156 case DIOCRSETADDRS: 1157 case DIOCRSETTFLAGS: 1158 if (((struct pfioc_table *)addr)->pfrio_flags & 1159 PFR_FLAG_DUMMY) { 1160 flags |= FWRITE; /* need write lock for dummy */ 1161 break; /* dummy operation ok */ 1162 } 1163 return (EACCES); 1164 case DIOCGETRULE: 1165 if (((struct pfioc_rule *)addr)->action == 1166 PF_GET_CLR_CNTR) 1167 return (EACCES); 1168 break; 1169 default: 1170 return (EACCES); 1171 } 1172 1173 rw_enter_write(&pfioctl_rw); 1174 1175 switch (cmd) { 1176 1177 case DIOCSTART: 1178 NET_LOCK(); 1179 PF_LOCK(); 1180 if (pf_status.running) 1181 error = EEXIST; 1182 else { 1183 pf_status.running = 1; 1184 pf_status.since = getuptime(); 1185 if (pf_status.stateid == 0) { 1186 pf_status.stateid = gettime(); 1187 pf_status.stateid = pf_status.stateid << 32; 1188 } 1189 timeout_add_sec(&pf_purge_to, 1); 1190 pf_create_queues(); 1191 DPFPRINTF(LOG_NOTICE, "pf: started"); 1192 } 1193 PF_UNLOCK(); 1194 NET_UNLOCK(); 1195 break; 1196 1197 case DIOCSTOP: 1198 NET_LOCK(); 1199 PF_LOCK(); 1200 if (!pf_status.running) 1201 error = ENOENT; 1202 else { 1203 pf_status.running = 0; 1204 pf_status.since = getuptime(); 1205 pf_remove_queues(); 1206 DPFPRINTF(LOG_NOTICE, "pf: stopped"); 1207 } 1208 PF_UNLOCK(); 1209 NET_UNLOCK(); 1210 break; 1211 1212 case DIOCGETQUEUES: { 1213 struct pfioc_queue *pq = (struct pfioc_queue *)addr; 1214 struct pf_queuespec *qs; 1215 u_int32_t nr = 0; 1216 1217 PF_LOCK(); 1218 pq->ticket = pf_main_ruleset.rules.active.version; 1219 1220 /* save state to not run over them all each time? */ 1221 qs = TAILQ_FIRST(pf_queues_active); 1222 while (qs != NULL) { 1223 qs = TAILQ_NEXT(qs, entries); 1224 nr++; 1225 } 1226 pq->nr = nr; 1227 PF_UNLOCK(); 1228 break; 1229 } 1230 1231 case DIOCGETQUEUE: { 1232 struct pfioc_queue *pq = (struct pfioc_queue *)addr; 1233 struct pf_queuespec *qs; 1234 u_int32_t nr = 0; 1235 1236 PF_LOCK(); 1237 if (pq->ticket != pf_main_ruleset.rules.active.version) { 1238 error = EBUSY; 1239 PF_UNLOCK(); 1240 goto fail; 1241 } 1242 1243 /* save state to not run over them all each time? */ 1244 qs = TAILQ_FIRST(pf_queues_active); 1245 while ((qs != NULL) && (nr++ < pq->nr)) 1246 qs = TAILQ_NEXT(qs, entries); 1247 if (qs == NULL) { 1248 error = EBUSY; 1249 PF_UNLOCK(); 1250 goto fail; 1251 } 1252 memcpy(&pq->queue, qs, sizeof(pq->queue)); 1253 PF_UNLOCK(); 1254 break; 1255 } 1256 1257 case DIOCGETQSTATS: { 1258 struct pfioc_qstats *pq = (struct pfioc_qstats *)addr; 1259 struct pf_queuespec *qs; 1260 u_int32_t nr; 1261 int nbytes; 1262 1263 NET_LOCK(); 1264 PF_LOCK(); 1265 if (pq->ticket != pf_main_ruleset.rules.active.version) { 1266 error = EBUSY; 1267 PF_UNLOCK(); 1268 NET_UNLOCK(); 1269 goto fail; 1270 } 1271 nbytes = pq->nbytes; 1272 nr = 0; 1273 1274 /* save state to not run over them all each time? */ 1275 qs = TAILQ_FIRST(pf_queues_active); 1276 while ((qs != NULL) && (nr++ < pq->nr)) 1277 qs = TAILQ_NEXT(qs, entries); 1278 if (qs == NULL) { 1279 error = EBUSY; 1280 PF_UNLOCK(); 1281 NET_UNLOCK(); 1282 goto fail; 1283 } 1284 memcpy(&pq->queue, qs, sizeof(pq->queue)); 1285 /* It's a root flow queue but is not an HFSC root class */ 1286 if ((qs->flags & PFQS_FLOWQUEUE) && qs->parent_qid == 0 && 1287 !(qs->flags & PFQS_ROOTCLASS)) 1288 error = pfq_fqcodel_ops->pfq_qstats(qs, pq->buf, 1289 &nbytes); 1290 else 1291 error = pfq_hfsc_ops->pfq_qstats(qs, pq->buf, 1292 &nbytes); 1293 if (error == 0) 1294 pq->nbytes = nbytes; 1295 PF_UNLOCK(); 1296 NET_UNLOCK(); 1297 break; 1298 } 1299 1300 case DIOCADDQUEUE: { 1301 struct pfioc_queue *q = (struct pfioc_queue *)addr; 1302 struct pf_queuespec *qs; 1303 1304 qs = pool_get(&pf_queue_pl, PR_WAITOK|PR_LIMITFAIL|PR_ZERO); 1305 if (qs == NULL) { 1306 error = ENOMEM; 1307 goto fail; 1308 } 1309 1310 NET_LOCK(); 1311 PF_LOCK(); 1312 if (q->ticket != pf_main_ruleset.rules.inactive.version) { 1313 error = EBUSY; 1314 PF_UNLOCK(); 1315 NET_UNLOCK(); 1316 pool_put(&pf_queue_pl, qs); 1317 goto fail; 1318 } 1319 memcpy(qs, &q->queue, sizeof(*qs)); 1320 qs->qid = pf_qname2qid(qs->qname, 1); 1321 if (qs->qid == 0) { 1322 error = EBUSY; 1323 PF_UNLOCK(); 1324 NET_UNLOCK(); 1325 pool_put(&pf_queue_pl, qs); 1326 goto fail; 1327 } 1328 if (qs->parent[0] && (qs->parent_qid = 1329 pf_qname2qid(qs->parent, 0)) == 0) { 1330 error = ESRCH; 1331 PF_UNLOCK(); 1332 NET_UNLOCK(); 1333 pool_put(&pf_queue_pl, qs); 1334 goto fail; 1335 } 1336 qs->kif = pfi_kif_get(qs->ifname, NULL); 1337 if (qs->kif == NULL) { 1338 error = ESRCH; 1339 PF_UNLOCK(); 1340 NET_UNLOCK(); 1341 pool_put(&pf_queue_pl, qs); 1342 goto fail; 1343 } 1344 /* XXX resolve bw percentage specs */ 1345 pfi_kif_ref(qs->kif, PFI_KIF_REF_RULE); 1346 1347 TAILQ_INSERT_TAIL(pf_queues_inactive, qs, entries); 1348 PF_UNLOCK(); 1349 NET_UNLOCK(); 1350 1351 break; 1352 } 1353 1354 case DIOCADDRULE: { 1355 struct pfioc_rule *pr = (struct pfioc_rule *)addr; 1356 struct pf_ruleset *ruleset; 1357 struct pf_rule *rule, *tail; 1358 1359 rule = pool_get(&pf_rule_pl, PR_WAITOK|PR_LIMITFAIL|PR_ZERO); 1360 if (rule == NULL) { 1361 error = ENOMEM; 1362 goto fail; 1363 } 1364 1365 if ((error = pf_rule_copyin(&pr->rule, rule))) { 1366 pf_rule_free(rule); 1367 rule = NULL; 1368 goto fail; 1369 } 1370 1371 if (pr->rule.return_icmp >> 8 > ICMP_MAXTYPE) { 1372 error = EINVAL; 1373 pf_rule_free(rule); 1374 rule = NULL; 1375 goto fail; 1376 } 1377 if ((error = pf_rule_checkaf(rule))) { 1378 pf_rule_free(rule); 1379 rule = NULL; 1380 goto fail; 1381 } 1382 if (rule->src.addr.type == PF_ADDR_NONE || 1383 rule->dst.addr.type == PF_ADDR_NONE) { 1384 error = EINVAL; 1385 pf_rule_free(rule); 1386 rule = NULL; 1387 goto fail; 1388 } 1389 1390 if (rule->rt && !rule->direction) { 1391 error = EINVAL; 1392 pf_rule_free(rule); 1393 rule = NULL; 1394 goto fail; 1395 } 1396 1397 NET_LOCK(); 1398 PF_LOCK(); 1399 pr->anchor[sizeof(pr->anchor) - 1] = '\0'; 1400 ruleset = pf_find_ruleset(pr->anchor); 1401 if (ruleset == NULL) { 1402 error = EINVAL; 1403 PF_UNLOCK(); 1404 NET_UNLOCK(); 1405 pf_rule_free(rule); 1406 goto fail; 1407 } 1408 if (pr->ticket != ruleset->rules.inactive.version) { 1409 error = EBUSY; 1410 PF_UNLOCK(); 1411 NET_UNLOCK(); 1412 pf_rule_free(rule); 1413 goto fail; 1414 } 1415 rule->cuid = p->p_ucred->cr_ruid; 1416 rule->cpid = p->p_p->ps_pid; 1417 1418 tail = TAILQ_LAST(ruleset->rules.inactive.ptr, 1419 pf_rulequeue); 1420 if (tail) 1421 rule->nr = tail->nr + 1; 1422 else 1423 rule->nr = 0; 1424 1425 rule->kif = pf_kif_setup(rule->kif); 1426 rule->rcv_kif = pf_kif_setup(rule->rcv_kif); 1427 rule->rdr.kif = pf_kif_setup(rule->rdr.kif); 1428 rule->nat.kif = pf_kif_setup(rule->nat.kif); 1429 rule->route.kif = pf_kif_setup(rule->route.kif); 1430 1431 if (rule->overload_tblname[0]) { 1432 if ((rule->overload_tbl = pfr_attach_table(ruleset, 1433 rule->overload_tblname, PR_WAITOK)) == NULL) 1434 error = EINVAL; 1435 else 1436 rule->overload_tbl->pfrkt_flags |= PFR_TFLAG_ACTIVE; 1437 } 1438 1439 if (pf_addr_setup(ruleset, &rule->src.addr, rule->af)) 1440 error = EINVAL; 1441 if (pf_addr_setup(ruleset, &rule->dst.addr, rule->af)) 1442 error = EINVAL; 1443 if (pf_addr_setup(ruleset, &rule->rdr.addr, rule->af)) 1444 error = EINVAL; 1445 if (pf_addr_setup(ruleset, &rule->nat.addr, rule->af)) 1446 error = EINVAL; 1447 if (pf_addr_setup(ruleset, &rule->route.addr, rule->af)) 1448 error = EINVAL; 1449 if (pf_anchor_setup(rule, ruleset, pr->anchor_call)) 1450 error = EINVAL; 1451 1452 if (error) { 1453 pf_rm_rule(NULL, rule); 1454 PF_UNLOCK(); 1455 NET_UNLOCK(); 1456 goto fail; 1457 } 1458 TAILQ_INSERT_TAIL(ruleset->rules.inactive.ptr, 1459 rule, entries); 1460 ruleset->rules.inactive.rcount++; 1461 PF_UNLOCK(); 1462 NET_UNLOCK(); 1463 break; 1464 } 1465 1466 case DIOCGETRULES: { 1467 struct pfioc_rule *pr = (struct pfioc_rule *)addr; 1468 struct pf_ruleset *ruleset; 1469 struct pf_rule *rule; 1470 struct pf_trans *t; 1471 u_int32_t ruleset_version; 1472 1473 NET_LOCK(); 1474 PF_LOCK(); 1475 pr->anchor[sizeof(pr->anchor) - 1] = '\0'; 1476 ruleset = pf_find_ruleset(pr->anchor); 1477 if (ruleset == NULL) { 1478 error = EINVAL; 1479 PF_UNLOCK(); 1480 NET_UNLOCK(); 1481 goto fail; 1482 } 1483 rule = TAILQ_LAST(ruleset->rules.active.ptr, pf_rulequeue); 1484 if (rule) 1485 pr->nr = rule->nr + 1; 1486 else 1487 pr->nr = 0; 1488 ruleset_version = ruleset->rules.active.version; 1489 pf_anchor_take(ruleset->anchor); 1490 rule = TAILQ_FIRST(ruleset->rules.active.ptr); 1491 PF_UNLOCK(); 1492 NET_UNLOCK(); 1493 1494 t = pf_open_trans(minor(dev)); 1495 pf_init_tgetrule(t, ruleset->anchor, ruleset_version, rule); 1496 pr->ticket = t->pft_ticket; 1497 1498 break; 1499 } 1500 1501 case DIOCGETRULE: { 1502 struct pfioc_rule *pr = (struct pfioc_rule *)addr; 1503 struct pf_ruleset *ruleset; 1504 struct pf_rule *rule; 1505 struct pf_trans *t; 1506 int i; 1507 1508 t = pf_find_trans(minor(dev), pr->ticket); 1509 if (t == NULL) 1510 return (ENXIO); 1511 KASSERT(t->pft_unit == minor(dev)); 1512 if (t->pft_type != PF_TRANS_GETRULE) 1513 return (EINVAL); 1514 1515 NET_LOCK(); 1516 PF_LOCK(); 1517 KASSERT(t->pftgr_anchor != NULL); 1518 ruleset = &t->pftgr_anchor->ruleset; 1519 if (t->pftgr_version != ruleset->rules.active.version) { 1520 error = EBUSY; 1521 PF_UNLOCK(); 1522 NET_UNLOCK(); 1523 goto fail; 1524 } 1525 rule = t->pftgr_rule; 1526 if (rule == NULL) { 1527 error = ENOENT; 1528 PF_UNLOCK(); 1529 NET_UNLOCK(); 1530 goto fail; 1531 } 1532 memcpy(&pr->rule, rule, sizeof(struct pf_rule)); 1533 memset(&pr->rule.entries, 0, sizeof(pr->rule.entries)); 1534 pr->rule.kif = NULL; 1535 pr->rule.nat.kif = NULL; 1536 pr->rule.rdr.kif = NULL; 1537 pr->rule.route.kif = NULL; 1538 pr->rule.rcv_kif = NULL; 1539 pr->rule.anchor = NULL; 1540 pr->rule.overload_tbl = NULL; 1541 pr->rule.pktrate.limit /= PF_THRESHOLD_MULT; 1542 if (pf_anchor_copyout(ruleset, rule, pr)) { 1543 error = EBUSY; 1544 PF_UNLOCK(); 1545 NET_UNLOCK(); 1546 goto fail; 1547 } 1548 pf_addr_copyout(&pr->rule.src.addr); 1549 pf_addr_copyout(&pr->rule.dst.addr); 1550 pf_addr_copyout(&pr->rule.rdr.addr); 1551 pf_addr_copyout(&pr->rule.nat.addr); 1552 pf_addr_copyout(&pr->rule.route.addr); 1553 for (i = 0; i < PF_SKIP_COUNT; ++i) 1554 if (rule->skip[i].ptr == NULL) 1555 pr->rule.skip[i].nr = (u_int32_t)-1; 1556 else 1557 pr->rule.skip[i].nr = 1558 rule->skip[i].ptr->nr; 1559 1560 if (pr->action == PF_GET_CLR_CNTR) { 1561 rule->evaluations = 0; 1562 rule->packets[0] = rule->packets[1] = 0; 1563 rule->bytes[0] = rule->bytes[1] = 0; 1564 rule->states_tot = 0; 1565 } 1566 pr->nr = rule->nr; 1567 t->pftgr_rule = TAILQ_NEXT(rule, entries); 1568 PF_UNLOCK(); 1569 NET_UNLOCK(); 1570 break; 1571 } 1572 1573 case DIOCCHANGERULE: { 1574 struct pfioc_rule *pcr = (struct pfioc_rule *)addr; 1575 struct pf_ruleset *ruleset; 1576 struct pf_rule *oldrule = NULL, *newrule = NULL; 1577 u_int32_t nr = 0; 1578 1579 if (pcr->action < PF_CHANGE_ADD_HEAD || 1580 pcr->action > PF_CHANGE_GET_TICKET) { 1581 error = EINVAL; 1582 goto fail; 1583 } 1584 1585 if (pcr->action == PF_CHANGE_GET_TICKET) { 1586 NET_LOCK(); 1587 PF_LOCK(); 1588 1589 ruleset = pf_find_ruleset(pcr->anchor); 1590 if (ruleset == NULL) 1591 error = EINVAL; 1592 else 1593 pcr->ticket = ++ruleset->rules.active.version; 1594 1595 PF_UNLOCK(); 1596 NET_UNLOCK(); 1597 goto fail; 1598 } 1599 1600 if (pcr->action != PF_CHANGE_REMOVE) { 1601 newrule = pool_get(&pf_rule_pl, 1602 PR_WAITOK|PR_LIMITFAIL|PR_ZERO); 1603 if (newrule == NULL) { 1604 error = ENOMEM; 1605 goto fail; 1606 } 1607 1608 if (pcr->rule.return_icmp >> 8 > ICMP_MAXTYPE) { 1609 error = EINVAL; 1610 pool_put(&pf_rule_pl, newrule); 1611 goto fail; 1612 } 1613 error = pf_rule_copyin(&pcr->rule, newrule); 1614 if (error != 0) { 1615 pf_rule_free(newrule); 1616 newrule = NULL; 1617 goto fail; 1618 } 1619 if ((error = pf_rule_checkaf(newrule))) { 1620 pf_rule_free(newrule); 1621 newrule = NULL; 1622 goto fail; 1623 } 1624 if (newrule->rt && !newrule->direction) { 1625 pf_rule_free(newrule); 1626 error = EINVAL; 1627 newrule = NULL; 1628 goto fail; 1629 } 1630 } 1631 1632 NET_LOCK(); 1633 PF_LOCK(); 1634 ruleset = pf_find_ruleset(pcr->anchor); 1635 if (ruleset == NULL) { 1636 error = EINVAL; 1637 PF_UNLOCK(); 1638 NET_UNLOCK(); 1639 pf_rule_free(newrule); 1640 goto fail; 1641 } 1642 1643 if (pcr->ticket != ruleset->rules.active.version) { 1644 error = EINVAL; 1645 PF_UNLOCK(); 1646 NET_UNLOCK(); 1647 pf_rule_free(newrule); 1648 goto fail; 1649 } 1650 1651 if (pcr->action != PF_CHANGE_REMOVE) { 1652 KASSERT(newrule != NULL); 1653 newrule->cuid = p->p_ucred->cr_ruid; 1654 newrule->cpid = p->p_p->ps_pid; 1655 1656 newrule->kif = pf_kif_setup(newrule->kif); 1657 newrule->rcv_kif = pf_kif_setup(newrule->rcv_kif); 1658 newrule->rdr.kif = pf_kif_setup(newrule->rdr.kif); 1659 newrule->nat.kif = pf_kif_setup(newrule->nat.kif); 1660 newrule->route.kif = pf_kif_setup(newrule->route.kif); 1661 1662 if (newrule->overload_tblname[0]) { 1663 newrule->overload_tbl = pfr_attach_table( 1664 ruleset, newrule->overload_tblname, 1665 PR_WAITOK); 1666 if (newrule->overload_tbl == NULL) 1667 error = EINVAL; 1668 else 1669 newrule->overload_tbl->pfrkt_flags |= 1670 PFR_TFLAG_ACTIVE; 1671 } 1672 1673 if (pf_addr_setup(ruleset, &newrule->src.addr, 1674 newrule->af)) 1675 error = EINVAL; 1676 if (pf_addr_setup(ruleset, &newrule->dst.addr, 1677 newrule->af)) 1678 error = EINVAL; 1679 if (pf_addr_setup(ruleset, &newrule->rdr.addr, 1680 newrule->af)) 1681 error = EINVAL; 1682 if (pf_addr_setup(ruleset, &newrule->nat.addr, 1683 newrule->af)) 1684 error = EINVAL; 1685 if (pf_addr_setup(ruleset, &newrule->route.addr, 1686 newrule->af)) 1687 error = EINVAL; 1688 if (pf_anchor_setup(newrule, ruleset, pcr->anchor_call)) 1689 error = EINVAL; 1690 1691 if (error) { 1692 pf_rm_rule(NULL, newrule); 1693 PF_UNLOCK(); 1694 NET_UNLOCK(); 1695 goto fail; 1696 } 1697 } 1698 1699 if (pcr->action == PF_CHANGE_ADD_HEAD) 1700 oldrule = TAILQ_FIRST(ruleset->rules.active.ptr); 1701 else if (pcr->action == PF_CHANGE_ADD_TAIL) 1702 oldrule = TAILQ_LAST(ruleset->rules.active.ptr, 1703 pf_rulequeue); 1704 else { 1705 oldrule = TAILQ_FIRST(ruleset->rules.active.ptr); 1706 while ((oldrule != NULL) && (oldrule->nr != pcr->nr)) 1707 oldrule = TAILQ_NEXT(oldrule, entries); 1708 if (oldrule == NULL) { 1709 if (newrule != NULL) 1710 pf_rm_rule(NULL, newrule); 1711 error = EINVAL; 1712 PF_UNLOCK(); 1713 NET_UNLOCK(); 1714 goto fail; 1715 } 1716 } 1717 1718 if (pcr->action == PF_CHANGE_REMOVE) { 1719 pf_rm_rule(ruleset->rules.active.ptr, oldrule); 1720 ruleset->rules.active.rcount--; 1721 } else { 1722 if (oldrule == NULL) 1723 TAILQ_INSERT_TAIL( 1724 ruleset->rules.active.ptr, 1725 newrule, entries); 1726 else if (pcr->action == PF_CHANGE_ADD_HEAD || 1727 pcr->action == PF_CHANGE_ADD_BEFORE) 1728 TAILQ_INSERT_BEFORE(oldrule, newrule, entries); 1729 else 1730 TAILQ_INSERT_AFTER( 1731 ruleset->rules.active.ptr, 1732 oldrule, newrule, entries); 1733 ruleset->rules.active.rcount++; 1734 } 1735 1736 nr = 0; 1737 TAILQ_FOREACH(oldrule, ruleset->rules.active.ptr, entries) 1738 oldrule->nr = nr++; 1739 1740 ruleset->rules.active.version++; 1741 1742 pf_calc_skip_steps(ruleset->rules.active.ptr); 1743 pf_remove_if_empty_ruleset(ruleset); 1744 1745 PF_UNLOCK(); 1746 NET_UNLOCK(); 1747 break; 1748 } 1749 1750 case DIOCCLRSTATES: 1751 error = pf_states_clr((struct pfioc_state_kill *)addr); 1752 break; 1753 1754 case DIOCKILLSTATES: { 1755 struct pf_state *st, *nextst; 1756 struct pf_state_item *si, *sit; 1757 struct pf_state_key *sk, key; 1758 struct pf_addr *srcaddr, *dstaddr; 1759 u_int16_t srcport, dstport; 1760 struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr; 1761 u_int i, killed = 0; 1762 const int dirs[] = { PF_IN, PF_OUT }; 1763 int sidx, didx; 1764 1765 if (psk->psk_pfcmp.id) { 1766 if (psk->psk_pfcmp.creatorid == 0) 1767 psk->psk_pfcmp.creatorid = pf_status.hostid; 1768 NET_LOCK(); 1769 PF_LOCK(); 1770 PF_STATE_ENTER_WRITE(); 1771 if ((st = pf_find_state_byid(&psk->psk_pfcmp))) { 1772 pf_remove_state(st); 1773 psk->psk_killed = 1; 1774 } 1775 PF_STATE_EXIT_WRITE(); 1776 PF_UNLOCK(); 1777 NET_UNLOCK(); 1778 goto fail; 1779 } 1780 1781 if (psk->psk_af && psk->psk_proto && 1782 psk->psk_src.port_op == PF_OP_EQ && 1783 psk->psk_dst.port_op == PF_OP_EQ) { 1784 1785 key.af = psk->psk_af; 1786 key.proto = psk->psk_proto; 1787 key.rdomain = psk->psk_rdomain; 1788 1789 NET_LOCK(); 1790 PF_LOCK(); 1791 PF_STATE_ENTER_WRITE(); 1792 for (i = 0; i < nitems(dirs); i++) { 1793 if (dirs[i] == PF_IN) { 1794 sidx = 0; 1795 didx = 1; 1796 } else { 1797 sidx = 1; 1798 didx = 0; 1799 } 1800 pf_addrcpy(&key.addr[sidx], 1801 &psk->psk_src.addr.v.a.addr, key.af); 1802 pf_addrcpy(&key.addr[didx], 1803 &psk->psk_dst.addr.v.a.addr, key.af); 1804 key.port[sidx] = psk->psk_src.port[0]; 1805 key.port[didx] = psk->psk_dst.port[0]; 1806 1807 sk = RBT_FIND(pf_state_tree, &pf_statetbl, 1808 &key); 1809 if (sk == NULL) 1810 continue; 1811 1812 TAILQ_FOREACH_SAFE(si, &sk->sk_states, 1813 si_entry, sit) { 1814 struct pf_state *sist = si->si_st; 1815 if (((sist->key[PF_SK_WIRE]->af == 1816 sist->key[PF_SK_STACK]->af && 1817 sk == (dirs[i] == PF_IN ? 1818 sist->key[PF_SK_WIRE] : 1819 sist->key[PF_SK_STACK])) || 1820 (sist->key[PF_SK_WIRE]->af != 1821 sist->key[PF_SK_STACK]->af && 1822 dirs[i] == PF_IN && 1823 (sk == sist->key[PF_SK_STACK] || 1824 sk == sist->key[PF_SK_WIRE]))) && 1825 (!psk->psk_ifname[0] || 1826 (sist->kif != pfi_all && 1827 !strcmp(psk->psk_ifname, 1828 sist->kif->pfik_name)))) { 1829 pf_remove_state(sist); 1830 killed++; 1831 } 1832 } 1833 } 1834 if (killed) 1835 psk->psk_killed = killed; 1836 PF_STATE_EXIT_WRITE(); 1837 PF_UNLOCK(); 1838 NET_UNLOCK(); 1839 goto fail; 1840 } 1841 1842 NET_LOCK(); 1843 PF_LOCK(); 1844 PF_STATE_ENTER_WRITE(); 1845 RBT_FOREACH_SAFE(st, pf_state_tree_id, &tree_id, nextst) { 1846 if (st->direction == PF_OUT) { 1847 sk = st->key[PF_SK_STACK]; 1848 srcaddr = &sk->addr[1]; 1849 dstaddr = &sk->addr[0]; 1850 srcport = sk->port[1]; 1851 dstport = sk->port[0]; 1852 } else { 1853 sk = st->key[PF_SK_WIRE]; 1854 srcaddr = &sk->addr[0]; 1855 dstaddr = &sk->addr[1]; 1856 srcport = sk->port[0]; 1857 dstport = sk->port[1]; 1858 } 1859 if ((!psk->psk_af || sk->af == psk->psk_af) 1860 && (!psk->psk_proto || psk->psk_proto == 1861 sk->proto) && psk->psk_rdomain == sk->rdomain && 1862 pf_match_addr(psk->psk_src.neg, 1863 &psk->psk_src.addr.v.a.addr, 1864 &psk->psk_src.addr.v.a.mask, 1865 srcaddr, sk->af) && 1866 pf_match_addr(psk->psk_dst.neg, 1867 &psk->psk_dst.addr.v.a.addr, 1868 &psk->psk_dst.addr.v.a.mask, 1869 dstaddr, sk->af) && 1870 (psk->psk_src.port_op == 0 || 1871 pf_match_port(psk->psk_src.port_op, 1872 psk->psk_src.port[0], psk->psk_src.port[1], 1873 srcport)) && 1874 (psk->psk_dst.port_op == 0 || 1875 pf_match_port(psk->psk_dst.port_op, 1876 psk->psk_dst.port[0], psk->psk_dst.port[1], 1877 dstport)) && 1878 (!psk->psk_label[0] || (st->rule.ptr->label[0] && 1879 !strcmp(psk->psk_label, st->rule.ptr->label))) && 1880 (!psk->psk_ifname[0] || !strcmp(psk->psk_ifname, 1881 st->kif->pfik_name))) { 1882 pf_remove_state(st); 1883 killed++; 1884 } 1885 } 1886 psk->psk_killed = killed; 1887 PF_STATE_EXIT_WRITE(); 1888 PF_UNLOCK(); 1889 NET_UNLOCK(); 1890 break; 1891 } 1892 1893 #if NPFSYNC > 0 1894 case DIOCADDSTATE: { 1895 struct pfioc_state *ps = (struct pfioc_state *)addr; 1896 struct pfsync_state *sp = &ps->state; 1897 1898 if (sp->timeout >= PFTM_MAX) { 1899 error = EINVAL; 1900 goto fail; 1901 } 1902 NET_LOCK(); 1903 PF_LOCK(); 1904 error = pf_state_import(sp, PFSYNC_SI_IOCTL); 1905 PF_UNLOCK(); 1906 NET_UNLOCK(); 1907 break; 1908 } 1909 #endif /* NPFSYNC > 0 */ 1910 1911 case DIOCGETSTATE: { 1912 struct pfioc_state *ps = (struct pfioc_state *)addr; 1913 struct pf_state *st; 1914 struct pf_state_cmp id_key; 1915 1916 memset(&id_key, 0, sizeof(id_key)); 1917 id_key.id = ps->state.id; 1918 id_key.creatorid = ps->state.creatorid; 1919 1920 NET_LOCK(); 1921 PF_STATE_ENTER_READ(); 1922 st = pf_find_state_byid(&id_key); 1923 st = pf_state_ref(st); 1924 PF_STATE_EXIT_READ(); 1925 NET_UNLOCK(); 1926 if (st == NULL) { 1927 error = ENOENT; 1928 goto fail; 1929 } 1930 1931 pf_state_export(&ps->state, st); 1932 pf_state_unref(st); 1933 break; 1934 } 1935 1936 case DIOCGETSTATES: 1937 error = pf_states_get((struct pfioc_states *)addr); 1938 break; 1939 1940 case DIOCGETSTATUS: { 1941 struct pf_status *s = (struct pf_status *)addr; 1942 NET_LOCK(); 1943 PF_LOCK(); 1944 memcpy(s, &pf_status, sizeof(struct pf_status)); 1945 pfi_update_status(s->ifname, s); 1946 PF_UNLOCK(); 1947 NET_UNLOCK(); 1948 break; 1949 } 1950 1951 case DIOCSETSTATUSIF: { 1952 struct pfioc_iface *pi = (struct pfioc_iface *)addr; 1953 1954 NET_LOCK(); 1955 PF_LOCK(); 1956 if (pi->pfiio_name[0] == 0) { 1957 memset(pf_status.ifname, 0, IFNAMSIZ); 1958 PF_UNLOCK(); 1959 NET_UNLOCK(); 1960 goto fail; 1961 } 1962 strlcpy(pf_trans_set.statusif, pi->pfiio_name, IFNAMSIZ); 1963 pf_trans_set.mask |= PF_TSET_STATUSIF; 1964 PF_UNLOCK(); 1965 NET_UNLOCK(); 1966 break; 1967 } 1968 1969 case DIOCCLRSTATUS: { 1970 struct pfioc_iface *pi = (struct pfioc_iface *)addr; 1971 1972 NET_LOCK(); 1973 PF_LOCK(); 1974 /* if ifname is specified, clear counters there only */ 1975 if (pi->pfiio_name[0]) { 1976 pfi_update_status(pi->pfiio_name, NULL); 1977 PF_UNLOCK(); 1978 NET_UNLOCK(); 1979 goto fail; 1980 } 1981 1982 memset(pf_status.counters, 0, sizeof(pf_status.counters)); 1983 memset(pf_status.fcounters, 0, sizeof(pf_status.fcounters)); 1984 memset(pf_status.scounters, 0, sizeof(pf_status.scounters)); 1985 pf_status.since = getuptime(); 1986 1987 PF_UNLOCK(); 1988 NET_UNLOCK(); 1989 break; 1990 } 1991 1992 case DIOCNATLOOK: { 1993 struct pfioc_natlook *pnl = (struct pfioc_natlook *)addr; 1994 struct pf_state_key *sk; 1995 struct pf_state *st; 1996 struct pf_state_key_cmp key; 1997 int m = 0, direction = pnl->direction; 1998 int sidx, didx; 1999 2000 switch (pnl->af) { 2001 case AF_INET: 2002 break; 2003 #ifdef INET6 2004 case AF_INET6: 2005 break; 2006 #endif /* INET6 */ 2007 default: 2008 error = EAFNOSUPPORT; 2009 goto fail; 2010 } 2011 2012 /* NATLOOK src and dst are reversed, so reverse sidx/didx */ 2013 sidx = (direction == PF_IN) ? 1 : 0; 2014 didx = (direction == PF_IN) ? 0 : 1; 2015 2016 if (!pnl->proto || 2017 PF_AZERO(&pnl->saddr, pnl->af) || 2018 PF_AZERO(&pnl->daddr, pnl->af) || 2019 ((pnl->proto == IPPROTO_TCP || 2020 pnl->proto == IPPROTO_UDP) && 2021 (!pnl->dport || !pnl->sport)) || 2022 pnl->rdomain > RT_TABLEID_MAX) 2023 error = EINVAL; 2024 else { 2025 key.af = pnl->af; 2026 key.proto = pnl->proto; 2027 key.rdomain = pnl->rdomain; 2028 pf_addrcpy(&key.addr[sidx], &pnl->saddr, pnl->af); 2029 key.port[sidx] = pnl->sport; 2030 pf_addrcpy(&key.addr[didx], &pnl->daddr, pnl->af); 2031 key.port[didx] = pnl->dport; 2032 2033 NET_LOCK(); 2034 PF_STATE_ENTER_READ(); 2035 st = pf_find_state_all(&key, direction, &m); 2036 st = pf_state_ref(st); 2037 PF_STATE_EXIT_READ(); 2038 NET_UNLOCK(); 2039 2040 if (m > 1) 2041 error = E2BIG; /* more than one state */ 2042 else if (st != NULL) { 2043 sk = st->key[sidx]; 2044 pf_addrcpy(&pnl->rsaddr, &sk->addr[sidx], 2045 sk->af); 2046 pnl->rsport = sk->port[sidx]; 2047 pf_addrcpy(&pnl->rdaddr, &sk->addr[didx], 2048 sk->af); 2049 pnl->rdport = sk->port[didx]; 2050 pnl->rrdomain = sk->rdomain; 2051 } else 2052 error = ENOENT; 2053 pf_state_unref(st); 2054 } 2055 break; 2056 } 2057 2058 case DIOCSETTIMEOUT: { 2059 struct pfioc_tm *pt = (struct pfioc_tm *)addr; 2060 2061 if (pt->timeout < 0 || pt->timeout >= PFTM_MAX || 2062 pt->seconds < 0) { 2063 error = EINVAL; 2064 goto fail; 2065 } 2066 NET_LOCK(); 2067 PF_LOCK(); 2068 if (pt->timeout == PFTM_INTERVAL && pt->seconds == 0) 2069 pt->seconds = 1; 2070 pf_default_rule_new.timeout[pt->timeout] = pt->seconds; 2071 pt->seconds = pf_default_rule.timeout[pt->timeout]; 2072 PF_UNLOCK(); 2073 NET_UNLOCK(); 2074 break; 2075 } 2076 2077 case DIOCGETTIMEOUT: { 2078 struct pfioc_tm *pt = (struct pfioc_tm *)addr; 2079 2080 if (pt->timeout < 0 || pt->timeout >= PFTM_MAX) { 2081 error = EINVAL; 2082 goto fail; 2083 } 2084 PF_LOCK(); 2085 pt->seconds = pf_default_rule.timeout[pt->timeout]; 2086 PF_UNLOCK(); 2087 break; 2088 } 2089 2090 case DIOCGETLIMIT: { 2091 struct pfioc_limit *pl = (struct pfioc_limit *)addr; 2092 2093 if (pl->index < 0 || pl->index >= PF_LIMIT_MAX) { 2094 error = EINVAL; 2095 goto fail; 2096 } 2097 PF_LOCK(); 2098 pl->limit = pf_pool_limits[pl->index].limit; 2099 PF_UNLOCK(); 2100 break; 2101 } 2102 2103 case DIOCSETLIMIT: { 2104 struct pfioc_limit *pl = (struct pfioc_limit *)addr; 2105 2106 PF_LOCK(); 2107 if (pl->index < 0 || pl->index >= PF_LIMIT_MAX) { 2108 error = EINVAL; 2109 PF_UNLOCK(); 2110 goto fail; 2111 } 2112 if (((struct pool *)pf_pool_limits[pl->index].pp)->pr_nout > 2113 pl->limit) { 2114 error = EBUSY; 2115 PF_UNLOCK(); 2116 goto fail; 2117 } 2118 /* Fragments reference mbuf clusters. */ 2119 if (pl->index == PF_LIMIT_FRAGS && pl->limit > nmbclust) { 2120 error = EINVAL; 2121 PF_UNLOCK(); 2122 goto fail; 2123 } 2124 2125 pf_pool_limits[pl->index].limit_new = pl->limit; 2126 pl->limit = pf_pool_limits[pl->index].limit; 2127 PF_UNLOCK(); 2128 break; 2129 } 2130 2131 case DIOCSETDEBUG: { 2132 u_int32_t *level = (u_int32_t *)addr; 2133 2134 NET_LOCK(); 2135 PF_LOCK(); 2136 pf_trans_set.debug = *level; 2137 pf_trans_set.mask |= PF_TSET_DEBUG; 2138 PF_UNLOCK(); 2139 NET_UNLOCK(); 2140 break; 2141 } 2142 2143 case DIOCGETRULESETS: { 2144 struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr; 2145 struct pf_ruleset *ruleset; 2146 struct pf_anchor *anchor; 2147 2148 PF_LOCK(); 2149 pr->path[sizeof(pr->path) - 1] = '\0'; 2150 if ((ruleset = pf_find_ruleset(pr->path)) == NULL) { 2151 error = EINVAL; 2152 PF_UNLOCK(); 2153 goto fail; 2154 } 2155 pr->nr = 0; 2156 if (ruleset == &pf_main_ruleset) { 2157 /* XXX kludge for pf_main_ruleset */ 2158 RB_FOREACH(anchor, pf_anchor_global, &pf_anchors) 2159 if (anchor->parent == NULL) 2160 pr->nr++; 2161 } else { 2162 RB_FOREACH(anchor, pf_anchor_node, 2163 &ruleset->anchor->children) 2164 pr->nr++; 2165 } 2166 PF_UNLOCK(); 2167 break; 2168 } 2169 2170 case DIOCGETRULESET: { 2171 struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr; 2172 struct pf_ruleset *ruleset; 2173 struct pf_anchor *anchor; 2174 u_int32_t nr = 0; 2175 2176 PF_LOCK(); 2177 pr->path[sizeof(pr->path) - 1] = '\0'; 2178 if ((ruleset = pf_find_ruleset(pr->path)) == NULL) { 2179 error = EINVAL; 2180 PF_UNLOCK(); 2181 goto fail; 2182 } 2183 pr->name[0] = '\0'; 2184 if (ruleset == &pf_main_ruleset) { 2185 /* XXX kludge for pf_main_ruleset */ 2186 RB_FOREACH(anchor, pf_anchor_global, &pf_anchors) 2187 if (anchor->parent == NULL && nr++ == pr->nr) { 2188 strlcpy(pr->name, anchor->name, 2189 sizeof(pr->name)); 2190 break; 2191 } 2192 } else { 2193 RB_FOREACH(anchor, pf_anchor_node, 2194 &ruleset->anchor->children) 2195 if (nr++ == pr->nr) { 2196 strlcpy(pr->name, anchor->name, 2197 sizeof(pr->name)); 2198 break; 2199 } 2200 } 2201 PF_UNLOCK(); 2202 if (!pr->name[0]) 2203 error = EBUSY; 2204 break; 2205 } 2206 2207 case DIOCRCLRTABLES: { 2208 struct pfioc_table *io = (struct pfioc_table *)addr; 2209 2210 if (io->pfrio_esize != 0) { 2211 error = ENODEV; 2212 goto fail; 2213 } 2214 NET_LOCK(); 2215 PF_LOCK(); 2216 error = pfr_clr_tables(&io->pfrio_table, &io->pfrio_ndel, 2217 io->pfrio_flags | PFR_FLAG_USERIOCTL); 2218 PF_UNLOCK(); 2219 NET_UNLOCK(); 2220 break; 2221 } 2222 2223 case DIOCRADDTABLES: { 2224 struct pfioc_table *io = (struct pfioc_table *)addr; 2225 2226 if (io->pfrio_esize != sizeof(struct pfr_table)) { 2227 error = ENODEV; 2228 goto fail; 2229 } 2230 error = pfr_add_tables(io->pfrio_buffer, io->pfrio_size, 2231 &io->pfrio_nadd, io->pfrio_flags | PFR_FLAG_USERIOCTL); 2232 break; 2233 } 2234 2235 case DIOCRDELTABLES: { 2236 struct pfioc_table *io = (struct pfioc_table *)addr; 2237 2238 if (io->pfrio_esize != sizeof(struct pfr_table)) { 2239 error = ENODEV; 2240 goto fail; 2241 } 2242 NET_LOCK(); 2243 PF_LOCK(); 2244 error = pfr_del_tables(io->pfrio_buffer, io->pfrio_size, 2245 &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL); 2246 PF_UNLOCK(); 2247 NET_UNLOCK(); 2248 break; 2249 } 2250 2251 case DIOCRGETTABLES: { 2252 struct pfioc_table *io = (struct pfioc_table *)addr; 2253 2254 if (io->pfrio_esize != sizeof(struct pfr_table)) { 2255 error = ENODEV; 2256 goto fail; 2257 } 2258 NET_LOCK(); 2259 PF_LOCK(); 2260 error = pfr_get_tables(&io->pfrio_table, io->pfrio_buffer, 2261 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); 2262 PF_UNLOCK(); 2263 NET_UNLOCK(); 2264 break; 2265 } 2266 2267 case DIOCRGETTSTATS: { 2268 struct pfioc_table *io = (struct pfioc_table *)addr; 2269 2270 if (io->pfrio_esize != sizeof(struct pfr_tstats)) { 2271 error = ENODEV; 2272 goto fail; 2273 } 2274 NET_LOCK(); 2275 PF_LOCK(); 2276 error = pfr_get_tstats(&io->pfrio_table, io->pfrio_buffer, 2277 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); 2278 PF_UNLOCK(); 2279 NET_UNLOCK(); 2280 break; 2281 } 2282 2283 case DIOCRCLRTSTATS: { 2284 struct pfioc_table *io = (struct pfioc_table *)addr; 2285 2286 if (io->pfrio_esize != sizeof(struct pfr_table)) { 2287 error = ENODEV; 2288 goto fail; 2289 } 2290 NET_LOCK(); 2291 PF_LOCK(); 2292 error = pfr_clr_tstats(io->pfrio_buffer, io->pfrio_size, 2293 &io->pfrio_nzero, io->pfrio_flags | PFR_FLAG_USERIOCTL); 2294 PF_UNLOCK(); 2295 NET_UNLOCK(); 2296 break; 2297 } 2298 2299 case DIOCRSETTFLAGS: { 2300 struct pfioc_table *io = (struct pfioc_table *)addr; 2301 2302 if (io->pfrio_esize != sizeof(struct pfr_table)) { 2303 error = ENODEV; 2304 goto fail; 2305 } 2306 NET_LOCK(); 2307 PF_LOCK(); 2308 error = pfr_set_tflags(io->pfrio_buffer, io->pfrio_size, 2309 io->pfrio_setflag, io->pfrio_clrflag, &io->pfrio_nchange, 2310 &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL); 2311 PF_UNLOCK(); 2312 NET_UNLOCK(); 2313 break; 2314 } 2315 2316 case DIOCRCLRADDRS: { 2317 struct pfioc_table *io = (struct pfioc_table *)addr; 2318 2319 if (io->pfrio_esize != 0) { 2320 error = ENODEV; 2321 goto fail; 2322 } 2323 NET_LOCK(); 2324 PF_LOCK(); 2325 error = pfr_clr_addrs(&io->pfrio_table, &io->pfrio_ndel, 2326 io->pfrio_flags | PFR_FLAG_USERIOCTL); 2327 PF_UNLOCK(); 2328 NET_UNLOCK(); 2329 break; 2330 } 2331 2332 case DIOCRADDADDRS: { 2333 struct pfioc_table *io = (struct pfioc_table *)addr; 2334 2335 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 2336 error = ENODEV; 2337 goto fail; 2338 } 2339 error = pfr_add_addrs(&io->pfrio_table, io->pfrio_buffer, 2340 io->pfrio_size, &io->pfrio_nadd, io->pfrio_flags | 2341 PFR_FLAG_USERIOCTL); 2342 break; 2343 } 2344 2345 case DIOCRDELADDRS: { 2346 struct pfioc_table *io = (struct pfioc_table *)addr; 2347 2348 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 2349 error = ENODEV; 2350 goto fail; 2351 } 2352 NET_LOCK(); 2353 PF_LOCK(); 2354 error = pfr_del_addrs(&io->pfrio_table, io->pfrio_buffer, 2355 io->pfrio_size, &io->pfrio_ndel, io->pfrio_flags | 2356 PFR_FLAG_USERIOCTL); 2357 PF_UNLOCK(); 2358 NET_UNLOCK(); 2359 break; 2360 } 2361 2362 case DIOCRSETADDRS: { 2363 struct pfioc_table *io = (struct pfioc_table *)addr; 2364 2365 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 2366 error = ENODEV; 2367 goto fail; 2368 } 2369 NET_LOCK(); 2370 PF_LOCK(); 2371 error = pfr_set_addrs(&io->pfrio_table, io->pfrio_buffer, 2372 io->pfrio_size, &io->pfrio_size2, &io->pfrio_nadd, 2373 &io->pfrio_ndel, &io->pfrio_nchange, io->pfrio_flags | 2374 PFR_FLAG_USERIOCTL, 0); 2375 PF_UNLOCK(); 2376 NET_UNLOCK(); 2377 break; 2378 } 2379 2380 case DIOCRGETADDRS: { 2381 struct pfioc_table *io = (struct pfioc_table *)addr; 2382 2383 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 2384 error = ENODEV; 2385 goto fail; 2386 } 2387 NET_LOCK(); 2388 PF_LOCK(); 2389 error = pfr_get_addrs(&io->pfrio_table, io->pfrio_buffer, 2390 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); 2391 PF_UNLOCK(); 2392 NET_UNLOCK(); 2393 break; 2394 } 2395 2396 case DIOCRGETASTATS: { 2397 struct pfioc_table *io = (struct pfioc_table *)addr; 2398 2399 if (io->pfrio_esize != sizeof(struct pfr_astats)) { 2400 error = ENODEV; 2401 goto fail; 2402 } 2403 NET_LOCK(); 2404 PF_LOCK(); 2405 error = pfr_get_astats(&io->pfrio_table, io->pfrio_buffer, 2406 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); 2407 PF_UNLOCK(); 2408 NET_UNLOCK(); 2409 break; 2410 } 2411 2412 case DIOCRCLRASTATS: { 2413 struct pfioc_table *io = (struct pfioc_table *)addr; 2414 2415 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 2416 error = ENODEV; 2417 goto fail; 2418 } 2419 NET_LOCK(); 2420 PF_LOCK(); 2421 error = pfr_clr_astats(&io->pfrio_table, io->pfrio_buffer, 2422 io->pfrio_size, &io->pfrio_nzero, io->pfrio_flags | 2423 PFR_FLAG_USERIOCTL); 2424 PF_UNLOCK(); 2425 NET_UNLOCK(); 2426 break; 2427 } 2428 2429 case DIOCRTSTADDRS: { 2430 struct pfioc_table *io = (struct pfioc_table *)addr; 2431 2432 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 2433 error = ENODEV; 2434 goto fail; 2435 } 2436 NET_LOCK(); 2437 PF_LOCK(); 2438 error = pfr_tst_addrs(&io->pfrio_table, io->pfrio_buffer, 2439 io->pfrio_size, &io->pfrio_nmatch, io->pfrio_flags | 2440 PFR_FLAG_USERIOCTL); 2441 PF_UNLOCK(); 2442 NET_UNLOCK(); 2443 break; 2444 } 2445 2446 case DIOCRINADEFINE: { 2447 struct pfioc_table *io = (struct pfioc_table *)addr; 2448 2449 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 2450 error = ENODEV; 2451 goto fail; 2452 } 2453 NET_LOCK(); 2454 PF_LOCK(); 2455 error = pfr_ina_define(&io->pfrio_table, io->pfrio_buffer, 2456 io->pfrio_size, &io->pfrio_nadd, &io->pfrio_naddr, 2457 io->pfrio_ticket, io->pfrio_flags | PFR_FLAG_USERIOCTL); 2458 PF_UNLOCK(); 2459 NET_UNLOCK(); 2460 break; 2461 } 2462 2463 case DIOCOSFPADD: { 2464 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr; 2465 error = pf_osfp_add(io); 2466 break; 2467 } 2468 2469 case DIOCOSFPGET: { 2470 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr; 2471 error = pf_osfp_get(io); 2472 break; 2473 } 2474 2475 case DIOCXBEGIN: { 2476 struct pfioc_trans *io = (struct pfioc_trans *)addr; 2477 struct pfioc_trans_e *ioe; 2478 struct pfr_table *table; 2479 int i; 2480 2481 if (io->esize != sizeof(*ioe)) { 2482 error = ENODEV; 2483 goto fail; 2484 } 2485 ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK); 2486 table = malloc(sizeof(*table), M_TEMP, M_WAITOK); 2487 NET_LOCK(); 2488 PF_LOCK(); 2489 pf_default_rule_new = pf_default_rule; 2490 PF_UNLOCK(); 2491 NET_UNLOCK(); 2492 memset(&pf_trans_set, 0, sizeof(pf_trans_set)); 2493 for (i = 0; i < io->size; i++) { 2494 if (copyin(io->array+i, ioe, sizeof(*ioe))) { 2495 free(table, M_TEMP, sizeof(*table)); 2496 free(ioe, M_TEMP, sizeof(*ioe)); 2497 error = EFAULT; 2498 goto fail; 2499 } 2500 if (strnlen(ioe->anchor, sizeof(ioe->anchor)) == 2501 sizeof(ioe->anchor)) { 2502 free(table, M_TEMP, sizeof(*table)); 2503 free(ioe, M_TEMP, sizeof(*ioe)); 2504 error = ENAMETOOLONG; 2505 goto fail; 2506 } 2507 NET_LOCK(); 2508 PF_LOCK(); 2509 switch (ioe->type) { 2510 case PF_TRANS_TABLE: 2511 memset(table, 0, sizeof(*table)); 2512 strlcpy(table->pfrt_anchor, ioe->anchor, 2513 sizeof(table->pfrt_anchor)); 2514 if ((error = pfr_ina_begin(table, 2515 &ioe->ticket, NULL, 0))) { 2516 PF_UNLOCK(); 2517 NET_UNLOCK(); 2518 free(table, M_TEMP, sizeof(*table)); 2519 free(ioe, M_TEMP, sizeof(*ioe)); 2520 goto fail; 2521 } 2522 break; 2523 case PF_TRANS_RULESET: 2524 if ((error = pf_begin_rules(&ioe->ticket, 2525 ioe->anchor))) { 2526 PF_UNLOCK(); 2527 NET_UNLOCK(); 2528 free(table, M_TEMP, sizeof(*table)); 2529 free(ioe, M_TEMP, sizeof(*ioe)); 2530 goto fail; 2531 } 2532 break; 2533 default: 2534 PF_UNLOCK(); 2535 NET_UNLOCK(); 2536 free(table, M_TEMP, sizeof(*table)); 2537 free(ioe, M_TEMP, sizeof(*ioe)); 2538 error = EINVAL; 2539 goto fail; 2540 } 2541 PF_UNLOCK(); 2542 NET_UNLOCK(); 2543 if (copyout(ioe, io->array+i, sizeof(io->array[i]))) { 2544 free(table, M_TEMP, sizeof(*table)); 2545 free(ioe, M_TEMP, sizeof(*ioe)); 2546 error = EFAULT; 2547 goto fail; 2548 } 2549 } 2550 free(table, M_TEMP, sizeof(*table)); 2551 free(ioe, M_TEMP, sizeof(*ioe)); 2552 break; 2553 } 2554 2555 case DIOCXROLLBACK: { 2556 struct pfioc_trans *io = (struct pfioc_trans *)addr; 2557 struct pfioc_trans_e *ioe; 2558 struct pfr_table *table; 2559 int i; 2560 2561 if (io->esize != sizeof(*ioe)) { 2562 error = ENODEV; 2563 goto fail; 2564 } 2565 ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK); 2566 table = malloc(sizeof(*table), M_TEMP, M_WAITOK); 2567 for (i = 0; i < io->size; i++) { 2568 if (copyin(io->array+i, ioe, sizeof(*ioe))) { 2569 free(table, M_TEMP, sizeof(*table)); 2570 free(ioe, M_TEMP, sizeof(*ioe)); 2571 error = EFAULT; 2572 goto fail; 2573 } 2574 if (strnlen(ioe->anchor, sizeof(ioe->anchor)) == 2575 sizeof(ioe->anchor)) { 2576 free(table, M_TEMP, sizeof(*table)); 2577 free(ioe, M_TEMP, sizeof(*ioe)); 2578 error = ENAMETOOLONG; 2579 goto fail; 2580 } 2581 NET_LOCK(); 2582 PF_LOCK(); 2583 switch (ioe->type) { 2584 case PF_TRANS_TABLE: 2585 memset(table, 0, sizeof(*table)); 2586 strlcpy(table->pfrt_anchor, ioe->anchor, 2587 sizeof(table->pfrt_anchor)); 2588 if ((error = pfr_ina_rollback(table, 2589 ioe->ticket, NULL, 0))) { 2590 PF_UNLOCK(); 2591 NET_UNLOCK(); 2592 free(table, M_TEMP, sizeof(*table)); 2593 free(ioe, M_TEMP, sizeof(*ioe)); 2594 goto fail; /* really bad */ 2595 } 2596 break; 2597 case PF_TRANS_RULESET: 2598 pf_rollback_rules(ioe->ticket, ioe->anchor); 2599 break; 2600 default: 2601 PF_UNLOCK(); 2602 NET_UNLOCK(); 2603 free(table, M_TEMP, sizeof(*table)); 2604 free(ioe, M_TEMP, sizeof(*ioe)); 2605 error = EINVAL; 2606 goto fail; /* really bad */ 2607 } 2608 PF_UNLOCK(); 2609 NET_UNLOCK(); 2610 } 2611 free(table, M_TEMP, sizeof(*table)); 2612 free(ioe, M_TEMP, sizeof(*ioe)); 2613 break; 2614 } 2615 2616 case DIOCXCOMMIT: { 2617 struct pfioc_trans *io = (struct pfioc_trans *)addr; 2618 struct pfioc_trans_e *ioe; 2619 struct pfr_table *table; 2620 struct pf_ruleset *rs; 2621 int i; 2622 2623 if (io->esize != sizeof(*ioe)) { 2624 error = ENODEV; 2625 goto fail; 2626 } 2627 ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK); 2628 table = malloc(sizeof(*table), M_TEMP, M_WAITOK); 2629 /* first makes sure everything will succeed */ 2630 for (i = 0; i < io->size; i++) { 2631 if (copyin(io->array+i, ioe, sizeof(*ioe))) { 2632 free(table, M_TEMP, sizeof(*table)); 2633 free(ioe, M_TEMP, sizeof(*ioe)); 2634 error = EFAULT; 2635 goto fail; 2636 } 2637 if (strnlen(ioe->anchor, sizeof(ioe->anchor)) == 2638 sizeof(ioe->anchor)) { 2639 free(table, M_TEMP, sizeof(*table)); 2640 free(ioe, M_TEMP, sizeof(*ioe)); 2641 error = ENAMETOOLONG; 2642 goto fail; 2643 } 2644 NET_LOCK(); 2645 PF_LOCK(); 2646 switch (ioe->type) { 2647 case PF_TRANS_TABLE: 2648 rs = pf_find_ruleset(ioe->anchor); 2649 if (rs == NULL || !rs->topen || ioe->ticket != 2650 rs->tticket) { 2651 PF_UNLOCK(); 2652 NET_UNLOCK(); 2653 free(table, M_TEMP, sizeof(*table)); 2654 free(ioe, M_TEMP, sizeof(*ioe)); 2655 error = EBUSY; 2656 goto fail; 2657 } 2658 break; 2659 case PF_TRANS_RULESET: 2660 rs = pf_find_ruleset(ioe->anchor); 2661 if (rs == NULL || 2662 !rs->rules.inactive.open || 2663 rs->rules.inactive.version != 2664 ioe->ticket) { 2665 PF_UNLOCK(); 2666 NET_UNLOCK(); 2667 free(table, M_TEMP, sizeof(*table)); 2668 free(ioe, M_TEMP, sizeof(*ioe)); 2669 error = EBUSY; 2670 goto fail; 2671 } 2672 break; 2673 default: 2674 PF_UNLOCK(); 2675 NET_UNLOCK(); 2676 free(table, M_TEMP, sizeof(*table)); 2677 free(ioe, M_TEMP, sizeof(*ioe)); 2678 error = EINVAL; 2679 goto fail; 2680 } 2681 PF_UNLOCK(); 2682 NET_UNLOCK(); 2683 } 2684 NET_LOCK(); 2685 PF_LOCK(); 2686 2687 /* 2688 * Checked already in DIOCSETLIMIT, but check again as the 2689 * situation might have changed. 2690 */ 2691 for (i = 0; i < PF_LIMIT_MAX; i++) { 2692 if (((struct pool *)pf_pool_limits[i].pp)->pr_nout > 2693 pf_pool_limits[i].limit_new) { 2694 PF_UNLOCK(); 2695 NET_UNLOCK(); 2696 free(table, M_TEMP, sizeof(*table)); 2697 free(ioe, M_TEMP, sizeof(*ioe)); 2698 error = EBUSY; 2699 goto fail; 2700 } 2701 } 2702 /* now do the commit - no errors should happen here */ 2703 for (i = 0; i < io->size; i++) { 2704 PF_UNLOCK(); 2705 NET_UNLOCK(); 2706 if (copyin(io->array+i, ioe, sizeof(*ioe))) { 2707 free(table, M_TEMP, sizeof(*table)); 2708 free(ioe, M_TEMP, sizeof(*ioe)); 2709 error = EFAULT; 2710 goto fail; 2711 } 2712 if (strnlen(ioe->anchor, sizeof(ioe->anchor)) == 2713 sizeof(ioe->anchor)) { 2714 free(table, M_TEMP, sizeof(*table)); 2715 free(ioe, M_TEMP, sizeof(*ioe)); 2716 error = ENAMETOOLONG; 2717 goto fail; 2718 } 2719 NET_LOCK(); 2720 PF_LOCK(); 2721 switch (ioe->type) { 2722 case PF_TRANS_TABLE: 2723 memset(table, 0, sizeof(*table)); 2724 strlcpy(table->pfrt_anchor, ioe->anchor, 2725 sizeof(table->pfrt_anchor)); 2726 if ((error = pfr_ina_commit(table, ioe->ticket, 2727 NULL, NULL, 0))) { 2728 PF_UNLOCK(); 2729 NET_UNLOCK(); 2730 free(table, M_TEMP, sizeof(*table)); 2731 free(ioe, M_TEMP, sizeof(*ioe)); 2732 goto fail; /* really bad */ 2733 } 2734 break; 2735 case PF_TRANS_RULESET: 2736 if ((error = pf_commit_rules(ioe->ticket, 2737 ioe->anchor))) { 2738 PF_UNLOCK(); 2739 NET_UNLOCK(); 2740 free(table, M_TEMP, sizeof(*table)); 2741 free(ioe, M_TEMP, sizeof(*ioe)); 2742 goto fail; /* really bad */ 2743 } 2744 break; 2745 default: 2746 PF_UNLOCK(); 2747 NET_UNLOCK(); 2748 free(table, M_TEMP, sizeof(*table)); 2749 free(ioe, M_TEMP, sizeof(*ioe)); 2750 error = EINVAL; 2751 goto fail; /* really bad */ 2752 } 2753 } 2754 for (i = 0; i < PF_LIMIT_MAX; i++) { 2755 if (pf_pool_limits[i].limit_new != 2756 pf_pool_limits[i].limit && 2757 pool_sethardlimit(pf_pool_limits[i].pp, 2758 pf_pool_limits[i].limit_new, NULL, 0) != 0) { 2759 PF_UNLOCK(); 2760 NET_UNLOCK(); 2761 free(table, M_TEMP, sizeof(*table)); 2762 free(ioe, M_TEMP, sizeof(*ioe)); 2763 error = EBUSY; 2764 goto fail; /* really bad */ 2765 } 2766 pf_pool_limits[i].limit = pf_pool_limits[i].limit_new; 2767 } 2768 for (i = 0; i < PFTM_MAX; i++) { 2769 int old = pf_default_rule.timeout[i]; 2770 2771 pf_default_rule.timeout[i] = 2772 pf_default_rule_new.timeout[i]; 2773 if (pf_default_rule.timeout[i] == PFTM_INTERVAL && 2774 pf_default_rule.timeout[i] < old) 2775 task_add(net_tq(0), &pf_purge_task); 2776 } 2777 pfi_xcommit(); 2778 pf_trans_set_commit(); 2779 PF_UNLOCK(); 2780 NET_UNLOCK(); 2781 free(table, M_TEMP, sizeof(*table)); 2782 free(ioe, M_TEMP, sizeof(*ioe)); 2783 break; 2784 } 2785 2786 case DIOCGETSRCNODES: { 2787 struct pfioc_src_nodes *psn = (struct pfioc_src_nodes *)addr; 2788 struct pf_src_node *n, *p, *pstore; 2789 u_int32_t nr = 0; 2790 size_t space = psn->psn_len; 2791 2792 pstore = malloc(sizeof(*pstore), M_TEMP, M_WAITOK); 2793 2794 NET_LOCK(); 2795 PF_LOCK(); 2796 if (space == 0) { 2797 RB_FOREACH(n, pf_src_tree, &tree_src_tracking) 2798 nr++; 2799 psn->psn_len = sizeof(struct pf_src_node) * nr; 2800 PF_UNLOCK(); 2801 NET_UNLOCK(); 2802 free(pstore, M_TEMP, sizeof(*pstore)); 2803 goto fail; 2804 } 2805 2806 p = psn->psn_src_nodes; 2807 RB_FOREACH(n, pf_src_tree, &tree_src_tracking) { 2808 int secs = getuptime(), diff; 2809 2810 if ((nr + 1) * sizeof(*p) > psn->psn_len) 2811 break; 2812 2813 memcpy(pstore, n, sizeof(*pstore)); 2814 memset(&pstore->entry, 0, sizeof(pstore->entry)); 2815 pstore->rule.ptr = NULL; 2816 pstore->kif = NULL; 2817 pstore->rule.nr = n->rule.ptr->nr; 2818 pstore->creation = secs - pstore->creation; 2819 if (pstore->expire > secs) 2820 pstore->expire -= secs; 2821 else 2822 pstore->expire = 0; 2823 2824 /* adjust the connection rate estimate */ 2825 diff = secs - n->conn_rate.last; 2826 if (diff >= n->conn_rate.seconds) 2827 pstore->conn_rate.count = 0; 2828 else 2829 pstore->conn_rate.count -= 2830 n->conn_rate.count * diff / 2831 n->conn_rate.seconds; 2832 2833 error = copyout(pstore, p, sizeof(*p)); 2834 if (error) { 2835 PF_UNLOCK(); 2836 NET_UNLOCK(); 2837 free(pstore, M_TEMP, sizeof(*pstore)); 2838 goto fail; 2839 } 2840 p++; 2841 nr++; 2842 } 2843 psn->psn_len = sizeof(struct pf_src_node) * nr; 2844 2845 PF_UNLOCK(); 2846 NET_UNLOCK(); 2847 free(pstore, M_TEMP, sizeof(*pstore)); 2848 break; 2849 } 2850 2851 case DIOCCLRSRCNODES: { 2852 struct pf_src_node *n; 2853 struct pf_state *st; 2854 2855 NET_LOCK(); 2856 PF_LOCK(); 2857 PF_STATE_ENTER_WRITE(); 2858 RBT_FOREACH(st, pf_state_tree_id, &tree_id) 2859 pf_src_tree_remove_state(st); 2860 PF_STATE_EXIT_WRITE(); 2861 RB_FOREACH(n, pf_src_tree, &tree_src_tracking) 2862 n->expire = 1; 2863 pf_purge_expired_src_nodes(); 2864 PF_UNLOCK(); 2865 NET_UNLOCK(); 2866 break; 2867 } 2868 2869 case DIOCKILLSRCNODES: { 2870 struct pf_src_node *sn; 2871 struct pf_state *st; 2872 struct pfioc_src_node_kill *psnk = 2873 (struct pfioc_src_node_kill *)addr; 2874 u_int killed = 0; 2875 2876 NET_LOCK(); 2877 PF_LOCK(); 2878 RB_FOREACH(sn, pf_src_tree, &tree_src_tracking) { 2879 if (pf_match_addr(psnk->psnk_src.neg, 2880 &psnk->psnk_src.addr.v.a.addr, 2881 &psnk->psnk_src.addr.v.a.mask, 2882 &sn->addr, sn->af) && 2883 pf_match_addr(psnk->psnk_dst.neg, 2884 &psnk->psnk_dst.addr.v.a.addr, 2885 &psnk->psnk_dst.addr.v.a.mask, 2886 &sn->raddr, sn->af)) { 2887 /* Handle state to src_node linkage */ 2888 if (sn->states != 0) { 2889 PF_ASSERT_LOCKED(); 2890 PF_STATE_ENTER_WRITE(); 2891 RBT_FOREACH(st, pf_state_tree_id, 2892 &tree_id) 2893 pf_state_rm_src_node(st, sn); 2894 PF_STATE_EXIT_WRITE(); 2895 } 2896 sn->expire = 1; 2897 killed++; 2898 } 2899 } 2900 2901 if (killed > 0) 2902 pf_purge_expired_src_nodes(); 2903 2904 psnk->psnk_killed = killed; 2905 PF_UNLOCK(); 2906 NET_UNLOCK(); 2907 break; 2908 } 2909 2910 case DIOCSETHOSTID: { 2911 u_int32_t *hostid = (u_int32_t *)addr; 2912 2913 NET_LOCK(); 2914 PF_LOCK(); 2915 if (*hostid == 0) 2916 pf_trans_set.hostid = arc4random(); 2917 else 2918 pf_trans_set.hostid = *hostid; 2919 pf_trans_set.mask |= PF_TSET_HOSTID; 2920 PF_UNLOCK(); 2921 NET_UNLOCK(); 2922 break; 2923 } 2924 2925 case DIOCOSFPFLUSH: 2926 pf_osfp_flush(); 2927 break; 2928 2929 case DIOCIGETIFACES: { 2930 struct pfioc_iface *io = (struct pfioc_iface *)addr; 2931 struct pfi_kif *kif_buf; 2932 int apfiio_size = io->pfiio_size; 2933 2934 if (io->pfiio_esize != sizeof(struct pfi_kif)) { 2935 error = ENODEV; 2936 goto fail; 2937 } 2938 2939 if ((kif_buf = mallocarray(sizeof(*kif_buf), apfiio_size, 2940 M_TEMP, M_WAITOK|M_CANFAIL)) == NULL) { 2941 error = EINVAL; 2942 goto fail; 2943 } 2944 2945 NET_LOCK(); 2946 PF_LOCK(); 2947 pfi_get_ifaces(io->pfiio_name, kif_buf, &io->pfiio_size); 2948 PF_UNLOCK(); 2949 NET_UNLOCK(); 2950 if (copyout(kif_buf, io->pfiio_buffer, sizeof(*kif_buf) * 2951 io->pfiio_size)) 2952 error = EFAULT; 2953 free(kif_buf, M_TEMP, sizeof(*kif_buf) * apfiio_size); 2954 break; 2955 } 2956 2957 case DIOCSETIFFLAG: { 2958 struct pfioc_iface *io = (struct pfioc_iface *)addr; 2959 2960 if (io == NULL) { 2961 error = EINVAL; 2962 goto fail; 2963 } 2964 2965 NET_LOCK(); 2966 PF_LOCK(); 2967 error = pfi_set_flags(io->pfiio_name, io->pfiio_flags); 2968 PF_UNLOCK(); 2969 NET_UNLOCK(); 2970 break; 2971 } 2972 2973 case DIOCCLRIFFLAG: { 2974 struct pfioc_iface *io = (struct pfioc_iface *)addr; 2975 2976 if (io == NULL) { 2977 error = EINVAL; 2978 goto fail; 2979 } 2980 2981 NET_LOCK(); 2982 PF_LOCK(); 2983 error = pfi_clear_flags(io->pfiio_name, io->pfiio_flags); 2984 PF_UNLOCK(); 2985 NET_UNLOCK(); 2986 break; 2987 } 2988 2989 case DIOCSETREASS: { 2990 u_int32_t *reass = (u_int32_t *)addr; 2991 2992 NET_LOCK(); 2993 PF_LOCK(); 2994 pf_trans_set.reass = *reass; 2995 pf_trans_set.mask |= PF_TSET_REASS; 2996 PF_UNLOCK(); 2997 NET_UNLOCK(); 2998 break; 2999 } 3000 3001 case DIOCSETSYNFLWATS: { 3002 struct pfioc_synflwats *io = (struct pfioc_synflwats *)addr; 3003 3004 NET_LOCK(); 3005 PF_LOCK(); 3006 error = pf_syncookies_setwats(io->hiwat, io->lowat); 3007 PF_UNLOCK(); 3008 NET_UNLOCK(); 3009 break; 3010 } 3011 3012 case DIOCGETSYNFLWATS: { 3013 struct pfioc_synflwats *io = (struct pfioc_synflwats *)addr; 3014 3015 NET_LOCK(); 3016 PF_LOCK(); 3017 error = pf_syncookies_getwats(io); 3018 PF_UNLOCK(); 3019 NET_UNLOCK(); 3020 break; 3021 } 3022 3023 case DIOCSETSYNCOOKIES: { 3024 u_int8_t *mode = (u_int8_t *)addr; 3025 3026 NET_LOCK(); 3027 PF_LOCK(); 3028 error = pf_syncookies_setmode(*mode); 3029 PF_UNLOCK(); 3030 NET_UNLOCK(); 3031 break; 3032 } 3033 3034 default: 3035 error = ENODEV; 3036 break; 3037 } 3038 fail: 3039 rw_exit_write(&pfioctl_rw); 3040 3041 return (error); 3042 } 3043 3044 void 3045 pf_trans_set_commit(void) 3046 { 3047 if (pf_trans_set.mask & PF_TSET_STATUSIF) 3048 strlcpy(pf_status.ifname, pf_trans_set.statusif, IFNAMSIZ); 3049 if (pf_trans_set.mask & PF_TSET_DEBUG) 3050 pf_status.debug = pf_trans_set.debug; 3051 if (pf_trans_set.mask & PF_TSET_HOSTID) 3052 pf_status.hostid = pf_trans_set.hostid; 3053 if (pf_trans_set.mask & PF_TSET_REASS) 3054 pf_status.reass = pf_trans_set.reass; 3055 } 3056 3057 void 3058 pf_pool_copyin(struct pf_pool *from, struct pf_pool *to) 3059 { 3060 memmove(to, from, sizeof(*to)); 3061 to->kif = NULL; 3062 to->addr.p.tbl = NULL; 3063 } 3064 3065 int 3066 pf_validate_range(u_int8_t op, u_int16_t port[2], int order) 3067 { 3068 u_int16_t a = (order == PF_ORDER_NET) ? ntohs(port[0]) : port[0]; 3069 u_int16_t b = (order == PF_ORDER_NET) ? ntohs(port[1]) : port[1]; 3070 3071 if ((op == PF_OP_RRG && a > b) || /* 34:12, i.e. none */ 3072 (op == PF_OP_IRG && a >= b) || /* 34><12, i.e. none */ 3073 (op == PF_OP_XRG && a > b)) /* 34<>22, i.e. all */ 3074 return 1; 3075 return 0; 3076 } 3077 3078 int 3079 pf_rule_copyin(struct pf_rule *from, struct pf_rule *to) 3080 { 3081 int i; 3082 3083 if (from->scrub_flags & PFSTATE_SETPRIO && 3084 (from->set_prio[0] > IFQ_MAXPRIO || 3085 from->set_prio[1] > IFQ_MAXPRIO)) 3086 return (EINVAL); 3087 3088 to->src = from->src; 3089 to->src.addr.p.tbl = NULL; 3090 to->dst = from->dst; 3091 to->dst.addr.p.tbl = NULL; 3092 3093 if (pf_validate_range(to->src.port_op, to->src.port, PF_ORDER_NET)) 3094 return (EINVAL); 3095 if (pf_validate_range(to->dst.port_op, to->dst.port, PF_ORDER_NET)) 3096 return (EINVAL); 3097 3098 /* XXX union skip[] */ 3099 3100 strlcpy(to->label, from->label, sizeof(to->label)); 3101 strlcpy(to->ifname, from->ifname, sizeof(to->ifname)); 3102 strlcpy(to->rcv_ifname, from->rcv_ifname, sizeof(to->rcv_ifname)); 3103 strlcpy(to->qname, from->qname, sizeof(to->qname)); 3104 strlcpy(to->pqname, from->pqname, sizeof(to->pqname)); 3105 strlcpy(to->tagname, from->tagname, sizeof(to->tagname)); 3106 strlcpy(to->match_tagname, from->match_tagname, 3107 sizeof(to->match_tagname)); 3108 strlcpy(to->overload_tblname, from->overload_tblname, 3109 sizeof(to->overload_tblname)); 3110 3111 pf_pool_copyin(&from->nat, &to->nat); 3112 pf_pool_copyin(&from->rdr, &to->rdr); 3113 pf_pool_copyin(&from->route, &to->route); 3114 3115 if (pf_validate_range(to->rdr.port_op, to->rdr.proxy_port, 3116 PF_ORDER_HOST)) 3117 return (EINVAL); 3118 3119 to->kif = (to->ifname[0]) ? 3120 pfi_kif_alloc(to->ifname, M_WAITOK) : NULL; 3121 to->rcv_kif = (to->rcv_ifname[0]) ? 3122 pfi_kif_alloc(to->rcv_ifname, M_WAITOK) : NULL; 3123 to->rdr.kif = (to->rdr.ifname[0]) ? 3124 pfi_kif_alloc(to->rdr.ifname, M_WAITOK) : NULL; 3125 to->nat.kif = (to->nat.ifname[0]) ? 3126 pfi_kif_alloc(to->nat.ifname, M_WAITOK) : NULL; 3127 to->route.kif = (to->route.ifname[0]) ? 3128 pfi_kif_alloc(to->route.ifname, M_WAITOK) : NULL; 3129 3130 to->os_fingerprint = from->os_fingerprint; 3131 3132 to->rtableid = from->rtableid; 3133 if (to->rtableid >= 0 && !rtable_exists(to->rtableid)) 3134 return (EBUSY); 3135 to->onrdomain = from->onrdomain; 3136 if (to->onrdomain != -1 && (to->onrdomain < 0 || 3137 to->onrdomain > RT_TABLEID_MAX)) 3138 return (EINVAL); 3139 3140 for (i = 0; i < PFTM_MAX; i++) 3141 to->timeout[i] = from->timeout[i]; 3142 to->states_tot = from->states_tot; 3143 to->max_states = from->max_states; 3144 to->max_src_nodes = from->max_src_nodes; 3145 to->max_src_states = from->max_src_states; 3146 to->max_src_conn = from->max_src_conn; 3147 to->max_src_conn_rate.limit = from->max_src_conn_rate.limit; 3148 to->max_src_conn_rate.seconds = from->max_src_conn_rate.seconds; 3149 pf_init_threshold(&to->pktrate, from->pktrate.limit, 3150 from->pktrate.seconds); 3151 3152 if (to->qname[0] != 0) { 3153 if ((to->qid = pf_qname2qid(to->qname, 0)) == 0) 3154 return (EBUSY); 3155 if (to->pqname[0] != 0) { 3156 if ((to->pqid = pf_qname2qid(to->pqname, 0)) == 0) 3157 return (EBUSY); 3158 } else 3159 to->pqid = to->qid; 3160 } 3161 to->rt_listid = from->rt_listid; 3162 to->prob = from->prob; 3163 to->return_icmp = from->return_icmp; 3164 to->return_icmp6 = from->return_icmp6; 3165 to->max_mss = from->max_mss; 3166 if (to->tagname[0]) 3167 if ((to->tag = pf_tagname2tag(to->tagname, 1)) == 0) 3168 return (EBUSY); 3169 if (to->match_tagname[0]) 3170 if ((to->match_tag = pf_tagname2tag(to->match_tagname, 1)) == 0) 3171 return (EBUSY); 3172 to->scrub_flags = from->scrub_flags; 3173 to->delay = from->delay; 3174 to->uid = from->uid; 3175 to->gid = from->gid; 3176 to->rule_flag = from->rule_flag; 3177 to->action = from->action; 3178 to->direction = from->direction; 3179 to->log = from->log; 3180 to->logif = from->logif; 3181 #if NPFLOG > 0 3182 if (!to->log) 3183 to->logif = 0; 3184 #endif /* NPFLOG > 0 */ 3185 to->quick = from->quick; 3186 to->ifnot = from->ifnot; 3187 to->rcvifnot = from->rcvifnot; 3188 to->match_tag_not = from->match_tag_not; 3189 to->keep_state = from->keep_state; 3190 to->af = from->af; 3191 to->naf = from->naf; 3192 to->proto = from->proto; 3193 to->type = from->type; 3194 to->code = from->code; 3195 to->flags = from->flags; 3196 to->flagset = from->flagset; 3197 to->min_ttl = from->min_ttl; 3198 to->allow_opts = from->allow_opts; 3199 to->rt = from->rt; 3200 to->return_ttl = from->return_ttl; 3201 to->tos = from->tos; 3202 to->set_tos = from->set_tos; 3203 to->anchor_relative = from->anchor_relative; /* XXX */ 3204 to->anchor_wildcard = from->anchor_wildcard; /* XXX */ 3205 to->flush = from->flush; 3206 to->divert.addr = from->divert.addr; 3207 to->divert.port = from->divert.port; 3208 to->divert.type = from->divert.type; 3209 to->prio = from->prio; 3210 to->set_prio[0] = from->set_prio[0]; 3211 to->set_prio[1] = from->set_prio[1]; 3212 3213 return (0); 3214 } 3215 3216 int 3217 pf_rule_checkaf(struct pf_rule *r) 3218 { 3219 switch (r->af) { 3220 case 0: 3221 if (r->rule_flag & PFRULE_AFTO) 3222 return (EPFNOSUPPORT); 3223 break; 3224 case AF_INET: 3225 if ((r->rule_flag & PFRULE_AFTO) && r->naf != AF_INET6) 3226 return (EPFNOSUPPORT); 3227 break; 3228 #ifdef INET6 3229 case AF_INET6: 3230 if ((r->rule_flag & PFRULE_AFTO) && r->naf != AF_INET) 3231 return (EPFNOSUPPORT); 3232 break; 3233 #endif /* INET6 */ 3234 default: 3235 return (EPFNOSUPPORT); 3236 } 3237 3238 if ((r->rule_flag & PFRULE_AFTO) == 0 && r->naf != 0) 3239 return (EPFNOSUPPORT); 3240 3241 return (0); 3242 } 3243 3244 int 3245 pf_sysctl(void *oldp, size_t *oldlenp, void *newp, size_t newlen) 3246 { 3247 struct pf_status pfs; 3248 3249 NET_LOCK_SHARED(); 3250 PF_LOCK(); 3251 memcpy(&pfs, &pf_status, sizeof(struct pf_status)); 3252 pfi_update_status(pfs.ifname, &pfs); 3253 PF_UNLOCK(); 3254 NET_UNLOCK_SHARED(); 3255 3256 return sysctl_rdstruct(oldp, oldlenp, newp, &pfs, sizeof(pfs)); 3257 } 3258 3259 struct pf_trans * 3260 pf_open_trans(uint32_t unit) 3261 { 3262 static uint64_t ticket = 1; 3263 struct pf_trans *t; 3264 3265 rw_assert_wrlock(&pfioctl_rw); 3266 3267 t = malloc(sizeof(*t), M_TEMP, M_WAITOK|M_ZERO); 3268 t->pft_unit = unit; 3269 t->pft_ticket = ticket++; 3270 3271 LIST_INSERT_HEAD(&pf_ioctl_trans, t, pft_entry); 3272 3273 return (t); 3274 } 3275 3276 struct pf_trans * 3277 pf_find_trans(uint32_t unit, uint64_t ticket) 3278 { 3279 struct pf_trans *t; 3280 3281 rw_assert_anylock(&pfioctl_rw); 3282 3283 LIST_FOREACH(t, &pf_ioctl_trans, pft_entry) { 3284 if (t->pft_ticket == ticket && t->pft_unit == unit) 3285 break; 3286 } 3287 3288 return (t); 3289 } 3290 3291 void 3292 pf_init_tgetrule(struct pf_trans *t, struct pf_anchor *a, 3293 uint32_t rs_version, struct pf_rule *r) 3294 { 3295 t->pft_type = PF_TRANS_GETRULE; 3296 if (a == NULL) 3297 t->pftgr_anchor = &pf_main_anchor; 3298 else 3299 t->pftgr_anchor = a; 3300 3301 t->pftgr_version = rs_version; 3302 t->pftgr_rule = r; 3303 } 3304 3305 void 3306 pf_cleanup_tgetrule(struct pf_trans *t) 3307 { 3308 KASSERT(t->pft_type == PF_TRANS_GETRULE); 3309 pf_anchor_rele(t->pftgr_anchor); 3310 } 3311 3312 void 3313 pf_free_trans(struct pf_trans *t) 3314 { 3315 switch (t->pft_type) { 3316 case PF_TRANS_GETRULE: 3317 pf_cleanup_tgetrule(t); 3318 break; 3319 default: 3320 log(LOG_ERR, "%s unknown transaction type: %d\n", 3321 __func__, t->pft_type); 3322 } 3323 free(t, M_TEMP, sizeof(*t)); 3324 } 3325 3326 void 3327 pf_rollback_trans(struct pf_trans *t) 3328 { 3329 if (t != NULL) { 3330 rw_assert_wrlock(&pfioctl_rw); 3331 LIST_REMOVE(t, pft_entry); 3332 pf_free_trans(t); 3333 } 3334 } 3335