LCOV - code coverage report
Current view: top level - vnet/bier - bier_fmask_db.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 37 43 86.0 %
Date: 2023-07-05 22:20:52 Functions: 7 9 77.8 %

          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/bier/bier_fmask_db.h>
      17             : #include <vnet/bier/bier_fmask.h>
      18             : 
      19             : /**
      20             :  * Global Table of fmask objects
      21             :  * The key into this table includes the table's key and the fmask's key,
      22             :  * so there could be a DB per-table. But it is more efficient
      23             :  * at forwarding time to extract the fmask from a single global table
      24             :  * which is hot in dcache.
      25             :  *
      26             :  * The table's key is part of this DB key, since the fmasks therein build up
      27             :  * their forwarding mask based on the routes that resolve through
      28             :  * it, so cross pollination would be bad.
      29             :  */
      30             : typedef struct bier_fmask_db_t_ {
      31             :     /**
      32             :      * hash table for underlying storage
      33             :      */
      34             :     uword *bfdb_hash;
      35             : 
      36             :     /**
      37             :      * Pool for memory
      38             :      */
      39             :     struct bier_fmask_t_ *bfdb_pool;
      40             : } bier_fmask_db_t;
      41             : 
      42             : /**
      43             :  * Single fmask DB
      44             :  */
      45             : static bier_fmask_db_t bier_fmask_db;
      46             : 
      47             : 
      48             : u32
      49           0 : bier_fmask_get_index (const bier_fmask_t *bfm)
      50             : {
      51           0 :     return (bfm - bier_fmask_db.bfdb_pool);
      52             : }
      53             : 
      54             : static void
      55         163 : bier_fmask_db_mk_key (index_t bti,
      56             :                       const fib_route_path_t *rpath,
      57             :                       bier_fmask_id_t *key)
      58             : {
      59             :     /*
      60             :      * Depending on what the ID is there may be padding.
      61             :      * This key will be memcmp'd in the mhash, so make sure it's all 0
      62             :      */
      63         163 :     clib_memset(key, 0, sizeof(*key));
      64             : 
      65             :     /*
      66             :      * Pick the attributes from the path that make the FMask unique
      67             :      */
      68         163 :     if (FIB_ROUTE_PATH_UDP_ENCAP & rpath->frp_flags)
      69             :     {
      70           2 :         key->bfmi_id = rpath->frp_udp_encap_id;
      71           2 :         key->bfmi_nh_type = BIER_NH_UDP;
      72             :     }
      73             :     else
      74             :     {
      75         161 :         memcpy(&key->bfmi_nh, &rpath->frp_addr, sizeof(rpath->frp_addr));
      76         161 :         key->bfmi_nh_type = BIER_NH_IP;
      77             :     }
      78         163 :     if (NULL == rpath->frp_label_stack)
      79             :     {
      80          13 :         key->bfmi_hdr_type = BIER_HDR_O_OTHER;
      81             :     }
      82             :     else
      83             :     {
      84         150 :         key->bfmi_hdr_type = BIER_HDR_O_MPLS;
      85             :     }
      86         163 :     key->bfmi_bti = bti;
      87         163 : }
      88             : 
      89             : u32
      90          81 : bier_fmask_db_find (index_t bti,
      91             :                     const fib_route_path_t *rpath)
      92             : {
      93             :     bier_fmask_id_t fmid;
      94             :     uword *p;
      95             : 
      96          81 :     bier_fmask_db_mk_key(bti, rpath, &fmid);
      97          81 :     p = hash_get_mem(bier_fmask_db.bfdb_hash, &fmid);
      98             : 
      99          81 :     if (NULL != p)
     100             :     {
     101          80 :         return (p[0]);
     102             :     }
     103             : 
     104           1 :     return (INDEX_INVALID);
     105             : }
     106             : 
     107             : u32
     108          82 : bier_fmask_db_find_or_create_and_lock (index_t bti,
     109             :                                        const fib_route_path_t *rpath)
     110             : {
     111             :     bier_fmask_id_t fmid;
     112             :     u32 index;
     113             :     uword *p;
     114             : 
     115          82 :     bier_fmask_db_mk_key(bti, rpath, &fmid);
     116          82 :     p = hash_get_mem(bier_fmask_db.bfdb_hash, &fmid);
     117             : 
     118          82 :     if (NULL == p)
     119             :     {
     120             :         bier_fmask_t *bfm;
     121             :         /*
     122             :          * adding a new fmask object
     123             :          */
     124          77 :         index = bier_fmask_create_and_lock(&fmid, rpath);
     125          77 :         bfm = bier_fmask_get(index);
     126         154 :         hash_set_mem(bier_fmask_db.bfdb_hash, bfm->bfm_id, index);
     127             :     }
     128             :     else
     129             :     {
     130           5 :         index = p[0];
     131           5 :         bier_fmask_lock(index);
     132             :     }
     133             : 
     134          82 :     return (index);
     135             : }
     136             : 
     137             : void
     138          77 : bier_fmask_db_remove (const bier_fmask_id_t *fmid)
     139             : {
     140             :     uword *p;
     141             : 
     142          77 :     p = hash_get_mem(bier_fmask_db.bfdb_hash, fmid);
     143             : 
     144          77 :     if (NULL == p) {
     145             :         /*
     146             :          * remove a non-existent entry - oops
     147             :          */
     148           0 :         ASSERT (!"remove non-existent fmask");
     149             :     } else {
     150          77 :         hash_unset(bier_fmask_db.bfdb_hash, fmid);
     151             :     }
     152          77 : }
     153             : 
     154             : void
     155           0 : bier_fmask_db_walk (bier_fmask_walk_fn_t fn, void *ctx)
     156             : {
     157             :     CLIB_UNUSED (bier_fmask_id_t *fmid);
     158             :     uword *bfmi;
     159             : 
     160           0 :     hash_foreach(fmid, bfmi, bier_fmask_db.bfdb_hash,
     161             :     ({
     162             :         if (WALK_STOP == fn(*bfmi, ctx))
     163             :             break;
     164             :     }));
     165           0 : }
     166             : 
     167             : clib_error_t *
     168         559 : bier_fmask_db_module_init (vlib_main_t *vm)
     169             : {
     170         559 :     bier_fmask_db.bfdb_hash = hash_create_mem(0,
     171             :                                               sizeof(bier_fmask_id_t),
     172             :                                               sizeof(index_t));
     173             : 
     174         559 :     return (NULL);
     175             : }
     176             : 
     177       89039 : VLIB_INIT_FUNCTION (bier_fmask_db_module_init);

Generated by: LCOV version 1.14