-u32 icmp_match_in2out_fast(snat_main_t *sm, vlib_node_runtime_t *node,
- u32 thread_index, vlib_buffer_t *b0, u8 *p_proto,
- snat_session_key_t *p_value,
- u8 *p_dont_translate, void *d, void *e);
-u32 icmp_match_in2out_slow(snat_main_t *sm, vlib_node_runtime_t *node,
- u32 thread_index, vlib_buffer_t *b0, u8 *p_proto,
- snat_session_key_t *p_value,
- u8 *p_dont_translate, void *d, void *e);
-u32 icmp_match_in2out_det(snat_main_t *sm, vlib_node_runtime_t *node,
- u32 thread_index, vlib_buffer_t *b0, u8 *p_proto,
- snat_session_key_t *p_value,
- u8 *p_dont_translate, void *d, void *e);
-u32 icmp_match_out2in_fast(snat_main_t *sm, vlib_node_runtime_t *node,
- u32 thread_index, vlib_buffer_t *b0, u8 *p_proto,
- snat_session_key_t *p_value,
- u8 *p_dont_translate, void *d, void *e);
-u32 icmp_match_out2in_slow(snat_main_t *sm, vlib_node_runtime_t *node,
- u32 thread_index, vlib_buffer_t *b0, u8 *p_proto,
- snat_session_key_t *p_value,
- u8 *p_dont_translate, void *d, void *e);
-u32 icmp_match_out2in_det(snat_main_t *sm, vlib_node_runtime_t *node,
- u32 thread_index, vlib_buffer_t *b0, u8 *p_proto,
- snat_session_key_t *p_value,
- u8 *p_dont_translate, void *d, void *e);
-void increment_v4_address(ip4_address_t * a);
-void snat_add_address(snat_main_t *sm, ip4_address_t *addr, u32 vrf_id);
-int snat_del_address(snat_main_t *sm, ip4_address_t addr, u8 delete_sm);
-int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr,
- u16 l_port, u16 e_port, u32 vrf_id, int addr_only,
- u32 sw_if_index, snat_protocol_t proto, int is_add);
-clib_error_t * snat_api_init(vlib_main_t * vm, snat_main_t * sm);
-int snat_set_workers (uword * bitmap);
-int snat_interface_add_del(u32 sw_if_index, u8 is_inside, int is_del);
-int snat_interface_add_del_output_feature(u32 sw_if_index, u8 is_inside,
- int is_del);
-int snat_add_interface_address(snat_main_t *sm, u32 sw_if_index, int is_del);
-uword unformat_snat_protocol(unformat_input_t * input, va_list * args);
-u8 * format_snat_protocol(u8 * s, va_list * args);
+/** \brief Check if NAT static mapping match only out2in direction.
+ @param sm NAT static mapping
+ @return 1 if rule match only out2in direction
+*/
+#define is_out2in_only_static_mapping(sm) (sm->flags & NAT_STATIC_MAPPING_FLAG_OUT2IN_ONLY)
+
+/** \brief Check if NAT static mapping is identity NAT.
+ @param sm NAT static mapping
+ @return 1 if identity NAT
+*/
+#define is_identity_static_mapping(sm) (sm->flags & NAT_STATIC_MAPPING_FLAG_IDENTITY_NAT)
+
+/** \brief Check if NAT static mapping is load-balancing.
+ @param sm NAT static mapping
+ @return 1 if load-balancing
+*/
+#define is_lb_static_mapping(sm) (sm->flags & NAT_STATIC_MAPPING_FLAG_LB)
+
+/* 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(...)\
+ vlib_log(VLIB_LOG_LEVEL_DEBUG, snat_main.log_class, __VA_ARGS__)
+
+/* ICMP session match functions */
+u32 icmp_match_in2out_fast (snat_main_t * sm, vlib_node_runtime_t * node,
+ u32 thread_index, vlib_buffer_t * b0,
+ ip4_header_t * ip0, u8 * p_proto,
+ snat_session_key_t * p_value,
+ u8 * p_dont_translate, void *d, void *e);
+u32 icmp_match_in2out_slow (snat_main_t * sm, vlib_node_runtime_t * node,
+ u32 thread_index, vlib_buffer_t * b0,
+ ip4_header_t * ip0, u8 * p_proto,
+ snat_session_key_t * p_value,
+ u8 * p_dont_translate, void *d, void *e);
+u32 icmp_match_out2in_fast (snat_main_t * sm, vlib_node_runtime_t * node,
+ u32 thread_index, vlib_buffer_t * b0,
+ ip4_header_t * ip0, u8 * p_proto,
+ snat_session_key_t * p_value,
+ u8 * p_dont_translate, void *d, void *e);
+u32 icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node,
+ u32 thread_index, vlib_buffer_t * b0,
+ ip4_header_t * ip0, u8 * p_proto,
+ snat_session_key_t * p_value,
+ u8 * p_dont_translate, void *d, void *e);
+
+/* ICMP deterministic NAT session match functions */
+u32 icmp_match_out2in_det (snat_main_t * sm, vlib_node_runtime_t * node,
+ u32 thread_index, vlib_buffer_t * b0,
+ ip4_header_t * ip0, u8 * p_proto,
+ snat_session_key_t * p_value,
+ u8 * p_dont_translate, void *d, void *e);
+u32 icmp_match_in2out_det (snat_main_t * sm, vlib_node_runtime_t * node,
+ u32 thread_index, vlib_buffer_t * b0,
+ ip4_header_t * ip0, u8 * p_proto,
+ snat_session_key_t * p_value,
+ u8 * p_dont_translate, void *d, void *e);
+
+/* ICMP endpoint-dependent session match functions */
+u32 icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node,
+ u32 thread_index, vlib_buffer_t * b0,
+ ip4_header_t * ip0, u8 * p_proto,
+ snat_session_key_t * p_value,
+ u8 * p_dont_translate, void *d, void *e);
+u32 icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node,
+ u32 thread_index, vlib_buffer_t * b0,
+ ip4_header_t * ip0, u8 * p_proto,
+ snat_session_key_t * p_value,
+ u8 * p_dont_translate, void *d, void *e);
+
+u32 icmp_in2out (snat_main_t * sm, vlib_buffer_t * b0, ip4_header_t * ip0,
+ icmp46_header_t * icmp0, u32 sw_if_index0, u32 rx_fib_index0,
+ vlib_node_runtime_t * node, u32 next0, u32 thread_index,
+ void *d, void *e);
+
+u32 icmp_out2in (snat_main_t * sm, vlib_buffer_t * b0, ip4_header_t * ip0,
+ icmp46_header_t * icmp0, u32 sw_if_index0, u32 rx_fib_index0,
+ vlib_node_runtime_t * node, u32 next0, u32 thread_index,
+ void *d, void *e);
+
+/* hairpinning functions */
+u32 snat_icmp_hairpinning (snat_main_t * sm, vlib_buffer_t * b0,
+ ip4_header_t * ip0, icmp46_header_t * icmp0,
+ int is_ed);
+void nat_hairpinning_sm_unknown_proto (snat_main_t * sm, vlib_buffer_t * b,
+ ip4_header_t * ip);
+void nat44_ed_hairpinning_unknown_proto (snat_main_t * sm, vlib_buffer_t * b,
+ ip4_header_t * ip);
+int snat_hairpinning (snat_main_t * sm, vlib_buffer_t * b0,
+ ip4_header_t * ip0, udp_header_t * udp0,
+ tcp_header_t * tcp0, u32 proto0, int is_ed);
+void nat44_reass_hairpinning (snat_main_t * sm, vlib_buffer_t * b0,
+ ip4_header_t * ip0, u16 sport, u16 dport,
+ u32 proto0, int is_ed);
+
+/* Call back functions for clib_bihash_add_or_overwrite_stale */
+int nat44_i2o_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg);
+int nat44_o2i_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg);
+int nat44_i2o_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg);
+int nat44_o2i_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg);
+
+/**
+ * @brief Increment IPv4 address
+ */
+void increment_v4_address (ip4_address_t * a);
+
+/**
+ * @brief Add external address to NAT44 pool
+ *
+ * @param addr IPv4 address
+ * @param vrf_id VRF id of tenant, ~0 means independent of VRF
+ * @param twice_nat 1 if twice NAT address
+ *
+ * @return 0 on success, non-zero value otherwise
+ */
+int snat_add_address (snat_main_t * sm, ip4_address_t * addr, u32 vrf_id,
+ u8 twice_nat);
+
+/**
+ * @brief Delete external address from NAT44 pool
+ *
+ * @param addr IPv4 address
+ * @param delete_sm 1 if delete static mapping using address
+ * @param twice_nat 1 if twice NAT address
+ *
+ * @return 0 on success, non-zero value otherwise
+ */
+int snat_del_address (snat_main_t * sm, ip4_address_t addr, u8 delete_sm,
+ u8 twice_nat);
+
+/**
+ * @brief Add/delete external address to FIB DPO (out2in DPO mode)
+ *
+ * @param addr IPv4 address
+ * @param is_add 1 = add, 0 = delete
+ *
+ * @return 0 on success, non-zero value otherwise
+ */
+void nat44_add_del_address_dpo (ip4_address_t addr, u8 is_add);
+
+/**
+ * @brief Add/delete NAT44 static mapping
+ *
+ * @param l_addr local IPv4 address
+ * @param e_addr external IPv4 address
+ * @param l_port local port number
+ * @param e_port external port number
+ * @param vrf_id local VRF ID
+ * @param addr_only 1 = 1:1NAT, 0 = 1:1NAPT
+ * @param sw_if_index use interface address as external IPv4 address
+ * @param proto L4 protocol
+ * @param is_add 1 = add, 0 = delete
+ * @param twice_nat twice-nat mode
+ * @param out2in_only if 1 rule match only out2in direction
+ * @param tag opaque string tag
+ * @param identity_nat identity NAT
+ *
+ * @return 0 on success, non-zero value otherwise
+ */
+int snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
+ u16 l_port, u16 e_port, u32 vrf_id,
+ int addr_only, u32 sw_if_index,
+ snat_protocol_t proto, int is_add,
+ twice_nat_type_t twice_nat, u8 out2in_only,
+ u8 * tag, u8 identity_nat);
+
+/**
+ * @brief Add/delete static mapping with load-balancing (multiple backends)
+ *
+ * @param e_addr external IPv4 address
+ * @param e_port external port number
+ * @param proto L4 protocol
+ * @param locals list of local backends
+ * @param is_add 1 = add, 0 = delete
+ * @param twice_nat twice-nat mode
+ * @param out2in_only if 1 rule match only out2in direction
+ * @param tag opaque string tag
+ * @param affinity 0 = disabled, otherwise client IP affinity sticky time
+ *
+ * @return 0 on success, non-zero value otherwise
+ */