1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2001 Daniel Hartmeier 5 * Copyright (c) 2002 - 2008 Henning Brauer 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 * $OpenBSD: pf_lb.c,v 1.2 2009/02/12 02:13:15 sthen Exp $ 37 */ 38 39 #include <sys/cdefs.h> 40 #include "opt_pf.h" 41 #include "opt_inet.h" 42 #include "opt_inet6.h" 43 44 #include <sys/param.h> 45 #include <sys/lock.h> 46 #include <sys/mbuf.h> 47 #include <sys/socket.h> 48 #include <sys/sysctl.h> 49 50 #include <crypto/siphash/siphash.h> 51 52 #include <net/if.h> 53 #include <net/if_var.h> 54 #include <net/vnet.h> 55 #include <net/pfvar.h> 56 #include <net/if_pflog.h> 57 58 #ifdef INET 59 #include <netinet/in_var.h> 60 #endif /* INET */ 61 62 #ifdef INET6 63 #include <netinet6/in6_var.h> 64 #endif /* INET6 */ 65 66 67 /* 68 * Limit the amount of work we do to find a free source port for redirects that 69 * introduce a state conflict. 70 */ 71 #define V_pf_rdr_srcport_rewrite_tries VNET(pf_rdr_srcport_rewrite_tries) 72 VNET_DEFINE_STATIC(int, pf_rdr_srcport_rewrite_tries) = 16; 73 74 static uint64_t pf_hash(struct pf_addr *, struct pf_addr *, 75 struct pf_poolhashkey *, sa_family_t); 76 static struct pf_krule *pf_match_translation(int, struct pf_test_ctx *); 77 static enum pf_test_status pf_step_into_translation_anchor(int, struct pf_test_ctx *, 78 struct pf_krule *); 79 static int pf_get_sport(struct pf_pdesc *, struct pf_krule *, 80 struct pf_addr *, uint16_t *, uint16_t, uint16_t, 81 struct pf_kpool *, struct pf_udp_mapping **, 82 pf_sn_types_t); 83 static bool pf_islinklocal(const sa_family_t, const struct pf_addr *); 84 85 static uint64_t 86 pf_hash(struct pf_addr *inaddr, struct pf_addr *hash, 87 struct pf_poolhashkey *key, sa_family_t af) 88 { 89 SIPHASH_CTX ctx; 90 #ifdef INET6 91 union { 92 uint64_t hash64; 93 uint32_t hash32[2]; 94 } h; 95 #endif /* INET6 */ 96 uint64_t res = 0; 97 98 _Static_assert(sizeof(*key) >= SIPHASH_KEY_LENGTH, ""); 99 100 switch (af) { 101 #ifdef INET 102 case AF_INET: 103 res = SipHash24(&ctx, (const uint8_t *)key, 104 &inaddr->addr32[0], sizeof(inaddr->addr32[0])); 105 hash->addr32[0] = res; 106 break; 107 #endif /* INET */ 108 #ifdef INET6 109 case AF_INET6: 110 res = SipHash24(&ctx, (const uint8_t *)key, 111 &inaddr->addr32[0], 4 * sizeof(inaddr->addr32[0])); 112 h.hash64 = res; 113 hash->addr32[0] = h.hash32[0]; 114 hash->addr32[1] = h.hash32[1]; 115 /* 116 * siphash isn't big enough, but flipping it around is 117 * good enough here. 118 */ 119 hash->addr32[2] = ~h.hash32[1]; 120 hash->addr32[3] = ~h.hash32[0]; 121 break; 122 #endif /* INET6 */ 123 default: 124 unhandled_af(af); 125 } 126 return (res); 127 } 128 129 #define PF_TEST_ATTRIB(t, a) \ 130 if (t) { \ 131 r = a; \ 132 continue; \ 133 } else do { \ 134 } while (0) 135 136 static enum pf_test_status 137 pf_match_translation_rule(int rs_num, struct pf_test_ctx *ctx, struct pf_kruleset *ruleset) 138 { 139 struct pf_krule *r; 140 struct pf_pdesc *pd = ctx->pd; 141 int rtableid = -1; 142 143 r = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr); 144 while (r != NULL) { 145 struct pf_rule_addr *src = NULL, *dst = NULL; 146 struct pf_addr_wrap *xdst = NULL; 147 148 if (r->action == PF_BINAT && pd->dir == PF_IN) { 149 src = &r->dst; 150 if (r->rdr.cur != NULL) 151 xdst = &r->rdr.cur->addr; 152 } else { 153 src = &r->src; 154 dst = &r->dst; 155 } 156 157 pf_counter_u64_add(&r->evaluations, 1); 158 PF_TEST_ATTRIB(pfi_kkif_match(r->kif, pd->kif) == r->ifnot, 159 r->skip[PF_SKIP_IFP]); 160 PF_TEST_ATTRIB(r->direction && r->direction != pd->dir, 161 r->skip[PF_SKIP_DIR]); 162 PF_TEST_ATTRIB(r->af && r->af != pd->af, 163 r->skip[PF_SKIP_AF]); 164 PF_TEST_ATTRIB(r->proto && r->proto != pd->proto, 165 r->skip[PF_SKIP_PROTO]); 166 PF_TEST_ATTRIB(PF_MISMATCHAW(&src->addr, &pd->nsaddr, pd->af, 167 src->neg, pd->kif, M_GETFIB(pd->m)), 168 r->skip[src == &r->src ? PF_SKIP_SRC_ADDR : 169 PF_SKIP_DST_ADDR]); 170 PF_TEST_ATTRIB(src->port_op && !pf_match_port(src->port_op, 171 src->port[0], src->port[1], pd->nsport), 172 r->skip[src == &r->src ? PF_SKIP_SRC_PORT : 173 PF_SKIP_DST_PORT]); 174 PF_TEST_ATTRIB(dst != NULL && 175 PF_MISMATCHAW(&dst->addr, &pd->ndaddr, pd->af, dst->neg, NULL, 176 M_GETFIB(pd->m)), 177 r->skip[PF_SKIP_DST_ADDR]); 178 PF_TEST_ATTRIB(xdst != NULL && PF_MISMATCHAW(xdst, &pd->ndaddr, pd->af, 179 0, NULL, M_GETFIB(pd->m)), 180 TAILQ_NEXT(r, entries)); 181 PF_TEST_ATTRIB(dst != NULL && dst->port_op && 182 !pf_match_port(dst->port_op, dst->port[0], 183 dst->port[1], pd->ndport), 184 r->skip[PF_SKIP_DST_PORT]); 185 PF_TEST_ATTRIB(r->match_tag && !pf_match_tag(pd->m, r, &ctx->tag, 186 pd->pf_mtag ? pd->pf_mtag->tag : 0), 187 TAILQ_NEXT(r, entries)); 188 PF_TEST_ATTRIB(r->os_fingerprint != PF_OSFP_ANY && (pd->proto != 189 IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, 190 &pd->hdr.tcp), r->os_fingerprint)), 191 TAILQ_NEXT(r, entries)); 192 if (r->tag) 193 ctx->tag = r->tag; 194 if (r->rtableid >= 0) 195 rtableid = r->rtableid; 196 if (r->anchor == NULL) { 197 if (r->action == PF_NONAT || 198 r->action == PF_NORDR || 199 r->action == PF_NOBINAT) { 200 *ctx->rm = NULL; 201 } else { 202 /* 203 * found matching r 204 */ 205 ctx->tr = r; 206 /* 207 * anchor, with ruleset, where r belongs to 208 */ 209 *ctx->am = ctx->a; 210 /* 211 * ruleset where r belongs to 212 */ 213 *ctx->rsm = ruleset; 214 /* 215 * ruleset, where anchor belongs to. 216 */ 217 ctx->arsm = ctx->aruleset; 218 } 219 break; 220 } else { 221 ctx->a = r; /* remember anchor */ 222 ctx->aruleset = ruleset; /* and its ruleset */ 223 if (pf_step_into_translation_anchor(rs_num, ctx, 224 r) != PF_TEST_OK) { 225 break; 226 } 227 } 228 r = TAILQ_NEXT(r, entries); 229 } 230 231 if (ctx->tag > 0 && pf_tag_packet(pd, ctx->tag)) 232 return (PF_TEST_FAIL); 233 if (rtableid >= 0) 234 M_SETFIB(pd->m, rtableid); 235 236 return (PF_TEST_OK); 237 } 238 239 static enum pf_test_status 240 pf_step_into_translation_anchor(int rs_num, struct pf_test_ctx *ctx, struct pf_krule *r) 241 { 242 enum pf_test_status rv; 243 244 PF_RULES_RASSERT(); 245 246 if (ctx->depth >= PF_ANCHOR_STACK_MAX) { 247 printf("%s: anchor stack overflow on %s\n", 248 __func__, r->anchor->name); 249 return (PF_TEST_FAIL); 250 } 251 252 ctx->depth++; 253 254 if (r->anchor_wildcard) { 255 struct pf_kanchor *child; 256 rv = PF_TEST_OK; 257 RB_FOREACH(child, pf_kanchor_node, &r->anchor->children) { 258 rv = pf_match_translation_rule(rs_num, ctx, &child->ruleset); 259 if ((rv == PF_TEST_QUICK) || (rv == PF_TEST_FAIL)) { 260 /* 261 * we either hit a rule qith quick action 262 * (more likely), or hit some runtime 263 * error (e.g. pool_get() faillure). 264 */ 265 break; 266 } 267 } 268 } else { 269 rv = pf_match_translation_rule(rs_num, ctx, &r->anchor->ruleset); 270 } 271 272 ctx->depth--; 273 274 return (rv); 275 } 276 277 static struct pf_krule * 278 pf_match_translation(int rs_num, struct pf_test_ctx *ctx) 279 { 280 enum pf_test_status rv; 281 282 MPASS(ctx->depth == 0); 283 rv = pf_match_translation_rule(rs_num, ctx, &pf_main_ruleset); 284 MPASS(ctx->depth == 0); 285 if (rv != PF_TEST_OK) 286 return (NULL); 287 288 return (ctx->tr); 289 } 290 291 static int 292 pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r, struct pf_addr *naddr, 293 uint16_t *nport, uint16_t low, uint16_t high, struct pf_kpool *rpool, 294 struct pf_udp_mapping **udp_mapping, pf_sn_types_t sn_type) 295 { 296 struct pf_state_key_cmp key; 297 struct pf_addr init_addr; 298 int dir = (pd->dir == PF_IN) ? PF_OUT : PF_IN; 299 int sidx = pd->sidx; 300 int didx = pd->didx; 301 302 bzero(&init_addr, sizeof(init_addr)); 303 304 if (udp_mapping) { 305 MPASS(*udp_mapping == NULL); 306 } 307 308 /* 309 * If we are UDP and have an existing mapping we can get source port 310 * from the mapping. In this case we have to look up the src_node as 311 * pf_map_addr would. 312 */ 313 if (pd->proto == IPPROTO_UDP && (rpool->opts & PF_POOL_ENDPI)) { 314 struct pf_udp_endpoint_cmp udp_source; 315 316 bzero(&udp_source, sizeof(udp_source)); 317 udp_source.af = pd->af; 318 pf_addrcpy(&udp_source.addr, &pd->nsaddr, pd->af); 319 udp_source.port = pd->nsport; 320 if (udp_mapping) { 321 struct pf_ksrc_node *sn = NULL; 322 struct pf_srchash *sh = NULL; 323 *udp_mapping = pf_udp_mapping_find(&udp_source); 324 if (*udp_mapping) { 325 pf_addrcpy(naddr, 326 &(*udp_mapping)->endpoints[1].addr, 327 pd->af); 328 *nport = (*udp_mapping)->endpoints[1].port; 329 /* 330 * Try to find a src_node as per pf_map_addr(). 331 * XXX: Why? This code seems to do nothing. 332 */ 333 if (rpool->opts & PF_POOL_STICKYADDR && 334 (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) 335 sn = pf_find_src_node(&pd->nsaddr, r, 336 pd->af, &sh, sn_type, false); 337 if (sn != NULL) 338 PF_SRC_NODE_UNLOCK(sn); 339 return (0); 340 } else { 341 *udp_mapping = pf_udp_mapping_create(pd->af, &pd->nsaddr, 342 pd->nsport, &init_addr, 0); 343 if (*udp_mapping == NULL) 344 return (1); 345 } 346 } 347 } 348 349 if (pf_map_addr_sn(pd->naf, r, &pd->nsaddr, naddr, &(pd->naf), NULL, 350 &init_addr, rpool, sn_type)) 351 goto failed; 352 353 if (pd->proto == IPPROTO_ICMP) { 354 if (pd->ndport == htons(ICMP_ECHO)) { 355 low = 1; 356 high = 65535; 357 } else 358 return (0); /* Don't try to modify non-echo ICMP */ 359 } 360 #ifdef INET6 361 if (pd->proto == IPPROTO_ICMPV6) { 362 if (pd->ndport == htons(ICMP6_ECHO_REQUEST)) { 363 low = 1; 364 high = 65535; 365 } else 366 return (0); /* Don't try to modify non-echo ICMP */ 367 } 368 #endif /* INET6 */ 369 370 bzero(&key, sizeof(key)); 371 key.af = pd->naf; 372 key.proto = pd->proto; 373 374 do { 375 pf_addrcpy(&key.addr[didx], &pd->ndaddr, key.af); 376 pf_addrcpy(&key.addr[sidx], naddr, key.af); 377 key.port[didx] = pd->ndport; 378 379 if (udp_mapping && *udp_mapping) 380 pf_addrcpy(&(*udp_mapping)->endpoints[1].addr, naddr, 381 pd->af); 382 383 /* 384 * port search; start random, step; 385 * similar 2 portloop in in_pcbbind 386 */ 387 if (pd->proto == IPPROTO_SCTP) { 388 key.port[sidx] = pd->nsport; 389 if (!pf_find_state_all_exists(&key, dir)) { 390 *nport = pd->nsport; 391 return (0); 392 } else { 393 return (1); /* Fail mapping. */ 394 } 395 } else if (!(pd->proto == IPPROTO_TCP || pd->proto == IPPROTO_UDP || 396 pd->proto == IPPROTO_ICMP) || (low == 0 && high == 0)) { 397 /* 398 * XXX bug: icmp states don't use the id on both sides. 399 * (traceroute -I through nat) 400 */ 401 key.port[sidx] = pd->nsport; 402 if (!pf_find_state_all_exists(&key, dir)) { 403 *nport = pd->nsport; 404 return (0); 405 } 406 } else if (low == high) { 407 key.port[sidx] = htons(low); 408 if (!pf_find_state_all_exists(&key, dir)) { 409 if (udp_mapping && *udp_mapping != NULL) { 410 (*udp_mapping)->endpoints[1].port = htons(low); 411 if (pf_udp_mapping_insert(*udp_mapping) == 0) { 412 *nport = htons(low); 413 return (0); 414 } 415 } else { 416 *nport = htons(low); 417 return (0); 418 } 419 } 420 } else { 421 uint32_t tmp; 422 uint16_t cut; 423 424 if (low > high) { 425 tmp = low; 426 low = high; 427 high = tmp; 428 } 429 /* low < high */ 430 cut = arc4random() % (1 + high - low) + low; 431 /* low <= cut <= high */ 432 for (tmp = cut; tmp <= high && tmp <= 0xffff; ++tmp) { 433 if (udp_mapping && *udp_mapping != NULL) { 434 (*udp_mapping)->endpoints[sidx].port = htons(tmp); 435 if (pf_udp_mapping_insert(*udp_mapping) == 0) { 436 *nport = htons(tmp); 437 return (0); 438 } 439 } else { 440 key.port[sidx] = htons(tmp); 441 if (!pf_find_state_all_exists(&key, dir)) { 442 *nport = htons(tmp); 443 return (0); 444 } 445 } 446 } 447 tmp = cut; 448 for (tmp -= 1; tmp >= low && tmp <= 0xffff; --tmp) { 449 if (pd->proto == IPPROTO_UDP && 450 (rpool->opts & PF_POOL_ENDPI && 451 udp_mapping != NULL)) { 452 (*udp_mapping)->endpoints[1].port = htons(tmp); 453 if (pf_udp_mapping_insert(*udp_mapping) == 0) { 454 *nport = htons(tmp); 455 return (0); 456 } 457 } else { 458 key.port[sidx] = htons(tmp); 459 if (!pf_find_state_all_exists(&key, dir)) { 460 *nport = htons(tmp); 461 return (0); 462 } 463 } 464 } 465 } 466 467 switch (rpool->opts & PF_POOL_TYPEMASK) { 468 case PF_POOL_RANDOM: 469 case PF_POOL_ROUNDROBIN: 470 /* 471 * pick a different source address since we're out 472 * of free port choices for the current one. 473 */ 474 if (pf_map_addr_sn(pd->naf, r, &pd->nsaddr, naddr, 475 &(pd->naf), NULL, &init_addr, rpool, sn_type)) 476 return (1); 477 break; 478 case PF_POOL_NONE: 479 case PF_POOL_SRCHASH: 480 case PF_POOL_BITMASK: 481 default: 482 return (1); 483 } 484 } while (! PF_AEQ(&init_addr, naddr, pd->naf) ); 485 486 failed: 487 if (udp_mapping) { 488 uma_zfree(V_pf_udp_mapping_z, *udp_mapping); 489 *udp_mapping = NULL; 490 } 491 492 return (1); /* none available */ 493 } 494 495 static bool 496 pf_islinklocal(const sa_family_t af, const struct pf_addr *addr) 497 { 498 if (af == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&addr->v6)) 499 return (true); 500 return (false); 501 } 502 503 static int 504 pf_get_mape_sport(struct pf_pdesc *pd, struct pf_krule *r, 505 struct pf_addr *naddr, uint16_t *nport, struct pf_udp_mapping **udp_mapping, 506 struct pf_kpool *rpool) 507 { 508 uint16_t psmask, low, highmask; 509 uint16_t i, ahigh, cut; 510 int ashift, psidshift; 511 512 ashift = 16 - rpool->mape.offset; 513 psidshift = ashift - rpool->mape.psidlen; 514 psmask = rpool->mape.psid & ((1U << rpool->mape.psidlen) - 1); 515 psmask = psmask << psidshift; 516 highmask = (1U << psidshift) - 1; 517 518 ahigh = (1U << rpool->mape.offset) - 1; 519 cut = arc4random() & ahigh; 520 if (cut == 0) 521 cut = 1; 522 523 for (i = cut; i <= ahigh; i++) { 524 low = (i << ashift) | psmask; 525 if (!pf_get_sport(pd, r, naddr, nport, low, low | highmask, 526 rpool, udp_mapping, PF_SN_NAT)) 527 return (0); 528 } 529 for (i = cut - 1; i > 0; i--) { 530 low = (i << ashift) | psmask; 531 if (!pf_get_sport(pd, r, naddr, nport, low, low | highmask, 532 rpool, udp_mapping, PF_SN_NAT)) 533 return (0); 534 } 535 return (1); 536 } 537 538 u_short 539 pf_map_addr(sa_family_t saf, struct pf_krule *r, struct pf_addr *saddr, 540 struct pf_addr *naddr, struct pfi_kkif **nkif, sa_family_t *naf, 541 struct pf_addr *init_addr, struct pf_kpool *rpool) 542 { 543 u_short reason = PFRES_MATCH; 544 struct pf_addr *raddr = NULL, *rmask = NULL; 545 struct pfr_ktable *kt; 546 uint64_t hashidx; 547 int cnt; 548 sa_family_t wanted_af; 549 u_int8_t pool_type; 550 bool prefer_ipv6_nexthop = rpool->opts & PF_POOL_IPV6NH; 551 552 KASSERT(saf != 0, ("%s: saf == 0", __func__)); 553 KASSERT(naf != NULL, ("%s: naf = NULL", __func__)); 554 KASSERT((*naf) != 0, ("%s: *naf = 0", __func__)); 555 556 /* 557 * Given (*naf) is a hint about AF of the forwarded packet. 558 * It might be changed if prefer_ipv6_nexthop is enabled and 559 * the combination of nexthop AF and packet AF allows for it. 560 */ 561 wanted_af = (*naf); 562 563 mtx_lock(&rpool->mtx); 564 /* Find the route using chosen algorithm. Store the found route 565 in src_node if it was given or found. */ 566 if (rpool->cur->addr.type == PF_ADDR_NOROUTE) { 567 reason = PFRES_MAPFAILED; 568 goto done_pool_mtx; 569 } 570 if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 571 switch (wanted_af) { 572 #ifdef INET 573 case AF_INET: 574 if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 && 575 !PF_POOL_DYNTYPE(rpool->opts)) { 576 reason = PFRES_MAPFAILED; 577 goto done_pool_mtx; 578 } 579 raddr = &rpool->cur->addr.p.dyn->pfid_addr4; 580 rmask = &rpool->cur->addr.p.dyn->pfid_mask4; 581 break; 582 #endif /* INET */ 583 #ifdef INET6 584 case AF_INET6: 585 if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 && 586 !PF_POOL_DYNTYPE(rpool->opts)) { 587 reason = PFRES_MAPFAILED; 588 goto done_pool_mtx; 589 } 590 raddr = &rpool->cur->addr.p.dyn->pfid_addr6; 591 rmask = &rpool->cur->addr.p.dyn->pfid_mask6; 592 break; 593 #endif /* INET6 */ 594 default: 595 unhandled_af(wanted_af); 596 } 597 } else if (rpool->cur->addr.type == PF_ADDR_TABLE) { 598 if (!PF_POOL_DYNTYPE(rpool->opts)) { 599 reason = PFRES_MAPFAILED; 600 goto done_pool_mtx; /* unsupported */ 601 } 602 } else { 603 raddr = &rpool->cur->addr.v.a.addr; 604 rmask = &rpool->cur->addr.v.a.mask; 605 } 606 607 /* 608 * For pools with a single host with the prefer-ipv6-nexthop option 609 * we can return pool address of any AF, unless the forwarded packet 610 * is IPv6, then we can return only if pool address is IPv6. 611 * For non-prefer-ipv6-nexthop we can return pool address only 612 * of wanted AF, unless the pool address'es AF is unknown, which 613 * happens in case old ioctls have been used to set up the pool. 614 * 615 * Round-robin pools have their own logic for retrying next addresses. 616 */ 617 pool_type = rpool->opts & PF_POOL_TYPEMASK; 618 if (pool_type == PF_POOL_NONE || pool_type == PF_POOL_BITMASK || 619 ((pool_type == PF_POOL_RANDOM || pool_type == PF_POOL_SRCHASH) && 620 rpool->cur->addr.type != PF_ADDR_TABLE && 621 rpool->cur->addr.type != PF_ADDR_DYNIFTL)) { 622 if (prefer_ipv6_nexthop) { 623 if (rpool->cur->af == AF_INET && (*naf) == AF_INET6) { 624 reason = PFRES_MAPFAILED; 625 goto done_pool_mtx; 626 } 627 wanted_af = rpool->cur->af; 628 } else { 629 if (rpool->cur->af != 0 && rpool->cur->af != (*naf)) { 630 reason = PFRES_MAPFAILED; 631 goto done_pool_mtx; 632 } 633 } 634 } 635 636 switch (pool_type) { 637 case PF_POOL_NONE: 638 pf_addrcpy(naddr, raddr, wanted_af); 639 break; 640 case PF_POOL_BITMASK: 641 pf_poolmask(naddr, raddr, rmask, saddr, wanted_af); 642 break; 643 case PF_POOL_RANDOM: 644 if (rpool->cur->addr.type == PF_ADDR_TABLE || 645 rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 646 if (rpool->cur->addr.type == PF_ADDR_TABLE) 647 kt = rpool->cur->addr.p.tbl; 648 else 649 kt = rpool->cur->addr.p.dyn->pfid_kt; 650 kt = pfr_ktable_select_active(kt); 651 if (kt == NULL) { 652 reason = PFRES_MAPFAILED; 653 goto done_pool_mtx; /* unsupported */ 654 } 655 cnt = kt->pfrkt_cnt; 656 if (cnt == 0) 657 rpool->tblidx = 0; 658 else 659 rpool->tblidx = (int)arc4random_uniform(cnt); 660 memset(&rpool->counter, 0, sizeof(rpool->counter)); 661 if (prefer_ipv6_nexthop) 662 wanted_af = AF_INET6; 663 retry_other_af_random: 664 if (pfr_pool_get(kt, &rpool->tblidx, &rpool->counter, 665 wanted_af, pf_islinklocal, false)) { 666 /* Retry with IPv4 nexthop for IPv4 traffic */ 667 if (prefer_ipv6_nexthop && 668 wanted_af == AF_INET6 && 669 (*naf) == AF_INET) { 670 wanted_af = AF_INET; 671 goto retry_other_af_random; 672 } else { 673 /* no hosts in wanted AF */ 674 reason = PFRES_MAPFAILED; 675 goto done_pool_mtx; 676 } 677 } 678 pf_addrcpy(naddr, &rpool->counter, wanted_af); 679 } else if (init_addr != NULL && PF_AZERO(init_addr, 680 wanted_af)) { 681 switch (wanted_af) { 682 #ifdef INET 683 case AF_INET: 684 rpool->counter.addr32[0] = arc4random(); 685 break; 686 #endif /* INET */ 687 #ifdef INET6 688 case AF_INET6: 689 if (rmask->addr32[3] != 0xffffffff) 690 rpool->counter.addr32[3] = 691 arc4random(); 692 else 693 break; 694 if (rmask->addr32[2] != 0xffffffff) 695 rpool->counter.addr32[2] = 696 arc4random(); 697 else 698 break; 699 if (rmask->addr32[1] != 0xffffffff) 700 rpool->counter.addr32[1] = 701 arc4random(); 702 else 703 break; 704 if (rmask->addr32[0] != 0xffffffff) 705 rpool->counter.addr32[0] = 706 arc4random(); 707 break; 708 #endif /* INET6 */ 709 } 710 pf_poolmask(naddr, raddr, rmask, &rpool->counter, 711 wanted_af); 712 pf_addrcpy(init_addr, naddr, wanted_af); 713 714 } else { 715 pf_addr_inc(&rpool->counter, wanted_af); 716 pf_poolmask(naddr, raddr, rmask, &rpool->counter, 717 wanted_af); 718 } 719 break; 720 case PF_POOL_SRCHASH: 721 { 722 unsigned char hash[16]; 723 724 hashidx = 725 pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, 726 wanted_af); 727 if (rpool->cur->addr.type == PF_ADDR_TABLE || 728 rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 729 if (rpool->cur->addr.type == PF_ADDR_TABLE) 730 kt = rpool->cur->addr.p.tbl; 731 else 732 kt = rpool->cur->addr.p.dyn->pfid_kt; 733 kt = pfr_ktable_select_active(kt); 734 if (kt == NULL) { 735 reason = PFRES_MAPFAILED; 736 goto done_pool_mtx; /* unsupported */ 737 } 738 cnt = kt->pfrkt_cnt; 739 if (cnt == 0) 740 rpool->tblidx = 0; 741 else 742 rpool->tblidx = (int)(hashidx % cnt); 743 memset(&rpool->counter, 0, sizeof(rpool->counter)); 744 if (prefer_ipv6_nexthop) 745 wanted_af = AF_INET6; 746 retry_other_af_srchash: 747 if (pfr_pool_get(kt, &rpool->tblidx, &rpool->counter, 748 wanted_af, pf_islinklocal, false)) { 749 /* Retry with IPv4 nexthop for IPv4 traffic */ 750 if (prefer_ipv6_nexthop && 751 wanted_af == AF_INET6 && 752 (*naf) == AF_INET) { 753 wanted_af = AF_INET; 754 goto retry_other_af_srchash; 755 } else { 756 /* no hosts in wanted AF */ 757 reason = PFRES_MAPFAILED; 758 goto done_pool_mtx; 759 } 760 } 761 pf_addrcpy(naddr, &rpool->counter, wanted_af); 762 } else { 763 pf_poolmask(naddr, raddr, rmask, 764 (struct pf_addr *)&hash, wanted_af); 765 } 766 break; 767 } 768 case PF_POOL_ROUNDROBIN: 769 { 770 struct pf_kpooladdr *acur = rpool->cur; 771 772 retry_other_af_rr: 773 if (prefer_ipv6_nexthop) 774 wanted_af = rpool->ipv6_nexthop_af; 775 if (rpool->cur->addr.type == PF_ADDR_TABLE) { 776 if (!pfr_pool_get(rpool->cur->addr.p.tbl, 777 &rpool->tblidx, &rpool->counter, wanted_af, 778 NULL, true)) 779 goto get_addr; 780 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 781 if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt, 782 &rpool->tblidx, &rpool->counter, wanted_af, 783 pf_islinklocal, true)) 784 goto get_addr; 785 } else if (rpool->cur->af == wanted_af && 786 pf_match_addr(0, raddr, rmask, &rpool->counter, wanted_af)) 787 goto get_addr; 788 if (prefer_ipv6_nexthop && 789 (*naf) == AF_INET && wanted_af == AF_INET6) { 790 /* Reset table index when changing wanted AF. */ 791 rpool->tblidx = -1; 792 rpool->ipv6_nexthop_af = AF_INET; 793 goto retry_other_af_rr; 794 } 795 try_next: 796 /* Reset prefer-ipv6-nexthop search to IPv6 when iterating pools. */ 797 rpool->ipv6_nexthop_af = AF_INET6; 798 if (TAILQ_NEXT(rpool->cur, entries) == NULL) 799 rpool->cur = TAILQ_FIRST(&rpool->list); 800 else 801 rpool->cur = TAILQ_NEXT(rpool->cur, entries); 802 try_next_ipv6_nexthop_rr: 803 /* Reset table index when iterating pools or changing wanted AF. */ 804 rpool->tblidx = -1; 805 if (prefer_ipv6_nexthop) 806 wanted_af = rpool->ipv6_nexthop_af; 807 if (rpool->cur->addr.type == PF_ADDR_TABLE) { 808 if (!pfr_pool_get(rpool->cur->addr.p.tbl, 809 &rpool->tblidx, &rpool->counter, wanted_af, NULL, 810 true)) 811 goto get_addr; 812 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 813 if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt, 814 &rpool->tblidx, &rpool->counter, wanted_af, pf_islinklocal, 815 true)) 816 goto get_addr; 817 } else { 818 if (rpool->cur->af == wanted_af) { 819 raddr = &rpool->cur->addr.v.a.addr; 820 rmask = &rpool->cur->addr.v.a.mask; 821 pf_addrcpy(&rpool->counter, raddr, wanted_af); 822 goto get_addr; 823 } 824 } 825 if (prefer_ipv6_nexthop && 826 (*naf) == AF_INET && wanted_af == AF_INET6) { 827 rpool->ipv6_nexthop_af = AF_INET; 828 goto try_next_ipv6_nexthop_rr; 829 } 830 if (rpool->cur != acur) 831 goto try_next; 832 reason = PFRES_MAPFAILED; 833 goto done_pool_mtx; 834 get_addr: 835 pf_addrcpy(naddr, &rpool->counter, wanted_af); 836 if (init_addr != NULL && PF_AZERO(init_addr, wanted_af)) 837 pf_addrcpy(init_addr, naddr, wanted_af); 838 pf_addr_inc(&rpool->counter, wanted_af); 839 break; 840 } 841 } 842 843 if (wanted_af == 0) { 844 reason = PFRES_MAPFAILED; 845 goto done_pool_mtx; 846 } 847 848 if (nkif) 849 *nkif = rpool->cur->kif; 850 851 (*naf) = wanted_af; 852 853 done_pool_mtx: 854 mtx_unlock(&rpool->mtx); 855 856 return (reason); 857 } 858 859 u_short 860 pf_map_addr_sn(sa_family_t saf, struct pf_krule *r, struct pf_addr *saddr, 861 struct pf_addr *naddr, sa_family_t *naf, struct pfi_kkif **nkif, 862 struct pf_addr *init_addr, struct pf_kpool *rpool, pf_sn_types_t sn_type) 863 { 864 struct pf_ksrc_node *sn = NULL; 865 struct pf_srchash *sh = NULL; 866 u_short reason = 0; 867 868 /* 869 * If this is a sticky-address rule, try to find an existing src_node. 870 */ 871 if (rpool->opts & PF_POOL_STICKYADDR && 872 (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) 873 sn = pf_find_src_node(saddr, r, saf, &sh, sn_type, false); 874 875 if (sn != NULL) { 876 PF_SRC_NODE_LOCK_ASSERT(sn); 877 (*naf) = sn->raf; 878 879 /* If the supplied address is the same as the current one we've 880 * been asked before, so tell the caller that there's no other 881 * address to be had. */ 882 883 if (PF_AEQ(naddr, &(sn->raddr), *naf)) { 884 printf("%s: no more addresses\n", __func__); 885 reason = PFRES_MAPFAILED; 886 goto done; 887 } 888 889 pf_addrcpy(naddr, &(sn->raddr), *naf); 890 891 if (nkif) 892 *nkif = sn->rkif; 893 if (V_pf_status.debug >= PF_DEBUG_NOISY) { 894 printf("%s: src tracking maps ", __func__); 895 pf_print_host(saddr, 0, saf); 896 printf(" to "); 897 pf_print_host(naddr, 0, *naf); 898 if (nkif) 899 printf("@%s", (*nkif)->pfik_name); 900 printf("\n"); 901 } 902 goto done; 903 } 904 905 /* 906 * Source node has not been found. Find a new address and store it 907 * in variables given by the caller. 908 */ 909 if ((reason = pf_map_addr(saf, r, saddr, naddr, nkif, naf, init_addr, 910 rpool)) != 0) { 911 if (V_pf_status.debug >= PF_DEBUG_MISC) 912 printf("%s: pf_map_addr has failed\n", __func__); 913 goto done; 914 } 915 916 if (V_pf_status.debug >= PF_DEBUG_NOISY && 917 (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) { 918 printf("%s: selected address ", __func__); 919 pf_print_host(naddr, 0, *naf); 920 if (nkif) 921 printf("@%s", (*nkif)->pfik_name); 922 printf("\n"); 923 } 924 925 done: 926 if (sn != NULL) 927 PF_SRC_NODE_UNLOCK(sn); 928 929 return (reason); 930 } 931 932 u_short 933 pf_get_translation(struct pf_test_ctx *ctx) 934 { 935 struct pf_krule *r = NULL; 936 u_short transerror; 937 938 PF_RULES_RASSERT(); 939 KASSERT(ctx->sk == NULL, ("*skp not NULL")); 940 KASSERT(ctx->nk == NULL, ("*nkp not NULL")); 941 942 ctx->nr = NULL; 943 944 if (ctx->pd->dir == PF_OUT) { 945 r = pf_match_translation(PF_RULESET_BINAT, ctx); 946 if (r == NULL) 947 r = pf_match_translation(PF_RULESET_NAT, ctx); 948 } else { 949 r = pf_match_translation(PF_RULESET_RDR, ctx); 950 if (r == NULL) 951 r = pf_match_translation(PF_RULESET_BINAT, ctx); 952 } 953 954 if (r == NULL) 955 return (PFRES_MAX); 956 957 switch (r->action) { 958 case PF_NONAT: 959 case PF_NOBINAT: 960 case PF_NORDR: 961 return (PFRES_MAX); 962 } 963 964 transerror = pf_get_transaddr(ctx, r, r->action, &(r->rdr)); 965 if (transerror == PFRES_MATCH) 966 ctx->nr = r; 967 968 return (transerror); 969 } 970 971 u_short 972 pf_get_transaddr(struct pf_test_ctx *ctx, struct pf_krule *r, 973 uint8_t nat_action, struct pf_kpool *rpool) 974 { 975 struct pf_pdesc *pd = ctx->pd; 976 struct pf_addr *naddr; 977 uint16_t *nportp; 978 uint16_t low, high; 979 u_short reason; 980 981 PF_RULES_RASSERT(); 982 KASSERT(r != NULL, ("r is NULL")); 983 KASSERT(!(r->rule_flag & PFRULE_AFTO), ("AFTO rule")); 984 985 if (ctx->sk == NULL && ctx->nk == NULL) { 986 if (pf_state_key_setup(pd, pd->nsport, pd->ndport, &ctx->sk, 987 &ctx->nk)) 988 return (PFRES_MEMORY); 989 } 990 991 naddr = &ctx->nk->addr[1]; 992 nportp = &ctx->nk->port[1]; 993 994 switch (nat_action) { 995 case PF_NAT: 996 if (pd->proto == IPPROTO_ICMP) { 997 low = 1; 998 high = 65535; 999 } else { 1000 low = rpool->proxy_port[0]; 1001 high = rpool->proxy_port[1]; 1002 } 1003 if (rpool->mape.offset > 0) { 1004 if (pf_get_mape_sport(pd, r, naddr, nportp, 1005 &ctx->udp_mapping, rpool)) { 1006 DPFPRINTF(PF_DEBUG_MISC, 1007 "pf: MAP-E port allocation (%u/%u/%u)" 1008 " failed", 1009 rpool->mape.offset, 1010 rpool->mape.psidlen, 1011 rpool->mape.psid); 1012 reason = PFRES_MAPFAILED; 1013 goto notrans; 1014 } 1015 } else if (pf_get_sport(pd, r, naddr, nportp, low, high, 1016 rpool, &ctx->udp_mapping, PF_SN_NAT)) { 1017 DPFPRINTF(PF_DEBUG_MISC, 1018 "pf: NAT proxy port allocation (%u-%u) failed", 1019 rpool->proxy_port[0], rpool->proxy_port[1]); 1020 reason = PFRES_MAPFAILED; 1021 goto notrans; 1022 } 1023 break; 1024 case PF_BINAT: 1025 switch (pd->dir) { 1026 case PF_OUT: 1027 if (rpool->cur->addr.type == PF_ADDR_DYNIFTL){ 1028 switch (pd->af) { 1029 #ifdef INET 1030 case AF_INET: 1031 if (rpool->cur->addr.p.dyn-> 1032 pfid_acnt4 < 1) { 1033 reason = PFRES_MAPFAILED; 1034 goto notrans; 1035 } 1036 pf_poolmask(naddr, 1037 &rpool->cur->addr.p.dyn->pfid_addr4, 1038 &rpool->cur->addr.p.dyn->pfid_mask4, 1039 &pd->nsaddr, AF_INET); 1040 break; 1041 #endif /* INET */ 1042 #ifdef INET6 1043 case AF_INET6: 1044 if (rpool->cur->addr.p.dyn-> 1045 pfid_acnt6 < 1) { 1046 reason = PFRES_MAPFAILED; 1047 goto notrans; 1048 } 1049 pf_poolmask(naddr, 1050 &rpool->cur->addr.p.dyn->pfid_addr6, 1051 &rpool->cur->addr.p.dyn->pfid_mask6, 1052 &pd->nsaddr, AF_INET6); 1053 break; 1054 #endif /* INET6 */ 1055 } 1056 } else 1057 pf_poolmask(naddr, 1058 &rpool->cur->addr.v.a.addr, 1059 &rpool->cur->addr.v.a.mask, &pd->nsaddr, 1060 pd->af); 1061 break; 1062 case PF_IN: 1063 if (r->src.addr.type == PF_ADDR_DYNIFTL) { 1064 switch (pd->af) { 1065 #ifdef INET 1066 case AF_INET: 1067 if (r->src.addr.p.dyn->pfid_acnt4 < 1) { 1068 reason = PFRES_MAPFAILED; 1069 goto notrans; 1070 } 1071 pf_poolmask(naddr, 1072 &r->src.addr.p.dyn->pfid_addr4, 1073 &r->src.addr.p.dyn->pfid_mask4, 1074 &pd->ndaddr, AF_INET); 1075 break; 1076 #endif /* INET */ 1077 #ifdef INET6 1078 case AF_INET6: 1079 if (r->src.addr.p.dyn->pfid_acnt6 < 1) { 1080 reason = PFRES_MAPFAILED; 1081 goto notrans; 1082 } 1083 pf_poolmask(naddr, 1084 &r->src.addr.p.dyn->pfid_addr6, 1085 &r->src.addr.p.dyn->pfid_mask6, 1086 &pd->ndaddr, AF_INET6); 1087 break; 1088 #endif /* INET6 */ 1089 } 1090 } else 1091 pf_poolmask(naddr, &r->src.addr.v.a.addr, 1092 &r->src.addr.v.a.mask, &pd->ndaddr, pd->af); 1093 break; 1094 } 1095 break; 1096 case PF_RDR: { 1097 struct pf_state_key_cmp key; 1098 int tries; 1099 uint16_t cut, low, high, nport; 1100 1101 reason = pf_map_addr_sn(pd->af, r, &pd->nsaddr, naddr, 1102 &(pd->naf), NULL, NULL, rpool, PF_SN_NAT); 1103 1104 if (reason != 0) 1105 goto notrans; 1106 if ((rpool->opts & PF_POOL_TYPEMASK) == PF_POOL_BITMASK) 1107 pf_poolmask(naddr, naddr, &rpool->cur->addr.v.a.mask, 1108 &pd->ndaddr, pd->af); 1109 1110 /* Do not change SCTP ports. */ 1111 if (pd->proto == IPPROTO_SCTP) 1112 break; 1113 1114 if (rpool->proxy_port[1]) { 1115 uint32_t tmp_nport; 1116 uint16_t div; 1117 1118 div = r->rdr.proxy_port[1] - r->rdr.proxy_port[0] + 1; 1119 div = (div == 0) ? 1 : div; 1120 1121 tmp_nport = ((ntohs(pd->ndport) - ntohs(r->dst.port[0])) % div) + 1122 rpool->proxy_port[0]; 1123 1124 /* Wrap around if necessary. */ 1125 if (tmp_nport > 65535) 1126 tmp_nport -= 65535; 1127 nport = htons((uint16_t)tmp_nport); 1128 } else if (rpool->proxy_port[0]) 1129 nport = htons(rpool->proxy_port[0]); 1130 else 1131 nport = pd->ndport; 1132 1133 /* 1134 * Update the destination port. 1135 */ 1136 *nportp = nport; 1137 1138 /* 1139 * Do we have a source port conflict in the stack state? Try to 1140 * modulate the source port if so. Note that this is racy since 1141 * the state lookup may not find any matches here but will once 1142 * pf_create_state() actually instantiates the state. 1143 */ 1144 bzero(&key, sizeof(key)); 1145 key.af = pd->af; 1146 key.proto = pd->proto; 1147 key.port[0] = pd->nsport; 1148 pf_addrcpy(&key.addr[0], &pd->nsaddr, key.af); 1149 key.port[1] = nport; 1150 pf_addrcpy(&key.addr[1], naddr, key.af); 1151 1152 if (!pf_find_state_all_exists(&key, PF_OUT)) 1153 break; 1154 1155 tries = 0; 1156 1157 low = 50001; /* XXX-MJ PF_NAT_PROXY_PORT_LOW/HIGH */ 1158 high = 65535; 1159 cut = arc4random() % (1 + high - low) + low; 1160 for (uint32_t tmp = cut; 1161 tmp <= high && tmp <= UINT16_MAX && 1162 tries < V_pf_rdr_srcport_rewrite_tries; 1163 tmp++, tries++) { 1164 key.port[0] = htons(tmp); 1165 if (!pf_find_state_all_exists(&key, PF_OUT)) { 1166 /* Update the source port. */ 1167 ctx->nk->port[0] = htons(tmp); 1168 goto out; 1169 } 1170 } 1171 for (uint32_t tmp = cut - 1; 1172 tmp >= low && tries < V_pf_rdr_srcport_rewrite_tries; 1173 tmp--, tries++) { 1174 key.port[0] = htons(tmp); 1175 if (!pf_find_state_all_exists(&key, PF_OUT)) { 1176 /* Update the source port. */ 1177 ctx->nk->port[0] = htons(tmp); 1178 goto out; 1179 } 1180 } 1181 1182 /* 1183 * We failed to find a match. Push on ahead anyway, let 1184 * pf_state_insert() be the arbiter of whether the state 1185 * conflict is tolerable. In particular, with TCP connections 1186 * the state may be reused if the TCP state is terminal. 1187 */ 1188 DPFPRINTF(PF_DEBUG_MISC, 1189 "pf: RDR source port allocation failed"); 1190 break; 1191 1192 out: 1193 DPFPRINTF(PF_DEBUG_MISC, 1194 "pf: RDR source port allocation %u->%u", 1195 ntohs(pd->nsport), ntohs(ctx->nk->port[0])); 1196 break; 1197 } 1198 default: 1199 panic("%s: unknown action %u", __func__, r->action); 1200 } 1201 1202 /* Return success only if translation really happened. */ 1203 if (bcmp(ctx->sk, ctx->nk, sizeof(struct pf_state_key_cmp))) { 1204 return (PFRES_MATCH); 1205 } 1206 1207 reason = PFRES_MAX; 1208 notrans: 1209 uma_zfree(V_pf_state_key_z, ctx->nk); 1210 uma_zfree(V_pf_state_key_z, ctx->sk); 1211 ctx->sk = ctx->nk = NULL; 1212 1213 return (reason); 1214 } 1215 1216 int 1217 pf_get_transaddr_af(struct pf_krule *r, struct pf_pdesc *pd) 1218 { 1219 #if defined(INET) && defined(INET6) 1220 struct pf_addr ndaddr, nsaddr, naddr; 1221 u_int16_t nport = 0; 1222 int prefixlen = 96; 1223 1224 bzero(&nsaddr, sizeof(nsaddr)); 1225 bzero(&ndaddr, sizeof(ndaddr)); 1226 1227 if (V_pf_status.debug >= PF_DEBUG_MISC) { 1228 printf("pf: af-to %s %s, ", 1229 pd->naf == AF_INET ? "inet" : "inet6", 1230 TAILQ_EMPTY(&r->rdr.list) ? "nat" : "rdr"); 1231 pf_print_host(&pd->nsaddr, pd->nsport, pd->af); 1232 printf(" -> "); 1233 pf_print_host(&pd->ndaddr, pd->ndport, pd->af); 1234 printf("\n"); 1235 } 1236 1237 if (TAILQ_EMPTY(&r->nat.list)) 1238 panic("pf_get_transaddr_af: no nat pool for source address"); 1239 1240 /* get source address and port */ 1241 if (pf_get_sport(pd, r, &nsaddr, &nport, r->nat.proxy_port[0], 1242 r->nat.proxy_port[1], &r->nat, NULL, PF_SN_NAT)) { 1243 DPFPRINTF(PF_DEBUG_MISC, 1244 "pf: af-to NAT proxy port allocation (%u-%u) failed", 1245 r->nat.proxy_port[0], r->nat.proxy_port[1]); 1246 return (-1); 1247 } 1248 1249 if (pd->proto == IPPROTO_ICMPV6 && pd->naf == AF_INET) { 1250 pd->ndport = ntohs(pd->ndport); 1251 if (pd->ndport == ICMP6_ECHO_REQUEST) 1252 pd->ndport = ICMP_ECHO; 1253 else if (pd->ndport == ICMP6_ECHO_REPLY) 1254 pd->ndport = ICMP_ECHOREPLY; 1255 pd->ndport = htons(pd->ndport); 1256 } else if (pd->proto == IPPROTO_ICMP && pd->naf == AF_INET6) { 1257 pd->nsport = ntohs(pd->nsport); 1258 if (pd->ndport == ICMP_ECHO) 1259 pd->ndport = ICMP6_ECHO_REQUEST; 1260 else if (pd->ndport == ICMP_ECHOREPLY) 1261 pd->ndport = ICMP6_ECHO_REPLY; 1262 pd->nsport = htons(pd->nsport); 1263 } 1264 1265 /* get the destination address and port */ 1266 if (! TAILQ_EMPTY(&r->rdr.list)) { 1267 if (pf_map_addr_sn(pd->naf, r, &nsaddr, &naddr, &(pd->naf), 1268 NULL, NULL, &r->rdr, PF_SN_NAT)) 1269 return (-1); 1270 if (r->rdr.proxy_port[0]) 1271 pd->ndport = htons(r->rdr.proxy_port[0]); 1272 1273 if (pd->naf == AF_INET) { 1274 /* The prefix is the IPv4 rdr address */ 1275 prefixlen = in_mask2len( 1276 (struct in_addr *)&r->rdr.cur->addr.v.a.mask); 1277 inet_nat46(pd->naf, &pd->ndaddr, &ndaddr, &naddr, 1278 prefixlen); 1279 } else { 1280 /* The prefix is the IPv6 rdr address */ 1281 prefixlen = in6_mask2len( 1282 (struct in6_addr *)&r->rdr.cur->addr.v.a.mask, NULL); 1283 inet_nat64(pd->naf, &pd->ndaddr, &ndaddr, &naddr, 1284 prefixlen); 1285 } 1286 } else { 1287 if (pd->naf == AF_INET) { 1288 /* The prefix is the IPv6 dst address */ 1289 prefixlen = in6_mask2len( 1290 (struct in6_addr *)&r->dst.addr.v.a.mask, NULL); 1291 if (prefixlen < 32) 1292 prefixlen = 96; 1293 inet_nat64(pd->naf, &pd->ndaddr, &ndaddr, &pd->ndaddr, 1294 prefixlen); 1295 } else { 1296 /* 1297 * The prefix is the IPv6 nat address 1298 * (that was stored in pd->nsaddr) 1299 */ 1300 prefixlen = in6_mask2len( 1301 (struct in6_addr *)&r->nat.cur->addr.v.a.mask, NULL); 1302 if (prefixlen > 96) 1303 prefixlen = 96; 1304 inet_nat64(pd->naf, &pd->ndaddr, &ndaddr, &nsaddr, 1305 prefixlen); 1306 } 1307 } 1308 1309 pf_addrcpy(&pd->nsaddr, &nsaddr, pd->naf); 1310 pf_addrcpy(&pd->ndaddr, &ndaddr, pd->naf); 1311 1312 if (V_pf_status.debug >= PF_DEBUG_MISC) { 1313 printf("pf: af-to %s done, prefixlen %d, ", 1314 pd->naf == AF_INET ? "inet" : "inet6", 1315 prefixlen); 1316 pf_print_host(&pd->nsaddr, pd->nsport, pd->naf); 1317 printf(" -> "); 1318 pf_print_host(&pd->ndaddr, pd->ndport, pd->naf); 1319 printf("\n"); 1320 } 1321 1322 return (0); 1323 #else 1324 return (-1); 1325 #endif 1326 } 1327