LCOV - code coverage report
Current view: top level - plugins/lisp/lisp-gpe - lisp_gpe_tenant.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 41 95 43.2 %
Date: 2023-07-05 22:20:52 Functions: 8 14 57.1 %

          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 <lisp/lisp-gpe/lisp_gpe_tenant.h>
      17             : 
      18             : /**
      19             :  * The pool of all tenants
      20             :  */
      21             : static lisp_gpe_tenant_t *lisp_gpe_tenant_pool;
      22             : 
      23             : /**
      24             :  * The hash table of all tenants: key:{VNI}.
      25             :  */
      26             : uword *lisp_gpe_tenant_db;
      27             : 
      28             : static lisp_gpe_tenant_t *
      29           4 : lisp_gpe_tenant_find (u32 vni)
      30             : {
      31             :   uword *p;
      32             : 
      33           4 :   p = hash_get (lisp_gpe_tenant_db, vni);
      34             : 
      35           4 :   if (NULL == p)
      36           1 :     return (NULL);
      37             : 
      38           3 :   return (pool_elt_at_index (lisp_gpe_tenant_pool, p[0]));
      39             : }
      40             : 
      41             : static lisp_gpe_tenant_t *
      42           2 : lisp_gpe_tenant_find_or_create_i (u32 vni)
      43             : {
      44             :   lisp_gpe_tenant_t *lt;
      45             : 
      46           2 :   lt = lisp_gpe_tenant_find (vni);
      47             : 
      48           2 :   if (NULL == lt)
      49             :     {
      50           1 :       pool_get (lisp_gpe_tenant_pool, lt);
      51           1 :       clib_memset (lt, 0, sizeof (*lt));
      52             : 
      53           1 :       lt->lt_vni = vni;
      54           1 :       lt->lt_table_id = ~0;
      55           1 :       lt->lt_bd_id = ~0;
      56             : 
      57           1 :       hash_set (lisp_gpe_tenant_db, vni, lt - lisp_gpe_tenant_pool);
      58             :     }
      59             : 
      60           2 :   return (lt);
      61             : }
      62             : 
      63             : /**
      64             :  * @brief Find or create a tenant for the given VNI
      65             :  */
      66             : u32
      67           1 : lisp_gpe_tenant_find_or_create (u32 vni)
      68             : {
      69             :   lisp_gpe_tenant_t *lt;
      70             : 
      71           1 :   lt = lisp_gpe_tenant_find (vni);
      72             : 
      73           1 :   if (NULL == lt)
      74             :     {
      75           0 :       lt = lisp_gpe_tenant_find_or_create_i (vni);
      76             :     }
      77             : 
      78           1 :   return (lt - lisp_gpe_tenant_pool);
      79             : }
      80             : 
      81             : /**
      82             :  * @brief If there are no more locks/users of te tenant, then delete it
      83             :  */
      84             : static void
      85           1 : lisp_gpe_tenant_delete_if_empty (lisp_gpe_tenant_t * lt)
      86             : {
      87             :   int i;
      88             : 
      89           2 :   for (i = 0; i < LISP_GPE_TENANT_LOCK_NUM; i++)
      90             :     {
      91           2 :       if (lt->lt_locks[i])
      92           1 :         return;
      93             :     }
      94             : 
      95           0 :   hash_unset (lisp_gpe_tenant_db, lt->lt_vni);
      96           0 :   pool_put (lisp_gpe_tenant_pool, lt);
      97             : }
      98             : 
      99             : /**
     100             :  * @brief Add/create and lock a new or find and lock the existing L3
     101             :  * interface for the tenant
     102             :  *
     103             :  * @paran vni The tenant's VNI
     104             :  * @param table_id the Tenant's L3 table ID.
     105             :  * @param with_default_route Install default route for the interface
     106             :  *
     107             :  * @return the SW IF index of the L3 interface
     108             :  */
     109             : u32
     110           2 : lisp_gpe_tenant_l3_iface_add_or_lock (u32 vni, u32 table_id,
     111             :                                       u8 with_default_route)
     112             : {
     113             :   lisp_gpe_tenant_t *lt;
     114             : 
     115           2 :   lt = lisp_gpe_tenant_find_or_create_i (vni);
     116             : 
     117           2 :   if (~0 == lt->lt_table_id)
     118           1 :     lt->lt_table_id = table_id;
     119             : 
     120           2 :   ASSERT (lt->lt_table_id == table_id);
     121             : 
     122           2 :   if (0 == lt->lt_locks[LISP_GPE_TENANT_LOCK_L3_IFACE])
     123             :     {
     124             :       /* create the l3 interface since there are currently no users of it */
     125           1 :       lt->lt_l3_sw_if_index =
     126           1 :         lisp_gpe_add_l3_iface (&lisp_gpe_main, vni, table_id,
     127             :                                with_default_route);
     128             :     }
     129             : 
     130           2 :   lt->lt_locks[LISP_GPE_TENANT_LOCK_L3_IFACE]++;
     131             : 
     132           2 :   return (lt->lt_l3_sw_if_index);
     133             : }
     134             : 
     135             : /**
     136             :  * @brief Release the lock held on the tenant's L3 interface
     137             :  */
     138             : void
     139           1 : lisp_gpe_tenant_l3_iface_unlock (u32 vni)
     140             : {
     141             :   lisp_gpe_tenant_t *lt;
     142             : 
     143           1 :   lt = lisp_gpe_tenant_find (vni);
     144             : 
     145           1 :   if (NULL == lt)
     146             :     {
     147           0 :       clib_warning ("No tenant for VNI %d", vni);
     148           0 :       return;
     149             :     }
     150             : 
     151           1 :   if (0 == lt->lt_locks[LISP_GPE_TENANT_LOCK_L3_IFACE])
     152             :     {
     153           0 :       clib_warning ("No L3 interface for tenant VNI %d", vni);
     154           0 :       return;
     155             :     }
     156             : 
     157           1 :   lt->lt_locks[LISP_GPE_TENANT_LOCK_L3_IFACE]--;
     158             : 
     159           1 :   if (0 == lt->lt_locks[LISP_GPE_TENANT_LOCK_L3_IFACE])
     160             :     {
     161             :       /* the last user has gone, so delete the l3 interface */
     162           0 :       lisp_gpe_del_l3_iface (&lisp_gpe_main, vni, lt->lt_table_id);
     163             :     }
     164             : 
     165             :   /*
     166             :    * If there are no more locks on any tenant managed resource, then
     167             :    * this tenant is toast.
     168             :    */
     169           1 :   lisp_gpe_tenant_delete_if_empty (lt);
     170             : }
     171             : 
     172             : /**
     173             :  * @brief Add/create and lock a new or find and lock the existing L2
     174             :  * interface for the tenant
     175             :  *
     176             :  * @paran vni The tenant's VNI
     177             :  * @param table_id the Tenant's L2 Bridge Domain ID.
     178             :  *
     179             :  * @return the SW IF index of the L2 interface
     180             :  */
     181             : u32
     182           0 : lisp_gpe_tenant_l2_iface_add_or_lock (u32 vni, u32 bd_id)
     183             : {
     184             :   lisp_gpe_tenant_t *lt;
     185             : 
     186           0 :   lt = lisp_gpe_tenant_find_or_create_i (vni);
     187             : 
     188           0 :   if (NULL == lt)
     189             :     {
     190           0 :       clib_warning ("No tenant for VNI %d", vni);
     191           0 :       return ~0;
     192             :     }
     193             : 
     194           0 :   if (~0 == lt->lt_bd_id)
     195           0 :     lt->lt_bd_id = bd_id;
     196             : 
     197           0 :   ASSERT (lt->lt_bd_id == bd_id);
     198             : 
     199           0 :   if (0 == lt->lt_locks[LISP_GPE_TENANT_LOCK_L2_IFACE])
     200             :     {
     201             :       /* create the l2 interface since there are currently no users of it */
     202           0 :       lt->lt_l2_sw_if_index =
     203           0 :         lisp_gpe_add_l2_iface (&lisp_gpe_main, vni, bd_id);
     204             :     }
     205             : 
     206           0 :   lt->lt_locks[LISP_GPE_TENANT_LOCK_L2_IFACE]++;
     207             : 
     208           0 :   return (lt->lt_l2_sw_if_index);
     209             : }
     210             : 
     211             : /**
     212             :  * @brief Release the lock held on the tenant's L3 interface
     213             :  */
     214             : void
     215           0 : lisp_gpe_tenant_l2_iface_unlock (u32 vni)
     216             : {
     217             :   lisp_gpe_tenant_t *lt;
     218             : 
     219           0 :   lt = lisp_gpe_tenant_find (vni);
     220             : 
     221           0 :   if (NULL == lt)
     222             :     {
     223           0 :       clib_warning ("No tenant for VNI %d", vni);
     224           0 :       return;
     225             :     }
     226             : 
     227           0 :   if (0 == lt->lt_locks[LISP_GPE_TENANT_LOCK_L2_IFACE])
     228             :     {
     229           0 :       clib_warning ("No L2 interface for tenant VNI %d", vni);
     230           0 :       return;
     231             :     }
     232             : 
     233           0 :   lt->lt_locks[LISP_GPE_TENANT_LOCK_L2_IFACE]--;
     234             : 
     235           0 :   if (0 == lt->lt_locks[LISP_GPE_TENANT_LOCK_L2_IFACE])
     236             :     {
     237             :       /* the last user has gone, so delete the l2 interface */
     238           0 :       lisp_gpe_del_l2_iface (&lisp_gpe_main, vni, lt->lt_bd_id);
     239             :     }
     240             : 
     241             :   /*
     242             :    * If there are no more locks on any tenant managed resource, then
     243             :    * this tenant is toast.
     244             :    */
     245           0 :   lisp_gpe_tenant_delete_if_empty (lt);
     246             : }
     247             : 
     248             : /**
     249             :  * @brief get a const pointer to the tenant object
     250             :  */
     251             : const lisp_gpe_tenant_t *
     252           0 : lisp_gpe_tenant_get (u32 index)
     253             : {
     254           0 :   return (pool_elt_at_index (lisp_gpe_tenant_pool, index));
     255             : }
     256             : 
     257             : /**
     258             :  * @brief Flush/delete ALL the tenants
     259             :  */
     260             : void
     261           0 : lisp_gpe_tenant_flush (void)
     262             : {
     263             :   lisp_gpe_tenant_t *lt;
     264             : 
     265             :   /* *INDENT-OFF* */
     266           0 :   pool_foreach (lt, lisp_gpe_tenant_pool)
     267             :    {
     268           0 :     lisp_gpe_tenant_l2_iface_unlock(lt->lt_vni);
     269           0 :     lisp_gpe_tenant_l3_iface_unlock(lt->lt_vni);
     270             :   }
     271             :   /* *INDENT-ON* */
     272           0 : }
     273             : 
     274             : /**
     275             :  * @brief Show/display one tenant
     276             :  */
     277             : static u8 *
     278           0 : format_lisp_gpe_tenant (u8 * s, va_list * ap)
     279             : {
     280           0 :   const lisp_gpe_tenant_t *lt = va_arg (*ap, lisp_gpe_tenant_t *);
     281             : 
     282           0 :   s = format (s, "VNI:%d ", lt->lt_vni);
     283             : 
     284           0 :   if (lt->lt_table_id != ~0)
     285             :     {
     286           0 :       s = format (s, "VRF:%d ", lt->lt_table_id);
     287           0 :       s = format (s, "L3-SW-IF:%d ", lt->lt_l3_sw_if_index);
     288             :     }
     289             : 
     290           0 :   if (lt->lt_bd_id != ~0)
     291             :     {
     292           0 :       s = format (s, "BD-ID:%d ", lt->lt_bd_id);
     293           0 :       s = format (s, "L2-SW-IF:%d ", lt->lt_l2_sw_if_index);
     294             :     }
     295             : 
     296           0 :   return (s);
     297             : }
     298             : 
     299             : /**
     300             :  * @brief CLI command to show LISP-GPE tenant.
     301             :  */
     302             : static clib_error_t *
     303           0 : lisp_gpe_tenant_show (vlib_main_t * vm,
     304             :                       unformat_input_t * input, vlib_cli_command_t * cmd)
     305             : {
     306             :   lisp_gpe_tenant_t *lt;
     307             : 
     308             :   /* *INDENT-OFF* */
     309           0 :   pool_foreach (lt, lisp_gpe_tenant_pool)
     310             :    {
     311           0 :     vlib_cli_output (vm, "%U", format_lisp_gpe_tenant, lt);
     312             :   }
     313             :   /* *INDENT-ON* */
     314             : 
     315           0 :   return 0;
     316             : }
     317             : 
     318             : /* *INDENT-OFF* */
     319      116069 : VLIB_CLI_COMMAND (lisp_gpe_tenant_command) = {
     320             :   .path = "show gpe tenant",
     321             :   .short_help = "show gpe tenant",
     322             :   .function = lisp_gpe_tenant_show,
     323             : };
     324             : /* *INDENT-ON* */
     325             : 
     326             : 
     327             : /*
     328             :  * fd.io coding-style-patch-verification: ON
     329             :  *
     330             :  * Local Variables:
     331             :  * eval: (c-set-style "gnu")
     332             :  * End:
     333             :  */

Generated by: LCOV version 1.14