LCOV - code coverage report
Current view: top level - vnet/policer - policer_api.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 119 215 55.3 %
Date: 2023-07-05 22:20:52 Functions: 13 18 72.2 %

          Line data    Source code
       1             : /*
       2             :  *------------------------------------------------------------------
       3             :  * policer_api.c - policer api
       4             :  *
       5             :  * Copyright (c) 2016 Cisco and/or its affiliates.
       6             :  * Licensed under the Apache License, Version 2.0 (the "License");
       7             :  * you may not use this file except in compliance with the License.
       8             :  * You may obtain a copy of the License at:
       9             :  *
      10             :  *     http://www.apache.org/licenses/LICENSE-2.0
      11             :  *
      12             :  * Unless required by applicable law or agreed to in writing, software
      13             :  * distributed under the License is distributed on an "AS IS" BASIS,
      14             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15             :  * See the License for the specific language governing permissions and
      16             :  * limitations under the License.
      17             :  *------------------------------------------------------------------
      18             :  */
      19             : 
      20             : #include <vnet/vnet.h>
      21             : #include <vlibmemory/api.h>
      22             : 
      23             : #include <vnet/interface.h>
      24             : #include <vnet/api_errno.h>
      25             : #include <vnet/policer/policer.h>
      26             : 
      27             : #include <vnet/format_fns.h>
      28             : #include <vnet/policer/policer.api_enum.h>
      29             : #include <vnet/policer/policer.api_types.h>
      30             : 
      31             : #define REPLY_MSG_ID_BASE vnet_policer_main.msg_id_base
      32             : #include <vlibapi/api_helper_macros.h>
      33             : 
      34             : static void
      35           0 : vl_api_policer_add_del_t_handler (vl_api_policer_add_del_t * mp)
      36             : {
      37           0 :   vlib_main_t *vm = vlib_get_main ();
      38           0 :   vnet_policer_main_t *pm = &vnet_policer_main;
      39             :   vl_api_policer_add_del_reply_t *rmp;
      40           0 :   int rv = 0;
      41             :   uword *p;
      42             :   char name[sizeof (mp->name) + 1];
      43             :   qos_pol_cfg_params_st cfg;
      44             :   u32 policer_index;
      45             : 
      46           0 :   snprintf (name, sizeof (name), "%s", mp->name);
      47             : 
      48           0 :   if (mp->is_add)
      49             :     {
      50           0 :       clib_memset (&cfg, 0, sizeof (cfg));
      51           0 :       cfg.rfc = (qos_policer_type_en) mp->type;
      52           0 :       cfg.rnd_type = (qos_round_type_en) mp->round_type;
      53           0 :       cfg.rate_type = (qos_rate_type_en) mp->rate_type;
      54           0 :       cfg.rb.kbps.cir_kbps = ntohl (mp->cir);
      55           0 :       cfg.rb.kbps.eir_kbps = ntohl (mp->eir);
      56           0 :       cfg.rb.kbps.cb_bytes = clib_net_to_host_u64 (mp->cb);
      57           0 :       cfg.rb.kbps.eb_bytes = clib_net_to_host_u64 (mp->eb);
      58           0 :       cfg.conform_action.action_type =
      59           0 :         (qos_action_type_en) mp->conform_action.type;
      60           0 :       cfg.conform_action.dscp = mp->conform_action.dscp;
      61           0 :       cfg.exceed_action.action_type =
      62           0 :         (qos_action_type_en) mp->exceed_action.type;
      63           0 :       cfg.exceed_action.dscp = mp->exceed_action.dscp;
      64           0 :       cfg.violate_action.action_type =
      65           0 :         (qos_action_type_en) mp->violate_action.type;
      66           0 :       cfg.violate_action.dscp = mp->violate_action.dscp;
      67           0 :       cfg.color_aware = mp->color_aware;
      68             : 
      69           0 :       rv = policer_add (vm, (u8 *) name, &cfg, &policer_index);
      70             :     }
      71             :   else
      72             :     {
      73           0 :       p = hash_get_mem (pm->policer_index_by_name, name);
      74             : 
      75           0 :       rv = VNET_API_ERROR_NO_SUCH_ENTRY;
      76           0 :       if (p != NULL)
      77           0 :         rv = policer_del (vm, p[0]);
      78             :     }
      79             : 
      80           0 :   REPLY_MACRO2 (VL_API_POLICER_ADD_DEL_REPLY, ({
      81             :                   if (rv == 0 && mp->is_add)
      82             :                     rmp->policer_index = htonl (policer_index);
      83             :                   else
      84             :                     rmp->policer_index = ~0;
      85             :                 }));
      86             : }
      87             : 
      88             : static_always_inline void
      89          29 : policer_set_configuration (qos_pol_cfg_params_st *cfg,
      90             :                            vl_api_policer_config_t *infos)
      91             : {
      92          29 :   clib_memset (cfg, 0, sizeof (*cfg));
      93          29 :   cfg->rfc = (qos_policer_type_en) infos->type;
      94          29 :   cfg->rnd_type = (qos_round_type_en) infos->round_type;
      95          29 :   cfg->rate_type = (qos_rate_type_en) infos->rate_type;
      96          29 :   cfg->rb.kbps.cir_kbps = ntohl (infos->cir);
      97          29 :   cfg->rb.kbps.eir_kbps = ntohl (infos->eir);
      98          29 :   cfg->rb.kbps.cb_bytes = clib_net_to_host_u64 (infos->cb);
      99          29 :   cfg->rb.kbps.eb_bytes = clib_net_to_host_u64 (infos->eb);
     100          29 :   cfg->conform_action.action_type =
     101          29 :     (qos_action_type_en) infos->conform_action.type;
     102          29 :   cfg->conform_action.dscp = infos->conform_action.dscp;
     103          29 :   cfg->exceed_action.action_type =
     104          29 :     (qos_action_type_en) infos->exceed_action.type;
     105          29 :   cfg->exceed_action.dscp = infos->exceed_action.dscp;
     106          29 :   cfg->violate_action.action_type =
     107          29 :     (qos_action_type_en) infos->violate_action.type;
     108          29 :   cfg->violate_action.dscp = infos->violate_action.dscp;
     109          29 :   cfg->color_aware = infos->color_aware;
     110          29 : }
     111             : 
     112             : static void
     113          28 : vl_api_policer_add_t_handler (vl_api_policer_add_t *mp)
     114             : {
     115          28 :   vlib_main_t *vm = vlib_get_main ();
     116             :   vl_api_policer_add_reply_t *rmp;
     117          28 :   int rv = 0;
     118             :   char name[sizeof (mp->name) + 1];
     119             :   qos_pol_cfg_params_st cfg;
     120             :   u32 policer_index;
     121             : 
     122          28 :   snprintf (name, sizeof (name), "%s", mp->name);
     123             : 
     124          28 :   policer_set_configuration (&cfg, &mp->infos);
     125             : 
     126          28 :   rv = policer_add (vm, (u8 *) name, &cfg, &policer_index);
     127             : 
     128          28 :   REPLY_MACRO2 (VL_API_POLICER_ADD_REPLY, ({
     129             :                   if (rv == 0)
     130             :                     rmp->policer_index = htonl (policer_index);
     131             :                   else
     132             :                     rmp->policer_index = ~0;
     133             :                 }));
     134             : }
     135             : 
     136             : static void
     137          28 : vl_api_policer_del_t_handler (vl_api_policer_del_t *mp)
     138             : {
     139          28 :   vlib_main_t *vm = vlib_get_main ();
     140             :   vl_api_policer_del_reply_t *rmp;
     141             :   u32 policer_index;
     142          28 :   int rv = 0;
     143             : 
     144          28 :   policer_index = ntohl (mp->policer_index);
     145          28 :   rv = policer_del (vm, policer_index);
     146             : 
     147          28 :   REPLY_MACRO (VL_API_POLICER_DEL_REPLY);
     148             : }
     149             : 
     150             : static void
     151           1 : vl_api_policer_update_t_handler (vl_api_policer_update_t *mp)
     152             : {
     153           1 :   vlib_main_t *vm = vlib_get_main ();
     154             :   vl_api_policer_update_reply_t *rmp;
     155           1 :   int rv = 0;
     156             :   qos_pol_cfg_params_st cfg;
     157             :   u32 policer_index;
     158             : 
     159           1 :   policer_set_configuration (&cfg, &mp->infos);
     160             : 
     161           1 :   policer_index = ntohl (mp->policer_index);
     162           1 :   rv = policer_update (vm, policer_index, &cfg);
     163             : 
     164           1 :   REPLY_MACRO (VL_API_POLICER_UPDATE_REPLY);
     165             : }
     166             : 
     167             : static void
     168           1 : vl_api_policer_reset_t_handler (vl_api_policer_reset_t *mp)
     169             : {
     170           1 :   vlib_main_t *vm = vlib_get_main ();
     171             :   vl_api_policer_reset_reply_t *rmp;
     172             :   u32 policer_index;
     173           1 :   int rv = 0;
     174             : 
     175           1 :   policer_index = ntohl (mp->policer_index);
     176           1 :   rv = policer_reset (vm, policer_index);
     177             : 
     178           1 :   REPLY_MACRO (VL_API_POLICER_RESET_REPLY);
     179             : }
     180             : 
     181             : static void
     182           0 : vl_api_policer_bind_t_handler (vl_api_policer_bind_t *mp)
     183             : {
     184             :   vl_api_policer_bind_reply_t *rmp;
     185           0 :   vnet_policer_main_t *pm = &vnet_policer_main;
     186             :   char name[sizeof (mp->name) + 1];
     187             :   uword *p;
     188             :   u32 worker_index;
     189             :   u8 bind_enable;
     190             :   int rv;
     191             : 
     192           0 :   snprintf (name, sizeof (name), "%s", mp->name);
     193             : 
     194           0 :   worker_index = ntohl (mp->worker_index);
     195           0 :   bind_enable = mp->bind_enable;
     196             : 
     197           0 :   p = hash_get_mem (pm->policer_index_by_name, name);
     198             : 
     199           0 :   rv = VNET_API_ERROR_NO_SUCH_ENTRY;
     200           0 :   if (p != NULL)
     201           0 :     rv = policer_bind_worker (p[0], worker_index, bind_enable);
     202             : 
     203           0 :   REPLY_MACRO (VL_API_POLICER_BIND_REPLY);
     204             : }
     205             : 
     206             : static void
     207          12 : vl_api_policer_bind_v2_t_handler (vl_api_policer_bind_v2_t *mp)
     208             : {
     209             :   vl_api_policer_bind_v2_reply_t *rmp;
     210             :   u32 policer_index;
     211             :   u32 worker_index;
     212             :   u8 bind_enable;
     213             :   int rv;
     214             : 
     215          12 :   policer_index = ntohl (mp->policer_index);
     216          12 :   worker_index = ntohl (mp->worker_index);
     217          12 :   bind_enable = mp->bind_enable;
     218             : 
     219          12 :   rv = policer_bind_worker (policer_index, worker_index, bind_enable);
     220             : 
     221          12 :   REPLY_MACRO (VL_API_POLICER_BIND_V2_REPLY);
     222             : }
     223             : 
     224             : static void
     225           0 : vl_api_policer_input_t_handler (vl_api_policer_input_t *mp)
     226             : {
     227             :   vl_api_policer_input_reply_t *rmp;
     228           0 :   vnet_policer_main_t *pm = &vnet_policer_main;
     229             :   char name[sizeof (mp->name) + 1];
     230             :   uword *p;
     231             :   u32 sw_if_index;
     232             :   u8 apply;
     233             :   int rv;
     234             : 
     235           0 :   VALIDATE_SW_IF_INDEX (mp);
     236             : 
     237           0 :   snprintf (name, sizeof (name), "%s", mp->name);
     238             : 
     239           0 :   sw_if_index = ntohl (mp->sw_if_index);
     240           0 :   apply = mp->apply;
     241             : 
     242           0 :   p = hash_get_mem (pm->policer_index_by_name, name);
     243             : 
     244           0 :   rv = VNET_API_ERROR_NO_SUCH_ENTRY;
     245           0 :   if (p != NULL)
     246           0 :     rv = policer_input (p[0], sw_if_index, VLIB_RX, apply);
     247             : 
     248           0 :   BAD_SW_IF_INDEX_LABEL;
     249           0 :   REPLY_MACRO (VL_API_POLICER_INPUT_REPLY);
     250             : }
     251             : 
     252             : static void
     253          16 : vl_api_policer_input_v2_t_handler (vl_api_policer_input_v2_t *mp)
     254             : {
     255             :   vl_api_policer_input_v2_reply_t *rmp;
     256             :   u32 policer_index;
     257             :   u32 sw_if_index;
     258             :   u8 apply;
     259             :   int rv;
     260             : 
     261          16 :   VALIDATE_SW_IF_INDEX (mp);
     262             : 
     263          16 :   policer_index = ntohl (mp->policer_index);
     264          16 :   sw_if_index = ntohl (mp->sw_if_index);
     265          16 :   apply = mp->apply;
     266             : 
     267          16 :   rv = policer_input (policer_index, sw_if_index, VLIB_RX, apply);
     268             : 
     269          16 :   BAD_SW_IF_INDEX_LABEL;
     270          16 :   REPLY_MACRO (VL_API_POLICER_INPUT_REPLY);
     271             : }
     272             : 
     273             : static void
     274           0 : vl_api_policer_output_t_handler (vl_api_policer_output_t *mp)
     275             : {
     276             :   vl_api_policer_output_reply_t *rmp;
     277           0 :   vnet_policer_main_t *pm = &vnet_policer_main;
     278             :   char name[sizeof (mp->name) + 1];
     279             :   uword *p;
     280             :   u32 sw_if_index;
     281             :   u8 apply;
     282             :   int rv;
     283             : 
     284           0 :   VALIDATE_SW_IF_INDEX (mp);
     285             : 
     286           0 :   snprintf (name, sizeof (name), "%s", mp->name);
     287             : 
     288           0 :   sw_if_index = ntohl (mp->sw_if_index);
     289           0 :   apply = mp->apply;
     290             : 
     291           0 :   p = hash_get_mem (pm->policer_index_by_name, name);
     292             : 
     293           0 :   rv = VNET_API_ERROR_NO_SUCH_ENTRY;
     294           0 :   if (p != NULL)
     295           0 :     rv = policer_input (p[0], sw_if_index, VLIB_TX, apply);
     296             : 
     297           0 :   BAD_SW_IF_INDEX_LABEL;
     298           0 :   REPLY_MACRO (VL_API_POLICER_OUTPUT_REPLY);
     299             : }
     300             : 
     301             : static void
     302           4 : vl_api_policer_output_v2_t_handler (vl_api_policer_output_v2_t *mp)
     303             : {
     304             :   vl_api_policer_output_reply_t *rmp;
     305             :   u32 policer_index;
     306             :   u32 sw_if_index;
     307             :   u8 apply;
     308             :   int rv;
     309             : 
     310           4 :   VALIDATE_SW_IF_INDEX (mp);
     311             : 
     312           4 :   policer_index = ntohl (mp->policer_index);
     313           4 :   sw_if_index = ntohl (mp->sw_if_index);
     314           4 :   apply = mp->apply;
     315             : 
     316           4 :   rv = policer_input (policer_index, sw_if_index, VLIB_TX, apply);
     317             : 
     318           4 :   BAD_SW_IF_INDEX_LABEL;
     319           4 :   REPLY_MACRO (VL_API_POLICER_OUTPUT_REPLY);
     320             : }
     321             : 
     322             : static void
     323           4 : send_policer_details (qos_pol_cfg_params_st *config, policer_t *policer,
     324             :                       vl_api_registration_t *reg, u32 context)
     325             : {
     326             :   vl_api_policer_details_t *mp;
     327             : 
     328           4 :   mp = vl_msg_api_alloc (sizeof (*mp));
     329           4 :   clib_memset (mp, 0, sizeof (*mp));
     330           4 :   mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_POLICER_DETAILS);
     331           4 :   mp->context = context;
     332           4 :   mp->cir = htonl (config->rb.kbps.cir_kbps);
     333           4 :   mp->eir = htonl (config->rb.kbps.eir_kbps);
     334           4 :   mp->cb = clib_host_to_net_u64 (config->rb.kbps.cb_bytes);
     335           4 :   mp->eb = clib_host_to_net_u64 (config->rb.kbps.eb_bytes);
     336           4 :   mp->rate_type = (vl_api_sse2_qos_rate_type_t) config->rate_type;
     337           4 :   mp->round_type = (vl_api_sse2_qos_round_type_t) config->rnd_type;
     338           4 :   mp->type = (vl_api_sse2_qos_policer_type_t) config->rfc;
     339           4 :   mp->conform_action.type =
     340           4 :     (vl_api_sse2_qos_action_type_t) policer->action[POLICE_CONFORM];
     341           4 :   mp->conform_action.dscp = policer->mark_dscp[POLICE_CONFORM];
     342           4 :   mp->exceed_action.type =
     343           4 :     (vl_api_sse2_qos_action_type_t) policer->action[POLICE_EXCEED];
     344           4 :   mp->exceed_action.dscp = policer->mark_dscp[POLICE_EXCEED];
     345           4 :   mp->violate_action.type =
     346           4 :     (vl_api_sse2_qos_action_type_t) policer->action[POLICE_VIOLATE];
     347           4 :   mp->violate_action.dscp = policer->mark_dscp[POLICE_VIOLATE];
     348           4 :   mp->single_rate = policer->single_rate ? 1 : 0;
     349           4 :   mp->color_aware = policer->color_aware ? 1 : 0;
     350           4 :   mp->scale = htonl (policer->scale);
     351           4 :   mp->cir_tokens_per_period = htonl (policer->cir_tokens_per_period);
     352           4 :   mp->pir_tokens_per_period = htonl (policer->pir_tokens_per_period);
     353           4 :   mp->current_limit = htonl (policer->current_limit);
     354           4 :   mp->current_bucket = htonl (policer->current_bucket);
     355           4 :   mp->extended_limit = htonl (policer->extended_limit);
     356           4 :   mp->extended_bucket = htonl (policer->extended_bucket);
     357           4 :   mp->last_update_time = clib_host_to_net_u64 (policer->last_update_time);
     358             : 
     359           4 :   strncpy ((char *) mp->name, (char *) policer->name,
     360             :            ARRAY_LEN (mp->name) - 1);
     361             : 
     362           4 :   vl_api_send_msg (reg, (u8 *) mp);
     363           4 : }
     364             : 
     365             : static void
     366           0 : vl_api_policer_dump_t_handler (vl_api_policer_dump_t * mp)
     367             : {
     368             :   vl_api_registration_t *reg;
     369           0 :   vnet_policer_main_t *pm = &vnet_policer_main;
     370             :   uword *p, *pi;
     371             :   u32 pool_index, policer_index;
     372           0 :   u8 *match_name = 0;
     373             :   qos_pol_cfg_params_st *config;
     374             :   policer_t *policer;
     375             : 
     376           0 :   reg = vl_api_client_index_to_registration (mp->client_index);
     377           0 :   if (!reg)
     378           0 :     return;
     379             : 
     380           0 :   if (mp->match_name_valid)
     381             :     {
     382           0 :       match_name = format (0, "%s%c", mp->match_name, 0);
     383           0 :       vec_terminate_c_string (match_name);
     384             :     }
     385             : 
     386           0 :   if (mp->match_name_valid)
     387             :     {
     388           0 :       p = hash_get_mem (pm->policer_config_by_name, match_name);
     389           0 :       pi = hash_get_mem (pm->policer_index_by_name, match_name);
     390           0 :       if (0 == p || 0 == pi)
     391           0 :         return;
     392             : 
     393           0 :       pool_index = p[0];
     394           0 :       policer_index = pi[0];
     395           0 :       config = pool_elt_at_index (pm->configs, pool_index);
     396           0 :       policer = pool_elt_at_index (pm->policers, policer_index);
     397           0 :       send_policer_details (config, policer, reg, mp->context);
     398             :     }
     399             :   else
     400             :     {
     401           0 :       pool_foreach (policer, pm->policers)
     402             :         {
     403           0 :           p = hash_get_mem (pm->policer_config_by_name, policer->name);
     404           0 :           if (0 == p)
     405           0 :             continue;
     406             : 
     407           0 :           pool_index = p[0];
     408           0 :           config = pool_elt_at_index (pm->configs, pool_index);
     409           0 :           send_policer_details (config, policer, reg, mp->context);
     410             :         };
     411             :     }
     412             : }
     413             : 
     414             : static void
     415          22 : vl_api_policer_dump_v2_t_handler (vl_api_policer_dump_v2_t *mp)
     416             : {
     417             :   vl_api_registration_t *reg;
     418          22 :   vnet_policer_main_t *pm = &vnet_policer_main;
     419             :   qos_pol_cfg_params_st *config;
     420             :   u32 policer_index, pool_index;
     421             :   policer_t *policer;
     422             :   uword *p;
     423             : 
     424          22 :   reg = vl_api_client_index_to_registration (mp->client_index);
     425          22 :   if (!reg)
     426           0 :     return;
     427             : 
     428          22 :   policer_index = ntohl (mp->policer_index);
     429             : 
     430          22 :   if (~0 == policer_index)
     431             :     {
     432          18 :       pool_foreach (policer, pm->policers)
     433             :         {
     434           0 :           p = hash_get_mem (pm->policer_config_by_name, policer->name);
     435           0 :           pool_index = p[0];
     436           0 :           config = pool_elt_at_index (pm->configs, pool_index);
     437           0 :           send_policer_details (config, policer, reg, mp->context);
     438             :         };
     439             :     }
     440             :   else
     441             :     {
     442           4 :       if (pool_is_free_index (pm->policers, policer_index))
     443           0 :         return;
     444             : 
     445           4 :       policer = &pm->policers[policer_index];
     446           8 :       p = hash_get_mem (pm->policer_config_by_name, policer->name);
     447           4 :       pool_index = p[0];
     448           4 :       config = pool_elt_at_index (pm->configs, pool_index);
     449           4 :       send_policer_details (config, policer, reg, mp->context);
     450             :     }
     451             : }
     452             : 
     453             : #include <vnet/policer/policer.api.c>
     454             : static clib_error_t *
     455         559 : policer_api_hookup (vlib_main_t * vm)
     456             : {
     457             :   /*
     458             :    * Set up the (msg_name, crc, message-id) table
     459             :    */
     460         559 :   REPLY_MSG_ID_BASE = setup_message_id_table ();
     461             : 
     462         559 :   return 0;
     463             : }
     464             : 
     465        2239 : VLIB_API_INIT_FUNCTION (policer_api_hookup);
     466             : 
     467             : /*
     468             :  * fd.io coding-style-patch-verification: ON
     469             :  *
     470             :  * Local Variables:
     471             :  * eval: (c-set-style "gnu")
     472             :  * End:
     473             :  */

Generated by: LCOV version 1.14