summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xsrc/plugins/nat/in2out.c68
-rw-r--r--src/plugins/nat/in2out_ed.c70
-rw-r--r--src/plugins/nat/nat44_classify.c27
-rw-r--r--src/plugins/nat/nat44_handoff.c15
-rw-r--r--src/plugins/nat/nat64_in2out.c63
-rw-r--r--src/plugins/nat/nat64_out2in.c69
-rwxr-xr-xsrc/plugins/nat/out2in.c66
-rw-r--r--src/plugins/nat/out2in_ed.c60
-rw-r--r--test/test_nat.py116
9 files changed, 477 insertions, 77 deletions
diff --git a/src/plugins/nat/in2out.c b/src/plugins/nat/in2out.c
index 786d82147a7..15dae650844 100755
--- a/src/plugins/nat/in2out.c
+++ b/src/plugins/nat/in2out.c
@@ -80,16 +80,23 @@ vlib_node_registration_t snat_in2out_output_slowpath_node;
vlib_node_registration_t nat44_in2out_reass_node;
#define foreach_snat_in2out_error \
-_(UNSUPPORTED_PROTOCOL, "Unsupported protocol") \
-_(IN2OUT_PACKETS, "Good in2out packets processed") \
-_(OUT_OF_PORTS, "Out of ports") \
-_(BAD_OUTSIDE_FIB, "Outside VRF ID not found") \
+_(UNSUPPORTED_PROTOCOL, "unsupported protocol") \
+_(IN2OUT_PACKETS, "good in2out packets processed") \
+_(OUT_OF_PORTS, "out of ports") \
+_(BAD_OUTSIDE_FIB, "outside VRF ID not found") \
_(BAD_ICMP_TYPE, "unsupported ICMP type") \
-_(NO_TRANSLATION, "No translation") \
-_(MAX_SESSIONS_EXCEEDED, "Maximum sessions exceeded") \
-_(DROP_FRAGMENT, "Drop fragment") \
-_(MAX_REASS, "Maximum reassemblies exceeded") \
-_(MAX_FRAG, "Maximum fragments per reassembly exceeded")
+_(NO_TRANSLATION, "no translation") \
+_(MAX_SESSIONS_EXCEEDED, "maximum sessions exceeded") \
+_(DROP_FRAGMENT, "drop fragment") \
+_(MAX_REASS, "maximum reassemblies exceeded") \
+_(MAX_FRAG, "maximum fragments per reassembly exceeded")\
+_(TCP_PACKETS, "TCP packets") \
+_(UDP_PACKETS, "UDP packets") \
+_(ICMP_PACKETS, "ICMP packets") \
+_(OTHER_PACKETS, "other protocol packets") \
+_(FRAGMENTS, "fragments") \
+_(CACHED_FRAGMENTS, "cached fragments") \
+_(PROCESSED_FRAGMENTS, "processed fragments")
typedef enum
{
@@ -851,6 +858,8 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
f64 now = vlib_time_now (vm);
u32 stats_node_index;
u32 thread_index = vm->thread_index;
+ u32 tcp_packets = 0, udp_packets = 0, icmp_packets = 0, other_packets =
+ 0, fragments = 0;
stats_node_index = is_slow_path ? snat_in2out_slowpath_node.index :
snat_in2out_node.index;
@@ -950,6 +959,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
b0->error =
node->errors[SNAT_IN2OUT_ERROR_UNSUPPORTED_PROTOCOL];
}
+ other_packets++;
goto trace00;
}
@@ -958,6 +968,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
next0 = icmp_in2out_slow_path
(sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0,
node, next0, now, thread_index, &s0);
+ icmp_packets++;
goto trace00;
}
}
@@ -972,6 +983,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
if (ip4_is_fragment (ip0))
{
next0 = SNAT_IN2OUT_NEXT_REASS;
+ fragments++;
goto trace00;
}
@@ -1064,12 +1076,14 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
length /* changed member */ );
mss_clamping (sm, tcp0, &sum0);
tcp0->checksum = ip_csum_fold (sum0);
+ tcp_packets++;
}
else
{
old_port0 = udp0->src_port;
udp0->src_port = s0->out2in.port;
udp0->checksum = 0;
+ udp_packets++;
}
/* Accounting */
@@ -1094,7 +1108,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
s0 - sm->per_thread_data[thread_index].sessions;
}
- pkts_processed += next0 != SNAT_IN2OUT_NEXT_DROP;
+ pkts_processed += next0 == SNAT_IN2OUT_NEXT_LOOKUP;
if (is_output_feature)
iph_offset1 = vnet_buffer (b1)->ip.save_rewrite_length;
@@ -1134,6 +1148,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
b1->error =
node->errors[SNAT_IN2OUT_ERROR_UNSUPPORTED_PROTOCOL];
}
+ other_packets++;
goto trace01;
}
@@ -1142,6 +1157,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
next1 = icmp_in2out_slow_path
(sm, b1, ip1, icmp1, sw_if_index1, rx_fib_index1, node,
next1, now, thread_index, &s1);
+ icmp_packets++;
goto trace01;
}
}
@@ -1156,6 +1172,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
if (ip4_is_fragment (ip1))
{
next1 = SNAT_IN2OUT_NEXT_REASS;
+ fragments++;
goto trace01;
}
@@ -1248,12 +1265,14 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
length /* changed member */ );
mss_clamping (sm, tcp1, &sum1);
tcp1->checksum = ip_csum_fold (sum1);
+ tcp_packets++;
}
else
{
old_port1 = udp1->src_port;
udp1->src_port = s1->out2in.port;
udp1->checksum = 0;
+ udp_packets++;
}
/* Accounting */
@@ -1277,7 +1296,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
s1 - sm->per_thread_data[thread_index].sessions;
}
- pkts_processed += next1 != SNAT_IN2OUT_NEXT_DROP;
+ pkts_processed += next1 == SNAT_IN2OUT_NEXT_LOOKUP;
/* verify speculative enqueues, maybe switch current next frame */
vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
@@ -1354,6 +1373,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
b0->error =
node->errors[SNAT_IN2OUT_ERROR_UNSUPPORTED_PROTOCOL];
}
+ other_packets++;
goto trace0;
}
@@ -1362,6 +1382,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
next0 = icmp_in2out_slow_path
(sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
next0, now, thread_index, &s0);
+ icmp_packets++;
goto trace0;
}
}
@@ -1376,6 +1397,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
if (ip4_is_fragment (ip0))
{
next0 = SNAT_IN2OUT_NEXT_REASS;
+ fragments++;
goto trace0;
}
@@ -1467,12 +1489,14 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
length /* changed member */ );
mss_clamping (sm, tcp0, &sum0);
tcp0->checksum = ip_csum_fold (sum0);
+ tcp_packets++;
}
else
{
old_port0 = udp0->src_port;
udp0->src_port = s0->out2in.port;
udp0->checksum = 0;
+ udp_packets++;
}
/* Accounting */
@@ -1497,7 +1521,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
s0 - sm->per_thread_data[thread_index].sessions;
}
- pkts_processed += next0 != SNAT_IN2OUT_NEXT_DROP;
+ pkts_processed += next0 == SNAT_IN2OUT_NEXT_LOOKUP;
/* verify speculative enqueue, maybe switch current next frame */
vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
@@ -1511,6 +1535,18 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
vlib_node_increment_counter (vm, stats_node_index,
SNAT_IN2OUT_ERROR_IN2OUT_PACKETS,
pkts_processed);
+ vlib_node_increment_counter (vm, stats_node_index,
+ SNAT_IN2OUT_ERROR_TCP_PACKETS, tcp_packets);
+ vlib_node_increment_counter (vm, stats_node_index,
+ SNAT_IN2OUT_ERROR_UDP_PACKETS, tcp_packets);
+ vlib_node_increment_counter (vm, stats_node_index,
+ SNAT_IN2OUT_ERROR_ICMP_PACKETS, icmp_packets);
+ vlib_node_increment_counter (vm, stats_node_index,
+ SNAT_IN2OUT_ERROR_OTHER_PACKETS,
+ other_packets);
+ vlib_node_increment_counter (vm, stats_node_index,
+ SNAT_IN2OUT_ERROR_FRAGMENTS, fragments);
+
return frame->n_vectors;
}
@@ -1669,7 +1705,7 @@ nat44_in2out_reass_node_fn (vlib_main_t * vm,
{
u32 n_left_from, *from, *to_next;
snat_in2out_next_t next_index;
- u32 pkts_processed = 0;
+ u32 pkts_processed = 0, cached_fragments = 0;
snat_main_t *sm = &snat_main;
f64 now = vlib_time_now (vm);
u32 thread_index = vm->thread_index;
@@ -1885,6 +1921,7 @@ nat44_in2out_reass_node_fn (vlib_main_t * vm,
{
n_left_to_next++;
to_next--;
+ cached_fragments++;
}
else
{
@@ -1922,8 +1959,11 @@ nat44_in2out_reass_node_fn (vlib_main_t * vm,
}
vlib_node_increment_counter (vm, nat44_in2out_reass_node.index,
- SNAT_IN2OUT_ERROR_IN2OUT_PACKETS,
+ SNAT_IN2OUT_ERROR_PROCESSED_FRAGMENTS,
pkts_processed);
+ vlib_node_increment_counter (vm, nat44_in2out_reass_node.index,
+ SNAT_IN2OUT_ERROR_CACHED_FRAGMENTS,
+ cached_fragments);
nat_send_all_to_node (vm, fragments_to_drop, node,
&node->errors[SNAT_IN2OUT_ERROR_DROP_FRAGMENT],
diff --git a/src/plugins/nat/in2out_ed.c b/src/plugins/nat/in2out_ed.c
index ab253e8206b..9a61af9dad9 100644
--- a/src/plugins/nat/in2out_ed.c
+++ b/src/plugins/nat/in2out_ed.c
@@ -30,16 +30,24 @@
#include <nat/nat_inlines.h>
#include <nat/nat_syslog.h>
-#define foreach_nat_in2out_ed_error \
-_(UNSUPPORTED_PROTOCOL, "Unsupported protocol") \
-_(IN2OUT_PACKETS, "Good in2out packets processed") \
-_(OUT_OF_PORTS, "Out of ports") \
+#define foreach_nat_in2out_ed_error \
+_(UNSUPPORTED_PROTOCOL, "unsupported protocol") \
+_(IN2OUT_PACKETS, "good in2out packets processed") \
+_(OUT_OF_PORTS, "out of ports") \
_(BAD_ICMP_TYPE, "unsupported ICMP type") \
-_(MAX_SESSIONS_EXCEEDED, "Maximum sessions exceeded") \
-_(DROP_FRAGMENT, "Drop fragment") \
-_(MAX_REASS, "Maximum reassemblies exceeded") \
-_(MAX_FRAG, "Maximum fragments per reassembly exceeded")\
-_(NON_SYN, "non-SYN packet try to create session")
+_(MAX_SESSIONS_EXCEEDED, "maximum sessions exceeded") \
+_(DROP_FRAGMENT, "drop fragment") \
+_(MAX_REASS, "maximum reassemblies exceeded") \
+_(MAX_FRAG, "maximum fragments per reassembly exceeded")\
+_(NON_SYN, "non-SYN packet try to create session") \
+_(TCP_PACKETS, "TCP packets") \
+_(UDP_PACKETS, "UDP packets") \
+_(ICMP_PACKETS, "ICMP packets") \
+_(OTHER_PACKETS, "other protocol packets") \
+_(FRAGMENTS, "fragments") \
+_(CACHED_FRAGMENTS, "cached fragments") \
+_(PROCESSED_FRAGMENTS, "processed fragments")
+
typedef enum
{
@@ -899,6 +907,8 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
f64 now = vlib_time_now (vm);
u32 thread_index = vm->thread_index;
snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
+ u32 tcp_packets = 0, udp_packets = 0, icmp_packets = 0, other_packets =
+ 0, fragments = 0;
stats_node_index = is_slow_path ? nat44_ed_in2out_slowpath_node.index :
nat44_ed_in2out_node.index;
@@ -993,6 +1003,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
node);
if (!s0)
next0 = NAT_IN2OUT_ED_NEXT_DROP;
+ other_packets++;
goto trace00;
}
@@ -1001,6 +1012,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
next0 = icmp_in2out_ed_slow_path
(sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
next0, now, thread_index, &s0);
+ icmp_packets++;
goto trace00;
}
}
@@ -1015,6 +1027,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
if (ip4_is_fragment (ip0))
{
next0 = NAT_IN2OUT_ED_NEXT_REASS;
+ fragments++;
goto trace00;
}
@@ -1120,6 +1133,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
}
mss_clamping (sm, tcp0, &sum0);
tcp0->checksum = ip_csum_fold (sum0);
+ tcp_packets++;
if (nat44_set_tcp_session_state_i2o
(sm, s0, tcp0, thread_index))
goto trace00;
@@ -1133,6 +1147,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
udp0->dst_port = s0->ext_host_port;
ip0->dst_address.as_u32 = s0->ext_host_addr.as_u32;
}
+ udp_packets++;
}
/* Accounting */
@@ -1156,7 +1171,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
t->session_index = s0 - tsm->sessions;
}
- pkts_processed += next0 != NAT_IN2OUT_ED_NEXT_DROP;
+ pkts_processed += next0 == NAT_IN2OUT_ED_NEXT_LOOKUP;
next1 = NAT_IN2OUT_ED_NEXT_LOOKUP;
@@ -1197,6 +1212,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
node);
if (!s1)
next1 = NAT_IN2OUT_ED_NEXT_DROP;
+ other_packets++;
goto trace01;
}
@@ -1205,6 +1221,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
next1 = icmp_in2out_ed_slow_path
(sm, b1, ip1, icmp1, sw_if_index1, rx_fib_index1, node,
next1, now, thread_index, &s1);
+ icmp_packets++;
goto trace01;
}
}
@@ -1219,6 +1236,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
if (ip4_is_fragment (ip1))
{
next1 = NAT_IN2OUT_ED_NEXT_REASS;
+ fragments++;
goto trace01;
}
@@ -1324,6 +1342,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
}
tcp1->checksum = ip_csum_fold (sum1);
mss_clamping (sm, tcp1, &sum1);
+ tcp_packets++;
if (nat44_set_tcp_session_state_i2o
(sm, s1, tcp1, thread_index))
goto trace01;
@@ -1337,6 +1356,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
udp1->dst_port = s1->ext_host_port;
ip1->dst_address.as_u32 = s1->ext_host_addr.as_u32;
}
+ udp_packets++;
}
/* Accounting */
@@ -1360,7 +1380,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
t->session_index = s1 - tsm->sessions;
}
- pkts_processed += next1 != NAT_IN2OUT_ED_NEXT_DROP;
+ pkts_processed += next1 == NAT_IN2OUT_ED_NEXT_LOOKUP;
/* verify speculative enqueues, maybe switch current next frame */
vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
@@ -1430,6 +1450,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
node);
if (!s0)
next0 = NAT_IN2OUT_ED_NEXT_DROP;
+ other_packets++;
goto trace0;
}
@@ -1438,6 +1459,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
next0 = icmp_in2out_ed_slow_path
(sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
next0, now, thread_index, &s0);
+ icmp_packets++;
goto trace0;
}
}
@@ -1452,6 +1474,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
if (ip4_is_fragment (ip0))
{
next0 = NAT_IN2OUT_ED_NEXT_REASS;
+ fragments++;
goto trace0;
}
@@ -1557,6 +1580,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
}
mss_clamping (sm, tcp0, &sum0);
tcp0->checksum = ip_csum_fold (sum0);
+ tcp_packets++;
if (nat44_set_tcp_session_state_i2o
(sm, s0, tcp0, thread_index))
goto trace0;
@@ -1570,6 +1594,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
udp0->dst_port = s0->ext_host_port;
ip0->dst_address.as_u32 = s0->ext_host_addr.as_u32;
}
+ udp_packets++;
}
/* Accounting */
@@ -1593,7 +1618,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
t->session_index = s0 - tsm->sessions;
}
- pkts_processed += next0 != NAT_IN2OUT_ED_NEXT_DROP;
+ pkts_processed += next0 == NAT_IN2OUT_ED_NEXT_LOOKUP;
/* verify speculative enqueue, maybe switch current next frame */
vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
@@ -1607,6 +1632,19 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
vlib_node_increment_counter (vm, stats_node_index,
NAT_IN2OUT_ED_ERROR_IN2OUT_PACKETS,
pkts_processed);
+ vlib_node_increment_counter (vm, stats_node_index,
+ NAT_IN2OUT_ED_ERROR_TCP_PACKETS, tcp_packets);
+ vlib_node_increment_counter (vm, stats_node_index,
+ NAT_IN2OUT_ED_ERROR_UDP_PACKETS, tcp_packets);
+ vlib_node_increment_counter (vm, stats_node_index,
+ NAT_IN2OUT_ED_ERROR_ICMP_PACKETS,
+ icmp_packets);
+ vlib_node_increment_counter (vm, stats_node_index,
+ NAT_IN2OUT_ED_ERROR_OTHER_PACKETS,
+ other_packets);
+ vlib_node_increment_counter (vm, stats_node_index,
+ NAT_IN2OUT_ED_ERROR_FRAGMENTS, fragments);
+
return frame->n_vectors;
}
@@ -1746,7 +1784,7 @@ nat44_ed_in2out_reass_node_fn_inline (vlib_main_t * vm,
{
u32 n_left_from, *from, *to_next;
nat_in2out_ed_next_t next_index;
- u32 pkts_processed = 0;
+ u32 pkts_processed = 0, cached_fragments = 0;
snat_main_t *sm = &snat_main;
f64 now = vlib_time_now (vm);
u32 thread_index = vm->thread_index;
@@ -2025,6 +2063,7 @@ nat44_ed_in2out_reass_node_fn_inline (vlib_main_t * vm,
{
n_left_to_next++;
to_next--;
+ cached_fragments++;
}
else
{
@@ -2062,8 +2101,11 @@ nat44_ed_in2out_reass_node_fn_inline (vlib_main_t * vm,
}
vlib_node_increment_counter (vm, nat44_ed_in2out_reass_node.index,
- NAT_IN2OUT_ED_ERROR_IN2OUT_PACKETS,
+ NAT_IN2OUT_ED_ERROR_PROCESSED_FRAGMENTS,
pkts_processed);
+ vlib_node_increment_counter (vm, nat44_ed_in2out_reass_node.index,
+ NAT_IN2OUT_ED_ERROR_CACHED_FRAGMENTS,
+ cached_fragments);
nat_send_all_to_node (vm, fragments_to_drop, node,
&node->errors[NAT_IN2OUT_ED_ERROR_DROP_FRAGMENT],
diff --git a/src/plugins/nat/nat44_classify.c b/src/plugins/nat/nat44_classify.c
index 8608fc532e2..8a417dcf5d9 100644
--- a/src/plugins/nat/nat44_classify.c
+++ b/src/plugins/nat/nat44_classify.c
@@ -31,7 +31,10 @@ vlib_node_registration_t nat44_handoff_classify_node;
#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
{
@@ -93,6 +96,7 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
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;
@@ -361,12 +365,18 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
{
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))
{
@@ -398,6 +408,13 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
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;
}
diff --git a/src/plugins/nat/nat44_handoff.c b/src/plugins/nat/nat44_handoff.c
index a49b8de658f..d7ab650a665 100644
--- a/src/plugins/nat/nat44_handoff.c
+++ b/src/plugins/nat/nat44_handoff.c
@@ -31,7 +31,9 @@ typedef struct
} nat44_handoff_trace_t;
#define foreach_nat44_handoff_error \
-_(CONGESTION_DROP, "congestion drop")
+_(CONGESTION_DROP, "congestion drop") \
+_(SAME_WORKER, "same worker") \
+_(DO_HANDOFF, "do handoff")
typedef enum
{
@@ -79,6 +81,8 @@ nat44_worker_handoff_fn_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
u16 thread_indices[VLIB_FRAME_SIZE], *ti;
u32 fq_index;
snat_get_worker_function_t *get_worker;
+ u32 thread_index = vm->thread_index;
+ u32 do_handoff = 0, same_worker = 0;
from = vlib_frame_vector_args (frame);
n_left_from = frame->n_vectors;
@@ -114,6 +118,11 @@ nat44_worker_handoff_fn_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
ip0 = vlib_buffer_get_current (b[0]);
ti[0] = get_worker (ip0, rx_fib_index0);
+ if (ti[0] != thread_index)
+ do_handoff++;
+ else
+ same_worker++;
+
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
&& (b[0]->flags & VLIB_BUFFER_IS_TRACED)))
{
@@ -136,6 +145,10 @@ nat44_worker_handoff_fn_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_node_increment_counter (vm, node->node_index,
NAT44_HANDOFF_ERROR_CONGESTION_DROP,
frame->n_vectors - n_enq);
+ vlib_node_increment_counter (vm, node->node_index,
+ NAT44_HANDOFF_ERROR_SAME_WORKER, same_worker);
+ vlib_node_increment_counter (vm, node->node_index,
+ NAT44_HANDOFF_ERROR_DO_HANDOFF, do_handoff);
return frame->n_vectors;
}
diff --git a/src/plugins/nat/nat64_in2out.c b/src/plugins/nat/nat64_in2out.c
index 0652f4481bc..372931c7e4b 100644
--- a/src/plugins/nat/nat64_in2out.c
+++ b/src/plugins/nat/nat64_in2out.c
@@ -80,9 +80,16 @@ _(UNSUPPORTED_PROTOCOL, "unsupported protocol") \
_(IN2OUT_PACKETS, "good in2out packets processed") \
_(NO_TRANSLATION, "no translation") \
_(UNKNOWN, "unknown") \
-_(DROP_FRAGMENT, "Drop fragment") \
-_(MAX_REASS, "Maximum reassemblies exceeded") \
-_(MAX_FRAG, "Maximum fragments per reassembly exceeded")
+_(DROP_FRAGMENT, "drop fragment") \
+_(MAX_REASS, "maximum reassemblies exceeded") \
+_(MAX_FRAG, "maximum fragments per reassembly exceeded") \
+_(TCP_PACKETS, "TCP packets") \
+_(UDP_PACKETS, "UDP packets") \
+_(ICMP_PACKETS, "ICMP packets") \
+_(OTHER_PACKETS, "other protocol packets") \
+_(FRAGMENTS, "fragments") \
+_(CACHED_FRAGMENTS, "cached fragments") \
+_(PROCESSED_FRAGMENTS, "processed fragments")
typedef enum
@@ -928,6 +935,8 @@ nat64_in2out_node_fn_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
u32 pkts_processed = 0;
u32 stats_node_index;
u32 thread_index = vm->thread_index;
+ u32 tcp_packets = 0, udp_packets = 0, icmp_packets = 0, other_packets =
+ 0, fragments = 0;
stats_node_index =
is_slow_path ? nat64_in2out_slowpath_node.index : nat64_in2out_node.index;
@@ -995,6 +1004,7 @@ nat64_in2out_node_fn_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
{
if (PREDICT_TRUE (proto0 == ~0))
{
+ other_packets++;
if (is_hairpinning (&ip60->dst_address))
{
next0 = NAT64_IN2OUT_NEXT_IP6_LOOKUP;
@@ -1031,11 +1041,13 @@ nat64_in2out_node_fn_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
(ip60->protocol == IP_PROTOCOL_IPV6_FRAGMENTATION))
{
next0 = NAT64_IN2OUT_NEXT_REASS;
+ fragments++;
goto trace0;
}
if (proto0 == SNAT_PROTOCOL_ICMP)
{
+ icmp_packets++;
if (is_hairpinning (&ip60->dst_address))
{
next0 = NAT64_IN2OUT_NEXT_IP6_LOOKUP;
@@ -1060,6 +1072,11 @@ nat64_in2out_node_fn_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
}
else if (proto0 == SNAT_PROTOCOL_TCP || proto0 == SNAT_PROTOCOL_UDP)
{
+ if (proto0 == SNAT_PROTOCOL_TCP)
+ tcp_packets++;
+ else
+ udp_packets++;
+
if (is_hairpinning (&ip60->dst_address))
{
next0 = NAT64_IN2OUT_NEXT_IP6_LOOKUP;
@@ -1093,7 +1110,7 @@ nat64_in2out_node_fn_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
t->is_slow_path = is_slow_path;
}
- pkts_processed += next0 != NAT64_IN2OUT_NEXT_DROP;
+ pkts_processed += next0 == NAT64_IN2OUT_NEXT_IP4_LOOKUP;
/* verify speculative enqueue, maybe switch current next frame */
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
@@ -1104,6 +1121,18 @@ nat64_in2out_node_fn_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_node_increment_counter (vm, stats_node_index,
NAT64_IN2OUT_ERROR_IN2OUT_PACKETS,
pkts_processed);
+ vlib_node_increment_counter (vm, stats_node_index,
+ NAT64_IN2OUT_ERROR_TCP_PACKETS, tcp_packets);
+ vlib_node_increment_counter (vm, stats_node_index,
+ NAT64_IN2OUT_ERROR_UDP_PACKETS, tcp_packets);
+ vlib_node_increment_counter (vm, stats_node_index,
+ NAT64_IN2OUT_ERROR_ICMP_PACKETS, icmp_packets);
+ vlib_node_increment_counter (vm, stats_node_index,
+ NAT64_IN2OUT_ERROR_OTHER_PACKETS,
+ other_packets);
+ vlib_node_increment_counter (vm, stats_node_index,
+ NAT64_IN2OUT_ERROR_FRAGMENTS, fragments);
+
return frame->n_vectors;
}
@@ -1321,7 +1350,7 @@ nat64_in2out_reass_node_fn (vlib_main_t * vm,
{
u32 n_left_from, *from, *to_next;
nat64_in2out_next_t next_index;
- u32 pkts_processed = 0;
+ u32 pkts_processed = 0, cached_fragments = 0;
u32 *fragments_to_drop = 0;
u32 *fragments_to_loopback = 0;
nat64_main_t *nm = &nat64_main;
@@ -1542,6 +1571,7 @@ nat64_in2out_reass_node_fn (vlib_main_t * vm,
{
n_left_to_next++;
to_next--;
+ cached_fragments++;
}
else
{
@@ -1579,8 +1609,11 @@ nat64_in2out_reass_node_fn (vlib_main_t * vm,
}
vlib_node_increment_counter (vm, nat64_in2out_reass_node.index,
- NAT64_IN2OUT_ERROR_IN2OUT_PACKETS,
+ NAT64_IN2OUT_ERROR_PROCESSED_FRAGMENTS,
pkts_processed);
+ vlib_node_increment_counter (vm, nat64_in2out_reass_node.index,
+ NAT64_IN2OUT_ERROR_CACHED_FRAGMENTS,
+ cached_fragments);
nat_send_all_to_node (vm, fragments_to_drop, node,
&node->errors[NAT64_IN2OUT_ERROR_DROP_FRAGMENT],
@@ -1616,7 +1649,9 @@ VLIB_NODE_FUNCTION_MULTIARCH (nat64_in2out_reass_node,
nat64_in2out_reass_node_fn);
#define foreach_nat64_in2out_handoff_error \
-_(CONGESTION_DROP, "congestion drop")
+_(CONGESTION_DROP, "congestion drop") \
+_(SAME_WORKER, "same worker") \
+_(DO_HANDOFF, "do handoff")
typedef enum
{
@@ -1660,6 +1695,8 @@ nat64_in2out_handoff_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
u32 n_enq, n_left_from, *from;
u16 thread_indices[VLIB_FRAME_SIZE], *ti;
u32 fq_index;
+ u32 thread_index = vm->thread_index;
+ u32 do_handoff = 0, same_worker = 0;
from = vlib_frame_vector_args (frame);
n_left_from = frame->n_vectors;
@@ -1677,6 +1714,11 @@ nat64_in2out_handoff_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
ip0 = vlib_buffer_get_current (b[0]);
ti[0] = nat64_get_worker_in2out (&ip0->src_address);
+ if (ti[0] != thread_index)
+ do_handoff++;
+ else
+ same_worker++;
+
if (PREDICT_FALSE
((node->flags & VLIB_NODE_FLAG_TRACE)
&& (b[0]->flags & VLIB_BUFFER_IS_TRACED)))
@@ -1699,6 +1741,13 @@ nat64_in2out_handoff_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_node_increment_counter (vm, node->node_index,
NAT64_IN2OUT_HANDOFF_ERROR_CONGESTION_DROP,
frame->n_vectors - n_enq);
+ vlib_node_increment_counter (vm, node->node_index,
+ NAT64_IN2OUT_HANDOFF_ERROR_SAME_WORKER,
+ same_worker);
+ vlib_node_increment_counter (vm, node->node_index,
+ NAT64_IN2OUT_HANDOFF_ERROR_DO_HANDOFF,
+ do_handoff);
+
return frame->n_vectors;
}
diff --git a/src/plugins/nat/nat64_out2in.c b/src/plugins/nat/nat64_out2in.c
index 1c8df8a16db..ba35de1e2a1 100644
--- a/src/plugins/nat/nat64_out2in.c
+++ b/src/plugins/nat/nat64_out2in.c
@@ -72,13 +72,20 @@ vlib_node_registration_t nat64_out2in_reass_node;
vlib_node_registration_t nat64_out2in_handoff_node;
#define foreach_nat64_out2in_error \
-_(UNSUPPORTED_PROTOCOL, "Unsupported protocol") \
-_(OUT2IN_PACKETS, "Good out2in packets processed") \
-_(NO_TRANSLATION, "No translation") \
+_(UNSUPPORTED_PROTOCOL, "unsupported protocol") \
+_(OUT2IN_PACKETS, "good out2in packets processed") \
+_(NO_TRANSLATION, "no translation") \
_(UNKNOWN, "unknown") \
-_(DROP_FRAGMENT, "Drop fragment") \
-_(MAX_REASS, "Maximum reassemblies exceeded") \
-_(MAX_FRAG, "Maximum fragments per reassembly exceeded")
+_(DROP_FRAGMENT, "drop fragment") \
+_(MAX_REASS, "maximum reassemblies exceeded") \
+_(MAX_FRAG, "maximum fragments per reassembly exceeded") \
+_(TCP_PACKETS, "TCP packets") \
+_(UDP_PACKETS, "UDP packets") \
+_(ICMP_PACKETS, "ICMP packets") \
+_(OTHER_PACKETS, "other protocol packets") \
+_(FRAGMENTS, "fragments") \
+_(CACHED_FRAGMENTS, "cached fragments") \
+_(PROCESSED_FRAGMENTS, "processed fragments")
typedef enum
@@ -413,6 +420,8 @@ nat64_out2in_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
nat64_out2in_next_t next_index;
u32 pkts_processed = 0;
u32 thread_index = vm->thread_index;
+ u32 tcp_packets = 0, udp_packets = 0, icmp_packets = 0, other_packets =
+ 0, fragments = 0;
from = vlib_frame_vector_args (frame);
n_left_from = frame->n_vectors;
@@ -459,17 +468,20 @@ nat64_out2in_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
next0 = NAT64_OUT2IN_NEXT_DROP;
b0->error = node->errors[NAT64_OUT2IN_ERROR_NO_TRANSLATION];
}
+ other_packets++;
goto trace0;
}
if (PREDICT_FALSE (ip4_is_fragment (ip40)))
{
next0 = NAT64_OUT2IN_NEXT_REASS;
+ fragments++;
goto trace0;
}
if (proto0 == SNAT_PROTOCOL_ICMP)
{
+ icmp_packets++;
if (icmp_to_icmp6
(b0, nat64_out2in_icmp_set_cb, &ctx0,
nat64_out2in_inner_icmp_set_cb, &ctx0))
@@ -481,6 +493,11 @@ nat64_out2in_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
}
else
{
+ if (proto0 == SNAT_PROTOCOL_TCP)
+ tcp_packets++;
+ else
+ udp_packets++;
+
if (ip4_to_ip6_tcp_udp (b0, nat64_out2in_tcp_udp_set_cb, &ctx0))
{
udp0 = ip4_next_header (ip40);
@@ -511,7 +528,7 @@ nat64_out2in_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
t->next_index = next0;
}
- pkts_processed += next0 != NAT64_OUT2IN_NEXT_DROP;
+ pkts_processed += next0 == NAT64_OUT2IN_NEXT_IP6_LOOKUP;
/* verify speculative enqueue, maybe switch current next frame */
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
@@ -522,6 +539,18 @@ nat64_out2in_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_node_increment_counter (vm, nat64_out2in_node.index,
NAT64_OUT2IN_ERROR_OUT2IN_PACKETS,
pkts_processed);
+ vlib_node_increment_counter (vm, nat64_out2in_node.index,
+ NAT64_OUT2IN_ERROR_TCP_PACKETS, tcp_packets);
+ vlib_node_increment_counter (vm, nat64_out2in_node.index,
+ NAT64_OUT2IN_ERROR_UDP_PACKETS, tcp_packets);
+ vlib_node_increment_counter (vm, nat64_out2in_node.index,
+ NAT64_OUT2IN_ERROR_ICMP_PACKETS, icmp_packets);
+ vlib_node_increment_counter (vm, nat64_out2in_node.index,
+ NAT64_OUT2IN_ERROR_OTHER_PACKETS,
+ other_packets);
+ vlib_node_increment_counter (vm, nat64_out2in_node.index,
+ NAT64_OUT2IN_ERROR_FRAGMENTS, fragments);
+
return frame->n_vectors;
}
@@ -651,7 +680,7 @@ nat64_out2in_reass_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
{
u32 n_left_from, *from, *to_next;
nat64_out2in_next_t next_index;
- u32 pkts_processed = 0;
+ u32 pkts_processed = 0, cached_fragments = 0;
u32 *fragments_to_drop = 0;
u32 *fragments_to_loopback = 0;
nat64_main_t *nm = &nat64_main;
@@ -825,6 +854,7 @@ nat64_out2in_reass_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
{
n_left_to_next++;
to_next--;
+ cached_fragments++;
}
else
{
@@ -862,8 +892,11 @@ nat64_out2in_reass_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
}
vlib_node_increment_counter (vm, nat64_out2in_reass_node.index,
- NAT64_OUT2IN_ERROR_OUT2IN_PACKETS,
+ NAT64_OUT2IN_ERROR_PROCESSED_FRAGMENTS,
pkts_processed);
+ vlib_node_increment_counter (vm, nat64_out2in_reass_node.index,
+ NAT64_OUT2IN_ERROR_CACHED_FRAGMENTS,
+ cached_fragments);
nat_send_all_to_node (vm, fragments_to_drop, node,
&node->errors[NAT64_OUT2IN_ERROR_DROP_FRAGMENT],
@@ -898,7 +931,9 @@ VLIB_NODE_FUNCTION_MULTIARCH (nat64_out2in_reass_node,
nat64_out2in_reass_node_fn);
#define foreach_nat64_out2in_handoff_error \
-_(CONGESTION_DROP, "congestion drop")
+_(CONGESTION_DROP, "congestion drop") \
+_(SAME_WORKER, "same worker") \
+_(DO_HANDOFF, "do handoff")
typedef enum
{
@@ -942,6 +977,8 @@ nat64_out2in_handoff_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
u32 n_enq, n_left_from, *from;
u16 thread_indices[VLIB_FRAME_SIZE], *ti;
u32 fq_index;
+ u32 thread_index = vm->thread_index;
+ u32 do_handoff = 0, same_worker = 0;
from = vlib_frame_vector_args (frame);
n_left_from = frame->n_vectors;
@@ -959,6 +996,11 @@ nat64_out2in_handoff_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
ip0 = vlib_buffer_get_current (b[0]);
ti[0] = nat64_get_worker_out2in (ip0);
+ if (ti[0] != thread_index)
+ do_handoff++;
+ else
+ same_worker++;
+
if (PREDICT_FALSE
((node->flags & VLIB_NODE_FLAG_TRACE)
&& (b[0]->flags & VLIB_BUFFER_IS_TRACED)))
@@ -981,6 +1023,13 @@ nat64_out2in_handoff_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_node_increment_counter (vm, node->node_index,
NAT64_OUT2IN_HANDOFF_ERROR_CONGESTION_DROP,
frame->n_vectors - n_enq);
+ vlib_node_increment_counter (vm, node->node_index,
+ NAT64_OUT2IN_HANDOFF_ERROR_SAME_WORKER,
+ same_worker);
+ vlib_node_increment_counter (vm, node->node_index,
+ NAT64_OUT2IN_HANDOFF_ERROR_DO_HANDOFF,
+ do_handoff);
+
return frame->n_vectors;
}
diff --git a/src/plugins/nat/out2in.c b/src/plugins/nat/out2in.c
index 74d20888f57..18595e9f0ad 100755
--- a/src/plugins/nat/out2in.c
+++ b/src/plugins/nat/out2in.c
@@ -74,15 +74,22 @@ vlib_node_registration_t snat_out2in_fast_node;
vlib_node_registration_t nat44_out2in_reass_node;
#define foreach_snat_out2in_error \
-_(UNSUPPORTED_PROTOCOL, "Unsupported protocol") \
-_(OUT2IN_PACKETS, "Good out2in packets processed") \
-_(OUT_OF_PORTS, "Out of ports") \
+_(UNSUPPORTED_PROTOCOL, "unsupported protocol") \
+_(OUT2IN_PACKETS, "good out2in packets processed") \
+_(OUT_OF_PORTS, "out of ports") \
_(BAD_ICMP_TYPE, "unsupported ICMP type") \
-_(NO_TRANSLATION, "No translation") \
-_(MAX_SESSIONS_EXCEEDED, "Maximum sessions exceeded") \
-_(DROP_FRAGMENT, "Drop fragment") \
-_(MAX_REASS, "Maximum reassemblies exceeded") \
-_(MAX_FRAG, "Maximum fragments per reassembly exceeded")
+_(NO_TRANSLATION, "no translation") \
+_(MAX_SESSIONS_EXCEEDED, "maximum sessions exceeded") \
+_(DROP_FRAGMENT, "drop fragment") \
+_(MAX_REASS, "maximum reassemblies exceeded") \
+_(MAX_FRAG, "maximum fragments per reassembly exceeded")\
+_(TCP_PACKETS, "TCP packets") \
+_(UDP_PACKETS, "UDP packets") \
+_(ICMP_PACKETS, "ICMP packets") \
+_(OTHER_PACKETS, "other protocol packets") \
+_(FRAGMENTS, "fragments") \
+_(CACHED_FRAGMENTS, "cached fragments") \
+_(PROCESSED_FRAGMENTS, "processed fragments")
typedef enum
{
@@ -689,6 +696,8 @@ snat_out2in_node_fn (vlib_main_t * vm,
snat_main_t *sm = &snat_main;
f64 now = vlib_time_now (vm);
u32 thread_index = vm->thread_index;
+ u32 tcp_packets = 0, udp_packets = 0, icmp_packets = 0, other_packets =
+ 0, fragments = 0;
from = vlib_frame_vector_args (frame);
n_left_from = frame->n_vectors;
@@ -783,12 +792,14 @@ snat_out2in_node_fn (vlib_main_t * vm,
next0 = SNAT_OUT2IN_NEXT_DROP;
}
}
+ other_packets++;
goto trace0;
}
if (PREDICT_FALSE (ip4_is_fragment (ip0)))
{
next0 = SNAT_OUT2IN_NEXT_REASS;
+ fragments++;
goto trace0;
}
@@ -797,6 +808,7 @@ snat_out2in_node_fn (vlib_main_t * vm,
next0 = icmp_out2in_slow_path
(sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
next0, now, thread_index, &s0);
+ icmp_packets++;
goto trace0;
}
@@ -880,12 +892,14 @@ snat_out2in_node_fn (vlib_main_t * vm,
ip4_header_t /* cheat */ ,
length /* changed member */ );
tcp0->checksum = ip_csum_fold (sum0);
+ tcp_packets++;
}
else
{
old_port0 = udp0->dst_port;
udp0->dst_port = s0->in2out.port;
udp0->checksum = 0;
+ udp_packets++;
}
/* Accounting */
@@ -909,7 +923,7 @@ snat_out2in_node_fn (vlib_main_t * vm,
s0 - sm->per_thread_data[thread_index].sessions;
}
- pkts_processed += next0 != SNAT_OUT2IN_NEXT_DROP;
+ pkts_processed += next0 == SNAT_OUT2IN_NEXT_LOOKUP;
ip1 = vlib_buffer_get_current (b1);
@@ -944,12 +958,14 @@ snat_out2in_node_fn (vlib_main_t * vm,
next1 = SNAT_OUT2IN_NEXT_DROP;
}
}
+ other_packets++;
goto trace1;
}
if (PREDICT_FALSE (ip4_is_fragment (ip1)))
{
next1 = SNAT_OUT2IN_NEXT_REASS;
+ fragments++;
goto trace1;
}
@@ -958,6 +974,7 @@ snat_out2in_node_fn (vlib_main_t * vm,
next1 = icmp_out2in_slow_path
(sm, b1, ip1, icmp1, sw_if_index1, rx_fib_index1, node,
next1, now, thread_index, &s1);
+ icmp_packets++;
goto trace1;
}
@@ -1041,12 +1058,14 @@ snat_out2in_node_fn (vlib_main_t * vm,
ip4_header_t /* cheat */ ,
length /* changed member */ );
tcp1->checksum = ip_csum_fold (sum1);
+ tcp_packets++;
}
else
{
old_port1 = udp1->dst_port;
udp1->dst_port = s1->in2out.port;
udp1->checksum = 0;
+ udp_packets++;
}
/* Accounting */
@@ -1070,7 +1089,7 @@ snat_out2in_node_fn (vlib_main_t * vm,
s1 - sm->per_thread_data[thread_index].sessions;
}
- pkts_processed += next1 != SNAT_OUT2IN_NEXT_DROP;
+ pkts_processed += next1 == SNAT_OUT2IN_NEXT_LOOKUP;
/* verify speculative enqueues, maybe switch current next frame */
vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
@@ -1132,6 +1151,7 @@ snat_out2in_node_fn (vlib_main_t * vm,
next0 = SNAT_OUT2IN_NEXT_DROP;
}
}
+ other_packets++;
goto trace00;
}
@@ -1148,6 +1168,7 @@ snat_out2in_node_fn (vlib_main_t * vm,
if (PREDICT_FALSE (ip4_is_fragment (ip0)))
{
next0 = SNAT_OUT2IN_NEXT_REASS;
+ fragments++;
goto trace00;
}
@@ -1156,6 +1177,7 @@ snat_out2in_node_fn (vlib_main_t * vm,
next0 = icmp_out2in_slow_path
(sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
next0, now, thread_index, &s0);
+ icmp_packets++;
goto trace00;
}
@@ -1239,12 +1261,14 @@ snat_out2in_node_fn (vlib_main_t * vm,
ip4_header_t /* cheat */ ,
length /* changed member */ );
tcp0->checksum = ip_csum_fold (sum0);
+ tcp_packets++;
}
else
{
old_port0 = udp0->dst_port;
udp0->dst_port = s0->in2out.port;
udp0->checksum = 0;
+ udp_packets++;
}
/* Accounting */
@@ -1268,7 +1292,7 @@ snat_out2in_node_fn (vlib_main_t * vm,
s0 - sm->per_thread_data[thread_index].sessions;
}
- pkts_processed += next0 != SNAT_OUT2IN_NEXT_DROP;
+ pkts_processed += next0 == SNAT_OUT2IN_NEXT_LOOKUP;
/* verify speculative enqueue, maybe switch current next frame */
vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
@@ -1282,6 +1306,18 @@ snat_out2in_node_fn (vlib_main_t * vm,
vlib_node_increment_counter (vm, snat_out2in_node.index,
SNAT_OUT2IN_ERROR_OUT2IN_PACKETS,
pkts_processed);
+ vlib_node_increment_counter (vm, snat_out2in_node.index,
+ SNAT_OUT2IN_ERROR_TCP_PACKETS, tcp_packets);
+ vlib_node_increment_counter (vm, snat_out2in_node.index,
+ SNAT_OUT2IN_ERROR_UDP_PACKETS, udp_packets);
+ vlib_node_increment_counter (vm, snat_out2in_node.index,
+ SNAT_OUT2IN_ERROR_ICMP_PACKETS, icmp_packets);
+ vlib_node_increment_counter (vm, snat_out2in_node.index,
+ SNAT_OUT2IN_ERROR_OTHER_PACKETS,
+ other_packets);
+ vlib_node_increment_counter (vm, snat_out2in_node.index,
+ SNAT_OUT2IN_ERROR_FRAGMENTS, fragments);
+
return frame->n_vectors;
}
@@ -1318,7 +1354,7 @@ nat44_out2in_reass_node_fn (vlib_main_t * vm,
{
u32 n_left_from, *from, *to_next;
snat_out2in_next_t next_index;
- u32 pkts_processed = 0;
+ u32 pkts_processed = 0, cached_fragments = 0;
snat_main_t *sm = &snat_main;
f64 now = vlib_time_now (vm);
u32 thread_index = vm->thread_index;
@@ -1570,6 +1606,7 @@ nat44_out2in_reass_node_fn (vlib_main_t * vm,
{
n_left_to_next++;
to_next--;
+ cached_fragments++;
}
else
{
@@ -1607,8 +1644,11 @@ nat44_out2in_reass_node_fn (vlib_main_t * vm,
}
vlib_node_increment_counter (vm, nat44_out2in_reass_node.index,
- SNAT_OUT2IN_ERROR_OUT2IN_PACKETS,
+ SNAT_OUT2IN_ERROR_PROCESSED_FRAGMENTS,
pkts_processed);
+ vlib_node_increment_counter (vm, nat44_out2in_reass_node.index,
+ SNAT_OUT2IN_ERROR_CACHED_FRAGMENTS,
+ cached_fragments);
nat_send_all_to_node (vm, fragments_to_drop, node,
&node->errors[SNAT_OUT2IN_ERROR_DROP_FRAGMENT],
diff --git a/src/plugins/nat/out2in_ed.c b/src/plugins/nat/out2in_ed.c
index f76fc60bda0..c3f05592acc 100644
--- a/src/plugins/nat/out2in_ed.c
+++ b/src/plugins/nat/out2in_ed.c
@@ -32,16 +32,23 @@
#include <nat/nat_syslog.h>
#define foreach_nat_out2in_ed_error \
-_(UNSUPPORTED_PROTOCOL, "Unsupported protocol") \
-_(OUT2IN_PACKETS, "Good out2in packets processed") \
-_(OUT_OF_PORTS, "Out of ports") \
+_(UNSUPPORTED_PROTOCOL, "unsupported protocol") \
+_(OUT2IN_PACKETS, "good out2in packets processed") \
+_(OUT_OF_PORTS, "out of ports") \
_(BAD_ICMP_TYPE, "unsupported ICMP type") \
-_(NO_TRANSLATION, "No translation") \
-_(MAX_SESSIONS_EXCEEDED, "Maximum sessions exceeded") \
-_(DROP_FRAGMENT, "Drop fragment") \
-_(MAX_REASS, "Maximum reassemblies exceeded") \
-_(MAX_FRAG, "Maximum fragments per reassembly exceeded")\
-_(NON_SYN, "non-SYN packet try to create session")
+_(NO_TRANSLATION, "no translation") \
+_(MAX_SESSIONS_EXCEEDED, "maximum sessions exceeded") \
+_(DROP_FRAGMENT, "drop fragment") \
+_(MAX_REASS, "maximum reassemblies exceeded") \
+_(MAX_FRAG, "maximum fragments per reassembly exceeded")\
+_(NON_SYN, "non-SYN packet try to create session") \
+_(TCP_PACKETS, "TCP packets") \
+_(UDP_PACKETS, "UDP packets") \
+_(ICMP_PACKETS, "ICMP packets") \
+_(OTHER_PACKETS, "other protocol packets") \
+_(FRAGMENTS, "fragments") \
+_(CACHED_FRAGMENTS, "cached fragments") \
+_(PROCESSED_FRAGMENTS, "processed fragments")
typedef enum
{
@@ -712,6 +719,8 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
f64 now = vlib_time_now (vm);
u32 thread_index = vm->thread_index;
snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
+ u32 tcp_packets = 0, udp_packets = 0, icmp_packets = 0, other_packets =
+ 0, fragments = 0;
stats_node_index = is_slow_path ? nat44_ed_out2in_slowpath_node.index :
nat44_ed_out2in_node.index;
@@ -804,6 +813,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
nat44_ed_out2in_unknown_proto (sm, b0, ip0, rx_fib_index0,
thread_index, now, vm,
node);
+ other_packets++;
if (!sm->forwarding_enabled)
{
if (!s0)
@@ -817,6 +827,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
next0 = icmp_out2in_ed_slow_path
(sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
next0, now, thread_index, &s0);
+ icmp_packets++;
goto trace00;
}
}
@@ -831,6 +842,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
if (ip4_is_fragment (ip0))
{
next0 = NAT44_ED_OUT2IN_NEXT_REASS;
+ fragments++;
goto trace00;
}
@@ -963,6 +975,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
ip0->src_address.as_u32 = s0->ext_host_nat_addr.as_u32;
}
tcp0->checksum = ip_csum_fold (sum0);
+ tcp_packets++;
if (nat44_set_tcp_session_state_o2i
(sm, s0, tcp0, thread_index))
goto trace00;
@@ -976,6 +989,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
ip0->src_address.as_u32 = s0->ext_host_nat_addr.as_u32;
}
udp0->checksum = 0;
+ udp_packets++;
}
/* Accounting */
@@ -999,7 +1013,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
t->session_index = s0 - tsm->sessions;
}
- pkts_processed += next0 != NAT44_ED_OUT2IN_NEXT_DROP;
+ pkts_processed += next0 == NAT44_ED_OUT2IN_NEXT_LOOKUP;
next1 = NAT44_ED_OUT2IN_NEXT_LOOKUP;
vnet_buffer (b1)->snat.flags = 0;
@@ -1033,6 +1047,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
nat44_ed_out2in_unknown_proto (sm, b1, ip1, rx_fib_index1,
thread_index, now, vm,
node);
+ other_packets++;
if (!sm->forwarding_enabled)
{
if (!s1)
@@ -1046,6 +1061,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
next1 = icmp_out2in_ed_slow_path
(sm, b1, ip1, icmp1, sw_if_index1, rx_fib_index1, node,
next1, now, thread_index, &s1);
+ icmp_packets++;
goto trace01;
}
}
@@ -1060,6 +1076,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
if (ip4_is_fragment (ip1))
{
next1 = NAT44_ED_OUT2IN_NEXT_REASS;
+ fragments++;
goto trace01;
}
@@ -1192,6 +1209,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
ip1->src_address.as_u32 = s1->ext_host_nat_addr.as_u32;
}
tcp1->checksum = ip_csum_fold (sum1);
+ tcp_packets++;
if (nat44_set_tcp_session_state_o2i
(sm, s1, tcp1, thread_index))
goto trace01;
@@ -1205,6 +1223,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
ip1->src_address.as_u32 = s1->ext_host_nat_addr.as_u32;
}
udp1->checksum = 0;
+ udp_packets++;
}
/* Accounting */
@@ -1228,7 +1247,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
t->session_index = s1 - tsm->sessions;
}
- pkts_processed += next1 != NAT44_ED_OUT2IN_NEXT_DROP;
+ pkts_processed += next1 == NAT44_ED_OUT2IN_NEXT_LOOKUP;
/* verify speculative enqueues, maybe switch current next frame */
vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
@@ -1296,6 +1315,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
nat44_ed_out2in_unknown_proto (sm, b0, ip0, rx_fib_index0,
thread_index, now, vm,
node);
+ other_packets++;
if (!sm->forwarding_enabled)
{
if (!s0)
@@ -1309,6 +1329,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
next0 = icmp_out2in_ed_slow_path
(sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
next0, now, thread_index, &s0);
+ icmp_packets++;
goto trace0;
}
}
@@ -1323,6 +1344,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
if (ip4_is_fragment (ip0))
{
next0 = NAT44_ED_OUT2IN_NEXT_REASS;
+ fragments++;
goto trace0;
}
@@ -1455,6 +1477,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
ip0->src_address.as_u32 = s0->ext_host_nat_addr.as_u32;
}
tcp0->checksum = ip_csum_fold (sum0);
+ tcp_packets++;
if (nat44_set_tcp_session_state_o2i
(sm, s0, tcp0, thread_index))
goto trace0;
@@ -1468,6 +1491,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
ip0->src_address.as_u32 = s0->ext_host_nat_addr.as_u32;
}
udp0->checksum = 0;
+ udp_packets++;
}
/* Accounting */
@@ -1491,7 +1515,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
t->session_index = s0 - tsm->sessions;
}
- pkts_processed += next0 != NAT44_ED_OUT2IN_NEXT_DROP;
+ pkts_processed += next0 == NAT44_ED_OUT2IN_NEXT_LOOKUP;
/* verify speculative enqueue, maybe switch current next frame */
vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
to_next, n_left_to_next,
@@ -1504,6 +1528,18 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
vlib_node_increment_counter (vm, stats_node_index,
NAT_OUT2IN_ED_ERROR_OUT2IN_PACKETS,
pkts_processed);
+ vlib_node_increment_counter (vm, stats_node_index,
+ NAT_OUT2IN_ED_ERROR_TCP_PACKETS, tcp_packets);
+ vlib_node_increment_counter (vm, stats_node_index,
+ NAT_OUT2IN_ED_ERROR_UDP_PACKETS, udp_packets);
+ vlib_node_increment_counter (vm, stats_node_index,
+ NAT_OUT2IN_ED_ERROR_ICMP_PACKETS,
+ icmp_packets);
+ vlib_node_increment_counter (vm, stats_node_index,
+ NAT_OUT2IN_ED_ERROR_OTHER_PACKETS,
+ other_packets);
+ vlib_node_increment_counter (vm, stats_node_index,
+ NAT_OUT2IN_ED_ERROR_FRAGMENTS, fragments);
return frame->n_vectors;
}
diff --git a/test/test_nat.py b/test/test_nat.py
index b873074eccc..a7ca6d3a6e0 100644
--- a/test/test_nat.py
+++ b/test/test_nat.py
@@ -1507,13 +1507,21 @@ class TestNAT44(MethodHolder):
def test_dynamic(self):
""" NAT44 dynamic translation test """
-
self.nat44_add_address(self.nat_addr)
self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
is_inside=0)
# in2out
+ tcpn = self.statistics.get_counter(
+ '/err/nat44-in2out-slowpath/TCP packets')
+ udpn = self.statistics.get_counter(
+ '/err/nat44-in2out-slowpath/UDP packets')
+ icmpn = self.statistics.get_counter(
+ '/err/nat44-in2out-slowpath/ICMP packets')
+ totaln = self.statistics.get_counter(
+ '/err/nat44-in2out-slowpath/good in2out packets processed')
+
pkts = self.create_stream_in(self.pg0, self.pg1)
self.pg0.add_stream(pkts)
self.pg_enable_capture(self.pg_interfaces)
@@ -1521,7 +1529,26 @@ class TestNAT44(MethodHolder):
capture = self.pg1.get_capture(len(pkts))
self.verify_capture_out(capture)
+ err = self.statistics.get_counter(
+ '/err/nat44-in2out-slowpath/TCP packets')
+ self.assertEqual(err - tcpn, 1)
+ err = self.statistics.get_counter(
+ '/err/nat44-in2out-slowpath/UDP packets')
+ self.assertEqual(err - udpn, 1)
+ err = self.statistics.get_counter(
+ '/err/nat44-in2out-slowpath/ICMP packets')
+ self.assertEqual(err - icmpn, 1)
+ err = self.statistics.get_counter(
+ '/err/nat44-in2out-slowpath/good in2out packets processed')
+ self.assertEqual(err - totaln, 3)
+
# out2in
+ tcpn = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
+ udpn = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
+ icmpn = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
+ totaln = self.statistics.get_counter(
+ '/err/nat44-out2in/good out2in packets processed')
+
pkts = self.create_stream_out(self.pg1)
self.pg1.add_stream(pkts)
self.pg_enable_capture(self.pg_interfaces)
@@ -1529,6 +1556,16 @@ class TestNAT44(MethodHolder):
capture = self.pg0.get_capture(len(pkts))
self.verify_capture_in(capture, self.pg0)
+ err = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
+ self.assertEqual(err - tcpn, 1)
+ err = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
+ self.assertEqual(err - udpn, 1)
+ err = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
+ self.assertEqual(err - icmpn, 1)
+ err = self.statistics.get_counter(
+ '/err/nat44-out2in/good out2in packets processed')
+ self.assertEqual(err - totaln, 3)
+
def test_dynamic_icmp_errors_in2out_ttl_1(self):
""" NAT44 handling of client packets with TTL=1 """
@@ -3356,6 +3393,11 @@ class TestNAT44(MethodHolder):
self.logger.error(ppp("Unexpected or invalid packet:", p))
raise
+ err = self.statistics.get_counter('/err/nat44-classify/next in2out')
+ self.assertEqual(err, 1)
+ err = self.statistics.get_counter('/err/nat44-classify/next out2in')
+ self.assertEqual(err, 1)
+
def test_del_session(self):
""" Delete NAT44 session """
self.nat44_add_address(self.nat_addr)
@@ -4008,6 +4050,15 @@ class TestNAT44EndpointDependent(MethodHolder):
self.assertEqual(1, nat_config.endpoint_dependent)
# in2out
+ tcpn = self.statistics.get_counter(
+ '/err/nat44-ed-in2out-slowpath/TCP packets')
+ udpn = self.statistics.get_counter(
+ '/err/nat44-ed-in2out-slowpath/UDP packets')
+ icmpn = self.statistics.get_counter(
+ '/err/nat44-ed-in2out-slowpath/ICMP packets')
+ totaln = self.statistics.get_counter(
+ '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
+
pkts = self.create_stream_in(self.pg0, self.pg1)
self.pg0.add_stream(pkts)
self.pg_enable_capture(self.pg_interfaces)
@@ -4015,7 +4066,27 @@ class TestNAT44EndpointDependent(MethodHolder):
capture = self.pg1.get_capture(len(pkts))
self.verify_capture_out(capture)
+ err = self.statistics.get_counter(
+ '/err/nat44-ed-in2out-slowpath/TCP packets')
+ self.assertEqual(err - tcpn, 1)
+ err = self.statistics.get_counter(
+ '/err/nat44-ed-in2out-slowpath/UDP packets')
+ self.assertEqual(err - udpn, 1)
+ err = self.statistics.get_counter(
+ '/err/nat44-ed-in2out-slowpath/ICMP packets')
+ self.assertEqual(err - icmpn, 1)
+ err = self.statistics.get_counter(
+ '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
+ self.assertEqual(err - totaln, 3)
+
# out2in
+ tcpn = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
+ udpn = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
+ icmpn = self.statistics.get_counter(
+ '/err/nat44-ed-out2in-slowpath/ICMP packets')
+ totaln = self.statistics.get_counter(
+ '/err/nat44-ed-out2in/good out2in packets processed')
+
pkts = self.create_stream_out(self.pg1)
self.pg1.add_stream(pkts)
self.pg_enable_capture(self.pg_interfaces)
@@ -4023,6 +4094,17 @@ class TestNAT44EndpointDependent(MethodHolder):
capture = self.pg0.get_capture(len(pkts))
self.verify_capture_in(capture, self.pg0)
+ err = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
+ self.assertEqual(err - tcpn, 1)
+ err = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
+ self.assertEqual(err - udpn, 1)
+ err = self.statistics.get_counter(
+ '/err/nat44-ed-out2in-slowpath/ICMP packets')
+ self.assertEqual(err - icmpn, 1)
+ err = self.statistics.get_counter(
+ '/err/nat44-ed-out2in/good out2in packets processed')
+ self.assertEqual(err - totaln, 2)
+
def test_forwarding(self):
""" NAT44 forwarding test """
@@ -6840,6 +6922,12 @@ class TestNAT64(MethodHolder):
self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
# in2out
+ tcpn = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
+ udpn = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
+ icmpn = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
+ totaln = self.statistics.get_counter(
+ '/err/nat64-in2out/good in2out packets processed')
+
pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
self.pg0.add_stream(pkts)
self.pg_enable_capture(self.pg_interfaces)
@@ -6848,7 +6936,23 @@ class TestNAT64(MethodHolder):
self.verify_capture_out(capture, nat_ip=self.nat_addr,
dst_ip=self.pg1.remote_ip4)
+ err = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
+ self.assertEqual(err - tcpn, 1)
+ err = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
+ self.assertEqual(err - udpn, 1)
+ err = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
+ self.assertEqual(err - icmpn, 1)
+ err = self.statistics.get_counter(
+ '/err/nat64-in2out/good in2out packets processed')
+ self.assertEqual(err - totaln, 3)
+
# out2in
+ tcpn = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
+ udpn = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
+ icmpn = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
+ totaln = self.statistics.get_counter(
+ '/err/nat64-out2in/good out2in packets processed')
+
pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
self.pg1.add_stream(pkts)
self.pg_enable_capture(self.pg_interfaces)
@@ -6857,6 +6961,16 @@ class TestNAT64(MethodHolder):
ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
+ err = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
+ self.assertEqual(err - tcpn, 1)
+ err = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
+ self.assertEqual(err - udpn, 1)
+ err = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
+ self.assertEqual(err - icmpn, 1)
+ err = self.statistics.get_counter(
+ '/err/nat64-out2in/good out2in packets processed')
+ self.assertEqual(err - totaln, 3)
+
# in2out
pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
self.pg0.add_stream(pkts)