1 /*- 2 * Copyright (c) 2014-2019 Mindaugas Rasiukevicius <rmind at netbsd org> 3 * Copyright (c) 2010-2013 The NetBSD Foundation, Inc. 4 * All rights reserved. 5 * 6 * This material is based upon work partially supported by The 7 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 /* 32 * NPF network address port translation (NAPT) and other forms of NAT. 33 * Described in RFC 2663, RFC 3022, etc. 34 * 35 * Overview 36 * 37 * There are a few mechanisms: NAT policy, port map and translation. 38 * The NAT module has a separate ruleset where rules always have an 39 * associated NAT policy. 40 * 41 * Translation types 42 * 43 * There are two types of translation: outbound (NPF_NATOUT) and 44 * inbound (NPF_NATIN). It should not be confused with connection 45 * direction. See npf_nat_which() for the description of how the 46 * addresses are rewritten. The bi-directional NAT is a combined 47 * outbound and inbound translation, therefore is constructed as 48 * two policies. 49 * 50 * NAT policies and port maps 51 * 52 * The NAT (translation) policy is applied when packet matches the 53 * rule. Apart from the filter criteria, the NAT policy always has 54 * a translation IP address or a table. If port translation is set, 55 * then NAT mechanism relies on port map mechanism. 56 * 57 * Connections, translation entries and their life-cycle 58 * 59 * NAT relies on the connection tracking module. Each translated 60 * connection has an associated translation entry (npf_nat_t) which 61 * contains information used for backwards stream translation, i.e. 62 * the original IP address with port and translation port, allocated 63 * from the port map. Each NAT entry is associated with the policy, 64 * which contains translation IP address. Allocated port is returned 65 * to the port map and NAT entry is destroyed when connection expires. 66 */ 67 68 #ifdef _KERNEL 69 #include <sys/cdefs.h> 70 __KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.48 2019/08/25 13:21:03 rmind Exp $"); 71 72 #include <sys/param.h> 73 #include <sys/types.h> 74 75 #include <sys/atomic.h> 76 #include <sys/condvar.h> 77 #include <sys/kmem.h> 78 #include <sys/mutex.h> 79 #include <sys/pool.h> 80 #include <sys/proc.h> 81 #endif 82 83 #include "npf_impl.h" 84 #include "npf_conn.h" 85 86 /* 87 * NAT policy structure. 88 */ 89 struct npf_natpolicy { 90 npf_t * n_npfctx; 91 kmutex_t n_lock; 92 LIST_HEAD(, npf_nat) n_nat_list; 93 volatile unsigned n_refcnt; 94 uint64_t n_id; 95 96 /* 97 * Translation type, flags, address or table and the port. 98 * Additionally, there may be translation algorithm and any 99 * auxiliary data, e.g. NPTv6 adjustment value. 100 * 101 * NPF_NP_CMP_START mark starts here. 102 */ 103 unsigned n_type; 104 unsigned n_flags; 105 unsigned n_alen; 106 107 npf_addr_t n_taddr; 108 npf_netmask_t n_tmask; 109 in_port_t n_tport; 110 unsigned n_tid; 111 112 unsigned n_algo; 113 union { 114 unsigned n_rr_idx; 115 uint16_t n_npt66_adj; 116 }; 117 }; 118 119 /* 120 * Private flags - must be in the NPF_NAT_PRIVMASK range. 121 */ 122 #define NPF_NAT_USETABLE (0x01000000 & NPF_NAT_PRIVMASK) 123 124 #define NPF_NP_CMP_START offsetof(npf_natpolicy_t, n_type) 125 #define NPF_NP_CMP_SIZE (sizeof(npf_natpolicy_t) - NPF_NP_CMP_START) 126 127 /* 128 * NAT translation entry for a connection. 129 */ 130 struct npf_nat { 131 /* Associated NAT policy. */ 132 npf_natpolicy_t * nt_natpolicy; 133 134 /* 135 * Translation address as well as the original address which is 136 * used for backwards translation. The same for ports. 137 */ 138 npf_addr_t nt_taddr; 139 npf_addr_t nt_oaddr; 140 141 unsigned nt_alen; 142 in_port_t nt_oport; 143 in_port_t nt_tport; 144 145 /* ALG (if any) associated with this NAT entry. */ 146 npf_alg_t * nt_alg; 147 uintptr_t nt_alg_arg; 148 149 LIST_ENTRY(npf_nat) nt_entry; 150 npf_conn_t * nt_conn; 151 }; 152 153 static pool_cache_t nat_cache __read_mostly; 154 155 /* 156 * npf_nat_sys{init,fini}: initialise/destroy NAT subsystem structures. 157 */ 158 159 void 160 npf_nat_sysinit(void) 161 { 162 nat_cache = pool_cache_init(sizeof(npf_nat_t), 0, 163 0, 0, "npfnatpl", NULL, IPL_NET, NULL, NULL, NULL); 164 KASSERT(nat_cache != NULL); 165 } 166 167 void 168 npf_nat_sysfini(void) 169 { 170 /* All NAT policies should already be destroyed. */ 171 pool_cache_destroy(nat_cache); 172 } 173 174 /* 175 * npf_nat_newpolicy: create a new NAT policy. 176 */ 177 npf_natpolicy_t * 178 npf_nat_newpolicy(npf_t *npf, const nvlist_t *nat, npf_ruleset_t *rset) 179 { 180 npf_natpolicy_t *np; 181 const void *addr; 182 size_t len; 183 184 np = kmem_zalloc(sizeof(npf_natpolicy_t), KM_SLEEP); 185 np->n_npfctx = npf; 186 187 /* The translation type, flags and policy ID. */ 188 np->n_type = dnvlist_get_number(nat, "type", 0); 189 np->n_flags = dnvlist_get_number(nat, "flags", 0) & ~NPF_NAT_PRIVMASK; 190 np->n_id = dnvlist_get_number(nat, "nat-policy", 0); 191 192 /* Should be exclusively either inbound or outbound NAT. */ 193 if (((np->n_type == NPF_NATIN) ^ (np->n_type == NPF_NATOUT)) == 0) { 194 goto err; 195 } 196 mutex_init(&np->n_lock, MUTEX_DEFAULT, IPL_SOFTNET); 197 LIST_INIT(&np->n_nat_list); 198 199 /* 200 * Translation IP, mask and port (if applicable). If using the 201 * the table, specified by the ID, then the nat-addr/nat-mask will 202 * be used as a filter for the addresses selected from table. 203 */ 204 if (nvlist_exists_number(nat, "nat-table-id")) { 205 if (np->n_flags & NPF_NAT_STATIC) { 206 goto err; 207 } 208 np->n_tid = nvlist_get_number(nat, "nat-table-id"); 209 np->n_tmask = NPF_NO_NETMASK; 210 np->n_flags |= NPF_NAT_USETABLE; 211 } else { 212 addr = dnvlist_get_binary(nat, "nat-addr", &len, NULL, 0); 213 if (!addr || len == 0 || len > sizeof(npf_addr_t)) { 214 goto err; 215 } 216 memcpy(&np->n_taddr, addr, len); 217 np->n_alen = len; 218 np->n_tmask = dnvlist_get_number(nat, "nat-mask", NPF_NO_NETMASK); 219 if (npf_netmask_check(np->n_alen, np->n_tmask)) { 220 goto err; 221 } 222 } 223 np->n_tport = dnvlist_get_number(nat, "nat-port", 0); 224 225 /* 226 * NAT algorithm. 227 */ 228 np->n_algo = dnvlist_get_number(nat, "nat-algo", 0); 229 switch (np->n_algo) { 230 case NPF_ALGO_NPT66: 231 np->n_npt66_adj = dnvlist_get_number(nat, "npt66-adj", 0); 232 break; 233 case NPF_ALGO_NETMAP: 234 break; 235 case NPF_ALGO_IPHASH: 236 case NPF_ALGO_RR: 237 default: 238 if (np->n_tmask != NPF_NO_NETMASK) { 239 goto err; 240 } 241 break; 242 } 243 return np; 244 err: 245 mutex_destroy(&np->n_lock); 246 kmem_free(np, sizeof(npf_natpolicy_t)); 247 return NULL; 248 } 249 250 int 251 npf_nat_policyexport(const npf_natpolicy_t *np, nvlist_t *nat) 252 { 253 nvlist_add_number(nat, "nat-policy", np->n_id); 254 nvlist_add_number(nat, "type", np->n_type); 255 nvlist_add_number(nat, "flags", np->n_flags); 256 257 if (np->n_flags & NPF_NAT_USETABLE) { 258 nvlist_add_number(nat, "nat-table-id", np->n_tid); 259 } else { 260 nvlist_add_binary(nat, "nat-addr", &np->n_taddr, np->n_alen); 261 nvlist_add_number(nat, "nat-mask", np->n_tmask); 262 } 263 nvlist_add_number(nat, "nat-port", np->n_tport); 264 nvlist_add_number(nat, "nat-algo", np->n_algo); 265 266 switch (np->n_algo) { 267 case NPF_ALGO_NPT66: 268 nvlist_add_number(nat, "npt66-adj", np->n_npt66_adj); 269 break; 270 } 271 return 0; 272 } 273 274 /* 275 * npf_nat_freepolicy: free the NAT policy. 276 * 277 * => Called from npf_rule_free() during the reload via npf_ruleset_destroy(). 278 */ 279 void 280 npf_nat_freepolicy(npf_natpolicy_t *np) 281 { 282 npf_conn_t *con; 283 npf_nat_t *nt; 284 285 /* 286 * Disassociate all entries from the policy. At this point, 287 * new entries can no longer be created for this policy. 288 */ 289 while (np->n_refcnt) { 290 mutex_enter(&np->n_lock); 291 LIST_FOREACH(nt, &np->n_nat_list, nt_entry) { 292 con = nt->nt_conn; 293 KASSERT(con != NULL); 294 npf_conn_expire(con); 295 } 296 mutex_exit(&np->n_lock); 297 298 /* Kick the worker - all references should be going away. */ 299 npf_worker_signal(np->n_npfctx); 300 kpause("npfgcnat", false, 1, NULL); 301 } 302 KASSERT(LIST_EMPTY(&np->n_nat_list)); 303 mutex_destroy(&np->n_lock); 304 kmem_free(np, sizeof(npf_natpolicy_t)); 305 } 306 307 void 308 npf_nat_freealg(npf_natpolicy_t *np, npf_alg_t *alg) 309 { 310 npf_nat_t *nt; 311 312 mutex_enter(&np->n_lock); 313 LIST_FOREACH(nt, &np->n_nat_list, nt_entry) { 314 if (nt->nt_alg == alg) { 315 nt->nt_alg = NULL; 316 } 317 } 318 mutex_exit(&np->n_lock); 319 } 320 321 /* 322 * npf_nat_cmppolicy: compare two NAT policies. 323 * 324 * => Return 0 on match, and non-zero otherwise. 325 */ 326 bool 327 npf_nat_cmppolicy(npf_natpolicy_t *np, npf_natpolicy_t *mnp) 328 { 329 const void *np_raw, *mnp_raw; 330 331 /* 332 * Compare the relevant NAT policy information (in raw form), 333 * which is enough for matching criterion. 334 */ 335 KASSERT(np && mnp && np != mnp); 336 np_raw = (const uint8_t *)np + NPF_NP_CMP_START; 337 mnp_raw = (const uint8_t *)mnp + NPF_NP_CMP_START; 338 return memcmp(np_raw, mnp_raw, NPF_NP_CMP_SIZE) == 0; 339 } 340 341 void 342 npf_nat_setid(npf_natpolicy_t *np, uint64_t id) 343 { 344 np->n_id = id; 345 } 346 347 uint64_t 348 npf_nat_getid(const npf_natpolicy_t *np) 349 { 350 return np->n_id; 351 } 352 353 /* 354 * npf_nat_which: tell which address (source or destination) should be 355 * rewritten given the combination of the NAT type and flow direction. 356 */ 357 static inline unsigned 358 npf_nat_which(const unsigned type, bool forw) 359 { 360 /* 361 * Outbound NAT rewrites: 362 * - Source (NPF_SRC) on "forwards" stream. 363 * - Destination (NPF_DST) on "backwards" stream. 364 * Inbound NAT is other way round. 365 */ 366 if (type == NPF_NATOUT) { 367 forw = !forw; 368 } else { 369 KASSERT(type == NPF_NATIN); 370 } 371 CTASSERT(NPF_SRC == 0 && NPF_DST == 1); 372 KASSERT(forw == NPF_SRC || forw == NPF_DST); 373 return (unsigned)forw; 374 } 375 376 /* 377 * npf_nat_inspect: inspect packet against NAT ruleset and return a policy. 378 * 379 * => Acquire a reference on the policy, if found. 380 */ 381 static npf_natpolicy_t * 382 npf_nat_inspect(npf_cache_t *npc, const int di) 383 { 384 npf_t *npf = npc->npc_ctx; 385 int slock = npf_config_read_enter(npf); 386 npf_ruleset_t *rlset = npf_config_natset(npf); 387 npf_natpolicy_t *np; 388 npf_rule_t *rl; 389 390 rl = npf_ruleset_inspect(npc, rlset, di, NPF_LAYER_3); 391 if (rl == NULL) { 392 npf_config_read_exit(npf, slock); 393 return NULL; 394 } 395 np = npf_rule_getnat(rl); 396 atomic_inc_uint(&np->n_refcnt); 397 npf_config_read_exit(npf, slock); 398 return np; 399 } 400 401 static void 402 npf_nat_algo_netmap(const npf_cache_t *npc, const npf_natpolicy_t *np, 403 const unsigned which, npf_addr_t *addr) 404 { 405 const npf_addr_t *orig_addr = npc->npc_ips[which]; 406 407 /* 408 * NETMAP: 409 * 410 * addr = net-addr | (orig-addr & ~mask) 411 */ 412 npf_addr_mask(&np->n_taddr, np->n_tmask, npc->npc_alen, addr); 413 npf_addr_bitor(orig_addr, np->n_tmask, npc->npc_alen, addr); 414 } 415 416 static inline npf_addr_t * 417 npf_nat_getaddr(npf_cache_t *npc, npf_natpolicy_t *np, const unsigned alen) 418 { 419 npf_tableset_t *ts = npf_config_tableset(np->n_npfctx); 420 npf_table_t *t = npf_tableset_getbyid(ts, np->n_tid); 421 unsigned idx; 422 423 /* 424 * Dynamically select the translation IP address. 425 */ 426 switch (np->n_algo) { 427 case NPF_ALGO_RR: 428 idx = atomic_inc_uint_nv(&np->n_rr_idx); 429 break; 430 case NPF_ALGO_IPHASH: 431 default: 432 idx = npf_addr_mix(alen, 433 npc->npc_ips[NPF_SRC], 434 npc->npc_ips[NPF_DST]); 435 break; 436 } 437 return npf_table_getsome(t, alen, idx); 438 } 439 440 /* 441 * npf_nat_create: create a new NAT translation entry. 442 */ 443 static npf_nat_t * 444 npf_nat_create(npf_cache_t *npc, npf_natpolicy_t *np, npf_conn_t *con) 445 { 446 const int proto = npc->npc_proto; 447 const unsigned alen = npc->npc_alen; 448 npf_t *npf = npc->npc_ctx; 449 npf_addr_t *taddr; 450 npf_nat_t *nt; 451 452 KASSERT(npf_iscached(npc, NPC_IP46)); 453 KASSERT(npf_iscached(npc, NPC_LAYER4)); 454 455 /* Construct a new NAT entry and associate it with the connection. */ 456 nt = pool_cache_get(nat_cache, PR_NOWAIT); 457 if (__predict_false(!nt)) { 458 return NULL; 459 } 460 npf_stats_inc(npf, NPF_STAT_NAT_CREATE); 461 nt->nt_natpolicy = np; 462 nt->nt_conn = con; 463 nt->nt_alg = NULL; 464 465 /* 466 * Select the translation address. 467 */ 468 if (np->n_flags & NPF_NAT_USETABLE) { 469 int slock = npf_config_read_enter(npf); 470 taddr = npf_nat_getaddr(npc, np, alen); 471 if (__predict_false(!taddr)) { 472 npf_config_read_exit(npf, slock); 473 pool_cache_put(nat_cache, nt); 474 return NULL; 475 } 476 memcpy(&nt->nt_taddr, taddr, alen); 477 npf_config_read_exit(npf, slock); 478 479 } else if (np->n_algo == NPF_ALGO_NETMAP) { 480 const unsigned which = npf_nat_which(np->n_type, true); 481 npf_nat_algo_netmap(npc, np, which, &nt->nt_taddr); 482 taddr = &nt->nt_taddr; 483 } else { 484 /* Static IP address. */ 485 taddr = &np->n_taddr; 486 memcpy(&nt->nt_taddr, taddr, alen); 487 } 488 nt->nt_alen = alen; 489 490 /* Save the original address which may be rewritten. */ 491 if (np->n_type == NPF_NATOUT) { 492 /* Outbound NAT: source (think internal) address. */ 493 memcpy(&nt->nt_oaddr, npc->npc_ips[NPF_SRC], alen); 494 } else { 495 /* Inbound NAT: destination (think external) address. */ 496 KASSERT(np->n_type == NPF_NATIN); 497 memcpy(&nt->nt_oaddr, npc->npc_ips[NPF_DST], alen); 498 } 499 500 /* 501 * Port translation, if required, and if it is TCP/UDP. 502 */ 503 if ((np->n_flags & NPF_NAT_PORTS) == 0 || 504 (proto != IPPROTO_TCP && proto != IPPROTO_UDP)) { 505 nt->nt_oport = 0; 506 nt->nt_tport = 0; 507 goto out; 508 } 509 510 /* Save the relevant TCP/UDP port. */ 511 if (proto == IPPROTO_TCP) { 512 const struct tcphdr *th = npc->npc_l4.tcp; 513 nt->nt_oport = (np->n_type == NPF_NATOUT) ? 514 th->th_sport : th->th_dport; 515 } else { 516 const struct udphdr *uh = npc->npc_l4.udp; 517 nt->nt_oport = (np->n_type == NPF_NATOUT) ? 518 uh->uh_sport : uh->uh_dport; 519 } 520 521 /* Get a new port for translation. */ 522 if ((np->n_flags & NPF_NAT_PORTMAP) != 0) { 523 npf_portmap_t *pm = np->n_npfctx->portmap; 524 nt->nt_tport = npf_portmap_get(pm, alen, taddr); 525 } else { 526 nt->nt_tport = np->n_tport; 527 } 528 out: 529 mutex_enter(&np->n_lock); 530 LIST_INSERT_HEAD(&np->n_nat_list, nt, nt_entry); 531 mutex_exit(&np->n_lock); 532 return nt; 533 } 534 535 /* 536 * npf_nat_translate: perform translation given the state data. 537 */ 538 static inline int 539 npf_nat_translate(npf_cache_t *npc, npf_nat_t *nt, bool forw) 540 { 541 const npf_natpolicy_t *np = nt->nt_natpolicy; 542 const unsigned which = npf_nat_which(np->n_type, forw); 543 const npf_addr_t *addr; 544 in_port_t port; 545 546 KASSERT(npf_iscached(npc, NPC_IP46)); 547 KASSERT(npf_iscached(npc, NPC_LAYER4)); 548 549 if (forw) { 550 /* "Forwards" stream: use translation address/port. */ 551 addr = &nt->nt_taddr; 552 port = nt->nt_tport; 553 } else { 554 /* "Backwards" stream: use original address/port. */ 555 addr = &nt->nt_oaddr; 556 port = nt->nt_oport; 557 } 558 KASSERT((np->n_flags & NPF_NAT_PORTS) != 0 || port == 0); 559 560 /* Execute ALG translation first. */ 561 if ((npc->npc_info & NPC_ALG_EXEC) == 0) { 562 npc->npc_info |= NPC_ALG_EXEC; 563 npf_alg_exec(npc, nt, forw); 564 npf_recache(npc); 565 } 566 KASSERT(!nbuf_flag_p(npc->npc_nbuf, NBUF_DATAREF_RESET)); 567 568 /* Finally, perform the translation. */ 569 return npf_napt_rwr(npc, which, addr, port); 570 } 571 572 /* 573 * npf_nat_algo: perform the translation given the algorithm. 574 */ 575 static inline int 576 npf_nat_algo(npf_cache_t *npc, const npf_natpolicy_t *np, bool forw) 577 { 578 const unsigned which = npf_nat_which(np->n_type, forw); 579 const npf_addr_t *taddr; 580 npf_addr_t addr; 581 582 KASSERT(np->n_flags & NPF_NAT_STATIC); 583 584 switch (np->n_algo) { 585 case NPF_ALGO_NETMAP: 586 npf_nat_algo_netmap(npc, np, which, &addr); 587 taddr = &addr; 588 break; 589 case NPF_ALGO_NPT66: 590 return npf_npt66_rwr(npc, which, &np->n_taddr, 591 np->n_tmask, np->n_npt66_adj); 592 default: 593 taddr = &np->n_taddr; 594 break; 595 } 596 return npf_napt_rwr(npc, which, taddr, np->n_tport); 597 } 598 599 /* 600 * npf_do_nat: 601 * 602 * - Inspect packet for a NAT policy, unless a connection with a NAT 603 * association already exists. In such case, determine whether it 604 * is a "forwards" or "backwards" stream. 605 * - Perform translation: rewrite source or destination fields, 606 * depending on translation type and direction. 607 * - Associate a NAT policy with a connection (may establish a new). 608 */ 609 int 610 npf_do_nat(npf_cache_t *npc, npf_conn_t *con, const int di) 611 { 612 nbuf_t *nbuf = npc->npc_nbuf; 613 npf_conn_t *ncon = NULL; 614 npf_natpolicy_t *np; 615 npf_nat_t *nt; 616 int error; 617 bool forw; 618 619 /* All relevant data should be already cached. */ 620 if (!npf_iscached(npc, NPC_IP46) || !npf_iscached(npc, NPC_LAYER4)) { 621 return 0; 622 } 623 KASSERT(!nbuf_flag_p(nbuf, NBUF_DATAREF_RESET)); 624 625 /* 626 * Return the NAT entry associated with the connection, if any. 627 * Determines whether the stream is "forwards" or "backwards". 628 * Note: no need to lock, since reference on connection is held. 629 */ 630 if (con && (nt = npf_conn_getnat(con, di, &forw)) != NULL) { 631 np = nt->nt_natpolicy; 632 goto translate; 633 } 634 635 /* 636 * Inspect the packet for a NAT policy, if there is no connection. 637 * Note: acquires a reference if found. 638 */ 639 np = npf_nat_inspect(npc, di); 640 if (np == NULL) { 641 /* If packet does not match - done. */ 642 return 0; 643 } 644 forw = true; 645 646 /* Static NAT - just perform the translation. */ 647 if (np->n_flags & NPF_NAT_STATIC) { 648 if (nbuf_cksum_barrier(nbuf, di)) { 649 npf_recache(npc); 650 } 651 error = npf_nat_algo(npc, np, forw); 652 atomic_dec_uint(&np->n_refcnt); 653 return error; 654 } 655 656 /* 657 * If there is no local connection (no "stateful" rule - unusual, 658 * but possible configuration), establish one before translation. 659 * Note that it is not a "pass" connection, therefore passing of 660 * "backwards" stream depends on other, stateless filtering rules. 661 */ 662 if (con == NULL) { 663 ncon = npf_conn_establish(npc, di, true); 664 if (ncon == NULL) { 665 atomic_dec_uint(&np->n_refcnt); 666 return ENOMEM; 667 } 668 con = ncon; 669 } 670 671 /* 672 * Create a new NAT entry and associate with the connection. 673 * We will consume the reference on success (release on error). 674 */ 675 nt = npf_nat_create(npc, np, con); 676 if (nt == NULL) { 677 atomic_dec_uint(&np->n_refcnt); 678 error = ENOMEM; 679 goto out; 680 } 681 682 /* Associate the NAT translation entry with the connection. */ 683 error = npf_conn_setnat(npc, con, nt, np->n_type); 684 if (error) { 685 /* Will release the reference. */ 686 npf_nat_destroy(nt); 687 goto out; 688 } 689 690 /* Determine whether any ALG matches. */ 691 if (npf_alg_match(npc, nt, di)) { 692 KASSERT(nt->nt_alg != NULL); 693 } 694 695 translate: 696 /* May need to process the delayed checksums first (XXX: NetBSD). */ 697 if (nbuf_cksum_barrier(nbuf, di)) { 698 npf_recache(npc); 699 } 700 701 /* Perform the translation. */ 702 error = npf_nat_translate(npc, nt, forw); 703 out: 704 if (__predict_false(ncon)) { 705 if (error) { 706 /* It created for NAT - just expire. */ 707 npf_conn_expire(ncon); 708 } 709 npf_conn_release(ncon); 710 } 711 return error; 712 } 713 714 /* 715 * npf_nat_gettrans: return translation IP address and port. 716 */ 717 void 718 npf_nat_gettrans(npf_nat_t *nt, npf_addr_t **addr, in_port_t *port) 719 { 720 *addr = &nt->nt_taddr; 721 *port = nt->nt_tport; 722 } 723 724 /* 725 * npf_nat_getorig: return original IP address and port from translation entry. 726 */ 727 void 728 npf_nat_getorig(npf_nat_t *nt, npf_addr_t **addr, in_port_t *port) 729 { 730 *addr = &nt->nt_oaddr; 731 *port = nt->nt_oport; 732 } 733 734 /* 735 * npf_nat_setalg: associate an ALG with the NAT entry. 736 */ 737 void 738 npf_nat_setalg(npf_nat_t *nt, npf_alg_t *alg, uintptr_t arg) 739 { 740 nt->nt_alg = alg; 741 nt->nt_alg_arg = arg; 742 } 743 744 /* 745 * npf_nat_destroy: destroy NAT structure (performed on connection expiration). 746 */ 747 void 748 npf_nat_destroy(npf_nat_t *nt) 749 { 750 npf_natpolicy_t *np = nt->nt_natpolicy; 751 npf_t *npf = np->n_npfctx; 752 753 /* Return taken port to the portmap. */ 754 if ((np->n_flags & NPF_NAT_PORTMAP) != 0 && nt->nt_tport) { 755 npf_portmap_t *pm = npf->portmap; 756 npf_portmap_put(pm, nt->nt_alen, &nt->nt_taddr, nt->nt_tport); 757 } 758 npf_stats_inc(np->n_npfctx, NPF_STAT_NAT_DESTROY); 759 760 mutex_enter(&np->n_lock); 761 LIST_REMOVE(nt, nt_entry); 762 KASSERT(np->n_refcnt > 0); 763 atomic_dec_uint(&np->n_refcnt); 764 mutex_exit(&np->n_lock); 765 pool_cache_put(nat_cache, nt); 766 } 767 768 /* 769 * npf_nat_export: serialise the NAT entry with a NAT policy ID. 770 */ 771 void 772 npf_nat_export(nvlist_t *condict, npf_nat_t *nt) 773 { 774 npf_natpolicy_t *np = nt->nt_natpolicy; 775 nvlist_t *nat; 776 777 nat = nvlist_create(0); 778 nvlist_add_binary(nat, "oaddr", &nt->nt_oaddr, sizeof(npf_addr_t)); 779 nvlist_add_number(nat, "oport", nt->nt_oport); 780 nvlist_add_number(nat, "tport", nt->nt_tport); 781 nvlist_add_number(nat, "nat-policy", np->n_id); 782 nvlist_move_nvlist(condict, "nat", nat); 783 } 784 785 /* 786 * npf_nat_import: find the NAT policy and unserialise the NAT entry. 787 */ 788 npf_nat_t * 789 npf_nat_import(npf_t *npf, const nvlist_t *nat, 790 npf_ruleset_t *natlist, npf_conn_t *con) 791 { 792 npf_natpolicy_t *np; 793 npf_nat_t *nt; 794 const void *oaddr; 795 uint64_t np_id; 796 size_t len; 797 798 np_id = dnvlist_get_number(nat, "nat-policy", UINT64_MAX); 799 if ((np = npf_ruleset_findnat(natlist, np_id)) == NULL) { 800 return NULL; 801 } 802 nt = pool_cache_get(nat_cache, PR_WAITOK); 803 memset(nt, 0, sizeof(npf_nat_t)); 804 805 oaddr = dnvlist_get_binary(nat, "oaddr", &len, NULL, 0); 806 if (!oaddr || len != sizeof(npf_addr_t)) { 807 pool_cache_put(nat_cache, nt); 808 return NULL; 809 } 810 memcpy(&nt->nt_oaddr, oaddr, sizeof(npf_addr_t)); 811 nt->nt_oport = dnvlist_get_number(nat, "oport", 0); 812 nt->nt_tport = dnvlist_get_number(nat, "tport", 0); 813 814 /* Take a specific port from port-map. */ 815 if ((np->n_flags & NPF_NAT_PORTMAP) != 0 && nt->nt_tport) { 816 npf_portmap_t *pm = npf->portmap; 817 818 if (!npf_portmap_take(pm, nt->nt_alen, 819 &nt->nt_taddr, nt->nt_tport)) { 820 pool_cache_put(nat_cache, nt); 821 return NULL; 822 } 823 } 824 npf_stats_inc(npf, NPF_STAT_NAT_CREATE); 825 826 /* 827 * Associate, take a reference and insert. Unlocked since 828 * the policy is not yet visible. 829 */ 830 nt->nt_natpolicy = np; 831 nt->nt_conn = con; 832 np->n_refcnt++; 833 LIST_INSERT_HEAD(&np->n_nat_list, nt, nt_entry); 834 return nt; 835 } 836 837 #if defined(DDB) || defined(_NPF_TESTING) 838 839 void 840 npf_nat_dump(const npf_nat_t *nt) 841 { 842 const npf_natpolicy_t *np; 843 struct in_addr ip; 844 845 np = nt->nt_natpolicy; 846 memcpy(&ip, &nt->nt_taddr, sizeof(ip)); 847 printf("\tNATP(%p): type %u flags 0x%x taddr %s tport %d\n", np, 848 np->n_type, np->n_flags, inet_ntoa(ip), ntohs(np->n_tport)); 849 memcpy(&ip, &nt->nt_oaddr, sizeof(ip)); 850 printf("\tNAT: original address %s oport %d tport %d\n", 851 inet_ntoa(ip), ntohs(nt->nt_oport), ntohs(nt->nt_tport)); 852 if (nt->nt_alg) { 853 printf("\tNAT ALG = %p, ARG = %p\n", 854 nt->nt_alg, (void *)nt->nt_alg_arg); 855 } 856 } 857 858 #endif 859