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