2 * This file is part of the PCEPlib, a PCEP protocol library.
4 * Copyright (C) 2020 Volta Networks https://voltanet.io/
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.
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.
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/>.
19 * Author : Brady Johnson <brady@voltanet.io>
25 * PCEP session logic counters configuration.
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"
40 void increment_message_counters(pcep_session
*session
,
41 struct pcep_message
*message
, bool is_rx
);
43 void create_session_counters(pcep_session
*session
)
46 * Message RX and TX counters
48 struct counters_subgroup
*rx_msg_subgroup
= create_counters_subgroup(
49 "RX Message counters", COUNTER_SUBGROUP_ID_RX_MSG
,
51 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_OPEN
,
53 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_KEEPALIVE
,
55 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_PCREQ
,
57 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_PCREP
,
59 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_PCNOTF
,
61 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_ERROR
,
63 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_CLOSE
,
65 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_REPORT
,
67 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_UPDATE
,
69 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_INITIATE
,
71 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_START_TLS
,
73 create_subgroup_counter(rx_msg_subgroup
, PCEP_TYPE_MAX
,
76 struct counters_subgroup
*tx_msg_subgroup
=
77 clone_counters_subgroup(rx_msg_subgroup
, "TX Message counters",
78 COUNTER_SUBGROUP_ID_TX_MSG
);
81 * Object RX and TX counters
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
,
90 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_RP
,
92 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_NOPATH
,
94 create_subgroup_counter(
96 ((PCEP_OBJ_CLASS_ENDPOINTS
<< 4) | PCEP_OBJ_TYPE_ENDPOINT_IPV4
),
97 "Object Endpoint IPv4");
98 create_subgroup_counter(
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
,
104 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_METRIC
,
106 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_ERO
,
108 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_RRO
,
110 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_LSPA
,
112 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_IRO
,
114 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_SVEC
,
116 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_NOTF
,
118 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_ERROR
,
120 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_CLOSE
,
122 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_LSP
,
124 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_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
,
140 create_subgroup_counter(rx_obj_subgroup
, PCEP_OBJ_CLASS_MAX
+ 1,
143 struct counters_subgroup
*tx_obj_subgroup
=
144 clone_counters_subgroup(rx_obj_subgroup
, "TX Object counters",
145 COUNTER_SUBGROUP_ID_TX_OBJ
);
148 * Sub-Object RX and TX counters
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
,
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");
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
);
175 * RO SR Sub-Object RX and TX counters
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");
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
);
212 * TLV RX and TX counters
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
,
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
,
270 struct counters_subgroup
*tx_tlv_subgroup
= clone_counters_subgroup(
271 rx_tlv_subgroup
, "TX TLV counters", COUNTER_SUBGROUP_ID_TX_TLV
);
274 * PCEP Event counters
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
,
281 create_subgroup_counter(events_subgroup
,
282 PCEP_EVENT_COUNTER_ID_PCE_CONNECT
,
284 create_subgroup_counter(events_subgroup
,
285 PCEP_EVENT_COUNTER_ID_PCC_DISCONNECT
,
287 create_subgroup_counter(events_subgroup
,
288 PCEP_EVENT_COUNTER_ID_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");
304 * Create the parent counters group
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
) {
311 &session
->socket_comm_session
->dest_sock_addr
312 .dest_sock_addr_ipv6
.sin6_addr
,
316 &session
->socket_comm_session
->dest_sock_addr
317 .dest_sock_addr_ipv4
.sin_addr
,
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
);
330 * Add all the subgroups to the parent counters group
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
,
338 add_counters_subgroup(session
->pcep_session_counters
,
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
);
349 /* Internal util function used by increment_message_rx_counters or
350 * increment_message_tx_counters */
351 void increment_message_counters(pcep_session
*session
,
352 struct pcep_message
*message
, bool is_rx
)
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
);
367 increment_counter(session
->pcep_session_counters
,
368 counter_subgroup_id_msg
, message
->msg_header
->type
);
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
;
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
);
385 increment_counter(session
->pcep_session_counters
,
386 counter_subgroup_id_obj
, obj_counter_id
);
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
;
395 double_linked_list_node
*ro_subobj_node
=
396 (ro_obj
->sub_objects
== 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
;
405 session
->pcep_session_counters
,
406 counter_subgroup_id_subobj
,
407 ro_subobj
->ro_subobj_type
);
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
*)
417 session
->pcep_session_counters
,
418 counter_subgroup_id_ro_sr_subobj
,
419 ro_sr_subobj
->nai_type
);
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
);
436 void increment_message_rx_counters(pcep_session
*session
,
437 struct pcep_message
*message
)
439 increment_message_counters(session
, message
, true);
442 void increment_message_tx_counters(pcep_session
*session
,
443 struct pcep_message
*message
)
445 increment_message_counters(session
, message
, false);
448 void increment_event_counters(
449 pcep_session
*session
,
450 pcep_session_counters_event_counter_ids counter_id
)
452 increment_counter(session
->pcep_session_counters
,
453 COUNTER_SUBGROUP_ID_EVENT
, counter_id
);