Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/netpfil/ipfw/nat64/nat64lsn.h
39536 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2015-2020 Yandex LLC
5
* Copyright (c) 2015 Alexander V. Chernikov <[email protected]>
6
* Copyright (c) 2015-2020 Andrey V. Elsukov <[email protected]>
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
37
struct nat64lsn_host;
38
struct nat64lsn_alias;
39
40
struct 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
60
struct 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)))
66
struct nat64lsn_pg {
67
uint16_t base_port;
68
uint16_t timestamp;
69
uint8_t proto;
70
uint8_t chunks_count;
71
uint16_t flags;
72
#define NAT64LSN_DEADPG 1
73
74
union {
75
uint64_t freemask64;
76
uint32_t freemask32[2];
77
uint64_t *freemask64_chunk;
78
uint32_t *freemask32_chunk;
79
void *freemask_chunk;
80
};
81
union {
82
struct nat64lsn_states_chunk *states;
83
struct nat64lsn_states_chunk **states_chunk;
84
};
85
/*
86
* An alias object holds chain of all allocated PGs.
87
* The chain is used mostly by expiration code.
88
*/
89
CK_SLIST_ENTRY(nat64lsn_pg) entries;
90
};
91
92
#define CHUNK_BY_FADDR(p, a) ((a) & ((p)->chunks_count - 1))
93
94
#ifdef __LP64__
95
#define FREEMASK_CHUNK(p, v) \
96
((p)->chunks_count == 1 ? &(p)->freemask64 : \
97
&(p)->freemask64_chunk[CHUNK_BY_FADDR(p, v)])
98
#define FREEMASK_BITCOUNT(pg, faddr) \
99
bitcount64(*FREEMASK_CHUNK((pg), (faddr)))
100
#else
101
#define FREEMASK_CHUNK(p, v) \
102
((p)->chunks_count == 1 ? &(p)->freemask32[0] : \
103
&(p)->freemask32_chunk[CHUNK_BY_FADDR(p, v) * 2])
104
#define FREEMASK_BITCOUNT(pg, faddr) \
105
bitcount64(*(uint64_t *)FREEMASK_CHUNK((pg), (faddr)))
106
#endif /* !__LP64__ */
107
108
struct nat64lsn_pgchunk {
109
struct nat64lsn_pg *pgptr[32];
110
};
111
112
struct nat64lsn_aliaslink {
113
CK_SLIST_ENTRY(nat64lsn_aliaslink) alias_entries;
114
CK_SLIST_ENTRY(nat64lsn_aliaslink) host_entries;
115
struct nat64lsn_alias *alias;
116
};
117
118
CK_SLIST_HEAD(nat64lsn_aliaslink_slist, nat64lsn_aliaslink);
119
CK_SLIST_HEAD(nat64lsn_states_slist, nat64lsn_state);
120
CK_SLIST_HEAD(nat64lsn_hosts_slist, nat64lsn_host);
121
CK_SLIST_HEAD(nat64lsn_pg_slist, nat64lsn_pg);
122
123
struct nat64lsn_alias {
124
struct nat64lsn_aliaslink_slist hosts;
125
struct nat64lsn_pg_slist portgroups;
126
127
struct mtx lock;
128
in_addr_t addr; /* host byte order */
129
uint32_t hosts_count;
130
131
uint16_t timestamp;
132
uint16_t tcp_pgcount;
133
uint16_t udp_pgcount;
134
uint16_t icmp_pgcount;
135
/*
136
* We keep PGs in chunks by 32 PGs in each.
137
* Each chunk allocated by demand, and then corresponding bit
138
* is set in chunkmask.
139
*
140
* Also we keep last used PG's index for each protocol.
141
* pgidx / 32 = index of pgchunk;
142
* pgidx % 32 = index of pgptr in pgchunk.
143
*/
144
uint32_t tcp_chunkmask;
145
uint32_t tcp_pgidx;
146
147
uint32_t udp_chunkmask;
148
uint32_t udp_pgidx;
149
150
uint32_t icmp_chunkmask;
151
uint32_t icmp_pgidx;
152
/*
153
* Each pgchunk keeps 32 pointers to PGs. If pgptr pointer is
154
* valid, we have corresponding bit set in the pgmask.
155
*/
156
uint32_t tcp_pgmask[32];
157
uint32_t udp_pgmask[32];
158
uint32_t icmp_pgmask[32];
159
160
struct nat64lsn_pgchunk *tcp[32];
161
struct nat64lsn_pgchunk *udp[32];
162
struct nat64lsn_pgchunk *icmp[32];
163
};
164
#define ALIAS_LOCK_INIT(p) \
165
mtx_init(&(p)->lock, "alias_lock", NULL, MTX_DEF)
166
#define ALIAS_LOCK_DESTROY(p) mtx_destroy(&(p)->lock)
167
#define ALIAS_LOCK(p) mtx_lock(&(p)->lock)
168
#define ALIAS_UNLOCK(p) mtx_unlock(&(p)->lock)
169
170
#define NAT64LSN_HSIZE 256
171
#define NAT64LSN_MAX_HSIZE 4096
172
#define NAT64LSN_HOSTS_HSIZE 1024
173
174
struct nat64lsn_host {
175
struct in6_addr addr;
176
struct nat64lsn_aliaslink_slist aliases;
177
struct nat64lsn_states_slist *states_hash;
178
CK_SLIST_ENTRY(nat64lsn_host) entries;
179
uint32_t states_count;
180
uint32_t hval;
181
uint32_t flags;
182
#define NAT64LSN_DEADHOST 1
183
#define NAT64LSN_GROWHASH 2
184
uint16_t states_hashsize;
185
uint16_t timestamp;
186
struct mtx lock;
187
};
188
189
#define HOST_LOCK_INIT(p) \
190
mtx_init(&(p)->lock, "host_lock", NULL, MTX_DEF|MTX_NEW)
191
#define HOST_LOCK_DESTROY(p) mtx_destroy(&(p)->lock)
192
#define HOST_LOCK(p) mtx_lock(&(p)->lock)
193
#define HOST_UNLOCK(p) mtx_unlock(&(p)->lock)
194
195
VNET_DECLARE(uint32_t, nat64lsn_eid);
196
#define V_nat64lsn_eid VNET(nat64lsn_eid)
197
#define IPFW_TLV_NAT64LSN_NAME IPFW_TLV_EACTION_NAME(V_nat64lsn_eid)
198
199
/* Timestamp macro */
200
#define _CT ((int)time_uptime % 65536)
201
#define SET_AGE(x) (x) = _CT
202
#define GET_AGE(x) ((_CT >= (x)) ? _CT - (x): (int)65536 + _CT - (x))
203
204
STAILQ_HEAD(nat64lsn_job_head, nat64lsn_job_item);
205
206
struct nat64lsn_cfg {
207
struct nat64lsn_hosts_slist *hosts_hash;
208
struct nat64lsn_alias *aliases; /* array of aliases */
209
210
struct mtx lock;
211
uint32_t hosts_hashsize;
212
uint32_t hash_seed;
213
214
uint32_t prefix4; /* IPv4 prefix */
215
uint32_t pmask4; /* IPv4 prefix mask */
216
uint8_t plen4;
217
uint8_t nomatch_verdict;/* Return value on no-match */
218
219
uint32_t hosts_count; /* Number of items in host hash */
220
uint32_t states_chunks; /* Number of states chunks per PG */
221
uint32_t jmaxlen; /* Max jobqueue length */
222
uint16_t host_delete_delay; /* Stale host delete delay */
223
uint16_t pgchunk_delete_delay;
224
uint16_t pg_delete_delay; /* Stale portgroup del delay */
225
uint16_t st_syn_ttl; /* TCP syn expire */
226
uint16_t st_close_ttl; /* TCP fin expire */
227
uint16_t st_estab_ttl; /* TCP established expire */
228
uint16_t st_udp_ttl; /* UDP expire */
229
uint16_t st_icmp_ttl; /* ICMP expire */
230
231
struct nat64_config base;
232
#define NAT64LSN_FLAGSMASK (NAT64_LOG | NAT64_ALLOW_PRIVATE | \
233
NAT64LSN_ALLOW_SWAPCONF)
234
#define NAT64LSN_ANYPREFIX 0x00000100
235
236
struct mtx periodic_lock;
237
struct callout periodic;
238
struct callout jcallout;
239
struct vnet *vp;
240
struct nat64lsn_job_head jhead;
241
int jlen;
242
char name[64]; /* Nat instance name */
243
};
244
245
struct nat64lsn_instance {
246
struct named_object no;
247
struct nat64lsn_cfg *cfg;
248
char name[64]; /* Nat instance name */
249
};
250
251
/* CFG_LOCK protects cfg->hosts_hash from modification */
252
#define CFG_LOCK_INIT(p) \
253
mtx_init(&(p)->lock, "cfg_lock", NULL, MTX_DEF)
254
#define CFG_LOCK_DESTROY(p) mtx_destroy(&(p)->lock)
255
#define CFG_LOCK(p) mtx_lock(&(p)->lock)
256
#define CFG_UNLOCK(p) mtx_unlock(&(p)->lock)
257
258
#define CALLOUT_LOCK_INIT(p) \
259
mtx_init(&(p)->periodic_lock, "periodic_lock", NULL, MTX_DEF)
260
#define CALLOUT_LOCK_DESTROY(p) mtx_destroy(&(p)->periodic_lock)
261
#define CALLOUT_LOCK(p) mtx_lock(&(p)->periodic_lock)
262
#define CALLOUT_UNLOCK(p) mtx_unlock(&(p)->periodic_lock)
263
264
MALLOC_DECLARE(M_NAT64LSN);
265
266
struct nat64lsn_cfg *nat64lsn_init_config(struct ip_fw_chain *ch,
267
in_addr_t prefix, int plen);
268
void nat64lsn_destroy_config(struct nat64lsn_cfg *cfg);
269
void nat64lsn_start_instance(struct nat64lsn_cfg *cfg);
270
void nat64lsn_init_internal(void);
271
void nat64lsn_uninit_internal(void);
272
int ipfw_nat64lsn(struct ip_fw_chain *ch, struct ip_fw_args *args,
273
ipfw_insn *cmd, int *done);
274
275
#endif /* _IP_FW_NAT64LSN_H_ */
276
277