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