FD.io VPP  v21.01.1
Vector Packet Processing
det44.h
Go to the documentation of this file.
1 /*
2  * det44.h - deterministic NAT definitions
3  *
4  * Copyright (c) 2020 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 /**
19  * @file
20  * @brief Deterministic NAT (CGN) definitions
21  */
22 
23 #ifndef __included_det44_h__
24 #define __included_det44_h__
25 
26 #include <vnet/vnet.h>
27 #include <vnet/ip/ip.h>
28 #include <vnet/ethernet/ethernet.h>
29 #include <vnet/ip/icmp46_packet.h>
30 #include <vnet/api_errno.h>
31 #include <vnet/fib/fib_source.h>
32 #include <vppinfra/dlist.h>
33 #include <vppinfra/error.h>
34 #include <vlibapi/api.h>
35 #include <vlib/log.h>
36 #include <vnet/fib/fib_table.h>
37 #include <vnet/fib/ip4_fib.h>
39 
40 #include <nat/lib/lib.h>
41 #include <nat/lib/inlines.h>
42 #include <nat/lib/ipfix_logging.h>
43 
44 /* Session state */
45 #define foreach_det44_session_state \
46  _(0, UNKNOWN, "unknown") \
47  _(1, UDP_ACTIVE, "udp-active") \
48  _(2, TCP_SYN_SENT, "tcp-syn-sent") \
49  _(3, TCP_ESTABLISHED, "tcp-established") \
50  _(4, TCP_FIN_WAIT, "tcp-fin-wait") \
51  _(5, TCP_CLOSE_WAIT, "tcp-close-wait") \
52  _(6, TCP_CLOSING, "tcp-closing") \
53  _(7, TCP_LAST_ACK, "tcp-last-ack") \
54  _(8, TCP_CLOSED, "tcp-closed") \
55  _(9, ICMP_ACTIVE, "icmp-active")
56 
57 typedef enum
58 {
59 #define _(v, N, s) DET44_SESSION_##N = v,
61 #undef _
63 
64 #define DET44_SES_PER_USER 1000
65 
66 typedef struct
67 {
71 
72 typedef struct
73 {
76 
77 typedef struct
78 {
82 
83 /* deterministic session outside key */
84 typedef struct
85 {
86  union
87  {
88  struct
89  {
93  };
95  };
97 
98 typedef struct
99 {
100  /* Inside network port */
102  /* Outside network address and port */
104  /* Session state */
106  /* Expire timeout */
109 
110 typedef struct
111 {
112  /* inside IP address range */
115  /* outside IP address range */
118  /* inside IP addresses / outside IP addresses */
120  /* number of ports available to internal host */
122  /* session counter */
124  /* vector of sessions */
127 
128 typedef struct
129 {
133 
134 typedef struct
135 {
139 
140 typedef struct
141 {
144 } det44_fib_t;
145 
146 typedef struct det44_main_s
147 {
149 
152 
153  /* Vector of outside fibs */
155 
158 
161 
162  /* Deterministic NAT mappings */
164 
165  /* TCP MSS clamping */
167 
168  /* Protocol timeouts */
170 
171  /* Expire walk process node index */
173 
175 
176  /* API message ID base */
178 
179  /* log class */
181 
183 
184  /* convenience */
186  /* required */
188 
189 } det44_main_t;
190 
191 extern det44_main_t det44_main;
192 
193 /* logging */
194 #define det44_log_err(...) \
195  vlib_log(VLIB_LOG_LEVEL_ERR, det44_main.log_class, __VA_ARGS__)
196 #define det44_log_warn(...) \
197  vlib_log(VLIB_LOG_LEVEL_WARNING, det44_main.log_class, __VA_ARGS__)
198 #define det44_log_notice(...) \
199  vlib_log(VLIB_LOG_LEVEL_NOTICE, det44_main.log_class, __VA_ARGS__)
200 #define det44_log_info(...) \
201  vlib_log(VLIB_LOG_LEVEL_INFO, det44_main.log_class, __VA_ARGS__)
202 #define det44_log_debug(...)\
203  vlib_log(VLIB_LOG_LEVEL_DEBUG, det44_main.log_class, __VA_ARGS__)
204 
205 /* Deterministic NAT interface flags */
206 #define DET44_INTERFACE_FLAG_IS_INSIDE 1
207 #define DET44_INTERFACE_FLAG_IS_OUTSIDE 2
208 
209 /** \brief Check if Deterministic NAT interface is inside.
210  @param i Deterministic NAT interface
211  @return 1 if inside interface
212 */
213 #define det44_interface_is_inside(i) i->flags & DET44_INTERFACE_FLAG_IS_INSIDE
214 
215 /** \brief Check if Deterministic NAT interface is outside.
216  @param i Deterministic NAT interface
217  @return 1 if outside interface
218 */
219 #define det44_interface_is_outside(i) i->flags & DET44_INTERFACE_FLAG_IS_OUTSIDE
220 
223 {
224  det44_main_t *dm = &det44_main;
225  return dm->enabled;
226 }
227 
230 
231 int det44_plugin_enable ();
232 int det44_plugin_disable ();
233 
234 int det44_interface_add_del (u32 sw_if_index, u8 is_inside, int is_del);
235 
236 int det44_set_timeouts (nat_timeouts_t * timeouts);
238 void det44_reset_timeouts ();
239 
240 /* format functions */
242 
243 int snat_det_add_map (ip4_address_t * in_addr, u8 in_plen,
244  ip4_address_t * out_addr, u8 out_plen, int is_add);
245 
246 /* icmp session match functions */
248  u32 thread_index, vlib_buffer_t * b0,
250  u16 * port, u32 * fib_index,
251  nat_protocol_t * proto, void *d, void *e,
252  u8 * dont_translate);
254  u32 thread_index, vlib_buffer_t * b0,
256  u16 * port, u32 * fib_index,
257  nat_protocol_t * proto, void *d, void *e,
258  u8 * dont_translate);
260  icmp46_header_t * icmp0, u32 sw_if_index0,
261  u32 rx_fib_index0, vlib_node_runtime_t * node,
262  u32 next0, u32 thread_index, void *d, void *e);
264  icmp46_header_t * icmp0, u32 sw_if_index0,
265  u32 rx_fib_index0, vlib_node_runtime_t * node,
266  u32 next0, u32 thread_index, void *d, void *e);
267 
270 {
271  if (net->as_u32 == (addr->as_u32 & ip4_main.fib_masks[plen]))
272  return 1;
273  return 0;
274 }
275 
278 {
279  det44_main_t *dm = &det44_main;
280  snat_det_map_t *mp;
281  /* *INDENT-OFF* */
282  pool_foreach (mp, dm->det_maps)
283  {
284  if (is_addr_in_net(user_addr, &mp->in_addr, mp->in_plen))
285  return mp;
286  }
287  /* *INDENT-ON* */
288  return 0;
289 }
290 
293 {
294  det44_main_t *dm = &det44_main;
295  snat_det_map_t *mp;
296  /* *INDENT-OFF* */
297  pool_foreach (mp, dm->det_maps)
298  {
299  if (is_addr_in_net(out_addr, &mp->out_addr, mp->out_plen))
300  return mp;
301  }
302  /* *INDENT-ON* */
303  return 0;
304 }
305 
308  ip4_address_t * out_addr, u16 * lo_port)
309 {
310  u32 in_offset, out_offset;
311 
312  in_offset = clib_net_to_host_u32 (in_addr->as_u32) -
313  clib_net_to_host_u32 (dm->in_addr.as_u32);
314  out_offset = in_offset / dm->sharing_ratio;
315  out_addr->as_u32 =
316  clib_host_to_net_u32 (clib_net_to_host_u32 (dm->out_addr.as_u32) +
317  out_offset);
318  *lo_port = 1024 + dm->ports_per_host * (in_offset % dm->sharing_ratio);
319 }
320 
322 snat_det_reverse (snat_det_map_t * dm, ip4_address_t * out_addr, u16 out_port,
323  ip4_address_t * in_addr)
324 {
325  u32 in_offset1, in_offset2, out_offset;
326 
327  out_offset = clib_net_to_host_u32 (out_addr->as_u32) -
328  clib_net_to_host_u32 (dm->out_addr.as_u32);
329  in_offset1 = out_offset * dm->sharing_ratio;
330  in_offset2 = (out_port - 1024) / dm->ports_per_host;
331  in_addr->as_u32 =
332  clib_host_to_net_u32 (clib_net_to_host_u32 (dm->in_addr.as_u32) +
333  in_offset1 + in_offset2);
334 }
335 
338 {
339  return (clib_net_to_host_u32 (addr->as_u32) & pow2_mask (32 - plen)) *
341 }
342 
345  u64 out_key)
346 {
347  u32 user_offset;
348  u16 i;
349 
350  user_offset = snat_det_user_ses_offset (in_addr, dm->in_plen);
351  for (i = 0; i < DET44_SES_PER_USER; i++)
352  {
353  if (dm->sessions[i + user_offset].out.as_u64 == out_key)
354  return &dm->sessions[i + user_offset];
355  }
356 
357  return 0;
358 }
359 
362  u16 in_port, snat_det_out_key_t out_key)
363 {
364  snat_det_session_t *ses;
365  u32 user_offset;
366  u16 i;
367 
368  user_offset = snat_det_user_ses_offset (in_addr, dm->in_plen);
369  for (i = 0; i < DET44_SES_PER_USER; i++)
370  {
371  ses = &dm->sessions[i + user_offset];
372  if (ses->in_port == in_port &&
373  ses->out.ext_host_addr.as_u32 == out_key.ext_host_addr.as_u32 &&
374  ses->out.ext_host_port == out_key.ext_host_port)
375  return &dm->sessions[i + user_offset];
376  }
377 
378  return 0;
379 }
380 
383  ip4_address_t * in_addr, u16 in_port,
384  snat_det_out_key_t * out)
385 {
386  u32 user_offset;
387  u16 i;
388 
389  user_offset = snat_det_user_ses_offset (in_addr, dm->in_plen);
390 
391  for (i = 0; i < DET44_SES_PER_USER; i++)
392  {
393  if (!dm->sessions[i + user_offset].in_port)
394  {
396  (&dm->sessions[i + user_offset].in_port, 0, in_port))
397  {
398  dm->sessions[i + user_offset].out.as_u64 = out->as_u64;
399  dm->sessions[i + user_offset].state = DET44_SESSION_UNKNOWN;
400  dm->sessions[i + user_offset].expire = 0;
401  clib_atomic_add_fetch (&dm->ses_num, 1);
402  return &dm->sessions[i + user_offset];
403  }
404  }
405  }
406 
408  DET44_SES_PER_USER,
409  in_addr->as_u32);
410  return 0;
411 }
412 
415 {
416  if (clib_atomic_bool_cmp_and_swap (&ses->in_port, ses->in_port, 0))
417  {
418  ses->out.as_u64 = 0;
419  clib_atomic_add_fetch (&dm->ses_num, -1);
420  }
421 }
422 
424 
425 #endif /* __included_det44_h__ */
426 
427 /*
428  * fd.io coding-style-patch-verification: ON
429  *
430  * Local Variables:
431  * eval: (c-set-style "gnu")
432  * End:
433  */
enum fib_source_t_ fib_source_t
The different sources that can create a route.
static_always_inline snat_det_session_t * snat_det_get_ses_by_out(snat_det_map_t *dm, ip4_address_t *in_addr, u64 out_key)
Definition: det44.h:344
u16 ext_host_port
Definition: det44.h:91
fib_source_t fib_src_low
Definition: det44.h:157
static_always_inline void snat_det_reverse(snat_det_map_t *dm, ip4_address_t *out_addr, u16 out_port, ip4_address_t *in_addr)
Definition: det44.h:322
nat_timeouts_t det44_get_timeouts()
Definition: det44.c:181
u32 inside_vrf_id
Definition: det44.h:137
#define clib_atomic_add_fetch(a, b)
Definition: atomics.h:30
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:527
vnet_main_t * vnet_main
Definition: det44.h:187
unsigned long u64
Definition: types.h:89
vl_api_ip_port_and_mask_t dst_port
Definition: flow_types.api:92
u32 det44_icmp_in2out(vlib_buffer_t *b0, ip4_header_t *ip0, icmp46_header_t *icmp0, u32 sw_if_index0, u32 rx_fib_index0, vlib_node_runtime_t *node, u32 next0, u32 thread_index, void *d, void *e)
Definition: det44_in2out.c:255
struct det44_main_s det44_main_t
nat_protocol_t
Definition: lib.h:63
NAT port/address allocation lib.
format_function_t format_det_map_ses
Definition: det44.h:241
vhost_vring_addr_t addr
Definition: vhost_user.h:111
unsigned char u8
Definition: types.h:56
det44_main_t det44_main
Definition: det44.c:30
static_always_inline u32 snat_det_user_ses_offset(ip4_address_t *addr, u8 plen)
Definition: det44.h:337
nat_timeouts_t timeouts
Definition: det44.h:169
u8 *() format_function_t(u8 *s, va_list *args)
Definition: format.h:48
u32 icmp_match_in2out_det(vlib_node_runtime_t *node, u32 thread_index, vlib_buffer_t *b0, ip4_header_t *ip0, ip4_address_t *addr, u16 *port, u32 *fib_index, nat_protocol_t *proto, void *d, void *e, u8 *dont_translate)
Get address and port values to be used for ICMP packet translation and create session if needed...
Definition: det44_in2out.c:100
det44_fib_t * outside_fibs
Definition: det44.h:154
static_always_inline u8 plugin_enabled()
Definition: det44.h:222
u32 vlib_log_class_t
Definition: vlib.h:51
#define static_always_inline
Definition: clib.h:109
u16 mss_clamping
Definition: det44.h:166
int det44_plugin_disable()
Definition: det44.c:385
ip4_address_t ext_host_addr
Definition: det44.h:90
int det44_plugin_enable()
static uword pow2_mask(uword x)
Definition: clib.h:238
static_always_inline snat_det_session_t * snat_det_find_ses_by_in(snat_det_map_t *dm, ip4_address_t *in_addr, u16 in_port, snat_det_out_key_t out_key)
Definition: det44.h:361
static_always_inline snat_det_session_t * snat_det_ses_create(u32 thread_index, snat_det_map_t *dm, ip4_address_t *in_addr, u16 in_port, snat_det_out_key_t *out)
Definition: det44.h:382
static_always_inline snat_det_map_t * snat_det_map_by_out(ip4_address_t *out_addr)
Definition: det44.h:292
u32 out2in_node_index
Definition: det44.h:159
u32 det44_icmp_out2in(vlib_buffer_t *b0, ip4_header_t *ip0, icmp46_header_t *icmp0, u32 sw_if_index0, u32 rx_fib_index0, vlib_node_runtime_t *node, u32 next0, u32 thread_index, void *d, void *e)
Definition: det44_out2in.c:233
u16 msg_id_base
Definition: det44.h:177
unsigned int u32
Definition: types.h:88
u32 outside_vrf_id
Definition: det44.h:136
u32 fib_index
Definition: det44.h:142
snat_det_session_t * sessions
Definition: det44.h:125
vl_api_ip_proto_t proto
Definition: acl_types.api:51
IPv4 shallow virtual reassembly.
unsigned short u16
Definition: types.h:57
static_always_inline int is_addr_in_net(ip4_address_t *addr, ip4_address_t *net, u8 plen)
Definition: det44.h:269
snat_det_map_t * det_maps
Definition: det44.h:163
u16 src_port
Definition: det44.h:74
void nat_ipfix_logging_max_entries_per_user(u32 thread_index, u32 limit, u32 src_ip)
Generate maximum entries per user exceeded event.
static_always_inline void snat_det_forward(snat_det_map_t *dm, ip4_address_t *in_addr, ip4_address_t *out_addr, u16 *lo_port)
Definition: det44.h:307
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
u32 in2out_node_index
Definition: det44.h:160
int snat_det_add_map(ip4_address_t *in_addr, u8 in_plen, ip4_address_t *out_addr, u8 out_plen, int is_add)
Add/delete deterministic NAT mapping.
Definition: det44.c:99
u32 sharing_ratio
Definition: det44.h:119
ip4_address_t out_addr
Definition: det44.h:116
u32 outside_fib_index
Definition: det44.h:150
static_always_inline void snat_det_ses_close(snat_det_map_t *dm, snat_det_session_t *ses)
Definition: det44.h:414
u32 cached_sw_if_index
Definition: det44.h:79
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1580
vlib_node_registration_t det44_out2in_node
(constructor) VLIB_REGISTER_NODE (det44_out2in_node)
Definition: det44_out2in.c:819
#define DET44_SES_PER_USER
Definition: det44.h:64
IPv4 main type.
Definition: ip4.h:107
u32 cached_ip4_address
Definition: det44.h:80
u32 refcount
Definition: det44.h:143
ip4_address_t in_addr
Definition: det44.h:113
u32 icmp_match_out2in_det(vlib_node_runtime_t *node, u32 thread_index, vlib_buffer_t *b0, ip4_header_t *ip0, ip4_address_t *addr, u16 *port, u32 *fib_index, nat_protocol_t *proto, void *d, void *e, u8 *dont_translate)
Get address and port values to be used for ICMP packet translation and create session if needed...
Definition: det44_out2in.c:100
#define foreach_det44_session_state
Definition: det44.h:45
void det44_reset_timeouts()
Definition: det44.c:188
vlib_node_registration_t det44_in2out_node
(constructor) VLIB_REGISTER_NODE (det44_in2out_node)
struct _vlib_node_registration vlib_node_registration_t
det44_interface_t * interfaces
Definition: det44.h:182
#define clib_atomic_bool_cmp_and_swap(addr, old, new)
Definition: atomics.h:38
u16 ports_per_host
Definition: det44.h:121
VLIB buffer representation.
Definition: buffer.h:102
snat_det_out_key_t out
Definition: det44.h:103
ip4_main_t * ip4_main
Definition: det44.h:185
u16 port
Definition: lb_types.api:73
u32 enabled
Definition: det44.h:174
clib_error_t * det44_api_hookup(vlib_main_t *vm)
Definition: det44_api.c:620
vlib_log_class_t log_class
Definition: det44.h:180
int det44_set_timeouts(nat_timeouts_t *timeouts)
Definition: det44.c:166
u32 expire_walk_node_index
Definition: det44.h:172
u32 inside_fib_index
Definition: det44.h:151
u32 ses_num
Definition: det44.h:123
int det44_interface_add_del(u32 sw_if_index, u8 is_inside, int is_del)
Definition: det44.c:195
static_always_inline snat_det_map_t * snat_det_map_by_user(ip4_address_t *user_addr)
Definition: det44.h:277
det44_session_state_t
Definition: det44.h:57
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
fib_source_t fib_src_hi
Definition: det44.h:156
det44_config_t config
Definition: det44.h:148
u32 fib_masks[33]
Definition: ip4.h:120