LCOV - code coverage report
Current view: top level - vnet/fib - fib_urpf_list.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 71 74 95.9 %
Date: 2023-10-26 01:39:38 Functions: 12 12 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/fib/fib_urpf_list.h>
      17             : #include <vnet/adj/adj.h>
      18             : 
      19             : /**
      20             :  * @brief pool of all fib_urpf_list
      21             :  */
      22             : fib_urpf_list_t *fib_urpf_list_pool;
      23             : 
      24             : u8 *
      25         244 : format_fib_urpf_list (u8 *s, va_list *args)
      26             : {
      27             :     fib_urpf_list_t *urpf;
      28             :     index_t ui;
      29             :     u32 *swi;
      30             : 
      31         244 :     ui = va_arg(*args, index_t);
      32             : 
      33         244 :     if (INDEX_INVALID != ui)
      34             :     {
      35         232 :         urpf = fib_urpf_list_get(ui);
      36             : 
      37         232 :         s = format(s, "uPRF-list:%d len:%d itfs:[",
      38         232 :                    ui, vec_len(urpf->furpf_itfs));
      39             : 
      40         378 :         vec_foreach(swi, urpf->furpf_itfs)
      41             :         {
      42         146 :             s = format(s, "%d, ", *swi);
      43             :         }
      44         232 :         s = format(s, "]");
      45             :     }
      46             :     else
      47             :     {
      48          12 :         s = format(s, "uRPF-list: None");
      49             :     }
      50             : 
      51         244 :     return (s);
      52             : }
      53             : 
      54             : index_t
      55       91473 : fib_urpf_list_alloc_and_lock (void)
      56             : {
      57             :     fib_urpf_list_t *urpf;
      58       91473 :     u8 need_barrier_sync = pool_get_will_expand (fib_urpf_list_pool);
      59       91473 :     vlib_main_t *vm = vlib_get_main();
      60       91473 :     ASSERT (vm->thread_index == 0);
      61             : 
      62       91473 :     if (need_barrier_sync)
      63        3932 :         vlib_worker_thread_barrier_sync (vm);
      64             : 
      65       91473 :     pool_get(fib_urpf_list_pool, urpf);
      66             : 
      67       91473 :     if (need_barrier_sync)
      68        3932 :         vlib_worker_thread_barrier_release (vm);
      69             : 
      70       91473 :     clib_memset(urpf, 0, sizeof(*urpf));
      71             : 
      72       91473 :     urpf->furpf_locks++;
      73             : 
      74       91473 :     return (urpf - fib_urpf_list_pool);
      75             : }
      76             : 
      77             : void
      78      262237 : fib_urpf_list_unlock (index_t ui)
      79             : {
      80             :     fib_urpf_list_t *urpf;
      81             : 
      82      262237 :     if (INDEX_INVALID == ui)
      83      112437 :         return;
      84             : 
      85      149800 :     urpf = fib_urpf_list_get(ui);
      86             : 
      87      149800 :     urpf->furpf_locks--;
      88             : 
      89      149800 :     if (0 == urpf->furpf_locks)
      90             :     {
      91       79447 :         vec_free(urpf->furpf_itfs);
      92       79447 :         pool_put(fib_urpf_list_pool, urpf);
      93             :     }
      94             : }
      95             : 
      96             : void
      97       79876 : fib_urpf_list_lock (index_t ui)
      98             : {
      99             :     fib_urpf_list_t *urpf;
     100             : 
     101       79876 :     urpf = fib_urpf_list_get(ui);
     102             : 
     103       79876 :     urpf->furpf_locks++;
     104       79876 : }
     105             : 
     106             : /**
     107             :  * @brief Append another interface to the list.
     108             :  */
     109             : void
     110       89741 : fib_urpf_list_append (index_t ui,
     111             :                       u32 sw_if_index)
     112             : {
     113             :     fib_urpf_list_t *urpf;
     114             : 
     115       89741 :     urpf = fib_urpf_list_get(ui);
     116             : 
     117       89741 :     vec_add1(urpf->furpf_itfs, sw_if_index);
     118       89741 : }
     119             : 
     120             : /**
     121             :  * @brief Combine to interface lists
     122             :  */
     123             : void
     124        3306 : fib_urpf_list_combine (index_t ui1,
     125             :                        index_t ui2)
     126             : {
     127             :     fib_urpf_list_t *urpf1, *urpf2;
     128             : 
     129        3306 :     urpf1 = fib_urpf_list_get(ui1);
     130        3306 :     urpf2 = fib_urpf_list_get(ui2);
     131             : 
     132        3306 :     vec_append(urpf1->furpf_itfs, urpf2->furpf_itfs);
     133        3306 : }
     134             : 
     135             : /**
     136             :  * @brief Sort the interface indicies.
     137             :  * The sort is the first step in obtaining a unique list, so the order,
     138             :  * w.r.t. next-hop, interface,etc is not important. So a sort based on the
     139             :  * index is all we need.
     140             :  */
     141             : static int
     142      110941 : fib_urpf_itf_cmp_for_sort (void * v1,
     143             :                            void * v2)
     144             : {
     145      110941 :     const adj_index_t *i1 = v1, *i2 = v2;
     146      110941 :     return (*i2 < *i1);
     147             : }
     148             : 
     149             : /**
     150             :  * @brief Convert the uRPF list from the itf set obtained during the walk
     151             :  * to a unique list.
     152             :  */
     153             : void
     154       91473 : fib_urpf_list_bake (index_t ui)
     155             : {
     156             :     fib_urpf_list_t *urpf;
     157             : 
     158       91473 :     urpf = fib_urpf_list_get(ui);
     159             : 
     160       91473 :     ASSERT(!(urpf->furpf_flags & FIB_URPF_LIST_BAKED));
     161             : 
     162       91473 :     if (vec_len(urpf->furpf_itfs) > 1)
     163             :       {
     164             :         u32 i, j;
     165             :         /*
     166             :          * cat list | sort | uniq > rpf_list
     167             :          */
     168             :         /* sort */
     169       12056 :         vec_sort_with_function(urpf->furpf_itfs, fib_urpf_itf_cmp_for_sort);
     170             :         /* remove duplicates */
     171       12056 :         i = 0;
     172       49623 :         for (j=1; j<vec_len(urpf->furpf_itfs); j++)
     173       37567 :           if (urpf->furpf_itfs[i] != urpf->furpf_itfs[j])
     174       24367 :             urpf->furpf_itfs[++i] = urpf->furpf_itfs[j];
     175             :         /* set the length of the vector to the number of unique itfs */
     176       12056 :         vec_set_len (urpf->furpf_itfs, i+1);
     177             :       }
     178             : 
     179       91473 :     urpf->furpf_flags |= FIB_URPF_LIST_BAKED;
     180       91473 : }
     181             : 
     182             : void
     183           1 : fib_urpf_list_show_mem (void)
     184             : {
     185           1 :     fib_show_memory_usage("uRPF-list",
     186           1 :                           pool_elts(fib_urpf_list_pool),
     187           1 :                           pool_len(fib_urpf_list_pool),
     188             :                           sizeof(fib_urpf_list_t));
     189           1 : }
     190             : 
     191             : static clib_error_t *
     192           1 : show_fib_urpf_list_command (vlib_main_t * vm,
     193             :                             unformat_input_t * input,
     194             :                             vlib_cli_command_t * cmd)
     195             : {
     196             :     index_t ui;
     197             : 
     198           1 :     if (unformat (input, "%d", &ui))
     199             :     {
     200             :         /*
     201             :          * show one in detail
     202             :          */
     203           0 :         if (!pool_is_free_index(fib_urpf_list_pool, ui))
     204             :         {
     205           0 :             vlib_cli_output (vm, "%d@%U",
     206             :                              ui,
     207             :                              format_fib_urpf_list, ui);
     208             :         }
     209             :         else
     210             :         {
     211           0 :             vlib_cli_output (vm, "uRPF %d invalid", ui);
     212             :         }
     213             :     }
     214             :     else
     215             :     {
     216             :         /*
     217             :          * show all
     218             :          */
     219           1 :         vlib_cli_output (vm, "FIB uRPF Entries:");
     220           8 :         pool_foreach_index (ui, fib_urpf_list_pool)
     221             :          {
     222           7 :             vlib_cli_output (vm, "%d@%U",
     223             :                              ui,
     224             :                              format_fib_urpf_list, ui);
     225             :         }
     226             :     }
     227             : 
     228           1 :     return (NULL);
     229             : }
     230             : 
     231             : /* *INDENT-OFF* */
     232             : /*?
     233             :  * The '<em>sh fib uRPF [index] </em>' command displays the uRPF lists
     234             :  *
     235             :  * @cliexpar
     236             :  * @cliexstart{show fib uRPF}
     237             :  * FIB uRPF Entries:
     238             :  *  0@uPRF-list:0 len:0 itfs:[]
     239             :  *  1@uPRF-list:1 len:2 itfs:[1, 2, ]
     240             :  *  2@uPRF-list:2 len:1 itfs:[3, ]
     241             :  *  3@uPRF-list:3 len:1 itfs:[9, ]
     242             :  * @cliexend
     243             : ?*/
     244      285289 : VLIB_CLI_COMMAND (show_fib_urpf_list, static) = {
     245             :   .path = "show fib uRPF",
     246             :   .function = show_fib_urpf_list_command,
     247             :   .short_help = "show fib uRPF",
     248             : };
     249             : /* *INDENT-OFF* */

Generated by: LCOV version 1.14