1 // SPDX-License-Identifier: LGPL-2.1-or-later
3 * This file is part of the PCEPlib, a PCEP protocol library.
5 * Copyright (C) 2020 Volta Networks https://voltanet.io/
7 * Author : Brady Johnson <brady@voltanet.io>
13 * Encoding and decoding for PCEP Object TLVs.
21 #include <sys/endian.h>
24 #endif /* __FreeBSD__ */
29 #include "pcep_msg_encoding.h"
30 #include "pcep_msg_tlvs.h"
31 #include "pcep_utils_logging.h"
32 #include "pcep_utils_memory.h"
34 void write_tlv_header(struct pcep_object_tlv_header
*tlv_hdr
,
35 uint16_t tlv_length
, struct pcep_versioning
*versioning
,
37 void pcep_decode_tlv_hdr(const uint8_t *tlv_buf
,
38 struct pcep_object_tlv_header
*tlv_hdr
);
41 * forward declarations for initialize_tlv_encoders()
43 uint16_t pcep_encode_tlv_no_path_vector(struct pcep_object_tlv_header
*tlv
,
44 struct pcep_versioning
*versioning
,
45 uint8_t *tlv_body_buf
);
47 pcep_encode_tlv_stateful_pce_capability(struct pcep_object_tlv_header
*tlv
,
48 struct pcep_versioning
*versioning
,
49 uint8_t *tlv_body_buf
);
50 uint16_t pcep_encode_tlv_symbolic_path_name(struct pcep_object_tlv_header
*tlv
,
51 struct pcep_versioning
*versioning
,
52 uint8_t *tlv_body_buf
);
54 pcep_encode_tlv_ipv4_lsp_identifiers(struct pcep_object_tlv_header
*tlv
,
55 struct pcep_versioning
*versioning
,
56 uint8_t *tlv_body_buf
);
58 pcep_encode_tlv_ipv6_lsp_identifiers(struct pcep_object_tlv_header
*tlv
,
59 struct pcep_versioning
*versioning
,
60 uint8_t *tlv_body_buf
);
61 uint16_t pcep_encode_tlv_lsp_error_code(struct pcep_object_tlv_header
*tlv
,
62 struct pcep_versioning
*versioning
,
63 uint8_t *tlv_body_buf
);
64 uint16_t pcep_encode_tlv_rsvp_error_spec(struct pcep_object_tlv_header
*tlv
,
65 struct pcep_versioning
*versioning
,
66 uint8_t *tlv_body_buf
);
67 uint16_t pcep_encode_tlv_lsp_db_version(struct pcep_object_tlv_header
*tlv
,
68 struct pcep_versioning
*versioning
,
69 uint8_t *tlv_body_buf
);
70 uint16_t pcep_encode_tlv_speaker_entity_id(struct pcep_object_tlv_header
*tlv
,
71 struct pcep_versioning
*versioning
,
72 uint8_t *tlv_body_buf
);
73 uint16_t pcep_encode_tlv_sr_pce_capability(struct pcep_object_tlv_header
*tlv
,
74 struct pcep_versioning
*versioning
,
75 uint8_t *tlv_body_buf
);
76 uint16_t pcep_encode_tlv_path_setup_type(struct pcep_object_tlv_header
*tlv
,
77 struct pcep_versioning
*versioning
,
78 uint8_t *tlv_body_buf
);
80 pcep_encode_tlv_path_setup_type_capability(struct pcep_object_tlv_header
*tlv
,
81 struct pcep_versioning
*versioning
,
82 uint8_t *tlv_body_buf
);
83 uint16_t pcep_encode_tlv_pol_id(struct pcep_object_tlv_header
*tlv
,
84 struct pcep_versioning
*versioning
,
85 uint8_t *tlv_body_buf
);
86 uint16_t pcep_encode_tlv_pol_name(struct pcep_object_tlv_header
*tlv
,
87 struct pcep_versioning
*versioning
,
88 uint8_t *tlv_body_buf
);
89 uint16_t pcep_encode_tlv_cpath_id(struct pcep_object_tlv_header
*tlv
,
90 struct pcep_versioning
*versioning
,
91 uint8_t *tlv_body_buf
);
92 uint16_t pcep_encode_tlv_cpath_preference(struct pcep_object_tlv_header
*tlv
,
93 struct pcep_versioning
*versioning
,
94 uint8_t *tlv_body_buf
);
95 uint16_t pcep_encode_tlv_vendor_info(struct pcep_object_tlv_header
*tlv
,
96 struct pcep_versioning
*versioning
,
97 uint8_t *tlv_body_buf
);
98 uint16_t pcep_encode_tlv_arbitrary(struct pcep_object_tlv_header
*tlv
,
99 struct pcep_versioning
*versioning
,
100 uint8_t *tlv_body_buf
);
101 uint16_t pcep_encode_tlv_of_list(struct pcep_object_tlv_header
*tlv
,
102 struct pcep_versioning
*versioning
,
103 uint8_t *tlv_body_buf
);
104 typedef uint16_t (*tlv_encoder_funcptr
)(struct pcep_object_tlv_header
*,
105 struct pcep_versioning
*versioning
,
106 uint8_t *tlv_body_buf
);
108 #define MAX_TLV_ENCODER_INDEX 65533 + 1 // 65
110 #define PCEP_TLV_ENCODERS_ARGS \
111 struct pcep_object_tlv_header *, struct pcep_versioning *versioning, \
112 uint8_t *tlv_body_buf
113 uint16_t (*const tlv_encoders
[MAX_TLV_ENCODER_INDEX
])(
114 PCEP_TLV_ENCODERS_ARGS
) = {
115 [PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR
] = pcep_encode_tlv_no_path_vector
,
116 [PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY
] =
117 pcep_encode_tlv_stateful_pce_capability
,
118 [PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME
] =
119 pcep_encode_tlv_symbolic_path_name
,
120 [PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS
] =
121 pcep_encode_tlv_ipv4_lsp_identifiers
,
122 [PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS
] =
123 pcep_encode_tlv_ipv6_lsp_identifiers
,
124 [PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE
] = pcep_encode_tlv_lsp_error_code
,
125 [PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC
] = pcep_encode_tlv_rsvp_error_spec
,
126 [PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION
] = pcep_encode_tlv_lsp_db_version
,
127 [PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID
] =
128 pcep_encode_tlv_speaker_entity_id
,
129 [PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY
] =
130 pcep_encode_tlv_sr_pce_capability
,
131 [PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE
] = pcep_encode_tlv_path_setup_type
,
132 [PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY
] =
133 pcep_encode_tlv_path_setup_type_capability
,
134 [PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID
] = pcep_encode_tlv_pol_id
,
135 [PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME
] = pcep_encode_tlv_pol_name
,
136 [PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID
] = pcep_encode_tlv_cpath_id
,
137 [PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE
] =
138 pcep_encode_tlv_cpath_preference
,
139 [PCEP_OBJ_TLV_TYPE_VENDOR_INFO
] = pcep_encode_tlv_vendor_info
,
140 [PCEP_OBJ_TLV_TYPE_ARBITRARY
] = pcep_encode_tlv_arbitrary
,
141 [PCEP_OBJ_TLV_TYPE_OBJECTIVE_FUNCTION_LIST
] = pcep_encode_tlv_of_list
,
144 * forward declarations for initialize_tlv_decoders()
146 struct pcep_object_tlv_header
*
147 pcep_decode_tlv_no_path_vector(struct pcep_object_tlv_header
*tlv_hdr
,
148 const uint8_t *tlv_body_buf
);
149 struct pcep_object_tlv_header
*
150 pcep_decode_tlv_stateful_pce_capability(struct pcep_object_tlv_header
*tlv_hdr
,
151 const uint8_t *tlv_body_buf
);
152 struct pcep_object_tlv_header
*
153 pcep_decode_tlv_symbolic_path_name(struct pcep_object_tlv_header
*tlv_hdr
,
154 const uint8_t *tlv_body_buf
);
155 struct pcep_object_tlv_header
*
156 pcep_decode_tlv_ipv4_lsp_identifiers(struct pcep_object_tlv_header
*tlv_hdr
,
157 const uint8_t *tlv_body_buf
);
158 struct pcep_object_tlv_header
*
159 pcep_decode_tlv_ipv6_lsp_identifiers(struct pcep_object_tlv_header
*tlv_hdr
,
160 const uint8_t *tlv_body_buf
);
161 struct pcep_object_tlv_header
*
162 pcep_decode_tlv_lsp_error_code(struct pcep_object_tlv_header
*tlv_hdr
,
163 const uint8_t *tlv_body_buf
);
164 struct pcep_object_tlv_header
*
165 pcep_decode_tlv_rsvp_error_spec(struct pcep_object_tlv_header
*tlv_hdr
,
166 const uint8_t *tlv_body_buf
);
167 struct pcep_object_tlv_header
*
168 pcep_decode_tlv_lsp_db_version(struct pcep_object_tlv_header
*tlv_hdr
,
169 const uint8_t *tlv_body_buf
);
170 struct pcep_object_tlv_header
*
171 pcep_decode_tlv_speaker_entity_id(struct pcep_object_tlv_header
*tlv_hdr
,
172 const uint8_t *tlv_body_buf
);
173 struct pcep_object_tlv_header
*
174 pcep_decode_tlv_sr_pce_capability(struct pcep_object_tlv_header
*tlv_hdr
,
175 const uint8_t *tlv_body_buf
);
176 struct pcep_object_tlv_header
*
177 pcep_decode_tlv_path_setup_type(struct pcep_object_tlv_header
*tlv_hdr
,
178 const uint8_t *tlv_body_buf
);
179 struct pcep_object_tlv_header
*pcep_decode_tlv_path_setup_type_capability(
180 struct pcep_object_tlv_header
*tlv_hdr
, const uint8_t *tlv_body_buf
);
181 struct pcep_object_tlv_header
*
182 pcep_decode_tlv_pol_id(struct pcep_object_tlv_header
*tlv_hdr
,
183 const uint8_t *tlv_body_buf
);
184 struct pcep_object_tlv_header
*
185 pcep_decode_tlv_pol_name(struct pcep_object_tlv_header
*tlv_hdr
,
186 const uint8_t *tlv_body_buf
);
187 struct pcep_object_tlv_header
*
188 pcep_decode_tlv_cpath_id(struct pcep_object_tlv_header
*tlv_hdr
,
189 const uint8_t *tlv_body_buf
);
190 struct pcep_object_tlv_header
*
191 pcep_decode_tlv_cpath_preference(struct pcep_object_tlv_header
*tlv_hdr
,
192 const uint8_t *tlv_body_buf
);
193 struct pcep_object_tlv_header
*
194 pcep_decode_tlv_vendor_info(struct pcep_object_tlv_header
*tlv_hdr
,
195 const uint8_t *tlv_body_buf
);
196 struct pcep_object_tlv_header
*
197 pcep_decode_tlv_arbitrary(struct pcep_object_tlv_header
*tlv_hdr
,
198 const uint8_t *tlv_body_buf
);
199 struct pcep_object_tlv_header
*
200 pcep_decode_tlv_of_list(struct pcep_object_tlv_header
*tlv_hdr
,
201 const uint8_t *tlv_body_buf
);
202 typedef struct pcep_object_tlv_header
*(*tlv_decoder_funcptr
)(
203 struct pcep_object_tlv_header
*tlv_hdr
, const uint8_t *tlv_body_buf
);
205 // tlv_decoder_funcptr tlv_decoders[MAX_TLV_ENCODER_INDEX];
207 #define PCEP_TLV_DECODERS_ARGS \
208 struct pcep_object_tlv_header *tlv_hdr, const uint8_t *tlv_body_buf
210 struct pcep_object_tlv_header
*(*const tlv_decoders
[MAX_TLV_ENCODER_INDEX
])(
211 PCEP_TLV_DECODERS_ARGS
) = {
212 [PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR
] = pcep_decode_tlv_no_path_vector
,
213 [PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY
] =
214 pcep_decode_tlv_stateful_pce_capability
,
215 [PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME
] =
216 pcep_decode_tlv_symbolic_path_name
,
217 [PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS
] =
218 pcep_decode_tlv_ipv4_lsp_identifiers
,
219 [PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS
] =
220 pcep_decode_tlv_ipv6_lsp_identifiers
,
221 [PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE
] = pcep_decode_tlv_lsp_error_code
,
222 [PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC
] = pcep_decode_tlv_rsvp_error_spec
,
223 [PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION
] = pcep_decode_tlv_lsp_db_version
,
224 [PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID
] =
225 pcep_decode_tlv_speaker_entity_id
,
226 [PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY
] =
227 pcep_decode_tlv_sr_pce_capability
,
228 [PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE
] = pcep_decode_tlv_path_setup_type
,
229 [PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY
] =
230 pcep_decode_tlv_path_setup_type_capability
,
231 [PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID
] = pcep_decode_tlv_pol_id
,
232 [PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME
] = pcep_decode_tlv_pol_name
,
233 [PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID
] = pcep_decode_tlv_cpath_id
,
234 [PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE
] =
235 pcep_decode_tlv_cpath_preference
,
236 [PCEP_OBJ_TLV_TYPE_VENDOR_INFO
] = pcep_decode_tlv_vendor_info
,
237 [PCEP_OBJ_TLV_TYPE_ARBITRARY
] = pcep_decode_tlv_arbitrary
,
238 [PCEP_OBJ_TLV_TYPE_OBJECTIVE_FUNCTION_LIST
] = pcep_decode_tlv_of_list
,
241 static void initialize_tlv_coders(void)
243 static bool initialized
= false;
245 if (initialized
== true) {
253 memset(tlv_encoders, 0, sizeof(tlv_encoder_funcptr) *
254 MAX_TLV_ENCODER_INDEX); tlv_encoders[PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR] =
255 pcep_encode_tlv_no_path_vector;
256 tlv_encoders[PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY] =
257 pcep_encode_tlv_stateful_pce_capability;
258 tlv_encoders[PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME] =
259 pcep_encode_tlv_symbolic_path_name;
260 tlv_encoders[PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS] =
261 pcep_encode_tlv_ipv4_lsp_identifiers;
262 tlv_encoders[PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS] =
263 pcep_encode_tlv_ipv6_lsp_identifiers;
264 tlv_encoders[PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE] =
265 pcep_encode_tlv_lsp_error_code;
266 tlv_encoders[PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC] =
267 pcep_encode_tlv_rsvp_error_spec;
268 tlv_encoders[PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION] =
269 pcep_encode_tlv_lsp_db_version;
270 tlv_encoders[PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID] =
271 pcep_encode_tlv_speaker_entity_id;
272 tlv_encoders[PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY] =
273 pcep_encode_tlv_sr_pce_capability;
274 tlv_encoders[PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE] =
275 pcep_encode_tlv_path_setup_type;
276 tlv_encoders[PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY] =
277 pcep_encode_tlv_path_setup_type_capability;
278 tlv_encoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID] =
279 pcep_encode_tlv_pol_id;
280 tlv_encoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME] =
281 pcep_encode_tlv_pol_name;
282 tlv_encoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID] =
283 pcep_encode_tlv_cpath_id;
284 tlv_encoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE] =
285 pcep_encode_tlv_cpath_preference;
286 tlv_encoders[PCEP_OBJ_TLV_TYPE_VENDOR_INFO] =
287 pcep_encode_tlv_vendor_info; tlv_encoders[PCEP_OBJ_TLV_TYPE_ARBITRARY] =
288 pcep_encode_tlv_arbitrary;
289 tlv_encoders[PCEP_OBJ_TLV_TYPE_OBJECTIVE_FUNCTION_LIST] =
290 pcep_encode_tlv_of_list;
295 memset(tlv_decoders, 0, sizeof(tlv_decoder_funcptr) *
296 MAX_TLV_ENCODER_INDEX); tlv_decoders[PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR] =
297 pcep_decode_tlv_no_path_vector;
298 tlv_decoders[PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY] =
299 pcep_decode_tlv_stateful_pce_capability;
300 tlv_decoders[PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME] =
301 pcep_decode_tlv_symbolic_path_name;
302 tlv_decoders[PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS] =
303 pcep_decode_tlv_ipv4_lsp_identifiers;
304 tlv_decoders[PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS] =
305 pcep_decode_tlv_ipv6_lsp_identifiers;
306 tlv_decoders[PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE] =
307 pcep_decode_tlv_lsp_error_code;
308 tlv_decoders[PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC] =
309 pcep_decode_tlv_rsvp_error_spec;
310 tlv_decoders[PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION] =
311 pcep_decode_tlv_lsp_db_version;
312 tlv_decoders[PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID] =
313 pcep_decode_tlv_speaker_entity_id;
314 tlv_decoders[PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY] =
315 pcep_decode_tlv_sr_pce_capability;
316 tlv_decoders[PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE] =
317 pcep_decode_tlv_path_setup_type;
318 tlv_decoders[PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY] =
319 pcep_decode_tlv_path_setup_type_capability;
320 tlv_decoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID] =
321 pcep_decode_tlv_pol_id;
322 tlv_decoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME] =
323 pcep_decode_tlv_pol_name;
324 tlv_decoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID] =
325 pcep_decode_tlv_cpath_id;
326 tlv_decoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE] =
327 pcep_decode_tlv_cpath_preference;
328 tlv_decoders[PCEP_OBJ_TLV_TYPE_VENDOR_INFO] =
329 pcep_decode_tlv_vendor_info; tlv_decoders[PCEP_OBJ_TLV_TYPE_ARBITRARY] =
330 pcep_decode_tlv_arbitrary;
331 tlv_decoders[PCEP_OBJ_TLV_TYPE_OBJECTIVE_FUNCTION_LIST] =
332 pcep_decode_tlv_of_list;
336 uint16_t pcep_encode_tlv(struct pcep_object_tlv_header
*tlv_hdr
,
337 struct pcep_versioning
*versioning
, uint8_t *buf
)
339 initialize_tlv_coders();
341 if (tlv_hdr
->type
>= MAX_TLV_ENCODER_INDEX
) {
343 "%s: Cannot encode unknown Object class [%d]",
344 __func__
, tlv_hdr
->type
);
348 tlv_encoder_funcptr tlv_encoder
= tlv_encoders
[tlv_hdr
->type
];
349 if (tlv_encoder
== NULL
) {
351 "%s: No object encoder found for Object class [%d]",
352 __func__
, tlv_hdr
->type
);
356 /* Notice: The length in the TLV header does not include the TLV header,
357 * so the length returned from the tlv_encoder() is only the TLV body.
359 uint16_t tlv_length
=
360 tlv_encoder(tlv_hdr
, versioning
, buf
+ TLV_HEADER_LENGTH
);
361 write_tlv_header(tlv_hdr
, tlv_length
, versioning
, buf
);
362 tlv_hdr
->encoded_tlv
= buf
;
363 tlv_hdr
->encoded_tlv_length
= tlv_length
;
365 return normalize_pcep_tlv_length(tlv_length
+ TLV_HEADER_LENGTH
);
371 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
372 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
373 * | Type (2 bytes) | Length (2 bytes) |
374 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
375 * | Value (Variable) |
376 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
379 void write_tlv_header(struct pcep_object_tlv_header
*tlv_hdr
,
380 uint16_t tlv_length
, struct pcep_versioning
*versioning
,
384 uint16_t *uint16_ptr
= (uint16_t *)buf
;
385 uint16_ptr
[0] = htons(tlv_hdr
->type
);
386 uint16_ptr
[1] = htons(tlv_length
);
390 * Functions to encode TLVs
393 uint16_t pcep_encode_tlv_no_path_vector(struct pcep_object_tlv_header
*tlv
,
394 struct pcep_versioning
*versioning
,
395 uint8_t *tlv_body_buf
)
398 struct pcep_object_tlv_nopath_vector
*nopath_tlv
=
399 (struct pcep_object_tlv_nopath_vector
*)tlv
;
400 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
401 *uint32_ptr
= htonl(nopath_tlv
->error_code
);
407 pcep_encode_tlv_stateful_pce_capability(struct pcep_object_tlv_header
*tlv
,
408 struct pcep_versioning
*versioning
,
409 uint8_t *tlv_body_buf
)
412 struct pcep_object_tlv_stateful_pce_capability
*spc_tlv
=
413 (struct pcep_object_tlv_stateful_pce_capability
*)tlv
;
415 ((spc_tlv
->flag_f_triggered_initial_sync
== true
416 ? TLV_STATEFUL_PCE_CAP_FLAG_F
418 | (spc_tlv
->flag_d_delta_lsp_sync
== true
419 ? TLV_STATEFUL_PCE_CAP_FLAG_D
421 | (spc_tlv
->flag_t_triggered_resync
== true
422 ? TLV_STATEFUL_PCE_CAP_FLAG_T
424 | (spc_tlv
->flag_i_lsp_instantiation_capability
== true
425 ? TLV_STATEFUL_PCE_CAP_FLAG_I
427 | (spc_tlv
->flag_s_include_db_version
== true
428 ? TLV_STATEFUL_PCE_CAP_FLAG_S
430 | (spc_tlv
->flag_u_lsp_update_capability
== true
431 ? TLV_STATEFUL_PCE_CAP_FLAG_U
437 uint16_t pcep_encode_tlv_symbolic_path_name(struct pcep_object_tlv_header
*tlv
,
438 struct pcep_versioning
*versioning
,
439 uint8_t *tlv_body_buf
)
442 struct pcep_object_tlv_symbolic_path_name
*spn_tlv
=
443 (struct pcep_object_tlv_symbolic_path_name
*)tlv
;
444 memcpy(tlv_body_buf
, spn_tlv
->symbolic_path_name
,
445 spn_tlv
->symbolic_path_name_length
);
447 return spn_tlv
->symbolic_path_name_length
;
451 pcep_encode_tlv_ipv4_lsp_identifiers(struct pcep_object_tlv_header
*tlv
,
452 struct pcep_versioning
*versioning
,
453 uint8_t *tlv_body_buf
)
456 struct pcep_object_tlv_ipv4_lsp_identifier
*ipv4_lsp
=
457 (struct pcep_object_tlv_ipv4_lsp_identifier
*)tlv
;
458 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
459 uint32_ptr
[0] = ipv4_lsp
->ipv4_tunnel_sender
.s_addr
;
460 /* uint32_t[1] is lsp_id and tunnel_id, below */
461 uint32_ptr
[2] = ipv4_lsp
->extended_tunnel_id
.s_addr
;
462 uint32_ptr
[3] = ipv4_lsp
->ipv4_tunnel_endpoint
.s_addr
;
464 uint16_t *uint16_ptr
= (uint16_t *)(tlv_body_buf
+ LENGTH_1WORD
);
465 uint16_ptr
[0] = htons(ipv4_lsp
->lsp_id
);
466 uint16_ptr
[1] = htons(ipv4_lsp
->tunnel_id
);
468 return LENGTH_4WORDS
;
472 pcep_encode_tlv_ipv6_lsp_identifiers(struct pcep_object_tlv_header
*tlv
,
473 struct pcep_versioning
*versioning
,
474 uint8_t *tlv_body_buf
)
477 struct pcep_object_tlv_ipv6_lsp_identifier
*ipv6_lsp
=
478 (struct pcep_object_tlv_ipv6_lsp_identifier
*)tlv
;
479 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
480 encode_ipv6(&ipv6_lsp
->ipv6_tunnel_sender
, uint32_ptr
);
481 encode_ipv6(&ipv6_lsp
->extended_tunnel_id
, uint32_ptr
+ 5);
482 encode_ipv6(&ipv6_lsp
->ipv6_tunnel_endpoint
, uint32_ptr
+ 9);
484 uint16_t *uint16_ptr
= (uint16_t *)(tlv_body_buf
+ LENGTH_4WORDS
);
485 uint16_ptr
[0] = htons(ipv6_lsp
->lsp_id
);
486 uint16_ptr
[1] = htons(ipv6_lsp
->tunnel_id
);
488 return LENGTH_13WORDS
;
491 uint16_t pcep_encode_tlv_lsp_error_code(struct pcep_object_tlv_header
*tlv
,
492 struct pcep_versioning
*versioning
,
493 uint8_t *tlv_body_buf
)
496 struct pcep_object_tlv_lsp_error_code
*lsp_error_tlv
=
497 (struct pcep_object_tlv_lsp_error_code
*)tlv
;
498 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
499 *uint32_ptr
= htonl(lsp_error_tlv
->lsp_error_code
);
504 uint16_t pcep_encode_tlv_rsvp_error_spec(struct pcep_object_tlv_header
*tlv
,
505 struct pcep_versioning
*versioning
,
506 uint8_t *tlv_body_buf
)
508 /* Same decode tlv function for both types:
509 pcep_create_tlv_rsvp_ipv4_error_spec(tlv);
510 pcep_create_tlv_rsvp_ipv6_error_spec(tlv); */
512 /* RSVP Object Header
515 * +-------------+-------------+-------------+-------------+
516 * | Length (bytes) | Class-Num | C-Type |
517 * +-------------+-------------+-------------+-------------+
519 * // (Object contents) //
521 * +-------------+-------------+-------------+-------------+
523 * IPv4 ERROR_SPEC object: Class = 6, C-Type = 1
524 * +-------------+-------------+-------------+-------------+
525 * | IPv4 Error Node Address (4 bytes) |
526 * +-------------+-------------+-------------+-------------+
527 * | Flags | Error Code | Error Value |
528 * +-------------+-------------+-------------+-------------+
530 * IPv6 ERROR_SPEC object: Class = 6, C-Type = 2
531 * +-------------+-------------+-------------+-------------+
532 * | IPv6 Error Node Address (16 bytes) |
533 * +-------------+-------------+-------------+-------------+
534 * | Flags | Error Code | Error Value |
535 * +-------------+-------------+-------------+-------------+
539 struct pcep_object_tlv_rsvp_error_spec
*rsvp_hdr
=
540 (struct pcep_object_tlv_rsvp_error_spec
*)tlv
;
541 tlv_body_buf
[2] = rsvp_hdr
->class_num
;
542 tlv_body_buf
[3] = rsvp_hdr
->c_type
;
544 uint16_t *length_ptr
= (uint16_t *)tlv_body_buf
;
545 uint32_t *uint32_ptr
= (uint32_t *)(tlv_body_buf
+ LENGTH_1WORD
);
546 if (rsvp_hdr
->c_type
== RSVP_ERROR_SPEC_IPV4_CTYPE
) {
547 *length_ptr
= htons(LENGTH_3WORDS
);
549 rsvp_hdr
->error_spec_ip
.ipv4_error_node_address
.s_addr
;
550 tlv_body_buf
[LENGTH_2WORDS
+ 1] = rsvp_hdr
->error_code
;
551 uint16_t *uint16_ptr
=
552 (uint16_t *)(tlv_body_buf
+ LENGTH_2WORDS
+ 2);
553 *uint16_ptr
= htons(rsvp_hdr
->error_value
);
555 return LENGTH_3WORDS
;
556 } else if (rsvp_hdr
->c_type
== RSVP_ERROR_SPEC_IPV6_CTYPE
) {
557 *length_ptr
= htons(LENGTH_6WORDS
);
558 encode_ipv6(&rsvp_hdr
->error_spec_ip
.ipv6_error_node_address
,
560 tlv_body_buf
[LENGTH_5WORDS
+ 1] = rsvp_hdr
->error_code
;
561 uint16_t *uint16_ptr
=
562 (uint16_t *)(tlv_body_buf
+ LENGTH_5WORDS
+ 2);
563 *uint16_ptr
= htons(rsvp_hdr
->error_value
);
565 return LENGTH_6WORDS
;
571 uint16_t pcep_encode_tlv_lsp_db_version(struct pcep_object_tlv_header
*tlv
,
572 struct pcep_versioning
*versioning
,
573 uint8_t *tlv_body_buf
)
576 struct pcep_object_tlv_lsp_db_version
*lsp_db_ver
=
577 (struct pcep_object_tlv_lsp_db_version
*)tlv
;
578 *((uint64_t *)tlv_body_buf
) = htobe64(lsp_db_ver
->lsp_db_version
);
580 return LENGTH_2WORDS
;
583 uint16_t pcep_encode_tlv_speaker_entity_id(struct pcep_object_tlv_header
*tlv
,
584 struct pcep_versioning
*versioning
,
585 uint8_t *tlv_body_buf
)
588 struct pcep_object_tlv_speaker_entity_identifier
*speaker_id
=
589 (struct pcep_object_tlv_speaker_entity_identifier
*)tlv
;
590 if (speaker_id
->speaker_entity_id_list
== NULL
) {
595 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
596 double_linked_list_node
*node
=
597 speaker_id
->speaker_entity_id_list
->head
;
598 for (; node
!= NULL
; node
= node
->next_node
) {
599 uint32_ptr
[index
++] = htonl(*((uint32_t *)node
->data
));
602 return speaker_id
->speaker_entity_id_list
->num_entries
* LENGTH_1WORD
;
605 uint16_t pcep_encode_tlv_sr_pce_capability(struct pcep_object_tlv_header
*tlv
,
606 struct pcep_versioning
*versioning
,
607 uint8_t *tlv_body_buf
)
610 struct pcep_object_tlv_sr_pce_capability
*sr_pce_cap
=
611 (struct pcep_object_tlv_sr_pce_capability
*)tlv
;
613 ((sr_pce_cap
->flag_n
== true ? TLV_SR_PCE_CAP_FLAG_N
: 0x00)
614 | (sr_pce_cap
->flag_x
== true ? TLV_SR_PCE_CAP_FLAG_X
: 0x00));
615 tlv_body_buf
[3] = sr_pce_cap
->max_sid_depth
;
620 uint16_t pcep_encode_tlv_path_setup_type(struct pcep_object_tlv_header
*tlv
,
621 struct pcep_versioning
*versioning
,
622 uint8_t *tlv_body_buf
)
625 struct pcep_object_tlv_path_setup_type
*pst
=
626 (struct pcep_object_tlv_path_setup_type
*)tlv
;
627 tlv_body_buf
[3] = pst
->path_setup_type
;
633 pcep_encode_tlv_path_setup_type_capability(struct pcep_object_tlv_header
*tlv
,
634 struct pcep_versioning
*versioning
,
635 uint8_t *tlv_body_buf
)
638 struct pcep_object_tlv_path_setup_type_capability
*pst_cap
=
639 (struct pcep_object_tlv_path_setup_type_capability
*)tlv
;
640 if (pst_cap
->pst_list
== NULL
) {
644 tlv_body_buf
[3] = pst_cap
->pst_list
->num_entries
;
646 /* Index past the reserved and NumPSTs fields */
648 double_linked_list_node
*node
= pst_cap
->pst_list
->head
;
649 for (; node
!= NULL
; node
= node
->next_node
) {
650 tlv_body_buf
[index
++] = *((uint8_t *)node
->data
);
653 uint16_t pst_length
= normalize_pcep_tlv_length(
654 LENGTH_1WORD
+ pst_cap
->pst_list
->num_entries
);
655 if (pst_cap
->sub_tlv_list
== NULL
) {
659 /* Any padding used for the PSTs should not be included in the tlv
661 index
= normalize_pcep_tlv_length(index
);
662 uint16_t sub_tlvs_length
= 0;
663 node
= pst_cap
->sub_tlv_list
->head
;
664 for (; node
!= NULL
; node
= node
->next_node
) {
665 struct pcep_object_tlv_header
*sub_tlv
=
666 (struct pcep_object_tlv_header
*)node
->data
;
667 uint16_t sub_tlv_length
= pcep_encode_tlv(sub_tlv
, versioning
,
668 tlv_body_buf
+ index
);
669 index
+= sub_tlv_length
;
670 sub_tlvs_length
+= sub_tlv_length
;
673 return sub_tlvs_length
+ pst_length
;
675 uint16_t pcep_encode_tlv_pol_id(struct pcep_object_tlv_header
*tlv
,
676 struct pcep_versioning
*versioning
,
677 uint8_t *tlv_body_buf
)
680 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
681 struct pcep_object_tlv_srpag_pol_id
*ipv4
=
682 (struct pcep_object_tlv_srpag_pol_id
*)tlv
;
684 uint32_ptr
[0] = htonl(ipv4
->color
);
685 uint32_ptr
[1] = ipv4
->end_point
.ipv4
.s_addr
;
686 return LENGTH_2WORDS
;
688 struct pcep_object_tlv_srpag_pol_id
*ipv6
=
689 (struct pcep_object_tlv_srpag_pol_id
*)tlv
;
690 uint32_ptr
[0] = htonl(ipv6
->color
);
691 encode_ipv6(&ipv6
->end_point
.ipv6
, &uint32_ptr
[1]);
692 return LENGTH_5WORDS
;
696 uint16_t pcep_encode_tlv_pol_name(struct pcep_object_tlv_header
*tlv
,
697 struct pcep_versioning
*versioning
,
698 uint8_t *tlv_body_buf
)
701 struct pcep_object_tlv_srpag_pol_name
*pol_name_tlv
=
702 (struct pcep_object_tlv_srpag_pol_name
*)tlv
;
703 memcpy(tlv_body_buf
, pol_name_tlv
->name
, pol_name_tlv
->name_length
);
705 return normalize_pcep_tlv_length(pol_name_tlv
->name_length
);
708 uint16_t pcep_encode_tlv_cpath_id(struct pcep_object_tlv_header
*tlv
,
709 struct pcep_versioning
*versioning
,
710 uint8_t *tlv_body_buf
)
713 struct pcep_object_tlv_srpag_cp_id
*cpath_id_tlv
=
714 (struct pcep_object_tlv_srpag_cp_id
*)tlv
;
716 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
717 tlv_body_buf
[0] = cpath_id_tlv
->proto
;
718 uint32_ptr
[1] = htonl(cpath_id_tlv
->orig_asn
);
719 encode_ipv6(&cpath_id_tlv
->orig_addres
, &uint32_ptr
[2]);
720 uint32_ptr
[6] = htonl(cpath_id_tlv
->discriminator
);
722 return sizeof(cpath_id_tlv
->proto
) + sizeof(cpath_id_tlv
->orig_asn
)
723 + sizeof(cpath_id_tlv
->orig_addres
)
724 + sizeof(cpath_id_tlv
->discriminator
);
727 uint16_t pcep_encode_tlv_cpath_preference(struct pcep_object_tlv_header
*tlv
,
728 struct pcep_versioning
*versioning
,
729 uint8_t *tlv_body_buf
)
732 struct pcep_object_tlv_srpag_cp_pref
*cpath_pref_tlv
=
733 (struct pcep_object_tlv_srpag_cp_pref
*)tlv
;
735 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
736 uint32_ptr
[0] = htonl(cpath_pref_tlv
->preference
);
738 return sizeof(cpath_pref_tlv
->preference
);
741 uint16_t pcep_encode_tlv_vendor_info(struct pcep_object_tlv_header
*tlv
,
742 struct pcep_versioning
*versioning
,
743 uint8_t *tlv_body_buf
)
746 struct pcep_object_tlv_vendor_info
*vendor_info
=
747 (struct pcep_object_tlv_vendor_info
*)tlv
;
749 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
750 uint32_ptr
[0] = htonl(vendor_info
->enterprise_number
);
751 uint32_ptr
[1] = htonl(vendor_info
->enterprise_specific_info
);
753 return LENGTH_2WORDS
;
756 uint16_t pcep_encode_tlv_arbitrary(struct pcep_object_tlv_header
*tlv
,
757 struct pcep_versioning
*versioning
,
758 uint8_t *tlv_body_buf
)
761 struct pcep_object_tlv_arbitrary
*tlv_arbitrary
=
762 (struct pcep_object_tlv_arbitrary
*)tlv
;
763 memcpy(tlv_body_buf
, tlv_arbitrary
->data
, tlv_arbitrary
->data_length
);
764 tlv
->type
= tlv_arbitrary
->arbitraty_type
;
766 return tlv_arbitrary
->data_length
;
769 uint16_t pcep_encode_tlv_of_list(struct pcep_object_tlv_header
*tlv
,
770 struct pcep_versioning
*versioning
,
771 uint8_t *tlv_body_buf
)
774 struct pcep_object_tlv_of_list
*of_list
=
775 (struct pcep_object_tlv_of_list
*)tlv
;
777 if (of_list
->of_list
== NULL
) {
782 double_linked_list_node
*node
= of_list
->of_list
->head
;
783 while (node
!= NULL
) {
784 uint16_t *of_code
= (uint16_t *)node
->data
;
785 if (of_code
== NULL
) {
789 uint16_t *uint16_ptr
= (uint16_t *)(tlv_body_buf
+ index
);
790 *uint16_ptr
= *of_code
;
793 node
= node
->next_node
;
796 return of_list
->of_list
->num_entries
* 2;
803 void pcep_decode_tlv_hdr(const uint8_t *tlv_buf
,
804 struct pcep_object_tlv_header
*tlv_hdr
)
806 memset(tlv_hdr
, 0, sizeof(struct pcep_object_tlv_header
));
808 uint16_t *uint16_ptr
= (uint16_t *)tlv_buf
;
809 tlv_hdr
->type
= ntohs(uint16_ptr
[0]);
810 tlv_hdr
->encoded_tlv_length
= ntohs(uint16_ptr
[1]);
811 tlv_hdr
->encoded_tlv
= tlv_buf
;
814 struct pcep_object_tlv_header
*pcep_decode_tlv(const uint8_t *tlv_buf
)
816 initialize_tlv_coders();
818 struct pcep_object_tlv_header tlv_hdr
;
819 /* Only initializes and decodes the Object Header: class, type, flags,
821 pcep_decode_tlv_hdr(tlv_buf
, &tlv_hdr
);
823 if (tlv_hdr
.type
>= MAX_TLV_ENCODER_INDEX
) {
824 pcep_log(LOG_INFO
, "%s: Cannot decode unknown TLV type [%d]",
825 __func__
, tlv_hdr
.type
);
829 tlv_decoder_funcptr tlv_decoder
= NULL
;
830 if (tlv_hdr
.type
== PCEP_OBJ_TYPE_CISCO_BSID
) {
832 "%s: Cisco BSID TLV decoder found for TLV type [%d]",
833 __func__
, tlv_hdr
.type
);
834 tlv_decoder
= tlv_decoders
[PCEP_OBJ_TLV_TYPE_ARBITRARY
];
836 tlv_decoder
= tlv_decoders
[tlv_hdr
.type
];
838 if (tlv_decoder
== NULL
) {
839 pcep_log(LOG_INFO
, "%s: No TLV decoder found for TLV type [%d]",
840 __func__
, tlv_hdr
.type
);
844 return tlv_decoder(&tlv_hdr
, tlv_buf
+ LENGTH_1WORD
);
847 static struct pcep_object_tlv_header
*
848 common_tlv_create(struct pcep_object_tlv_header
*hdr
, uint16_t new_tlv_length
)
850 struct pcep_object_tlv_header
*new_tlv
=
851 pceplib_malloc(PCEPLIB_MESSAGES
, new_tlv_length
);
852 memset(new_tlv
, 0, new_tlv_length
);
853 memcpy(new_tlv
, hdr
, sizeof(struct pcep_object_tlv_header
));
858 struct pcep_object_tlv_header
*
859 pcep_decode_tlv_no_path_vector(struct pcep_object_tlv_header
*tlv_hdr
,
860 const uint8_t *tlv_body_buf
)
862 struct pcep_object_tlv_nopath_vector
*tlv
=
863 (struct pcep_object_tlv_nopath_vector
*)common_tlv_create(
864 tlv_hdr
, sizeof(struct pcep_object_tlv_nopath_vector
));
866 tlv
->error_code
= ntohl(*((uint32_t *)tlv_body_buf
));
868 return (struct pcep_object_tlv_header
*)tlv
;
871 struct pcep_object_tlv_header
*
872 pcep_decode_tlv_stateful_pce_capability(struct pcep_object_tlv_header
*tlv_hdr
,
873 const uint8_t *tlv_body_buf
)
875 struct pcep_object_tlv_stateful_pce_capability
*tlv
=
876 (struct pcep_object_tlv_stateful_pce_capability
*)
880 pcep_object_tlv_stateful_pce_capability
));
882 tlv
->flag_f_triggered_initial_sync
=
883 (tlv_body_buf
[3] & TLV_STATEFUL_PCE_CAP_FLAG_F
);
884 tlv
->flag_d_delta_lsp_sync
=
885 (tlv_body_buf
[3] & TLV_STATEFUL_PCE_CAP_FLAG_D
);
886 tlv
->flag_t_triggered_resync
=
887 (tlv_body_buf
[3] & TLV_STATEFUL_PCE_CAP_FLAG_T
);
888 tlv
->flag_i_lsp_instantiation_capability
=
889 (tlv_body_buf
[3] & TLV_STATEFUL_PCE_CAP_FLAG_I
);
890 tlv
->flag_s_include_db_version
=
891 (tlv_body_buf
[3] & TLV_STATEFUL_PCE_CAP_FLAG_S
);
892 tlv
->flag_u_lsp_update_capability
=
893 (tlv_body_buf
[3] & TLV_STATEFUL_PCE_CAP_FLAG_U
);
895 return (struct pcep_object_tlv_header
*)tlv
;
898 struct pcep_object_tlv_header
*
899 pcep_decode_tlv_symbolic_path_name(struct pcep_object_tlv_header
*tlv_hdr
,
900 const uint8_t *tlv_body_buf
)
902 struct pcep_object_tlv_symbolic_path_name
*tlv
=
903 (struct pcep_object_tlv_symbolic_path_name
*)common_tlv_create(
905 sizeof(struct pcep_object_tlv_symbolic_path_name
));
907 uint16_t length
= tlv_hdr
->encoded_tlv_length
;
908 if (length
> MAX_SYMBOLIC_PATH_NAME
) {
909 /* TODO should we also reset the tlv_hdr->encoded_tlv_length ?
911 length
= MAX_SYMBOLIC_PATH_NAME
;
914 "%s: Decoding Symbolic Path Name TLV, truncate path name from [%d] to [%d].\",",
915 __func__
, tlv_hdr
->encoded_tlv_length
,
916 MAX_SYMBOLIC_PATH_NAME
);
919 tlv
->symbolic_path_name_length
= length
;
920 memcpy(tlv
->symbolic_path_name
, tlv_body_buf
, length
);
922 return (struct pcep_object_tlv_header
*)tlv
;
925 struct pcep_object_tlv_header
*
926 pcep_decode_tlv_ipv4_lsp_identifiers(struct pcep_object_tlv_header
*tlv_hdr
,
927 const uint8_t *tlv_body_buf
)
929 struct pcep_object_tlv_ipv4_lsp_identifier
*tlv
=
930 (struct pcep_object_tlv_ipv4_lsp_identifier
*)common_tlv_create(
932 sizeof(struct pcep_object_tlv_ipv4_lsp_identifier
));
934 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
935 tlv
->ipv4_tunnel_sender
.s_addr
= uint32_ptr
[0];
936 /* uint32_t[1] is lsp_id and tunnel_id, below */
937 tlv
->extended_tunnel_id
.s_addr
= uint32_ptr
[2];
938 tlv
->ipv4_tunnel_endpoint
.s_addr
= uint32_ptr
[3];
940 uint16_t *uint16_ptr
= (uint16_t *)(tlv_body_buf
+ LENGTH_1WORD
);
941 tlv
->lsp_id
= ntohs(uint16_ptr
[0]);
942 tlv
->tunnel_id
= ntohs(uint16_ptr
[1]);
944 return (struct pcep_object_tlv_header
*)tlv
;
947 struct pcep_object_tlv_header
*
948 pcep_decode_tlv_ipv6_lsp_identifiers(struct pcep_object_tlv_header
*tlv_hdr
,
949 const uint8_t *tlv_body_buf
)
951 struct pcep_object_tlv_ipv6_lsp_identifier
*tlv
=
952 (struct pcep_object_tlv_ipv6_lsp_identifier
*)common_tlv_create(
954 sizeof(struct pcep_object_tlv_ipv6_lsp_identifier
));
956 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
957 decode_ipv6(uint32_ptr
, &tlv
->ipv6_tunnel_sender
);
958 decode_ipv6(uint32_ptr
+ 5, &tlv
->extended_tunnel_id
);
959 decode_ipv6(uint32_ptr
+ 9, &tlv
->ipv6_tunnel_endpoint
);
961 uint16_t *uint16_ptr
= (uint16_t *)(tlv_body_buf
+ LENGTH_4WORDS
);
962 tlv
->lsp_id
= htons(uint16_ptr
[0]);
963 tlv
->tunnel_id
= htons(uint16_ptr
[1]);
965 return (struct pcep_object_tlv_header
*)tlv
;
968 struct pcep_object_tlv_header
*
969 pcep_decode_tlv_lsp_error_code(struct pcep_object_tlv_header
*tlv_hdr
,
970 const uint8_t *tlv_body_buf
)
972 struct pcep_object_tlv_lsp_error_code
*tlv
=
973 (struct pcep_object_tlv_lsp_error_code
*)common_tlv_create(
974 tlv_hdr
, sizeof(struct pcep_object_tlv_lsp_error_code
));
976 tlv
->lsp_error_code
= ntohl(*((uint32_t *)tlv_body_buf
));
978 return (struct pcep_object_tlv_header
*)tlv
;
981 struct pcep_object_tlv_header
*
982 pcep_decode_tlv_rsvp_error_spec(struct pcep_object_tlv_header
*tlv_hdr
,
983 const uint8_t *tlv_body_buf
)
985 uint8_t class_num
= tlv_body_buf
[2];
986 uint8_t ctype
= tlv_body_buf
[3];
988 if (class_num
!= RSVP_ERROR_SPEC_CLASS_NUM
) {
991 "%s: Decoding RSVP Error Spec TLV, unknown class num [%d]",
992 __func__
, class_num
);
996 if (ctype
!= RSVP_ERROR_SPEC_IPV4_CTYPE
997 && ctype
!= RSVP_ERROR_SPEC_IPV6_CTYPE
) {
999 "%s: Decoding RSVP Error Spec TLV, unknown ctype [%d]",
1004 struct pcep_object_tlv_rsvp_error_spec
*tlv
=
1005 (struct pcep_object_tlv_rsvp_error_spec
*)common_tlv_create(
1007 sizeof(struct pcep_object_tlv_rsvp_error_spec
));
1009 tlv
->class_num
= class_num
;
1010 tlv
->c_type
= ctype
;
1012 uint32_t *uint32_ptr
= (uint32_t *)(tlv_body_buf
+ LENGTH_1WORD
);
1013 if (ctype
== RSVP_ERROR_SPEC_IPV4_CTYPE
) {
1014 tlv
->error_spec_ip
.ipv4_error_node_address
.s_addr
= *uint32_ptr
;
1015 tlv
->error_code
= tlv_body_buf
[LENGTH_2WORDS
+ 1];
1016 tlv
->error_value
= ntohs(
1017 *((uint16_t *)(tlv_body_buf
+ LENGTH_2WORDS
+ 2)));
1018 } else /* RSVP_ERROR_SPEC_IPV6_CTYPE */
1020 decode_ipv6(uint32_ptr
,
1021 &tlv
->error_spec_ip
.ipv6_error_node_address
);
1022 tlv
->error_code
= tlv_body_buf
[LENGTH_5WORDS
+ 1];
1023 tlv
->error_value
= ntohs(
1024 *((uint16_t *)(tlv_body_buf
+ LENGTH_5WORDS
+ 2)));
1027 return (struct pcep_object_tlv_header
*)tlv
;
1030 struct pcep_object_tlv_header
*
1031 pcep_decode_tlv_lsp_db_version(struct pcep_object_tlv_header
*tlv_hdr
,
1032 const uint8_t *tlv_body_buf
)
1034 struct pcep_object_tlv_lsp_db_version
*tlv
=
1035 (struct pcep_object_tlv_lsp_db_version
*)common_tlv_create(
1036 tlv_hdr
, sizeof(struct pcep_object_tlv_lsp_db_version
));
1038 tlv
->lsp_db_version
= be64toh(*((uint64_t *)tlv_body_buf
));
1040 return (struct pcep_object_tlv_header
*)tlv
;
1043 struct pcep_object_tlv_header
*
1044 pcep_decode_tlv_speaker_entity_id(struct pcep_object_tlv_header
*tlv_hdr
,
1045 const uint8_t *tlv_body_buf
)
1047 struct pcep_object_tlv_speaker_entity_identifier
*tlv
=
1048 (struct pcep_object_tlv_speaker_entity_identifier
*)
1052 pcep_object_tlv_speaker_entity_identifier
));
1054 uint8_t num_entity_ids
= tlv_hdr
->encoded_tlv_length
/ LENGTH_1WORD
;
1055 if (num_entity_ids
> MAX_ITERATIONS
) {
1056 num_entity_ids
= MAX_ITERATIONS
;
1059 "%s: Decode Speaker Entity ID, truncating num entities from [%d] to [%d].",
1060 __func__
, num_entity_ids
, MAX_ITERATIONS
);
1063 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
1064 tlv
->speaker_entity_id_list
= dll_initialize();
1066 for (i
= 0; i
< num_entity_ids
; i
++) {
1067 uint32_t *entity_id
=
1068 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint32_t));
1069 *entity_id
= ntohl(uint32_ptr
[i
]);
1070 dll_append(tlv
->speaker_entity_id_list
, entity_id
);
1073 return (struct pcep_object_tlv_header
*)tlv
;
1076 struct pcep_object_tlv_header
*
1077 pcep_decode_tlv_sr_pce_capability(struct pcep_object_tlv_header
*tlv_hdr
,
1078 const uint8_t *tlv_body_buf
)
1080 struct pcep_object_tlv_sr_pce_capability
*tlv
=
1081 (struct pcep_object_tlv_sr_pce_capability
*)common_tlv_create(
1083 sizeof(struct pcep_object_tlv_sr_pce_capability
));
1085 tlv
->flag_n
= (tlv_body_buf
[2] & TLV_SR_PCE_CAP_FLAG_N
);
1086 tlv
->flag_x
= (tlv_body_buf
[2] & TLV_SR_PCE_CAP_FLAG_X
);
1087 tlv
->max_sid_depth
= tlv_body_buf
[3];
1089 return (struct pcep_object_tlv_header
*)tlv
;
1092 struct pcep_object_tlv_header
*
1093 pcep_decode_tlv_path_setup_type(struct pcep_object_tlv_header
*tlv_hdr
,
1094 const uint8_t *tlv_body_buf
)
1096 struct pcep_object_tlv_path_setup_type
*tlv
=
1097 (struct pcep_object_tlv_path_setup_type
*)common_tlv_create(
1099 sizeof(struct pcep_object_tlv_path_setup_type
));
1101 tlv
->path_setup_type
= tlv_body_buf
[3];
1103 return (struct pcep_object_tlv_header
*)tlv
;
1106 struct pcep_object_tlv_header
*pcep_decode_tlv_path_setup_type_capability(
1107 struct pcep_object_tlv_header
*tlv_hdr
, const uint8_t *tlv_body_buf
)
1109 struct pcep_object_tlv_path_setup_type_capability
*tlv
=
1110 (struct pcep_object_tlv_path_setup_type_capability
*)
1114 pcep_object_tlv_path_setup_type_capability
));
1116 uint8_t num_psts
= tlv_body_buf
[3];
1117 if (num_psts
> MAX_ITERATIONS
) {
1120 "%s: Decode Path Setup Type Capability num PSTs [%d] exceeds MAX [%d] continuing anyways",
1121 __func__
, num_psts
, MAX_ITERATIONS
);
1125 tlv
->pst_list
= dll_initialize();
1126 for (i
= 0; i
< num_psts
; i
++) {
1128 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint8_t));
1129 *pst
= tlv_body_buf
[i
+ LENGTH_1WORD
];
1130 dll_append(tlv
->pst_list
, pst
);
1133 if (tlv
->header
.encoded_tlv_length
1134 == (TLV_HEADER_LENGTH
+ LENGTH_1WORD
+ num_psts
)) {
1135 return (struct pcep_object_tlv_header
*)tlv
;
1138 uint8_t num_iterations
= 0;
1139 tlv
->sub_tlv_list
= dll_initialize();
1140 uint16_t buf_index
= normalize_pcep_tlv_length(
1141 TLV_HEADER_LENGTH
+ LENGTH_1WORD
+ num_psts
);
1142 while ((tlv
->header
.encoded_tlv_length
- buf_index
) > TLV_HEADER_LENGTH
1143 && num_iterations
++ < MAX_ITERATIONS
) {
1144 struct pcep_object_tlv_header
*sub_tlv
=
1145 pcep_decode_tlv(tlv_body_buf
+ buf_index
);
1146 if (sub_tlv
== NULL
) {
1149 "%s: Decode PathSetupType Capability sub-TLV decode returned NULL",
1151 return (struct pcep_object_tlv_header
*)tlv
;
1155 normalize_pcep_tlv_length(sub_tlv
->encoded_tlv_length
);
1156 dll_append(tlv
->sub_tlv_list
, sub_tlv
);
1159 return (struct pcep_object_tlv_header
*)tlv
;
1161 struct pcep_object_tlv_header
*
1162 pcep_decode_tlv_pol_id(struct pcep_object_tlv_header
*tlv_hdr
,
1163 const uint8_t *tlv_body_buf
)
1165 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
1166 struct pcep_object_tlv_srpag_pol_id
*ipv4
=
1167 (struct pcep_object_tlv_srpag_pol_id
*)common_tlv_create(
1168 tlv_hdr
, sizeof(struct pcep_object_tlv_srpag_pol_id
));
1169 if (tlv_hdr
->encoded_tlv_length
== 8) {
1170 ipv4
->is_ipv4
= true;
1171 ipv4
->color
= ntohl(uint32_ptr
[0]);
1172 ipv4
->end_point
.ipv4
.s_addr
= uint32_ptr
[1];
1173 return (struct pcep_object_tlv_header
*)ipv4
;
1175 ipv4
->is_ipv4
= false;
1176 struct pcep_object_tlv_srpag_pol_id
*ipv6
= ipv4
;
1177 ipv6
->color
= ntohl(uint32_ptr
[0]);
1178 decode_ipv6(&uint32_ptr
[1], &ipv6
->end_point
.ipv6
);
1179 return (struct pcep_object_tlv_header
*)ipv6
;
1182 struct pcep_object_tlv_header
*
1183 pcep_decode_tlv_pol_name(struct pcep_object_tlv_header
*tlv_hdr
,
1184 const uint8_t *tlv_body_buf
)
1186 struct pcep_object_tlv_srpag_pol_name
*tlv
=
1187 (struct pcep_object_tlv_srpag_pol_name
*)common_tlv_create(
1188 tlv_hdr
, sizeof(struct pcep_object_tlv_srpag_pol_name
));
1190 memcpy(tlv
->name
, tlv_body_buf
, tlv
->header
.encoded_tlv_length
);
1192 return (struct pcep_object_tlv_header
*)tlv
;
1194 struct pcep_object_tlv_header
*
1195 pcep_decode_tlv_cpath_id(struct pcep_object_tlv_header
*tlv_hdr
,
1196 const uint8_t *tlv_body_buf
)
1198 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
1199 struct pcep_object_tlv_srpag_cp_id
*tlv
=
1200 (struct pcep_object_tlv_srpag_cp_id
*)common_tlv_create(
1201 tlv_hdr
, sizeof(struct pcep_object_tlv_srpag_cp_id
));
1203 tlv
->proto
= tlv_body_buf
[0];
1204 tlv
->orig_asn
= ntohl(uint32_ptr
[1]);
1205 decode_ipv6(&uint32_ptr
[2], &tlv
->orig_addres
);
1206 tlv
->discriminator
= ntohl(uint32_ptr
[6]);
1208 return (struct pcep_object_tlv_header
*)tlv
;
1210 struct pcep_object_tlv_header
*
1211 pcep_decode_tlv_cpath_preference(struct pcep_object_tlv_header
*tlv_hdr
,
1212 const uint8_t *tlv_body_buf
)
1214 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
1215 struct pcep_object_tlv_srpag_cp_pref
*tlv
=
1216 (struct pcep_object_tlv_srpag_cp_pref
*)common_tlv_create(
1217 tlv_hdr
, sizeof(struct pcep_object_tlv_srpag_cp_pref
));
1219 tlv
->preference
= ntohl(uint32_ptr
[0]);
1221 return (struct pcep_object_tlv_header
*)tlv
;
1224 struct pcep_object_tlv_header
*
1225 pcep_decode_tlv_vendor_info(struct pcep_object_tlv_header
*tlv_hdr
,
1226 const uint8_t *tlv_body_buf
)
1228 struct pcep_object_tlv_vendor_info
*tlv
=
1229 (struct pcep_object_tlv_vendor_info
*)common_tlv_create(
1230 tlv_hdr
, sizeof(struct pcep_object_tlv_vendor_info
));
1232 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
1233 tlv
->enterprise_number
= ntohl(uint32_ptr
[0]);
1234 tlv
->enterprise_specific_info
= ntohl(uint32_ptr
[1]);
1236 return (struct pcep_object_tlv_header
*)tlv
;
1239 struct pcep_object_tlv_header
*
1240 pcep_decode_tlv_arbitrary(struct pcep_object_tlv_header
*tlv_hdr
,
1241 const uint8_t *tlv_body_buf
)
1243 struct pcep_object_tlv_arbitrary
*tlv_arbitrary
=
1244 (struct pcep_object_tlv_arbitrary
*)common_tlv_create(
1245 tlv_hdr
, sizeof(struct pcep_object_tlv_arbitrary
));
1247 uint16_t length
= tlv_hdr
->encoded_tlv_length
;
1248 if (length
> MAX_ARBITRARY_SIZE
) {
1249 /* TODO should we also reset the tlv_hdr->encoded_tlv_length ?
1251 length
= MAX_ARBITRARY_SIZE
;
1254 "%s: Decoding Arbitrary TLV , truncate path name from [%d] to [%d].\",",
1255 __func__
, tlv_hdr
->encoded_tlv_length
,
1256 MAX_ARBITRARY_SIZE
);
1259 tlv_arbitrary
->data_length
= length
;
1260 tlv_arbitrary
->arbitraty_type
= tlv_hdr
->type
;
1261 tlv_hdr
->type
= PCEP_OBJ_TLV_TYPE_ARBITRARY
;
1262 memcpy(tlv_arbitrary
->data
, tlv_body_buf
, length
);
1264 return (struct pcep_object_tlv_header
*)tlv_arbitrary
;
1267 struct pcep_object_tlv_header
*
1268 pcep_decode_tlv_of_list(struct pcep_object_tlv_header
*tlv_hdr
,
1269 const uint8_t *tlv_body_buf
)
1271 struct pcep_object_tlv_of_list
*of_tlv
=
1272 (struct pcep_object_tlv_of_list
*)common_tlv_create(
1273 tlv_hdr
, sizeof(struct pcep_object_tlv_of_list
));
1275 of_tlv
->of_list
= dll_initialize();
1276 uint16_t *uint16_ptr
= (uint16_t *)tlv_body_buf
;
1278 for (; i
< tlv_hdr
->encoded_tlv_length
&& i
< MAX_ITERATIONS
; i
++) {
1279 uint16_t *of_code_ptr
=
1280 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint16_t));
1281 *of_code_ptr
= ntohs(uint16_ptr
[i
]);
1282 dll_append(of_tlv
->of_list
, of_code_ptr
);
1285 return (struct pcep_object_tlv_header
*)of_tlv
;