]> git.proxmox.com Git - mirror_frr.git/blob - pceplib/pcep_msg_tlvs_encoding.c
Merge pull request #8115 from mjstapp/fix_ax_pthread
[mirror_frr.git] / pceplib / pcep_msg_tlvs_encoding.c
1 /*
2 * This file is part of the PCEPlib, a PCEP protocol library.
3 *
4 * Copyright (C) 2020 Volta Networks https://voltanet.io/
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 *
19 * Author : Brady Johnson <brady@voltanet.io>
20 *
21 */
22
23
24 /*
25 * Encoding and decoding for PCEP Object TLVs.
26 */
27
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include "pcep.h"
32 #include "pcep_msg_encoding.h"
33 #include "pcep_msg_tlvs.h"
34 #include "pcep_utils_logging.h"
35 #include "pcep_utils_memory.h"
36
37 void write_tlv_header(struct pcep_object_tlv_header *tlv_hdr,
38 uint16_t tlv_length, struct pcep_versioning *versioning,
39 uint8_t *buf);
40 void pcep_decode_tlv_hdr(const uint8_t *tlv_buf,
41 struct pcep_object_tlv_header *tlv_hdr);
42
43 /*
44 * forward declarations for initialize_tlv_encoders()
45 */
46 uint16_t pcep_encode_tlv_no_path_vector(struct pcep_object_tlv_header *tlv,
47 struct pcep_versioning *versioning,
48 uint8_t *tlv_body_buf);
49 uint16_t
50 pcep_encode_tlv_stateful_pce_capability(struct pcep_object_tlv_header *tlv,
51 struct pcep_versioning *versioning,
52 uint8_t *tlv_body_buf);
53 uint16_t pcep_encode_tlv_symbolic_path_name(struct pcep_object_tlv_header *tlv,
54 struct pcep_versioning *versioning,
55 uint8_t *tlv_body_buf);
56 uint16_t
57 pcep_encode_tlv_ipv4_lsp_identifiers(struct pcep_object_tlv_header *tlv,
58 struct pcep_versioning *versioning,
59 uint8_t *tlv_body_buf);
60 uint16_t
61 pcep_encode_tlv_ipv6_lsp_identifiers(struct pcep_object_tlv_header *tlv,
62 struct pcep_versioning *versioning,
63 uint8_t *tlv_body_buf);
64 uint16_t pcep_encode_tlv_lsp_error_code(struct pcep_object_tlv_header *tlv,
65 struct pcep_versioning *versioning,
66 uint8_t *tlv_body_buf);
67 uint16_t pcep_encode_tlv_rsvp_error_spec(struct pcep_object_tlv_header *tlv,
68 struct pcep_versioning *versioning,
69 uint8_t *tlv_body_buf);
70 uint16_t pcep_encode_tlv_lsp_db_version(struct pcep_object_tlv_header *tlv,
71 struct pcep_versioning *versioning,
72 uint8_t *tlv_body_buf);
73 uint16_t pcep_encode_tlv_speaker_entity_id(struct pcep_object_tlv_header *tlv,
74 struct pcep_versioning *versioning,
75 uint8_t *tlv_body_buf);
76 uint16_t pcep_encode_tlv_sr_pce_capability(struct pcep_object_tlv_header *tlv,
77 struct pcep_versioning *versioning,
78 uint8_t *tlv_body_buf);
79 uint16_t pcep_encode_tlv_path_setup_type(struct pcep_object_tlv_header *tlv,
80 struct pcep_versioning *versioning,
81 uint8_t *tlv_body_buf);
82 uint16_t
83 pcep_encode_tlv_path_setup_type_capability(struct pcep_object_tlv_header *tlv,
84 struct pcep_versioning *versioning,
85 uint8_t *tlv_body_buf);
86 uint16_t pcep_encode_tlv_pol_id(struct pcep_object_tlv_header *tlv,
87 struct pcep_versioning *versioning,
88 uint8_t *tlv_body_buf);
89 uint16_t pcep_encode_tlv_pol_name(struct pcep_object_tlv_header *tlv,
90 struct pcep_versioning *versioning,
91 uint8_t *tlv_body_buf);
92 uint16_t pcep_encode_tlv_cpath_id(struct pcep_object_tlv_header *tlv,
93 struct pcep_versioning *versioning,
94 uint8_t *tlv_body_buf);
95 uint16_t pcep_encode_tlv_cpath_preference(struct pcep_object_tlv_header *tlv,
96 struct pcep_versioning *versioning,
97 uint8_t *tlv_body_buf);
98 uint16_t pcep_encode_tlv_vendor_info(struct pcep_object_tlv_header *tlv,
99 struct pcep_versioning *versioning,
100 uint8_t *tlv_body_buf);
101 uint16_t pcep_encode_tlv_arbitrary(struct pcep_object_tlv_header *tlv,
102 struct pcep_versioning *versioning,
103 uint8_t *tlv_body_buf);
104 uint16_t pcep_encode_tlv_of_list(struct pcep_object_tlv_header *tlv,
105 struct pcep_versioning *versioning,
106 uint8_t *tlv_body_buf);
107 typedef uint16_t (*tlv_encoder_funcptr)(struct pcep_object_tlv_header *,
108 struct pcep_versioning *versioning,
109 uint8_t *tlv_body_buf);
110
111 #define MAX_TLV_ENCODER_INDEX 65533 + 1 // 65
112
113 #define PCEP_TLV_ENCODERS_ARGS \
114 struct pcep_object_tlv_header *, struct pcep_versioning *versioning, \
115 uint8_t *tlv_body_buf
116 uint16_t (*const tlv_encoders[MAX_TLV_ENCODER_INDEX])(
117 PCEP_TLV_ENCODERS_ARGS) = {
118 [PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR] = pcep_encode_tlv_no_path_vector,
119 [PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY] =
120 pcep_encode_tlv_stateful_pce_capability,
121 [PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME] =
122 pcep_encode_tlv_symbolic_path_name,
123 [PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS] =
124 pcep_encode_tlv_ipv4_lsp_identifiers,
125 [PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS] =
126 pcep_encode_tlv_ipv6_lsp_identifiers,
127 [PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE] = pcep_encode_tlv_lsp_error_code,
128 [PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC] = pcep_encode_tlv_rsvp_error_spec,
129 [PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION] = pcep_encode_tlv_lsp_db_version,
130 [PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID] =
131 pcep_encode_tlv_speaker_entity_id,
132 [PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY] =
133 pcep_encode_tlv_sr_pce_capability,
134 [PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE] = pcep_encode_tlv_path_setup_type,
135 [PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY] =
136 pcep_encode_tlv_path_setup_type_capability,
137 [PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID] = pcep_encode_tlv_pol_id,
138 [PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME] = pcep_encode_tlv_pol_name,
139 [PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID] = pcep_encode_tlv_cpath_id,
140 [PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE] =
141 pcep_encode_tlv_cpath_preference,
142 [PCEP_OBJ_TLV_TYPE_VENDOR_INFO] = pcep_encode_tlv_vendor_info,
143 [PCEP_OBJ_TLV_TYPE_ARBITRARY] = pcep_encode_tlv_arbitrary,
144 [PCEP_OBJ_TLV_TYPE_OBJECTIVE_FUNCTION_LIST] = pcep_encode_tlv_of_list,
145 };
146 /*
147 * forward declarations for initialize_tlv_decoders()
148 */
149 struct pcep_object_tlv_header *
150 pcep_decode_tlv_no_path_vector(struct pcep_object_tlv_header *tlv_hdr,
151 const uint8_t *tlv_body_buf);
152 struct pcep_object_tlv_header *
153 pcep_decode_tlv_stateful_pce_capability(struct pcep_object_tlv_header *tlv_hdr,
154 const uint8_t *tlv_body_buf);
155 struct pcep_object_tlv_header *
156 pcep_decode_tlv_symbolic_path_name(struct pcep_object_tlv_header *tlv_hdr,
157 const uint8_t *tlv_body_buf);
158 struct pcep_object_tlv_header *
159 pcep_decode_tlv_ipv4_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_ipv6_lsp_identifiers(struct pcep_object_tlv_header *tlv_hdr,
163 const uint8_t *tlv_body_buf);
164 struct pcep_object_tlv_header *
165 pcep_decode_tlv_lsp_error_code(struct pcep_object_tlv_header *tlv_hdr,
166 const uint8_t *tlv_body_buf);
167 struct pcep_object_tlv_header *
168 pcep_decode_tlv_rsvp_error_spec(struct pcep_object_tlv_header *tlv_hdr,
169 const uint8_t *tlv_body_buf);
170 struct pcep_object_tlv_header *
171 pcep_decode_tlv_lsp_db_version(struct pcep_object_tlv_header *tlv_hdr,
172 const uint8_t *tlv_body_buf);
173 struct pcep_object_tlv_header *
174 pcep_decode_tlv_speaker_entity_id(struct pcep_object_tlv_header *tlv_hdr,
175 const uint8_t *tlv_body_buf);
176 struct pcep_object_tlv_header *
177 pcep_decode_tlv_sr_pce_capability(struct pcep_object_tlv_header *tlv_hdr,
178 const uint8_t *tlv_body_buf);
179 struct pcep_object_tlv_header *
180 pcep_decode_tlv_path_setup_type(struct pcep_object_tlv_header *tlv_hdr,
181 const uint8_t *tlv_body_buf);
182 struct pcep_object_tlv_header *pcep_decode_tlv_path_setup_type_capability(
183 struct pcep_object_tlv_header *tlv_hdr, const uint8_t *tlv_body_buf);
184 struct pcep_object_tlv_header *
185 pcep_decode_tlv_pol_id(struct pcep_object_tlv_header *tlv_hdr,
186 const uint8_t *tlv_body_buf);
187 struct pcep_object_tlv_header *
188 pcep_decode_tlv_pol_name(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_id(struct pcep_object_tlv_header *tlv_hdr,
192 const uint8_t *tlv_body_buf);
193 struct pcep_object_tlv_header *
194 pcep_decode_tlv_cpath_preference(struct pcep_object_tlv_header *tlv_hdr,
195 const uint8_t *tlv_body_buf);
196 struct pcep_object_tlv_header *
197 pcep_decode_tlv_vendor_info(struct pcep_object_tlv_header *tlv_hdr,
198 const uint8_t *tlv_body_buf);
199 struct pcep_object_tlv_header *
200 pcep_decode_tlv_arbitrary(struct pcep_object_tlv_header *tlv_hdr,
201 const uint8_t *tlv_body_buf);
202 struct pcep_object_tlv_header *
203 pcep_decode_tlv_of_list(struct pcep_object_tlv_header *tlv_hdr,
204 const uint8_t *tlv_body_buf);
205 typedef struct pcep_object_tlv_header *(*tlv_decoder_funcptr)(
206 struct pcep_object_tlv_header *tlv_hdr, const uint8_t *tlv_body_buf);
207
208 // tlv_decoder_funcptr tlv_decoders[MAX_TLV_ENCODER_INDEX];
209
210 #define PCEP_TLV_DECODERS_ARGS \
211 struct pcep_object_tlv_header *tlv_hdr, const uint8_t *tlv_body_buf
212
213 struct pcep_object_tlv_header *(*const tlv_decoders[MAX_TLV_ENCODER_INDEX])(
214 PCEP_TLV_DECODERS_ARGS) = {
215 [PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR] = pcep_decode_tlv_no_path_vector,
216 [PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY] =
217 pcep_decode_tlv_stateful_pce_capability,
218 [PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME] =
219 pcep_decode_tlv_symbolic_path_name,
220 [PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS] =
221 pcep_decode_tlv_ipv4_lsp_identifiers,
222 [PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS] =
223 pcep_decode_tlv_ipv6_lsp_identifiers,
224 [PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE] = pcep_decode_tlv_lsp_error_code,
225 [PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC] = pcep_decode_tlv_rsvp_error_spec,
226 [PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION] = pcep_decode_tlv_lsp_db_version,
227 [PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID] =
228 pcep_decode_tlv_speaker_entity_id,
229 [PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY] =
230 pcep_decode_tlv_sr_pce_capability,
231 [PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE] = pcep_decode_tlv_path_setup_type,
232 [PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY] =
233 pcep_decode_tlv_path_setup_type_capability,
234 [PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID] = pcep_decode_tlv_pol_id,
235 [PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME] = pcep_decode_tlv_pol_name,
236 [PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID] = pcep_decode_tlv_cpath_id,
237 [PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE] =
238 pcep_decode_tlv_cpath_preference,
239 [PCEP_OBJ_TLV_TYPE_VENDOR_INFO] = pcep_decode_tlv_vendor_info,
240 [PCEP_OBJ_TLV_TYPE_ARBITRARY] = pcep_decode_tlv_arbitrary,
241 [PCEP_OBJ_TLV_TYPE_OBJECTIVE_FUNCTION_LIST] = pcep_decode_tlv_of_list,
242 };
243
244 static void initialize_tlv_coders()
245 {
246 static bool initialized = false;
247
248 if (initialized == true) {
249 return;
250 }
251
252 initialized = true;
253
254 /* Encoders */
255 /*
256 memset(tlv_encoders, 0, sizeof(tlv_encoder_funcptr) *
257 MAX_TLV_ENCODER_INDEX); tlv_encoders[PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR] =
258 pcep_encode_tlv_no_path_vector;
259 tlv_encoders[PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY] =
260 pcep_encode_tlv_stateful_pce_capability;
261 tlv_encoders[PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME] =
262 pcep_encode_tlv_symbolic_path_name;
263 tlv_encoders[PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS] =
264 pcep_encode_tlv_ipv4_lsp_identifiers;
265 tlv_encoders[PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS] =
266 pcep_encode_tlv_ipv6_lsp_identifiers;
267 tlv_encoders[PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE] =
268 pcep_encode_tlv_lsp_error_code;
269 tlv_encoders[PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC] =
270 pcep_encode_tlv_rsvp_error_spec;
271 tlv_encoders[PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION] =
272 pcep_encode_tlv_lsp_db_version;
273 tlv_encoders[PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID] =
274 pcep_encode_tlv_speaker_entity_id;
275 tlv_encoders[PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY] =
276 pcep_encode_tlv_sr_pce_capability;
277 tlv_encoders[PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE] =
278 pcep_encode_tlv_path_setup_type;
279 tlv_encoders[PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY] =
280 pcep_encode_tlv_path_setup_type_capability;
281 tlv_encoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID] =
282 pcep_encode_tlv_pol_id;
283 tlv_encoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME] =
284 pcep_encode_tlv_pol_name;
285 tlv_encoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID] =
286 pcep_encode_tlv_cpath_id;
287 tlv_encoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE] =
288 pcep_encode_tlv_cpath_preference;
289 tlv_encoders[PCEP_OBJ_TLV_TYPE_VENDOR_INFO] =
290 pcep_encode_tlv_vendor_info; tlv_encoders[PCEP_OBJ_TLV_TYPE_ARBITRARY] =
291 pcep_encode_tlv_arbitrary;
292 tlv_encoders[PCEP_OBJ_TLV_TYPE_OBJECTIVE_FUNCTION_LIST] =
293 pcep_encode_tlv_of_list;
294 */
295
296 /* Decoders */
297 /*
298 memset(tlv_decoders, 0, sizeof(tlv_decoder_funcptr) *
299 MAX_TLV_ENCODER_INDEX); tlv_decoders[PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR] =
300 pcep_decode_tlv_no_path_vector;
301 tlv_decoders[PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY] =
302 pcep_decode_tlv_stateful_pce_capability;
303 tlv_decoders[PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME] =
304 pcep_decode_tlv_symbolic_path_name;
305 tlv_decoders[PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS] =
306 pcep_decode_tlv_ipv4_lsp_identifiers;
307 tlv_decoders[PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS] =
308 pcep_decode_tlv_ipv6_lsp_identifiers;
309 tlv_decoders[PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE] =
310 pcep_decode_tlv_lsp_error_code;
311 tlv_decoders[PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC] =
312 pcep_decode_tlv_rsvp_error_spec;
313 tlv_decoders[PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION] =
314 pcep_decode_tlv_lsp_db_version;
315 tlv_decoders[PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID] =
316 pcep_decode_tlv_speaker_entity_id;
317 tlv_decoders[PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY] =
318 pcep_decode_tlv_sr_pce_capability;
319 tlv_decoders[PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE] =
320 pcep_decode_tlv_path_setup_type;
321 tlv_decoders[PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY] =
322 pcep_decode_tlv_path_setup_type_capability;
323 tlv_decoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID] =
324 pcep_decode_tlv_pol_id;
325 tlv_decoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME] =
326 pcep_decode_tlv_pol_name;
327 tlv_decoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID] =
328 pcep_decode_tlv_cpath_id;
329 tlv_decoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE] =
330 pcep_decode_tlv_cpath_preference;
331 tlv_decoders[PCEP_OBJ_TLV_TYPE_VENDOR_INFO] =
332 pcep_decode_tlv_vendor_info; tlv_decoders[PCEP_OBJ_TLV_TYPE_ARBITRARY] =
333 pcep_decode_tlv_arbitrary;
334 tlv_decoders[PCEP_OBJ_TLV_TYPE_OBJECTIVE_FUNCTION_LIST] =
335 pcep_decode_tlv_of_list;
336 */
337 }
338
339 uint16_t pcep_encode_tlv(struct pcep_object_tlv_header *tlv_hdr,
340 struct pcep_versioning *versioning, uint8_t *buf)
341 {
342 initialize_tlv_coders();
343
344 if (tlv_hdr->type >= MAX_TLV_ENCODER_INDEX) {
345 pcep_log(LOG_INFO,
346 "%s: Cannot encode unknown Object class [%d]",
347 __func__, tlv_hdr->type);
348 return 0;
349 }
350
351 tlv_encoder_funcptr tlv_encoder = tlv_encoders[tlv_hdr->type];
352 if (tlv_encoder == NULL) {
353 pcep_log(LOG_INFO,
354 "%s: No object encoder found for Object class [%d]",
355 __func__, tlv_hdr->type);
356 return 0;
357 }
358
359 /* Notice: The length in the TLV header does not include the TLV header,
360 * so the length returned from the tlv_encoder() is only the TLV body.
361 */
362 uint16_t tlv_length =
363 tlv_encoder(tlv_hdr, versioning, buf + TLV_HEADER_LENGTH);
364 write_tlv_header(tlv_hdr, tlv_length, versioning, buf);
365 tlv_hdr->encoded_tlv = buf;
366 tlv_hdr->encoded_tlv_length = tlv_length;
367
368 return normalize_pcep_tlv_length(tlv_length + TLV_HEADER_LENGTH);
369 }
370
371 /* TLV Header format
372 *
373 * 0 1 2 3
374 * 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
375 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
376 * | Type (2 bytes) | Length (2 bytes) |
377 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
378 * | Value (Variable) |
379 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
380 */
381
382 void write_tlv_header(struct pcep_object_tlv_header *tlv_hdr,
383 uint16_t tlv_length, struct pcep_versioning *versioning,
384 uint8_t *buf)
385 {
386 (void)versioning;
387 uint16_t *uint16_ptr = (uint16_t *)buf;
388 uint16_ptr[0] = htons(tlv_hdr->type);
389 uint16_ptr[1] = htons(tlv_length);
390 }
391
392 /*
393 * Functions to encode TLVs
394 */
395
396 uint16_t pcep_encode_tlv_no_path_vector(struct pcep_object_tlv_header *tlv,
397 struct pcep_versioning *versioning,
398 uint8_t *tlv_body_buf)
399 {
400 (void)versioning;
401 struct pcep_object_tlv_nopath_vector *nopath_tlv =
402 (struct pcep_object_tlv_nopath_vector *)tlv;
403 uint32_t *uint32_ptr = (uint32_t *)tlv_body_buf;
404 *uint32_ptr = htonl(nopath_tlv->error_code);
405
406 return LENGTH_1WORD;
407 }
408
409 uint16_t
410 pcep_encode_tlv_stateful_pce_capability(struct pcep_object_tlv_header *tlv,
411 struct pcep_versioning *versioning,
412 uint8_t *tlv_body_buf)
413 {
414 (void)versioning;
415 struct pcep_object_tlv_stateful_pce_capability *spc_tlv =
416 (struct pcep_object_tlv_stateful_pce_capability *)tlv;
417 tlv_body_buf[3] =
418 ((spc_tlv->flag_f_triggered_initial_sync == true
419 ? TLV_STATEFUL_PCE_CAP_FLAG_F
420 : 0x00)
421 | (spc_tlv->flag_d_delta_lsp_sync == true
422 ? TLV_STATEFUL_PCE_CAP_FLAG_D
423 : 0x00)
424 | (spc_tlv->flag_t_triggered_resync == true
425 ? TLV_STATEFUL_PCE_CAP_FLAG_T
426 : 0x00)
427 | (spc_tlv->flag_i_lsp_instantiation_capability == true
428 ? TLV_STATEFUL_PCE_CAP_FLAG_I
429 : 0x00)
430 | (spc_tlv->flag_s_include_db_version == true
431 ? TLV_STATEFUL_PCE_CAP_FLAG_S
432 : 0x00)
433 | (spc_tlv->flag_u_lsp_update_capability == true
434 ? TLV_STATEFUL_PCE_CAP_FLAG_U
435 : 0x00));
436
437 return LENGTH_1WORD;
438 }
439
440 uint16_t pcep_encode_tlv_symbolic_path_name(struct pcep_object_tlv_header *tlv,
441 struct pcep_versioning *versioning,
442 uint8_t *tlv_body_buf)
443 {
444 (void)versioning;
445 struct pcep_object_tlv_symbolic_path_name *spn_tlv =
446 (struct pcep_object_tlv_symbolic_path_name *)tlv;
447 memcpy(tlv_body_buf, spn_tlv->symbolic_path_name,
448 spn_tlv->symbolic_path_name_length);
449
450 return spn_tlv->symbolic_path_name_length;
451 }
452
453 uint16_t
454 pcep_encode_tlv_ipv4_lsp_identifiers(struct pcep_object_tlv_header *tlv,
455 struct pcep_versioning *versioning,
456 uint8_t *tlv_body_buf)
457 {
458 (void)versioning;
459 struct pcep_object_tlv_ipv4_lsp_identifier *ipv4_lsp =
460 (struct pcep_object_tlv_ipv4_lsp_identifier *)tlv;
461 uint32_t *uint32_ptr = (uint32_t *)tlv_body_buf;
462 uint32_ptr[0] = ipv4_lsp->ipv4_tunnel_sender.s_addr;
463 /* uint32_t[1] is lsp_id and tunnel_id, below */
464 uint32_ptr[2] = ipv4_lsp->extended_tunnel_id.s_addr;
465 uint32_ptr[3] = ipv4_lsp->ipv4_tunnel_endpoint.s_addr;
466
467 uint16_t *uint16_ptr = (uint16_t *)(tlv_body_buf + LENGTH_1WORD);
468 uint16_ptr[0] = htons(ipv4_lsp->lsp_id);
469 uint16_ptr[1] = htons(ipv4_lsp->tunnel_id);
470
471 return LENGTH_4WORDS;
472 }
473
474 uint16_t
475 pcep_encode_tlv_ipv6_lsp_identifiers(struct pcep_object_tlv_header *tlv,
476 struct pcep_versioning *versioning,
477 uint8_t *tlv_body_buf)
478 {
479 (void)versioning;
480 struct pcep_object_tlv_ipv6_lsp_identifier *ipv6_lsp =
481 (struct pcep_object_tlv_ipv6_lsp_identifier *)tlv;
482 uint32_t *uint32_ptr = (uint32_t *)tlv_body_buf;
483 encode_ipv6(&ipv6_lsp->ipv6_tunnel_sender, uint32_ptr);
484 encode_ipv6(&ipv6_lsp->extended_tunnel_id, uint32_ptr + 5);
485 encode_ipv6(&ipv6_lsp->ipv6_tunnel_endpoint, uint32_ptr + 9);
486
487 uint16_t *uint16_ptr = (uint16_t *)(tlv_body_buf + LENGTH_4WORDS);
488 uint16_ptr[0] = htons(ipv6_lsp->lsp_id);
489 uint16_ptr[1] = htons(ipv6_lsp->tunnel_id);
490
491 return LENGTH_13WORDS;
492 }
493
494 uint16_t pcep_encode_tlv_lsp_error_code(struct pcep_object_tlv_header *tlv,
495 struct pcep_versioning *versioning,
496 uint8_t *tlv_body_buf)
497 {
498 (void)versioning;
499 struct pcep_object_tlv_lsp_error_code *lsp_error_tlv =
500 (struct pcep_object_tlv_lsp_error_code *)tlv;
501 uint32_t *uint32_ptr = (uint32_t *)tlv_body_buf;
502 *uint32_ptr = htonl(lsp_error_tlv->lsp_error_code);
503
504 return LENGTH_1WORD;
505 }
506
507 uint16_t pcep_encode_tlv_rsvp_error_spec(struct pcep_object_tlv_header *tlv,
508 struct pcep_versioning *versioning,
509 uint8_t *tlv_body_buf)
510 {
511 /* Same decode tlv function for both types:
512 pcep_create_tlv_rsvp_ipv4_error_spec(tlv);
513 pcep_create_tlv_rsvp_ipv6_error_spec(tlv); */
514
515 /* RSVP Object Header
516 *
517 * 0 1 2 3
518 * +-------------+-------------+-------------+-------------+
519 * | Length (bytes) | Class-Num | C-Type |
520 * +-------------+-------------+-------------+-------------+
521 * | |
522 * // (Object contents) //
523 * | |
524 * +-------------+-------------+-------------+-------------+
525 *
526 * IPv4 ERROR_SPEC object: Class = 6, C-Type = 1
527 * +-------------+-------------+-------------+-------------+
528 * | IPv4 Error Node Address (4 bytes) |
529 * +-------------+-------------+-------------+-------------+
530 * | Flags | Error Code | Error Value |
531 * +-------------+-------------+-------------+-------------+
532 *
533 * IPv6 ERROR_SPEC object: Class = 6, C-Type = 2
534 * +-------------+-------------+-------------+-------------+
535 * | IPv6 Error Node Address (16 bytes) |
536 * +-------------+-------------+-------------+-------------+
537 * | Flags | Error Code | Error Value |
538 * +-------------+-------------+-------------+-------------+
539 */
540
541 (void)versioning;
542 struct pcep_object_tlv_rsvp_error_spec *rsvp_hdr =
543 (struct pcep_object_tlv_rsvp_error_spec *)tlv;
544 tlv_body_buf[2] = rsvp_hdr->class_num;
545 tlv_body_buf[3] = rsvp_hdr->c_type;
546
547 uint16_t *length_ptr = (uint16_t *)tlv_body_buf;
548 uint32_t *uint32_ptr = (uint32_t *)(tlv_body_buf + LENGTH_1WORD);
549 if (rsvp_hdr->c_type == RSVP_ERROR_SPEC_IPV4_CTYPE) {
550 *length_ptr = htons(LENGTH_3WORDS);
551 *uint32_ptr =
552 rsvp_hdr->error_spec_ip.ipv4_error_node_address.s_addr;
553 tlv_body_buf[LENGTH_2WORDS + 1] = rsvp_hdr->error_code;
554 uint16_t *uint16_ptr =
555 (uint16_t *)(tlv_body_buf + LENGTH_2WORDS + 2);
556 *uint16_ptr = htons(rsvp_hdr->error_value);
557
558 return LENGTH_3WORDS;
559 } else if (rsvp_hdr->c_type == RSVP_ERROR_SPEC_IPV6_CTYPE) {
560 *length_ptr = htons(LENGTH_6WORDS);
561 encode_ipv6(&rsvp_hdr->error_spec_ip.ipv6_error_node_address,
562 uint32_ptr);
563 tlv_body_buf[LENGTH_5WORDS + 1] = rsvp_hdr->error_code;
564 uint16_t *uint16_ptr =
565 (uint16_t *)(tlv_body_buf + LENGTH_5WORDS + 2);
566 *uint16_ptr = htons(rsvp_hdr->error_value);
567
568 return LENGTH_6WORDS;
569 }
570
571 return 0;
572 }
573
574 uint16_t pcep_encode_tlv_lsp_db_version(struct pcep_object_tlv_header *tlv,
575 struct pcep_versioning *versioning,
576 uint8_t *tlv_body_buf)
577 {
578 (void)versioning;
579 struct pcep_object_tlv_lsp_db_version *lsp_db_ver =
580 (struct pcep_object_tlv_lsp_db_version *)tlv;
581 *((uint64_t *)tlv_body_buf) = htobe64(lsp_db_ver->lsp_db_version);
582
583 return LENGTH_2WORDS;
584 }
585
586 uint16_t pcep_encode_tlv_speaker_entity_id(struct pcep_object_tlv_header *tlv,
587 struct pcep_versioning *versioning,
588 uint8_t *tlv_body_buf)
589 {
590 (void)versioning;
591 struct pcep_object_tlv_speaker_entity_identifier *speaker_id =
592 (struct pcep_object_tlv_speaker_entity_identifier *)tlv;
593 if (speaker_id->speaker_entity_id_list == NULL) {
594 return 0;
595 }
596
597 int index = 0;
598 uint32_t *uint32_ptr = (uint32_t *)tlv_body_buf;
599 double_linked_list_node *node =
600 speaker_id->speaker_entity_id_list->head;
601 for (; node != NULL; node = node->next_node) {
602 uint32_ptr[index++] = htonl(*((uint32_t *)node->data));
603 }
604
605 return speaker_id->speaker_entity_id_list->num_entries * LENGTH_1WORD;
606 }
607
608 uint16_t pcep_encode_tlv_sr_pce_capability(struct pcep_object_tlv_header *tlv,
609 struct pcep_versioning *versioning,
610 uint8_t *tlv_body_buf)
611 {
612 (void)versioning;
613 struct pcep_object_tlv_sr_pce_capability *sr_pce_cap =
614 (struct pcep_object_tlv_sr_pce_capability *)tlv;
615 tlv_body_buf[2] =
616 ((sr_pce_cap->flag_n == true ? TLV_SR_PCE_CAP_FLAG_N : 0x00)
617 | (sr_pce_cap->flag_x == true ? TLV_SR_PCE_CAP_FLAG_X : 0x00));
618 tlv_body_buf[3] = sr_pce_cap->max_sid_depth;
619
620 return LENGTH_1WORD;
621 }
622
623 uint16_t pcep_encode_tlv_path_setup_type(struct pcep_object_tlv_header *tlv,
624 struct pcep_versioning *versioning,
625 uint8_t *tlv_body_buf)
626 {
627 (void)versioning;
628 struct pcep_object_tlv_path_setup_type *pst =
629 (struct pcep_object_tlv_path_setup_type *)tlv;
630 tlv_body_buf[3] = pst->path_setup_type;
631
632 return LENGTH_1WORD;
633 }
634
635 uint16_t
636 pcep_encode_tlv_path_setup_type_capability(struct pcep_object_tlv_header *tlv,
637 struct pcep_versioning *versioning,
638 uint8_t *tlv_body_buf)
639 {
640 (void)versioning;
641 struct pcep_object_tlv_path_setup_type_capability *pst_cap =
642 (struct pcep_object_tlv_path_setup_type_capability *)tlv;
643 if (pst_cap->pst_list == NULL) {
644 return 0;
645 }
646
647 tlv_body_buf[3] = pst_cap->pst_list->num_entries;
648
649 /* Index past the reserved and NumPSTs fields */
650 int index = 4;
651 double_linked_list_node *node = pst_cap->pst_list->head;
652 for (; node != NULL; node = node->next_node) {
653 tlv_body_buf[index++] = *((uint8_t *)node->data);
654 }
655
656 uint16_t pst_length = normalize_pcep_tlv_length(
657 LENGTH_1WORD + pst_cap->pst_list->num_entries);
658 if (pst_cap->sub_tlv_list == NULL) {
659 return pst_length;
660 }
661
662 /* Any padding used for the PSTs should not be included in the tlv
663 * header length */
664 index = normalize_pcep_tlv_length(index);
665 uint16_t sub_tlvs_length = 0;
666 node = pst_cap->sub_tlv_list->head;
667 for (; node != NULL; node = node->next_node) {
668 struct pcep_object_tlv_header *sub_tlv =
669 (struct pcep_object_tlv_header *)node->data;
670 uint16_t sub_tlv_length = pcep_encode_tlv(sub_tlv, versioning,
671 tlv_body_buf + index);
672 index += sub_tlv_length;
673 sub_tlvs_length += sub_tlv_length;
674 }
675
676 return sub_tlvs_length + pst_length;
677 }
678 uint16_t pcep_encode_tlv_pol_id(struct pcep_object_tlv_header *tlv,
679 struct pcep_versioning *versioning,
680 uint8_t *tlv_body_buf)
681 {
682 (void)versioning;
683 uint32_t *uint32_ptr = (uint32_t *)tlv_body_buf;
684 struct pcep_object_tlv_srpag_pol_id *ipv4 =
685 (struct pcep_object_tlv_srpag_pol_id *)tlv;
686 if (ipv4->is_ipv4) {
687 uint32_ptr[0] = htonl(ipv4->color);
688 uint32_ptr[1] = ipv4->end_point.ipv4.s_addr;
689 return LENGTH_2WORDS;
690 } else {
691 struct pcep_object_tlv_srpag_pol_id *ipv6 =
692 (struct pcep_object_tlv_srpag_pol_id *)tlv;
693 uint32_ptr[0] = htonl(ipv6->color);
694 encode_ipv6(&ipv6->end_point.ipv6, &uint32_ptr[1]);
695 return LENGTH_5WORDS;
696 }
697 }
698
699 uint16_t pcep_encode_tlv_pol_name(struct pcep_object_tlv_header *tlv,
700 struct pcep_versioning *versioning,
701 uint8_t *tlv_body_buf)
702 {
703 (void)versioning;
704 struct pcep_object_tlv_srpag_pol_name *pol_name_tlv =
705 (struct pcep_object_tlv_srpag_pol_name *)tlv;
706 memcpy(tlv_body_buf, pol_name_tlv->name, pol_name_tlv->name_length);
707
708 return normalize_pcep_tlv_length(pol_name_tlv->name_length);
709 }
710
711 uint16_t pcep_encode_tlv_cpath_id(struct pcep_object_tlv_header *tlv,
712 struct pcep_versioning *versioning,
713 uint8_t *tlv_body_buf)
714 {
715 (void)versioning;
716 struct pcep_object_tlv_srpag_cp_id *cpath_id_tlv =
717 (struct pcep_object_tlv_srpag_cp_id *)tlv;
718
719 uint32_t *uint32_ptr = (uint32_t *)tlv_body_buf;
720 tlv_body_buf[0] = cpath_id_tlv->proto;
721 uint32_ptr[1] = htonl(cpath_id_tlv->orig_asn);
722 encode_ipv6(&cpath_id_tlv->orig_addres, &uint32_ptr[2]);
723 uint32_ptr[6] = htonl(cpath_id_tlv->discriminator);
724
725 return sizeof(cpath_id_tlv->proto) + sizeof(cpath_id_tlv->orig_asn)
726 + sizeof(cpath_id_tlv->orig_addres)
727 + sizeof(cpath_id_tlv->discriminator);
728 }
729
730 uint16_t pcep_encode_tlv_cpath_preference(struct pcep_object_tlv_header *tlv,
731 struct pcep_versioning *versioning,
732 uint8_t *tlv_body_buf)
733 {
734 (void)versioning;
735 struct pcep_object_tlv_srpag_cp_pref *cpath_pref_tlv =
736 (struct pcep_object_tlv_srpag_cp_pref *)tlv;
737
738 uint32_t *uint32_ptr = (uint32_t *)tlv_body_buf;
739 uint32_ptr[0] = htonl(cpath_pref_tlv->preference);
740
741 return sizeof(cpath_pref_tlv->preference);
742 }
743
744 uint16_t pcep_encode_tlv_vendor_info(struct pcep_object_tlv_header *tlv,
745 struct pcep_versioning *versioning,
746 uint8_t *tlv_body_buf)
747 {
748 (void)versioning;
749 struct pcep_object_tlv_vendor_info *vendor_info =
750 (struct pcep_object_tlv_vendor_info *)tlv;
751
752 uint32_t *uint32_ptr = (uint32_t *)tlv_body_buf;
753 uint32_ptr[0] = htonl(vendor_info->enterprise_number);
754 uint32_ptr[1] = htonl(vendor_info->enterprise_specific_info);
755
756 return LENGTH_2WORDS;
757 }
758
759 uint16_t pcep_encode_tlv_arbitrary(struct pcep_object_tlv_header *tlv,
760 struct pcep_versioning *versioning,
761 uint8_t *tlv_body_buf)
762 {
763 (void)versioning;
764 struct pcep_object_tlv_arbitrary *tlv_arbitrary =
765 (struct pcep_object_tlv_arbitrary *)tlv;
766 memcpy(tlv_body_buf, tlv_arbitrary->data, tlv_arbitrary->data_length);
767 tlv->type = tlv_arbitrary->arbitraty_type;
768
769 return tlv_arbitrary->data_length;
770 }
771
772 uint16_t pcep_encode_tlv_of_list(struct pcep_object_tlv_header *tlv,
773 struct pcep_versioning *versioning,
774 uint8_t *tlv_body_buf)
775 {
776 (void)versioning;
777 struct pcep_object_tlv_of_list *of_list =
778 (struct pcep_object_tlv_of_list *)tlv;
779
780 if (of_list->of_list == NULL) {
781 return 0;
782 }
783
784 int index = 0;
785 double_linked_list_node *node = of_list->of_list->head;
786 while (node != NULL) {
787 uint16_t *of_code = (uint16_t *)node->data;
788 if (of_code == NULL) {
789 return 0;
790 }
791
792 uint16_t *uint16_ptr = (uint16_t *)(tlv_body_buf + index);
793 *uint16_ptr = *of_code;
794 index += 2;
795
796 node = node->next_node;
797 }
798
799 return of_list->of_list->num_entries * 2;
800 }
801
802 /*
803 * Decoding functions
804 */
805
806 void pcep_decode_tlv_hdr(const uint8_t *tlv_buf,
807 struct pcep_object_tlv_header *tlv_hdr)
808 {
809 memset(tlv_hdr, 0, sizeof(struct pcep_object_tlv_header));
810
811 uint16_t *uint16_ptr = (uint16_t *)tlv_buf;
812 tlv_hdr->type = ntohs(uint16_ptr[0]);
813 tlv_hdr->encoded_tlv_length = ntohs(uint16_ptr[1]);
814 tlv_hdr->encoded_tlv = tlv_buf;
815 }
816
817 struct pcep_object_tlv_header *pcep_decode_tlv(const uint8_t *tlv_buf)
818 {
819 initialize_tlv_coders();
820
821 struct pcep_object_tlv_header tlv_hdr;
822 /* Only initializes and decodes the Object Header: class, type, flags,
823 * and length */
824 pcep_decode_tlv_hdr(tlv_buf, &tlv_hdr);
825
826 if (tlv_hdr.type >= MAX_TLV_ENCODER_INDEX) {
827 pcep_log(LOG_INFO, "%s: Cannot decode unknown TLV type [%d]",
828 __func__, tlv_hdr.type);
829 return NULL;
830 }
831
832 tlv_decoder_funcptr tlv_decoder = tlv_decoders[tlv_hdr.type];
833 if (tlv_decoder == NULL) {
834 pcep_log(LOG_INFO, "%s: No TLV decoder found for TLV type [%d]",
835 __func__, tlv_hdr.type);
836 return NULL;
837 }
838
839 return tlv_decoder(&tlv_hdr, tlv_buf + LENGTH_1WORD);
840 }
841
842 static struct pcep_object_tlv_header *
843 common_tlv_create(struct pcep_object_tlv_header *hdr, uint16_t new_tlv_length)
844 {
845 struct pcep_object_tlv_header *new_tlv =
846 pceplib_malloc(PCEPLIB_MESSAGES, new_tlv_length);
847 memset(new_tlv, 0, new_tlv_length);
848 memcpy(new_tlv, hdr, sizeof(struct pcep_object_tlv_header));
849
850 return new_tlv;
851 }
852
853 struct pcep_object_tlv_header *
854 pcep_decode_tlv_no_path_vector(struct pcep_object_tlv_header *tlv_hdr,
855 const uint8_t *tlv_body_buf)
856 {
857 struct pcep_object_tlv_nopath_vector *tlv =
858 (struct pcep_object_tlv_nopath_vector *)common_tlv_create(
859 tlv_hdr, sizeof(struct pcep_object_tlv_nopath_vector));
860
861 tlv->error_code = ntohl(*((uint32_t *)tlv_body_buf));
862
863 return (struct pcep_object_tlv_header *)tlv;
864 }
865
866 struct pcep_object_tlv_header *
867 pcep_decode_tlv_stateful_pce_capability(struct pcep_object_tlv_header *tlv_hdr,
868 const uint8_t *tlv_body_buf)
869 {
870 struct pcep_object_tlv_stateful_pce_capability *tlv =
871 (struct pcep_object_tlv_stateful_pce_capability *)
872 common_tlv_create(
873 tlv_hdr,
874 sizeof(struct
875 pcep_object_tlv_stateful_pce_capability));
876
877 tlv->flag_f_triggered_initial_sync =
878 (tlv_body_buf[3] & TLV_STATEFUL_PCE_CAP_FLAG_F);
879 tlv->flag_d_delta_lsp_sync =
880 (tlv_body_buf[3] & TLV_STATEFUL_PCE_CAP_FLAG_D);
881 tlv->flag_t_triggered_resync =
882 (tlv_body_buf[3] & TLV_STATEFUL_PCE_CAP_FLAG_T);
883 tlv->flag_i_lsp_instantiation_capability =
884 (tlv_body_buf[3] & TLV_STATEFUL_PCE_CAP_FLAG_I);
885 tlv->flag_s_include_db_version =
886 (tlv_body_buf[3] & TLV_STATEFUL_PCE_CAP_FLAG_S);
887 tlv->flag_u_lsp_update_capability =
888 (tlv_body_buf[3] & TLV_STATEFUL_PCE_CAP_FLAG_U);
889
890 return (struct pcep_object_tlv_header *)tlv;
891 }
892
893 struct pcep_object_tlv_header *
894 pcep_decode_tlv_symbolic_path_name(struct pcep_object_tlv_header *tlv_hdr,
895 const uint8_t *tlv_body_buf)
896 {
897 struct pcep_object_tlv_symbolic_path_name *tlv =
898 (struct pcep_object_tlv_symbolic_path_name *)common_tlv_create(
899 tlv_hdr,
900 sizeof(struct pcep_object_tlv_symbolic_path_name));
901
902 uint16_t length = tlv_hdr->encoded_tlv_length;
903 if (length > MAX_SYMBOLIC_PATH_NAME) {
904 /* TODO should we also reset the tlv_hdr->encoded_tlv_length ?
905 */
906 length = MAX_SYMBOLIC_PATH_NAME;
907 pcep_log(
908 LOG_INFO,
909 "%s: Decoding Symbolic Path Name TLV, truncate path name from [%d] to [%d].\",",
910 __func__, tlv_hdr->encoded_tlv_length,
911 MAX_SYMBOLIC_PATH_NAME);
912 }
913
914 tlv->symbolic_path_name_length = length;
915 memcpy(tlv->symbolic_path_name, tlv_body_buf, length);
916
917 return (struct pcep_object_tlv_header *)tlv;
918 }
919
920 struct pcep_object_tlv_header *
921 pcep_decode_tlv_ipv4_lsp_identifiers(struct pcep_object_tlv_header *tlv_hdr,
922 const uint8_t *tlv_body_buf)
923 {
924 struct pcep_object_tlv_ipv4_lsp_identifier *tlv =
925 (struct pcep_object_tlv_ipv4_lsp_identifier *)common_tlv_create(
926 tlv_hdr,
927 sizeof(struct pcep_object_tlv_ipv4_lsp_identifier));
928
929 uint32_t *uint32_ptr = (uint32_t *)tlv_body_buf;
930 tlv->ipv4_tunnel_sender.s_addr = uint32_ptr[0];
931 /* uint32_t[1] is lsp_id and tunnel_id, below */
932 tlv->extended_tunnel_id.s_addr = uint32_ptr[2];
933 tlv->ipv4_tunnel_endpoint.s_addr = uint32_ptr[3];
934
935 uint16_t *uint16_ptr = (uint16_t *)(tlv_body_buf + LENGTH_1WORD);
936 tlv->lsp_id = ntohs(uint16_ptr[0]);
937 tlv->tunnel_id = ntohs(uint16_ptr[1]);
938
939 return (struct pcep_object_tlv_header *)tlv;
940 }
941
942 struct pcep_object_tlv_header *
943 pcep_decode_tlv_ipv6_lsp_identifiers(struct pcep_object_tlv_header *tlv_hdr,
944 const uint8_t *tlv_body_buf)
945 {
946 struct pcep_object_tlv_ipv6_lsp_identifier *tlv =
947 (struct pcep_object_tlv_ipv6_lsp_identifier *)common_tlv_create(
948 tlv_hdr,
949 sizeof(struct pcep_object_tlv_ipv6_lsp_identifier));
950
951 uint32_t *uint32_ptr = (uint32_t *)tlv_body_buf;
952 decode_ipv6(uint32_ptr, &tlv->ipv6_tunnel_sender);
953 decode_ipv6(uint32_ptr + 5, &tlv->extended_tunnel_id);
954 decode_ipv6(uint32_ptr + 9, &tlv->ipv6_tunnel_endpoint);
955
956 uint16_t *uint16_ptr = (uint16_t *)(tlv_body_buf + LENGTH_4WORDS);
957 tlv->lsp_id = htons(uint16_ptr[0]);
958 tlv->tunnel_id = htons(uint16_ptr[1]);
959
960 return (struct pcep_object_tlv_header *)tlv;
961 }
962
963 struct pcep_object_tlv_header *
964 pcep_decode_tlv_lsp_error_code(struct pcep_object_tlv_header *tlv_hdr,
965 const uint8_t *tlv_body_buf)
966 {
967 struct pcep_object_tlv_lsp_error_code *tlv =
968 (struct pcep_object_tlv_lsp_error_code *)common_tlv_create(
969 tlv_hdr, sizeof(struct pcep_object_tlv_lsp_error_code));
970
971 tlv->lsp_error_code = ntohl(*((uint32_t *)tlv_body_buf));
972
973 return (struct pcep_object_tlv_header *)tlv;
974 }
975
976 struct pcep_object_tlv_header *
977 pcep_decode_tlv_rsvp_error_spec(struct pcep_object_tlv_header *tlv_hdr,
978 const uint8_t *tlv_body_buf)
979 {
980 uint8_t class_num = tlv_body_buf[2];
981 uint8_t ctype = tlv_body_buf[3];
982
983 if (class_num != RSVP_ERROR_SPEC_CLASS_NUM) {
984 pcep_log(
985 LOG_INFO,
986 "%s: Decoding RSVP Error Spec TLV, unknown class num [%d]",
987 __func__, class_num);
988 return NULL;
989 }
990
991 if (ctype != RSVP_ERROR_SPEC_IPV4_CTYPE
992 && ctype != RSVP_ERROR_SPEC_IPV6_CTYPE) {
993 pcep_log(LOG_INFO,
994 "%s: Decoding RSVP Error Spec TLV, unknown ctype [%d]",
995 __func__, ctype);
996 return NULL;
997 }
998
999 struct pcep_object_tlv_rsvp_error_spec *tlv =
1000 (struct pcep_object_tlv_rsvp_error_spec *)common_tlv_create(
1001 tlv_hdr,
1002 sizeof(struct pcep_object_tlv_rsvp_error_spec));
1003
1004 tlv->class_num = class_num;
1005 tlv->c_type = ctype;
1006
1007 uint32_t *uint32_ptr = (uint32_t *)(tlv_body_buf + LENGTH_1WORD);
1008 if (ctype == RSVP_ERROR_SPEC_IPV4_CTYPE) {
1009 tlv->error_spec_ip.ipv4_error_node_address.s_addr = *uint32_ptr;
1010 tlv->error_code = tlv_body_buf[LENGTH_2WORDS + 1];
1011 tlv->error_value = ntohs(
1012 *((uint16_t *)(tlv_body_buf + LENGTH_2WORDS + 2)));
1013 } else /* RSVP_ERROR_SPEC_IPV6_CTYPE */
1014 {
1015 decode_ipv6(uint32_ptr,
1016 &tlv->error_spec_ip.ipv6_error_node_address);
1017 tlv->error_code = tlv_body_buf[LENGTH_5WORDS + 1];
1018 tlv->error_value = ntohs(
1019 *((uint16_t *)(tlv_body_buf + LENGTH_5WORDS + 2)));
1020 }
1021
1022 return (struct pcep_object_tlv_header *)tlv;
1023 }
1024
1025 struct pcep_object_tlv_header *
1026 pcep_decode_tlv_lsp_db_version(struct pcep_object_tlv_header *tlv_hdr,
1027 const uint8_t *tlv_body_buf)
1028 {
1029 struct pcep_object_tlv_lsp_db_version *tlv =
1030 (struct pcep_object_tlv_lsp_db_version *)common_tlv_create(
1031 tlv_hdr, sizeof(struct pcep_object_tlv_lsp_db_version));
1032
1033 tlv->lsp_db_version = be64toh(*((uint64_t *)tlv_body_buf));
1034
1035 return (struct pcep_object_tlv_header *)tlv;
1036 }
1037
1038 struct pcep_object_tlv_header *
1039 pcep_decode_tlv_speaker_entity_id(struct pcep_object_tlv_header *tlv_hdr,
1040 const uint8_t *tlv_body_buf)
1041 {
1042 struct pcep_object_tlv_speaker_entity_identifier *tlv =
1043 (struct pcep_object_tlv_speaker_entity_identifier *)
1044 common_tlv_create(
1045 tlv_hdr,
1046 sizeof(struct
1047 pcep_object_tlv_speaker_entity_identifier));
1048
1049 uint8_t num_entity_ids = tlv_hdr->encoded_tlv_length / LENGTH_1WORD;
1050 if (num_entity_ids > MAX_ITERATIONS) {
1051 num_entity_ids = MAX_ITERATIONS;
1052 pcep_log(
1053 LOG_INFO,
1054 "%s: Decode Speaker Entity ID, truncating num entities from [%d] to [%d].",
1055 __func__, num_entity_ids, MAX_ITERATIONS);
1056 }
1057
1058 uint32_t *uint32_ptr = (uint32_t *)tlv_body_buf;
1059 tlv->speaker_entity_id_list = dll_initialize();
1060 int i;
1061 for (i = 0; i < num_entity_ids; i++) {
1062 uint32_t *entity_id =
1063 pceplib_malloc(PCEPLIB_MESSAGES, sizeof(uint32_t));
1064 *entity_id = ntohl(uint32_ptr[i]);
1065 dll_append(tlv->speaker_entity_id_list, entity_id);
1066 }
1067
1068 return (struct pcep_object_tlv_header *)tlv;
1069 }
1070
1071 struct pcep_object_tlv_header *
1072 pcep_decode_tlv_sr_pce_capability(struct pcep_object_tlv_header *tlv_hdr,
1073 const uint8_t *tlv_body_buf)
1074 {
1075 struct pcep_object_tlv_sr_pce_capability *tlv =
1076 (struct pcep_object_tlv_sr_pce_capability *)common_tlv_create(
1077 tlv_hdr,
1078 sizeof(struct pcep_object_tlv_sr_pce_capability));
1079
1080 tlv->flag_n = (tlv_body_buf[2] & TLV_SR_PCE_CAP_FLAG_N);
1081 tlv->flag_x = (tlv_body_buf[2] & TLV_SR_PCE_CAP_FLAG_X);
1082 tlv->max_sid_depth = tlv_body_buf[3];
1083
1084 return (struct pcep_object_tlv_header *)tlv;
1085 }
1086
1087 struct pcep_object_tlv_header *
1088 pcep_decode_tlv_path_setup_type(struct pcep_object_tlv_header *tlv_hdr,
1089 const uint8_t *tlv_body_buf)
1090 {
1091 struct pcep_object_tlv_path_setup_type *tlv =
1092 (struct pcep_object_tlv_path_setup_type *)common_tlv_create(
1093 tlv_hdr,
1094 sizeof(struct pcep_object_tlv_path_setup_type));
1095
1096 tlv->path_setup_type = tlv_body_buf[3];
1097
1098 return (struct pcep_object_tlv_header *)tlv;
1099 }
1100
1101 struct pcep_object_tlv_header *pcep_decode_tlv_path_setup_type_capability(
1102 struct pcep_object_tlv_header *tlv_hdr, const uint8_t *tlv_body_buf)
1103 {
1104 struct pcep_object_tlv_path_setup_type_capability *tlv =
1105 (struct pcep_object_tlv_path_setup_type_capability *)
1106 common_tlv_create(
1107 tlv_hdr,
1108 sizeof(struct
1109 pcep_object_tlv_path_setup_type_capability));
1110
1111 uint8_t num_psts = tlv_body_buf[3];
1112 if (num_psts > MAX_ITERATIONS) {
1113 pcep_log(
1114 LOG_INFO,
1115 "%s: Decode Path Setup Type Capability num PSTs [%d] exceeds MAX [%d] continuing anyways",
1116 __func__, num_psts, MAX_ITERATIONS);
1117 }
1118
1119 int i;
1120 tlv->pst_list = dll_initialize();
1121 for (i = 0; i < num_psts; i++) {
1122 uint8_t *pst =
1123 pceplib_malloc(PCEPLIB_MESSAGES, sizeof(uint8_t));
1124 *pst = tlv_body_buf[i + LENGTH_1WORD];
1125 dll_append(tlv->pst_list, pst);
1126 }
1127
1128 if (tlv->header.encoded_tlv_length
1129 == (TLV_HEADER_LENGTH + LENGTH_1WORD + num_psts)) {
1130 return (struct pcep_object_tlv_header *)tlv;
1131 }
1132
1133 uint8_t num_iterations = 0;
1134 tlv->sub_tlv_list = dll_initialize();
1135 uint16_t buf_index = normalize_pcep_tlv_length(
1136 TLV_HEADER_LENGTH + LENGTH_1WORD + num_psts);
1137 while ((tlv->header.encoded_tlv_length - buf_index) > TLV_HEADER_LENGTH
1138 && num_iterations++ < MAX_ITERATIONS) {
1139 struct pcep_object_tlv_header *sub_tlv =
1140 pcep_decode_tlv(tlv_body_buf + buf_index);
1141 if (sub_tlv == NULL) {
1142 pcep_log(
1143 LOG_INFO,
1144 "%s: Decode PathSetupType Capability sub-TLV decode returned NULL",
1145 __func__);
1146 return (struct pcep_object_tlv_header *)tlv;
1147 }
1148
1149 buf_index +=
1150 normalize_pcep_tlv_length(sub_tlv->encoded_tlv_length);
1151 dll_append(tlv->sub_tlv_list, sub_tlv);
1152 }
1153
1154 return (struct pcep_object_tlv_header *)tlv;
1155 }
1156 struct pcep_object_tlv_header *
1157 pcep_decode_tlv_pol_id(struct pcep_object_tlv_header *tlv_hdr,
1158 const uint8_t *tlv_body_buf)
1159 {
1160 uint32_t *uint32_ptr = (uint32_t *)tlv_body_buf;
1161 struct pcep_object_tlv_srpag_pol_id *ipv4 =
1162 (struct pcep_object_tlv_srpag_pol_id *)common_tlv_create(
1163 tlv_hdr, sizeof(struct pcep_object_tlv_srpag_pol_id));
1164 if (tlv_hdr->encoded_tlv_length == 8) {
1165 ipv4->is_ipv4 = true;
1166 ipv4->color = ntohl(uint32_ptr[0]);
1167 ipv4->end_point.ipv4.s_addr = uint32_ptr[1];
1168 return (struct pcep_object_tlv_header *)ipv4;
1169 } else {
1170 ipv4->is_ipv4 = false;
1171 struct pcep_object_tlv_srpag_pol_id *ipv6 =
1172 (struct pcep_object_tlv_srpag_pol_id *)ipv4;
1173 ipv6->color = ntohl(uint32_ptr[0]);
1174 decode_ipv6(&uint32_ptr[1], &ipv6->end_point.ipv6);
1175 return (struct pcep_object_tlv_header *)ipv6;
1176 }
1177 }
1178 struct pcep_object_tlv_header *
1179 pcep_decode_tlv_pol_name(struct pcep_object_tlv_header *tlv_hdr,
1180 const uint8_t *tlv_body_buf)
1181 {
1182 struct pcep_object_tlv_srpag_pol_name *tlv =
1183 (struct pcep_object_tlv_srpag_pol_name *)common_tlv_create(
1184 tlv_hdr, sizeof(struct pcep_object_tlv_srpag_pol_name));
1185
1186 memcpy(tlv->name, tlv_body_buf, tlv->header.encoded_tlv_length);
1187
1188 return (struct pcep_object_tlv_header *)tlv;
1189 }
1190 struct pcep_object_tlv_header *
1191 pcep_decode_tlv_cpath_id(struct pcep_object_tlv_header *tlv_hdr,
1192 const uint8_t *tlv_body_buf)
1193 {
1194 uint32_t *uint32_ptr = (uint32_t *)tlv_body_buf;
1195 struct pcep_object_tlv_srpag_cp_id *tlv =
1196 (struct pcep_object_tlv_srpag_cp_id *)common_tlv_create(
1197 tlv_hdr, sizeof(struct pcep_object_tlv_srpag_cp_id));
1198
1199 tlv->proto = tlv_body_buf[0];
1200 tlv->orig_asn = ntohl(uint32_ptr[1]);
1201 decode_ipv6(&uint32_ptr[2], &tlv->orig_addres);
1202 tlv->discriminator = ntohl(uint32_ptr[6]);
1203
1204 return (struct pcep_object_tlv_header *)tlv;
1205 }
1206 struct pcep_object_tlv_header *
1207 pcep_decode_tlv_cpath_preference(struct pcep_object_tlv_header *tlv_hdr,
1208 const uint8_t *tlv_body_buf)
1209 {
1210 uint32_t *uint32_ptr = (uint32_t *)tlv_body_buf;
1211 struct pcep_object_tlv_srpag_cp_pref *tlv =
1212 (struct pcep_object_tlv_srpag_cp_pref *)common_tlv_create(
1213 tlv_hdr, sizeof(struct pcep_object_tlv_srpag_cp_pref));
1214
1215 tlv->preference = ntohl(uint32_ptr[0]);
1216
1217 return (struct pcep_object_tlv_header *)tlv;
1218 }
1219
1220 struct pcep_object_tlv_header *
1221 pcep_decode_tlv_vendor_info(struct pcep_object_tlv_header *tlv_hdr,
1222 const uint8_t *tlv_body_buf)
1223 {
1224 struct pcep_object_tlv_vendor_info *tlv =
1225 (struct pcep_object_tlv_vendor_info *)common_tlv_create(
1226 tlv_hdr, sizeof(struct pcep_object_tlv_vendor_info));
1227
1228 uint32_t *uint32_ptr = (uint32_t *)tlv_body_buf;
1229 tlv->enterprise_number = ntohl(uint32_ptr[0]);
1230 tlv->enterprise_specific_info = ntohl(uint32_ptr[1]);
1231
1232 return (struct pcep_object_tlv_header *)tlv;
1233 }
1234
1235 struct pcep_object_tlv_header *
1236 pcep_decode_tlv_arbitrary(struct pcep_object_tlv_header *tlv_hdr,
1237 const uint8_t *tlv_body_buf)
1238 {
1239 struct pcep_object_tlv_arbitrary *tlv_arbitrary =
1240 (struct pcep_object_tlv_arbitrary *)common_tlv_create(
1241 tlv_hdr, sizeof(struct pcep_object_tlv_arbitrary));
1242
1243 uint16_t length = tlv_hdr->encoded_tlv_length;
1244 if (length > MAX_ARBITRARY_SIZE) {
1245 /* TODO should we also reset the tlv_hdr->encoded_tlv_length ?
1246 */
1247 length = MAX_ARBITRARY_SIZE;
1248 pcep_log(
1249 LOG_INFO,
1250 "%s: Decoding Arbitrary TLV , truncate path name from [%d] to [%d].\",",
1251 __func__, tlv_hdr->encoded_tlv_length,
1252 MAX_ARBITRARY_SIZE);
1253 }
1254
1255 tlv_arbitrary->data_length = length;
1256 tlv_arbitrary->arbitraty_type = tlv_hdr->type;
1257 tlv_hdr->type = PCEP_OBJ_TLV_TYPE_ARBITRARY;
1258 memcpy(tlv_arbitrary->data, tlv_body_buf, length);
1259
1260 return (struct pcep_object_tlv_header *)tlv_arbitrary;
1261 }
1262
1263 struct pcep_object_tlv_header *
1264 pcep_decode_tlv_of_list(struct pcep_object_tlv_header *tlv_hdr,
1265 const uint8_t *tlv_body_buf)
1266 {
1267 struct pcep_object_tlv_of_list *of_tlv =
1268 (struct pcep_object_tlv_of_list *)common_tlv_create(
1269 tlv_hdr, sizeof(struct pcep_object_tlv_of_list));
1270
1271 of_tlv->of_list = dll_initialize();
1272 uint16_t *uint16_ptr = (uint16_t *)tlv_body_buf;
1273 int i = 0;
1274 for (; i < tlv_hdr->encoded_tlv_length && i < MAX_ITERATIONS; i++) {
1275 uint16_t *of_code_ptr =
1276 pceplib_malloc(PCEPLIB_MESSAGES, sizeof(uint16_t));
1277 *of_code_ptr = ntohs(uint16_ptr[i]);
1278 dll_append(of_tlv->of_list, of_code_ptr);
1279 }
1280
1281 return (struct pcep_object_tlv_header *)of_tlv;
1282 }