LCOV - code coverage report
Current view: top level - vnet/mfib - mfib_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/mfib/mfib_entry_cover.h>
      17             : #include <vnet/mfib/mfib_entry_src.h>
      18             : #include <vnet/fib/fib_node_list.h>
      19             : 
      20             : u32
      21           8 : mfib_entry_cover_track (mfib_entry_t* cover,
      22             :                        fib_node_index_t covered)
      23             : {
      24             :     mfib_entry_delegate_t *mfed;
      25             : 
      26           8 :     MFIB_ENTRY_DBG(cover, "cover-track %d", covered);
      27             : 
      28           8 :     ASSERT(mfib_entry_get_index(cover) != covered);
      29             : 
      30           8 :     mfed = mfib_entry_delegate_get(cover, MFIB_ENTRY_DELEGATE_COVERED);
      31             : 
      32           8 :     if (NULL == mfed)
      33             :     {
      34           8 :         mfed = mfib_entry_delegate_find_or_add(cover, MFIB_ENTRY_DELEGATE_COVERED);
      35           8 :         mfed->mfd_list = fib_node_list_create();
      36             :     }
      37             : 
      38           8 :     return (fib_node_list_push_front(mfed->mfd_list,
      39             :                                      0, FIB_NODE_TYPE_MFIB_ENTRY,
      40             :                                      covered));
      41             : }
      42             : 
      43             : void
      44           8 : mfib_entry_cover_untrack (mfib_entry_t* cover,
      45             :                          u32 tracked_index)
      46             : {
      47             :     mfib_entry_delegate_t *mfed;
      48             : 
      49           8 :     MFIB_ENTRY_DBG(cover, "cover-untrack @ %d", tracked_index);
      50             : 
      51           8 :     mfed = mfib_entry_delegate_get(cover, MFIB_ENTRY_DELEGATE_COVERED);
      52             : 
      53           8 :     if (NULL == mfed)
      54           0 :         return;
      55             : 
      56           8 :     fib_node_list_remove(mfed->mfd_list, tracked_index);
      57             : 
      58           8 :     if (0 == fib_node_list_get_size(mfed->mfd_list))
      59             :     {
      60           8 :         fib_node_list_destroy(&mfed->mfd_list);
      61           8 :         mfib_entry_delegate_remove(cover, MFIB_ENTRY_DELEGATE_COVERED);        
      62             :     }
      63             : }
      64             : 
      65             : /**
      66             :  * Internal struct to hold user supplied paraneters for the cover walk
      67             :  */
      68             : typedef struct mfib_enty_cover_walk_ctx_t_ {
      69             :     mfib_entry_t *cover;
      70             :     mfib_entry_covered_walk_t walk;
      71             :     void *ctx;
      72             : } mfib_enty_cover_walk_ctx_t;
      73             : 
      74             : static walk_rc_t
      75          24 : mfib_entry_cover_walk_node_ptr (fib_node_ptr_t *depend,
      76             :                                 void *args)
      77             : {
      78          24 :     mfib_enty_cover_walk_ctx_t *ctx = args;
      79             : 
      80          24 :     ctx->walk(ctx->cover, depend->fnp_index, ctx->ctx);
      81             : 
      82          24 :     return (WALK_CONTINUE);
      83             : }
      84             : 
      85             : void
      86      102098 : mfib_entry_cover_walk (mfib_entry_t *cover,
      87             :                       mfib_entry_covered_walk_t walk,
      88             :                       void *args)
      89             : {
      90             :     mfib_entry_delegate_t *mfed;
      91             : 
      92      102098 :     mfed = mfib_entry_delegate_get(cover, MFIB_ENTRY_DELEGATE_COVERED);
      93             : 
      94      102098 :     if (NULL == mfed)
      95      102074 :         return;
      96             : 
      97          24 :     mfib_enty_cover_walk_ctx_t ctx = {
      98             :         .cover = cover,
      99             :         .walk = walk,
     100             :         .ctx = args,
     101             :     };
     102             : 
     103          24 :     fib_node_list_walk(mfed->mfd_list,
     104             :                        mfib_entry_cover_walk_node_ptr,
     105             :                        &ctx);
     106             : }
     107             : 
     108             : static int
     109           6 : mfib_entry_cover_change_one (mfib_entry_t *cover,
     110             :                             fib_node_index_t covered,
     111             :                             void *args)
     112             : {
     113             :     fib_node_index_t new_cover;
     114             : 
     115             :     /*
     116             :      * The 3 entries involved here are:
     117             :      *   cover - the least specific. It will cover both the others
     118             :      *  new_cover - the enty just inserted below the cover
     119             :      *  covered - the entry that was tracking the cover.
     120             :      *
     121             :      * The checks below are to determine if new_cover is a cover for covered.
     122             :      */
     123           6 :     new_cover = pointer_to_uword(args);
     124             : 
     125           6 :     if (FIB_NODE_INDEX_INVALID == new_cover)
     126             :     {
     127             :         /*
     128             :          * nothing has been inserted, which implies the cover was removed.
     129             :          * 'cover' is thus the new cover.
     130             :          */
     131           2 :         mfib_entry_cover_changed(covered);
     132             :     }
     133           4 :     else if (new_cover != covered)
     134             :     {
     135             :         const mfib_prefix_t *pfx_covered, *pfx_new_cover;
     136             : 
     137           2 :         pfx_covered = mfib_entry_get_prefix(covered);
     138           2 :         pfx_new_cover = mfib_entry_get_prefix(new_cover);
     139             : 
     140           2 :         if (mfib_prefix_is_cover(pfx_new_cover, pfx_covered))
     141             :         {
     142           2 :             mfib_entry_cover_changed(covered);
     143             :         }
     144             :     }
     145             :     /* continue */
     146           6 :     return (1);
     147             : }
     148             : 
     149             : void
     150       11207 : mfib_entry_cover_change_notify (fib_node_index_t cover_index,
     151             :                                 fib_node_index_t covered)
     152             : {
     153             :     mfib_entry_t *cover;
     154             : 
     155       11207 :     cover = mfib_entry_get(cover_index);
     156             : 
     157       11207 :     mfib_entry_cover_walk(cover, 
     158             :                           mfib_entry_cover_change_one,
     159       11207 :                           uword_to_pointer(covered, void*));
     160       11207 : }
     161             : 
     162             : static int
     163          18 : mfib_entry_cover_update_one (mfib_entry_t *cover,
     164             :                             fib_node_index_t covered,
     165             :                             void *args)
     166             : {
     167          18 :     mfib_entry_cover_updated(covered);
     168             : 
     169             :     /* continue */
     170          18 :     return (1);
     171             : }
     172             : 
     173             : void
     174       90891 : mfib_entry_cover_update_notify (mfib_entry_t *mfib_entry)
     175             : {
     176       90891 :     mfib_entry_cover_walk(mfib_entry, 
     177             :                          mfib_entry_cover_update_one,
     178             :                          NULL);
     179       90891 : }

Generated by: LCOV version 1.14