1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
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>
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 * 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 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.
28 */
29
30#ifndef	_IP_FW_NAT64LSN_H_
31#define	_IP_FW_NAT64LSN_H_
32
33#include "ip_fw_nat64.h"
34#include "nat64_translate.h"
35
36#define	NAT64_MIN_PORT		1024
37struct nat64lsn_host;
38struct nat64lsn_alias;
39
40struct nat64lsn_state {
41	/* IPv6 host entry keeps hash table to speedup state lookup */
42	CK_SLIST_ENTRY(nat64lsn_state)	entries;
43	struct nat64lsn_host	*host;
44
45	struct in6_addr	ip6_dst;	/* Destination IPv6 address */
46
47	in_addr_t	ip_src;		/* Alias IPv4 address */
48	in_addr_t	ip_dst;		/* Destination IPv4 address */
49	uint16_t	dport;		/* Destination port */
50	uint16_t	sport;		/* Source port */
51
52	uint32_t	hval;
53	uint32_t	flags;		/* Internal flags */
54	uint16_t	aport;
55	uint16_t	timestamp;	/* last used */
56	uint8_t		proto;
57	uint8_t		_spare[7];
58};
59
60struct nat64lsn_states_chunk {
61	struct nat64lsn_state	state[64];
62};
63
64#define	ISSET64(mask, bit)	((mask) & ((uint64_t)1 << (bit)))
65#define	ISSET32(mask, bit)	((mask) & ((uint32_t)1 << (bit)))
66struct nat64lsn_pg {
67	CK_SLIST_ENTRY(nat64lsn_pg)	entries;
68
69	uint16_t		base_port;
70	uint16_t		timestamp;
71	uint8_t			proto;
72	uint8_t			chunks_count;
73	uint8_t			spare[2];
74
75	union {
76		uint64_t	freemask64;
77		uint32_t	freemask32[2];
78		uint64_t	*freemask64_chunk;
79		uint32_t	*freemask32_chunk;
80		void		*freemask_chunk;
81	};
82	union {
83		struct nat64lsn_states_chunk *states;
84		struct nat64lsn_states_chunk **states_chunk;
85	};
86};
87
88#define	CHUNK_BY_FADDR(p, a)	((a) & ((p)->chunks_count - 1))
89
90#ifdef __LP64__
91#define	FREEMASK_CHUNK(p, v)	\
92    ((p)->chunks_count == 1 ? &(p)->freemask64 : \
93	&(p)->freemask64_chunk[CHUNK_BY_FADDR(p, v)])
94#define	FREEMASK_BITCOUNT(pg, faddr)	\
95    bitcount64(*FREEMASK_CHUNK((pg), (faddr)))
96#else
97#define	FREEMASK_CHUNK(p, v)	\
98    ((p)->chunks_count == 1 ? &(p)->freemask32[0] : \
99	&(p)->freemask32_chunk[CHUNK_BY_FADDR(p, v) * 2])
100#define	FREEMASK_BITCOUNT(pg, faddr)	\
101    bitcount64(*(uint64_t *)FREEMASK_CHUNK((pg), (faddr)))
102#endif /* !__LP64__ */
103
104struct nat64lsn_pgchunk {
105	struct nat64lsn_pg	*pgptr[32];
106};
107
108struct nat64lsn_aliaslink {
109	CK_SLIST_ENTRY(nat64lsn_aliaslink)	alias_entries;
110	CK_SLIST_ENTRY(nat64lsn_aliaslink)	host_entries;
111	struct nat64lsn_alias	*alias;
112};
113
114CK_SLIST_HEAD(nat64lsn_aliaslink_slist, nat64lsn_aliaslink);
115CK_SLIST_HEAD(nat64lsn_states_slist, nat64lsn_state);
116CK_SLIST_HEAD(nat64lsn_hosts_slist, nat64lsn_host);
117CK_SLIST_HEAD(nat64lsn_pg_slist, nat64lsn_pg);
118
119struct nat64lsn_alias {
120	struct nat64lsn_aliaslink_slist	hosts;
121	struct nat64lsn_pg_slist	portgroups;
122
123	struct mtx		lock;
124	in_addr_t		addr;	/* host byte order */
125	uint32_t		hosts_count;
126	uint32_t		portgroups_count;
127	uint32_t		tcp_chunkmask;
128	uint32_t		udp_chunkmask;
129	uint32_t		icmp_chunkmask;
130
131	uint32_t		tcp_pgidx;
132	uint32_t		udp_pgidx;
133	uint32_t		icmp_pgidx;
134	uint16_t		timestamp;
135	uint16_t		spare;
136
137	uint32_t		tcp_pgmask[32];
138	uint32_t		udp_pgmask[32];
139	uint32_t		icmp_pgmask[32];
140	struct nat64lsn_pgchunk	*tcp[32];
141	struct nat64lsn_pgchunk	*udp[32];
142	struct nat64lsn_pgchunk	*icmp[32];
143
144	/* pointer to PG that can be used for faster state allocation */
145	struct nat64lsn_pg	*tcp_pg;
146	struct nat64lsn_pg	*udp_pg;
147	struct nat64lsn_pg	*icmp_pg;
148};
149#define	ALIAS_LOCK_INIT(p)	\
150	mtx_init(&(p)->lock, "alias_lock", NULL, MTX_DEF)
151#define	ALIAS_LOCK_DESTROY(p)	mtx_destroy(&(p)->lock)
152#define	ALIAS_LOCK(p)		mtx_lock(&(p)->lock)
153#define	ALIAS_UNLOCK(p)		mtx_unlock(&(p)->lock)
154
155#define	NAT64LSN_HSIZE		256
156#define	NAT64LSN_MAX_HSIZE	4096
157#define	NAT64LSN_HOSTS_HSIZE	1024
158
159struct nat64lsn_host {
160	struct in6_addr		addr;
161	struct nat64lsn_aliaslink_slist	aliases;
162	struct nat64lsn_states_slist	*states_hash;
163	CK_SLIST_ENTRY(nat64lsn_host)	entries;
164	uint32_t		states_count;
165	uint32_t		hval;
166	uint32_t		flags;
167#define	NAT64LSN_DEADHOST	1
168#define	NAT64LSN_GROWHASH	2
169	uint16_t		states_hashsize;
170	uint16_t		timestamp;
171	struct mtx		lock;
172};
173
174#define	HOST_LOCK_INIT(p)	\
175	mtx_init(&(p)->lock, "host_lock", NULL, MTX_DEF|MTX_NEW)
176#define	HOST_LOCK_DESTROY(p)	mtx_destroy(&(p)->lock)
177#define	HOST_LOCK(p)		mtx_lock(&(p)->lock)
178#define	HOST_UNLOCK(p)		mtx_unlock(&(p)->lock)
179
180VNET_DECLARE(uint16_t, nat64lsn_eid);
181#define	V_nat64lsn_eid		VNET(nat64lsn_eid)
182#define	IPFW_TLV_NAT64LSN_NAME	IPFW_TLV_EACTION_NAME(V_nat64lsn_eid)
183
184/* Timestamp macro */
185#define	_CT		((int)time_uptime % 65536)
186#define	SET_AGE(x)	(x) = _CT
187#define	GET_AGE(x)	((_CT >= (x)) ? _CT - (x): (int)65536 + _CT - (x))
188
189STAILQ_HEAD(nat64lsn_job_head, nat64lsn_job_item);
190
191struct nat64lsn_cfg {
192	struct named_object	no;
193
194	struct nat64lsn_hosts_slist	*hosts_hash;
195	struct nat64lsn_alias	*aliases;	/* array of aliases */
196
197	struct mtx	lock;
198	uint32_t	hosts_hashsize;
199	uint32_t	hash_seed;
200
201	uint32_t	prefix4;	/* IPv4 prefix */
202	uint32_t	pmask4;		/* IPv4 prefix mask */
203	uint8_t		plen4;
204	uint8_t		nomatch_verdict;/* Return value on no-match */
205
206	uint32_t	hosts_count;	/* Number of items in host hash */
207	uint32_t	states_chunks;	/* Number of states chunks per PG */
208	uint32_t	jmaxlen;	/* Max jobqueue length */
209	uint16_t	host_delete_delay;	/* Stale host delete delay */
210	uint16_t	pgchunk_delete_delay;
211	uint16_t	pg_delete_delay;	/* Stale portgroup del delay */
212	uint16_t	st_syn_ttl;	/* TCP syn expire */
213	uint16_t	st_close_ttl;	/* TCP fin expire */
214	uint16_t	st_estab_ttl;	/* TCP established expire */
215	uint16_t	st_udp_ttl;	/* UDP expire */
216	uint16_t	st_icmp_ttl;	/* ICMP expire */
217
218	struct nat64_config	base;
219#define	NAT64LSN_FLAGSMASK	(NAT64_LOG | NAT64_ALLOW_PRIVATE)
220#define	NAT64LSN_ANYPREFIX	0x00000100
221
222	struct mtx		periodic_lock;
223	struct callout		periodic;
224	struct callout		jcallout;
225	struct vnet		*vp;
226	struct nat64lsn_job_head	jhead;
227	int			jlen;
228	char			name[64];	/* Nat instance name */
229};
230
231/* CFG_LOCK protects cfg->hosts_hash from modification */
232#define	CFG_LOCK_INIT(p)	\
233	mtx_init(&(p)->lock, "cfg_lock", NULL, MTX_DEF)
234#define	CFG_LOCK_DESTROY(p)	mtx_destroy(&(p)->lock)
235#define	CFG_LOCK(p)		mtx_lock(&(p)->lock)
236#define	CFG_UNLOCK(p)		mtx_unlock(&(p)->lock)
237
238#define	CALLOUT_LOCK_INIT(p)	\
239	mtx_init(&(p)->periodic_lock, "periodic_lock", NULL, MTX_DEF)
240#define	CALLOUT_LOCK_DESTROY(p)	mtx_destroy(&(p)->periodic_lock)
241#define	CALLOUT_LOCK(p)		mtx_lock(&(p)->periodic_lock)
242#define	CALLOUT_UNLOCK(p)	mtx_unlock(&(p)->periodic_lock)
243
244struct nat64lsn_cfg *nat64lsn_init_instance(struct ip_fw_chain *ch,
245    in_addr_t prefix, int plen);
246void nat64lsn_destroy_instance(struct nat64lsn_cfg *cfg);
247void nat64lsn_start_instance(struct nat64lsn_cfg *cfg);
248void nat64lsn_init_internal(void);
249void nat64lsn_uninit_internal(void);
250int ipfw_nat64lsn(struct ip_fw_chain *ch, struct ip_fw_args *args,
251    ipfw_insn *cmd, int *done);
252
253#endif /* _IP_FW_NAT64LSN_H_ */
254