1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2021 Intel Corporation
6 #include <rte_telemetry.h>
7 #include <rte_malloc.h>
11 struct ipsec_telemetry_entry {
12 LIST_ENTRY(ipsec_telemetry_entry) next;
13 const struct rte_ipsec_sa *sa;
15 static LIST_HEAD(ipsec_telemetry_head, ipsec_telemetry_entry)
16 ipsec_telemetry_list = LIST_HEAD_INITIALIZER();
19 handle_telemetry_cmd_ipsec_sa_list(const char *cmd __rte_unused,
20 const char *params __rte_unused,
21 struct rte_tel_data *data)
23 struct ipsec_telemetry_entry *entry;
24 rte_tel_data_start_array(data, RTE_TEL_U64_VAL);
26 LIST_FOREACH(entry, &ipsec_telemetry_list, next) {
27 const struct rte_ipsec_sa *sa = entry->sa;
28 rte_tel_data_add_array_u64(data, rte_be_to_cpu_32(sa->spi));
35 * Handle IPsec SA statistics telemetry request
37 * Return dict of SA's with dict of key/value counters
40 * "SA_SPI_XX": {"count": 0, "bytes": 0, "errors": 0},
41 * "SA_SPI_YY": {"count": 0, "bytes": 0, "errors": 0}
46 handle_telemetry_cmd_ipsec_sa_stats(const char *cmd __rte_unused,
48 struct rte_tel_data *data)
50 struct ipsec_telemetry_entry *entry;
51 const struct rte_ipsec_sa *sa;
55 sa_spi = rte_cpu_to_be_32((uint32_t)strtoul(params, NULL, 0));
60 rte_tel_data_start_dict(data);
62 LIST_FOREACH(entry, &ipsec_telemetry_list, next) {
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;
70 /* If user provided SPI only get telemetry for that SA */
71 if (sa_spi && (sa_spi != sa->spi))
74 /* allocate telemetry data struct for SA telemetry */
75 sa_data = rte_tel_data_alloc();
79 rte_tel_data_start_dict(sa_data);
81 /* add telemetry key/values pairs */
82 rte_tel_data_add_dict_u64(sa_data, name_pkt_cnt,
83 sa->statistics.count);
85 rte_tel_data_add_dict_u64(sa_data, name_byte_cnt,
86 sa->statistics.bytes -
87 (sa->statistics.count * sa->hdr_len));
89 rte_tel_data_add_dict_u64(sa_data, name_error_cnt,
90 sa->statistics.errors.count);
92 /* generate telemetry label */
93 snprintf(sa_name, sizeof(sa_name), "SA_SPI_%i",
94 rte_be_to_cpu_32(sa->spi));
96 /* add SA telemetry to dictionary container */
97 rte_tel_data_add_dict_container(data, sa_name, sa_data, 0);
104 handle_telemetry_cmd_ipsec_sa_details(const char *cmd __rte_unused,
106 struct rte_tel_data *data)
108 struct ipsec_telemetry_entry *entry;
109 const struct rte_ipsec_sa *sa;
113 sa_spi = rte_cpu_to_be_32((uint32_t)strtoul(params, NULL, 0));
114 /* valid SPI needed */
119 rte_tel_data_start_dict(data);
121 LIST_FOREACH(entry, &ipsec_telemetry_list, next) {
124 if (sa_spi != sa->spi)
127 /* add SA configuration key/values pairs */
128 rte_tel_data_add_dict_string(data, "Type",
129 (sa->type & RTE_IPSEC_SATP_PROTO_MASK) ==
130 RTE_IPSEC_SATP_PROTO_AH ? "AH" : "ESP");
132 rte_tel_data_add_dict_string(data, "Direction",
133 (sa->type & RTE_IPSEC_SATP_DIR_MASK) ==
134 RTE_IPSEC_SATP_DIR_IB ? "Inbound" : "Outbound");
136 mode = sa->type & RTE_IPSEC_SATP_MODE_MASK;
138 if (mode == RTE_IPSEC_SATP_MODE_TRANS) {
139 rte_tel_data_add_dict_string(data, "Mode", "Transport");
141 rte_tel_data_add_dict_string(data, "Mode", "Tunnel");
143 if ((sa->type & RTE_IPSEC_SATP_NATT_MASK) ==
144 RTE_IPSEC_SATP_NATT_ENABLE) {
145 if (sa->type & RTE_IPSEC_SATP_MODE_TUNLV4) {
146 rte_tel_data_add_dict_string(data,
149 } else if (sa->type &
150 RTE_IPSEC_SATP_MODE_TUNLV6) {
151 rte_tel_data_add_dict_string(data,
156 if (sa->type & RTE_IPSEC_SATP_MODE_TUNLV4) {
157 rte_tel_data_add_dict_string(data,
160 } else if (sa->type &
161 RTE_IPSEC_SATP_MODE_TUNLV6) {
162 rte_tel_data_add_dict_string(data,
169 rte_tel_data_add_dict_string(data,
170 "extended-sequence-number",
171 (sa->type & RTE_IPSEC_SATP_ESN_MASK) ==
172 RTE_IPSEC_SATP_ESN_ENABLE ?
173 "enabled" : "disabled");
175 if ((sa->type & RTE_IPSEC_SATP_DIR_MASK) ==
176 RTE_IPSEC_SATP_DIR_IB)
178 if (sa->sqn.inb.rsn[sa->sqn.inb.rdidx])
179 rte_tel_data_add_dict_u64(data,
181 sa->sqn.inb.rsn[sa->sqn.inb.rdidx]->sqn);
183 rte_tel_data_add_dict_u64(data,
184 "sequence-number", 0);
186 rte_tel_data_add_dict_u64(data, "sequence-number",
189 rte_tel_data_add_dict_string(data,
190 "explicit-congestion-notification",
191 (sa->type & RTE_IPSEC_SATP_ECN_MASK) ==
192 RTE_IPSEC_SATP_ECN_ENABLE ?
193 "enabled" : "disabled");
195 rte_tel_data_add_dict_string(data,
197 (sa->type & RTE_IPSEC_SATP_DSCP_MASK) ==
198 RTE_IPSEC_SATP_DSCP_ENABLE ?
199 "enabled" : "disabled");
207 rte_ipsec_telemetry_sa_add(const struct rte_ipsec_sa *sa)
209 struct ipsec_telemetry_entry *entry = rte_zmalloc(NULL,
210 sizeof(struct ipsec_telemetry_entry), 0);
214 LIST_INSERT_HEAD(&ipsec_telemetry_list, entry, next);
219 rte_ipsec_telemetry_sa_del(const struct rte_ipsec_sa *sa)
221 struct ipsec_telemetry_entry *entry;
222 LIST_FOREACH(entry, &ipsec_telemetry_list, next) {
223 if (sa == entry->sa) {
224 LIST_REMOVE(entry, next);
232 RTE_INIT(rte_ipsec_telemetry_init)
234 rte_telemetry_register_cmd("/ipsec/sa/list",
235 handle_telemetry_cmd_ipsec_sa_list,
236 "Return list of IPsec SAs with telemetry enabled.");
237 rte_telemetry_register_cmd("/ipsec/sa/stats",
238 handle_telemetry_cmd_ipsec_sa_stats,
239 "Returns IPsec SA stastistics. Parameters: int sa_spi");
240 rte_telemetry_register_cmd("/ipsec/sa/details",
241 handle_telemetry_cmd_ipsec_sa_details,
242 "Returns IPsec SA configuration. Parameters: int sa_spi");