LCOV - code coverage report
Current view: top level - vnet/fib - fib_entry_src_mpls.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 50 50 100.0 %
Date: 2023-07-05 22:20:52 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/mpls/mpls_types.h>
      17             : #include <vnet/dpo/drop_dpo.h>
      18             : 
      19             : #include <vnet/fib/fib_table.h>
      20             : #include <vnet/fib/fib_entry.h>
      21             : #include <vnet/fib/fib_entry_src.h>
      22             : #include <vnet/fib/mpls_fib.h>
      23             : 
      24             : /**
      25             :  * Source initialisation Function
      26             :  */
      27             : static void
      28         140 : fib_entry_src_mpls_init (fib_entry_src_t *src)
      29             : {
      30             :     mpls_eos_bit_t eos;
      31             : 
      32         140 :     src->fes_flags = FIB_ENTRY_SRC_FLAG_NONE;
      33         140 :     src->u.mpls.fesm_label = MPLS_LABEL_INVALID;
      34             : 
      35         420 :     FOR_EACH_MPLS_EOS_BIT(eos)
      36             :     {
      37         280 :         src->u.mpls.fesm_lfes[eos] = FIB_NODE_INDEX_INVALID;
      38             :     }
      39         140 : }
      40             : 
      41             : /**
      42             :  * Source deinitialisation Function
      43             :  */
      44             : static void
      45         140 : fib_entry_src_mpls_deinit (fib_entry_src_t *src)
      46             : {
      47         140 : }
      48             : 
      49             : static void
      50         140 : fib_entry_src_mpls_remove (fib_entry_src_t *src)
      51             : {
      52         140 :     src->fes_pl = FIB_NODE_INDEX_INVALID;
      53         140 :     src->u.mpls.fesm_label = MPLS_LABEL_INVALID;
      54         140 : }
      55             : 
      56             : static void
      57         140 : fib_entry_src_mpls_add (fib_entry_src_t *src,
      58             :                         const fib_entry_t *entry,
      59             :                         fib_entry_flag_t flags,
      60             :                         dpo_proto_t proto,
      61             :                         const dpo_id_t *dpo)
      62             : {
      63         140 :     src->fes_pl =
      64         140 :         fib_path_list_create_special(proto,
      65             :                                      FIB_PATH_LIST_FLAG_DROP,
      66             :                                      drop_dpo_get(proto));
      67         140 : }
      68             : 
      69             : static void
      70         281 : fib_entry_src_mpls_set_data (fib_entry_src_t *src,
      71             :                              const fib_entry_t *entry,
      72             :                              const void *data)
      73             : {
      74             :     fib_protocol_t payload_proto;
      75             :     fib_node_index_t fei;
      76             :     mpls_label_t label;
      77             :     mpls_eos_bit_t eos;
      78             : 
      79             :     /*
      80             :      * post MPLS table alloc and the possible rea-alloc of fib entrys
      81             :      * the entry pointer will no longer be valid. so save its index
      82             :      */
      83         281 :     payload_proto = entry->fe_prefix.fp_proto;
      84         281 :     fei = fib_entry_get_index(entry);
      85         281 :     label = *(mpls_label_t*)data;
      86             : 
      87         281 :     if (MPLS_LABEL_INVALID == label)
      88             :     {
      89             :         /*
      90             :          * removing the local label
      91             :          */
      92         420 :         FOR_EACH_MPLS_EOS_BIT(eos)
      93             :         {
      94         280 :             fib_table_entry_delete_index(src->u.mpls.fesm_lfes[eos],
      95             :                                          FIB_SOURCE_SPECIAL);
      96             :         }
      97         140 :         fib_table_unlock(MPLS_FIB_DEFAULT_TABLE_ID,
      98             :                          FIB_PROTOCOL_MPLS,
      99             :                          FIB_SOURCE_MPLS);
     100         140 :         src->u.mpls.fesm_label = label;
     101             :     }
     102             :     else
     103             :     {
     104         141 :         fib_prefix_t prefix = {
     105             :             .fp_proto = FIB_PROTOCOL_MPLS,
     106             :             .fp_label = label,
     107             :         };
     108             :         fib_node_index_t fib_index;
     109         141 :         dpo_id_t dpo = DPO_INVALID;
     110             : 
     111             :         /*
     112             :          * adding a new local label. make sure the MPLS fib exists.
     113             :          */
     114         141 :         if (MPLS_LABEL_INVALID == src->u.mpls.fesm_label)
     115             :         {
     116             :             fib_index =
     117         140 :                 fib_table_find_or_create_and_lock(FIB_PROTOCOL_MPLS,
     118             :                                                   MPLS_FIB_DEFAULT_TABLE_ID,
     119             :                                                   FIB_SOURCE_MPLS);
     120             :         }
     121             :         else
     122             :         {
     123           1 :             fib_index = mpls_fib_index_from_table_id(MPLS_FIB_DEFAULT_TABLE_ID);
     124             : 
     125             :             /*
     126             :              * if this is a change in label, remove the old one first
     127             :              */
     128           1 :             if (src->u.mpls.fesm_label != label)
     129             :             {
     130           3 :                 FOR_EACH_MPLS_EOS_BIT(eos)
     131             :                 {
     132           2 :                     ASSERT(FIB_NODE_INDEX_INVALID != src->u.mpls.fesm_lfes[eos]);
     133           2 :                     fib_table_entry_delete_index(src->u.mpls.fesm_lfes[eos],
     134             :                                                  FIB_SOURCE_SPECIAL);
     135             :                 }
     136             :             }
     137             :         }
     138             : 
     139         141 :         src->u.mpls.fesm_label = label;
     140             : 
     141         423 :         FOR_EACH_MPLS_EOS_BIT(eos)
     142             :         {
     143         282 :             prefix.fp_eos = eos;
     144         282 :             prefix.fp_payload_proto = fib_proto_to_dpo(payload_proto);
     145             : 
     146         282 :             fib_entry_contribute_forwarding(fei,
     147             :                                             (eos ?
     148             :                                              FIB_FORW_CHAIN_TYPE_MPLS_EOS :
     149             :                                              FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS),
     150             :                                             &dpo);
     151         282 :             src->u.mpls.fesm_lfes[eos] =
     152         282 :                 fib_table_entry_special_dpo_add(fib_index,
     153             :                                                 &prefix,
     154             :                                                 FIB_SOURCE_SPECIAL,
     155             :                                                 FIB_ENTRY_FLAG_EXCLUSIVE,
     156             :                                                 &dpo);
     157         282 :             dpo_reset(&dpo);
     158             :         }
     159             :     }
     160         281 : }
     161             : 
     162             : static const void *
     163         140 : fib_entry_src_mpls_get_data (fib_entry_src_t *src,
     164             :                              const fib_entry_t *entry)
     165             : {
     166         140 :     return (&(src->u.mpls.fesm_label));
     167             : }
     168             : 
     169             : static u8*
     170          67 : fib_entry_src_mpls_format (fib_entry_src_t *src,
     171             :                            u8* s)
     172             : {
     173          67 :     return (format(s, " local-label:%d", src->u.mpls.fesm_label));
     174             : }
     175             : 
     176             : const static fib_entry_src_vft_t mpls_src_vft = {
     177             :     .fesv_init = fib_entry_src_mpls_init,
     178             :     .fesv_deinit = fib_entry_src_mpls_deinit,
     179             :     .fesv_add = fib_entry_src_mpls_add,
     180             :     .fesv_remove = fib_entry_src_mpls_remove,
     181             :     .fesv_format = fib_entry_src_mpls_format,
     182             :     .fesv_set_data = fib_entry_src_mpls_set_data,
     183             :     .fesv_get_data = fib_entry_src_mpls_get_data,
     184             :     /*
     185             :      * .fesv_fwd_update = fib_entry_src_mpls_fwd_update,
     186             :      *  When the forwarding for the IP entry is updated, any MPLS chains
     187             :      * it has created are also updated. Since the MPLS entry will have already
     188             :      * installed that chain/load-balance there is no need to update the netry
     189             :      * FIXME: later: propagate any walk to the children of the MPLS entry. for SR
     190             :      */
     191             : };
     192             : 
     193             : void
     194         559 : fib_entry_src_mpls_register (void)
     195             : {
     196         559 :     fib_entry_src_behaviour_register(FIB_SOURCE_BH_MPLS, &mpls_src_vft);
     197         559 : }

Generated by: LCOV version 1.14