tcp: make syn-rcvd timeout configurable
[vpp.git] / src / plugins / nat / nat44-ei / nat44_ei.h
1 /*
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:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
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.
14  */
15 /**
16  * @file nat44_ei.h
17  * NAT44 endpoint independent plugin declarations
18  */
19 #ifndef __included_nat44_ei_h__
20 #define __included_nat44_ei_h__
21
22 #include <vlib/log.h>
23 #include <vlibapi/api.h>
24
25 #include <vnet/vnet.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ethernet/ethernet.h>
28 #include <vnet/ip/icmp46_packet.h>
29 #include <vnet/api_errno.h>
30 #include <vnet/fib/fib_source.h>
31
32 #include <vppinfra/dlist.h>
33 #include <vppinfra/error.h>
34 #include <vppinfra/bihash_8_8.h>
35 #include <vppinfra/hash.h>
36
37 #include <nat/lib/lib.h>
38 #include <nat/lib/inlines.h>
39 #include <nat/lib/nat_proto.h>
40
41 /* default number of worker handoff frame queue elements */
42 #define NAT_FQ_NELTS_DEFAULT 64
43
44 /* External address and port allocation modes */
45 #define foreach_nat44_ei_addr_and_port_alloc_alg                              \
46   _ (0, DEFAULT, "default")                                                   \
47   _ (1, MAPE, "map-e")                                                        \
48   _ (2, RANGE, "port-range")
49
50 typedef enum
51 {
52 #define _(v, N, s) NAT44_EI_ADDR_AND_PORT_ALLOC_ALG_##N = v,
53   foreach_nat44_ei_addr_and_port_alloc_alg
54 #undef _
55 } nat44_ei_addr_and_port_alloc_alg_t;
56
57 /* Interface flags */
58 #define NAT44_EI_INTERFACE_FLAG_IS_INSIDE  (1 << 0)
59 #define NAT44_EI_INTERFACE_FLAG_IS_OUTSIDE (1 << 1)
60
61 /* Session flags */
62 #define NAT44_EI_SESSION_FLAG_STATIC_MAPPING (1 << 0)
63 #define NAT44_EI_SESSION_FLAG_UNKNOWN_PROTO  (1 << 1)
64
65 /* Static mapping flags */
66 #define NAT44_EI_SM_FLAG_ADDR_ONLY      (1 << 0)
67 #define NAT44_EI_SM_FLAG_IDENTITY_NAT   (1 << 1)
68 #define NAT44_EI_SM_FLAG_SWITCH_ADDRESS (1 << 2)
69
70 typedef struct
71 {
72   ip4_address_t addr;
73   u32 fib_index;
74   u32 busy_ports[NAT_N_PROTOCOLS];
75   u32 *busy_ports_per_thread[NAT_N_PROTOCOLS];
76   uword *busy_port_bitmap[NAT_N_PROTOCOLS];
77 } nat44_ei_address_t;
78
79 clib_error_t *nat44_ei_api_hookup (vlib_main_t *vm);
80
81 /* NAT address and port allocation function */
82 typedef int (nat44_ei_alloc_out_addr_and_port_function_t) (
83   nat44_ei_address_t *addresses, u32 fib_index, u32 thread_index,
84   nat_protocol_t proto, ip4_address_t s_addr, ip4_address_t *addr, u16 *port,
85   u16 port_per_thread, u32 snat_thread_index);
86
87 typedef struct
88 {
89   u16 identifier;
90   u16 sequence;
91 } icmp_echo_header_t;
92
93 typedef struct
94 {
95   u16 src_port, dst_port;
96 } tcp_udp_header_t;
97
98 typedef struct
99 {
100   union
101   {
102     struct
103     {
104       ip4_address_t addr;
105       u32 fib_index;
106     };
107     u64 as_u64;
108   };
109 } nat44_ei_user_key_t;
110
111 typedef struct
112 {
113   /* maximum number of users */
114   u32 users;
115   /* maximum number of sessions */
116   u32 sessions;
117   /* maximum number of ssessions per user */
118   u32 user_sessions;
119
120   /* plugin features */
121   u8 static_mapping_only;
122   u8 connection_tracking;
123   u8 out2in_dpo;
124
125   u32 inside_vrf;
126   u32 outside_vrf;
127
128 } nat44_ei_config_t;
129
130 typedef struct
131 {
132   ip4_address_t l_addr;
133   ip4_address_t pool_addr;
134   u16 l_port;
135   u16 e_port;
136   u32 sw_if_index;
137   u32 vrf_id;
138   u32 flags;
139   nat_protocol_t proto;
140   u8 *tag;
141 } nat44_ei_static_map_resolve_t;
142
143 typedef struct
144 {
145   /* backend IP address */
146   ip4_address_t addr;
147   /* backend port number */
148   u16 port;
149   /* probability of the backend to be randomly matched */
150   u8 probability;
151   u8 prefix;
152   /* backend FIB table */
153   u32 vrf_id;
154   u32 fib_index;
155 } nat44_ei_lb_addr_port_t;
156
157 typedef struct
158 {
159   /* preferred pool address */
160   ip4_address_t pool_addr;
161   /* local IP address */
162   ip4_address_t local_addr;
163   /* external IP address */
164   ip4_address_t external_addr;
165   /* local port */
166   u16 local_port;
167   /* external port */
168   u16 external_port;
169   /* local FIB table */
170   u32 vrf_id;
171   u32 fib_index;
172   /* protocol */
173   nat_protocol_t proto;
174   /* worker threads used by backends/local host */
175   u32 *workers;
176   /* opaque string tag */
177   u8 *tag;
178   /* backends for load-balancing mode */
179   nat44_ei_lb_addr_port_t *locals;
180   /* flags */
181   u32 flags;
182 } nat44_ei_static_mapping_t;
183
184 typedef struct
185 {
186   u32 sw_if_index;
187   u8 flags;
188 } nat44_ei_interface_t;
189
190 typedef struct
191 {
192   u32 fib_index;
193   u32 ref_count;
194 } nat44_ei_fib_t;
195
196 typedef struct
197 {
198   u32 fib_index;
199   u32 refcount;
200 } nat44_ei_outside_fib_t;
201
202 typedef CLIB_PACKED (struct {
203   /* Outside network tuple */
204   struct
205   {
206     ip4_address_t addr;
207     u32 fib_index;
208     u16 port;
209   } out2in;
210
211   /* Inside network tuple */
212   struct
213   {
214     ip4_address_t addr;
215     u32 fib_index;
216     u16 port;
217   } in2out;
218
219   nat_protocol_t nat_proto;
220
221   /* Flags */
222   u32 flags;
223
224   /* Per-user translations */
225   u32 per_user_index;
226   u32 per_user_list_head_index;
227
228   /* head of LRU list in which this session is tracked */
229   u32 lru_head_index;
230   /* index in global LRU list */
231   u32 lru_index;
232   f64 last_lru_update;
233
234   /* Last heard timer */
235   f64 last_heard;
236
237   /* Last HA refresh */
238   f64 ha_last_refreshed;
239
240   /* Counters */
241   u64 total_bytes;
242   u32 total_pkts;
243
244   /* External host address and port */
245   ip4_address_t ext_host_addr;
246   u16 ext_host_port;
247
248   /* External host address and port after translation */
249   ip4_address_t ext_host_nat_addr;
250   u16 ext_host_nat_port;
251
252   /* TCP session state */
253   u8 state;
254   u32 i2o_fin_seq;
255   u32 o2i_fin_seq;
256   u64 tcp_closed_timestamp;
257
258   /* user index */
259   u32 user_index;
260 }) nat44_ei_session_t;
261
262 typedef CLIB_PACKED (struct {
263   ip4_address_t addr;
264   u32 fib_index;
265   u32 sessions_per_user_list_head_index;
266   u32 nsessions;
267   u32 nstaticsessions;
268 }) nat44_ei_user_t;
269
270 typedef struct
271 {
272   /* Find-a-user => src address lookup */
273   clib_bihash_8_8_t user_hash;
274
275   /* User pool */
276   nat44_ei_user_t *users;
277
278   /* Session pool */
279   nat44_ei_session_t *sessions;
280
281   /* Pool of doubly-linked list elements */
282   dlist_elt_t *list_pool;
283
284   /* LRU session list - head is stale, tail is fresh */
285   dlist_elt_t *lru_pool;
286   u32 tcp_trans_lru_head_index;
287   u32 tcp_estab_lru_head_index;
288   u32 udp_lru_head_index;
289   u32 icmp_lru_head_index;
290   u32 unk_proto_lru_head_index;
291
292   /* NAT thread index */
293   u32 snat_thread_index;
294
295   /* real thread index */
296   u32 thread_index;
297
298 } nat44_ei_main_per_thread_data_t;
299
300 typedef struct
301 {
302   u32 cached_sw_if_index;
303   uword *cached_presence_by_ip4_address;
304 } nat44_ei_runtime_t;
305
306 typedef struct
307 {
308   u32 thread_index;
309   f64 now;
310 } nat44_ei_is_idle_session_ctx_t;
311
312 typedef struct nat44_ei_main_s
313 {
314   u32 translations;
315   u32 translation_buckets;
316   u32 user_buckets;
317
318   u8 out2in_dpo;
319   u8 forwarding_enabled;
320   u8 static_mapping_only;
321   u8 static_mapping_connection_tracking;
322
323   u16 mss_clamping;
324
325   /* Find a static mapping by local */
326   clib_bihash_8_8_t static_mapping_by_local;
327
328   /* Find a static mapping by external */
329   clib_bihash_8_8_t static_mapping_by_external;
330
331   /* Static mapping pool */
332   nat44_ei_static_mapping_t *static_mappings;
333
334   /* Interface pool */
335   nat44_ei_interface_t *interfaces;
336   nat44_ei_interface_t *output_feature_interfaces;
337   // broken api backward compatibility
338   nat44_ei_interface_t *output_feature_dummy_interfaces;
339
340   /* Is translation memory size calculated or user defined */
341   u8 translation_memory_size_set;
342
343   u32 max_users_per_thread;
344   u32 max_translations_per_thread;
345   u32 max_translations_per_user;
346
347   u32 inside_vrf_id;
348   u32 inside_fib_index;
349
350   u32 outside_vrf_id;
351   u32 outside_fib_index;
352
353   /* Thread settings */
354   u32 num_workers;
355   u32 first_worker_index;
356   u32 *workers;
357   u16 port_per_thread;
358
359   /* Main lookup tables */
360   clib_bihash_8_8_t out2in;
361   clib_bihash_8_8_t in2out;
362
363   /* Per thread data */
364   nat44_ei_main_per_thread_data_t *per_thread_data;
365
366   /* Vector of outside addresses */
367   nat44_ei_address_t *addresses;
368
369   nat44_ei_alloc_out_addr_and_port_function_t *alloc_addr_and_port;
370   /* Address and port allocation type */
371   nat44_ei_addr_and_port_alloc_alg_t addr_and_port_alloc_alg;
372   /* Port set parameters (MAP-E) */
373   u8 psid_offset;
374   u8 psid_length;
375   u16 psid;
376   /* Port range parameters */
377   u16 start_port;
378   u16 end_port;
379
380   /* vector of fibs */
381   nat44_ei_fib_t *fibs;
382
383   /* vector of outside fibs */
384   nat44_ei_outside_fib_t *outside_fibs;
385
386   /* sw_if_indices whose intfc addresses should be auto-added */
387   u32 *auto_add_sw_if_indices;
388
389   /* vector of interface address static mappings to resolve. */
390   nat44_ei_static_map_resolve_t *to_resolve;
391
392   u32 in2out_node_index;
393   u32 out2in_node_index;
394   u32 in2out_output_node_index;
395
396   u32 fq_in2out_index;
397   u32 fq_in2out_output_index;
398   u32 fq_out2in_index;
399
400   /* Randomize port allocation order */
401   u32 random_seed;
402
403   nat_timeouts_t timeouts;
404
405   /* counters */
406   vlib_simple_counter_main_t total_users;
407   vlib_simple_counter_main_t total_sessions;
408   vlib_simple_counter_main_t user_limit_reached;
409
410 #define _(x) vlib_simple_counter_main_t x;
411   struct
412   {
413     struct
414     {
415       struct
416       {
417         foreach_nat_counter;
418       } in2out;
419
420       struct
421       {
422         foreach_nat_counter;
423       } out2in;
424
425     } fastpath;
426
427     struct
428     {
429       struct
430       {
431         foreach_nat_counter;
432       } in2out;
433
434       struct
435       {
436         foreach_nat_counter;
437       } out2in;
438     } slowpath;
439
440     vlib_simple_counter_main_t hairpinning;
441   } counters;
442 #undef _
443
444   /* API message ID base */
445   u16 msg_id_base;
446
447   /* log class */
448   vlib_log_class_t log_class;
449   /* logging level */
450   u8 log_level;
451
452   /* convenience */
453   api_main_t *api_main;
454   ip4_main_t *ip4_main;
455   ip_lookup_main_t *ip4_lookup_main;
456
457   fib_source_t fib_src_hi;
458   fib_source_t fib_src_low;
459
460   /* pat (port address translation)
461    * dynamic mapping enabled or conneciton tracking */
462   u8 pat;
463
464   /* number of worker handoff frame queue elements */
465   u32 frame_queue_nelts;
466
467   /* nat44 plugin enabled */
468   u8 enabled;
469
470   /* hairpinning registration counter */
471   u32 hairpin_reg;
472
473   nat44_ei_config_t rconfig;
474
475   u32 in2out_hairpinning_finish_ip4_lookup_node_fq_index;
476   u32 in2out_hairpinning_finish_interface_output_node_fq_index;
477   u32 hairpinning_fq_index;
478
479   vnet_main_t *vnet_main;
480 } nat44_ei_main_t;
481
482 extern nat44_ei_main_t nat44_ei_main;
483
484 int nat44_ei_plugin_enable (nat44_ei_config_t c);
485 int nat44_ei_plugin_disable ();
486
487 int nat44_ei_add_interface (u32 sw_if_index, u8 is_inside);
488 int nat44_ei_del_interface (u32 sw_if_index, u8 is_inside);
489 int nat44_ei_add_output_interface (u32 sw_if_index);
490 int nat44_ei_del_output_interface (u32 sw_if_index);
491 int nat44_ei_add_address (ip4_address_t *addr, u32 vrf_id);
492 int nat44_ei_del_address (ip4_address_t addr, u8 delete_sm);
493 int nat44_ei_add_interface_address (u32 sw_if_index);
494 int nat44_ei_del_interface_address (u32 sw_if_index);
495
496 /**
497  * @brief Delete specific NAT44 EI user and his sessions
498  *
499  * @param addr         IPv4 address
500  * @param fib_index    FIB table index
501  */
502 int nat44_ei_user_del (ip4_address_t *addr, u32 fib_index);
503
504 /**
505  * @brief Delete session for static mapping
506  *
507  * @param addr         IPv4 address
508  * @param fib_index    FIB table index
509  */
510 void nat44_ei_static_mapping_del_sessions (
511   nat44_ei_main_t *nm, nat44_ei_main_per_thread_data_t *tnm,
512   nat44_ei_user_key_t u_key, int addr_only, ip4_address_t e_addr, u16 e_port);
513
514 u32 nat44_ei_get_in2out_worker_index (ip4_header_t *ip0, u32 rx_fib_index0,
515                                       u8 is_output);
516
517 u32 nat44_ei_get_out2in_worker_index (vlib_buffer_t *b, ip4_header_t *ip0,
518                                       u32 rx_fib_index0, u8 is_output);
519
520 /**
521  * @brief Set address and port assignment algorithm to default/standard
522  */
523 void nat44_ei_set_alloc_default (void);
524
525 /**
526  * @brief Set address and port assignment algorithm for MAP-E CE
527  *
528  * @param psid        Port Set Identifier value
529  * @param psid_offset number of offset bits
530  * @param psid_length length of PSID
531  */
532 void nat44_ei_set_alloc_mape (u16 psid, u16 psid_offset, u16 psid_length);
533
534 /**
535  * @brief Set address and port assignment algorithm for port range
536  *
537  * @param start_port beginning of the port range
538  * @param end_port   end of the port range
539  */
540 void nat44_ei_set_alloc_range (u16 start_port, u16 end_port);
541
542 int nat44_ei_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
543                                  u16 l_port, u16 e_port, nat_protocol_t proto,
544                                  u32 vrf_id, u32 sw_if_index, u32 flags,
545                                  ip4_address_t pool_addr, u8 *tag);
546
547 int nat44_ei_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
548                                  u16 l_port, u16 e_port, nat_protocol_t proto,
549                                  u32 vrf_id, u32 sw_if_index, u32 flags);
550
551 /**
552  * @brief Delete NAT44-EI session
553  *
554  * @param addr   IPv4 address
555  * @param port   L4 port number
556  * @param proto  L4 protocol
557  * @param vrf_id VRF ID
558  * @param is_in  1 = inside network address and port pair, 0 = outside
559  *
560  * @return 0 on success, non-zero value otherwise
561  */
562 int nat44_ei_del_session (nat44_ei_main_t *nm, ip4_address_t *addr, u16 port,
563                           nat_protocol_t proto, u32 vrf_id, int is_in);
564
565 /**
566  * @brief Match NAT44-EI static mapping.
567  *
568  * @param key             address and port to match
569  * @param addr            external/local address of the matched mapping
570  * @param port            port of the matched mapping
571  * @param fib_index       fib index of the matched mapping
572  * @param by_external     if 0 match by local address otherwise match by
573  * external address
574  * @param is_addr_only    1 if matched mapping is address only
575  * @param is_identity_nat 1 if indentity mapping
576  *
577  * @returns 0 if match found otherwise 1.
578  */
579 int nat44_ei_static_mapping_match (ip4_address_t match_addr, u16 match_port,
580                                    u32 match_fib_index,
581                                    nat_protocol_t match_protocol,
582                                    ip4_address_t *mapping_addr,
583                                    u16 *mapping_port, u32 *mapping_fib_index,
584                                    u8 by_external, u8 *is_addr_only,
585                                    u8 *is_identity_nat);
586
587 /**
588  * @brief Clear all active NAT44-EI sessions.
589  */
590 void nat44_ei_sessions_clear ();
591
592 nat44_ei_user_t *nat44_ei_user_get_or_create (nat44_ei_main_t *nm,
593                                               ip4_address_t *addr,
594                                               u32 fib_index, u32 thread_index);
595
596 nat44_ei_session_t *nat44_ei_session_alloc_or_recycle (nat44_ei_main_t *nm,
597                                                        nat44_ei_user_t *u,
598                                                        u32 thread_index,
599                                                        f64 now);
600
601 void nat44_ei_free_session_data_v2 (nat44_ei_main_t *nm, nat44_ei_session_t *s,
602                                     u32 thread_index, u8 is_ha);
603
604 void nat44_ei_free_outside_address_and_port (nat44_ei_address_t *addresses,
605                                              u32 thread_index,
606                                              ip4_address_t *addr, u16 port,
607                                              nat_protocol_t protocol);
608
609 int nat44_ei_set_outside_address_and_port (nat44_ei_address_t *addresses,
610                                            u32 thread_index,
611                                            ip4_address_t addr, u16 port,
612                                            nat_protocol_t protocol);
613
614 void nat44_ei_free_session_data (nat44_ei_main_t *nm, nat44_ei_session_t *s,
615                                  u32 thread_index, u8 is_ha);
616
617 int nat44_ei_set_workers (uword *bitmap);
618
619 void nat44_ei_add_del_address_dpo (ip4_address_t addr, u8 is_add);
620
621 void nat44_ei_delete_session (nat44_ei_main_t *nm, nat44_ei_session_t *ses,
622                               u32 thread_index);
623
624 /* Call back functions for clib_bihash_add_or_overwrite_stale */
625 int nat44_i2o_is_idle_session_cb (clib_bihash_kv_8_8_t *kv, void *arg);
626 int nat44_o2i_is_idle_session_cb (clib_bihash_kv_8_8_t *kv, void *arg);
627
628 int nat44_ei_set_frame_queue_nelts (u32 frame_queue_nelts);
629
630 always_inline bool
631 nat44_ei_is_session_static (nat44_ei_session_t *s)
632 {
633   return (s->flags & NAT44_EI_SESSION_FLAG_STATIC_MAPPING);
634 }
635
636 always_inline bool
637 nat44_ei_is_unk_proto_session (nat44_ei_session_t *s)
638 {
639   return (s->flags & NAT44_EI_SESSION_FLAG_UNKNOWN_PROTO);
640 }
641
642 always_inline bool
643 nat44_ei_interface_is_inside (nat44_ei_interface_t *i)
644 {
645   return (i->flags & NAT44_EI_INTERFACE_FLAG_IS_INSIDE);
646 }
647
648 always_inline bool
649 nat44_ei_interface_is_outside (nat44_ei_interface_t *i)
650 {
651   return (i->flags & NAT44_EI_INTERFACE_FLAG_IS_OUTSIDE);
652 }
653
654 always_inline bool
655 is_sm_addr_only (u32 f)
656 {
657   return (f & NAT44_EI_SM_FLAG_ADDR_ONLY);
658 }
659
660 always_inline bool
661 is_sm_identity_nat (u32 f)
662 {
663   return (f & NAT44_EI_SM_FLAG_IDENTITY_NAT);
664 }
665
666 always_inline bool
667 is_sm_switch_address (u32 f)
668 {
669   return (f & NAT44_EI_SM_FLAG_SWITCH_ADDRESS);
670 }
671
672 /* logging */
673 #define nat44_ei_log_err(...)                                                 \
674   vlib_log (VLIB_LOG_LEVEL_ERR, nat44_ei_main.log_class, __VA_ARGS__)
675 #define nat44_ei_log_warn(...)                                                \
676   vlib_log (VLIB_LOG_LEVEL_WARNING, nat44_ei_main.log_class, __VA_ARGS__)
677 #define nat44_ei_log_notice(...)                                              \
678   vlib_log (VLIB_LOG_LEVEL_NOTICE, nat44_ei_main.log_class, __VA_ARGS__)
679 #define nat44_ei_log_info(...)                                                \
680   vlib_log (VLIB_LOG_LEVEL_INFO, nat44_ei_main.log_class, __VA_ARGS__)
681 #define nat44_ei_log_debug(...)                                               \
682   vlib_log (VLIB_LOG_LEVEL_DEBUG, nat44_ei_main.log_class, __VA_ARGS__)
683
684 #endif /* __included_nat44_ei_h__ */
685 /*
686  * fd.io coding-style-patch-verification: ON
687  *
688  * Local Variables:
689  * eval: (c-set-style "gnu")
690  * End:
691  */