LCOV - code coverage report
Current view: top level - plugins/linux-cp - lcp_adj.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 33 76 43.4 %
Date: 2023-10-26 01:39:38 Functions: 9 12 75.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2020 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/adj/adj_delegate.h>
      17             : 
      18             : #include <linux-cp/lcp_interface.h>
      19             : #include <linux-cp/lcp_adj.h>
      20             : 
      21             : #include <vppinfra/bihash_32_8.h>
      22             : #include <vppinfra/bihash_template.c>
      23             : 
      24             : static adj_delegate_type_t adj_type;
      25             : static lcp_adj_key_t *adj_keys;
      26             : 
      27             : /**
      28             :  * The table of adjacencies indexed by the rewrite string
      29             :  */
      30             : BVT (clib_bihash) lcp_adj_tbl;
      31             : 
      32             : static_always_inline void
      33           4 : lcp_adj_mk_key_adj (const ip_adjacency_t *adj, lcp_adj_key_t *key)
      34             : {
      35           4 :   lcp_adj_mk_key (adj->rewrite_header.data, adj->rewrite_header.data_bytes,
      36             :                   adj->rewrite_header.sw_if_index, key);
      37           4 : }
      38             : 
      39             : static u8 *
      40           0 : lcp_adj_delegate_format (const adj_delegate_t *aed, u8 *s)
      41             : {
      42           0 :   return (format (s, "lcp"));
      43             : }
      44             : 
      45             : static void
      46           4 : lcp_adj_delegate_adj_deleted (adj_delegate_t *aed)
      47             : {
      48             :   ip_adjacency_t *adj;
      49             :   lcp_adj_kv_t kv;
      50             : 
      51           4 :   adj = adj_get (aed->ad_adj_index);
      52             : 
      53           4 :   lcp_adj_mk_key_adj (adj, &kv.k);
      54             : 
      55           4 :   BV (clib_bihash_add_del) (&lcp_adj_tbl, &kv.kv, 0);
      56             : 
      57           4 :   if (aed->ad_index != INDEX_INVALID)
      58           0 :     pool_put_index (adj_keys, aed->ad_index);
      59           4 : }
      60             : 
      61             : /* when an adj is modified:
      62             :  *
      63             :  * An existing hash entry may need to be deleted. This may occur when:
      64             :  * * The newly modified adj does not have IP_LOOKUP_NEXT_REWRITE as next idx
      65             :  * * The rewrite (== major component of hash key) changed
      66             :  *
      67             :  * A new hash entry may need to be added. This may occur when:
      68             :  * * The newly modified adj has IP_LOOKUP_NEXT_REWRITE as next idx
      69             :  * * The rewrite changed or there was no existing hash entry
      70             :  */
      71             : static void
      72           0 : lcp_adj_delegate_adj_modified (adj_delegate_t *aed)
      73             : {
      74             :   ip_adjacency_t *adj;
      75             :   lcp_adj_kv_t kv;
      76           0 :   lcp_adj_key_t *adj_key = NULL;
      77             :   u8 save_adj, key_changed;
      78             : 
      79           0 :   key_changed = 0;
      80             : 
      81           0 :   adj = adj_get (aed->ad_adj_index);
      82           0 :   save_adj = (IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index);
      83             : 
      84           0 :   if (aed->ad_index != INDEX_INVALID)
      85           0 :     adj_key = pool_elt_at_index (adj_keys, aed->ad_index);
      86             : 
      87             :   /* return if there was no stored adj and we will not add one */
      88           0 :   if (!adj_key && !save_adj)
      89           0 :     return;
      90             : 
      91             :   /* build kv if a new entry should be stored */
      92           0 :   if (save_adj)
      93             :     {
      94           0 :       lcp_adj_mk_key_adj (adj, &kv.k);
      95           0 :       kv.v = aed->ad_adj_index;
      96           0 :       if (adj_key)
      97           0 :         key_changed = (clib_memcmp (adj_key, &kv.k, sizeof (*adj_key)) != 0);
      98             :     }
      99             : 
     100             :   /* delete old entry if needed */
     101           0 :   if (adj_key && ((save_adj && key_changed) || (!save_adj)))
     102             :     {
     103             :       lcp_adj_kv_t old_kv;
     104             : 
     105           0 :       clib_memcpy_fast (&old_kv.k, adj_key, sizeof (*adj_key));
     106           0 :       old_kv.v = 0;
     107             : 
     108           0 :       BV (clib_bihash_add_del) (&lcp_adj_tbl, &old_kv.kv, 0);
     109             : 
     110           0 :       if (!save_adj)
     111             :         {
     112           0 :           pool_put (adj_keys, adj_key);
     113           0 :           aed->ad_index = INDEX_INVALID;
     114             :         }
     115             :     }
     116             : 
     117             :   /* add new entry if needed */
     118           0 :   if (save_adj)
     119             :     {
     120           0 :       BV (clib_bihash_add_del) (&lcp_adj_tbl, &kv.kv, 1);
     121             : 
     122           0 :       if (!adj_key)
     123             :         {
     124           0 :           pool_get (adj_keys, adj_key);
     125           0 :           aed->ad_index = adj_key - adj_keys;
     126             :         }
     127           0 :       clib_memcpy_fast (adj_key, &kv.k, sizeof (*adj_key));
     128             :     }
     129             : }
     130             : 
     131             : static void
     132          78 : lcp_adj_delegate_adj_created (adj_index_t ai)
     133             : {
     134             :   ip_adjacency_t *adj;
     135             :   lcp_adj_kv_t kv;
     136          78 :   index_t lai = INDEX_INVALID;
     137             :   lcp_adj_key_t *adj_key;
     138             :   index_t lipi;
     139             :   lcp_itf_pair_t *lip;
     140             : 
     141          78 :   adj = adj_get (ai);
     142             : 
     143          78 :   lipi = lcp_itf_pair_find_by_phy (adj->rewrite_header.sw_if_index);
     144          78 :   if (lipi == INDEX_INVALID)
     145          74 :     return;
     146             : 
     147           6 :   lip = lcp_itf_pair_get (lipi);
     148           6 :   if (lip->lip_host_type == LCP_ITF_HOST_TUN)
     149           2 :     return;
     150             : 
     151           4 :   if (IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index)
     152             :     {
     153           0 :       lcp_adj_mk_key_adj (adj, &kv.k);
     154           0 :       pool_get (adj_keys, adj_key);
     155           0 :       clib_memcpy_fast (adj_key, &kv.k, sizeof (*adj_key));
     156           0 :       kv.v = ai;
     157             : 
     158           0 :       BV (clib_bihash_add_del) (&lcp_adj_tbl, &kv.kv, 1);
     159           0 :       lai = adj_key - adj_keys;
     160             :     }
     161             : 
     162           4 :   adj_delegate_add (adj, adj_type, lai);
     163             : }
     164             : 
     165             : u8 *
     166           0 : format_lcp_adj_kvp (u8 *s, va_list *args)
     167             : {
     168           0 :   BVT (clib_bihash_kv) *kv = va_arg (*args, BVT (clib_bihash_kv) *);
     169           0 :   CLIB_UNUSED (int verbose) = va_arg (*args, int);
     170           0 :   lcp_adj_kv_t *akv = (lcp_adj_kv_t *) kv;
     171             : 
     172           0 :   s = format (s, "  %U:%U\n    %U", format_vnet_sw_if_index_name,
     173             :               vnet_get_main (), akv->k.sw_if_index, format_hex_bytes,
     174           0 :               akv->k.rewrite, 18, format_adj_nbr, akv->v, 4);
     175             : 
     176           0 :   return (s);
     177             : }
     178             : 
     179             : static clib_error_t *
     180           2 : lcp_adj_show_cmd (vlib_main_t *vm, unformat_input_t *input,
     181             :                   vlib_cli_command_t *cmd)
     182             : {
     183           2 :   u8 verbose = 0;
     184             : 
     185           2 :   if (unformat (input, "verbose"))
     186           2 :     verbose = 1;
     187             : 
     188           2 :   vlib_cli_output (vm, "linux-cp adjacencies:\n%U", BV (format_bihash),
     189             :                    &lcp_adj_tbl, verbose);
     190             : 
     191           2 :   return 0;
     192             : }
     193             : 
     194         604 : VLIB_CLI_COMMAND (lcp_itf_pair_show_cmd_node, static) = {
     195             :   .path = "show lcp adj",
     196             :   .function = lcp_adj_show_cmd,
     197             :   .short_help = "show lcp adj",
     198             :   .is_mp_safe = 1,
     199             : };
     200             : 
     201             : const adj_delegate_vft_t lcp_adj_vft = {
     202             :   .adv_format = lcp_adj_delegate_format,
     203             :   .adv_adj_deleted = lcp_adj_delegate_adj_deleted,
     204             :   .adv_adj_modified = lcp_adj_delegate_adj_modified,
     205             :   .adv_adj_created = lcp_adj_delegate_adj_created,
     206             : };
     207             : 
     208             : static clib_error_t *
     209           2 : lcp_adj_init (vlib_main_t *vm)
     210             : {
     211           2 :   adj_type = adj_delegate_register_new_type (&lcp_adj_vft);
     212             : 
     213           2 :   BV (clib_bihash_init) (&lcp_adj_tbl, "linux-cp adjacencies", 1024, 1 << 24);
     214           2 :   BV (clib_bihash_set_kvp_format_fn) (&lcp_adj_tbl, format_lcp_adj_kvp);
     215             : 
     216           2 :   return (NULL);
     217             : }
     218             : 
     219           8 : VLIB_INIT_FUNCTION (lcp_adj_init);
     220             : 
     221             : /*
     222             :  * fd.io coding-style-patch-verification: ON
     223             :  *
     224             :  * Local Variables:
     225             :  * eval: (c-set-style "gnu")
     226             :  * End:
     227             :  */

Generated by: LCOV version 1.14