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 * This is the implementation of a High Level PCEP message object TLV API.
37 #include "pcep_msg_tlvs.h"
38 #include "pcep_msg_encoding.h"
39 #include "pcep_utils_memory.h"
41 static struct pcep_object_tlv_header
*
42 pcep_tlv_common_create(enum pcep_object_tlv_types type
, uint16_t size
)
44 struct pcep_object_tlv_header
*tlv
=
45 pceplib_malloc(PCEPLIB_MESSAGES
, size
);
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
)
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
,
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
;
79 struct pcep_object_tlv_lsp_db_version
*
80 pcep_tlv_create_lsp_db_version(uint64_t lsp_db_version
)
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
;
91 struct pcep_object_tlv_speaker_entity_identifier
*
92 pcep_tlv_create_speaker_entity_id(double_linked_list
*speaker_entity_id_list
)
94 if (speaker_entity_id_list
== NULL
) {
98 if (speaker_entity_id_list
->num_entries
== 0) {
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
,
107 pcep_object_tlv_speaker_entity_identifier
));
108 tlv
->speaker_entity_id_list
= speaker_entity_id_list
;
113 struct pcep_object_tlv_path_setup_type
*
114 pcep_tlv_create_path_setup_type(uint8_t pst
)
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
;
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
)
130 if (pst_list
== NULL
) {
134 if (pst_list
->num_entries
== 0) {
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
,
143 pcep_object_tlv_path_setup_type_capability
));
145 tlv
->pst_list
= pst_list
;
146 tlv
->sub_tlv_list
= sub_tlv_list
;
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
)
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
,
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
;
168 struct pcep_object_tlv_of_list
*
169 pcep_tlv_create_of_list(double_linked_list
*of_list
)
171 if (of_list
== NULL
) {
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
));
180 tlv
->of_list
= of_list
;
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
)
195 if (ipv4_tunnel_sender
== NULL
|| ipv4_tunnel_endpoint
== NULL
) {
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
,
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
);
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
)
222 if (ipv6_tunnel_sender
== NULL
|| ipv6_tunnel_endpoint
== NULL
) {
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
,
231 pcep_object_tlv_ipv6_lsp_identifier
));
233 memcpy(&tlv
->ipv6_tunnel_sender
, ipv6_tunnel_sender
,
234 sizeof(struct in6_addr
));
236 tlv
->tunnel_id
= tunnel_id
;
237 tlv
->lsp_id
= lsp_id
;
239 memcpy(&tlv
->extended_tunnel_id
, extended_tunnel_id
,
240 sizeof(struct in6_addr
));
242 memcpy(&tlv
->ipv6_tunnel_endpoint
, ipv6_tunnel_endpoint
,
243 sizeof(struct in6_addr
));
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
)
252 /* symbolic_path_name_length should NOT include the null terminator and
254 if (symbolic_path_name
== NULL
|| symbolic_path_name_length
== 0) {
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
,
263 pcep_object_tlv_symbolic_path_name
));
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
;
274 struct pcep_object_tlv_lsp_error_code
*
275 pcep_tlv_create_lsp_error_code(enum pcep_tlv_lsp_error_codes lsp_error_code
)
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
;
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
)
290 if (error_node_ip
== NULL
) {
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
));
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
;
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
)
314 if (error_node_ip
== NULL
) {
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
));
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
));
333 struct pcep_object_tlv_nopath_vector
*
334 pcep_tlv_create_nopath_vector(uint32_t error_code
)
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
));
341 tlv
->error_code
= error_code
;
346 struct pcep_object_tlv_vendor_info
*
347 pcep_tlv_create_vendor_info(uint32_t enterprise_number
,
348 uint32_t enterprise_specific_info
)
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
));
355 tlv
->enterprise_number
= enterprise_number
;
356 tlv
->enterprise_specific_info
= enterprise_specific_info
;
362 * SRPAG (SR Association Group) TLVs
365 struct pcep_object_tlv_srpag_pol_id
*
366 pcep_tlv_create_srpag_pol_id_ipv4(uint32_t color
, struct in_addr
*ipv4
)
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
));
374 memcpy(&tlv
->end_point
.ipv4
.s_addr
, ipv4
, sizeof(struct in_addr
));
379 struct pcep_object_tlv_srpag_pol_id
*
380 pcep_tlv_create_srpag_pol_id_ipv6(uint32_t color
, struct in6_addr
*ipv6
)
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
));
387 tlv
->is_ipv4
= false;
388 memcpy(&tlv
->end_point
.ipv6
, ipv6
, sizeof(struct in6_addr
));
394 struct pcep_object_tlv_srpag_pol_name
*
395 pcep_tlv_create_srpag_pol_name(const char *pol_name
, uint16_t pol_name_length
)
397 if (pol_name
== NULL
) {
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
));
405 (normalize_pcep_tlv_length(pol_name_length
) > MAX_POLICY_NAME
)
408 memcpy(tlv
->name
, pol_name
, length
);
409 tlv
->name_length
= length
;
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
)
418 if (!in6_addr_with_mapped_ipv4
) {
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
;
428 memcpy(&(tlv
->orig_addres
), in6_addr_with_mapped_ipv4
,
429 sizeof(*in6_addr_with_mapped_ipv4
));
430 tlv
->discriminator
= discriminator
;
434 struct pcep_object_tlv_srpag_cp_pref
*
435 pcep_tlv_create_srpag_cp_pref(uint32_t pref
)
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
;
447 struct pcep_object_tlv_arbitrary
*
448 pcep_tlv_create_tlv_arbitrary(const char *data
, uint16_t data_length
,
451 if (data
== NULL
|| data_length
== 0) {
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
));
460 uint16_t length
= (data_length
> MAX_ARBITRARY_SIZE
)
463 memcpy(tlv
->data
, data
, length
);
464 tlv
->data_length
= length
;
465 tlv
->arbitraty_type
= tlv_id
;