X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fcnat%2Fcnat_node_snat.c;h=9212d67ead6a5901530490e5062549b900ec15ff;hb=3fd77f7de;hp=aaa9e162ef0560048f6cd898e525a6e05983f180;hpb=ece39214bcb05c535ba5de9af97b5f84f6911cba;p=vpp.git diff --git a/src/plugins/cnat/cnat_node_snat.c b/src/plugins/cnat/cnat_node_snat.c index aaa9e162ef0..9212d67ead6 100644 --- a/src/plugins/cnat/cnat_node_snat.c +++ b/src/plugins/cnat/cnat_node_snat.c @@ -15,7 +15,9 @@ #include #include -#include +#include +#include +#include typedef enum cnat_snat_next_ { @@ -23,46 +25,27 @@ typedef enum cnat_snat_next_ CNAT_SNAT_N_NEXT, } cnat_snat_next_t; -typedef struct cnat_snat_trace_ -{ - u32 found; - cnat_session_t session; -} cnat_snat_trace_t; - vlib_node_registration_t cnat_snat_ip4_node; vlib_node_registration_t cnat_snat_ip6_node; -static u8 * -format_cnat_snat_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 *); - cnat_snat_trace_t *t = va_arg (*args, cnat_snat_trace_t *); - - if (t->found) - s = format (s, "found: %U", format_cnat_session, &t->session, 1); - else - s = format (s, "not found"); - return s; -} - /* CNat sub for source NAT as a feature arc on ip[46]-unicast This node's sub shouldn't apply to the same flows as cnat_vip_inline */ -always_inline uword -cnat_snat_inline (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_buffer_t * b, - cnat_node_ctx_t * ctx, int rv, cnat_session_t * session) +static uword +cnat_snat_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, + vlib_buffer_t *b, cnat_node_ctx_t *ctx, + int session_not_found, cnat_session_t *session) { - cnat_main_t *cm = &cnat_main; - ip4_header_t *ip4; + cnat_snat_policy_main_t *cpm = &cnat_snat_policy_main; + ip4_header_t *ip4 = NULL; ip_protocol_t iproto; - ip6_header_t *ip6; + ip6_header_t *ip6 = NULL; udp_header_t *udp0; u32 arc_next0; u16 next0; u16 sport; + u8 trace_flags = 0; + int rv, do_snat; if (AF_IP4 == ctx->af) { @@ -81,14 +64,11 @@ cnat_snat_inline (vlib_main_t * vm, vnet_feature_next (&arc_next0, b); next0 = arc_next0; - if (iproto != IP_PROTOCOL_UDP && iproto != IP_PROTOCOL_TCP - && iproto != IP_PROTOCOL_ICMP && iproto != IP_PROTOCOL_ICMP6) - { - /* Dont translate */ - goto trace; - } + /* Wrong session key */ + if (session->key.cs_proto == 0) + goto trace; - if (!rv) + if (!session_not_found) { /* session table hit */ cnat_timestamp_update (session->value.cs_ts_index, ctx->now); @@ -100,12 +80,11 @@ cnat_snat_inline (vlib_main_t * vm, ip46_address_set_ip4 (&ip46_dst_address, &ip4->dst_address); else ip46_address_set_ip6 (&ip46_dst_address, &ip6->dst_address); - rv = cnat_search_snat_prefix (&ip46_dst_address, ctx->af); - if (!rv) - { - /* Prefix table hit, we shouldn't source NAT */ - goto trace; - } + + do_snat = cpm->snat_policy (b, session); + if (!do_snat) + goto trace; + /* New flow, create the sessions if necessary. session will be a snat session, and rsession will be a dnat session Note: packet going through this path are going to the outside, @@ -113,23 +92,26 @@ cnat_snat_inline (vlib_main_t * vm, a VIP) */ if (AF_IP4 == ctx->af) { + if (!(cpm->snat_ip4.ce_flags & CNAT_EP_FLAG_RESOLVED)) + goto trace; ip46_address_set_ip4 (&session->value.cs_ip[VLIB_RX], - &cm->snat_ip4); + &ip_addr_v4 (&cpm->snat_ip4.ce_ip)); ip46_address_set_ip4 (&session->value.cs_ip[VLIB_TX], &ip4->dst_address); } else { + if (!(cpm->snat_ip6.ce_flags & CNAT_EP_FLAG_RESOLVED)) + goto trace; ip46_address_set_ip6 (&session->value.cs_ip[VLIB_RX], - &cm->snat_ip6); + &ip_addr_v6 (&cpm->snat_ip6.ce_ip)); ip46_address_set_ip6 (&session->value.cs_ip[VLIB_TX], &ip6->dst_address); } - /* Port allocation, first try to use the original port, allocate one - if it is already used */ - sport = udp0->src_port; - rv = cnat_allocate_port (cm, &sport); + + sport = 0; + rv = cnat_allocate_port (&sport, iproto); if (rv) { vlib_node_increment_counter (vm, cnat_snat_ip4_node.index, @@ -137,14 +119,18 @@ cnat_snat_inline (vlib_main_t * vm, next0 = CNAT_SNAT_NEXT_DROP; goto trace; } - session->value.cs_port[VLIB_RX] = sport; - session->value.cs_port[VLIB_TX] = udp0->dst_port; + session->value.cs_port[VLIB_TX] = sport; + if (iproto == IP_PROTOCOL_TCP || iproto == IP_PROTOCOL_UDP) + session->value.cs_port[VLIB_TX] = udp0->dst_port; + session->value.cs_lbi = INDEX_INVALID; session->value.flags = CNAT_SESSION_FLAG_NO_CLIENT | CNAT_SESSION_FLAG_ALLOC_PORT; + trace_flags |= CNAT_TRACE_SESSION_CREATED; - cnat_session_create (session, ctx, CNAT_SESSION_FLAG_HAS_SNAT); + cnat_session_create (session, ctx, CNAT_LOCATION_FIB, + CNAT_SESSION_FLAG_HAS_SNAT); } @@ -156,12 +142,8 @@ cnat_snat_inline (vlib_main_t * vm, trace: if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED)) { - cnat_snat_trace_t *t; - - t = vlib_add_trace (vm, node, b, sizeof (*t)); - - if (NULL != session) - clib_memcpy (&t->session, session, sizeof (t->session)); + trace_flags |= session_not_found ? 0 : CNAT_TRACE_SESSION_FOUND; + cnat_add_trace (vm, node, b, session, NULL, trace_flags); } return next0; } @@ -171,10 +153,10 @@ VLIB_NODE_FN (cnat_snat_ip4_node) (vlib_main_t * vm, vlib_frame_t * frame) { if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE))) - return cnat_node_inline (vm, node, frame, cnat_snat_inline, AF_IP4, - 1 /* do_trace */ ); - return cnat_node_inline (vm, node, frame, cnat_snat_inline, AF_IP4, - 0 /* do_trace */ ); + return cnat_node_inline (vm, node, frame, cnat_snat_node_fn, AF_IP4, + CNAT_LOCATION_FIB, 1 /* do_trace */); + return cnat_node_inline (vm, node, frame, cnat_snat_node_fn, AF_IP4, + CNAT_LOCATION_FIB, 0 /* do_trace */); } VLIB_NODE_FN (cnat_snat_ip6_node) (vlib_main_t * vm, @@ -182,52 +164,47 @@ VLIB_NODE_FN (cnat_snat_ip6_node) (vlib_main_t * vm, vlib_frame_t * frame) { if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE))) - return cnat_node_inline (vm, node, frame, cnat_snat_inline, AF_IP6, - 1 /* do_trace */ ); - return cnat_node_inline (vm, node, frame, cnat_snat_inline, AF_IP6, - 0 /* do_trace */ ); + return cnat_node_inline (vm, node, frame, cnat_snat_node_fn, AF_IP6, + CNAT_LOCATION_FIB, 1 /* do_trace */); + return cnat_node_inline (vm, node, frame, cnat_snat_node_fn, AF_IP6, + CNAT_LOCATION_FIB, 0 /* do_trace */); } -/* *INDENT-OFF* */ -VLIB_REGISTER_NODE (cnat_snat_ip4_node) = -{ - .name = "ip4-cnat-snat", +VLIB_REGISTER_NODE (cnat_snat_ip4_node) = { + .name = "cnat-snat-ip4", .vector_size = sizeof (u32), - .format_trace = format_cnat_snat_trace, + .format_trace = format_cnat_trace, .type = VLIB_NODE_TYPE_INTERNAL, .n_errors = CNAT_N_ERROR, .error_strings = cnat_error_strings, .n_next_nodes = CNAT_SNAT_N_NEXT, - .next_nodes = - { - [CNAT_SNAT_NEXT_DROP] = "ip4-drop", - } + .next_nodes = { + [CNAT_SNAT_NEXT_DROP] = "ip4-drop", + }, }; -VLIB_REGISTER_NODE (cnat_snat_ip6_node) = -{ - .name = "ip6-cnat-snat", +VLIB_REGISTER_NODE (cnat_snat_ip6_node) = { + .name = "cnat-snat-ip6", .vector_size = sizeof (u32), - .format_trace = format_cnat_snat_trace, + .format_trace = format_cnat_trace, .type = VLIB_NODE_TYPE_INTERNAL, .n_errors = CNAT_N_ERROR, .error_strings = cnat_error_strings, .n_next_nodes = CNAT_SNAT_N_NEXT, - .next_nodes = - { - [CNAT_SNAT_NEXT_DROP] = "ip6-drop", - } + .next_nodes = { + [CNAT_SNAT_NEXT_DROP] = "ip6-drop", + }, }; -/* *INDENT-ON* */ - -VNET_FEATURE_INIT (cnat_snat_ip4_node, static) = -{ -.arc_name = "ip4-unicast",.node_name = "ip4-cnat-snat",}; +VNET_FEATURE_INIT (cnat_snat_ip4_node, static) = { + .arc_name = "ip4-unicast", + .node_name = "cnat-snat-ip4", +}; -VNET_FEATURE_INIT (cnat_snat_ip6_node, static) = -{ -.arc_name = "ip6-unicast",.node_name = "ip6-cnat-snat",}; +VNET_FEATURE_INIT (cnat_snat_ip6_node, static) = { + .arc_name = "ip6-unicast", + .node_name = "cnat-snat-ip6", +}; /* * fd.io coding-style-patch-verification: ON