LCOV - code coverage report
Current view: top level - vnet/fib - fib_entry_track.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 43 43 100.0 %
Date: 2023-10-26 01:39:38 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2019 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_entry_track.h>
      17             : #include <vnet/fib/fib_table.h>
      18             : #include <vnet/fib/fib_entry_delegate.h>
      19             : #include <vnet/fib/fib_walk.h>
      20             : 
      21             : static fib_entry_delegate_t *
      22        3905 : fib_entry_track_delegate_add (u32 fib_index,
      23             :                               const fib_prefix_t *prefix)
      24             : {
      25             :     fib_entry_delegate_t *fed;
      26             :     fib_node_index_t fei;
      27             : 
      28        3905 :     fei = fib_table_entry_special_add(fib_index,
      29             :                                       prefix,
      30             :                                       FIB_SOURCE_RR,
      31             :                                       FIB_ENTRY_FLAG_NONE);
      32             : 
      33        3905 :     fed = fib_entry_delegate_find_or_add(fib_entry_get(fei),
      34             :                                          FIB_ENTRY_DELEGATE_TRACK);
      35             : 
      36        3905 :     fib_node_init(&fed->fd_track.fedt_node,
      37             :                   FIB_NODE_TYPE_ENTRY_TRACK);
      38             : 
      39        3905 :     fed->fd_entry_index = fei;
      40        3905 :     fed->fd_track.fedt_sibling =
      41        3905 :         fib_entry_child_add(fei,
      42             :                             FIB_NODE_TYPE_ENTRY_TRACK,
      43             :                             fib_entry_delegate_get_index(fed));
      44             : 
      45        3905 :     return (fed);
      46             : }
      47             : 
      48             : fib_node_index_t
      49        4357 : fib_entry_track (u32 fib_index,
      50             :                  const fib_prefix_t *prefix,
      51             :                  fib_node_type_t child_type,
      52             :                  index_t child_index,
      53             :                  u32 *sibling)
      54             : {
      55             :     fib_entry_delegate_t *fed;
      56             :     fib_node_index_t fei;
      57             : 
      58        4357 :     fei = fib_table_lookup_exact_match(fib_index, prefix);
      59             : 
      60        8699 :     if (INDEX_INVALID == fei ||
      61        4342 :         NULL == (fed = fib_entry_delegate_find(fib_entry_get(fei),
      62             :                                                FIB_ENTRY_DELEGATE_TRACK)))
      63             :     {
      64        3905 :         fed = fib_entry_track_delegate_add(fib_index, prefix);
      65             :     }
      66             : 
      67             :     /*
      68             :      * add this child to the entry's delegate
      69             :      */
      70        4357 :     *sibling = fib_node_child_add(FIB_NODE_TYPE_ENTRY_TRACK,
      71             :                                   fib_entry_delegate_get_index(fed),
      72             :                                   child_type,
      73             :                                   child_index);
      74             : 
      75        4357 :     return (fed->fd_entry_index);
      76             : }
      77             : 
      78             : void
      79        4300 : fib_entry_untrack (fib_node_index_t fei,
      80             :                    u32 sibling)
      81             : {
      82             :     fib_entry_delegate_t *fed;
      83             : 
      84        4300 :     fed = fib_entry_delegate_find(fib_entry_get(fei),
      85             :                                   FIB_ENTRY_DELEGATE_TRACK);
      86             : 
      87        4300 :     if (NULL != fed)
      88             :     {
      89        4300 :         fib_node_child_remove(FIB_NODE_TYPE_ENTRY_TRACK,
      90             :                               fib_entry_delegate_get_index(fed),
      91             :                               sibling);
      92             :         /* if this is the last child the delegate will be removed. */
      93             :     }
      94             :     /* else untracked */
      95        4300 : }
      96             : 
      97             : static fib_node_t *
      98       11185 : fib_entry_track_get_node (fib_node_index_t index)
      99             : {
     100             :     fib_entry_delegate_t *fed;
     101             : 
     102       11185 :     fed = fib_entry_delegate_get(index);
     103       11185 :     return (&fed->fd_track.fedt_node);
     104             : }
     105             : 
     106             : static fib_entry_delegate_t*
     107        4504 : fib_entry_delegate_from_fib_node (fib_node_t *node)
     108             : {
     109        4504 :     ASSERT(FIB_NODE_TYPE_ENTRY_TRACK == node->fn_type);
     110        4504 :     return ((fib_entry_delegate_t *) (((char *) node) -
     111             :                                       STRUCT_OFFSET_OF (fib_entry_delegate_t,
     112             :                                                         fd_track.fedt_node)));
     113             : }
     114             : 
     115             : static void
     116        3872 : fib_entry_track_last_lock_gone (fib_node_t *node)
     117             : {
     118             :     fib_entry_delegate_t *fed;
     119             :     fib_node_index_t fei;
     120             :     u32 sibling;
     121             : 
     122        3872 :     fed = fib_entry_delegate_from_fib_node(node);
     123        3872 :     fei = fed->fd_entry_index;
     124        3872 :     sibling = fed->fd_track.fedt_sibling;
     125             : 
     126             :     /*
     127             :      * the tracker has no more children so it can be removed,
     128             :      * and the FIB entry unsourced.
     129             :      * remove the delegate first, then unlock the fib entry,
     130             :      * since the delegate may be holding the last lock
     131             :      */
     132        3872 :     fib_entry_delegate_remove(fib_entry_get(fei),
     133             :                               FIB_ENTRY_DELEGATE_TRACK);
     134             :     /* having removed the deletegate the fed object is now toast */
     135        3872 :     fib_entry_child_remove(fei, sibling);
     136             : 
     137        3872 :     fib_table_entry_delete_index(fei, FIB_SOURCE_RR);
     138        3872 : }
     139             : 
     140             : static fib_node_back_walk_rc_t
     141         632 : fib_entry_track_back_walk_notify (fib_node_t *node,
     142             :                                   fib_node_back_walk_ctx_t *ctx)
     143             : {
     144             :     fib_entry_delegate_t *fed;
     145             : 
     146         632 :     fed = fib_entry_delegate_from_fib_node(node);
     147             : 
     148             :     /*
     149             :      * propagate the walk to the delgate's children
     150             :      */
     151             :     
     152         632 :     fib_walk_sync(FIB_NODE_TYPE_ENTRY_TRACK,
     153             :                   fib_entry_delegate_get_index(fed),
     154             :                   ctx);
     155             : 
     156         632 :     return (FIB_NODE_BACK_WALK_CONTINUE);
     157             : }
     158             : 
     159             : static void
     160           1 : fib_entry_track_show_memory (void)
     161             : {
     162           1 : }
     163             : 
     164             : /*
     165             :  * The FIB entry tracker's graph node virtual function table
     166             :  */
     167             : static const fib_node_vft_t fib_entry_track_vft = {
     168             :     .fnv_get = fib_entry_track_get_node,
     169             :     .fnv_last_lock = fib_entry_track_last_lock_gone,
     170             :     .fnv_back_walk = fib_entry_track_back_walk_notify,
     171             :     .fnv_mem_show = fib_entry_track_show_memory,
     172             : };
     173             : 
     174             : void
     175         575 : fib_entry_track_module_init (void)
     176             : {
     177         575 :     fib_node_register_type(FIB_NODE_TYPE_ENTRY_TRACK, &fib_entry_track_vft);
     178         575 : }

Generated by: LCOV version 1.14