+ b0 = vlib_get_buffer (vm, bi0);
+ ip0 = vlib_buffer_get_current (b0);
+
+ /* *INDENT-OFF* */
+ vec_foreach (ap, sm->addresses)
+ {
+ if (ip0->dst_address.as_u32 == ap->addr.as_u32)
+ {
+ next0 = NAT_NEXT_OUT2IN_CLASSIFY;
+ goto enqueue0;
+ }
+ }
+ /* *INDENT-ON* */
+
+ if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
+ {
+ init_nat_k (&kv0, ip0->dst_address, 0, 0, 0);
+ /* try to classify the fragment based on IP header alone */
+ if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external,
+ &kv0, &value0))
+ {
+ m = pool_elt_at_index (sm->static_mappings, value0.value);
+ if (m->local_addr.as_u32 != m->external_addr.as_u32)
+ next0 = NAT_NEXT_OUT2IN_CLASSIFY;
+ goto enqueue0;
+ }
+ init_nat_k (&kv0, ip0->dst_address,
+ vnet_buffer (b0)->ip.reass.l4_dst_port, 0,
+ ip_proto_to_nat_proto (ip0->protocol));
+ if (!clib_bihash_search_8_8
+ (&sm->static_mapping_by_external, &kv0, &value0))
+ {
+ m = pool_elt_at_index (sm->static_mappings, value0.value);
+ if (m->local_addr.as_u32 != m->external_addr.as_u32)
+ next0 = NAT_NEXT_OUT2IN_CLASSIFY;
+ }
+ }
+
+ enqueue0:
+ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
+ && (b0->flags & VLIB_BUFFER_IS_TRACED)))
+ {
+ nat44_classify_trace_t *t =
+ vlib_add_trace (vm, node, b0, sizeof (*t));
+ t->cached = 0;
+ t->next_in2out = next0 == NAT_NEXT_IN2OUT_CLASSIFY ? 1 : 0;
+ }
+
+ next_in2out += next0 == NAT_NEXT_IN2OUT_CLASSIFY;
+ next_out2in += next0 == NAT_NEXT_OUT2IN_CLASSIFY;
+
+ /* verify speculative enqueue, maybe switch current next frame */
+ vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
+ to_next, n_left_to_next,
+ bi0, next0);
+ }
+
+ vlib_put_next_frame (vm, node, next_index, n_left_to_next);
+ }
+
+ nat_send_all_to_node (vm, fragments_to_drop, node, 0, NAT_NEXT_DROP);
+
+ vec_free (fragments_to_drop);
+
+ vlib_node_increment_counter (vm, node->node_index,
+ NAT44_CLASSIFY_ERROR_NEXT_IN2OUT, next_in2out);
+ vlib_node_increment_counter (vm, node->node_index,
+ NAT44_CLASSIFY_ERROR_NEXT_OUT2IN, next_out2in);