LCOV - code coverage report
Current view: top level - vnet/bier - bier_imp.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 69 87 79.3 %
Date: 2023-07-05 22:20:52 Functions: 15 17 88.2 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2017 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             :  * bier_imposition : The BIER imposition object
      17             :  *
      18             :  * A BIER imposition object is present in the IP mcast output list
      19             :  * and represents the imposition of a BIER bitmask. After BIER header
      20             :  * imposition the packet is forward within the appropriate/specified
      21             :  * BIER table
      22             :  */
      23             : 
      24             : #include <vnet/bier/bier_imp.h>
      25             : #include <vnet/bier/bier_table.h>
      26             : #include <vnet/bier/bier_hdr_inlines.h>
      27             : #include <vnet/fib/fib_node.h>
      28             : #include <vnet/mpls/mpls_types.h>
      29             : 
      30             : /**
      31             :  * The memory pool of all imp objects
      32             :  */
      33             : bier_imp_t *bier_imp_pool;
      34             : 
      35             : /**
      36             :  * When constructing the BIER imp ID from an index and BSL, shift
      37             :  * the BSL this far
      38             :  */
      39             : #define BIER_IMP_ID_HLEN_SHIFT 24
      40             : 
      41             : static void
      42          85 : bier_imp_lock_i (bier_imp_t *bi)
      43             : {
      44          85 :     bi->bi_locks++;
      45          85 : }
      46             : 
      47             : void
      48          78 : bier_imp_lock (index_t bii)
      49             : {
      50          78 :     bier_imp_lock_i(bier_imp_get(bii));
      51          78 : }
      52             : 
      53             : static index_t
      54         349 : bier_imp_get_index(bier_imp_t *bi)
      55             : {
      56         349 :     return (bi - bier_imp_pool);
      57             : }
      58             : 
      59             : index_t
      60           7 : bier_imp_add_or_lock (const bier_table_id_t *bti,
      61             :                       bier_bp_t sender,
      62             :                       const bier_bit_string_t *bs)
      63             : {
      64           7 :     bier_imp_t *bi = NULL;
      65             :     fib_protocol_t fproto;
      66             :     index_t btii;
      67             : 
      68           7 :     pool_get_aligned(bier_imp_pool, bi, CLIB_CACHE_LINE_BYTES);
      69             : 
      70           7 :     bi->bi_tbl = *bti;
      71           7 :     btii = bier_table_lock(bti);
      72             : 
      73             :     /*
      74             :      * init the BIER header we will paint on in the data plane
      75             :      */
      76           7 :     bier_hdr_init(&bi->bi_hdr,
      77             :                   BIER_HDR_VERSION_1,
      78             :                   BIER_HDR_PROTO_INVALID, // filled in later
      79           7 :                   bti->bti_hdr_len,
      80             :                   0, // entropy
      81             :                   sender);
      82           7 :     bier_hdr_hton(&bi->bi_hdr);
      83           7 :     clib_memcpy_fast(&bi->bi_bits, bs->bbs_buckets, bs->bbs_len);
      84             : 
      85           7 :     bier_imp_lock_i(bi);
      86             : 
      87             :     /*
      88             :      * get and stack on the forwarding info from the table
      89             :      */
      90          21 :     FOR_EACH_FIB_IP_PROTOCOL(fproto)
      91             :     {
      92             :         /*
      93             :          * initialise to invalid first, lest we pick up garbage
      94             :          * from the pool alloc
      95             :          */
      96          14 :         dpo_id_t dpo = DPO_INVALID;
      97          14 :         bi->bi_dpo[fproto] = dpo;
      98             : 
      99          14 :         bier_table_contribute_forwarding(btii, &dpo);
     100          14 :         dpo_stack(DPO_BIER_IMP, fib_proto_to_dpo(fproto),
     101          14 :                   &bi->bi_dpo[fproto],
     102             :                   &dpo);
     103          14 :         dpo_reset(&dpo);
     104             :     }
     105             : 
     106           7 :     return (bier_imp_get_index(bi));
     107             : }
     108             : 
     109             : void
     110          85 : bier_imp_unlock (index_t bii)
     111             : {
     112             :     fib_protocol_t fproto;
     113             :     bier_imp_t *bi;
     114             : 
     115          85 :     if (INDEX_INVALID == bii)
     116             :     {
     117           0 :         return;
     118             :     }
     119             : 
     120          85 :     bi = bier_imp_get(bii);
     121             : 
     122          85 :     bi->bi_locks--;
     123             : 
     124          85 :     if (0 == bi->bi_locks)
     125             :     {
     126           7 :         bier_table_unlock(&bi->bi_tbl);
     127             : 
     128          21 :         FOR_EACH_FIB_IP_PROTOCOL(fproto)
     129             :         {
     130          14 :             dpo_reset(&bi->bi_dpo[fproto]);
     131             :         }
     132           7 :         pool_put(bier_imp_pool, bi);
     133             :     }
     134             : }
     135             : 
     136             : u8*
     137         342 : format_bier_imp (u8* s, va_list *args)
     138             : {
     139         342 :     index_t bii = va_arg (*args, index_t);
     140         342 :     u32 indent = va_arg(*args, u32);
     141         342 :     bier_show_flags_t flags = va_arg(*args, bier_show_flags_t);
     142             :     bier_imp_t *bi;
     143             : 
     144         342 :     bi = bier_imp_get(bii);
     145             : 
     146         342 :     s = format(s, "bier-imp:[%d]: tbl:[%U] hdr:[%U]",
     147             :                bier_imp_get_index(bi),
     148             :                format_bier_table_id, &bi->bi_tbl,
     149             :                format_bier_hdr, &bi->bi_hdr);
     150             : 
     151         342 :     if (BIER_SHOW_DETAIL & flags)
     152             :     {
     153             :         bier_bit_string_t bbs;
     154             :         bier_hdr_t copy;
     155             : 
     156         171 :         copy = bi->bi_hdr;
     157         171 :         bier_hdr_ntoh(&copy);
     158         171 :         bier_bit_string_init(&bbs,
     159         171 :                              bier_hdr_get_len_id(&copy),
     160         171 :                              bi->bi_bits);
     161             : 
     162         171 :         s = format(s, "\n%U%U",
     163             :                    format_white_space, indent,
     164             :                    format_bier_bit_string, &bbs);
     165         171 :         s = format(s, "\n%U%U",
     166             :                    format_white_space, indent,
     167             :                    format_dpo_id, &bi->bi_dpo, indent+2);
     168             :     }
     169             : 
     170         342 :     return (s);
     171             : }
     172             : 
     173             : void
     174          28 : bier_imp_contribute_forwarding (index_t bii,
     175             :                                 dpo_proto_t proto,
     176             :                                 dpo_id_t *dpo)
     177             : {
     178          28 :     dpo_set(dpo, DPO_BIER_IMP, proto, bii);
     179          28 : }
     180             : 
     181             : const static char* const bier_imp_ip4_nodes[] =
     182             : {
     183             :     "bier-imp-ip4",
     184             :     NULL,
     185             : };
     186             : const static char* const bier_imp_ip6_nodes[] =
     187             : {
     188             :     "bier-imp-ip6",
     189             :     NULL,
     190             : };
     191             : 
     192             : const static char* const * const bier_imp_nodes[DPO_PROTO_NUM] =
     193             : {
     194             :     [DPO_PROTO_IP4]  = bier_imp_ip4_nodes,
     195             :     [DPO_PROTO_IP6]  = bier_imp_ip6_nodes,
     196             : };
     197             : 
     198             : static void
     199          72 : bier_imp_dpo_lock (dpo_id_t *dpo)
     200             : {
     201          72 :     bier_imp_lock(dpo->dpoi_index);
     202          72 : }
     203             : 
     204             : static void
     205          72 : bier_imp_dpo_unlock (dpo_id_t *dpo)
     206             : {
     207          72 :     bier_imp_unlock(dpo->dpoi_index);
     208          72 : }
     209             : 
     210             : static void
     211           0 : bier_imp_dpo_mem_show (void)
     212             : {
     213           0 :     fib_show_memory_usage("BIER imposition",
     214           0 :                           pool_elts(bier_imp_pool),
     215           0 :                           pool_len(bier_imp_pool),
     216             :                           sizeof(bier_imp_t));
     217           0 : }
     218             : 
     219             : static u8*
     220         171 : format_bier_imp_dpo (u8* s, va_list *ap)
     221             : {
     222         171 :     index_t index = va_arg(*ap, index_t);
     223         171 :     u32 indent = va_arg(*ap, u32);
     224             : 
     225         171 :     s = format(s, "%U", format_bier_imp, index, indent, BIER_SHOW_DETAIL);
     226             : 
     227         171 :     return (s);
     228             : }
     229             : 
     230             : const static dpo_vft_t bier_imp_vft = {
     231             :     .dv_lock = bier_imp_dpo_lock,
     232             :     .dv_unlock = bier_imp_dpo_unlock,
     233             :     .dv_format = format_bier_imp_dpo,
     234             :     .dv_mem_show = bier_imp_dpo_mem_show,
     235             : };
     236             : 
     237             : clib_error_t *
     238         559 : bier_imp_db_module_init (vlib_main_t *vm)
     239             : {
     240         559 :     dpo_register(DPO_BIER_IMP, &bier_imp_vft, bier_imp_nodes);
     241             : 
     242         559 :     return (NULL);
     243             : }
     244             : 
     245       90719 : VLIB_INIT_FUNCTION (bier_imp_db_module_init);
     246             : 
     247             : static clib_error_t *
     248           0 : show_bier_imp (vlib_main_t * vm,
     249             :                unformat_input_t * input,
     250             :                vlib_cli_command_t * cmd)
     251             : {
     252             :     bier_imp_t *bi;
     253             :     index_t bii;
     254             : 
     255           0 :     bii = INDEX_INVALID;
     256             : 
     257           0 :     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
     258           0 :         if (unformat (input, "%d", &bii))
     259             :             ;
     260             :         else
     261             :         {
     262           0 :             break;
     263             :         }
     264             :     }
     265             : 
     266           0 :     if (INDEX_INVALID == bii)
     267             :     {
     268           0 :         pool_foreach (bi, bier_imp_pool)
     269             :          {
     270           0 :             vlib_cli_output(vm, "%U", format_bier_imp,
     271             :                             bier_imp_get_index(bi),
     272             :                             1,
     273             :                             BIER_SHOW_BRIEF);
     274             :         }
     275             :     }
     276             :     else
     277             :     {
     278           0 :         if (pool_is_free_index(bier_imp_pool, bii))
     279             :         {
     280           0 :             vlib_cli_output(vm, "No such BIER imposition: %d", bii);
     281             :         }
     282             :         else
     283             :         {
     284           0 :             vlib_cli_output(vm, "%U", format_bier_imp, bii, 1,
     285             :                             BIER_SHOW_DETAIL);
     286             :         }
     287             :     }
     288           0 :     return (NULL);
     289             : }
     290             : 
     291      272887 : VLIB_CLI_COMMAND (show_bier_imp_node, static) = {
     292             :     .path = "show bier imp",
     293             :     .short_help = "show bier imp [index]",
     294             :     .function = show_bier_imp,
     295             : };

Generated by: LCOV version 1.14