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.
33 #include "pcep_msg_tlvs.h"
34 #include "pcep_msg_encoding.h"
35 #include "pcep_utils_memory.h"
37 static struct pcep_object_tlv_header
*
38 pcep_tlv_common_create(enum pcep_object_tlv_types type
, uint16_t size
)
40 struct pcep_object_tlv_header
*tlv
=
41 pceplib_malloc(PCEPLIB_MESSAGES
, size
);
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
)
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
,
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
;
75 struct pcep_object_tlv_lsp_db_version
*
76 pcep_tlv_create_lsp_db_version(uint64_t lsp_db_version
)
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
;
87 struct pcep_object_tlv_speaker_entity_identifier
*
88 pcep_tlv_create_speaker_entity_id(double_linked_list
*speaker_entity_id_list
)
90 if (speaker_entity_id_list
== NULL
) {
94 if (speaker_entity_id_list
->num_entries
== 0) {
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
,
103 pcep_object_tlv_speaker_entity_identifier
));
104 tlv
->speaker_entity_id_list
= speaker_entity_id_list
;
109 struct pcep_object_tlv_path_setup_type
*
110 pcep_tlv_create_path_setup_type(uint8_t pst
)
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
;
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
)
126 if (pst_list
== NULL
) {
130 if (pst_list
->num_entries
== 0) {
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
,
139 pcep_object_tlv_path_setup_type_capability
));
141 tlv
->pst_list
= pst_list
;
142 tlv
->sub_tlv_list
= sub_tlv_list
;
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
)
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
,
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
;
164 struct pcep_object_tlv_of_list
*
165 pcep_tlv_create_of_list(double_linked_list
*of_list
)
167 if (of_list
== NULL
) {
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
));
176 tlv
->of_list
= of_list
;
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
)
191 if (ipv4_tunnel_sender
== NULL
|| ipv4_tunnel_endpoint
== NULL
) {
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
,
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
);
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
)
218 if (ipv6_tunnel_sender
== NULL
|| ipv6_tunnel_endpoint
== NULL
) {
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
,
227 pcep_object_tlv_ipv6_lsp_identifier
));
229 memcpy(&tlv
->ipv6_tunnel_sender
, ipv6_tunnel_sender
,
230 sizeof(struct in6_addr
));
232 tlv
->tunnel_id
= tunnel_id
;
233 tlv
->lsp_id
= lsp_id
;
235 memcpy(&tlv
->extended_tunnel_id
, extended_tunnel_id
,
236 sizeof(struct in6_addr
));
238 memcpy(&tlv
->ipv6_tunnel_endpoint
, ipv6_tunnel_endpoint
,
239 sizeof(struct in6_addr
));
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
)
248 /* symbolic_path_name_length should NOT include the null terminator and
250 if (symbolic_path_name
== NULL
|| symbolic_path_name_length
== 0) {
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
,
259 pcep_object_tlv_symbolic_path_name
));
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
;
270 struct pcep_object_tlv_lsp_error_code
*
271 pcep_tlv_create_lsp_error_code(enum pcep_tlv_lsp_error_codes lsp_error_code
)
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
;
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
)
286 if (error_node_ip
== NULL
) {
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
));
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
;
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
)
310 if (error_node_ip
== NULL
) {
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
));
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
));
329 struct pcep_object_tlv_nopath_vector
*
330 pcep_tlv_create_nopath_vector(uint32_t error_code
)
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
));
337 tlv
->error_code
= error_code
;
342 struct pcep_object_tlv_vendor_info
*
343 pcep_tlv_create_vendor_info(uint32_t enterprise_number
,
344 uint32_t enterprise_specific_info
)
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
));
351 tlv
->enterprise_number
= enterprise_number
;
352 tlv
->enterprise_specific_info
= enterprise_specific_info
;
358 * SRPAG (SR Association Group) TLVs
361 struct pcep_object_tlv_srpag_pol_id
*
362 pcep_tlv_create_srpag_pol_id_ipv4(uint32_t color
, struct in_addr
*ipv4
)
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
));
370 memcpy(&tlv
->end_point
.ipv4
.s_addr
, ipv4
, sizeof(struct in_addr
));
375 struct pcep_object_tlv_srpag_pol_id
*
376 pcep_tlv_create_srpag_pol_id_ipv6(uint32_t color
, struct in6_addr
*ipv6
)
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
));
383 tlv
->is_ipv4
= false;
384 memcpy(&tlv
->end_point
.ipv6
, ipv6
, sizeof(struct in6_addr
));
390 struct pcep_object_tlv_srpag_pol_name
*
391 pcep_tlv_create_srpag_pol_name(const char *pol_name
, uint16_t pol_name_length
)
393 if (pol_name
== NULL
) {
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
));
401 (normalize_pcep_tlv_length(pol_name_length
) > MAX_POLICY_NAME
)
404 memcpy(tlv
->name
, pol_name
, length
);
405 tlv
->name_length
= length
;
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
)
414 if (!in6_addr_with_mapped_ipv4
) {
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
;
424 memcpy(&(tlv
->orig_addres
), in6_addr_with_mapped_ipv4
,
425 sizeof(*in6_addr_with_mapped_ipv4
));
426 tlv
->discriminator
= discriminator
;
430 struct pcep_object_tlv_srpag_cp_pref
*
431 pcep_tlv_create_srpag_cp_pref(uint32_t pref
)
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
;
443 struct pcep_object_tlv_arbitrary
*
444 pcep_tlv_create_tlv_arbitrary(const char *data
, uint16_t data_length
,
447 if (data
== NULL
|| data_length
== 0) {
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
));
456 uint16_t length
= (data_length
> MAX_ARBITRARY_SIZE
)
459 memcpy(tlv
->data
, data
, length
);
460 tlv
->data_length
= length
;
461 tlv
->arbitraty_type
= tlv_id
;