diff options
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/nat/in2out.c | 11 | ||||
-rw-r--r-- | src/plugins/nat/nat.h | 6 | ||||
-rw-r--r-- | src/plugins/nat/nat44_hairpinning.c | 82 |
3 files changed, 84 insertions, 15 deletions
diff --git a/src/plugins/nat/in2out.c b/src/plugins/nat/in2out.c index 980a638f059..8616d90ad2b 100644 --- a/src/plugins/nat/in2out.c +++ b/src/plugins/nat/in2out.c @@ -43,6 +43,7 @@ typedef struct u32 next_index; u32 session_index; u32 is_slow_path; + u32 is_hairpinning; } snat_in2out_trace_t; /* packet trace format function */ @@ -58,6 +59,10 @@ format_snat_in2out_trace (u8 * s, va_list * args) s = format (s, "%s: sw_if_index %d, next index %d, session %d", tag, t->sw_if_index, t->next_index, t->session_index); + if (t->is_hairpinning) + { + s = format (s, ", with-hairpinning"); + } return s; } @@ -1776,6 +1781,7 @@ VLIB_NODE_FN (snat_in2out_fast_node) (vlib_main_t * vm, u32 pkts_processed = 0; snat_main_t *sm = &snat_main; u32 stats_node_index; + int is_hairpinning = 0; stats_node_index = sm->in2out_fast_node_index; @@ -1923,7 +1929,9 @@ VLIB_NODE_FN (snat_in2out_fast_node) (vlib_main_t * vm, } /* Hairpinning */ - snat_hairpinning (sm, b0, ip0, udp0, tcp0, proto0, 0); + snat_hairpinning (vm, node, sm, b0, ip0, udp0, tcp0, proto0, 0, + 0 /* do_trace */ ); + is_hairpinning = 1; trace0: if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) @@ -1933,6 +1941,7 @@ VLIB_NODE_FN (snat_in2out_fast_node) (vlib_main_t * vm, vlib_add_trace (vm, node, b0, sizeof (*t)); t->sw_if_index = sw_if_index0; t->next_index = next0; + t->is_hairpinning = is_hairpinning; } pkts_processed += next0 != SNAT_IN2OUT_NEXT_DROP; diff --git a/src/plugins/nat/nat.h b/src/plugins/nat/nat.h index de2353889da..fbf2105dea3 100644 --- a/src/plugins/nat/nat.h +++ b/src/plugins/nat/nat.h @@ -1069,9 +1069,11 @@ void nat_hairpinning_sm_unknown_proto (snat_main_t * sm, vlib_buffer_t * b, ip4_header_t * ip); void nat44_ed_hairpinning_unknown_proto (snat_main_t * sm, vlib_buffer_t * b, ip4_header_t * ip); -int snat_hairpinning (snat_main_t * sm, vlib_buffer_t * b0, +int snat_hairpinning (vlib_main_t * vm, vlib_node_runtime_t * node, + snat_main_t * sm, vlib_buffer_t * b0, ip4_header_t * ip0, udp_header_t * udp0, - tcp_header_t * tcp0, u32 proto0, int is_ed); + tcp_header_t * tcp0, u32 proto0, int is_ed, + int do_trace); /* Call back functions for clib_bihash_add_or_overwrite_stale */ int nat44_i2o_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg); diff --git a/src/plugins/nat/nat44_hairpinning.c b/src/plugins/nat/nat44_hairpinning.c index 02cdfb12380..21e2eee188b 100644 --- a/src/plugins/nat/nat44_hairpinning.c +++ b/src/plugins/nat/nat44_hairpinning.c @@ -56,6 +56,36 @@ static char *nat44_hairpin_error_strings[] = { #undef _ }; +typedef struct +{ + ip4_address_t addr; + u16 port; + u32 fib_index; + u32 session_index; +} nat_hairpin_trace_t; + +static u8 * +format_nat_hairpin_trace (u8 * s, va_list * args) +{ + CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); + CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); + nat_hairpin_trace_t *t = va_arg (*args, nat_hairpin_trace_t *); + + s = + format (s, "new dst addr %U port %u fib-index %u", format_ip4_address, + &t->addr, clib_net_to_host_u16 (t->port), t->fib_index); + if (~0 == t->session_index) + { + s = format (s, " is-static-mapping"); + } + else + { + s = format (s, " session-index %u", t->session_index); + } + + return s; +} + extern vnet_feature_arc_registration_t vnet_feat_arc_ip4_local; static_always_inline int @@ -86,18 +116,17 @@ is_hairpinning (snat_main_t * sm, ip4_address_t * dst_addr) #ifndef CLIB_MARCH_VARIANT int -snat_hairpinning (snat_main_t * sm, - vlib_buffer_t * b0, - ip4_header_t * ip0, - udp_header_t * udp0, - tcp_header_t * tcp0, u32 proto0, int is_ed) +snat_hairpinning (vlib_main_t * vm, vlib_node_runtime_t * node, + snat_main_t * sm, vlib_buffer_t * b0, ip4_header_t * ip0, + udp_header_t * udp0, tcp_header_t * tcp0, u32 proto0, + int is_ed, int do_trace) { snat_session_key_t key0, sm0; snat_session_t *s0; clib_bihash_kv_8_8_t kv0, value0; ip_csum_t sum0; - u32 new_dst_addr0 = 0, old_dst_addr0, ti = 0, si; - u16 new_dst_port0, old_dst_port0; + u32 new_dst_addr0 = 0, old_dst_addr0, ti = 0, si = ~0; + u16 new_dst_port0 = ~0, old_dst_port0; int rv; key0.addr = ip0->dst_address; @@ -140,7 +169,10 @@ snat_hairpinning (snat_main_t * sm, si = value0.value; } if (rv) - return 0; + { + rv = 0; + goto trace; + } s0 = pool_elt_at_index (sm->per_thread_data[ti].sessions, si); new_dst_addr0 = s0->in2out.addr.as_u32; @@ -187,9 +219,28 @@ snat_hairpinning (snat_main_t * sm, tcp0->checksum = ip_csum_fold (sum0); } } - return 1; + rv = 1; + goto trace; } - return 0; + rv = 0; +trace: + if (do_trace && PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) + && (b0->flags & VLIB_BUFFER_IS_TRACED))) + { + nat_hairpin_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t)); + t->addr.as_u32 = new_dst_addr0; + t->port = new_dst_port0; + t->fib_index = vnet_buffer (b0)->sw_if_index[VLIB_TX]; + if (s0) + { + t->session_index = si; + } + else + { + t->session_index = ~0; + } + } + return rv; } #endif @@ -479,7 +530,9 @@ nat44_hairpinning_fn_inline (vlib_main_t * vm, vnet_get_config_data (&cm->config_main, &b0->current_config_index, &next0, 0); - if (snat_hairpinning (sm, b0, ip0, udp0, tcp0, proto0, is_ed)) + if (snat_hairpinning + (vm, node, sm, b0, ip0, udp0, tcp0, proto0, is_ed, + 1 /* do_trace */ )) next0 = NAT_HAIRPIN_NEXT_LOOKUP; pkts_processed += next0 != NAT_HAIRPIN_NEXT_DROP; @@ -511,6 +564,7 @@ VLIB_REGISTER_NODE (nat44_hairpinning_node) = { .vector_size = sizeof (u32), .type = VLIB_NODE_TYPE_INTERNAL, .n_errors = ARRAY_LEN(nat44_hairpin_error_strings), + .format_trace = format_nat_hairpin_trace, .error_strings = nat44_hairpin_error_strings, .n_next_nodes = NAT_HAIRPIN_N_NEXT, .next_nodes = { @@ -534,6 +588,7 @@ VLIB_REGISTER_NODE (nat44_ed_hairpinning_node) = { .type = VLIB_NODE_TYPE_INTERNAL, .n_errors = ARRAY_LEN(nat44_hairpin_error_strings), .error_strings = nat44_hairpin_error_strings, + .format_trace = format_nat_hairpin_trace, .n_next_nodes = NAT_HAIRPIN_N_NEXT, .next_nodes = { [NAT_HAIRPIN_NEXT_DROP] = "error-drop", @@ -595,7 +650,8 @@ snat_hairpin_dst_fn_inline (vlib_main_t * vm, udp_header_t *udp0 = ip4_next_header (ip0); tcp_header_t *tcp0 = (tcp_header_t *) udp0; - snat_hairpinning (sm, b0, ip0, udp0, tcp0, proto0, is_ed); + snat_hairpinning (vm, node, sm, b0, ip0, udp0, tcp0, proto0, + is_ed, 1 /* do_trace */ ); } else if (proto0 == NAT_PROTOCOL_ICMP) { @@ -643,6 +699,7 @@ VLIB_REGISTER_NODE (snat_hairpin_dst_node) = { .vector_size = sizeof (u32), .type = VLIB_NODE_TYPE_INTERNAL, .n_errors = ARRAY_LEN(nat44_hairpin_error_strings), + .format_trace = format_nat_hairpin_trace, .error_strings = nat44_hairpin_error_strings, .n_next_nodes = NAT_HAIRPIN_N_NEXT, .next_nodes = { @@ -665,6 +722,7 @@ VLIB_REGISTER_NODE (nat44_ed_hairpin_dst_node) = { .vector_size = sizeof (u32), .type = VLIB_NODE_TYPE_INTERNAL, .n_errors = ARRAY_LEN(nat44_hairpin_error_strings), + .format_trace = format_nat_hairpin_trace, .error_strings = nat44_hairpin_error_strings, .n_next_nodes = NAT_HAIRPIN_N_NEXT, .next_nodes = { |