diff options
Diffstat (limited to 'plugins/vcgn-plugin/vcgn/nat64_db.h')
-rw-r--r-- | plugins/vcgn-plugin/vcgn/nat64_db.h | 480 |
1 files changed, 480 insertions, 0 deletions
diff --git a/plugins/vcgn-plugin/vcgn/nat64_db.h b/plugins/vcgn-plugin/vcgn/nat64_db.h new file mode 100644 index 00000000000..837464f6940 --- /dev/null +++ b/plugins/vcgn-plugin/vcgn/nat64_db.h @@ -0,0 +1,480 @@ +/* + *------------------------------------------------------------------ + * nat64_db.h - Stateful NAT64 translation database definitions + * + * Copyright (c) 2010-2013 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------ + */ +#ifndef __NAT64_DB_H__ +#define __NAT64_DB_H__ + +#include "cnat_cli.h" +#include "index_list.h" +#include "cnat_ports.h" +#include "cnat_db.h" +#include "nat64_defs.h" +#include "cnat_bulk_port_defs.h" + +nat64_vrfmap_t *nat64_map_by_vrf; + +#define SESSION_OPT + +#define HASH_ENHANCE 4 + + +#define NAT64_MAIN_DB_SIZE \ + (PLATFORM_NAT64_MAX_SESSIONS / PLATFORM_CNAT_INSTS) +#define NAT64_MAIN_HASH_SIZE \ + (HASH_ENHANCE * PLATFORM_CNAT_MAIN_PRELIM_HASH_SIZE) + +#define NAT64_MAIN_HASH_MASK (NAT64_MAIN_HASH_SIZE-1) + + +/* nb: 200000 users / 64 CNAT = 3125, 76% occupancy */ +#define NAT64_USER_HASH_SIZE CNAT_USER_HASH_SIZE +#define NAT64_USER_HASH_MASK (NAT64_USER_HASH_SIZE-1) + +/* Number of sessions per BIB entry/NAT64 translation + - nsessions is u16 type. So selected 0xFFFF + - Ideally Sessions per transltion will not reach the limit + - Only DoS can possible. It can take care of it */ +#define NAT64_MAX_SESSIONS_PER_BIB 0xFFFF + +/* No. of per ip/port config will be limited to 1000 */ +/* totally 25K across all instances) */ +#define NAT64_TIMEOUT_HASH_SIZE \ + PLATFORM_NAT64_TIMEOUT_HASH_SIZE + +#define NAT64_TIMEOUT_HASH_MASK (NAT64_TIMEOUT_HASH_SIZE - 1) +#define NAT64_TIMEOUT_FULL_MASK 0xFFFFFFFFFFFFFFFF + + +#define FORCE_DEL 1 /* Delete static BIB entries as well */ + +/* default timeout values */ +#define NAT64_UDP_DEFAULT 300 /* 5 min */ +#define NAT64_UDP_MIN 120 /* 2 min */ +#define NAT64_TCP_TRANS 240 /* 4 min */ +#define NAT64_TCP_EST 7200 /* 2 hrs */ +#define NAT64_TCP_V4_SYN 6 /* 6 sec */ +#define NAT64_FRAG_MIN 2 /* 2 sec */ +#define NAT64_ICMP_DEFAULT 60 /* 1 min */ + + +#define NAT64_V6_GET_HASH(in_key, hash, mask) \ + a = in_key->ipv6[0] ^ in_key->ipv6[1] ^ in_key->ipv6[2] ^ in_key->ipv6[3] \ + ^ ((in_key->port << 16) | in_key->vrf); \ + b = c = 0x9e3779b9;\ + /* Jenkins hash, arbitrarily use c as the "answer" */ \ + hash_mix32(a, b, c); \ + hash = c & mask; \ + + +#define NAT64_V4_GET_HASH(in_key, hash, mask) \ + a = in_key.ipv4 ^ ((in_key.port << 16) | in_key.vrf); \ + b = c = 0x9e3779b9; \ + /* Jenkins hash, arbitrarily use c as the "answer" */ \ + hash_mix32(a, b, c); \ + hash = c & mask; + + + +#define NAT64_V6_GET_SESSION_HASH(bib_index, in_addr, port, vrf, hash, mask) \ + a = bib_index ^ in_addr[0] ^ in_addr[1] ^ in_addr[2] ^ in_addr[3] \ + ^ port ^ vrf; \ + b = c = 0x9e3779b9; \ + /* Jenkins hash, arbitrarily use c as the "answer" */ \ + hash_mix32(a, b, c); \ + hash = c & mask; + +#define NAT64_V4_GET_SESSION_HASH(bib_index, in_addr, port, vrf, hash, mask) \ + a = bib_index ^ in_addr ^ port ^ vrf; \ + b = c = 0x9e3779b9; \ + /* Jenkins hash, arbitrarily use c as the "answer" */ \ + hash_mix32(a, b, c); \ + hash = c & mask; + + +extern index_slist_t *nat64_bib_out2in_hash; +extern index_slist_t *nat64_bib_in2out_hash; +extern index_slist_t *nat64_bib_user_hash; +extern index_slist_t *nat64_session_out2in_hash; +#ifndef SESSION_OPT +extern index_slist_t *nat64_session_in2out_hash; +#endif +extern index_slist_t *nat64_frag_out2in_hash; +extern index_slist_t *nat64_frag_in2out_hash; +extern index_slist_t *nat64_timeout_hash; + + +/* + * nat64_ bib_entry_t + * This structure depicts Binding Information Base of NAT64 sessions. + * It stores information about the inside v6 source transport address and + * corresponding outside v4 source transport address for each protocol. + */ + +typedef struct { + + index_slist_t nat64_bib_out2in_hash; + index_slist_t nat64_bib_in2out_hash; + + /* 0x08 */ + u16 flags; /* flags in cnat_db.h (cnat_main_db_entry_t) */ +#define NAT64_DB_FLAG_STATIC_PORT CNAT_DB_FLAG_STATIC_PORT +#define NAT64_DB_NAT64_FLAG CNAT_DB_NAT64_FLAG +#define NAT64_DB_FLAG_ALG_ENTRY CNAT_DB_FLAG_ALG_ENTRY +#define NAT64_DB_FLAG_PCPI CNAT_DB_FLAG_PCPI +#define NAT64_DB_FLAG_PCPE CNAT_DB_FLAG_PCPE + + /* 0x0A */ + u16 nat64_inst_id; + /* 0x0C */ + u32 user_index; + + /* 0x10 */ + nat64_v4_key_t v4_out_key; + + /* 0x18 */ + nat64_v6_key_t v6_in_key; + + /* 0x2C */ + index_dlist_t user_ports; + /* 0x34 */ + u32 session_head_index; + /* 0x38 - 56B*/ + u16 nsessions; + u16 pad2; + + /* 0x3C - 60B */ + u32 in2outpkts; + u32 out2inpkts; + /* 0x44 - 68B */ + + /* 0x42 - 70B */ + union { /* used by FTP ALG, pkt len delta due to FTP PORT cmd */ + u16 delta; + i8 alg_dlt[2]; /* two delta values, 0 for previous, 1 for current */ + u16 il; /* Used to indicate if interleaved mode is used + in case of RTSP ALG */ + } alg; + + u16 temp1; + + u32 entry_expires; + + u32 temp3; + /* unused, temp1 ,temp2 and temp3 put to make it in sync with nat44 main db entry size */ + /* size of = 0x54 = 84 B */ + u32 unused; + +} nat64_bib_entry_t ; + +/* + * nat64_bib_user_entry_t + * This structure stores information about translations of a particular user + * (User here refers to a same inside source address) + */ +typedef struct { + /* 0x00 */ + index_slist_t user_hash; + /* 0x04 */ + u16 ntranslations; + /* 0x06 */ + u8 icmp_msg_count; + /* 0x07 */ + u8 flags; +#define NAT64_USER_DB_NAT64_FLAG CNAT_USER_DB_NAT64_FLAG + + /* 0x08 */ + u32 translation_list_head_index; + /* 0x0C */ + u32 portmap_index; + /* 0x10 */ + nat64_v6_key_t v6_in_key; + /* 0x24 = 36 B */ + + u32 align1; /* Make it 8B boundary and in sync with nat44 user db entry size */ +#ifndef NO_BULK_LOGGING + /* size of = 0x28 = 40 B */ + /* Now adding 8 more bytes for bulk allocation.. This makes it + * 0x30 (48). For nat64 stful, we may support bulk allocation + * later */ + /* Indicates the currently used bulk port range */ + i16 bulk_port_range_cache[BULK_RANGE_CACHE_SIZE]; +#endif /* NO_BULK_LOGGING */ +} nat64_bib_user_entry_t; + +/* + * nat64_session_entry_t + * This structure represents the session table. It maintains the information + * about the flow of the packets. It would consist of source and destination + * (inside and outside) ipv4 and ipv4 transport addresses. + */ +typedef struct { + + /* 0x00 */ + index_slist_t nat64_session_out2in_hash; + + /* 0x04 */ + u32 bib_index; /* would point to v4/v6 src transport address */ + + /* 0x08 */ + nat64_v4_key_t v4_dest_key; + +#ifndef SESSION_OPT + index_slist_t nat64_session_in2out_hash; + nat64_v6_key_t v6_dest_key; +#endif + + /* 0x10 */ + u16 flags;/* Will be used for flags same as nat44 session */ + + /* 0x12 */ + u16 timeout; + + /* 0x14 */ + u32 entry_expires; + /* 0x18 */ + index_dlist_t bib_list; + /* 0x20 = 32 B */ + + union { /* alg same as cnat_main_db_t */ + u16 delta; + i8 alg_dlt[2]; + u16 il; + } alg; + + /* 0x22 */ + u16 tcp_flags; /* Mainly TCP events - check nat64_tcp_sm.h */ + + /* 0x24 */ + u32 tcp_seq_num; + + /* 0x28 */ /* unused1, unused2 and unused3 are put to make it in sync with + * cnat_session_db */ + u32 unused1; + + /* 0x2C */ + u32 unused2; + + /* 0x30 */ + u16 unused3; + + /* 0x32 - 50B */ + +} nat64_session_entry_t; + +/* + * nat64_session_tcp_init_entry_t + * This structure will be used to store information about v4 initiation + * tcp entries. + */ +typedef struct { + nat64_v6_key_t v6_in_key; + nat64_v4_key_t v4_out_key; +} nat64_session_tcp_init_entry_t; + +/* + * nat64_in_v6_frag_entry_t + * This structure will be used to store information about fragment flows + * that are coming from inside v6 hosts. + */ +typedef struct { + index_slist_t nat64_frag_in2out_hash; + + u32 v6_src_addr[4]; + u32 v6_destn_addr[4]; + u32 frag_iden; + u16 vrf; + u16 pad1; +} nat64_in_v6_frag_entry_t ; + +/* + * nat64_out_v4_frag_entry_t + * This structure will be used to store information about fragment flows + * that are coming from outside v4 machines. + */ +typedef struct { + index_slist_t nat64_frag_out2in_hash; + + u32 v4_src_addr; + u32 v4_destn_addr; + u16 frag_iden; + u16 vrf; +} nat64_out_v4_frag_entry_t ; + +/* + * nat64_timeout _t + * These following structures will be used to store information destination + * timeouts configured. + */ +typedef struct { + nat64_v4_key_t timeout_key; + u16 timeout_value; +} nat64_timeout_t; + +/* + * nat64_timeout_db_entry_t + */ +typedef struct { + nat64_timeout_t t_key; + index_slist_t t_hash; +} nat64_timeout_db_entry_t; + + +typedef union { + cnat_main_db_entry_t nat44_main_db; + nat64_bib_entry_t nat64_bib_db; +} cgse_nat_db_entry_t; + +typedef union { + cnat_session_entry_t nat44_session_db; + nat64_session_entry_t nat64_session_db; +} cgse_nat_session_db_entry_t; + +typedef union { + cnat_user_db_entry_t nat44_user_db; + nat64_bib_user_entry_t nat64_user_db; +} cgse_nat_user_db_entry_t; + +extern index_slist_t *nat64_bib_out2in_hash; +extern index_slist_t *nat64_bib_in2out_hash; +extern index_slist_t *nat64_bib_user_hash; +extern index_slist_t *nat64_session_out2in_hash; +extern index_slist_t *nat64_session_in2out_hash; +extern index_slist_t *nat64_frag_out2in_hash; +extern index_slist_t *nat64_frag_in2out_hash; +extern index_slist_t *nat64_timeout_hash; + +extern nat64_bib_entry_t *nat64_bib_db; +extern nat64_bib_user_entry_t *nat64_bib_user_db; +extern nat64_session_entry_t *nat64_session_db; +extern nat64_in_v6_frag_entry_t *nat64_in_frag_db; +extern nat64_out_v4_frag_entry_t *nat64_out_frag_db; +extern nat64_session_tcp_init_entry_t *nat64_tcp_init_db ; +extern nat64_timeout_db_entry_t *nat64_timeout_db; + +extern nat64_table_entry_t nat64_table_array[NAT64_MAX_NAT64_ENTRIES]; +extern nat64_table_entry_t *nat64_table_ptr; + +extern cgse_nat_db_entry_t *cgse_nat_db; +extern cgse_nat_user_db_entry_t *cgse_user_db; +extern cgse_nat_session_db_entry_t *cgse_session_db; + +void nat64_bib_user_db_delete (nat64_bib_user_entry_t *up); + +nat64_bib_user_entry_t* +nat64_bib_user_db_create_entry(nat64_v6_key_t *uki, u32 bucket, + u32 portmap_index); + +nat64_bib_user_entry_t* +nat64_bib_user_db_lookup_entry(nat64_v6_key_t *uki, u32 *bucket); + + +nat64_bib_entry_t* +nat64_bib_db_lookup_entry(nat64_v6_key_t *ki); + +void nat64_bib_db_in2out_hash_delete (nat64_bib_entry_t *ep); + +void nat64_bib_db_out2in_hash_delete (nat64_bib_entry_t *ep); + +nat64_bib_entry_t * +nat64_create_bib_db_entry_and_hash(nat64_v6_key_t *ki, + nat64_v4_key_t *ko, + nat64_bib_user_entry_t *udb); + + +void nat64_delete_bib_db_entry (nat64_bib_entry_t *ep, u8 force); + +nat64_bib_entry_t * +nat64_bib_db_lookup_entry_out2in (nat64_v4_key_t *ko); + +nat64_bib_entry_t * +nat64_get_bib_db_entry (nat64_v6_key_t *ki, + port_pair_t port_pair_type, + port_type_t port_type, + cnat_gen_icmp_info *info); + + +nat64_bib_entry_t* +nat64_create_static_bib_db_entry (nat64_v6_key_t *ki, + nat64_v4_key_t *ko, + nat64_table_entry_t *my_table, + cnat_gen_icmp_info *info); + + + +//void nat64_session_db_in2out_hash_delete (nat64_session_entry_t *ep); +void nat64_session_db_out2in_hash_delete (nat64_session_entry_t *ep); + +/*nat64_session_entry_t * +nat64_session_db_lookup_entry(nat64_v6_key_t *ki, u32 bib_index); */ + + +nat64_session_entry_t * +nat64_session_db_lookup_entry_out2in (nat64_v4_key_t *ko,u32 bib_index); + +/* +nat64_session_entry_t * +nat64_create_session_db_entry(nat64_v6_key_t *ki, + nat64_v4_key_t *ko, + nat64_bib_entry_t *bdb); +*/ +nat64_session_entry_t * +nat64_create_session_db_entry_v2( nat64_v4_key_t *ko, + nat64_bib_entry_t *bdb); + + +//void nat64_delete_session_db_entry (nat64_session_entry_t *ep); +void nat64_delete_session_db_entry_v2 (nat64_session_entry_t *ep, u8 force); + +u32 nat64_timeout_db_hash_lookup (nat64_v4_key_t t_key); + +u16 query_and_update_db_timeout_nat64(nat64_session_entry_t *db); + +void nat64_timeout_db_hash_add (nat64_timeout_db_entry_t *t_entry); + +u16 nat64_timeout_db_create (nat64_timeout_t t_entry); + +void nat64_timeout_db_delete(nat64_v4_key_t t_key); + +#define NAT64_CMP_V6_KEY(key1, key2) \ + memcmp(key1, key2, sizeof(nat64_v6_key_t)) + +#define NAT64_CMP_V4_KEY(key1, key2) \ + memcmp(key1, key2, sizeof(nat64_v4_key_t)) + + +#define NAT64_CMP_V6_IP(ip1, ip2) \ + memcmp(ip1, ip2, (sizeof(u32) * 4)) + + +#define NAT64_CMP_V6_KEY1(key1, key2) \ + (key1.ipv6[0] == key2.ipv6[0]) && (key1.ipv6[1] == key2.ipv6[1]) && \ + (key1.ipv6[2] == key2.ipv6[2]) && (key1.ipv6[3] == key2.ipv6[3]) && \ + (key1.port == key2.port) && (key1.vrf == key2.vrf) + + +#define NAT64_CMP_V6_IP1(ip1, ip2) \ + ((ip1[0] == ip2[0]) && (ip1[1] == ip2[1]) && \ + (ip1[2] == ip2[2]) && (ip1[3] == ip2[3])) + +#define NAT64_CMP_V4_KEY1(key1, key2) \ + (key1.key64 == key2.key64) + + +extern u8 nat64_timeout_dirty_flag[NAT64_MAX_NAT64_ENTRIES]; + +#endif |