2 * This file is part of the PCEPlib, a PCEP protocol library.
4 * Copyright (C) 2020 Volta Networks https://voltanet.io/
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 * Author : Brady Johnson <brady@voltanet.io>
25 * Encoding and decoding for PCEP Object TLVs.
33 #include <sys/endian.h>
36 #endif /* __FreeBSD__ */
41 #include "pcep_msg_encoding.h"
42 #include "pcep_msg_tlvs.h"
43 #include "pcep_utils_logging.h"
44 #include "pcep_utils_memory.h"
46 void write_tlv_header(struct pcep_object_tlv_header
*tlv_hdr
,
47 uint16_t tlv_length
, struct pcep_versioning
*versioning
,
49 void pcep_decode_tlv_hdr(const uint8_t *tlv_buf
,
50 struct pcep_object_tlv_header
*tlv_hdr
);
53 * forward declarations for initialize_tlv_encoders()
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
);
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
);
66 pcep_encode_tlv_ipv4_lsp_identifiers(struct pcep_object_tlv_header
*tlv
,
67 struct pcep_versioning
*versioning
,
68 uint8_t *tlv_body_buf
);
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
);
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
);
120 #define MAX_TLV_ENCODER_INDEX 65533 + 1 // 65
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
,
156 * forward declarations for initialize_tlv_decoders()
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
);
217 // tlv_decoder_funcptr tlv_decoders[MAX_TLV_ENCODER_INDEX];
219 #define PCEP_TLV_DECODERS_ARGS \
220 struct pcep_object_tlv_header *tlv_hdr, const uint8_t *tlv_body_buf
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
,
253 static void initialize_tlv_coders()
255 static bool initialized
= false;
257 if (initialized
== true) {
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;
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;
348 uint16_t pcep_encode_tlv(struct pcep_object_tlv_header
*tlv_hdr
,
349 struct pcep_versioning
*versioning
, uint8_t *buf
)
351 initialize_tlv_coders();
353 if (tlv_hdr
->type
>= MAX_TLV_ENCODER_INDEX
) {
355 "%s: Cannot encode unknown Object class [%d]",
356 __func__
, tlv_hdr
->type
);
360 tlv_encoder_funcptr tlv_encoder
= tlv_encoders
[tlv_hdr
->type
];
361 if (tlv_encoder
== NULL
) {
363 "%s: No object encoder found for Object class [%d]",
364 __func__
, tlv_hdr
->type
);
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.
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
;
377 return normalize_pcep_tlv_length(tlv_length
+ TLV_HEADER_LENGTH
);
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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
391 void write_tlv_header(struct pcep_object_tlv_header
*tlv_hdr
,
392 uint16_t tlv_length
, struct pcep_versioning
*versioning
,
396 uint16_t *uint16_ptr
= (uint16_t *)buf
;
397 uint16_ptr
[0] = htons(tlv_hdr
->type
);
398 uint16_ptr
[1] = htons(tlv_length
);
402 * Functions to encode TLVs
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
)
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
);
419 pcep_encode_tlv_stateful_pce_capability(struct pcep_object_tlv_header
*tlv
,
420 struct pcep_versioning
*versioning
,
421 uint8_t *tlv_body_buf
)
424 struct pcep_object_tlv_stateful_pce_capability
*spc_tlv
=
425 (struct pcep_object_tlv_stateful_pce_capability
*)tlv
;
427 ((spc_tlv
->flag_f_triggered_initial_sync
== true
428 ? TLV_STATEFUL_PCE_CAP_FLAG_F
430 | (spc_tlv
->flag_d_delta_lsp_sync
== true
431 ? TLV_STATEFUL_PCE_CAP_FLAG_D
433 | (spc_tlv
->flag_t_triggered_resync
== true
434 ? TLV_STATEFUL_PCE_CAP_FLAG_T
436 | (spc_tlv
->flag_i_lsp_instantiation_capability
== true
437 ? TLV_STATEFUL_PCE_CAP_FLAG_I
439 | (spc_tlv
->flag_s_include_db_version
== true
440 ? TLV_STATEFUL_PCE_CAP_FLAG_S
442 | (spc_tlv
->flag_u_lsp_update_capability
== true
443 ? TLV_STATEFUL_PCE_CAP_FLAG_U
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
)
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
);
459 return spn_tlv
->symbolic_path_name_length
;
463 pcep_encode_tlv_ipv4_lsp_identifiers(struct pcep_object_tlv_header
*tlv
,
464 struct pcep_versioning
*versioning
,
465 uint8_t *tlv_body_buf
)
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
;
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
);
480 return LENGTH_4WORDS
;
484 pcep_encode_tlv_ipv6_lsp_identifiers(struct pcep_object_tlv_header
*tlv
,
485 struct pcep_versioning
*versioning
,
486 uint8_t *tlv_body_buf
)
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);
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
);
500 return LENGTH_13WORDS
;
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
)
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
);
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
)
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); */
524 /* RSVP Object Header
527 * +-------------+-------------+-------------+-------------+
528 * | Length (bytes) | Class-Num | C-Type |
529 * +-------------+-------------+-------------+-------------+
531 * // (Object contents) //
533 * +-------------+-------------+-------------+-------------+
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 * +-------------+-------------+-------------+-------------+
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 * +-------------+-------------+-------------+-------------+
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
;
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
);
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
);
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
,
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
);
577 return LENGTH_6WORDS
;
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
)
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
);
592 return LENGTH_2WORDS
;
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
)
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
) {
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
));
614 return speaker_id
->speaker_entity_id_list
->num_entries
* LENGTH_1WORD
;
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
)
622 struct pcep_object_tlv_sr_pce_capability
*sr_pce_cap
=
623 (struct pcep_object_tlv_sr_pce_capability
*)tlv
;
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
;
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
)
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
;
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
)
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
) {
656 tlv_body_buf
[3] = pst_cap
->pst_list
->num_entries
;
658 /* Index past the reserved and NumPSTs fields */
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
);
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
) {
671 /* Any padding used for the PSTs should not be included in the tlv
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
;
685 return sub_tlvs_length
+ pst_length
;
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
)
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
;
696 uint32_ptr
[0] = htonl(ipv4
->color
);
697 uint32_ptr
[1] = ipv4
->end_point
.ipv4
.s_addr
;
698 return LENGTH_2WORDS
;
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
;
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
)
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
);
717 return normalize_pcep_tlv_length(pol_name_tlv
->name_length
);
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
)
725 struct pcep_object_tlv_srpag_cp_id
*cpath_id_tlv
=
726 (struct pcep_object_tlv_srpag_cp_id
*)tlv
;
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
);
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
);
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
)
744 struct pcep_object_tlv_srpag_cp_pref
*cpath_pref_tlv
=
745 (struct pcep_object_tlv_srpag_cp_pref
*)tlv
;
747 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
748 uint32_ptr
[0] = htonl(cpath_pref_tlv
->preference
);
750 return sizeof(cpath_pref_tlv
->preference
);
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
)
758 struct pcep_object_tlv_vendor_info
*vendor_info
=
759 (struct pcep_object_tlv_vendor_info
*)tlv
;
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
);
765 return LENGTH_2WORDS
;
768 uint16_t pcep_encode_tlv_arbitrary(struct pcep_object_tlv_header
*tlv
,
769 struct pcep_versioning
*versioning
,
770 uint8_t *tlv_body_buf
)
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
;
778 return tlv_arbitrary
->data_length
;
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
)
786 struct pcep_object_tlv_of_list
*of_list
=
787 (struct pcep_object_tlv_of_list
*)tlv
;
789 if (of_list
->of_list
== NULL
) {
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
) {
801 uint16_t *uint16_ptr
= (uint16_t *)(tlv_body_buf
+ index
);
802 *uint16_ptr
= *of_code
;
805 node
= node
->next_node
;
808 return of_list
->of_list
->num_entries
* 2;
815 void pcep_decode_tlv_hdr(const uint8_t *tlv_buf
,
816 struct pcep_object_tlv_header
*tlv_hdr
)
818 memset(tlv_hdr
, 0, sizeof(struct pcep_object_tlv_header
));
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
;
826 struct pcep_object_tlv_header
*pcep_decode_tlv(const uint8_t *tlv_buf
)
828 initialize_tlv_coders();
830 struct pcep_object_tlv_header tlv_hdr
;
831 /* Only initializes and decodes the Object Header: class, type, flags,
833 pcep_decode_tlv_hdr(tlv_buf
, &tlv_hdr
);
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
);
841 tlv_decoder_funcptr tlv_decoder
= NULL
;
842 if (tlv_hdr
.type
== PCEP_OBJ_TYPE_CISCO_BSID
) {
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
];
848 tlv_decoder
= tlv_decoders
[tlv_hdr
.type
];
850 if (tlv_decoder
== NULL
) {
851 pcep_log(LOG_INFO
, "%s: No TLV decoder found for TLV type [%d]",
852 __func__
, tlv_hdr
.type
);
856 return tlv_decoder(&tlv_hdr
, tlv_buf
+ LENGTH_1WORD
);
859 static struct pcep_object_tlv_header
*
860 common_tlv_create(struct pcep_object_tlv_header
*hdr
, uint16_t new_tlv_length
)
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
));
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
)
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
));
878 tlv
->error_code
= ntohl(*((uint32_t *)tlv_body_buf
));
880 return (struct pcep_object_tlv_header
*)tlv
;
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
)
887 struct pcep_object_tlv_stateful_pce_capability
*tlv
=
888 (struct pcep_object_tlv_stateful_pce_capability
*)
892 pcep_object_tlv_stateful_pce_capability
));
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
);
907 return (struct pcep_object_tlv_header
*)tlv
;
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
)
914 struct pcep_object_tlv_symbolic_path_name
*tlv
=
915 (struct pcep_object_tlv_symbolic_path_name
*)common_tlv_create(
917 sizeof(struct pcep_object_tlv_symbolic_path_name
));
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 ?
923 length
= MAX_SYMBOLIC_PATH_NAME
;
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
);
931 tlv
->symbolic_path_name_length
= length
;
932 memcpy(tlv
->symbolic_path_name
, tlv_body_buf
, length
);
934 return (struct pcep_object_tlv_header
*)tlv
;
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
)
941 struct pcep_object_tlv_ipv4_lsp_identifier
*tlv
=
942 (struct pcep_object_tlv_ipv4_lsp_identifier
*)common_tlv_create(
944 sizeof(struct pcep_object_tlv_ipv4_lsp_identifier
));
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];
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]);
956 return (struct pcep_object_tlv_header
*)tlv
;
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
)
963 struct pcep_object_tlv_ipv6_lsp_identifier
*tlv
=
964 (struct pcep_object_tlv_ipv6_lsp_identifier
*)common_tlv_create(
966 sizeof(struct pcep_object_tlv_ipv6_lsp_identifier
));
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
);
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]);
977 return (struct pcep_object_tlv_header
*)tlv
;
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
)
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
));
988 tlv
->lsp_error_code
= ntohl(*((uint32_t *)tlv_body_buf
));
990 return (struct pcep_object_tlv_header
*)tlv
;
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
)
997 uint8_t class_num
= tlv_body_buf
[2];
998 uint8_t ctype
= tlv_body_buf
[3];
1000 if (class_num
!= RSVP_ERROR_SPEC_CLASS_NUM
) {
1003 "%s: Decoding RSVP Error Spec TLV, unknown class num [%d]",
1004 __func__
, class_num
);
1008 if (ctype
!= RSVP_ERROR_SPEC_IPV4_CTYPE
1009 && ctype
!= RSVP_ERROR_SPEC_IPV6_CTYPE
) {
1011 "%s: Decoding RSVP Error Spec TLV, unknown ctype [%d]",
1016 struct pcep_object_tlv_rsvp_error_spec
*tlv
=
1017 (struct pcep_object_tlv_rsvp_error_spec
*)common_tlv_create(
1019 sizeof(struct pcep_object_tlv_rsvp_error_spec
));
1021 tlv
->class_num
= class_num
;
1022 tlv
->c_type
= ctype
;
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 */
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)));
1039 return (struct pcep_object_tlv_header
*)tlv
;
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
)
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
));
1050 tlv
->lsp_db_version
= be64toh(*((uint64_t *)tlv_body_buf
));
1052 return (struct pcep_object_tlv_header
*)tlv
;
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
)
1059 struct pcep_object_tlv_speaker_entity_identifier
*tlv
=
1060 (struct pcep_object_tlv_speaker_entity_identifier
*)
1064 pcep_object_tlv_speaker_entity_identifier
));
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
;
1071 "%s: Decode Speaker Entity ID, truncating num entities from [%d] to [%d].",
1072 __func__
, num_entity_ids
, MAX_ITERATIONS
);
1075 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
1076 tlv
->speaker_entity_id_list
= dll_initialize();
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
);
1085 return (struct pcep_object_tlv_header
*)tlv
;
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
)
1092 struct pcep_object_tlv_sr_pce_capability
*tlv
=
1093 (struct pcep_object_tlv_sr_pce_capability
*)common_tlv_create(
1095 sizeof(struct pcep_object_tlv_sr_pce_capability
));
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];
1101 return (struct pcep_object_tlv_header
*)tlv
;
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
)
1108 struct pcep_object_tlv_path_setup_type
*tlv
=
1109 (struct pcep_object_tlv_path_setup_type
*)common_tlv_create(
1111 sizeof(struct pcep_object_tlv_path_setup_type
));
1113 tlv
->path_setup_type
= tlv_body_buf
[3];
1115 return (struct pcep_object_tlv_header
*)tlv
;
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
)
1121 struct pcep_object_tlv_path_setup_type_capability
*tlv
=
1122 (struct pcep_object_tlv_path_setup_type_capability
*)
1126 pcep_object_tlv_path_setup_type_capability
));
1128 uint8_t num_psts
= tlv_body_buf
[3];
1129 if (num_psts
> MAX_ITERATIONS
) {
1132 "%s: Decode Path Setup Type Capability num PSTs [%d] exceeds MAX [%d] continuing anyways",
1133 __func__
, num_psts
, MAX_ITERATIONS
);
1137 tlv
->pst_list
= dll_initialize();
1138 for (i
= 0; i
< num_psts
; i
++) {
1140 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint8_t));
1141 *pst
= tlv_body_buf
[i
+ LENGTH_1WORD
];
1142 dll_append(tlv
->pst_list
, pst
);
1145 if (tlv
->header
.encoded_tlv_length
1146 == (TLV_HEADER_LENGTH
+ LENGTH_1WORD
+ num_psts
)) {
1147 return (struct pcep_object_tlv_header
*)tlv
;
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
) {
1161 "%s: Decode PathSetupType Capability sub-TLV decode returned NULL",
1163 return (struct pcep_object_tlv_header
*)tlv
;
1167 normalize_pcep_tlv_length(sub_tlv
->encoded_tlv_length
);
1168 dll_append(tlv
->sub_tlv_list
, sub_tlv
);
1171 return (struct pcep_object_tlv_header
*)tlv
;
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
)
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
;
1187 ipv4
->is_ipv4
= false;
1188 struct pcep_object_tlv_srpag_pol_id
*ipv6
=
1189 (struct pcep_object_tlv_srpag_pol_id
*)ipv4
;
1190 ipv6
->color
= ntohl(uint32_ptr
[0]);
1191 decode_ipv6(&uint32_ptr
[1], &ipv6
->end_point
.ipv6
);
1192 return (struct pcep_object_tlv_header
*)ipv6
;
1195 struct pcep_object_tlv_header
*
1196 pcep_decode_tlv_pol_name(struct pcep_object_tlv_header
*tlv_hdr
,
1197 const uint8_t *tlv_body_buf
)
1199 struct pcep_object_tlv_srpag_pol_name
*tlv
=
1200 (struct pcep_object_tlv_srpag_pol_name
*)common_tlv_create(
1201 tlv_hdr
, sizeof(struct pcep_object_tlv_srpag_pol_name
));
1203 memcpy(tlv
->name
, tlv_body_buf
, tlv
->header
.encoded_tlv_length
);
1205 return (struct pcep_object_tlv_header
*)tlv
;
1207 struct pcep_object_tlv_header
*
1208 pcep_decode_tlv_cpath_id(struct pcep_object_tlv_header
*tlv_hdr
,
1209 const uint8_t *tlv_body_buf
)
1211 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
1212 struct pcep_object_tlv_srpag_cp_id
*tlv
=
1213 (struct pcep_object_tlv_srpag_cp_id
*)common_tlv_create(
1214 tlv_hdr
, sizeof(struct pcep_object_tlv_srpag_cp_id
));
1216 tlv
->proto
= tlv_body_buf
[0];
1217 tlv
->orig_asn
= ntohl(uint32_ptr
[1]);
1218 decode_ipv6(&uint32_ptr
[2], &tlv
->orig_addres
);
1219 tlv
->discriminator
= ntohl(uint32_ptr
[6]);
1221 return (struct pcep_object_tlv_header
*)tlv
;
1223 struct pcep_object_tlv_header
*
1224 pcep_decode_tlv_cpath_preference(struct pcep_object_tlv_header
*tlv_hdr
,
1225 const uint8_t *tlv_body_buf
)
1227 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
1228 struct pcep_object_tlv_srpag_cp_pref
*tlv
=
1229 (struct pcep_object_tlv_srpag_cp_pref
*)common_tlv_create(
1230 tlv_hdr
, sizeof(struct pcep_object_tlv_srpag_cp_pref
));
1232 tlv
->preference
= ntohl(uint32_ptr
[0]);
1234 return (struct pcep_object_tlv_header
*)tlv
;
1237 struct pcep_object_tlv_header
*
1238 pcep_decode_tlv_vendor_info(struct pcep_object_tlv_header
*tlv_hdr
,
1239 const uint8_t *tlv_body_buf
)
1241 struct pcep_object_tlv_vendor_info
*tlv
=
1242 (struct pcep_object_tlv_vendor_info
*)common_tlv_create(
1243 tlv_hdr
, sizeof(struct pcep_object_tlv_vendor_info
));
1245 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
1246 tlv
->enterprise_number
= ntohl(uint32_ptr
[0]);
1247 tlv
->enterprise_specific_info
= ntohl(uint32_ptr
[1]);
1249 return (struct pcep_object_tlv_header
*)tlv
;
1252 struct pcep_object_tlv_header
*
1253 pcep_decode_tlv_arbitrary(struct pcep_object_tlv_header
*tlv_hdr
,
1254 const uint8_t *tlv_body_buf
)
1256 struct pcep_object_tlv_arbitrary
*tlv_arbitrary
=
1257 (struct pcep_object_tlv_arbitrary
*)common_tlv_create(
1258 tlv_hdr
, sizeof(struct pcep_object_tlv_arbitrary
));
1260 uint16_t length
= tlv_hdr
->encoded_tlv_length
;
1261 if (length
> MAX_ARBITRARY_SIZE
) {
1262 /* TODO should we also reset the tlv_hdr->encoded_tlv_length ?
1264 length
= MAX_ARBITRARY_SIZE
;
1267 "%s: Decoding Arbitrary TLV , truncate path name from [%d] to [%d].\",",
1268 __func__
, tlv_hdr
->encoded_tlv_length
,
1269 MAX_ARBITRARY_SIZE
);
1272 tlv_arbitrary
->data_length
= length
;
1273 tlv_arbitrary
->arbitraty_type
= tlv_hdr
->type
;
1274 tlv_hdr
->type
= PCEP_OBJ_TLV_TYPE_ARBITRARY
;
1275 memcpy(tlv_arbitrary
->data
, tlv_body_buf
, length
);
1277 return (struct pcep_object_tlv_header
*)tlv_arbitrary
;
1280 struct pcep_object_tlv_header
*
1281 pcep_decode_tlv_of_list(struct pcep_object_tlv_header
*tlv_hdr
,
1282 const uint8_t *tlv_body_buf
)
1284 struct pcep_object_tlv_of_list
*of_tlv
=
1285 (struct pcep_object_tlv_of_list
*)common_tlv_create(
1286 tlv_hdr
, sizeof(struct pcep_object_tlv_of_list
));
1288 of_tlv
->of_list
= dll_initialize();
1289 uint16_t *uint16_ptr
= (uint16_t *)tlv_body_buf
;
1291 for (; i
< tlv_hdr
->encoded_tlv_length
&& i
< MAX_ITERATIONS
; i
++) {
1292 uint16_t *of_code_ptr
=
1293 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint16_t));
1294 *of_code_ptr
= ntohs(uint16_ptr
[i
]);
1295 dll_append(of_tlv
->of_list
, of_code_ptr
);
1298 return (struct pcep_object_tlv_header
*)of_tlv
;