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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * NAT44 endpoint independent plugin declarations
19 #ifndef __included_nat44_ei_h__
20 #define __included_nat44_ei_h__
23 #include <vlibapi/api.h>
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>
32 #include <vppinfra/dlist.h>
33 #include <vppinfra/error.h>
34 #include <vppinfra/bihash_8_8.h>
36 #include <nat/lib/lib.h>
37 #include <nat/lib/inlines.h>
39 /* default number of worker handoff frame queue elements */
40 #define NAT_FQ_NELTS_DEFAULT 64
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")
50 #define _(v, N, s) NAT44_EI_ADDR_AND_PORT_ALLOC_ALG_##N = v,
51 foreach_nat44_ei_addr_and_port_alloc_alg
53 } nat44_ei_addr_and_port_alloc_alg_t;
56 #define NAT44_EI_INTERFACE_FLAG_IS_INSIDE (1 << 0)
57 #define NAT44_EI_INTERFACE_FLAG_IS_OUTSIDE (1 << 1)
60 #define NAT44_EI_SESSION_FLAG_STATIC_MAPPING (1 << 0)
61 #define NAT44_EI_SESSION_FLAG_UNKNOWN_PROTO (1 << 1)
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)
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];
79 clib_error_t *nat44_ei_api_hookup (vlib_main_t *vm);
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);
95 u16 src_port, dst_port;
109 } nat44_ei_user_key_t;
113 /* maximum number of users */
115 /* maximum number of sessions */
117 /* maximum number of ssessions per user */
120 /* plugin features */
121 u8 static_mapping_only;
122 u8 connection_tracking;
132 ip4_address_t l_addr;
133 ip4_address_t pool_addr;
139 nat_protocol_t proto;
144 } nat44_ei_static_map_resolve_t;
146 // TODO: cleanup/redo (there is no lb in EI nat)
149 /* backend IP address */
151 /* backend port number */
153 /* probability of the backend to be randomly matched */
156 /* backend FIB table */
159 } nat44_ei_lb_addr_port_t;
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;
173 /* local FIB table */
177 nat_protocol_t proto;
178 /* worker threads used by backends/local host */
180 /* opaque string tag */
182 /* backends for load-balancing mode */
183 nat44_ei_lb_addr_port_t *locals;
186 } nat44_ei_static_mapping_t;
192 } nat44_ei_interface_t;
204 } nat44_ei_outside_fib_t;
206 typedef CLIB_PACKED (struct {
207 /* Outside network tuple */
215 /* Inside network tuple */
223 nat_protocol_t nat_proto;
228 /* Per-user translations */
230 u32 per_user_list_head_index;
232 /* head of LRU list in which this session is tracked */
234 /* index in global LRU list */
238 /* Last heard timer */
241 /* Last HA refresh */
242 f64 ha_last_refreshed;
248 /* External host address and port */
249 ip4_address_t ext_host_addr;
252 /* External host address and port after translation */
253 ip4_address_t ext_host_nat_addr;
254 u16 ext_host_nat_port;
256 /* TCP session state */
260 u64 tcp_closed_timestamp;
264 }) nat44_ei_session_t;
266 typedef CLIB_PACKED (struct {
269 u32 sessions_per_user_list_head_index;
276 /* Find-a-user => src address lookup */
277 clib_bihash_8_8_t user_hash;
280 nat44_ei_user_t *users;
283 nat44_ei_session_t *sessions;
285 /* Pool of doubly-linked list elements */
286 dlist_elt_t *list_pool;
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;
296 /* NAT thread index */
297 u32 snat_thread_index;
299 /* real thread index */
302 } nat44_ei_main_per_thread_data_t;
304 /* Return worker thread index for given packet */
305 typedef u32 (nat44_ei_get_worker_in2out_function_t) (ip4_header_t *ip,
309 typedef u32 (nat44_ei_get_worker_out2in_function_t) (vlib_buffer_t *b,
316 u32 cached_sw_if_index;
317 u32 cached_ip4_address;
318 } nat44_ei_runtime_t;
324 } nat44_ei_is_idle_session_ctx_t;
326 typedef struct nat44_ei_main_s
329 u32 translation_buckets;
333 u8 forwarding_enabled;
334 u8 static_mapping_only;
335 u8 static_mapping_connection_tracking;
339 /* Find a static mapping by local */
340 clib_bihash_8_8_t static_mapping_by_local;
342 /* Find a static mapping by external */
343 clib_bihash_8_8_t static_mapping_by_external;
345 /* Static mapping pool */
346 nat44_ei_static_mapping_t *static_mappings;
349 nat44_ei_interface_t *interfaces;
350 nat44_ei_interface_t *output_feature_interfaces;
352 /* Is translation memory size calculated or user defined */
353 u8 translation_memory_size_set;
355 u32 max_users_per_thread;
356 u32 max_translations_per_thread;
357 u32 max_translations_per_user;
360 u32 inside_fib_index;
363 u32 outside_fib_index;
365 /* Thread settings */
367 u32 first_worker_index;
369 nat44_ei_get_worker_in2out_function_t *worker_in2out_cb;
370 nat44_ei_get_worker_out2in_function_t *worker_out2in_cb;
373 /* Main lookup tables */
374 clib_bihash_8_8_t out2in;
375 clib_bihash_8_8_t in2out;
377 /* Per thread data */
378 nat44_ei_main_per_thread_data_t *per_thread_data;
380 /* Vector of outside addresses */
381 nat44_ei_address_t *addresses;
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) */
390 /* Port range parameters */
395 nat44_ei_fib_t *fibs;
397 /* vector of outside fibs */
398 nat44_ei_outside_fib_t *outside_fibs;
400 /* sw_if_indices whose intfc addresses should be auto-added */
401 u32 *auto_add_sw_if_indices;
403 /* vector of interface address static mappings to resolve. */
404 nat44_ei_static_map_resolve_t *to_resolve;
406 u32 in2out_node_index;
407 u32 out2in_node_index;
408 u32 in2out_output_node_index;
411 u32 fq_in2out_output_index;
414 /* Randomize port allocation order */
417 nat_timeouts_t timeouts;
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;
424 #define _(x) vlib_simple_counter_main_t x;
454 vlib_simple_counter_main_t hairpinning;
458 /* API message ID base */
462 vlib_log_class_t log_class;
467 api_main_t *api_main;
468 ip4_main_t *ip4_main;
469 ip_lookup_main_t *ip4_lookup_main;
471 fib_source_t fib_src_hi;
472 fib_source_t fib_src_low;
474 /* pat (port address translation)
475 * dynamic mapping enabled or conneciton tracking */
478 /* number of worker handoff frame queue elements */
479 u32 frame_queue_nelts;
481 /* nat44 plugin enabled */
484 nat44_ei_config_t rconfig;
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;
491 vnet_main_t *vnet_main;
494 extern nat44_ei_main_t nat44_ei_main;
496 int nat44_ei_plugin_enable (nat44_ei_config_t c);
498 int nat44_ei_plugin_disable ();
501 * @brief Delete specific NAT44 EI user and his sessions
503 * @param addr IPv4 address
504 * @param fib_index FIB table index
506 int nat44_ei_user_del (ip4_address_t *addr, u32 fib_index);
509 * @brief Delete session for static mapping
511 * @param addr IPv4 address
512 * @param fib_index FIB table index
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);
518 u32 nat44_ei_get_in2out_worker_index (ip4_header_t *ip0, u32 rx_fib_index0,
521 u32 nat44_ei_get_out2in_worker_index (vlib_buffer_t *b, ip4_header_t *ip0,
522 u32 rx_fib_index0, u8 is_output);
525 * @brief Set address and port assignment algorithm to default/standard
527 void nat44_ei_set_alloc_default (void);
530 * @brief Set address and port assignment algorithm for MAP-E CE
532 * @param psid Port Set Identifier value
533 * @param psid_offset number of offset bits
534 * @param psid_length length of PSID
536 void nat44_ei_set_alloc_mape (u16 psid, u16 psid_offset, u16 psid_length);
539 * @brief Set address and port assignment algorithm for port range
541 * @param start_port beginning of the port range
542 * @param end_port end of the port range
544 void nat44_ei_set_alloc_range (u16 start_port, u16 end_port);
547 * @brief Add/delete NAT44-EI static mapping
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
561 * @return 0 on success, non-zero value otherwise
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);
571 * @brief Delete NAT44-EI session
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
579 * @return 0 on success, non-zero value otherwise
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);
585 * @brief Match NAT44-EI static mapping.
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
593 * @param is_addr_only 1 if matched mapping is address only
594 * @param is_identity_nat 1 if indentity mapping
596 * @returns 0 if match found otherwise 1.
598 int nat44_ei_static_mapping_match (ip4_address_t match_addr, u16 match_port,
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);
607 * @brief Clear all active NAT44-EI sessions.
609 void nat44_ei_sessions_clear ();
611 nat44_ei_user_t *nat44_ei_user_get_or_create (nat44_ei_main_t *nm,
613 u32 fib_index, u32 thread_index);
615 nat44_ei_session_t *nat44_ei_session_alloc_or_recycle (nat44_ei_main_t *nm,
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);
623 void nat44_ei_free_outside_address_and_port (nat44_ei_address_t *addresses,
625 ip4_address_t *addr, u16 port,
626 nat_protocol_t protocol);
628 int nat44_ei_set_outside_address_and_port (nat44_ei_address_t *addresses,
630 ip4_address_t addr, u16 port,
631 nat_protocol_t protocol);
633 int nat44_ei_del_address (nat44_ei_main_t *nm, ip4_address_t addr,
636 void nat44_ei_free_session_data (nat44_ei_main_t *nm, nat44_ei_session_t *s,
637 u32 thread_index, u8 is_ha);
639 int nat44_ei_set_workers (uword *bitmap);
641 void nat44_ei_add_del_address_dpo (ip4_address_t addr, u8 is_add);
643 int nat44_ei_add_address (nat44_ei_main_t *nm, ip4_address_t *addr,
646 void nat44_ei_delete_session (nat44_ei_main_t *nm, nat44_ei_session_t *ses,
649 int nat44_ei_interface_add_del (u32 sw_if_index, u8 is_inside, int is_del);
651 int nat44_ei_interface_add_del_output_feature (u32 sw_if_index, u8 is_inside,
654 int nat44_ei_add_interface_address (nat44_ei_main_t *nm, u32 sw_if_index,
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);
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);
667 void nat44_ei_hairpinning_sm_unknown_proto (nat44_ei_main_t *nm,
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);
676 int nat44_ei_set_frame_queue_nelts (u32 frame_queue_nelts);
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)
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)
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)
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__)
705 #endif /* __included_nat44_ei_h__ */
707 * fd.io coding-style-patch-verification: ON
710 * eval: (c-set-style "gnu")