nat: get rid of worker selection callbacks
[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 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 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 typedef struct
305 {
306   u32 cached_sw_if_index;
307   u32 cached_ip4_address;
308 } nat44_ei_runtime_t;
309
310 typedef struct
311 {
312   u32 thread_index;
313   f64 now;
314 } nat44_ei_is_idle_session_ctx_t;
315
316 typedef struct nat44_ei_main_s
317 {
318   u32 translations;
319   u32 translation_buckets;
320   u32 user_buckets;
321
322   u8 out2in_dpo;
323   u8 forwarding_enabled;
324   u8 static_mapping_only;
325   u8 static_mapping_connection_tracking;
326
327   u16 mss_clamping;
328
329   /* Find a static mapping by local */
330   clib_bihash_8_8_t static_mapping_by_local;
331
332   /* Find a static mapping by external */
333   clib_bihash_8_8_t static_mapping_by_external;
334
335   /* Static mapping pool */
336   nat44_ei_static_mapping_t *static_mappings;
337
338   /* Interface pool */
339   nat44_ei_interface_t *interfaces;
340   nat44_ei_interface_t *output_feature_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
486 int nat44_ei_plugin_disable ();
487
488 /**
489  * @brief Delete specific NAT44 EI user and his sessions
490  *
491  * @param addr         IPv4 address
492  * @param fib_index    FIB table index
493  */
494 int nat44_ei_user_del (ip4_address_t *addr, u32 fib_index);
495
496 /**
497  * @brief Delete session for static mapping
498  *
499  * @param addr         IPv4 address
500  * @param fib_index    FIB table index
501  */
502 void nat44_ei_static_mapping_del_sessions (
503   nat44_ei_main_t *nm, nat44_ei_main_per_thread_data_t *tnm,
504   nat44_ei_user_key_t u_key, int addr_only, ip4_address_t e_addr, u16 e_port);
505
506 u32 nat44_ei_get_in2out_worker_index (ip4_header_t *ip0, u32 rx_fib_index0,
507                                       u8 is_output);
508
509 u32 nat44_ei_get_out2in_worker_index (vlib_buffer_t *b, ip4_header_t *ip0,
510                                       u32 rx_fib_index0, u8 is_output);
511
512 /**
513  * @brief Set address and port assignment algorithm to default/standard
514  */
515 void nat44_ei_set_alloc_default (void);
516
517 /**
518  * @brief Set address and port assignment algorithm for MAP-E CE
519  *
520  * @param psid        Port Set Identifier value
521  * @param psid_offset number of offset bits
522  * @param psid_length length of PSID
523  */
524 void nat44_ei_set_alloc_mape (u16 psid, u16 psid_offset, u16 psid_length);
525
526 /**
527  * @brief Set address and port assignment algorithm for port range
528  *
529  * @param start_port beginning of the port range
530  * @param end_port   end of the port range
531  */
532 void nat44_ei_set_alloc_range (u16 start_port, u16 end_port);
533
534 /**
535  * @brief Add/delete NAT44-EI static mapping
536  *
537  * @param l_addr       local IPv4 address
538  * @param e_addr       external IPv4 address
539  * @param l_port       local port number
540  * @param e_port       external port number
541  * @param proto        L4 protocol
542  * @param sw_if_index  use interface address as external IPv4 address
543  * @param vrf_id       local VRF ID
544  * @param addr_only    1 = 1:1NAT, 0 = 1:1NAPT
545  * @param identity_nat identity NAT
546  * @param tag opaque   string tag
547  * @param is_add       1 = add, 0 = delete
548  *
549  * @return 0 on success, non-zero value otherwise
550
551  */
552 int nat44_ei_add_del_static_mapping (ip4_address_t l_addr,
553                                      ip4_address_t e_addr, u16 l_port,
554                                      u16 e_port, nat_protocol_t proto,
555                                      u32 sw_if_index, u32 vrf_id, u8 addr_only,
556                                      u8 identity_nat, u8 *tag, u8 is_add);
557
558 /**
559  * @brief Delete NAT44-EI session
560  *
561  * @param addr   IPv4 address
562  * @param port   L4 port number
563  * @param proto  L4 protocol
564  * @param vrf_id VRF ID
565  * @param is_in  1 = inside network address and port pair, 0 = outside
566  *
567  * @return 0 on success, non-zero value otherwise
568  */
569 int nat44_ei_del_session (nat44_ei_main_t *nm, ip4_address_t *addr, u16 port,
570                           nat_protocol_t proto, u32 vrf_id, int is_in);
571
572 /**
573  * @brief Match NAT44-EI static mapping.
574  *
575  * @param key             address and port to match
576  * @param addr            external/local address of the matched mapping
577  * @param port            port of the matched mapping
578  * @param fib_index       fib index of the matched mapping
579  * @param by_external     if 0 match by local address otherwise match by
580  * external address
581  * @param is_addr_only    1 if matched mapping is address only
582  * @param is_identity_nat 1 if indentity mapping
583  *
584  * @returns 0 if match found otherwise 1.
585  */
586 int nat44_ei_static_mapping_match (ip4_address_t match_addr, u16 match_port,
587                                    u32 match_fib_index,
588                                    nat_protocol_t match_protocol,
589                                    ip4_address_t *mapping_addr,
590                                    u16 *mapping_port, u32 *mapping_fib_index,
591                                    u8 by_external, u8 *is_addr_only,
592                                    u8 *is_identity_nat);
593
594 /**
595  * @brief Clear all active NAT44-EI sessions.
596  */
597 void nat44_ei_sessions_clear ();
598
599 nat44_ei_user_t *nat44_ei_user_get_or_create (nat44_ei_main_t *nm,
600                                               ip4_address_t *addr,
601                                               u32 fib_index, u32 thread_index);
602
603 nat44_ei_session_t *nat44_ei_session_alloc_or_recycle (nat44_ei_main_t *nm,
604                                                        nat44_ei_user_t *u,
605                                                        u32 thread_index,
606                                                        f64 now);
607
608 void nat44_ei_free_session_data_v2 (nat44_ei_main_t *nm, nat44_ei_session_t *s,
609                                     u32 thread_index, u8 is_ha);
610
611 void nat44_ei_free_outside_address_and_port (nat44_ei_address_t *addresses,
612                                              u32 thread_index,
613                                              ip4_address_t *addr, u16 port,
614                                              nat_protocol_t protocol);
615
616 int nat44_ei_set_outside_address_and_port (nat44_ei_address_t *addresses,
617                                            u32 thread_index,
618                                            ip4_address_t addr, u16 port,
619                                            nat_protocol_t protocol);
620
621 int nat44_ei_del_address (nat44_ei_main_t *nm, ip4_address_t addr,
622                           u8 delete_sm);
623
624 void nat44_ei_free_session_data (nat44_ei_main_t *nm, nat44_ei_session_t *s,
625                                  u32 thread_index, u8 is_ha);
626
627 int nat44_ei_set_workers (uword *bitmap);
628
629 void nat44_ei_add_del_address_dpo (ip4_address_t addr, u8 is_add);
630
631 int nat44_ei_add_address (nat44_ei_main_t *nm, ip4_address_t *addr,
632                           u32 vrf_id);
633
634 void nat44_ei_delete_session (nat44_ei_main_t *nm, nat44_ei_session_t *ses,
635                               u32 thread_index);
636
637 int nat44_ei_interface_add_del (u32 sw_if_index, u8 is_inside, int is_del);
638
639 int nat44_ei_interface_add_del_output_feature (u32 sw_if_index, u8 is_inside,
640                                                int is_del);
641
642 int nat44_ei_add_interface_address (nat44_ei_main_t *nm, u32 sw_if_index,
643                                     int is_del);
644
645 /* Call back functions for clib_bihash_add_or_overwrite_stale */
646 int nat44_i2o_is_idle_session_cb (clib_bihash_kv_8_8_t *kv, void *arg);
647 int nat44_o2i_is_idle_session_cb (clib_bihash_kv_8_8_t *kv, void *arg);
648
649 int nat44_ei_hairpinning (vlib_main_t *vm, vlib_node_runtime_t *node,
650                           nat44_ei_main_t *nm, u32 thread_index,
651                           vlib_buffer_t *b0, ip4_header_t *ip0,
652                           udp_header_t *udp0, tcp_header_t *tcp0, u32 proto0,
653                           int do_trace, u32 *required_thread_index);
654
655 void nat44_ei_hairpinning_sm_unknown_proto (nat44_ei_main_t *nm,
656                                             vlib_buffer_t *b,
657                                             ip4_header_t *ip);
658
659 u32 nat44_ei_icmp_hairpinning (nat44_ei_main_t *nm, vlib_buffer_t *b0,
660                                u32 thread_index, ip4_header_t *ip0,
661                                icmp46_header_t *icmp0,
662                                u32 *required_thread_index);
663
664 int nat44_ei_set_frame_queue_nelts (u32 frame_queue_nelts);
665
666 #define nat44_ei_is_session_static(sp)                                        \
667   (sp->flags & NAT44_EI_SESSION_FLAG_STATIC_MAPPING)
668 #define nat44_ei_is_unk_proto_session(sp)                                     \
669   (sp->flags & NAT44_EI_SESSION_FLAG_UNKNOWN_PROTO)
670
671 #define nat44_ei_interface_is_inside(ip)                                      \
672   (ip->flags & NAT44_EI_INTERFACE_FLAG_IS_INSIDE)
673 #define nat44_ei_interface_is_outside(ip)                                     \
674   (ip->flags & NAT44_EI_INTERFACE_FLAG_IS_OUTSIDE)
675
676 #define nat44_ei_is_addr_only_static_mapping(mp)                              \
677   (mp->flags & NAT44_EI_STATIC_MAPPING_FLAG_ADDR_ONLY)
678 #define nat44_ei_is_identity_static_mapping(mp)                               \
679   (mp->flags & NAT44_EI_STATIC_MAPPING_FLAG_IDENTITY_NAT)
680
681 /* logging */
682 #define nat44_ei_log_err(...)                                                 \
683   vlib_log (VLIB_LOG_LEVEL_ERR, nat44_ei_main.log_class, __VA_ARGS__)
684 #define nat44_ei_log_warn(...)                                                \
685   vlib_log (VLIB_LOG_LEVEL_WARNING, nat44_ei_main.log_class, __VA_ARGS__)
686 #define nat44_ei_log_notice(...)                                              \
687   vlib_log (VLIB_LOG_LEVEL_NOTICE, nat44_ei_main.log_class, __VA_ARGS__)
688 #define nat44_ei_log_info(...)                                                \
689   vlib_log (VLIB_LOG_LEVEL_INFO, nat44_ei_main.log_class, __VA_ARGS__)
690 #define nat44_ei_log_debug(...)                                               \
691   vlib_log (VLIB_LOG_LEVEL_DEBUG, nat44_ei_main.log_class, __VA_ARGS__)
692
693 #endif /* __included_nat44_ei_h__ */
694 /*
695  * fd.io coding-style-patch-verification: ON
696  *
697  * Local Variables:
698  * eval: (c-set-style "gnu")
699  * End:
700  */