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