]> git.proxmox.com Git - mirror_frr.git/blob - pceplib/pcep_msg_tlvs.c
pceplib: Fixing coverity messages.
[mirror_frr.git] / pceplib / pcep_msg_tlvs.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 * This is the implementation of a High Level PCEP message object TLV API.
26 */
27
28 #include <stdbool.h>
29 #include <stdint.h>
30 #include <string.h>
31 #include <unistd.h>
32
33 #include "pcep_msg_tlvs.h"
34 #include "pcep_msg_encoding.h"
35 #include "pcep_utils_memory.h"
36
37 static struct pcep_object_tlv_header *
38 pcep_tlv_common_create(enum pcep_object_tlv_types type, uint16_t size)
39 {
40 struct pcep_object_tlv_header *tlv =
41 pceplib_malloc(PCEPLIB_MESSAGES, size);
42 memset(tlv, 0, size);
43 tlv->type = type;
44
45 return tlv;
46 }
47
48 /*
49 * Open Object TLVs
50 */
51
52 struct pcep_object_tlv_stateful_pce_capability *
53 pcep_tlv_create_stateful_pce_capability(
54 bool flag_u_lsp_update_capability, bool flag_s_include_db_version,
55 bool flag_i_lsp_instantiation_capability, bool flag_t_triggered_resync,
56 bool flag_d_delta_lsp_sync, bool flag_f_triggered_initial_sync)
57 {
58 struct pcep_object_tlv_stateful_pce_capability *tlv =
59 (struct pcep_object_tlv_stateful_pce_capability *)
60 pcep_tlv_common_create(
61 PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY,
62 sizeof(struct
63 pcep_object_tlv_stateful_pce_capability));
64 tlv->flag_u_lsp_update_capability = flag_u_lsp_update_capability;
65 tlv->flag_s_include_db_version = flag_s_include_db_version;
66 tlv->flag_i_lsp_instantiation_capability =
67 flag_i_lsp_instantiation_capability;
68 tlv->flag_t_triggered_resync = flag_t_triggered_resync;
69 tlv->flag_d_delta_lsp_sync = flag_d_delta_lsp_sync;
70 tlv->flag_f_triggered_initial_sync = flag_f_triggered_initial_sync;
71
72 return tlv;
73 }
74
75 struct pcep_object_tlv_lsp_db_version *
76 pcep_tlv_create_lsp_db_version(uint64_t lsp_db_version)
77 {
78 struct pcep_object_tlv_lsp_db_version *tlv =
79 (struct pcep_object_tlv_lsp_db_version *)pcep_tlv_common_create(
80 PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION,
81 sizeof(struct pcep_object_tlv_lsp_db_version));
82 tlv->lsp_db_version = lsp_db_version;
83
84 return tlv;
85 }
86
87 struct pcep_object_tlv_speaker_entity_identifier *
88 pcep_tlv_create_speaker_entity_id(double_linked_list *speaker_entity_id_list)
89 {
90 if (speaker_entity_id_list == NULL) {
91 return NULL;
92 }
93
94 if (speaker_entity_id_list->num_entries == 0) {
95 return NULL;
96 }
97
98 struct pcep_object_tlv_speaker_entity_identifier *tlv =
99 (struct pcep_object_tlv_speaker_entity_identifier *)
100 pcep_tlv_common_create(
101 PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID,
102 sizeof(struct
103 pcep_object_tlv_speaker_entity_identifier));
104 tlv->speaker_entity_id_list = speaker_entity_id_list;
105
106 return tlv;
107 }
108
109 struct pcep_object_tlv_path_setup_type *
110 pcep_tlv_create_path_setup_type(uint8_t pst)
111 {
112 struct pcep_object_tlv_path_setup_type *tlv =
113 (struct pcep_object_tlv_path_setup_type *)
114 pcep_tlv_common_create(
115 PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE,
116 sizeof(struct pcep_object_tlv_path_setup_type));
117 tlv->path_setup_type = pst;
118
119 return tlv;
120 }
121
122 struct pcep_object_tlv_path_setup_type_capability *
123 pcep_tlv_create_path_setup_type_capability(double_linked_list *pst_list,
124 double_linked_list *sub_tlv_list)
125 {
126 if (pst_list == NULL) {
127 return NULL;
128 }
129
130 if (pst_list->num_entries == 0) {
131 return NULL;
132 }
133
134 struct pcep_object_tlv_path_setup_type_capability *tlv =
135 (struct pcep_object_tlv_path_setup_type_capability *)
136 pcep_tlv_common_create(
137 PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY,
138 sizeof(struct
139 pcep_object_tlv_path_setup_type_capability));
140
141 tlv->pst_list = pst_list;
142 tlv->sub_tlv_list = sub_tlv_list;
143
144 return tlv;
145 }
146
147 struct pcep_object_tlv_sr_pce_capability *
148 pcep_tlv_create_sr_pce_capability(bool flag_n, bool flag_x,
149 uint8_t max_sid_depth)
150 {
151 struct pcep_object_tlv_sr_pce_capability *tlv =
152 (struct pcep_object_tlv_sr_pce_capability *)
153 pcep_tlv_common_create(
154 PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY,
155 sizeof(struct
156 pcep_object_tlv_sr_pce_capability));
157 tlv->flag_n = flag_n;
158 tlv->flag_x = flag_x;
159 tlv->max_sid_depth = max_sid_depth;
160
161 return tlv;
162 }
163
164 struct pcep_object_tlv_of_list *
165 pcep_tlv_create_of_list(double_linked_list *of_list)
166 {
167 if (of_list == NULL) {
168 return NULL;
169 }
170
171 struct pcep_object_tlv_of_list *tlv =
172 (struct pcep_object_tlv_of_list *)pcep_tlv_common_create(
173 PCEP_OBJ_TLV_TYPE_OBJECTIVE_FUNCTION_LIST,
174 sizeof(struct pcep_object_tlv_of_list));
175
176 tlv->of_list = of_list;
177
178 return tlv;
179 }
180
181 /*
182 * LSP Object TLVs
183 */
184
185 struct pcep_object_tlv_ipv4_lsp_identifier *
186 pcep_tlv_create_ipv4_lsp_identifiers(struct in_addr *ipv4_tunnel_sender,
187 struct in_addr *ipv4_tunnel_endpoint,
188 uint16_t lsp_id, uint16_t tunnel_id,
189 struct in_addr *extended_tunnel_id)
190 {
191 if (ipv4_tunnel_sender == NULL || ipv4_tunnel_endpoint == NULL) {
192 return NULL;
193 }
194
195 struct pcep_object_tlv_ipv4_lsp_identifier *tlv =
196 (struct pcep_object_tlv_ipv4_lsp_identifier *)
197 pcep_tlv_common_create(
198 PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS,
199 sizeof(struct
200 pcep_object_tlv_ipv4_lsp_identifier));
201 tlv->ipv4_tunnel_sender.s_addr = ipv4_tunnel_sender->s_addr;
202 tlv->ipv4_tunnel_endpoint.s_addr = ipv4_tunnel_endpoint->s_addr;
203 tlv->lsp_id = lsp_id;
204 tlv->tunnel_id = tunnel_id;
205 tlv->extended_tunnel_id.s_addr =
206 (extended_tunnel_id == NULL ? INADDR_ANY
207 : extended_tunnel_id->s_addr);
208
209 return tlv;
210 }
211
212 struct pcep_object_tlv_ipv6_lsp_identifier *
213 pcep_tlv_create_ipv6_lsp_identifiers(struct in6_addr *ipv6_tunnel_sender,
214 struct in6_addr *ipv6_tunnel_endpoint,
215 uint16_t lsp_id, uint16_t tunnel_id,
216 struct in6_addr *extended_tunnel_id)
217 {
218 if (ipv6_tunnel_sender == NULL || ipv6_tunnel_endpoint == NULL) {
219 return NULL;
220 }
221
222 struct pcep_object_tlv_ipv6_lsp_identifier *tlv =
223 (struct pcep_object_tlv_ipv6_lsp_identifier *)
224 pcep_tlv_common_create(
225 PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS,
226 sizeof(struct
227 pcep_object_tlv_ipv6_lsp_identifier));
228
229 memcpy(&tlv->ipv6_tunnel_sender, ipv6_tunnel_sender,
230 sizeof(struct in6_addr));
231
232 tlv->tunnel_id = tunnel_id;
233 tlv->lsp_id = lsp_id;
234
235 memcpy(&tlv->extended_tunnel_id, extended_tunnel_id,
236 sizeof(struct in6_addr));
237
238 memcpy(&tlv->ipv6_tunnel_endpoint, ipv6_tunnel_endpoint,
239 sizeof(struct in6_addr));
240
241 return tlv;
242 }
243
244 struct pcep_object_tlv_symbolic_path_name *
245 pcep_tlv_create_symbolic_path_name(const char *symbolic_path_name,
246 uint16_t symbolic_path_name_length)
247 {
248 /* symbolic_path_name_length should NOT include the null terminator and
249 * cannot be zero */
250 if (symbolic_path_name == NULL || symbolic_path_name_length == 0) {
251 return NULL;
252 }
253
254 struct pcep_object_tlv_symbolic_path_name *tlv =
255 (struct pcep_object_tlv_symbolic_path_name *)
256 pcep_tlv_common_create(
257 PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME,
258 sizeof(struct
259 pcep_object_tlv_symbolic_path_name));
260
261 uint16_t length = (symbolic_path_name_length > MAX_SYMBOLIC_PATH_NAME)
262 ? MAX_SYMBOLIC_PATH_NAME
263 : symbolic_path_name_length;
264 memcpy(tlv->symbolic_path_name, symbolic_path_name, length);
265 tlv->symbolic_path_name_length = length;
266
267 return tlv;
268 }
269
270 struct pcep_object_tlv_lsp_error_code *
271 pcep_tlv_create_lsp_error_code(enum pcep_tlv_lsp_error_codes lsp_error_code)
272 {
273 struct pcep_object_tlv_lsp_error_code *tlv =
274 (struct pcep_object_tlv_lsp_error_code *)pcep_tlv_common_create(
275 PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE,
276 sizeof(struct pcep_object_tlv_lsp_error_code));
277 tlv->lsp_error_code = lsp_error_code;
278
279 return tlv;
280 }
281
282 struct pcep_object_tlv_rsvp_error_spec *
283 pcep_tlv_create_rsvp_ipv4_error_spec(struct in_addr *error_node_ip,
284 uint8_t error_code, uint16_t error_value)
285 {
286 if (error_node_ip == NULL) {
287 return NULL;
288 }
289
290 struct pcep_object_tlv_rsvp_error_spec *tlv =
291 (struct pcep_object_tlv_rsvp_error_spec *)
292 pcep_tlv_common_create(
293 PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC,
294 sizeof(struct pcep_object_tlv_rsvp_error_spec));
295
296 tlv->c_type = RSVP_ERROR_SPEC_IPV4_CTYPE;
297 tlv->class_num = RSVP_ERROR_SPEC_CLASS_NUM;
298 tlv->error_code = error_code;
299 tlv->error_value = error_value;
300 tlv->error_spec_ip.ipv4_error_node_address.s_addr =
301 error_node_ip->s_addr;
302
303 return tlv;
304 }
305
306 struct pcep_object_tlv_rsvp_error_spec *
307 pcep_tlv_create_rsvp_ipv6_error_spec(struct in6_addr *error_node_ip,
308 uint8_t error_code, uint16_t error_value)
309 {
310 if (error_node_ip == NULL) {
311 return NULL;
312 }
313
314 struct pcep_object_tlv_rsvp_error_spec *tlv =
315 (struct pcep_object_tlv_rsvp_error_spec *)
316 pcep_tlv_common_create(
317 PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC,
318 sizeof(struct pcep_object_tlv_rsvp_error_spec));
319
320 tlv->c_type = RSVP_ERROR_SPEC_IPV6_CTYPE;
321 tlv->class_num = RSVP_ERROR_SPEC_CLASS_NUM;
322 tlv->error_code = error_code;
323 tlv->error_value = error_value;
324 memcpy(&tlv->error_spec_ip, error_node_ip, sizeof(struct in6_addr));
325
326 return tlv;
327 }
328
329 struct pcep_object_tlv_nopath_vector *
330 pcep_tlv_create_nopath_vector(uint32_t error_code)
331 {
332 struct pcep_object_tlv_nopath_vector *tlv =
333 (struct pcep_object_tlv_nopath_vector *)pcep_tlv_common_create(
334 PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR,
335 sizeof(struct pcep_object_tlv_nopath_vector));
336
337 tlv->error_code = error_code;
338
339 return tlv;
340 }
341
342 struct pcep_object_tlv_vendor_info *
343 pcep_tlv_create_vendor_info(uint32_t enterprise_number,
344 uint32_t enterprise_specific_info)
345 {
346 struct pcep_object_tlv_vendor_info *tlv =
347 (struct pcep_object_tlv_vendor_info *)pcep_tlv_common_create(
348 PCEP_OBJ_TLV_TYPE_VENDOR_INFO,
349 sizeof(struct pcep_object_tlv_vendor_info));
350
351 tlv->enterprise_number = enterprise_number;
352 tlv->enterprise_specific_info = enterprise_specific_info;
353
354 return tlv;
355 }
356
357 /*
358 * SRPAG (SR Association Group) TLVs
359 */
360
361 struct pcep_object_tlv_srpag_pol_id *
362 pcep_tlv_create_srpag_pol_id_ipv4(uint32_t color, struct in_addr *ipv4)
363 {
364 struct pcep_object_tlv_srpag_pol_id *tlv =
365 (struct pcep_object_tlv_srpag_pol_id *)pcep_tlv_common_create(
366 PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID,
367 sizeof(struct pcep_object_tlv_srpag_pol_id));
368 tlv->color = color;
369 tlv->is_ipv4 = true;
370 memcpy(&tlv->end_point.ipv4.s_addr, ipv4, sizeof(struct in_addr));
371
372 return tlv;
373 }
374
375 struct pcep_object_tlv_srpag_pol_id *
376 pcep_tlv_create_srpag_pol_id_ipv6(uint32_t color, struct in6_addr *ipv6)
377 {
378 struct pcep_object_tlv_srpag_pol_id *tlv =
379 (struct pcep_object_tlv_srpag_pol_id *)pcep_tlv_common_create(
380 PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID,
381 sizeof(struct pcep_object_tlv_srpag_pol_id));
382 tlv->color = color;
383 tlv->is_ipv4 = false;
384 memcpy(&tlv->end_point.ipv6, ipv6, sizeof(struct in6_addr));
385
386 return tlv;
387 }
388
389
390 struct pcep_object_tlv_srpag_pol_name *
391 pcep_tlv_create_srpag_pol_name(const char *pol_name, uint16_t pol_name_length)
392 {
393 if (pol_name == NULL) {
394 return NULL;
395 }
396 struct pcep_object_tlv_srpag_pol_name *tlv =
397 (struct pcep_object_tlv_srpag_pol_name *)pcep_tlv_common_create(
398 PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME,
399 sizeof(struct pcep_object_tlv_srpag_pol_name));
400 uint16_t length =
401 (normalize_pcep_tlv_length(pol_name_length) > MAX_POLICY_NAME)
402 ? MAX_POLICY_NAME
403 : pol_name_length;
404 memcpy(tlv->name, pol_name, length);
405 tlv->name_length = length;
406
407 return tlv;
408 }
409 struct pcep_object_tlv_srpag_cp_id *
410 pcep_tlv_create_srpag_cp_id(uint8_t proto_origin, uint32_t asn,
411 struct in6_addr *in6_addr_with_mapped_ipv4,
412 uint32_t discriminator)
413 {
414 if (!in6_addr_with_mapped_ipv4) {
415 return NULL;
416 }
417
418 struct pcep_object_tlv_srpag_cp_id *tlv =
419 (struct pcep_object_tlv_srpag_cp_id *)pcep_tlv_common_create(
420 PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID,
421 sizeof(struct pcep_object_tlv_srpag_cp_id));
422 tlv->proto = proto_origin;
423 tlv->orig_asn = asn;
424 memcpy(&(tlv->orig_addres), in6_addr_with_mapped_ipv4,
425 sizeof(*in6_addr_with_mapped_ipv4));
426 tlv->discriminator = discriminator;
427
428 return tlv;
429 }
430 struct pcep_object_tlv_srpag_cp_pref *
431 pcep_tlv_create_srpag_cp_pref(uint32_t pref)
432 {
433
434 struct pcep_object_tlv_srpag_cp_pref *tlv =
435 (struct pcep_object_tlv_srpag_cp_pref *)pcep_tlv_common_create(
436 PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE,
437 sizeof(struct pcep_object_tlv_srpag_cp_pref));
438 tlv->preference = pref;
439
440 return tlv;
441 }
442
443 struct pcep_object_tlv_arbitrary *
444 pcep_tlv_create_tlv_arbitrary(const char *data, uint16_t data_length,
445 int tlv_id)
446 {
447 if (data == NULL || data_length == 0) {
448 return NULL;
449 }
450
451 struct pcep_object_tlv_arbitrary *tlv =
452 (struct pcep_object_tlv_arbitrary *)pcep_tlv_common_create(
453 PCEP_OBJ_TLV_TYPE_ARBITRARY,
454 sizeof(struct pcep_object_tlv_arbitrary));
455
456 uint16_t length = (data_length > MAX_ARBITRARY_SIZE)
457 ? MAX_ARBITRARY_SIZE
458 : data_length;
459 memcpy(tlv->data, data, length);
460 tlv->data_length = length;
461 tlv->arbitraty_type = tlv_id;
462
463 return tlv;
464 }