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