LCOV - code coverage report
Current view: top level - lib/ipsec - ipsec_telemetry.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 5 85 5.9 %
Date: 2025-03-01 20:23:48 Functions: 1 6 16.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 62 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2021 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <stdlib.h>
       6                 :            : #include <rte_ipsec.h>
       7                 :            : #include <rte_telemetry.h>
       8                 :            : #include <rte_malloc.h>
       9                 :            : #include "sa.h"
      10                 :            : 
      11                 :            : 
      12                 :            : struct ipsec_telemetry_entry {
      13                 :            :         LIST_ENTRY(ipsec_telemetry_entry) next;
      14                 :            :         const struct rte_ipsec_sa *sa;
      15                 :            : };
      16                 :            : static LIST_HEAD(ipsec_telemetry_head, ipsec_telemetry_entry)
      17                 :            :                 ipsec_telemetry_list = LIST_HEAD_INITIALIZER();
      18                 :            : 
      19                 :            : static int
      20                 :          0 : handle_telemetry_cmd_ipsec_sa_list(const char *cmd __rte_unused,
      21                 :            :                 const char *params __rte_unused,
      22                 :            :                 struct rte_tel_data *data)
      23                 :            : {
      24                 :            :         struct ipsec_telemetry_entry *entry;
      25                 :          0 :         rte_tel_data_start_array(data, RTE_TEL_UINT_VAL);
      26                 :            : 
      27         [ #  # ]:          0 :         LIST_FOREACH(entry, &ipsec_telemetry_list, next) {
      28                 :          0 :                 const struct rte_ipsec_sa *sa = entry->sa;
      29         [ #  # ]:          0 :                 rte_tel_data_add_array_uint(data, rte_be_to_cpu_32(sa->spi));
      30                 :            :         }
      31                 :            : 
      32                 :          0 :         return 0;
      33                 :            : }
      34                 :            : 
      35                 :            : /**
      36                 :            :  * Handle IPsec SA statistics telemetry request
      37                 :            :  *
      38                 :            :  * Return dict of SA's with dict of key/value counters
      39                 :            :  *
      40                 :            :  * {
      41                 :            :  *     "SA_SPI_XX": {"count": 0, "bytes": 0, "errors": 0},
      42                 :            :  *     "SA_SPI_YY": {"count": 0, "bytes": 0, "errors": 0}
      43                 :            :  * }
      44                 :            :  */
      45                 :            : static int
      46                 :          0 : handle_telemetry_cmd_ipsec_sa_stats(const char *cmd __rte_unused,
      47                 :            :                 const char *params,
      48                 :            :                 struct rte_tel_data *data)
      49                 :            : {
      50                 :            :         struct ipsec_telemetry_entry *entry;
      51                 :            :         const struct rte_ipsec_sa *sa;
      52                 :            :         uint32_t sa_spi = 0;
      53                 :            : 
      54         [ #  # ]:          0 :         if (params) {
      55                 :          0 :                 sa_spi = rte_cpu_to_be_32((uint32_t)strtoul(params, NULL, 0));
      56         [ #  # ]:          0 :                 if (sa_spi == 0)
      57                 :            :                         return -EINVAL;
      58                 :            :         }
      59                 :            : 
      60                 :          0 :         rte_tel_data_start_dict(data);
      61                 :            : 
      62         [ #  # ]:          0 :         LIST_FOREACH(entry, &ipsec_telemetry_list, next) {
      63                 :            :                 char sa_name[64];
      64                 :          0 :                 sa = entry->sa;
      65                 :            :                 static const char *name_pkt_cnt = "count";
      66                 :            :                 static const char *name_byte_cnt = "bytes";
      67                 :            :                 static const char *name_error_cnt = "errors";
      68                 :            :                 struct rte_tel_data *sa_data;
      69                 :            : 
      70                 :            :                 /* If user provided SPI only get telemetry for that SA */
      71   [ #  #  #  # ]:          0 :                 if (sa_spi && (sa_spi != sa->spi))
      72                 :          0 :                         continue;
      73                 :            : 
      74                 :            :                 /* allocate telemetry data struct for SA telemetry */
      75                 :          0 :                 sa_data = rte_tel_data_alloc();
      76         [ #  # ]:          0 :                 if (!sa_data)
      77                 :          0 :                         return -ENOMEM;
      78                 :            : 
      79                 :          0 :                 rte_tel_data_start_dict(sa_data);
      80                 :            : 
      81                 :            :                 /* add telemetry key/values pairs */
      82                 :          0 :                 rte_tel_data_add_dict_uint(sa_data, name_pkt_cnt,
      83                 :          0 :                                            sa->statistics.count);
      84                 :            : 
      85                 :          0 :                 rte_tel_data_add_dict_uint(sa_data, name_byte_cnt,
      86                 :          0 :                                            sa->statistics.bytes -
      87                 :          0 :                                            (sa->statistics.count * sa->hdr_len));
      88                 :            : 
      89                 :          0 :                 rte_tel_data_add_dict_uint(sa_data, name_error_cnt,
      90                 :          0 :                                            sa->statistics.errors.count);
      91                 :            : 
      92                 :            :                 /* generate telemetry label */
      93                 :          0 :                 snprintf(sa_name, sizeof(sa_name), "SA_SPI_%i",
      94         [ #  # ]:          0 :                                 rte_be_to_cpu_32(sa->spi));
      95                 :            : 
      96                 :            :                 /* add SA telemetry to dictionary container */
      97                 :          0 :                 rte_tel_data_add_dict_container(data, sa_name, sa_data, 0);
      98                 :            :         }
      99                 :            : 
     100                 :            :         return 0;
     101                 :            : }
     102                 :            : 
     103                 :            : static int
     104                 :          0 : handle_telemetry_cmd_ipsec_sa_details(const char *cmd __rte_unused,
     105                 :            :                 const char *params,
     106                 :            :                 struct rte_tel_data *data)
     107                 :            : {
     108                 :            :         struct ipsec_telemetry_entry *entry;
     109                 :            :         const struct rte_ipsec_sa *sa;
     110                 :            :         uint32_t sa_spi = 0;
     111                 :            : 
     112         [ #  # ]:          0 :         if (params)
     113                 :          0 :                 sa_spi = rte_cpu_to_be_32((uint32_t)strtoul(params, NULL, 0));
     114                 :            :         /* valid SPI needed */
     115         [ #  # ]:          0 :         if (sa_spi == 0)
     116                 :          0 :                 return -EINVAL;
     117                 :            : 
     118                 :            : 
     119                 :          0 :         rte_tel_data_start_dict(data);
     120                 :            : 
     121         [ #  # ]:          0 :         LIST_FOREACH(entry, &ipsec_telemetry_list, next) {
     122                 :            :                 uint64_t mode;
     123                 :          0 :                 sa = entry->sa;
     124         [ #  # ]:          0 :                 if (sa_spi != sa->spi)
     125                 :          0 :                         continue;
     126                 :            : 
     127                 :            :                 /* add SA configuration key/values pairs */
     128                 :          0 :                 rte_tel_data_add_dict_string(data, "Type",
     129         [ #  # ]:          0 :                         (sa->type & RTE_IPSEC_SATP_PROTO_MASK) ==
     130                 :            :                         RTE_IPSEC_SATP_PROTO_AH ? "AH" : "ESP");
     131                 :            : 
     132                 :          0 :                 rte_tel_data_add_dict_string(data, "Direction",
     133         [ #  # ]:          0 :                         (sa->type & RTE_IPSEC_SATP_DIR_MASK) ==
     134                 :            :                         RTE_IPSEC_SATP_DIR_IB ? "Inbound" : "Outbound");
     135                 :            : 
     136                 :          0 :                 mode = sa->type & RTE_IPSEC_SATP_MODE_MASK;
     137                 :            : 
     138         [ #  # ]:          0 :                 if (mode == RTE_IPSEC_SATP_MODE_TRANS) {
     139                 :          0 :                         rte_tel_data_add_dict_string(data, "Mode", "Transport");
     140                 :            :                 } else {
     141                 :          0 :                         rte_tel_data_add_dict_string(data, "Mode", "Tunnel");
     142                 :            : 
     143         [ #  # ]:          0 :                         if ((sa->type & RTE_IPSEC_SATP_NATT_MASK) ==
     144                 :            :                                 RTE_IPSEC_SATP_NATT_ENABLE) {
     145         [ #  # ]:          0 :                                 if (sa->type & RTE_IPSEC_SATP_MODE_TUNLV4) {
     146                 :          0 :                                         rte_tel_data_add_dict_string(data,
     147                 :            :                                                 "Tunnel-Type",
     148                 :            :                                                 "IPv4-UDP");
     149         [ #  # ]:          0 :                                 } else if (sa->type &
     150                 :            :                                                 RTE_IPSEC_SATP_MODE_TUNLV6) {
     151                 :          0 :                                         rte_tel_data_add_dict_string(data,
     152                 :            :                                                 "Tunnel-Type",
     153                 :            :                                                 "IPv6-UDP");
     154                 :            :                                 }
     155                 :            :                         } else {
     156         [ #  # ]:          0 :                                 if (sa->type & RTE_IPSEC_SATP_MODE_TUNLV4) {
     157                 :          0 :                                         rte_tel_data_add_dict_string(data,
     158                 :            :                                                 "Tunnel-Type",
     159                 :            :                                                 "IPv4");
     160         [ #  # ]:          0 :                                 } else if (sa->type &
     161                 :            :                                                 RTE_IPSEC_SATP_MODE_TUNLV6) {
     162                 :          0 :                                         rte_tel_data_add_dict_string(data,
     163                 :            :                                                 "Tunnel-Type",
     164                 :            :                                                 "IPv6");
     165                 :            :                                 }
     166                 :            :                         }
     167                 :            :                 }
     168                 :            : 
     169                 :          0 :                 rte_tel_data_add_dict_string(data,
     170                 :            :                                 "extended-sequence-number",
     171         [ #  # ]:          0 :                                 (sa->type & RTE_IPSEC_SATP_ESN_MASK) ==
     172                 :            :                                  RTE_IPSEC_SATP_ESN_ENABLE ?
     173                 :            :                                 "enabled" : "disabled");
     174                 :            : 
     175         [ #  # ]:          0 :                 if ((sa->type & RTE_IPSEC_SATP_DIR_MASK) ==
     176                 :            :                         RTE_IPSEC_SATP_DIR_IB)
     177                 :            : 
     178         [ #  # ]:          0 :                         if (sa->sqn.inb.rsn[sa->sqn.inb.rdidx])
     179                 :          0 :                                 rte_tel_data_add_dict_uint(data,
     180                 :            :                                                            "sequence-number",
     181                 :            :                                                            sa->sqn.inb.rsn[sa->sqn.inb.rdidx]->sqn);
     182                 :            :                         else
     183                 :          0 :                                 rte_tel_data_add_dict_uint(data,
     184                 :            :                                                            "sequence-number",
     185                 :            :                                                            0);
     186                 :            :                 else
     187                 :          0 :                         rte_tel_data_add_dict_uint(data, "sequence-number",
     188                 :          0 :                                                    sa->sqn.outb);
     189                 :            : 
     190                 :          0 :                 rte_tel_data_add_dict_string(data,
     191                 :            :                                 "explicit-congestion-notification",
     192         [ #  # ]:          0 :                                 (sa->type & RTE_IPSEC_SATP_ECN_MASK) ==
     193                 :            :                                 RTE_IPSEC_SATP_ECN_ENABLE ?
     194                 :            :                                 "enabled" : "disabled");
     195                 :            : 
     196                 :          0 :                 rte_tel_data_add_dict_string(data,
     197                 :            :                                 "copy-DSCP",
     198         [ #  # ]:          0 :                                 (sa->type & RTE_IPSEC_SATP_DSCP_MASK) ==
     199                 :            :                                 RTE_IPSEC_SATP_DSCP_ENABLE ?
     200                 :            :                                 "enabled" : "disabled");
     201                 :            :         }
     202                 :            : 
     203                 :            :         return 0;
     204                 :            : }
     205                 :            : 
     206                 :            : 
     207                 :            : int
     208                 :          0 : rte_ipsec_telemetry_sa_add(const struct rte_ipsec_sa *sa)
     209                 :            : {
     210                 :          0 :         struct ipsec_telemetry_entry *entry = rte_zmalloc(NULL,
     211                 :            :                         sizeof(struct ipsec_telemetry_entry), 0);
     212         [ #  # ]:          0 :         if (entry == NULL)
     213                 :            :                 return -ENOMEM;
     214                 :          0 :         entry->sa = sa;
     215         [ #  # ]:          0 :         LIST_INSERT_HEAD(&ipsec_telemetry_list, entry, next);
     216                 :          0 :         return 0;
     217                 :            : }
     218                 :            : 
     219                 :            : void
     220                 :          0 : rte_ipsec_telemetry_sa_del(const struct rte_ipsec_sa *sa)
     221                 :            : {
     222                 :            :         struct ipsec_telemetry_entry *entry;
     223         [ #  # ]:          0 :         LIST_FOREACH(entry, &ipsec_telemetry_list, next) {
     224         [ #  # ]:          0 :                 if (sa == entry->sa) {
     225         [ #  # ]:          0 :                         LIST_REMOVE(entry, next);
     226                 :          0 :                         rte_free(entry);
     227                 :          0 :                         return;
     228                 :            :                 }
     229                 :            :         }
     230                 :            : }
     231                 :            : 
     232                 :            : 
     233                 :        252 : RTE_INIT(rte_ipsec_telemetry_init)
     234                 :            : {
     235                 :        252 :         rte_telemetry_register_cmd("/ipsec/sa/list",
     236                 :            :                 handle_telemetry_cmd_ipsec_sa_list,
     237                 :            :                 "Return list of IPsec SAs with telemetry enabled.");
     238                 :        252 :         rte_telemetry_register_cmd("/ipsec/sa/stats",
     239                 :            :                 handle_telemetry_cmd_ipsec_sa_stats,
     240                 :            :                 "Returns IPsec SA statistics. Parameters: int sa_spi");
     241                 :        252 :         rte_telemetry_register_cmd("/ipsec/sa/details",
     242                 :            :                 handle_telemetry_cmd_ipsec_sa_details,
     243                 :            :                 "Returns IPsec SA configuration. Parameters: int sa_spi");
     244                 :        252 : }

Generated by: LCOV version 1.14