1 /* $OpenBSD: pf_if.c,v 1.109 2022/11/22 22:28:40 sashan Exp $ */ 2 3 /* 4 * Copyright 2005 Henning Brauer <henning@openbsd.org> 5 * Copyright 2005 Ryan McBride <mcbride@openbsd.org> 6 * Copyright (c) 2001 Daniel Hartmeier 7 * Copyright (c) 2003 Cedric Berger 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * - Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * - Redistributions in binary form must reproduce the above 17 * copyright notice, this list of conditions and the following 18 * disclaimer in the documentation and/or other materials provided 19 * with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 * POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/mbuf.h> 38 #include <sys/filio.h> 39 #include <sys/socket.h> 40 #include <sys/socketvar.h> 41 #include <sys/kernel.h> 42 #include <sys/device.h> 43 #include <sys/time.h> 44 #include <sys/pool.h> 45 #include <sys/syslog.h> 46 47 #include <net/if.h> 48 #include <net/if_var.h> 49 50 #include <netinet/in.h> 51 #include <netinet/ip.h> 52 #include <netinet/ip_var.h> 53 54 #include <net/pfvar.h> 55 56 #include <netinet/ip_icmp.h> 57 #include <netinet/tcp.h> 58 #include <netinet/udp.h> 59 60 #ifdef INET6 61 #include <netinet/ip6.h> 62 #include <netinet/icmp6.h> 63 #endif /* INET6 */ 64 65 #include <net/pfvar_priv.h> 66 67 #define isupper(c) ((c) >= 'A' && (c) <= 'Z') 68 #define islower(c) ((c) >= 'a' && (c) <= 'z') 69 #define isalpha(c) (isupper(c)||islower(c)) 70 71 struct pfi_kif *pfi_all = NULL; 72 struct pool pfi_addr_pl; 73 struct pfi_ifhead pfi_ifs; 74 long pfi_update = 1; 75 struct pfr_addr *pfi_buffer; 76 int pfi_buffer_cnt; 77 int pfi_buffer_max; 78 79 void pfi_kif_update(struct pfi_kif *); 80 void pfi_dynaddr_update(struct pfi_dynaddr *dyn); 81 void pfi_table_update(struct pfr_ktable *, struct pfi_kif *, 82 u_int8_t, int); 83 void pfi_kifaddr_update(void *); 84 void pfi_instance_add(struct ifnet *, u_int8_t, int); 85 void pfi_address_add(struct sockaddr *, sa_family_t, u_int8_t); 86 int pfi_if_compare(struct pfi_kif *, struct pfi_kif *); 87 int pfi_skip_if(const char *, struct pfi_kif *); 88 int pfi_unmask(void *); 89 void pfi_group_change(const char *); 90 91 RB_PROTOTYPE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare); 92 RB_GENERATE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare); 93 94 #define PFI_BUFFER_MAX 0x10000 95 #define PFI_MTYPE M_IFADDR 96 97 struct pfi_kif * 98 pfi_kif_alloc(const char *kif_name, int mflags) 99 { 100 struct pfi_kif *kif; 101 102 kif = malloc(sizeof(*pfi_all), PFI_MTYPE, mflags|M_ZERO); 103 if (kif == NULL) 104 return (NULL); 105 strlcpy(kif->pfik_name, kif_name, sizeof(kif->pfik_name)); 106 kif->pfik_tzero = gettime(); 107 TAILQ_INIT(&kif->pfik_dynaddrs); 108 109 if (!strcmp(kif->pfik_name, "any")) { 110 /* both so it works in the ioctl and the regular case */ 111 kif->pfik_flags |= PFI_IFLAG_ANY; 112 kif->pfik_flags_new |= PFI_IFLAG_ANY; 113 } 114 115 return (kif); 116 } 117 118 void 119 pfi_kif_free(struct pfi_kif *kif) 120 { 121 if (kif == NULL) 122 return; 123 124 if (kif->pfik_rules || kif->pfik_states || kif->pfik_routes || 125 kif->pfik_srcnodes || kif->pfik_flagrefs) 126 panic("kif is still alive"); 127 128 free(kif, PFI_MTYPE, sizeof(*kif)); 129 } 130 131 void 132 pfi_initialize(void) 133 { 134 /* 135 * The first time we arrive here is during kernel boot, 136 * when if_attachsetup() for the first time. No locking 137 * is needed in this case, because it's granted there 138 * is a single thread, which sets pfi_all global var. 139 */ 140 if (pfi_all != NULL) /* already initialized */ 141 return; 142 143 pool_init(&pfi_addr_pl, sizeof(struct pfi_dynaddr), 0, IPL_SOFTNET, 0, 144 "pfiaddrpl", NULL); 145 pfi_buffer_max = 64; 146 pfi_buffer = mallocarray(pfi_buffer_max, sizeof(*pfi_buffer), 147 PFI_MTYPE, M_WAITOK); 148 149 pfi_all = pfi_kif_alloc(IFG_ALL, M_WAITOK); 150 151 if (RB_INSERT(pfi_ifhead, &pfi_ifs, pfi_all) != NULL) 152 panic("IFG_ALL kif found already"); 153 } 154 155 struct pfi_kif * 156 pfi_kif_find(const char *kif_name) 157 { 158 struct pfi_kif_cmp s; 159 160 memset(&s, 0, sizeof(s)); 161 strlcpy(s.pfik_name, kif_name, sizeof(s.pfik_name)); 162 return (RB_FIND(pfi_ifhead, &pfi_ifs, (struct pfi_kif *)&s)); 163 } 164 165 struct pfi_kif * 166 pfi_kif_get(const char *kif_name, struct pfi_kif **prealloc) 167 { 168 struct pfi_kif *kif; 169 170 if ((kif = pfi_kif_find(kif_name))) 171 return (kif); 172 173 /* create new one */ 174 if ((prealloc == NULL) || (*prealloc == NULL)) { 175 kif = pfi_kif_alloc(kif_name, M_NOWAIT); 176 if (kif == NULL) 177 return (NULL); 178 } else { 179 kif = *prealloc; 180 *prealloc = NULL; 181 } 182 183 RB_INSERT(pfi_ifhead, &pfi_ifs, kif); 184 return (kif); 185 } 186 187 void 188 pfi_kif_ref(struct pfi_kif *kif, enum pfi_kif_refs what) 189 { 190 switch (what) { 191 case PFI_KIF_REF_RULE: 192 kif->pfik_rules++; 193 break; 194 case PFI_KIF_REF_STATE: 195 kif->pfik_states++; 196 break; 197 case PFI_KIF_REF_ROUTE: 198 kif->pfik_routes++; 199 break; 200 case PFI_KIF_REF_SRCNODE: 201 kif->pfik_srcnodes++; 202 break; 203 case PFI_KIF_REF_FLAG: 204 kif->pfik_flagrefs++; 205 break; 206 default: 207 panic("pfi_kif_ref with unknown type"); 208 } 209 } 210 211 void 212 pfi_kif_unref(struct pfi_kif *kif, enum pfi_kif_refs what) 213 { 214 if (kif == NULL) 215 return; 216 217 switch (what) { 218 case PFI_KIF_REF_NONE: 219 break; 220 case PFI_KIF_REF_RULE: 221 if (kif->pfik_rules <= 0) { 222 DPFPRINTF(LOG_ERR, 223 "pfi_kif_unref (%s): rules refcount <= 0", 224 kif->pfik_name); 225 return; 226 } 227 kif->pfik_rules--; 228 break; 229 case PFI_KIF_REF_STATE: 230 if (kif->pfik_states <= 0) { 231 DPFPRINTF(LOG_ERR, 232 "pfi_kif_unref (%s): state refcount <= 0", 233 kif->pfik_name); 234 return; 235 } 236 kif->pfik_states--; 237 break; 238 case PFI_KIF_REF_ROUTE: 239 if (kif->pfik_routes <= 0) { 240 DPFPRINTF(LOG_ERR, 241 "pfi_kif_unref (%s): route refcount <= 0", 242 kif->pfik_name); 243 return; 244 } 245 kif->pfik_routes--; 246 break; 247 case PFI_KIF_REF_SRCNODE: 248 if (kif->pfik_srcnodes <= 0) { 249 DPFPRINTF(LOG_ERR, 250 "pfi_kif_unref (%s): src-node refcount <= 0", 251 kif->pfik_name); 252 return; 253 } 254 kif->pfik_srcnodes--; 255 break; 256 case PFI_KIF_REF_FLAG: 257 if (kif->pfik_flagrefs <= 0) { 258 DPFPRINTF(LOG_ERR, 259 "pfi_kif_unref (%s): flags refcount <= 0", 260 kif->pfik_name); 261 return; 262 } 263 kif->pfik_flagrefs--; 264 break; 265 default: 266 panic("pfi_kif_unref (%s) with unknown type", kif->pfik_name); 267 } 268 269 if (kif->pfik_ifp != NULL || kif->pfik_group != NULL || kif == pfi_all) 270 return; 271 272 if (kif->pfik_rules || kif->pfik_states || kif->pfik_routes || 273 kif->pfik_srcnodes || kif->pfik_flagrefs) 274 return; 275 276 RB_REMOVE(pfi_ifhead, &pfi_ifs, kif); 277 free(kif, PFI_MTYPE, sizeof(*kif)); 278 } 279 280 int 281 pfi_kif_match(struct pfi_kif *rule_kif, struct pfi_kif *packet_kif) 282 { 283 struct ifg_list *p; 284 285 if (rule_kif == NULL || rule_kif == packet_kif) 286 return (1); 287 288 if (rule_kif->pfik_group != NULL) 289 TAILQ_FOREACH(p, &packet_kif->pfik_ifp->if_groups, ifgl_next) 290 if (p->ifgl_group == rule_kif->pfik_group) 291 return (1); 292 293 if (rule_kif->pfik_flags & PFI_IFLAG_ANY && packet_kif->pfik_ifp && 294 !(packet_kif->pfik_ifp->if_flags & IFF_LOOPBACK)) 295 return (1); 296 297 return (0); 298 } 299 300 void 301 pfi_attach_ifnet(struct ifnet *ifp) 302 { 303 struct pfi_kif *kif; 304 struct task *t; 305 306 PF_LOCK(); 307 pfi_initialize(); 308 pfi_update++; 309 if ((kif = pfi_kif_get(ifp->if_xname, NULL)) == NULL) 310 panic("%s: pfi_kif_get failed", __func__); 311 312 kif->pfik_ifp = ifp; 313 ifp->if_pf_kif = (caddr_t)kif; 314 315 t = malloc(sizeof(*t), PFI_MTYPE, M_WAITOK); 316 task_set(t, pfi_kifaddr_update, kif); 317 if_addrhook_add(ifp, t); 318 kif->pfik_ah_cookie = t; 319 320 pfi_kif_update(kif); 321 PF_UNLOCK(); 322 } 323 324 void 325 pfi_detach_ifnet(struct ifnet *ifp) 326 { 327 struct pfi_kif *kif; 328 struct task *t; 329 330 if ((kif = (struct pfi_kif *)ifp->if_pf_kif) == NULL) 331 return; 332 333 PF_LOCK(); 334 pfi_update++; 335 t = kif->pfik_ah_cookie; 336 kif->pfik_ah_cookie = NULL; 337 if_addrhook_del(ifp, t); 338 free(t, PFI_MTYPE, sizeof(*t)); 339 340 pfi_kif_update(kif); 341 342 kif->pfik_ifp = NULL; 343 ifp->if_pf_kif = NULL; 344 pfi_kif_unref(kif, PFI_KIF_REF_NONE); 345 PF_UNLOCK(); 346 } 347 348 void 349 pfi_attach_ifgroup(struct ifg_group *ifg) 350 { 351 struct pfi_kif *kif; 352 353 PF_LOCK(); 354 pfi_initialize(); 355 pfi_update++; 356 if ((kif = pfi_kif_get(ifg->ifg_group, NULL)) == NULL) 357 panic("%s: pfi_kif_get failed", __func__); 358 359 kif->pfik_group = ifg; 360 ifg->ifg_pf_kif = (caddr_t)kif; 361 PF_UNLOCK(); 362 } 363 364 void 365 pfi_detach_ifgroup(struct ifg_group *ifg) 366 { 367 struct pfi_kif *kif; 368 369 if ((kif = (struct pfi_kif *)ifg->ifg_pf_kif) == NULL) 370 return; 371 372 PF_LOCK(); 373 pfi_update++; 374 375 kif->pfik_group = NULL; 376 ifg->ifg_pf_kif = NULL; 377 pfi_kif_unref(kif, PFI_KIF_REF_NONE); 378 PF_UNLOCK(); 379 } 380 381 void 382 pfi_group_change(const char *group) 383 { 384 struct pfi_kif *kif; 385 386 pfi_update++; 387 if ((kif = pfi_kif_get(group, NULL)) == NULL) 388 panic("%s: pfi_kif_get failed", __func__); 389 390 pfi_kif_update(kif); 391 } 392 393 void 394 pfi_group_delmember(const char *group) 395 { 396 PF_LOCK(); 397 pfi_group_change(group); 398 pfi_xcommit(); 399 PF_UNLOCK(); 400 } 401 402 void 403 pfi_group_addmember(const char *group) 404 { 405 PF_LOCK(); 406 pfi_group_change(group); 407 pfi_xcommit(); 408 PF_UNLOCK(); 409 } 410 411 int 412 pfi_match_addr(struct pfi_dynaddr *dyn, struct pf_addr *a, sa_family_t af) 413 { 414 switch (af) { 415 case AF_INET: 416 switch (dyn->pfid_acnt4) { 417 case 0: 418 return (0); 419 case 1: 420 return (pf_match_addr(0, &dyn->pfid_addr4, 421 &dyn->pfid_mask4, a, AF_INET)); 422 default: 423 return (pfr_match_addr(dyn->pfid_kt, a, AF_INET)); 424 } 425 break; 426 #ifdef INET6 427 case AF_INET6: 428 switch (dyn->pfid_acnt6) { 429 case 0: 430 return (0); 431 case 1: 432 return (pf_match_addr(0, &dyn->pfid_addr6, 433 &dyn->pfid_mask6, a, AF_INET6)); 434 default: 435 return (pfr_match_addr(dyn->pfid_kt, a, AF_INET6)); 436 } 437 break; 438 #endif /* INET6 */ 439 default: 440 return (0); 441 } 442 } 443 444 int 445 pfi_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af, int wait) 446 { 447 struct pfi_dynaddr *dyn; 448 char tblname[PF_TABLE_NAME_SIZE]; 449 struct pf_ruleset *ruleset = NULL; 450 int rv = 0; 451 452 if (aw->type != PF_ADDR_DYNIFTL) 453 return (0); 454 if ((dyn = pool_get(&pfi_addr_pl, wait|PR_LIMITFAIL|PR_ZERO)) == NULL) 455 return (1); 456 457 if (!strcmp(aw->v.ifname, "self")) 458 dyn->pfid_kif = pfi_kif_get(IFG_ALL, NULL); 459 else 460 dyn->pfid_kif = pfi_kif_get(aw->v.ifname, NULL); 461 if (dyn->pfid_kif == NULL) { 462 rv = 1; 463 goto _bad; 464 } 465 pfi_kif_ref(dyn->pfid_kif, PFI_KIF_REF_RULE); 466 467 dyn->pfid_net = pfi_unmask(&aw->v.a.mask); 468 if (af == AF_INET && dyn->pfid_net == 32) 469 dyn->pfid_net = 128; 470 strlcpy(tblname, aw->v.ifname, sizeof(tblname)); 471 if (aw->iflags & PFI_AFLAG_NETWORK) 472 strlcat(tblname, ":network", sizeof(tblname)); 473 if (aw->iflags & PFI_AFLAG_BROADCAST) 474 strlcat(tblname, ":broadcast", sizeof(tblname)); 475 if (aw->iflags & PFI_AFLAG_PEER) 476 strlcat(tblname, ":peer", sizeof(tblname)); 477 if (aw->iflags & PFI_AFLAG_NOALIAS) 478 strlcat(tblname, ":0", sizeof(tblname)); 479 if (dyn->pfid_net != 128) 480 snprintf(tblname + strlen(tblname), 481 sizeof(tblname) - strlen(tblname), "/%d", dyn->pfid_net); 482 if ((ruleset = pf_find_or_create_ruleset(PF_RESERVED_ANCHOR)) == NULL) { 483 rv = 1; 484 goto _bad; 485 } 486 487 if ((dyn->pfid_kt = pfr_attach_table(ruleset, tblname, wait)) == NULL) { 488 rv = 1; 489 goto _bad; 490 } 491 492 dyn->pfid_kt->pfrkt_flags |= PFR_TFLAG_ACTIVE; 493 dyn->pfid_iflags = aw->iflags; 494 dyn->pfid_af = af; 495 496 TAILQ_INSERT_TAIL(&dyn->pfid_kif->pfik_dynaddrs, dyn, entry); 497 aw->p.dyn = dyn; 498 pfi_kif_update(dyn->pfid_kif); 499 return (0); 500 501 _bad: 502 if (dyn->pfid_kt != NULL) 503 pfr_detach_table(dyn->pfid_kt); 504 if (ruleset != NULL) 505 pf_remove_if_empty_ruleset(ruleset); 506 if (dyn->pfid_kif != NULL) 507 pfi_kif_unref(dyn->pfid_kif, PFI_KIF_REF_RULE); 508 pool_put(&pfi_addr_pl, dyn); 509 return (rv); 510 } 511 512 void 513 pfi_kif_update(struct pfi_kif *kif) 514 { 515 struct ifg_list *ifgl; 516 struct pfi_dynaddr *p; 517 518 /* update all dynaddr */ 519 TAILQ_FOREACH(p, &kif->pfik_dynaddrs, entry) 520 pfi_dynaddr_update(p); 521 522 /* again for all groups kif is member of */ 523 if (kif->pfik_ifp != NULL) 524 TAILQ_FOREACH(ifgl, &kif->pfik_ifp->if_groups, ifgl_next) 525 pfi_kif_update((struct pfi_kif *) 526 ifgl->ifgl_group->ifg_pf_kif); 527 } 528 529 void 530 pfi_dynaddr_update(struct pfi_dynaddr *dyn) 531 { 532 struct pfi_kif *kif; 533 struct pfr_ktable *kt; 534 535 if (dyn == NULL || dyn->pfid_kif == NULL || dyn->pfid_kt == NULL) 536 panic("pfi_dynaddr_update"); 537 538 kif = dyn->pfid_kif; 539 kt = dyn->pfid_kt; 540 541 if (kt->pfrkt_larg != pfi_update) { 542 /* this table needs to be brought up-to-date */ 543 pfi_table_update(kt, kif, dyn->pfid_net, dyn->pfid_iflags); 544 kt->pfrkt_larg = pfi_update; 545 } 546 pfr_dynaddr_update(kt, dyn); 547 } 548 549 void 550 pfi_table_update(struct pfr_ktable *kt, struct pfi_kif *kif, u_int8_t net, int flags) 551 { 552 int e, size2 = 0; 553 struct ifg_member *ifgm; 554 555 pfi_buffer_cnt = 0; 556 557 if (kif->pfik_ifp != NULL) 558 pfi_instance_add(kif->pfik_ifp, net, flags); 559 else if (kif->pfik_group != NULL) 560 TAILQ_FOREACH(ifgm, &kif->pfik_group->ifg_members, ifgm_next) 561 pfi_instance_add(ifgm->ifgm_ifp, net, flags); 562 563 if ((e = pfr_set_addrs(&kt->pfrkt_t, pfi_buffer, pfi_buffer_cnt, &size2, 564 NULL, NULL, NULL, 0, PFR_TFLAG_ALLMASK))) 565 DPFPRINTF(LOG_ERR, 566 "pfi_table_update: cannot set %d new addresses " 567 "into table %s: %d", pfi_buffer_cnt, kt->pfrkt_name, e); 568 } 569 570 void 571 pfi_instance_add(struct ifnet *ifp, u_int8_t net, int flags) 572 { 573 struct ifaddr *ifa; 574 int got4 = 0, got6 = 0; 575 int net2, af; 576 577 if (ifp == NULL) 578 return; 579 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 580 if (ifa->ifa_addr == NULL) 581 continue; 582 af = ifa->ifa_addr->sa_family; 583 if (af != AF_INET && af != AF_INET6) 584 continue; 585 if ((flags & PFI_AFLAG_BROADCAST) && af == AF_INET6) 586 continue; 587 if ((flags & PFI_AFLAG_BROADCAST) && 588 !(ifp->if_flags & IFF_BROADCAST)) 589 continue; 590 if ((flags & PFI_AFLAG_PEER) && 591 !(ifp->if_flags & IFF_POINTOPOINT)) 592 continue; 593 if ((flags & PFI_AFLAG_NETWORK) && af == AF_INET6 && 594 IN6_IS_ADDR_LINKLOCAL( 595 &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) 596 continue; 597 if (flags & PFI_AFLAG_NOALIAS) { 598 if (af == AF_INET && got4) 599 continue; 600 if (af == AF_INET6 && got6) 601 continue; 602 } 603 if (af == AF_INET) 604 got4 = 1; 605 else if (af == AF_INET6) 606 got6 = 1; 607 net2 = net; 608 if (net2 == 128 && (flags & PFI_AFLAG_NETWORK)) { 609 if (af == AF_INET) 610 net2 = pfi_unmask(&((struct sockaddr_in *) 611 ifa->ifa_netmask)->sin_addr); 612 else if (af == AF_INET6) 613 net2 = pfi_unmask(&((struct sockaddr_in6 *) 614 ifa->ifa_netmask)->sin6_addr); 615 } 616 if (af == AF_INET && net2 > 32) 617 net2 = 32; 618 if (flags & PFI_AFLAG_BROADCAST) 619 pfi_address_add(ifa->ifa_broadaddr, af, net2); 620 else if (flags & PFI_AFLAG_PEER) 621 pfi_address_add(ifa->ifa_dstaddr, af, net2); 622 else 623 pfi_address_add(ifa->ifa_addr, af, net2); 624 } 625 } 626 627 void 628 pfi_address_add(struct sockaddr *sa, sa_family_t af, u_int8_t net) 629 { 630 struct pfr_addr *p; 631 int i; 632 633 if (pfi_buffer_cnt >= pfi_buffer_max) { 634 int new_max = pfi_buffer_max * 2; 635 636 if (new_max > PFI_BUFFER_MAX) { 637 DPFPRINTF(LOG_ERR, 638 "pfi_address_add: address buffer full (%d/%d)", 639 pfi_buffer_cnt, PFI_BUFFER_MAX); 640 return; 641 } 642 p = mallocarray(new_max, sizeof(*pfi_buffer), PFI_MTYPE, 643 M_DONTWAIT); 644 if (p == NULL) { 645 DPFPRINTF(LOG_ERR, 646 "pfi_address_add: no memory to grow buffer " 647 "(%d/%d)", pfi_buffer_cnt, PFI_BUFFER_MAX); 648 return; 649 } 650 memcpy(p, pfi_buffer, pfi_buffer_max * sizeof(*pfi_buffer)); 651 /* no need to zero buffer */ 652 free(pfi_buffer, PFI_MTYPE, pfi_buffer_max * sizeof(*pfi_buffer)); 653 pfi_buffer = p; 654 pfi_buffer_max = new_max; 655 } 656 if (af == AF_INET && net > 32) 657 net = 128; 658 p = pfi_buffer + pfi_buffer_cnt++; 659 memset(p, 0, sizeof(*p)); 660 p->pfra_af = af; 661 p->pfra_net = net; 662 if (af == AF_INET) 663 p->pfra_ip4addr = ((struct sockaddr_in *)sa)->sin_addr; 664 else if (af == AF_INET6) { 665 p->pfra_ip6addr = ((struct sockaddr_in6 *)sa)->sin6_addr; 666 if (IN6_IS_SCOPE_EMBED(&p->pfra_ip6addr)) 667 p->pfra_ip6addr.s6_addr16[1] = 0; 668 } 669 /* mask network address bits */ 670 if (net < 128) 671 ((caddr_t)p)[p->pfra_net/8] &= ~(0xFF >> (p->pfra_net%8)); 672 for (i = (p->pfra_net+7)/8; i < sizeof(p->pfra_u); i++) 673 ((caddr_t)p)[i] = 0; 674 } 675 676 void 677 pfi_dynaddr_remove(struct pf_addr_wrap *aw) 678 { 679 if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL || 680 aw->p.dyn->pfid_kif == NULL || aw->p.dyn->pfid_kt == NULL) 681 return; 682 683 TAILQ_REMOVE(&aw->p.dyn->pfid_kif->pfik_dynaddrs, aw->p.dyn, entry); 684 pfi_kif_unref(aw->p.dyn->pfid_kif, PFI_KIF_REF_RULE); 685 aw->p.dyn->pfid_kif = NULL; 686 pfr_detach_table(aw->p.dyn->pfid_kt); 687 aw->p.dyn->pfid_kt = NULL; 688 pool_put(&pfi_addr_pl, aw->p.dyn); 689 aw->p.dyn = NULL; 690 } 691 692 void 693 pfi_dynaddr_copyout(struct pf_addr_wrap *aw) 694 { 695 if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL || 696 aw->p.dyn->pfid_kif == NULL) 697 return; 698 aw->p.dyncnt = aw->p.dyn->pfid_acnt4 + aw->p.dyn->pfid_acnt6; 699 } 700 701 void 702 pfi_kifaddr_update(void *v) 703 { 704 struct pfi_kif *kif = (struct pfi_kif *)v; 705 706 NET_ASSERT_LOCKED(); 707 708 PF_LOCK(); 709 pfi_update++; 710 pfi_kif_update(kif); 711 PF_UNLOCK(); 712 } 713 714 int 715 pfi_if_compare(struct pfi_kif *p, struct pfi_kif *q) 716 { 717 return (strncmp(p->pfik_name, q->pfik_name, IFNAMSIZ)); 718 } 719 720 void 721 pfi_update_status(const char *name, struct pf_status *pfs) 722 { 723 struct pfi_kif *p; 724 struct pfi_kif_cmp key; 725 struct ifg_member p_member, *ifgm; 726 TAILQ_HEAD(, ifg_member) ifg_members; 727 int i, j, k; 728 729 if (*name == '\0' && pfs == NULL) { 730 RB_FOREACH(p, pfi_ifhead, &pfi_ifs) { 731 memset(p->pfik_packets, 0, sizeof(p->pfik_packets)); 732 memset(p->pfik_bytes, 0, sizeof(p->pfik_bytes)); 733 p->pfik_tzero = gettime(); 734 } 735 return; 736 } 737 738 strlcpy(key.pfik_name, name, sizeof(key.pfik_name)); 739 p = RB_FIND(pfi_ifhead, &pfi_ifs, (struct pfi_kif *)&key); 740 if (p == NULL) { 741 return; 742 } 743 if (p->pfik_group != NULL) { 744 memcpy(&ifg_members, &p->pfik_group->ifg_members, 745 sizeof(ifg_members)); 746 } else { 747 /* build a temporary list for p only */ 748 memset(&p_member, 0, sizeof(p_member)); 749 p_member.ifgm_ifp = p->pfik_ifp; 750 TAILQ_INIT(&ifg_members); 751 TAILQ_INSERT_TAIL(&ifg_members, &p_member, ifgm_next); 752 } 753 if (pfs) { 754 memset(pfs->pcounters, 0, sizeof(pfs->pcounters)); 755 memset(pfs->bcounters, 0, sizeof(pfs->bcounters)); 756 } 757 TAILQ_FOREACH(ifgm, &ifg_members, ifgm_next) { 758 if (ifgm->ifgm_ifp == NULL) 759 continue; 760 p = (struct pfi_kif *)ifgm->ifgm_ifp->if_pf_kif; 761 762 /* just clear statistics */ 763 if (pfs == NULL) { 764 memset(p->pfik_packets, 0, sizeof(p->pfik_packets)); 765 memset(p->pfik_bytes, 0, sizeof(p->pfik_bytes)); 766 p->pfik_tzero = gettime(); 767 continue; 768 } 769 for (i = 0; i < 2; i++) 770 for (j = 0; j < 2; j++) 771 for (k = 0; k < 2; k++) { 772 pfs->pcounters[i][j][k] += 773 p->pfik_packets[i][j][k]; 774 pfs->bcounters[i][j] += 775 p->pfik_bytes[i][j][k]; 776 } 777 } 778 } 779 780 void 781 pfi_get_ifaces(const char *name, struct pfi_kif *buf, int *size) 782 { 783 struct pfi_kif *p; 784 int n = 0; 785 786 RB_FOREACH(p, pfi_ifhead, &pfi_ifs) { 787 if (pfi_skip_if(name, p)) 788 continue; 789 if (*size <= ++n) 790 break; 791 if (!p->pfik_tzero) 792 p->pfik_tzero = gettime(); 793 memcpy(buf++, p, sizeof(*buf)); 794 } 795 *size = n; 796 } 797 798 int 799 pfi_skip_if(const char *filter, struct pfi_kif *p) 800 { 801 struct ifg_list *i; 802 int n; 803 804 if (filter == NULL || !*filter) 805 return (0); 806 if (!strcmp(p->pfik_name, filter)) 807 return (0); /* exact match */ 808 n = strlen(filter); 809 if (n < 1 || n >= IFNAMSIZ) 810 return (1); /* sanity check */ 811 if (filter[n-1] >= '0' && filter[n-1] <= '9') 812 return (1); /* group names may not end in a digit */ 813 if (p->pfik_ifp != NULL) 814 TAILQ_FOREACH(i, &p->pfik_ifp->if_groups, ifgl_next) 815 if (!strncmp(i->ifgl_group->ifg_group, filter, IFNAMSIZ)) 816 return (0); /* iface is in group "filter" */ 817 return (1); 818 } 819 820 int 821 pfi_set_flags(const char *name, int flags) 822 { 823 struct pfi_kif *p; 824 size_t n; 825 826 if (name != NULL && name[0] != '\0') { 827 p = pfi_kif_find(name); 828 if (p == NULL) { 829 n = strlen(name); 830 if (n < 1 || n >= IFNAMSIZ) 831 return (EINVAL); 832 833 if (!isalpha(name[0])) 834 return (EINVAL); 835 836 p = pfi_kif_get(name, NULL); 837 if (p != NULL) { 838 p->pfik_flags_new = p->pfik_flags | flags; 839 /* 840 * We use pfik_flagrefs counter as an 841 * indication whether the kif has been created 842 * on behalf of 'pfi_set_flags()' or not. 843 */ 844 KASSERT(p->pfik_flagrefs == 0); 845 if (ISSET(p->pfik_flags_new, PFI_IFLAG_SKIP)) 846 pfi_kif_ref(p, PFI_KIF_REF_FLAG); 847 } else 848 panic("%s pfi_kif_get() returned NULL\n", 849 __func__); 850 } else 851 p->pfik_flags_new = p->pfik_flags | flags; 852 } else { 853 RB_FOREACH(p, pfi_ifhead, &pfi_ifs) 854 p->pfik_flags_new = p->pfik_flags | flags; 855 } 856 857 return (0); 858 } 859 860 int 861 pfi_clear_flags(const char *name, int flags) 862 { 863 struct pfi_kif *p, *w; 864 865 if (name != NULL && name[0] != '\0') { 866 p = pfi_kif_find(name); 867 if (p != NULL) { 868 p->pfik_flags_new = p->pfik_flags & ~flags; 869 870 KASSERT((p->pfik_flagrefs == 0) || 871 (p->pfik_flagrefs == 1)); 872 873 if (!ISSET(p->pfik_flags_new, PFI_IFLAG_SKIP) && 874 (p->pfik_flagrefs == 1)) 875 pfi_kif_unref(p, PFI_KIF_REF_FLAG); 876 } else 877 return (ESRCH); 878 879 } else 880 RB_FOREACH_SAFE(p, pfi_ifhead, &pfi_ifs, w) { 881 p->pfik_flags_new = p->pfik_flags & ~flags; 882 883 KASSERT((p->pfik_flagrefs == 0) || 884 (p->pfik_flagrefs == 1)); 885 886 if (!ISSET(p->pfik_flags_new, PFI_IFLAG_SKIP) && 887 (p->pfik_flagrefs == 1)) 888 pfi_kif_unref(p, PFI_KIF_REF_FLAG); 889 } 890 891 return (0); 892 } 893 894 void 895 pfi_xcommit(void) 896 { 897 struct pfi_kif *p, *gkif; 898 struct ifg_list *g; 899 struct ifnet *ifp; 900 size_t n; 901 902 RB_FOREACH(p, pfi_ifhead, &pfi_ifs) { 903 p->pfik_flags = p->pfik_flags_new; 904 n = strlen(p->pfik_name); 905 ifp = p->pfik_ifp; 906 /* 907 * if kif is backed by existing interface, then we must use 908 * skip flags found in groups. We use pfik_flags_new, otherwise 909 * we would need to do two RB_FOREACH() passes: the first to 910 * commit group changes the second to commit flag changes for 911 * interfaces. 912 */ 913 if (ifp != NULL) 914 TAILQ_FOREACH(g, &ifp->if_groups, ifgl_next) { 915 gkif = 916 (struct pfi_kif *)g->ifgl_group->ifg_pf_kif; 917 KASSERT(gkif != NULL); 918 p->pfik_flags |= gkif->pfik_flags_new; 919 } 920 } 921 } 922 923 /* from pf_print_state.c */ 924 int 925 pfi_unmask(void *addr) 926 { 927 struct pf_addr *m = addr; 928 int i = 31, j = 0, b = 0; 929 u_int32_t tmp; 930 931 while (j < 4 && m->addr32[j] == 0xffffffff) { 932 b += 32; 933 j++; 934 } 935 if (j < 4) { 936 tmp = ntohl(m->addr32[j]); 937 for (i = 31; tmp & (1 << i); --i) 938 b++; 939 } 940 return (b); 941 } 942 943