X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fpolicer%2Fpolicer.c;h=4aaf9e01e04775769aa6ad9a9df74e3e5de291d0;hb=40ee2003b;hp=5a7b7711661d2606160180ba46738e3f7f25ec9e;hpb=913b87306642a1c2d59431e4d0639c7a8399808f;p=vpp.git diff --git a/src/vnet/policer/policer.c b/src/vnet/policer/policer.c index 5a7b7711661..4aaf9e01e04 100644 --- a/src/vnet/policer/policer.c +++ b/src/vnet/policer/policer.c @@ -13,18 +13,49 @@ * limitations under the License. */ #include +#include #include +#include #include +#include + +vnet_policer_main_t vnet_policer_main; + +u8 * +format_policer_handoff_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 *); + policer_handoff_trace_t *t = va_arg (*args, policer_handoff_trace_t *); + + s = format (s, "policer %d, handoff thread %d to %d", t->policer_index, + t->current_worker_index, t->next_worker_index); + + return s; +} + +vlib_combined_counter_main_t policer_counters[] = { + { + .name = "Policer-Conform", + .stat_segment_name = "/net/policer/conform", + }, + { + .name = "Policer-Exceed", + .stat_segment_name = "/net/policer/exceed", + }, + { + .name = "Policer-Violate", + .stat_segment_name = "/net/policer/violate", + }, +}; clib_error_t * -policer_add_del (vlib_main_t * vm, - u8 * name, - sse2_qos_pol_cfg_params_st * cfg, - u32 * policer_index, u8 is_add) +policer_add_del (vlib_main_t *vm, u8 *name, qos_pol_cfg_params_st *cfg, + u32 *policer_index, u8 is_add) { vnet_policer_main_t *pm = &vnet_policer_main; - policer_read_response_type_st test_policer; - policer_read_response_type_st *policer; + policer_t test_policer; + policer_t *policer; uword *p; u32 pi; int rv; @@ -64,12 +95,13 @@ policer_add_del (vlib_main_t * vm, } /* Vet the configuration before adding it to the table */ - rv = sse2_pol_logical_2_physical (cfg, &test_policer); + rv = pol_logical_2_physical (cfg, &test_policer); if (rv == 0) { - policer_read_response_type_st *pp; - sse2_qos_pol_cfg_params_st *cp; + policer_t *pp; + qos_pol_cfg_params_st *cp; + int i; pool_get (pm->configs, cp); pool_get (pm->policer_templates, pp); @@ -85,6 +117,13 @@ policer_add_del (vlib_main_t * vm, pi = policer - pm->policers; hash_set_mem (pm->policer_index_by_name, name, pi); *policer_index = pi; + policer->thread_index = ~0; + + for (i = 0; i < NUM_POLICE_RESULTS; i++) + { + vlib_validate_combined_counter (&policer_counters[i], pi); + vlib_zero_combined_counter (&policer_counters[i], pi); + } } else { @@ -95,11 +134,82 @@ policer_add_del (vlib_main_t * vm, return 0; } +int +policer_bind_worker (u8 *name, u32 worker, bool bind) +{ + vnet_policer_main_t *pm = &vnet_policer_main; + policer_t *policer; + uword *p; + + p = hash_get_mem (pm->policer_index_by_name, name); + if (p == 0) + { + return VNET_API_ERROR_NO_SUCH_ENTRY; + } + + policer = &pm->policers[p[0]]; + + if (bind) + { + if (worker >= vlib_num_workers ()) + { + return VNET_API_ERROR_INVALID_WORKER; + } + + policer->thread_index = vlib_get_worker_thread_index (worker); + } + else + { + policer->thread_index = ~0; + } + return 0; +} + +int +policer_input (u8 *name, u32 sw_if_index, bool apply) +{ + vnet_policer_main_t *pm = &vnet_policer_main; + policer_t *policer; + u32 policer_index; + uword *p; + + p = hash_get_mem (pm->policer_index_by_name, name); + if (p == 0) + { + return VNET_API_ERROR_NO_SUCH_ENTRY; + } + + policer = &pm->policers[p[0]]; + policer_index = policer - pm->policers; + + if (apply) + { + vec_validate (pm->policer_index_by_sw_if_index, sw_if_index); + pm->policer_index_by_sw_if_index[sw_if_index] = policer_index; + } + else + { + pm->policer_index_by_sw_if_index[sw_if_index] = ~0; + } + + vnet_feature_enable_disable ("device-input", "policer-input", sw_if_index, + apply, 0, 0); + return 0; +} + u8 * format_policer_instance (u8 * s, va_list * va) { - policer_read_response_type_st *i - = va_arg (*va, policer_read_response_type_st *); + policer_t *i = va_arg (*va, policer_t *); + uword pi = va_arg (*va, uword); + int result; + vlib_counter_t counts[NUM_POLICE_RESULTS]; + + for (result = 0; result < NUM_POLICE_RESULTS; result++) + { + vlib_get_combined_counter (&policer_counters[result], pi, + &counts[result]); + } s = format (s, "policer at %llx: %s rate, %s color-aware\n", i, i->single_rate ? "single" : "dual", @@ -110,19 +220,25 @@ format_policer_instance (u8 * s, va_list * va) i->current_limit, i->current_bucket, i->extended_limit, i->extended_bucket); s = format (s, "last update %llu\n", i->last_update_time); + s = format (s, "conform %llu packets, %llu bytes\n", + counts[POLICE_CONFORM].packets, counts[POLICE_CONFORM].bytes); + s = format (s, "exceed %llu packets, %llu bytes\n", + counts[POLICE_EXCEED].packets, counts[POLICE_EXCEED].bytes); + s = format (s, "violate %llu packets, %llu bytes\n", + counts[POLICE_VIOLATE].packets, counts[POLICE_VIOLATE].bytes); return s; } static u8 * format_policer_round_type (u8 * s, va_list * va) { - sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *); + qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *); - if (c->rnd_type == SSE2_QOS_ROUND_TO_CLOSEST) + if (c->rnd_type == QOS_ROUND_TO_CLOSEST) s = format (s, "closest"); - else if (c->rnd_type == SSE2_QOS_ROUND_TO_UP) + else if (c->rnd_type == QOS_ROUND_TO_UP) s = format (s, "up"); - else if (c->rnd_type == SSE2_QOS_ROUND_TO_DOWN) + else if (c->rnd_type == QOS_ROUND_TO_DOWN) s = format (s, "down"); else s = format (s, "ILLEGAL"); @@ -133,11 +249,11 @@ format_policer_round_type (u8 * s, va_list * va) static u8 * format_policer_rate_type (u8 * s, va_list * va) { - sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *); + qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *); - if (c->rate_type == SSE2_QOS_RATE_KBPS) + if (c->rate_type == QOS_RATE_KBPS) s = format (s, "kbps"); - else if (c->rate_type == SSE2_QOS_RATE_PPS) + else if (c->rate_type == QOS_RATE_PPS) s = format (s, "pps"); else s = format (s, "ILLEGAL"); @@ -147,57 +263,38 @@ format_policer_rate_type (u8 * s, va_list * va) static u8 * format_policer_type (u8 * s, va_list * va) { - sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *); + qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *); - if (c->rfc == SSE2_QOS_POLICER_TYPE_1R2C) + if (c->rfc == QOS_POLICER_TYPE_1R2C) s = format (s, "1r2c"); - else if (c->rfc == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697) + else if (c->rfc == QOS_POLICER_TYPE_1R3C_RFC_2697) s = format (s, "1r3c"); - else if (c->rfc == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698) + else if (c->rfc == QOS_POLICER_TYPE_2R3C_RFC_2698) s = format (s, "2r3c-2698"); - else if (c->rfc == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115) + else if (c->rfc == QOS_POLICER_TYPE_2R3C_RFC_4115) s = format (s, "2r3c-4115"); - else if (c->rfc == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1) + else if (c->rfc == QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1) s = format (s, "2r3c-mef5cf1"); else s = format (s, "ILLEGAL"); return s; } -static u8 * -format_dscp (u8 * s, va_list * va) -{ - u32 i = va_arg (*va, u32); - char *t = 0; - - switch (i) - { -#define _(v,f,str) case VNET_DSCP_##f: t = str; break; - foreach_vnet_dscp -#undef _ - default: - return format (s, "ILLEGAL"); - } - s = format (s, "%s", t); - return s; -} - static u8 * format_policer_action_type (u8 * s, va_list * va) { - sse2_qos_pol_action_params_st *a - = va_arg (*va, sse2_qos_pol_action_params_st *); + qos_pol_action_params_st *a = va_arg (*va, qos_pol_action_params_st *); - if (a->action_type == SSE2_QOS_ACTION_DROP) + if (a->action_type == QOS_ACTION_DROP) s = format (s, "drop"); - else if (a->action_type == SSE2_QOS_ACTION_TRANSMIT) + else if (a->action_type == QOS_ACTION_TRANSMIT) s = format (s, "transmit"); - else if (a->action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT) - s = format (s, "mark-and-transmit %U", format_dscp, a->dscp); + else if (a->action_type == QOS_ACTION_MARK_AND_TRANSMIT) + s = format (s, "mark-and-transmit %U", format_ip_dscp, a->dscp); else s = format (s, "ILLEGAL"); return s; @@ -206,7 +303,7 @@ format_policer_action_type (u8 * s, va_list * va) u8 * format_policer_config (u8 * s, va_list * va) { - sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *); + qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *); s = format (s, "type %U cir %u eir %u cb %u eb %u\n", format_policer_type, c, @@ -224,21 +321,21 @@ format_policer_config (u8 * s, va_list * va) static uword unformat_policer_type (unformat_input_t * input, va_list * va) { - sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *); + qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *); if (!unformat (input, "type")) return 0; if (unformat (input, "1r2c")) - c->rfc = SSE2_QOS_POLICER_TYPE_1R2C; + c->rfc = QOS_POLICER_TYPE_1R2C; else if (unformat (input, "1r3c")) - c->rfc = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697; + c->rfc = QOS_POLICER_TYPE_1R3C_RFC_2697; else if (unformat (input, "2r3c-2698")) - c->rfc = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698; + c->rfc = QOS_POLICER_TYPE_2R3C_RFC_2698; else if (unformat (input, "2r3c-4115")) - c->rfc = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115; + c->rfc = QOS_POLICER_TYPE_2R3C_RFC_4115; else if (unformat (input, "2r3c-mef5cf1")) - c->rfc = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1; + c->rfc = QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1; else return 0; return 1; @@ -247,17 +344,17 @@ unformat_policer_type (unformat_input_t * input, va_list * va) static uword unformat_policer_round_type (unformat_input_t * input, va_list * va) { - sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *); + qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *); if (!unformat (input, "round")) return 0; if (unformat (input, "closest")) - c->rnd_type = SSE2_QOS_ROUND_TO_CLOSEST; + c->rnd_type = QOS_ROUND_TO_CLOSEST; else if (unformat (input, "up")) - c->rnd_type = SSE2_QOS_ROUND_TO_UP; + c->rnd_type = QOS_ROUND_TO_UP; else if (unformat (input, "down")) - c->rnd_type = SSE2_QOS_ROUND_TO_DOWN; + c->rnd_type = QOS_ROUND_TO_DOWN; else return 0; return 1; @@ -266,15 +363,15 @@ unformat_policer_round_type (unformat_input_t * input, va_list * va) static uword unformat_policer_rate_type (unformat_input_t * input, va_list * va) { - sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *); + qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *); if (!unformat (input, "rate")) return 0; if (unformat (input, "kbps")) - c->rate_type = SSE2_QOS_RATE_KBPS; + c->rate_type = QOS_RATE_KBPS; else if (unformat (input, "pps")) - c->rate_type = SSE2_QOS_RATE_PPS; + c->rate_type = QOS_RATE_PPS; else return 0; return 1; @@ -283,7 +380,7 @@ unformat_policer_rate_type (unformat_input_t * input, va_list * va) static uword unformat_policer_cir (unformat_input_t * input, va_list * va) { - sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *); + qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *); if (unformat (input, "cir %u", &c->rb.kbps.cir_kbps)) return 1; @@ -293,7 +390,7 @@ unformat_policer_cir (unformat_input_t * input, va_list * va) static uword unformat_policer_eir (unformat_input_t * input, va_list * va) { - sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *); + qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *); if (unformat (input, "eir %u", &c->rb.kbps.eir_kbps)) return 1; @@ -303,7 +400,7 @@ unformat_policer_eir (unformat_input_t * input, va_list * va) static uword unformat_policer_cb (unformat_input_t * input, va_list * va) { - sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *); + qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *); if (unformat (input, "cb %u", &c->rb.kbps.cb_bytes)) return 1; @@ -313,39 +410,25 @@ unformat_policer_cb (unformat_input_t * input, va_list * va) static uword unformat_policer_eb (unformat_input_t * input, va_list * va) { - sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *); + qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *); if (unformat (input, "eb %u", &c->rb.kbps.eb_bytes)) return 1; return 0; } -static uword -unformat_dscp (unformat_input_t * input, va_list * va) -{ - u8 *r = va_arg (*va, u8 *); - - if (0); -#define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f; - foreach_vnet_dscp -#undef _ - else - return 0; - return 1; -} - static uword unformat_policer_action_type (unformat_input_t * input, va_list * va) { - sse2_qos_pol_action_params_st *a - = va_arg (*va, sse2_qos_pol_action_params_st *); + qos_pol_action_params_st *a = va_arg (*va, qos_pol_action_params_st *); if (unformat (input, "drop")) - a->action_type = SSE2_QOS_ACTION_DROP; + a->action_type = QOS_ACTION_DROP; else if (unformat (input, "transmit")) - a->action_type = SSE2_QOS_ACTION_TRANSMIT; - else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp)) - a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT; + a->action_type = QOS_ACTION_TRANSMIT; + else if (unformat (input, "mark-and-transmit %U", unformat_ip_dscp, + &a->dscp)) + a->action_type = QOS_ACTION_MARK_AND_TRANSMIT; else return 0; return 1; @@ -354,7 +437,7 @@ unformat_policer_action_type (unformat_input_t * input, va_list * va) static uword unformat_policer_action (unformat_input_t * input, va_list * va) { - sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *); + qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *); if (unformat (input, "conform-action %U", unformat_policer_action_type, &c->conform_action)) @@ -421,7 +504,7 @@ configure_policer_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { - sse2_qos_pol_cfg_params_st c; + qos_pol_cfg_params_st c; unformat_input_t _line_input, *line_input = &_line_input; u8 is_add = 1; u8 *name = 0; @@ -432,7 +515,7 @@ configure_policer_command_fn (vlib_main_t * vm, if (!unformat_user (input, unformat_line_input, line_input)) return 0; - memset (&c, 0, sizeof (c)); + clib_memset (&c, 0, sizeof (c)); while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { @@ -479,8 +562,9 @@ show_policer_command_fn (vlib_main_t * vm, u32 pool_index; u8 *match_name = 0; u8 *name; - sse2_qos_pol_cfg_params_st *config; - policer_read_response_type_st *templ; + uword *pi; + qos_pol_cfg_params_st *config; + policer_t *templ; (void) unformat (input, "name %s", &match_name); @@ -490,14 +574,16 @@ show_policer_command_fn (vlib_main_t * vm, name = (u8 *) p->key; if (match_name == 0 || !strcmp((char *) name, (char *) match_name)) { - pool_index = p->value[0]; - config = pool_elt_at_index (pm->configs, pool_index); - templ = pool_elt_at_index (pm->policer_templates, pool_index); - vlib_cli_output (vm, "Name \"%s\" %U ", - name, format_policer_config, config); - vlib_cli_output (vm, "Template %U", - format_policer_instance, templ); - vlib_cli_output (vm, "-----------"); + pi = hash_get_mem (pm->policer_index_by_name, name); + + pool_index = p->value[0]; + config = pool_elt_at_index (pm->configs, pool_index); + templ = pool_elt_at_index (pm->policer_templates, pool_index); + vlib_cli_output (vm, "Name \"%s\" %U ", name, format_policer_config, + config); + vlib_cli_output (vm, "Template %U", format_policer_instance, templ, + pi[0]); + vlib_cli_output (vm, "-----------"); } })); /* *INDENT-ON* */ @@ -538,12 +624,11 @@ clib_error_t * policer_init (vlib_main_t * vm) { vnet_policer_main_t *pm = &vnet_policer_main; - void vnet_policer_node_funcs_reference (void); - - vnet_policer_node_funcs_reference (); pm->vlib_main = vm; pm->vnet_main = vnet_get_main (); + pm->log_class = vlib_log_register_class ("policer", 0); + pm->fq_index = vlib_frame_queue_main_init (policer_input_node.index, 0); pm->policer_config_by_name = hash_create_string (0, sizeof (uword)); pm->policer_index_by_name = hash_create_string (0, sizeof (uword));