]> git.proxmox.com Git - mirror_frr.git/blob - pceplib/pcep_msg_tlvs_encoding.c
Merge pull request #12805 from karlquan/kquan_self_orig
[mirror_frr.git] / pceplib / pcep_msg_tlvs_encoding.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 * Encoding and decoding for PCEP Object TLVs.
14 */
15
16 #ifdef HAVE_CONFIG_H
17 #include "config.h"
18 #endif
19
20 #ifdef __FreeBSD__
21 #include <sys/endian.h>
22 #else
23 #include <endian.h>
24 #endif /* __FreeBSD__ */
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "pcep.h"
29 #include "pcep_msg_encoding.h"
30 #include "pcep_msg_tlvs.h"
31 #include "pcep_utils_logging.h"
32 #include "pcep_utils_memory.h"
33
34 void write_tlv_header(struct pcep_object_tlv_header *tlv_hdr,
35 uint16_t tlv_length, struct pcep_versioning *versioning,
36 uint8_t *buf);
37 void pcep_decode_tlv_hdr(const uint8_t *tlv_buf,
38 struct pcep_object_tlv_header *tlv_hdr);
39
40 /*
41 * forward declarations for initialize_tlv_encoders()
42 */
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);
46 uint16_t
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);
53 uint16_t
54 pcep_encode_tlv_ipv4_lsp_identifiers(struct pcep_object_tlv_header *tlv,
55 struct pcep_versioning *versioning,
56 uint8_t *tlv_body_buf);
57 uint16_t
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);
79 uint16_t
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);
107
108 #define MAX_TLV_ENCODER_INDEX 65533 + 1 // 65
109
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,
142 };
143 /*
144 * forward declarations for initialize_tlv_decoders()
145 */
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);
204
205 // tlv_decoder_funcptr tlv_decoders[MAX_TLV_ENCODER_INDEX];
206
207 #define PCEP_TLV_DECODERS_ARGS \
208 struct pcep_object_tlv_header *tlv_hdr, const uint8_t *tlv_body_buf
209
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,
239 };
240
241 static void initialize_tlv_coders(void)
242 {
243 static bool initialized = false;
244
245 if (initialized == true) {
246 return;
247 }
248
249 initialized = true;
250
251 /* Encoders */
252 /*
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;
291 */
292
293 /* Decoders */
294 /*
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;
333 */
334 }
335
336 uint16_t pcep_encode_tlv(struct pcep_object_tlv_header *tlv_hdr,
337 struct pcep_versioning *versioning, uint8_t *buf)
338 {
339 initialize_tlv_coders();
340
341 if (tlv_hdr->type >= MAX_TLV_ENCODER_INDEX) {
342 pcep_log(LOG_INFO,
343 "%s: Cannot encode unknown Object class [%d]",
344 __func__, tlv_hdr->type);
345 return 0;
346 }
347
348 tlv_encoder_funcptr tlv_encoder = tlv_encoders[tlv_hdr->type];
349 if (tlv_encoder == NULL) {
350 pcep_log(LOG_INFO,
351 "%s: No object encoder found for Object class [%d]",
352 __func__, tlv_hdr->type);
353 return 0;
354 }
355
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.
358 */
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;
364
365 return normalize_pcep_tlv_length(tlv_length + TLV_HEADER_LENGTH);
366 }
367
368 /* TLV Header format
369 *
370 * 0 1 2 3
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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
377 */
378
379 void write_tlv_header(struct pcep_object_tlv_header *tlv_hdr,
380 uint16_t tlv_length, struct pcep_versioning *versioning,
381 uint8_t *buf)
382 {
383 (void)versioning;
384 uint16_t *uint16_ptr = (uint16_t *)buf;
385 uint16_ptr[0] = htons(tlv_hdr->type);
386 uint16_ptr[1] = htons(tlv_length);
387 }
388
389 /*
390 * Functions to encode TLVs
391 */
392
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)
396 {
397 (void)versioning;
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);
402
403 return LENGTH_1WORD;
404 }
405
406 uint16_t
407 pcep_encode_tlv_stateful_pce_capability(struct pcep_object_tlv_header *tlv,
408 struct pcep_versioning *versioning,
409 uint8_t *tlv_body_buf)
410 {
411 (void)versioning;
412 struct pcep_object_tlv_stateful_pce_capability *spc_tlv =
413 (struct pcep_object_tlv_stateful_pce_capability *)tlv;
414 tlv_body_buf[3] =
415 ((spc_tlv->flag_f_triggered_initial_sync == true
416 ? TLV_STATEFUL_PCE_CAP_FLAG_F
417 : 0x00)
418 | (spc_tlv->flag_d_delta_lsp_sync == true
419 ? TLV_STATEFUL_PCE_CAP_FLAG_D
420 : 0x00)
421 | (spc_tlv->flag_t_triggered_resync == true
422 ? TLV_STATEFUL_PCE_CAP_FLAG_T
423 : 0x00)
424 | (spc_tlv->flag_i_lsp_instantiation_capability == true
425 ? TLV_STATEFUL_PCE_CAP_FLAG_I
426 : 0x00)
427 | (spc_tlv->flag_s_include_db_version == true
428 ? TLV_STATEFUL_PCE_CAP_FLAG_S
429 : 0x00)
430 | (spc_tlv->flag_u_lsp_update_capability == true
431 ? TLV_STATEFUL_PCE_CAP_FLAG_U
432 : 0x00));
433
434 return LENGTH_1WORD;
435 }
436
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)
440 {
441 (void)versioning;
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);
446
447 return spn_tlv->symbolic_path_name_length;
448 }
449
450 uint16_t
451 pcep_encode_tlv_ipv4_lsp_identifiers(struct pcep_object_tlv_header *tlv,
452 struct pcep_versioning *versioning,
453 uint8_t *tlv_body_buf)
454 {
455 (void)versioning;
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;
463
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);
467
468 return LENGTH_4WORDS;
469 }
470
471 uint16_t
472 pcep_encode_tlv_ipv6_lsp_identifiers(struct pcep_object_tlv_header *tlv,
473 struct pcep_versioning *versioning,
474 uint8_t *tlv_body_buf)
475 {
476 (void)versioning;
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);
483
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);
487
488 return LENGTH_13WORDS;
489 }
490
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)
494 {
495 (void)versioning;
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);
500
501 return LENGTH_1WORD;
502 }
503
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)
507 {
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); */
511
512 /* RSVP Object Header
513 *
514 * 0 1 2 3
515 * +-------------+-------------+-------------+-------------+
516 * | Length (bytes) | Class-Num | C-Type |
517 * +-------------+-------------+-------------+-------------+
518 * | |
519 * // (Object contents) //
520 * | |
521 * +-------------+-------------+-------------+-------------+
522 *
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 * +-------------+-------------+-------------+-------------+
529 *
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 * +-------------+-------------+-------------+-------------+
536 */
537
538 (void)versioning;
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;
543
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);
548 *uint32_ptr =
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);
554
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,
559 uint32_ptr);
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);
564
565 return LENGTH_6WORDS;
566 }
567
568 return 0;
569 }
570
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)
574 {
575 (void)versioning;
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);
579
580 return LENGTH_2WORDS;
581 }
582
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)
586 {
587 (void)versioning;
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) {
591 return 0;
592 }
593
594 int index = 0;
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));
600 }
601
602 return speaker_id->speaker_entity_id_list->num_entries * LENGTH_1WORD;
603 }
604
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)
608 {
609 (void)versioning;
610 struct pcep_object_tlv_sr_pce_capability *sr_pce_cap =
611 (struct pcep_object_tlv_sr_pce_capability *)tlv;
612 tlv_body_buf[2] =
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;
616
617 return LENGTH_1WORD;
618 }
619
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)
623 {
624 (void)versioning;
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;
628
629 return LENGTH_1WORD;
630 }
631
632 uint16_t
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)
636 {
637 (void)versioning;
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) {
641 return 0;
642 }
643
644 tlv_body_buf[3] = pst_cap->pst_list->num_entries;
645
646 /* Index past the reserved and NumPSTs fields */
647 int index = 4;
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);
651 }
652
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) {
656 return pst_length;
657 }
658
659 /* Any padding used for the PSTs should not be included in the tlv
660 * header length */
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;
671 }
672
673 return sub_tlvs_length + pst_length;
674 }
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)
678 {
679 (void)versioning;
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;
683 if (ipv4->is_ipv4) {
684 uint32_ptr[0] = htonl(ipv4->color);
685 uint32_ptr[1] = ipv4->end_point.ipv4.s_addr;
686 return LENGTH_2WORDS;
687 } else {
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;
693 }
694 }
695
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)
699 {
700 (void)versioning;
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);
704
705 return normalize_pcep_tlv_length(pol_name_tlv->name_length);
706 }
707
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)
711 {
712 (void)versioning;
713 struct pcep_object_tlv_srpag_cp_id *cpath_id_tlv =
714 (struct pcep_object_tlv_srpag_cp_id *)tlv;
715
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);
721
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);
725 }
726
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)
730 {
731 (void)versioning;
732 struct pcep_object_tlv_srpag_cp_pref *cpath_pref_tlv =
733 (struct pcep_object_tlv_srpag_cp_pref *)tlv;
734
735 uint32_t *uint32_ptr = (uint32_t *)tlv_body_buf;
736 uint32_ptr[0] = htonl(cpath_pref_tlv->preference);
737
738 return sizeof(cpath_pref_tlv->preference);
739 }
740
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)
744 {
745 (void)versioning;
746 struct pcep_object_tlv_vendor_info *vendor_info =
747 (struct pcep_object_tlv_vendor_info *)tlv;
748
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);
752
753 return LENGTH_2WORDS;
754 }
755
756 uint16_t pcep_encode_tlv_arbitrary(struct pcep_object_tlv_header *tlv,
757 struct pcep_versioning *versioning,
758 uint8_t *tlv_body_buf)
759 {
760 (void)versioning;
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;
765
766 return tlv_arbitrary->data_length;
767 }
768
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)
772 {
773 (void)versioning;
774 struct pcep_object_tlv_of_list *of_list =
775 (struct pcep_object_tlv_of_list *)tlv;
776
777 if (of_list->of_list == NULL) {
778 return 0;
779 }
780
781 int index = 0;
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) {
786 return 0;
787 }
788
789 uint16_t *uint16_ptr = (uint16_t *)(tlv_body_buf + index);
790 *uint16_ptr = *of_code;
791 index += 2;
792
793 node = node->next_node;
794 }
795
796 return of_list->of_list->num_entries * 2;
797 }
798
799 /*
800 * Decoding functions
801 */
802
803 void pcep_decode_tlv_hdr(const uint8_t *tlv_buf,
804 struct pcep_object_tlv_header *tlv_hdr)
805 {
806 memset(tlv_hdr, 0, sizeof(struct pcep_object_tlv_header));
807
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;
812 }
813
814 struct pcep_object_tlv_header *pcep_decode_tlv(const uint8_t *tlv_buf)
815 {
816 initialize_tlv_coders();
817
818 struct pcep_object_tlv_header tlv_hdr;
819 /* Only initializes and decodes the Object Header: class, type, flags,
820 * and length */
821 pcep_decode_tlv_hdr(tlv_buf, &tlv_hdr);
822
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);
826 return NULL;
827 }
828
829 tlv_decoder_funcptr tlv_decoder = NULL;
830 if (tlv_hdr.type == PCEP_OBJ_TYPE_CISCO_BSID) {
831 pcep_log(LOG_INFO,
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];
835 } else {
836 tlv_decoder = tlv_decoders[tlv_hdr.type];
837 }
838 if (tlv_decoder == NULL) {
839 pcep_log(LOG_INFO, "%s: No TLV decoder found for TLV type [%d]",
840 __func__, tlv_hdr.type);
841 return NULL;
842 }
843
844 return tlv_decoder(&tlv_hdr, tlv_buf + LENGTH_1WORD);
845 }
846
847 static struct pcep_object_tlv_header *
848 common_tlv_create(struct pcep_object_tlv_header *hdr, uint16_t new_tlv_length)
849 {
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));
854
855 return new_tlv;
856 }
857
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)
861 {
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));
865
866 tlv->error_code = ntohl(*((uint32_t *)tlv_body_buf));
867
868 return (struct pcep_object_tlv_header *)tlv;
869 }
870
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)
874 {
875 struct pcep_object_tlv_stateful_pce_capability *tlv =
876 (struct pcep_object_tlv_stateful_pce_capability *)
877 common_tlv_create(
878 tlv_hdr,
879 sizeof(struct
880 pcep_object_tlv_stateful_pce_capability));
881
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);
894
895 return (struct pcep_object_tlv_header *)tlv;
896 }
897
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)
901 {
902 struct pcep_object_tlv_symbolic_path_name *tlv =
903 (struct pcep_object_tlv_symbolic_path_name *)common_tlv_create(
904 tlv_hdr,
905 sizeof(struct pcep_object_tlv_symbolic_path_name));
906
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 ?
910 */
911 length = MAX_SYMBOLIC_PATH_NAME;
912 pcep_log(
913 LOG_INFO,
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);
917 }
918
919 tlv->symbolic_path_name_length = length;
920 memcpy(tlv->symbolic_path_name, tlv_body_buf, length);
921
922 return (struct pcep_object_tlv_header *)tlv;
923 }
924
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)
928 {
929 struct pcep_object_tlv_ipv4_lsp_identifier *tlv =
930 (struct pcep_object_tlv_ipv4_lsp_identifier *)common_tlv_create(
931 tlv_hdr,
932 sizeof(struct pcep_object_tlv_ipv4_lsp_identifier));
933
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];
939
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]);
943
944 return (struct pcep_object_tlv_header *)tlv;
945 }
946
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)
950 {
951 struct pcep_object_tlv_ipv6_lsp_identifier *tlv =
952 (struct pcep_object_tlv_ipv6_lsp_identifier *)common_tlv_create(
953 tlv_hdr,
954 sizeof(struct pcep_object_tlv_ipv6_lsp_identifier));
955
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);
960
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]);
964
965 return (struct pcep_object_tlv_header *)tlv;
966 }
967
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)
971 {
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));
975
976 tlv->lsp_error_code = ntohl(*((uint32_t *)tlv_body_buf));
977
978 return (struct pcep_object_tlv_header *)tlv;
979 }
980
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)
984 {
985 uint8_t class_num = tlv_body_buf[2];
986 uint8_t ctype = tlv_body_buf[3];
987
988 if (class_num != RSVP_ERROR_SPEC_CLASS_NUM) {
989 pcep_log(
990 LOG_INFO,
991 "%s: Decoding RSVP Error Spec TLV, unknown class num [%d]",
992 __func__, class_num);
993 return NULL;
994 }
995
996 if (ctype != RSVP_ERROR_SPEC_IPV4_CTYPE
997 && ctype != RSVP_ERROR_SPEC_IPV6_CTYPE) {
998 pcep_log(LOG_INFO,
999 "%s: Decoding RSVP Error Spec TLV, unknown ctype [%d]",
1000 __func__, ctype);
1001 return NULL;
1002 }
1003
1004 struct pcep_object_tlv_rsvp_error_spec *tlv =
1005 (struct pcep_object_tlv_rsvp_error_spec *)common_tlv_create(
1006 tlv_hdr,
1007 sizeof(struct pcep_object_tlv_rsvp_error_spec));
1008
1009 tlv->class_num = class_num;
1010 tlv->c_type = ctype;
1011
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 */
1019 {
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)));
1025 }
1026
1027 return (struct pcep_object_tlv_header *)tlv;
1028 }
1029
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)
1033 {
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));
1037
1038 tlv->lsp_db_version = be64toh(*((uint64_t *)tlv_body_buf));
1039
1040 return (struct pcep_object_tlv_header *)tlv;
1041 }
1042
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)
1046 {
1047 struct pcep_object_tlv_speaker_entity_identifier *tlv =
1048 (struct pcep_object_tlv_speaker_entity_identifier *)
1049 common_tlv_create(
1050 tlv_hdr,
1051 sizeof(struct
1052 pcep_object_tlv_speaker_entity_identifier));
1053
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;
1057 pcep_log(
1058 LOG_INFO,
1059 "%s: Decode Speaker Entity ID, truncating num entities from [%d] to [%d].",
1060 __func__, num_entity_ids, MAX_ITERATIONS);
1061 }
1062
1063 uint32_t *uint32_ptr = (uint32_t *)tlv_body_buf;
1064 tlv->speaker_entity_id_list = dll_initialize();
1065 int i;
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);
1071 }
1072
1073 return (struct pcep_object_tlv_header *)tlv;
1074 }
1075
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)
1079 {
1080 struct pcep_object_tlv_sr_pce_capability *tlv =
1081 (struct pcep_object_tlv_sr_pce_capability *)common_tlv_create(
1082 tlv_hdr,
1083 sizeof(struct pcep_object_tlv_sr_pce_capability));
1084
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];
1088
1089 return (struct pcep_object_tlv_header *)tlv;
1090 }
1091
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)
1095 {
1096 struct pcep_object_tlv_path_setup_type *tlv =
1097 (struct pcep_object_tlv_path_setup_type *)common_tlv_create(
1098 tlv_hdr,
1099 sizeof(struct pcep_object_tlv_path_setup_type));
1100
1101 tlv->path_setup_type = tlv_body_buf[3];
1102
1103 return (struct pcep_object_tlv_header *)tlv;
1104 }
1105
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)
1108 {
1109 struct pcep_object_tlv_path_setup_type_capability *tlv =
1110 (struct pcep_object_tlv_path_setup_type_capability *)
1111 common_tlv_create(
1112 tlv_hdr,
1113 sizeof(struct
1114 pcep_object_tlv_path_setup_type_capability));
1115
1116 uint8_t num_psts = tlv_body_buf[3];
1117 if (num_psts > MAX_ITERATIONS) {
1118 pcep_log(
1119 LOG_INFO,
1120 "%s: Decode Path Setup Type Capability num PSTs [%d] exceeds MAX [%d] continuing anyways",
1121 __func__, num_psts, MAX_ITERATIONS);
1122 }
1123
1124 int i;
1125 tlv->pst_list = dll_initialize();
1126 for (i = 0; i < num_psts; i++) {
1127 uint8_t *pst =
1128 pceplib_malloc(PCEPLIB_MESSAGES, sizeof(uint8_t));
1129 *pst = tlv_body_buf[i + LENGTH_1WORD];
1130 dll_append(tlv->pst_list, pst);
1131 }
1132
1133 if (tlv->header.encoded_tlv_length
1134 == (TLV_HEADER_LENGTH + LENGTH_1WORD + num_psts)) {
1135 return (struct pcep_object_tlv_header *)tlv;
1136 }
1137
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) {
1147 pcep_log(
1148 LOG_INFO,
1149 "%s: Decode PathSetupType Capability sub-TLV decode returned NULL",
1150 __func__);
1151 return (struct pcep_object_tlv_header *)tlv;
1152 }
1153
1154 buf_index +=
1155 normalize_pcep_tlv_length(sub_tlv->encoded_tlv_length);
1156 dll_append(tlv->sub_tlv_list, sub_tlv);
1157 }
1158
1159 return (struct pcep_object_tlv_header *)tlv;
1160 }
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)
1164 {
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;
1174 } else {
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;
1180 }
1181 }
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)
1185 {
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));
1189
1190 memcpy(tlv->name, tlv_body_buf, tlv->header.encoded_tlv_length);
1191
1192 return (struct pcep_object_tlv_header *)tlv;
1193 }
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)
1197 {
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));
1202
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]);
1207
1208 return (struct pcep_object_tlv_header *)tlv;
1209 }
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)
1213 {
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));
1218
1219 tlv->preference = ntohl(uint32_ptr[0]);
1220
1221 return (struct pcep_object_tlv_header *)tlv;
1222 }
1223
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)
1227 {
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));
1231
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]);
1235
1236 return (struct pcep_object_tlv_header *)tlv;
1237 }
1238
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)
1242 {
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));
1246
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 ?
1250 */
1251 length = MAX_ARBITRARY_SIZE;
1252 pcep_log(
1253 LOG_INFO,
1254 "%s: Decoding Arbitrary TLV , truncate path name from [%d] to [%d].\",",
1255 __func__, tlv_hdr->encoded_tlv_length,
1256 MAX_ARBITRARY_SIZE);
1257 }
1258
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);
1263
1264 return (struct pcep_object_tlv_header *)tlv_arbitrary;
1265 }
1266
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)
1270 {
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));
1274
1275 of_tlv->of_list = dll_initialize();
1276 uint16_t *uint16_ptr = (uint16_t *)tlv_body_buf;
1277 int i = 0;
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);
1283 }
1284
1285 return (struct pcep_object_tlv_header *)of_tlv;
1286 }