xref: /freebsd/sys/netpfil/ipfw/nat64/nat64lsn.h (revision 4a77657cbc011ea657ccb079fff6b58b295eccb0)
1d8caf56eSAndrey V. Elsukov /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3002cae78SAndrey V. Elsukov  *
4*4a77657cSAndrey V. Elsukov  * Copyright (c) 2015-2020 Yandex LLC
5d8caf56eSAndrey V. Elsukov  * Copyright (c) 2015 Alexander V. Chernikov <melifaro@FreeBSD.org>
6*4a77657cSAndrey V. Elsukov  * Copyright (c) 2015-2020 Andrey V. Elsukov <ae@FreeBSD.org>
7d8caf56eSAndrey V. Elsukov  *
8d8caf56eSAndrey V. Elsukov  * Redistribution and use in source and binary forms, with or without
9d8caf56eSAndrey V. Elsukov  * modification, are permitted provided that the following conditions
10d8caf56eSAndrey V. Elsukov  * are met:
11d8caf56eSAndrey V. Elsukov  *
12d8caf56eSAndrey V. Elsukov  * 1. Redistributions of source code must retain the above copyright
13d8caf56eSAndrey V. Elsukov  *    notice, this list of conditions and the following disclaimer.
14d8caf56eSAndrey V. Elsukov  * 2. Redistributions in binary form must reproduce the above copyright
15d8caf56eSAndrey V. Elsukov  *    notice, this list of conditions and the following disclaimer in the
16d8caf56eSAndrey V. Elsukov  *    documentation and/or other materials provided with the distribution.
17d8caf56eSAndrey V. Elsukov  *
18d8caf56eSAndrey V. Elsukov  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19d8caf56eSAndrey V. Elsukov  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20d8caf56eSAndrey V. Elsukov  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21d8caf56eSAndrey V. Elsukov  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22d8caf56eSAndrey V. Elsukov  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23d8caf56eSAndrey V. Elsukov  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24d8caf56eSAndrey V. Elsukov  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25d8caf56eSAndrey V. Elsukov  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26d8caf56eSAndrey V. Elsukov  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27d8caf56eSAndrey V. Elsukov  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28d8caf56eSAndrey V. Elsukov  */
29d8caf56eSAndrey V. Elsukov 
30d8caf56eSAndrey V. Elsukov #ifndef	_IP_FW_NAT64LSN_H_
31d8caf56eSAndrey V. Elsukov #define	_IP_FW_NAT64LSN_H_
32d8caf56eSAndrey V. Elsukov 
33782360deSAndrey V. Elsukov #include "ip_fw_nat64.h"
34782360deSAndrey V. Elsukov #include "nat64_translate.h"
35782360deSAndrey V. Elsukov 
36d8caf56eSAndrey V. Elsukov #define	NAT64_MIN_PORT		1024
37d18c1f26SAndrey V. Elsukov struct nat64lsn_host;
38d18c1f26SAndrey V. Elsukov struct nat64lsn_alias;
39d8caf56eSAndrey V. Elsukov 
40d18c1f26SAndrey V. Elsukov struct nat64lsn_state {
41d18c1f26SAndrey V. Elsukov 	/* IPv6 host entry keeps hash table to speedup state lookup */
42d18c1f26SAndrey V. Elsukov 	CK_SLIST_ENTRY(nat64lsn_state)	entries;
43d18c1f26SAndrey V. Elsukov 	struct nat64lsn_host	*host;
44d18c1f26SAndrey V. Elsukov 
45d18c1f26SAndrey V. Elsukov 	struct in6_addr	ip6_dst;	/* Destination IPv6 address */
46d18c1f26SAndrey V. Elsukov 
47d18c1f26SAndrey V. Elsukov 	in_addr_t	ip_src;		/* Alias IPv4 address */
48d18c1f26SAndrey V. Elsukov 	in_addr_t	ip_dst;		/* Destination IPv4 address */
49d18c1f26SAndrey V. Elsukov 	uint16_t	dport;		/* Destination port */
50d18c1f26SAndrey V. Elsukov 	uint16_t	sport;		/* Source port */
51d18c1f26SAndrey V. Elsukov 
52d18c1f26SAndrey V. Elsukov 	uint32_t	hval;
53d18c1f26SAndrey V. Elsukov 	uint32_t	flags;		/* Internal flags */
54d18c1f26SAndrey V. Elsukov 	uint16_t	aport;
55d18c1f26SAndrey V. Elsukov 	uint16_t	timestamp;	/* last used */
56d18c1f26SAndrey V. Elsukov 	uint8_t		proto;
57d18c1f26SAndrey V. Elsukov 	uint8_t		_spare[7];
58d8caf56eSAndrey V. Elsukov };
59d8caf56eSAndrey V. Elsukov 
60d18c1f26SAndrey V. Elsukov struct nat64lsn_states_chunk {
61d18c1f26SAndrey V. Elsukov 	struct nat64lsn_state	state[64];
62d18c1f26SAndrey V. Elsukov };
63d18c1f26SAndrey V. Elsukov 
64d18c1f26SAndrey V. Elsukov #define	ISSET64(mask, bit)	((mask) & ((uint64_t)1 << (bit)))
65d18c1f26SAndrey V. Elsukov #define	ISSET32(mask, bit)	((mask) & ((uint32_t)1 << (bit)))
66d18c1f26SAndrey V. Elsukov struct nat64lsn_pg {
67d18c1f26SAndrey V. Elsukov 	uint16_t		base_port;
68d18c1f26SAndrey V. Elsukov 	uint16_t		timestamp;
69d18c1f26SAndrey V. Elsukov 	uint8_t			proto;
70d18c1f26SAndrey V. Elsukov 	uint8_t			chunks_count;
71*4a77657cSAndrey V. Elsukov 	uint16_t		flags;
72*4a77657cSAndrey V. Elsukov #define	NAT64LSN_DEADPG		1
73d18c1f26SAndrey V. Elsukov 
74d18c1f26SAndrey V. Elsukov 	union {
75d18c1f26SAndrey V. Elsukov 		uint64_t	freemask64;
76d18c1f26SAndrey V. Elsukov 		uint32_t	freemask32[2];
77d18c1f26SAndrey V. Elsukov 		uint64_t	*freemask64_chunk;
78d18c1f26SAndrey V. Elsukov 		uint32_t	*freemask32_chunk;
79d18c1f26SAndrey V. Elsukov 		void		*freemask_chunk;
80d18c1f26SAndrey V. Elsukov 	};
81d18c1f26SAndrey V. Elsukov 	union {
82d18c1f26SAndrey V. Elsukov 		struct nat64lsn_states_chunk *states;
83d18c1f26SAndrey V. Elsukov 		struct nat64lsn_states_chunk **states_chunk;
84d18c1f26SAndrey V. Elsukov 	};
85*4a77657cSAndrey V. Elsukov 	/*
86*4a77657cSAndrey V. Elsukov 	 * An alias object holds chain of all allocated PGs.
87*4a77657cSAndrey V. Elsukov 	 * The chain is used mostly by expiration code.
88*4a77657cSAndrey V. Elsukov 	 */
89*4a77657cSAndrey V. Elsukov 	CK_SLIST_ENTRY(nat64lsn_pg)	entries;
90d18c1f26SAndrey V. Elsukov };
91d18c1f26SAndrey V. Elsukov 
92d18c1f26SAndrey V. Elsukov #define	CHUNK_BY_FADDR(p, a)	((a) & ((p)->chunks_count - 1))
93d18c1f26SAndrey V. Elsukov 
94d18c1f26SAndrey V. Elsukov #ifdef __LP64__
95d18c1f26SAndrey V. Elsukov #define	FREEMASK_CHUNK(p, v)	\
96d18c1f26SAndrey V. Elsukov     ((p)->chunks_count == 1 ? &(p)->freemask64 : \
97d18c1f26SAndrey V. Elsukov 	&(p)->freemask64_chunk[CHUNK_BY_FADDR(p, v)])
98d18c1f26SAndrey V. Elsukov #define	FREEMASK_BITCOUNT(pg, faddr)	\
99d18c1f26SAndrey V. Elsukov     bitcount64(*FREEMASK_CHUNK((pg), (faddr)))
100d18c1f26SAndrey V. Elsukov #else
101d18c1f26SAndrey V. Elsukov #define	FREEMASK_CHUNK(p, v)	\
102d18c1f26SAndrey V. Elsukov     ((p)->chunks_count == 1 ? &(p)->freemask32[0] : \
103d18c1f26SAndrey V. Elsukov 	&(p)->freemask32_chunk[CHUNK_BY_FADDR(p, v) * 2])
104d18c1f26SAndrey V. Elsukov #define	FREEMASK_BITCOUNT(pg, faddr)	\
105d18c1f26SAndrey V. Elsukov     bitcount64(*(uint64_t *)FREEMASK_CHUNK((pg), (faddr)))
106d18c1f26SAndrey V. Elsukov #endif /* !__LP64__ */
107d18c1f26SAndrey V. Elsukov 
108d18c1f26SAndrey V. Elsukov struct nat64lsn_pgchunk {
109d18c1f26SAndrey V. Elsukov 	struct nat64lsn_pg	*pgptr[32];
110d18c1f26SAndrey V. Elsukov };
111d18c1f26SAndrey V. Elsukov 
112d18c1f26SAndrey V. Elsukov struct nat64lsn_aliaslink {
113d18c1f26SAndrey V. Elsukov 	CK_SLIST_ENTRY(nat64lsn_aliaslink)	alias_entries;
114d18c1f26SAndrey V. Elsukov 	CK_SLIST_ENTRY(nat64lsn_aliaslink)	host_entries;
115d18c1f26SAndrey V. Elsukov 	struct nat64lsn_alias	*alias;
116d18c1f26SAndrey V. Elsukov };
117d18c1f26SAndrey V. Elsukov 
118d18c1f26SAndrey V. Elsukov CK_SLIST_HEAD(nat64lsn_aliaslink_slist, nat64lsn_aliaslink);
119d18c1f26SAndrey V. Elsukov CK_SLIST_HEAD(nat64lsn_states_slist, nat64lsn_state);
120d18c1f26SAndrey V. Elsukov CK_SLIST_HEAD(nat64lsn_hosts_slist, nat64lsn_host);
121d18c1f26SAndrey V. Elsukov CK_SLIST_HEAD(nat64lsn_pg_slist, nat64lsn_pg);
122d18c1f26SAndrey V. Elsukov 
123d18c1f26SAndrey V. Elsukov struct nat64lsn_alias {
124d18c1f26SAndrey V. Elsukov 	struct nat64lsn_aliaslink_slist	hosts;
125d18c1f26SAndrey V. Elsukov 	struct nat64lsn_pg_slist	portgroups;
126d18c1f26SAndrey V. Elsukov 
127d18c1f26SAndrey V. Elsukov 	struct mtx		lock;
128d18c1f26SAndrey V. Elsukov 	in_addr_t		addr;	/* host byte order */
129d18c1f26SAndrey V. Elsukov 	uint32_t		hosts_count;
130d18c1f26SAndrey V. Elsukov 
131d18c1f26SAndrey V. Elsukov 	uint16_t		timestamp;
132*4a77657cSAndrey V. Elsukov 	uint16_t		tcp_pgcount;
133*4a77657cSAndrey V. Elsukov 	uint16_t		udp_pgcount;
134*4a77657cSAndrey V. Elsukov 	uint16_t		icmp_pgcount;
135*4a77657cSAndrey V. Elsukov 	/*
136*4a77657cSAndrey V. Elsukov 	 * We keep PGs in chunks by 32 PGs in each.
137*4a77657cSAndrey V. Elsukov 	 * Each chunk allocated by demand, and then corresponding bit
138*4a77657cSAndrey V. Elsukov 	 * is set in chunkmask.
139*4a77657cSAndrey V. Elsukov 	 *
140*4a77657cSAndrey V. Elsukov 	 * Also we keep last used PG's index for each protocol.
141*4a77657cSAndrey V. Elsukov 	 *   pgidx / 32 = index of pgchunk;
142*4a77657cSAndrey V. Elsukov 	 *   pgidx % 32 = index of pgptr in pgchunk.
143*4a77657cSAndrey V. Elsukov 	 */
144*4a77657cSAndrey V. Elsukov 	uint32_t		tcp_chunkmask;
145*4a77657cSAndrey V. Elsukov 	uint32_t		tcp_pgidx;
146d18c1f26SAndrey V. Elsukov 
147*4a77657cSAndrey V. Elsukov 	uint32_t		udp_chunkmask;
148*4a77657cSAndrey V. Elsukov 	uint32_t		udp_pgidx;
149*4a77657cSAndrey V. Elsukov 
150*4a77657cSAndrey V. Elsukov 	uint32_t		icmp_chunkmask;
151*4a77657cSAndrey V. Elsukov 	uint32_t		icmp_pgidx;
152*4a77657cSAndrey V. Elsukov 	/*
153*4a77657cSAndrey V. Elsukov 	 * Each pgchunk keeps 32 pointers to PGs. If pgptr pointer is
154*4a77657cSAndrey V. Elsukov 	 * valid, we have corresponding bit set in the pgmask.
155*4a77657cSAndrey V. Elsukov 	 */
156d18c1f26SAndrey V. Elsukov 	uint32_t		tcp_pgmask[32];
157d18c1f26SAndrey V. Elsukov 	uint32_t		udp_pgmask[32];
158d18c1f26SAndrey V. Elsukov 	uint32_t		icmp_pgmask[32];
159*4a77657cSAndrey V. Elsukov 
160d18c1f26SAndrey V. Elsukov 	struct nat64lsn_pgchunk	*tcp[32];
161d18c1f26SAndrey V. Elsukov 	struct nat64lsn_pgchunk	*udp[32];
162d18c1f26SAndrey V. Elsukov 	struct nat64lsn_pgchunk	*icmp[32];
163d18c1f26SAndrey V. Elsukov };
164d18c1f26SAndrey V. Elsukov #define	ALIAS_LOCK_INIT(p)	\
165d18c1f26SAndrey V. Elsukov 	mtx_init(&(p)->lock, "alias_lock", NULL, MTX_DEF)
166d18c1f26SAndrey V. Elsukov #define	ALIAS_LOCK_DESTROY(p)	mtx_destroy(&(p)->lock)
167d18c1f26SAndrey V. Elsukov #define	ALIAS_LOCK(p)		mtx_lock(&(p)->lock)
168d18c1f26SAndrey V. Elsukov #define	ALIAS_UNLOCK(p)		mtx_unlock(&(p)->lock)
169d18c1f26SAndrey V. Elsukov 
170d18c1f26SAndrey V. Elsukov #define	NAT64LSN_HSIZE		256
171d18c1f26SAndrey V. Elsukov #define	NAT64LSN_MAX_HSIZE	4096
172d18c1f26SAndrey V. Elsukov #define	NAT64LSN_HOSTS_HSIZE	1024
173d18c1f26SAndrey V. Elsukov 
174d8caf56eSAndrey V. Elsukov struct nat64lsn_host {
175d8caf56eSAndrey V. Elsukov 	struct in6_addr		addr;
176d18c1f26SAndrey V. Elsukov 	struct nat64lsn_aliaslink_slist	aliases;
177d18c1f26SAndrey V. Elsukov 	struct nat64lsn_states_slist	*states_hash;
178d18c1f26SAndrey V. Elsukov 	CK_SLIST_ENTRY(nat64lsn_host)	entries;
179d18c1f26SAndrey V. Elsukov 	uint32_t		states_count;
180d18c1f26SAndrey V. Elsukov 	uint32_t		hval;
181d18c1f26SAndrey V. Elsukov 	uint32_t		flags;
182d18c1f26SAndrey V. Elsukov #define	NAT64LSN_DEADHOST	1
183d18c1f26SAndrey V. Elsukov #define	NAT64LSN_GROWHASH	2
184d18c1f26SAndrey V. Elsukov 	uint16_t		states_hashsize;
185d18c1f26SAndrey V. Elsukov 	uint16_t		timestamp;
186d18c1f26SAndrey V. Elsukov 	struct mtx		lock;
187d8caf56eSAndrey V. Elsukov };
188d8caf56eSAndrey V. Elsukov 
189d18c1f26SAndrey V. Elsukov #define	HOST_LOCK_INIT(p)	\
190d18c1f26SAndrey V. Elsukov 	mtx_init(&(p)->lock, "host_lock", NULL, MTX_DEF|MTX_NEW)
191d18c1f26SAndrey V. Elsukov #define	HOST_LOCK_DESTROY(p)	mtx_destroy(&(p)->lock)
192d18c1f26SAndrey V. Elsukov #define	HOST_LOCK(p)		mtx_lock(&(p)->lock)
193d18c1f26SAndrey V. Elsukov #define	HOST_UNLOCK(p)		mtx_unlock(&(p)->lock)
194d8caf56eSAndrey V. Elsukov 
195*4a77657cSAndrey V. Elsukov VNET_DECLARE(uint32_t, nat64lsn_eid);
196d8caf56eSAndrey V. Elsukov #define	V_nat64lsn_eid		VNET(nat64lsn_eid)
197d8caf56eSAndrey V. Elsukov #define	IPFW_TLV_NAT64LSN_NAME	IPFW_TLV_EACTION_NAME(V_nat64lsn_eid)
198d8caf56eSAndrey V. Elsukov 
199d8caf56eSAndrey V. Elsukov /* Timestamp macro */
200d8caf56eSAndrey V. Elsukov #define	_CT		((int)time_uptime % 65536)
201d8caf56eSAndrey V. Elsukov #define	SET_AGE(x)	(x) = _CT
202d18c1f26SAndrey V. Elsukov #define	GET_AGE(x)	((_CT >= (x)) ? _CT - (x): (int)65536 + _CT - (x))
203d8caf56eSAndrey V. Elsukov 
204d18c1f26SAndrey V. Elsukov STAILQ_HEAD(nat64lsn_job_head, nat64lsn_job_item);
205d8caf56eSAndrey V. Elsukov 
206d8caf56eSAndrey V. Elsukov struct nat64lsn_cfg {
207d18c1f26SAndrey V. Elsukov 	struct nat64lsn_hosts_slist	*hosts_hash;
208d18c1f26SAndrey V. Elsukov 	struct nat64lsn_alias	*aliases;	/* array of aliases */
209d18c1f26SAndrey V. Elsukov 
210d18c1f26SAndrey V. Elsukov 	struct mtx	lock;
211d18c1f26SAndrey V. Elsukov 	uint32_t	hosts_hashsize;
212d18c1f26SAndrey V. Elsukov 	uint32_t	hash_seed;
213d18c1f26SAndrey V. Elsukov 
214d8caf56eSAndrey V. Elsukov 	uint32_t	prefix4;	/* IPv4 prefix */
215d8caf56eSAndrey V. Elsukov 	uint32_t	pmask4;		/* IPv4 prefix mask */
216d8caf56eSAndrey V. Elsukov 	uint8_t		plen4;
217d18c1f26SAndrey V. Elsukov 	uint8_t		nomatch_verdict;/* Return value on no-match */
218d8caf56eSAndrey V. Elsukov 
219d18c1f26SAndrey V. Elsukov 	uint32_t	hosts_count;	/* Number of items in host hash */
220d18c1f26SAndrey V. Elsukov 	uint32_t	states_chunks;	/* Number of states chunks per PG */
221d8caf56eSAndrey V. Elsukov 	uint32_t	jmaxlen;	/* Max jobqueue length */
222d18c1f26SAndrey V. Elsukov 	uint16_t	host_delete_delay;	/* Stale host delete delay */
223d18c1f26SAndrey V. Elsukov 	uint16_t	pgchunk_delete_delay;
224d8caf56eSAndrey V. Elsukov 	uint16_t	pg_delete_delay;	/* Stale portgroup del delay */
225d8caf56eSAndrey V. Elsukov 	uint16_t	st_syn_ttl;	/* TCP syn expire */
226d8caf56eSAndrey V. Elsukov 	uint16_t	st_close_ttl;	/* TCP fin expire */
227d8caf56eSAndrey V. Elsukov 	uint16_t	st_estab_ttl;	/* TCP established expire */
228d8caf56eSAndrey V. Elsukov 	uint16_t	st_udp_ttl;	/* UDP expire */
229d8caf56eSAndrey V. Elsukov 	uint16_t	st_icmp_ttl;	/* ICMP expire */
230d18c1f26SAndrey V. Elsukov 
231782360deSAndrey V. Elsukov 	struct nat64_config	base;
232*4a77657cSAndrey V. Elsukov #define	NAT64LSN_FLAGSMASK	(NAT64_LOG | NAT64_ALLOW_PRIVATE | \
233*4a77657cSAndrey V. Elsukov     NAT64LSN_ALLOW_SWAPCONF)
234d18c1f26SAndrey V. Elsukov #define	NAT64LSN_ANYPREFIX	0x00000100
235d8caf56eSAndrey V. Elsukov 
236d18c1f26SAndrey V. Elsukov 	struct mtx		periodic_lock;
237d8caf56eSAndrey V. Elsukov 	struct callout		periodic;
238d8caf56eSAndrey V. Elsukov 	struct callout		jcallout;
239d8caf56eSAndrey V. Elsukov 	struct vnet		*vp;
240d8caf56eSAndrey V. Elsukov 	struct nat64lsn_job_head	jhead;
241d8caf56eSAndrey V. Elsukov 	int			jlen;
242d8caf56eSAndrey V. Elsukov 	char			name[64];	/* Nat instance name */
243d8caf56eSAndrey V. Elsukov };
244d8caf56eSAndrey V. Elsukov 
245*4a77657cSAndrey V. Elsukov struct nat64lsn_instance {
246*4a77657cSAndrey V. Elsukov 	struct named_object	no;
247*4a77657cSAndrey V. Elsukov 	struct nat64lsn_cfg	*cfg;
248*4a77657cSAndrey V. Elsukov 	char			name[64];	/* Nat instance name */
249*4a77657cSAndrey V. Elsukov };
250*4a77657cSAndrey V. Elsukov 
251d18c1f26SAndrey V. Elsukov /* CFG_LOCK protects cfg->hosts_hash from modification */
252d18c1f26SAndrey V. Elsukov #define	CFG_LOCK_INIT(p)	\
253d18c1f26SAndrey V. Elsukov 	mtx_init(&(p)->lock, "cfg_lock", NULL, MTX_DEF)
254d18c1f26SAndrey V. Elsukov #define	CFG_LOCK_DESTROY(p)	mtx_destroy(&(p)->lock)
255d18c1f26SAndrey V. Elsukov #define	CFG_LOCK(p)		mtx_lock(&(p)->lock)
256d18c1f26SAndrey V. Elsukov #define	CFG_UNLOCK(p)		mtx_unlock(&(p)->lock)
257d18c1f26SAndrey V. Elsukov 
258d18c1f26SAndrey V. Elsukov #define	CALLOUT_LOCK_INIT(p)	\
259d18c1f26SAndrey V. Elsukov 	mtx_init(&(p)->periodic_lock, "periodic_lock", NULL, MTX_DEF)
260d18c1f26SAndrey V. Elsukov #define	CALLOUT_LOCK_DESTROY(p)	mtx_destroy(&(p)->periodic_lock)
261d18c1f26SAndrey V. Elsukov #define	CALLOUT_LOCK(p)		mtx_lock(&(p)->periodic_lock)
262d18c1f26SAndrey V. Elsukov #define	CALLOUT_UNLOCK(p)	mtx_unlock(&(p)->periodic_lock)
263d18c1f26SAndrey V. Elsukov 
264*4a77657cSAndrey V. Elsukov MALLOC_DECLARE(M_NAT64LSN);
265*4a77657cSAndrey V. Elsukov 
266*4a77657cSAndrey V. Elsukov struct nat64lsn_cfg *nat64lsn_init_config(struct ip_fw_chain *ch,
267d18c1f26SAndrey V. Elsukov     in_addr_t prefix, int plen);
268*4a77657cSAndrey V. Elsukov void nat64lsn_destroy_config(struct nat64lsn_cfg *cfg);
269d8caf56eSAndrey V. Elsukov void nat64lsn_start_instance(struct nat64lsn_cfg *cfg);
270d8caf56eSAndrey V. Elsukov void nat64lsn_init_internal(void);
271d8caf56eSAndrey V. Elsukov void nat64lsn_uninit_internal(void);
272d8caf56eSAndrey V. Elsukov int ipfw_nat64lsn(struct ip_fw_chain *ch, struct ip_fw_args *args,
273d8caf56eSAndrey V. Elsukov     ipfw_insn *cmd, int *done);
274d8caf56eSAndrey V. Elsukov 
275d8caf56eSAndrey V. Elsukov #endif /* _IP_FW_NAT64LSN_H_ */
276