1 // SPDX-License-Identifier: LGPL-2.1-or-later
3 * This file is part of the PCEPlib, a PCEP protocol library.
5 * Copyright (C) 2020 Volta Networks https://voltanet.io/
7 * Author : Brady Johnson <brady@voltanet.io>
13 * PCEP session logic counters configuration.
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"
28 void increment_message_counters(pcep_session
*session
,
29 struct pcep_message
*message
, bool is_rx
);
31 void create_session_counters(pcep_session
*session
)
34 * Message RX and TX counters
36 struct counters_subgroup
*rx_msg_subgroup
= create_counters_subgroup(
37 "RX Message counters", COUNTER_SUBGROUP_ID_RX_MSG
,
39 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_OPEN
,
41 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_KEEPALIVE
,
43 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_PCREQ
,
45 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_PCREP
,
47 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_PCNOTF
,
49 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_ERROR
,
51 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_CLOSE
,
53 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_REPORT
,
55 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_UPDATE
,
57 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_INITIATE
,
59 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_START_TLS
,
61 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_MAX
,
64 struct counters_subgroup
*tx_msg_subgroup
=
65 clone_counters_subgroup(rx_msg_subgroup
, "TX Message counters",
66 COUNTER_SUBGROUP_ID_TX_MSG
);
69 * Object RX and TX counters
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
,
78 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_RP
,
80 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_NOPATH
,
82 create_subgroup_counter(
84 ((PCEP_OBJ_CLASS_ENDPOINTS
<< 4) | PCEP_OBJ_TYPE_ENDPOINT_IPV4
),
85 "Object Endpoint IPv4");
86 create_subgroup_counter(
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
,
92 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_METRIC
,
94 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_ERO
,
96 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_RRO
,
98 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_LSPA
,
100 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_IRO
,
102 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_SVEC
,
104 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_NOTF
,
106 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_ERROR
,
108 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_CLOSE
,
110 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_LSP
,
112 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_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
,
128 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_MAX
+ 1,
131 struct counters_subgroup
*tx_obj_subgroup
=
132 clone_counters_subgroup(rx_obj_subgroup
, "TX Object counters",
133 COUNTER_SUBGROUP_ID_TX_OBJ
);
136 * Sub-Object RX and TX counters
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
,
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");
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
);
163 * RO SR Sub-Object RX and TX counters
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");
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
);
200 * TLV RX and TX counters
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
,
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
,
258 struct counters_subgroup
*tx_tlv_subgroup
= clone_counters_subgroup(
259 rx_tlv_subgroup
, "TX TLV counters", COUNTER_SUBGROUP_ID_TX_TLV
);
262 * PCEP Event counters
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
,
269 create_subgroup_counter(events_subgroup
,
270 PCEP_EVENT_COUNTER_ID_PCE_CONNECT
,
272 create_subgroup_counter(events_subgroup
,
273 PCEP_EVENT_COUNTER_ID_PCC_DISCONNECT
,
275 create_subgroup_counter(events_subgroup
,
276 PCEP_EVENT_COUNTER_ID_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");
292 * Create the parent counters group
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
) {
299 &session
->socket_comm_session
->dest_sock_addr
300 .dest_sock_addr_ipv6
.sin6_addr
,
304 &session
->socket_comm_session
->dest_sock_addr
305 .dest_sock_addr_ipv4
.sin_addr
,
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
);
318 * Add all the subgroups to the parent counters group
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
,
326 add_counters_subgroup(session
->pcep_session_counters
,
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
);
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
)
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
);
355 increment_counter(session
->pcep_session_counters
,
356 counter_subgroup_id_msg
, message
->msg_header
->type
);
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
;
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
);
373 increment_counter(session
->pcep_session_counters
,
374 counter_subgroup_id_obj
, obj_counter_id
);
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
;
383 double_linked_list_node
*ro_subobj_node
=
384 (ro_obj
->sub_objects
== 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
;
393 session
->pcep_session_counters
,
394 counter_subgroup_id_subobj
,
395 ro_subobj
->ro_subobj_type
);
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
*)
405 session
->pcep_session_counters
,
406 counter_subgroup_id_ro_sr_subobj
,
407 ro_sr_subobj
->nai_type
);
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
);
424 void increment_message_rx_counters(pcep_session
*session
,
425 struct pcep_message
*message
)
427 increment_message_counters(session
, message
, true);
430 void increment_message_tx_counters(pcep_session
*session
,
431 struct pcep_message
*message
)
433 increment_message_counters(session
, message
, false);
436 void increment_event_counters(
437 pcep_session
*session
,
438 pcep_session_counters_event_counter_ids counter_id
)
440 increment_counter(session
->pcep_session_counters
,
441 COUNTER_SUBGROUP_ID_EVENT
, counter_id
);