diff options
-rw-r--r-- | src/plugins/nat/lib/lib.h | 11 | ||||
-rw-r--r-- | src/plugins/nat/nat44-ed/nat44_ed.api | 866 | ||||
-rw-r--r-- | src/plugins/nat/nat44-ed/nat44_ed.c | 304 | ||||
-rw-r--r-- | src/plugins/nat/nat44-ed/nat44_ed.h | 136 | ||||
-rw-r--r-- | src/plugins/nat/nat44-ed/nat44_ed_api.c | 439 | ||||
-rw-r--r-- | src/plugins/nat/nat44-ed/nat44_ed_format.c | 181 | ||||
-rw-r--r-- | src/plugins/nat/nat44-ed/nat44_ed_inlines.h | 11 | ||||
-rw-r--r-- | test/test_dslite.py | 8 | ||||
-rw-r--r-- | test/test_nat44_ed.py | 25 | ||||
-rw-r--r-- | test/test_nat44_ed_output.py | 9 |
10 files changed, 664 insertions, 1326 deletions
diff --git a/src/plugins/nat/lib/lib.h b/src/plugins/nat/lib/lib.h index cea9ed71c8c..dc2c43beaaf 100644 --- a/src/plugins/nat/lib/lib.h +++ b/src/plugins/nat/lib/lib.h @@ -21,6 +21,17 @@ #include <vlibapi/api.h> +typedef struct +{ + u16 identifier; + u16 sequence; +} nat_icmp_echo_header_t; + +typedef struct +{ + u16 src_port, dst_port; +} nat_tcp_udp_header_t; + /* NAT API Configuration flags */ #define foreach_nat_config_flag \ _(0x01, IS_TWICE_NAT) \ diff --git a/src/plugins/nat/nat44-ed/nat44_ed.api b/src/plugins/nat/nat44-ed/nat44_ed.api index 36637b26246..afb55021bec 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed.api +++ b/src/plugins/nat/nat44-ed/nat44_ed.api @@ -13,13 +13,13 @@ * limitations under the License. */ -option version = "5.4.0"; +option version = "5.5.0"; import "vnet/ip/ip_types.api"; import "vnet/interface_types.api"; import "plugins/nat/lib/nat_types.api"; /** - * @file nat44.api + * @file nat44_ed.api * @brief VPP control-plane API messages. * * This file defines VPP control-plane API messages which are generally @@ -35,41 +35,6 @@ enum nat44_config_flags : u8 NAT44_IS_OUT2IN_DPO = 0x08, }; -/** \brief Enable/disable NAT44 plugin - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param inside_vrf - inside vrf id - @param outside_vrf - outside vrf id - @param users - maximum number of users per thread - (NAT44_IS_ENDPOINT_INDEPENDENT) - @param user_memory - overwrite hash allocation parameter - (NAT44_IS_ENDPOINT_INDEPENDENT) - @param sessions - maximum number of sessions per thread - @param session_memory - overwrite hash allocation parameter - @param user_sessions - maximum number of sessions per user - (NAT44_IS_ENDPOINT_INDEPENDENT) - @param enable - true if enable, false if disable - @param flags - flag NAT44_IS_ENDPOINT_INDEPENDENT, - NAT44_IS_ENDPOINT_DEPENDENT, - NAT44_IS_STATIC_MAPPING_ONLY, - NAT44_IS_CONNECTION_TRACKING, - NAT44_IS_OUT2IN_DPO -*/ -autoreply define nat44_plugin_enable_disable { - option deprecated; - u32 client_index; - u32 context; - u32 inside_vrf; - u32 outside_vrf; - u32 users; - u32 user_memory; - u32 sessions; - u32 session_memory; - u32 user_sessions; - bool enable; - vl_api_nat44_config_flags_t flags; -}; - /** \brief Enable/disable NAT44ED plugin @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @@ -82,7 +47,6 @@ autoreply define nat44_plugin_enable_disable { NAT44_IS_CONNECTION_TRACKING */ autoreply define nat44_ed_plugin_enable_disable { - option in_progress; u32 client_index; u32 context; u32 inside_vrf; @@ -93,146 +57,65 @@ autoreply define nat44_ed_plugin_enable_disable { vl_api_nat44_config_flags_t flags; }; -/** \brief Control ping from client to api server request +/** \brief Enable/disable forwarding for NAT44 + Forward packets which don't match existing translation + or static mapping instead of dropping them. @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request + @param enable - true for enable, false for disable */ -define nat_control_ping -{ +autoreply define nat44_forwarding_enable_disable { option deprecated; u32 client_index; u32 context; + bool enable; }; -/** \brief Control ping from the client to the server response +/** \brief Enable/disable NAT IPFIX logging @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request - @param retval - return code for the request - @param vpe_pid - the pid of the vpe, returned by the server + @param domain_id - observation domain ID + @param src_port - source port number + @param enable - true if enable, false if disable */ -define nat_control_ping_reply -{ +autoreply define nat_ipfix_enable_disable { option deprecated; - u32 context; - i32 retval; u32 client_index; - u32 vpe_pid; + u32 context; + u32 domain_id; + u16 src_port; + bool enable; }; -/** \brief Show NAT plugin startup config +/** \brief Set values of timeouts for NAT sessions (seconds) @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request + @param udp - UDP timeout (default 300sec) + @param tcp_established - TCP established timeout (default 7440sec) + @param tcp_transitory - TCP transitory timeout (default 240sec) + @param icmp - ICMP timeout (default 60sec) */ -define nat_show_config -{ +autoreply define nat_set_timeouts { option deprecated; u32 client_index; u32 context; + u32 udp; + u32 tcp_established; + u32 tcp_transitory; + u32 icmp; }; -/** \brief DEPRECATED: Show NAT plugin startup config reply - @param context - sender context, to match reply w/ request - @param retval - return code for the request - @param static_mapping_only - if true dynamic translations disabled - @param static_mapping_connection_tracking - if true create session data - @param deterministic - if true deterministic mapping - @param endpoint_dependent - if true endpoint-dependent mode - @param out2in_dpo - if true out2in dpo mode - @param dslite_ce - if true DS-Lite is CE/B4 element, if false AFTR elemet - @param translation_buckets - number of translation hash buckets - @param translation_memory_size - translation hash memory size - @param user_buckets - number of user hash buckets - @param user_memory_size - user hash memory size - @param max_translations_per_user - maximum number of translations per user - @param outside_vrf_id - outside VRF id - @param inside_vrf_id - default inside VRF id - @param nat64_bib_buckets - number of NAT64 BIB hash buckets - @param nat64_bib_memory_size - memory size of NAT64 BIB hash - @param nat64_st_buckets - number of NAT64 session table hash buckets - @param nat64_st_memory_size - memory size of NAT64 session table hash -*/ -define nat_show_config_reply -{ - option deprecated; - u32 context; - i32 retval; - bool static_mapping_only; - bool static_mapping_connection_tracking; - bool deterministic; - bool endpoint_dependent; - bool out2in_dpo; - bool dslite_ce; - u32 translation_buckets; - u32 translation_memory_size; - u32 user_buckets; - u64 user_memory_size; - u32 max_translations_per_user; - u32 outside_vrf_id; - u32 inside_vrf_id; - u32 nat64_bib_buckets; - u64 nat64_bib_memory_size; - u32 nat64_st_buckets; - u64 nat64_st_memory_size; -}; - -/** \brief Show NAT plugin startup config +/** \brief NAT44 set session limit @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request + @param session_limit - session limit + @param vrf_id - vrf id */ -define nat_show_config_2 -{ - option deprecated; +autoreply define nat44_set_session_limit { u32 client_index; u32 context; -}; - -/** \brief Show NAT plugin startup config reply - @param context - sender context, to match reply w/ request - @param retval - return code for the request - @param static_mapping_only - if true dynamic translations disabled - @param static_mapping_connection_tracking - if true create session data - @param deterministic - if true deterministic mapping - @param endpoint_dependent - if true endpoint-dependent mode - @param out2in_dpo - if true out2in dpo mode - @param dslite_ce - if true DS-Lite is CE/B4 element, if false AFTR elemet - @param translation_buckets - number of translation hash buckets - @param translation_memory_size - translation hash memory size - @param user_buckets - number of user hash buckets - @param user_memory_size - user hash memory size - @param max_translations_per_user - maximum number of translations per user - @param outside_vrf_id - outside VRF id - @param inside_vrf_id - default inside VRF id - @param nat64_bib_buckets - number of NAT64 BIB hash buckets - @param nat64_bib_memory_size - memory size of NAT64 BIB hash - @param nat64_st_buckets - number of NAT64 session table hash buckets - @param nat64_st_memory_size - memory size of NAT64 session table hash - @param max_translations_per_thread - max translations per worker thread - @param max_users_per_thread - max users per worker thread -*/ -define nat_show_config_2_reply -{ - option deprecated; - u32 context; - i32 retval; - bool static_mapping_only; - bool static_mapping_connection_tracking; - bool deterministic; - bool endpoint_dependent; - bool out2in_dpo; - bool dslite_ce; - u32 translation_buckets; - u64 translation_memory_size; - u32 user_buckets; - u64 user_memory_size; - u32 max_translations_per_user; - u32 outside_vrf_id; - u32 inside_vrf_id; - u32 nat64_bib_buckets; - u64 nat64_bib_memory_size; - u32 nat64_st_buckets; - u64 nat64_st_memory_size; - u32 max_translations_per_thread; - u32 max_users_per_thread; + u32 session_limit; + u32 vrf_id; }; /** \brief Show NAT44 plugin running config @@ -241,7 +124,6 @@ define nat_show_config_2_reply */ define nat44_show_running_config { - option in_progress; u32 client_index; u32 context; }; @@ -267,7 +149,6 @@ define nat44_show_running_config */ define nat44_show_running_config_reply { - option in_progress; u32 context; i32 retval; u32 inside_vrf; @@ -284,41 +165,6 @@ define nat44_show_running_config_reply vl_api_nat44_config_flags_t flags; }; -/** \brief Run nat44 garbage collection - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request -*/ -autoreply define nat44_session_cleanup { - option deprecated; - u32 client_index; - u32 context; -}; - -/** \brief NAT44 set session limit - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param session_limit - session limit - @param vrf_id - vrf id -*/ -autoreply define nat44_set_session_limit { - u32 client_index; - u32 context; - u32 session_limit; - u32 vrf_id; -}; - -/** \brief Set NAT logging level - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param log_level - logging level -*/ -autoreply define nat_set_log_level { - option deprecated; - u32 client_index; - u32 context; - vl_api_nat_log_level_t log_level; -}; - /** \brief Set NAT workers @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @@ -352,123 +198,6 @@ define nat_worker_details { string name[64]; }; -/** \brief Enable/disable NAT IPFIX logging - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param domain_id - observation domain ID - @param src_port - source port number - @param enable - true if enable, false if disable -*/ -autoreply define nat_ipfix_enable_disable { - option deprecated; - u32 client_index; - u32 context; - u32 domain_id; - u16 src_port; - bool enable; -}; - -/** \brief Set values of timeouts for NAT sessions (seconds) - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param udp - UDP timeout (default 300sec) - @param tcp_established - TCP established timeout (default 7440sec) - @param tcp_transitory - TCP transitory timeout (default 240sec) - @param icmp - ICMP timeout (default 60sec) -*/ -autoreply define nat_set_timeouts { - option deprecated; - u32 client_index; - u32 context; - u32 udp; - u32 tcp_established; - u32 tcp_transitory; - u32 icmp; -}; - -/** \brief Get values of timeouts for NAT sessions (seconds) - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request -*/ -define nat_get_timeouts { - option deprecated; - u32 client_index; - u32 context; -}; - -/** \brief Get values of timeouts for NAT sessions reply - @param context - sender context, to match reply w/ request - @param retval - return code - @param udp - UDP timeout - @param tcp_established - TCP established timeout - @param tcp_transitory - TCP transitory timeout - @param icmp - ICMP timeout -*/ -define nat_get_timeouts_reply { - option deprecated; - u32 context; - i32 retval; - u32 udp; - u32 tcp_established; - u32 tcp_transitory; - u32 icmp; -}; - -/** \brief Set address and port assignment algorithm - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param alg - address and port assignment algorithm: - 0 - default, 1 - MAP-E, 2 - port range - (see nat_addr_and_port_alloc_alg_t in nat.h) - @param psid_offset - number of offset bits (valid only for MAP-E alg) - @param psid_length - length of PSID (valid only for MAP-E alg) - @param psid - Port Set Identifier (PSID) value (valid only for MAP-E alg) - @param start_port - beginning of the port range - @param end_port - end of the port range -*/ -autoreply define nat_set_addr_and_port_alloc_alg { - u32 client_index; - u32 context; - u8 alg; - u8 psid_offset; - u8 psid_length; - u16 psid; - u16 start_port; - u16 end_port; -}; - -/** \brief Get address and port assignment algorithm - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request -*/ -define nat_get_addr_and_port_alloc_alg { - u32 client_index; - u32 context; -}; - -/** \brief Get address and port assignment algorithm reply - @param context - sender context, to match reply w/ request - @param retval - return code - @param alg - address and port assignment algorithm: - 0 - default, 1 - MAP-E, 2 - port range - (see nat_addr_and_port_alloc_alg_t in nat.h) - @param psid_offset - number of offset bits (valid only for MAP-E alg) - @param psid_length - length of PSID (valid only for MAP-E alg) - @param psid - Port Set Identifier (PSID) value (valid only for MAP-E alg) - @param start_port - beginning of the port range - @param end_port - end of the port range -*/ -define nat_get_addr_and_port_alloc_alg_reply { - u32 context; - i32 retval; - u8 alg; - u8 psid_offset; - u8 psid_length; - u16 psid; - u16 start_port; - u16 end_port; -}; - /** \brief Set TCP MSS rewriting configuration @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @@ -504,138 +233,73 @@ define nat_get_mss_clamping_reply { bool enable; }; -/** \brief Set HA listener (local settings) - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param ip_address - local IP4 address - @param port - local UDP port number - @param path_mtu - path MTU between local and failover -*/ -autoreply define nat_ha_set_listener { - u32 client_index; - u32 context; - vl_api_ip4_address_t ip_address; - u16 port; - u32 path_mtu; -}; - -/** \brief Set HA failover (remote settings) +/** \brief Set NAT handoff frame queue options @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request - @param ip_address - failover IP4 address - @param port - failvoer UDP port number - @param session_refresh_interval - number of seconds after which to send - session counters refresh + @param frame_queue_nelts - number of worker handoff frame queue elements */ -autoreply define nat_ha_set_failover { +autoreply define nat44_ed_set_fq_options { u32 client_index; u32 context; - vl_api_ip4_address_t ip_address; - u16 port; - u32 session_refresh_interval; + u32 frame_queue_nelts; }; -/** \brief Get HA listener/local configuration +/** \brief Show NAT handoff frame queue options @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request */ -define nat_ha_get_listener { +define nat44_ed_show_fq_options +{ u32 client_index; u32 context; }; -/** \brief Get HA listener/local configuration reply +/** \brief Show NAT handoff frame queue options reply @param context - sender context, to match reply w/ request - @param retval - return code - @param ip_address - local IP4 address - @param port - local UDP port number - @param path_mtu - Path MTU between local and failover + @param retval - return code for the request + @param frame_queue_nelts - number of worker handoff frame queue elements */ -define nat_ha_get_listener_reply { +define nat44_ed_show_fq_options_reply +{ u32 context; i32 retval; - vl_api_ip4_address_t ip_address; - u16 port; - u32 path_mtu; + u32 frame_queue_nelts; }; -/** \brief Get HA failover/remote settings +/** \brief Add/delete NAT44 pool address from specific interfce @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request + @param is_add - true if add, false if delete + @param sw_if_index - software index of the interface + @param flags - flag NAT_TWICE_NAT if NAT address range for external hosts */ -define nat_ha_get_failover { +autoreply define nat44_add_del_interface_addr { u32 client_index; u32 context; + bool is_add; + vl_api_interface_index_t sw_if_index; + vl_api_nat_config_flags_t flags; }; -/** \brief Get HA failover/remote settings reply - @param context - sender context, to match reply w/ request - @param retval - return code - @param ip_address - failover IP4 address - @param port - failvoer UDP port number - @param session_refresh_interval - number of seconds after which to send - session counters refresh -*/ -define nat_ha_get_failover_reply { - u32 context; - i32 retval; - vl_api_ip4_address_t ip_address; - u16 port; - u32 session_refresh_interval; -}; - -/** \brief Flush the current HA data (for testing) +/** \brief Dump NAT44 pool addresses interfaces @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request */ -autoreply define nat_ha_flush { +define nat44_interface_addr_dump { u32 client_index; u32 context; }; -/** \brief Resync HA (resend existing sessions to new failover) - @param client_index - opaque cookie to identify the sender +/** \brief NAT44 pool addresses interfaces details response @param context - sender context, to match reply w/ request - @param want_resync_event - resync completed event sent to the sender via - nat_ha_resync_completed_event API message if - non-zero - @param pid - sender's pid -*/ -autoreply define nat_ha_resync -{ - u32 client_index; - u32 context; - u8 want_resync_event; - u32 pid; -}; - -/** \brief Tell client about a HA resync completion event - @param client_index - opaque cookie to identify the sender - @param pid - client pid registered to receive notification - @param missed_count - number of missed (not ACKed) messages -*/ -define nat_ha_resync_completed_event -{ - u32 client_index; - u32 pid; - u32 missed_count; -}; - -service { - rpc nat_ha_resync returns nat_ha_resync_reply events nat_ha_resync_completed_event; -}; + @param sw_if_index - software index of the interface + @param flags - flag NAT_TWICE_NAT if NAT address range for external hosts -/** \brief Del NAT44 user - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param ip_address - IPv4 address - @param fib_index - FIB index */ -autoreply define nat44_del_user { - u32 client_index; +define nat44_interface_addr_details { u32 context; - vl_api_ip4_address_t ip_address; - u32 fib_index; + vl_api_interface_index_t sw_if_index; + vl_api_nat_config_flags_t flags; }; /** \brief Add/del NAT44 address range @@ -719,47 +383,6 @@ define nat44_interface_details { vl_api_interface_index_t sw_if_index; }; -/** \brief Enable/disbale NAT44 as an interface output feature (postrouting - in2out translation) - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param is_add - true if add, false if delete - @param flags - flag NAT_IS_INSIDE if interface is inside else - interface is outside - @param sw_if_index - software index of the interface -*/ -autoreply define nat44_interface_add_del_output_feature { - option deprecated; - u32 client_index; - u32 context; - bool is_add; - vl_api_nat_config_flags_t flags; - vl_api_interface_index_t sw_if_index; -}; - -/** \brief Dump interfaces with NAT44 output feature - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request -*/ -define nat44_interface_output_feature_dump { - option deprecated; - u32 client_index; - u32 context; -}; - -/** \brief NAT44 interface with output feature details response - @param context - sender context, to match reply w/ request - @param flags - flag NAT_IS_INSIDE if interface is inside else - interface is outside - @param sw_if_index - software index of the interface -*/ -define nat44_interface_output_feature_details { - option deprecated; - u32 context; - vl_api_nat_config_flags_t flags; - vl_api_interface_index_t sw_if_index; -}; - /** \brief add/del NAT output interface (postrouting in2out translation) @param client_index - opaque cookie to identify the sender @@ -859,7 +482,6 @@ autoreply define nat44_add_del_static_mapping { @param tag - opaque string tag */ autoreply define nat44_add_del_static_mapping_v2 { - option in_progress; u32 client_index; u32 context; bool is_add; @@ -971,40 +593,131 @@ define nat44_identity_mapping_details { string tag[64]; }; -/** \brief Add/delete NAT44 pool address from specific interfce +/** \brief NAT44 load-balancing address and port pair + @param addr - IPv4 address of the internal node + @param port - L4 port number of the internal node + @param probability - probability of the internal node to be randomly matched + @param vrf_id - VRF id +*/ +typedef nat44_lb_addr_port { + vl_api_ip4_address_t addr; + u16 port; + u8 probability; + u32 vrf_id; +}; + +/** \brief Add/delete NAT44 load-balancing static mapping rule @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @param is_add - true if add, false if delete - @param sw_if_index - software index of the interface - @param flags - flag NAT_TWICE_NAT if NAT address range for external hosts + @param flags - flag NAT_TWICE_NAT if NAT address range for external hosts, + flag NAT_SELF_TWICE_NAT if translate external host address + and port whenever external host address equals local + address of internal host, + flag NAT_OUT2IN_ONLY if rule match only out2in direction + @param external_addr - external IPv4 address of the service + @param external_port - external L4 port number of the service + @param protocol - IP protocol number of the service + @param affinity - if 0 disabled, otherwise client IP affinity sticky time + in seconds + @param local_num - number of local network nodes + @param locals - local network nodes + @param tag - opaque string tag */ -autoreply define nat44_add_del_interface_addr { +autoreply define nat44_add_del_lb_static_mapping { u32 client_index; u32 context; bool is_add; - vl_api_interface_index_t sw_if_index; vl_api_nat_config_flags_t flags; + vl_api_ip4_address_t external_addr; + u16 external_port; + u8 protocol; + u32 affinity; + string tag[64]; + u32 local_num; + vl_api_nat44_lb_addr_port_t locals[local_num]; }; -/** \brief Dump NAT44 pool addresses interfaces +/** \brief Add/delete NAT44 load-balancing static mapping rule backend @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request + @param is_add - true if add, false if delete + @param external_addr - external IPv4 address of the service + @param external_port - external L4 port number of the service + @param protocol - IP protocol number of the service + @param local - local network node */ -define nat44_interface_addr_dump { +autoreply define nat44_lb_static_mapping_add_del_local { + u32 client_index; + u32 context; + bool is_add; + vl_api_ip4_address_t external_addr; + u16 external_port; + u8 protocol; + vl_api_nat44_lb_addr_port_t local; +}; + +/** \brief Dump NAT44 load-balancing static mapping rules + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request +*/ +define nat44_lb_static_mapping_dump { u32 client_index; u32 context; }; -/** \brief NAT44 pool addresses interfaces details response +/** \brief NAT44 load-balancing static mapping rule details response @param context - sender context, to match reply w/ request - @param sw_if_index - software index of the interface - @param flags - flag NAT_TWICE_NAT if NAT address range for external hosts + @param external_addr - external IPv4 address of the service + @param external_port - external L4 port number of the service + @param protocol - IP protocol number of the service + @param flags - flag NAT_TWICE_NAT if NAT address range for external hosts, + flag NAT_SELF_TWICE_NAT if translate external host address + and port whenever external host address equals local + address of internal host, + flag NAT_OUT2IN_ONLY if rule match only out2in direction + @param affinity - if 0 disabled, otherwise client IP affinity sticky time + in seconds + @param local_num - number of local network nodes + @param locals - local network nodes + @param tag - opaque string tag +*/ +define nat44_lb_static_mapping_details { + u32 context; + vl_api_ip4_address_t external_addr; + u16 external_port; + u8 protocol; + vl_api_nat_config_flags_t flags; + u32 affinity; + string tag[64]; + u32 local_num; + vl_api_nat44_lb_addr_port_t locals[local_num]; +}; +/** \brief Delete NAT44 session + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param ip_address - IPv4 address + @param protocol - IP protocol + @param port - port number + @param vfr_id - VRF ID + @param flags - flag NAT_IS_INSIDE if interface is inside or + interface is outside, + flag NAT_IS_EXT_HOST_VALID if external host address and + port are valid + @param ext_host_address - external host IPv4 address + @param ext_host_port - external host port */ -define nat44_interface_addr_details { +autoreply define nat44_del_session { + u32 client_index; u32 context; - vl_api_interface_index_t sw_if_index; + vl_api_ip4_address_t address; + u8 protocol; + u16 port; + u32 vrf_id; vl_api_nat_config_flags_t flags; + vl_api_ip4_address_t ext_host_address; + u16 ext_host_port; }; /** \brief Dump NAT44 users @@ -1089,7 +802,6 @@ define nat44_user_session_details { @param vrf_id - VRF_ID */ define nat44_user_session_v2_dump { - option in_progress; u32 client_index; u32 context; vl_api_ip4_address_t ip_address; @@ -1120,7 +832,6 @@ define nat44_user_session_v2_dump { is active */ define nat44_user_session_v2_details { - option in_progress; u32 context; vl_api_ip4_address_t outside_ip_address; u16 outside_port; @@ -1138,199 +849,206 @@ define nat44_user_session_v2_details { bool is_timed_out; }; -/** \brief NAT44 load-balancing address and port pair - @param addr - IPv4 address of the internal node - @param port - L4 port number of the internal node - @param probability - probability of the internal node to be randomly matched - @param vrf_id - VRF id -*/ -typedef nat44_lb_addr_port { - vl_api_ip4_address_t addr; - u16 port; - u8 probability; - u32 vrf_id; -}; +// DEPRECATED, obsolete messages completely unsupported -/** \brief Add/delete NAT44 load-balancing static mapping rule +/** \brief Del NAT44 user @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request - @param is_add - true if add, false if delete - @param flags - flag NAT_TWICE_NAT if NAT address range for external hosts, - flag NAT_SELF_TWICE_NAT if translate external host address - and port whenever external host address equals local - address of internal host, - flag NAT_OUT2IN_ONLY if rule match only out2in direction - @param external_addr - external IPv4 address of the service - @param external_port - external L4 port number of the service - @param protocol - IP protocol number of the service - @param affinity - if 0 disabled, otherwise client IP affinity sticky time - in seconds - @param local_num - number of local network nodes - @param locals - local network nodes - @param tag - opaque string tag + @param ip_address - IPv4 address + @param fib_index - FIB index */ -autoreply define nat44_add_del_lb_static_mapping { +autoreply define nat44_del_user { + option deprecated; u32 client_index; u32 context; - bool is_add; - vl_api_nat_config_flags_t flags; - vl_api_ip4_address_t external_addr; - u16 external_port; - u8 protocol; - u32 affinity; - string tag[64]; - u32 local_num; - vl_api_nat44_lb_addr_port_t locals[local_num]; + vl_api_ip4_address_t ip_address; + u32 fib_index; }; -/** \brief Add/delete NAT44 load-balancing static mapping rule backend +/** \brief Set address and port assignment algorithm @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request - @param is_add - true if add, false if delete - @param external_addr - external IPv4 address of the service - @param external_port - external L4 port number of the service - @param protocol - IP protocol number of the service - @param local - local network node + @param alg - address and port assignment algorithm: + 0 - default, 1 - MAP-E, 2 - port range + (see nat_addr_and_port_alloc_alg_t in nat.h) + @param psid_offset - number of offset bits (valid only for MAP-E alg) + @param psid_length - length of PSID (valid only for MAP-E alg) + @param psid - Port Set Identifier (PSID) value (valid only for MAP-E alg) + @param start_port - beginning of the port range + @param end_port - end of the port range */ -autoreply define nat44_lb_static_mapping_add_del_local { +autoreply define nat_set_addr_and_port_alloc_alg { + option deprecated; u32 client_index; u32 context; - bool is_add; - vl_api_ip4_address_t external_addr; - u16 external_port; - u8 protocol; - vl_api_nat44_lb_addr_port_t local; + u8 alg; + u8 psid_offset; + u8 psid_length; + u16 psid; + u16 start_port; + u16 end_port; }; -/** \brief Dump NAT44 load-balancing static mapping rules +/** \brief Get address and port assignment algorithm @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request */ -define nat44_lb_static_mapping_dump { +define nat_get_addr_and_port_alloc_alg { + option deprecated; u32 client_index; u32 context; }; -/** \brief NAT44 load-balancing static mapping rule details response +/** \brief Get address and port assignment algorithm reply @param context - sender context, to match reply w/ request - @param external_addr - external IPv4 address of the service - @param external_port - external L4 port number of the service - @param protocol - IP protocol number of the service - @param flags - flag NAT_TWICE_NAT if NAT address range for external hosts, - flag NAT_SELF_TWICE_NAT if translate external host address - and port whenever external host address equals local - address of internal host, - flag NAT_OUT2IN_ONLY if rule match only out2in direction - @param affinity - if 0 disabled, otherwise client IP affinity sticky time - in seconds - @param local_num - number of local network nodes - @param locals - local network nodes - @param tag - opaque string tag + @param retval - return code + @param alg - address and port assignment algorithm: + 0 - default, 1 - MAP-E, 2 - port range + (see nat_addr_and_port_alloc_alg_t in nat.h) + @param psid_offset - number of offset bits (valid only for MAP-E alg) + @param psid_length - length of PSID (valid only for MAP-E alg) + @param psid - Port Set Identifier (PSID) value (valid only for MAP-E alg) + @param start_port - beginning of the port range + @param end_port - end of the port range */ -define nat44_lb_static_mapping_details { +define nat_get_addr_and_port_alloc_alg_reply { + option deprecated; u32 context; - vl_api_ip4_address_t external_addr; - u16 external_port; - u8 protocol; - vl_api_nat_config_flags_t flags; - u32 affinity; - string tag[64]; - u32 local_num; - vl_api_nat44_lb_addr_port_t locals[local_num]; + i32 retval; + u8 alg; + u8 psid_offset; + u8 psid_length; + u16 psid; + u16 start_port; + u16 end_port; }; -/** \brief Delete NAT44 session +/** \brief Set HA listener (local settings) @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request - @param ip_address - IPv4 address - @param protocol - IP protocol - @param port - port number - @param vfr_id - VRF ID - @param flags - flag NAT_IS_INSIDE if interface is inside or - interface is outside, - flag NAT_IS_EXT_HOST_VALID if external host address and - port are valid - @param ext_host_address - external host IPv4 address - @param ext_host_port - external host port + @param ip_address - local IP4 address + @param port - local UDP port number + @param path_mtu - path MTU between local and failover */ -autoreply define nat44_del_session { +autoreply define nat_ha_set_listener { + option deprecated; u32 client_index; u32 context; - vl_api_ip4_address_t address; - u8 protocol; + vl_api_ip4_address_t ip_address; u16 port; - u32 vrf_id; - vl_api_nat_config_flags_t flags; - vl_api_ip4_address_t ext_host_address; - u16 ext_host_port; + u32 path_mtu; }; -/** \brief Enable/disable forwarding for NAT44 - Forward packets which don't match existing translation - or static mapping instead of dropping them. +/** \brief Set HA failover (remote settings) @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request - @param enable - true for enable, false for disable + @param ip_address - failover IP4 address + @param port - failvoer UDP port number + @param session_refresh_interval - number of seconds after which to send + session counters refresh */ -autoreply define nat44_forwarding_enable_disable { +autoreply define nat_ha_set_failover { option deprecated; u32 client_index; u32 context; - bool enable; + vl_api_ip4_address_t ip_address; + u16 port; + u32 session_refresh_interval; }; -/** \brief Check if forwarding is enabled or disabled +/** \brief Get HA listener/local configuration @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request */ -define nat44_forwarding_is_enabled { +define nat_ha_get_listener { option deprecated; u32 client_index; u32 context; }; -/** \brief Response to check if forwarding is enabled or disabled +/** \brief Get HA listener/local configuration reply @param context - sender context, to match reply w/ request - @param enabled - true if enabled, false if disabled + @param retval - return code + @param ip_address - local IP4 address + @param port - local UDP port number + @param path_mtu - Path MTU between local and failover */ -define nat44_forwarding_is_enabled_reply { +define nat_ha_get_listener_reply { option deprecated; u32 context; - bool enabled; + i32 retval; + vl_api_ip4_address_t ip_address; + u16 port; + u32 path_mtu; }; -/** \brief Set NAT handoff frame queue options +/** \brief Get HA failover/remote settings @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request - @param frame_queue_nelts - number of worker handoff frame queue elements */ -autoreply define nat44_ed_set_fq_options { - option in_progress; +define nat_ha_get_failover { + option deprecated; u32 client_index; u32 context; - u32 frame_queue_nelts; }; -/** \brief Show NAT handoff frame queue options +/** \brief Get HA failover/remote settings reply + @param context - sender context, to match reply w/ request + @param retval - return code + @param ip_address - failover IP4 address + @param port - failvoer UDP port number + @param session_refresh_interval - number of seconds after which to send + session counters refresh +*/ +define nat_ha_get_failover_reply { + option deprecated; + u32 context; + i32 retval; + vl_api_ip4_address_t ip_address; + u16 port; + u32 session_refresh_interval; +}; + +/** \brief Flush the current HA data (for testing) @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request */ -define nat44_ed_show_fq_options -{ - option in_progress; +autoreply define nat_ha_flush { + option deprecated; u32 client_index; u32 context; }; -/** \brief Show NAT handoff frame queue options reply +/** \brief Resync HA (resend existing sessions to new failover) + @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request - @param retval - return code for the request - @param frame_queue_nelts - number of worker handoff frame queue elements + @param want_resync_event - resync completed event sent to the sender via + nat_ha_resync_completed_event API message if + non-zero + @param pid - sender's pid */ -define nat44_ed_show_fq_options_reply +autoreply define nat_ha_resync { - option in_progress; + option deprecated; + u32 client_index; u32 context; - i32 retval; - u32 frame_queue_nelts; + u8 want_resync_event; + u32 pid; +}; + +/** \brief Tell client about a HA resync completion event + @param client_index - opaque cookie to identify the sender + @param pid - client pid registered to receive notification + @param missed_count - number of missed (not ACKed) messages +*/ +define nat_ha_resync_completed_event +{ + option deprecated; + u32 client_index; + u32 pid; + u32 missed_count; +}; + +service { + rpc nat_ha_resync returns nat_ha_resync_reply events nat_ha_resync_completed_event; }; diff --git a/src/plugins/nat/nat44-ed/nat44_ed.c b/src/plugins/nat/nat44-ed/nat44_ed.c index 8f356430e20..bf802f59323 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed.c +++ b/src/plugins/nat/nat44-ed/nat44_ed.c @@ -1,6 +1,4 @@ /* - * snat.c - simple nat plugin - * * Copyright (c) 2016 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -78,7 +76,6 @@ static_always_inline void nat_validate_interface_counters (snat_main_t *sm, } \ while (0) -/* Hook up input features */ VNET_FEATURE_INIT (nat_pre_in2out, static) = { .arc_name = "ip4-unicast", .node_name = "nat-pre-in2out", @@ -92,6 +89,18 @@ VNET_FEATURE_INIT (nat_pre_out2in, static) = { "ip4-dhcp-client-detect", "ip4-sv-reassembly-feature"), }; +VNET_FEATURE_INIT (ip4_nat44_ed_classify, static) = { + .arc_name = "ip4-unicast", + .node_name = "nat44-ed-classify", + .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa", + "ip4-sv-reassembly-feature"), +}; +VNET_FEATURE_INIT (ip4_nat_handoff_classify, static) = { + .arc_name = "ip4-unicast", + .node_name = "nat44-handoff-classify", + .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa", + "ip4-sv-reassembly-feature"), +}; VNET_FEATURE_INIT (snat_in2out_worker_handoff, static) = { .arc_name = "ip4-unicast", .node_name = "nat44-in2out-worker-handoff", @@ -103,17 +112,6 @@ VNET_FEATURE_INIT (snat_out2in_worker_handoff, static) = { .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa", "ip4-dhcp-client-detect"), }; -VNET_FEATURE_INIT (ip4_snat_in2out, static) = { - .arc_name = "ip4-unicast", - .node_name = "nat44-in2out", - .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature"), -}; -VNET_FEATURE_INIT (ip4_snat_out2in, static) = { - .arc_name = "ip4-unicast", - .node_name = "nat44-out2in", - .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature", - "ip4-dhcp-client-detect"), -}; VNET_FEATURE_INIT (ip4_nat44_ed_in2out, static) = { .arc_name = "ip4-unicast", .node_name = "nat44-ed-in2out", @@ -125,32 +123,9 @@ VNET_FEATURE_INIT (ip4_nat44_ed_out2in, static) = { .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature", "ip4-dhcp-client-detect"), }; -VNET_FEATURE_INIT (ip4_nat44_ed_classify, static) = { - .arc_name = "ip4-unicast", - .node_name = "nat44-ed-classify", - .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature"), -}; -VNET_FEATURE_INIT (ip4_nat_handoff_classify, static) = { - .arc_name = "ip4-unicast", - .node_name = "nat44-handoff-classify", - .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature"), -}; -VNET_FEATURE_INIT (ip4_snat_in2out_fast, static) = { - .arc_name = "ip4-unicast", - .node_name = "nat44-in2out-fast", - .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature"), -}; -VNET_FEATURE_INIT (ip4_snat_out2in_fast, static) = { - .arc_name = "ip4-unicast", - .node_name = "nat44-out2in-fast", - .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature", - "ip4-dhcp-client-detect"), -}; - -/* Hook up output features */ -VNET_FEATURE_INIT (ip4_snat_in2out_output, static) = { +VNET_FEATURE_INIT (nat_pre_in2out_output, static) = { .arc_name = "ip4-output", - .node_name = "nat44-in2out-output", + .node_name = "nat-pre-in2out-output", .runs_after = VNET_FEATURES ("ip4-sv-reassembly-output-feature"), .runs_before = VNET_FEATURES ("acl-plugin-out-ip4-fa"), }; @@ -160,12 +135,6 @@ VNET_FEATURE_INIT (ip4_snat_in2out_output_worker_handoff, static) = { .runs_after = VNET_FEATURES ("ip4-sv-reassembly-output-feature"), .runs_before = VNET_FEATURES ("acl-plugin-out-ip4-fa"), }; -VNET_FEATURE_INIT (nat_pre_in2out_output, static) = { - .arc_name = "ip4-output", - .node_name = "nat-pre-in2out-output", - .runs_after = VNET_FEATURES ("ip4-sv-reassembly-output-feature"), - .runs_before = VNET_FEATURES ("acl-plugin-out-ip4-fa"), -}; VNET_FEATURE_INIT (ip4_nat44_ed_in2out_output, static) = { .arc_name = "ip4-output", .node_name = "nat44-ed-in2out-output", @@ -193,28 +162,6 @@ static int nat44_ed_del_static_mapping_internal (ip4_address_t l_addr, u32 nat_calc_bihash_buckets (u32 n_elts); -u8 * -format_ed_session_kvp (u8 * s, va_list * args) -{ - clib_bihash_kv_16_8_t *v = va_arg (*args, clib_bihash_kv_16_8_t *); - - u8 proto; - u16 r_port, l_port; - ip4_address_t l_addr, r_addr; - u32 fib_index; - - split_ed_kv (v, &l_addr, &r_addr, &proto, &fib_index, &l_port, &r_port); - s = format (s, - "local %U:%d remote %U:%d proto %U fib %d thread-index %u " - "session-index %u", - format_ip4_address, &l_addr, clib_net_to_host_u16 (l_port), - format_ip4_address, &r_addr, clib_net_to_host_u16 (r_port), - format_ip_protocol, proto, fib_index, - ed_value_get_thread_index (v), ed_value_get_session_index (v)); - - return s; -} - static_always_inline int nat44_ed_sm_i2o_add (snat_main_t *sm, snat_static_mapping_t *m, ip4_address_t addr, u16 port, u32 fib_index, u8 proto) @@ -2068,6 +2015,18 @@ nat44_ed_set_frame_queue_nelts (u32 frame_queue_nelts) { fail_if_enabled (); snat_main_t *sm = &snat_main; + + if ((sm->fq_in2out_index != ~0) || (sm->fq_out2in_index != ~0) || + (sm->fq_in2out_output_index != ~0)) + { + // frame queu nelts can be set only before first + // call to nat44_plugin_enable after that it + // doesn't make sense + nat_log_err ("Frame queue was already initialized. " + "Change is not possible"); + return 1; + } + sm->frame_queue_nelts = frame_queue_nelts; return 0; } @@ -2211,21 +2170,6 @@ nat_ip_table_add_del (vnet_main_t * vnm, u32 table_id, u32 is_add) VNET_IP_TABLE_ADD_DEL_FUNCTION (nat_ip_table_add_del); -void -nat44_set_node_indexes (snat_main_t * sm, vlib_main_t * vm) -{ - vlib_node_t *node; - - node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-out2in"); - sm->out2in_node_index = node->index; - - node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-in2out"); - sm->in2out_node_index = node->index; - - node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-in2out-output"); - sm->in2out_output_node_index = node->index; -} - #define nat_validate_simple_counter(c, i) \ do \ { \ @@ -2273,8 +2217,6 @@ nat_init (vlib_main_t * vm) sm->vnet_main = vnet_get_main (); // convenience sm->ip4_main = &ip4_main; - sm->api_main = vlibapi_get_main (); - sm->ip4_lookup_main = &ip4_main.lookup_main; // frame queue indices used for handoff sm->fq_out2in_index = ~0; @@ -2283,8 +2225,6 @@ nat_init (vlib_main_t * vm) sm->log_level = NAT_LOG_ERROR; - nat44_set_node_indexes (sm, vm); - sm->log_class = vlib_log_register_class ("nat", 0); nat_ipfix_logging_init (vm); @@ -2405,20 +2345,26 @@ nat44_plugin_enable (nat44_config_t c) if (sm->num_workers > 1) { + vlib_main_t *vm = vlib_get_main (); + vlib_node_t *node; + if (sm->fq_in2out_index == ~0) { - sm->fq_in2out_index = vlib_frame_queue_main_init ( - sm->in2out_node_index, sm->frame_queue_nelts); + node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-in2out"); + sm->fq_in2out_index = + vlib_frame_queue_main_init (node->index, sm->frame_queue_nelts); } if (sm->fq_out2in_index == ~0) { - sm->fq_out2in_index = vlib_frame_queue_main_init ( - sm->out2in_node_index, sm->frame_queue_nelts); + node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-out2in"); + sm->fq_out2in_index = + vlib_frame_queue_main_init (node->index, sm->frame_queue_nelts); } if (sm->fq_in2out_output_index == ~0) { - sm->fq_in2out_output_index = vlib_frame_queue_main_init ( - sm->in2out_output_node_index, sm->frame_queue_nelts); + node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-in2out-output"); + sm->fq_in2out_output_index = + vlib_frame_queue_main_init (node->index, sm->frame_queue_nelts); } } @@ -3037,7 +2983,7 @@ nat44_ed_get_out2in_worker_index (vlib_buffer_t *b, ip4_header_t *ip, { udp_header_t *udp = ip4_next_header (ip); icmp46_header_t *icmp = (icmp46_header_t *) udp; - icmp_echo_header_t *echo = (icmp_echo_header_t *) (icmp + 1); + nat_icmp_echo_header_t *echo = (nat_icmp_echo_header_t *) (icmp + 1); if (!icmp_type_is_error_message (vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags)) port = vnet_buffer (b)->ip.reass.l4_src_port; @@ -3051,13 +2997,13 @@ nat44_ed_get_out2in_worker_index (vlib_buffer_t *b, ip4_header_t *ip, { case IP_PROTOCOL_ICMP: icmp = (icmp46_header_t *) l4_header; - echo = (icmp_echo_header_t *) (icmp + 1); + echo = (nat_icmp_echo_header_t *) (icmp + 1); port = echo->identifier; break; case IP_PROTOCOL_UDP: /* breakthrough */ case IP_PROTOCOL_TCP: - port = ((tcp_udp_header_t *) l4_header)->src_port; + port = ((nat_tcp_udp_header_t *) l4_header)->src_port; break; default: next_worker_index = vlib_get_thread_index (); @@ -3705,7 +3651,7 @@ nat_6t_flow_icmp_translate (vlib_main_t *vm, snat_main_t *sm, vlib_buffer_t *b, return NAT_ED_TRNSL_ERR_TRANSLATION_FAILED; icmp46_header_t *icmp = ip4_next_header (ip); - icmp_echo_header_t *echo = (icmp_echo_header_t *) (icmp + 1); + nat_icmp_echo_header_t *echo = (nat_icmp_echo_header_t *) (icmp + 1); if ((!vnet_buffer (b)->ip.reass.is_non_first_fragment)) { @@ -3721,7 +3667,7 @@ nat_6t_flow_icmp_translate (vlib_main_t *vm, snat_main_t *sm, vlib_buffer_t *b, { ip_csum_t sum = icmp->checksum; sum = ip_csum_update (sum, echo->identifier, f->rewrite.icmp_id, - icmp_echo_header_t, + nat_icmp_echo_header_t, identifier /* changed member */); echo->identifier = f->rewrite.icmp_id; icmp->checksum = ip_csum_fold (sum); @@ -3811,19 +3757,21 @@ nat_6t_flow_icmp_translate (vlib_main_t *vm, snat_main_t *sm, vlib_buffer_t *b, { return NAT_ED_TRNSL_ERR_PACKET_TRUNCATED; } - icmp_echo_header_t *inner_echo = - (icmp_echo_header_t *) (inner_icmp + 1); + nat_icmp_echo_header_t *inner_echo = + (nat_icmp_echo_header_t *) (inner_icmp + 1); if (f->rewrite.icmp_id != inner_echo->identifier) { ip_csum_t sum = icmp->checksum; - sum = ip_csum_update ( - sum, inner_echo->identifier, f->rewrite.icmp_id, - icmp_echo_header_t, identifier /* changed member */); + sum = ip_csum_update (sum, inner_echo->identifier, + f->rewrite.icmp_id, + nat_icmp_echo_header_t, + identifier /* changed member */); icmp->checksum = ip_csum_fold (sum); ip_csum_t inner_sum = inner_icmp->checksum; inner_sum = ip_csum_update ( sum, inner_echo->identifier, f->rewrite.icmp_id, - icmp_echo_header_t, identifier /* changed member */); + nat_icmp_echo_header_t, + identifier /* changed member */); inner_icmp->checksum = ip_csum_fold (inner_sum); inner_echo->identifier = f->rewrite.icmp_id; } @@ -3895,110 +3843,7 @@ nat_6t_flow_buf_translate_o2i (vlib_main_t *vm, snat_main_t *sm, 0 /* is_i2o */); } -u8 * -format_nat_6t (u8 *s, va_list *args) -{ - nat_6t_t *t = va_arg (*args, nat_6t_t *); - - s = format (s, "saddr %U sport %u daddr %U dport %u proto %U fib_idx %u", - format_ip4_address, t->saddr.as_u8, - clib_net_to_host_u16 (t->sport), format_ip4_address, - t->daddr.as_u8, clib_net_to_host_u16 (t->dport), - format_ip_protocol, t->proto, t->fib_index); - return s; -} - -u8 * -format_nat_ed_translation_error (u8 *s, va_list *args) -{ - nat_translation_error_e e = va_arg (*args, nat_translation_error_e); - - switch (e) - { - case NAT_ED_TRNSL_ERR_SUCCESS: - s = format (s, "success"); - break; - case NAT_ED_TRNSL_ERR_TRANSLATION_FAILED: - s = format (s, "translation-failed"); - break; - case NAT_ED_TRNSL_ERR_FLOW_MISMATCH: - s = format (s, "flow-mismatch"); - break; - case NAT_ED_TRNSL_ERR_PACKET_TRUNCATED: - s = format (s, "packet-truncated"); - break; - case NAT_ED_TRNSL_ERR_INNER_IP_CORRUPT: - s = format (s, "inner-ip-corrupted"); - break; - case NAT_ED_TRNSL_ERR_INVALID_CSUM: - s = format (s, "invalid-checksum"); - break; - } - return s; -} - -u8 * -format_nat_6t_flow (u8 *s, va_list *args) -{ - nat_6t_flow_t *f = va_arg (*args, nat_6t_flow_t *); - - s = format (s, "match: %U ", format_nat_6t, &f->match); - int r = 0; - if (f->ops & NAT_FLOW_OP_SADDR_REWRITE) - { - s = format (s, "rewrite: saddr %U ", format_ip4_address, - f->rewrite.saddr.as_u8); - r = 1; - } - if (f->ops & NAT_FLOW_OP_SPORT_REWRITE) - { - if (!r) - { - s = format (s, "rewrite: "); - r = 1; - } - s = format (s, "sport %u ", clib_net_to_host_u16 (f->rewrite.sport)); - } - if (f->ops & NAT_FLOW_OP_DADDR_REWRITE) - { - if (!r) - { - s = format (s, "rewrite: "); - r = 1; - } - s = format (s, "daddr %U ", format_ip4_address, f->rewrite.daddr.as_u8); - } - if (f->ops & NAT_FLOW_OP_DPORT_REWRITE) - { - if (!r) - { - s = format (s, "rewrite: "); - r = 1; - } - s = format (s, "dport %u ", clib_net_to_host_u16 (f->rewrite.dport)); - } - if (f->ops & NAT_FLOW_OP_ICMP_ID_REWRITE) - { - if (!r) - { - s = format (s, "rewrite: "); - r = 1; - } - s = format (s, "icmp-id %u ", clib_net_to_host_u16 (f->rewrite.icmp_id)); - } - if (f->ops & NAT_FLOW_OP_TXFIB_REWRITE) - { - if (!r) - { - s = format (s, "rewrite: "); - r = 1; - } - s = format (s, "txfib %u ", f->rewrite.fib_index); - } - return s; -} - -static inline void +static_always_inline void nat_syslog_nat44_sess (u32 ssubix, u32 sfibix, ip4_address_t *isaddr, u16 isport, ip4_address_t *xsaddr, u16 xsport, ip4_address_t *idaddr, u16 idport, @@ -4073,51 +3918,6 @@ nat_syslog_nat44_sdel (u32 ssubix, u32 sfibix, ip4_address_t *isaddr, is_twicenat); } -u8 * -format_nat44_ed_tcp_state (u8 *s, va_list *args) -{ - nat44_ed_tcp_state_e e = va_arg (*args, nat44_ed_tcp_state_e); - switch (e) - { - case NAT44_ED_TCP_STATE_CLOSED: - s = format (s, "closed"); - break; - case NAT44_ED_TCP_STATE_SYN_I2O: - s = format (s, "SYN seen in in2out direction"); - break; - case NAT44_ED_TCP_STATE_SYN_O2I: - s = format (s, "SYN seen in out2in direction"); - break; - case NAT44_ED_TCP_STATE_ESTABLISHED: - s = format (s, "SYN seen in both directions/established"); - break; - case NAT44_ED_TCP_STATE_FIN_I2O: - s = format (s, "FIN seen in in2out direction"); - break; - case NAT44_ED_TCP_STATE_FIN_O2I: - s = format (s, "FIN seen in out2in direction"); - break; - case NAT44_ED_TCP_STATE_RST_TRANS: - s = format (s, "RST seen/transitory timeout"); - break; - case NAT44_ED_TCP_STATE_FIN_TRANS: - s = format (s, "FIN seen in both directions/transitory timeout"); - break; - case NAT44_ED_TCP_STATE_FIN_REOPEN_SYN_O2I: - s = format (s, "FIN seen in both directions/transitory timeout/session " - "reopening in out2in direction"); - break; - case NAT44_ED_TCP_STATE_FIN_REOPEN_SYN_I2O: - s = format (s, "FIN seen in both directions/transitory timeout/session " - "reopening in in2out direction"); - break; - case NAT44_ED_TCP_N_STATE: - s = format (s, "BUG! unexpected N_STATE! BUG!"); - break; - } - return s; -} - /* * fd.io coding-style-patch-verification: ON * diff --git a/src/plugins/nat/nat44-ed/nat44_ed.h b/src/plugins/nat/nat44-ed/nat44_ed.h index 0706785514b..e2047fe12ac 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed.h +++ b/src/plugins/nat/nat44-ed/nat44_ed.h @@ -12,10 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/** - * @file nat.c - * NAT plugin global declarations - */ + #ifndef __included_nat44_ed_h__ #define __included_nat44_ed_h__ @@ -65,10 +62,7 @@ typedef struct { u32 inside_vrf; u32 outside_vrf; - - /* maximum number of sessions */ u32 sessions; - } nat44_config_t; typedef enum @@ -92,19 +86,6 @@ typedef struct u32 arc_next_index; } nat_pre_trace_t; -/* External address and port allocation modes */ -#define foreach_nat_addr_and_port_alloc_alg \ - _(0, DEFAULT, "default") \ - _(1, MAPE, "map-e") \ - _(2, RANGE, "port-range") - -typedef enum -{ -#define _(v, N, s) NAT_ADDR_AND_PORT_ALLOC_ALG_##N = v, - foreach_nat_addr_and_port_alloc_alg -#undef _ -} nat_addr_and_port_alloc_alg_t; - #define foreach_nat_in2out_ed_error \ _ (UNSUPPORTED_PROTOCOL, "unsupported protocol") \ _ (OUT_OF_PORTS, "out of ports") \ @@ -176,6 +157,13 @@ typedef enum NAT44_ED_TCP_N_STATE, } nat44_ed_tcp_state_e; +format_function_t format_ed_session_kvp; +format_function_t format_snat_session; +format_function_t format_snat_static_mapping; +format_function_t format_snat_static_map_to_resolve; +format_function_t format_nat_ed_translation_error; +format_function_t format_nat_6t_flow; +format_function_t format_nat_6t; format_function_t format_nat44_ed_tcp_state; /* Session flags */ @@ -551,18 +539,6 @@ typedef struct snat_main_s /* first interface address should be auto-added */ snat_address_resolve_t *addr_to_resolve; - /* Address and port allocation function */ - nat_alloc_out_addr_and_port_function_t *alloc_addr_and_port; - /* Address and port allocation type */ - nat_addr_and_port_alloc_alg_t addr_and_port_alloc_alg; - /* Port set parameters (MAP-E) */ - u8 psid_offset; - u8 psid_length; - u16 psid; - /* Port range parameters */ - u16 start_port; - u16 end_port; - /* vector of fibs */ nat_fib_t *fibs; @@ -583,12 +559,7 @@ typedef struct snat_main_s u32 fq_in2out_output_index; u32 fq_out2in_index; - u32 out2in_node_index; - u32 in2out_node_index; - u32 in2out_output_node_index; - nat44_config_t rconfig; - //nat44_config_t cconfig; /* If forwarding is enabled */ u8 forwarding_enabled; @@ -657,9 +628,7 @@ typedef struct snat_main_s u8 log_level; /* convenience */ - api_main_t *api_main; ip4_main_t *ip4_main; - ip_lookup_main_t *ip4_lookup_main; fib_source_t fib_src_hi; fib_source_t fib_src_low; @@ -696,32 +665,25 @@ typedef struct uword *cached_presence_by_ip4_address; } snat_runtime_t; +/* + * Why is this here? Because we don't need to touch this layer to + * simply reply to an icmp. We need to change id to a unique + * value to NAT an echo request/reply. + */ + extern snat_main_t snat_main; -// nat pre ed next_node feature classification extern vlib_node_registration_t nat_default_node; extern vlib_node_registration_t nat_pre_in2out_node; extern vlib_node_registration_t nat_pre_out2in_node; -extern vlib_node_registration_t snat_in2out_node; -extern vlib_node_registration_t snat_in2out_output_node; -extern vlib_node_registration_t snat_out2in_node; -extern vlib_node_registration_t snat_in2out_worker_handoff_node; -extern vlib_node_registration_t snat_in2out_output_worker_handoff_node; -extern vlib_node_registration_t snat_out2in_worker_handoff_node; extern vlib_node_registration_t nat44_ed_in2out_node; extern vlib_node_registration_t nat44_ed_in2out_output_node; extern vlib_node_registration_t nat44_ed_out2in_node; -extern fib_source_t nat_fib_src_hi; -extern fib_source_t nat_fib_src_low; - -/* format functions */ -format_function_t format_snat_static_mapping; -format_function_t format_snat_static_map_to_resolve; -format_function_t format_snat_session; -format_function_t format_static_mapping_key; -format_function_t format_nat_addr_and_port_alloc_alg; +extern vlib_node_registration_t snat_in2out_worker_handoff_node; +extern vlib_node_registration_t snat_in2out_output_worker_handoff_node; +extern vlib_node_registration_t snat_out2in_worker_handoff_node; /** \brief Check if SNAT session is created from static mapping. @param s SNAT session @@ -861,13 +823,10 @@ is_sm_switch_address (u32 f) return (f & NAT_SM_FLAG_SWITCH_ADDRESS); } -/* logging */ #define nat_log_err(...) \ vlib_log(VLIB_LOG_LEVEL_ERR, snat_main.log_class, __VA_ARGS__) #define nat_log_warn(...) \ vlib_log(VLIB_LOG_LEVEL_WARNING, snat_main.log_class, __VA_ARGS__) -#define nat_log_notice(...) \ - vlib_log(VLIB_LOG_LEVEL_NOTICE, snat_main.log_class, __VA_ARGS__) #define nat_log_info(...) \ vlib_log(VLIB_LOG_LEVEL_INFO, snat_main.log_class, __VA_ARGS__) #define nat_log_debug(...)\ @@ -977,29 +936,8 @@ int snat_static_mapping_match ( lb_nat_type_t *lb, ip4_address_t *ext_host_addr, u8 *is_identity_nat, snat_static_mapping_t **out); -/* - * Why is this here? Because we don't need to touch this layer to - * simply reply to an icmp. We need to change id to a unique - * value to NAT an echo request/reply. - */ - -typedef struct -{ - u16 identifier; - u16 sequence; -} icmp_echo_header_t; - -typedef struct -{ - u16 src_port, dst_port; -} tcp_udp_header_t; - u32 get_thread_idx_by_port (u16 e_port); -u8 *format_static_mapping_kvp (u8 *s, va_list *args); - -u8 *format_session_kvp (u8 *s, va_list *args); - u32 nat_calc_bihash_buckets (u32 n_elts); void nat44_addresses_free (snat_address_t **addresses); @@ -1008,30 +946,8 @@ void nat44_ed_sessions_clear (); int nat44_ed_set_frame_queue_nelts (u32 frame_queue_nelts); -typedef enum -{ - NAT_ED_TRNSL_ERR_SUCCESS = 0, - NAT_ED_TRNSL_ERR_TRANSLATION_FAILED = 1, - NAT_ED_TRNSL_ERR_FLOW_MISMATCH = 2, - NAT_ED_TRNSL_ERR_PACKET_TRUNCATED = 3, - NAT_ED_TRNSL_ERR_INNER_IP_CORRUPT = 4, - NAT_ED_TRNSL_ERR_INVALID_CSUM = 5, -} nat_translation_error_e; - -nat_translation_error_e nat_6t_flow_buf_translate_i2o ( - vlib_main_t *vm, snat_main_t *sm, vlib_buffer_t *b, ip4_header_t *ip, - nat_6t_flow_t *f, ip_protocol_t proto, int is_output_feature); - -nat_translation_error_e nat_6t_flow_buf_translate_o2i ( - vlib_main_t *vm, snat_main_t *sm, vlib_buffer_t *b, ip4_header_t *ip, - nat_6t_flow_t *f, ip_protocol_t proto, int is_output_feature); - void nat_6t_l3_l4_csum_calc (nat_6t_flow_t *f); -format_function_t format_nat_ed_translation_error; -format_function_t format_nat_6t_flow; -format_function_t format_ed_session_kvp; - snat_static_mapping_t *nat44_ed_sm_i2o_lookup (snat_main_t *sm, ip4_address_t addr, u16 port, u32 fib_index, u8 proto); @@ -1052,6 +968,24 @@ void nat_syslog_nat44_sdel (u32 ssubix, u32 sfibix, ip4_address_t *isaddr, ip4_address_t *xdaddr, u16 xdport, u8 proto, u8 is_twicenat); +typedef enum +{ + NAT_ED_TRNSL_ERR_SUCCESS = 0, + NAT_ED_TRNSL_ERR_TRANSLATION_FAILED = 1, + NAT_ED_TRNSL_ERR_FLOW_MISMATCH = 2, + NAT_ED_TRNSL_ERR_PACKET_TRUNCATED = 3, + NAT_ED_TRNSL_ERR_INNER_IP_CORRUPT = 4, + NAT_ED_TRNSL_ERR_INVALID_CSUM = 5, +} nat_translation_error_e; + +nat_translation_error_e nat_6t_flow_buf_translate_i2o ( + vlib_main_t *vm, snat_main_t *sm, vlib_buffer_t *b, ip4_header_t *ip, + nat_6t_flow_t *f, ip_protocol_t proto, int is_output_feature); + +nat_translation_error_e nat_6t_flow_buf_translate_o2i ( + vlib_main_t *vm, snat_main_t *sm, vlib_buffer_t *b, ip4_header_t *ip, + nat_6t_flow_t *f, ip_protocol_t proto, int is_output_feature); + #endif /* __included_nat44_ed_h__ */ /* * fd.io coding-style-patch-verification: ON diff --git a/src/plugins/nat/nat44-ed/nat44_ed_api.c b/src/plugins/nat/nat44-ed/nat44_ed_api.c index 6ab3aaa35d9..f4ba2bc9e8e 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed_api.c +++ b/src/plugins/nat/nat44-ed/nat44_ed_api.c @@ -177,21 +177,6 @@ vl_api_nat44_set_session_limit_t_handler (vl_api_nat44_set_session_limit_t * } static void -vl_api_nat_set_log_level_t_handler (vl_api_nat_set_log_level_t * mp) -{ - snat_main_t *sm = &snat_main; - vl_api_nat_set_log_level_reply_t *rmp; - int rv = 0; - - if (sm->log_level > NAT_LOG_DEBUG) - rv = VNET_API_ERROR_UNSUPPORTED; - else - sm->log_level = mp->log_level; - - REPLY_MACRO (VL_API_NAT_SET_WORKERS_REPLY); -} - -static void vl_api_nat_ipfix_enable_disable_t_handler (vl_api_nat_ipfix_enable_disable_t * mp) { @@ -223,22 +208,6 @@ vl_api_nat_set_timeouts_t_handler (vl_api_nat_set_timeouts_t * mp) } static void -vl_api_nat_get_timeouts_t_handler (vl_api_nat_get_timeouts_t * mp) -{ - snat_main_t *sm = &snat_main; - vl_api_nat_get_timeouts_reply_t *rmp; - int rv = 0; - - REPLY_MACRO2 (VL_API_NAT_GET_TIMEOUTS_REPLY, - ({ - rmp->udp = htonl (sm->timeouts.udp); - rmp->tcp_established = htonl (sm->timeouts.tcp.established); - rmp->tcp_transitory = htonl (sm->timeouts.tcp.transitory); - rmp->icmp = htonl (sm->timeouts.icmp); - })) -} - -static void vl_api_nat_set_mss_clamping_t_handler (vl_api_nat_set_mss_clamping_t * mp) { snat_main_t *sm = &snat_main; @@ -431,121 +400,6 @@ vl_api_nat44_interface_dump_t_handler (vl_api_nat44_interface_dump_t * mp) } } -static_always_inline int -add_del_dummy_output_interface (u32 sw_if_index, u8 is_inside, u8 is_add) -{ - snat_main_t *sm = &snat_main; - snat_interface_t *i; - int rv = 1; - - pool_foreach (i, sm->output_feature_dummy_interfaces) - { - if (i->sw_if_index == sw_if_index) - { - if (!is_add) - { - pool_put (sm->output_feature_dummy_interfaces, i); - rv = 0; - } - goto done; - } - } - - if (is_add) - { - pool_get (sm->output_feature_dummy_interfaces, i); - i->sw_if_index = sw_if_index; - - if (is_inside) - { - i->flags |= NAT_INTERFACE_FLAG_IS_INSIDE; - } - else - { - i->flags |= NAT_INTERFACE_FLAG_IS_OUTSIDE; - } - - rv = 0; - } - -done: - return rv; -} - -static void - vl_api_nat44_interface_add_del_output_feature_t_handler - (vl_api_nat44_interface_add_del_output_feature_t * mp) -{ - vl_api_nat44_interface_add_del_output_feature_reply_t *rmp; - snat_main_t *sm = &snat_main; - u32 sw_if_index; - int rv = 0; - - VALIDATE_SW_IF_INDEX (mp); - - sw_if_index = ntohl (mp->sw_if_index); - - // register all interfaces in the dummy structure - rv = add_del_dummy_output_interface ( - sw_if_index, mp->flags & NAT_API_IS_INSIDE, mp->is_add); - - if (!(mp->flags & NAT_API_IS_INSIDE)) - { - if (mp->is_add) - { - rv = nat44_ed_add_output_interface (sw_if_index); - } - else - { - rv = nat44_ed_del_output_interface (sw_if_index); - } - } - - BAD_SW_IF_INDEX_LABEL; - REPLY_MACRO (VL_API_NAT44_INTERFACE_ADD_DEL_OUTPUT_FEATURE_REPLY); -} - -static void -send_nat44_interface_output_feature_details (snat_interface_t * i, - vl_api_registration_t * reg, - u32 context) -{ - vl_api_nat44_interface_output_feature_details_t *rmp; - snat_main_t *sm = &snat_main; - - rmp = vl_msg_api_alloc (sizeof (*rmp)); - clib_memset (rmp, 0, sizeof (*rmp)); - rmp->_vl_msg_id = - ntohs (VL_API_NAT44_INTERFACE_OUTPUT_FEATURE_DETAILS + sm->msg_id_base); - rmp->sw_if_index = ntohl (i->sw_if_index); - rmp->context = context; - - if (nat44_ed_is_interface_inside (i)) - { - rmp->flags |= NAT_API_IS_INSIDE; - } - - vl_api_send_msg (reg, (u8 *) rmp); -} - -static void - vl_api_nat44_interface_output_feature_dump_t_handler - (vl_api_nat44_interface_output_feature_dump_t * mp) -{ - vl_api_registration_t *reg; - snat_main_t *sm = &snat_main; - snat_interface_t *i; - - reg = vl_api_client_index_to_registration (mp->client_index); - if (!reg) - return; - - pool_foreach (i, sm->output_feature_dummy_interfaces) - { - send_nat44_interface_output_feature_details (i, reg, mp->context); - } -} - static void vl_api_nat44_ed_add_del_output_interface_t_handler ( vl_api_nat44_ed_add_del_output_interface_t *mp) @@ -1307,214 +1161,6 @@ vl_api_nat44_forwarding_enable_disable_t_handler ( } static void -vl_api_nat44_forwarding_is_enabled_t_handler ( - vl_api_nat44_forwarding_is_enabled_t *mp) -{ - vl_api_registration_t *reg; - snat_main_t *sm = &snat_main; - vl_api_nat44_forwarding_is_enabled_reply_t *rmp; - - reg = vl_api_client_index_to_registration (mp->client_index); - if (!reg) - return; - - rmp = vl_msg_api_alloc (sizeof (*rmp)); - clib_memset (rmp, 0, sizeof (*rmp)); - rmp->_vl_msg_id = - ntohs (VL_API_NAT44_FORWARDING_IS_ENABLED_REPLY + sm->msg_id_base); - rmp->context = mp->context; - - rmp->enabled = sm->forwarding_enabled; - - vl_api_send_msg (reg, (u8 *) rmp); -} - -/* Obsolete calls hold back because of deprecation - * should not be used */ - -static void -vl_api_nat_set_addr_and_port_alloc_alg_t_handler ( - vl_api_nat_set_addr_and_port_alloc_alg_t *mp) -{ - snat_main_t *sm = &snat_main; - vl_api_nat_set_addr_and_port_alloc_alg_reply_t *rmp; - int rv = VNET_API_ERROR_UNSUPPORTED; - REPLY_MACRO (VL_API_NAT_SET_ADDR_AND_PORT_ALLOC_ALG_REPLY); -} - -static void -vl_api_nat_get_addr_and_port_alloc_alg_t_handler ( - vl_api_nat_get_addr_and_port_alloc_alg_t *mp) -{ - snat_main_t *sm = &snat_main; - vl_api_nat_get_addr_and_port_alloc_alg_reply_t *rmp; - int rv = VNET_API_ERROR_UNSUPPORTED; - REPLY_MACRO (VL_API_NAT_GET_ADDR_AND_PORT_ALLOC_ALG_REPLY); -} - -static void -vl_api_nat_ha_set_listener_t_handler (vl_api_nat_ha_set_listener_t *mp) -{ - snat_main_t *sm = &snat_main; - vl_api_nat_ha_set_listener_reply_t *rmp; - int rv = VNET_API_ERROR_UNSUPPORTED; - REPLY_MACRO (VL_API_NAT_HA_SET_LISTENER_REPLY); -} - -static void -vl_api_nat_ha_get_listener_t_handler (vl_api_nat_ha_get_listener_t *mp) -{ - snat_main_t *sm = &snat_main; - vl_api_nat_ha_get_listener_reply_t *rmp; - int rv = VNET_API_ERROR_UNSUPPORTED; - REPLY_MACRO (VL_API_NAT_HA_GET_LISTENER_REPLY); -} - -static void -vl_api_nat_ha_set_failover_t_handler (vl_api_nat_ha_set_failover_t *mp) -{ - snat_main_t *sm = &snat_main; - vl_api_nat_ha_set_failover_reply_t *rmp; - int rv = VNET_API_ERROR_UNSUPPORTED; - REPLY_MACRO (VL_API_NAT_HA_SET_FAILOVER_REPLY); -} - -static void -vl_api_nat_ha_get_failover_t_handler (vl_api_nat_ha_get_failover_t *mp) -{ - snat_main_t *sm = &snat_main; - vl_api_nat_ha_get_failover_reply_t *rmp; - int rv = VNET_API_ERROR_UNSUPPORTED; - REPLY_MACRO (VL_API_NAT_HA_GET_FAILOVER_REPLY); -} - -static void -vl_api_nat_ha_flush_t_handler (vl_api_nat_ha_flush_t *mp) -{ - snat_main_t *sm = &snat_main; - vl_api_nat_ha_flush_reply_t *rmp; - int rv = VNET_API_ERROR_UNSUPPORTED; - REPLY_MACRO (VL_API_NAT_HA_FLUSH_REPLY); -} - -static void -vl_api_nat_ha_resync_t_handler (vl_api_nat_ha_resync_t *mp) -{ - snat_main_t *sm = &snat_main; - vl_api_nat_ha_resync_reply_t *rmp; - int rv = VNET_API_ERROR_UNSUPPORTED; - REPLY_MACRO (VL_API_NAT_HA_RESYNC_REPLY); -} - -static void -vl_api_nat44_del_user_t_handler (vl_api_nat44_del_user_t *mp) -{ - snat_main_t *sm = &snat_main; - vl_api_nat44_del_user_reply_t *rmp; - int rv = VNET_API_ERROR_UNSUPPORTED; - REPLY_MACRO (VL_API_NAT44_DEL_USER_REPLY); -} - -static void -vl_api_nat44_session_cleanup_t_handler (vl_api_nat44_session_cleanup_t *mp) -{ - snat_main_t *sm = &snat_main; - vl_api_nat44_session_cleanup_reply_t *rmp; - int rv = VNET_API_ERROR_UNSUPPORTED; - REPLY_MACRO (VL_API_NAT44_SESSION_CLEANUP_REPLY); -} - -static void -vl_api_nat44_plugin_enable_disable_t_handler ( - vl_api_nat44_plugin_enable_disable_t *mp) -{ - snat_main_t *sm = &snat_main; - nat44_config_t c = { 0 }; - vl_api_nat44_plugin_enable_disable_reply_t *rmp; - int rv = 0; - - if (mp->enable) - { - if ((mp->flags & NAT44_API_IS_STATIC_MAPPING_ONLY) || - (mp->flags & NAT44_API_IS_CONNECTION_TRACKING) || mp->users || - mp->user_sessions) - { - rv = VNET_API_ERROR_UNSUPPORTED; - } - else - { - c.sessions = ntohl (mp->sessions); - c.inside_vrf = ntohl (mp->inside_vrf); - c.outside_vrf = ntohl (mp->outside_vrf); - - rv = nat44_plugin_enable (c); - } - } - else - { - rv = nat44_plugin_disable (); - } - - REPLY_MACRO (VL_API_NAT44_PLUGIN_ENABLE_DISABLE_REPLY); -} - -static void -vl_api_nat_control_ping_t_handler (vl_api_nat_control_ping_t *mp) -{ - vl_api_nat_control_ping_reply_t *rmp; - snat_main_t *sm = &snat_main; - int rv = 0; - - REPLY_MACRO2 (VL_API_NAT_CONTROL_PING_REPLY, - ({ rmp->vpe_pid = ntohl (getpid ()); })); -} - -static void -vl_api_nat_show_config_t_handler (vl_api_nat_show_config_t *mp) -{ - vl_api_nat_show_config_reply_t *rmp; - snat_main_t *sm = &snat_main; - int rv = 0; - - REPLY_MACRO2_ZERO (VL_API_NAT_SHOW_CONFIG_REPLY, ({ - rmp->translation_buckets = - htonl (sm->translation_buckets); - rmp->user_buckets = 0; - rmp->max_translations_per_user = 0; - rmp->outside_vrf_id = htonl (sm->outside_vrf_id); - rmp->inside_vrf_id = htonl (sm->inside_vrf_id); - rmp->static_mapping_only = 0; - rmp->static_mapping_connection_tracking = 0; - rmp->endpoint_dependent = 1; - rmp->out2in_dpo = 0; - })); -} - -static void -vl_api_nat_show_config_2_t_handler (vl_api_nat_show_config_2_t *mp) -{ - vl_api_nat_show_config_2_reply_t *rmp; - snat_main_t *sm = &snat_main; - int rv = 0; - - REPLY_MACRO2_ZERO ( - VL_API_NAT_SHOW_CONFIG_2_REPLY, ({ - rmp->translation_buckets = htonl (sm->translation_buckets); - rmp->user_buckets = 0; - rmp->max_translations_per_user = 0; - rmp->outside_vrf_id = htonl (sm->outside_vrf_id); - rmp->inside_vrf_id = htonl (sm->inside_vrf_id); - rmp->static_mapping_only = 0; - rmp->static_mapping_connection_tracking = 0; - rmp->endpoint_dependent = 1; - rmp->out2in_dpo = 0; - rmp->max_translations_per_thread = - clib_net_to_host_u32 (sm->max_translations_per_thread); - rmp->max_users_per_thread = 0; - })); -} - -static void vl_api_nat44_show_running_config_t_handler ( vl_api_nat44_show_running_config_t *mp) { @@ -1848,6 +1494,91 @@ vl_api_nat44_user_session_v2_dump_t_handler ( } } +// DEPRECATED, obsolete messages completely unsupported + +static void +vl_api_nat_set_addr_and_port_alloc_alg_t_handler ( + vl_api_nat_set_addr_and_port_alloc_alg_t *mp) +{ + snat_main_t *sm = &snat_main; + vl_api_nat_set_addr_and_port_alloc_alg_reply_t *rmp; + int rv = VNET_API_ERROR_UNSUPPORTED; + REPLY_MACRO (VL_API_NAT_SET_ADDR_AND_PORT_ALLOC_ALG_REPLY); +} + +static void +vl_api_nat_get_addr_and_port_alloc_alg_t_handler ( + vl_api_nat_get_addr_and_port_alloc_alg_t *mp) +{ + snat_main_t *sm = &snat_main; + vl_api_nat_get_addr_and_port_alloc_alg_reply_t *rmp; + int rv = VNET_API_ERROR_UNSUPPORTED; + REPLY_MACRO (VL_API_NAT_GET_ADDR_AND_PORT_ALLOC_ALG_REPLY); +} + +static void +vl_api_nat_ha_set_listener_t_handler (vl_api_nat_ha_set_listener_t *mp) +{ + snat_main_t *sm = &snat_main; + vl_api_nat_ha_set_listener_reply_t *rmp; + int rv = VNET_API_ERROR_UNSUPPORTED; + REPLY_MACRO (VL_API_NAT_HA_SET_LISTENER_REPLY); +} + +static void +vl_api_nat_ha_get_listener_t_handler (vl_api_nat_ha_get_listener_t *mp) +{ + snat_main_t *sm = &snat_main; + vl_api_nat_ha_get_listener_reply_t *rmp; + int rv = VNET_API_ERROR_UNSUPPORTED; + REPLY_MACRO (VL_API_NAT_HA_GET_LISTENER_REPLY); +} + +static void +vl_api_nat_ha_set_failover_t_handler (vl_api_nat_ha_set_failover_t *mp) +{ + snat_main_t *sm = &snat_main; + vl_api_nat_ha_set_failover_reply_t *rmp; + int rv = VNET_API_ERROR_UNSUPPORTED; + REPLY_MACRO (VL_API_NAT_HA_SET_FAILOVER_REPLY); +} + +static void +vl_api_nat_ha_get_failover_t_handler (vl_api_nat_ha_get_failover_t *mp) +{ + snat_main_t *sm = &snat_main; + vl_api_nat_ha_get_failover_reply_t *rmp; + int rv = VNET_API_ERROR_UNSUPPORTED; + REPLY_MACRO (VL_API_NAT_HA_GET_FAILOVER_REPLY); +} + +static void +vl_api_nat_ha_flush_t_handler (vl_api_nat_ha_flush_t *mp) +{ + snat_main_t *sm = &snat_main; + vl_api_nat_ha_flush_reply_t *rmp; + int rv = VNET_API_ERROR_UNSUPPORTED; + REPLY_MACRO (VL_API_NAT_HA_FLUSH_REPLY); +} + +static void +vl_api_nat_ha_resync_t_handler (vl_api_nat_ha_resync_t *mp) +{ + snat_main_t *sm = &snat_main; + vl_api_nat_ha_resync_reply_t *rmp; + int rv = VNET_API_ERROR_UNSUPPORTED; + REPLY_MACRO (VL_API_NAT_HA_RESYNC_REPLY); +} + +static void +vl_api_nat44_del_user_t_handler (vl_api_nat44_del_user_t *mp) +{ + snat_main_t *sm = &snat_main; + vl_api_nat44_del_user_reply_t *rmp; + int rv = VNET_API_ERROR_UNSUPPORTED; + REPLY_MACRO (VL_API_NAT44_DEL_USER_REPLY); +} + /* API definitions */ #include <vnet/format_fns.h> #include <nat/nat44-ed/nat44_ed.api.c> diff --git a/src/plugins/nat/nat44-ed/nat44_ed_format.c b/src/plugins/nat/nat44-ed/nat44_ed_format.c index 4598c02208f..f643d1c6056 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed_format.c +++ b/src/plugins/nat/nat44-ed/nat44_ed_format.c @@ -12,30 +12,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/** - * @file - * @brief NAT formatting - */ #include <nat/nat44-ed/nat44_ed.h> #include <nat/nat44-ed/nat44_ed_inlines.h> u8 * -format_nat_addr_and_port_alloc_alg (u8 * s, va_list * args) +format_ed_session_kvp (u8 *s, va_list *args) { - u32 i = va_arg (*args, u32); - u8 *t = 0; + clib_bihash_kv_16_8_t *v = va_arg (*args, clib_bihash_kv_16_8_t *); + + u8 proto; + u16 r_port, l_port; + ip4_address_t l_addr, r_addr; + u32 fib_index; + + split_ed_kv (v, &l_addr, &r_addr, &proto, &fib_index, &l_port, &r_port); + s = format (s, + "local %U:%d remote %U:%d proto %U fib %d thread-index %u " + "session-index %u", + format_ip4_address, &l_addr, clib_net_to_host_u16 (l_port), + format_ip4_address, &r_addr, clib_net_to_host_u16 (r_port), + format_ip_protocol, proto, fib_index, + ed_value_get_thread_index (v), ed_value_get_session_index (v)); - switch (i) - { -#define _(v, N, s) case NAT_ADDR_AND_PORT_ALLOC_ALG_##N: t = (u8 *) s; break; - foreach_nat_addr_and_port_alloc_alg -#undef _ - default: - s = format (s, "unknown"); - return s; - } - s = format (s, "%s", t); return s; } @@ -192,6 +191,154 @@ format_snat_static_map_to_resolve (u8 * s, va_list * args) return s; } +u8 * +format_nat_ed_translation_error (u8 *s, va_list *args) +{ + nat_translation_error_e e = va_arg (*args, nat_translation_error_e); + + switch (e) + { + case NAT_ED_TRNSL_ERR_SUCCESS: + s = format (s, "success"); + break; + case NAT_ED_TRNSL_ERR_TRANSLATION_FAILED: + s = format (s, "translation-failed"); + break; + case NAT_ED_TRNSL_ERR_FLOW_MISMATCH: + s = format (s, "flow-mismatch"); + break; + case NAT_ED_TRNSL_ERR_PACKET_TRUNCATED: + s = format (s, "packet-truncated"); + break; + case NAT_ED_TRNSL_ERR_INNER_IP_CORRUPT: + s = format (s, "inner-ip-corrupted"); + break; + case NAT_ED_TRNSL_ERR_INVALID_CSUM: + s = format (s, "invalid-checksum"); + break; + } + return s; +} + +u8 * +format_nat_6t_flow (u8 *s, va_list *args) +{ + nat_6t_flow_t *f = va_arg (*args, nat_6t_flow_t *); + + s = format (s, "match: %U ", format_nat_6t, &f->match); + int r = 0; + if (f->ops & NAT_FLOW_OP_SADDR_REWRITE) + { + s = format (s, "rewrite: saddr %U ", format_ip4_address, + f->rewrite.saddr.as_u8); + r = 1; + } + if (f->ops & NAT_FLOW_OP_SPORT_REWRITE) + { + if (!r) + { + s = format (s, "rewrite: "); + r = 1; + } + s = format (s, "sport %u ", clib_net_to_host_u16 (f->rewrite.sport)); + } + if (f->ops & NAT_FLOW_OP_DADDR_REWRITE) + { + if (!r) + { + s = format (s, "rewrite: "); + r = 1; + } + s = format (s, "daddr %U ", format_ip4_address, f->rewrite.daddr.as_u8); + } + if (f->ops & NAT_FLOW_OP_DPORT_REWRITE) + { + if (!r) + { + s = format (s, "rewrite: "); + r = 1; + } + s = format (s, "dport %u ", clib_net_to_host_u16 (f->rewrite.dport)); + } + if (f->ops & NAT_FLOW_OP_ICMP_ID_REWRITE) + { + if (!r) + { + s = format (s, "rewrite: "); + r = 1; + } + s = format (s, "icmp-id %u ", clib_net_to_host_u16 (f->rewrite.icmp_id)); + } + if (f->ops & NAT_FLOW_OP_TXFIB_REWRITE) + { + if (!r) + { + s = format (s, "rewrite: "); + r = 1; + } + s = format (s, "txfib %u ", f->rewrite.fib_index); + } + return s; +} + +u8 * +format_nat_6t (u8 *s, va_list *args) +{ + nat_6t_t *t = va_arg (*args, nat_6t_t *); + + s = format (s, "saddr %U sport %u daddr %U dport %u proto %U fib_idx %u", + format_ip4_address, t->saddr.as_u8, + clib_net_to_host_u16 (t->sport), format_ip4_address, + t->daddr.as_u8, clib_net_to_host_u16 (t->dport), + format_ip_protocol, t->proto, t->fib_index); + return s; +} + +u8 * +format_nat44_ed_tcp_state (u8 *s, va_list *args) +{ + nat44_ed_tcp_state_e e = va_arg (*args, nat44_ed_tcp_state_e); + switch (e) + { + case NAT44_ED_TCP_STATE_CLOSED: + s = format (s, "closed"); + break; + case NAT44_ED_TCP_STATE_SYN_I2O: + s = format (s, "SYN seen in in2out direction"); + break; + case NAT44_ED_TCP_STATE_SYN_O2I: + s = format (s, "SYN seen in out2in direction"); + break; + case NAT44_ED_TCP_STATE_ESTABLISHED: + s = format (s, "SYN seen in both directions/established"); + break; + case NAT44_ED_TCP_STATE_FIN_I2O: + s = format (s, "FIN seen in in2out direction"); + break; + case NAT44_ED_TCP_STATE_FIN_O2I: + s = format (s, "FIN seen in out2in direction"); + break; + case NAT44_ED_TCP_STATE_RST_TRANS: + s = format (s, "RST seen/transitory timeout"); + break; + case NAT44_ED_TCP_STATE_FIN_TRANS: + s = format (s, "FIN seen in both directions/transitory timeout"); + break; + case NAT44_ED_TCP_STATE_FIN_REOPEN_SYN_O2I: + s = format (s, "FIN seen in both directions/transitory timeout/session " + "reopening in out2in direction"); + break; + case NAT44_ED_TCP_STATE_FIN_REOPEN_SYN_I2O: + s = format (s, "FIN seen in both directions/transitory timeout/session " + "reopening in in2out direction"); + break; + case NAT44_ED_TCP_N_STATE: + s = format (s, "BUG! unexpected N_STATE! BUG!"); + break; + } + return s; +} + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/plugins/nat/nat44-ed/nat44_ed_inlines.h b/src/plugins/nat/nat44-ed/nat44_ed_inlines.h index a13f250cd3b..f50ecf7ffcc 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed_inlines.h +++ b/src/plugins/nat/nat44-ed/nat44_ed_inlines.h @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + /** * @brief The NAT inline functions */ @@ -124,13 +125,13 @@ nat_get_icmp_session_lookup_values (vlib_buffer_t *b, ip4_header_t *ip0, u16 *lookup_dport, u8 *lookup_protocol) { icmp46_header_t *icmp0; - icmp_echo_header_t *echo0, *inner_echo0 = 0; + nat_icmp_echo_header_t *echo0, *inner_echo0 = 0; ip4_header_t *inner_ip0 = 0; void *l4_header = 0; icmp46_header_t *inner_icmp0; icmp0 = (icmp46_header_t *) ip4_next_header (ip0); - echo0 = (icmp_echo_header_t *) (icmp0 + 1); + echo0 = (nat_icmp_echo_header_t *) (icmp0 + 1); // avoid warning about unused variables in caller by setting to bogus values *lookup_sport = 0; @@ -156,14 +157,14 @@ nat_get_icmp_session_lookup_values (vlib_buffer_t *b, ip4_header_t *ip0, { case IP_PROTOCOL_ICMP: inner_icmp0 = (icmp46_header_t *) l4_header; - inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1); + inner_echo0 = (nat_icmp_echo_header_t *) (inner_icmp0 + 1); *lookup_sport = inner_echo0->identifier; *lookup_dport = inner_echo0->identifier; break; case IP_PROTOCOL_UDP: case IP_PROTOCOL_TCP: - *lookup_sport = ((tcp_udp_header_t *) l4_header)->dst_port; - *lookup_dport = ((tcp_udp_header_t *) l4_header)->src_port; + *lookup_sport = ((nat_tcp_udp_header_t *) l4_header)->dst_port; + *lookup_dport = ((nat_tcp_udp_header_t *) l4_header)->src_port; break; default: return NAT_IN2OUT_ED_ERROR_UNSUPPORTED_PROTOCOL; diff --git a/test/test_dslite.py b/test/test_dslite.py index 8f5995e61fa..912ae17da58 100644 --- a/test/test_dslite.py +++ b/test/test_dslite.py @@ -90,9 +90,6 @@ class TestDSlite(VppTestCase): def test_dslite(self): """ Test DS-Lite """ - nat_config = self.vapi.nat_show_config() - self.assertEqual(0, nat_config.dslite_ce) - self.vapi.dslite_add_del_pool_addr_range(start_addr=self.nat_addr, end_addr=self.nat_addr, is_add=1) @@ -265,11 +262,6 @@ class TestDSliteCE(VppTestCase): def test_dslite_ce(self): """ Test DS-Lite CE """ - - # TODO: add message to retrieve dslite config - # nat_config = self.vapi.nat_show_config() - # self.assertEqual(1, nat_config.dslite_ce) - b4_ip4 = '192.0.0.2' b4_ip6 = '2001:db8:62aa::375e:f4c1:1' self.vapi.dslite_set_b4_addr(ip4_addr=b4_ip4, ip6_addr=b4_ip6) diff --git a/test/test_nat44_ed.py b/test/test_nat44_ed.py index b761213d52b..f172dabe98b 100644 --- a/test/test_nat44_ed.py +++ b/test/test_nat44_ed.py @@ -1201,8 +1201,9 @@ class TestNAT44ED(VppTestCase): self.vapi.nat44_forwarding_enable_disable(enable=1) self.nat_add_address(self.nat_addr) - self.vapi.nat44_interface_add_del_output_feature( - sw_if_index=self.pg1.sw_if_index, is_add=1,) + self.vapi.nat44_ed_add_del_output_interface( + sw_if_index=self.pg1.sw_if_index, + is_add=1) # session initiated from service host - translate pkts = self.create_stream_in(self.pg0, self.pg1) @@ -1274,8 +1275,9 @@ class TestNAT44ED(VppTestCase): self.nat_add_address(self.nat_addr) self.nat_add_outside_interface(self.pg0) - self.vapi.nat44_interface_add_del_output_feature( - sw_if_index=self.pg1.sw_if_index, is_add=1) + self.vapi.nat44_ed_add_del_output_interface( + sw_if_index=self.pg1.sw_if_index, + is_add=1) # in2out pkts = self.create_stream_in(self.pg0, self.pg1) @@ -1790,7 +1792,7 @@ class TestNAT44ED(VppTestCase): self.nat_add_address(self.nat_addr) flags = self.config_flags.NAT_IS_INSIDE - self.vapi.nat44_interface_add_del_output_feature( + self.vapi.nat44_ed_add_del_output_interface( sw_if_index=self.pg1.sw_if_index, is_add=1) self.vapi.nat44_interface_add_del_feature( @@ -2519,9 +2521,9 @@ class TestNAT44EDMW(TestNAT44ED): def test_show_max_translations(self): """ NAT44ED API test - max translations per thread """ - nat_config = self.vapi.nat_show_config_2() + config = self.vapi.nat44_show_running_config() self.assertEqual(self.max_sessions, - nat_config.max_translations_per_thread) + config.sessions) def test_lru_cleanup(self): """ NAT44ED LRU cleanup algorithm """ @@ -3252,7 +3254,8 @@ class TestNAT44EDMW(TestNAT44ED): def test_tcp_close(self): """ NAT44ED Close TCP session from inside network - output feature """ - old_timeouts = self.vapi.nat_get_timeouts() + config = self.vapi.nat44_show_running_config() + old_timeouts = config.timeouts new_transitory = 2 self.vapi.nat_set_timeouts( udp=old_timeouts.udp, @@ -3802,9 +3805,9 @@ class TestNAT44EDMW(TestNAT44ED): new_vrf_id = 22 self.nat_add_address(self.nat_addr) - self.vapi.nat44_interface_add_del_output_feature( - sw_if_index=self.pg8.sw_if_index, is_add=1) - + self.vapi.nat44_ed_add_del_output_interface( + sw_if_index=self.pg8.sw_if_index, + is_add=1) try: self.configure_ip4_interface(self.pg7, table_id=new_vrf_id) self.configure_ip4_interface(self.pg8, table_id=new_vrf_id) diff --git a/test/test_nat44_ed_output.py b/test/test_nat44_ed_output.py index ea5c14e7064..4ea8a5b5eda 100644 --- a/test/test_nat44_ed_output.py +++ b/test/test_nat44_ed_output.py @@ -56,7 +56,8 @@ class TestNAT44EDOutput(VppTestCase): def test_static_dynamic(self): """ Create static mapping which matches existing dynamic mapping """ - old_timeouts = self.vapi.nat_get_timeouts() + config = self.vapi.nat44_show_running_config() + old_timeouts = config.timeouts new_transitory = 2 self.vapi.nat_set_timeouts( udp=old_timeouts.udp, @@ -80,9 +81,9 @@ class TestNAT44EDOutput(VppTestCase): self.vapi.nat44_interface_add_del_feature( sw_if_index=self.pg0.sw_if_index, flags=VppEnum.vl_api_nat_config_flags_t.NAT_IS_INSIDE, is_add=1) - self.vapi.nat44_interface_add_del_output_feature( - is_add=1, - sw_if_index=self.pg1.sw_if_index) + self.vapi.nat44_ed_add_del_output_interface( + sw_if_index=self.pg1.sw_if_index, + is_add=1) thread_index = get_nat44_ed_in2out_worker_index( local_host, self.vpp_worker_count) |