LCOV - code coverage report
Current view: top level - vnet/adj - adj_midchain_delegate.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 59 60 98.3 %
Date: 2023-10-26 01:39:38 Functions: 11 11 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/adj/adj_delegate.h>
      17             : #include <vnet/adj/adj_midchain.h>
      18             : #include <vnet/fib/fib_table.h>
      19             : #include <vnet/fib/fib_entry_track.h>
      20             : 
      21             : /**
      22             :  * Midchain stacker delegate
      23             :  */
      24             : typedef struct adj_midchain_delegate_t_
      25             : {
      26             :     /**
      27             :      * the Fib Entry we are stacked on
      28             :      */
      29             :     fib_node_index_t amd_fei;
      30             : 
      31             :     /**
      32             :      * The sibling entry on the FIB entry
      33             :      */
      34             :     u32 amd_sibling;
      35             : } adj_midchain_delegate_t;
      36             : 
      37             : /**
      38             :  * Pool of delegates
      39             :  */
      40             : static adj_midchain_delegate_t *amd_pool;
      41             : 
      42             : static inline const adj_midchain_delegate_t*
      43           2 : adj_midchain_from_const_base (const adj_delegate_t *ad)
      44             : {
      45           2 :     if (NULL != ad)
      46             :     {
      47           2 :         return (pool_elt_at_index(amd_pool, ad->ad_index));
      48             :     }
      49           0 :     return (NULL);
      50             : }
      51             : 
      52             : static void
      53         729 : adj_midchain_delegate_restack_i (adj_index_t ai,
      54             :                                  adj_midchain_delegate_t *amd)
      55             : {
      56         729 :     if (vnet_sw_interface_is_admin_up (vnet_get_main (),
      57         693 :                                        adj_get_sw_if_index(ai)) &&
      58         693 :         (FIB_NODE_INDEX_INVALID != amd->amd_fei))
      59         693 :     {
      60             :         const fib_prefix_t *pfx;
      61             : 
      62         693 :         pfx = fib_entry_get_prefix(amd->amd_fei);
      63             : 
      64         693 :         adj_nbr_midchain_stack_on_fib_entry (
      65             :             ai,
      66             :             amd->amd_fei,
      67         693 :             fib_forw_chain_type_from_fib_proto(pfx->fp_proto));
      68             :     }
      69             :     else
      70             :     {
      71          36 :         adj_nbr_midchain_unstack (ai);
      72             :     }
      73         729 : }
      74             : 
      75             : void
      76         263 : adj_midchain_delegate_restack (adj_index_t ai)
      77             : {
      78             :     adj_midchain_delegate_t *amd;
      79             :     ip_adjacency_t *adj;
      80             :     adj_delegate_t *ad;
      81             : 
      82             :     /*
      83             :      * if there's a delegate already use that
      84             :      */
      85         263 :     adj = adj_get(ai);
      86         263 :     ad = adj_delegate_get(adj, ADJ_DELEGATE_MIDCHAIN);
      87             : 
      88         263 :     if (NULL != ad)
      89             :     {
      90         263 :         amd = pool_elt_at_index(amd_pool, ad->ad_index);
      91             : 
      92         263 :         adj_midchain_delegate_restack_i(ai, amd);
      93             :     }
      94             :     /*
      95             :      * else
      96             :      *  nothing to stack
      97             :      */
      98         263 : }
      99             : 
     100             : void
     101         466 : adj_midchain_delegate_stack (adj_index_t ai,
     102             :                              u32 fib_index,
     103             :                              const fib_prefix_t *pfx)
     104             : {
     105             :     adj_midchain_delegate_t *amd;
     106             :     ip_adjacency_t *adj;
     107             :     adj_delegate_t *ad;
     108             : 
     109             :     /*
     110             :      * if there's a delegate already use that
     111             :      */
     112         466 :     adj = adj_get(ai);
     113         466 :     ad = adj_delegate_get(adj, ADJ_DELEGATE_MIDCHAIN);
     114             : 
     115         466 :     if (NULL != ad)
     116             :     {
     117          87 :         amd = pool_elt_at_index(amd_pool, ad->ad_index);
     118             :     }
     119             :     else
     120             :     {
     121         379 :         pool_get(amd_pool, amd);
     122         379 :         amd->amd_fei = FIB_NODE_INDEX_INVALID;
     123         379 :         adj_delegate_add(adj, ADJ_DELEGATE_MIDCHAIN, amd - amd_pool);
     124             : 
     125         379 :         amd->amd_fei = fib_entry_track(fib_index,
     126             :                                        pfx,
     127             :                                        FIB_NODE_TYPE_ADJ,
     128             :                                        ai,
     129         379 :                                        &amd->amd_sibling);
     130             :     }
     131         466 :     adj_midchain_delegate_restack_i(ai, amd);
     132         466 : }
     133             : 
     134             : void
     135           8 : adj_midchain_delegate_remove (adj_index_t ai)
     136             : {
     137             :     adj_midchain_delegate_t *amd;
     138             :     ip_adjacency_t *adj;
     139             :     adj_delegate_t *ad;
     140             : 
     141             :     /*
     142             :      * if there's a delegate, it can be removed
     143             :      */
     144           8 :     adj = adj_get(ai);
     145           8 :     ad = adj_delegate_get(adj, ADJ_DELEGATE_MIDCHAIN);
     146             : 
     147           8 :     if (NULL != ad)
     148             :     {
     149           8 :         adj_nbr_midchain_unstack(ai);
     150             : 
     151           8 :         amd = pool_elt_at_index(amd_pool, ad->ad_index);
     152           8 :         fib_entry_untrack(amd->amd_fei, amd->amd_sibling);
     153           8 :         pool_put(amd_pool, amd);
     154             : 
     155           8 :         adj_delegate_remove (ai, ADJ_DELEGATE_MIDCHAIN);
     156             :     }
     157           8 : }
     158             : 
     159             : void
     160         343 : adj_midchain_delegate_unstack (adj_index_t ai)
     161             : {
     162         343 :     adj_nbr_midchain_unstack(ai);
     163         343 : }
     164             : 
     165             : static void
     166         369 : adj_midchain_delegate_adj_deleted (adj_delegate_t *ad)
     167             : {
     168             :     adj_midchain_delegate_t *amd;
     169             : 
     170         369 :     amd = pool_elt_at_index(amd_pool, ad->ad_index);
     171             : 
     172         369 :     fib_entry_untrack(amd->amd_fei, amd->amd_sibling);
     173             : 
     174         369 :     pool_put(amd_pool, amd);
     175         369 : }
     176             : 
     177             : /**
     178             :  * Print a delegate that represents MIDCHAIN tracking
     179             :  */
     180             : static u8 *
     181           2 : adj_midchain_delegate_fmt (const adj_delegate_t *aed, u8 *s)
     182             : {
     183           2 :     const adj_midchain_delegate_t *amd = adj_midchain_from_const_base(aed);
     184             : 
     185           2 :     s = format(s, "MIDCHAIN:[fib-entry:%d]", amd->amd_fei);
     186             : 
     187           2 :     return (s);
     188             : }
     189             : 
     190             : const static adj_delegate_vft_t adj_delegate_vft = {
     191             :   .adv_format = adj_midchain_delegate_fmt,
     192             :   .adv_adj_deleted = adj_midchain_delegate_adj_deleted,
     193             : };
     194             : 
     195             : static clib_error_t *
     196         575 : adj_midchain_delegate_module_init (vlib_main_t * vm)
     197             : {
     198         575 :     clib_error_t * error = NULL;
     199             : 
     200         575 :     adj_delegate_register_type (ADJ_DELEGATE_MIDCHAIN, &adj_delegate_vft);
     201             : 
     202         575 :     return (error);
     203             : }
     204             : 
     205       83519 : VLIB_INIT_FUNCTION (adj_midchain_delegate_module_init);
     206             : 

Generated by: LCOV version 1.14