]> git.proxmox.com Git - mirror_frr.git/blob - pceplib/pcep_session_logic_counters.c
Merge pull request #12751 from Pdoijode/pdoijode/ospf-vrf-neighbor-detail-1
[mirror_frr.git] / pceplib / pcep_session_logic_counters.c
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 /*
3 * This file is part of the PCEPlib, a PCEP protocol library.
4 *
5 * Copyright (C) 2020 Volta Networks https://voltanet.io/
6 *
7 * Author : Brady Johnson <brady@voltanet.io>
8 *
9 */
10
11
12 /*
13 * PCEP session logic counters configuration.
14 */
15
16 #ifdef HAVE_CONFIG_H
17 #include "config.h"
18 #endif
19
20 #include <stdio.h>
21 #include <time.h>
22
23 #include "pcep_session_logic.h"
24 #include "pcep_session_logic_internals.h"
25 #include "pcep_utils_counters.h"
26 #include "pcep_utils_logging.h"
27
28 void increment_message_counters(pcep_session *session,
29 struct pcep_message *message, bool is_rx);
30
31 void create_session_counters(pcep_session *session)
32 {
33 /*
34 * Message RX and TX counters
35 */
36 struct counters_subgroup *rx_msg_subgroup = create_counters_subgroup(
37 "RX Message counters", COUNTER_SUBGROUP_ID_RX_MSG,
38 PCEP_TYPE_MAX + 1);
39 create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_OPEN,
40 "Message Open");
41 create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_KEEPALIVE,
42 "Message KeepAlive");
43 create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_PCREQ,
44 "Message PcReq");
45 create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_PCREP,
46 "Message PcRep");
47 create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_PCNOTF,
48 "Message Notify");
49 create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_ERROR,
50 "Message Error");
51 create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_CLOSE,
52 "Message Close");
53 create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_REPORT,
54 "Message Report");
55 create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_UPDATE,
56 "Message Update");
57 create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_INITIATE,
58 "Message Initiate");
59 create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_START_TLS,
60 "Message StartTls");
61 create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_MAX,
62 "Message Erroneous");
63
64 struct counters_subgroup *tx_msg_subgroup =
65 clone_counters_subgroup(rx_msg_subgroup, "TX Message counters",
66 COUNTER_SUBGROUP_ID_TX_MSG);
67
68 /*
69 * Object RX and TX counters
70 */
71
72 /* For the Endpoints, the ID will be either 64 or 65, so setting
73 * num_counters to 100 */
74 struct counters_subgroup *rx_obj_subgroup = create_counters_subgroup(
75 "RX Object counters", COUNTER_SUBGROUP_ID_RX_OBJ, 100);
76 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_OPEN,
77 "Object Open");
78 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_RP,
79 "Object RP");
80 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_NOPATH,
81 "Object Nopath");
82 create_subgroup_counter(
83 rx_obj_subgroup,
84 ((PCEP_OBJ_CLASS_ENDPOINTS << 4) | PCEP_OBJ_TYPE_ENDPOINT_IPV4),
85 "Object Endpoint IPv4");
86 create_subgroup_counter(
87 rx_obj_subgroup,
88 ((PCEP_OBJ_CLASS_ENDPOINTS << 4) | PCEP_OBJ_TYPE_ENDPOINT_IPV6),
89 "Object Endpoint IPv6");
90 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_BANDWIDTH,
91 "Object Bandwidth");
92 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_METRIC,
93 "Object Metric");
94 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_ERO,
95 "Object ERO");
96 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_RRO,
97 "Object RRO");
98 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_LSPA,
99 "Object LSPA");
100 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_IRO,
101 "Object IRO");
102 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_SVEC,
103 "Object SVEC");
104 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_NOTF,
105 "Object Notify");
106 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_ERROR,
107 "Object Error");
108 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_CLOSE,
109 "Object Close");
110 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_LSP,
111 "Object LSP");
112 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_SRP,
113 "Object SRP");
114 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_VENDOR_INFO,
115 "Object Vendor Info");
116 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_INTER_LAYER,
117 "Object Inter-Layer");
118 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_SWITCH_LAYER,
119 "Object Switch-Layer");
120 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_REQ_ADAP_CAP,
121 "Object Requested Adap-Cap");
122 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_SERVER_IND,
123 "Object Server-Indication");
124 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_ASSOCIATION,
125 "Object Association");
126 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_MAX,
127 "Object Unknown");
128 create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_MAX + 1,
129 "Object Erroneous");
130
131 struct counters_subgroup *tx_obj_subgroup =
132 clone_counters_subgroup(rx_obj_subgroup, "TX Object counters",
133 COUNTER_SUBGROUP_ID_TX_OBJ);
134
135 /*
136 * Sub-Object RX and TX counters
137 */
138 struct counters_subgroup *rx_subobj_subgroup = create_counters_subgroup(
139 "RX RO Sub-Object counters", COUNTER_SUBGROUP_ID_RX_SUBOBJ,
140 RO_SUBOBJ_UNKNOWN + 2);
141 create_subgroup_counter(rx_subobj_subgroup, RO_SUBOBJ_TYPE_IPV4,
142 "RO Sub-Object IPv4");
143 create_subgroup_counter(rx_subobj_subgroup, RO_SUBOBJ_TYPE_IPV6,
144 "RO Sub-Object IPv6");
145 create_subgroup_counter(rx_subobj_subgroup, RO_SUBOBJ_TYPE_LABEL,
146 "RO Sub-Object Label");
147 create_subgroup_counter(rx_subobj_subgroup, RO_SUBOBJ_TYPE_UNNUM,
148 "RO Sub-Object Unnum");
149 create_subgroup_counter(rx_subobj_subgroup, RO_SUBOBJ_TYPE_ASN,
150 "RO Sub-Object ASN");
151 create_subgroup_counter(rx_subobj_subgroup, RO_SUBOBJ_TYPE_SR,
152 "RO Sub-Object SR");
153 create_subgroup_counter(rx_subobj_subgroup, RO_SUBOBJ_UNKNOWN,
154 "RO Sub-Object Unknown");
155 create_subgroup_counter(rx_subobj_subgroup, RO_SUBOBJ_UNKNOWN + 1,
156 "RO Sub-Object Erroneous");
157
158 struct counters_subgroup *tx_subobj_subgroup = clone_counters_subgroup(
159 rx_subobj_subgroup, "TX RO Sub-Object counters",
160 COUNTER_SUBGROUP_ID_TX_SUBOBJ);
161
162 /*
163 * RO SR Sub-Object RX and TX counters
164 */
165 struct counters_subgroup *rx_subobj_sr_nai_subgroup =
166 create_counters_subgroup("RX RO SR NAI Sub-Object counters",
167 COUNTER_SUBGROUP_ID_RX_RO_SR_SUBOBJ,
168 PCEP_SR_SUBOBJ_NAI_UNKNOWN + 1);
169 create_subgroup_counter(rx_subobj_sr_nai_subgroup,
170 PCEP_SR_SUBOBJ_NAI_ABSENT,
171 "RO Sub-Object SR NAI absent");
172 create_subgroup_counter(rx_subobj_sr_nai_subgroup,
173 PCEP_SR_SUBOBJ_NAI_IPV4_NODE,
174 "RO Sub-Object SR NAI IPv4 Node");
175 create_subgroup_counter(rx_subobj_sr_nai_subgroup,
176 PCEP_SR_SUBOBJ_NAI_IPV6_NODE,
177 "RO Sub-Object SR NAI IPv6 Node");
178 create_subgroup_counter(rx_subobj_sr_nai_subgroup,
179 PCEP_SR_SUBOBJ_NAI_IPV4_ADJACENCY,
180 "RO Sub-Object SR NAI IPv4 Adj");
181 create_subgroup_counter(rx_subobj_sr_nai_subgroup,
182 PCEP_SR_SUBOBJ_NAI_IPV6_ADJACENCY,
183 "RO Sub-Object SR NAI IPv6 Adj");
184 create_subgroup_counter(rx_subobj_sr_nai_subgroup,
185 PCEP_SR_SUBOBJ_NAI_UNNUMBERED_IPV4_ADJACENCY,
186 "RO Sub-Object SR NAI Unnumbered IPv4 Adj");
187 create_subgroup_counter(rx_subobj_sr_nai_subgroup,
188 PCEP_SR_SUBOBJ_NAI_LINK_LOCAL_IPV6_ADJACENCY,
189 "RO Sub-Object SR NAI Link Local IPv6 Adj");
190 create_subgroup_counter(rx_subobj_sr_nai_subgroup,
191 PCEP_SR_SUBOBJ_NAI_UNKNOWN,
192 "RO Sub-Object SR NAI Unknown");
193
194 struct counters_subgroup *tx_subobj_sr_nai_subgroup =
195 clone_counters_subgroup(rx_subobj_sr_nai_subgroup,
196 "TX RO SR NAI Sub-Object counters",
197 COUNTER_SUBGROUP_ID_TX_RO_SR_SUBOBJ);
198
199 /*
200 * TLV RX and TX counters
201 */
202 struct counters_subgroup *rx_tlv_subgroup = create_counters_subgroup(
203 "RX TLV counters", COUNTER_SUBGROUP_ID_RX_TLV,
204 PCEP_OBJ_TLV_TYPE_UNKNOWN + 1);
205 create_subgroup_counter(rx_tlv_subgroup,
206 PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR,
207 "TLV No Path Vector");
208 create_subgroup_counter(rx_tlv_subgroup, PCEP_OBJ_TLV_TYPE_VENDOR_INFO,
209 "TLV Vendor Info");
210 create_subgroup_counter(rx_tlv_subgroup,
211 PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY,
212 "TLV Stateful PCE Capability");
213 create_subgroup_counter(rx_tlv_subgroup,
214 PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME,
215 "TLV Symbolic Path Name");
216 create_subgroup_counter(rx_tlv_subgroup,
217 PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS,
218 "TLV IPv4 LSP Identifier");
219 create_subgroup_counter(rx_tlv_subgroup,
220 PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS,
221 "TLV IPv6 LSP Identifier");
222 create_subgroup_counter(rx_tlv_subgroup,
223 PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE,
224 "TLV LSP Error Code");
225 create_subgroup_counter(rx_tlv_subgroup,
226 PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC,
227 "TLV RSVP Error Spec");
228 create_subgroup_counter(rx_tlv_subgroup,
229 PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION,
230 "TLV LSP DB Version");
231 create_subgroup_counter(rx_tlv_subgroup,
232 PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID,
233 "TLV Speaker Entity ID");
234 create_subgroup_counter(rx_tlv_subgroup,
235 PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY,
236 "TLV SR PCE Capability");
237 create_subgroup_counter(rx_tlv_subgroup,
238 PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE,
239 "TLV Path Setup Type");
240 create_subgroup_counter(rx_tlv_subgroup,
241 PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY,
242 "TLV Path Setup Type Capability");
243 create_subgroup_counter(rx_tlv_subgroup,
244 PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID,
245 "TLV SR Policy PolId");
246 create_subgroup_counter(rx_tlv_subgroup,
247 PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME,
248 "TLV SR Policy PolName");
249 create_subgroup_counter(rx_tlv_subgroup,
250 PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID,
251 "TLV SR Policy CpathId");
252 create_subgroup_counter(rx_tlv_subgroup,
253 PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE,
254 "TLV SR Policy CpathRef");
255 create_subgroup_counter(rx_tlv_subgroup, PCEP_OBJ_TLV_TYPE_UNKNOWN,
256 "TLV Unknown");
257
258 struct counters_subgroup *tx_tlv_subgroup = clone_counters_subgroup(
259 rx_tlv_subgroup, "TX TLV counters", COUNTER_SUBGROUP_ID_TX_TLV);
260
261 /*
262 * PCEP Event counters
263 */
264 struct counters_subgroup *events_subgroup = create_counters_subgroup(
265 "Events counters", COUNTER_SUBGROUP_ID_EVENT, MAX_COUNTERS);
266 create_subgroup_counter(events_subgroup,
267 PCEP_EVENT_COUNTER_ID_PCC_CONNECT,
268 "PCC connect");
269 create_subgroup_counter(events_subgroup,
270 PCEP_EVENT_COUNTER_ID_PCE_CONNECT,
271 "PCE connect");
272 create_subgroup_counter(events_subgroup,
273 PCEP_EVENT_COUNTER_ID_PCC_DISCONNECT,
274 "PCC disconnect");
275 create_subgroup_counter(events_subgroup,
276 PCEP_EVENT_COUNTER_ID_PCE_DISCONNECT,
277 "PCE disconnect");
278 create_subgroup_counter(events_subgroup,
279 PCEP_EVENT_COUNTER_ID_TIMER_KEEPALIVE,
280 "Timer KeepAlive expired");
281 create_subgroup_counter(events_subgroup,
282 PCEP_EVENT_COUNTER_ID_TIMER_DEADTIMER,
283 "Timer DeadTimer expired");
284 create_subgroup_counter(events_subgroup,
285 PCEP_EVENT_COUNTER_ID_TIMER_OPENKEEPWAIT,
286 "Timer OpenKeepWait expired");
287 create_subgroup_counter(events_subgroup,
288 PCEP_EVENT_COUNTER_ID_TIMER_OPENKEEPALIVE,
289 "Timer OpenKeepAlive expired");
290
291 /*
292 * Create the parent counters group
293 */
294 time_t now = time(NULL);
295 char counters_name[MAX_COUNTER_STR_LENGTH] = {0};
296 char ip_str[40] = {0};
297 if (session->socket_comm_session->is_ipv6) {
298 inet_ntop(AF_INET6,
299 &session->socket_comm_session->dest_sock_addr
300 .dest_sock_addr_ipv6.sin6_addr,
301 ip_str, 40);
302 } else {
303 inet_ntop(AF_INET,
304 &session->socket_comm_session->dest_sock_addr
305 .dest_sock_addr_ipv4.sin_addr,
306 ip_str, 40);
307 }
308 snprintf(counters_name, MAX_COUNTER_STR_LENGTH,
309 "PCEP Session [%d], connected to [%s] for [%u seconds]",
310 session->session_id, ip_str,
311 (uint32_t)(now - session->time_connected));
312 /* The (time(NULL) - session->time_connected) will probably be 0,
313 * so the group name will be updated when the counters are dumped */
314 session->pcep_session_counters =
315 create_counters_group(counters_name, MAX_COUNTER_GROUPS);
316
317 /*
318 * Add all the subgroups to the parent counters group
319 */
320 add_counters_subgroup(session->pcep_session_counters, rx_msg_subgroup);
321 add_counters_subgroup(session->pcep_session_counters, tx_msg_subgroup);
322 add_counters_subgroup(session->pcep_session_counters, rx_obj_subgroup);
323 add_counters_subgroup(session->pcep_session_counters, tx_obj_subgroup);
324 add_counters_subgroup(session->pcep_session_counters,
325 rx_subobj_subgroup);
326 add_counters_subgroup(session->pcep_session_counters,
327 tx_subobj_subgroup);
328 add_counters_subgroup(session->pcep_session_counters,
329 rx_subobj_sr_nai_subgroup);
330 add_counters_subgroup(session->pcep_session_counters,
331 tx_subobj_sr_nai_subgroup);
332 add_counters_subgroup(session->pcep_session_counters, rx_tlv_subgroup);
333 add_counters_subgroup(session->pcep_session_counters, tx_tlv_subgroup);
334 add_counters_subgroup(session->pcep_session_counters, events_subgroup);
335 }
336
337 /* Internal util function used by increment_message_rx_counters or
338 * increment_message_tx_counters */
339 void increment_message_counters(pcep_session *session,
340 struct pcep_message *message, bool is_rx)
341 {
342 uint16_t counter_subgroup_id_msg = (is_rx ? COUNTER_SUBGROUP_ID_RX_MSG
343 : COUNTER_SUBGROUP_ID_TX_MSG);
344 uint16_t counter_subgroup_id_obj = (is_rx ? COUNTER_SUBGROUP_ID_RX_OBJ
345 : COUNTER_SUBGROUP_ID_TX_OBJ);
346 uint16_t counter_subgroup_id_subobj =
347 (is_rx ? COUNTER_SUBGROUP_ID_RX_SUBOBJ
348 : COUNTER_SUBGROUP_ID_TX_SUBOBJ);
349 uint16_t counter_subgroup_id_ro_sr_subobj =
350 (is_rx ? COUNTER_SUBGROUP_ID_RX_RO_SR_SUBOBJ
351 : COUNTER_SUBGROUP_ID_TX_RO_SR_SUBOBJ);
352 uint16_t counter_subgroup_id_tlv = (is_rx ? COUNTER_SUBGROUP_ID_RX_TLV
353 : COUNTER_SUBGROUP_ID_TX_TLV);
354
355 increment_counter(session->pcep_session_counters,
356 counter_subgroup_id_msg, message->msg_header->type);
357
358 /* Iterate the objects */
359 double_linked_list_node *obj_node =
360 (message->obj_list == NULL ? NULL : message->obj_list->head);
361 for (; obj_node != NULL; obj_node = obj_node->next_node) {
362 struct pcep_object_header *obj =
363 (struct pcep_object_header *)obj_node->data;
364
365 /* Handle class: PCEP_OBJ_CLASS_ENDPOINTS,
366 * type: PCEP_OBJ_TYPE_ENDPOINT_IPV4 or
367 * PCEP_OBJ_TYPE_ENDPOINT_IPV6 */
368 uint16_t obj_counter_id =
369 (obj->object_class == PCEP_OBJ_CLASS_ENDPOINTS
370 ? (obj->object_class << 4) | obj->object_type
371 : obj->object_class);
372
373 increment_counter(session->pcep_session_counters,
374 counter_subgroup_id_obj, obj_counter_id);
375
376 /* Iterate the RO Sub-objects */
377 if (obj->object_class == PCEP_OBJ_CLASS_ERO
378 || obj->object_class == PCEP_OBJ_CLASS_IRO
379 || obj->object_class == PCEP_OBJ_CLASS_RRO) {
380 struct pcep_object_ro *ro_obj =
381 (struct pcep_object_ro *)obj;
382
383 double_linked_list_node *ro_subobj_node =
384 (ro_obj->sub_objects == NULL
385 ? NULL
386 : ro_obj->sub_objects->head);
387 for (; ro_subobj_node != NULL;
388 ro_subobj_node = ro_subobj_node->next_node) {
389 struct pcep_object_ro_subobj *ro_subobj =
390 (struct pcep_object_ro_subobj *)
391 ro_subobj_node->data;
392 increment_counter(
393 session->pcep_session_counters,
394 counter_subgroup_id_subobj,
395 ro_subobj->ro_subobj_type);
396
397 /* Handle the ro subobj type RO_SUBOBJ_TYPE_SR
398 * different NAI types */
399 if (ro_subobj->ro_subobj_type
400 == RO_SUBOBJ_TYPE_SR) {
401 struct pcep_ro_subobj_sr *ro_sr_subobj =
402 (struct pcep_ro_subobj_sr *)
403 ro_subobj;
404 increment_counter(
405 session->pcep_session_counters,
406 counter_subgroup_id_ro_sr_subobj,
407 ro_sr_subobj->nai_type);
408 }
409 }
410 }
411
412 /* Iterate the TLVs */
413 double_linked_list_node *tlv_node =
414 (obj->tlv_list == NULL ? NULL : obj->tlv_list->head);
415 for (; tlv_node != NULL; tlv_node = tlv_node->next_node) {
416 struct pcep_object_tlv_header *tlv =
417 (struct pcep_object_tlv_header *)tlv_node->data;
418 increment_counter(session->pcep_session_counters,
419 counter_subgroup_id_tlv, tlv->type);
420 }
421 }
422 }
423
424 void increment_message_rx_counters(pcep_session *session,
425 struct pcep_message *message)
426 {
427 increment_message_counters(session, message, true);
428 }
429
430 void increment_message_tx_counters(pcep_session *session,
431 struct pcep_message *message)
432 {
433 increment_message_counters(session, message, false);
434 }
435
436 void increment_event_counters(
437 pcep_session *session,
438 pcep_session_counters_event_counter_ids counter_id)
439 {
440 increment_counter(session->pcep_session_counters,
441 COUNTER_SUBGROUP_ID_EVENT, counter_id);
442 }