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>
35 #include <vppinfra/hash.h>
37 #include <nat/lib/lib.h>
38 #include <nat/lib/inlines.h>
39 #include <nat/lib/nat_proto.h>
41 /* default number of worker handoff frame queue elements */
42 #define NAT_FQ_NELTS_DEFAULT 64
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")
52 #define _(v, N, s) NAT44_EI_ADDR_AND_PORT_ALLOC_ALG_##N = v,
53 foreach_nat44_ei_addr_and_port_alloc_alg
55 } nat44_ei_addr_and_port_alloc_alg_t;
58 #define NAT44_EI_INTERFACE_FLAG_IS_INSIDE (1 << 0)
59 #define NAT44_EI_INTERFACE_FLAG_IS_OUTSIDE (1 << 1)
62 #define NAT44_EI_SESSION_FLAG_STATIC_MAPPING (1 << 0)
63 #define NAT44_EI_SESSION_FLAG_UNKNOWN_PROTO (1 << 1)
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)
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];
81 clib_error_t *nat44_ei_api_hookup (vlib_main_t *vm);
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);
97 u16 src_port, dst_port;
111 } nat44_ei_user_key_t;
115 /* maximum number of users */
117 /* maximum number of sessions */
119 /* maximum number of ssessions per user */
122 /* plugin features */
123 u8 static_mapping_only;
124 u8 connection_tracking;
134 ip4_address_t l_addr;
135 ip4_address_t pool_addr;
141 nat_protocol_t proto;
146 } nat44_ei_static_map_resolve_t;
148 // TODO: cleanup/redo (there is no lb in EI nat)
151 /* backend IP address */
153 /* backend port number */
155 /* probability of the backend to be randomly matched */
158 /* backend FIB table */
161 } nat44_ei_lb_addr_port_t;
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;
175 /* local FIB table */
179 nat_protocol_t proto;
180 /* worker threads used by backends/local host */
182 /* opaque string tag */
184 /* backends for load-balancing mode */
185 nat44_ei_lb_addr_port_t *locals;
188 } nat44_ei_static_mapping_t;
194 } nat44_ei_interface_t;
206 } nat44_ei_outside_fib_t;
208 typedef CLIB_PACKED (struct {
209 /* Outside network tuple */
217 /* Inside network tuple */
225 nat_protocol_t nat_proto;
230 /* Per-user translations */
232 u32 per_user_list_head_index;
234 /* head of LRU list in which this session is tracked */
236 /* index in global LRU list */
240 /* Last heard timer */
243 /* Last HA refresh */
244 f64 ha_last_refreshed;
250 /* External host address and port */
251 ip4_address_t ext_host_addr;
254 /* External host address and port after translation */
255 ip4_address_t ext_host_nat_addr;
256 u16 ext_host_nat_port;
258 /* TCP session state */
262 u64 tcp_closed_timestamp;
266 }) nat44_ei_session_t;
268 typedef CLIB_PACKED (struct {
271 u32 sessions_per_user_list_head_index;
278 /* Find-a-user => src address lookup */
279 clib_bihash_8_8_t user_hash;
282 nat44_ei_user_t *users;
285 nat44_ei_session_t *sessions;
287 /* Pool of doubly-linked list elements */
288 dlist_elt_t *list_pool;
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;
298 /* NAT thread index */
299 u32 snat_thread_index;
301 /* real thread index */
304 } nat44_ei_main_per_thread_data_t;
308 u32 cached_sw_if_index;
309 uword *cached_presence_by_ip4_address;
310 } nat44_ei_runtime_t;
316 } nat44_ei_is_idle_session_ctx_t;
318 typedef struct nat44_ei_main_s
321 u32 translation_buckets;
325 u8 forwarding_enabled;
326 u8 static_mapping_only;
327 u8 static_mapping_connection_tracking;
331 /* Find a static mapping by local */
332 clib_bihash_8_8_t static_mapping_by_local;
334 /* Find a static mapping by external */
335 clib_bihash_8_8_t static_mapping_by_external;
337 /* Static mapping pool */
338 nat44_ei_static_mapping_t *static_mappings;
341 nat44_ei_interface_t *interfaces;
342 nat44_ei_interface_t *output_feature_interfaces;
344 /* Is translation memory size calculated or user defined */
345 u8 translation_memory_size_set;
347 u32 max_users_per_thread;
348 u32 max_translations_per_thread;
349 u32 max_translations_per_user;
352 u32 inside_fib_index;
355 u32 outside_fib_index;
357 /* Thread settings */
359 u32 first_worker_index;
363 /* Main lookup tables */
364 clib_bihash_8_8_t out2in;
365 clib_bihash_8_8_t in2out;
367 /* Per thread data */
368 nat44_ei_main_per_thread_data_t *per_thread_data;
370 /* Vector of outside addresses */
371 nat44_ei_address_t *addresses;
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) */
380 /* Port range parameters */
385 nat44_ei_fib_t *fibs;
387 /* vector of outside fibs */
388 nat44_ei_outside_fib_t *outside_fibs;
390 /* sw_if_indices whose intfc addresses should be auto-added */
391 u32 *auto_add_sw_if_indices;
393 /* vector of interface address static mappings to resolve. */
394 nat44_ei_static_map_resolve_t *to_resolve;
396 u32 in2out_node_index;
397 u32 out2in_node_index;
398 u32 in2out_output_node_index;
401 u32 fq_in2out_output_index;
404 /* Randomize port allocation order */
407 nat_timeouts_t timeouts;
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;
414 #define _(x) vlib_simple_counter_main_t x;
444 vlib_simple_counter_main_t hairpinning;
448 /* API message ID base */
452 vlib_log_class_t log_class;
457 api_main_t *api_main;
458 ip4_main_t *ip4_main;
459 ip_lookup_main_t *ip4_lookup_main;
461 fib_source_t fib_src_hi;
462 fib_source_t fib_src_low;
464 /* pat (port address translation)
465 * dynamic mapping enabled or conneciton tracking */
468 /* number of worker handoff frame queue elements */
469 u32 frame_queue_nelts;
471 /* nat44 plugin enabled */
474 nat44_ei_config_t rconfig;
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;
481 vnet_main_t *vnet_main;
484 extern nat44_ei_main_t nat44_ei_main;
486 int nat44_ei_plugin_enable (nat44_ei_config_t c);
488 int nat44_ei_plugin_disable ();
491 * @brief Delete specific NAT44 EI user and his sessions
493 * @param addr IPv4 address
494 * @param fib_index FIB table index
496 int nat44_ei_user_del (ip4_address_t *addr, u32 fib_index);
499 * @brief Delete session for static mapping
501 * @param addr IPv4 address
502 * @param fib_index FIB table index
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);
508 u32 nat44_ei_get_in2out_worker_index (ip4_header_t *ip0, u32 rx_fib_index0,
511 u32 nat44_ei_get_out2in_worker_index (vlib_buffer_t *b, ip4_header_t *ip0,
512 u32 rx_fib_index0, u8 is_output);
515 * @brief Set address and port assignment algorithm to default/standard
517 void nat44_ei_set_alloc_default (void);
520 * @brief Set address and port assignment algorithm for MAP-E CE
522 * @param psid Port Set Identifier value
523 * @param psid_offset number of offset bits
524 * @param psid_length length of PSID
526 void nat44_ei_set_alloc_mape (u16 psid, u16 psid_offset, u16 psid_length);
529 * @brief Set address and port assignment algorithm for port range
531 * @param start_port beginning of the port range
532 * @param end_port end of the port range
534 void nat44_ei_set_alloc_range (u16 start_port, u16 end_port);
537 * @brief Add/delete NAT44-EI static mapping
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
551 * @return 0 on success, non-zero value otherwise
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);
561 * @brief Delete NAT44-EI session
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
569 * @return 0 on success, non-zero value otherwise
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);
575 * @brief Match NAT44-EI static mapping.
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
583 * @param is_addr_only 1 if matched mapping is address only
584 * @param is_identity_nat 1 if indentity mapping
586 * @returns 0 if match found otherwise 1.
588 int nat44_ei_static_mapping_match (ip4_address_t match_addr, u16 match_port,
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);
597 * @brief Clear all active NAT44-EI sessions.
599 void nat44_ei_sessions_clear ();
601 nat44_ei_user_t *nat44_ei_user_get_or_create (nat44_ei_main_t *nm,
603 u32 fib_index, u32 thread_index);
605 nat44_ei_session_t *nat44_ei_session_alloc_or_recycle (nat44_ei_main_t *nm,
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);
613 void nat44_ei_free_outside_address_and_port (nat44_ei_address_t *addresses,
615 ip4_address_t *addr, u16 port,
616 nat_protocol_t protocol);
618 int nat44_ei_set_outside_address_and_port (nat44_ei_address_t *addresses,
620 ip4_address_t addr, u16 port,
621 nat_protocol_t protocol);
623 int nat44_ei_del_address (nat44_ei_main_t *nm, ip4_address_t addr,
626 void nat44_ei_free_session_data (nat44_ei_main_t *nm, nat44_ei_session_t *s,
627 u32 thread_index, u8 is_ha);
629 int nat44_ei_set_workers (uword *bitmap);
631 void nat44_ei_add_del_address_dpo (ip4_address_t addr, u8 is_add);
633 int nat44_ei_add_address (nat44_ei_main_t *nm, ip4_address_t *addr,
636 void nat44_ei_delete_session (nat44_ei_main_t *nm, nat44_ei_session_t *ses,
639 int nat44_ei_interface_add_del (u32 sw_if_index, u8 is_inside, int is_del);
641 int nat44_ei_interface_add_del_output_feature (u32 sw_if_index, u8 is_inside,
644 int nat44_ei_add_interface_address (nat44_ei_main_t *nm, u32 sw_if_index,
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);
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);
657 void nat44_ei_hairpinning_sm_unknown_proto (nat44_ei_main_t *nm,
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);
666 int nat44_ei_set_frame_queue_nelts (u32 frame_queue_nelts);
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)
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)
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)
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__)
695 #endif /* __included_nat44_ei_h__ */
697 * fd.io coding-style-patch-verification: ON
700 * eval: (c-set-style "gnu")