#define foreach_nat44_classify_error \
_(MAX_REASS, "Maximum reassemblies exceeded") \
-_(MAX_FRAG, "Maximum fragments per reassembly exceeded")
+_(MAX_FRAG, "Maximum fragments per reassembly exceeded") \
+_(NEXT_IN2OUT, "next in2out") \
+_(NEXT_OUT2IN, "next out2in") \
+_(FRAG_CACHED, "fragment cached")
typedef enum
{
snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
u32 *fragments_to_drop = 0;
u32 *fragments_to_loopback = 0;
+ u32 next_in2out = 0, next_out2in = 0, frag_cached = 0;
from = vlib_frame_vector_args (frame);
n_left_from = frame->n_vectors;
!(reass0->flags & NAT_REASS_FLAG_CLASSIFY_ED_CONTINUE))
{
/* first fragment still hasn't arrived, cache this fragment */
- if (nat_ip4_reass_add_fragment (reass0, bi0,
- &fragments_to_drop))
+ if (nat_ip4_reass_add_fragment
+ (thread_index, reass0, bi0, &fragments_to_drop))
{
b0->error =
node->errors[NAT44_CLASSIFY_ERROR_MAX_FRAG];
if (reass0->classify_next == NAT_REASS_IP4_CLASSIFY_NONE)
/* first fragment still hasn't arrived */
{
- if (nat_ip4_reass_add_fragment (reass0, bi0,
- &fragments_to_drop))
+ if (nat_ip4_reass_add_fragment
+ (thread_index, reass0, bi0, &fragments_to_drop))
{
b0->error =
node->errors[NAT44_CLASSIFY_ERROR_MAX_FRAG];
{
n_left_to_next++;
to_next--;
+ frag_cached++;
}
else
- /* 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);
+ {
+ next_in2out += next0 == NAT44_CLASSIFY_NEXT_IN2OUT;
+ next_out2in += next0 == NAT44_CLASSIFY_NEXT_OUT2IN;
+
+ /* 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);
+ }
if (n_left_from == 0 && vec_len (fragments_to_loopback))
{
u32 len = vec_len (fragments_to_loopback);
if (len <= VLIB_FRAME_SIZE)
{
- clib_memcpy (from, fragments_to_loopback,
- sizeof (u32) * len);
+ clib_memcpy_fast (from, fragments_to_loopback,
+ sizeof (u32) * len);
n_left_from = len;
vec_reset_length (fragments_to_loopback);
}
else
{
- clib_memcpy (from,
- fragments_to_loopback + (len -
- VLIB_FRAME_SIZE),
- sizeof (u32) * VLIB_FRAME_SIZE);
+ clib_memcpy_fast (from, fragments_to_loopback +
+ (len - VLIB_FRAME_SIZE),
+ sizeof (u32) * VLIB_FRAME_SIZE);
n_left_from = VLIB_FRAME_SIZE;
_vec_len (fragments_to_loopback) = len - VLIB_FRAME_SIZE;
}
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);
+ vlib_node_increment_counter (vm, node->node_index,
+ NAT44_CLASSIFY_ERROR_FRAG_CACHED, frag_cached);
+
return frame->n_vectors;
}