Lines Matching +full:host +full:- +full:port

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2015-2020 Yandex LLC
6 * Copyright (c) 2016-2020 Andrey V. Elsukov <ae@FreeBSD.org>
87 (struct nat64lsn_instance *)SRV_OBJECT((chain), insntod(cmd, kidx)->kidx)
105 struct nat64lsn_host *host; member
111 uint16_t port; member
139 static void nat64lsn_destroy_host(struct nat64lsn_host *host);
150 #define NAT64_BIT_TCP_SYN 1 /* First syn in->out */
181 plog->length = PFLOG_REAL_HDRLEN; in nat64lsn_log()
182 plog->af = family; in nat64lsn_log()
183 plog->action = PF_NAT; in nat64lsn_log()
184 plog->dir = PF_IN; in nat64lsn_log()
185 plog->rulenr = htonl(state->ip_src); in nat64lsn_log()
186 plog->subrulenr = htonl((uint32_t)(state->aport << 16) | in nat64lsn_log()
187 (state->proto << 8) | (state->ip_dst & 0xff)); in nat64lsn_log()
188 plog->ruleset[0] = '\0'; in nat64lsn_log()
189 strlcpy(plog->ifname, "NAT64LSN", sizeof(plog->ifname)); in nat64lsn_log()
195 sizeof(struct in6_addr) / sizeof(uint32_t), (c)->hash_seed)
196 #define HOSTS(c, v) ((c)->hosts_hash[(v) & ((c)->hosts_hashsize - 1)])
198 #define ALIASLINK_HVAL(c, f) HVAL(&(f)->dst_ip6,\
199 sizeof(struct in6_addr) * 2 / sizeof(uint32_t), (c)->hash_seed)
201 ((c)->aliases[(v) & ((1 << (32 - (c)->plen4)) - 1)])
204 struct nat64lsn_host *host, const struct ipfw_flow_id *f_id __unused) in nat64lsn_get_aliaslink() argument
212 return (CK_SLIST_FIRST(&host->aliases)); in nat64lsn_get_aliaslink()
230 #define STATE_HVAL(c, d) HVAL((d), 2, (c)->hash_seed)
232 ((h)->states_hash[(v) & ((h)->states_hashsize - 1)])
234 ((p)->chunks_count == 1 ? (p)->states : \
235 ((p)->states_chunk[CHUNK_BY_FADDR(p, v)]))
298 &chunks[idx / 32]->pgptr[idx % 32]); in nat64lsn_get_pg()
303 if ((pg->flags & NAT64LSN_DEADPG) == 0 && in nat64lsn_get_pg()
318 nat64lsn_get_state6to4(struct nat64lsn_cfg *cfg, struct nat64lsn_host *host, in nat64lsn_get_state6to4() argument
320 uint16_t port, uint8_t proto) in nat64lsn_get_state6to4() argument
330 CK_SLIST_FOREACH(state, &STATE_HASH(host, hval), entries) { in nat64lsn_get_state6to4()
331 if (state->proto == proto && state->ip_dst == faddr && in nat64lsn_get_state6to4()
332 state->sport == port && state->dport == f_id->dst_port) in nat64lsn_get_state6to4()
336 link = nat64lsn_get_aliaslink(cfg, host, f_id); in nat64lsn_get_state6to4()
342 pg = nat64lsn_get_pg(&link->alias->tcp_chunkmask, in nat64lsn_get_state6to4()
343 link->alias->tcp_pgmask, link->alias->tcp, in nat64lsn_get_state6to4()
344 &link->alias->tcp_pgidx, faddr); in nat64lsn_get_state6to4()
347 pg = nat64lsn_get_pg(&link->alias->udp_chunkmask, in nat64lsn_get_state6to4()
348 link->alias->udp_pgmask, link->alias->udp, in nat64lsn_get_state6to4()
349 &link->alias->udp_pgidx, faddr); in nat64lsn_get_state6to4()
352 pg = nat64lsn_get_pg(&link->alias->icmp_chunkmask, in nat64lsn_get_state6to4()
353 link->alias->icmp_pgmask, link->alias->icmp, in nat64lsn_get_state6to4()
354 &link->alias->icmp_pgidx, faddr); in nat64lsn_get_state6to4()
359 if (pg == NULL || (pg->flags & NAT64LSN_DEADPG) != 0) in nat64lsn_get_state6to4()
365 while (i-- > 0) { in nat64lsn_get_state6to4()
376 if (FREEMASK_BTR(pg, faddr, offset - 1)) { in nat64lsn_get_state6to4()
377 state = &STATES_CHUNK(pg, faddr)->state[offset - 1]; in nat64lsn_get_state6to4()
379 state->flags = proto != IPPROTO_TCP ? 0 : in nat64lsn_get_state6to4()
380 convert_tcp_flags(f_id->_flags); in nat64lsn_get_state6to4()
381 state->proto = proto; in nat64lsn_get_state6to4()
382 state->aport = pg->base_port + offset - 1; in nat64lsn_get_state6to4()
383 state->dport = f_id->dst_port; in nat64lsn_get_state6to4()
384 state->sport = port; in nat64lsn_get_state6to4()
385 state->ip6_dst = f_id->dst_ip6; in nat64lsn_get_state6to4()
386 state->ip_dst = faddr; in nat64lsn_get_state6to4()
387 state->ip_src = link->alias->addr; in nat64lsn_get_state6to4()
388 state->hval = hval; in nat64lsn_get_state6to4()
389 state->host = host; in nat64lsn_get_state6to4()
390 SET_AGE(state->timestamp); in nat64lsn_get_state6to4()
392 /* Insert new state into host's hash table */ in nat64lsn_get_state6to4()
393 HOST_LOCK(host); in nat64lsn_get_state6to4()
394 SET_AGE(host->timestamp); in nat64lsn_get_state6to4()
395 CK_SLIST_INSERT_HEAD(&STATE_HASH(host, hval), in nat64lsn_get_state6to4()
397 host->states_count++; in nat64lsn_get_state6to4()
398 HOST_UNLOCK(host); in nat64lsn_get_state6to4()
399 NAT64STAT_INC(&cfg->base.stats, screated); in nat64lsn_get_state6to4()
402 ck_pr_bts_32(&state->flags, NAT64_BIT_READY_IPV4); in nat64lsn_get_state6to4()
411 * packet header so we need to alter @addr and @port.
415 uint16_t *port) in inspect_icmp_mbuf() argument
423 off = (ip->ip_hl << 2) + ICMP_MINLEN; in inspect_icmp_mbuf()
424 if ((*mp)->m_len < off) in inspect_icmp_mbuf()
431 switch (icmp->icmp_type) { in inspect_icmp_mbuf()
435 *port = ntohs(icmp->icmp_id); in inspect_icmp_mbuf()
447 if ((*mp)->m_pkthdr.len < off + sizeof(struct ip) + ICMP_MINLEN) in inspect_icmp_mbuf()
449 if ((*mp)->m_len < off + sizeof(struct ip) + ICMP_MINLEN) in inspect_icmp_mbuf()
454 inner_proto = ip->ip_p; in inspect_icmp_mbuf()
455 off += ip->ip_hl << 2; /* Skip inner IP header */ in inspect_icmp_mbuf()
456 *addr = ntohl(ip->ip_src.s_addr); in inspect_icmp_mbuf()
457 if ((*mp)->m_len < off + ICMP_MINLEN) in inspect_icmp_mbuf()
464 /* Copy source port from the header */ in inspect_icmp_mbuf()
465 *port = ntohs(*((uint16_t *)mtodo(*mp, off))); in inspect_icmp_mbuf()
474 if (icmp->icmp_type != ICMP_ECHO) in inspect_icmp_mbuf()
476 *port = ntohs(icmp->icmp_id); in inspect_icmp_mbuf()
484 in_addr_t faddr, uint16_t port, uint8_t proto) in nat64lsn_get_state4to6() argument
492 if (port < NAT64_MIN_PORT) in nat64lsn_get_state4to6()
499 port -= NAT64_MIN_PORT; in nat64lsn_get_state4to6()
500 chunk_idx = port / 2048; in nat64lsn_get_state4to6()
502 port -= chunk_idx * 2048; in nat64lsn_get_state4to6()
503 pg_idx = port / 64; in nat64lsn_get_state4to6()
504 state_idx = port % 64; in nat64lsn_get_state4to6()
513 if (ISSET32(alias->tcp_chunkmask, chunk_idx) && in nat64lsn_get_state4to6()
514 ISSET32(alias->tcp_pgmask[chunk_idx], pg_idx)) { in nat64lsn_get_state4to6()
515 pg = alias->tcp[chunk_idx]->pgptr[pg_idx]; in nat64lsn_get_state4to6()
520 if (ISSET32(alias->udp_chunkmask, chunk_idx) && in nat64lsn_get_state4to6()
521 ISSET32(alias->udp_pgmask[chunk_idx], pg_idx)) { in nat64lsn_get_state4to6()
522 pg = alias->udp[chunk_idx]->pgptr[pg_idx]; in nat64lsn_get_state4to6()
527 if (ISSET32(alias->icmp_chunkmask, chunk_idx) && in nat64lsn_get_state4to6()
528 ISSET32(alias->icmp_pgmask[chunk_idx], pg_idx)) { in nat64lsn_get_state4to6()
529 pg = alias->icmp[chunk_idx]->pgptr[pg_idx]; in nat64lsn_get_state4to6()
542 state = &STATES_CHUNK(pg, faddr)->state[state_idx]; in nat64lsn_get_state4to6()
544 if (ck_pr_load_32(&state->flags) & NAT64_FLAG_READY) in nat64lsn_get_state4to6()
555 uint16_t *port) in nat64lsn_reassemble4() argument
565 len = ip->ip_hl << 2; in nat64lsn_reassemble4()
566 switch (ip->ip_p) { in nat64lsn_reassemble4()
578 NAT64STAT_INC(&cfg->base.stats, noproto); in nat64lsn_reassemble4()
581 if (m->m_len < len) { in nat64lsn_reassemble4()
584 NAT64STAT_INC(&cfg->base.stats, nomem); in nat64lsn_reassemble4()
589 switch (ip->ip_p) { in nat64lsn_reassemble4()
591 *port = ntohs(L3HDR(ip, struct tcphdr *)->th_dport); in nat64lsn_reassemble4()
594 *port = ntohs(L3HDR(ip, struct udphdr *)->uh_dport); in nat64lsn_reassemble4()
609 uint16_t port, ts; in nat64lsn_translate4() local
613 addr = f_id->dst_ip; in nat64lsn_translate4()
614 port = f_id->dst_port; in nat64lsn_translate4()
615 proto = f_id->proto; in nat64lsn_translate4()
616 if (addr < cfg->prefix4 || addr > cfg->pmask4) { in nat64lsn_translate4()
617 NAT64STAT_INC(&cfg->base.stats, nomatch4); in nat64lsn_translate4()
618 return (cfg->nomatch_verdict); in nat64lsn_translate4()
622 ret = ntohs(mtod(*mp, struct ip *)->ip_off); in nat64lsn_translate4()
624 *mp = nat64lsn_reassemble4(cfg, *mp, &port); in nat64lsn_translate4()
632 ret = inspect_icmp_mbuf(mp, &proto, &addr, &port); in nat64lsn_translate4()
635 NAT64STAT_INC(&cfg->base.stats, nomem); in nat64lsn_translate4()
638 NAT64STAT_INC(&cfg->base.stats, noproto); in nat64lsn_translate4()
639 return (cfg->nomatch_verdict); in nat64lsn_translate4()
641 if (addr < cfg->prefix4 || addr > cfg->pmask4) { in nat64lsn_translate4()
642 NAT64STAT_INC(&cfg->base.stats, nomatch4); in nat64lsn_translate4()
643 return (cfg->nomatch_verdict); in nat64lsn_translate4()
650 NAT64STAT_INC(&cfg->base.stats, noproto); in nat64lsn_translate4()
651 return (cfg->nomatch_verdict); in nat64lsn_translate4()
655 MPASS(addr == alias->addr); in nat64lsn_translate4()
657 /* Check that we have state for this port */ in nat64lsn_translate4()
658 state = nat64lsn_get_state4to6(cfg, alias, f_id->src_ip, in nat64lsn_translate4()
659 port, proto); in nat64lsn_translate4()
661 NAT64STAT_INC(&cfg->base.stats, nomatch4); in nat64lsn_translate4()
662 return (cfg->nomatch_verdict); in nat64lsn_translate4()
669 if (f_id->proto == IPPROTO_TCP) in nat64lsn_translate4()
670 flags = convert_tcp_flags(f_id->_flags); in nat64lsn_translate4()
673 if (state->timestamp != ts) in nat64lsn_translate4()
674 state->timestamp = ts; in nat64lsn_translate4()
675 if ((state->flags & flags) != flags) in nat64lsn_translate4()
676 state->flags |= flags; in nat64lsn_translate4()
678 port = htons(state->sport); in nat64lsn_translate4()
679 src6 = state->ip6_dst; in nat64lsn_translate4()
681 if (cfg->base.flags & NAT64_LOG) { in nat64lsn_translate4()
689 * that src_ip is different than state->ip_dst, this is why we in nat64lsn_translate4()
692 nat64_embed_ip4(&src6, cfg->base.plat_plen, htonl(f_id->src_ip)); in nat64lsn_translate4()
693 ret = nat64_do_handle_ip4(*mp, &src6, &state->host->addr, port, in nat64lsn_translate4()
694 &cfg->base, logdata); in nat64lsn_translate4()
696 return (cfg->nomatch_verdict); in nat64lsn_translate4()
712 if (ISSET32(state->flags, NAT64_BIT_STALE)) in nat64lsn_check_state()
716 if (!ISSET32(state->flags, NAT64_BIT_READY_IPV4)) in nat64lsn_check_state()
719 age = GET_AGE(state->timestamp); in nat64lsn_check_state()
720 switch (state->proto) { in nat64lsn_check_state()
722 if (ISSET32(state->flags, NAT64_BIT_TCP_FIN)) in nat64lsn_check_state()
723 ttl = cfg->st_close_ttl; in nat64lsn_check_state()
724 else if (ISSET32(state->flags, NAT64_BIT_TCP_ESTAB)) in nat64lsn_check_state()
725 ttl = cfg->st_estab_ttl; in nat64lsn_check_state()
726 else if (ISSET32(state->flags, NAT64_BIT_TCP_SYN)) in nat64lsn_check_state()
727 ttl = cfg->st_syn_ttl; in nat64lsn_check_state()
729 ttl = cfg->st_syn_ttl; in nat64lsn_check_state()
734 if (age > cfg->st_udp_ttl) in nat64lsn_check_state()
738 if (age > cfg->st_icmp_ttl) in nat64lsn_check_state()
747 case IPPROTO_TCP: (alias)->tcp_pgcount += (value); break; \
748 case IPPROTO_UDP: (alias)->udp_pgcount += (value); break; \
749 case IPPROTO_ICMP: (alias)->icmp_pgcount += (value); break; \
752 #define PGCOUNT_DEC(alias, proto) PGCOUNT_ADD(alias, proto, -1)
762 ck_pr_btr_32(&state->flags, NAT64_BIT_READY_IPV4); in nat64lsn_state_cleanup()
767 ck_pr_bts_32(&state->flags, NAT64_BIT_STALE); in nat64lsn_state_cleanup()
775 struct nat64lsn_host *host; in nat64lsn_maintain_pg() local
780 for (c = 0; c < pg->chunks_count; c++) { in nat64lsn_maintain_pg()
785 state = &STATES_CHUNK(pg, c)->state[i]; in nat64lsn_maintain_pg()
792 * 1. Mark as STALE and unlink from host's hash. in nat64lsn_maintain_pg()
795 if (ISSET32(state->flags, NAT64_BIT_STALE)) { in nat64lsn_maintain_pg()
800 state->flags = 0; in nat64lsn_maintain_pg()
803 NAT64STAT_INC(&cfg->base.stats, sdeleted); in nat64lsn_maintain_pg()
806 MPASS(state->flags & NAT64_FLAG_READY); in nat64lsn_maintain_pg()
808 host = state->host; in nat64lsn_maintain_pg()
809 HOST_LOCK(host); in nat64lsn_maintain_pg()
810 CK_SLIST_REMOVE(&STATE_HASH(host, state->hval), in nat64lsn_maintain_pg()
815 host->states_count--; in nat64lsn_maintain_pg()
816 HOST_UNLOCK(host); in nat64lsn_maintain_pg()
825 SET_AGE(pg->timestamp); in nat64lsn_maintain_pg()
827 if (GET_AGE(pg->timestamp) < cfg->pg_delete_delay) in nat64lsn_maintain_pg()
842 for (i = 0; i < 1 << (32 - cfg->plen4); i++) { in nat64lsn_expire_portgroups()
843 alias = &cfg->aliases[i]; in nat64lsn_expire_portgroups()
844 CK_SLIST_FOREACH_SAFE(pg, &alias->portgroups, entries, tpg) { in nat64lsn_expire_portgroups()
848 if (pg->base_port == NAT64_MIN_PORT) in nat64lsn_expire_portgroups()
855 idx = (pg->base_port - NAT64_MIN_PORT) / 64; in nat64lsn_expire_portgroups()
856 switch (pg->proto) { in nat64lsn_expire_portgroups()
858 pgmask = alias->tcp_pgmask; in nat64lsn_expire_portgroups()
859 pgidx = &alias->tcp_pgidx; in nat64lsn_expire_portgroups()
862 pgmask = alias->udp_pgmask; in nat64lsn_expire_portgroups()
863 pgidx = &alias->udp_pgidx; in nat64lsn_expire_portgroups()
866 pgmask = alias->icmp_pgmask; in nat64lsn_expire_portgroups()
867 pgidx = &alias->icmp_pgidx; in nat64lsn_expire_portgroups()
870 if (pg->flags & NAT64LSN_DEADPG) { in nat64lsn_expire_portgroups()
873 CK_SLIST_REMOVE(&alias->portgroups, pg, in nat64lsn_expire_portgroups()
875 PGCOUNT_DEC(alias, pg->proto); in nat64lsn_expire_portgroups()
881 NAT64STAT_INC(&cfg->base.stats, spgdeleted); in nat64lsn_expire_portgroups()
888 pg->flags |= NAT64LSN_DEADPG; in nat64lsn_expire_portgroups()
900 struct nat64lsn_host *host, *tmp; in nat64lsn_expire_hosts() local
903 for (i = 0; i < cfg->hosts_hashsize; i++) { in nat64lsn_expire_hosts()
904 CK_SLIST_FOREACH_SAFE(host, &cfg->hosts_hash[i], in nat64lsn_expire_hosts()
906 /* Is host was marked in previous call? */ in nat64lsn_expire_hosts()
907 if (host->flags & NAT64LSN_DEADHOST) { in nat64lsn_expire_hosts()
908 if (host->states_count > 0 || in nat64lsn_expire_hosts()
909 GET_AGE(host->timestamp) < in nat64lsn_expire_hosts()
910 cfg->host_delete_delay) { in nat64lsn_expire_hosts()
911 host->flags &= ~NAT64LSN_DEADHOST; in nat64lsn_expire_hosts()
915 * Unlink host from hash table and schedule in nat64lsn_expire_hosts()
919 CK_SLIST_REMOVE(&cfg->hosts_hash[i], host, in nat64lsn_expire_hosts()
921 cfg->hosts_count--; in nat64lsn_expire_hosts()
923 CK_SLIST_INSERT_HEAD(hosts, host, entries); in nat64lsn_expire_hosts()
926 if (host->states_count > 0 || in nat64lsn_expire_hosts()
927 GET_AGE(host->timestamp) < cfg->host_delete_delay) in nat64lsn_expire_hosts()
929 /* Mark host as going to be expired in next pass */ in nat64lsn_expire_hosts()
930 host->flags |= NAT64LSN_DEADHOST; in nat64lsn_expire_hosts()
945 for (i = 0; i < 1 << (32 - cfg->plen4); i++) { in nat64lsn_expire_pgchunk()
946 alias = &cfg->aliases[i]; in nat64lsn_expire_pgchunk()
947 if (GET_AGE(alias->timestamp) < cfg->pgchunk_delete_delay) in nat64lsn_expire_pgchunk()
951 if ((alias->tcp_chunkmask & (1 << c)) == 0) in nat64lsn_expire_pgchunk()
953 chunk = ck_pr_load_ptr(&alias->tcp[c]); in nat64lsn_expire_pgchunk()
954 if (ck_pr_load_32(&alias->tcp_pgmask[c]) != 0) in nat64lsn_expire_pgchunk()
956 ck_pr_btr_32(&alias->tcp_chunkmask, c); in nat64lsn_expire_pgchunk()
958 if (ck_pr_load_32(&alias->tcp_pgmask[c]) != 0) in nat64lsn_expire_pgchunk()
974 for (i = 0; i < cfg->hosts_hashsize; i++) {
975 CK_SLIST_FOREACH(h, &cfg->hosts_hash[i], entries) {
976 if (h->states_count / 2 < h->states_hashsize ||
977 h->states_hashsize >= NAT64LSN_MAX_HSIZE)
979 hsize = h->states_hashsize * 2;
986 ck_pr_bts_32(&h->flags, NAT64LSN_GROWHASH);
1003 CURVNET_SET(cfg->vp); in nat64lsn_periodic()
1004 if (cfg->hosts_count > 0) { in nat64lsn_periodic()
1007 ji->jtype = JTYPE_DESTROY; in nat64lsn_periodic()
1008 CK_SLIST_INIT(&ji->hosts); in nat64lsn_periodic()
1009 CK_SLIST_INIT(&ji->portgroups); in nat64lsn_periodic()
1010 nat64lsn_expire_hosts(cfg, &ji->hosts); in nat64lsn_periodic()
1011 nat64lsn_expire_portgroups(cfg, &ji->portgroups); in nat64lsn_periodic()
1012 ji->pgchunk = nat64lsn_expire_pgchunk(cfg); in nat64lsn_periodic()
1013 NAT64LSN_EPOCH_CALL(&ji->epoch_ctx, in nat64lsn_periodic()
1016 NAT64STAT_INC(&cfg->base.stats, jnomem); in nat64lsn_periodic()
1018 callout_schedule(&cfg->periodic, hz * PERIODIC_DELAY); in nat64lsn_periodic()
1030 struct nat64lsn_host *host; in nat64lsn_alloc_host() local
1035 /* Check that host was not yet added. */ in nat64lsn_alloc_host()
1037 CK_SLIST_FOREACH(host, &HOSTS(cfg, ji->src6_hval), entries) { in nat64lsn_alloc_host()
1038 if (IN6_ARE_ADDR_EQUAL(&ji->f_id.src_ip6, &host->addr)) { in nat64lsn_alloc_host()
1039 /* The host was allocated in previous call. */ in nat64lsn_alloc_host()
1040 ji->host = host; in nat64lsn_alloc_host()
1045 host = ji->host = uma_zalloc(nat64lsn_host_zone, M_NOWAIT); in nat64lsn_alloc_host()
1046 if (ji->host == NULL) in nat64lsn_alloc_host()
1049 host->states_hashsize = NAT64LSN_HSIZE; in nat64lsn_alloc_host()
1050 host->states_hash = malloc(sizeof(struct nat64lsn_states_slist) * in nat64lsn_alloc_host()
1051 host->states_hashsize, M_NAT64LSN, M_NOWAIT); in nat64lsn_alloc_host()
1052 if (host->states_hash == NULL) { in nat64lsn_alloc_host()
1053 uma_zfree(nat64lsn_host_zone, host); in nat64lsn_alloc_host()
1059 free(host->states_hash, M_NAT64LSN); in nat64lsn_alloc_host()
1060 uma_zfree(nat64lsn_host_zone, host); in nat64lsn_alloc_host()
1065 HOST_LOCK_INIT(host); in nat64lsn_alloc_host()
1066 SET_AGE(host->timestamp); in nat64lsn_alloc_host()
1067 host->addr = ji->f_id.src_ip6; in nat64lsn_alloc_host()
1068 host->hval = ji->src6_hval; in nat64lsn_alloc_host()
1069 host->flags = 0; in nat64lsn_alloc_host()
1070 host->states_count = 0; in nat64lsn_alloc_host()
1071 CK_SLIST_INIT(&host->aliases); in nat64lsn_alloc_host()
1072 for (i = 0; i < host->states_hashsize; i++) in nat64lsn_alloc_host()
1073 CK_SLIST_INIT(&host->states_hash[i]); in nat64lsn_alloc_host()
1075 link->alias = nat64lsn_get_alias(cfg, &ji->f_id); in nat64lsn_alloc_host()
1076 CK_SLIST_INSERT_HEAD(&host->aliases, link, host_entries); in nat64lsn_alloc_host()
1078 ALIAS_LOCK(link->alias); in nat64lsn_alloc_host()
1079 CK_SLIST_INSERT_HEAD(&link->alias->hosts, link, alias_entries); in nat64lsn_alloc_host()
1080 link->alias->hosts_count++; in nat64lsn_alloc_host()
1081 ALIAS_UNLOCK(link->alias); in nat64lsn_alloc_host()
1084 CK_SLIST_INSERT_HEAD(&HOSTS(cfg, ji->src6_hval), host, entries); in nat64lsn_alloc_host()
1085 cfg->hosts_count++; in nat64lsn_alloc_host()
1089 data[0] = ji->faddr; in nat64lsn_alloc_host()
1090 data[1] = (ji->f_id.dst_port << 16) | ji->port; in nat64lsn_alloc_host()
1091 ji->state_hval = hval = STATE_HVAL(cfg, data); in nat64lsn_alloc_host()
1092 state = nat64lsn_get_state6to4(cfg, host, &ji->f_id, hval, in nat64lsn_alloc_host()
1093 ji->faddr, ji->port, ji->proto); in nat64lsn_alloc_host()
1104 ji->state = state; in nat64lsn_alloc_host()
1106 ji->done = 1; in nat64lsn_alloc_host()
1107 DPRINTF(DP_OBJ, "ALLOC HOST %s %p", in nat64lsn_alloc_host()
1108 inet_ntop(AF_INET6, &host->addr, a, sizeof(a)), host); in nat64lsn_alloc_host()
1120 return (i * 32 + ffs(~data[i]) - 1); in nat64lsn_find_pg_place()
1122 return (-1); in nat64lsn_find_pg_place()
1151 pg->chunks_count = cfg->states_chunks; in nat64lsn_alloc_proto_pg()
1152 if (pg->chunks_count > 1) { in nat64lsn_alloc_proto_pg()
1153 pg->freemask_chunk = malloc(pg->chunks_count * in nat64lsn_alloc_proto_pg()
1155 if (pg->freemask_chunk == NULL) { in nat64lsn_alloc_proto_pg()
1159 pg->states_chunk = malloc(pg->chunks_count * in nat64lsn_alloc_proto_pg()
1162 if (pg->states_chunk == NULL) { in nat64lsn_alloc_proto_pg()
1163 free(pg->freemask_chunk, M_NAT64LSN); in nat64lsn_alloc_proto_pg()
1167 for (i = 0; i < pg->chunks_count; i++) { in nat64lsn_alloc_proto_pg()
1168 pg->states_chunk[i] = uma_zalloc( in nat64lsn_alloc_proto_pg()
1170 if (pg->states_chunk[i] == NULL) in nat64lsn_alloc_proto_pg()
1173 memset(pg->freemask_chunk, 0xff, in nat64lsn_alloc_proto_pg()
1174 sizeof(uint64_t) * pg->chunks_count); in nat64lsn_alloc_proto_pg()
1176 pg->states = uma_zalloc(nat64lsn_state_zone, M_NOWAIT); in nat64lsn_alloc_proto_pg()
1177 if (pg->states == NULL) { in nat64lsn_alloc_proto_pg()
1181 memset(&pg->freemask64, 0xff, sizeof(uint64_t)); in nat64lsn_alloc_proto_pg()
1185 SET_AGE(pg->timestamp); in nat64lsn_alloc_proto_pg()
1186 pg->flags = 0; in nat64lsn_alloc_proto_pg()
1187 pg->proto = proto; in nat64lsn_alloc_proto_pg()
1188 pg->base_port = NAT64_MIN_PORT + 64 * pg_idx; in nat64lsn_alloc_proto_pg()
1189 ck_pr_store_ptr(&chunks[chunk_idx]->pgptr[pg_idx % 32], pg); in nat64lsn_alloc_proto_pg()
1197 CK_SLIST_INSERT_HEAD(&alias->portgroups, pg, entries); in nat64lsn_alloc_proto_pg()
1198 SET_AGE(alias->timestamp); in nat64lsn_alloc_proto_pg()
1201 NAT64STAT_INC(&cfg->base.stats, spgcreated); in nat64lsn_alloc_proto_pg()
1205 for (i = 0; i < pg->chunks_count; i++) in nat64lsn_alloc_proto_pg()
1206 uma_zfree(nat64lsn_state_zone, pg->states_chunk[i]); in nat64lsn_alloc_proto_pg()
1207 free(pg->freemask_chunk, M_NAT64LSN); in nat64lsn_alloc_proto_pg()
1208 free(pg->states_chunk, M_NAT64LSN); in nat64lsn_alloc_proto_pg()
1220 link = nat64lsn_get_aliaslink(cfg, ji->host, &ji->f_id); in nat64lsn_alloc_pg()
1230 alias = link->alias; in nat64lsn_alloc_pg()
1232 switch (ji->proto) { in nat64lsn_alloc_pg()
1235 &alias->tcp_chunkmask, alias->tcp_pgmask, in nat64lsn_alloc_pg()
1236 alias->tcp, &alias->tcp_pgidx, ji->proto); in nat64lsn_alloc_pg()
1240 &alias->udp_chunkmask, alias->udp_pgmask, in nat64lsn_alloc_pg()
1241 alias->udp, &alias->udp_pgidx, ji->proto); in nat64lsn_alloc_pg()
1245 &alias->icmp_chunkmask, alias->icmp_pgmask, in nat64lsn_alloc_pg()
1246 alias->icmp, &alias->icmp_pgidx, ji->proto); in nat64lsn_alloc_pg()
1249 panic("%s: wrong proto %d", __func__, ji->proto); in nat64lsn_alloc_pg()
1261 ji->state = nat64lsn_get_state6to4(cfg, ji->host, &ji->f_id, in nat64lsn_alloc_pg()
1262 ji->state_hval, ji->faddr, ji->port, ji->proto); in nat64lsn_alloc_pg()
1263 if (ji->state == NULL) in nat64lsn_alloc_pg()
1266 ji->done = 1; in nat64lsn_alloc_pg()
1282 if (cfg->jlen == 0) in nat64lsn_do_request()
1285 CURVNET_SET(cfg->vp); in nat64lsn_do_request()
1290 STAILQ_SWAP(&jhead, &cfg->jhead, nat64lsn_job_item); in nat64lsn_do_request()
1291 jcount = cfg->jlen; in nat64lsn_do_request()
1292 cfg->jlen = 0; in nat64lsn_do_request()
1297 NAT64STAT_INC(&cfg->base.stats, jcalls); in nat64lsn_do_request()
1306 * TODO: Limit per-call number of items in nat64lsn_do_request()
1311 switch (ji->jtype) { in nat64lsn_do_request()
1314 NAT64STAT_INC(&cfg->base.stats, jhostfails); in nat64lsn_do_request()
1318 NAT64STAT_INC(&cfg->base.stats, jportfails); in nat64lsn_do_request()
1323 if (ji->done != 0) { in nat64lsn_do_request()
1324 flags = ji->proto != IPPROTO_TCP ? 0 : in nat64lsn_do_request()
1325 convert_tcp_flags(ji->f_id._flags); in nat64lsn_do_request()
1326 nat64lsn_translate6_internal(cfg, &ji->m, in nat64lsn_do_request()
1327 ji->state, flags); in nat64lsn_do_request()
1328 NAT64STAT_INC(&cfg->base.stats, jreinjected); in nat64lsn_do_request()
1340 m_freem(ji->m); in nat64lsn_do_request()
1357 if (cfg->jlen >= cfg->jmaxlen) in nat64lsn_create_job()
1358 NAT64STAT_INC(&cfg->base.stats, jmaxlen); in nat64lsn_create_job()
1362 NAT64STAT_INC(&cfg->base.stats, jnomem); in nat64lsn_create_job()
1365 NAT64STAT_INC(&cfg->base.stats, dropped); in nat64lsn_create_job()
1368 ji->jtype = jtype; in nat64lsn_create_job()
1369 ji->done = 0; in nat64lsn_create_job()
1379 STAILQ_INSERT_TAIL(&cfg->jhead, ji, entries); in nat64lsn_enqueue_job()
1380 NAT64STAT_INC(&cfg->base.stats, jrequests); in nat64lsn_enqueue_job()
1381 cfg->jlen++; in nat64lsn_enqueue_job()
1383 if (callout_pending(&cfg->jcallout) == 0) in nat64lsn_enqueue_job()
1384 callout_reset(&cfg->jcallout, 1, nat64lsn_do_request, cfg); in nat64lsn_enqueue_job()
1390 * race condition, when host object was deleted, but some translation
1393 * Since the state expiration removes state from host's hash table,
1395 * with this host entry.
1398 nat64lsn_host_cleanup(struct nat64lsn_host *host) in nat64lsn_host_cleanup() argument
1403 printf("NAT64LSN: %s: race condition has been detected for host %p\n", in nat64lsn_host_cleanup()
1404 __func__, host); in nat64lsn_host_cleanup()
1405 for (i = 0; i < host->states_hashsize; i++) { in nat64lsn_host_cleanup()
1406 CK_SLIST_FOREACH_SAFE(state, &host->states_hash[i], in nat64lsn_host_cleanup()
1410 * because this host entry is unlinked and will in nat64lsn_host_cleanup()
1413 CK_SLIST_REMOVE(&host->states_hash[i], state, in nat64lsn_host_cleanup()
1415 host->states_count--; in nat64lsn_host_cleanup()
1419 MPASS(host->states_count == 0); in nat64lsn_host_cleanup()
1427 * Since states entries are accessible via host's hash table, we need
1429 * linked with any host entries.
1440 for (c = 0; c < pg->chunks_count; c++) { in nat64lsn_pg_cleanup()
1450 state = &STATES_CHUNK(pg, c)->state[i]; in nat64lsn_pg_cleanup()
1453 * is already unlinked from host's hash table. in nat64lsn_pg_cleanup()
1457 if (ISSET32(state->flags, NAT64_BIT_STALE)) { in nat64lsn_pg_cleanup()
1464 * linked into host's hash table. in nat64lsn_pg_cleanup()
1469 if (ISSET32(state->flags, NAT64_BIT_READY_IPV4)) { in nat64lsn_pg_cleanup()
1470 struct nat64lsn_host *host; in nat64lsn_pg_cleanup() local
1472 host = state->host; in nat64lsn_pg_cleanup()
1473 HOST_LOCK(host); in nat64lsn_pg_cleanup()
1474 CK_SLIST_REMOVE(&STATE_HASH(host, in nat64lsn_pg_cleanup()
1475 state->hval), state, nat64lsn_state, in nat64lsn_pg_cleanup()
1477 host->states_count--; in nat64lsn_pg_cleanup()
1478 HOST_UNLOCK(host); in nat64lsn_pg_cleanup()
1491 struct nat64lsn_host *host; in nat64lsn_job_destroy() local
1498 MPASS(ji->jtype == JTYPE_DESTROY); in nat64lsn_job_destroy()
1499 while (!CK_SLIST_EMPTY(&ji->hosts)) { in nat64lsn_job_destroy()
1500 host = CK_SLIST_FIRST(&ji->hosts); in nat64lsn_job_destroy()
1501 CK_SLIST_REMOVE_HEAD(&ji->hosts, entries); in nat64lsn_job_destroy()
1502 if (host->states_count > 0) { in nat64lsn_job_destroy()
1504 * The state has been created during host deletion. in nat64lsn_job_destroy()
1506 printf("NAT64LSN: %s: destroying host with %d " in nat64lsn_job_destroy()
1507 "states\n", __func__, host->states_count); in nat64lsn_job_destroy()
1510 * possible access to already deleted host in in nat64lsn_job_destroy()
1513 nat64lsn_host_cleanup(host); in nat64lsn_job_destroy()
1514 CK_SLIST_INSERT_HEAD(&hosts, host, entries); in nat64lsn_job_destroy()
1516 * Keep host entry for next deferred destroying. in nat64lsn_job_destroy()
1522 nat64lsn_destroy_host(host); in nat64lsn_job_destroy()
1524 while (!CK_SLIST_EMPTY(&ji->portgroups)) { in nat64lsn_job_destroy()
1525 pg = CK_SLIST_FIRST(&ji->portgroups); in nat64lsn_job_destroy()
1526 CK_SLIST_REMOVE_HEAD(&ji->portgroups, entries); in nat64lsn_job_destroy()
1527 for (i = 0; i < pg->chunks_count; i++) { in nat64lsn_job_destroy()
1534 "with non-empty chunk %d\n", __func__, in nat64lsn_job_destroy()
1539 i = -1; in nat64lsn_job_destroy()
1543 if (i != -1) in nat64lsn_job_destroy()
1548 uma_zfree(nat64lsn_pgchunk_zone, ji->pgchunk); in nat64lsn_job_destroy()
1554 CK_SLIST_MOVE(&ji->hosts, &hosts, entries); in nat64lsn_job_destroy()
1555 CK_SLIST_MOVE(&ji->portgroups, &portgroups, entries); in nat64lsn_job_destroy()
1556 NAT64LSN_EPOCH_CALL(&ji->epoch_ctx, nat64lsn_job_destroy); in nat64lsn_job_destroy()
1562 in_addr_t faddr, uint16_t port, uint8_t proto) in nat64lsn_request_host() argument
1568 ji->m = *mp; in nat64lsn_request_host()
1569 ji->f_id = *f_id; in nat64lsn_request_host()
1570 ji->faddr = faddr; in nat64lsn_request_host()
1571 ji->port = port; in nat64lsn_request_host()
1572 ji->proto = proto; in nat64lsn_request_host()
1573 ji->src6_hval = hval; in nat64lsn_request_host()
1576 NAT64STAT_INC(&cfg->base.stats, jhostsreq); in nat64lsn_request_host()
1583 nat64lsn_request_pg(struct nat64lsn_cfg *cfg, struct nat64lsn_host *host, in nat64lsn_request_pg() argument
1585 in_addr_t faddr, uint16_t port, uint8_t proto) in nat64lsn_request_pg() argument
1591 ji->m = *mp; in nat64lsn_request_pg()
1592 ji->f_id = *f_id; in nat64lsn_request_pg()
1593 ji->faddr = faddr; in nat64lsn_request_pg()
1594 ji->port = port; in nat64lsn_request_pg()
1595 ji->proto = proto; in nat64lsn_request_pg()
1596 ji->state_hval = hval; in nat64lsn_request_pg()
1597 ji->host = host; in nat64lsn_request_pg()
1600 NAT64STAT_INC(&cfg->base.stats, jportreq); in nat64lsn_request_pg()
1616 if (state->timestamp != ts) in nat64lsn_translate6_internal()
1617 state->timestamp = ts; in nat64lsn_translate6_internal()
1618 if ((state->flags & flags) != 0) in nat64lsn_translate6_internal()
1619 state->flags |= flags; in nat64lsn_translate6_internal()
1621 if (cfg->base.flags & NAT64_LOG) { in nat64lsn_translate6_internal()
1627 ret = nat64_do_handle_ip6(*mp, htonl(state->ip_src), in nat64lsn_translate6_internal()
1628 htons(state->aport), &cfg->base, logdata); in nat64lsn_translate6_internal()
1630 return (cfg->nomatch_verdict); in nat64lsn_translate6_internal()
1641 struct nat64lsn_host *host; in nat64lsn_translate6() local
1645 uint16_t port; in nat64lsn_translate6() local
1649 port = f_id->src_port; in nat64lsn_translate6()
1650 proto = f_id->proto; in nat64lsn_translate6()
1651 switch (f_id->proto) { in nat64lsn_translate6()
1655 * local port. in nat64lsn_translate6()
1660 NAT64STAT_INC(&cfg->base.stats, dropped); in nat64lsn_translate6()
1666 if (icmp6->icmp6_type == ICMP6_ECHO_REQUEST || in nat64lsn_translate6()
1667 icmp6->icmp6_type == ICMP6_ECHO_REPLY) in nat64lsn_translate6()
1668 port = ntohs(icmp6->icmp6_id); in nat64lsn_translate6()
1676 NAT64STAT_INC(&cfg->base.stats, noproto); in nat64lsn_translate6()
1677 return (cfg->nomatch_verdict); in nat64lsn_translate6()
1681 addr = nat64_extract_ip4(&f_id->dst_ip6, cfg->base.plat_plen); in nat64lsn_translate6()
1682 if (addr == 0 || nat64_check_private_ip4(&cfg->base, addr) != 0) { in nat64lsn_translate6()
1685 NAT64STAT_INC(&cfg->base.stats, dropped); in nat64lsn_translate6()
1691 /* Try to find host */ in nat64lsn_translate6()
1692 hval = HOST_HVAL(cfg, &f_id->src_ip6); in nat64lsn_translate6()
1693 CK_SLIST_FOREACH(host, &HOSTS(cfg, hval), entries) { in nat64lsn_translate6()
1694 if (IN6_ARE_ADDR_EQUAL(&f_id->src_ip6, &host->addr)) in nat64lsn_translate6()
1697 /* We use IPv4 address in host byte order */ in nat64lsn_translate6()
1699 if (host == NULL) in nat64lsn_translate6()
1701 hval, addr, port, proto)); in nat64lsn_translate6()
1703 flags = proto != IPPROTO_TCP ? 0 : convert_tcp_flags(f_id->_flags); in nat64lsn_translate6()
1706 data[1] = (f_id->dst_port << 16) | port; in nat64lsn_translate6()
1708 state = nat64lsn_get_state6to4(cfg, host, f_id, hval, addr, in nat64lsn_translate6()
1709 port, proto); in nat64lsn_translate6()
1711 return (nat64lsn_request_pg(cfg, host, f_id, mp, hval, addr, in nat64lsn_translate6()
1712 port, proto)); in nat64lsn_translate6()
1731 if (cmd->opcode != O_EXTERNAL_ACTION || in ipfw_nat64lsn()
1732 insntod(cmd, kidx)->kidx != V_nat64lsn_eid || in ipfw_nat64lsn()
1733 icmd->opcode != O_EXTERNAL_INSTANCE || in ipfw_nat64lsn()
1739 switch (args->f_id.addr_type) { in ipfw_nat64lsn()
1741 ret = nat64lsn_translate4(i->cfg, &args->f_id, &args->m); in ipfw_nat64lsn()
1747 if ((i->cfg->base.flags & NAT64LSN_ANYPREFIX) == 0 && in ipfw_nat64lsn()
1748 memcmp(&args->f_id.dst_ip6, &i->cfg->base.plat_prefix, in ipfw_nat64lsn()
1749 i->cfg->base.plat_plen / 8) != 0) { in ipfw_nat64lsn()
1750 ret = i->cfg->nomatch_verdict; in ipfw_nat64lsn()
1753 ret = nat64lsn_translate6(i->cfg, &args->f_id, &args->m); in ipfw_nat64lsn()
1756 ret = i->cfg->nomatch_verdict; in ipfw_nat64lsn()
1759 if (ret != IP_FW_PASS && args->m != NULL) { in ipfw_nat64lsn()
1760 m_freem(args->m); in ipfw_nat64lsn()
1761 args->m = NULL; in ipfw_nat64lsn()
1774 chunk->state[i].flags = 0; in nat64lsn_state_ctor()
1822 callout_reset(&cfg->periodic, hz * PERIODIC_DELAY, in nat64lsn_start_instance()
1839 STAILQ_INIT(&cfg->jhead); in nat64lsn_init_config()
1840 cfg->vp = curvnet; in nat64lsn_init_config()
1841 COUNTER_ARRAY_ALLOC(cfg->base.stats.cnt, NAT64STATS, M_WAITOK); in nat64lsn_init_config()
1843 cfg->hash_seed = arc4random(); in nat64lsn_init_config()
1844 cfg->hosts_hashsize = NAT64LSN_HOSTS_HSIZE; in nat64lsn_init_config()
1845 cfg->hosts_hash = malloc(sizeof(struct nat64lsn_hosts_slist) * in nat64lsn_init_config()
1846 cfg->hosts_hashsize, M_NAT64LSN, M_WAITOK | M_ZERO); in nat64lsn_init_config()
1847 for (i = 0; i < cfg->hosts_hashsize; i++) in nat64lsn_init_config()
1848 CK_SLIST_INIT(&cfg->hosts_hash[i]); in nat64lsn_init_config()
1850 naddr = 1 << (32 - plen); in nat64lsn_init_config()
1851 cfg->prefix4 = prefix; in nat64lsn_init_config()
1852 cfg->pmask4 = prefix | (naddr - 1); in nat64lsn_init_config()
1853 cfg->plen4 = plen; in nat64lsn_init_config()
1854 cfg->aliases = malloc(sizeof(struct nat64lsn_alias) * naddr, in nat64lsn_init_config()
1857 alias = &cfg->aliases[i]; in nat64lsn_init_config()
1858 alias->addr = prefix + i; /* host byte order */ in nat64lsn_init_config()
1859 CK_SLIST_INIT(&alias->hosts); in nat64lsn_init_config()
1863 callout_init_mtx(&cfg->periodic, &cfg->periodic_lock, 0); in nat64lsn_init_config()
1864 callout_init(&cfg->jcallout, CALLOUT_MPSAFE); in nat64lsn_init_config()
1874 if (pg->chunks_count == 1) { in nat64lsn_destroy_pg()
1875 uma_zfree(nat64lsn_state_zone, pg->states); in nat64lsn_destroy_pg()
1877 for (i = 0; i < pg->chunks_count; i++) in nat64lsn_destroy_pg()
1878 uma_zfree(nat64lsn_state_zone, pg->states_chunk[i]); in nat64lsn_destroy_pg()
1879 free(pg->states_chunk, M_NAT64LSN); in nat64lsn_destroy_pg()
1880 free(pg->freemask_chunk, M_NAT64LSN); in nat64lsn_destroy_pg()
1892 while (!CK_SLIST_EMPTY(&alias->portgroups)) { in nat64lsn_destroy_alias()
1893 pg = CK_SLIST_FIRST(&alias->portgroups); in nat64lsn_destroy_alias()
1894 CK_SLIST_REMOVE_HEAD(&alias->portgroups, entries); in nat64lsn_destroy_alias()
1898 if (ISSET32(alias->tcp_chunkmask, i)) in nat64lsn_destroy_alias()
1899 uma_zfree(nat64lsn_pgchunk_zone, alias->tcp[i]); in nat64lsn_destroy_alias()
1900 if (ISSET32(alias->udp_chunkmask, i)) in nat64lsn_destroy_alias()
1901 uma_zfree(nat64lsn_pgchunk_zone, alias->udp[i]); in nat64lsn_destroy_alias()
1902 if (ISSET32(alias->icmp_chunkmask, i)) in nat64lsn_destroy_alias()
1903 uma_zfree(nat64lsn_pgchunk_zone, alias->icmp[i]); in nat64lsn_destroy_alias()
1909 nat64lsn_destroy_host(struct nat64lsn_host *host) in nat64lsn_destroy_host() argument
1913 while (!CK_SLIST_EMPTY(&host->aliases)) { in nat64lsn_destroy_host()
1914 link = CK_SLIST_FIRST(&host->aliases); in nat64lsn_destroy_host()
1915 CK_SLIST_REMOVE_HEAD(&host->aliases, host_entries); in nat64lsn_destroy_host()
1917 ALIAS_LOCK(link->alias); in nat64lsn_destroy_host()
1918 CK_SLIST_REMOVE(&link->alias->hosts, link, in nat64lsn_destroy_host()
1920 link->alias->hosts_count--; in nat64lsn_destroy_host()
1921 ALIAS_UNLOCK(link->alias); in nat64lsn_destroy_host()
1925 HOST_LOCK_DESTROY(host); in nat64lsn_destroy_host()
1926 free(host->states_hash, M_NAT64LSN); in nat64lsn_destroy_host()
1927 uma_zfree(nat64lsn_host_zone, host); in nat64lsn_destroy_host()
1933 struct nat64lsn_host *host; in nat64lsn_destroy_config() local
1937 callout_drain(&cfg->periodic); in nat64lsn_destroy_config()
1939 callout_drain(&cfg->jcallout); in nat64lsn_destroy_config()
1941 for (i = 0; i < cfg->hosts_hashsize; i++) { in nat64lsn_destroy_config()
1942 while (!CK_SLIST_EMPTY(&cfg->hosts_hash[i])) { in nat64lsn_destroy_config()
1943 host = CK_SLIST_FIRST(&cfg->hosts_hash[i]); in nat64lsn_destroy_config()
1944 CK_SLIST_REMOVE_HEAD(&cfg->hosts_hash[i], entries); in nat64lsn_destroy_config()
1945 nat64lsn_destroy_host(host); in nat64lsn_destroy_config()
1949 for (i = 0; i < (1 << (32 - cfg->plen4)); i++) in nat64lsn_destroy_config()
1950 nat64lsn_destroy_alias(cfg, &cfg->aliases[i]); in nat64lsn_destroy_config()
1954 COUNTER_ARRAY_FREE(cfg->base.stats.cnt, NAT64STATS); in nat64lsn_destroy_config()
1955 free(cfg->hosts_hash, M_NAT64LSN); in nat64lsn_destroy_config()
1956 free(cfg->aliases, M_NAT64LSN); in nat64lsn_destroy_config()