1 /* $OpenBSD: pf_ioctl.c,v 1.300 2016/09/15 02:00:18 dlg Exp $ */ 2 3 /* 4 * Copyright (c) 2001 Daniel Hartmeier 5 * Copyright (c) 2002 - 2013 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/mbuf.h> 44 #include <sys/filio.h> 45 #include <sys/fcntl.h> 46 #include <sys/socket.h> 47 #include <sys/socketvar.h> 48 #include <sys/kernel.h> 49 #include <sys/time.h> 50 #include <sys/timeout.h> 51 #include <sys/pool.h> 52 #include <sys/malloc.h> 53 #include <sys/kthread.h> 54 #include <sys/rwlock.h> 55 #include <sys/syslog.h> 56 #include <uvm/uvm_extern.h> 57 58 #include <net/if.h> 59 #include <net/if_var.h> 60 #include <net/route.h> 61 #include <net/hfsc.h> 62 63 #include <netinet/in.h> 64 #include <netinet/ip.h> 65 #include <netinet/ip_var.h> 66 #include <netinet/ip_icmp.h> 67 68 #include <crypto/md5.h> 69 #include <net/pfvar.h> 70 71 #if NPFSYNC > 0 72 #include <netinet/ip_ipsp.h> 73 #include <net/if_pfsync.h> 74 #endif /* NPFSYNC > 0 */ 75 76 #ifdef INET6 77 #include <netinet/ip6.h> 78 #include <netinet/in_pcb.h> 79 #endif /* INET6 */ 80 81 void pfattach(int); 82 void pf_thread_create(void *); 83 int pfopen(dev_t, int, int, struct proc *); 84 int pfclose(dev_t, int, int, struct proc *); 85 int pfioctl(dev_t, u_long, caddr_t, int, struct proc *); 86 int pf_begin_rules(u_int32_t *, const char *); 87 int pf_rollback_rules(u_int32_t, char *); 88 int pf_enable_queues(void); 89 void pf_remove_queues(void); 90 int pf_commit_queues(void); 91 void pf_free_queues(struct pf_queuehead *); 92 int pf_setup_pfsync_matching(struct pf_ruleset *); 93 void pf_hash_rule(MD5_CTX *, struct pf_rule *); 94 void pf_hash_rule_addr(MD5_CTX *, struct pf_rule_addr *); 95 int pf_commit_rules(u_int32_t, char *); 96 int pf_addr_setup(struct pf_ruleset *, 97 struct pf_addr_wrap *, sa_family_t); 98 int pf_kif_setup(char *, struct pfi_kif **); 99 void pf_addr_copyout(struct pf_addr_wrap *); 100 void pf_trans_set_commit(void); 101 void pf_pool_copyin(struct pf_pool *, struct pf_pool *); 102 int pf_rule_copyin(struct pf_rule *, struct pf_rule *, 103 struct pf_ruleset *); 104 u_int16_t pf_qname2qid(char *, int); 105 void pf_qid2qname(u_int16_t, char *); 106 void pf_qid_unref(u_int16_t); 107 108 struct pf_rule pf_default_rule, pf_default_rule_new; 109 struct rwlock pf_consistency_lock = RWLOCK_INITIALIZER("pfcnslk"); 110 111 struct { 112 char statusif[IFNAMSIZ]; 113 u_int32_t debug; 114 u_int32_t hostid; 115 u_int32_t reass; 116 u_int32_t mask; 117 } pf_trans_set; 118 119 #define PF_TSET_STATUSIF 0x01 120 #define PF_TSET_DEBUG 0x02 121 #define PF_TSET_HOSTID 0x04 122 #define PF_TSET_REASS 0x08 123 124 #define TAGID_MAX 50000 125 TAILQ_HEAD(pf_tags, pf_tagname) pf_tags = TAILQ_HEAD_INITIALIZER(pf_tags), 126 pf_qids = TAILQ_HEAD_INITIALIZER(pf_qids); 127 128 #if (PF_QNAME_SIZE != PF_TAG_NAME_SIZE) 129 #error PF_QNAME_SIZE must be equal to PF_TAG_NAME_SIZE 130 #endif 131 u_int16_t tagname2tag(struct pf_tags *, char *, int); 132 void tag2tagname(struct pf_tags *, u_int16_t, char *); 133 void tag_unref(struct pf_tags *, u_int16_t); 134 int pf_rtlabel_add(struct pf_addr_wrap *); 135 void pf_rtlabel_remove(struct pf_addr_wrap *); 136 void pf_rtlabel_copyout(struct pf_addr_wrap *); 137 138 139 void 140 pfattach(int num) 141 { 142 u_int32_t *timeout = pf_default_rule.timeout; 143 144 pool_init(&pf_rule_pl, sizeof(struct pf_rule), 0, 145 IPL_SOFTNET, 0, "pfrule", NULL); 146 pool_init(&pf_src_tree_pl, sizeof(struct pf_src_node), 0, 147 IPL_SOFTNET, 0, "pfsrctr", NULL); 148 pool_init(&pf_sn_item_pl, sizeof(struct pf_sn_item), 0, 149 IPL_SOFTNET, 0, "pfsnitem", NULL); 150 pool_init(&pf_state_pl, sizeof(struct pf_state), 0, 151 IPL_SOFTNET, 0, "pfstate", NULL); 152 pool_init(&pf_state_key_pl, sizeof(struct pf_state_key), 0, 153 IPL_SOFTNET, 0, "pfstkey", NULL); 154 pool_init(&pf_state_item_pl, sizeof(struct pf_state_item), 0, 155 IPL_SOFTNET, 0, "pfstitem", NULL); 156 pool_init(&pf_rule_item_pl, sizeof(struct pf_rule_item), 0, 157 IPL_SOFTNET, 0, "pfruleitem", NULL); 158 pool_init(&pf_queue_pl, sizeof(struct pf_queuespec), 0, 159 IPL_SOFTNET, 0, "pfqueue", NULL); 160 hfsc_initialize(); 161 pfr_initialize(); 162 pfi_initialize(); 163 pf_osfp_initialize(); 164 165 pool_sethardlimit(pf_pool_limits[PF_LIMIT_STATES].pp, 166 pf_pool_limits[PF_LIMIT_STATES].limit, NULL, 0); 167 168 if (physmem <= atop(100*1024*1024)) 169 pf_pool_limits[PF_LIMIT_TABLE_ENTRIES].limit = 170 PFR_KENTRY_HIWAT_SMALL; 171 172 RB_INIT(&tree_src_tracking); 173 RB_INIT(&pf_anchors); 174 pf_init_ruleset(&pf_main_ruleset); 175 TAILQ_INIT(&pf_queues[0]); 176 TAILQ_INIT(&pf_queues[1]); 177 pf_queues_active = &pf_queues[0]; 178 pf_queues_inactive = &pf_queues[1]; 179 TAILQ_INIT(&state_list); 180 181 /* default rule should never be garbage collected */ 182 pf_default_rule.entries.tqe_prev = &pf_default_rule.entries.tqe_next; 183 pf_default_rule.action = PF_PASS; 184 pf_default_rule.nr = (u_int32_t)-1; 185 pf_default_rule.rtableid = -1; 186 187 /* initialize default timeouts */ 188 timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL; 189 timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL; 190 timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL; 191 timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL; 192 timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL; 193 timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL; 194 timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL; 195 timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL; 196 timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL; 197 timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL; 198 timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL; 199 timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL; 200 timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL; 201 timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL; 202 timeout[PFTM_FRAG] = PFTM_FRAG_VAL; 203 timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL; 204 timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL; 205 timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL; 206 timeout[PFTM_ADAPTIVE_START] = PFSTATE_ADAPT_START; 207 timeout[PFTM_ADAPTIVE_END] = PFSTATE_ADAPT_END; 208 209 pf_default_rule.src.addr.type = PF_ADDR_ADDRMASK; 210 pf_default_rule.dst.addr.type = PF_ADDR_ADDRMASK; 211 pf_default_rule.rdr.addr.type = PF_ADDR_NONE; 212 pf_default_rule.nat.addr.type = PF_ADDR_NONE; 213 pf_default_rule.route.addr.type = PF_ADDR_NONE; 214 215 pf_normalize_init(); 216 bzero(&pf_status, sizeof(pf_status)); 217 pf_status.debug = LOG_ERR; 218 pf_status.reass = PF_REASS_ENABLED; 219 220 /* XXX do our best to avoid a conflict */ 221 pf_status.hostid = arc4random(); 222 223 /* require process context to purge states, so perform in a thread */ 224 kthread_create_deferred(pf_thread_create, NULL); 225 } 226 227 void 228 pf_thread_create(void *v) 229 { 230 if (kthread_create(pf_purge_thread, NULL, NULL, "pfpurge")) 231 panic("pfpurge thread"); 232 } 233 234 int 235 pfopen(dev_t dev, int flags, int fmt, struct proc *p) 236 { 237 if (minor(dev) >= 1) 238 return (ENXIO); 239 return (0); 240 } 241 242 int 243 pfclose(dev_t dev, int flags, int fmt, struct proc *p) 244 { 245 if (minor(dev) >= 1) 246 return (ENXIO); 247 return (0); 248 } 249 250 void 251 pf_rm_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule) 252 { 253 if (rulequeue != NULL) { 254 if (rule->states_cur == 0 && rule->src_nodes == 0) { 255 /* 256 * XXX - we need to remove the table *before* detaching 257 * the rule to make sure the table code does not delete 258 * the anchor under our feet. 259 */ 260 pf_tbladdr_remove(&rule->src.addr); 261 pf_tbladdr_remove(&rule->dst.addr); 262 pf_tbladdr_remove(&rule->rdr.addr); 263 pf_tbladdr_remove(&rule->nat.addr); 264 pf_tbladdr_remove(&rule->route.addr); 265 if (rule->overload_tbl) 266 pfr_detach_table(rule->overload_tbl); 267 } 268 TAILQ_REMOVE(rulequeue, rule, entries); 269 rule->entries.tqe_prev = NULL; 270 rule->nr = (u_int32_t)-1; 271 } 272 273 if (rule->states_cur > 0 || rule->src_nodes > 0 || 274 rule->entries.tqe_prev != NULL) 275 return; 276 pf_tag_unref(rule->tag); 277 pf_tag_unref(rule->match_tag); 278 pf_rtlabel_remove(&rule->src.addr); 279 pf_rtlabel_remove(&rule->dst.addr); 280 pfi_dynaddr_remove(&rule->src.addr); 281 pfi_dynaddr_remove(&rule->dst.addr); 282 pfi_dynaddr_remove(&rule->rdr.addr); 283 pfi_dynaddr_remove(&rule->nat.addr); 284 pfi_dynaddr_remove(&rule->route.addr); 285 if (rulequeue == NULL) { 286 pf_tbladdr_remove(&rule->src.addr); 287 pf_tbladdr_remove(&rule->dst.addr); 288 pf_tbladdr_remove(&rule->rdr.addr); 289 pf_tbladdr_remove(&rule->nat.addr); 290 pf_tbladdr_remove(&rule->route.addr); 291 if (rule->overload_tbl) 292 pfr_detach_table(rule->overload_tbl); 293 } 294 pfi_kif_unref(rule->rcv_kif, PFI_KIF_REF_RULE); 295 pfi_kif_unref(rule->kif, PFI_KIF_REF_RULE); 296 pfi_kif_unref(rule->rdr.kif, PFI_KIF_REF_RULE); 297 pfi_kif_unref(rule->nat.kif, PFI_KIF_REF_RULE); 298 pfi_kif_unref(rule->route.kif, PFI_KIF_REF_RULE); 299 pf_anchor_remove(rule); 300 pool_put(&pf_rule_pl, rule); 301 } 302 303 void 304 pf_purge_rule(struct pf_rule *rule) 305 { 306 u_int32_t nr = 0; 307 struct pf_ruleset *ruleset; 308 309 KASSERT((rule != NULL) && (rule->ruleset != NULL)); 310 ruleset = rule->ruleset; 311 312 pf_rm_rule(ruleset->rules.active.ptr, rule); 313 ruleset->rules.active.rcount--; 314 TAILQ_FOREACH(rule, ruleset->rules.active.ptr, entries) 315 rule->nr = nr++; 316 ruleset->rules.active.ticket++; 317 pf_calc_skip_steps(ruleset->rules.active.ptr); 318 } 319 320 u_int16_t 321 tagname2tag(struct pf_tags *head, char *tagname, int create) 322 { 323 struct pf_tagname *tag, *p = NULL; 324 u_int16_t new_tagid = 1; 325 326 TAILQ_FOREACH(tag, head, entries) 327 if (strcmp(tagname, tag->name) == 0) { 328 tag->ref++; 329 return (tag->tag); 330 } 331 332 if (!create) 333 return (0); 334 335 /* 336 * to avoid fragmentation, we do a linear search from the beginning 337 * and take the first free slot we find. if there is none or the list 338 * is empty, append a new entry at the end. 339 */ 340 341 /* new entry */ 342 if (!TAILQ_EMPTY(head)) 343 for (p = TAILQ_FIRST(head); p != NULL && 344 p->tag == new_tagid; p = TAILQ_NEXT(p, entries)) 345 new_tagid = p->tag + 1; 346 347 if (new_tagid > TAGID_MAX) 348 return (0); 349 350 /* allocate and fill new struct pf_tagname */ 351 tag = malloc(sizeof(*tag), M_RTABLE, M_NOWAIT|M_ZERO); 352 if (tag == NULL) 353 return (0); 354 strlcpy(tag->name, tagname, sizeof(tag->name)); 355 tag->tag = new_tagid; 356 tag->ref++; 357 358 if (p != NULL) /* insert new entry before p */ 359 TAILQ_INSERT_BEFORE(p, tag, entries); 360 else /* either list empty or no free slot in between */ 361 TAILQ_INSERT_TAIL(head, tag, entries); 362 363 return (tag->tag); 364 } 365 366 void 367 tag2tagname(struct pf_tags *head, u_int16_t tagid, char *p) 368 { 369 struct pf_tagname *tag; 370 371 TAILQ_FOREACH(tag, head, entries) 372 if (tag->tag == tagid) { 373 strlcpy(p, tag->name, PF_TAG_NAME_SIZE); 374 return; 375 } 376 } 377 378 void 379 tag_unref(struct pf_tags *head, u_int16_t tag) 380 { 381 struct pf_tagname *p, *next; 382 383 if (tag == 0) 384 return; 385 386 for (p = TAILQ_FIRST(head); p != NULL; p = next) { 387 next = TAILQ_NEXT(p, entries); 388 if (tag == p->tag) { 389 if (--p->ref == 0) { 390 TAILQ_REMOVE(head, p, entries); 391 free(p, M_RTABLE, sizeof(*p)); 392 } 393 break; 394 } 395 } 396 } 397 398 u_int16_t 399 pf_tagname2tag(char *tagname, int create) 400 { 401 return (tagname2tag(&pf_tags, tagname, create)); 402 } 403 404 void 405 pf_tag2tagname(u_int16_t tagid, char *p) 406 { 407 tag2tagname(&pf_tags, tagid, p); 408 } 409 410 void 411 pf_tag_ref(u_int16_t tag) 412 { 413 struct pf_tagname *t; 414 415 TAILQ_FOREACH(t, &pf_tags, entries) 416 if (t->tag == tag) 417 break; 418 if (t != NULL) 419 t->ref++; 420 } 421 422 void 423 pf_tag_unref(u_int16_t tag) 424 { 425 tag_unref(&pf_tags, tag); 426 } 427 428 int 429 pf_rtlabel_add(struct pf_addr_wrap *a) 430 { 431 if (a->type == PF_ADDR_RTLABEL && 432 (a->v.rtlabel = rtlabel_name2id(a->v.rtlabelname)) == 0) 433 return (-1); 434 return (0); 435 } 436 437 void 438 pf_rtlabel_remove(struct pf_addr_wrap *a) 439 { 440 if (a->type == PF_ADDR_RTLABEL) 441 rtlabel_unref(a->v.rtlabel); 442 } 443 444 void 445 pf_rtlabel_copyout(struct pf_addr_wrap *a) 446 { 447 const char *name; 448 449 if (a->type == PF_ADDR_RTLABEL && a->v.rtlabel) { 450 if ((name = rtlabel_id2name(a->v.rtlabel)) == NULL) 451 strlcpy(a->v.rtlabelname, "?", 452 sizeof(a->v.rtlabelname)); 453 else 454 strlcpy(a->v.rtlabelname, name, 455 sizeof(a->v.rtlabelname)); 456 } 457 } 458 459 u_int16_t 460 pf_qname2qid(char *qname, int create) 461 { 462 return (tagname2tag(&pf_qids, qname, create)); 463 } 464 465 void 466 pf_qid2qname(u_int16_t qid, char *p) 467 { 468 tag2tagname(&pf_qids, qid, p); 469 } 470 471 void 472 pf_qid_unref(u_int16_t qid) 473 { 474 tag_unref(&pf_qids, (u_int16_t)qid); 475 } 476 477 int 478 pf_begin_rules(u_int32_t *ticket, const char *anchor) 479 { 480 struct pf_ruleset *rs; 481 struct pf_rule *rule; 482 483 if ((rs = pf_find_or_create_ruleset(anchor)) == NULL) 484 return (EINVAL); 485 while ((rule = TAILQ_FIRST(rs->rules.inactive.ptr)) != NULL) { 486 pf_rm_rule(rs->rules.inactive.ptr, rule); 487 rs->rules.inactive.rcount--; 488 } 489 *ticket = ++rs->rules.inactive.ticket; 490 rs->rules.inactive.open = 1; 491 return (0); 492 } 493 494 int 495 pf_rollback_rules(u_int32_t ticket, char *anchor) 496 { 497 struct pf_ruleset *rs; 498 struct pf_rule *rule; 499 500 rs = pf_find_ruleset(anchor); 501 if (rs == NULL || !rs->rules.inactive.open || 502 rs->rules.inactive.ticket != ticket) 503 return (0); 504 while ((rule = TAILQ_FIRST(rs->rules.inactive.ptr)) != NULL) { 505 pf_rm_rule(rs->rules.inactive.ptr, rule); 506 rs->rules.inactive.rcount--; 507 } 508 rs->rules.inactive.open = 0; 509 510 /* queue defs only in the main ruleset */ 511 if (anchor[0]) 512 return (0); 513 514 pf_free_queues(pf_queues_inactive); 515 516 return (0); 517 } 518 519 void 520 pf_free_queues(struct pf_queuehead *where) 521 { 522 struct pf_queuespec *q, *qtmp; 523 524 TAILQ_FOREACH_SAFE(q, where, entries, qtmp) { 525 TAILQ_REMOVE(where, q, entries); 526 pfi_kif_unref(q->kif, PFI_KIF_REF_RULE); 527 pool_put(&pf_queue_pl, q); 528 } 529 } 530 531 void 532 pf_remove_queues(void) 533 { 534 struct pf_queuespec *q; 535 struct ifnet *ifp; 536 537 /* put back interfaces in normal queueing mode */ 538 TAILQ_FOREACH(q, pf_queues_active, entries) { 539 if (q->parent_qid != 0) 540 continue; 541 542 ifp = q->kif->pfik_ifp; 543 if (ifp == NULL) 544 continue; 545 546 KASSERT(HFSC_ENABLED(&ifp->if_snd)); 547 548 ifq_attach(&ifp->if_snd, ifq_priq_ops, NULL); 549 } 550 } 551 552 struct pf_hfsc_queue { 553 struct ifnet *ifp; 554 struct hfsc_if *hif; 555 struct pf_hfsc_queue *next; 556 }; 557 558 static inline struct pf_hfsc_queue * 559 pf_hfsc_ifp2q(struct pf_hfsc_queue *list, struct ifnet *ifp) 560 { 561 struct pf_hfsc_queue *phq = list; 562 563 while (phq != NULL) { 564 if (phq->ifp == ifp) 565 return (phq); 566 567 phq = phq->next; 568 } 569 570 return (phq); 571 } 572 573 int 574 pf_create_queues(void) 575 { 576 struct pf_queuespec *q; 577 struct ifnet *ifp; 578 struct pf_hfsc_queue *list = NULL, *phq; 579 int error; 580 581 /* find root queues and alloc hfsc for these interfaces */ 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 phq = malloc(sizeof(*phq), M_TEMP, M_WAITOK); 591 phq->ifp = ifp; 592 phq->hif = hfsc_pf_alloc(ifp); 593 594 phq->next = list; 595 list = phq; 596 } 597 598 /* and now everything */ 599 TAILQ_FOREACH(q, pf_queues_active, entries) { 600 ifp = q->kif->pfik_ifp; 601 if (ifp == NULL) 602 continue; 603 604 phq = pf_hfsc_ifp2q(list, ifp); 605 KASSERT(phq != NULL); 606 607 error = hfsc_pf_addqueue(phq->hif, q); 608 if (error != 0) 609 goto error; 610 } 611 612 /* find root queues in old list to disable them if necessary */ 613 TAILQ_FOREACH(q, pf_queues_inactive, entries) { 614 if (q->parent_qid != 0) 615 continue; 616 617 ifp = q->kif->pfik_ifp; 618 if (ifp == NULL) 619 continue; 620 621 phq = pf_hfsc_ifp2q(list, ifp); 622 if (phq != NULL) 623 continue; 624 625 ifq_attach(&ifp->if_snd, ifq_priq_ops, NULL); 626 } 627 628 /* commit the new queues */ 629 while (list != NULL) { 630 phq = list; 631 list = phq->next; 632 633 ifp = phq->ifp; 634 635 ifq_attach(&ifp->if_snd, ifq_hfsc_ops, phq->hif); 636 free(phq, M_TEMP, sizeof(*phq)); 637 } 638 639 return (0); 640 641 error: 642 while (list != NULL) { 643 phq = list; 644 list = phq->next; 645 646 hfsc_pf_free(phq->hif); 647 free(phq, M_TEMP, sizeof(*phq)); 648 } 649 650 return (error); 651 } 652 653 int 654 pf_commit_queues(void) 655 { 656 struct pf_queuehead *qswap; 657 int error; 658 659 /* swap */ 660 qswap = pf_queues_active; 661 pf_queues_active = pf_queues_inactive; 662 pf_queues_inactive = qswap; 663 664 error = pf_create_queues(); 665 if (error != 0) { 666 pf_queues_inactive = pf_queues_active; 667 pf_queues_active = qswap; 668 return (error); 669 } 670 671 pf_free_queues(pf_queues_inactive); 672 673 return (0); 674 } 675 676 #define PF_MD5_UPD(st, elm) \ 677 MD5Update(ctx, (u_int8_t *) &(st)->elm, sizeof((st)->elm)) 678 679 #define PF_MD5_UPD_STR(st, elm) \ 680 MD5Update(ctx, (u_int8_t *) (st)->elm, strlen((st)->elm)) 681 682 #define PF_MD5_UPD_HTONL(st, elm, stor) do { \ 683 (stor) = htonl((st)->elm); \ 684 MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int32_t));\ 685 } while (0) 686 687 #define PF_MD5_UPD_HTONS(st, elm, stor) do { \ 688 (stor) = htons((st)->elm); \ 689 MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int16_t));\ 690 } while (0) 691 692 void 693 pf_hash_rule_addr(MD5_CTX *ctx, struct pf_rule_addr *pfr) 694 { 695 PF_MD5_UPD(pfr, addr.type); 696 switch (pfr->addr.type) { 697 case PF_ADDR_DYNIFTL: 698 PF_MD5_UPD(pfr, addr.v.ifname); 699 PF_MD5_UPD(pfr, addr.iflags); 700 break; 701 case PF_ADDR_TABLE: 702 PF_MD5_UPD(pfr, addr.v.tblname); 703 break; 704 case PF_ADDR_ADDRMASK: 705 /* XXX ignore af? */ 706 PF_MD5_UPD(pfr, addr.v.a.addr.addr32); 707 PF_MD5_UPD(pfr, addr.v.a.mask.addr32); 708 break; 709 case PF_ADDR_RTLABEL: 710 PF_MD5_UPD(pfr, addr.v.rtlabelname); 711 break; 712 } 713 714 PF_MD5_UPD(pfr, port[0]); 715 PF_MD5_UPD(pfr, port[1]); 716 PF_MD5_UPD(pfr, neg); 717 PF_MD5_UPD(pfr, port_op); 718 } 719 720 void 721 pf_hash_rule(MD5_CTX *ctx, struct pf_rule *rule) 722 { 723 u_int16_t x; 724 u_int32_t y; 725 726 pf_hash_rule_addr(ctx, &rule->src); 727 pf_hash_rule_addr(ctx, &rule->dst); 728 PF_MD5_UPD_STR(rule, label); 729 PF_MD5_UPD_STR(rule, ifname); 730 PF_MD5_UPD_STR(rule, rcv_ifname); 731 PF_MD5_UPD_STR(rule, match_tagname); 732 PF_MD5_UPD_HTONS(rule, match_tag, x); /* dup? */ 733 PF_MD5_UPD_HTONL(rule, os_fingerprint, y); 734 PF_MD5_UPD_HTONL(rule, prob, y); 735 PF_MD5_UPD_HTONL(rule, uid.uid[0], y); 736 PF_MD5_UPD_HTONL(rule, uid.uid[1], y); 737 PF_MD5_UPD(rule, uid.op); 738 PF_MD5_UPD_HTONL(rule, gid.gid[0], y); 739 PF_MD5_UPD_HTONL(rule, gid.gid[1], y); 740 PF_MD5_UPD(rule, gid.op); 741 PF_MD5_UPD_HTONL(rule, rule_flag, y); 742 PF_MD5_UPD(rule, action); 743 PF_MD5_UPD(rule, direction); 744 PF_MD5_UPD(rule, af); 745 PF_MD5_UPD(rule, quick); 746 PF_MD5_UPD(rule, ifnot); 747 PF_MD5_UPD(rule, rcvifnot); 748 PF_MD5_UPD(rule, match_tag_not); 749 PF_MD5_UPD(rule, keep_state); 750 PF_MD5_UPD(rule, proto); 751 PF_MD5_UPD(rule, type); 752 PF_MD5_UPD(rule, code); 753 PF_MD5_UPD(rule, flags); 754 PF_MD5_UPD(rule, flagset); 755 PF_MD5_UPD(rule, allow_opts); 756 PF_MD5_UPD(rule, rt); 757 PF_MD5_UPD(rule, tos); 758 } 759 760 int 761 pf_commit_rules(u_int32_t ticket, char *anchor) 762 { 763 struct pf_ruleset *rs; 764 struct pf_rule *rule, **old_array; 765 struct pf_rulequeue *old_rules; 766 int s, error; 767 u_int32_t old_rcount; 768 769 /* Make sure any expired rules get removed from active rules first. */ 770 pf_purge_expired_rules(1); 771 772 rs = pf_find_ruleset(anchor); 773 if (rs == NULL || !rs->rules.inactive.open || 774 ticket != rs->rules.inactive.ticket) 775 return (EBUSY); 776 777 /* Calculate checksum for the main ruleset */ 778 if (rs == &pf_main_ruleset) { 779 error = pf_setup_pfsync_matching(rs); 780 if (error != 0) 781 return (error); 782 } 783 784 /* Swap rules, keep the old. */ 785 s = splsoftnet(); 786 old_rules = rs->rules.active.ptr; 787 old_rcount = rs->rules.active.rcount; 788 old_array = rs->rules.active.ptr_array; 789 790 rs->rules.active.ptr = rs->rules.inactive.ptr; 791 rs->rules.active.ptr_array = rs->rules.inactive.ptr_array; 792 rs->rules.active.rcount = rs->rules.inactive.rcount; 793 rs->rules.inactive.ptr = old_rules; 794 rs->rules.inactive.ptr_array = old_array; 795 rs->rules.inactive.rcount = old_rcount; 796 797 rs->rules.active.ticket = rs->rules.inactive.ticket; 798 pf_calc_skip_steps(rs->rules.active.ptr); 799 800 801 /* Purge the old rule list. */ 802 while ((rule = TAILQ_FIRST(old_rules)) != NULL) 803 pf_rm_rule(old_rules, rule); 804 if (rs->rules.inactive.ptr_array) 805 free(rs->rules.inactive.ptr_array, M_TEMP, 0); 806 rs->rules.inactive.ptr_array = NULL; 807 rs->rules.inactive.rcount = 0; 808 rs->rules.inactive.open = 0; 809 pf_remove_if_empty_ruleset(rs); 810 splx(s); 811 812 /* queue defs only in the main ruleset */ 813 if (anchor[0]) 814 return (0); 815 return (pf_commit_queues()); 816 } 817 818 int 819 pf_setup_pfsync_matching(struct pf_ruleset *rs) 820 { 821 MD5_CTX ctx; 822 struct pf_rule *rule; 823 u_int8_t digest[PF_MD5_DIGEST_LENGTH]; 824 825 MD5Init(&ctx); 826 if (rs->rules.inactive.ptr_array) 827 free(rs->rules.inactive.ptr_array, M_TEMP, 0); 828 rs->rules.inactive.ptr_array = NULL; 829 830 if (rs->rules.inactive.rcount) { 831 rs->rules.inactive.ptr_array = 832 mallocarray(rs->rules.inactive.rcount, sizeof(caddr_t), 833 M_TEMP, M_NOWAIT); 834 835 if (!rs->rules.inactive.ptr_array) 836 return (ENOMEM); 837 838 TAILQ_FOREACH(rule, rs->rules.inactive.ptr, entries) { 839 pf_hash_rule(&ctx, rule); 840 (rs->rules.inactive.ptr_array)[rule->nr] = rule; 841 } 842 } 843 844 MD5Final(digest, &ctx); 845 memcpy(pf_status.pf_chksum, digest, sizeof(pf_status.pf_chksum)); 846 return (0); 847 } 848 849 int 850 pf_addr_setup(struct pf_ruleset *ruleset, struct pf_addr_wrap *addr, 851 sa_family_t af) 852 { 853 if (pfi_dynaddr_setup(addr, af) || 854 pf_tbladdr_setup(ruleset, addr) || 855 pf_rtlabel_add(addr)) 856 return (EINVAL); 857 858 return (0); 859 } 860 861 int 862 pf_kif_setup(char *ifname, struct pfi_kif **kif) 863 { 864 if (ifname[0]) { 865 *kif = pfi_kif_get(ifname); 866 if (*kif == NULL) 867 return (EINVAL); 868 869 pfi_kif_ref(*kif, PFI_KIF_REF_RULE); 870 } else 871 *kif = NULL; 872 873 return (0); 874 } 875 876 void 877 pf_addr_copyout(struct pf_addr_wrap *addr) 878 { 879 pfi_dynaddr_copyout(addr); 880 pf_tbladdr_copyout(addr); 881 pf_rtlabel_copyout(addr); 882 } 883 884 int 885 pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) 886 { 887 int s; 888 int error = 0; 889 890 /* XXX keep in sync with switch() below */ 891 if (securelevel > 1) 892 switch (cmd) { 893 case DIOCGETRULES: 894 case DIOCGETRULE: 895 case DIOCGETSTATE: 896 case DIOCSETSTATUSIF: 897 case DIOCGETSTATUS: 898 case DIOCCLRSTATUS: 899 case DIOCNATLOOK: 900 case DIOCSETDEBUG: 901 case DIOCGETSTATES: 902 case DIOCGETTIMEOUT: 903 case DIOCCLRRULECTRS: 904 case DIOCGETLIMIT: 905 case DIOCGETRULESETS: 906 case DIOCGETRULESET: 907 case DIOCGETQUEUES: 908 case DIOCGETQUEUE: 909 case DIOCGETQSTATS: 910 case DIOCRGETTABLES: 911 case DIOCRGETTSTATS: 912 case DIOCRCLRTSTATS: 913 case DIOCRCLRADDRS: 914 case DIOCRADDADDRS: 915 case DIOCRDELADDRS: 916 case DIOCRSETADDRS: 917 case DIOCRGETASTATS: 918 case DIOCRCLRASTATS: 919 case DIOCRTSTADDRS: 920 case DIOCOSFPGET: 921 case DIOCGETSRCNODES: 922 case DIOCCLRSRCNODES: 923 case DIOCIGETIFACES: 924 case DIOCSETIFFLAG: 925 case DIOCCLRIFFLAG: 926 break; 927 case DIOCRCLRTABLES: 928 case DIOCRADDTABLES: 929 case DIOCRDELTABLES: 930 case DIOCRSETTFLAGS: 931 if (((struct pfioc_table *)addr)->pfrio_flags & 932 PFR_FLAG_DUMMY) 933 break; /* dummy operation ok */ 934 return (EPERM); 935 default: 936 return (EPERM); 937 } 938 939 if (!(flags & FWRITE)) 940 switch (cmd) { 941 case DIOCGETRULES: 942 case DIOCGETSTATE: 943 case DIOCGETSTATUS: 944 case DIOCGETSTATES: 945 case DIOCGETTIMEOUT: 946 case DIOCGETLIMIT: 947 case DIOCGETRULESETS: 948 case DIOCGETRULESET: 949 case DIOCGETQUEUES: 950 case DIOCGETQUEUE: 951 case DIOCGETQSTATS: 952 case DIOCNATLOOK: 953 case DIOCRGETTABLES: 954 case DIOCRGETTSTATS: 955 case DIOCRGETADDRS: 956 case DIOCRGETASTATS: 957 case DIOCRTSTADDRS: 958 case DIOCOSFPGET: 959 case DIOCGETSRCNODES: 960 case DIOCIGETIFACES: 961 break; 962 case DIOCRCLRTABLES: 963 case DIOCRADDTABLES: 964 case DIOCRDELTABLES: 965 case DIOCRCLRTSTATS: 966 case DIOCRCLRADDRS: 967 case DIOCRADDADDRS: 968 case DIOCRDELADDRS: 969 case DIOCRSETADDRS: 970 case DIOCRSETTFLAGS: 971 if (((struct pfioc_table *)addr)->pfrio_flags & 972 PFR_FLAG_DUMMY) { 973 flags |= FWRITE; /* need write lock for dummy */ 974 break; /* dummy operation ok */ 975 } 976 return (EACCES); 977 case DIOCGETRULE: 978 if (((struct pfioc_rule *)addr)->action == 979 PF_GET_CLR_CNTR) 980 return (EACCES); 981 break; 982 default: 983 return (EACCES); 984 } 985 986 if (flags & FWRITE) 987 rw_enter_write(&pf_consistency_lock); 988 else 989 rw_enter_read(&pf_consistency_lock); 990 991 s = splsoftnet(); 992 switch (cmd) { 993 994 case DIOCSTART: 995 if (pf_status.running) 996 error = EEXIST; 997 else { 998 pf_status.running = 1; 999 pf_status.since = time_second; 1000 if (pf_status.stateid == 0) { 1001 pf_status.stateid = time_second; 1002 pf_status.stateid = pf_status.stateid << 32; 1003 } 1004 pf_create_queues(); 1005 DPFPRINTF(LOG_NOTICE, "pf: started"); 1006 } 1007 break; 1008 1009 case DIOCSTOP: 1010 if (!pf_status.running) 1011 error = ENOENT; 1012 else { 1013 pf_status.running = 0; 1014 pf_status.since = time_second; 1015 pf_remove_queues(); 1016 DPFPRINTF(LOG_NOTICE, "pf: stopped"); 1017 } 1018 break; 1019 1020 case DIOCGETQUEUES: { 1021 struct pfioc_queue *pq = (struct pfioc_queue *)addr; 1022 struct pf_queuespec *qs; 1023 u_int32_t nr = 0; 1024 1025 pq->ticket = pf_main_ruleset.rules.active.ticket; 1026 1027 /* save state to not run over them all each time? */ 1028 qs = TAILQ_FIRST(pf_queues_active); 1029 while (qs != NULL) { 1030 qs = TAILQ_NEXT(qs, entries); 1031 nr++; 1032 } 1033 pq->nr = nr; 1034 break; 1035 } 1036 1037 case DIOCGETQUEUE: { 1038 struct pfioc_queue *pq = (struct pfioc_queue *)addr; 1039 struct pf_queuespec *qs; 1040 u_int32_t nr = 0; 1041 1042 if (pq->ticket != pf_main_ruleset.rules.active.ticket) { 1043 error = EBUSY; 1044 break; 1045 } 1046 1047 /* save state to not run over them all each time? */ 1048 qs = TAILQ_FIRST(pf_queues_active); 1049 while ((qs != NULL) && (nr++ < pq->nr)) 1050 qs = TAILQ_NEXT(qs, entries); 1051 if (qs == NULL) { 1052 error = EBUSY; 1053 break; 1054 } 1055 bcopy(qs, &pq->queue, sizeof(pq->queue)); 1056 break; 1057 } 1058 1059 case DIOCGETQSTATS: { 1060 struct pfioc_qstats *pq = (struct pfioc_qstats *)addr; 1061 struct pf_queuespec *qs; 1062 u_int32_t nr; 1063 int nbytes; 1064 1065 if (pq->ticket != pf_main_ruleset.rules.active.ticket) { 1066 error = EBUSY; 1067 break; 1068 } 1069 nbytes = pq->nbytes; 1070 nr = 0; 1071 1072 /* save state to not run over them all each time? */ 1073 qs = TAILQ_FIRST(pf_queues_active); 1074 while ((qs != NULL) && (nr++ < pq->nr)) 1075 qs = TAILQ_NEXT(qs, entries); 1076 if (qs == NULL) { 1077 error = EBUSY; 1078 break; 1079 } 1080 bcopy(qs, &pq->queue, sizeof(pq->queue)); 1081 error = hfsc_pf_qstats(qs, pq->buf, &nbytes); 1082 if (error == 0) 1083 pq->nbytes = nbytes; 1084 break; 1085 } 1086 1087 case DIOCADDQUEUE: { 1088 struct pfioc_queue *q = (struct pfioc_queue *)addr; 1089 struct pf_queuespec *qs; 1090 1091 if (q->ticket != pf_main_ruleset.rules.inactive.ticket) { 1092 error = EBUSY; 1093 break; 1094 } 1095 qs = pool_get(&pf_queue_pl, PR_WAITOK|PR_LIMITFAIL|PR_ZERO); 1096 if (qs == NULL) { 1097 error = ENOMEM; 1098 break; 1099 } 1100 bcopy(&q->queue, qs, sizeof(*qs)); 1101 qs->qid = pf_qname2qid(qs->qname, 1); 1102 if (qs->parent[0] && (qs->parent_qid = 1103 pf_qname2qid(qs->parent, 0)) == 0) { 1104 pool_put(&pf_queue_pl, qs); 1105 error = ESRCH; 1106 break; 1107 } 1108 qs->kif = pfi_kif_get(qs->ifname); 1109 if (qs->kif == NULL) { 1110 pool_put(&pf_queue_pl, qs); 1111 error = ESRCH; 1112 break; 1113 } 1114 /* XXX resolve bw percentage specs */ 1115 pfi_kif_ref(qs->kif, PFI_KIF_REF_RULE); 1116 if (qs->qlimit == 0) 1117 qs->qlimit = HFSC_DEFAULT_QLIMIT; 1118 TAILQ_INSERT_TAIL(pf_queues_inactive, qs, entries); 1119 1120 break; 1121 } 1122 1123 case DIOCADDRULE: { 1124 struct pfioc_rule *pr = (struct pfioc_rule *)addr; 1125 struct pf_ruleset *ruleset; 1126 struct pf_rule *rule, *tail; 1127 1128 pr->anchor[sizeof(pr->anchor) - 1] = 0; 1129 ruleset = pf_find_ruleset(pr->anchor); 1130 if (ruleset == NULL) { 1131 error = EINVAL; 1132 break; 1133 } 1134 if (pr->rule.return_icmp >> 8 > ICMP_MAXTYPE) { 1135 error = EINVAL; 1136 break; 1137 } 1138 if (pr->ticket != ruleset->rules.inactive.ticket) { 1139 error = EBUSY; 1140 break; 1141 } 1142 rule = pool_get(&pf_rule_pl, PR_WAITOK|PR_LIMITFAIL|PR_ZERO); 1143 if (rule == NULL) { 1144 error = ENOMEM; 1145 break; 1146 } 1147 if ((error = pf_rule_copyin(&pr->rule, rule, ruleset))) { 1148 pf_rm_rule(NULL, rule); 1149 rule = NULL; 1150 break; 1151 } 1152 rule->cuid = p->p_ucred->cr_ruid; 1153 rule->cpid = p->p_p->ps_pid; 1154 1155 switch (rule->af) { 1156 case 0: 1157 break; 1158 case AF_INET: 1159 break; 1160 #ifdef INET6 1161 case AF_INET6: 1162 break; 1163 #endif /* INET6 */ 1164 default: 1165 pf_rm_rule(NULL, rule); 1166 rule = NULL; 1167 error = EAFNOSUPPORT; 1168 goto fail; 1169 } 1170 tail = TAILQ_LAST(ruleset->rules.inactive.ptr, 1171 pf_rulequeue); 1172 if (tail) 1173 rule->nr = tail->nr + 1; 1174 else 1175 rule->nr = 0; 1176 1177 if (rule->src.addr.type == PF_ADDR_NONE || 1178 rule->dst.addr.type == PF_ADDR_NONE) 1179 error = EINVAL; 1180 1181 if (pf_addr_setup(ruleset, &rule->src.addr, rule->af)) 1182 error = EINVAL; 1183 if (pf_addr_setup(ruleset, &rule->dst.addr, rule->af)) 1184 error = EINVAL; 1185 if (pf_addr_setup(ruleset, &rule->rdr.addr, rule->af)) 1186 error = EINVAL; 1187 if (pf_addr_setup(ruleset, &rule->nat.addr, rule->af)) 1188 error = EINVAL; 1189 if (pf_addr_setup(ruleset, &rule->route.addr, rule->af)) 1190 error = EINVAL; 1191 if (pf_anchor_setup(rule, ruleset, pr->anchor_call)) 1192 error = EINVAL; 1193 if (rule->rt && !rule->direction) 1194 error = EINVAL; 1195 if (rule->scrub_flags & PFSTATE_SETPRIO && 1196 (rule->set_prio[0] > IFQ_MAXPRIO || 1197 rule->set_prio[1] > IFQ_MAXPRIO)) 1198 error = EINVAL; 1199 1200 if (error) { 1201 pf_rm_rule(NULL, rule); 1202 break; 1203 } 1204 TAILQ_INSERT_TAIL(ruleset->rules.inactive.ptr, 1205 rule, entries); 1206 rule->ruleset = ruleset; 1207 ruleset->rules.inactive.rcount++; 1208 break; 1209 } 1210 1211 case DIOCGETRULES: { 1212 struct pfioc_rule *pr = (struct pfioc_rule *)addr; 1213 struct pf_ruleset *ruleset; 1214 struct pf_rule *tail; 1215 1216 pr->anchor[sizeof(pr->anchor) - 1] = 0; 1217 ruleset = pf_find_ruleset(pr->anchor); 1218 if (ruleset == NULL) { 1219 error = EINVAL; 1220 break; 1221 } 1222 tail = TAILQ_LAST(ruleset->rules.active.ptr, pf_rulequeue); 1223 if (tail) 1224 pr->nr = tail->nr + 1; 1225 else 1226 pr->nr = 0; 1227 pr->ticket = ruleset->rules.active.ticket; 1228 break; 1229 } 1230 1231 case DIOCGETRULE: { 1232 struct pfioc_rule *pr = (struct pfioc_rule *)addr; 1233 struct pf_ruleset *ruleset; 1234 struct pf_rule *rule; 1235 int i; 1236 1237 pr->anchor[sizeof(pr->anchor) - 1] = 0; 1238 ruleset = pf_find_ruleset(pr->anchor); 1239 if (ruleset == NULL) { 1240 error = EINVAL; 1241 break; 1242 } 1243 if (pr->ticket != ruleset->rules.active.ticket) { 1244 error = EBUSY; 1245 break; 1246 } 1247 rule = TAILQ_FIRST(ruleset->rules.active.ptr); 1248 while ((rule != NULL) && (rule->nr != pr->nr)) 1249 rule = TAILQ_NEXT(rule, entries); 1250 if (rule == NULL) { 1251 error = EBUSY; 1252 break; 1253 } 1254 bcopy(rule, &pr->rule, sizeof(struct pf_rule)); 1255 bzero(&pr->rule.entries, sizeof(pr->rule.entries)); 1256 pr->rule.kif = NULL; 1257 pr->rule.nat.kif = NULL; 1258 pr->rule.rdr.kif = NULL; 1259 pr->rule.route.kif = NULL; 1260 pr->rule.rcv_kif = NULL; 1261 pr->rule.anchor = NULL; 1262 pr->rule.overload_tbl = NULL; 1263 bzero(&pr->rule.gcle, sizeof(pr->rule.gcle)); 1264 pr->rule.ruleset = NULL; 1265 if (pf_anchor_copyout(ruleset, rule, pr)) { 1266 error = EBUSY; 1267 break; 1268 } 1269 pf_addr_copyout(&pr->rule.src.addr); 1270 pf_addr_copyout(&pr->rule.dst.addr); 1271 pf_addr_copyout(&pr->rule.rdr.addr); 1272 pf_addr_copyout(&pr->rule.nat.addr); 1273 pf_addr_copyout(&pr->rule.route.addr); 1274 for (i = 0; i < PF_SKIP_COUNT; ++i) 1275 if (rule->skip[i].ptr == NULL) 1276 pr->rule.skip[i].nr = (u_int32_t)-1; 1277 else 1278 pr->rule.skip[i].nr = 1279 rule->skip[i].ptr->nr; 1280 1281 if (pr->action == PF_GET_CLR_CNTR) { 1282 rule->evaluations = 0; 1283 rule->packets[0] = rule->packets[1] = 0; 1284 rule->bytes[0] = rule->bytes[1] = 0; 1285 rule->states_tot = 0; 1286 } 1287 break; 1288 } 1289 1290 case DIOCCHANGERULE: { 1291 struct pfioc_rule *pcr = (struct pfioc_rule *)addr; 1292 struct pf_ruleset *ruleset; 1293 struct pf_rule *oldrule = NULL, *newrule = NULL; 1294 u_int32_t nr = 0; 1295 1296 if (pcr->action < PF_CHANGE_ADD_HEAD || 1297 pcr->action > PF_CHANGE_GET_TICKET) { 1298 error = EINVAL; 1299 break; 1300 } 1301 ruleset = pf_find_ruleset(pcr->anchor); 1302 if (ruleset == NULL) { 1303 error = EINVAL; 1304 break; 1305 } 1306 1307 if (pcr->action == PF_CHANGE_GET_TICKET) { 1308 pcr->ticket = ++ruleset->rules.active.ticket; 1309 break; 1310 } else { 1311 if (pcr->ticket != 1312 ruleset->rules.active.ticket) { 1313 error = EINVAL; 1314 break; 1315 } 1316 if (pcr->rule.return_icmp >> 8 > ICMP_MAXTYPE) { 1317 error = EINVAL; 1318 break; 1319 } 1320 } 1321 1322 if (pcr->action != PF_CHANGE_REMOVE) { 1323 newrule = pool_get(&pf_rule_pl, 1324 PR_WAITOK|PR_LIMITFAIL|PR_ZERO); 1325 if (newrule == NULL) { 1326 error = ENOMEM; 1327 break; 1328 } 1329 pf_rule_copyin(&pcr->rule, newrule, ruleset); 1330 newrule->cuid = p->p_ucred->cr_ruid; 1331 newrule->cpid = p->p_p->ps_pid; 1332 1333 switch (newrule->af) { 1334 case 0: 1335 break; 1336 case AF_INET: 1337 break; 1338 #ifdef INET6 1339 case AF_INET6: 1340 break; 1341 #endif /* INET6 */ 1342 default: 1343 pool_put(&pf_rule_pl, newrule); 1344 error = EAFNOSUPPORT; 1345 goto fail; 1346 } 1347 1348 if (newrule->rt && !newrule->direction) 1349 error = EINVAL; 1350 if (pf_addr_setup(ruleset, &newrule->src.addr, newrule->af)) 1351 error = EINVAL; 1352 if (pf_addr_setup(ruleset, &newrule->dst.addr, newrule->af)) 1353 error = EINVAL; 1354 if (pf_addr_setup(ruleset, &newrule->rdr.addr, newrule->af)) 1355 error = EINVAL; 1356 if (pf_addr_setup(ruleset, &newrule->nat.addr, newrule->af)) 1357 error = EINVAL; 1358 if (pf_addr_setup(ruleset, &newrule->route.addr, newrule->af)) 1359 error = EINVAL; 1360 if (pf_anchor_setup(newrule, ruleset, pcr->anchor_call)) 1361 error = EINVAL; 1362 1363 if (error) { 1364 pf_rm_rule(NULL, newrule); 1365 break; 1366 } 1367 } 1368 1369 if (pcr->action == PF_CHANGE_ADD_HEAD) 1370 oldrule = TAILQ_FIRST(ruleset->rules.active.ptr); 1371 else if (pcr->action == PF_CHANGE_ADD_TAIL) 1372 oldrule = TAILQ_LAST(ruleset->rules.active.ptr, 1373 pf_rulequeue); 1374 else { 1375 oldrule = TAILQ_FIRST(ruleset->rules.active.ptr); 1376 while ((oldrule != NULL) && (oldrule->nr != pcr->nr)) 1377 oldrule = TAILQ_NEXT(oldrule, entries); 1378 if (oldrule == NULL) { 1379 if (newrule != NULL) 1380 pf_rm_rule(NULL, newrule); 1381 error = EINVAL; 1382 break; 1383 } 1384 } 1385 1386 if (pcr->action == PF_CHANGE_REMOVE) { 1387 pf_rm_rule(ruleset->rules.active.ptr, oldrule); 1388 ruleset->rules.active.rcount--; 1389 } else { 1390 if (oldrule == NULL) 1391 TAILQ_INSERT_TAIL( 1392 ruleset->rules.active.ptr, 1393 newrule, entries); 1394 else if (pcr->action == PF_CHANGE_ADD_HEAD || 1395 pcr->action == PF_CHANGE_ADD_BEFORE) 1396 TAILQ_INSERT_BEFORE(oldrule, newrule, entries); 1397 else 1398 TAILQ_INSERT_AFTER( 1399 ruleset->rules.active.ptr, 1400 oldrule, newrule, entries); 1401 ruleset->rules.active.rcount++; 1402 } 1403 1404 nr = 0; 1405 TAILQ_FOREACH(oldrule, ruleset->rules.active.ptr, entries) 1406 oldrule->nr = nr++; 1407 1408 ruleset->rules.active.ticket++; 1409 1410 pf_calc_skip_steps(ruleset->rules.active.ptr); 1411 pf_remove_if_empty_ruleset(ruleset); 1412 1413 break; 1414 } 1415 1416 case DIOCCLRSTATES: { 1417 struct pf_state *s, *nexts; 1418 struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr; 1419 u_int killed = 0; 1420 1421 for (s = RB_MIN(pf_state_tree_id, &tree_id); s; s = nexts) { 1422 nexts = RB_NEXT(pf_state_tree_id, &tree_id, s); 1423 1424 if (!psk->psk_ifname[0] || !strcmp(psk->psk_ifname, 1425 s->kif->pfik_name)) { 1426 #if NPFSYNC > 0 1427 /* don't send out individual delete messages */ 1428 SET(s->state_flags, PFSTATE_NOSYNC); 1429 #endif /* NPFSYNC > 0 */ 1430 pf_remove_state(s); 1431 killed++; 1432 } 1433 } 1434 psk->psk_killed = killed; 1435 #if NPFSYNC > 0 1436 pfsync_clear_states(pf_status.hostid, psk->psk_ifname); 1437 #endif /* NPFSYNC > 0 */ 1438 break; 1439 } 1440 1441 case DIOCKILLSTATES: { 1442 struct pf_state *s, *nexts; 1443 struct pf_state_key *sk; 1444 struct pf_addr *srcaddr, *dstaddr; 1445 u_int16_t srcport, dstport; 1446 struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr; 1447 u_int killed = 0; 1448 1449 if (psk->psk_pfcmp.id) { 1450 if (psk->psk_pfcmp.creatorid == 0) 1451 psk->psk_pfcmp.creatorid = pf_status.hostid; 1452 if ((s = pf_find_state_byid(&psk->psk_pfcmp))) { 1453 pf_remove_state(s); 1454 psk->psk_killed = 1; 1455 } 1456 break; 1457 } 1458 1459 for (s = RB_MIN(pf_state_tree_id, &tree_id); s; 1460 s = nexts) { 1461 nexts = RB_NEXT(pf_state_tree_id, &tree_id, s); 1462 1463 if (s->direction == PF_OUT) { 1464 sk = s->key[PF_SK_STACK]; 1465 srcaddr = &sk->addr[1]; 1466 dstaddr = &sk->addr[0]; 1467 srcport = sk->port[1]; 1468 dstport = sk->port[0]; 1469 } else { 1470 sk = s->key[PF_SK_WIRE]; 1471 srcaddr = &sk->addr[0]; 1472 dstaddr = &sk->addr[1]; 1473 srcport = sk->port[0]; 1474 dstport = sk->port[1]; 1475 } 1476 if ((!psk->psk_af || sk->af == psk->psk_af) 1477 && (!psk->psk_proto || psk->psk_proto == 1478 sk->proto) && psk->psk_rdomain == sk->rdomain && 1479 PF_MATCHA(psk->psk_src.neg, 1480 &psk->psk_src.addr.v.a.addr, 1481 &psk->psk_src.addr.v.a.mask, 1482 srcaddr, sk->af) && 1483 PF_MATCHA(psk->psk_dst.neg, 1484 &psk->psk_dst.addr.v.a.addr, 1485 &psk->psk_dst.addr.v.a.mask, 1486 dstaddr, sk->af) && 1487 (psk->psk_src.port_op == 0 || 1488 pf_match_port(psk->psk_src.port_op, 1489 psk->psk_src.port[0], psk->psk_src.port[1], 1490 srcport)) && 1491 (psk->psk_dst.port_op == 0 || 1492 pf_match_port(psk->psk_dst.port_op, 1493 psk->psk_dst.port[0], psk->psk_dst.port[1], 1494 dstport)) && 1495 (!psk->psk_label[0] || (s->rule.ptr->label[0] && 1496 !strcmp(psk->psk_label, s->rule.ptr->label))) && 1497 (!psk->psk_ifname[0] || !strcmp(psk->psk_ifname, 1498 s->kif->pfik_name))) { 1499 pf_remove_state(s); 1500 killed++; 1501 } 1502 } 1503 psk->psk_killed = killed; 1504 break; 1505 } 1506 1507 #if NPFSYNC > 0 1508 case DIOCADDSTATE: { 1509 struct pfioc_state *ps = (struct pfioc_state *)addr; 1510 struct pfsync_state *sp = &ps->state; 1511 1512 if (sp->timeout >= PFTM_MAX) { 1513 error = EINVAL; 1514 break; 1515 } 1516 error = pfsync_state_import(sp, PFSYNC_SI_IOCTL); 1517 break; 1518 } 1519 #endif /* NPFSYNC > 0 */ 1520 1521 case DIOCGETSTATE: { 1522 struct pfioc_state *ps = (struct pfioc_state *)addr; 1523 struct pf_state *s; 1524 struct pf_state_cmp id_key; 1525 1526 bzero(&id_key, sizeof(id_key)); 1527 id_key.id = ps->state.id; 1528 id_key.creatorid = ps->state.creatorid; 1529 1530 s = pf_find_state_byid(&id_key); 1531 if (s == NULL) { 1532 error = ENOENT; 1533 break; 1534 } 1535 1536 pf_state_export(&ps->state, s); 1537 break; 1538 } 1539 1540 case DIOCGETSTATES: { 1541 struct pfioc_states *ps = (struct pfioc_states *)addr; 1542 struct pf_state *state; 1543 struct pfsync_state *p, *pstore; 1544 u_int32_t nr = 0; 1545 1546 if (ps->ps_len == 0) { 1547 nr = pf_status.states; 1548 ps->ps_len = sizeof(struct pfsync_state) * nr; 1549 break; 1550 } 1551 1552 pstore = malloc(sizeof(*pstore), M_TEMP, M_WAITOK); 1553 1554 p = ps->ps_states; 1555 1556 state = TAILQ_FIRST(&state_list); 1557 while (state) { 1558 if (state->timeout != PFTM_UNLINKED) { 1559 if ((nr+1) * sizeof(*p) > (unsigned)ps->ps_len) 1560 break; 1561 pf_state_export(pstore, state); 1562 error = copyout(pstore, p, sizeof(*p)); 1563 if (error) { 1564 free(pstore, M_TEMP, sizeof(*pstore)); 1565 goto fail; 1566 } 1567 p++; 1568 nr++; 1569 } 1570 state = TAILQ_NEXT(state, entry_list); 1571 } 1572 1573 ps->ps_len = sizeof(struct pfsync_state) * nr; 1574 1575 free(pstore, M_TEMP, sizeof(*pstore)); 1576 break; 1577 } 1578 1579 case DIOCGETSTATUS: { 1580 struct pf_status *s = (struct pf_status *)addr; 1581 bcopy(&pf_status, s, sizeof(struct pf_status)); 1582 pfi_update_status(s->ifname, s); 1583 break; 1584 } 1585 1586 case DIOCSETSTATUSIF: { 1587 struct pfioc_iface *pi = (struct pfioc_iface *)addr; 1588 1589 if (pi->pfiio_name[0] == 0) { 1590 bzero(pf_status.ifname, IFNAMSIZ); 1591 break; 1592 } 1593 strlcpy(pf_trans_set.statusif, pi->pfiio_name, IFNAMSIZ); 1594 pf_trans_set.mask |= PF_TSET_STATUSIF; 1595 break; 1596 } 1597 1598 case DIOCCLRSTATUS: { 1599 struct pfioc_iface *pi = (struct pfioc_iface *)addr; 1600 1601 /* if ifname is specified, clear counters there only */ 1602 if (pi->pfiio_name[0]) { 1603 pfi_update_status(pi->pfiio_name, NULL); 1604 break; 1605 } 1606 1607 bzero(pf_status.counters, sizeof(pf_status.counters)); 1608 bzero(pf_status.fcounters, sizeof(pf_status.fcounters)); 1609 bzero(pf_status.scounters, sizeof(pf_status.scounters)); 1610 pf_status.since = time_second; 1611 1612 break; 1613 } 1614 1615 case DIOCNATLOOK: { 1616 struct pfioc_natlook *pnl = (struct pfioc_natlook *)addr; 1617 struct pf_state_key *sk; 1618 struct pf_state *state; 1619 struct pf_state_key_cmp key; 1620 int m = 0, direction = pnl->direction; 1621 int sidx, didx; 1622 1623 /* NATLOOK src and dst are reversed, so reverse sidx/didx */ 1624 sidx = (direction == PF_IN) ? 1 : 0; 1625 didx = (direction == PF_IN) ? 0 : 1; 1626 1627 if (!pnl->proto || 1628 PF_AZERO(&pnl->saddr, pnl->af) || 1629 PF_AZERO(&pnl->daddr, pnl->af) || 1630 ((pnl->proto == IPPROTO_TCP || 1631 pnl->proto == IPPROTO_UDP) && 1632 (!pnl->dport || !pnl->sport)) || 1633 pnl->rdomain > RT_TABLEID_MAX) 1634 error = EINVAL; 1635 else { 1636 key.af = pnl->af; 1637 key.proto = pnl->proto; 1638 key.rdomain = pnl->rdomain; 1639 PF_ACPY(&key.addr[sidx], &pnl->saddr, pnl->af); 1640 key.port[sidx] = pnl->sport; 1641 PF_ACPY(&key.addr[didx], &pnl->daddr, pnl->af); 1642 key.port[didx] = pnl->dport; 1643 1644 state = pf_find_state_all(&key, direction, &m); 1645 1646 if (m > 1) 1647 error = E2BIG; /* more than one state */ 1648 else if (state != NULL) { 1649 sk = state->key[sidx]; 1650 PF_ACPY(&pnl->rsaddr, &sk->addr[sidx], sk->af); 1651 pnl->rsport = sk->port[sidx]; 1652 PF_ACPY(&pnl->rdaddr, &sk->addr[didx], sk->af); 1653 pnl->rdport = sk->port[didx]; 1654 pnl->rrdomain = sk->rdomain; 1655 } else 1656 error = ENOENT; 1657 } 1658 break; 1659 } 1660 1661 case DIOCSETTIMEOUT: { 1662 struct pfioc_tm *pt = (struct pfioc_tm *)addr; 1663 1664 if (pt->timeout < 0 || pt->timeout >= PFTM_MAX || 1665 pt->seconds < 0) { 1666 error = EINVAL; 1667 goto fail; 1668 } 1669 if (pt->timeout == PFTM_INTERVAL && pt->seconds == 0) 1670 pt->seconds = 1; 1671 pf_default_rule_new.timeout[pt->timeout] = pt->seconds; 1672 pt->seconds = pf_default_rule.timeout[pt->timeout]; 1673 break; 1674 } 1675 1676 case DIOCGETTIMEOUT: { 1677 struct pfioc_tm *pt = (struct pfioc_tm *)addr; 1678 1679 if (pt->timeout < 0 || pt->timeout >= PFTM_MAX) { 1680 error = EINVAL; 1681 goto fail; 1682 } 1683 pt->seconds = pf_default_rule.timeout[pt->timeout]; 1684 break; 1685 } 1686 1687 case DIOCGETLIMIT: { 1688 struct pfioc_limit *pl = (struct pfioc_limit *)addr; 1689 1690 if (pl->index < 0 || pl->index >= PF_LIMIT_MAX) { 1691 error = EINVAL; 1692 goto fail; 1693 } 1694 pl->limit = pf_pool_limits[pl->index].limit; 1695 break; 1696 } 1697 1698 case DIOCSETLIMIT: { 1699 struct pfioc_limit *pl = (struct pfioc_limit *)addr; 1700 1701 if (pl->index < 0 || pl->index >= PF_LIMIT_MAX || 1702 pf_pool_limits[pl->index].pp == NULL) { 1703 error = EINVAL; 1704 goto fail; 1705 } 1706 if (((struct pool *)pf_pool_limits[pl->index].pp)->pr_nout > 1707 pl->limit) { 1708 error = EBUSY; 1709 goto fail; 1710 } 1711 /* Fragments reference mbuf clusters. */ 1712 if (pl->index == PF_LIMIT_FRAGS && pl->limit > nmbclust) { 1713 error = EINVAL; 1714 goto fail; 1715 } 1716 1717 pf_pool_limits[pl->index].limit_new = pl->limit; 1718 pl->limit = pf_pool_limits[pl->index].limit; 1719 break; 1720 } 1721 1722 case DIOCSETDEBUG: { 1723 u_int32_t *level = (u_int32_t *)addr; 1724 1725 pf_trans_set.debug = *level; 1726 pf_trans_set.mask |= PF_TSET_DEBUG; 1727 break; 1728 } 1729 1730 case DIOCCLRRULECTRS: { 1731 /* obsoleted by DIOCGETRULE with action=PF_GET_CLR_CNTR */ 1732 struct pf_ruleset *ruleset = &pf_main_ruleset; 1733 struct pf_rule *rule; 1734 1735 TAILQ_FOREACH(rule, 1736 ruleset->rules.active.ptr, entries) { 1737 rule->evaluations = 0; 1738 rule->packets[0] = rule->packets[1] = 0; 1739 rule->bytes[0] = rule->bytes[1] = 0; 1740 } 1741 break; 1742 } 1743 1744 case DIOCGETRULESETS: { 1745 struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr; 1746 struct pf_ruleset *ruleset; 1747 struct pf_anchor *anchor; 1748 1749 pr->path[sizeof(pr->path) - 1] = 0; 1750 if ((ruleset = pf_find_ruleset(pr->path)) == NULL) { 1751 error = EINVAL; 1752 break; 1753 } 1754 pr->nr = 0; 1755 if (ruleset->anchor == NULL) { 1756 /* XXX kludge for pf_main_ruleset */ 1757 RB_FOREACH(anchor, pf_anchor_global, &pf_anchors) 1758 if (anchor->parent == NULL) 1759 pr->nr++; 1760 } else { 1761 RB_FOREACH(anchor, pf_anchor_node, 1762 &ruleset->anchor->children) 1763 pr->nr++; 1764 } 1765 break; 1766 } 1767 1768 case DIOCGETRULESET: { 1769 struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr; 1770 struct pf_ruleset *ruleset; 1771 struct pf_anchor *anchor; 1772 u_int32_t nr = 0; 1773 1774 pr->path[sizeof(pr->path) - 1] = 0; 1775 if ((ruleset = pf_find_ruleset(pr->path)) == NULL) { 1776 error = EINVAL; 1777 break; 1778 } 1779 pr->name[0] = 0; 1780 if (ruleset->anchor == NULL) { 1781 /* XXX kludge for pf_main_ruleset */ 1782 RB_FOREACH(anchor, pf_anchor_global, &pf_anchors) 1783 if (anchor->parent == NULL && nr++ == pr->nr) { 1784 strlcpy(pr->name, anchor->name, 1785 sizeof(pr->name)); 1786 break; 1787 } 1788 } else { 1789 RB_FOREACH(anchor, pf_anchor_node, 1790 &ruleset->anchor->children) 1791 if (nr++ == pr->nr) { 1792 strlcpy(pr->name, anchor->name, 1793 sizeof(pr->name)); 1794 break; 1795 } 1796 } 1797 if (!pr->name[0]) 1798 error = EBUSY; 1799 break; 1800 } 1801 1802 case DIOCRCLRTABLES: { 1803 struct pfioc_table *io = (struct pfioc_table *)addr; 1804 1805 if (io->pfrio_esize != 0) { 1806 error = ENODEV; 1807 break; 1808 } 1809 error = pfr_clr_tables(&io->pfrio_table, &io->pfrio_ndel, 1810 io->pfrio_flags | PFR_FLAG_USERIOCTL); 1811 break; 1812 } 1813 1814 case DIOCRADDTABLES: { 1815 struct pfioc_table *io = (struct pfioc_table *)addr; 1816 1817 if (io->pfrio_esize != sizeof(struct pfr_table)) { 1818 error = ENODEV; 1819 break; 1820 } 1821 error = pfr_add_tables(io->pfrio_buffer, io->pfrio_size, 1822 &io->pfrio_nadd, io->pfrio_flags | PFR_FLAG_USERIOCTL); 1823 break; 1824 } 1825 1826 case DIOCRDELTABLES: { 1827 struct pfioc_table *io = (struct pfioc_table *)addr; 1828 1829 if (io->pfrio_esize != sizeof(struct pfr_table)) { 1830 error = ENODEV; 1831 break; 1832 } 1833 error = pfr_del_tables(io->pfrio_buffer, io->pfrio_size, 1834 &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL); 1835 break; 1836 } 1837 1838 case DIOCRGETTABLES: { 1839 struct pfioc_table *io = (struct pfioc_table *)addr; 1840 1841 if (io->pfrio_esize != sizeof(struct pfr_table)) { 1842 error = ENODEV; 1843 break; 1844 } 1845 error = pfr_get_tables(&io->pfrio_table, io->pfrio_buffer, 1846 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); 1847 break; 1848 } 1849 1850 case DIOCRGETTSTATS: { 1851 struct pfioc_table *io = (struct pfioc_table *)addr; 1852 1853 if (io->pfrio_esize != sizeof(struct pfr_tstats)) { 1854 error = ENODEV; 1855 break; 1856 } 1857 error = pfr_get_tstats(&io->pfrio_table, io->pfrio_buffer, 1858 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); 1859 break; 1860 } 1861 1862 case DIOCRCLRTSTATS: { 1863 struct pfioc_table *io = (struct pfioc_table *)addr; 1864 1865 if (io->pfrio_esize != sizeof(struct pfr_table)) { 1866 error = ENODEV; 1867 break; 1868 } 1869 error = pfr_clr_tstats(io->pfrio_buffer, io->pfrio_size, 1870 &io->pfrio_nzero, io->pfrio_flags | PFR_FLAG_USERIOCTL); 1871 break; 1872 } 1873 1874 case DIOCRSETTFLAGS: { 1875 struct pfioc_table *io = (struct pfioc_table *)addr; 1876 1877 if (io->pfrio_esize != sizeof(struct pfr_table)) { 1878 error = ENODEV; 1879 break; 1880 } 1881 error = pfr_set_tflags(io->pfrio_buffer, io->pfrio_size, 1882 io->pfrio_setflag, io->pfrio_clrflag, &io->pfrio_nchange, 1883 &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL); 1884 break; 1885 } 1886 1887 case DIOCRCLRADDRS: { 1888 struct pfioc_table *io = (struct pfioc_table *)addr; 1889 1890 if (io->pfrio_esize != 0) { 1891 error = ENODEV; 1892 break; 1893 } 1894 error = pfr_clr_addrs(&io->pfrio_table, &io->pfrio_ndel, 1895 io->pfrio_flags | PFR_FLAG_USERIOCTL); 1896 break; 1897 } 1898 1899 case DIOCRADDADDRS: { 1900 struct pfioc_table *io = (struct pfioc_table *)addr; 1901 1902 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 1903 error = ENODEV; 1904 break; 1905 } 1906 error = pfr_add_addrs(&io->pfrio_table, io->pfrio_buffer, 1907 io->pfrio_size, &io->pfrio_nadd, io->pfrio_flags | 1908 PFR_FLAG_USERIOCTL); 1909 break; 1910 } 1911 1912 case DIOCRDELADDRS: { 1913 struct pfioc_table *io = (struct pfioc_table *)addr; 1914 1915 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 1916 error = ENODEV; 1917 break; 1918 } 1919 error = pfr_del_addrs(&io->pfrio_table, io->pfrio_buffer, 1920 io->pfrio_size, &io->pfrio_ndel, io->pfrio_flags | 1921 PFR_FLAG_USERIOCTL); 1922 break; 1923 } 1924 1925 case DIOCRSETADDRS: { 1926 struct pfioc_table *io = (struct pfioc_table *)addr; 1927 1928 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 1929 error = ENODEV; 1930 break; 1931 } 1932 error = pfr_set_addrs(&io->pfrio_table, io->pfrio_buffer, 1933 io->pfrio_size, &io->pfrio_size2, &io->pfrio_nadd, 1934 &io->pfrio_ndel, &io->pfrio_nchange, io->pfrio_flags | 1935 PFR_FLAG_USERIOCTL, 0); 1936 break; 1937 } 1938 1939 case DIOCRGETADDRS: { 1940 struct pfioc_table *io = (struct pfioc_table *)addr; 1941 1942 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 1943 error = ENODEV; 1944 break; 1945 } 1946 error = pfr_get_addrs(&io->pfrio_table, io->pfrio_buffer, 1947 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); 1948 break; 1949 } 1950 1951 case DIOCRGETASTATS: { 1952 struct pfioc_table *io = (struct pfioc_table *)addr; 1953 1954 if (io->pfrio_esize != sizeof(struct pfr_astats)) { 1955 error = ENODEV; 1956 break; 1957 } 1958 error = pfr_get_astats(&io->pfrio_table, io->pfrio_buffer, 1959 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); 1960 break; 1961 } 1962 1963 case DIOCRCLRASTATS: { 1964 struct pfioc_table *io = (struct pfioc_table *)addr; 1965 1966 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 1967 error = ENODEV; 1968 break; 1969 } 1970 error = pfr_clr_astats(&io->pfrio_table, io->pfrio_buffer, 1971 io->pfrio_size, &io->pfrio_nzero, io->pfrio_flags | 1972 PFR_FLAG_USERIOCTL); 1973 break; 1974 } 1975 1976 case DIOCRTSTADDRS: { 1977 struct pfioc_table *io = (struct pfioc_table *)addr; 1978 1979 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 1980 error = ENODEV; 1981 break; 1982 } 1983 error = pfr_tst_addrs(&io->pfrio_table, io->pfrio_buffer, 1984 io->pfrio_size, &io->pfrio_nmatch, io->pfrio_flags | 1985 PFR_FLAG_USERIOCTL); 1986 break; 1987 } 1988 1989 case DIOCRINADEFINE: { 1990 struct pfioc_table *io = (struct pfioc_table *)addr; 1991 1992 if (io->pfrio_esize != sizeof(struct pfr_addr)) { 1993 error = ENODEV; 1994 break; 1995 } 1996 error = pfr_ina_define(&io->pfrio_table, io->pfrio_buffer, 1997 io->pfrio_size, &io->pfrio_nadd, &io->pfrio_naddr, 1998 io->pfrio_ticket, io->pfrio_flags | PFR_FLAG_USERIOCTL); 1999 break; 2000 } 2001 2002 case DIOCOSFPADD: { 2003 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr; 2004 error = pf_osfp_add(io); 2005 break; 2006 } 2007 2008 case DIOCOSFPGET: { 2009 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr; 2010 error = pf_osfp_get(io); 2011 break; 2012 } 2013 2014 case DIOCXBEGIN: { 2015 struct pfioc_trans *io = (struct pfioc_trans *)addr; 2016 struct pfioc_trans_e *ioe; 2017 struct pfr_table *table; 2018 int i; 2019 2020 if (io->esize != sizeof(*ioe)) { 2021 error = ENODEV; 2022 goto fail; 2023 } 2024 ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK); 2025 table = malloc(sizeof(*table), M_TEMP, M_WAITOK); 2026 pf_default_rule_new = pf_default_rule; 2027 bzero(&pf_trans_set, sizeof(pf_trans_set)); 2028 for (i = 0; i < io->size; i++) { 2029 if (copyin(io->array+i, ioe, sizeof(*ioe))) { 2030 free(table, M_TEMP, sizeof(*table)); 2031 free(ioe, M_TEMP, sizeof(*ioe)); 2032 error = EFAULT; 2033 goto fail; 2034 } 2035 switch (ioe->type) { 2036 case PF_TRANS_TABLE: 2037 bzero(table, sizeof(*table)); 2038 strlcpy(table->pfrt_anchor, ioe->anchor, 2039 sizeof(table->pfrt_anchor)); 2040 if ((error = pfr_ina_begin(table, 2041 &ioe->ticket, NULL, 0))) { 2042 free(table, M_TEMP, sizeof(*table)); 2043 free(ioe, M_TEMP, sizeof(*ioe)); 2044 goto fail; 2045 } 2046 break; 2047 default: 2048 if ((error = pf_begin_rules(&ioe->ticket, 2049 ioe->anchor))) { 2050 free(table, M_TEMP, sizeof(*table)); 2051 free(ioe, M_TEMP, sizeof(*ioe)); 2052 goto fail; 2053 } 2054 break; 2055 } 2056 if (copyout(ioe, io->array+i, sizeof(io->array[i]))) { 2057 free(table, M_TEMP, sizeof(*table)); 2058 free(ioe, M_TEMP, sizeof(*ioe)); 2059 error = EFAULT; 2060 goto fail; 2061 } 2062 } 2063 free(table, M_TEMP, sizeof(*table)); 2064 free(ioe, M_TEMP, sizeof(*ioe)); 2065 break; 2066 } 2067 2068 case DIOCXROLLBACK: { 2069 struct pfioc_trans *io = (struct pfioc_trans *)addr; 2070 struct pfioc_trans_e *ioe; 2071 struct pfr_table *table; 2072 int i; 2073 2074 if (io->esize != sizeof(*ioe)) { 2075 error = ENODEV; 2076 goto fail; 2077 } 2078 ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK); 2079 table = malloc(sizeof(*table), M_TEMP, M_WAITOK); 2080 for (i = 0; i < io->size; i++) { 2081 if (copyin(io->array+i, ioe, sizeof(*ioe))) { 2082 free(table, M_TEMP, sizeof(*table)); 2083 free(ioe, M_TEMP, sizeof(*ioe)); 2084 error = EFAULT; 2085 goto fail; 2086 } 2087 switch (ioe->type) { 2088 case PF_TRANS_TABLE: 2089 bzero(table, sizeof(*table)); 2090 strlcpy(table->pfrt_anchor, ioe->anchor, 2091 sizeof(table->pfrt_anchor)); 2092 if ((error = pfr_ina_rollback(table, 2093 ioe->ticket, NULL, 0))) { 2094 free(table, M_TEMP, sizeof(*table)); 2095 free(ioe, M_TEMP, sizeof(*ioe)); 2096 goto fail; /* really bad */ 2097 } 2098 break; 2099 default: 2100 if ((error = pf_rollback_rules(ioe->ticket, 2101 ioe->anchor))) { 2102 free(table, M_TEMP, sizeof(*table)); 2103 free(ioe, M_TEMP, sizeof(*ioe)); 2104 goto fail; /* really bad */ 2105 } 2106 break; 2107 } 2108 } 2109 free(table, M_TEMP, sizeof(*table)); 2110 free(ioe, M_TEMP, sizeof(*ioe)); 2111 break; 2112 } 2113 2114 case DIOCXCOMMIT: { 2115 struct pfioc_trans *io = (struct pfioc_trans *)addr; 2116 struct pfioc_trans_e *ioe; 2117 struct pfr_table *table; 2118 struct pf_ruleset *rs; 2119 int i; 2120 2121 if (io->esize != sizeof(*ioe)) { 2122 error = ENODEV; 2123 goto fail; 2124 } 2125 ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK); 2126 table = malloc(sizeof(*table), M_TEMP, M_WAITOK); 2127 /* first makes sure everything will succeed */ 2128 for (i = 0; i < io->size; i++) { 2129 if (copyin(io->array+i, ioe, sizeof(*ioe))) { 2130 free(table, M_TEMP, sizeof(*table)); 2131 free(ioe, M_TEMP, sizeof(*ioe)); 2132 error = EFAULT; 2133 goto fail; 2134 } 2135 switch (ioe->type) { 2136 case PF_TRANS_TABLE: 2137 rs = pf_find_ruleset(ioe->anchor); 2138 if (rs == NULL || !rs->topen || ioe->ticket != 2139 rs->tticket) { 2140 free(table, M_TEMP, sizeof(*table)); 2141 free(ioe, M_TEMP, sizeof(*ioe)); 2142 error = EBUSY; 2143 goto fail; 2144 } 2145 break; 2146 default: 2147 rs = pf_find_ruleset(ioe->anchor); 2148 if (rs == NULL || 2149 !rs->rules.inactive.open || 2150 rs->rules.inactive.ticket != 2151 ioe->ticket) { 2152 free(table, M_TEMP, sizeof(*table)); 2153 free(ioe, M_TEMP, sizeof(*ioe)); 2154 error = EBUSY; 2155 goto fail; 2156 } 2157 break; 2158 } 2159 } 2160 2161 /* 2162 * Checked already in DIOCSETLIMIT, but check again as the 2163 * situation might have changed. 2164 */ 2165 for (i = 0; i < PF_LIMIT_MAX; i++) { 2166 if (((struct pool *)pf_pool_limits[i].pp)->pr_nout > 2167 pf_pool_limits[i].limit_new) { 2168 free(table, M_TEMP, sizeof(*table)); 2169 free(ioe, M_TEMP, sizeof(*ioe)); 2170 error = EBUSY; 2171 goto fail; 2172 } 2173 } 2174 /* now do the commit - no errors should happen here */ 2175 for (i = 0; i < io->size; i++) { 2176 if (copyin(io->array+i, ioe, sizeof(*ioe))) { 2177 free(table, M_TEMP, sizeof(*table)); 2178 free(ioe, M_TEMP, sizeof(*ioe)); 2179 error = EFAULT; 2180 goto fail; 2181 } 2182 switch (ioe->type) { 2183 case PF_TRANS_TABLE: 2184 bzero(table, sizeof(*table)); 2185 strlcpy(table->pfrt_anchor, ioe->anchor, 2186 sizeof(table->pfrt_anchor)); 2187 if ((error = pfr_ina_commit(table, ioe->ticket, 2188 NULL, NULL, 0))) { 2189 free(table, M_TEMP, sizeof(*table)); 2190 free(ioe, M_TEMP, sizeof(*ioe)); 2191 goto fail; /* really bad */ 2192 } 2193 break; 2194 default: 2195 if ((error = pf_commit_rules(ioe->ticket, 2196 ioe->anchor))) { 2197 free(table, M_TEMP, sizeof(*table)); 2198 free(ioe, M_TEMP, sizeof(*ioe)); 2199 goto fail; /* really bad */ 2200 } 2201 break; 2202 } 2203 } 2204 for (i = 0; i < PF_LIMIT_MAX; i++) { 2205 if (pf_pool_limits[i].limit_new != 2206 pf_pool_limits[i].limit && 2207 pool_sethardlimit(pf_pool_limits[i].pp, 2208 pf_pool_limits[i].limit_new, NULL, 0) != 0) { 2209 free(table, M_TEMP, sizeof(*table)); 2210 free(ioe, M_TEMP, sizeof(*ioe)); 2211 error = EBUSY; 2212 goto fail; /* really bad */ 2213 } 2214 pf_pool_limits[i].limit = pf_pool_limits[i].limit_new; 2215 } 2216 for (i = 0; i < PFTM_MAX; i++) { 2217 int old = pf_default_rule.timeout[i]; 2218 2219 pf_default_rule.timeout[i] = 2220 pf_default_rule_new.timeout[i]; 2221 if (pf_default_rule.timeout[i] == PFTM_INTERVAL && 2222 pf_default_rule.timeout[i] < old) 2223 wakeup(pf_purge_thread); 2224 } 2225 pfi_xcommit(); 2226 pf_trans_set_commit(); 2227 free(table, M_TEMP, sizeof(*table)); 2228 free(ioe, M_TEMP, sizeof(*ioe)); 2229 break; 2230 } 2231 2232 case DIOCGETSRCNODES: { 2233 struct pfioc_src_nodes *psn = (struct pfioc_src_nodes *)addr; 2234 struct pf_src_node *n, *p, *pstore; 2235 u_int32_t nr = 0; 2236 int space = psn->psn_len; 2237 2238 if (space == 0) { 2239 RB_FOREACH(n, pf_src_tree, &tree_src_tracking) 2240 nr++; 2241 psn->psn_len = sizeof(struct pf_src_node) * nr; 2242 break; 2243 } 2244 2245 pstore = malloc(sizeof(*pstore), M_TEMP, M_WAITOK); 2246 2247 p = psn->psn_src_nodes; 2248 RB_FOREACH(n, pf_src_tree, &tree_src_tracking) { 2249 int secs = time_uptime, diff; 2250 2251 if ((nr + 1) * sizeof(*p) > (unsigned)psn->psn_len) 2252 break; 2253 2254 bcopy(n, pstore, sizeof(*pstore)); 2255 bzero(&pstore->entry, sizeof(pstore->entry)); 2256 pstore->rule.ptr = NULL; 2257 pstore->kif = NULL; 2258 pstore->rule.nr = n->rule.ptr->nr; 2259 pstore->creation = secs - pstore->creation; 2260 if (pstore->expire > secs) 2261 pstore->expire -= secs; 2262 else 2263 pstore->expire = 0; 2264 2265 /* adjust the connection rate estimate */ 2266 diff = secs - n->conn_rate.last; 2267 if (diff >= n->conn_rate.seconds) 2268 pstore->conn_rate.count = 0; 2269 else 2270 pstore->conn_rate.count -= 2271 n->conn_rate.count * diff / 2272 n->conn_rate.seconds; 2273 2274 error = copyout(pstore, p, sizeof(*p)); 2275 if (error) { 2276 free(pstore, M_TEMP, sizeof(*pstore)); 2277 goto fail; 2278 } 2279 p++; 2280 nr++; 2281 } 2282 psn->psn_len = sizeof(struct pf_src_node) * nr; 2283 2284 free(pstore, M_TEMP, sizeof(*pstore)); 2285 break; 2286 } 2287 2288 case DIOCCLRSRCNODES: { 2289 struct pf_src_node *n; 2290 struct pf_state *state; 2291 2292 RB_FOREACH(state, pf_state_tree_id, &tree_id) 2293 pf_src_tree_remove_state(state); 2294 RB_FOREACH(n, pf_src_tree, &tree_src_tracking) 2295 n->expire = 1; 2296 pf_purge_expired_src_nodes(1); 2297 break; 2298 } 2299 2300 case DIOCKILLSRCNODES: { 2301 struct pf_src_node *sn; 2302 struct pf_state *s; 2303 struct pfioc_src_node_kill *psnk = 2304 (struct pfioc_src_node_kill *)addr; 2305 u_int killed = 0; 2306 2307 RB_FOREACH(sn, pf_src_tree, &tree_src_tracking) { 2308 if (PF_MATCHA(psnk->psnk_src.neg, 2309 &psnk->psnk_src.addr.v.a.addr, 2310 &psnk->psnk_src.addr.v.a.mask, 2311 &sn->addr, sn->af) && 2312 PF_MATCHA(psnk->psnk_dst.neg, 2313 &psnk->psnk_dst.addr.v.a.addr, 2314 &psnk->psnk_dst.addr.v.a.mask, 2315 &sn->raddr, sn->af)) { 2316 /* Handle state to src_node linkage */ 2317 if (sn->states != 0) 2318 RB_FOREACH(s, pf_state_tree_id, 2319 &tree_id) 2320 pf_state_rm_src_node(s, sn); 2321 sn->expire = 1; 2322 killed++; 2323 } 2324 } 2325 2326 if (killed > 0) 2327 pf_purge_expired_src_nodes(1); 2328 2329 psnk->psnk_killed = killed; 2330 break; 2331 } 2332 2333 case DIOCSETHOSTID: { 2334 u_int32_t *hostid = (u_int32_t *)addr; 2335 2336 if (*hostid == 0) 2337 pf_trans_set.hostid = arc4random(); 2338 else 2339 pf_trans_set.hostid = *hostid; 2340 pf_trans_set.mask |= PF_TSET_HOSTID; 2341 break; 2342 } 2343 2344 case DIOCOSFPFLUSH: 2345 pf_osfp_flush(); 2346 break; 2347 2348 case DIOCIGETIFACES: { 2349 struct pfioc_iface *io = (struct pfioc_iface *)addr; 2350 2351 if (io->pfiio_esize != sizeof(struct pfi_kif)) { 2352 error = ENODEV; 2353 break; 2354 } 2355 error = pfi_get_ifaces(io->pfiio_name, io->pfiio_buffer, 2356 &io->pfiio_size); 2357 break; 2358 } 2359 2360 case DIOCSETIFFLAG: { 2361 struct pfioc_iface *io = (struct pfioc_iface *)addr; 2362 2363 error = pfi_set_flags(io->pfiio_name, io->pfiio_flags); 2364 break; 2365 } 2366 2367 case DIOCCLRIFFLAG: { 2368 struct pfioc_iface *io = (struct pfioc_iface *)addr; 2369 2370 error = pfi_clear_flags(io->pfiio_name, io->pfiio_flags); 2371 break; 2372 } 2373 2374 case DIOCSETREASS: { 2375 u_int32_t *reass = (u_int32_t *)addr; 2376 2377 pf_trans_set.reass = *reass; 2378 pf_trans_set.mask |= PF_TSET_REASS; 2379 break; 2380 } 2381 2382 default: 2383 error = ENODEV; 2384 break; 2385 } 2386 fail: 2387 splx(s); 2388 if (flags & FWRITE) 2389 rw_exit_write(&pf_consistency_lock); 2390 else 2391 rw_exit_read(&pf_consistency_lock); 2392 return (error); 2393 } 2394 2395 void 2396 pf_trans_set_commit(void) 2397 { 2398 if (pf_trans_set.mask & PF_TSET_STATUSIF) 2399 strlcpy(pf_status.ifname, pf_trans_set.statusif, IFNAMSIZ); 2400 if (pf_trans_set.mask & PF_TSET_DEBUG) 2401 pf_status.debug = pf_trans_set.debug; 2402 if (pf_trans_set.mask & PF_TSET_HOSTID) 2403 pf_status.hostid = pf_trans_set.hostid; 2404 if (pf_trans_set.mask & PF_TSET_REASS) 2405 pf_status.reass = pf_trans_set.reass; 2406 } 2407 2408 void 2409 pf_pool_copyin(struct pf_pool *from, struct pf_pool *to) 2410 { 2411 bcopy(from, to, sizeof(*to)); 2412 to->kif = NULL; 2413 } 2414 2415 int 2416 pf_rule_copyin(struct pf_rule *from, struct pf_rule *to, 2417 struct pf_ruleset *ruleset) 2418 { 2419 int i; 2420 2421 to->src = from->src; 2422 to->dst = from->dst; 2423 2424 /* XXX union skip[] */ 2425 2426 strlcpy(to->label, from->label, sizeof(to->label)); 2427 strlcpy(to->ifname, from->ifname, sizeof(to->ifname)); 2428 strlcpy(to->rcv_ifname, from->rcv_ifname, sizeof(to->rcv_ifname)); 2429 strlcpy(to->qname, from->qname, sizeof(to->qname)); 2430 strlcpy(to->pqname, from->pqname, sizeof(to->pqname)); 2431 strlcpy(to->tagname, from->tagname, sizeof(to->tagname)); 2432 strlcpy(to->match_tagname, from->match_tagname, 2433 sizeof(to->match_tagname)); 2434 strlcpy(to->overload_tblname, from->overload_tblname, 2435 sizeof(to->overload_tblname)); 2436 2437 pf_pool_copyin(&from->nat, &to->nat); 2438 pf_pool_copyin(&from->rdr, &to->rdr); 2439 pf_pool_copyin(&from->route, &to->route); 2440 2441 if (pf_kif_setup(to->ifname, &to->kif)) 2442 return (EINVAL); 2443 if (pf_kif_setup(to->rcv_ifname, &to->rcv_kif)) 2444 return (EINVAL); 2445 if (to->overload_tblname[0]) { 2446 if ((to->overload_tbl = pfr_attach_table(ruleset, 2447 to->overload_tblname, 0)) == NULL) 2448 return (EINVAL); 2449 else 2450 to->overload_tbl->pfrkt_flags |= PFR_TFLAG_ACTIVE; 2451 } 2452 2453 if (pf_kif_setup(to->rdr.ifname, &to->rdr.kif)) 2454 return (EINVAL); 2455 if (pf_kif_setup(to->nat.ifname, &to->nat.kif)) 2456 return (EINVAL); 2457 if (pf_kif_setup(to->route.ifname, &to->route.kif)) 2458 return (EINVAL); 2459 2460 to->os_fingerprint = from->os_fingerprint; 2461 2462 to->rtableid = from->rtableid; 2463 if (to->rtableid >= 0 && !rtable_exists(to->rtableid)) 2464 return (EBUSY); 2465 to->onrdomain = from->onrdomain; 2466 if (to->onrdomain >= 0 && !rtable_exists(to->onrdomain)) 2467 return (EBUSY); 2468 if (to->onrdomain >= 0) /* make sure it is a real rdomain */ 2469 to->onrdomain = rtable_l2(to->onrdomain); 2470 2471 for (i = 0; i < PFTM_MAX; i++) 2472 to->timeout[i] = from->timeout[i]; 2473 to->states_tot = from->states_tot; 2474 to->max_states = from->max_states; 2475 to->max_src_nodes = from->max_src_nodes; 2476 to->max_src_states = from->max_src_states; 2477 to->max_src_conn = from->max_src_conn; 2478 to->max_src_conn_rate.limit = from->max_src_conn_rate.limit; 2479 to->max_src_conn_rate.seconds = from->max_src_conn_rate.seconds; 2480 2481 if (to->qname[0] != 0) { 2482 if ((to->qid = pf_qname2qid(to->qname, 0)) == 0) 2483 return (EBUSY); 2484 if (to->pqname[0] != 0) { 2485 if ((to->pqid = pf_qname2qid(to->pqname, 0)) == 0) 2486 return (EBUSY); 2487 } else 2488 to->pqid = to->qid; 2489 } 2490 to->rt_listid = from->rt_listid; 2491 to->prob = from->prob; 2492 to->return_icmp = from->return_icmp; 2493 to->return_icmp6 = from->return_icmp6; 2494 to->max_mss = from->max_mss; 2495 if (to->tagname[0]) 2496 if ((to->tag = pf_tagname2tag(to->tagname, 1)) == 0) 2497 return (EBUSY); 2498 if (to->match_tagname[0]) 2499 if ((to->match_tag = pf_tagname2tag(to->match_tagname, 1)) == 0) 2500 return (EBUSY); 2501 to->scrub_flags = from->scrub_flags; 2502 to->uid = from->uid; 2503 to->gid = from->gid; 2504 to->rule_flag = from->rule_flag; 2505 to->action = from->action; 2506 to->direction = from->direction; 2507 to->log = from->log; 2508 to->logif = from->logif; 2509 #if NPFLOG > 0 2510 if (!to->log) 2511 to->logif = 0; 2512 #endif /* NPFLOG > 0 */ 2513 to->quick = from->quick; 2514 to->ifnot = from->ifnot; 2515 to->rcvifnot = from->rcvifnot; 2516 to->match_tag_not = from->match_tag_not; 2517 to->keep_state = from->keep_state; 2518 to->af = from->af; 2519 to->naf = from->naf; 2520 to->proto = from->proto; 2521 to->type = from->type; 2522 to->code = from->code; 2523 to->flags = from->flags; 2524 to->flagset = from->flagset; 2525 to->min_ttl = from->min_ttl; 2526 to->allow_opts = from->allow_opts; 2527 to->rt = from->rt; 2528 to->return_ttl = from->return_ttl; 2529 to->tos = from->tos; 2530 to->set_tos = from->set_tos; 2531 to->anchor_relative = from->anchor_relative; /* XXX */ 2532 to->anchor_wildcard = from->anchor_wildcard; /* XXX */ 2533 to->flush = from->flush; 2534 to->divert.addr = from->divert.addr; 2535 to->divert.port = from->divert.port; 2536 to->divert_packet.addr = from->divert_packet.addr; 2537 to->divert_packet.port = from->divert_packet.port; 2538 to->prio = from->prio; 2539 to->set_prio[0] = from->set_prio[0]; 2540 to->set_prio[1] = from->set_prio[1]; 2541 2542 return (0); 2543 } 2544