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