+ *(snat_det_map_t **) e = mp0;
+ return next0;
+}
+#endif
+
+#ifndef CLIB_MARCH_VARIANT
+u32
+det44_icmp_out2in (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)
+{
+ vlib_main_t *vm = vlib_get_main ();
+ u32 new_addr0, old_addr0, next0_tmp, fib_index;
+ u16 old_id0, new_id0, port, checksum0;
+ icmp_echo_header_t *echo0, *inner_echo0;
+ icmp46_header_t *inner_icmp0;
+ ip4_header_t *inner_ip0;
+ ip4_address_t addr;
+ void *l4_header;
+ u8 dont_translate;
+ ip_csum_t sum0;
+ nat_protocol_t proto;
+
+ echo0 = (icmp_echo_header_t *) (icmp0 + 1);
+ next0_tmp = icmp_match_out2in_det (node, thread_index, b0, ip0,
+ &addr, &port, &fib_index, &proto,
+ d, e, &dont_translate);
+ if (next0_tmp != ~0)
+ next0 = next0_tmp;
+ if (next0 == DET44_OUT2IN_NEXT_DROP || dont_translate)
+ goto out;
+
+ if (PREDICT_TRUE (!ip4_is_fragment (ip0)))
+ {
+ sum0 =
+ ip_incremental_checksum_buffer (vm, b0,
+ (u8 *) icmp0 -
+ (u8 *) vlib_buffer_get_current (b0),
+ ntohs (ip0->length) -
+ ip4_header_bytes (ip0), 0);
+ checksum0 = ~ip_csum_fold (sum0);
+ if (checksum0 != 0 && checksum0 != 0xffff)
+ {
+ next0 = DET44_OUT2IN_NEXT_DROP;
+ goto out;
+ }
+ }
+
+ old_addr0 = ip0->dst_address.as_u32;
+ new_addr0 = ip0->dst_address.as_u32 = addr.as_u32;
+ vnet_buffer (b0)->sw_if_index[VLIB_TX] = fib_index;
+
+ sum0 = ip0->checksum;
+ sum0 = ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t,
+ dst_address /* changed member */ );
+ ip0->checksum = ip_csum_fold (sum0);
+
+
+ if (!vnet_buffer (b0)->ip.reass.is_non_first_fragment)
+ {
+ if (icmp0->checksum == 0)
+ icmp0->checksum = 0xffff;
+
+ if (!icmp_type_is_error_message (icmp0->type))
+ {
+ new_id0 = port;
+ if (PREDICT_FALSE (new_id0 != echo0->identifier))
+ {
+ old_id0 = echo0->identifier;
+ new_id0 = port;
+ echo0->identifier = new_id0;
+
+ sum0 = icmp0->checksum;
+ sum0 =
+ ip_csum_update (sum0, old_id0, new_id0, icmp_echo_header_t,
+ identifier /* changed member */ );
+ icmp0->checksum = ip_csum_fold (sum0);
+ }
+ }
+ else
+ {
+ inner_ip0 = (ip4_header_t *) (echo0 + 1);
+ l4_header = ip4_next_header (inner_ip0);
+
+ if (!ip4_header_checksum_is_valid (inner_ip0))
+ {
+ next0 = DET44_OUT2IN_NEXT_DROP;
+ goto out;
+ }
+
+ old_addr0 = inner_ip0->src_address.as_u32;
+ inner_ip0->src_address = addr;
+ new_addr0 = inner_ip0->src_address.as_u32;
+
+ sum0 = icmp0->checksum;
+ sum0 = ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t,
+ src_address /* changed member */ );
+ icmp0->checksum = ip_csum_fold (sum0);
+
+ switch (proto)
+ {
+ case NAT_PROTOCOL_ICMP:
+ inner_icmp0 = (icmp46_header_t *) l4_header;
+ inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1);
+
+ old_id0 = inner_echo0->identifier;
+ new_id0 = port;
+ inner_echo0->identifier = new_id0;
+
+ sum0 = icmp0->checksum;
+ sum0 =
+ ip_csum_update (sum0, old_id0, new_id0, icmp_echo_header_t,
+ identifier);
+ icmp0->checksum = ip_csum_fold (sum0);
+ break;
+ case NAT_PROTOCOL_UDP:
+ case NAT_PROTOCOL_TCP:
+ old_id0 = ((tcp_udp_header_t *) l4_header)->src_port;
+ new_id0 = port;
+ ((tcp_udp_header_t *) l4_header)->src_port = new_id0;
+
+ sum0 = icmp0->checksum;
+ sum0 = ip_csum_update (sum0, old_id0, new_id0, tcp_udp_header_t,
+ src_port);
+ icmp0->checksum = ip_csum_fold (sum0);
+ break;
+ default:
+ ASSERT (0);
+ }
+ }
+ }
+
+out: