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