1 // SPDX-License-Identifier: LGPL-2.1-or-later
3 * This file is part of the PCEPlib, a PCEP protocol library.
5 * Copyright (C) 2020 Volta Networks https://voltanet.io/
7 * Author : Brady Johnson <brady@voltanet.io>
13 * Encoding and decoding for PCEP Objects.
23 #include "pcep_msg_objects.h"
24 #include "pcep_msg_encoding.h"
25 #include "pcep_utils_logging.h"
26 #include "pcep_utils_memory.h"
28 void write_object_header(struct pcep_object_header
*object_hdr
,
29 uint16_t object_length
, uint8_t *buf
);
30 void pcep_decode_object_hdr(const uint8_t *obj_buf
,
31 struct pcep_object_header
*obj_hdr
);
32 void set_ro_subobj_fields(struct pcep_object_ro_subobj
*subobj
, bool flag_l
,
36 * forward declarations for initialize_object_encoders()
38 uint16_t pcep_encode_obj_open(struct pcep_object_header
*obj
,
39 struct pcep_versioning
*versioning
, uint8_t *buf
);
40 uint16_t pcep_encode_obj_rp(struct pcep_object_header
*obj
,
41 struct pcep_versioning
*versioning
, uint8_t *buf
);
42 uint16_t pcep_encode_obj_nopath(struct pcep_object_header
*obj
,
43 struct pcep_versioning
*versioning
,
45 uint16_t pcep_encode_obj_endpoints(struct pcep_object_header
*obj
,
46 struct pcep_versioning
*versioning
,
48 uint16_t pcep_encode_obj_association(struct pcep_object_header
*obj
,
49 struct pcep_versioning
*versioning
,
51 uint16_t pcep_encode_obj_bandwidth(struct pcep_object_header
*obj
,
52 struct pcep_versioning
*versioning
,
54 uint16_t pcep_encode_obj_metric(struct pcep_object_header
*obj
,
55 struct pcep_versioning
*versioning
,
57 uint16_t pcep_encode_obj_ro(struct pcep_object_header
*obj
,
58 struct pcep_versioning
*versioning
, uint8_t *buf
);
59 uint16_t pcep_encode_obj_lspa(struct pcep_object_header
*obj
,
60 struct pcep_versioning
*versioning
, uint8_t *buf
);
61 uint16_t pcep_encode_obj_svec(struct pcep_object_header
*obj
,
62 struct pcep_versioning
*versioning
, uint8_t *buf
);
63 uint16_t pcep_encode_obj_notify(struct pcep_object_header
*obj
,
64 struct pcep_versioning
*versioning
,
66 uint16_t pcep_encode_obj_error(struct pcep_object_header
*error
,
67 struct pcep_versioning
*versioning
,
69 uint16_t pcep_encode_obj_close(struct pcep_object_header
*close
,
70 struct pcep_versioning
*versioning
,
72 uint16_t pcep_encode_obj_srp(struct pcep_object_header
*obj
,
73 struct pcep_versioning
*versioning
, uint8_t *buf
);
74 uint16_t pcep_encode_obj_lsp(struct pcep_object_header
*obj
,
75 struct pcep_versioning
*versioning
, uint8_t *buf
);
76 uint16_t pcep_encode_obj_vendor_info(struct pcep_object_header
*obj
,
77 struct pcep_versioning
*versioning
,
79 uint16_t pcep_encode_obj_inter_layer(struct pcep_object_header
*obj
,
80 struct pcep_versioning
*versioning
,
82 uint16_t pcep_encode_obj_switch_layer(struct pcep_object_header
*obj
,
83 struct pcep_versioning
*versioning
,
85 uint16_t pcep_encode_obj_req_adap_cap(struct pcep_object_header
*obj
,
86 struct pcep_versioning
*versioning
,
88 uint16_t pcep_encode_obj_server_ind(struct pcep_object_header
*obj
,
89 struct pcep_versioning
*versioning
,
91 uint16_t pcep_encode_obj_objective_function(struct pcep_object_header
*obj
,
92 struct pcep_versioning
*versioning
,
94 typedef uint16_t (*object_encoder_funcptr
)(struct pcep_object_header
*,
95 struct pcep_versioning
*versioning
,
98 #define MAX_OBJECT_ENCODER_INDEX 64
100 #define PCEP_ENCODERS_ARGS \
101 struct pcep_object_header *, struct pcep_versioning *versioning, \
103 uint16_t (*const object_encoders
[MAX_OBJECT_ENCODER_INDEX
])(
104 PCEP_ENCODERS_ARGS
) = {
105 [PCEP_OBJ_CLASS_OPEN
] = pcep_encode_obj_open
,
106 [PCEP_OBJ_CLASS_RP
] = pcep_encode_obj_rp
,
107 [PCEP_OBJ_CLASS_NOPATH
] = pcep_encode_obj_nopath
,
108 [PCEP_OBJ_CLASS_ENDPOINTS
] = pcep_encode_obj_endpoints
,
109 [PCEP_OBJ_CLASS_BANDWIDTH
] = pcep_encode_obj_bandwidth
,
110 [PCEP_OBJ_CLASS_METRIC
] = pcep_encode_obj_metric
,
111 [PCEP_OBJ_CLASS_ERO
] = pcep_encode_obj_ro
,
112 [PCEP_OBJ_CLASS_RRO
] = pcep_encode_obj_ro
,
113 [PCEP_OBJ_CLASS_LSPA
] = pcep_encode_obj_lspa
,
114 [PCEP_OBJ_CLASS_IRO
] = pcep_encode_obj_ro
,
115 [PCEP_OBJ_CLASS_SVEC
] = pcep_encode_obj_svec
,
116 [PCEP_OBJ_CLASS_NOTF
] = pcep_encode_obj_notify
,
117 [PCEP_OBJ_CLASS_ERROR
] = pcep_encode_obj_error
,
118 [PCEP_OBJ_CLASS_CLOSE
] = pcep_encode_obj_close
,
119 [PCEP_OBJ_CLASS_LSP
] = pcep_encode_obj_lsp
,
120 [PCEP_OBJ_CLASS_SRP
] = pcep_encode_obj_srp
,
121 [PCEP_OBJ_CLASS_ASSOCIATION
] = pcep_encode_obj_association
,
122 [PCEP_OBJ_CLASS_INTER_LAYER
] = pcep_encode_obj_inter_layer
,
123 [PCEP_OBJ_CLASS_SWITCH_LAYER
] = pcep_encode_obj_switch_layer
,
124 [PCEP_OBJ_CLASS_REQ_ADAP_CAP
] = pcep_encode_obj_req_adap_cap
,
125 [PCEP_OBJ_CLASS_SERVER_IND
] = pcep_encode_obj_server_ind
,
126 [PCEP_OBJ_CLASS_VENDOR_INFO
] = pcep_encode_obj_vendor_info
,
127 [PCEP_OBJ_CLASS_OF
] = pcep_encode_obj_objective_function
,
130 * forward declarations for initialize_object_decoders()
132 struct pcep_object_header
*pcep_decode_obj_open(struct pcep_object_header
*hdr
,
134 struct pcep_object_header
*pcep_decode_obj_rp(struct pcep_object_header
*hdr
,
136 struct pcep_object_header
*
137 pcep_decode_obj_nopath(struct pcep_object_header
*hdr
, const uint8_t *buf
);
138 struct pcep_object_header
*
139 pcep_decode_obj_endpoints(struct pcep_object_header
*hdr
, const uint8_t *buf
);
140 struct pcep_object_header
*
141 pcep_decode_obj_association(struct pcep_object_header
*hdr
, const uint8_t *buf
);
142 struct pcep_object_header
*
143 pcep_decode_obj_bandwidth(struct pcep_object_header
*hdr
, const uint8_t *buf
);
144 struct pcep_object_header
*
145 pcep_decode_obj_metric(struct pcep_object_header
*hdr
, const uint8_t *buf
);
146 struct pcep_object_header
*pcep_decode_obj_ro(struct pcep_object_header
*hdr
,
148 struct pcep_object_header
*pcep_decode_obj_lspa(struct pcep_object_header
*hdr
,
150 struct pcep_object_header
*pcep_decode_obj_svec(struct pcep_object_header
*hdr
,
152 struct pcep_object_header
*
153 pcep_decode_obj_notify(struct pcep_object_header
*hdr
, const uint8_t *buf
);
154 struct pcep_object_header
*pcep_decode_obj_error(struct pcep_object_header
*hdr
,
156 struct pcep_object_header
*pcep_decode_obj_close(struct pcep_object_header
*hdr
,
158 struct pcep_object_header
*pcep_decode_obj_srp(struct pcep_object_header
*hdr
,
160 struct pcep_object_header
*pcep_decode_obj_lsp(struct pcep_object_header
*hdr
,
162 struct pcep_object_header
*
163 pcep_decode_obj_vendor_info(struct pcep_object_header
*hdr
, const uint8_t *buf
);
164 struct pcep_object_header
*
165 pcep_decode_obj_inter_layer(struct pcep_object_header
*hdr
, const uint8_t *buf
);
166 struct pcep_object_header
*
167 pcep_decode_obj_switch_layer(struct pcep_object_header
*hdr
,
169 struct pcep_object_header
*
170 pcep_decode_obj_req_adap_cap(struct pcep_object_header
*hdr
,
172 struct pcep_object_header
*
173 pcep_decode_obj_server_ind(struct pcep_object_header
*hdr
, const uint8_t *buf
);
174 struct pcep_object_header
*
175 pcep_decode_obj_objective_function(struct pcep_object_header
*hdr
,
177 typedef struct pcep_object_header
*(*object_decoder_funcptr
)(
178 struct pcep_object_header
*, const uint8_t *buf
);
180 #define PCEP_DECODERS_ARGS struct pcep_object_header *, const uint8_t *buf
182 struct pcep_object_header
*(*const object_decoders
[MAX_OBJECT_ENCODER_INDEX
])(
183 PCEP_DECODERS_ARGS
) = {
184 [PCEP_OBJ_CLASS_OPEN
] = pcep_decode_obj_open
,
185 [PCEP_OBJ_CLASS_RP
] = pcep_decode_obj_rp
,
186 [PCEP_OBJ_CLASS_NOPATH
] = pcep_decode_obj_nopath
,
187 [PCEP_OBJ_CLASS_ENDPOINTS
] = pcep_decode_obj_endpoints
,
188 [PCEP_OBJ_CLASS_BANDWIDTH
] = pcep_decode_obj_bandwidth
,
189 [PCEP_OBJ_CLASS_METRIC
] = pcep_decode_obj_metric
,
190 [PCEP_OBJ_CLASS_ERO
] = pcep_decode_obj_ro
,
191 [PCEP_OBJ_CLASS_RRO
] = pcep_decode_obj_ro
,
192 [PCEP_OBJ_CLASS_LSPA
] = pcep_decode_obj_lspa
,
193 [PCEP_OBJ_CLASS_IRO
] = pcep_decode_obj_ro
,
194 [PCEP_OBJ_CLASS_SVEC
] = pcep_decode_obj_svec
,
195 [PCEP_OBJ_CLASS_NOTF
] = pcep_decode_obj_notify
,
196 [PCEP_OBJ_CLASS_ERROR
] = pcep_decode_obj_error
,
197 [PCEP_OBJ_CLASS_CLOSE
] = pcep_decode_obj_close
,
198 [PCEP_OBJ_CLASS_LSP
] = pcep_decode_obj_lsp
,
199 [PCEP_OBJ_CLASS_SRP
] = pcep_decode_obj_srp
,
200 [PCEP_OBJ_CLASS_ASSOCIATION
] = pcep_decode_obj_association
,
201 [PCEP_OBJ_CLASS_INTER_LAYER
] = pcep_decode_obj_inter_layer
,
202 [PCEP_OBJ_CLASS_SWITCH_LAYER
] = pcep_decode_obj_switch_layer
,
203 [PCEP_OBJ_CLASS_REQ_ADAP_CAP
] = pcep_decode_obj_req_adap_cap
,
204 [PCEP_OBJ_CLASS_SERVER_IND
] = pcep_decode_obj_server_ind
,
205 [PCEP_OBJ_CLASS_VENDOR_INFO
] = pcep_decode_obj_vendor_info
,
206 [PCEP_OBJ_CLASS_OF
] = pcep_decode_obj_objective_function
,
209 /* Object lengths, including the Object Header.
210 * Used by pcep_object_get_length() and pcep_object_has_tlvs() */
211 static uint8_t pcep_object_class_lengths
[] = {
212 0, /* Object class 0 unused */
213 8, /* PCEP_OBJ_CLASS_OPEN = 1 */
214 12, /* PCEP_OBJ_CLASS_RP = 2 */
215 16, /* PCEP_OBJ_CLASS_NOPATH = 3, includes 8 for mandatory TLV */
216 0, /* PCEP_OBJ_CLASS_ENDPOINTS = 4, could be ipv4 or ipv6, setting to 0
218 8, /* PCEP_OBJ_CLASS_BANDWIDTH = 5 */
219 12, /* PCEP_OBJ_CLASS_METRIC = 6 */
220 0, /* PCEP_OBJ_CLASS_ERO = 7, setting 0, ROs cannot have TLVs */
221 0, /* PCEP_OBJ_CLASS_RRO = 8, setting 0, ROs cannot have TLVs */
222 20, /* PCEP_OBJ_CLASS_LSPA = 9 */
223 0, /* PCEP_OBJ_CLASS_IRO = 10, setting 0, ROs cannot have TLVs */
224 0, /* PCEP_OBJ_CLASS_SVEC = 11, SVECs cannot have TLVs */
225 8, /* PCEP_OBJ_CLASS_NOTF = 12 */
226 8, /* PCEP_OBJ_CLASS_ERROR = 13 */
227 0, /* Object class 14 unused */
228 8, /* PCEP_OBJ_CLASS_CLOSE = 15 */
229 0, 0, 0, 0, 0, /* Object classes 16 - 20 are not used */
230 8, /* PCEP_OBJ_CLASS_OF = 21 */
231 0, 0, 0, 0, 0, /* Object classes 22 - 26 are not used */
232 0, 0, 0, 0, 0, /* Object classes 27 - 31 are not used */
233 8, /* PCEP_OBJ_CLASS_LSP = 32 */
234 12, /* PCEP_OBJ_CLASS_SRP = 33 */
235 12, /* PCEP_OBJ_CLASS_VENDOR_INFO = 34 */
236 0, /* Object class 35 unused */
237 0, /* PCEP_OBJ_CLASS_INTER_LAYER = 36, cannot have TLVs */
238 0, /* PCEP_OBJ_CLASS_SWITCH_LAYER = 37, cannot have TLVs */
239 0, /* PCEP_OBJ_CLASS_REQ_ADAP_CAP = 38, cannot have TLVs*/
240 8, /* PCEP_OBJ_CLASS_SERVER_IND = 39 */
241 0, /* PCEP_OBJ_CLASS_ASSOCIATION = 40, cannot have TLVs */
245 * The TLVs can have strange length values, since they do not include padding in
246 * the TLV header length, but that extra padding must be taken into account by
247 * the enclosing object by rounding up to the next 4 byte boundary.
248 * Example returned lengths:
249 * normalize_length(4) = 4, normalize_length(5) = 8, normalize_length(6)
250 * = 8, normalize_length(7) = 8, normalize_length(8) = 8
251 * normalize_length(9) = 12, normalize_length(10) = 12, normalize_length(11) =
252 * 12, normalize_length(12) = 12, normalize_length(13) = 13...
254 uint16_t normalize_pcep_tlv_length(uint16_t length
)
256 return (length
% 4 == 0) ? length
: (length
+ (4 - (length
% 4)));
262 uint16_t pcep_encode_object(struct pcep_object_header
*object_hdr
,
263 struct pcep_versioning
*versioning
, uint8_t *buf
)
266 if (object_hdr
->object_class
>= MAX_OBJECT_ENCODER_INDEX
) {
268 "%s: Cannot encode unknown Object class [%d]",
269 __func__
, object_hdr
->object_class
);
273 object_encoder_funcptr obj_encoder
=
274 object_encoders
[object_hdr
->object_class
];
275 if (obj_encoder
== NULL
) {
277 "%s: No object encoder found for Object class [%d]",
278 __func__
, object_hdr
->object_class
);
282 uint16_t object_length
= OBJECT_HEADER_LENGTH
283 + obj_encoder(object_hdr
, versioning
,
284 buf
+ OBJECT_HEADER_LENGTH
);
285 double_linked_list_node
*node
=
286 (object_hdr
->tlv_list
== NULL
? NULL
287 : object_hdr
->tlv_list
->head
);
288 for (; node
!= NULL
; node
= node
->next_node
) {
289 /* Returns the length of the TLV, including the TLV header */
290 object_length
+= pcep_encode_tlv(
291 (struct pcep_object_tlv_header
*)node
->data
, versioning
,
292 buf
+ object_length
);
294 object_length
= normalize_pcep_tlv_length(object_length
);
295 write_object_header(object_hdr
, object_length
, buf
);
296 object_hdr
->encoded_object
= buf
;
297 object_hdr
->encoded_object_length
= object_length
;
299 return object_length
;
306 * 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
307 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
308 * | Object-Class | OT |Res|P|I| Object Length (bytes) |
309 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
311 * // (Object body) //
313 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
317 void write_object_header(struct pcep_object_header
*object_hdr
,
318 uint16_t object_length
, uint8_t *buf
)
320 buf
[0] = object_hdr
->object_class
;
321 buf
[1] = ((object_hdr
->object_type
<< 4)
322 | (object_hdr
->flag_p
? OBJECT_HEADER_FLAG_P
: 0x00)
323 | (object_hdr
->flag_i
? OBJECT_HEADER_FLAG_I
: 0x00));
324 uint16_t net_order_length
= htons(object_length
);
325 memcpy(buf
+ 2, &net_order_length
, sizeof(net_order_length
));
330 * Functions to encode objects
331 * - they will be passed a pointer to a buffer to write the object body,
332 * which is past the object header.
333 * - they should return the object body length, not including the object header
337 uint16_t pcep_encode_obj_open(struct pcep_object_header
*hdr
,
338 struct pcep_versioning
*versioning
,
339 uint8_t *obj_body_buf
)
342 struct pcep_object_open
*open
= (struct pcep_object_open
*)hdr
;
343 obj_body_buf
[0] = (open
->open_version
<< 5) & 0xe0;
344 obj_body_buf
[1] = open
->open_keepalive
;
345 obj_body_buf
[2] = open
->open_deadtimer
;
346 obj_body_buf
[3] = open
->open_sid
;
351 uint16_t pcep_encode_obj_rp(struct pcep_object_header
*hdr
,
352 struct pcep_versioning
*versioning
,
353 uint8_t *obj_body_buf
)
356 struct pcep_object_rp
*rp
= (struct pcep_object_rp
*)hdr
;
357 obj_body_buf
[3] = ((rp
->flag_strict
? OBJECT_RP_FLAG_O
: 0x00)
358 | (rp
->flag_bidirectional
? OBJECT_RP_FLAG_B
: 0x00)
359 | (rp
->flag_reoptimization
? OBJECT_RP_FLAG_R
: 0x00)
360 | (rp
->flag_of
? OBJECT_RP_FLAG_OF
: 0x00)
361 | (rp
->priority
& 0x07));
362 uint32_t *uint32_ptr
= (uint32_t *)(obj_body_buf
+ 4);
363 *uint32_ptr
= htonl(rp
->request_id
);
365 return LENGTH_2WORDS
;
368 uint16_t pcep_encode_obj_notify(struct pcep_object_header
*hdr
,
369 struct pcep_versioning
*versioning
,
370 uint8_t *obj_body_buf
)
373 struct pcep_object_notify
*notify
= (struct pcep_object_notify
*)hdr
;
374 obj_body_buf
[2] = notify
->notification_type
;
375 obj_body_buf
[3] = notify
->notification_value
;
380 uint16_t pcep_encode_obj_nopath(struct pcep_object_header
*hdr
,
381 struct pcep_versioning
*versioning
,
382 uint8_t *obj_body_buf
)
385 struct pcep_object_nopath
*nopath
= (struct pcep_object_nopath
*)hdr
;
386 obj_body_buf
[0] = nopath
->ni
;
387 obj_body_buf
[1] = ((nopath
->flag_c
) ? OBJECT_NOPATH_FLAG_C
: 0x00);
392 uint16_t pcep_encode_obj_association(struct pcep_object_header
*hdr
,
393 struct pcep_versioning
*versioning
,
394 uint8_t *obj_body_buf
)
397 uint16_t *uint16_ptr
= (uint16_t *)obj_body_buf
;
398 uint32_t *uint32_ptr
= (uint32_t *)obj_body_buf
;
399 if (hdr
->object_type
== PCEP_OBJ_TYPE_ASSOCIATION_IPV4
) {
400 struct pcep_object_association_ipv4
*ipv4
=
401 (struct pcep_object_association_ipv4
*)hdr
;
403 (ipv4
->R_flag
? OBJECT_ASSOCIATION_FLAG_R
: 0x00);
404 uint16_ptr
[2] = htons(ipv4
->association_type
);
405 uint16_ptr
[3] = htons(ipv4
->association_id
);
406 uint32_ptr
[2] = ipv4
->src
.s_addr
;
408 return LENGTH_3WORDS
;
410 struct pcep_object_association_ipv6
*ipv6
=
411 (struct pcep_object_association_ipv6
*)hdr
;
413 (ipv6
->R_flag
? OBJECT_ASSOCIATION_FLAG_R
: 0x00);
414 uint16_ptr
[2] = htons(ipv6
->association_type
);
415 uint16_ptr
[3] = htons(ipv6
->association_id
);
416 memcpy(uint32_ptr
, &ipv6
->src
, sizeof(struct in6_addr
));
418 return LENGTH_6WORDS
;
422 uint16_t pcep_encode_obj_endpoints(struct pcep_object_header
*hdr
,
423 struct pcep_versioning
*versioning
,
424 uint8_t *obj_body_buf
)
427 uint32_t *uint32_ptr
= (uint32_t *)obj_body_buf
;
428 if (hdr
->object_type
== PCEP_OBJ_TYPE_ENDPOINT_IPV4
) {
429 struct pcep_object_endpoints_ipv4
*ipv4
=
430 (struct pcep_object_endpoints_ipv4
*)hdr
;
431 uint32_ptr
[0] = ipv4
->src_ipv4
.s_addr
;
432 uint32_ptr
[1] = ipv4
->dst_ipv4
.s_addr
;
434 return LENGTH_2WORDS
;
436 struct pcep_object_endpoints_ipv6
*ipv6
=
437 (struct pcep_object_endpoints_ipv6
*)hdr
;
438 memcpy(uint32_ptr
, &ipv6
->src_ipv6
, sizeof(struct in6_addr
));
439 memcpy(&uint32_ptr
[4], &ipv6
->dst_ipv6
,
440 sizeof(struct in6_addr
));
442 return LENGTH_8WORDS
;
446 uint16_t pcep_encode_obj_bandwidth(struct pcep_object_header
*hdr
,
447 struct pcep_versioning
*versioning
,
448 uint8_t *obj_body_buf
)
451 struct pcep_object_bandwidth
*bandwidth
=
452 (struct pcep_object_bandwidth
*)hdr
;
453 uint32_t *uint32_ptr
= (uint32_t *)obj_body_buf
;
454 /* Seems like the compiler doesn't correctly copy the float, so memcpy()
456 memcpy(uint32_ptr
, &(bandwidth
->bandwidth
), sizeof(uint32_t));
457 *uint32_ptr
= htonl(*uint32_ptr
);
462 uint16_t pcep_encode_obj_metric(struct pcep_object_header
*hdr
,
463 struct pcep_versioning
*versioning
,
464 uint8_t *obj_body_buf
)
467 struct pcep_object_metric
*metric
= (struct pcep_object_metric
*)hdr
;
468 obj_body_buf
[2] = ((metric
->flag_c
? OBJECT_METRIC_FLAC_C
: 0x00)
469 | (metric
->flag_b
? OBJECT_METRIC_FLAC_B
: 0x00));
470 obj_body_buf
[3] = metric
->type
;
471 uint32_t *uint32_ptr
= (uint32_t *)(obj_body_buf
+ 4);
472 /* Seems like the compiler doesn't correctly copy the float, so memcpy()
474 memcpy(uint32_ptr
, &(metric
->value
), sizeof(uint32_t));
475 *uint32_ptr
= htonl(*uint32_ptr
);
477 return LENGTH_2WORDS
;
480 uint16_t pcep_encode_obj_lspa(struct pcep_object_header
*hdr
,
481 struct pcep_versioning
*versioning
,
482 uint8_t *obj_body_buf
)
485 struct pcep_object_lspa
*lspa
= (struct pcep_object_lspa
*)hdr
;
486 uint32_t *uint32_ptr
= (uint32_t *)obj_body_buf
;
487 uint32_ptr
[0] = htonl(lspa
->lspa_exclude_any
);
488 uint32_ptr
[1] = htonl(lspa
->lspa_include_any
);
489 uint32_ptr
[2] = htonl(lspa
->lspa_include_all
);
490 obj_body_buf
[12] = lspa
->setup_priority
;
491 obj_body_buf
[13] = lspa
->holding_priority
;
493 (lspa
->flag_local_protection
? OBJECT_LSPA_FLAG_L
: 0x00);
495 return LENGTH_4WORDS
;
498 uint16_t pcep_encode_obj_svec(struct pcep_object_header
*hdr
,
499 struct pcep_versioning
*versioning
,
500 uint8_t *obj_body_buf
)
503 struct pcep_object_svec
*svec
= (struct pcep_object_svec
*)hdr
;
505 ((svec
->flag_srlg_diverse
? OBJECT_SVEC_FLAG_S
: 0x00)
506 | (svec
->flag_node_diverse
? OBJECT_SVEC_FLAG_N
: 0x00)
507 | (svec
->flag_link_diverse
? OBJECT_SVEC_FLAG_L
: 0x00));
509 if (svec
->request_id_list
== NULL
) {
514 uint32_t *uint32_ptr
= (uint32_t *)obj_body_buf
;
515 double_linked_list_node
*node
= svec
->request_id_list
->head
;
516 for (; node
!= NULL
; node
= node
->next_node
) {
517 uint32_ptr
[index
++] = htonl(*((uint32_t *)(node
->data
)));
521 + (svec
->request_id_list
->num_entries
* sizeof(uint32_t));
524 uint16_t pcep_encode_obj_error(struct pcep_object_header
*hdr
,
525 struct pcep_versioning
*versioning
,
526 uint8_t *obj_body_buf
)
529 struct pcep_object_error
*error
= (struct pcep_object_error
*)hdr
;
530 obj_body_buf
[2] = error
->error_type
;
531 obj_body_buf
[3] = error
->error_value
;
536 uint16_t pcep_encode_obj_close(struct pcep_object_header
*hdr
,
537 struct pcep_versioning
*versioning
,
538 uint8_t *obj_body_buf
)
541 struct pcep_object_close
*close
= (struct pcep_object_close
*)hdr
;
542 obj_body_buf
[3] = close
->reason
;
547 uint16_t pcep_encode_obj_srp(struct pcep_object_header
*hdr
,
548 struct pcep_versioning
*versioning
,
549 uint8_t *obj_body_buf
)
552 struct pcep_object_srp
*srp
= (struct pcep_object_srp
*)hdr
;
553 obj_body_buf
[3] = (srp
->flag_lsp_remove
? OBJECT_SRP_FLAG_R
: 0x00);
554 uint32_t *uint32_ptr
= (uint32_t *)(obj_body_buf
+ 4);
555 *uint32_ptr
= htonl(srp
->srp_id_number
);
557 return LENGTH_2WORDS
;
560 uint16_t pcep_encode_obj_lsp(struct pcep_object_header
*hdr
,
561 struct pcep_versioning
*versioning
,
562 uint8_t *obj_body_buf
)
565 struct pcep_object_lsp
*lsp
= (struct pcep_object_lsp
*)hdr
;
566 uint32_t *uint32_ptr
= (uint32_t *)obj_body_buf
;
567 uint32_ptr
[0] = htonl((lsp
->plsp_id
<< 12) & 0xfffff000);
568 obj_body_buf
[3] = ((lsp
->flag_c
? OBJECT_LSP_FLAG_C
: 0x00)
569 | ((lsp
->operational_status
<< 4) & 0x70)
570 | (lsp
->flag_a
? OBJECT_LSP_FLAG_A
: 0x00)
571 | (lsp
->flag_r
? OBJECT_LSP_FLAG_R
: 0x00)
572 | (lsp
->flag_s
? OBJECT_LSP_FLAG_S
: 0x00)
573 | (lsp
->flag_d
? OBJECT_LSP_FLAG_D
: 0x00));
578 uint16_t pcep_encode_obj_vendor_info(struct pcep_object_header
*hdr
,
579 struct pcep_versioning
*versioning
,
580 uint8_t *obj_body_buf
)
583 struct pcep_object_vendor_info
*obj
=
584 (struct pcep_object_vendor_info
*)hdr
;
585 uint32_t *uint32_ptr
= (uint32_t *)obj_body_buf
;
586 uint32_ptr
[0] = htonl(obj
->enterprise_number
);
587 uint32_ptr
[1] = htonl(obj
->enterprise_specific_info
);
589 return LENGTH_2WORDS
;
592 uint16_t pcep_encode_obj_inter_layer(struct pcep_object_header
*hdr
,
593 struct pcep_versioning
*versioning
,
594 uint8_t *obj_body_buf
)
597 struct pcep_object_inter_layer
*obj
=
598 (struct pcep_object_inter_layer
*)hdr
;
599 obj_body_buf
[3] = ((obj
->flag_i
? OBJECT_INTER_LAYER_FLAG_I
: 0x00)
600 | (obj
->flag_m
? OBJECT_INTER_LAYER_FLAG_M
: 0x00)
601 | (obj
->flag_t
? OBJECT_INTER_LAYER_FLAG_T
: 0x00));
606 uint16_t pcep_encode_obj_switch_layer(struct pcep_object_header
*hdr
,
607 struct pcep_versioning
*versioning
,
608 uint8_t *obj_body_buf
)
611 struct pcep_object_switch_layer
*obj
=
612 (struct pcep_object_switch_layer
*)hdr
;
613 uint8_t buf_index
= 0;
615 double_linked_list_node
*node
= obj
->switch_layer_rows
->head
;
616 while (node
!= NULL
) {
617 struct pcep_object_switch_layer_row
*row
= node
->data
;
622 obj_body_buf
[buf_index
] = row
->lsp_encoding_type
;
623 obj_body_buf
[buf_index
+ 1] = row
->switching_type
;
624 obj_body_buf
[buf_index
+ 3] =
625 (row
->flag_i
? OBJECT_SWITCH_LAYER_FLAG_I
: 0x00);
627 buf_index
+= LENGTH_1WORD
;
633 uint16_t pcep_encode_obj_req_adap_cap(struct pcep_object_header
*hdr
,
634 struct pcep_versioning
*versioning
,
635 uint8_t *obj_body_buf
)
638 struct pcep_object_req_adap_cap
*obj
=
639 (struct pcep_object_req_adap_cap
*)hdr
;
641 obj_body_buf
[0] = obj
->switching_capability
;
642 obj_body_buf
[1] = obj
->encoding
;
647 uint16_t pcep_encode_obj_server_ind(struct pcep_object_header
*hdr
,
648 struct pcep_versioning
*versioning
,
649 uint8_t *obj_body_buf
)
652 struct pcep_object_server_indication
*obj
=
653 (struct pcep_object_server_indication
*)hdr
;
655 obj_body_buf
[0] = obj
->switching_capability
;
656 obj_body_buf
[1] = obj
->encoding
;
661 uint16_t pcep_encode_obj_objective_function(struct pcep_object_header
*hdr
,
662 struct pcep_versioning
*versioning
,
663 uint8_t *obj_body_buf
)
666 struct pcep_object_objective_function
*obj
=
667 (struct pcep_object_objective_function
*)hdr
;
669 uint16_t *uint16_ptr
= (uint16_t *)obj_body_buf
;
670 *uint16_ptr
= htons(obj
->of_code
);
675 uint16_t pcep_encode_obj_ro(struct pcep_object_header
*hdr
,
676 struct pcep_versioning
*versioning
,
677 uint8_t *obj_body_buf
)
680 struct pcep_object_ro
*ro
= (struct pcep_object_ro
*)hdr
;
681 if (ro
== NULL
|| ro
->sub_objects
== NULL
) {
685 /* RO Subobject format
688 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
689 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------//----------------+
690 * |L| Type | Length | (Subobject contents) |
691 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------//----------------+
695 double_linked_list_node
*node
= ro
->sub_objects
->head
;
696 for (; node
!= NULL
; node
= node
->next_node
) {
697 struct pcep_object_ro_subobj
*ro_subobj
= node
->data
;
698 obj_body_buf
[index
++] =
699 ((ro_subobj
->flag_subobj_loose_hop
? 0x80 : 0x00)
700 | (ro_subobj
->ro_subobj_type
));
701 /* The length will be written below, depending on the subobj
703 uint8_t *length_ptr
= &(obj_body_buf
[index
++]);
704 uint32_t *uint32_ptr
= (uint32_t *)(obj_body_buf
+ index
);
706 /* - The index has already been incremented past the header,
707 * and now points to the ro_subobj body. Below it just needs
708 * to be incremented past the body.
710 * - Each section below needs to write the total length,
711 * including the 2 byte subobj header. */
713 switch (ro_subobj
->ro_subobj_type
) {
714 case RO_SUBOBJ_TYPE_IPV4
: {
715 struct pcep_ro_subobj_ipv4
*ipv4
=
716 (struct pcep_ro_subobj_ipv4
*)ro_subobj
;
717 uint32_ptr
[0] = ipv4
->ip_addr
.s_addr
;
718 index
+= LENGTH_1WORD
;
719 obj_body_buf
[index
++] = ipv4
->prefix_length
;
720 obj_body_buf
[index
++] =
721 (ipv4
->flag_local_protection
722 ? OBJECT_SUBOBJ_IP_FLAG_LOCAL_PROT
724 *length_ptr
= LENGTH_2WORDS
;
727 case RO_SUBOBJ_TYPE_IPV6
: {
728 struct pcep_ro_subobj_ipv6
*ipv6
=
729 (struct pcep_ro_subobj_ipv6
*)ro_subobj
;
730 encode_ipv6(&ipv6
->ip_addr
, uint32_ptr
);
731 index
+= LENGTH_4WORDS
;
732 obj_body_buf
[index
++] = ipv6
->prefix_length
;
733 obj_body_buf
[index
++] =
734 (ipv6
->flag_local_protection
735 ? OBJECT_SUBOBJ_IP_FLAG_LOCAL_PROT
737 *length_ptr
= LENGTH_5WORDS
;
740 case RO_SUBOBJ_TYPE_LABEL
: {
741 struct pcep_ro_subobj_32label
*label
=
742 (struct pcep_ro_subobj_32label
*)ro_subobj
;
743 obj_body_buf
[index
++] =
744 (label
->flag_global_label
745 ? OBJECT_SUBOBJ_LABEL_FLAG_GLOGAL
747 obj_body_buf
[index
++] = label
->class_type
;
748 uint32_ptr
= (uint32_t *)(obj_body_buf
+ index
);
749 *uint32_ptr
= htonl(label
->label
);
750 *length_ptr
= LENGTH_2WORDS
;
751 index
+= LENGTH_1WORD
;
754 case RO_SUBOBJ_TYPE_UNNUM
: {
755 struct pcep_ro_subobj_unnum
*unum
=
756 (struct pcep_ro_subobj_unnum
*)ro_subobj
;
757 index
+= 2; /* increment past 2 reserved bytes */
758 uint32_ptr
= (uint32_t *)(obj_body_buf
+ index
);
759 uint32_ptr
[0] = unum
->router_id
.s_addr
;
760 uint32_ptr
[1] = htonl(unum
->interface_id
);
761 *length_ptr
= LENGTH_3WORDS
;
762 index
+= LENGTH_2WORDS
;
765 case RO_SUBOBJ_TYPE_ASN
: {
766 struct pcep_ro_subobj_asn
*asn
=
767 (struct pcep_ro_subobj_asn
*)ro_subobj
;
768 uint16_t *uint16_ptr
=
769 (uint16_t *)(obj_body_buf
+ index
);
770 *uint16_ptr
= htons(asn
->asn
);
771 *length_ptr
= LENGTH_1WORD
;
775 case RO_SUBOBJ_TYPE_SR
: {
776 /* SR-ERO subobject format
779 * 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
780 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
781 * |L| Type=36 | Length | NT | Flags
783 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
785 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
786 * // NAI (variable, optional) //
787 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
790 struct pcep_ro_subobj_sr
*sr_subobj
=
791 (struct pcep_ro_subobj_sr
*)ro_subobj
;
792 obj_body_buf
[index
++] =
793 ((sr_subobj
->nai_type
<< 4) & 0xf0);
794 obj_body_buf
[index
++] =
795 ((sr_subobj
->flag_f
? OBJECT_SUBOBJ_SR_FLAG_F
797 | (sr_subobj
->flag_s
? OBJECT_SUBOBJ_SR_FLAG_S
799 | (sr_subobj
->flag_c
? OBJECT_SUBOBJ_SR_FLAG_C
801 | (sr_subobj
->flag_m
? OBJECT_SUBOBJ_SR_FLAG_M
803 uint32_ptr
= (uint32_t *)(obj_body_buf
+ index
);
804 /* Start with LENGTH_1WORD for the SubObj HDR + NT +
806 uint8_t sr_base_length
= LENGTH_1WORD
;
807 /* If the sid_absent flag is true, then dont convert the
809 if (sr_subobj
->flag_s
== false) {
810 uint32_ptr
[0] = htonl(sr_subobj
->sid
);
811 index
+= LENGTH_1WORD
;
812 uint32_ptr
= (uint32_t *)(obj_body_buf
+ index
);
813 sr_base_length
+= LENGTH_1WORD
;
816 /* The lengths below need to include:
817 * - sr_base_length: set above to include SR SubObj Hdr
818 * and the SID if present
819 * - Number of bytes written to the NAI
820 * The index will only be incremented below by the
821 * number of bytes written to the NAI, since the RO SR
822 * subobj header and the SID have already been written.
825 double_linked_list_node
*nai_node
=
826 (sr_subobj
->nai_list
== NULL
828 : sr_subobj
->nai_list
->head
);
829 if (nai_node
== NULL
) {
830 if (sr_subobj
->nai_type
831 == PCEP_SR_SUBOBJ_NAI_ABSENT
) {
832 *length_ptr
= sr_base_length
;
838 switch (sr_subobj
->nai_type
) {
839 case PCEP_SR_SUBOBJ_NAI_IPV4_NODE
:
841 ((struct in_addr
*)nai_node
->data
)
843 *length_ptr
= sr_base_length
+ LENGTH_1WORD
;
844 index
+= LENGTH_1WORD
;
847 case PCEP_SR_SUBOBJ_NAI_IPV6_NODE
:
848 encode_ipv6((struct in6_addr
*)nai_node
->data
,
850 *length_ptr
= sr_base_length
+ LENGTH_4WORDS
;
851 index
+= LENGTH_4WORDS
;
854 case PCEP_SR_SUBOBJ_NAI_UNNUMBERED_IPV4_ADJACENCY
:
856 ((struct in_addr
*)nai_node
->data
)
858 nai_node
= nai_node
->next_node
;
860 ((struct in_addr
*)nai_node
->data
)
862 nai_node
= nai_node
->next_node
;
864 ((struct in_addr
*)nai_node
->data
)
866 nai_node
= nai_node
->next_node
;
868 ((struct in_addr
*)nai_node
->data
)
870 *length_ptr
= sr_base_length
+ LENGTH_4WORDS
;
871 index
+= LENGTH_4WORDS
;
874 case PCEP_SR_SUBOBJ_NAI_IPV4_ADJACENCY
:
876 ((struct in_addr
*)nai_node
->data
)
878 nai_node
= nai_node
->next_node
;
880 ((struct in_addr
*)nai_node
->data
)
882 *length_ptr
= sr_base_length
+ LENGTH_2WORDS
;
883 index
+= LENGTH_2WORDS
;
886 case PCEP_SR_SUBOBJ_NAI_IPV6_ADJACENCY
:
887 encode_ipv6((struct in6_addr
*)nai_node
->data
,
889 nai_node
= nai_node
->next_node
;
890 encode_ipv6((struct in6_addr
*)nai_node
->data
,
892 *length_ptr
= sr_base_length
+ LENGTH_8WORDS
;
893 index
+= LENGTH_8WORDS
;
896 case PCEP_SR_SUBOBJ_NAI_LINK_LOCAL_IPV6_ADJACENCY
:
897 encode_ipv6((struct in6_addr
*)nai_node
->data
,
899 nai_node
= nai_node
->next_node
;
901 ((struct in_addr
*)nai_node
->data
)
903 nai_node
= nai_node
->next_node
;
904 encode_ipv6((struct in6_addr
*)nai_node
->data
,
906 nai_node
= nai_node
->next_node
;
908 ((struct in_addr
*)nai_node
->data
)
910 *length_ptr
= sr_base_length
+ LENGTH_10WORDS
;
911 index
+= LENGTH_10WORDS
;
914 case PCEP_SR_SUBOBJ_NAI_ABSENT
:
915 case PCEP_SR_SUBOBJ_NAI_UNKNOWN
:
920 case RO_SUBOBJ_UNKNOWN
:
928 void encode_ipv6(struct in6_addr
*src_ipv6
, uint32_t *dst
)
930 memcpy(dst
, src_ipv6
, sizeof(struct in6_addr
));
934 * Decoding functions.
937 void pcep_decode_object_hdr(const uint8_t *obj_buf
,
938 struct pcep_object_header
*obj_hdr
)
940 memset(obj_hdr
, 0, sizeof(struct pcep_object_header
));
942 obj_hdr
->object_class
= obj_buf
[0];
943 obj_hdr
->object_type
= (obj_buf
[1] >> 4) & 0x0f;
944 obj_hdr
->flag_p
= (obj_buf
[1] & OBJECT_HEADER_FLAG_P
);
945 obj_hdr
->flag_i
= (obj_buf
[1] & OBJECT_HEADER_FLAG_I
);
946 uint16_t net_order_length
;
947 memcpy(&net_order_length
, obj_buf
+ 2, sizeof(net_order_length
));
948 obj_hdr
->encoded_object_length
= ntohs(net_order_length
);
949 obj_hdr
->encoded_object
= obj_buf
;
952 uint16_t pcep_object_get_length(enum pcep_object_classes object_class
,
953 enum pcep_object_types object_type
)
955 uint8_t object_length
= pcep_object_class_lengths
[object_class
];
956 if (object_length
== 0) {
957 if (object_class
== PCEP_OBJ_CLASS_ENDPOINTS
) {
958 if (object_type
== PCEP_OBJ_TYPE_ENDPOINT_IPV4
) {
960 } else if (object_type
== PCEP_OBJ_TYPE_ENDPOINT_IPV6
) {
968 return object_length
;
971 uint16_t pcep_object_get_length_by_hdr(struct pcep_object_header
*object_hdr
)
973 return (pcep_object_get_length(object_hdr
->object_class
,
974 object_hdr
->object_type
));
977 bool pcep_object_has_tlvs(struct pcep_object_header
*object_hdr
)
979 uint8_t object_length
= pcep_object_get_length_by_hdr(object_hdr
);
980 if (object_length
== 0) {
984 return (object_hdr
->encoded_object_length
- object_length
) > 0;
987 struct pcep_object_header
*pcep_decode_object(const uint8_t *obj_buf
)
990 struct pcep_object_header object_hdr
;
991 /* Only initializes and decodes the Object Header: class, type, flags,
993 pcep_decode_object_hdr(obj_buf
, &object_hdr
);
995 if (object_hdr
.object_class
>= MAX_OBJECT_ENCODER_INDEX
) {
997 "%s: Cannot decode unknown Object class [%d]",
998 __func__
, object_hdr
.object_class
);
1002 object_decoder_funcptr obj_decoder
=
1003 object_decoders
[object_hdr
.object_class
];
1004 if (obj_decoder
== NULL
) {
1006 "%s: No object decoder found for Object class [%d]",
1007 __func__
, object_hdr
.object_class
);
1011 /* The object decoders will start decoding the object body, if
1012 * anything from the header is needed, they have the object_hdr */
1013 struct pcep_object_header
*object
=
1014 obj_decoder(&object_hdr
, obj_buf
+ OBJECT_HEADER_LENGTH
);
1015 if (object
== NULL
) {
1016 pcep_log(LOG_INFO
, "%s: Unable to decode Object class [%d].",
1017 __func__
, object_hdr
.object_class
);
1021 if (pcep_object_has_tlvs(&object_hdr
)) {
1022 object
->tlv_list
= dll_initialize();
1023 int num_iterations
= 0;
1024 uint16_t tlv_index
= pcep_object_get_length_by_hdr(&object_hdr
);
1025 while ((object
->encoded_object_length
- tlv_index
) > 0
1026 && num_iterations
++ < MAX_ITERATIONS
) {
1027 struct pcep_object_tlv_header
*tlv
=
1028 pcep_decode_tlv(obj_buf
+ tlv_index
);
1030 /* TODO should we do anything else here ? */
1034 /* The TLV length does not include the TLV header */
1035 tlv_index
+= normalize_pcep_tlv_length(
1036 tlv
->encoded_tlv_length
+ TLV_HEADER_LENGTH
);
1037 dll_append(object
->tlv_list
, tlv
);
1044 static struct pcep_object_header
*
1045 common_object_create(struct pcep_object_header
*hdr
, uint16_t new_obj_length
)
1047 struct pcep_object_header
*new_object
=
1048 pceplib_malloc(PCEPLIB_MESSAGES
, new_obj_length
);
1049 memset(new_object
, 0, new_obj_length
);
1050 memcpy(new_object
, hdr
, sizeof(struct pcep_object_header
));
1059 struct pcep_object_header
*pcep_decode_obj_open(struct pcep_object_header
*hdr
,
1060 const uint8_t *obj_buf
)
1062 struct pcep_object_open
*obj
=
1063 (struct pcep_object_open
*)common_object_create(
1064 hdr
, sizeof(struct pcep_object_open
));
1066 obj
->open_version
= (obj_buf
[0] >> 5) & 0x07;
1067 obj
->open_keepalive
= obj_buf
[1];
1068 obj
->open_deadtimer
= obj_buf
[2];
1069 obj
->open_sid
= obj_buf
[3];
1071 return (struct pcep_object_header
*)obj
;
1074 struct pcep_object_header
*pcep_decode_obj_rp(struct pcep_object_header
*hdr
,
1075 const uint8_t *obj_buf
)
1077 struct pcep_object_rp
*obj
=
1078 (struct pcep_object_rp
*)common_object_create(
1079 hdr
, sizeof(struct pcep_object_rp
));
1081 obj
->flag_reoptimization
= (obj_buf
[3] & OBJECT_RP_FLAG_R
);
1082 obj
->flag_bidirectional
= (obj_buf
[3] & OBJECT_RP_FLAG_B
);
1083 obj
->flag_strict
= (obj_buf
[3] & OBJECT_RP_FLAG_O
);
1084 obj
->flag_of
= (obj_buf
[3] & OBJECT_RP_FLAG_OF
);
1085 obj
->priority
= (obj_buf
[3] & 0x07);
1086 obj
->request_id
= ntohl(*((uint32_t *)(obj_buf
+ 4)));
1088 return (struct pcep_object_header
*)obj
;
1091 struct pcep_object_header
*
1092 pcep_decode_obj_notify(struct pcep_object_header
*hdr
, const uint8_t *obj_buf
)
1094 struct pcep_object_notify
*obj
=
1095 (struct pcep_object_notify
*)common_object_create(
1096 hdr
, sizeof(struct pcep_object_notify
));
1098 obj
->notification_type
= obj_buf
[2];
1099 obj
->notification_value
= obj_buf
[3];
1101 return (struct pcep_object_header
*)obj
;
1104 struct pcep_object_header
*
1105 pcep_decode_obj_nopath(struct pcep_object_header
*hdr
, const uint8_t *obj_buf
)
1107 struct pcep_object_nopath
*obj
=
1108 (struct pcep_object_nopath
*)common_object_create(
1109 hdr
, sizeof(struct pcep_object_nopath
));
1111 obj
->ni
= (obj_buf
[0] >> 1);
1112 obj
->flag_c
= (obj_buf
[0] & OBJECT_NOPATH_FLAG_C
);
1114 return (struct pcep_object_header
*)obj
;
1117 struct pcep_object_header
*
1118 pcep_decode_obj_association(struct pcep_object_header
*hdr
,
1119 const uint8_t *obj_buf
)
1121 uint16_t *uint16_ptr
= (uint16_t *)obj_buf
;
1122 uint32_t *uint32_ptr
= (uint32_t *)obj_buf
;
1124 if (hdr
->object_type
== PCEP_OBJ_TYPE_ASSOCIATION_IPV4
) {
1125 struct pcep_object_association_ipv4
*obj
=
1126 (struct pcep_object_association_ipv4
*)
1127 common_object_create(
1130 pcep_object_association_ipv4
));
1131 obj
->R_flag
= (obj_buf
[3] & OBJECT_ASSOCIATION_FLAG_R
);
1132 obj
->association_type
= ntohs(uint16_ptr
[2]);
1133 obj
->association_id
= ntohs(uint16_ptr
[3]);
1134 obj
->src
.s_addr
= uint32_ptr
[2];
1136 return (struct pcep_object_header
*)obj
;
1137 } else if (hdr
->object_type
== PCEP_OBJ_TYPE_ENDPOINT_IPV6
) {
1138 struct pcep_object_association_ipv6
*obj
=
1139 (struct pcep_object_association_ipv6
*)
1140 common_object_create(
1143 pcep_object_association_ipv6
));
1145 obj
->R_flag
= (obj_buf
[3] & OBJECT_ASSOCIATION_FLAG_R
);
1146 obj
->association_type
= ntohs(uint16_ptr
[2]);
1147 obj
->association_id
= ntohs(uint16_ptr
[3]);
1148 memcpy(&obj
->src
, &uint32_ptr
[2], sizeof(struct in6_addr
));
1150 return (struct pcep_object_header
*)obj
;
1155 struct pcep_object_header
*
1156 pcep_decode_obj_endpoints(struct pcep_object_header
*hdr
,
1157 const uint8_t *obj_buf
)
1159 uint32_t *uint32_ptr
= (uint32_t *)obj_buf
;
1161 if (hdr
->object_type
== PCEP_OBJ_TYPE_ENDPOINT_IPV4
) {
1162 struct pcep_object_endpoints_ipv4
*obj
=
1163 (struct pcep_object_endpoints_ipv4
*)
1164 common_object_create(
1167 pcep_object_endpoints_ipv4
));
1168 obj
->src_ipv4
.s_addr
= uint32_ptr
[0];
1169 obj
->dst_ipv4
.s_addr
= uint32_ptr
[1];
1171 return (struct pcep_object_header
*)obj
;
1172 } else if (hdr
->object_type
== PCEP_OBJ_TYPE_ENDPOINT_IPV6
) {
1173 struct pcep_object_endpoints_ipv6
*obj
=
1174 (struct pcep_object_endpoints_ipv6
*)
1175 common_object_create(
1178 pcep_object_endpoints_ipv6
));
1180 memcpy(&obj
->src_ipv6
, &uint32_ptr
[0], sizeof(struct in6_addr
));
1181 memcpy(&obj
->dst_ipv6
, &uint32_ptr
[4], sizeof(struct in6_addr
));
1183 return (struct pcep_object_header
*)obj
;
1189 struct pcep_object_header
*
1190 pcep_decode_obj_bandwidth(struct pcep_object_header
*hdr
,
1191 const uint8_t *obj_buf
)
1193 struct pcep_object_bandwidth
*obj
=
1194 (struct pcep_object_bandwidth
*)common_object_create(
1195 hdr
, sizeof(struct pcep_object_bandwidth
));
1197 uint32_t value
= ntohl(*((uint32_t *)obj_buf
));
1198 /* Seems like the compiler doesn't correctly copy to the float, so
1200 memcpy(&obj
->bandwidth
, &value
, sizeof(uint32_t));
1202 return (struct pcep_object_header
*)obj
;
1205 struct pcep_object_header
*
1206 pcep_decode_obj_metric(struct pcep_object_header
*hdr
, const uint8_t *obj_buf
)
1208 struct pcep_object_metric
*obj
=
1209 (struct pcep_object_metric
*)common_object_create(
1210 hdr
, sizeof(struct pcep_object_metric
));
1211 obj
->flag_b
= (obj_buf
[2] & OBJECT_METRIC_FLAC_B
);
1212 obj
->flag_c
= (obj_buf
[2] & OBJECT_METRIC_FLAC_C
);
1213 obj
->type
= obj_buf
[3];
1214 uint32_t value
= ntohl(*((uint32_t *)(obj_buf
+ 4)));
1215 /* Seems like the compiler doesn't correctly copy to the float, so
1217 memcpy(&obj
->value
, &value
, sizeof(uint32_t));
1219 return (struct pcep_object_header
*)obj
;
1222 struct pcep_object_header
*pcep_decode_obj_lspa(struct pcep_object_header
*hdr
,
1223 const uint8_t *obj_buf
)
1225 struct pcep_object_lspa
*obj
=
1226 (struct pcep_object_lspa
*)common_object_create(
1227 hdr
, sizeof(struct pcep_object_lspa
));
1228 uint32_t *uint32_ptr
= (uint32_t *)obj_buf
;
1230 obj
->lspa_exclude_any
= ntohl(uint32_ptr
[0]);
1231 obj
->lspa_include_any
= ntohl(uint32_ptr
[1]);
1232 obj
->lspa_include_all
= ntohl(uint32_ptr
[2]);
1233 obj
->setup_priority
= obj_buf
[12];
1234 obj
->holding_priority
= obj_buf
[13];
1235 obj
->flag_local_protection
= (obj_buf
[14] & OBJECT_LSPA_FLAG_L
);
1237 return (struct pcep_object_header
*)obj
;
1240 struct pcep_object_header
*pcep_decode_obj_svec(struct pcep_object_header
*hdr
,
1241 const uint8_t *obj_buf
)
1243 struct pcep_object_svec
*obj
=
1244 (struct pcep_object_svec
*)common_object_create(
1245 hdr
, sizeof(struct pcep_object_svec
));
1247 obj
->flag_link_diverse
= (obj_buf
[3] & OBJECT_SVEC_FLAG_L
);
1248 obj
->flag_node_diverse
= (obj_buf
[3] & OBJECT_SVEC_FLAG_N
);
1249 obj
->flag_srlg_diverse
= (obj_buf
[3] & OBJECT_SVEC_FLAG_S
);
1251 if (hdr
->encoded_object_length
> LENGTH_2WORDS
) {
1252 obj
->request_id_list
= dll_initialize();
1254 uint32_t *uint32_ptr
= (uint32_t *)obj_buf
;
1256 index
< ((hdr
->encoded_object_length
- LENGTH_2WORDS
) / 4);
1258 uint32_t *req_id_ptr
= pceplib_malloc(PCEPLIB_MESSAGES
,
1260 *req_id_ptr
= uint32_ptr
[index
];
1261 dll_append(obj
->request_id_list
, req_id_ptr
);
1265 return (struct pcep_object_header
*)obj
;
1268 struct pcep_object_header
*pcep_decode_obj_error(struct pcep_object_header
*hdr
,
1269 const uint8_t *obj_buf
)
1271 struct pcep_object_error
*obj
=
1272 (struct pcep_object_error
*)common_object_create(
1273 hdr
, sizeof(struct pcep_object_error
));
1275 obj
->error_type
= obj_buf
[2];
1276 obj
->error_value
= obj_buf
[3];
1278 return (struct pcep_object_header
*)obj
;
1281 struct pcep_object_header
*pcep_decode_obj_close(struct pcep_object_header
*hdr
,
1282 const uint8_t *obj_buf
)
1284 struct pcep_object_close
*obj
=
1285 (struct pcep_object_close
*)common_object_create(
1286 hdr
, sizeof(struct pcep_object_close
));
1288 obj
->reason
= obj_buf
[3];
1290 return (struct pcep_object_header
*)obj
;
1293 struct pcep_object_header
*pcep_decode_obj_srp(struct pcep_object_header
*hdr
,
1294 const uint8_t *obj_buf
)
1296 struct pcep_object_srp
*obj
=
1297 (struct pcep_object_srp
*)common_object_create(
1298 hdr
, sizeof(struct pcep_object_srp
));
1300 obj
->flag_lsp_remove
= (obj_buf
[3] & OBJECT_SRP_FLAG_R
);
1301 obj
->srp_id_number
= ntohl(*((uint32_t *)(obj_buf
+ 4)));
1303 return (struct pcep_object_header
*)obj
;
1306 struct pcep_object_header
*pcep_decode_obj_lsp(struct pcep_object_header
*hdr
,
1307 const uint8_t *obj_buf
)
1309 struct pcep_object_lsp
*obj
=
1310 (struct pcep_object_lsp
*)common_object_create(
1311 hdr
, sizeof(struct pcep_object_lsp
));
1313 obj
->flag_d
= (obj_buf
[3] & OBJECT_LSP_FLAG_D
);
1314 obj
->flag_s
= (obj_buf
[3] & OBJECT_LSP_FLAG_S
);
1315 obj
->flag_r
= (obj_buf
[3] & OBJECT_LSP_FLAG_R
);
1316 obj
->flag_a
= (obj_buf
[3] & OBJECT_LSP_FLAG_A
);
1317 obj
->flag_c
= (obj_buf
[3] & OBJECT_LSP_FLAG_C
);
1318 obj
->operational_status
= ((obj_buf
[3] >> 4) & 0x07);
1319 obj
->plsp_id
= ((ntohl(*((uint32_t *)obj_buf
)) >> 12) & 0x000fffff);
1321 return (struct pcep_object_header
*)obj
;
1324 struct pcep_object_header
*
1325 pcep_decode_obj_vendor_info(struct pcep_object_header
*hdr
,
1326 const uint8_t *obj_buf
)
1328 struct pcep_object_vendor_info
*obj
=
1329 (struct pcep_object_vendor_info
*)common_object_create(
1330 hdr
, sizeof(struct pcep_object_vendor_info
));
1332 obj
->enterprise_number
= ntohl(*((uint32_t *)(obj_buf
)));
1333 obj
->enterprise_specific_info
= ntohl(*((uint32_t *)(obj_buf
+ 4)));
1334 if (obj
->enterprise_number
== ENTERPRISE_NUMBER_CISCO
1335 && obj
->enterprise_specific_info
== ENTERPRISE_COLOR_CISCO
)
1336 obj
->enterprise_specific_info1
=
1337 ntohl(*((uint32_t *)(obj_buf
+ 8)));
1339 obj
->enterprise_specific_info1
= 0;
1341 return (struct pcep_object_header
*)obj
;
1344 struct pcep_object_header
*
1345 pcep_decode_obj_inter_layer(struct pcep_object_header
*hdr
,
1346 const uint8_t *obj_buf
)
1348 struct pcep_object_inter_layer
*obj
=
1349 (struct pcep_object_inter_layer
*)common_object_create(
1350 hdr
, sizeof(struct pcep_object_inter_layer
));
1351 obj
->flag_t
= (obj_buf
[3] & OBJECT_INTER_LAYER_FLAG_T
);
1352 obj
->flag_m
= (obj_buf
[3] & OBJECT_INTER_LAYER_FLAG_M
);
1353 obj
->flag_i
= (obj_buf
[3] & OBJECT_INTER_LAYER_FLAG_I
);
1355 return (struct pcep_object_header
*)obj
;
1358 struct pcep_object_header
*
1359 pcep_decode_obj_switch_layer(struct pcep_object_header
*hdr
,
1360 const uint8_t *obj_buf
)
1362 struct pcep_object_switch_layer
*obj
=
1363 (struct pcep_object_switch_layer
*)common_object_create(
1364 hdr
, sizeof(struct pcep_object_switch_layer
));
1365 obj
->switch_layer_rows
= dll_initialize();
1366 int num_rows
= ((hdr
->encoded_object_length
- 4) / 4);
1367 uint8_t buf_index
= 0;
1370 for (; i
< num_rows
; i
++) {
1371 struct pcep_object_switch_layer_row
*row
= pceplib_malloc(
1373 sizeof(struct pcep_object_switch_layer_row
));
1374 row
->lsp_encoding_type
= obj_buf
[buf_index
];
1375 row
->switching_type
= obj_buf
[buf_index
+ 1];
1377 (obj_buf
[buf_index
+ 3] & OBJECT_SWITCH_LAYER_FLAG_I
);
1378 dll_append(obj
->switch_layer_rows
, row
);
1380 buf_index
+= LENGTH_1WORD
;
1383 return (struct pcep_object_header
*)obj
;
1386 struct pcep_object_header
*
1387 pcep_decode_obj_req_adap_cap(struct pcep_object_header
*hdr
,
1388 const uint8_t *obj_buf
)
1390 struct pcep_object_req_adap_cap
*obj
=
1391 (struct pcep_object_req_adap_cap
*)common_object_create(
1392 hdr
, sizeof(struct pcep_object_req_adap_cap
));
1394 obj
->switching_capability
= obj_buf
[0];
1395 obj
->encoding
= obj_buf
[1];
1397 return (struct pcep_object_header
*)obj
;
1400 struct pcep_object_header
*
1401 pcep_decode_obj_server_ind(struct pcep_object_header
*hdr
,
1402 const uint8_t *obj_buf
)
1404 struct pcep_object_server_indication
*obj
=
1405 (struct pcep_object_server_indication
*)common_object_create(
1406 hdr
, sizeof(struct pcep_object_server_indication
));
1408 obj
->switching_capability
= obj_buf
[0];
1409 obj
->encoding
= obj_buf
[1];
1411 return (struct pcep_object_header
*)obj
;
1414 struct pcep_object_header
*
1415 pcep_decode_obj_objective_function(struct pcep_object_header
*hdr
,
1416 const uint8_t *obj_buf
)
1418 struct pcep_object_objective_function
*obj
=
1419 (struct pcep_object_objective_function
*)common_object_create(
1420 hdr
, sizeof(struct pcep_object_objective_function
));
1422 uint16_t *uint16_ptr
= (uint16_t *)obj_buf
;
1423 obj
->of_code
= ntohs(*uint16_ptr
);
1425 return (struct pcep_object_header
*)obj
;
1428 void set_ro_subobj_fields(struct pcep_object_ro_subobj
*subobj
, bool flag_l
,
1429 uint8_t subobj_type
)
1431 subobj
->flag_subobj_loose_hop
= flag_l
;
1432 subobj
->ro_subobj_type
= subobj_type
;
1435 void decode_ipv6(const uint32_t *src
, struct in6_addr
*dst_ipv6
)
1437 memcpy(dst_ipv6
, src
, sizeof(struct in6_addr
));
1439 struct pcep_object_header
*pcep_decode_obj_ro(struct pcep_object_header
*hdr
,
1440 const uint8_t *obj_buf
)
1442 struct pcep_object_ro
*obj
=
1443 (struct pcep_object_ro
*)common_object_create(
1444 hdr
, sizeof(struct pcep_object_ro
));
1445 obj
->sub_objects
= dll_initialize();
1447 /* RO Subobject format
1450 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
1451 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------//----------------+
1452 * |L| Type | Length | (Subobject contents) |
1453 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------//----------------+
1456 uint16_t read_count
= 0;
1457 int num_sub_objects
= 1;
1458 uint32_t *uint32_ptr
;
1459 uint16_t obj_body_length
=
1460 hdr
->encoded_object_length
- OBJECT_HEADER_LENGTH
;
1462 while ((obj_body_length
- read_count
) > OBJECT_RO_SUBOBJ_HEADER_LENGTH
1463 && num_sub_objects
< MAX_ITERATIONS
) {
1465 /* Read the Sub-Object Header */
1466 bool flag_l
= (obj_buf
[read_count
] & 0x80);
1467 uint8_t subobj_type
= (obj_buf
[read_count
++] & 0x7f);
1468 uint8_t subobj_length
= obj_buf
[read_count
++];
1470 if (subobj_length
<= OBJECT_RO_SUBOBJ_HEADER_LENGTH
) {
1472 "%s: Invalid ro subobj type [%d] length [%d]",
1473 __func__
, subobj_type
, subobj_length
);
1474 pceplib_free(PCEPLIB_MESSAGES
, obj
);
1478 switch (subobj_type
) {
1479 case RO_SUBOBJ_TYPE_IPV4
: {
1480 struct pcep_ro_subobj_ipv4
*ipv4
= pceplib_malloc(
1482 sizeof(struct pcep_ro_subobj_ipv4
));
1483 ipv4
->ro_subobj
.flag_subobj_loose_hop
= flag_l
;
1484 ipv4
->ro_subobj
.ro_subobj_type
= subobj_type
;
1485 uint32_ptr
= (uint32_t *)(obj_buf
+ read_count
);
1486 ipv4
->ip_addr
.s_addr
= *uint32_ptr
;
1487 read_count
+= LENGTH_1WORD
;
1488 ipv4
->prefix_length
= obj_buf
[read_count
++];
1489 ipv4
->flag_local_protection
=
1490 (obj_buf
[read_count
++]
1491 & OBJECT_SUBOBJ_IP_FLAG_LOCAL_PROT
);
1493 dll_append(obj
->sub_objects
, ipv4
);
1496 case RO_SUBOBJ_TYPE_IPV6
: {
1497 struct pcep_ro_subobj_ipv6
*ipv6
= pceplib_malloc(
1499 sizeof(struct pcep_ro_subobj_ipv6
));
1500 ipv6
->ro_subobj
.flag_subobj_loose_hop
= flag_l
;
1501 ipv6
->ro_subobj
.ro_subobj_type
= subobj_type
;
1502 decode_ipv6((uint32_t *)obj_buf
, &ipv6
->ip_addr
);
1503 read_count
+= LENGTH_4WORDS
;
1504 ipv6
->prefix_length
= obj_buf
[read_count
++];
1505 ipv6
->flag_local_protection
=
1506 (obj_buf
[read_count
++]
1507 & OBJECT_SUBOBJ_IP_FLAG_LOCAL_PROT
);
1509 dll_append(obj
->sub_objects
, ipv6
);
1512 case RO_SUBOBJ_TYPE_LABEL
: {
1513 struct pcep_ro_subobj_32label
*label
= pceplib_malloc(
1515 sizeof(struct pcep_ro_subobj_32label
));
1516 label
->ro_subobj
.flag_subobj_loose_hop
= flag_l
;
1517 label
->ro_subobj
.ro_subobj_type
= subobj_type
;
1518 label
->flag_global_label
=
1519 (obj_buf
[read_count
++]
1520 & OBJECT_SUBOBJ_LABEL_FLAG_GLOGAL
);
1521 label
->class_type
= obj_buf
[read_count
++];
1522 label
->label
= ntohl(obj_buf
[read_count
]);
1523 read_count
+= LENGTH_1WORD
;
1525 dll_append(obj
->sub_objects
, label
);
1528 case RO_SUBOBJ_TYPE_UNNUM
: {
1529 struct pcep_ro_subobj_unnum
*unum
= pceplib_malloc(
1531 sizeof(struct pcep_ro_subobj_unnum
));
1532 unum
->ro_subobj
.flag_subobj_loose_hop
= flag_l
;
1533 unum
->ro_subobj
.ro_subobj_type
= subobj_type
;
1534 set_ro_subobj_fields(
1535 (struct pcep_object_ro_subobj
*)unum
, flag_l
,
1537 uint32_ptr
= (uint32_t *)(obj_buf
+ read_count
);
1538 unum
->interface_id
= ntohl(uint32_ptr
[0]);
1539 unum
->router_id
.s_addr
= uint32_ptr
[1];
1542 dll_append(obj
->sub_objects
, unum
);
1545 case RO_SUBOBJ_TYPE_ASN
: {
1546 struct pcep_ro_subobj_asn
*asn
= pceplib_malloc(
1548 sizeof(struct pcep_ro_subobj_asn
));
1549 asn
->ro_subobj
.flag_subobj_loose_hop
= flag_l
;
1550 asn
->ro_subobj
.ro_subobj_type
= subobj_type
;
1551 uint16_t *uint16_ptr
=
1552 (uint16_t *)(obj_buf
+ read_count
);
1553 asn
->asn
= ntohs(*uint16_ptr
);
1556 dll_append(obj
->sub_objects
, asn
);
1559 case RO_SUBOBJ_TYPE_SR
: {
1560 /* SR-ERO subobject format
1563 * 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
1564 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1565 * |L| Type=36 | Length | NT | Flags
1567 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1568 * | SID (optional) |
1569 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1570 * // NAI (variable, optional) //
1571 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1574 struct pcep_ro_subobj_sr
*sr_subobj
= pceplib_malloc(
1576 sizeof(struct pcep_ro_subobj_sr
));
1577 sr_subobj
->ro_subobj
.flag_subobj_loose_hop
= flag_l
;
1578 sr_subobj
->ro_subobj
.ro_subobj_type
= subobj_type
;
1579 dll_append(obj
->sub_objects
, sr_subobj
);
1581 sr_subobj
->nai_list
= dll_initialize();
1582 sr_subobj
->nai_type
=
1583 ((obj_buf
[read_count
++] >> 4) & 0x0f);
1585 (obj_buf
[read_count
] & OBJECT_SUBOBJ_SR_FLAG_F
);
1587 (obj_buf
[read_count
] & OBJECT_SUBOBJ_SR_FLAG_S
);
1589 (obj_buf
[read_count
] & OBJECT_SUBOBJ_SR_FLAG_C
);
1591 (obj_buf
[read_count
] & OBJECT_SUBOBJ_SR_FLAG_M
);
1594 /* If the sid_absent flag is true, then dont decode the
1596 uint32_ptr
= (uint32_t *)(obj_buf
+ read_count
);
1597 if (sr_subobj
->flag_s
== false) {
1598 sr_subobj
->sid
= ntohl(*uint32_ptr
);
1599 read_count
+= LENGTH_1WORD
;
1603 switch (sr_subobj
->nai_type
) {
1604 case PCEP_SR_SUBOBJ_NAI_IPV4_NODE
: {
1605 struct in_addr
*ipv4
=
1606 pceplib_malloc(PCEPLIB_MESSAGES
,
1607 sizeof(struct in_addr
));
1608 ipv4
->s_addr
= *uint32_ptr
;
1609 dll_append(sr_subobj
->nai_list
, ipv4
);
1610 read_count
+= LENGTH_1WORD
;
1613 case PCEP_SR_SUBOBJ_NAI_IPV6_NODE
: {
1614 struct in6_addr
*ipv6
=
1615 pceplib_malloc(PCEPLIB_MESSAGES
,
1616 sizeof(struct in6_addr
));
1617 decode_ipv6(uint32_ptr
, ipv6
);
1618 dll_append(sr_subobj
->nai_list
, ipv6
);
1619 read_count
+= LENGTH_4WORDS
;
1622 case PCEP_SR_SUBOBJ_NAI_UNNUMBERED_IPV4_ADJACENCY
: {
1623 struct in_addr
*ipv4
=
1624 pceplib_malloc(PCEPLIB_MESSAGES
,
1625 sizeof(struct in_addr
));
1626 ipv4
->s_addr
= uint32_ptr
[0];
1627 dll_append(sr_subobj
->nai_list
, ipv4
);
1629 ipv4
= pceplib_malloc(PCEPLIB_MESSAGES
,
1630 sizeof(struct in_addr
));
1631 ipv4
->s_addr
= uint32_ptr
[1];
1632 dll_append(sr_subobj
->nai_list
, ipv4
);
1634 ipv4
= pceplib_malloc(PCEPLIB_MESSAGES
,
1635 sizeof(struct in_addr
));
1636 ipv4
->s_addr
= uint32_ptr
[2];
1637 dll_append(sr_subobj
->nai_list
, ipv4
);
1639 ipv4
= pceplib_malloc(PCEPLIB_MESSAGES
,
1640 sizeof(struct in_addr
));
1641 ipv4
->s_addr
= uint32_ptr
[3];
1642 dll_append(sr_subobj
->nai_list
, ipv4
);
1644 read_count
+= LENGTH_4WORDS
;
1647 case PCEP_SR_SUBOBJ_NAI_IPV4_ADJACENCY
: {
1648 struct in_addr
*ipv4
=
1649 pceplib_malloc(PCEPLIB_MESSAGES
,
1650 sizeof(struct in_addr
));
1651 ipv4
->s_addr
= uint32_ptr
[0];
1652 dll_append(sr_subobj
->nai_list
, ipv4
);
1654 ipv4
= pceplib_malloc(PCEPLIB_MESSAGES
,
1655 sizeof(struct in_addr
));
1656 ipv4
->s_addr
= uint32_ptr
[1];
1657 dll_append(sr_subobj
->nai_list
, ipv4
);
1659 read_count
+= LENGTH_2WORDS
;
1662 case PCEP_SR_SUBOBJ_NAI_IPV6_ADJACENCY
: {
1663 struct in6_addr
*ipv6
=
1664 pceplib_malloc(PCEPLIB_MESSAGES
,
1665 sizeof(struct in6_addr
));
1666 decode_ipv6(uint32_ptr
, ipv6
);
1667 dll_append(sr_subobj
->nai_list
, ipv6
);
1669 ipv6
= pceplib_malloc(PCEPLIB_MESSAGES
,
1670 sizeof(struct in6_addr
));
1671 decode_ipv6(uint32_ptr
+ 4, ipv6
);
1672 dll_append(sr_subobj
->nai_list
, ipv6
);
1674 read_count
+= LENGTH_8WORDS
;
1677 case PCEP_SR_SUBOBJ_NAI_LINK_LOCAL_IPV6_ADJACENCY
: {
1678 struct in6_addr
*ipv6
=
1679 pceplib_malloc(PCEPLIB_MESSAGES
,
1680 sizeof(struct in6_addr
));
1681 decode_ipv6(uint32_ptr
, ipv6
);
1682 dll_append(sr_subobj
->nai_list
, ipv6
);
1684 struct in_addr
*ipv4
=
1685 pceplib_malloc(PCEPLIB_MESSAGES
,
1686 sizeof(struct in_addr
));
1687 ipv4
->s_addr
= uint32_ptr
[4];
1688 dll_append(sr_subobj
->nai_list
, ipv4
);
1690 ipv6
= pceplib_malloc(PCEPLIB_MESSAGES
,
1691 sizeof(struct in6_addr
));
1692 decode_ipv6(uint32_ptr
+ 5, ipv6
);
1693 dll_append(sr_subobj
->nai_list
, ipv6
);
1695 ipv4
= pceplib_malloc(PCEPLIB_MESSAGES
,
1696 sizeof(struct in_addr
));
1697 ipv4
->s_addr
= uint32_ptr
[9];
1698 dll_append(sr_subobj
->nai_list
, ipv4
);
1700 read_count
+= LENGTH_10WORDS
;
1703 case PCEP_SR_SUBOBJ_NAI_ABSENT
:
1704 case PCEP_SR_SUBOBJ_NAI_UNKNOWN
:
1712 "%s: pcep_decode_obj_ro skipping unrecognized sub-object type [%d]",
1713 __func__
, subobj_type
);
1714 read_count
+= subobj_length
;
1719 return (struct pcep_object_header
*)obj
;