LCOV - code coverage report
Current view: top level - vnet/fib - fib_node.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 82 83 98.8 %
Date: 2023-10-26 01:39:38 Functions: 19 19 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_node.h>
      17             : #include <vnet/fib/fib_node_list.h>
      18             : #include <vnet/fib/fib_table.h>
      19             : #include <vnet/mfib/mfib_table.h>
      20             : 
      21             : /*
      22             :  * The per-type vector of virtual function tables
      23             :  */
      24             : static fib_node_vft_t *fn_vfts;
      25             : 
      26             : /**
      27             :  * The last registered new type
      28             :  */
      29             : static fib_node_type_t last_new_type = FIB_NODE_TYPE_LAST;
      30             : 
      31             : /*
      32             :  * the node type names
      33             :  */
      34             : static const char *fn_type_builtin_names[] = FIB_NODE_TYPES;
      35             : static const char **fn_type_names;
      36             : 
      37             : const char*
      38         127 : fib_node_type_get_name (fib_node_type_t type)
      39             : {
      40         127 :     if ((type < vec_len(fn_type_names)) &&
      41         127 :          (NULL != fn_type_names[type]))
      42             :     {
      43         127 :         return (fn_type_names[type]);
      44             :     }
      45             :     else
      46             :     {
      47           0 :         return ("unknown");
      48             :     }
      49             : }
      50             : 
      51             : /**
      52             :  * fib_node_register_type
      53             :  *
      54             :  * Register the function table for a given type
      55             :  */
      56             : static void
      57       17826 : fib_node_register_type_i (fib_node_type_t type,
      58             :                           const char *name,
      59             :                           const fib_node_vft_t *vft)
      60             : {
      61             :     /*
      62             :      * assert that one only registration is made per-node type
      63             :      */
      64       17826 :     if (vec_len(fn_vfts) > type)
      65        9775 :         ASSERT(NULL == fn_vfts[type].fnv_get);
      66             : 
      67             :     /*
      68             :      * Assert that we are getting each of the required functions
      69             :      */
      70       17826 :     ASSERT(NULL != vft->fnv_get);
      71       17826 :     ASSERT(NULL != vft->fnv_last_lock);
      72             : 
      73       17826 :     vec_validate(fn_vfts, type);
      74       17826 :     fn_vfts[type] = *vft;
      75       17826 :     vec_validate(fn_type_names, type);
      76       17826 :     fn_type_names[type] = name;
      77       17826 : }
      78             : 
      79             : /**
      80             :  * fib_node_register_type
      81             :  *
      82             :  * Register the function table for a given type
      83             :  */
      84             : void
      85       10925 : fib_node_register_type (fib_node_type_t type,
      86             :                         const fib_node_vft_t *vft)
      87             : {
      88       10925 :     fib_node_register_type_i(type, fn_type_builtin_names[type], vft);
      89       10925 : }
      90             : 
      91             : fib_node_type_t
      92        6901 : fib_node_register_new_type (const char *name,
      93             :                             const fib_node_vft_t *vft)
      94             : {
      95             :     fib_node_type_t new_type;
      96             : 
      97        6901 :     new_type = ++last_new_type;
      98             : 
      99        6901 :     fib_node_register_type_i(new_type, name, vft);
     100             : 
     101        6901 :     return (new_type);
     102             : }   
     103             : 
     104             : static u8*
     105          13 : fib_node_format (fib_node_ptr_t *fnp, u8*s)
     106             : {
     107          13 :     return (format(s, "{%s:%d}", fn_type_names[fnp->fnp_type], fnp->fnp_index)); 
     108             : }
     109             : 
     110             : u32
     111      234999 : fib_node_child_add (fib_node_type_t parent_type,
     112             :                     fib_node_index_t parent_index,
     113             :                     fib_node_type_t type,
     114             :                     fib_node_index_t index)
     115             : {
     116             :     fib_node_t *parent;
     117             : 
     118      234999 :     parent = fn_vfts[parent_type].fnv_get(parent_index);
     119             : 
     120             :     /*
     121             :      * return the index of the sibling in the child list
     122             :      */
     123      234999 :     fib_node_lock(parent);
     124             : 
     125      234999 :     if (FIB_NODE_INDEX_INVALID == parent->fn_children)
     126             :     {
     127      130792 :         parent->fn_children = fib_node_list_create();
     128             :     }   
     129             : 
     130      234999 :     return (fib_node_list_push_front(parent->fn_children,
     131             :                                      0, type,
     132             :                                      index));
     133             : }
     134             : 
     135             : void
     136      215555 : fib_node_child_remove (fib_node_type_t parent_type,
     137             :                        fib_node_index_t parent_index,
     138             :                        fib_node_index_t sibling_index)
     139             : {
     140             :     fib_node_t *parent;
     141             : 
     142      215555 :     parent = fn_vfts[parent_type].fnv_get(parent_index);
     143             : 
     144      215555 :     fib_node_list_remove(parent->fn_children, sibling_index);
     145             : 
     146      215555 :     if (0 == fib_node_list_get_size(parent->fn_children))
     147             :     {
     148      112427 :         fib_node_list_destroy(&parent->fn_children);
     149             :     }
     150             : 
     151      215555 :     fib_node_unlock(parent);
     152      215555 : }
     153             : 
     154             : u32
     155      326233 : fib_node_get_n_children (fib_node_type_t parent_type,
     156             :                          fib_node_index_t parent_index)
     157             : {
     158             :     fib_node_t *parent;
     159             : 
     160      326233 :     parent = fn_vfts[parent_type].fnv_get(parent_index);
     161             : 
     162      326233 :     return (fib_node_list_get_size(parent->fn_children));
     163             : }
     164             : 
     165             : 
     166             : fib_node_back_walk_rc_t
     167       81035 : fib_node_back_walk_one (fib_node_ptr_t *ptr,
     168             :                         fib_node_back_walk_ctx_t *ctx)
     169             : {
     170             :     fib_node_t *node;
     171             : 
     172       81035 :     node = fn_vfts[ptr->fnp_type].fnv_get(ptr->fnp_index);
     173             : 
     174       81035 :     return (fn_vfts[ptr->fnp_type].fnv_back_walk(node, ctx));
     175             : }
     176             : 
     177             : static walk_rc_t
     178          13 : fib_node_ptr_format_one_child (fib_node_ptr_t *ptr,
     179             :                                void *arg)
     180             : {
     181          13 :     u8 **s = (u8**) arg;
     182             : 
     183          13 :     *s = fib_node_format(ptr, *s);
     184             : 
     185          13 :     return (WALK_CONTINUE);
     186             : }
     187             : 
     188             : u8*
     189          10 : fib_node_children_format (fib_node_list_t list,
     190             :                           u8 *s)
     191             : {
     192          10 :     fib_node_list_walk(list, fib_node_ptr_format_one_child, (void*)&s);
     193             : 
     194          10 :     return (s);
     195             : }
     196             : 
     197             : void
     198      319667 : fib_node_init (fib_node_t *node,
     199             :                fib_node_type_t type)
     200             : {
     201             :     /**
     202             :      * The node's type. used to retrieve the VFT.
     203             :      */
     204      319667 :     node->fn_type = type;
     205      319667 :     node->fn_locks = 0;
     206      319667 :     node->fn_children = FIB_NODE_INDEX_INVALID;
     207      319667 : }
     208             : 
     209             : void
     210      258690 : fib_node_deinit (fib_node_t *node)
     211             : {
     212      258690 :     fib_node_list_destroy(&node->fn_children);
     213      258690 : }
     214             : 
     215             : void
     216      877948 : fib_node_lock (fib_node_t *node)
     217             : {
     218      877948 :     node->fn_locks++;
     219      877948 : }
     220             : 
     221             : void
     222      806696 : fib_node_unlock (fib_node_t *node)
     223             : {
     224      806696 :     node->fn_locks--;
     225             : 
     226      806696 :     if (0 == node->fn_locks)
     227             :     {
     228      109787 :         fn_vfts[node->fn_type].fnv_last_lock(node);
     229             :     }
     230      806696 : }
     231             : 
     232             : void
     233           9 : fib_show_memory_usage (const char *name,
     234             :                        u32 in_use_elts,
     235             :                        u32 allocd_elts,
     236             :                        size_t size_elt)
     237             : {
     238           9 :     vlib_cli_output (vlib_get_main(), "%=30s %=5d %=8d/%=9d   %d/%d ",
     239             :                      name, size_elt,
     240             :                      in_use_elts, allocd_elts,
     241             :                      in_use_elts*size_elt, allocd_elts*size_elt);
     242           9 : }
     243             : 
     244             : static clib_error_t *
     245           1 : fib_memory_show (vlib_main_t * vm,
     246             :                  unformat_input_t * input,
     247             :                  vlib_cli_command_t * cmd)
     248             : {
     249             :     fib_node_vft_t *vft;
     250             : 
     251           1 :     vlib_cli_output (vm, "FIB memory");
     252           1 :     vlib_cli_output (vm, "  Tables:");
     253           1 :     vlib_cli_output (vm, "%=30s %=6s %=12s", "SAFI", "Number", "Bytes");
     254           1 :     vlib_cli_output (vm, "%U", format_fib_table_memory);
     255           1 :     vlib_cli_output (vm, "%U", format_mfib_table_memory);
     256           1 :     vlib_cli_output (vm, "  Nodes:");
     257           1 :     vlib_cli_output (vm, "%=30s %=5s %=8s/%=9s   totals",
     258             :                      "Name","Size", "in-use", "allocated");
     259             : 
     260          36 :     vec_foreach(vft, fn_vfts)
     261             :     {
     262          35 :         if (NULL != vft->fnv_mem_show)
     263           5 :             vft->fnv_mem_show();
     264             :     }
     265             : 
     266           1 :     fib_node_list_memory_show();
     267             : 
     268           1 :     return (NULL);
     269             : }
     270             : 
     271             : /* *INDENT-OFF* */
     272             : /*?
     273             :  * The '<em>sh fib memory </em>' command displays the memory usage for each
     274             :  * FIB object type.
     275             :  *
     276             :  * @cliexpar
     277             :  * @cliexstart{show fib memory}
     278             :  *FIB memory
     279             :  * Tables:
     280             :  *            SAFI              Number   Bytes
     281             :  *        IPv4 unicast             2    673066
     282             :  *        IPv6 unicast             2    1054608
     283             :  *            MPLS                 1    4194312
     284             :  *       IPv4 multicast            2     2322
     285             :  *       IPv6 multicast            2      ???
     286             :  * Nodes:
     287             :  *            Name               Size  in-use /allocated   totals
     288             :  *            Entry               96     20   /    20      1920/1920
     289             :  *        Entry Source            32      0   /    0       0/0
     290             :  *    Entry Path-Extensions       60      0   /    0       0/0
     291             :  *       multicast-Entry         192     12   /    12      2304/2304
     292             :  *          Path-list             40     28   /    28      1120/1120
     293             :  *          uRPF-list             16     20   /    20      320/320
     294             :  *            Path                72     28   /    28      2016/2016
     295             :  *     Node-list elements         20     28   /    28      560/560
     296             :  *       Node-list heads          8      30   /    30      240/240
     297             :  * @cliexend
     298             : ?*/
     299      285289 : VLIB_CLI_COMMAND (show_fib_memory, static) = {
     300             :     .path = "show fib memory",
     301             :     .function = fib_memory_show,
     302             :     .short_help = "show fib memory",
     303             : };
     304             : /* *INDENT-ON* */

Generated by: LCOV version 1.14