X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fdpo%2Freplicate_dpo.c;h=8c8206c4a0cae1ad24bb57a581a00d960677586a;hb=28c142e3;hp=a2d5fdb68bd90e6359d6018ad972c113f94b6386;hpb=32e1c010b0c34fd0984f7fc45fae648a182025c5;p=vpp.git diff --git a/src/vnet/dpo/replicate_dpo.c b/src/vnet/dpo/replicate_dpo.c index a2d5fdb68bd..8c8206c4a0c 100644 --- a/src/vnet/dpo/replicate_dpo.c +++ b/src/vnet/dpo/replicate_dpo.c @@ -17,6 +17,7 @@ #include #include #include +#include #undef REP_DEBUG @@ -34,6 +35,21 @@ #define REP_DBG(_p, _fmt, _args...) #endif +#define foreach_replicate_dpo_error \ +_(BUFFER_ALLOCATION_FAILURE, "Buffer Allocation Failure") + +typedef enum { +#define _(sym,str) REPLICATE_DPO_ERROR_##sym, + foreach_replicate_dpo_error +#undef _ + REPLICATE_DPO_N_ERROR, +} replicate_dpo_error_t; + +static char * replicate_dpo_error_strings[] = { +#define _(sym,string) string, + foreach_replicate_dpo_error +#undef _ +}; /** * Pool of all DPOs. It's not static so the DP can have fast access @@ -43,7 +59,12 @@ replicate_t *replicate_pool; /** * The one instance of replicate main */ -replicate_main_t replicate_main; +replicate_main_t replicate_main = { + .repm_counters = { + .name = "mroutes", + .stat_segment_name = "/net/mroute", + }, +}; static inline index_t replicate_get_index (const replicate_t *rep) @@ -91,6 +112,7 @@ replicate_format (index_t repi, dpo_id_t *buckets; u32 i; + repi &= ~MPLS_IS_REPLICATE; rep = replicate_get(repi); vlib_get_combined_counter(&(replicate_main.repm_counters), repi, &to); buckets = replicate_get_buckets(rep); @@ -172,6 +194,7 @@ replicate_set_bucket (index_t repi, replicate_t *rep; dpo_id_t *buckets; + repi &= ~MPLS_IS_REPLICATE; rep = replicate_get(repi); buckets = replicate_get_buckets(rep); @@ -184,11 +207,13 @@ int replicate_is_drop (const dpo_id_t *dpo) { replicate_t *rep; + index_t repi; if (DPO_REPLICATE != dpo->dpoi_type) return (0); - rep = replicate_get(dpo->dpoi_index); + repi = dpo->dpoi_index & ~MPLS_IS_REPLICATE; + rep = replicate_get(repi); if (1 == rep->rep_n_buckets) { @@ -203,6 +228,7 @@ replicate_get_bucket (index_t repi, { replicate_t *rep; + repi &= ~MPLS_IS_REPLICATE; rep = replicate_get(repi); return (replicate_get_bucket_i(rep, bucket)); @@ -240,7 +266,7 @@ replicate_fill_buckets (replicate_t *rep, u32 n_buckets) { load_balance_path_t * nh; - u16 ii, bucket; + u16 bucket; bucket = 0; @@ -250,11 +276,8 @@ replicate_fill_buckets (replicate_t *rep, */ vec_foreach (nh, nhs) { - for (ii = 0; ii < nh->path_weight; ii++) - { - ASSERT(bucket < n_buckets); - replicate_set_bucket_i(rep, bucket++, buckets, &nh->path_dpo); - } + ASSERT(bucket < n_buckets); + replicate_set_bucket_i(rep, bucket++, buckets, &nh->path_dpo); } } @@ -273,9 +296,11 @@ replicate_multipath_update (const dpo_id_t *dpo, dpo_id_t *tmp_dpo; u32 ii, n_buckets; replicate_t *rep; + index_t repi; ASSERT(DPO_REPLICATE == dpo->dpoi_type); - rep = replicate_get(dpo->dpoi_index); + repi = dpo->dpoi_index & ~MPLS_IS_REPLICATE; + rep = replicate_get(repi); nhs = replicate_multipath_next_hop_fixup(next_hops, rep->rep_proto); n_buckets = vec_len(nhs); @@ -601,8 +626,7 @@ VLIB_CLI_COMMAND (replicate_show_command, static) = { typedef struct replicate_trace_t_ { index_t rep_index; - index_t dpo_index; - dpo_type_t dpo_type; + dpo_id_t dpo; } replicate_trace_t; static uword @@ -611,8 +635,9 @@ replicate_inline (vlib_main_t * vm, vlib_frame_t * frame) { vlib_combined_counter_main_t * cm = &replicate_main.repm_counters; + replicate_main_t * rm = &replicate_main; u32 n_left_from, * from, * to_next, next_index; - u32 cpu_index = os_get_cpu_number(); + u32 thread_index = vlib_get_thread_index(); from = vlib_frame_vector_args (frame); n_left_from = frame->n_vectors; @@ -631,44 +656,36 @@ replicate_inline (vlib_main_t * vm, const replicate_t *rep0; vlib_buffer_t * b0, *c0; const dpo_id_t *dpo0; + u8 num_cloned; bi0 = from[0]; - to_next[0] = bi0; from += 1; - to_next += 1; n_left_from -= 1; - n_left_to_next -= 1; b0 = vlib_get_buffer (vm, bi0); repi0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX]; rep0 = replicate_get(repi0); vlib_increment_combined_counter( - cm, cpu_index, repi0, 1, + cm, thread_index, repi0, 1, vlib_buffer_length_in_chain(vm, b0)); - /* ship the original to the first bucket */ - dpo0 = replicate_get_bucket_i(rep0, 0); - next0 = dpo0->dpoi_next_node; - vnet_buffer (b0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index; + vec_validate (rm->clones[thread_index], rep0->rep_n_buckets - 1); - if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) - { - replicate_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t)); - t->rep_index = repi0; - t->dpo_index = dpo0->dpoi_index; - t->dpo_type = dpo0->dpoi_type; - } - vlib_validate_buffer_enqueue_x1 (vm, node, next_index, - to_next, n_left_to_next, - bi0, next0); + num_cloned = vlib_buffer_clone (vm, bi0, rm->clones[thread_index], + rep0->rep_n_buckets, 128); + + if (num_cloned != rep0->rep_n_buckets) + { + vlib_node_increment_counter + (vm, node->node_index, + REPLICATE_DPO_ERROR_BUFFER_ALLOCATION_FAILURE, 1); + } - /* ship copies to the rest of the buckets */ - for (bucket = 1; bucket < rep0->rep_n_buckets; bucket++) + for (bucket = 0; bucket < num_cloned; bucket++) { - /* Make a copy */ - c0 = vlib_buffer_copy(vm, b0); - ci0 = vlib_get_buffer_index(vm, c0); + ci0 = rm->clones[thread_index][bucket]; + c0 = vlib_get_buffer(vm, ci0); to_next[0] = ci0; to_next += 1; @@ -678,18 +695,26 @@ replicate_inline (vlib_main_t * vm, next0 = dpo0->dpoi_next_node; vnet_buffer (c0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index; - if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) + if (PREDICT_FALSE(c0->flags & VLIB_BUFFER_IS_TRACED)) { - replicate_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t)); + replicate_trace_t *t; + + vlib_trace_buffer (vm, node, next0, c0, 0); + t = vlib_add_trace (vm, node, c0, sizeof (*t)); t->rep_index = repi0; - t->dpo_index = dpo0->dpoi_index; - t->dpo_type = dpo0->dpoi_type; + t->dpo = *dpo0; } vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, n_left_to_next, ci0, next0); + if (PREDICT_FALSE (n_left_to_next == 0)) + { + vlib_put_next_frame (vm, node, next_index, n_left_to_next); + vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); + } } + vec_reset_length (rm->clones[thread_index]); } vlib_put_next_frame (vm, node, next_index, n_left_to_next); @@ -705,10 +730,9 @@ format_replicate_trace (u8 * s, va_list * args) CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); replicate_trace_t *t = va_arg (*args, replicate_trace_t *); - s = format (s, "replicate: %d via %U:%d", + s = format (s, "replicate: %d via %U", t->rep_index, - format_dpo_type, t->dpo_type, - t->dpo_index); + format_dpo_id, &t->dpo, 0); return s; } @@ -721,17 +745,20 @@ ip4_replicate (vlib_main_t * vm, } /** - * @brief + * @brief IP4 replication node */ VLIB_REGISTER_NODE (ip4_replicate_node) = { .function = ip4_replicate, .name = "ip4-replicate", .vector_size = sizeof (u32), + .n_errors = ARRAY_LEN(replicate_dpo_error_strings), + .error_strings = replicate_dpo_error_strings, + .format_trace = format_replicate_trace, .n_next_nodes = 1, .next_nodes = { - [0] = "error-drop", + [0] = "ip4-drop", }, }; @@ -744,16 +771,57 @@ ip6_replicate (vlib_main_t * vm, } /** - * @brief + * @brief IPv6 replication node */ VLIB_REGISTER_NODE (ip6_replicate_node) = { .function = ip6_replicate, .name = "ip6-replicate", .vector_size = sizeof (u32), + .n_errors = ARRAY_LEN(replicate_dpo_error_strings), + .error_strings = replicate_dpo_error_strings, + + .format_trace = format_replicate_trace, + .n_next_nodes = 1, + .next_nodes = { + [0] = "ip6-drop", + }, +}; + +static uword +mpls_replicate (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * frame) +{ + return (replicate_inline (vm, node, frame)); +} + +/** + * @brief MPLS replication node + */ +VLIB_REGISTER_NODE (mpls_replicate_node) = { + .function = mpls_replicate, + .name = "mpls-replicate", + .vector_size = sizeof (u32), + + .n_errors = ARRAY_LEN(replicate_dpo_error_strings), + .error_strings = replicate_dpo_error_strings, + .format_trace = format_replicate_trace, .n_next_nodes = 1, .next_nodes = { - [0] = "error-drop", + [0] = "mpls-drop", }, }; + +clib_error_t * +replicate_dpo_init (vlib_main_t * vm) +{ + replicate_main_t * rm = &replicate_main; + + vec_validate (rm->clones, vlib_num_workers()); + + return 0; +} + +VLIB_INIT_FUNCTION (replicate_dpo_init);