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