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