From 418abe2a259bc8c04c3b8839099204d56ae504ba Mon Sep 17 00:00:00 2001 From: Nathan Skrzypczak Date: Fri, 5 Mar 2021 17:16:40 +0100 Subject: [PATCH] cnat: maglev fixes This fixes cnat_feature node LB - use siblings instead of direct next_nodes - only do the lookup if we have NO_NAT - fix behavior in v6 Type: fix Change-Id: Ie80c9912946bf55c30eadeb51340f4aec9bb297e Signed-off-by: Nathan Skrzypczak --- src/plugins/cnat/cnat_node_feature.c | 38 ++++++++++++++++++------------------ src/plugins/cnat/cnat_translation.h | 5 ----- src/plugins/cnat/cnat_types.c | 26 +++++++++++++++++------- src/plugins/cnat/cnat_types.h | 9 +++++++++ 4 files changed, 47 insertions(+), 31 deletions(-) diff --git a/src/plugins/cnat/cnat_node_feature.c b/src/plugins/cnat/cnat_node_feature.c index 4585fcb5dd6..f9b6fa2a40d 100644 --- a/src/plugins/cnat/cnat_node_feature.c +++ b/src/plugins/cnat/cnat_node_feature.c @@ -126,19 +126,19 @@ cnat_input_feature_fn (vlib_main_t *vm, vlib_node_runtime_t *node, clib_host_to_net_u16 (trk0->ct_ep[VLIB_TX].ce_port); session->value.cs_port[VLIB_RX] = udp0->src_port; - const dpo_id_t *dpo0; - const load_balance_t *lb1; - fib_entry_t *fib_entry; - fib_entry = fib_entry_get (trk0->ct_fei); - - lb1 = load_balance_get (fib_entry->fe_lb /*[fct] */.dpoi_index); - dpo0 = load_balance_get_bucket_i (lb1, 0); + if (trk0->ct_flags & CNAT_TRK_FLAG_NO_NAT) + { + const dpo_id_t *dpo0; + const load_balance_t *lb1; - session->value.dpoi_next_node = dpo0->dpoi_next_node; - session->value.cs_lbi = dpo0->dpoi_index; + lb1 = load_balance_get (trk0->ct_dpo.dpoi_index); + /* Assume backend has exactly one item in LB */ + dpo0 = load_balance_get_bucket_i (lb1, 0); - if (trk0->ct_flags & CNAT_TRK_FLAG_NO_NAT) - session->value.flags |= CNAT_SESSION_FLAG_NO_NAT; + session->value.dpoi_next_node = dpo0->dpoi_next_node; + session->value.cs_lbi = dpo0->dpoi_index; + session->value.flags = CNAT_SESSION_FLAG_NO_NAT; + } /* refcnt session in current client */ cnat_client_cnt_session (cc); @@ -146,11 +146,13 @@ cnat_input_feature_fn (vlib_main_t *vm, vlib_node_runtime_t *node, trace_flags |= CNAT_TRACE_SESSION_CREATED; } - next0 = session->value.dpoi_next_node; - vnet_buffer (b)->ip.adj_index[VLIB_TX] = session->value.cs_lbi; - if (session->value.flags & CNAT_SESSION_FLAG_NO_NAT) - goto trace; + { + /* If we don't translate, directly do the lookup & bypass arc */ + next0 = session->value.dpoi_next_node; + vnet_buffer (b)->ip.adj_index[VLIB_TX] = session->value.cs_lbi; + goto trace; + } if (AF_IP4 == ctx->af) cnat_translation_ip4 (session, ip4, udp0); @@ -190,8 +192,7 @@ VLIB_REGISTER_NODE (cnat_input_feature_ip4_node) = { .type = VLIB_NODE_TYPE_INTERNAL, .n_errors = CNAT_N_ERROR, .error_strings = cnat_error_strings, - .n_next_nodes = IP_LOOKUP_N_NEXT, - .next_nodes = IP4_LOOKUP_NEXT_NODES, + .sibling_of = "ip4-lookup", }; VNET_FEATURE_INIT (cnat_in_ip4_feature, static) = { @@ -217,8 +218,7 @@ VLIB_REGISTER_NODE (cnat_input_feature_ip6_node) = { .type = VLIB_NODE_TYPE_INTERNAL, .n_errors = CNAT_N_ERROR, .error_strings = cnat_error_strings, - .n_next_nodes = IP6_LOOKUP_N_NEXT, - .next_nodes = IP6_LOOKUP_NEXT_NODES, + .sibling_of = "ip6-lookup", }; VNET_FEATURE_INIT (cnat_in_ip6_feature, static) = { diff --git a/src/plugins/cnat/cnat_translation.h b/src/plugins/cnat/cnat_translation.h index 3b6e694a845..97b0c908b42 100644 --- a/src/plugins/cnat/cnat_translation.h +++ b/src/plugins/cnat/cnat_translation.h @@ -25,11 +25,6 @@ */ extern vlib_combined_counter_main_t cnat_translation_counters; -typedef enum cnat_trk_flag_t_ -{ - CNAT_TRK_ACTIVE = (1 << 0), - CNAT_TRK_FLAG_NO_NAT = (1 << 1), -} cnat_trk_flag_t; /** * Data used to track an EP in the FIB diff --git a/src/plugins/cnat/cnat_types.c b/src/plugins/cnat/cnat_types.c index 837f40082c3..9b164c6069d 100644 --- a/src/plugins/cnat/cnat_types.c +++ b/src/plugins/cnat/cnat_types.c @@ -102,17 +102,29 @@ unformat_cnat_ep (unformat_input_t * input, va_list * args) return 1; } +uword +unformat_cnat_ep_flags (unformat_input_t *input, va_list *args) +{ + int *a = va_arg (*args, int *); + if (unformat (input, ":nonat")) + *a = CNAT_TRK_FLAG_NO_NAT; + return 1; +} + uword unformat_cnat_ep_tuple (unformat_input_t * input, va_list * args) { cnat_endpoint_tuple_t *a = va_arg (*args, cnat_endpoint_tuple_t *); - if (unformat (input, "%U->%U", unformat_cnat_ep, &a->src_ep, - unformat_cnat_ep, &a->dst_ep)) - ; - else if (unformat (input, "->%U", unformat_cnat_ep, &a->dst_ep)) - ; - else if (unformat (input, "%U->", unformat_cnat_ep, &a->src_ep)) - ; + int flgs = 0; + if (unformat (input, "%U->%U%U", unformat_cnat_ep, &a->src_ep, + unformat_cnat_ep, &a->dst_ep, unformat_cnat_ep_flags, &flgs)) + a->ep_flags = flgs; + else if (unformat (input, "->%U%U", unformat_cnat_ep, &a->dst_ep, + unformat_cnat_ep_flags, &flgs)) + a->ep_flags = flgs; + else if (unformat (input, "%U->%U", unformat_cnat_ep, &a->src_ep, + unformat_cnat_ep_flags, &flgs)) + a->ep_flags = flgs; else return 0; return 1; diff --git a/src/plugins/cnat/cnat_types.h b/src/plugins/cnat/cnat_types.h index 47e34e1f232..c3ec74c345f 100644 --- a/src/plugins/cnat/cnat_types.h +++ b/src/plugins/cnat/cnat_types.h @@ -55,6 +55,15 @@ #define MIN_SRC_PORT ((u16) 0xC000) +typedef enum cnat_trk_flag_t_ +{ + /* Endpoint is active (static or dhcp resolved) */ + CNAT_TRK_ACTIVE = (1 << 0), + /* Don't translate this endpoint, but still + * forward. Used by maglev for DSR */ + CNAT_TRK_FLAG_NO_NAT = (1 << 1), +} cnat_trk_flag_t; + typedef enum { /* Endpoint addr has been resolved */ -- 2.16.6