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