2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2015-2019 Yandex LLC
5 * Copyright (c) 2015 Alexander V. Chernikov <melifaro@FreeBSD.org>
6 * Copyright (c) 2015-2019 Andrey V. Elsukov <ae@FreeBSD.org>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #ifndef _IP_FW_NAT64LSN_H_
33 #define _IP_FW_NAT64LSN_H_
35 #include "ip_fw_nat64.h"
36 #include "nat64_translate.h"
38 #define NAT64_MIN_PORT 1024
40 struct nat64lsn_alias;
42 struct nat64lsn_state {
43 /* IPv6 host entry keeps hash table to speedup state lookup */
44 CK_SLIST_ENTRY(nat64lsn_state) entries;
45 struct nat64lsn_host *host;
47 struct in6_addr ip6_dst; /* Destination IPv6 address */
49 in_addr_t ip_src; /* Alias IPv4 address */
50 in_addr_t ip_dst; /* Destination IPv4 address */
51 uint16_t dport; /* Destination port */
52 uint16_t sport; /* Source port */
55 uint32_t flags; /* Internal flags */
57 uint16_t timestamp; /* last used */
62 struct nat64lsn_states_chunk {
63 struct nat64lsn_state state[64];
66 #define ISSET64(mask, bit) ((mask) & ((uint64_t)1 << (bit)))
67 #define ISSET32(mask, bit) ((mask) & ((uint32_t)1 << (bit)))
69 CK_SLIST_ENTRY(nat64lsn_pg) entries;
79 uint32_t freemask32[2];
80 uint64_t *freemask64_chunk;
81 uint32_t *freemask32_chunk;
85 struct nat64lsn_states_chunk *states;
86 struct nat64lsn_states_chunk **states_chunk;
90 #define CHUNK_BY_FADDR(p, a) ((a) & ((p)->chunks_count - 1))
93 #define FREEMASK_CHUNK(p, v) \
94 ((p)->chunks_count == 1 ? &(p)->freemask64 : \
95 &(p)->freemask64_chunk[CHUNK_BY_FADDR(p, v)])
96 #define FREEMASK_BITCOUNT(pg, faddr) \
97 bitcount64(*FREEMASK_CHUNK((pg), (faddr)))
99 #define FREEMASK_CHUNK(p, v) \
100 ((p)->chunks_count == 1 ? &(p)->freemask32[0] : \
101 &(p)->freemask32_chunk[CHUNK_BY_FADDR(p, v) * 2])
102 #define FREEMASK_BITCOUNT(pg, faddr) \
103 bitcount64(*(uint64_t *)FREEMASK_CHUNK((pg), (faddr)))
104 #endif /* !__LP64__ */
106 struct nat64lsn_pgchunk {
107 struct nat64lsn_pg *pgptr[32];
110 struct nat64lsn_aliaslink {
111 CK_SLIST_ENTRY(nat64lsn_aliaslink) alias_entries;
112 CK_SLIST_ENTRY(nat64lsn_aliaslink) host_entries;
113 struct nat64lsn_alias *alias;
116 CK_SLIST_HEAD(nat64lsn_aliaslink_slist, nat64lsn_aliaslink);
117 CK_SLIST_HEAD(nat64lsn_states_slist, nat64lsn_state);
118 CK_SLIST_HEAD(nat64lsn_hosts_slist, nat64lsn_host);
119 CK_SLIST_HEAD(nat64lsn_pg_slist, nat64lsn_pg);
121 struct nat64lsn_alias {
122 struct nat64lsn_aliaslink_slist hosts;
123 struct nat64lsn_pg_slist portgroups;
126 in_addr_t addr; /* host byte order */
127 uint32_t hosts_count;
128 uint32_t portgroups_count;
129 uint32_t tcp_chunkmask;
130 uint32_t udp_chunkmask;
131 uint32_t icmp_chunkmask;
139 uint32_t tcp_pgmask[32];
140 uint32_t udp_pgmask[32];
141 uint32_t icmp_pgmask[32];
142 struct nat64lsn_pgchunk *tcp[32];
143 struct nat64lsn_pgchunk *udp[32];
144 struct nat64lsn_pgchunk *icmp[32];
146 /* pointer to PG that can be used for faster state allocation */
147 struct nat64lsn_pg *tcp_pg;
148 struct nat64lsn_pg *udp_pg;
149 struct nat64lsn_pg *icmp_pg;
151 #define ALIAS_LOCK_INIT(p) \
152 mtx_init(&(p)->lock, "alias_lock", NULL, MTX_DEF)
153 #define ALIAS_LOCK_DESTROY(p) mtx_destroy(&(p)->lock)
154 #define ALIAS_LOCK(p) mtx_lock(&(p)->lock)
155 #define ALIAS_UNLOCK(p) mtx_unlock(&(p)->lock)
157 #define NAT64LSN_HSIZE 256
158 #define NAT64LSN_MAX_HSIZE 4096
159 #define NAT64LSN_HOSTS_HSIZE 1024
161 struct nat64lsn_host {
162 struct in6_addr addr;
163 struct nat64lsn_aliaslink_slist aliases;
164 struct nat64lsn_states_slist *states_hash;
165 CK_SLIST_ENTRY(nat64lsn_host) entries;
166 uint32_t states_count;
169 #define NAT64LSN_DEADHOST 1
170 #define NAT64LSN_GROWHASH 2
171 uint16_t states_hashsize;
176 #define HOST_LOCK_INIT(p) \
177 mtx_init(&(p)->lock, "host_lock", NULL, MTX_DEF|MTX_NEW)
178 #define HOST_LOCK_DESTROY(p) mtx_destroy(&(p)->lock)
179 #define HOST_LOCK(p) mtx_lock(&(p)->lock)
180 #define HOST_UNLOCK(p) mtx_unlock(&(p)->lock)
182 VNET_DECLARE(uint16_t, nat64lsn_eid);
183 #define V_nat64lsn_eid VNET(nat64lsn_eid)
184 #define IPFW_TLV_NAT64LSN_NAME IPFW_TLV_EACTION_NAME(V_nat64lsn_eid)
186 /* Timestamp macro */
187 #define _CT ((int)time_uptime % 65536)
188 #define SET_AGE(x) (x) = _CT
189 #define GET_AGE(x) ((_CT >= (x)) ? _CT - (x): (int)65536 + _CT - (x))
191 STAILQ_HEAD(nat64lsn_job_head, nat64lsn_job_item);
193 struct nat64lsn_cfg {
194 struct named_object no;
196 struct nat64lsn_hosts_slist *hosts_hash;
197 struct nat64lsn_alias *aliases; /* array of aliases */
200 uint32_t hosts_hashsize;
203 uint32_t prefix4; /* IPv4 prefix */
204 uint32_t pmask4; /* IPv4 prefix mask */
206 uint8_t nomatch_verdict;/* Return value on no-match */
208 uint32_t hosts_count; /* Number of items in host hash */
209 uint32_t states_chunks; /* Number of states chunks per PG */
210 uint32_t jmaxlen; /* Max jobqueue length */
211 uint16_t host_delete_delay; /* Stale host delete delay */
212 uint16_t pgchunk_delete_delay;
213 uint16_t pg_delete_delay; /* Stale portgroup del delay */
214 uint16_t st_syn_ttl; /* TCP syn expire */
215 uint16_t st_close_ttl; /* TCP fin expire */
216 uint16_t st_estab_ttl; /* TCP established expire */
217 uint16_t st_udp_ttl; /* UDP expire */
218 uint16_t st_icmp_ttl; /* ICMP expire */
220 struct nat64_config base;
221 #define NAT64LSN_FLAGSMASK (NAT64_LOG | NAT64_ALLOW_PRIVATE)
222 #define NAT64LSN_ANYPREFIX 0x00000100
224 struct mtx periodic_lock;
225 struct callout periodic;
226 struct callout jcallout;
228 struct nat64lsn_job_head jhead;
230 char name[64]; /* Nat instance name */
233 /* CFG_LOCK protects cfg->hosts_hash from modification */
234 #define CFG_LOCK_INIT(p) \
235 mtx_init(&(p)->lock, "cfg_lock", NULL, MTX_DEF)
236 #define CFG_LOCK_DESTROY(p) mtx_destroy(&(p)->lock)
237 #define CFG_LOCK(p) mtx_lock(&(p)->lock)
238 #define CFG_UNLOCK(p) mtx_unlock(&(p)->lock)
240 #define CALLOUT_LOCK_INIT(p) \
241 mtx_init(&(p)->periodic_lock, "periodic_lock", NULL, MTX_DEF)
242 #define CALLOUT_LOCK_DESTROY(p) mtx_destroy(&(p)->periodic_lock)
243 #define CALLOUT_LOCK(p) mtx_lock(&(p)->periodic_lock)
244 #define CALLOUT_UNLOCK(p) mtx_unlock(&(p)->periodic_lock)
246 struct nat64lsn_cfg *nat64lsn_init_instance(struct ip_fw_chain *ch,
247 in_addr_t prefix, int plen);
248 void nat64lsn_destroy_instance(struct nat64lsn_cfg *cfg);
249 void nat64lsn_start_instance(struct nat64lsn_cfg *cfg);
250 void nat64lsn_init_internal(void);
251 void nat64lsn_uninit_internal(void);
252 int ipfw_nat64lsn(struct ip_fw_chain *ch, struct ip_fw_args *args,
253 ipfw_insn *cmd, int *done);
255 #endif /* _IP_FW_NAT64LSN_H_ */