+out:
+ *p_key = key0;
+ if (s0)
+ *p_value = s0->out2in;
+ *p_dont_translate = dont_translate;
+ if (d)
+ *(snat_session_t**)d = s0;
+ return next0;
+}
+
+/**
+ * Get address and port values to be used for packet SNAT translation
+ *
+ * @param[in] sm SNAT main
+ * @param[in,out] node SNAT node runtime
+ * @param[in] cpu_index CPU index
+ * @param[in,out] b0 buffer containing packet to be translated
+ * @param[out] p_key address and port before NAT translation
+ * @param[out] p_value address and port after NAT translation
+ * @param[out] p_dont_translate if packet should not be translated
+ * @param d optional parameter
+ */
+u32 icmp_match_in2out_fast(snat_main_t *sm, vlib_node_runtime_t *node,
+ u32 cpu_index, vlib_buffer_t *b0,
+ snat_session_key_t *p_key,
+ snat_session_key_t *p_value,
+ u8 *p_dont_translate, void *d)
+{
+ snat_runtime_t *rt;
+ ip4_header_t *ip0;
+ icmp46_header_t *icmp0;
+ u32 sw_if_index0;
+ u32 rx_fib_index0;
+ snat_session_key_t key0;
+ snat_session_key_t sm0;
+ u8 dont_translate = 0;
+ u32 next0 = ~0;
+ int err;
+
+ rt = (snat_runtime_t *) node->runtime_data;
+ ip0 = vlib_buffer_get_current (b0);
+ icmp0 = (icmp46_header_t *) ip4_next_header (ip0);
+ sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX];
+ rx_fib_index0 = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0);
+
+ err = icmp_get_key (icmp0, &key0);
+ if (err != -1)
+ {
+ b0->error = node->errors[err];
+ next0 = SNAT_IN2OUT_NEXT_DROP;
+ goto out2;
+ }
+ key0.addr = ip0->src_address;
+ key0.fib_index = rx_fib_index0;
+
+ if (snat_static_mapping_match(sm, key0, &sm0, 0))
+ {
+ if (PREDICT_FALSE(snat_not_translate(sm, rt, sw_if_index0, ip0,
+ IP_PROTOCOL_ICMP, rx_fib_index0)))
+ {
+ dont_translate = 1;
+ goto out;
+ }
+
+ if (icmp_is_error_message (icmp0))
+ {
+ next0 = SNAT_IN2OUT_NEXT_DROP;
+ goto out;
+ }
+
+ b0->error = node->errors[SNAT_IN2OUT_ERROR_NO_TRANSLATION];
+ next0 = SNAT_IN2OUT_NEXT_DROP;
+ goto out;
+ }
+
+out:
+ *p_value = sm0;
+out2:
+ *p_key = key0;
+ *p_dont_translate = dont_translate;
+ return next0;
+}
+
+static inline 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 cpu_index,
+ void *d)
+{
+ snat_session_key_t key0, sm0;
+ icmp_echo_header_t *echo0, *inner_echo0 = 0;
+ ip4_header_t *inner_ip0;
+ void *l4_header = 0;
+ icmp46_header_t *inner_icmp0;
+ u8 dont_translate;
+ u32 new_addr0, old_addr0;
+ u16 old_id0, new_id0;
+ ip_csum_t sum0;
+ u16 checksum0;
+ u32 next0_tmp;
+
+ echo0 = (icmp_echo_header_t *)(icmp0+1);
+
+ next0_tmp = sm->icmp_match_in2out_cb(sm, node, cpu_index, b0,
+ &key0, &sm0, &dont_translate, d);
+ if (next0_tmp != ~0)
+ next0 = next0_tmp;
+ if (next0 == SNAT_IN2OUT_NEXT_DROP || dont_translate)
+ goto out;
+