LCOV - code coverage report
Current view: top level - vnet/fib - fib_entry_cover.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 47 48 97.9 %
Date: 2023-10-26 01:39:38 Functions: 8 8 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_entry_cover.h>
      17             : #include <vnet/fib/fib_entry_src.h>
      18             : #include <vnet/fib/fib_node_list.h>
      19             : #include <vnet/fib/fib_entry_delegate.h>
      20             : 
      21             : u32
      22       18948 : fib_entry_cover_track (fib_entry_t* cover,
      23             :                        fib_node_index_t covered)
      24             : {
      25             :     fib_entry_delegate_t *fed;
      26             : 
      27       18948 :     FIB_ENTRY_DBG(cover, "cover-track %d", covered);
      28             : 
      29       18948 :     ASSERT(fib_entry_get_index(cover) != covered);
      30             : 
      31       18948 :     fed = fib_entry_delegate_find(cover, FIB_ENTRY_DELEGATE_COVERED);
      32             : 
      33       18948 :     if (NULL == fed)
      34             :     {
      35        7656 :         fed = fib_entry_delegate_find_or_add(cover, FIB_ENTRY_DELEGATE_COVERED);
      36        7656 :         fed->fd_list = fib_node_list_create();
      37             :     }
      38             : 
      39       18948 :     return (fib_node_list_push_front(fed->fd_list,
      40             :                                      0, FIB_NODE_TYPE_ENTRY,
      41             :                                      covered));
      42             : }
      43             : 
      44             : void
      45       14567 : fib_entry_cover_untrack (fib_entry_t* cover,
      46             :                          u32 tracked_index)
      47             : {
      48             :     fib_entry_delegate_t *fed;
      49             : 
      50       14567 :     FIB_ENTRY_DBG(cover, "cover-untrack @ %d", tracked_index);
      51             : 
      52       14567 :     fed = fib_entry_delegate_find(cover, FIB_ENTRY_DELEGATE_COVERED);
      53             : 
      54       14567 :     if (NULL == fed)
      55           0 :         return;
      56             : 
      57       14567 :     fib_node_list_remove(fed->fd_list, tracked_index);
      58             : 
      59       14567 :     if (0 == fib_node_list_get_size(fed->fd_list))
      60             :     {
      61        7250 :         fib_node_list_destroy(&fed->fd_list);
      62        7250 :         fib_entry_delegate_remove(cover, FIB_ENTRY_DELEGATE_COVERED);        
      63             :     }
      64             : }
      65             : 
      66             : /**
      67             :  * Internal struct to hold user supplied parameters for the cover walk
      68             :  */
      69             : typedef struct fib_enty_cover_walk_ctx_t_ {
      70             :     fib_entry_t *cover;
      71             :     fib_entry_covered_walk_t walk;
      72             :     void *ctx;
      73             : } fib_enty_cover_walk_ctx_t;
      74             : 
      75             : static walk_rc_t
      76        5539 : fib_entry_cover_walk_node_ptr (fib_node_ptr_t *depend,
      77             :                                void *args)
      78             : {
      79        5539 :     fib_enty_cover_walk_ctx_t *ctx = args;
      80             : 
      81        5539 :     ctx->walk(ctx->cover, depend->fnp_index, ctx->ctx);
      82             : 
      83        5539 :     return (WALK_CONTINUE);
      84             : }
      85             : 
      86             : void
      87       53088 : fib_entry_cover_walk (fib_entry_t *cover,
      88             :                       fib_entry_covered_walk_t walk,
      89             :                       void *args)
      90             : {
      91             :     fib_entry_delegate_t *fed;
      92             : 
      93       53088 :     fed = fib_entry_delegate_find(cover, FIB_ENTRY_DELEGATE_COVERED);
      94             : 
      95       53088 :     if (NULL == fed)
      96       49111 :         return;
      97             : 
      98        3977 :     fib_enty_cover_walk_ctx_t ctx = {
      99             :         .cover = cover,
     100             :         .walk = walk,
     101             :         .ctx = args,
     102             :     };
     103             : 
     104        3977 :     fib_node_list_walk(fed->fd_list,
     105             :                        fib_entry_cover_walk_node_ptr,
     106             :                        &ctx);
     107             : }
     108             : 
     109             : static walk_rc_t
     110        4375 : fib_entry_cover_change_one (fib_entry_t *cover,
     111             :                             fib_node_index_t covered,
     112             :                             void *args)
     113             : {
     114             :     fib_node_index_t new_cover;
     115             : 
     116             :     /*
     117             :      * The 3 entries involved here are:
     118             :      *   cover - the least specific. It will cover both the others
     119             :      *  new_cover - the enty just inserted below the cover
     120             :      *  covered - the entry that was tracking the cover.
     121             :      *
     122             :      * The checks below are to determine if new_cover is a cover for covered.
     123             :      */
     124        4375 :     new_cover = pointer_to_uword(args);
     125             : 
     126        4375 :     if (FIB_NODE_INDEX_INVALID == new_cover)
     127             :     {
     128             :         /*
     129             :          * nothing has been inserted, which implies the cover was removed.
     130             :          * 'cover' is thus the new cover.
     131             :          */
     132        4087 :         fib_entry_cover_changed(covered);
     133             :     }
     134         288 :     else if (new_cover != covered)
     135             :     {
     136             :         const fib_prefix_t *pfx_covered, *pfx_new_cover;
     137             : 
     138         288 :         pfx_covered = fib_entry_get_prefix(covered);
     139         288 :         pfx_new_cover = fib_entry_get_prefix(new_cover);
     140             : 
     141         288 :         if (fib_prefix_is_cover(pfx_new_cover, pfx_covered))
     142             :         {
     143         153 :             fib_entry_cover_changed(covered);
     144             :         }
     145             :     }
     146        4375 :     return (WALK_CONTINUE);
     147             : }
     148             : 
     149             : void
     150       40293 : fib_entry_cover_change_notify (fib_node_index_t cover_index,
     151             :                                fib_node_index_t covered)
     152             : {
     153             :     fib_entry_t *cover;
     154             : 
     155       40293 :     cover = fib_entry_get(cover_index);
     156             : 
     157       40293 :     fib_entry_cover_walk(cover, 
     158             :                          fib_entry_cover_change_one,
     159       40293 :                          uword_to_pointer(covered, void*));
     160       40293 : }
     161             : 
     162             : static walk_rc_t
     163          14 : fib_entry_cover_update_one (fib_entry_t *cover,
     164             :                             fib_node_index_t covered,
     165             :                             void *args)
     166             : {
     167          14 :     fib_entry_cover_updated(covered);
     168             : 
     169          14 :     return (WALK_CONTINUE);
     170             : }
     171             : 
     172             : void
     173        4213 : fib_entry_cover_update_notify (fib_entry_t *fib_entry)
     174             : {
     175        4213 :     fib_entry_cover_walk(fib_entry, 
     176             :                          fib_entry_cover_update_one,
     177             :                          NULL);
     178        4213 : }

Generated by: LCOV version 1.14