2 * Copyright (c) 2020 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 #ifndef __CNAT_TYPES_H__
17 #define __CNAT_TYPES_H__
19 #include <vnet/fib/fib_node.h>
20 #include <vnet/fib/fib_source.h>
21 #include <vnet/ip/ip_types.h>
22 #include <vnet/ip/ip.h>
24 /* only in the default table for v4 and v6 */
25 #define CNAT_FIB_TABLE 0
27 /* default lifetime of NAT sessions (seconds) */
28 #define CNAT_DEFAULT_SESSION_MAX_AGE 30
29 /* lifetime of TCP conn NAT sessions after SYNACK (seconds) */
30 #define CNAT_DEFAULT_TCP_MAX_AGE 3600
31 /* lifetime of TCP conn NAT sessions after RST/FIN (seconds) */
32 #define CNAT_DEFAULT_TCP_RST_TIMEOUT 5
33 #define CNAT_DEFAULT_SCANNER_TIMEOUT (1.0)
35 #define CNAT_DEFAULT_SESSION_BUCKETS 1024
36 #define CNAT_DEFAULT_TRANSLATION_BUCKETS 1024
37 #define CNAT_DEFAULT_SNAT_BUCKETS 1024
39 #define CNAT_DEFAULT_SESSION_MEMORY (1 << 20)
40 #define CNAT_DEFAULT_TRANSLATION_MEMORY (256 << 10)
41 #define CNAT_DEFAULT_SNAT_MEMORY (64 << 20)
43 /* This should be strictly lower than FIB_SOURCE_INTERFACE
44 * from fib_source.h */
45 #define CNAT_FIB_SOURCE_PRIORITY 0x02
47 /* Initial refcnt for timestamps (2 : session & rsession) */
48 #define CNAT_TIMESTAMP_INIT_REFCNT 2
50 #define MIN_SRC_PORT ((u16) 0xC000)
56 CNAT_SPORT_PROTO_ICMP,
57 CNAT_SPORT_PROTO_ICMP6,
61 typedef struct cnat_endpoint_t_
67 typedef struct cnat_endpoint_tuple_t_
69 cnat_endpoint_t dst_ep;
70 cnat_endpoint_t src_ep;
71 } cnat_endpoint_tuple_t;
81 u32 dst_address_length_refcounts[129];
82 u16 *prefix_lengths_in_search_order;
83 uword *non_empty_dst_address_length_bitmap;
84 } cnat_snat_pfx_table_meta_t;
88 /* Stores (ip family, prefix & mask) */
89 clib_bihash_24_8_t ip_hash;
90 /* family dependant cache */
91 cnat_snat_pfx_table_meta_t meta[2];
92 /* Precomputed ip masks (ip4 & ip6) */
93 ip6_address_t ip_masks[129];
94 } cnat_snat_pfx_table_t;
96 typedef struct cnat_src_port_allocator_
98 /* Source ports bitmap for snat */
101 /* Lock for src_ports access */
102 clib_spinlock_t lock;
103 } cnat_src_port_allocator_t;
105 typedef struct cnat_main_
107 /* Memory size of the session bihash */
108 uword session_hash_memory;
110 /* Number of buckets of the session bihash */
111 u32 session_hash_buckets;
113 /* Memory size of the translation bihash */
114 uword translation_hash_memory;
116 /* Number of buckets of the translation bihash */
117 u32 translation_hash_buckets;
119 /* Memory size of the source NAT prefix bihash */
120 uword snat_hash_memory;
122 /* Number of buckets of the source NAT prefix bihash */
123 u32 snat_hash_buckets;
125 /* Timeout after which to clear sessions (in seconds) */
128 /* Timeout after which to clear an established TCP
129 * session (in seconds) */
132 /* delay in seconds between two scans of session/clients tables */
135 /* Lock for the timestamp pool */
136 clib_rwlock_t ts_lock;
138 /* Per proto source ports allocator for snat */
139 cnat_src_port_allocator_t *src_ports;
141 /* Ip4 Address to use for source NATing */
142 ip4_address_t snat_ip4;
144 /* Ip6 Address to use for source NATing */
145 ip6_address_t snat_ip6;
147 /* Longest prefix Match table for source NATing */
148 cnat_snat_pfx_table_t snat_pfx_table;
150 /* Index of the scanner process node */
151 uword scanner_node_index;
153 /* Did we do lazy init ? */
156 /* Enable or Disable the scanner on startup */
157 u8 default_scanner_state;
160 typedef struct cnat_timestamp_t_
162 /* Last time said session was seen */
164 /* expire after N seconds */
166 /* Users refcount, initially 3 (session, rsession, dpo) */
170 typedef struct cnat_node_ctx_t_
175 ip_address_family_t af;
179 extern u8 *format_cnat_endpoint (u8 * s, va_list * args);
180 extern uword unformat_cnat_ep_tuple (unformat_input_t * input,
182 extern uword unformat_cnat_ep (unformat_input_t * input, va_list * args);
183 extern cnat_timestamp_t *cnat_timestamps;
184 extern fib_source_t cnat_fib_source;
185 extern cnat_main_t cnat_main;
186 extern throttle_t cnat_throttle;
188 extern char *cnat_error_strings[];
192 #define cnat_error(n,s) CNAT_ERROR_##n,
193 #include <cnat/cnat_error.def>
198 typedef enum cnat_scanner_cmd_t_
202 } cnat_scanner_cmd_t;
205 * Lazy initialization when first adding a translation
208 extern void cnat_lazy_init ();
211 * Enable/Disable session cleanup
213 extern void cnat_enable_disable_scanner (cnat_scanner_cmd_t event_type);
220 cnat_timestamp_new (f64 t)
223 cnat_timestamp_t *ts;
224 clib_rwlock_writer_lock (&cnat_main.ts_lock);
225 pool_get (cnat_timestamps, ts);
227 ts->lifetime = cnat_main.session_max_age;
228 ts->refcnt = CNAT_TIMESTAMP_INIT_REFCNT;
229 index = ts - cnat_timestamps;
230 clib_rwlock_writer_unlock (&cnat_main.ts_lock);
235 cnat_timestamp_inc_refcnt (u32 index)
237 clib_rwlock_reader_lock (&cnat_main.ts_lock);
238 cnat_timestamp_t *ts = pool_elt_at_index (cnat_timestamps, index);
240 clib_rwlock_reader_unlock (&cnat_main.ts_lock);
244 cnat_timestamp_update (u32 index, f64 t)
246 clib_rwlock_reader_lock (&cnat_main.ts_lock);
247 cnat_timestamp_t *ts = pool_elt_at_index (cnat_timestamps, index);
249 clib_rwlock_reader_unlock (&cnat_main.ts_lock);
253 cnat_timestamp_set_lifetime (u32 index, u16 lifetime)
255 clib_rwlock_reader_lock (&cnat_main.ts_lock);
256 cnat_timestamp_t *ts = pool_elt_at_index (cnat_timestamps, index);
257 ts->lifetime = lifetime;
258 clib_rwlock_reader_unlock (&cnat_main.ts_lock);
262 cnat_timestamp_exp (u32 index)
265 if (INDEX_INVALID == index)
267 clib_rwlock_reader_lock (&cnat_main.ts_lock);
268 cnat_timestamp_t *ts = pool_elt_at_index (cnat_timestamps, index);
269 t = ts->last_seen + (f64) ts->lifetime;
270 clib_rwlock_reader_unlock (&cnat_main.ts_lock);
275 cnat_timestamp_free (u32 index)
277 if (INDEX_INVALID == index)
279 clib_rwlock_writer_lock (&cnat_main.ts_lock);
280 cnat_timestamp_t *ts = pool_elt_at_index (cnat_timestamps, index);
283 pool_put (cnat_timestamps, ts);
284 clib_rwlock_writer_unlock (&cnat_main.ts_lock);
287 always_inline cnat_src_port_allocator_t *
288 cnat_get_src_port_allocator (ip_protocol_t iproto)
290 cnat_main_t *cm = &cnat_main;
293 case IP_PROTOCOL_TCP:
294 return &cm->src_ports[CNAT_SPORT_PROTO_TCP];
295 case IP_PROTOCOL_UDP:
296 return &cm->src_ports[CNAT_SPORT_PROTO_UDP];
297 case IP_PROTOCOL_ICMP:
298 return &cm->src_ports[CNAT_SPORT_PROTO_ICMP];
299 case IP_PROTOCOL_ICMP6:
300 return &cm->src_ports[CNAT_SPORT_PROTO_ICMP6];
307 cnat_free_port (u16 port, ip_protocol_t iproto)
309 cnat_src_port_allocator_t *ca;
310 ca = cnat_get_src_port_allocator (iproto);
313 clib_spinlock_lock (&ca->lock);
314 clib_bitmap_set_no_check (ca->bmap, port, 0);
315 clib_spinlock_unlock (&ca->lock);
319 cnat_allocate_port (u16 * port, ip_protocol_t iproto)
321 *port = clib_net_to_host_u16 (*port);
323 *port = MIN_SRC_PORT;
324 cnat_src_port_allocator_t *ca;
325 ca = cnat_get_src_port_allocator (iproto);
328 clib_spinlock_lock (&ca->lock);
329 if (clib_bitmap_get_no_check (ca->bmap, *port))
331 *port = clib_bitmap_next_clear (ca->bmap, *port);
332 if (PREDICT_FALSE (*port >= UINT16_MAX))
333 *port = clib_bitmap_next_clear (ca->bmap, MIN_SRC_PORT);
334 if (PREDICT_FALSE (*port >= UINT16_MAX))
337 clib_bitmap_set_no_check (ca->bmap, *port, 1);
338 *port = clib_host_to_net_u16 (*port);
339 clib_spinlock_unlock (&ca->lock);
344 * fd.io coding-style-patch-verification: ON
347 * eval: (c-set-style "gnu")