LCOV - code coverage report
Current view: top level - vnet/fib - fib_entry_src_interface.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 65 68 95.6 %
Date: 2023-07-05 22:20:52 Functions: 11 12 91.7 %

          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 "fib_entry.h"
      17             : #include "fib_entry_src.h"
      18             : #include "fib_path_list.h"
      19             : #include "fib_internal.h"
      20             : #include "fib_table.h"
      21             : #include "fib_entry_cover.h"
      22             : #include "fib_attached_export.h"
      23             : 
      24             : /**
      25             :  * Source initialisation Function 
      26             :  */
      27             : static void
      28       13991 : fib_entry_src_interface_init (fib_entry_src_t *src)
      29             : {
      30       13991 :     src->u.interface.fesi_cover = FIB_NODE_INDEX_INVALID;
      31       13991 :     src->u.interface.fesi_sibling = FIB_NODE_INDEX_INVALID;
      32       13991 : }
      33             : 
      34             : static void
      35       13991 : fib_entry_src_interface_add (fib_entry_src_t *src,
      36             :                              const fib_entry_t *entry,
      37             :                              fib_entry_flag_t flags,
      38             :                              dpo_proto_t proto,
      39             :                              const dpo_id_t *dpo)
      40             : {
      41       13991 :     src->fes_pl = fib_path_list_create_special(
      42             :                       proto,
      43             :                       fib_entry_src_flags_2_path_list_flags(flags),
      44             :                       dpo);
      45       13991 : }
      46             : 
      47             : static void
      48       12680 : fib_entry_src_interface_remove (fib_entry_src_t *src)
      49             : {
      50       12680 :     src->fes_pl = FIB_NODE_INDEX_INVALID;
      51       12680 :     ASSERT(src->u.interface.fesi_sibling == ~0);
      52       12680 : }
      53             : 
      54             : static int
      55        8651 : fib_entry_src_interface_update_glean (fib_entry_t *cover,
      56             :                                       const fib_entry_t *local)
      57             : {
      58             :     fib_entry_src_t *src;
      59             :     adj_index_t ai;
      60             : 
      61        8651 :     src = fib_entry_src_find (cover, FIB_SOURCE_INTERFACE);
      62             : 
      63        8651 :     if (NULL == src)
      64             :     {
      65             :         /*
      66             :          * The cover is not an interface source, no work
      67             :          */
      68        3083 :         return 0;
      69             :     }
      70             : 
      71        5568 :     ai = fib_path_list_get_adj(src->fes_pl,
      72        5568 :                                fib_entry_get_default_chain_type(cover));
      73             : 
      74        5568 :     if (INDEX_INVALID != ai)
      75             :     {
      76             :         ip_adjacency_t *adj;
      77             : 
      78        5418 :         adj = adj_get(ai);
      79             : 
      80        5418 :         if (IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index)
      81             :         {
      82             :             /*
      83             :              * the connected prefix will link to a glean on a non-p2p
      84             :              * interface.
      85             :              * Ensure we are updating with a host in the connected's subnet
      86             :              */
      87        5127 :             if (fib_prefix_is_cover(&adj->sub_type.glean.rx_pfx,
      88             :                                     &local->fe_prefix))
      89             :             {
      90        5127 :                 adj->sub_type.glean.rx_pfx.fp_addr = local->fe_prefix.fp_addr;
      91        5127 :                 return (1);
      92             :             }
      93             :         }
      94             :     }
      95             : 
      96         441 :     return (0);
      97             : }
      98             : 
      99             : static walk_rc_t
     100        2192 : fib_entry_src_interface_update_glean_walk (fib_entry_t *cover,
     101             :                                            fib_node_index_t covered,
     102             :                                            void *ctx)
     103             : {
     104        2192 :     if (fib_entry_src_interface_update_glean(cover, fib_entry_get(covered)))
     105         960 :         return (WALK_STOP);
     106             : 
     107        1232 :     return (WALK_CONTINUE);
     108             : }
     109             : 
     110             : static void
     111        9174 : fib_entry_src_interface_path_swap (fib_entry_src_t *src,
     112             :                                    const fib_entry_t *entry,
     113             :                                    fib_path_list_flags_t pl_flags,
     114             :                                    const fib_route_path_t *paths)
     115             : {
     116        9174 :     src->fes_pl = fib_path_list_create(pl_flags, paths);
     117        9174 : }
     118             : 
     119             : /*
     120             :  * Source activate. 
     121             :  * Called when the source is teh new longer best source on the entry
     122             :  */
     123             : static int
     124       15902 : fib_entry_src_interface_activate (fib_entry_src_t *src,
     125             :                                   const fib_entry_t *fib_entry)
     126             : {
     127             :     fib_entry_t *cover;
     128             : 
     129       15902 :     if (FIB_ENTRY_FLAG_LOCAL & src->fes_entry_flags)
     130             :     {
     131             :         /*
     132             :          * Track the covering attached/connected cover. This is so that
     133             :          * during an attached export of the cover, this local prefix is
     134             :          * also exported
     135             :          */
     136        6459 :         src->u.interface.fesi_cover =
     137        6459 :             fib_table_get_less_specific(fib_entry->fe_fib_index,
     138             :                                         &fib_entry->fe_prefix);
     139             : 
     140        6459 :         ASSERT(FIB_NODE_INDEX_INVALID != src->u.interface.fesi_cover);
     141             : 
     142        6459 :         cover = fib_entry_get(src->u.interface.fesi_cover);
     143             : 
     144        6459 :         src->u.interface.fesi_sibling =
     145        6459 :             fib_entry_cover_track(cover, fib_entry_get_index(fib_entry));
     146             : 
     147        6459 :         fib_entry_src_interface_update_glean(cover, fib_entry);
     148             :     }
     149             : 
     150       15902 :     return (!0);
     151             : }
     152             : 
     153             : 
     154             : /*
     155             :  * Source Deactivate. 
     156             :  * Called when the source is no longer best source on the entry
     157             :  */
     158             : static void
     159       14591 : fib_entry_src_interface_deactivate (fib_entry_src_t *src,
     160             :                                     const fib_entry_t *fib_entry)
     161             : {
     162             :     fib_entry_t *cover;
     163             : 
     164             :     /*
     165             :      * remove the dependency on the covering entry
     166             :      */
     167       14591 :     if (FIB_NODE_INDEX_INVALID != src->u.interface.fesi_cover)
     168             :     {
     169        6050 :         cover = fib_entry_get(src->u.interface.fesi_cover);
     170             : 
     171        6050 :         fib_entry_cover_untrack(cover, src->u.interface.fesi_sibling);
     172             : 
     173        6050 :         src->u.interface.fesi_cover = FIB_NODE_INDEX_INVALID;
     174        6050 :         src->u.interface.fesi_sibling = ~0;
     175             : 
     176        6050 :         fib_entry_cover_walk(cover,
     177             :                              fib_entry_src_interface_update_glean_walk,
     178             :                              NULL);
     179             :     }
     180       14591 : }
     181             : 
     182             : static fib_entry_src_cover_res_t
     183        1911 : fib_entry_src_interface_cover_change (fib_entry_src_t *src,
     184             :                                       const fib_entry_t *fib_entry)
     185             : {
     186        1911 :     fib_entry_src_cover_res_t res = {
     187             :         .install = !0,
     188             :         .bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
     189             :     };
     190             : 
     191        1911 :     if (FIB_NODE_INDEX_INVALID == src->u.interface.fesi_cover)
     192             :     {
     193             :         /*
     194             :          * not tracking the cover. surprised we got poked?
     195             :          */
     196           0 :         return (res);
     197             :     }
     198             : 
     199             :     /*
     200             :      * this function is called when this entry's cover has a more specific
     201             :      * entry inserted benaeth it. That does not necessarily mean that this
     202             :      * entry is covered by the new prefix. check that
     203             :      */
     204        1911 :     if (src->u.interface.fesi_cover !=
     205        1911 :         fib_table_get_less_specific(fib_entry->fe_fib_index,
     206             :                                     &fib_entry->fe_prefix))
     207             :     {
     208        1911 :         fib_entry_src_interface_deactivate(src, fib_entry);
     209        1911 :         fib_entry_src_interface_activate(src, fib_entry);
     210             :     }
     211        1911 :     return (res);
     212             : }
     213             : 
     214             : static void
     215       15957 : fib_entry_src_interface_installed (fib_entry_src_t *src,
     216             :                                    const fib_entry_t *fib_entry)
     217             : {
     218             :     /*
     219             :      * The interface source now rules! poke our cover to get exported
     220             :      */
     221             :     fib_entry_t *cover;
     222             : 
     223       15957 :     if (FIB_NODE_INDEX_INVALID != src->u.interface.fesi_cover)
     224             :     {
     225        6461 :         cover = fib_entry_get(src->u.interface.fesi_cover);
     226             : 
     227        6461 :         fib_attached_export_covered_added(cover,
     228             :                                           fib_entry_get_index(fib_entry));
     229             :     }
     230       15957 : }
     231             : 
     232             : static u8*
     233           0 : fib_entry_src_interface_format (fib_entry_src_t *src,
     234             :                                 u8* s)
     235             : {
     236           0 :     return (format(s, " cover:%d", src->u.interface.fesi_cover));
     237             : }
     238             : 
     239             : const static fib_entry_src_vft_t interface_src_vft = {
     240             :     .fesv_init = fib_entry_src_interface_init,
     241             :     .fesv_add = fib_entry_src_interface_add,
     242             :     .fesv_remove = fib_entry_src_interface_remove,
     243             :     .fesv_path_swap = fib_entry_src_interface_path_swap,
     244             :     .fesv_activate = fib_entry_src_interface_activate,
     245             :     .fesv_deactivate = fib_entry_src_interface_deactivate,
     246             :     .fesv_format = fib_entry_src_interface_format,
     247             :     .fesv_installed = fib_entry_src_interface_installed,
     248             :     .fesv_cover_change = fib_entry_src_interface_cover_change,
     249             :     /*
     250             :      * not concerned about updates to the cover. the cover will
     251             :      * decide to export or not
     252             :      */
     253             : };
     254             : 
     255             : void
     256         559 : fib_entry_src_interface_register (void)
     257             : {
     258         559 :     fib_entry_src_behaviour_register(FIB_SOURCE_BH_INTERFACE,
     259             :                                      &interface_src_vft);
     260         559 : }

Generated by: LCOV version 1.14