Initial commit of vpp code.
[vpp.git] / vnet / vnet / vcgn / nat64_db.h
1 /*
2  *------------------------------------------------------------------
3  * nat64_db.h - Stateful NAT64 translation database definitions
4  *
5  * Copyright (c) 2010-2013 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19 #ifndef __NAT64_DB_H__
20 #define __NAT64_DB_H__
21
22 #include "cnat_cli.h"
23 #include "index_list.h"
24 #include "cnat_ports.h"
25 #include "cnat_db.h"
26 #include "nat64_defs.h"
27 #include "cnat_bulk_port_defs.h"
28
29 nat64_vrfmap_t *nat64_map_by_vrf;
30
31 #define SESSION_OPT
32
33 #define HASH_ENHANCE 4
34
35
36 #define NAT64_MAIN_DB_SIZE \
37                (PLATFORM_NAT64_MAX_SESSIONS / PLATFORM_CNAT_INSTS)
38 #define NAT64_MAIN_HASH_SIZE \
39          (HASH_ENHANCE * PLATFORM_CNAT_MAIN_PRELIM_HASH_SIZE) 
40
41 #define NAT64_MAIN_HASH_MASK (NAT64_MAIN_HASH_SIZE-1)
42
43
44 /* nb: 200000 users / 64 CNAT = 3125, 76% occupancy */
45 #define NAT64_USER_HASH_SIZE CNAT_USER_HASH_SIZE
46 #define NAT64_USER_HASH_MASK (NAT64_USER_HASH_SIZE-1)
47
48 /* Number of sessions per BIB entry/NAT64 translation
49    - nsessions is u16 type. So selected 0xFFFF
50    - Ideally Sessions per transltion will not reach the limit
51    - Only DoS can possible. It can take care of it   */
52 #define NAT64_MAX_SESSIONS_PER_BIB  0xFFFF
53
54 /* No. of per ip/port config will be limited to 1000 */
55 /* totally 25K across all instances) */
56 #define NAT64_TIMEOUT_HASH_SIZE \
57                        PLATFORM_NAT64_TIMEOUT_HASH_SIZE 
58
59 #define NAT64_TIMEOUT_HASH_MASK (NAT64_TIMEOUT_HASH_SIZE - 1)
60 #define NAT64_TIMEOUT_FULL_MASK 0xFFFFFFFFFFFFFFFF
61
62
63 #define FORCE_DEL 1 /* Delete static BIB entries as well */
64
65 /* default timeout values */
66 #define NAT64_UDP_DEFAULT          300  /* 5 min */
67 #define NAT64_UDP_MIN              120  /* 2 min */
68 #define NAT64_TCP_TRANS            240  /* 4 min */
69 #define NAT64_TCP_EST             7200  /* 2 hrs */
70 #define NAT64_TCP_V4_SYN             6  /* 6 sec */
71 #define NAT64_FRAG_MIN               2  /* 2 sec */
72 #define NAT64_ICMP_DEFAULT          60  /* 1 min */
73
74
75 #define NAT64_V6_GET_HASH(in_key, hash, mask) \
76     a = in_key->ipv6[0] ^ in_key->ipv6[1] ^ in_key->ipv6[2] ^ in_key->ipv6[3] \
77          ^ ((in_key->port << 16) | in_key->vrf); \
78     b = c = 0x9e3779b9;\
79     /* Jenkins hash, arbitrarily use c as the "answer" */ \
80     hash_mix32(a, b, c); \
81     hash = c & mask; \
82
83
84 #define NAT64_V4_GET_HASH(in_key, hash, mask) \
85     a = in_key.ipv4 ^ ((in_key.port << 16) | in_key.vrf); \
86     b = c = 0x9e3779b9; \
87     /* Jenkins hash, arbitrarily use c as the "answer" */ \
88     hash_mix32(a, b, c); \
89     hash = c & mask;
90
91
92
93 #define NAT64_V6_GET_SESSION_HASH(bib_index, in_addr, port, vrf, hash, mask) \
94     a = bib_index ^ in_addr[0] ^ in_addr[1] ^ in_addr[2] ^ in_addr[3] \
95             ^ port ^ vrf; \
96     b = c = 0x9e3779b9; \
97     /* Jenkins hash, arbitrarily use c as the "answer" */ \
98     hash_mix32(a, b, c); \
99     hash = c & mask;
100
101 #define NAT64_V4_GET_SESSION_HASH(bib_index, in_addr, port, vrf, hash, mask) \
102     a = bib_index ^ in_addr ^ port ^ vrf; \
103     b = c = 0x9e3779b9; \
104     /* Jenkins hash, arbitrarily use c as the "answer" */ \
105     hash_mix32(a, b, c); \
106     hash = c & mask;
107
108
109 extern index_slist_t        *nat64_bib_out2in_hash;
110 extern index_slist_t        *nat64_bib_in2out_hash;
111 extern index_slist_t        *nat64_bib_user_hash;
112 extern index_slist_t        *nat64_session_out2in_hash;
113 #ifndef SESSION_OPT
114 extern index_slist_t        *nat64_session_in2out_hash;
115 #endif
116 extern index_slist_t        *nat64_frag_out2in_hash;
117 extern index_slist_t        *nat64_frag_in2out_hash;
118 extern index_slist_t        *nat64_timeout_hash;
119
120
121 /*
122  * nat64_ bib_entry_t
123  * This structure depicts Binding Information Base of NAT64 sessions. 
124  * It stores information about the inside v6 source transport address and 
125  * corresponding outside v4 source transport address for each protocol.
126  */
127
128 typedef struct {
129
130     index_slist_t     nat64_bib_out2in_hash;
131     index_slist_t     nat64_bib_in2out_hash;
132
133     /* 0x08 */
134     u16               flags; /* flags in cnat_db.h (cnat_main_db_entry_t) */
135 #define NAT64_DB_FLAG_STATIC_PORT CNAT_DB_FLAG_STATIC_PORT
136 #define NAT64_DB_NAT64_FLAG       CNAT_DB_NAT64_FLAG
137 #define NAT64_DB_FLAG_ALG_ENTRY   CNAT_DB_FLAG_ALG_ENTRY
138 #define NAT64_DB_FLAG_PCPI        CNAT_DB_FLAG_PCPI 
139 #define NAT64_DB_FLAG_PCPE        CNAT_DB_FLAG_PCPE
140
141     /* 0x0A */
142     u16              nat64_inst_id;
143     /* 0x0C */
144     u32              user_index;
145
146     /* 0x10 */
147     nat64_v4_key_t     v4_out_key;
148
149     /* 0x18 */
150     nat64_v6_key_t     v6_in_key;      
151
152     /* 0x2C */
153     index_dlist_t    user_ports;   
154     /* 0x34 */
155     u32              session_head_index;
156      /* 0x38 - 56B*/
157     u16              nsessions;
158     u16              pad2;
159
160     /* 0x3C - 60B */
161     u32              in2outpkts;
162     u32              out2inpkts;
163     /* 0x44 - 68B */
164
165     /* 0x42 - 70B */
166     union {                     /* used by FTP ALG, pkt len delta due to FTP PORT cmd */
167     u16 delta;
168     i8  alg_dlt[2];             /* two delta values, 0 for previous, 1 for current */
169     u16 il;                     /* Used to indicate if interleaved mode is used
170                                    in case of RTSP ALG */
171     } alg;
172
173     u16 temp1;
174
175     u32 entry_expires;
176
177     u32 temp3;
178     /* unused, temp1 ,temp2 and temp3 put to make it in sync with nat44 main db entry size */
179     /* size of = 0x54 = 84 B */
180     u32 unused;
181
182 } nat64_bib_entry_t ;
183
184 /* 
185  * nat64_bib_user_entry_t
186  * This structure stores information about translations of a particular user 
187  * (User here refers to a same inside source address)
188  */
189 typedef struct {
190     /* 0x00 */
191     index_slist_t user_hash;    
192      /* 0x04 */
193     u16 ntranslations;          
194     /* 0x06 */
195     u8 icmp_msg_count;
196     /* 0x07 */
197     u8 flags;                
198 #define NAT64_USER_DB_NAT64_FLAG CNAT_USER_DB_NAT64_FLAG
199
200     /* 0x08 */ 
201     u32 translation_list_head_index;
202     /* 0x0C */
203     u32 portmap_index;          
204     /* 0x10 */
205     nat64_v6_key_t     v6_in_key;      
206     /* 0x24 = 36 B */
207
208     u32 align1; /* Make it 8B boundary  and in sync with nat44 user db entry size */
209 #ifndef NO_BULK_LOGGING
210     /* size of = 0x28 = 40 B */
211     /* Now adding 8 more bytes for bulk allocation.. This makes it
212      * 0x30 (48).  For nat64 stful, we may support bulk allocation
213      * later */
214     /* Indicates the currently used bulk port range */
215     i16 bulk_port_range_cache[BULK_RANGE_CACHE_SIZE];
216 #endif /*  NO_BULK_LOGGING */
217 } nat64_bib_user_entry_t;
218
219 /*
220  * nat64_session_entry_t
221  * This structure represents the session table. It maintains the information 
222  * about the flow of the packets. It would consist of source and destination 
223  * (inside and outside) ipv4 and ipv4 transport addresses. 
224  */
225 typedef struct {
226
227     /* 0x00 */
228     index_slist_t   nat64_session_out2in_hash;
229
230     /* 0x04 */ 
231     u32 bib_index; /* would point to v4/v6 src transport address */
232
233     /* 0x08 */
234     nat64_v4_key_t     v4_dest_key;
235
236 #ifndef SESSION_OPT
237    index_slist_t   nat64_session_in2out_hash;
238    nat64_v6_key_t     v6_dest_key;
239 #endif
240
241     /* 0x10 */
242     u16  flags;/* Will be used for flags same as nat44 session */ 
243
244     /* 0x12 */
245     u16 timeout; 
246
247     /* 0x14 */
248     u32 entry_expires;
249     /* 0x18 */
250     index_dlist_t    bib_list;
251     /* 0x20 = 32 B */
252
253     union {                     /* alg same as cnat_main_db_t */
254     u16 delta;
255     i8  alg_dlt[2];
256     u16 il;
257     } alg;
258
259     /* 0x22 */
260     u16  tcp_flags; /* Mainly TCP events - check nat64_tcp_sm.h */
261
262     /* 0x24  */
263     u32 tcp_seq_num;
264
265     /* 0x28 */      /* unused1, unused2 and unused3 are put to make it in sync with 
266                      * cnat_session_db */
267     u32 unused1;
268
269     /* 0x2C */
270     u32 unused2;
271
272     /* 0x30 */
273     u16 unused3;
274
275     /* 0x32 - 50B */
276
277 } nat64_session_entry_t;
278
279 /*
280  * nat64_session_tcp_init_entry_t 
281  * This structure will be used to store information about v4 initiation 
282  * tcp entries.
283  */
284 typedef struct {
285     nat64_v6_key_t     v6_in_key;      
286     nat64_v4_key_t     v4_out_key;
287 } nat64_session_tcp_init_entry_t;
288
289 /* 
290  * nat64_in_v6_frag_entry_t 
291  * This structure will be used to store information about fragment flows 
292  * that are coming from inside v6 hosts.
293  */
294 typedef struct {
295      index_slist_t  nat64_frag_in2out_hash;
296
297      u32 v6_src_addr[4];
298      u32 v6_destn_addr[4];
299      u32 frag_iden;
300      u16  vrf;
301      u16  pad1;
302 } nat64_in_v6_frag_entry_t ;
303
304 /*
305  * nat64_out_v4_frag_entry_t 
306  * This structure will be used to store information about fragment flows 
307  * that are coming from outside v4 machines.
308  */
309 typedef struct {
310      index_slist_t  nat64_frag_out2in_hash;
311
312      u32 v4_src_addr;
313      u32 v4_destn_addr;
314      u16 frag_iden;
315      u16  vrf;
316 } nat64_out_v4_frag_entry_t ;
317
318 /*
319  * nat64_timeout _t 
320  * These following structures will be used to store information destination 
321  * timeouts configured.
322  */
323 typedef struct {
324     nat64_v4_key_t timeout_key;
325     u16        timeout_value;
326 } nat64_timeout_t;
327
328 /*
329  * nat64_timeout_db_entry_t 
330  */
331 typedef struct {
332     nat64_timeout_t  t_key;
333     index_slist_t  t_hash;
334 } nat64_timeout_db_entry_t;
335
336
337 typedef union {
338     cnat_main_db_entry_t nat44_main_db;
339     nat64_bib_entry_t nat64_bib_db; 
340 } cgse_nat_db_entry_t;
341
342 typedef union {
343     cnat_session_entry_t   nat44_session_db;
344     nat64_session_entry_t     nat64_session_db;
345 } cgse_nat_session_db_entry_t;
346
347 typedef union {
348     cnat_user_db_entry_t   nat44_user_db;
349     nat64_bib_user_entry_t nat64_user_db;
350 } cgse_nat_user_db_entry_t;
351
352 extern index_slist_t        *nat64_bib_out2in_hash;
353 extern index_slist_t        *nat64_bib_in2out_hash;
354 extern index_slist_t        *nat64_bib_user_hash;
355 extern index_slist_t        *nat64_session_out2in_hash;
356 extern index_slist_t        *nat64_session_in2out_hash;
357 extern index_slist_t        *nat64_frag_out2in_hash;
358 extern index_slist_t        *nat64_frag_in2out_hash;
359 extern index_slist_t        *nat64_timeout_hash;
360
361 extern nat64_bib_entry_t               *nat64_bib_db;
362 extern nat64_bib_user_entry_t          *nat64_bib_user_db;
363 extern nat64_session_entry_t           *nat64_session_db;
364 extern nat64_in_v6_frag_entry_t        *nat64_in_frag_db;
365 extern nat64_out_v4_frag_entry_t       *nat64_out_frag_db;
366 extern nat64_session_tcp_init_entry_t  *nat64_tcp_init_db ;
367 extern nat64_timeout_db_entry_t        *nat64_timeout_db;
368
369 extern nat64_table_entry_t         nat64_table_array[NAT64_MAX_NAT64_ENTRIES];
370 extern nat64_table_entry_t         *nat64_table_ptr;
371
372 extern cgse_nat_db_entry_t         *cgse_nat_db;
373 extern cgse_nat_user_db_entry_t    *cgse_user_db;
374 extern cgse_nat_session_db_entry_t *cgse_session_db;
375
376 void nat64_bib_user_db_delete (nat64_bib_user_entry_t *up);
377
378 nat64_bib_user_entry_t*
379 nat64_bib_user_db_create_entry(nat64_v6_key_t *uki, u32 bucket,
380                           u32 portmap_index);
381
382 nat64_bib_user_entry_t*
383 nat64_bib_user_db_lookup_entry(nat64_v6_key_t *uki, u32 *bucket);
384
385
386 nat64_bib_entry_t*
387 nat64_bib_db_lookup_entry(nat64_v6_key_t *ki);
388
389 void nat64_bib_db_in2out_hash_delete (nat64_bib_entry_t *ep);
390
391 void nat64_bib_db_out2in_hash_delete (nat64_bib_entry_t *ep);
392
393 nat64_bib_entry_t *
394 nat64_create_bib_db_entry_and_hash(nat64_v6_key_t *ki,
395                                    nat64_v4_key_t *ko,
396                                    nat64_bib_user_entry_t *udb);
397
398
399 void nat64_delete_bib_db_entry (nat64_bib_entry_t *ep, u8 force);
400
401 nat64_bib_entry_t *
402 nat64_bib_db_lookup_entry_out2in (nat64_v4_key_t *ko);
403
404 nat64_bib_entry_t *
405 nat64_get_bib_db_entry (nat64_v6_key_t *ki,
406                         port_pair_t port_pair_type,
407                         port_type_t port_type,
408                         cnat_gen_icmp_info *info);
409
410
411 nat64_bib_entry_t*
412 nat64_create_static_bib_db_entry (nat64_v6_key_t *ki,
413                                   nat64_v4_key_t *ko,
414                                   nat64_table_entry_t *my_table,
415                                   cnat_gen_icmp_info   *info);
416
417
418
419 //void nat64_session_db_in2out_hash_delete (nat64_session_entry_t *ep);
420 void nat64_session_db_out2in_hash_delete (nat64_session_entry_t *ep);
421
422 /*nat64_session_entry_t *
423 nat64_session_db_lookup_entry(nat64_v6_key_t *ki, u32 bib_index); */
424
425
426 nat64_session_entry_t *
427 nat64_session_db_lookup_entry_out2in (nat64_v4_key_t *ko,u32 bib_index);
428
429 /*
430 nat64_session_entry_t *
431 nat64_create_session_db_entry(nat64_v6_key_t *ki,
432                               nat64_v4_key_t *ko,
433                               nat64_bib_entry_t *bdb);
434 */
435 nat64_session_entry_t *
436 nat64_create_session_db_entry_v2( nat64_v4_key_t *ko,
437                               nat64_bib_entry_t *bdb);
438
439
440 //void nat64_delete_session_db_entry (nat64_session_entry_t *ep);
441 void nat64_delete_session_db_entry_v2 (nat64_session_entry_t *ep, u8 force);
442
443 u32 nat64_timeout_db_hash_lookup (nat64_v4_key_t t_key);
444
445 u16 query_and_update_db_timeout_nat64(nat64_session_entry_t *db);
446
447 void nat64_timeout_db_hash_add (nat64_timeout_db_entry_t *t_entry);
448
449 u16 nat64_timeout_db_create (nat64_timeout_t t_entry);
450
451 void nat64_timeout_db_delete(nat64_v4_key_t t_key);
452
453 #define NAT64_CMP_V6_KEY(key1, key2) \
454        memcmp(key1, key2, sizeof(nat64_v6_key_t))
455
456 #define NAT64_CMP_V4_KEY(key1, key2) \
457        memcmp(key1, key2, sizeof(nat64_v4_key_t))
458
459
460 #define NAT64_CMP_V6_IP(ip1, ip2) \
461        memcmp(ip1, ip2, (sizeof(u32) * 4))
462
463
464 #define NAT64_CMP_V6_KEY1(key1, key2) \
465     (key1.ipv6[0] == key2.ipv6[0]) && (key1.ipv6[1] == key2.ipv6[1]) && \
466     (key1.ipv6[2] == key2.ipv6[2]) &&  (key1.ipv6[3] == key2.ipv6[3]) && \
467     (key1.port == key2.port) && (key1.vrf == key2.vrf) 
468
469
470 #define NAT64_CMP_V6_IP1(ip1, ip2) \
471     ((ip1[0] == ip2[0]) && (ip1[1] == ip2[1]) && \
472     (ip1[2] == ip2[2]) && (ip1[3] == ip2[3]))
473
474 #define NAT64_CMP_V4_KEY1(key1, key2) \
475        (key1.key64 == key2.key64)
476
477
478 extern u8  nat64_timeout_dirty_flag[NAT64_MAX_NAT64_ENTRIES];
479
480 #endif