X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fvxlan-gbp%2Fdecap.c;h=23995c49fcbd1f1c1ab56afcf458a3dd5bcda935;hb=317b8e08367c769b90463613231b9fcfad486098;hp=613cb0123199e1f22748e9443e14db3a51e35b1e;hpb=5ecbbc128999813fcb6ee9025541b01ae87b824a;p=vpp.git diff --git a/src/vnet/vxlan-gbp/decap.c b/src/vnet/vxlan-gbp/decap.c index 613cb012319..23995c49fcb 100644 --- a/src/vnet/vxlan-gbp/decap.c +++ b/src/vnet/vxlan-gbp/decap.c @@ -16,11 +16,8 @@ */ #include -#include -#include -vlib_node_registration_t vxlan4_gbp_input_node; -vlib_node_registration_t vxlan6_gbp_input_node; +#include typedef struct { @@ -70,46 +67,47 @@ typedef vxlan4_gbp_tunnel_key_t last_tunnel_cache4; always_inline vxlan_gbp_tunnel_t * vxlan4_gbp_find_tunnel (vxlan_gbp_main_t * vxm, last_tunnel_cache4 * cache, u32 fib_index, ip4_header_t * ip4_0, - vxlan_gbp_header_t * vxlan_gbp0, - vxlan_gbp_tunnel_t ** stats_t0) + vxlan_gbp_header_t * vxlan_gbp0) { - /* Make sure VXLAN_GBP tunnel exist according to packet SIP and VNI */ + /* + * Check unicast first since that's where most of the traffic comes from + * Make sure VXLAN_GBP tunnel exist according to packet SIP, DIP and VNI + */ vxlan4_gbp_tunnel_key_t key4; + int rv; + key4.key[1] = ((u64) fib_index << 32) | vxlan_gbp0->vni_reserved; + key4.key[0] = (((u64) ip4_0->dst_address.as_u32 << 32) | + ip4_0->src_address.as_u32); - if (PREDICT_FALSE (key4.key[1] != cache->key[1] || - ip4_0->src_address.as_u32 != (u32) cache->key[0])) + if (PREDICT_FALSE (key4.key[0] != cache->key[0] || + key4.key[1] != cache->key[1])) { - key4.key[0] = ip4_0->src_address.as_u32; - int rv = clib_bihash_search_inline_16_8 (&vxm->vxlan4_gbp_tunnel_by_key, - &key4); - if (PREDICT_FALSE (rv != 0)) - return 0; - - *cache = key4; + rv = clib_bihash_search_inline_16_8 (&vxm->vxlan4_gbp_tunnel_by_key, + &key4); + if (PREDICT_FALSE (rv == 0)) + { + *cache = key4; + return (pool_elt_at_index (vxm->tunnels, cache->value)); + } } - vxlan_gbp_tunnel_t *t0 = pool_elt_at_index (vxm->tunnels, cache->value); - - /* Validate VXLAN_GBP tunnel SIP against packet DIP */ - if (PREDICT_TRUE (ip4_0->dst_address.as_u32 == t0->src.ip4.as_u32)) - *stats_t0 = t0; else { - /* try multicast */ - if (PREDICT_TRUE (!ip4_address_is_multicast (&ip4_0->dst_address))) - return 0; + return (pool_elt_at_index (vxm->tunnels, cache->value)); + } - key4.key[0] = ip4_0->dst_address.as_u32; - /* Make sure mcast VXLAN_GBP tunnel exist by packet DIP and VNI */ - int rv = clib_bihash_search_inline_16_8 (&vxm->vxlan4_gbp_tunnel_by_key, - &key4); - if (PREDICT_FALSE (rv != 0)) - return 0; + /* No unicast match - try multicast */ + if (PREDICT_TRUE (!ip4_address_is_multicast (&ip4_0->dst_address))) + return (NULL); - *stats_t0 = pool_elt_at_index (vxm->tunnels, key4.value); - } + key4.key[0] = ip4_0->dst_address.as_u32; + /* Make sure mcast VXLAN_GBP tunnel exist by packet DIP and VNI */ + rv = clib_bihash_search_inline_16_8 (&vxm->vxlan4_gbp_tunnel_by_key, &key4); - return t0; + if (PREDICT_FALSE (rv != 0)) + return (NULL); + + return (pool_elt_at_index (vxm->tunnels, key4.value)); } typedef vxlan6_gbp_tunnel_key_t last_tunnel_cache6; @@ -117,8 +115,7 @@ typedef vxlan6_gbp_tunnel_key_t last_tunnel_cache6; always_inline vxlan_gbp_tunnel_t * vxlan6_gbp_find_tunnel (vxlan_gbp_main_t * vxm, last_tunnel_cache6 * cache, u32 fib_index, ip6_header_t * ip6_0, - vxlan_gbp_header_t * vxlan_gbp0, - vxlan_gbp_tunnel_t ** stats_t0) + vxlan_gbp_header_t * vxlan_gbp0) { /* Make sure VXLAN_GBP tunnel exist according to packet SIP and VNI */ vxlan6_gbp_tunnel_key_t key6 = { @@ -128,23 +125,23 @@ vxlan6_gbp_find_tunnel (vxlan_gbp_main_t * vxm, last_tunnel_cache6 * cache, [2] = (((u64) fib_index) << 32) | vxlan_gbp0->vni_reserved, } }; + int rv; if (PREDICT_FALSE (clib_bihash_key_compare_24_8 (key6.key, cache->key) == 0)) { - int rv = clib_bihash_search_inline_24_8 (&vxm->vxlan6_gbp_tunnel_by_key, - &key6); + rv = clib_bihash_search_inline_24_8 (&vxm->vxlan6_gbp_tunnel_by_key, + &key6); if (PREDICT_FALSE (rv != 0)) - return 0; + return NULL; *cache = key6; } vxlan_gbp_tunnel_t *t0 = pool_elt_at_index (vxm->tunnels, cache->value); /* Validate VXLAN_GBP tunnel SIP against packet DIP */ - if (PREDICT_TRUE (ip6_address_is_equal (&ip6_0->dst_address, &t0->src.ip6))) - *stats_t0 = t0; - else + if (PREDICT_FALSE + (!ip6_address_is_equal (&ip6_0->dst_address, &t0->src.ip6))) { /* try multicast */ if (PREDICT_TRUE (!ip6_address_is_multicast (&ip6_0->dst_address))) @@ -153,12 +150,11 @@ vxlan6_gbp_find_tunnel (vxlan_gbp_main_t * vxm, last_tunnel_cache6 * cache, /* Make sure mcast VXLAN_GBP tunnel exist by packet DIP and VNI */ key6.key[0] = ip6_0->dst_address.as_u64[0]; key6.key[1] = ip6_0->dst_address.as_u64[1]; - int rv = clib_bihash_search_inline_24_8 (&vxm->vxlan6_gbp_tunnel_by_key, - &key6); + rv = clib_bihash_search_inline_24_8 (&vxm->vxlan6_gbp_tunnel_by_key, + &key6); if (PREDICT_FALSE (rv != 0)) return 0; - *stats_t0 = pool_elt_at_index (vxm->tunnels, key6.value); } return t0; @@ -269,25 +265,20 @@ vxlan_gbp_input (vlib_main_t * vm, u32 fi0 = buf_fib_index (b0, is_ip4); u32 fi1 = buf_fib_index (b1, is_ip4); - vxlan_gbp_tunnel_t *t0, *stats_t0 = 0; - vxlan_gbp_tunnel_t *t1, *stats_t1 = 0; + vxlan_gbp_tunnel_t *t0, *t1; if (is_ip4) { t0 = - vxlan4_gbp_find_tunnel (vxm, &last4, fi0, ip4_0, vxlan_gbp0, - &stats_t0); + vxlan4_gbp_find_tunnel (vxm, &last4, fi0, ip4_0, vxlan_gbp0); t1 = - vxlan4_gbp_find_tunnel (vxm, &last4, fi1, ip4_1, vxlan_gbp1, - &stats_t1); + vxlan4_gbp_find_tunnel (vxm, &last4, fi1, ip4_1, vxlan_gbp1); } else { t0 = - vxlan6_gbp_find_tunnel (vxm, &last6, fi0, ip6_0, vxlan_gbp0, - &stats_t0); + vxlan6_gbp_find_tunnel (vxm, &last6, fi0, ip6_0, vxlan_gbp0); t1 = - vxlan6_gbp_find_tunnel (vxm, &last6, fi1, ip6_1, vxlan_gbp1, - &stats_t1); + vxlan6_gbp_find_tunnel (vxm, &last6, fi1, ip6_1, vxlan_gbp1); } u32 len0 = vlib_buffer_length_in_chain (vm, b0); @@ -304,21 +295,27 @@ vxlan_gbp_input (vlib_main_t * vm, /* Validate VXLAN_GBP tunnel encap-fib index against packet */ if (PREDICT_FALSE - (t0 == 0 || flags0 != (VXLAN_GBP_FLAGS_I | VXLAN_GBP_FLAGS_G))) + (t0 == NULL + || flags0 != (VXLAN_GBP_FLAGS_I | VXLAN_GBP_FLAGS_G))) { - if (t0 != 0 + if (t0 != NULL && flags0 != (VXLAN_GBP_FLAGS_I | VXLAN_GBP_FLAGS_G)) { error0 = VXLAN_GBP_ERROR_BAD_FLAGS; vlib_increment_combined_counter - (drop_counter, thread_index, stats_t0->sw_if_index, 1, - len0); + (drop_counter, thread_index, t0->sw_if_index, 1, len0); next0 = VXLAN_GBP_INPUT_NEXT_DROP; } else { error0 = VXLAN_GBP_ERROR_NO_SUCH_TUNNEL; - next0 = VXLAN_GBP_INPUT_NEXT_NO_TUNNEL; + next0 = VXLAN_GBP_INPUT_NEXT_PUNT; + if (is_ip4) + b0->punt_reason = + vxm->punt_no_such_tunnel[FIB_PROTOCOL_IP4]; + else + b0->punt_reason = + vxm->punt_no_such_tunnel[FIB_PROTOCOL_IP6]; } b0->error = node->errors[error0]; } @@ -329,12 +326,13 @@ vxlan_gbp_input (vlib_main_t * vm, /* Set packet input sw_if_index to unicast VXLAN tunnel for learning */ vnet_buffer (b0)->sw_if_index[VLIB_RX] = t0->sw_if_index; vlib_increment_combined_counter - (rx_counter, thread_index, stats_t0->sw_if_index, 1, len0); + (rx_counter, thread_index, t0->sw_if_index, 1, len0); pkts_decapsulated++; } - vnet_buffer2 (b0)->gbp.flags = vxlan_gbp_get_gpflags (vxlan_gbp0); - vnet_buffer2 (b0)->gbp.src_epg = vxlan_gbp_get_sclass (vxlan_gbp0); + vnet_buffer2 (b0)->gbp.flags = (vxlan_gbp_get_gpflags (vxlan_gbp0) | + VXLAN_GBP_GPFLAGS_R); + vnet_buffer2 (b0)->gbp.sclass = vxlan_gbp_get_sclass (vxlan_gbp0); if (PREDICT_FALSE @@ -345,14 +343,19 @@ vxlan_gbp_input (vlib_main_t * vm, { error1 = VXLAN_GBP_ERROR_BAD_FLAGS; vlib_increment_combined_counter - (drop_counter, thread_index, stats_t1->sw_if_index, 1, - len1); + (drop_counter, thread_index, t1->sw_if_index, 1, len1); next1 = VXLAN_GBP_INPUT_NEXT_DROP; } else { error1 = VXLAN_GBP_ERROR_NO_SUCH_TUNNEL; - next1 = VXLAN_GBP_INPUT_NEXT_NO_TUNNEL; + next1 = VXLAN_GBP_INPUT_NEXT_PUNT; + if (is_ip4) + b1->punt_reason = + vxm->punt_no_such_tunnel[FIB_PROTOCOL_IP4]; + else + b1->punt_reason = + vxm->punt_no_such_tunnel[FIB_PROTOCOL_IP6]; } b1->error = node->errors[error1]; } @@ -365,11 +368,13 @@ vxlan_gbp_input (vlib_main_t * vm, pkts_decapsulated++; vlib_increment_combined_counter - (rx_counter, thread_index, stats_t1->sw_if_index, 1, len1); + (rx_counter, thread_index, t1->sw_if_index, 1, len1); } - vnet_buffer2 (b1)->gbp.flags = vxlan_gbp_get_gpflags (vxlan_gbp1); - vnet_buffer2 (b1)->gbp.src_epg = vxlan_gbp_get_sclass (vxlan_gbp1); + vnet_buffer2 (b1)->gbp.flags = (vxlan_gbp_get_gpflags (vxlan_gbp1) | + VXLAN_GBP_GPFLAGS_R); + + vnet_buffer2 (b1)->gbp.sclass = vxlan_gbp_get_sclass (vxlan_gbp1); vnet_update_l2_len (b0); vnet_update_l2_len (b1); @@ -424,15 +429,11 @@ vxlan_gbp_input (vlib_main_t * vm, u32 fi0 = buf_fib_index (b0, is_ip4); - vxlan_gbp_tunnel_t *t0, *stats_t0 = 0; + vxlan_gbp_tunnel_t *t0; if (is_ip4) - t0 = - vxlan4_gbp_find_tunnel (vxm, &last4, fi0, ip4_0, vxlan_gbp0, - &stats_t0); + t0 = vxlan4_gbp_find_tunnel (vxm, &last4, fi0, ip4_0, vxlan_gbp0); else - t0 = - vxlan6_gbp_find_tunnel (vxm, &last6, fi0, ip6_0, vxlan_gbp0, - &stats_t0); + t0 = vxlan6_gbp_find_tunnel (vxm, &last6, fi0, ip6_0, vxlan_gbp0); uword len0 = vlib_buffer_length_in_chain (vm, b0); @@ -444,21 +445,27 @@ vxlan_gbp_input (vlib_main_t * vm, vlib_buffer_advance (b0, sizeof (*vxlan_gbp0)); /* Validate VXLAN_GBP tunnel encap-fib index against packet */ if (PREDICT_FALSE - (t0 == 0 || flags0 != (VXLAN_GBP_FLAGS_I | VXLAN_GBP_FLAGS_G))) + (t0 == NULL + || flags0 != (VXLAN_GBP_FLAGS_I | VXLAN_GBP_FLAGS_G))) { - if (t0 != 0 + if (t0 != NULL && flags0 != (VXLAN_GBP_FLAGS_I | VXLAN_GBP_FLAGS_G)) { error0 = VXLAN_GBP_ERROR_BAD_FLAGS; vlib_increment_combined_counter - (drop_counter, thread_index, stats_t0->sw_if_index, 1, - len0); + (drop_counter, thread_index, t0->sw_if_index, 1, len0); next0 = VXLAN_GBP_INPUT_NEXT_DROP; } else { error0 = VXLAN_GBP_ERROR_NO_SUCH_TUNNEL; - next0 = VXLAN_GBP_INPUT_NEXT_NO_TUNNEL; + next0 = VXLAN_GBP_INPUT_NEXT_PUNT; + if (is_ip4) + b0->punt_reason = + vxm->punt_no_such_tunnel[FIB_PROTOCOL_IP4]; + else + b0->punt_reason = + vxm->punt_no_such_tunnel[FIB_PROTOCOL_IP6]; } b0->error = node->errors[error0]; } @@ -470,10 +477,12 @@ vxlan_gbp_input (vlib_main_t * vm, pkts_decapsulated++; vlib_increment_combined_counter - (rx_counter, thread_index, stats_t0->sw_if_index, 1, len0); + (rx_counter, thread_index, t0->sw_if_index, 1, len0); } - vnet_buffer2 (b0)->gbp.flags = vxlan_gbp_get_gpflags (vxlan_gbp0); - vnet_buffer2 (b0)->gbp.src_epg = vxlan_gbp_get_sclass (vxlan_gbp0); + vnet_buffer2 (b0)->gbp.flags = (vxlan_gbp_get_gpflags (vxlan_gbp0) | + VXLAN_GBP_GPFLAGS_R); + + vnet_buffer2 (b0)->gbp.sclass = vxlan_gbp_get_sclass (vxlan_gbp0); /* Required to make the l2 tag push / pop code work on l2 subifs */ vnet_update_l2_len (b0); @@ -505,16 +514,16 @@ vxlan_gbp_input (vlib_main_t * vm, return from_frame->n_vectors; } -static uword -vxlan4_gbp_input (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * from_frame) +VLIB_NODE_FN (vxlan4_gbp_input_node) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * from_frame) { return vxlan_gbp_input (vm, node, from_frame, /* is_ip4 */ 1); } -static uword -vxlan6_gbp_input (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * from_frame) +VLIB_NODE_FN (vxlan6_gbp_input_node) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * from_frame) { return vxlan_gbp_input (vm, node, from_frame, /* is_ip4 */ 0); } @@ -529,7 +538,6 @@ static char *vxlan_gbp_error_strings[] = { /* *INDENT-OFF* */ VLIB_REGISTER_NODE (vxlan4_gbp_input_node) = { - .function = vxlan4_gbp_input, .name = "vxlan4-gbp-input", .vector_size = sizeof (u32), .n_errors = VXLAN_GBP_N_ERROR, @@ -542,11 +550,9 @@ VLIB_REGISTER_NODE (vxlan4_gbp_input_node) = #undef _ }, }; -VLIB_NODE_FUNCTION_MULTIARCH (vxlan4_gbp_input_node, vxlan4_gbp_input) VLIB_REGISTER_NODE (vxlan6_gbp_input_node) = { - .function = vxlan6_gbp_input, .name = "vxlan6-gbp-input", .vector_size = sizeof (u32), .n_errors = VXLAN_GBP_N_ERROR, @@ -559,7 +565,6 @@ VLIB_REGISTER_NODE (vxlan6_gbp_input_node) = }, .format_trace = format_vxlan_gbp_rx_trace, }; -VLIB_NODE_FUNCTION_MULTIARCH (vxlan6_gbp_input_node, vxlan6_gbp_input) /* *INDENT-ON* */ typedef enum @@ -567,7 +572,7 @@ typedef enum IP_VXLAN_GBP_BYPASS_NEXT_DROP, IP_VXLAN_GBP_BYPASS_NEXT_VXLAN_GBP, IP_VXLAN_GBP_BYPASS_N_NEXT, -} ip_vxan_gbp_bypass_next_t; +} ip_vxlan_gbp_bypass_next_t; always_inline uword ip_vxlan_gbp_bypass_inline (vlib_main_t * vm, @@ -968,9 +973,9 @@ ip_vxlan_gbp_bypass_inline (vlib_main_t * vm, return frame->n_vectors; } -static uword -ip4_vxlan_gbp_bypass (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) +VLIB_NODE_FN (ip4_vxlan_gbp_bypass_node) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * frame) { return ip_vxlan_gbp_bypass_inline (vm, node, frame, /* is_ip4 */ 1); } @@ -978,7 +983,6 @@ ip4_vxlan_gbp_bypass (vlib_main_t * vm, /* *INDENT-OFF* */ VLIB_REGISTER_NODE (ip4_vxlan_gbp_bypass_node) = { - .function = ip4_vxlan_gbp_bypass, .name = "ip4-vxlan-gbp-bypass", .vector_size = sizeof (u32), .n_next_nodes = IP_VXLAN_GBP_BYPASS_N_NEXT, @@ -989,10 +993,9 @@ VLIB_REGISTER_NODE (ip4_vxlan_gbp_bypass_node) = .format_buffer = format_ip4_header, .format_trace = format_ip4_forward_next_trace, }; - -VLIB_NODE_FUNCTION_MULTIARCH (ip4_vxlan_gbp_bypass_node, ip4_vxlan_gbp_bypass) /* *INDENT-ON* */ +#ifndef CLIB_MARCH_VARIANT /* Dummy init function to get us linked in. */ clib_error_t * ip4_vxlan_gbp_bypass_init (vlib_main_t * vm) @@ -1001,10 +1004,11 @@ ip4_vxlan_gbp_bypass_init (vlib_main_t * vm) } VLIB_INIT_FUNCTION (ip4_vxlan_gbp_bypass_init); +#endif /* CLIB_MARCH_VARIANT */ -static uword -ip6_vxlan_gbp_bypass (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) +VLIB_NODE_FN (ip6_vxlan_gbp_bypass_node) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * frame) { return ip_vxlan_gbp_bypass_inline (vm, node, frame, /* is_ip4 */ 0); } @@ -1012,7 +1016,6 @@ ip6_vxlan_gbp_bypass (vlib_main_t * vm, /* *INDENT-OFF* */ VLIB_REGISTER_NODE (ip6_vxlan_gbp_bypass_node) = { - .function = ip6_vxlan_gbp_bypass, .name = "ip6-vxlan-gbp-bypass", .vector_size = sizeof (u32), .n_next_nodes = IP_VXLAN_GBP_BYPASS_N_NEXT, @@ -1023,10 +1026,9 @@ VLIB_REGISTER_NODE (ip6_vxlan_gbp_bypass_node) = .format_buffer = format_ip6_header, .format_trace = format_ip6_forward_next_trace, }; - -VLIB_NODE_FUNCTION_MULTIARCH (ip6_vxlan_gbp_bypass_node, ip6_vxlan_gbp_bypass) /* *INDENT-ON* */ +#ifndef CLIB_MARCH_VARIANT /* Dummy init function to get us linked in. */ clib_error_t * ip6_vxlan_gbp_bypass_init (vlib_main_t * vm) @@ -1035,6 +1037,7 @@ ip6_vxlan_gbp_bypass_init (vlib_main_t * vm) } VLIB_INIT_FUNCTION (ip6_vxlan_gbp_bypass_init); +#endif /* CLIB_MARCH_VARIANT */ /* * fd.io coding-style-patch-verification: ON