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