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.
32 #include "pcep_msg_encoding.h"
33 #include "pcep_msg_tlvs.h"
34 #include "pcep_utils_logging.h"
35 #include "pcep_utils_memory.h"
37 void write_tlv_header(struct pcep_object_tlv_header
*tlv_hdr
,
38 uint16_t tlv_length
, struct pcep_versioning
*versioning
,
40 void pcep_decode_tlv_hdr(const uint8_t *tlv_buf
,
41 struct pcep_object_tlv_header
*tlv_hdr
);
44 * forward declarations for initialize_tlv_encoders()
46 uint16_t pcep_encode_tlv_no_path_vector(struct pcep_object_tlv_header
*tlv
,
47 struct pcep_versioning
*versioning
,
48 uint8_t *tlv_body_buf
);
50 pcep_encode_tlv_stateful_pce_capability(struct pcep_object_tlv_header
*tlv
,
51 struct pcep_versioning
*versioning
,
52 uint8_t *tlv_body_buf
);
53 uint16_t pcep_encode_tlv_symbolic_path_name(struct pcep_object_tlv_header
*tlv
,
54 struct pcep_versioning
*versioning
,
55 uint8_t *tlv_body_buf
);
57 pcep_encode_tlv_ipv4_lsp_identifiers(struct pcep_object_tlv_header
*tlv
,
58 struct pcep_versioning
*versioning
,
59 uint8_t *tlv_body_buf
);
61 pcep_encode_tlv_ipv6_lsp_identifiers(struct pcep_object_tlv_header
*tlv
,
62 struct pcep_versioning
*versioning
,
63 uint8_t *tlv_body_buf
);
64 uint16_t pcep_encode_tlv_lsp_error_code(struct pcep_object_tlv_header
*tlv
,
65 struct pcep_versioning
*versioning
,
66 uint8_t *tlv_body_buf
);
67 uint16_t pcep_encode_tlv_rsvp_error_spec(struct pcep_object_tlv_header
*tlv
,
68 struct pcep_versioning
*versioning
,
69 uint8_t *tlv_body_buf
);
70 uint16_t pcep_encode_tlv_lsp_db_version(struct pcep_object_tlv_header
*tlv
,
71 struct pcep_versioning
*versioning
,
72 uint8_t *tlv_body_buf
);
73 uint16_t pcep_encode_tlv_speaker_entity_id(struct pcep_object_tlv_header
*tlv
,
74 struct pcep_versioning
*versioning
,
75 uint8_t *tlv_body_buf
);
76 uint16_t pcep_encode_tlv_sr_pce_capability(struct pcep_object_tlv_header
*tlv
,
77 struct pcep_versioning
*versioning
,
78 uint8_t *tlv_body_buf
);
79 uint16_t pcep_encode_tlv_path_setup_type(struct pcep_object_tlv_header
*tlv
,
80 struct pcep_versioning
*versioning
,
81 uint8_t *tlv_body_buf
);
83 pcep_encode_tlv_path_setup_type_capability(struct pcep_object_tlv_header
*tlv
,
84 struct pcep_versioning
*versioning
,
85 uint8_t *tlv_body_buf
);
86 uint16_t pcep_encode_tlv_pol_id(struct pcep_object_tlv_header
*tlv
,
87 struct pcep_versioning
*versioning
,
88 uint8_t *tlv_body_buf
);
89 uint16_t pcep_encode_tlv_pol_name(struct pcep_object_tlv_header
*tlv
,
90 struct pcep_versioning
*versioning
,
91 uint8_t *tlv_body_buf
);
92 uint16_t pcep_encode_tlv_cpath_id(struct pcep_object_tlv_header
*tlv
,
93 struct pcep_versioning
*versioning
,
94 uint8_t *tlv_body_buf
);
95 uint16_t pcep_encode_tlv_cpath_preference(struct pcep_object_tlv_header
*tlv
,
96 struct pcep_versioning
*versioning
,
97 uint8_t *tlv_body_buf
);
98 uint16_t pcep_encode_tlv_vendor_info(struct pcep_object_tlv_header
*tlv
,
99 struct pcep_versioning
*versioning
,
100 uint8_t *tlv_body_buf
);
101 uint16_t pcep_encode_tlv_arbitrary(struct pcep_object_tlv_header
*tlv
,
102 struct pcep_versioning
*versioning
,
103 uint8_t *tlv_body_buf
);
104 uint16_t pcep_encode_tlv_of_list(struct pcep_object_tlv_header
*tlv
,
105 struct pcep_versioning
*versioning
,
106 uint8_t *tlv_body_buf
);
107 typedef uint16_t (*tlv_encoder_funcptr
)(struct pcep_object_tlv_header
*,
108 struct pcep_versioning
*versioning
,
109 uint8_t *tlv_body_buf
);
111 #define MAX_TLV_ENCODER_INDEX 65533 + 1 // 65
113 #define PCEP_TLV_ENCODERS_ARGS \
114 struct pcep_object_tlv_header *, struct pcep_versioning *versioning, \
115 uint8_t *tlv_body_buf
116 uint16_t (*const tlv_encoders
[MAX_TLV_ENCODER_INDEX
])(
117 PCEP_TLV_ENCODERS_ARGS
) = {
118 [PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR
] = pcep_encode_tlv_no_path_vector
,
119 [PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY
] =
120 pcep_encode_tlv_stateful_pce_capability
,
121 [PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME
] =
122 pcep_encode_tlv_symbolic_path_name
,
123 [PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS
] =
124 pcep_encode_tlv_ipv4_lsp_identifiers
,
125 [PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS
] =
126 pcep_encode_tlv_ipv6_lsp_identifiers
,
127 [PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE
] = pcep_encode_tlv_lsp_error_code
,
128 [PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC
] = pcep_encode_tlv_rsvp_error_spec
,
129 [PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION
] = pcep_encode_tlv_lsp_db_version
,
130 [PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID
] =
131 pcep_encode_tlv_speaker_entity_id
,
132 [PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY
] =
133 pcep_encode_tlv_sr_pce_capability
,
134 [PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE
] = pcep_encode_tlv_path_setup_type
,
135 [PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY
] =
136 pcep_encode_tlv_path_setup_type_capability
,
137 [PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID
] = pcep_encode_tlv_pol_id
,
138 [PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME
] = pcep_encode_tlv_pol_name
,
139 [PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID
] = pcep_encode_tlv_cpath_id
,
140 [PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE
] =
141 pcep_encode_tlv_cpath_preference
,
142 [PCEP_OBJ_TLV_TYPE_VENDOR_INFO
] = pcep_encode_tlv_vendor_info
,
143 [PCEP_OBJ_TLV_TYPE_ARBITRARY
] = pcep_encode_tlv_arbitrary
,
144 [PCEP_OBJ_TLV_TYPE_OBJECTIVE_FUNCTION_LIST
] = pcep_encode_tlv_of_list
,
147 * forward declarations for initialize_tlv_decoders()
149 struct pcep_object_tlv_header
*
150 pcep_decode_tlv_no_path_vector(struct pcep_object_tlv_header
*tlv_hdr
,
151 const uint8_t *tlv_body_buf
);
152 struct pcep_object_tlv_header
*
153 pcep_decode_tlv_stateful_pce_capability(struct pcep_object_tlv_header
*tlv_hdr
,
154 const uint8_t *tlv_body_buf
);
155 struct pcep_object_tlv_header
*
156 pcep_decode_tlv_symbolic_path_name(struct pcep_object_tlv_header
*tlv_hdr
,
157 const uint8_t *tlv_body_buf
);
158 struct pcep_object_tlv_header
*
159 pcep_decode_tlv_ipv4_lsp_identifiers(struct pcep_object_tlv_header
*tlv_hdr
,
160 const uint8_t *tlv_body_buf
);
161 struct pcep_object_tlv_header
*
162 pcep_decode_tlv_ipv6_lsp_identifiers(struct pcep_object_tlv_header
*tlv_hdr
,
163 const uint8_t *tlv_body_buf
);
164 struct pcep_object_tlv_header
*
165 pcep_decode_tlv_lsp_error_code(struct pcep_object_tlv_header
*tlv_hdr
,
166 const uint8_t *tlv_body_buf
);
167 struct pcep_object_tlv_header
*
168 pcep_decode_tlv_rsvp_error_spec(struct pcep_object_tlv_header
*tlv_hdr
,
169 const uint8_t *tlv_body_buf
);
170 struct pcep_object_tlv_header
*
171 pcep_decode_tlv_lsp_db_version(struct pcep_object_tlv_header
*tlv_hdr
,
172 const uint8_t *tlv_body_buf
);
173 struct pcep_object_tlv_header
*
174 pcep_decode_tlv_speaker_entity_id(struct pcep_object_tlv_header
*tlv_hdr
,
175 const uint8_t *tlv_body_buf
);
176 struct pcep_object_tlv_header
*
177 pcep_decode_tlv_sr_pce_capability(struct pcep_object_tlv_header
*tlv_hdr
,
178 const uint8_t *tlv_body_buf
);
179 struct pcep_object_tlv_header
*
180 pcep_decode_tlv_path_setup_type(struct pcep_object_tlv_header
*tlv_hdr
,
181 const uint8_t *tlv_body_buf
);
182 struct pcep_object_tlv_header
*pcep_decode_tlv_path_setup_type_capability(
183 struct pcep_object_tlv_header
*tlv_hdr
, const uint8_t *tlv_body_buf
);
184 struct pcep_object_tlv_header
*
185 pcep_decode_tlv_pol_id(struct pcep_object_tlv_header
*tlv_hdr
,
186 const uint8_t *tlv_body_buf
);
187 struct pcep_object_tlv_header
*
188 pcep_decode_tlv_pol_name(struct pcep_object_tlv_header
*tlv_hdr
,
189 const uint8_t *tlv_body_buf
);
190 struct pcep_object_tlv_header
*
191 pcep_decode_tlv_cpath_id(struct pcep_object_tlv_header
*tlv_hdr
,
192 const uint8_t *tlv_body_buf
);
193 struct pcep_object_tlv_header
*
194 pcep_decode_tlv_cpath_preference(struct pcep_object_tlv_header
*tlv_hdr
,
195 const uint8_t *tlv_body_buf
);
196 struct pcep_object_tlv_header
*
197 pcep_decode_tlv_vendor_info(struct pcep_object_tlv_header
*tlv_hdr
,
198 const uint8_t *tlv_body_buf
);
199 struct pcep_object_tlv_header
*
200 pcep_decode_tlv_arbitrary(struct pcep_object_tlv_header
*tlv_hdr
,
201 const uint8_t *tlv_body_buf
);
202 struct pcep_object_tlv_header
*
203 pcep_decode_tlv_of_list(struct pcep_object_tlv_header
*tlv_hdr
,
204 const uint8_t *tlv_body_buf
);
205 typedef struct pcep_object_tlv_header
*(*tlv_decoder_funcptr
)(
206 struct pcep_object_tlv_header
*tlv_hdr
, const uint8_t *tlv_body_buf
);
208 // tlv_decoder_funcptr tlv_decoders[MAX_TLV_ENCODER_INDEX];
210 #define PCEP_TLV_DECODERS_ARGS \
211 struct pcep_object_tlv_header *tlv_hdr, const uint8_t *tlv_body_buf
213 struct pcep_object_tlv_header
*(*const tlv_decoders
[MAX_TLV_ENCODER_INDEX
])(
214 PCEP_TLV_DECODERS_ARGS
) = {
215 [PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR
] = pcep_decode_tlv_no_path_vector
,
216 [PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY
] =
217 pcep_decode_tlv_stateful_pce_capability
,
218 [PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME
] =
219 pcep_decode_tlv_symbolic_path_name
,
220 [PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS
] =
221 pcep_decode_tlv_ipv4_lsp_identifiers
,
222 [PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS
] =
223 pcep_decode_tlv_ipv6_lsp_identifiers
,
224 [PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE
] = pcep_decode_tlv_lsp_error_code
,
225 [PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC
] = pcep_decode_tlv_rsvp_error_spec
,
226 [PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION
] = pcep_decode_tlv_lsp_db_version
,
227 [PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID
] =
228 pcep_decode_tlv_speaker_entity_id
,
229 [PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY
] =
230 pcep_decode_tlv_sr_pce_capability
,
231 [PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE
] = pcep_decode_tlv_path_setup_type
,
232 [PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY
] =
233 pcep_decode_tlv_path_setup_type_capability
,
234 [PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID
] = pcep_decode_tlv_pol_id
,
235 [PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME
] = pcep_decode_tlv_pol_name
,
236 [PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID
] = pcep_decode_tlv_cpath_id
,
237 [PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE
] =
238 pcep_decode_tlv_cpath_preference
,
239 [PCEP_OBJ_TLV_TYPE_VENDOR_INFO
] = pcep_decode_tlv_vendor_info
,
240 [PCEP_OBJ_TLV_TYPE_ARBITRARY
] = pcep_decode_tlv_arbitrary
,
241 [PCEP_OBJ_TLV_TYPE_OBJECTIVE_FUNCTION_LIST
] = pcep_decode_tlv_of_list
,
244 static void initialize_tlv_coders()
246 static bool initialized
= false;
248 if (initialized
== true) {
256 memset(tlv_encoders, 0, sizeof(tlv_encoder_funcptr) *
257 MAX_TLV_ENCODER_INDEX); tlv_encoders[PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR] =
258 pcep_encode_tlv_no_path_vector;
259 tlv_encoders[PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY] =
260 pcep_encode_tlv_stateful_pce_capability;
261 tlv_encoders[PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME] =
262 pcep_encode_tlv_symbolic_path_name;
263 tlv_encoders[PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS] =
264 pcep_encode_tlv_ipv4_lsp_identifiers;
265 tlv_encoders[PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS] =
266 pcep_encode_tlv_ipv6_lsp_identifiers;
267 tlv_encoders[PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE] =
268 pcep_encode_tlv_lsp_error_code;
269 tlv_encoders[PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC] =
270 pcep_encode_tlv_rsvp_error_spec;
271 tlv_encoders[PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION] =
272 pcep_encode_tlv_lsp_db_version;
273 tlv_encoders[PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID] =
274 pcep_encode_tlv_speaker_entity_id;
275 tlv_encoders[PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY] =
276 pcep_encode_tlv_sr_pce_capability;
277 tlv_encoders[PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE] =
278 pcep_encode_tlv_path_setup_type;
279 tlv_encoders[PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY] =
280 pcep_encode_tlv_path_setup_type_capability;
281 tlv_encoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID] =
282 pcep_encode_tlv_pol_id;
283 tlv_encoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME] =
284 pcep_encode_tlv_pol_name;
285 tlv_encoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID] =
286 pcep_encode_tlv_cpath_id;
287 tlv_encoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE] =
288 pcep_encode_tlv_cpath_preference;
289 tlv_encoders[PCEP_OBJ_TLV_TYPE_VENDOR_INFO] =
290 pcep_encode_tlv_vendor_info; tlv_encoders[PCEP_OBJ_TLV_TYPE_ARBITRARY] =
291 pcep_encode_tlv_arbitrary;
292 tlv_encoders[PCEP_OBJ_TLV_TYPE_OBJECTIVE_FUNCTION_LIST] =
293 pcep_encode_tlv_of_list;
298 memset(tlv_decoders, 0, sizeof(tlv_decoder_funcptr) *
299 MAX_TLV_ENCODER_INDEX); tlv_decoders[PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR] =
300 pcep_decode_tlv_no_path_vector;
301 tlv_decoders[PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY] =
302 pcep_decode_tlv_stateful_pce_capability;
303 tlv_decoders[PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME] =
304 pcep_decode_tlv_symbolic_path_name;
305 tlv_decoders[PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS] =
306 pcep_decode_tlv_ipv4_lsp_identifiers;
307 tlv_decoders[PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS] =
308 pcep_decode_tlv_ipv6_lsp_identifiers;
309 tlv_decoders[PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE] =
310 pcep_decode_tlv_lsp_error_code;
311 tlv_decoders[PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC] =
312 pcep_decode_tlv_rsvp_error_spec;
313 tlv_decoders[PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION] =
314 pcep_decode_tlv_lsp_db_version;
315 tlv_decoders[PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID] =
316 pcep_decode_tlv_speaker_entity_id;
317 tlv_decoders[PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY] =
318 pcep_decode_tlv_sr_pce_capability;
319 tlv_decoders[PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE] =
320 pcep_decode_tlv_path_setup_type;
321 tlv_decoders[PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY] =
322 pcep_decode_tlv_path_setup_type_capability;
323 tlv_decoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID] =
324 pcep_decode_tlv_pol_id;
325 tlv_decoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME] =
326 pcep_decode_tlv_pol_name;
327 tlv_decoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID] =
328 pcep_decode_tlv_cpath_id;
329 tlv_decoders[PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE] =
330 pcep_decode_tlv_cpath_preference;
331 tlv_decoders[PCEP_OBJ_TLV_TYPE_VENDOR_INFO] =
332 pcep_decode_tlv_vendor_info; tlv_decoders[PCEP_OBJ_TLV_TYPE_ARBITRARY] =
333 pcep_decode_tlv_arbitrary;
334 tlv_decoders[PCEP_OBJ_TLV_TYPE_OBJECTIVE_FUNCTION_LIST] =
335 pcep_decode_tlv_of_list;
339 uint16_t pcep_encode_tlv(struct pcep_object_tlv_header
*tlv_hdr
,
340 struct pcep_versioning
*versioning
, uint8_t *buf
)
342 initialize_tlv_coders();
344 if (tlv_hdr
->type
>= MAX_TLV_ENCODER_INDEX
) {
346 "%s: Cannot encode unknown Object class [%d]",
347 __func__
, tlv_hdr
->type
);
351 tlv_encoder_funcptr tlv_encoder
= tlv_encoders
[tlv_hdr
->type
];
352 if (tlv_encoder
== NULL
) {
354 "%s: No object encoder found for Object class [%d]",
355 __func__
, tlv_hdr
->type
);
359 /* Notice: The length in the TLV header does not include the TLV header,
360 * so the length returned from the tlv_encoder() is only the TLV body.
362 uint16_t tlv_length
=
363 tlv_encoder(tlv_hdr
, versioning
, buf
+ TLV_HEADER_LENGTH
);
364 write_tlv_header(tlv_hdr
, tlv_length
, versioning
, buf
);
365 tlv_hdr
->encoded_tlv
= buf
;
366 tlv_hdr
->encoded_tlv_length
= tlv_length
;
368 return normalize_pcep_tlv_length(tlv_length
+ TLV_HEADER_LENGTH
);
374 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
375 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
376 * | Type (2 bytes) | Length (2 bytes) |
377 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
378 * | Value (Variable) |
379 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
382 void write_tlv_header(struct pcep_object_tlv_header
*tlv_hdr
,
383 uint16_t tlv_length
, struct pcep_versioning
*versioning
,
387 uint16_t *uint16_ptr
= (uint16_t *)buf
;
388 uint16_ptr
[0] = htons(tlv_hdr
->type
);
389 uint16_ptr
[1] = htons(tlv_length
);
393 * Functions to encode TLVs
396 uint16_t pcep_encode_tlv_no_path_vector(struct pcep_object_tlv_header
*tlv
,
397 struct pcep_versioning
*versioning
,
398 uint8_t *tlv_body_buf
)
401 struct pcep_object_tlv_nopath_vector
*nopath_tlv
=
402 (struct pcep_object_tlv_nopath_vector
*)tlv
;
403 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
404 *uint32_ptr
= htonl(nopath_tlv
->error_code
);
410 pcep_encode_tlv_stateful_pce_capability(struct pcep_object_tlv_header
*tlv
,
411 struct pcep_versioning
*versioning
,
412 uint8_t *tlv_body_buf
)
415 struct pcep_object_tlv_stateful_pce_capability
*spc_tlv
=
416 (struct pcep_object_tlv_stateful_pce_capability
*)tlv
;
418 ((spc_tlv
->flag_f_triggered_initial_sync
== true
419 ? TLV_STATEFUL_PCE_CAP_FLAG_F
421 | (spc_tlv
->flag_d_delta_lsp_sync
== true
422 ? TLV_STATEFUL_PCE_CAP_FLAG_D
424 | (spc_tlv
->flag_t_triggered_resync
== true
425 ? TLV_STATEFUL_PCE_CAP_FLAG_T
427 | (spc_tlv
->flag_i_lsp_instantiation_capability
== true
428 ? TLV_STATEFUL_PCE_CAP_FLAG_I
430 | (spc_tlv
->flag_s_include_db_version
== true
431 ? TLV_STATEFUL_PCE_CAP_FLAG_S
433 | (spc_tlv
->flag_u_lsp_update_capability
== true
434 ? TLV_STATEFUL_PCE_CAP_FLAG_U
440 uint16_t pcep_encode_tlv_symbolic_path_name(struct pcep_object_tlv_header
*tlv
,
441 struct pcep_versioning
*versioning
,
442 uint8_t *tlv_body_buf
)
445 struct pcep_object_tlv_symbolic_path_name
*spn_tlv
=
446 (struct pcep_object_tlv_symbolic_path_name
*)tlv
;
447 memcpy(tlv_body_buf
, spn_tlv
->symbolic_path_name
,
448 spn_tlv
->symbolic_path_name_length
);
450 return spn_tlv
->symbolic_path_name_length
;
454 pcep_encode_tlv_ipv4_lsp_identifiers(struct pcep_object_tlv_header
*tlv
,
455 struct pcep_versioning
*versioning
,
456 uint8_t *tlv_body_buf
)
459 struct pcep_object_tlv_ipv4_lsp_identifier
*ipv4_lsp
=
460 (struct pcep_object_tlv_ipv4_lsp_identifier
*)tlv
;
461 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
462 uint32_ptr
[0] = ipv4_lsp
->ipv4_tunnel_sender
.s_addr
;
463 /* uint32_t[1] is lsp_id and tunnel_id, below */
464 uint32_ptr
[2] = ipv4_lsp
->extended_tunnel_id
.s_addr
;
465 uint32_ptr
[3] = ipv4_lsp
->ipv4_tunnel_endpoint
.s_addr
;
467 uint16_t *uint16_ptr
= (uint16_t *)(tlv_body_buf
+ LENGTH_1WORD
);
468 uint16_ptr
[0] = htons(ipv4_lsp
->lsp_id
);
469 uint16_ptr
[1] = htons(ipv4_lsp
->tunnel_id
);
471 return LENGTH_4WORDS
;
475 pcep_encode_tlv_ipv6_lsp_identifiers(struct pcep_object_tlv_header
*tlv
,
476 struct pcep_versioning
*versioning
,
477 uint8_t *tlv_body_buf
)
480 struct pcep_object_tlv_ipv6_lsp_identifier
*ipv6_lsp
=
481 (struct pcep_object_tlv_ipv6_lsp_identifier
*)tlv
;
482 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
483 encode_ipv6(&ipv6_lsp
->ipv6_tunnel_sender
, uint32_ptr
);
484 encode_ipv6(&ipv6_lsp
->extended_tunnel_id
, uint32_ptr
+ 5);
485 encode_ipv6(&ipv6_lsp
->ipv6_tunnel_endpoint
, uint32_ptr
+ 9);
487 uint16_t *uint16_ptr
= (uint16_t *)(tlv_body_buf
+ LENGTH_4WORDS
);
488 uint16_ptr
[0] = htons(ipv6_lsp
->lsp_id
);
489 uint16_ptr
[1] = htons(ipv6_lsp
->tunnel_id
);
491 return LENGTH_13WORDS
;
494 uint16_t pcep_encode_tlv_lsp_error_code(struct pcep_object_tlv_header
*tlv
,
495 struct pcep_versioning
*versioning
,
496 uint8_t *tlv_body_buf
)
499 struct pcep_object_tlv_lsp_error_code
*lsp_error_tlv
=
500 (struct pcep_object_tlv_lsp_error_code
*)tlv
;
501 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
502 *uint32_ptr
= htonl(lsp_error_tlv
->lsp_error_code
);
507 uint16_t pcep_encode_tlv_rsvp_error_spec(struct pcep_object_tlv_header
*tlv
,
508 struct pcep_versioning
*versioning
,
509 uint8_t *tlv_body_buf
)
511 /* Same decode tlv function for both types:
512 pcep_create_tlv_rsvp_ipv4_error_spec(tlv);
513 pcep_create_tlv_rsvp_ipv6_error_spec(tlv); */
515 /* RSVP Object Header
518 * +-------------+-------------+-------------+-------------+
519 * | Length (bytes) | Class-Num | C-Type |
520 * +-------------+-------------+-------------+-------------+
522 * // (Object contents) //
524 * +-------------+-------------+-------------+-------------+
526 * IPv4 ERROR_SPEC object: Class = 6, C-Type = 1
527 * +-------------+-------------+-------------+-------------+
528 * | IPv4 Error Node Address (4 bytes) |
529 * +-------------+-------------+-------------+-------------+
530 * | Flags | Error Code | Error Value |
531 * +-------------+-------------+-------------+-------------+
533 * IPv6 ERROR_SPEC object: Class = 6, C-Type = 2
534 * +-------------+-------------+-------------+-------------+
535 * | IPv6 Error Node Address (16 bytes) |
536 * +-------------+-------------+-------------+-------------+
537 * | Flags | Error Code | Error Value |
538 * +-------------+-------------+-------------+-------------+
542 struct pcep_object_tlv_rsvp_error_spec
*rsvp_hdr
=
543 (struct pcep_object_tlv_rsvp_error_spec
*)tlv
;
544 tlv_body_buf
[2] = rsvp_hdr
->class_num
;
545 tlv_body_buf
[3] = rsvp_hdr
->c_type
;
547 uint16_t *length_ptr
= (uint16_t *)tlv_body_buf
;
548 uint32_t *uint32_ptr
= (uint32_t *)(tlv_body_buf
+ LENGTH_1WORD
);
549 if (rsvp_hdr
->c_type
== RSVP_ERROR_SPEC_IPV4_CTYPE
) {
550 *length_ptr
= htons(LENGTH_3WORDS
);
552 rsvp_hdr
->error_spec_ip
.ipv4_error_node_address
.s_addr
;
553 tlv_body_buf
[LENGTH_2WORDS
+ 1] = rsvp_hdr
->error_code
;
554 uint16_t *uint16_ptr
=
555 (uint16_t *)(tlv_body_buf
+ LENGTH_2WORDS
+ 2);
556 *uint16_ptr
= htons(rsvp_hdr
->error_value
);
558 return LENGTH_3WORDS
;
559 } else if (rsvp_hdr
->c_type
== RSVP_ERROR_SPEC_IPV6_CTYPE
) {
560 *length_ptr
= htons(LENGTH_6WORDS
);
561 encode_ipv6(&rsvp_hdr
->error_spec_ip
.ipv6_error_node_address
,
563 tlv_body_buf
[LENGTH_5WORDS
+ 1] = rsvp_hdr
->error_code
;
564 uint16_t *uint16_ptr
=
565 (uint16_t *)(tlv_body_buf
+ LENGTH_5WORDS
+ 2);
566 *uint16_ptr
= htons(rsvp_hdr
->error_value
);
568 return LENGTH_6WORDS
;
574 uint16_t pcep_encode_tlv_lsp_db_version(struct pcep_object_tlv_header
*tlv
,
575 struct pcep_versioning
*versioning
,
576 uint8_t *tlv_body_buf
)
579 struct pcep_object_tlv_lsp_db_version
*lsp_db_ver
=
580 (struct pcep_object_tlv_lsp_db_version
*)tlv
;
581 *((uint64_t *)tlv_body_buf
) = htobe64(lsp_db_ver
->lsp_db_version
);
583 return LENGTH_2WORDS
;
586 uint16_t pcep_encode_tlv_speaker_entity_id(struct pcep_object_tlv_header
*tlv
,
587 struct pcep_versioning
*versioning
,
588 uint8_t *tlv_body_buf
)
591 struct pcep_object_tlv_speaker_entity_identifier
*speaker_id
=
592 (struct pcep_object_tlv_speaker_entity_identifier
*)tlv
;
593 if (speaker_id
->speaker_entity_id_list
== NULL
) {
598 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
599 double_linked_list_node
*node
=
600 speaker_id
->speaker_entity_id_list
->head
;
601 for (; node
!= NULL
; node
= node
->next_node
) {
602 uint32_ptr
[index
++] = htonl(*((uint32_t *)node
->data
));
605 return speaker_id
->speaker_entity_id_list
->num_entries
* LENGTH_1WORD
;
608 uint16_t pcep_encode_tlv_sr_pce_capability(struct pcep_object_tlv_header
*tlv
,
609 struct pcep_versioning
*versioning
,
610 uint8_t *tlv_body_buf
)
613 struct pcep_object_tlv_sr_pce_capability
*sr_pce_cap
=
614 (struct pcep_object_tlv_sr_pce_capability
*)tlv
;
616 ((sr_pce_cap
->flag_n
== true ? TLV_SR_PCE_CAP_FLAG_N
: 0x00)
617 | (sr_pce_cap
->flag_x
== true ? TLV_SR_PCE_CAP_FLAG_X
: 0x00));
618 tlv_body_buf
[3] = sr_pce_cap
->max_sid_depth
;
623 uint16_t pcep_encode_tlv_path_setup_type(struct pcep_object_tlv_header
*tlv
,
624 struct pcep_versioning
*versioning
,
625 uint8_t *tlv_body_buf
)
628 struct pcep_object_tlv_path_setup_type
*pst
=
629 (struct pcep_object_tlv_path_setup_type
*)tlv
;
630 tlv_body_buf
[3] = pst
->path_setup_type
;
636 pcep_encode_tlv_path_setup_type_capability(struct pcep_object_tlv_header
*tlv
,
637 struct pcep_versioning
*versioning
,
638 uint8_t *tlv_body_buf
)
641 struct pcep_object_tlv_path_setup_type_capability
*pst_cap
=
642 (struct pcep_object_tlv_path_setup_type_capability
*)tlv
;
643 if (pst_cap
->pst_list
== NULL
) {
647 tlv_body_buf
[3] = pst_cap
->pst_list
->num_entries
;
649 /* Index past the reserved and NumPSTs fields */
651 double_linked_list_node
*node
= pst_cap
->pst_list
->head
;
652 for (; node
!= NULL
; node
= node
->next_node
) {
653 tlv_body_buf
[index
++] = *((uint8_t *)node
->data
);
656 uint16_t pst_length
= normalize_pcep_tlv_length(
657 LENGTH_1WORD
+ pst_cap
->pst_list
->num_entries
);
658 if (pst_cap
->sub_tlv_list
== NULL
) {
662 /* Any padding used for the PSTs should not be included in the tlv
664 index
= normalize_pcep_tlv_length(index
);
665 uint16_t sub_tlvs_length
= 0;
666 node
= pst_cap
->sub_tlv_list
->head
;
667 for (; node
!= NULL
; node
= node
->next_node
) {
668 struct pcep_object_tlv_header
*sub_tlv
=
669 (struct pcep_object_tlv_header
*)node
->data
;
670 uint16_t sub_tlv_length
= pcep_encode_tlv(sub_tlv
, versioning
,
671 tlv_body_buf
+ index
);
672 index
+= sub_tlv_length
;
673 sub_tlvs_length
+= sub_tlv_length
;
676 return sub_tlvs_length
+ pst_length
;
678 uint16_t pcep_encode_tlv_pol_id(struct pcep_object_tlv_header
*tlv
,
679 struct pcep_versioning
*versioning
,
680 uint8_t *tlv_body_buf
)
683 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
684 struct pcep_object_tlv_srpag_pol_id
*ipv4
=
685 (struct pcep_object_tlv_srpag_pol_id
*)tlv
;
687 uint32_ptr
[0] = htonl(ipv4
->color
);
688 uint32_ptr
[1] = ipv4
->end_point
.ipv4
.s_addr
;
689 return LENGTH_2WORDS
;
691 struct pcep_object_tlv_srpag_pol_id
*ipv6
=
692 (struct pcep_object_tlv_srpag_pol_id
*)tlv
;
693 uint32_ptr
[0] = htonl(ipv6
->color
);
694 encode_ipv6(&ipv6
->end_point
.ipv6
, &uint32_ptr
[1]);
695 return LENGTH_5WORDS
;
699 uint16_t pcep_encode_tlv_pol_name(struct pcep_object_tlv_header
*tlv
,
700 struct pcep_versioning
*versioning
,
701 uint8_t *tlv_body_buf
)
704 struct pcep_object_tlv_srpag_pol_name
*pol_name_tlv
=
705 (struct pcep_object_tlv_srpag_pol_name
*)tlv
;
706 memcpy(tlv_body_buf
, pol_name_tlv
->name
, pol_name_tlv
->name_length
);
708 return normalize_pcep_tlv_length(pol_name_tlv
->name_length
);
711 uint16_t pcep_encode_tlv_cpath_id(struct pcep_object_tlv_header
*tlv
,
712 struct pcep_versioning
*versioning
,
713 uint8_t *tlv_body_buf
)
716 struct pcep_object_tlv_srpag_cp_id
*cpath_id_tlv
=
717 (struct pcep_object_tlv_srpag_cp_id
*)tlv
;
719 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
720 tlv_body_buf
[0] = cpath_id_tlv
->proto
;
721 uint32_ptr
[1] = htonl(cpath_id_tlv
->orig_asn
);
722 encode_ipv6(&cpath_id_tlv
->orig_addres
, &uint32_ptr
[2]);
723 uint32_ptr
[6] = htonl(cpath_id_tlv
->discriminator
);
725 return sizeof(cpath_id_tlv
->proto
) + sizeof(cpath_id_tlv
->orig_asn
)
726 + sizeof(cpath_id_tlv
->orig_addres
)
727 + sizeof(cpath_id_tlv
->discriminator
);
730 uint16_t pcep_encode_tlv_cpath_preference(struct pcep_object_tlv_header
*tlv
,
731 struct pcep_versioning
*versioning
,
732 uint8_t *tlv_body_buf
)
735 struct pcep_object_tlv_srpag_cp_pref
*cpath_pref_tlv
=
736 (struct pcep_object_tlv_srpag_cp_pref
*)tlv
;
738 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
739 uint32_ptr
[0] = htonl(cpath_pref_tlv
->preference
);
741 return sizeof(cpath_pref_tlv
->preference
);
744 uint16_t pcep_encode_tlv_vendor_info(struct pcep_object_tlv_header
*tlv
,
745 struct pcep_versioning
*versioning
,
746 uint8_t *tlv_body_buf
)
749 struct pcep_object_tlv_vendor_info
*vendor_info
=
750 (struct pcep_object_tlv_vendor_info
*)tlv
;
752 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
753 uint32_ptr
[0] = htonl(vendor_info
->enterprise_number
);
754 uint32_ptr
[1] = htonl(vendor_info
->enterprise_specific_info
);
756 return LENGTH_2WORDS
;
759 uint16_t pcep_encode_tlv_arbitrary(struct pcep_object_tlv_header
*tlv
,
760 struct pcep_versioning
*versioning
,
761 uint8_t *tlv_body_buf
)
764 struct pcep_object_tlv_arbitrary
*tlv_arbitrary
=
765 (struct pcep_object_tlv_arbitrary
*)tlv
;
766 memcpy(tlv_body_buf
, tlv_arbitrary
->data
, tlv_arbitrary
->data_length
);
767 tlv
->type
= tlv_arbitrary
->arbitraty_type
;
769 return tlv_arbitrary
->data_length
;
772 uint16_t pcep_encode_tlv_of_list(struct pcep_object_tlv_header
*tlv
,
773 struct pcep_versioning
*versioning
,
774 uint8_t *tlv_body_buf
)
777 struct pcep_object_tlv_of_list
*of_list
=
778 (struct pcep_object_tlv_of_list
*)tlv
;
780 if (of_list
->of_list
== NULL
) {
785 double_linked_list_node
*node
= of_list
->of_list
->head
;
786 while (node
!= NULL
) {
787 uint16_t *of_code
= (uint16_t *)node
->data
;
788 if (of_code
== NULL
) {
792 uint16_t *uint16_ptr
= (uint16_t *)(tlv_body_buf
+ index
);
793 *uint16_ptr
= *of_code
;
796 node
= node
->next_node
;
799 return of_list
->of_list
->num_entries
* 2;
806 void pcep_decode_tlv_hdr(const uint8_t *tlv_buf
,
807 struct pcep_object_tlv_header
*tlv_hdr
)
809 memset(tlv_hdr
, 0, sizeof(struct pcep_object_tlv_header
));
811 uint16_t *uint16_ptr
= (uint16_t *)tlv_buf
;
812 tlv_hdr
->type
= ntohs(uint16_ptr
[0]);
813 tlv_hdr
->encoded_tlv_length
= ntohs(uint16_ptr
[1]);
814 tlv_hdr
->encoded_tlv
= tlv_buf
;
817 struct pcep_object_tlv_header
*pcep_decode_tlv(const uint8_t *tlv_buf
)
819 initialize_tlv_coders();
821 struct pcep_object_tlv_header tlv_hdr
;
822 /* Only initializes and decodes the Object Header: class, type, flags,
824 pcep_decode_tlv_hdr(tlv_buf
, &tlv_hdr
);
826 if (tlv_hdr
.type
>= MAX_TLV_ENCODER_INDEX
) {
827 pcep_log(LOG_INFO
, "%s: Cannot decode unknown TLV type [%d]",
828 __func__
, tlv_hdr
.type
);
832 tlv_decoder_funcptr tlv_decoder
= tlv_decoders
[tlv_hdr
.type
];
833 if (tlv_decoder
== NULL
) {
834 pcep_log(LOG_INFO
, "%s: No TLV decoder found for TLV type [%d]",
835 __func__
, tlv_hdr
.type
);
839 return tlv_decoder(&tlv_hdr
, tlv_buf
+ LENGTH_1WORD
);
842 static struct pcep_object_tlv_header
*
843 common_tlv_create(struct pcep_object_tlv_header
*hdr
, uint16_t new_tlv_length
)
845 struct pcep_object_tlv_header
*new_tlv
=
846 pceplib_malloc(PCEPLIB_MESSAGES
, new_tlv_length
);
847 memset(new_tlv
, 0, new_tlv_length
);
848 memcpy(new_tlv
, hdr
, sizeof(struct pcep_object_tlv_header
));
853 struct pcep_object_tlv_header
*
854 pcep_decode_tlv_no_path_vector(struct pcep_object_tlv_header
*tlv_hdr
,
855 const uint8_t *tlv_body_buf
)
857 struct pcep_object_tlv_nopath_vector
*tlv
=
858 (struct pcep_object_tlv_nopath_vector
*)common_tlv_create(
859 tlv_hdr
, sizeof(struct pcep_object_tlv_nopath_vector
));
861 tlv
->error_code
= ntohl(*((uint32_t *)tlv_body_buf
));
863 return (struct pcep_object_tlv_header
*)tlv
;
866 struct pcep_object_tlv_header
*
867 pcep_decode_tlv_stateful_pce_capability(struct pcep_object_tlv_header
*tlv_hdr
,
868 const uint8_t *tlv_body_buf
)
870 struct pcep_object_tlv_stateful_pce_capability
*tlv
=
871 (struct pcep_object_tlv_stateful_pce_capability
*)
875 pcep_object_tlv_stateful_pce_capability
));
877 tlv
->flag_f_triggered_initial_sync
=
878 (tlv_body_buf
[3] & TLV_STATEFUL_PCE_CAP_FLAG_F
);
879 tlv
->flag_d_delta_lsp_sync
=
880 (tlv_body_buf
[3] & TLV_STATEFUL_PCE_CAP_FLAG_D
);
881 tlv
->flag_t_triggered_resync
=
882 (tlv_body_buf
[3] & TLV_STATEFUL_PCE_CAP_FLAG_T
);
883 tlv
->flag_i_lsp_instantiation_capability
=
884 (tlv_body_buf
[3] & TLV_STATEFUL_PCE_CAP_FLAG_I
);
885 tlv
->flag_s_include_db_version
=
886 (tlv_body_buf
[3] & TLV_STATEFUL_PCE_CAP_FLAG_S
);
887 tlv
->flag_u_lsp_update_capability
=
888 (tlv_body_buf
[3] & TLV_STATEFUL_PCE_CAP_FLAG_U
);
890 return (struct pcep_object_tlv_header
*)tlv
;
893 struct pcep_object_tlv_header
*
894 pcep_decode_tlv_symbolic_path_name(struct pcep_object_tlv_header
*tlv_hdr
,
895 const uint8_t *tlv_body_buf
)
897 struct pcep_object_tlv_symbolic_path_name
*tlv
=
898 (struct pcep_object_tlv_symbolic_path_name
*)common_tlv_create(
900 sizeof(struct pcep_object_tlv_symbolic_path_name
));
902 uint16_t length
= tlv_hdr
->encoded_tlv_length
;
903 if (length
> MAX_SYMBOLIC_PATH_NAME
) {
904 /* TODO should we also reset the tlv_hdr->encoded_tlv_length ?
906 length
= MAX_SYMBOLIC_PATH_NAME
;
909 "%s: Decoding Symbolic Path Name TLV, truncate path name from [%d] to [%d].\",",
910 __func__
, tlv_hdr
->encoded_tlv_length
,
911 MAX_SYMBOLIC_PATH_NAME
);
914 tlv
->symbolic_path_name_length
= length
;
915 memcpy(tlv
->symbolic_path_name
, tlv_body_buf
, length
);
917 return (struct pcep_object_tlv_header
*)tlv
;
920 struct pcep_object_tlv_header
*
921 pcep_decode_tlv_ipv4_lsp_identifiers(struct pcep_object_tlv_header
*tlv_hdr
,
922 const uint8_t *tlv_body_buf
)
924 struct pcep_object_tlv_ipv4_lsp_identifier
*tlv
=
925 (struct pcep_object_tlv_ipv4_lsp_identifier
*)common_tlv_create(
927 sizeof(struct pcep_object_tlv_ipv4_lsp_identifier
));
929 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
930 tlv
->ipv4_tunnel_sender
.s_addr
= uint32_ptr
[0];
931 /* uint32_t[1] is lsp_id and tunnel_id, below */
932 tlv
->extended_tunnel_id
.s_addr
= uint32_ptr
[2];
933 tlv
->ipv4_tunnel_endpoint
.s_addr
= uint32_ptr
[3];
935 uint16_t *uint16_ptr
= (uint16_t *)(tlv_body_buf
+ LENGTH_1WORD
);
936 tlv
->lsp_id
= ntohs(uint16_ptr
[0]);
937 tlv
->tunnel_id
= ntohs(uint16_ptr
[1]);
939 return (struct pcep_object_tlv_header
*)tlv
;
942 struct pcep_object_tlv_header
*
943 pcep_decode_tlv_ipv6_lsp_identifiers(struct pcep_object_tlv_header
*tlv_hdr
,
944 const uint8_t *tlv_body_buf
)
946 struct pcep_object_tlv_ipv6_lsp_identifier
*tlv
=
947 (struct pcep_object_tlv_ipv6_lsp_identifier
*)common_tlv_create(
949 sizeof(struct pcep_object_tlv_ipv6_lsp_identifier
));
951 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
952 decode_ipv6(uint32_ptr
, &tlv
->ipv6_tunnel_sender
);
953 decode_ipv6(uint32_ptr
+ 5, &tlv
->extended_tunnel_id
);
954 decode_ipv6(uint32_ptr
+ 9, &tlv
->ipv6_tunnel_endpoint
);
956 uint16_t *uint16_ptr
= (uint16_t *)(tlv_body_buf
+ LENGTH_4WORDS
);
957 tlv
->lsp_id
= htons(uint16_ptr
[0]);
958 tlv
->tunnel_id
= htons(uint16_ptr
[1]);
960 return (struct pcep_object_tlv_header
*)tlv
;
963 struct pcep_object_tlv_header
*
964 pcep_decode_tlv_lsp_error_code(struct pcep_object_tlv_header
*tlv_hdr
,
965 const uint8_t *tlv_body_buf
)
967 struct pcep_object_tlv_lsp_error_code
*tlv
=
968 (struct pcep_object_tlv_lsp_error_code
*)common_tlv_create(
969 tlv_hdr
, sizeof(struct pcep_object_tlv_lsp_error_code
));
971 tlv
->lsp_error_code
= ntohl(*((uint32_t *)tlv_body_buf
));
973 return (struct pcep_object_tlv_header
*)tlv
;
976 struct pcep_object_tlv_header
*
977 pcep_decode_tlv_rsvp_error_spec(struct pcep_object_tlv_header
*tlv_hdr
,
978 const uint8_t *tlv_body_buf
)
980 uint8_t class_num
= tlv_body_buf
[2];
981 uint8_t ctype
= tlv_body_buf
[3];
983 if (class_num
!= RSVP_ERROR_SPEC_CLASS_NUM
) {
986 "%s: Decoding RSVP Error Spec TLV, unknown class num [%d]",
987 __func__
, class_num
);
991 if (ctype
!= RSVP_ERROR_SPEC_IPV4_CTYPE
992 && ctype
!= RSVP_ERROR_SPEC_IPV6_CTYPE
) {
994 "%s: Decoding RSVP Error Spec TLV, unknown ctype [%d]",
999 struct pcep_object_tlv_rsvp_error_spec
*tlv
=
1000 (struct pcep_object_tlv_rsvp_error_spec
*)common_tlv_create(
1002 sizeof(struct pcep_object_tlv_rsvp_error_spec
));
1004 tlv
->class_num
= class_num
;
1005 tlv
->c_type
= ctype
;
1007 uint32_t *uint32_ptr
= (uint32_t *)(tlv_body_buf
+ LENGTH_1WORD
);
1008 if (ctype
== RSVP_ERROR_SPEC_IPV4_CTYPE
) {
1009 tlv
->error_spec_ip
.ipv4_error_node_address
.s_addr
= *uint32_ptr
;
1010 tlv
->error_code
= tlv_body_buf
[LENGTH_2WORDS
+ 1];
1011 tlv
->error_value
= ntohs(
1012 *((uint16_t *)(tlv_body_buf
+ LENGTH_2WORDS
+ 2)));
1013 } else /* RSVP_ERROR_SPEC_IPV6_CTYPE */
1015 decode_ipv6(uint32_ptr
,
1016 &tlv
->error_spec_ip
.ipv6_error_node_address
);
1017 tlv
->error_code
= tlv_body_buf
[LENGTH_5WORDS
+ 1];
1018 tlv
->error_value
= ntohs(
1019 *((uint16_t *)(tlv_body_buf
+ LENGTH_5WORDS
+ 2)));
1022 return (struct pcep_object_tlv_header
*)tlv
;
1025 struct pcep_object_tlv_header
*
1026 pcep_decode_tlv_lsp_db_version(struct pcep_object_tlv_header
*tlv_hdr
,
1027 const uint8_t *tlv_body_buf
)
1029 struct pcep_object_tlv_lsp_db_version
*tlv
=
1030 (struct pcep_object_tlv_lsp_db_version
*)common_tlv_create(
1031 tlv_hdr
, sizeof(struct pcep_object_tlv_lsp_db_version
));
1033 tlv
->lsp_db_version
= be64toh(*((uint64_t *)tlv_body_buf
));
1035 return (struct pcep_object_tlv_header
*)tlv
;
1038 struct pcep_object_tlv_header
*
1039 pcep_decode_tlv_speaker_entity_id(struct pcep_object_tlv_header
*tlv_hdr
,
1040 const uint8_t *tlv_body_buf
)
1042 struct pcep_object_tlv_speaker_entity_identifier
*tlv
=
1043 (struct pcep_object_tlv_speaker_entity_identifier
*)
1047 pcep_object_tlv_speaker_entity_identifier
));
1049 uint8_t num_entity_ids
= tlv_hdr
->encoded_tlv_length
/ LENGTH_1WORD
;
1050 if (num_entity_ids
> MAX_ITERATIONS
) {
1051 num_entity_ids
= MAX_ITERATIONS
;
1054 "%s: Decode Speaker Entity ID, truncating num entities from [%d] to [%d].",
1055 __func__
, num_entity_ids
, MAX_ITERATIONS
);
1058 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
1059 tlv
->speaker_entity_id_list
= dll_initialize();
1061 for (i
= 0; i
< num_entity_ids
; i
++) {
1062 uint32_t *entity_id
=
1063 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint32_t));
1064 *entity_id
= ntohl(uint32_ptr
[i
]);
1065 dll_append(tlv
->speaker_entity_id_list
, entity_id
);
1068 return (struct pcep_object_tlv_header
*)tlv
;
1071 struct pcep_object_tlv_header
*
1072 pcep_decode_tlv_sr_pce_capability(struct pcep_object_tlv_header
*tlv_hdr
,
1073 const uint8_t *tlv_body_buf
)
1075 struct pcep_object_tlv_sr_pce_capability
*tlv
=
1076 (struct pcep_object_tlv_sr_pce_capability
*)common_tlv_create(
1078 sizeof(struct pcep_object_tlv_sr_pce_capability
));
1080 tlv
->flag_n
= (tlv_body_buf
[2] & TLV_SR_PCE_CAP_FLAG_N
);
1081 tlv
->flag_x
= (tlv_body_buf
[2] & TLV_SR_PCE_CAP_FLAG_X
);
1082 tlv
->max_sid_depth
= tlv_body_buf
[3];
1084 return (struct pcep_object_tlv_header
*)tlv
;
1087 struct pcep_object_tlv_header
*
1088 pcep_decode_tlv_path_setup_type(struct pcep_object_tlv_header
*tlv_hdr
,
1089 const uint8_t *tlv_body_buf
)
1091 struct pcep_object_tlv_path_setup_type
*tlv
=
1092 (struct pcep_object_tlv_path_setup_type
*)common_tlv_create(
1094 sizeof(struct pcep_object_tlv_path_setup_type
));
1096 tlv
->path_setup_type
= tlv_body_buf
[3];
1098 return (struct pcep_object_tlv_header
*)tlv
;
1101 struct pcep_object_tlv_header
*pcep_decode_tlv_path_setup_type_capability(
1102 struct pcep_object_tlv_header
*tlv_hdr
, const uint8_t *tlv_body_buf
)
1104 struct pcep_object_tlv_path_setup_type_capability
*tlv
=
1105 (struct pcep_object_tlv_path_setup_type_capability
*)
1109 pcep_object_tlv_path_setup_type_capability
));
1111 uint8_t num_psts
= tlv_body_buf
[3];
1112 if (num_psts
> MAX_ITERATIONS
) {
1115 "%s: Decode Path Setup Type Capability num PSTs [%d] exceeds MAX [%d] continuing anyways",
1116 __func__
, num_psts
, MAX_ITERATIONS
);
1120 tlv
->pst_list
= dll_initialize();
1121 for (i
= 0; i
< num_psts
; i
++) {
1123 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint8_t));
1124 *pst
= tlv_body_buf
[i
+ LENGTH_1WORD
];
1125 dll_append(tlv
->pst_list
, pst
);
1128 if (tlv
->header
.encoded_tlv_length
1129 == (TLV_HEADER_LENGTH
+ LENGTH_1WORD
+ num_psts
)) {
1130 return (struct pcep_object_tlv_header
*)tlv
;
1133 uint8_t num_iterations
= 0;
1134 tlv
->sub_tlv_list
= dll_initialize();
1135 uint16_t buf_index
= normalize_pcep_tlv_length(
1136 TLV_HEADER_LENGTH
+ LENGTH_1WORD
+ num_psts
);
1137 while ((tlv
->header
.encoded_tlv_length
- buf_index
) > TLV_HEADER_LENGTH
1138 && num_iterations
++ < MAX_ITERATIONS
) {
1139 struct pcep_object_tlv_header
*sub_tlv
=
1140 pcep_decode_tlv(tlv_body_buf
+ buf_index
);
1141 if (sub_tlv
== NULL
) {
1144 "%s: Decode PathSetupType Capability sub-TLV decode returned NULL",
1146 return (struct pcep_object_tlv_header
*)tlv
;
1150 normalize_pcep_tlv_length(sub_tlv
->encoded_tlv_length
);
1151 dll_append(tlv
->sub_tlv_list
, sub_tlv
);
1154 return (struct pcep_object_tlv_header
*)tlv
;
1156 struct pcep_object_tlv_header
*
1157 pcep_decode_tlv_pol_id(struct pcep_object_tlv_header
*tlv_hdr
,
1158 const uint8_t *tlv_body_buf
)
1160 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
1161 struct pcep_object_tlv_srpag_pol_id
*ipv4
=
1162 (struct pcep_object_tlv_srpag_pol_id
*)common_tlv_create(
1163 tlv_hdr
, sizeof(struct pcep_object_tlv_srpag_pol_id
));
1164 if (tlv_hdr
->encoded_tlv_length
== 8) {
1165 ipv4
->is_ipv4
= true;
1166 ipv4
->color
= ntohl(uint32_ptr
[0]);
1167 ipv4
->end_point
.ipv4
.s_addr
= uint32_ptr
[1];
1168 return (struct pcep_object_tlv_header
*)ipv4
;
1170 ipv4
->is_ipv4
= false;
1171 struct pcep_object_tlv_srpag_pol_id
*ipv6
=
1172 (struct pcep_object_tlv_srpag_pol_id
*)ipv4
;
1173 ipv6
->color
= ntohl(uint32_ptr
[0]);
1174 decode_ipv6(&uint32_ptr
[1], &ipv6
->end_point
.ipv6
);
1175 return (struct pcep_object_tlv_header
*)ipv6
;
1178 struct pcep_object_tlv_header
*
1179 pcep_decode_tlv_pol_name(struct pcep_object_tlv_header
*tlv_hdr
,
1180 const uint8_t *tlv_body_buf
)
1182 struct pcep_object_tlv_srpag_pol_name
*tlv
=
1183 (struct pcep_object_tlv_srpag_pol_name
*)common_tlv_create(
1184 tlv_hdr
, sizeof(struct pcep_object_tlv_srpag_pol_name
));
1186 memcpy(tlv
->name
, tlv_body_buf
, tlv
->header
.encoded_tlv_length
);
1188 return (struct pcep_object_tlv_header
*)tlv
;
1190 struct pcep_object_tlv_header
*
1191 pcep_decode_tlv_cpath_id(struct pcep_object_tlv_header
*tlv_hdr
,
1192 const uint8_t *tlv_body_buf
)
1194 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
1195 struct pcep_object_tlv_srpag_cp_id
*tlv
=
1196 (struct pcep_object_tlv_srpag_cp_id
*)common_tlv_create(
1197 tlv_hdr
, sizeof(struct pcep_object_tlv_srpag_cp_id
));
1199 tlv
->proto
= tlv_body_buf
[0];
1200 tlv
->orig_asn
= ntohl(uint32_ptr
[1]);
1201 decode_ipv6(&uint32_ptr
[2], &tlv
->orig_addres
);
1202 tlv
->discriminator
= ntohl(uint32_ptr
[6]);
1204 return (struct pcep_object_tlv_header
*)tlv
;
1206 struct pcep_object_tlv_header
*
1207 pcep_decode_tlv_cpath_preference(struct pcep_object_tlv_header
*tlv_hdr
,
1208 const uint8_t *tlv_body_buf
)
1210 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
1211 struct pcep_object_tlv_srpag_cp_pref
*tlv
=
1212 (struct pcep_object_tlv_srpag_cp_pref
*)common_tlv_create(
1213 tlv_hdr
, sizeof(struct pcep_object_tlv_srpag_cp_pref
));
1215 tlv
->preference
= ntohl(uint32_ptr
[0]);
1217 return (struct pcep_object_tlv_header
*)tlv
;
1220 struct pcep_object_tlv_header
*
1221 pcep_decode_tlv_vendor_info(struct pcep_object_tlv_header
*tlv_hdr
,
1222 const uint8_t *tlv_body_buf
)
1224 struct pcep_object_tlv_vendor_info
*tlv
=
1225 (struct pcep_object_tlv_vendor_info
*)common_tlv_create(
1226 tlv_hdr
, sizeof(struct pcep_object_tlv_vendor_info
));
1228 uint32_t *uint32_ptr
= (uint32_t *)tlv_body_buf
;
1229 tlv
->enterprise_number
= ntohl(uint32_ptr
[0]);
1230 tlv
->enterprise_specific_info
= ntohl(uint32_ptr
[1]);
1232 return (struct pcep_object_tlv_header
*)tlv
;
1235 struct pcep_object_tlv_header
*
1236 pcep_decode_tlv_arbitrary(struct pcep_object_tlv_header
*tlv_hdr
,
1237 const uint8_t *tlv_body_buf
)
1239 struct pcep_object_tlv_arbitrary
*tlv_arbitrary
=
1240 (struct pcep_object_tlv_arbitrary
*)common_tlv_create(
1241 tlv_hdr
, sizeof(struct pcep_object_tlv_arbitrary
));
1243 uint16_t length
= tlv_hdr
->encoded_tlv_length
;
1244 if (length
> MAX_ARBITRARY_SIZE
) {
1245 /* TODO should we also reset the tlv_hdr->encoded_tlv_length ?
1247 length
= MAX_ARBITRARY_SIZE
;
1250 "%s: Decoding Arbitrary TLV , truncate path name from [%d] to [%d].\",",
1251 __func__
, tlv_hdr
->encoded_tlv_length
,
1252 MAX_ARBITRARY_SIZE
);
1255 tlv_arbitrary
->data_length
= length
;
1256 tlv_arbitrary
->arbitraty_type
= tlv_hdr
->type
;
1257 tlv_hdr
->type
= PCEP_OBJ_TLV_TYPE_ARBITRARY
;
1258 memcpy(tlv_arbitrary
->data
, tlv_body_buf
, length
);
1260 return (struct pcep_object_tlv_header
*)tlv_arbitrary
;
1263 struct pcep_object_tlv_header
*
1264 pcep_decode_tlv_of_list(struct pcep_object_tlv_header
*tlv_hdr
,
1265 const uint8_t *tlv_body_buf
)
1267 struct pcep_object_tlv_of_list
*of_tlv
=
1268 (struct pcep_object_tlv_of_list
*)common_tlv_create(
1269 tlv_hdr
, sizeof(struct pcep_object_tlv_of_list
));
1271 of_tlv
->of_list
= dll_initialize();
1272 uint16_t *uint16_ptr
= (uint16_t *)tlv_body_buf
;
1274 for (; i
< tlv_hdr
->encoded_tlv_length
&& i
< MAX_ITERATIONS
; i
++) {
1275 uint16_t *of_code_ptr
=
1276 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint16_t));
1277 *of_code_ptr
= ntohs(uint16_ptr
[i
]);
1278 dll_append(of_tlv
->of_list
, of_code_ptr
);
1281 return (struct pcep_object_tlv_header
*)of_tlv
;