LCOV - code coverage report
Current view: top level - vnet/srv6 - sr_pt.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 8 113 7.1 %
Date: 2023-10-26 01:39:38 Functions: 9 15 60.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: Apache-2.0
       2             :  * Copyright(c) 2022 Cisco Systems, Inc.
       3             :  */
       4             : 
       5             : /**
       6             :  * @file
       7             :  * @brief SR Path Tracing (PT)
       8             :  *
       9             :  * SR PT CLI
      10             :  *
      11             :  */
      12             : 
      13             : #include <vlib/vlib.h>
      14             : #include <vnet/vnet.h>
      15             : #include <vnet/srv6/sr.h>
      16             : #include <vnet/ip/ip.h>
      17             : #include <vnet/srv6/sr_packet.h>
      18             : #include <vnet/ip/ip6_packet.h>
      19             : #include <vnet/fib/ip6_fib.h>
      20             : #include <vnet/dpo/dpo.h>
      21             : #include <vnet/adj/adj.h>
      22             : #include <vnet/srv6/sr_pt.h>
      23             : 
      24             : #include <vppinfra/error.h>
      25             : #include <vppinfra/elog.h>
      26             : 
      27             : sr_pt_main_t sr_pt_main;
      28             : 
      29             : void *
      30           0 : sr_pt_find_iface (u32 iface)
      31             : {
      32           0 :   sr_pt_main_t *sr_pt = &sr_pt_main;
      33             :   uword *p;
      34             : 
      35             :   /* Search for the item */
      36           0 :   p = mhash_get (&sr_pt->sr_pt_iface_index_hash, &iface);
      37           0 :   if (p)
      38             :     {
      39             :       /* Retrieve sr_pt_iface */
      40           0 :       return pool_elt_at_index (sr_pt->sr_pt_iface, p[0]);
      41             :     }
      42           0 :   return NULL;
      43             : }
      44             : 
      45             : int
      46           0 : sr_pt_add_iface (u32 iface, u16 id, u8 ingress_load, u8 egress_load,
      47             :                  u8 tts_template)
      48             : {
      49           0 :   sr_pt_main_t *sr_pt = &sr_pt_main;
      50             :   uword *p;
      51             : 
      52           0 :   sr_pt_iface_t *ls = 0;
      53             : 
      54           0 :   if (iface == (u32) ~0)
      55           0 :     return SR_PT_ERR_IFACE_INVALID;
      56             : 
      57             :   /* Search for the item */
      58           0 :   p = mhash_get (&sr_pt->sr_pt_iface_index_hash, &iface);
      59             : 
      60           0 :   if (p)
      61           0 :     return SR_PT_ERR_EXIST;
      62             : 
      63           0 :   if (id > SR_PT_ID_MAX)
      64           0 :     return SR_PT_ERR_ID_INVALID;
      65             : 
      66           0 :   if (ingress_load > SR_PT_LOAD_MAX || egress_load > SR_PT_LOAD_MAX)
      67           0 :     return SR_PT_ERR_LOAD_INVALID;
      68             : 
      69           0 :   if (tts_template > SR_PT_TTS_TEMPLATE_MAX)
      70           0 :     return SR_PT_ERR_TTS_TEMPLATE_INVALID;
      71             : 
      72           0 :   vnet_feature_enable_disable ("ip6-output", "pt", iface, 1, 0, 0);
      73             : 
      74             :   /* Create a new sr_pt_iface */
      75           0 :   pool_get_zero (sr_pt->sr_pt_iface, ls);
      76           0 :   ls->iface = iface;
      77           0 :   ls->id = id;
      78           0 :   ls->ingress_load = ingress_load;
      79           0 :   ls->egress_load = egress_load;
      80           0 :   ls->tts_template = tts_template;
      81             : 
      82             :   /* Set hash key for searching sr_pt_iface by iface */
      83           0 :   mhash_set (&sr_pt->sr_pt_iface_index_hash, &iface, ls - sr_pt->sr_pt_iface,
      84             :              NULL);
      85           0 :   return 0;
      86             : }
      87             : 
      88             : int
      89           0 : sr_pt_del_iface (u32 iface)
      90             : {
      91           0 :   sr_pt_main_t *sr_pt = &sr_pt_main;
      92             :   uword *p;
      93             : 
      94           0 :   sr_pt_iface_t *ls = 0;
      95             : 
      96           0 :   if (iface == (u32) ~0)
      97           0 :     return SR_PT_ERR_IFACE_INVALID;
      98             : 
      99             :   /* Search for the item */
     100           0 :   p = mhash_get (&sr_pt->sr_pt_iface_index_hash, &iface);
     101             : 
     102           0 :   if (p)
     103             :     {
     104             :       /* Retrieve sr_pt_iface */
     105           0 :       ls = pool_elt_at_index (sr_pt->sr_pt_iface, p[0]);
     106           0 :       vnet_feature_enable_disable ("ip6-output", "pt", iface, 0, 0, 0);
     107             :       /* Delete sr_pt_iface */
     108           0 :       pool_put (sr_pt->sr_pt_iface, ls);
     109           0 :       mhash_unset (&sr_pt->sr_pt_iface_index_hash, &iface, NULL);
     110             :     }
     111             :   else
     112             :     {
     113           0 :       return SR_PT_ERR_NOENT;
     114             :     }
     115           0 :   return 0;
     116             : }
     117             : 
     118             : /**
     119             :  * @brief "sr pt add iface" CLI function.
     120             :  *
     121             :  * @see sr_pt_add_iface
     122             :  */
     123             : static clib_error_t *
     124           0 : sr_pt_add_iface_command_fn (vlib_main_t *vm, unformat_input_t *input,
     125             :                             vlib_cli_command_t *cmd)
     126             : {
     127           0 :   vnet_main_t *vnm = vnet_get_main ();
     128           0 :   u32 iface = (u32) ~0;
     129           0 :   u32 id = (u32) ~0;
     130           0 :   u32 ingress_load = 0;
     131           0 :   u32 egress_load = 0;
     132           0 :   u32 tts_template = SR_PT_TTS_TEMPLATE_DEFAULT;
     133             : 
     134             :   int rv;
     135             : 
     136           0 :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     137             :     {
     138           0 :       if (unformat (input, "%U", unformat_vnet_sw_interface, vnm, &iface))
     139             :         ;
     140           0 :       else if (unformat (input, "id %u", &id))
     141             :         ;
     142           0 :       else if (unformat (input, "ingress-load %u", &ingress_load))
     143             :         ;
     144           0 :       else if (unformat (input, "egress-load %u", &egress_load))
     145             :         ;
     146           0 :       else if (unformat (input, "tts-template %u", &tts_template))
     147             :         ;
     148             :       else
     149           0 :         break;
     150             :     }
     151             : 
     152           0 :   rv = sr_pt_add_iface (iface, id, ingress_load, egress_load, tts_template);
     153             : 
     154           0 :   switch (rv)
     155             :     {
     156           0 :     case 0:
     157           0 :       break;
     158           0 :     case SR_PT_ERR_EXIST:
     159           0 :       return clib_error_return (0, "Error: Identical iface already exists.");
     160           0 :     case SR_PT_ERR_IFACE_INVALID:
     161           0 :       return clib_error_return (0, "Error: The iface name invalid.");
     162           0 :     case SR_PT_ERR_ID_INVALID:
     163           0 :       return clib_error_return (0, "Error: The iface id value invalid.");
     164           0 :     case SR_PT_ERR_LOAD_INVALID:
     165           0 :       return clib_error_return (
     166             :         0, "Error: The iface ingress or egress load value invalid.");
     167           0 :     case SR_PT_ERR_TTS_TEMPLATE_INVALID:
     168           0 :       return clib_error_return (
     169             :         0, "Error: The iface TTS Template value invalid.");
     170           0 :     default:
     171           0 :       return clib_error_return (0, "Error: unknown error.");
     172             :     }
     173           0 :   return 0;
     174             : }
     175             : 
     176             : /**
     177             :  * @brief "sr pt del iface" CLI function.
     178             :  *
     179             :  * @see sr_pt_del_iface
     180             :  */
     181             : static clib_error_t *
     182           0 : sr_pt_del_iface_command_fn (vlib_main_t *vm, unformat_input_t *input,
     183             :                             vlib_cli_command_t *cmd)
     184             : {
     185           0 :   vnet_main_t *vnm = vnet_get_main ();
     186           0 :   u32 iface = (u32) ~0;
     187             : 
     188             :   int rv;
     189             : 
     190           0 :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     191             :     {
     192           0 :       if (unformat (input, "%U", unformat_vnet_sw_interface, vnm, &iface))
     193             :         ;
     194             :       else
     195           0 :         break;
     196             :     }
     197             : 
     198           0 :   rv = sr_pt_del_iface (iface);
     199             : 
     200           0 :   switch (rv)
     201             :     {
     202           0 :     case 0:
     203           0 :       break;
     204           0 :     case SR_PT_ERR_NOENT:
     205           0 :       return clib_error_return (0, "Error: No such iface.");
     206           0 :     case SR_PT_ERR_IFACE_INVALID:
     207           0 :       return clib_error_return (0, "Error: The iface name is not valid.");
     208           0 :     default:
     209           0 :       return clib_error_return (0, "Error: unknown error.");
     210             :     }
     211           0 :   return 0;
     212             : }
     213             : 
     214             : /**
     215             :  * @brief CLI function to show all SR PT interfcaes
     216             :  */
     217             : static clib_error_t *
     218           0 : sr_pt_show_iface_command_fn (vlib_main_t *vm, unformat_input_t *input,
     219             :                              vlib_cli_command_t *cmd)
     220             : {
     221           0 :   vnet_main_t *vnm = vnet_get_main ();
     222           0 :   sr_pt_main_t *sr_pt = &sr_pt_main;
     223           0 :   sr_pt_iface_t **sr_pt_iface_list = 0;
     224             :   sr_pt_iface_t *ls;
     225             :   int i;
     226             : 
     227           0 :   vlib_cli_output (vm, "SR PT Interfaces");
     228           0 :   vlib_cli_output (vm, "==================================");
     229             : 
     230           0 :   pool_foreach (ls, sr_pt->sr_pt_iface)
     231             :     {
     232           0 :       vec_add1 (sr_pt_iface_list, ls);
     233             :     };
     234             : 
     235           0 :   for (i = 0; i < vec_len (sr_pt_iface_list); i++)
     236             :     {
     237           0 :       ls = sr_pt_iface_list[i];
     238           0 :       vlib_cli_output (
     239             :         vm,
     240             :         "\tiface       : \t%U\n\tid          : \t%d\n\tingress-load: "
     241             :         "\t%d\n\tegress-load : \t%d\n\ttts-template: \t%d  ",
     242           0 :         format_vnet_sw_if_index_name, vnm, ls->iface, ls->id, ls->ingress_load,
     243           0 :         ls->egress_load, ls->tts_template);
     244           0 :       vlib_cli_output (vm, "--------------------------------");
     245             :     }
     246             : 
     247           0 :   return 0;
     248             : }
     249             : 
     250      285289 : VLIB_CLI_COMMAND (sr_pt_add_iface_command, static) = {
     251             :   .path = "sr pt add iface",
     252             :   .short_help = "sr pt add iface <iface-name> id <pt-iface-id> ingress-load "
     253             :                 "<ingress-load-value> egress-load <egress-load-value> "
     254             :                 "tts-template <tts-template-value>",
     255             :   .function = sr_pt_add_iface_command_fn,
     256             : };
     257             : 
     258      285289 : VLIB_CLI_COMMAND (sr_pt_del_iface_command, static) = {
     259             :   .path = "sr pt del iface",
     260             :   .short_help = "sr pt del iface <iface-name>",
     261             :   .function = sr_pt_del_iface_command_fn,
     262             : };
     263             : 
     264      285289 : VLIB_CLI_COMMAND (sr_pt_show_iface_command, static) = {
     265             :   .path = "sr pt show iface",
     266             :   .short_help = "sr pt show iface",
     267             :   .function = sr_pt_show_iface_command_fn,
     268             : };
     269             : 
     270             : /**
     271             :  *  * @brief SR PT initialization
     272             :  *   */
     273             : clib_error_t *
     274         575 : sr_pt_init (vlib_main_t *vm)
     275             : {
     276         575 :   sr_pt_main_t *pt = &sr_pt_main;
     277         575 :   mhash_init (&pt->sr_pt_iface_index_hash, sizeof (uword), sizeof (u32));
     278         575 :   return 0;
     279             : }
     280             : 
     281       69119 : VLIB_INIT_FUNCTION (sr_pt_init);

Generated by: LCOV version 1.14