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
copy_outb_sa_9k(struct rte_tel_data * d,uint32_t i,void * sa)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
copy_inb_sa_9k(struct rte_tel_data * d,uint32_t i,void * sa)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
copy_outb_sa_10k(struct rte_tel_data * d,uint32_t i,void * sa)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
copy_inb_sa_10k(struct rte_tel_data * d,uint32_t i,void * sa)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
ethdev_sec_tel_handle_info(const char * cmd __rte_unused,const char * params,struct rte_tel_data * d)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
RTE_INIT(cnxk_ipsec_init_telemetry)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