LCOV - code coverage report
Current view: top level - vnet/fib - fib_source.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 68 71 95.8 %
Date: 2023-07-05 22:20:52 Functions: 14 14 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2016 Cisco and/or its affiliates.
       3             :  * Licensed under the Apache License, Version 2.0 (the "License");
       4             :  * you may not use this file except in compliance with the License.
       5             :  * You may obtain a copy of the License at:
       6             :  *
       7             :  *     http://www.apache.org/licenses/LICENSE-2.0
       8             :  *
       9             :  * Unless required by applicable law or agreed to in writing, software
      10             :  * distributed under the License is distributed on an "AS IS" BASIS,
      11             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             :  * See the License for the specific language governing permissions and
      13             :  * limitations under the License.
      14             :  */
      15             : 
      16             : #include <vnet/fib/fib_source.h>
      17             : 
      18             : static const char *fib_source_names[] = FIB_SOURCES;
      19             : static const char *fib_source_behaviour_names[] = FIB_SOURCE_BEHAVIOURS;
      20             : 
      21             : static fib_source_t fib_source_id = FIB_SOURCE_LAST+1;
      22             : 
      23             : typedef struct fib_source_prio_t_
      24             : {
      25             :     fib_source_priority_t fsp_class;
      26             :     fib_source_priority_t fsp_slot;
      27             : } fib_source_prio_t;
      28             : 
      29             : /**
      30             :  * for each client requested priority count the number pf uses of
      31             :  * that prio so we can asign is usage a slot number, and therefore
      32             :  * each request will have a unique value.
      33             :  */
      34             : STATIC_ASSERT_SIZEOF(fib_source_priority_t, 1);
      35             : static fib_source_priority_t fib_source_prio_by_class[0x100];
      36             : 
      37             : typedef struct fib_source_reg_t_
      38             : {
      39             :     fib_source_t fsr_source;
      40             :     const char *fsr_name;
      41             :     fib_source_behaviour_t fsr_behaviour;
      42             :     fib_source_prio_t fsr_prio;
      43             : } fib_source_reg_t;
      44             : 
      45             : static fib_source_reg_t *fib_source_regs;
      46             : 
      47             : 
      48             : u16
      49      190572 : fib_source_get_prio (fib_source_t src)
      50             : {
      51      190572 :     ASSERT(vec_len(fib_source_regs) > src);
      52             : 
      53      381144 :     return (((u16)fib_source_regs[src].fsr_prio.fsp_class << 8) |
      54      190572 :             fib_source_regs[src].fsr_prio.fsp_slot);
      55             : }
      56             : 
      57             : fib_source_behaviour_t
      58      554076 : fib_source_get_behaviour (fib_source_t src)
      59             : {
      60      554076 :     ASSERT(vec_len(fib_source_regs) > src);
      61             : 
      62      554076 :     return (fib_source_regs[src].fsr_behaviour);
      63             : }
      64             : 
      65             : u8 *
      66        1451 : format_fib_source (u8 *s, va_list *a)
      67             : {
      68        1451 :     fib_source_t src = va_arg(*a, int);
      69             : 
      70        1451 :     ASSERT(vec_len(fib_source_regs) > src);
      71             : 
      72        1451 :     return (format(s, "%s", fib_source_regs[src].fsr_name));
      73             : }
      74             : 
      75             : fib_source_priority_cmp_t
      76       45583 : fib_source_cmp (fib_source_t s1,
      77             :                 fib_source_t s2)
      78             : {
      79       91166 :     if (fib_source_get_prio(s1) <
      80       45583 :         fib_source_get_prio(s2))
      81             :     {
      82         304 :         return (FIB_SOURCE_CMP_BETTER);
      83             :     }
      84       90558 :     else if (fib_source_get_prio(s1) >
      85       45279 :              fib_source_get_prio(s2))
      86             :     {
      87       11377 :         return (FIB_SOURCE_CMP_WORSE);
      88             :     }
      89       33902 :     return (FIB_SOURCE_CMP_EQUAL);
      90             : }
      91             : 
      92             : static void
      93       21244 : fib_source_reg_init (fib_source_t src,
      94             :                      const char *name,
      95             :                      fib_source_priority_t prio,
      96             :                      fib_source_behaviour_t bh)
      97             : {
      98             :     fib_source_priority_t slot;
      99             :     fib_source_reg_t *fsr;
     100             : 
     101             :     /*
     102             :      * ensure we assign a unique priority to each request
     103             :      * otherwise different source will be treated like ECMP
     104             :      */
     105       21244 :     slot = fib_source_prio_by_class[prio]++;
     106             : 
     107       21244 :     vec_validate(fib_source_regs, src);
     108             : 
     109       21244 :     fsr = &fib_source_regs[src];
     110       21244 :     fsr->fsr_source = src;
     111       21244 :     fsr->fsr_name = strdup(name);
     112       21244 :     fsr->fsr_prio.fsp_class = prio;
     113       21244 :     fsr->fsr_prio.fsp_slot = slot;
     114       21244 :     fsr->fsr_behaviour = bh;
     115       21244 : }
     116             : 
     117             : fib_source_t
     118        8946 : fib_source_allocate (const char *name,
     119             :                      fib_source_priority_t prio,
     120             :                      fib_source_behaviour_t bh)
     121             : {
     122             :     fib_source_t src;
     123             : 
     124             :     // max value range
     125        8946 :     ASSERT(fib_source_id < 255);
     126        8946 :     if (fib_source_id == 255)
     127           0 :         return (FIB_SOURCE_INVALID);
     128             : 
     129        8946 :     src = fib_source_id++;
     130             : 
     131        8946 :     fib_source_reg_init(src, name, prio, bh);
     132             : 
     133        8946 :     return (src);
     134             : }
     135             : 
     136             : void
     137       12298 : fib_source_register (fib_source_t src,
     138             :                      fib_source_priority_t prio,
     139             :                      fib_source_behaviour_t bh)
     140             : {
     141       12298 :     fib_source_reg_init(src, fib_source_names[src], prio, bh);
     142       12298 : }
     143             : 
     144             : static u8 *
     145          78 : format_fib_source_reg (u8 *s, va_list *a)
     146             : {
     147          78 :     fib_source_reg_t *fsr = va_arg(*a, fib_source_reg_t*);
     148             : 
     149          78 :     s = format(s, "[%d] %U prio:%d.%d behaviour:%s",
     150          78 :                fsr->fsr_source,
     151          78 :                format_fib_source, fsr->fsr_source,
     152          78 :                fsr->fsr_prio.fsp_class, fsr->fsr_prio.fsp_slot,
     153          78 :                fib_source_behaviour_names[fsr->fsr_behaviour]);
     154             : 
     155          78 :     return (s);
     156             : }
     157             : 
     158             : static int
     159         150 : fib_source_reg_cmp_for_sort (void * v1,
     160             :                              void * v2)
     161             : {
     162         150 :     fib_source_reg_t *fsr1 = v1, *fsr2 = v2;
     163             : 
     164         150 :     return (fib_source_get_prio(fsr1->fsr_source) -
     165         150 :             fib_source_get_prio(fsr2->fsr_source));
     166             : }
     167             : 
     168             : void
     169           2 : fib_source_walk (fib_source_walk_t fn,
     170             :                  void *ctx)
     171             : {
     172             :     fib_source_reg_t *fsr;
     173             : 
     174          79 :     vec_foreach(fsr, fib_source_regs)
     175             :     {
     176          77 :         if (WALK_STOP == fn(fsr->fsr_source,
     177             :                             fsr->fsr_name,
     178          77 :                             fsr->fsr_prio.fsp_class,
     179             :                             fsr->fsr_behaviour,
     180             :                             ctx))
     181           0 :             break;
     182             :     }
     183           2 : }
     184             : 
     185             : static clib_error_t *
     186           2 : fib_source_show (vlib_main_t * vm,
     187             :                  unformat_input_t * input,
     188             :                  vlib_cli_command_t * cmd)
     189             : {
     190             :     fib_source_reg_t *fsr, *fsrs;
     191             : 
     192           2 :     fsrs = vec_dup(fib_source_regs);
     193             : 
     194           3 :     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     195             :     {
     196           1 :         if (unformat (input, "prio")   ||
     197           0 :             unformat (input, "priority"))
     198           1 :             vec_sort_with_function(fsrs, fib_source_reg_cmp_for_sort);
     199             :     }
     200          80 :     vec_foreach(fsr, fsrs)
     201             :     {
     202          78 :         vlib_cli_output(vm, "%U", format_fib_source_reg, fsr);
     203             :     }
     204           2 :     vec_free(fsrs);
     205             : 
     206           2 :     return (NULL);
     207             : }
     208             : 
     209      272887 : VLIB_CLI_COMMAND (show_fib_sources, static) = {
     210             :     .path = "show fib source",
     211             :     .function = fib_source_show,
     212             :     .short_help = "show fib source [prio]",
     213             : };
     214             : 
     215             : 
     216             : void
     217         559 : fib_source_module_init (void)
     218             : {
     219             : #define _(s,p,b) fib_source_register(s,p,b);
     220         559 :     foreach_fib_source
     221             : #undef _
     222         559 : }

Generated by: LCOV version 1.14