1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2022 Marvell. 3 */ 4 5 #include <rte_telemetry.h> 6 7 #include <roc_api.h> 8 9 #include "cnxk_ethdev.h" 10 11 #define STR_MAXLEN 20 12 #define W0_MAXLEN 21 13 14 static int 15 copy_outb_sa_9k(struct rte_tel_data *d, uint32_t i, void *sa) 16 { 17 struct roc_onf_ipsec_outb_sa *out_sa; 18 union { 19 struct roc_ie_onf_sa_ctl ctl; 20 uint64_t u64; 21 } w0; 22 char strw0[W0_MAXLEN]; 23 char str[STR_MAXLEN]; 24 25 out_sa = (struct roc_onf_ipsec_outb_sa *)sa; 26 w0.ctl = out_sa->ctl; 27 28 snprintf(str, sizeof(str), "outsa_w0_%u", i); 29 snprintf(strw0, sizeof(strw0), "%" PRIu64, w0.u64); 30 rte_tel_data_add_dict_string(d, str, strw0); 31 32 snprintf(str, sizeof(str), "outsa_src_%u", i); 33 rte_tel_data_add_dict_u64(d, str, out_sa->udp_src); 34 35 snprintf(str, sizeof(str), "outsa_dst_%u", i); 36 rte_tel_data_add_dict_u64(d, str, out_sa->udp_dst); 37 38 snprintf(str, sizeof(str), "outsa_isrc_%u", i); 39 rte_tel_data_add_dict_u64(d, str, out_sa->ip_src); 40 41 snprintf(str, sizeof(str), "outsa_idst_%u", i); 42 rte_tel_data_add_dict_u64(d, str, out_sa->ip_dst); 43 44 return 0; 45 } 46 47 static int 48 copy_inb_sa_9k(struct rte_tel_data *d, uint32_t i, void *sa) 49 { 50 struct roc_onf_ipsec_inb_sa *in_sa; 51 union { 52 struct roc_ie_onf_sa_ctl ctl; 53 uint64_t u64; 54 } w0; 55 char strw0[W0_MAXLEN]; 56 char str[STR_MAXLEN]; 57 58 in_sa = (struct roc_onf_ipsec_inb_sa *)sa; 59 w0.ctl = in_sa->ctl; 60 61 snprintf(str, sizeof(str), "insa_w0_%u", i); 62 snprintf(strw0, sizeof(strw0), "%" PRIu64, w0.u64); 63 rte_tel_data_add_dict_string(d, str, strw0); 64 65 snprintf(str, sizeof(str), "insa_esnh_%u", i); 66 rte_tel_data_add_dict_u64(d, str, in_sa->esn_hi); 67 68 snprintf(str, sizeof(str), "insa_esnl_%u", i); 69 rte_tel_data_add_dict_u64(d, str, in_sa->esn_low); 70 71 return 0; 72 } 73 74 static int 75 copy_outb_sa_10k(struct rte_tel_data *d, uint32_t i, void *sa) 76 { 77 struct roc_ot_ipsec_outb_sa *out_sa; 78 struct rte_tel_data *outer_hdr; 79 char str[STR_MAXLEN]; 80 char s64[W0_MAXLEN]; 81 uint32_t j; 82 83 out_sa = (struct roc_ot_ipsec_outb_sa *)sa; 84 85 snprintf(str, sizeof(str), "outsa_w0_%u", i); 86 snprintf(s64, sizeof(s64), "%" PRIu64, out_sa->w0.u64); 87 rte_tel_data_add_dict_string(d, str, s64); 88 89 snprintf(str, sizeof(str), "outsa_w1_%u", i); 90 snprintf(s64, sizeof(s64), "%" PRIu64, out_sa->w1.u64); 91 rte_tel_data_add_dict_string(d, str, s64); 92 93 snprintf(str, sizeof(str), "outsa_w2_%u", i); 94 snprintf(s64, sizeof(s64), "%" PRIu64, out_sa->w2.u64); 95 rte_tel_data_add_dict_string(d, str, s64); 96 97 snprintf(str, sizeof(str), "outsa_w10_%u", i); 98 snprintf(s64, sizeof(s64), "%" PRIu64, out_sa->w10.u64); 99 rte_tel_data_add_dict_string(d, str, s64); 100 101 outer_hdr = rte_tel_data_alloc(); 102 if (!outer_hdr) { 103 plt_err("Could not allocate space for outer header"); 104 return -ENOMEM; 105 } 106 107 rte_tel_data_start_array(outer_hdr, RTE_TEL_U64_VAL); 108 109 for (j = 0; j < RTE_DIM(out_sa->outer_hdr.ipv6.src_addr); j++) 110 rte_tel_data_add_array_u64(outer_hdr, 111 out_sa->outer_hdr.ipv6.src_addr[j]); 112 113 for (j = 0; j < RTE_DIM(out_sa->outer_hdr.ipv6.dst_addr); j++) 114 rte_tel_data_add_array_u64(outer_hdr, 115 out_sa->outer_hdr.ipv6.dst_addr[j]); 116 117 snprintf(str, sizeof(str), "outsa_outer_hdr_%u", i); 118 rte_tel_data_add_dict_container(d, str, outer_hdr, 0); 119 120 snprintf(str, sizeof(str), "outsa_errctl_%u", i); 121 snprintf(s64, sizeof(s64), "%" PRIu64, out_sa->ctx.err_ctl.u64); 122 rte_tel_data_add_dict_string(d, str, s64); 123 124 snprintf(str, sizeof(str), "outsa_esnval_%u", i); 125 snprintf(s64, sizeof(s64), "%" PRIu64, out_sa->ctx.esn_val); 126 rte_tel_data_add_dict_string(d, str, s64); 127 128 snprintf(str, sizeof(str), "outsa_hl_%u", i); 129 snprintf(s64, sizeof(s64), "%" PRIu64, out_sa->ctx.hard_life); 130 rte_tel_data_add_dict_string(d, str, s64); 131 132 snprintf(str, sizeof(str), "outsa_sl_%u", i); 133 snprintf(s64, sizeof(s64), "%" PRIu64, out_sa->ctx.soft_life); 134 rte_tel_data_add_dict_string(d, str, s64); 135 136 snprintf(str, sizeof(str), "outsa_octs_%u", i); 137 snprintf(s64, sizeof(s64), "%" PRIu64, out_sa->ctx.mib_octs); 138 rte_tel_data_add_dict_string(d, str, s64); 139 140 snprintf(str, sizeof(str), "outsa_pkts_%u", i); 141 snprintf(s64, sizeof(s64), "%" PRIu64, out_sa->ctx.mib_pkts); 142 rte_tel_data_add_dict_string(d, str, s64); 143 144 return 0; 145 } 146 147 static int 148 copy_inb_sa_10k(struct rte_tel_data *d, uint32_t i, void *sa) 149 { 150 struct roc_ot_ipsec_inb_sa *in_sa; 151 struct rte_tel_data *outer_hdr; 152 char str[STR_MAXLEN]; 153 char s64[W0_MAXLEN]; 154 uint32_t j; 155 156 in_sa = (struct roc_ot_ipsec_inb_sa *)sa; 157 158 snprintf(str, sizeof(str), "insa_w0_%u", i); 159 snprintf(s64, sizeof(s64), "%" PRIu64, in_sa->w0.u64); 160 rte_tel_data_add_dict_string(d, str, s64); 161 162 snprintf(str, sizeof(str), "insa_w1_%u", i); 163 snprintf(s64, sizeof(s64), "%" PRIu64, in_sa->w1.u64); 164 rte_tel_data_add_dict_string(d, str, s64); 165 166 snprintf(str, sizeof(str), "insa_w2_%u", i); 167 snprintf(s64, sizeof(s64), "%" PRIu64, in_sa->w2.u64); 168 rte_tel_data_add_dict_string(d, str, s64); 169 170 snprintf(str, sizeof(str), "insa_w10_%u", i); 171 snprintf(s64, sizeof(s64), "%" PRIu64, in_sa->w10.u64); 172 rte_tel_data_add_dict_string(d, str, s64); 173 174 outer_hdr = rte_tel_data_alloc(); 175 if (!outer_hdr) { 176 plt_err("Could not allocate space for outer header"); 177 return -ENOMEM; 178 } 179 180 rte_tel_data_start_array(outer_hdr, RTE_TEL_U64_VAL); 181 182 for (j = 0; j < RTE_DIM(in_sa->outer_hdr.ipv6.src_addr); j++) 183 rte_tel_data_add_array_u64(outer_hdr, 184 in_sa->outer_hdr.ipv6.src_addr[j]); 185 186 for (j = 0; j < RTE_DIM(in_sa->outer_hdr.ipv6.dst_addr); j++) 187 rte_tel_data_add_array_u64(outer_hdr, 188 in_sa->outer_hdr.ipv6.dst_addr[j]); 189 190 snprintf(str, sizeof(str), "insa_outer_hdr_%u", i); 191 rte_tel_data_add_dict_container(d, str, outer_hdr, 0); 192 193 snprintf(str, sizeof(str), "insa_arbase_%u", i); 194 snprintf(s64, sizeof(s64), "%" PRIu64, in_sa->ctx.ar_base); 195 rte_tel_data_add_dict_string(d, str, s64); 196 197 snprintf(str, sizeof(str), "insa_ar_validm_%u", i); 198 snprintf(s64, sizeof(s64), "%" PRIu64, in_sa->ctx.ar_valid_mask); 199 rte_tel_data_add_dict_string(d, str, s64); 200 201 snprintf(str, sizeof(str), "insa_hl_%u", i); 202 snprintf(s64, sizeof(s64), "%" PRIu64, in_sa->ctx.hard_life); 203 rte_tel_data_add_dict_string(d, str, s64); 204 205 snprintf(str, sizeof(str), "insa_sl_%u", i); 206 snprintf(s64, sizeof(s64), "%" PRIu64, in_sa->ctx.soft_life); 207 rte_tel_data_add_dict_string(d, str, s64); 208 209 snprintf(str, sizeof(str), "insa_octs_%u", i); 210 snprintf(s64, sizeof(s64), "%" PRIu64, in_sa->ctx.mib_octs); 211 rte_tel_data_add_dict_string(d, str, s64); 212 213 snprintf(str, sizeof(str), "insa_pkts_%u", i); 214 snprintf(s64, sizeof(s64), "%" PRIu64, in_sa->ctx.mib_pkts); 215 rte_tel_data_add_dict_string(d, str, s64); 216 217 return 0; 218 } 219 220 static int 221 ethdev_sec_tel_handle_info(const char *cmd __rte_unused, const char *params, 222 struct rte_tel_data *d) 223 { 224 struct cnxk_eth_sec_sess *eth_sec, *tvar; 225 struct rte_eth_dev *eth_dev; 226 struct cnxk_eth_dev *dev; 227 uint16_t port_id; 228 char *end_p; 229 uint32_t i; 230 int ret; 231 232 port_id = strtoul(params, &end_p, 0); 233 if (errno != 0) 234 return -EINVAL; 235 236 if (*end_p != '\0') 237 plt_err("Extra parameters passed to telemetry, ignoring it"); 238 239 if (!rte_eth_dev_is_valid_port(port_id)) { 240 plt_err("Invalid port id %u", port_id); 241 return -EINVAL; 242 } 243 244 eth_dev = &rte_eth_devices[port_id]; 245 if (!eth_dev) { 246 plt_err("Ethdev not available"); 247 return -EINVAL; 248 } 249 250 dev = cnxk_eth_pmd_priv(eth_dev); 251 252 rte_tel_data_start_dict(d); 253 254 rte_tel_data_add_dict_int(d, "nb_outb_sa", dev->outb.nb_sess); 255 256 i = 0; 257 if (dev->tx_offloads & RTE_ETH_TX_OFFLOAD_SECURITY) { 258 tvar = NULL; 259 RTE_TAILQ_FOREACH_SAFE(eth_sec, &dev->outb.list, entry, tvar) { 260 if (roc_model_is_cn10k()) 261 ret = copy_outb_sa_10k(d, i++, eth_sec->sa); 262 else 263 ret = copy_outb_sa_9k(d, i++, eth_sec->sa); 264 if (ret < 0) 265 return ret; 266 } 267 } 268 269 rte_tel_data_add_dict_int(d, "nb_inb_sa", dev->inb.nb_sess); 270 271 i = 0; 272 if (dev->rx_offloads & RTE_ETH_RX_OFFLOAD_SECURITY) { 273 tvar = NULL; 274 RTE_TAILQ_FOREACH_SAFE(eth_sec, &dev->inb.list, entry, tvar) { 275 if (roc_model_is_cn10k()) 276 ret = copy_inb_sa_10k(d, i++, eth_sec->sa); 277 else 278 ret = copy_inb_sa_9k(d, i++, eth_sec->sa); 279 if (ret < 0) 280 return ret; 281 } 282 } 283 284 return 0; 285 } 286 287 RTE_INIT(cnxk_ipsec_init_telemetry) 288 { 289 rte_telemetry_register_cmd("/cnxk/ipsec/info", 290 ethdev_sec_tel_handle_info, 291 "Returns ipsec info. Parameters: port id"); 292 } 293