X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fpolicer%2Fnode_funcs.c;h=efa2f830f8ccfed0da06265cb874ab98b396ac96;hb=b03eec969f3db186fc354c3e885e51c0b24803f0;hp=5c185991e8b5f4cc8349745ab2d5e5650fe7e741;hpb=3b81a1e5f205482b8ea30edbfd39559c4368ac4d;p=vpp.git diff --git a/src/vnet/policer/node_funcs.c b/src/vnet/policer/node_funcs.c index 5c185991e8b..efa2f830f8c 100644 --- a/src/vnet/policer/node_funcs.c +++ b/src/vnet/policer/node_funcs.c @@ -67,9 +67,8 @@ static char *vnet_policer_error_strings[] = { }; static inline uword -vnet_policer_inline (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame, vnet_policer_index_t which) +vnet_policer_inline (vlib_main_t *vm, vlib_node_runtime_t *node, + vlib_frame_t *frame, vlib_dir_t dir) { u32 n_left_from, *from, *to_next; vnet_policer_next_t next_index; @@ -121,62 +120,50 @@ vnet_policer_inline (vlib_main_t * vm, b0 = vlib_get_buffer (vm, bi0); b1 = vlib_get_buffer (vm, bi1); - sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; - next0 = VNET_POLICER_NEXT_TRANSMIT; + sw_if_index0 = vnet_buffer (b0)->sw_if_index[dir]; + sw_if_index1 = vnet_buffer (b1)->sw_if_index[dir]; - sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX]; - next1 = VNET_POLICER_NEXT_TRANSMIT; - - - if (which == VNET_POLICER_INDEX_BY_SW_IF_INDEX) - { - pi0 = pm->policer_index_by_sw_if_index[sw_if_index0]; - pi1 = pm->policer_index_by_sw_if_index[sw_if_index1]; - } - - if (which == VNET_POLICER_INDEX_BY_OPAQUE) - { - pi0 = vnet_buffer (b0)->policer.index; - pi1 = vnet_buffer (b1)->policer.index; - } - - if (which == VNET_POLICER_INDEX_BY_EITHER) - { - pi0 = vnet_buffer (b0)->policer.index; - pi0 = (pi0 != ~0) ? pi0 : - pm->policer_index_by_sw_if_index[sw_if_index0]; - pi1 = vnet_buffer (b1)->policer.index; - pi1 = (pi1 != ~0) ? pi1 : - pm->policer_index_by_sw_if_index[sw_if_index1]; - } + pi0 = pm->policer_index_by_sw_if_index[dir][sw_if_index0]; + pi1 = pm->policer_index_by_sw_if_index[dir][sw_if_index1]; act0 = vnet_policer_police (vm, b0, pi0, time_in_policer_periods, - POLICE_CONFORM /* no chaining */ ); + POLICE_CONFORM /* no chaining */, true); act1 = vnet_policer_police (vm, b1, pi1, time_in_policer_periods, - POLICE_CONFORM /* no chaining */ ); + POLICE_CONFORM /* no chaining */, true); - if (PREDICT_FALSE (act0 == SSE2_QOS_ACTION_DROP)) /* drop action */ + if (PREDICT_FALSE (act0 == QOS_ACTION_HANDOFF)) + { + next0 = VNET_POLICER_NEXT_HANDOFF; + vnet_buffer (b0)->policer.index = pi0; + } + else if (PREDICT_FALSE (act0 == QOS_ACTION_DROP)) { next0 = VNET_POLICER_NEXT_DROP; b0->error = node->errors[VNET_POLICER_ERROR_DROP]; } - else /* transmit or mark-and-transmit action */ + else /* transmit or mark-and-transmit action */ { transmitted++; + vnet_feature_next (&next0, b0); } - if (PREDICT_FALSE (act1 == SSE2_QOS_ACTION_DROP)) /* drop action */ + if (PREDICT_FALSE (act1 == QOS_ACTION_HANDOFF)) + { + next1 = VNET_POLICER_NEXT_HANDOFF; + vnet_buffer (b1)->policer.index = pi1; + } + else if (PREDICT_FALSE (act1 == QOS_ACTION_DROP)) /* drop action */ { next1 = VNET_POLICER_NEXT_DROP; b1->error = node->errors[VNET_POLICER_ERROR_DROP]; } - else /* transmit or mark-and-transmit action */ + else /* transmit or mark-and-transmit action */ { transmitted++; + vnet_feature_next (&next1, b1); } - if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE))) { if (b0->flags & VLIB_BUFFER_IS_TRACED) @@ -219,33 +206,26 @@ vnet_policer_inline (vlib_main_t * vm, b0 = vlib_get_buffer (vm, bi0); - sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; - next0 = VNET_POLICER_NEXT_TRANSMIT; + sw_if_index0 = vnet_buffer (b0)->sw_if_index[dir]; + pi0 = pm->policer_index_by_sw_if_index[dir][sw_if_index0]; - if (which == VNET_POLICER_INDEX_BY_SW_IF_INDEX) - pi0 = pm->policer_index_by_sw_if_index[sw_if_index0]; - - if (which == VNET_POLICER_INDEX_BY_OPAQUE) - pi0 = vnet_buffer (b0)->policer.index; + act0 = vnet_policer_police (vm, b0, pi0, time_in_policer_periods, + POLICE_CONFORM /* no chaining */, true); - if (which == VNET_POLICER_INDEX_BY_EITHER) + if (PREDICT_FALSE (act0 == QOS_ACTION_HANDOFF)) { - pi0 = vnet_buffer (b0)->policer.index; - pi0 = (pi0 != ~0) ? pi0 : - pm->policer_index_by_sw_if_index[sw_if_index0]; + next0 = VNET_POLICER_NEXT_HANDOFF; + vnet_buffer (b0)->policer.index = pi0; } - - act0 = vnet_policer_police (vm, b0, pi0, time_in_policer_periods, - POLICE_CONFORM /* no chaining */ ); - - if (PREDICT_FALSE (act0 == SSE2_QOS_ACTION_DROP)) /* drop action */ + else if (PREDICT_FALSE (act0 == QOS_ACTION_DROP)) { next0 = VNET_POLICER_NEXT_DROP; b0->error = node->errors[VNET_POLICER_ERROR_DROP]; } - else /* transmit or mark-and-transmit action */ + else /* transmit or mark-and-transmit action */ { transmitted++; + vnet_feature_next (&next0, b0); } if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) @@ -272,200 +252,105 @@ vnet_policer_inline (vlib_main_t * vm, return frame->n_vectors; } -uword -vnet_policer_by_sw_if_index (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) +VLIB_NODE_FN (policer_input_node) +(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame) { - return vnet_policer_inline (vm, node, frame, - VNET_POLICER_INDEX_BY_SW_IF_INDEX); + return vnet_policer_inline (vm, node, frame, VLIB_RX); } -uword -vnet_policer_by_opaque (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) -{ - return vnet_policer_inline (vm, node, frame, VNET_POLICER_INDEX_BY_OPAQUE); -} +VLIB_REGISTER_NODE (policer_input_node) = { + .name = "policer-input", + .vector_size = sizeof (u32), + .format_trace = format_policer_trace, + .type = VLIB_NODE_TYPE_INTERNAL, + .n_errors = ARRAY_LEN(vnet_policer_error_strings), + .error_strings = vnet_policer_error_strings, + .n_next_nodes = VNET_POLICER_N_NEXT, + .next_nodes = { + [VNET_POLICER_NEXT_DROP] = "error-drop", + [VNET_POLICER_NEXT_HANDOFF] = "policer-input-handoff", + }, +}; -uword -vnet_policer_by_either (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) -{ - return vnet_policer_inline (vm, node, frame, VNET_POLICER_INDEX_BY_EITHER); -} +VNET_FEATURE_INIT (policer_input_node, static) = { + .arc_name = "device-input", + .node_name = "policer-input", + .runs_before = VNET_FEATURES ("ethernet-input"), +}; -void -vnet_policer_node_funcs_reference (void) +VLIB_NODE_FN (policer_output_node) +(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame) { + return vnet_policer_inline (vm, node, frame, VLIB_TX); } - -#define TEST_CODE 1 - -#ifdef TEST_CODE - -/* *INDENT-OFF* */ -VLIB_REGISTER_NODE (policer_by_sw_if_index_node, static) = { - .function = vnet_policer_by_sw_if_index, - .name = "policer-by-sw-if-index", +VLIB_REGISTER_NODE (policer_output_node) = { + .name = "policer-output", .vector_size = sizeof (u32), .format_trace = format_policer_trace, .type = VLIB_NODE_TYPE_INTERNAL, - .n_errors = ARRAY_LEN(vnet_policer_error_strings), .error_strings = vnet_policer_error_strings, - .n_next_nodes = VNET_POLICER_N_NEXT, - - /* edit / add dispositions here */ .next_nodes = { - [VNET_POLICER_NEXT_TRANSMIT] = "ethernet-input", - [VNET_POLICER_NEXT_DROP] = "error-drop", - }, + [VNET_POLICER_NEXT_DROP] = "error-drop", + [VNET_POLICER_NEXT_HANDOFF] = "policer-output-handoff", + }, }; -VLIB_NODE_FUNCTION_MULTIARCH (policer_by_sw_if_index_node, - vnet_policer_by_sw_if_index); -/* *INDENT-ON* */ - - -int -test_policer_add_del (u32 rx_sw_if_index, u8 * config_name, int is_add) -{ - vnet_policer_main_t *pm = &vnet_policer_main; - policer_read_response_type_st *template; - policer_read_response_type_st *policer; - vnet_hw_interface_t *rxhi; - uword *p; - - rxhi = vnet_get_sup_hw_interface (pm->vnet_main, rx_sw_if_index); - - /* Make sure caller didn't pass a vlan subif, etc. */ - if (rxhi->sw_if_index != rx_sw_if_index) - return VNET_API_ERROR_INVALID_SW_IF_INDEX; - - if (is_add) - { - - p = hash_get_mem (pm->policer_config_by_name, config_name); - - if (p == 0) - return -2; - - template = pool_elt_at_index (pm->policer_templates, p[0]); - - vnet_hw_interface_rx_redirect_to_node - (pm->vnet_main, rxhi->hw_if_index, policer_by_sw_if_index_node.index); - - pool_get_aligned (pm->policers, policer, CLIB_CACHE_LINE_BYTES); - - policer[0] = template[0]; +VNET_FEATURE_INIT (policer_output_node, static) = { + .arc_name = "ip4-output", + .node_name = "policer-output", +}; - vec_validate (pm->policer_index_by_sw_if_index, rx_sw_if_index); - pm->policer_index_by_sw_if_index[rx_sw_if_index] - = policer - pm->policers; - } - else - { - u32 pi; - vnet_hw_interface_rx_redirect_to_node (pm->vnet_main, - rxhi->hw_if_index, - ~0 /* disable */ ); - - pi = pm->policer_index_by_sw_if_index[rx_sw_if_index]; - pm->policer_index_by_sw_if_index[rx_sw_if_index] = ~0; - pool_put_index (pm->policers, pi); - } +VNET_FEATURE_INIT (policer6_output_node, static) = { + .arc_name = "ip6-output", + .node_name = "policer-output", +}; - return 0; -} +static char *policer_input_handoff_error_strings[] = { "congestion drop" }; -static clib_error_t * -test_policer_command_fn (vlib_main_t * vm, - unformat_input_t * input, vlib_cli_command_t * cmd) +VLIB_NODE_FN (policer_input_handoff_node) +(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame) { - vnet_policer_main_t *pm = &vnet_policer_main; - unformat_input_t _line_input, *line_input = &_line_input; - u32 rx_sw_if_index; - int rv; - u8 *config_name = 0; - int rx_set = 0; - int is_add = 1; - int is_show = 0; - clib_error_t *error = NULL; - - /* Get a line of input. */ - if (!unformat_user (input, unformat_line_input, line_input)) - return 0; - - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (line_input, "intfc %U", unformat_vnet_sw_interface, - pm->vnet_main, &rx_sw_if_index)) - rx_set = 1; - else if (unformat (line_input, "show")) - is_show = 1; - else if (unformat (line_input, "policer %s", &config_name)) - ; - else if (unformat (line_input, "del")) - is_add = 0; - else - break; - } - - if (rx_set == 0) - { - error = clib_error_return (0, "interface not set"); - goto done; - } - - if (is_show) - { - u32 pi = pm->policer_index_by_sw_if_index[rx_sw_if_index]; - policer_read_response_type_st *policer; - policer = pool_elt_at_index (pm->policers, pi); - - vlib_cli_output (vm, "%U", format_policer_instance, policer); - goto done; - } - - if (is_add && config_name == 0) - { - error = clib_error_return (0, "policer config name required"); - goto done; - } - - rv = test_policer_add_del (rx_sw_if_index, config_name, is_add); - - switch (rv) - { - case 0: - break; - - default: - error = clib_error_return - (0, "WARNING: vnet_vnet_policer_add_del returned %d", rv); - goto done; - } - -done: - unformat_free (line_input); - - return error; + return policer_handoff (vm, node, frame, vnet_policer_main.fq_index[VLIB_RX], + ~0); } -/* *INDENT-OFF* */ -VLIB_CLI_COMMAND (test_patch_command, static) = { - .path = "test policer", - .short_help = - "intfc policer [del]", - .function = test_policer_command_fn, +VLIB_REGISTER_NODE (policer_input_handoff_node) = { + .name = "policer-input-handoff", + .vector_size = sizeof (u32), + .format_trace = format_policer_handoff_trace, + .type = VLIB_NODE_TYPE_INTERNAL, + .n_errors = ARRAY_LEN(policer_input_handoff_error_strings), + .error_strings = policer_input_handoff_error_strings, + + .n_next_nodes = 1, + .next_nodes = { + [0] = "error-drop", + }, }; -/* *INDENT-ON* */ -#endif /* TEST_CODE */ +VLIB_NODE_FN (policer_output_handoff_node) +(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame) +{ + return policer_handoff (vm, node, frame, vnet_policer_main.fq_index[VLIB_TX], + ~0); +} +VLIB_REGISTER_NODE (policer_output_handoff_node) = { + .name = "policer-output-handoff", + .vector_size = sizeof (u32), + .format_trace = format_policer_handoff_trace, + .type = VLIB_NODE_TYPE_INTERNAL, + .n_errors = ARRAY_LEN(policer_input_handoff_error_strings), + .error_strings = policer_input_handoff_error_strings, + .n_next_nodes = 1, + .next_nodes = { + [0] = "error-drop", + }, +}; typedef struct { u32 sw_if_index; @@ -492,7 +377,7 @@ format_policer_classify_trace (u8 * s, va_list * args) #define foreach_policer_classify_error \ _(MISS, "Policer classify misses") \ _(HIT, "Policer classify hits") \ -_(CHAIN_HIT, "Polcier classify hits after chain walk") \ +_(CHAIN_HIT, "Policer classify hits after chain walk") \ _(DROP, "Policer classify action drop") typedef enum @@ -523,7 +408,6 @@ policer_classify_inline (vlib_main_t * vm, u32 hits = 0; u32 misses = 0; u32 chain_hits = 0; - u32 drop = 0; u32 n_next_nodes; u64 time_in_policer_periods; @@ -553,9 +437,9 @@ policer_classify_inline (vlib_main_t * vm, p2 = vlib_get_buffer (vm, from[2]); vlib_prefetch_buffer_header (p1, STORE); - CLIB_PREFETCH (p1->data, CLIB_CACHE_LINE_BYTES, STORE); + clib_prefetch_store (p1->data); vlib_prefetch_buffer_header (p2, STORE); - CLIB_PREFETCH (p2->data, CLIB_CACHE_LINE_BYTES, STORE); + clib_prefetch_store (p2->data); } bi0 = from[0]; @@ -643,7 +527,7 @@ policer_classify_inline (vlib_main_t * vm, u32 table_index0; vnet_classify_table_t *t0; vnet_classify_entry_t *e0; - u64 hash0; + u32 hash0; u8 *h0; u8 act0; @@ -653,7 +537,7 @@ policer_classify_inline (vlib_main_t * vm, vlib_buffer_t *p1 = vlib_get_buffer (vm, from[3]); vnet_classify_table_t *tp1; u32 table_index1; - u64 phash1; + u32 phash1; table_index1 = vnet_buffer (p1)->l2_classify.table_index; @@ -700,16 +584,13 @@ policer_classify_inline (vlib_main_t * vm, if (e0) { - act0 = vnet_policer_police (vm, - b0, - e0->next_index, + act0 = vnet_policer_police (vm, b0, e0->next_index, time_in_policer_periods, - e0->opaque_index); - if (PREDICT_FALSE (act0 == SSE2_QOS_ACTION_DROP)) + e0->opaque_index, false); + if (PREDICT_FALSE (act0 == QOS_ACTION_DROP)) { next0 = POLICER_CLASSIFY_NEXT_INDEX_DROP; b0->error = node->errors[POLICER_CLASSIFY_ERROR_DROP]; - drop++; } hits++; } @@ -735,17 +616,14 @@ policer_classify_inline (vlib_main_t * vm, vnet_classify_find_entry (t0, (u8 *) h0, hash0, now); if (e0) { - act0 = vnet_policer_police (vm, - b0, - e0->next_index, + act0 = vnet_policer_police (vm, b0, e0->next_index, time_in_policer_periods, - e0->opaque_index); - if (PREDICT_FALSE (act0 == SSE2_QOS_ACTION_DROP)) + e0->opaque_index, false); + if (PREDICT_FALSE (act0 == QOS_ACTION_DROP)) { next0 = POLICER_CLASSIFY_NEXT_INDEX_DROP; b0->error = node->errors[POLICER_CLASSIFY_ERROR_DROP]; - drop++; } hits++; chain_hits++; @@ -780,15 +658,13 @@ policer_classify_inline (vlib_main_t * vm, POLICER_CLASSIFY_ERROR_HIT, hits); vlib_node_increment_counter (vm, node->node_index, POLICER_CLASSIFY_ERROR_CHAIN_HIT, chain_hits); - vlib_node_increment_counter (vm, node->node_index, - POLICER_CLASSIFY_ERROR_DROP, drop); return frame->n_vectors; } -static uword -ip4_policer_classify (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) +VLIB_NODE_FN (ip4_policer_classify_node) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * frame) { return policer_classify_inline (vm, node, frame, POLICER_CLASSIFY_TABLE_IP4); @@ -796,7 +672,6 @@ ip4_policer_classify (vlib_main_t * vm, /* *INDENT-OFF* */ VLIB_REGISTER_NODE (ip4_policer_classify_node) = { - .function = ip4_policer_classify, .name = "ip4-policer-classify", .vector_size = sizeof (u32), .format_trace = format_policer_classify_trace, @@ -807,13 +682,11 @@ VLIB_REGISTER_NODE (ip4_policer_classify_node) = { [POLICER_CLASSIFY_NEXT_INDEX_DROP] = "error-drop", }, }; - -VLIB_NODE_FUNCTION_MULTIARCH (ip4_policer_classify_node, ip4_policer_classify); /* *INDENT-ON* */ -static uword -ip6_policer_classify (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) +VLIB_NODE_FN (ip6_policer_classify_node) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * frame) { return policer_classify_inline (vm, node, frame, POLICER_CLASSIFY_TABLE_IP6); @@ -821,7 +694,6 @@ ip6_policer_classify (vlib_main_t * vm, /* *INDENT-OFF* */ VLIB_REGISTER_NODE (ip6_policer_classify_node) = { - .function = ip6_policer_classify, .name = "ip6-policer-classify", .vector_size = sizeof (u32), .format_trace = format_policer_classify_trace, @@ -832,20 +704,17 @@ VLIB_REGISTER_NODE (ip6_policer_classify_node) = { [POLICER_CLASSIFY_NEXT_INDEX_DROP] = "error-drop", }, }; - -VLIB_NODE_FUNCTION_MULTIARCH (ip6_policer_classify_node, ip6_policer_classify); /* *INDENT-ON* */ -static uword -l2_policer_classify (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) +VLIB_NODE_FN (l2_policer_classify_node) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * frame) { return policer_classify_inline (vm, node, frame, POLICER_CLASSIFY_TABLE_L2); } /* *INDENT-OFF* */ VLIB_REGISTER_NODE (l2_policer_classify_node) = { - .function = l2_policer_classify, .name = "l2-policer-classify", .vector_size = sizeof (u32), .format_trace = format_policer_classify_trace, @@ -856,10 +725,9 @@ VLIB_REGISTER_NODE (l2_policer_classify_node) = { [POLICER_CLASSIFY_NEXT_INDEX_DROP] = "error-drop", }, }; - -VLIB_NODE_FUNCTION_MULTIARCH (l2_policer_classify_node, l2_policer_classify); /* *INDENT-ON* */ +#ifndef CLIB_MARCH_VARIANT static clib_error_t * policer_classify_init (vlib_main_t * vm) { @@ -880,6 +748,7 @@ policer_classify_init (vlib_main_t * vm) } VLIB_INIT_FUNCTION (policer_classify_init); +#endif /* CLIB_MARCH_VARIANT */ /* * fd.io coding-style-patch-verification: ON