1 /* $OpenBSD: pf_ioctl.c,v 1.382 2022/06/26 11:37:08 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, PR_WAITOK) || 895 pf_tbladdr_setup(ruleset, addr, PR_WAITOK) || 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, PR_WAITOK)) == 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, 1640 PR_WAITOK); 1641 if (newrule->overload_tbl == NULL) 1642 error = EINVAL; 1643 else 1644 newrule->overload_tbl->pfrkt_flags |= 1645 PFR_TFLAG_ACTIVE; 1646 } 1647 1648 if (pf_addr_setup(ruleset, &newrule->src.addr, 1649 newrule->af)) 1650 error = EINVAL; 1651 if (pf_addr_setup(ruleset, &newrule->dst.addr, 1652 newrule->af)) 1653 error = EINVAL; 1654 if (pf_addr_setup(ruleset, &newrule->rdr.addr, 1655 newrule->af)) 1656 error = EINVAL; 1657 if (pf_addr_setup(ruleset, &newrule->nat.addr, 1658 newrule->af)) 1659 error = EINVAL; 1660 if (pf_addr_setup(ruleset, &newrule->route.addr, 1661 newrule->af)) 1662 error = EINVAL; 1663 if (pf_anchor_setup(newrule, ruleset, pcr->anchor_call)) 1664 error = EINVAL; 1665 1666 if (error) { 1667 pf_rm_rule(NULL, newrule); 1668 PF_UNLOCK(); 1669 NET_UNLOCK(); 1670 goto fail; 1671 } 1672 } 1673 1674 if (pcr->action == PF_CHANGE_ADD_HEAD) 1675 oldrule = TAILQ_FIRST(ruleset->rules.active.ptr); 1676 else if (pcr->action == PF_CHANGE_ADD_TAIL) 1677 oldrule = TAILQ_LAST(ruleset->rules.active.ptr, 1678 pf_rulequeue); 1679 else { 1680 oldrule = TAILQ_FIRST(ruleset->rules.active.ptr); 1681 while ((oldrule != NULL) && (oldrule->nr != pcr->nr)) 1682 oldrule = TAILQ_NEXT(oldrule, entries); 1683 if (oldrule == NULL) { 1684 if (newrule != NULL) 1685 pf_rm_rule(NULL, newrule); 1686 error = EINVAL; 1687 PF_UNLOCK(); 1688 NET_UNLOCK(); 1689 goto fail; 1690 } 1691 } 1692 1693 if (pcr->action == PF_CHANGE_REMOVE) { 1694 pf_rm_rule(ruleset->rules.active.ptr, oldrule); 1695 ruleset->rules.active.rcount--; 1696 } else { 1697 if (oldrule == NULL) 1698 TAILQ_INSERT_TAIL( 1699 ruleset->rules.active.ptr, 1700 newrule, entries); 1701 else if (pcr->action == PF_CHANGE_ADD_HEAD || 1702 pcr->action == PF_CHANGE_ADD_BEFORE) 1703 TAILQ_INSERT_BEFORE(oldrule, newrule, entries); 1704 else 1705 TAILQ_INSERT_AFTER( 1706 ruleset->rules.active.ptr, 1707 oldrule, newrule, entries); 1708 ruleset->rules.active.rcount++; 1709 newrule->ruleset = ruleset; 1710 } 1711 1712 nr = 0; 1713 TAILQ_FOREACH(oldrule, ruleset->rules.active.ptr, entries) 1714 oldrule->nr = nr++; 1715 1716 ruleset->rules.active.ticket++; 1717 1718 pf_calc_skip_steps(ruleset->rules.active.ptr); 1719 pf_remove_if_empty_ruleset(ruleset); 1720 1721 PF_UNLOCK(); 1722 NET_UNLOCK(); 1723 break; 1724 } 1725 1726 case DIOCCLRSTATES: 1727 error = pf_states_clr((struct pfioc_state_kill *)addr); 1728 break; 1729 1730 case DIOCKILLSTATES: { 1731 struct pf_state *s, *nexts; 1732 struct pf_state_item *si, *sit; 1733 struct pf_state_key *sk, key; 1734 struct pf_addr *srcaddr, *dstaddr; 1735 u_int16_t srcport, dstport; 1736 struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr; 1737 u_int i, killed = 0; 1738 const int dirs[] = { PF_IN, PF_OUT }; 1739 int sidx, didx; 1740 1741 if (psk->psk_pfcmp.id) { 1742 if (psk->psk_pfcmp.creatorid == 0) 1743 psk->psk_pfcmp.creatorid = pf_status.hostid; 1744 NET_LOCK(); 1745 PF_LOCK(); 1746 PF_STATE_ENTER_WRITE(); 1747 if ((s = pf_find_state_byid(&psk->psk_pfcmp))) { 1748 pf_remove_state(s); 1749 psk->psk_killed = 1; 1750 } 1751 PF_STATE_EXIT_WRITE(); 1752 PF_UNLOCK(); 1753 NET_UNLOCK(); 1754 goto fail; 1755 } 1756 1757 if (psk->psk_af && psk->psk_proto && 1758 psk->psk_src.port_op == PF_OP_EQ && 1759 psk->psk_dst.port_op == PF_OP_EQ) { 1760 1761 key.af = psk->psk_af; 1762 key.proto = psk->psk_proto; 1763 key.rdomain = psk->psk_rdomain; 1764 1765 NET_LOCK(); 1766 PF_LOCK(); 1767 PF_STATE_ENTER_WRITE(); 1768 for (i = 0; i < nitems(dirs); i++) { 1769 if (dirs[i] == PF_IN) { 1770 sidx = 0; 1771 didx = 1; 1772 } else { 1773 sidx = 1; 1774 didx = 0; 1775 } 1776 pf_addrcpy(&key.addr[sidx], 1777 &psk->psk_src.addr.v.a.addr, key.af); 1778 pf_addrcpy(&key.addr[didx], 1779 &psk->psk_dst.addr.v.a.addr, key.af); 1780 key.port[sidx] = psk->psk_src.port[0]; 1781 key.port[didx] = psk->psk_dst.port[0]; 1782 1783 sk = RB_FIND(pf_state_tree, &pf_statetbl, &key); 1784 if (sk == NULL) 1785 continue; 1786 1787 TAILQ_FOREACH_SAFE(si, &sk->states, entry, sit) 1788 if (((si->s->key[PF_SK_WIRE]->af == 1789 si->s->key[PF_SK_STACK]->af && 1790 sk == (dirs[i] == PF_IN ? 1791 si->s->key[PF_SK_WIRE] : 1792 si->s->key[PF_SK_STACK])) || 1793 (si->s->key[PF_SK_WIRE]->af != 1794 si->s->key[PF_SK_STACK]->af && 1795 dirs[i] == PF_IN && 1796 (sk == si->s->key[PF_SK_STACK] || 1797 sk == si->s->key[PF_SK_WIRE]))) && 1798 (!psk->psk_ifname[0] || 1799 (si->s->kif != pfi_all && 1800 !strcmp(psk->psk_ifname, 1801 si->s->kif->pfik_name)))) { 1802 pf_remove_state(si->s); 1803 killed++; 1804 } 1805 } 1806 if (killed) 1807 psk->psk_killed = killed; 1808 PF_STATE_EXIT_WRITE(); 1809 PF_UNLOCK(); 1810 NET_UNLOCK(); 1811 goto fail; 1812 } 1813 1814 NET_LOCK(); 1815 PF_LOCK(); 1816 PF_STATE_ENTER_WRITE(); 1817 for (s = RB_MIN(pf_state_tree_id, &tree_id); s; 1818 s = nexts) { 1819 nexts = RB_NEXT(pf_state_tree_id, &tree_id, s); 1820 1821 if (s->direction == PF_OUT) { 1822 sk = s->key[PF_SK_STACK]; 1823 srcaddr = &sk->addr[1]; 1824 dstaddr = &sk->addr[0]; 1825 srcport = sk->port[1]; 1826 dstport = sk->port[0]; 1827 } else { 1828 sk = s->key[PF_SK_WIRE]; 1829 srcaddr = &sk->addr[0]; 1830 dstaddr = &sk->addr[1]; 1831 srcport = sk->port[0]; 1832 dstport = sk->port[1]; 1833 } 1834 if ((!psk->psk_af || sk->af == psk->psk_af) 1835 && (!psk->psk_proto || psk->psk_proto == 1836 sk->proto) && psk->psk_rdomain == sk->rdomain && 1837 pf_match_addr(psk->psk_src.neg, 1838 &psk->psk_src.addr.v.a.addr, 1839 &psk->psk_src.addr.v.a.mask, 1840 srcaddr, sk->af) && 1841 pf_match_addr(psk->psk_dst.neg, 1842 &psk->psk_dst.addr.v.a.addr, 1843 &psk->psk_dst.addr.v.a.mask, 1844 dstaddr, sk->af) && 1845 (psk->psk_src.port_op == 0 || 1846 pf_match_port(psk->psk_src.port_op, 1847 psk->psk_src.port[0], psk->psk_src.port[1], 1848 srcport)) && 1849 (psk->psk_dst.port_op == 0 || 1850 pf_match_port(psk->psk_dst.port_op, 1851 psk->psk_dst.port[0], psk->psk_dst.port[1], 1852 dstport)) && 1853 (!psk->psk_label[0] || (s->rule.ptr->label[0] && 1854 !strcmp(psk->psk_label, s->rule.ptr->label))) && 1855 (!psk->psk_ifname[0] || !strcmp(psk->psk_ifname, 1856 s->kif->pfik_name))) { 1857 pf_remove_state(s); 1858 killed++; 1859 } 1860 } 1861 psk->psk_killed = killed; 1862 PF_STATE_EXIT_WRITE(); 1863 PF_UNLOCK(); 1864 NET_UNLOCK(); 1865 break; 1866 } 1867 1868 #if NPFSYNC > 0 1869 case DIOCADDSTATE: { 1870 struct pfioc_state *ps = (struct pfioc_state *)addr; 1871 struct pfsync_state *sp = &ps->state; 1872 1873 if (sp->timeout >= PFTM_MAX) { 1874 error = EINVAL; 1875 goto fail; 1876 } 1877 NET_LOCK(); 1878 PF_LOCK(); 1879 error = pfsync_state_import(sp, PFSYNC_SI_IOCTL); 1880 PF_UNLOCK(); 1881 NET_UNLOCK(); 1882 break; 1883 } 1884 #endif /* NPFSYNC > 0 */ 1885 1886 case DIOCGETSTATE: { 1887 struct pfioc_state *ps = (struct pfioc_state *)addr; 1888 struct pf_state *s; 1889 struct pf_state_cmp id_key; 1890 1891 memset(&id_key, 0, sizeof(id_key)); 1892 id_key.id = ps->state.id; 1893 id_key.creatorid = ps->state.creatorid; 1894 1895 NET_LOCK(); 1896 PF_STATE_ENTER_READ(); 1897 s = pf_find_state_byid(&id_key); 1898 s = pf_state_ref(s); 1899 PF_STATE_EXIT_READ(); 1900 NET_UNLOCK(); 1901 if (s == NULL) { 1902 error = ENOENT; 1903 goto fail; 1904 } 1905 1906 pf_state_export(&ps->state, s); 1907 pf_state_unref(s); 1908 break; 1909 } 1910 1911 case DIOCGETSTATES: 1912 error = pf_states_get((struct pfioc_states *)addr); 1913 break; 1914 1915 case DIOCGETSTATUS: { 1916 struct pf_status *s = (struct pf_status *)addr; 1917 NET_LOCK(); 1918 PF_LOCK(); 1919 memcpy(s, &pf_status, sizeof(struct pf_status)); 1920 pfi_update_status(s->ifname, s); 1921 PF_UNLOCK(); 1922 NET_UNLOCK(); 1923 break; 1924 } 1925 1926 case DIOCSETSTATUSIF: { 1927 struct pfioc_iface *pi = (struct pfioc_iface *)addr; 1928 1929 NET_LOCK(); 1930 PF_LOCK(); 1931 if (pi->pfiio_name[0] == 0) { 1932 memset(pf_status.ifname, 0, IFNAMSIZ); 1933 PF_UNLOCK(); 1934 NET_UNLOCK(); 1935 goto fail; 1936 } 1937 strlcpy(pf_trans_set.statusif, pi->pfiio_name, IFNAMSIZ); 1938 pf_trans_set.mask |= PF_TSET_STATUSIF; 1939 PF_UNLOCK(); 1940 NET_UNLOCK(); 1941 break; 1942 } 1943 1944 case DIOCCLRSTATUS: { 1945 struct pfioc_iface *pi = (struct pfioc_iface *)addr; 1946 1947 NET_LOCK(); 1948 PF_LOCK(); 1949 /* if ifname is specified, clear counters there only */ 1950 if (pi->pfiio_name[0]) { 1951 pfi_update_status(pi->pfiio_name, NULL); 1952 PF_UNLOCK(); 1953 NET_UNLOCK(); 1954 goto fail; 1955 } 1956 1957 memset(pf_status.counters, 0, sizeof(pf_status.counters)); 1958 memset(pf_status.fcounters, 0, sizeof(pf_status.fcounters)); 1959 memset(pf_status.scounters, 0, sizeof(pf_status.scounters)); 1960 pf_status.since = getuptime(); 1961 1962 PF_UNLOCK(); 1963 NET_UNLOCK(); 1964 break; 1965 } 1966 1967 case DIOCNATLOOK: { 1968 struct pfioc_natlook *pnl = (struct pfioc_natlook *)addr; 1969 struct pf_state_key *sk; 1970 struct pf_state *state; 1971 struct pf_state_key_cmp key; 1972 int m = 0, direction = pnl->direction; 1973 int sidx, didx; 1974 1975 switch (pnl->af) { 1976 case AF_INET: 1977 break; 1978 #ifdef INET6 1979 case AF_INET6: 1980 break; 1981 #endif /* INET6 */ 1982 default: 1983 error = EAFNOSUPPORT; 1984 goto fail; 1985 } 1986 1987 /* NATLOOK src and dst are reversed, so reverse sidx/didx */ 1988 sidx = (direction == PF_IN) ? 1 : 0; 1989 didx = (direction == PF_IN) ? 0 : 1; 1990 1991 if (!pnl->proto || 1992 PF_AZERO(&pnl->saddr, pnl->af) || 1993 PF_AZERO(&pnl->daddr, pnl->af) || 1994 ((pnl->proto == IPPROTO_TCP || 1995 pnl->proto == IPPROTO_UDP) && 1996 (!pnl->dport || !pnl->sport)) || 1997 pnl->rdomain > RT_TABLEID_MAX) 1998 error = EINVAL; 1999 else { 2000 key.af = pnl->af; 2001 key.proto = pnl->proto; 2002 key.rdomain = pnl->rdomain; 2003 pf_addrcpy(&key.addr[sidx], &pnl->saddr, pnl->af); 2004 key.port[sidx] = pnl->sport; 2005 pf_addrcpy(&key.addr[didx], &pnl->daddr, pnl->af); 2006 key.port[didx] = pnl->dport; 2007 2008 NET_LOCK(); 2009 PF_STATE_ENTER_READ(); 2010 state = pf_find_state_all(&key, direction, &m); 2011 state = pf_state_ref(state); 2012 PF_STATE_EXIT_READ(); 2013 NET_UNLOCK(); 2014 2015 if (m > 1) 2016 error = E2BIG; /* more than one state */ 2017 else if (state != NULL) { 2018 sk = state->key[sidx]; 2019 pf_addrcpy(&pnl->rsaddr, &sk->addr[sidx], 2020 sk->af); 2021 pnl->rsport = sk->port[sidx]; 2022 pf_addrcpy(&pnl->rdaddr, &sk->addr[didx], 2023 sk->af); 2024 pnl->rdport = sk->port[didx]; 2025 pnl->rrdomain = sk->rdomain; 2026 } else 2027 error = ENOENT; 2028 pf_state_unref(state); 2029 } 2030 break; 2031 } 2032 2033 case DIOCSETTIMEOUT: { 2034 struct pfioc_tm *pt = (struct pfioc_tm *)addr; 2035 2036 if (pt->timeout < 0 || pt->timeout >= PFTM_MAX || 2037 pt->seconds < 0) { 2038 error = EINVAL; 2039 goto fail; 2040 } 2041 NET_LOCK(); 2042 PF_LOCK(); 2043 if (pt->timeout == PFTM_INTERVAL && pt->seconds == 0) 2044 pt->seconds = 1; 2045 pf_default_rule_new.timeout[pt->timeout] = pt->seconds; 2046 pt->seconds = pf_default_rule.timeout[pt->timeout]; 2047 PF_UNLOCK(); 2048 NET_UNLOCK(); 2049 break; 2050 } 2051 2052 case DIOCGETTIMEOUT: { 2053 struct pfioc_tm *pt = (struct pfioc_tm *)addr; 2054 2055 if (pt->timeout < 0 || pt->timeout >= PFTM_MAX) { 2056 error = EINVAL; 2057 goto fail; 2058 } 2059 NET_LOCK(); 2060 PF_LOCK(); 2061 pt->seconds = pf_default_rule.timeout[pt->timeout]; 2062 PF_UNLOCK(); 2063 NET_UNLOCK(); 2064 break; 2065 } 2066 2067 case DIOCGETLIMIT: { 2068 struct pfioc_limit *pl = (struct pfioc_limit *)addr; 2069 2070 if (pl->index < 0 || pl->index >= PF_LIMIT_MAX) { 2071 error = EINVAL; 2072 goto fail; 2073 } 2074 NET_LOCK(); 2075 PF_LOCK(); 2076 pl->limit = pf_pool_limits[pl->index].limit; 2077 PF_UNLOCK(); 2078 NET_UNLOCK(); 2079 break; 2080 } 2081 2082 case DIOCSETLIMIT: { 2083 struct pfioc_limit *pl = (struct pfioc_limit *)addr; 2084 2085 NET_LOCK(); 2086 PF_LOCK(); 2087 if (pl->index < 0 || pl->index >= PF_LIMIT_MAX || 2088 pf_pool_limits[pl->index].pp == NULL) { 2089 error = EINVAL; 2090 PF_UNLOCK(); 2091 NET_UNLOCK(); 2092 goto fail; 2093 } 2094 if (((struct pool *)pf_pool_limits[pl->index].pp)->pr_nout > 2095 pl->limit) { 2096 error = EBUSY; 2097 PF_UNLOCK(); 2098 NET_UNLOCK(); 2099 goto fail; 2100 } 2101 /* Fragments reference mbuf clusters. */ 2102 if (pl->index == PF_LIMIT_FRAGS && pl->limit > nmbclust) { 2103 error = EINVAL; 2104 PF_UNLOCK(); 2105 NET_UNLOCK(); 2106 goto fail; 2107 } 2108 2109 pf_pool_limits[pl->index].limit_new = pl->limit; 2110 pl->limit = pf_pool_limits[pl->index].limit; 2111 PF_UNLOCK(); 2112 NET_UNLOCK(); 2113 break; 2114 } 2115 2116 case DIOCSETDEBUG: { 2117 u_int32_t *level = (u_int32_t *)addr; 2118 2119 NET_LOCK(); 2120 PF_LOCK(); 2121 pf_trans_set.debug = *level; 2122 pf_trans_set.mask |= PF_TSET_DEBUG; 2123 PF_UNLOCK(); 2124 NET_UNLOCK(); 2125 break; 2126 } 2127 2128 case DIOCGETRULESETS: { 2129 struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr; 2130 struct pf_ruleset *ruleset; 2131 struct pf_anchor *anchor; 2132 2133 NET_LOCK(); 2134 PF_LOCK(); 2135 pr->path[sizeof(pr->path) - 1] = '\0'; 2136 if ((ruleset = pf_find_ruleset(pr->path)) == NULL) { 2137 error = EINVAL; 2138 PF_UNLOCK(); 2139 NET_UNLOCK(); 2140 goto fail; 2141 } 2142 pr->nr = 0; 2143 if (ruleset == &pf_main_ruleset) { 2144 /* XXX kludge for pf_main_ruleset */ 2145 RB_FOREACH(anchor, pf_anchor_global, &pf_anchors) 2146 if (anchor->parent == NULL) 2147 pr->nr++; 2148 } else { 2149 RB_FOREACH(anchor, pf_anchor_node, 2150 &ruleset->anchor->children) 2151 pr->nr++; 2152 } 2153 PF_UNLOCK(); 2154 NET_UNLOCK(); 2155 break; 2156 } 2157 2158 case DIOCGETRULESET: { 2159 struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr; 2160 struct pf_ruleset *ruleset; 2161 struct pf_anchor *anchor; 2162 u_int32_t nr = 0; 2163 2164 NET_LOCK(); 2165 PF_LOCK(); 2166 pr->path[sizeof(pr->path) - 1] = '\0'; 2167 if ((ruleset = pf_find_ruleset(pr->path)) == NULL) { 2168 error = EINVAL; 2169 PF_UNLOCK(); 2170 NET_UNLOCK(); 2171 goto fail; 2172 } 2173 pr->name[0] = '\0'; 2174 if (ruleset == &pf_main_ruleset) { 2175 /* XXX kludge for pf_main_ruleset */ 2176 RB_FOREACH(anchor, pf_anchor_global, &pf_anchors) 2177 if (anchor->parent == NULL && nr++ == pr->nr) { 2178 strlcpy(pr->name, anchor->name, 2179 sizeof(pr->name)); 2180 break; 2181 } 2182 } else { 2183 RB_FOREACH(anchor, pf_anchor_node, 2184 &ruleset->anchor->children) 2185 if (nr++ == pr->nr) { 2186 strlcpy(pr->name, anchor->name, 2187 sizeof(pr->name)); 2188 break; 2189 } 2190 } 2191 PF_UNLOCK(); 2192 NET_UNLOCK(); 2193 if (!pr->name[0]) 2194 error = EBUSY; 2195 break; 2196 } 2197 2198 case DIOCRCLRTABLES: { 2199 struct pfioc_table *io = (struct pfioc_table *)addr; 2200 2201 if (io->pfrio_esize != 0) { 2202 error = ENODEV; 2203 goto fail; 2204 } 2205 NET_LOCK(); 2206 PF_LOCK(); 2207 error = pfr_clr_tables(&io->pfrio_table, &io->pfrio_ndel, 2208 io->pfrio_flags | PFR_FLAG_USERIOCTL); 2209 PF_UNLOCK(); 2210 NET_UNLOCK(); 2211 break; 2212 } 2213 2214 case DIOCRADDTABLES: { 2215 struct pfioc_table *io = (struct pfioc_table *)addr; 2216 2217 if (io->pfrio_esize != sizeof(struct pfr_table)) { 2218 error = ENODEV; 2219 goto fail; 2220 } 2221 error = pfr_add_tables(io->pfrio_buffer, io->pfrio_size, 2222 &io->pfrio_nadd, io->pfrio_flags | PFR_FLAG_USERIOCTL); 2223 break; 2224 } 2225 2226 case DIOCRDELTABLES: { 2227 struct pfioc_table *io = (struct pfioc_table *)addr; 2228 2229 if (io->pfrio_esize != sizeof(struct pfr_table)) { 2230 error = ENODEV; 2231 goto fail; 2232 } 2233 NET_LOCK(); 2234 PF_LOCK(); 2235 error = pfr_del_tables(io->pfrio_buffer, io->pfrio_size, 2236 &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL); 2237 PF_UNLOCK(); 2238 NET_UNLOCK(); 2239 break; 2240 } 2241 2242 case DIOCRGETTABLES: { 2243 struct pfioc_table *io = (struct pfioc_table *)addr; 2244 2245 if (io->pfrio_esize != sizeof(struct pfr_table)) { 2246 error = ENODEV; 2247 goto fail; 2248 } 2249 NET_LOCK(); 2250 PF_LOCK(); 2251 error = pfr_get_tables(&io->pfrio_table, io->pfrio_buffer, 2252 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); 2253 PF_UNLOCK(); 2254 NET_UNLOCK(); 2255 break; 2256 } 2257 2258 case DIOCRGETTSTATS: { 2259 struct pfioc_table *io = (struct pfioc_table *)addr; 2260 2261 if (io->pfrio_esize != sizeof(struct pfr_tstats)) { 2262 error = ENODEV; 2263 goto fail; 2264 } 2265 NET_LOCK(); 2266 PF_LOCK(); 2267 error = pfr_get_tstats(&io->pfrio_table, io->pfrio_buffer, 2268 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); 2269 PF_UNLOCK(); 2270 NET_UNLOCK(); 2271 break; 2272 } 2273 2274 case DIOCRCLRTSTATS: { 2275 struct pfioc_table *io = (struct pfioc_table *)addr; 2276 2277 if (io->pfrio_esize != sizeof(struct pfr_table)) { 2278 error = ENODEV; 2279 goto fail; 2280 } 2281 NET_LOCK(); 2282 PF_LOCK(); 2283 error = pfr_clr_tstats(io->pfrio_buffer, io->pfrio_size, 2284 &io->pfrio_nzero, io->pfrio_flags | PFR_FLAG_USERIOCTL); 2285 PF_UNLOCK(); 2286 NET_UNLOCK(); 2287 break; 2288 } 2289 2290 case DIOCRSETTFLAGS: { 2291 struct pfioc_table *io = (struct pfioc_table *)addr; 2292 2293 if (io->pfrio_esize != sizeof(struct pfr_table)) { 2294 error = ENODEV; 2295 goto fail; 2296 } 2297 NET_LOCK(); 2298 PF_LOCK(); 2299 error = pfr_set_tflags(io->pfrio_buffer, io->pfrio_size, 2300 io->pfrio_setflag, io->pfrio_clrflag, &io->pfrio_nchange, 2301 &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL); 2302 PF_UNLOCK(); 2303 NET_UNLOCK(); 2304 break; 2305 } 2306 2307 case DIOCRCLRADDRS: { 2308 struct pfioc_table *io = (struct pfioc_table *)addr; 2309 2310 if (io->pfrio_esize != 0) { 2311 error = ENODEV; 2312 goto fail; 2313 } 2314 NET_LOCK(); 2315 PF_LOCK(); 2316 error = pfr_clr_addrs(&io->pfrio_table, &io->pfrio_ndel, 2317 io->pfrio_flags | PFR_FLAG_USERIOCTL); 2318 PF_UNLOCK(); 2319 NET_UNLOCK(); 2320 break; 2321 } 2322 2323 case DIOCRADDADDRS: { 2324 struct pfioc_table *io = (struct pfioc_table *)addr; 2325 2326 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 2327 error = ENODEV; 2328 goto fail; 2329 } 2330 error = pfr_add_addrs(&io->pfrio_table, io->pfrio_buffer, 2331 io->pfrio_size, &io->pfrio_nadd, io->pfrio_flags | 2332 PFR_FLAG_USERIOCTL); 2333 break; 2334 } 2335 2336 case DIOCRDELADDRS: { 2337 struct pfioc_table *io = (struct pfioc_table *)addr; 2338 2339 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 2340 error = ENODEV; 2341 goto fail; 2342 } 2343 NET_LOCK(); 2344 PF_LOCK(); 2345 error = pfr_del_addrs(&io->pfrio_table, io->pfrio_buffer, 2346 io->pfrio_size, &io->pfrio_ndel, io->pfrio_flags | 2347 PFR_FLAG_USERIOCTL); 2348 PF_UNLOCK(); 2349 NET_UNLOCK(); 2350 break; 2351 } 2352 2353 case DIOCRSETADDRS: { 2354 struct pfioc_table *io = (struct pfioc_table *)addr; 2355 2356 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 2357 error = ENODEV; 2358 goto fail; 2359 } 2360 NET_LOCK(); 2361 PF_LOCK(); 2362 error = pfr_set_addrs(&io->pfrio_table, io->pfrio_buffer, 2363 io->pfrio_size, &io->pfrio_size2, &io->pfrio_nadd, 2364 &io->pfrio_ndel, &io->pfrio_nchange, io->pfrio_flags | 2365 PFR_FLAG_USERIOCTL, 0); 2366 PF_UNLOCK(); 2367 NET_UNLOCK(); 2368 break; 2369 } 2370 2371 case DIOCRGETADDRS: { 2372 struct pfioc_table *io = (struct pfioc_table *)addr; 2373 2374 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 2375 error = ENODEV; 2376 goto fail; 2377 } 2378 NET_LOCK(); 2379 PF_LOCK(); 2380 error = pfr_get_addrs(&io->pfrio_table, io->pfrio_buffer, 2381 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); 2382 PF_UNLOCK(); 2383 NET_UNLOCK(); 2384 break; 2385 } 2386 2387 case DIOCRGETASTATS: { 2388 struct pfioc_table *io = (struct pfioc_table *)addr; 2389 2390 if (io->pfrio_esize != sizeof(struct pfr_astats)) { 2391 error = ENODEV; 2392 goto fail; 2393 } 2394 NET_LOCK(); 2395 PF_LOCK(); 2396 error = pfr_get_astats(&io->pfrio_table, io->pfrio_buffer, 2397 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); 2398 PF_UNLOCK(); 2399 NET_UNLOCK(); 2400 break; 2401 } 2402 2403 case DIOCRCLRASTATS: { 2404 struct pfioc_table *io = (struct pfioc_table *)addr; 2405 2406 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 2407 error = ENODEV; 2408 goto fail; 2409 } 2410 NET_LOCK(); 2411 PF_LOCK(); 2412 error = pfr_clr_astats(&io->pfrio_table, io->pfrio_buffer, 2413 io->pfrio_size, &io->pfrio_nzero, io->pfrio_flags | 2414 PFR_FLAG_USERIOCTL); 2415 PF_UNLOCK(); 2416 NET_UNLOCK(); 2417 break; 2418 } 2419 2420 case DIOCRTSTADDRS: { 2421 struct pfioc_table *io = (struct pfioc_table *)addr; 2422 2423 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 2424 error = ENODEV; 2425 goto fail; 2426 } 2427 NET_LOCK(); 2428 PF_LOCK(); 2429 error = pfr_tst_addrs(&io->pfrio_table, io->pfrio_buffer, 2430 io->pfrio_size, &io->pfrio_nmatch, io->pfrio_flags | 2431 PFR_FLAG_USERIOCTL); 2432 PF_UNLOCK(); 2433 NET_UNLOCK(); 2434 break; 2435 } 2436 2437 case DIOCRINADEFINE: { 2438 struct pfioc_table *io = (struct pfioc_table *)addr; 2439 2440 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 2441 error = ENODEV; 2442 goto fail; 2443 } 2444 NET_LOCK(); 2445 PF_LOCK(); 2446 error = pfr_ina_define(&io->pfrio_table, io->pfrio_buffer, 2447 io->pfrio_size, &io->pfrio_nadd, &io->pfrio_naddr, 2448 io->pfrio_ticket, io->pfrio_flags | PFR_FLAG_USERIOCTL); 2449 PF_UNLOCK(); 2450 NET_UNLOCK(); 2451 break; 2452 } 2453 2454 case DIOCOSFPADD: { 2455 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr; 2456 error = pf_osfp_add(io); 2457 break; 2458 } 2459 2460 case DIOCOSFPGET: { 2461 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr; 2462 error = pf_osfp_get(io); 2463 break; 2464 } 2465 2466 case DIOCXBEGIN: { 2467 struct pfioc_trans *io = (struct pfioc_trans *)addr; 2468 struct pfioc_trans_e *ioe; 2469 struct pfr_table *table; 2470 int i; 2471 2472 if (io->esize != sizeof(*ioe)) { 2473 error = ENODEV; 2474 goto fail; 2475 } 2476 ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK); 2477 table = malloc(sizeof(*table), M_TEMP, M_WAITOK); 2478 NET_LOCK(); 2479 PF_LOCK(); 2480 pf_default_rule_new = pf_default_rule; 2481 PF_UNLOCK(); 2482 NET_UNLOCK(); 2483 memset(&pf_trans_set, 0, sizeof(pf_trans_set)); 2484 for (i = 0; i < io->size; i++) { 2485 if (copyin(io->array+i, ioe, sizeof(*ioe))) { 2486 free(table, M_TEMP, sizeof(*table)); 2487 free(ioe, M_TEMP, sizeof(*ioe)); 2488 error = EFAULT; 2489 goto fail; 2490 } 2491 if (strnlen(ioe->anchor, sizeof(ioe->anchor)) == 2492 sizeof(ioe->anchor)) { 2493 free(table, M_TEMP, sizeof(*table)); 2494 free(ioe, M_TEMP, sizeof(*ioe)); 2495 error = ENAMETOOLONG; 2496 goto fail; 2497 } 2498 NET_LOCK(); 2499 PF_LOCK(); 2500 switch (ioe->type) { 2501 case PF_TRANS_TABLE: 2502 memset(table, 0, sizeof(*table)); 2503 strlcpy(table->pfrt_anchor, ioe->anchor, 2504 sizeof(table->pfrt_anchor)); 2505 if ((error = pfr_ina_begin(table, 2506 &ioe->ticket, NULL, 0))) { 2507 PF_UNLOCK(); 2508 NET_UNLOCK(); 2509 free(table, M_TEMP, sizeof(*table)); 2510 free(ioe, M_TEMP, sizeof(*ioe)); 2511 goto fail; 2512 } 2513 break; 2514 case PF_TRANS_RULESET: 2515 if ((error = pf_begin_rules(&ioe->ticket, 2516 ioe->anchor))) { 2517 PF_UNLOCK(); 2518 NET_UNLOCK(); 2519 free(table, M_TEMP, sizeof(*table)); 2520 free(ioe, M_TEMP, sizeof(*ioe)); 2521 goto fail; 2522 } 2523 break; 2524 default: 2525 PF_UNLOCK(); 2526 NET_UNLOCK(); 2527 free(table, M_TEMP, sizeof(*table)); 2528 free(ioe, M_TEMP, sizeof(*ioe)); 2529 error = EINVAL; 2530 goto fail; 2531 } 2532 PF_UNLOCK(); 2533 NET_UNLOCK(); 2534 if (copyout(ioe, io->array+i, sizeof(io->array[i]))) { 2535 free(table, M_TEMP, sizeof(*table)); 2536 free(ioe, M_TEMP, sizeof(*ioe)); 2537 error = EFAULT; 2538 goto fail; 2539 } 2540 } 2541 free(table, M_TEMP, sizeof(*table)); 2542 free(ioe, M_TEMP, sizeof(*ioe)); 2543 break; 2544 } 2545 2546 case DIOCXROLLBACK: { 2547 struct pfioc_trans *io = (struct pfioc_trans *)addr; 2548 struct pfioc_trans_e *ioe; 2549 struct pfr_table *table; 2550 int i; 2551 2552 if (io->esize != sizeof(*ioe)) { 2553 error = ENODEV; 2554 goto fail; 2555 } 2556 ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK); 2557 table = malloc(sizeof(*table), M_TEMP, M_WAITOK); 2558 for (i = 0; i < io->size; i++) { 2559 if (copyin(io->array+i, ioe, sizeof(*ioe))) { 2560 free(table, M_TEMP, sizeof(*table)); 2561 free(ioe, M_TEMP, sizeof(*ioe)); 2562 error = EFAULT; 2563 goto fail; 2564 } 2565 if (strnlen(ioe->anchor, sizeof(ioe->anchor)) == 2566 sizeof(ioe->anchor)) { 2567 free(table, M_TEMP, sizeof(*table)); 2568 free(ioe, M_TEMP, sizeof(*ioe)); 2569 error = ENAMETOOLONG; 2570 goto fail; 2571 } 2572 NET_LOCK(); 2573 PF_LOCK(); 2574 switch (ioe->type) { 2575 case PF_TRANS_TABLE: 2576 memset(table, 0, sizeof(*table)); 2577 strlcpy(table->pfrt_anchor, ioe->anchor, 2578 sizeof(table->pfrt_anchor)); 2579 if ((error = pfr_ina_rollback(table, 2580 ioe->ticket, NULL, 0))) { 2581 PF_UNLOCK(); 2582 NET_UNLOCK(); 2583 free(table, M_TEMP, sizeof(*table)); 2584 free(ioe, M_TEMP, sizeof(*ioe)); 2585 goto fail; /* really bad */ 2586 } 2587 break; 2588 case PF_TRANS_RULESET: 2589 pf_rollback_rules(ioe->ticket, ioe->anchor); 2590 break; 2591 default: 2592 PF_UNLOCK(); 2593 NET_UNLOCK(); 2594 free(table, M_TEMP, sizeof(*table)); 2595 free(ioe, M_TEMP, sizeof(*ioe)); 2596 error = EINVAL; 2597 goto fail; /* really bad */ 2598 } 2599 PF_UNLOCK(); 2600 NET_UNLOCK(); 2601 } 2602 free(table, M_TEMP, sizeof(*table)); 2603 free(ioe, M_TEMP, sizeof(*ioe)); 2604 break; 2605 } 2606 2607 case DIOCXCOMMIT: { 2608 struct pfioc_trans *io = (struct pfioc_trans *)addr; 2609 struct pfioc_trans_e *ioe; 2610 struct pfr_table *table; 2611 struct pf_ruleset *rs; 2612 int i; 2613 2614 if (io->esize != sizeof(*ioe)) { 2615 error = ENODEV; 2616 goto fail; 2617 } 2618 ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK); 2619 table = malloc(sizeof(*table), M_TEMP, M_WAITOK); 2620 NET_LOCK(); 2621 PF_LOCK(); 2622 /* first makes sure everything will succeed */ 2623 for (i = 0; i < io->size; i++) { 2624 if (copyin(io->array+i, ioe, sizeof(*ioe))) { 2625 PF_UNLOCK(); 2626 NET_UNLOCK(); 2627 free(table, M_TEMP, sizeof(*table)); 2628 free(ioe, M_TEMP, sizeof(*ioe)); 2629 error = EFAULT; 2630 goto fail; 2631 } 2632 if (strnlen(ioe->anchor, sizeof(ioe->anchor)) == 2633 sizeof(ioe->anchor)) { 2634 PF_UNLOCK(); 2635 NET_UNLOCK(); 2636 free(table, M_TEMP, sizeof(*table)); 2637 free(ioe, M_TEMP, sizeof(*ioe)); 2638 error = ENAMETOOLONG; 2639 goto fail; 2640 } 2641 switch (ioe->type) { 2642 case PF_TRANS_TABLE: 2643 rs = pf_find_ruleset(ioe->anchor); 2644 if (rs == NULL || !rs->topen || ioe->ticket != 2645 rs->tticket) { 2646 PF_UNLOCK(); 2647 NET_UNLOCK(); 2648 free(table, M_TEMP, sizeof(*table)); 2649 free(ioe, M_TEMP, sizeof(*ioe)); 2650 error = EBUSY; 2651 goto fail; 2652 } 2653 break; 2654 case PF_TRANS_RULESET: 2655 rs = pf_find_ruleset(ioe->anchor); 2656 if (rs == NULL || 2657 !rs->rules.inactive.open || 2658 rs->rules.inactive.ticket != 2659 ioe->ticket) { 2660 PF_UNLOCK(); 2661 NET_UNLOCK(); 2662 free(table, M_TEMP, sizeof(*table)); 2663 free(ioe, M_TEMP, sizeof(*ioe)); 2664 error = EBUSY; 2665 goto fail; 2666 } 2667 break; 2668 default: 2669 PF_UNLOCK(); 2670 NET_UNLOCK(); 2671 free(table, M_TEMP, sizeof(*table)); 2672 free(ioe, M_TEMP, sizeof(*ioe)); 2673 error = EINVAL; 2674 goto fail; 2675 } 2676 } 2677 2678 /* 2679 * Checked already in DIOCSETLIMIT, but check again as the 2680 * situation might have changed. 2681 */ 2682 for (i = 0; i < PF_LIMIT_MAX; i++) { 2683 if (((struct pool *)pf_pool_limits[i].pp)->pr_nout > 2684 pf_pool_limits[i].limit_new) { 2685 PF_UNLOCK(); 2686 NET_UNLOCK(); 2687 free(table, M_TEMP, sizeof(*table)); 2688 free(ioe, M_TEMP, sizeof(*ioe)); 2689 error = EBUSY; 2690 goto fail; 2691 } 2692 } 2693 /* now do the commit - no errors should happen here */ 2694 for (i = 0; i < io->size; i++) { 2695 if (copyin(io->array+i, ioe, sizeof(*ioe))) { 2696 PF_UNLOCK(); 2697 NET_UNLOCK(); 2698 free(table, M_TEMP, sizeof(*table)); 2699 free(ioe, M_TEMP, sizeof(*ioe)); 2700 error = EFAULT; 2701 goto fail; 2702 } 2703 if (strnlen(ioe->anchor, sizeof(ioe->anchor)) == 2704 sizeof(ioe->anchor)) { 2705 PF_UNLOCK(); 2706 NET_UNLOCK(); 2707 free(table, M_TEMP, sizeof(*table)); 2708 free(ioe, M_TEMP, sizeof(*ioe)); 2709 error = ENAMETOOLONG; 2710 goto fail; 2711 } 2712 switch (ioe->type) { 2713 case PF_TRANS_TABLE: 2714 memset(table, 0, sizeof(*table)); 2715 strlcpy(table->pfrt_anchor, ioe->anchor, 2716 sizeof(table->pfrt_anchor)); 2717 if ((error = pfr_ina_commit(table, ioe->ticket, 2718 NULL, NULL, 0))) { 2719 PF_UNLOCK(); 2720 NET_UNLOCK(); 2721 free(table, M_TEMP, sizeof(*table)); 2722 free(ioe, M_TEMP, sizeof(*ioe)); 2723 goto fail; /* really bad */ 2724 } 2725 break; 2726 case PF_TRANS_RULESET: 2727 if ((error = pf_commit_rules(ioe->ticket, 2728 ioe->anchor))) { 2729 PF_UNLOCK(); 2730 NET_UNLOCK(); 2731 free(table, M_TEMP, sizeof(*table)); 2732 free(ioe, M_TEMP, sizeof(*ioe)); 2733 goto fail; /* really bad */ 2734 } 2735 break; 2736 default: 2737 PF_UNLOCK(); 2738 NET_UNLOCK(); 2739 free(table, M_TEMP, sizeof(*table)); 2740 free(ioe, M_TEMP, sizeof(*ioe)); 2741 error = EINVAL; 2742 goto fail; /* really bad */ 2743 } 2744 } 2745 for (i = 0; i < PF_LIMIT_MAX; i++) { 2746 if (pf_pool_limits[i].limit_new != 2747 pf_pool_limits[i].limit && 2748 pool_sethardlimit(pf_pool_limits[i].pp, 2749 pf_pool_limits[i].limit_new, NULL, 0) != 0) { 2750 PF_UNLOCK(); 2751 NET_UNLOCK(); 2752 free(table, M_TEMP, sizeof(*table)); 2753 free(ioe, M_TEMP, sizeof(*ioe)); 2754 error = EBUSY; 2755 goto fail; /* really bad */ 2756 } 2757 pf_pool_limits[i].limit = pf_pool_limits[i].limit_new; 2758 } 2759 for (i = 0; i < PFTM_MAX; i++) { 2760 int old = pf_default_rule.timeout[i]; 2761 2762 pf_default_rule.timeout[i] = 2763 pf_default_rule_new.timeout[i]; 2764 if (pf_default_rule.timeout[i] == PFTM_INTERVAL && 2765 pf_default_rule.timeout[i] < old) 2766 task_add(net_tq(0), &pf_purge_task); 2767 } 2768 pfi_xcommit(); 2769 pf_trans_set_commit(); 2770 PF_UNLOCK(); 2771 NET_UNLOCK(); 2772 free(table, M_TEMP, sizeof(*table)); 2773 free(ioe, M_TEMP, sizeof(*ioe)); 2774 break; 2775 } 2776 2777 case DIOCGETSRCNODES: { 2778 struct pfioc_src_nodes *psn = (struct pfioc_src_nodes *)addr; 2779 struct pf_src_node *n, *p, *pstore; 2780 u_int32_t nr = 0; 2781 size_t space = psn->psn_len; 2782 2783 pstore = malloc(sizeof(*pstore), M_TEMP, M_WAITOK); 2784 2785 NET_LOCK(); 2786 PF_LOCK(); 2787 if (space == 0) { 2788 RB_FOREACH(n, pf_src_tree, &tree_src_tracking) 2789 nr++; 2790 psn->psn_len = sizeof(struct pf_src_node) * nr; 2791 PF_UNLOCK(); 2792 NET_UNLOCK(); 2793 free(pstore, M_TEMP, sizeof(*pstore)); 2794 goto fail; 2795 } 2796 2797 p = psn->psn_src_nodes; 2798 RB_FOREACH(n, pf_src_tree, &tree_src_tracking) { 2799 int secs = getuptime(), diff; 2800 2801 if ((nr + 1) * sizeof(*p) > psn->psn_len) 2802 break; 2803 2804 memcpy(pstore, n, sizeof(*pstore)); 2805 memset(&pstore->entry, 0, sizeof(pstore->entry)); 2806 pstore->rule.ptr = NULL; 2807 pstore->kif = NULL; 2808 pstore->rule.nr = n->rule.ptr->nr; 2809 pstore->creation = secs - pstore->creation; 2810 if (pstore->expire > secs) 2811 pstore->expire -= secs; 2812 else 2813 pstore->expire = 0; 2814 2815 /* adjust the connection rate estimate */ 2816 diff = secs - n->conn_rate.last; 2817 if (diff >= n->conn_rate.seconds) 2818 pstore->conn_rate.count = 0; 2819 else 2820 pstore->conn_rate.count -= 2821 n->conn_rate.count * diff / 2822 n->conn_rate.seconds; 2823 2824 error = copyout(pstore, p, sizeof(*p)); 2825 if (error) { 2826 PF_UNLOCK(); 2827 NET_UNLOCK(); 2828 free(pstore, M_TEMP, sizeof(*pstore)); 2829 goto fail; 2830 } 2831 p++; 2832 nr++; 2833 } 2834 psn->psn_len = sizeof(struct pf_src_node) * nr; 2835 2836 PF_UNLOCK(); 2837 NET_UNLOCK(); 2838 free(pstore, M_TEMP, sizeof(*pstore)); 2839 break; 2840 } 2841 2842 case DIOCCLRSRCNODES: { 2843 struct pf_src_node *n; 2844 struct pf_state *state; 2845 2846 NET_LOCK(); 2847 PF_LOCK(); 2848 PF_STATE_ENTER_WRITE(); 2849 RB_FOREACH(state, pf_state_tree_id, &tree_id) 2850 pf_src_tree_remove_state(state); 2851 PF_STATE_EXIT_WRITE(); 2852 RB_FOREACH(n, pf_src_tree, &tree_src_tracking) 2853 n->expire = 1; 2854 pf_purge_expired_src_nodes(); 2855 PF_UNLOCK(); 2856 NET_UNLOCK(); 2857 break; 2858 } 2859 2860 case DIOCKILLSRCNODES: { 2861 struct pf_src_node *sn; 2862 struct pf_state *s; 2863 struct pfioc_src_node_kill *psnk = 2864 (struct pfioc_src_node_kill *)addr; 2865 u_int killed = 0; 2866 2867 NET_LOCK(); 2868 PF_LOCK(); 2869 RB_FOREACH(sn, pf_src_tree, &tree_src_tracking) { 2870 if (pf_match_addr(psnk->psnk_src.neg, 2871 &psnk->psnk_src.addr.v.a.addr, 2872 &psnk->psnk_src.addr.v.a.mask, 2873 &sn->addr, sn->af) && 2874 pf_match_addr(psnk->psnk_dst.neg, 2875 &psnk->psnk_dst.addr.v.a.addr, 2876 &psnk->psnk_dst.addr.v.a.mask, 2877 &sn->raddr, sn->af)) { 2878 /* Handle state to src_node linkage */ 2879 if (sn->states != 0) { 2880 PF_ASSERT_LOCKED(); 2881 PF_STATE_ENTER_WRITE(); 2882 RB_FOREACH(s, pf_state_tree_id, 2883 &tree_id) 2884 pf_state_rm_src_node(s, sn); 2885 PF_STATE_EXIT_WRITE(); 2886 } 2887 sn->expire = 1; 2888 killed++; 2889 } 2890 } 2891 2892 if (killed > 0) 2893 pf_purge_expired_src_nodes(); 2894 2895 psnk->psnk_killed = killed; 2896 PF_UNLOCK(); 2897 NET_UNLOCK(); 2898 break; 2899 } 2900 2901 case DIOCSETHOSTID: { 2902 u_int32_t *hostid = (u_int32_t *)addr; 2903 2904 NET_LOCK(); 2905 PF_LOCK(); 2906 if (*hostid == 0) 2907 pf_trans_set.hostid = arc4random(); 2908 else 2909 pf_trans_set.hostid = *hostid; 2910 pf_trans_set.mask |= PF_TSET_HOSTID; 2911 PF_UNLOCK(); 2912 NET_UNLOCK(); 2913 break; 2914 } 2915 2916 case DIOCOSFPFLUSH: 2917 pf_osfp_flush(); 2918 break; 2919 2920 case DIOCIGETIFACES: { 2921 struct pfioc_iface *io = (struct pfioc_iface *)addr; 2922 struct pfi_kif *kif_buf; 2923 int apfiio_size = io->pfiio_size; 2924 2925 if (io->pfiio_esize != sizeof(struct pfi_kif)) { 2926 error = ENODEV; 2927 goto fail; 2928 } 2929 2930 if ((kif_buf = mallocarray(sizeof(*kif_buf), apfiio_size, 2931 M_TEMP, M_WAITOK|M_CANFAIL)) == NULL) { 2932 error = EINVAL; 2933 goto fail; 2934 } 2935 2936 NET_LOCK(); 2937 PF_LOCK(); 2938 pfi_get_ifaces(io->pfiio_name, kif_buf, &io->pfiio_size); 2939 PF_UNLOCK(); 2940 NET_UNLOCK(); 2941 if (copyout(kif_buf, io->pfiio_buffer, sizeof(*kif_buf) * 2942 io->pfiio_size)) 2943 error = EFAULT; 2944 free(kif_buf, M_TEMP, sizeof(*kif_buf) * apfiio_size); 2945 break; 2946 } 2947 2948 case DIOCSETIFFLAG: { 2949 struct pfioc_iface *io = (struct pfioc_iface *)addr; 2950 2951 if (io == NULL) { 2952 error = EINVAL; 2953 goto fail; 2954 } 2955 2956 NET_LOCK(); 2957 PF_LOCK(); 2958 error = pfi_set_flags(io->pfiio_name, io->pfiio_flags); 2959 PF_UNLOCK(); 2960 NET_UNLOCK(); 2961 break; 2962 } 2963 2964 case DIOCCLRIFFLAG: { 2965 struct pfioc_iface *io = (struct pfioc_iface *)addr; 2966 2967 if (io == NULL) { 2968 error = EINVAL; 2969 goto fail; 2970 } 2971 2972 NET_LOCK(); 2973 PF_LOCK(); 2974 error = pfi_clear_flags(io->pfiio_name, io->pfiio_flags); 2975 PF_UNLOCK(); 2976 NET_UNLOCK(); 2977 break; 2978 } 2979 2980 case DIOCSETREASS: { 2981 u_int32_t *reass = (u_int32_t *)addr; 2982 2983 NET_LOCK(); 2984 PF_LOCK(); 2985 pf_trans_set.reass = *reass; 2986 pf_trans_set.mask |= PF_TSET_REASS; 2987 PF_UNLOCK(); 2988 NET_UNLOCK(); 2989 break; 2990 } 2991 2992 case DIOCSETSYNFLWATS: { 2993 struct pfioc_synflwats *io = (struct pfioc_synflwats *)addr; 2994 2995 NET_LOCK(); 2996 PF_LOCK(); 2997 error = pf_syncookies_setwats(io->hiwat, io->lowat); 2998 PF_UNLOCK(); 2999 NET_UNLOCK(); 3000 break; 3001 } 3002 3003 case DIOCGETSYNFLWATS: { 3004 struct pfioc_synflwats *io = (struct pfioc_synflwats *)addr; 3005 3006 NET_LOCK(); 3007 PF_LOCK(); 3008 error = pf_syncookies_getwats(io); 3009 PF_UNLOCK(); 3010 NET_UNLOCK(); 3011 break; 3012 } 3013 3014 case DIOCSETSYNCOOKIES: { 3015 u_int8_t *mode = (u_int8_t *)addr; 3016 3017 NET_LOCK(); 3018 PF_LOCK(); 3019 error = pf_syncookies_setmode(*mode); 3020 PF_UNLOCK(); 3021 NET_UNLOCK(); 3022 break; 3023 } 3024 3025 default: 3026 error = ENODEV; 3027 break; 3028 } 3029 fail: 3030 if (flags & FWRITE) 3031 rw_exit_write(&pfioctl_rw); 3032 else 3033 rw_exit_read(&pfioctl_rw); 3034 3035 return (error); 3036 } 3037 3038 void 3039 pf_trans_set_commit(void) 3040 { 3041 if (pf_trans_set.mask & PF_TSET_STATUSIF) 3042 strlcpy(pf_status.ifname, pf_trans_set.statusif, IFNAMSIZ); 3043 if (pf_trans_set.mask & PF_TSET_DEBUG) 3044 pf_status.debug = pf_trans_set.debug; 3045 if (pf_trans_set.mask & PF_TSET_HOSTID) 3046 pf_status.hostid = pf_trans_set.hostid; 3047 if (pf_trans_set.mask & PF_TSET_REASS) 3048 pf_status.reass = pf_trans_set.reass; 3049 } 3050 3051 void 3052 pf_pool_copyin(struct pf_pool *from, struct pf_pool *to) 3053 { 3054 memmove(to, from, sizeof(*to)); 3055 to->kif = NULL; 3056 to->addr.p.tbl = NULL; 3057 } 3058 3059 int 3060 pf_validate_range(u_int8_t op, u_int16_t port[2], int order) 3061 { 3062 u_int16_t a = (order == PF_ORDER_NET) ? ntohs(port[0]) : port[0]; 3063 u_int16_t b = (order == PF_ORDER_NET) ? ntohs(port[1]) : port[1]; 3064 3065 if ((op == PF_OP_RRG && a > b) || /* 34:12, i.e. none */ 3066 (op == PF_OP_IRG && a >= b) || /* 34><12, i.e. none */ 3067 (op == PF_OP_XRG && a > b)) /* 34<>22, i.e. all */ 3068 return 1; 3069 return 0; 3070 } 3071 3072 int 3073 pf_rule_copyin(struct pf_rule *from, struct pf_rule *to) 3074 { 3075 int i; 3076 3077 if (from->scrub_flags & PFSTATE_SETPRIO && 3078 (from->set_prio[0] > IFQ_MAXPRIO || 3079 from->set_prio[1] > IFQ_MAXPRIO)) 3080 return (EINVAL); 3081 3082 to->src = from->src; 3083 to->src.addr.p.tbl = NULL; 3084 to->dst = from->dst; 3085 to->dst.addr.p.tbl = NULL; 3086 3087 if (pf_validate_range(to->src.port_op, to->src.port, PF_ORDER_NET)) 3088 return (EINVAL); 3089 if (pf_validate_range(to->dst.port_op, to->dst.port, PF_ORDER_NET)) 3090 return (EINVAL); 3091 3092 /* XXX union skip[] */ 3093 3094 strlcpy(to->label, from->label, sizeof(to->label)); 3095 strlcpy(to->ifname, from->ifname, sizeof(to->ifname)); 3096 strlcpy(to->rcv_ifname, from->rcv_ifname, sizeof(to->rcv_ifname)); 3097 strlcpy(to->qname, from->qname, sizeof(to->qname)); 3098 strlcpy(to->pqname, from->pqname, sizeof(to->pqname)); 3099 strlcpy(to->tagname, from->tagname, sizeof(to->tagname)); 3100 strlcpy(to->match_tagname, from->match_tagname, 3101 sizeof(to->match_tagname)); 3102 strlcpy(to->overload_tblname, from->overload_tblname, 3103 sizeof(to->overload_tblname)); 3104 3105 pf_pool_copyin(&from->nat, &to->nat); 3106 pf_pool_copyin(&from->rdr, &to->rdr); 3107 pf_pool_copyin(&from->route, &to->route); 3108 3109 if (pf_validate_range(to->rdr.port_op, to->rdr.proxy_port, 3110 PF_ORDER_HOST)) 3111 return (EINVAL); 3112 3113 to->kif = (to->ifname[0]) ? 3114 pfi_kif_alloc(to->ifname, M_WAITOK) : NULL; 3115 to->rcv_kif = (to->rcv_ifname[0]) ? 3116 pfi_kif_alloc(to->rcv_ifname, M_WAITOK) : NULL; 3117 to->rdr.kif = (to->rdr.ifname[0]) ? 3118 pfi_kif_alloc(to->rdr.ifname, M_WAITOK) : NULL; 3119 to->nat.kif = (to->nat.ifname[0]) ? 3120 pfi_kif_alloc(to->nat.ifname, M_WAITOK) : NULL; 3121 to->route.kif = (to->route.ifname[0]) ? 3122 pfi_kif_alloc(to->route.ifname, M_WAITOK) : NULL; 3123 3124 to->os_fingerprint = from->os_fingerprint; 3125 3126 to->rtableid = from->rtableid; 3127 if (to->rtableid >= 0 && !rtable_exists(to->rtableid)) 3128 return (EBUSY); 3129 to->onrdomain = from->onrdomain; 3130 if (to->onrdomain != -1 && (to->onrdomain < 0 || 3131 to->onrdomain > RT_TABLEID_MAX)) 3132 return (EINVAL); 3133 3134 for (i = 0; i < PFTM_MAX; i++) 3135 to->timeout[i] = from->timeout[i]; 3136 to->states_tot = from->states_tot; 3137 to->max_states = from->max_states; 3138 to->max_src_nodes = from->max_src_nodes; 3139 to->max_src_states = from->max_src_states; 3140 to->max_src_conn = from->max_src_conn; 3141 to->max_src_conn_rate.limit = from->max_src_conn_rate.limit; 3142 to->max_src_conn_rate.seconds = from->max_src_conn_rate.seconds; 3143 pf_init_threshold(&to->pktrate, from->pktrate.limit, 3144 from->pktrate.seconds); 3145 3146 if (to->qname[0] != 0) { 3147 if ((to->qid = pf_qname2qid(to->qname, 0)) == 0) 3148 return (EBUSY); 3149 if (to->pqname[0] != 0) { 3150 if ((to->pqid = pf_qname2qid(to->pqname, 0)) == 0) 3151 return (EBUSY); 3152 } else 3153 to->pqid = to->qid; 3154 } 3155 to->rt_listid = from->rt_listid; 3156 to->prob = from->prob; 3157 to->return_icmp = from->return_icmp; 3158 to->return_icmp6 = from->return_icmp6; 3159 to->max_mss = from->max_mss; 3160 if (to->tagname[0]) 3161 if ((to->tag = pf_tagname2tag(to->tagname, 1)) == 0) 3162 return (EBUSY); 3163 if (to->match_tagname[0]) 3164 if ((to->match_tag = pf_tagname2tag(to->match_tagname, 1)) == 0) 3165 return (EBUSY); 3166 to->scrub_flags = from->scrub_flags; 3167 to->delay = from->delay; 3168 to->uid = from->uid; 3169 to->gid = from->gid; 3170 to->rule_flag = from->rule_flag; 3171 to->action = from->action; 3172 to->direction = from->direction; 3173 to->log = from->log; 3174 to->logif = from->logif; 3175 #if NPFLOG > 0 3176 if (!to->log) 3177 to->logif = 0; 3178 #endif /* NPFLOG > 0 */ 3179 to->quick = from->quick; 3180 to->ifnot = from->ifnot; 3181 to->rcvifnot = from->rcvifnot; 3182 to->match_tag_not = from->match_tag_not; 3183 to->keep_state = from->keep_state; 3184 to->af = from->af; 3185 to->naf = from->naf; 3186 to->proto = from->proto; 3187 to->type = from->type; 3188 to->code = from->code; 3189 to->flags = from->flags; 3190 to->flagset = from->flagset; 3191 to->min_ttl = from->min_ttl; 3192 to->allow_opts = from->allow_opts; 3193 to->rt = from->rt; 3194 to->return_ttl = from->return_ttl; 3195 to->tos = from->tos; 3196 to->set_tos = from->set_tos; 3197 to->anchor_relative = from->anchor_relative; /* XXX */ 3198 to->anchor_wildcard = from->anchor_wildcard; /* XXX */ 3199 to->flush = from->flush; 3200 to->divert.addr = from->divert.addr; 3201 to->divert.port = from->divert.port; 3202 to->divert.type = from->divert.type; 3203 to->prio = from->prio; 3204 to->set_prio[0] = from->set_prio[0]; 3205 to->set_prio[1] = from->set_prio[1]; 3206 3207 return (0); 3208 } 3209 3210 int 3211 pf_rule_checkaf(struct pf_rule *r) 3212 { 3213 switch (r->af) { 3214 case 0: 3215 if (r->rule_flag & PFRULE_AFTO) 3216 return (EPFNOSUPPORT); 3217 break; 3218 case AF_INET: 3219 if ((r->rule_flag & PFRULE_AFTO) && r->naf != AF_INET6) 3220 return (EPFNOSUPPORT); 3221 break; 3222 #ifdef INET6 3223 case AF_INET6: 3224 if ((r->rule_flag & PFRULE_AFTO) && r->naf != AF_INET) 3225 return (EPFNOSUPPORT); 3226 break; 3227 #endif /* INET6 */ 3228 default: 3229 return (EPFNOSUPPORT); 3230 } 3231 3232 if ((r->rule_flag & PFRULE_AFTO) == 0 && r->naf != 0) 3233 return (EPFNOSUPPORT); 3234 3235 return (0); 3236 } 3237 3238 int 3239 pf_sysctl(void *oldp, size_t *oldlenp, void *newp, size_t newlen) 3240 { 3241 struct pf_status pfs; 3242 3243 NET_RLOCK_IN_IOCTL(); 3244 PF_LOCK(); 3245 memcpy(&pfs, &pf_status, sizeof(struct pf_status)); 3246 pfi_update_status(pfs.ifname, &pfs); 3247 PF_UNLOCK(); 3248 NET_RUNLOCK_IN_IOCTL(); 3249 3250 return sysctl_rdstruct(oldp, oldlenp, newp, &pfs, sizeof(pfs)); 3251 } 3252