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