FD.io VPP  v17.04-9-g99c0734
Vector Packet Processing
snat.h
Go to the documentation of this file.
1 
2 /*
3  * snat.h - simple nat definitions
4  *
5  * Copyright (c) 2016 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 #ifndef __included_snat_h__
19 #define __included_snat_h__
20 
21 #include <vnet/vnet.h>
22 #include <vnet/ip/ip.h>
23 #include <vnet/ethernet/ethernet.h>
24 #include <vnet/ip/icmp46_packet.h>
25 #include <vnet/api_errno.h>
26 #include <vppinfra/bihash_8_8.h>
27 #include <vppinfra/dlist.h>
28 #include <vppinfra/error.h>
29 #include <vlibapi/api.h>
30 
31 
32 #define SNAT_UDP_TIMEOUT 300
33 #define SNAT_TCP_TRANSITORY_TIMEOUT 240
34 #define SNAT_TCP_ESTABLISHED_TIMEOUT 7440
35 
36 /* Key */
37 typedef struct {
38  union
39  {
40  struct
41  {
44  u16 protocol:3,
45  fib_index:13;
46  };
48  };
50 
51 typedef struct {
52  union
53  {
54  struct
55  {
59  };
61  };
63 
64 typedef struct {
65  union
66  {
67  struct
68  {
71  };
73  };
75 
76 typedef struct {
77  union
78  {
79  struct
80  {
84  };
86  };
88 
89 
90 #define foreach_snat_protocol \
91  _(UDP, 0, udp, "udp") \
92  _(TCP, 1, tcp, "tcp") \
93  _(ICMP, 2, icmp, "icmp")
94 
95 typedef enum {
96 #define _(N, i, n, s) SNAT_PROTOCOL_##N = i,
98 #undef _
100 
101 
102 #define foreach_snat_session_state \
103  _(0, UNKNOWN, "unknown") \
104  _(1, UDP_ACTIVE, "udp-active") \
105  _(2, TCP_SYN_SENT, "tcp-syn-sent") \
106  _(3, TCP_ESTABLISHED, "tcp-established") \
107  _(4, TCP_FIN_WAIT, "tcp-fin-wait") \
108  _(5, TCP_CLOSE_WAIT, "tcp-close-wait") \
109  _(6, TCP_LAST_ACK, "tcp-last-ack")
110 
111 typedef enum {
112 #define _(v, N, s) SNAT_SESSION_##N = v,
114 #undef _
116 
117 
118 #define SNAT_SESSION_FLAG_STATIC_MAPPING 1
119 
120 typedef CLIB_PACKED(struct {
121  snat_session_key_t out2in; /* 0-15 */
122 
123  snat_session_key_t in2out; /* 16-31 */
124 
125  u32 flags; /* 32-35 */
126 
127  /* per-user translations */
128  u32 per_user_index; /* 36-39 */
129 
130  u32 per_user_list_head_index; /* 40-43 */
131 
132  /* Last heard timer */
133  f64 last_heard; /* 44-51 */
134 
135  u64 total_bytes; /* 52-59 */
136 
137  u32 total_pkts; /* 60-63 */
138 
139  /* Outside address */
140  u32 outside_address_index; /* 64-67 */
141 
142 }) snat_session_t;
143 
144 
145 typedef struct {
151 } snat_user_t;
152 
153 typedef struct {
156 #define _(N, i, n, s) \
157  u32 busy_##n##_ports; \
158  uword * busy_##n##_port_bitmap;
160 #undef _
161 } snat_address_t;
162 
163 typedef struct {
169 
170 typedef struct {
178  /* vector of sessions */
181 
182 typedef struct {
190  snat_protocol_t proto;
192 
193 typedef struct {
197 
198 typedef struct {
204  snat_protocol_t proto;
206  int is_add;
208 
209 typedef struct {
210  /* User pool */
212 
213  /* Session pool */
214  snat_session_t * sessions;
215 
216  /* Pool of doubly-linked list elements */
219 
220 struct snat_main_s;
221 
223  vlib_node_runtime_t *node,
224  u32 cpu_index,
225  vlib_buffer_t *b0,
226  snat_session_key_t *p_key,
227  snat_session_key_t *p_value,
228  u8 *p_dont_translate,
229  void *d);
230 
231 typedef u32 (snat_get_worker_function_t) (ip4_header_t * ip, u32 rx_fib_index);
232 
233 typedef struct snat_main_s {
234  /* Main lookup tables */
235  clib_bihash_8_8_t out2in;
236  clib_bihash_8_8_t in2out;
237 
238  /* Find-a-user => src address lookup */
239  clib_bihash_8_8_t user_hash;
240 
241  /* Non-translated packets worker lookup => src address + VRF */
242  clib_bihash_8_8_t worker_by_in;
243 
244  /* Translated packets worker lookup => IP address + port number */
245  clib_bihash_8_8_t worker_by_out;
246 
249 
256 
257  /* Per thread data */
259 
260  /* Find a static mapping by local */
261  clib_bihash_8_8_t static_mapping_by_local;
262 
263  /* Find a static mapping by external */
264  clib_bihash_8_8_t static_mapping_by_external;
265 
266  /* Static mapping pool */
268 
269  /* Interface pool */
271 
272  /* Vector of outside addresses */
273  snat_address_t * addresses;
274 
275  /* sw_if_indices whose intfc addresses should be auto-added */
277 
278  /* vector of interface address static mappings to resolve. */
280 
281  /* Randomize port allocation order */
283 
284  /* Worker handoff index */
287 
288  /* in2out and out2in node index */
291 
292  /* Deterministic NAT */
294 
295  /* Config parameters */
308 
309  /* tenant VRF aware address pool activation flag */
311 
312  /* API message ID base */
314 
315  /* convenience */
321 } snat_main_t;
322 
323 extern snat_main_t snat_main;
332 
334  snat_session_key_t * k,
335  u32 address_index);
336 
338  u32 fib_index,
339  snat_session_key_t * k,
340  u32 * address_indexp);
341 
343  snat_session_key_t match,
344  snat_session_key_t * mapping,
345  u8 by_external,
346  u8 *is_addr_only);
347 
349  u8 p_len,
350  u32 sw_if_index,
351  int is_add);
352 
354 
355 typedef struct {
359 
360 /** \brief Check if SNAT session is created from static mapping.
361  @param s SNAT session
362  @return 1 if SNAT session is created from static mapping otherwise 0
363 */
364 #define snat_is_session_static(s) s->flags & SNAT_SESSION_FLAG_STATIC_MAPPING
365 
366 /*
367  * Why is this here? Because we don't need to touch this layer to
368  * simply reply to an icmp. We need to change id to a unique
369  * value to NAT an echo request/reply.
370  */
371 
372 typedef struct {
376 
377 always_inline snat_protocol_t
379 {
380  snat_protocol_t snat_proto = ~0;
381 
382  snat_proto = (ip_proto == IP_PROTOCOL_UDP) ? SNAT_PROTOCOL_UDP : snat_proto;
383  snat_proto = (ip_proto == IP_PROTOCOL_TCP) ? SNAT_PROTOCOL_TCP : snat_proto;
384  snat_proto = (ip_proto == IP_PROTOCOL_ICMP) ? SNAT_PROTOCOL_ICMP : snat_proto;
385 
386  return snat_proto;
387 }
388 
390 snat_proto_to_ip_proto (snat_protocol_t snat_proto)
391 {
392  u8 ip_proto = ~0;
393 
394  ip_proto = (snat_proto == SNAT_PROTOCOL_UDP) ? IP_PROTOCOL_UDP : ip_proto;
395  ip_proto = (snat_proto == SNAT_PROTOCOL_TCP) ? IP_PROTOCOL_TCP : ip_proto;
396  ip_proto = (snat_proto == SNAT_PROTOCOL_ICMP) ? IP_PROTOCOL_ICMP : ip_proto;
397 
398  return ip_proto;
399 }
400 
401 typedef struct {
402  u16 src_port, dst_port;
404 
406  u32 cpu_index, vlib_buffer_t *b0,
407  snat_session_key_t *p_key,
408  snat_session_key_t *p_value,
409  u8 *p_dont_translate, void *d);
411  u32 cpu_index, vlib_buffer_t *b0,
412  snat_session_key_t *p_key,
413  snat_session_key_t *p_value,
414  u8 *p_dont_translate, void *d);
416  u32 cpu_index, vlib_buffer_t *b0,
417  snat_session_key_t *p_key,
418  snat_session_key_t *p_value,
419  u8 *p_dont_translate, void *d);
421  u32 cpu_index, vlib_buffer_t *b0,
422  snat_session_key_t *p_key,
423  snat_session_key_t *p_value,
424  u8 *p_dont_translate, void *d);
425 
427 icmp_is_error_message (icmp46_header_t * icmp)
428 {
429  switch(icmp->type)
430  {
431  case ICMP4_destination_unreachable:
432  case ICMP4_time_exceeded:
433  case ICMP4_parameter_problem:
434  case ICMP4_source_quench:
435  case ICMP4_redirect:
436  case ICMP4_alternate_host_address:
437  return 1;
438  }
439  return 0;
440 }
441 
442 #endif /* __included_snat_h__ */
ip4_address_t external_addr
Definition: snat.h:184
u32 user_memory_size
Definition: snat.h:302
typedef CLIB_PACKED(struct{snat_session_key_t out2in;snat_session_key_t in2out;u32 flags;u32 per_user_index;u32 per_user_list_head_index;f64 last_heard;u64 total_bytes;u32 total_pkts;u32 outside_address_index;}) snat_session_t
u32 sessions_per_user_list_head_index
Definition: snat.h:148
u16 ext_host_port
Definition: snat.h:57
int snat_alloc_outside_address_and_port(snat_main_t *sm, u32 fib_index, snat_session_key_t *k, u32 *address_indexp)
Definition: snat.c:1901
u16 fib_index
Definition: snat.h:83
u32 nsessions
Definition: snat.h:149
u32 snat_icmp_match_function_t(struct snat_main_s *sm, vlib_node_runtime_t *node, u32 cpu_index, vlib_buffer_t *b0, snat_session_key_t *p_key, snat_session_key_t *p_value, u8 *p_dont_translate, void *d)
Definition: snat.h:222
snat_protocol_t proto
Definition: snat.h:190
clib_bihash_8_8_t in2out
Definition: snat.h:236
static_always_inline u8 icmp_is_error_message(icmp46_header_t *icmp)
Definition: snat.h:427
vlib_node_registration_t snat_out2in_worker_handoff_node
(constructor) VLIB_REGISTER_NODE (snat_out2in_worker_handoff_node)
Definition: out2in.c:83
u32 nstaticsessions
Definition: snat.h:150
struct _vlib_node_registration vlib_node_registration_t
vlib_node_registration_t snat_det_in2out_node
(constructor) VLIB_REGISTER_NODE (snat_det_in2out_node)
Definition: in2out.c:90
u32 fib_index
Definition: snat.h:147
u8 *( format_function_t)(u8 *s, va_list *args)
Definition: format.h:48
snat_det_map_t * det_maps
Definition: snat.h:293
u8 vrf_mode
Definition: snat.h:310
dlist_elt_t * list_pool
Definition: snat.h:217
u8 in_plen
Definition: snat.h:172
clib_bihash_8_8_t worker_by_out
Definition: snat.h:245
u8 deterministic
Definition: snat.h:298
u32 user_buckets
Definition: snat.h:301
u32 cached_sw_if_index
Definition: snat.h:356
u32 icmp_match_out2in_slow(snat_main_t *sm, vlib_node_runtime_t *node, u32 cpu_index, vlib_buffer_t *b0, snat_session_key_t *p_key, snat_session_key_t *p_value, u8 *p_dont_translate, void *d)
Get address and port values to be used for packet SNAT translation and create session if needed...
Definition: out2in.c:312
u32 max_translations_per_user
Definition: snat.h:303
#define static_always_inline
Definition: clib.h:85
ip4_address_t ext_host_addr
Definition: snat.h:56
clib_bihash_8_8_t out2in
Definition: snat.h:235
#define always_inline
Definition: clib.h:84
u32 translation_buckets
Definition: snat.h:299
ip4_address_t addr
Definition: snat.h:146
vlib_node_registration_t snat_in2out_node
(constructor) VLIB_REGISTER_NODE (snat_in2out_node)
Definition: in2out.c:86
ip4_main_t * ip4_main
Definition: snat.h:318
unsigned long u64
Definition: types.h:89
ip4_address_t local_addr
Definition: snat.h:183
snat_protocol_t proto
Definition: snat.h:204
format_function_t format_snat_user
Definition: snat.h:353
u32 icmp_match_out2in_fast(snat_main_t *sm, vlib_node_runtime_t *node, u32 cpu_index, vlib_buffer_t *b0, snat_session_key_t *p_key, snat_session_key_t *p_value, u8 *p_dont_translate, void *d)
Get address and port values to be used for packet SNAT translation.
Definition: out2in.c:420
snat_session_state_t
Definition: snat.h:111
snat_det_session_t * sessions
Definition: snat.h:179
vlib_main_t * vlib_main
Definition: snat.h:316
snat_static_mapping_t * static_mappings
Definition: snat.h:267
u32 inside_fib_index
Definition: snat.h:307
u32 icmp_match_in2out_fast(snat_main_t *sm, vlib_node_runtime_t *node, u32 cpu_index, vlib_buffer_t *b0, snat_session_key_t *p_key, snat_session_key_t *p_value, u8 *p_dont_translate, void *d)
Get address and port values to be used for packet SNAT translation.
Definition: in2out.c:571
u8 static_mapping_only
Definition: snat.h:296
clib_bihash_8_8_t user_hash
Definition: snat.h:239
vlib_node_registration_t snat_in2out_worker_handoff_node
(constructor) VLIB_REGISTER_NODE (snat_in2out_worker_handoff_node)
Definition: in2out.c:89
u32( snat_get_worker_function_t)(ip4_header_t *ip, u32 rx_fib_index)
Definition: snat.h:231
clib_bihash_8_8_t static_mapping_by_external
Definition: snat.h:264
u32 icmp_match_in2out_slow(snat_main_t *sm, vlib_node_runtime_t *node, u32 cpu_index, vlib_buffer_t *b0, snat_session_key_t *p_key, snat_session_key_t *p_value, u8 *p_dont_translate, void *d)
Get address and port values to be used for packet SNAT translation and create session if needed...
Definition: in2out.c:477
api_main_t * api_main
Definition: snat.h:320
u8 out_plen
Definition: snat.h:174
ip4_address_t addr
Definition: snat.h:81
vnet_main_t * vnet_main
Definition: snat.h:317
u32 inside_vrf_id
Definition: snat.h:306
void snat_free_outside_address_and_port(snat_main_t *sm, snat_session_key_t *k, u32 address_index)
Definition: snat.c:1804
u32 fq_out2in_index
Definition: snat.h:286
u16 src_port
Definition: snat.h:402
vlib_node_registration_t snat_det_out2in_node
(constructor) VLIB_REGISTER_NODE (snat_det_out2in_node)
Definition: out2in.c:84
snat_user_t * users
Definition: snat.h:211
vlib_node_registration_t snat_out2in_node
(constructor) VLIB_REGISTER_NODE (snat_out2in_node)
Definition: out2in.c:81
u32 random_seed
Definition: snat.h:282
struct snat_main_s snat_main_t
u32 outside_vrf_id
Definition: snat.h:304
u8 static_mapping_connection_tracking
Definition: snat.h:297
snat_get_worker_function_t * worker_in2out_cb
Definition: snat.h:254
u32 sharing_ratio
Definition: snat.h:175
ip4_address_t out_addr
Definition: snat.h:173
u32 outside_fib_index
Definition: snat.h:305
ip4_address_t addr
Definition: snat.h:42
clib_bihash_8_8_t worker_by_in
Definition: snat.h:242
u32 sw_if_index
Definition: snat.h:194
static u8 snat_proto_to_ip_proto(snat_protocol_t snat_proto)
Definition: snat.h:390
#define foreach_snat_session_state
Definition: snat.h:102
int snat_static_mapping_match(snat_main_t *sm, snat_session_key_t match, snat_session_key_t *mapping, u8 by_external, u8 *is_addr_only)
Match SNAT static mapping.
Definition: snat.c:1845
u32 * auto_add_sw_if_indices
Definition: snat.h:276
snat_protocol_t
Definition: snat.h:95
u32 num_workers
Definition: snat.h:250
unsigned int u32
Definition: types.h:88
u32 first_worker_index
Definition: snat.h:251
snat_get_worker_function_t * worker_out2in_cb
Definition: snat.h:255
ip4_address_t l_addr
Definition: snat.h:199
static snat_protocol_t ip_proto_to_snat_proto(u8 ip_proto)
Definition: snat.h:378
snat_icmp_match_function_t * icmp_match_out2in_cb
Definition: snat.h:248
IPv4 main type.
Definition: ip4.h:107
vlib_node_registration_t snat_out2in_fast_node
(constructor) VLIB_REGISTER_NODE (snat_out2in_fast_node)
Definition: out2in.c:82
u64 as_u64
Definition: snat.h:72
vlib_node_registration_t snat_in2out_fast_node
(constructor) VLIB_REGISTER_NODE (snat_in2out_fast_node)
Definition: in2out.c:88
snat_main_t snat_main
Definition: jvpp_snat.h:39
ip4_address_t addr
Definition: snat.h:69
ip4_address_t in_addr
Definition: snat.h:171
u32 fq_in2out_index
Definition: snat.h:285
u32 out2in_node_index
Definition: snat.h:290
ip4_address_t addr
Definition: snat.h:154
unsigned short u16
Definition: types.h:57
double f64
Definition: types.h:142
unsigned char u8
Definition: types.h:56
u16 msg_id_base
Definition: snat.h:313
u16 ports_per_host
Definition: snat.h:176
u32 * workers
Definition: snat.h:253
snat_main_per_thread_data_t * per_thread_data
Definition: snat.h:258
snat_det_out_key_t out
Definition: snat.h:165
void snat_add_del_addr_to_fib(ip4_address_t *addr, u8 p_len, u32 sw_if_index, int is_add)
Add/del NAT address to FIB.
Definition: snat.c:127
u32 fib_index
Definition: snat.h:70
snat_address_t * addresses
Definition: snat.h:273
u32 in2out_node_index
Definition: snat.h:289
snat_static_map_resolve_t * to_resolve
Definition: snat.h:279
u32 translation_memory_size
Definition: snat.h:300
u32 ses_num
Definition: snat.h:177
u32 next_worker
Definition: snat.h:252
#define foreach_snat_protocol
Definition: snat.h:90
vhost_vring_addr_t addr
Definition: vhost-user.h:84
u32 flags
Definition: vhost-user.h:78
ip_lookup_main_t * ip4_lookup_main
Definition: snat.h:319
snat_session_t * sessions
Definition: snat.h:214
u32 cached_ip4_address
Definition: snat.h:357
snat_icmp_match_function_t * icmp_match_in2out_cb
Definition: snat.h:247
clib_bihash_8_8_t static_mapping_by_local
Definition: snat.h:261
u32 fib_index
Definition: snat.h:155
snat_interface_t * interfaces
Definition: snat.h:270