]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/netpfil/ipfw/nat64/nat64lsn.h
MFHead @347527
[FreeBSD/FreeBSD.git] / sys / netpfil / ipfw / nat64 / nat64lsn.h
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
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  * $FreeBSD$
30  */
31
32 #ifndef _IP_FW_NAT64LSN_H_
33 #define _IP_FW_NAT64LSN_H_
34
35 #include "ip_fw_nat64.h"
36 #include "nat64_translate.h"
37
38 #define NAT64_MIN_PORT          1024
39 struct nat64lsn_host;
40 struct nat64lsn_alias;
41
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;
46
47         struct in6_addr ip6_dst;        /* Destination IPv6 address */
48
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 */
53
54         uint32_t        hval;
55         uint32_t        flags;          /* Internal flags */
56         uint16_t        aport;
57         uint16_t        timestamp;      /* last used */
58         uint8_t         proto;
59         uint8_t         _spare[7];
60 };
61
62 struct nat64lsn_states_chunk {
63         struct nat64lsn_state   state[64];
64 };
65
66 #define ISSET64(mask, bit)      ((mask) & ((uint64_t)1 << (bit)))
67 #define ISSET32(mask, bit)      ((mask) & ((uint32_t)1 << (bit)))
68 struct nat64lsn_pg {
69         CK_SLIST_ENTRY(nat64lsn_pg)     entries;
70
71         uint16_t                base_port;
72         uint16_t                timestamp;
73         uint8_t                 proto;
74         uint8_t                 chunks_count;
75         uint8_t                 spare[2];
76
77         union {
78                 uint64_t        freemask64;
79                 uint32_t        freemask32[2];
80                 uint64_t        *freemask64_chunk;
81                 uint32_t        *freemask32_chunk;
82                 void            *freemask_chunk;
83         };
84         union {
85                 struct nat64lsn_states_chunk *states;
86                 struct nat64lsn_states_chunk **states_chunk;
87         };
88 };
89
90 #define CHUNK_BY_FADDR(p, a)    ((a) & ((p)->chunks_count - 1))
91
92 #ifdef __LP64__
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)))
98 #else
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__ */
105
106 struct nat64lsn_pgchunk {
107         struct nat64lsn_pg      *pgptr[32];
108 };
109
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;
114 };
115
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);
120
121 struct nat64lsn_alias {
122         struct nat64lsn_aliaslink_slist hosts;
123         struct nat64lsn_pg_slist        portgroups;
124
125         struct mtx              lock;
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;
132
133         uint32_t                tcp_pgidx;
134         uint32_t                udp_pgidx;
135         uint32_t                icmp_pgidx;
136         uint16_t                timestamp;
137         uint16_t                spare;
138
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];
145
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;
150 };
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)
156
157 #define NAT64LSN_HSIZE          256
158 #define NAT64LSN_MAX_HSIZE      4096
159 #define NAT64LSN_HOSTS_HSIZE    1024
160
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;
167         uint32_t                hval;
168         uint32_t                flags;
169 #define NAT64LSN_DEADHOST       1
170 #define NAT64LSN_GROWHASH       2
171         uint16_t                states_hashsize;
172         uint16_t                timestamp;
173         struct mtx              lock;
174 };
175
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)
181
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)
185
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))
190
191 STAILQ_HEAD(nat64lsn_job_head, nat64lsn_job_item);
192
193 struct nat64lsn_cfg {
194         struct named_object     no;
195
196         struct nat64lsn_hosts_slist     *hosts_hash;
197         struct nat64lsn_alias   *aliases;       /* array of aliases */
198
199         struct mtx      lock;
200         uint32_t        hosts_hashsize;
201         uint32_t        hash_seed;
202
203         uint32_t        prefix4;        /* IPv4 prefix */
204         uint32_t        pmask4;         /* IPv4 prefix mask */
205         uint8_t         plen4;
206         uint8_t         nomatch_verdict;/* Return value on no-match */
207
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 */
219
220         struct nat64_config     base;
221 #define NAT64LSN_FLAGSMASK      (NAT64_LOG | NAT64_ALLOW_PRIVATE)
222 #define NAT64LSN_ANYPREFIX      0x00000100
223
224         struct mtx              periodic_lock;
225         struct callout          periodic;
226         struct callout          jcallout;
227         struct vnet             *vp;
228         struct nat64lsn_job_head        jhead;
229         int                     jlen;
230         char                    name[64];       /* Nat instance name */
231 };
232
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)
239
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)
245
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);
254
255 #endif /* _IP_FW_NAT64LSN_H_ */