From: Matus Fabian Date: Fri, 14 Dec 2018 09:55:16 +0000 (-0800) Subject: NAT: counters (VPP-1484) X-Git-Tag: v19.04-rc0~166 X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commitdiff_plain;h=a5e73762d585e9fa405b56ebd9f5c78d12c4d1f9 NAT: counters (VPP-1484) Change-Id: I5d1852a09712adfe7547c200d161539736aca6f5 Signed-off-by: Matus Fabian --- 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 #include -#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 #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)