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 Objects.
31 #include "pcep_msg_objects.h"
32 #include "pcep_msg_encoding.h"
33 #include "pcep_utils_logging.h"
34 #include "pcep_utils_memory.h"
36 void write_object_header(struct pcep_object_header
*object_hdr
,
37 uint16_t object_length
, uint8_t *buf
);
38 void pcep_decode_object_hdr(const uint8_t *obj_buf
,
39 struct pcep_object_header
*obj_hdr
);
40 void set_ro_subobj_fields(struct pcep_object_ro_subobj
*subobj
, bool flag_l
,
44 * forward declarations for initialize_object_encoders()
46 uint16_t pcep_encode_obj_open(struct pcep_object_header
*obj
,
47 struct pcep_versioning
*versioning
, uint8_t *buf
);
48 uint16_t pcep_encode_obj_rp(struct pcep_object_header
*obj
,
49 struct pcep_versioning
*versioning
, uint8_t *buf
);
50 uint16_t pcep_encode_obj_nopath(struct pcep_object_header
*obj
,
51 struct pcep_versioning
*versioning
,
53 uint16_t pcep_encode_obj_endpoints(struct pcep_object_header
*obj
,
54 struct pcep_versioning
*versioning
,
56 uint16_t pcep_encode_obj_association(struct pcep_object_header
*obj
,
57 struct pcep_versioning
*versioning
,
59 uint16_t pcep_encode_obj_bandwidth(struct pcep_object_header
*obj
,
60 struct pcep_versioning
*versioning
,
62 uint16_t pcep_encode_obj_metric(struct pcep_object_header
*obj
,
63 struct pcep_versioning
*versioning
,
65 uint16_t pcep_encode_obj_ro(struct pcep_object_header
*obj
,
66 struct pcep_versioning
*versioning
, uint8_t *buf
);
67 uint16_t pcep_encode_obj_lspa(struct pcep_object_header
*obj
,
68 struct pcep_versioning
*versioning
, uint8_t *buf
);
69 uint16_t pcep_encode_obj_svec(struct pcep_object_header
*obj
,
70 struct pcep_versioning
*versioning
, uint8_t *buf
);
71 uint16_t pcep_encode_obj_notify(struct pcep_object_header
*obj
,
72 struct pcep_versioning
*versioning
,
74 uint16_t pcep_encode_obj_error(struct pcep_object_header
*error
,
75 struct pcep_versioning
*versioning
,
77 uint16_t pcep_encode_obj_close(struct pcep_object_header
*close
,
78 struct pcep_versioning
*versioning
,
80 uint16_t pcep_encode_obj_srp(struct pcep_object_header
*obj
,
81 struct pcep_versioning
*versioning
, uint8_t *buf
);
82 uint16_t pcep_encode_obj_lsp(struct pcep_object_header
*obj
,
83 struct pcep_versioning
*versioning
, uint8_t *buf
);
84 uint16_t pcep_encode_obj_vendor_info(struct pcep_object_header
*obj
,
85 struct pcep_versioning
*versioning
,
87 uint16_t pcep_encode_obj_inter_layer(struct pcep_object_header
*obj
,
88 struct pcep_versioning
*versioning
,
90 uint16_t pcep_encode_obj_switch_layer(struct pcep_object_header
*obj
,
91 struct pcep_versioning
*versioning
,
93 uint16_t pcep_encode_obj_req_adap_cap(struct pcep_object_header
*obj
,
94 struct pcep_versioning
*versioning
,
96 uint16_t pcep_encode_obj_server_ind(struct pcep_object_header
*obj
,
97 struct pcep_versioning
*versioning
,
99 uint16_t pcep_encode_obj_objective_function(struct pcep_object_header
*obj
,
100 struct pcep_versioning
*versioning
,
102 typedef uint16_t (*object_encoder_funcptr
)(struct pcep_object_header
*,
103 struct pcep_versioning
*versioning
,
106 #define MAX_OBJECT_ENCODER_INDEX 64
108 #define PCEP_ENCODERS_ARGS \
109 struct pcep_object_header *, struct pcep_versioning *versioning, \
111 uint16_t (*const object_encoders
[MAX_OBJECT_ENCODER_INDEX
])(
112 PCEP_ENCODERS_ARGS
) = {
113 [PCEP_OBJ_CLASS_OPEN
] = pcep_encode_obj_open
,
114 [PCEP_OBJ_CLASS_RP
] = pcep_encode_obj_rp
,
115 [PCEP_OBJ_CLASS_NOPATH
] = pcep_encode_obj_nopath
,
116 [PCEP_OBJ_CLASS_ENDPOINTS
] = pcep_encode_obj_endpoints
,
117 [PCEP_OBJ_CLASS_BANDWIDTH
] = pcep_encode_obj_bandwidth
,
118 [PCEP_OBJ_CLASS_METRIC
] = pcep_encode_obj_metric
,
119 [PCEP_OBJ_CLASS_ERO
] = pcep_encode_obj_ro
,
120 [PCEP_OBJ_CLASS_RRO
] = pcep_encode_obj_ro
,
121 [PCEP_OBJ_CLASS_LSPA
] = pcep_encode_obj_lspa
,
122 [PCEP_OBJ_CLASS_IRO
] = pcep_encode_obj_ro
,
123 [PCEP_OBJ_CLASS_SVEC
] = pcep_encode_obj_svec
,
124 [PCEP_OBJ_CLASS_NOTF
] = pcep_encode_obj_notify
,
125 [PCEP_OBJ_CLASS_ERROR
] = pcep_encode_obj_error
,
126 [PCEP_OBJ_CLASS_CLOSE
] = pcep_encode_obj_close
,
127 [PCEP_OBJ_CLASS_LSP
] = pcep_encode_obj_lsp
,
128 [PCEP_OBJ_CLASS_SRP
] = pcep_encode_obj_srp
,
129 [PCEP_OBJ_CLASS_ASSOCIATION
] = pcep_encode_obj_association
,
130 [PCEP_OBJ_CLASS_INTER_LAYER
] = pcep_encode_obj_inter_layer
,
131 [PCEP_OBJ_CLASS_SWITCH_LAYER
] = pcep_encode_obj_switch_layer
,
132 [PCEP_OBJ_CLASS_REQ_ADAP_CAP
] = pcep_encode_obj_req_adap_cap
,
133 [PCEP_OBJ_CLASS_SERVER_IND
] = pcep_encode_obj_server_ind
,
134 [PCEP_OBJ_CLASS_VENDOR_INFO
] = pcep_encode_obj_vendor_info
,
135 [PCEP_OBJ_CLASS_OF
] = pcep_encode_obj_objective_function
,
138 * forward declarations for initialize_object_decoders()
140 struct pcep_object_header
*pcep_decode_obj_open(struct pcep_object_header
*hdr
,
142 struct pcep_object_header
*pcep_decode_obj_rp(struct pcep_object_header
*hdr
,
144 struct pcep_object_header
*
145 pcep_decode_obj_nopath(struct pcep_object_header
*hdr
, const uint8_t *buf
);
146 struct pcep_object_header
*
147 pcep_decode_obj_endpoints(struct pcep_object_header
*hdr
, const uint8_t *buf
);
148 struct pcep_object_header
*
149 pcep_decode_obj_association(struct pcep_object_header
*hdr
, const uint8_t *buf
);
150 struct pcep_object_header
*
151 pcep_decode_obj_bandwidth(struct pcep_object_header
*hdr
, const uint8_t *buf
);
152 struct pcep_object_header
*
153 pcep_decode_obj_metric(struct pcep_object_header
*hdr
, const uint8_t *buf
);
154 struct pcep_object_header
*pcep_decode_obj_ro(struct pcep_object_header
*hdr
,
156 struct pcep_object_header
*pcep_decode_obj_lspa(struct pcep_object_header
*hdr
,
158 struct pcep_object_header
*pcep_decode_obj_svec(struct pcep_object_header
*hdr
,
160 struct pcep_object_header
*
161 pcep_decode_obj_notify(struct pcep_object_header
*hdr
, const uint8_t *buf
);
162 struct pcep_object_header
*pcep_decode_obj_error(struct pcep_object_header
*hdr
,
164 struct pcep_object_header
*pcep_decode_obj_close(struct pcep_object_header
*hdr
,
166 struct pcep_object_header
*pcep_decode_obj_srp(struct pcep_object_header
*hdr
,
168 struct pcep_object_header
*pcep_decode_obj_lsp(struct pcep_object_header
*hdr
,
170 struct pcep_object_header
*
171 pcep_decode_obj_vendor_info(struct pcep_object_header
*hdr
, const uint8_t *buf
);
172 struct pcep_object_header
*
173 pcep_decode_obj_inter_layer(struct pcep_object_header
*hdr
, const uint8_t *buf
);
174 struct pcep_object_header
*
175 pcep_decode_obj_switch_layer(struct pcep_object_header
*hdr
,
177 struct pcep_object_header
*
178 pcep_decode_obj_req_adap_cap(struct pcep_object_header
*hdr
,
180 struct pcep_object_header
*
181 pcep_decode_obj_server_ind(struct pcep_object_header
*hdr
, const uint8_t *buf
);
182 struct pcep_object_header
*
183 pcep_decode_obj_objective_function(struct pcep_object_header
*hdr
,
185 typedef struct pcep_object_header
*(*object_decoder_funcptr
)(
186 struct pcep_object_header
*, const uint8_t *buf
);
188 #define PCEP_DECODERS_ARGS struct pcep_object_header *, const uint8_t *buf
190 struct pcep_object_header
*(*const object_decoders
[MAX_OBJECT_ENCODER_INDEX
])(
191 PCEP_DECODERS_ARGS
) = {
192 [PCEP_OBJ_CLASS_OPEN
] = pcep_decode_obj_open
,
193 [PCEP_OBJ_CLASS_RP
] = pcep_decode_obj_rp
,
194 [PCEP_OBJ_CLASS_NOPATH
] = pcep_decode_obj_nopath
,
195 [PCEP_OBJ_CLASS_ENDPOINTS
] = pcep_decode_obj_endpoints
,
196 [PCEP_OBJ_CLASS_BANDWIDTH
] = pcep_decode_obj_bandwidth
,
197 [PCEP_OBJ_CLASS_METRIC
] = pcep_decode_obj_metric
,
198 [PCEP_OBJ_CLASS_ERO
] = pcep_decode_obj_ro
,
199 [PCEP_OBJ_CLASS_RRO
] = pcep_decode_obj_ro
,
200 [PCEP_OBJ_CLASS_LSPA
] = pcep_decode_obj_lspa
,
201 [PCEP_OBJ_CLASS_IRO
] = pcep_decode_obj_ro
,
202 [PCEP_OBJ_CLASS_SVEC
] = pcep_decode_obj_svec
,
203 [PCEP_OBJ_CLASS_NOTF
] = pcep_decode_obj_notify
,
204 [PCEP_OBJ_CLASS_ERROR
] = pcep_decode_obj_error
,
205 [PCEP_OBJ_CLASS_CLOSE
] = pcep_decode_obj_close
,
206 [PCEP_OBJ_CLASS_LSP
] = pcep_decode_obj_lsp
,
207 [PCEP_OBJ_CLASS_SRP
] = pcep_decode_obj_srp
,
208 [PCEP_OBJ_CLASS_ASSOCIATION
] = pcep_decode_obj_association
,
209 [PCEP_OBJ_CLASS_INTER_LAYER
] = pcep_decode_obj_inter_layer
,
210 [PCEP_OBJ_CLASS_SWITCH_LAYER
] = pcep_decode_obj_switch_layer
,
211 [PCEP_OBJ_CLASS_REQ_ADAP_CAP
] = pcep_decode_obj_req_adap_cap
,
212 [PCEP_OBJ_CLASS_SERVER_IND
] = pcep_decode_obj_server_ind
,
213 [PCEP_OBJ_CLASS_VENDOR_INFO
] = pcep_decode_obj_vendor_info
,
214 [PCEP_OBJ_CLASS_OF
] = pcep_decode_obj_objective_function
,
217 /* Object lengths, including the Object Header.
218 * Used by pcep_object_get_length() and pcep_object_has_tlvs() */
219 static uint8_t pcep_object_class_lengths
[] = {
220 0, /* Object class 0 unused */
221 8, /* PCEP_OBJ_CLASS_OPEN = 1 */
222 12, /* PCEP_OBJ_CLASS_RP = 2 */
223 16, /* PCEP_OBJ_CLASS_NOPATH = 3, includes 8 for mandatory TLV */
224 0, /* PCEP_OBJ_CLASS_ENDPOINTS = 4, could be ipv4 or ipv6, setting to 0
226 8, /* PCEP_OBJ_CLASS_BANDWIDTH = 5 */
227 12, /* PCEP_OBJ_CLASS_METRIC = 6 */
228 0, /* PCEP_OBJ_CLASS_ERO = 7, setting 0, ROs cannot have TLVs */
229 0, /* PCEP_OBJ_CLASS_RRO = 8, setting 0, ROs cannot have TLVs */
230 20, /* PCEP_OBJ_CLASS_LSPA = 9 */
231 0, /* PCEP_OBJ_CLASS_IRO = 10, setting 0, ROs cannot have TLVs */
232 0, /* PCEP_OBJ_CLASS_SVEC = 11, SVECs cannot have TLVs */
233 8, /* PCEP_OBJ_CLASS_NOTF = 12 */
234 8, /* PCEP_OBJ_CLASS_ERROR = 13 */
235 0, /* Object class 14 unused */
236 8, /* PCEP_OBJ_CLASS_CLOSE = 15 */
237 0, 0, 0, 0, 0, /* Object classes 16 - 20 are not used */
238 8, /* PCEP_OBJ_CLASS_OF = 21 */
239 0, 0, 0, 0, 0, /* Object classes 22 - 26 are not used */
240 0, 0, 0, 0, 0, /* Object classes 27 - 31 are not used */
241 8, /* PCEP_OBJ_CLASS_LSP = 32 */
242 12, /* PCEP_OBJ_CLASS_SRP = 33 */
243 12, /* PCEP_OBJ_CLASS_VENDOR_INFO = 34 */
244 0, /* Object class 35 unused */
245 0, /* PCEP_OBJ_CLASS_INTER_LAYER = 36, cannot have TLVs */
246 0, /* PCEP_OBJ_CLASS_SWITCH_LAYER = 37, cannot have TLVs */
247 0, /* PCEP_OBJ_CLASS_REQ_ADAP_CAP = 38, cannot have TLVs*/
248 8, /* PCEP_OBJ_CLASS_SERVER_IND = 39 */
249 0, /* PCEP_OBJ_CLASS_ASSOCIATION = 40, cannot have TLVs */
253 * The TLVs can have strange length values, since they do not include padding in
254 * the TLV header length, but that extra padding must be taken into account by
255 * the enclosing object by rounding up to the next 4 byte boundary.
256 * Example returned lengths:
257 * normalize_length(4) = 4, normalize_length(5) = 8, normalize_length(6)
258 * = 8, normalize_length(7) = 8, normalize_length(8) = 8
259 * normalize_length(9) = 12, normalize_length(10) = 12, normalize_length(11) =
260 * 12, normalize_length(12) = 12, normalize_length(13) = 13...
262 uint16_t normalize_pcep_tlv_length(uint16_t length
)
264 return (length
% 4 == 0) ? length
: (length
+ (4 - (length
% 4)));
270 uint16_t pcep_encode_object(struct pcep_object_header
*object_hdr
,
271 struct pcep_versioning
*versioning
, uint8_t *buf
)
274 if (object_hdr
->object_class
>= MAX_OBJECT_ENCODER_INDEX
) {
276 "%s: Cannot encode unknown Object class [%d]",
277 __func__
, object_hdr
->object_class
);
281 object_encoder_funcptr obj_encoder
=
282 object_encoders
[object_hdr
->object_class
];
283 if (obj_encoder
== NULL
) {
285 "%s: No object encoder found for Object class [%d]",
286 __func__
, object_hdr
->object_class
);
290 uint16_t object_length
= OBJECT_HEADER_LENGTH
291 + obj_encoder(object_hdr
, versioning
,
292 buf
+ OBJECT_HEADER_LENGTH
);
293 double_linked_list_node
*node
=
294 (object_hdr
->tlv_list
== NULL
? NULL
295 : object_hdr
->tlv_list
->head
);
296 for (; node
!= NULL
; node
= node
->next_node
) {
297 /* Returns the length of the TLV, including the TLV header */
298 object_length
+= pcep_encode_tlv(
299 (struct pcep_object_tlv_header
*)node
->data
, versioning
,
300 buf
+ object_length
);
302 object_length
= normalize_pcep_tlv_length(object_length
);
303 write_object_header(object_hdr
, object_length
, buf
);
304 object_hdr
->encoded_object
= buf
;
305 object_hdr
->encoded_object_length
= object_length
;
307 return object_length
;
314 * 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
315 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
316 * | Object-Class | OT |Res|P|I| Object Length (bytes) |
317 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
319 * // (Object body) //
321 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
325 void write_object_header(struct pcep_object_header
*object_hdr
,
326 uint16_t object_length
, uint8_t *buf
)
328 buf
[0] = object_hdr
->object_class
;
329 buf
[1] = ((object_hdr
->object_type
<< 4)
330 | (object_hdr
->flag_p
? OBJECT_HEADER_FLAG_P
: 0x00)
331 | (object_hdr
->flag_i
? OBJECT_HEADER_FLAG_I
: 0x00));
332 uint16_t net_order_length
= htons(object_length
);
333 memcpy(buf
+ 2, &net_order_length
, sizeof(net_order_length
));
338 * Functions to encode objects
339 * - they will be passed a pointer to a buffer to write the object body,
340 * which is past the object header.
341 * - they should return the object body length, not including the object header
345 uint16_t pcep_encode_obj_open(struct pcep_object_header
*hdr
,
346 struct pcep_versioning
*versioning
,
347 uint8_t *obj_body_buf
)
350 struct pcep_object_open
*open
= (struct pcep_object_open
*)hdr
;
351 obj_body_buf
[0] = (open
->open_version
<< 5) & 0xe0;
352 obj_body_buf
[1] = open
->open_keepalive
;
353 obj_body_buf
[2] = open
->open_deadtimer
;
354 obj_body_buf
[3] = open
->open_sid
;
359 uint16_t pcep_encode_obj_rp(struct pcep_object_header
*hdr
,
360 struct pcep_versioning
*versioning
,
361 uint8_t *obj_body_buf
)
364 struct pcep_object_rp
*rp
= (struct pcep_object_rp
*)hdr
;
365 obj_body_buf
[3] = ((rp
->flag_strict
? OBJECT_RP_FLAG_O
: 0x00)
366 | (rp
->flag_bidirectional
? OBJECT_RP_FLAG_B
: 0x00)
367 | (rp
->flag_reoptimization
? OBJECT_RP_FLAG_R
: 0x00)
368 | (rp
->flag_of
? OBJECT_RP_FLAG_OF
: 0x00)
369 | (rp
->priority
& 0x07));
370 uint32_t *uint32_ptr
= (uint32_t *)(obj_body_buf
+ 4);
371 *uint32_ptr
= htonl(rp
->request_id
);
373 return LENGTH_2WORDS
;
376 uint16_t pcep_encode_obj_notify(struct pcep_object_header
*hdr
,
377 struct pcep_versioning
*versioning
,
378 uint8_t *obj_body_buf
)
381 struct pcep_object_notify
*notify
= (struct pcep_object_notify
*)hdr
;
382 obj_body_buf
[2] = notify
->notification_type
;
383 obj_body_buf
[3] = notify
->notification_value
;
388 uint16_t pcep_encode_obj_nopath(struct pcep_object_header
*hdr
,
389 struct pcep_versioning
*versioning
,
390 uint8_t *obj_body_buf
)
393 struct pcep_object_nopath
*nopath
= (struct pcep_object_nopath
*)hdr
;
394 obj_body_buf
[0] = nopath
->ni
;
395 obj_body_buf
[1] = ((nopath
->flag_c
) ? OBJECT_NOPATH_FLAG_C
: 0x00);
400 uint16_t pcep_encode_obj_association(struct pcep_object_header
*hdr
,
401 struct pcep_versioning
*versioning
,
402 uint8_t *obj_body_buf
)
405 uint16_t *uint16_ptr
= (uint16_t *)obj_body_buf
;
406 uint32_t *uint32_ptr
= (uint32_t *)obj_body_buf
;
407 if (hdr
->object_type
== PCEP_OBJ_TYPE_ASSOCIATION_IPV4
) {
408 struct pcep_object_association_ipv4
*ipv4
=
409 (struct pcep_object_association_ipv4
*)hdr
;
411 (ipv4
->R_flag
? OBJECT_ASSOCIATION_FLAG_R
: 0x00);
412 uint16_ptr
[2] = htons(ipv4
->association_type
);
413 uint16_ptr
[3] = htons(ipv4
->association_id
);
414 uint32_ptr
[2] = ipv4
->src
.s_addr
;
416 return LENGTH_3WORDS
;
418 struct pcep_object_association_ipv6
*ipv6
=
419 (struct pcep_object_association_ipv6
*)hdr
;
421 (ipv6
->R_flag
? OBJECT_ASSOCIATION_FLAG_R
: 0x00);
422 uint16_ptr
[2] = htons(ipv6
->association_type
);
423 uint16_ptr
[3] = htons(ipv6
->association_id
);
424 memcpy(uint32_ptr
, &ipv6
->src
, sizeof(struct in6_addr
));
426 return LENGTH_6WORDS
;
430 uint16_t pcep_encode_obj_endpoints(struct pcep_object_header
*hdr
,
431 struct pcep_versioning
*versioning
,
432 uint8_t *obj_body_buf
)
435 uint32_t *uint32_ptr
= (uint32_t *)obj_body_buf
;
436 if (hdr
->object_type
== PCEP_OBJ_TYPE_ENDPOINT_IPV4
) {
437 struct pcep_object_endpoints_ipv4
*ipv4
=
438 (struct pcep_object_endpoints_ipv4
*)hdr
;
439 uint32_ptr
[0] = ipv4
->src_ipv4
.s_addr
;
440 uint32_ptr
[1] = ipv4
->dst_ipv4
.s_addr
;
442 return LENGTH_2WORDS
;
444 struct pcep_object_endpoints_ipv6
*ipv6
=
445 (struct pcep_object_endpoints_ipv6
*)hdr
;
446 memcpy(uint32_ptr
, &ipv6
->src_ipv6
, sizeof(struct in6_addr
));
447 memcpy(&uint32_ptr
[4], &ipv6
->dst_ipv6
,
448 sizeof(struct in6_addr
));
450 return LENGTH_8WORDS
;
454 uint16_t pcep_encode_obj_bandwidth(struct pcep_object_header
*hdr
,
455 struct pcep_versioning
*versioning
,
456 uint8_t *obj_body_buf
)
459 struct pcep_object_bandwidth
*bandwidth
=
460 (struct pcep_object_bandwidth
*)hdr
;
461 uint32_t *uint32_ptr
= (uint32_t *)obj_body_buf
;
462 /* Seems like the compiler doesnt correctly copy the float, so memcpy()
464 memcpy(uint32_ptr
, &(bandwidth
->bandwidth
), sizeof(uint32_t));
465 *uint32_ptr
= htonl(*uint32_ptr
);
470 uint16_t pcep_encode_obj_metric(struct pcep_object_header
*hdr
,
471 struct pcep_versioning
*versioning
,
472 uint8_t *obj_body_buf
)
475 struct pcep_object_metric
*metric
= (struct pcep_object_metric
*)hdr
;
476 obj_body_buf
[2] = ((metric
->flag_c
? OBJECT_METRIC_FLAC_C
: 0x00)
477 | (metric
->flag_b
? OBJECT_METRIC_FLAC_B
: 0x00));
478 obj_body_buf
[3] = metric
->type
;
479 uint32_t *uint32_ptr
= (uint32_t *)(obj_body_buf
+ 4);
480 /* Seems like the compiler doesnt correctly copy the float, so memcpy()
482 memcpy(uint32_ptr
, &(metric
->value
), sizeof(uint32_t));
483 *uint32_ptr
= htonl(*uint32_ptr
);
485 return LENGTH_2WORDS
;
488 uint16_t pcep_encode_obj_lspa(struct pcep_object_header
*hdr
,
489 struct pcep_versioning
*versioning
,
490 uint8_t *obj_body_buf
)
493 struct pcep_object_lspa
*lspa
= (struct pcep_object_lspa
*)hdr
;
494 uint32_t *uint32_ptr
= (uint32_t *)obj_body_buf
;
495 uint32_ptr
[0] = htonl(lspa
->lspa_exclude_any
);
496 uint32_ptr
[1] = htonl(lspa
->lspa_include_any
);
497 uint32_ptr
[2] = htonl(lspa
->lspa_include_all
);
498 obj_body_buf
[12] = lspa
->setup_priority
;
499 obj_body_buf
[13] = lspa
->holding_priority
;
501 (lspa
->flag_local_protection
? OBJECT_LSPA_FLAG_L
: 0x00);
503 return LENGTH_4WORDS
;
506 uint16_t pcep_encode_obj_svec(struct pcep_object_header
*hdr
,
507 struct pcep_versioning
*versioning
,
508 uint8_t *obj_body_buf
)
511 struct pcep_object_svec
*svec
= (struct pcep_object_svec
*)hdr
;
513 ((svec
->flag_srlg_diverse
? OBJECT_SVEC_FLAG_S
: 0x00)
514 | (svec
->flag_node_diverse
? OBJECT_SVEC_FLAG_N
: 0x00)
515 | (svec
->flag_link_diverse
? OBJECT_SVEC_FLAG_L
: 0x00));
517 if (svec
->request_id_list
== NULL
) {
522 uint32_t *uint32_ptr
= (uint32_t *)obj_body_buf
;
523 double_linked_list_node
*node
= svec
->request_id_list
->head
;
524 for (; node
!= NULL
; node
= node
->next_node
) {
525 uint32_ptr
[index
++] = htonl(*((uint32_t *)(node
->data
)));
529 + (svec
->request_id_list
->num_entries
* sizeof(uint32_t));
532 uint16_t pcep_encode_obj_error(struct pcep_object_header
*hdr
,
533 struct pcep_versioning
*versioning
,
534 uint8_t *obj_body_buf
)
537 struct pcep_object_error
*error
= (struct pcep_object_error
*)hdr
;
538 obj_body_buf
[2] = error
->error_type
;
539 obj_body_buf
[3] = error
->error_value
;
544 uint16_t pcep_encode_obj_close(struct pcep_object_header
*hdr
,
545 struct pcep_versioning
*versioning
,
546 uint8_t *obj_body_buf
)
549 struct pcep_object_close
*close
= (struct pcep_object_close
*)hdr
;
550 obj_body_buf
[3] = close
->reason
;
555 uint16_t pcep_encode_obj_srp(struct pcep_object_header
*hdr
,
556 struct pcep_versioning
*versioning
,
557 uint8_t *obj_body_buf
)
560 struct pcep_object_srp
*srp
= (struct pcep_object_srp
*)hdr
;
561 obj_body_buf
[3] = (srp
->flag_lsp_remove
? OBJECT_SRP_FLAG_R
: 0x00);
562 uint32_t *uint32_ptr
= (uint32_t *)(obj_body_buf
+ 4);
563 *uint32_ptr
= htonl(srp
->srp_id_number
);
565 return LENGTH_2WORDS
;
568 uint16_t pcep_encode_obj_lsp(struct pcep_object_header
*hdr
,
569 struct pcep_versioning
*versioning
,
570 uint8_t *obj_body_buf
)
573 struct pcep_object_lsp
*lsp
= (struct pcep_object_lsp
*)hdr
;
574 uint32_t *uint32_ptr
= (uint32_t *)obj_body_buf
;
575 uint32_ptr
[0] = htonl((lsp
->plsp_id
<< 12) & 0xfffff000);
576 obj_body_buf
[3] = ((lsp
->flag_c
? OBJECT_LSP_FLAG_C
: 0x00)
577 | ((lsp
->operational_status
<< 4) & 0x70)
578 | (lsp
->flag_a
? OBJECT_LSP_FLAG_A
: 0x00)
579 | (lsp
->flag_r
? OBJECT_LSP_FLAG_R
: 0x00)
580 | (lsp
->flag_s
? OBJECT_LSP_FLAG_S
: 0x00)
581 | (lsp
->flag_d
? OBJECT_LSP_FLAG_D
: 0x00));
586 uint16_t pcep_encode_obj_vendor_info(struct pcep_object_header
*hdr
,
587 struct pcep_versioning
*versioning
,
588 uint8_t *obj_body_buf
)
591 struct pcep_object_vendor_info
*obj
=
592 (struct pcep_object_vendor_info
*)hdr
;
593 uint32_t *uint32_ptr
= (uint32_t *)obj_body_buf
;
594 uint32_ptr
[0] = htonl(obj
->enterprise_number
);
595 uint32_ptr
[1] = htonl(obj
->enterprise_specific_info
);
597 return LENGTH_2WORDS
;
600 uint16_t pcep_encode_obj_inter_layer(struct pcep_object_header
*hdr
,
601 struct pcep_versioning
*versioning
,
602 uint8_t *obj_body_buf
)
605 struct pcep_object_inter_layer
*obj
=
606 (struct pcep_object_inter_layer
*)hdr
;
607 obj_body_buf
[3] = ((obj
->flag_i
? OBJECT_INTER_LAYER_FLAG_I
: 0x00)
608 | (obj
->flag_m
? OBJECT_INTER_LAYER_FLAG_M
: 0x00)
609 | (obj
->flag_t
? OBJECT_INTER_LAYER_FLAG_T
: 0x00));
614 uint16_t pcep_encode_obj_switch_layer(struct pcep_object_header
*hdr
,
615 struct pcep_versioning
*versioning
,
616 uint8_t *obj_body_buf
)
619 struct pcep_object_switch_layer
*obj
=
620 (struct pcep_object_switch_layer
*)hdr
;
621 uint8_t buf_index
= 0;
623 double_linked_list_node
*node
= obj
->switch_layer_rows
->head
;
624 while (node
!= NULL
) {
625 struct pcep_object_switch_layer_row
*row
= node
->data
;
630 obj_body_buf
[buf_index
] = row
->lsp_encoding_type
;
631 obj_body_buf
[buf_index
+ 1] = row
->switching_type
;
632 obj_body_buf
[buf_index
+ 3] =
633 (row
->flag_i
? OBJECT_SWITCH_LAYER_FLAG_I
: 0x00);
635 buf_index
+= LENGTH_1WORD
;
641 uint16_t pcep_encode_obj_req_adap_cap(struct pcep_object_header
*hdr
,
642 struct pcep_versioning
*versioning
,
643 uint8_t *obj_body_buf
)
646 struct pcep_object_req_adap_cap
*obj
=
647 (struct pcep_object_req_adap_cap
*)hdr
;
649 obj_body_buf
[0] = obj
->switching_capability
;
650 obj_body_buf
[1] = obj
->encoding
;
655 uint16_t pcep_encode_obj_server_ind(struct pcep_object_header
*hdr
,
656 struct pcep_versioning
*versioning
,
657 uint8_t *obj_body_buf
)
660 struct pcep_object_server_indication
*obj
=
661 (struct pcep_object_server_indication
*)hdr
;
663 obj_body_buf
[0] = obj
->switching_capability
;
664 obj_body_buf
[1] = obj
->encoding
;
669 uint16_t pcep_encode_obj_objective_function(struct pcep_object_header
*hdr
,
670 struct pcep_versioning
*versioning
,
671 uint8_t *obj_body_buf
)
674 struct pcep_object_objective_function
*obj
=
675 (struct pcep_object_objective_function
*)hdr
;
677 uint16_t *uint16_ptr
= (uint16_t *)obj_body_buf
;
678 *uint16_ptr
= htons(obj
->of_code
);
683 uint16_t pcep_encode_obj_ro(struct pcep_object_header
*hdr
,
684 struct pcep_versioning
*versioning
,
685 uint8_t *obj_body_buf
)
688 struct pcep_object_ro
*ro
= (struct pcep_object_ro
*)hdr
;
689 if (ro
== NULL
|| ro
->sub_objects
== NULL
) {
693 /* RO Subobject format
696 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
697 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------//----------------+
698 * |L| Type | Length | (Subobject contents) |
699 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------//----------------+
703 double_linked_list_node
*node
= ro
->sub_objects
->head
;
704 for (; node
!= NULL
; node
= node
->next_node
) {
705 struct pcep_object_ro_subobj
*ro_subobj
= node
->data
;
706 obj_body_buf
[index
++] =
707 ((ro_subobj
->flag_subobj_loose_hop
? 0x80 : 0x00)
708 | (ro_subobj
->ro_subobj_type
));
709 /* The length will be written below, depending on the subobj
711 uint8_t *length_ptr
= &(obj_body_buf
[index
++]);
712 uint32_t *uint32_ptr
= (uint32_t *)(obj_body_buf
+ index
);
714 /* - The index has already been incremented past the header,
715 * and now points to the ro_subobj body. Below it just needs
716 * to be incremented past the body.
718 * - Each section below needs to write the total length,
719 * including the 2 byte subobj header. */
721 switch (ro_subobj
->ro_subobj_type
) {
722 case RO_SUBOBJ_TYPE_IPV4
: {
723 struct pcep_ro_subobj_ipv4
*ipv4
=
724 (struct pcep_ro_subobj_ipv4
*)ro_subobj
;
725 uint32_ptr
[0] = ipv4
->ip_addr
.s_addr
;
726 index
+= LENGTH_1WORD
;
727 obj_body_buf
[index
++] = ipv4
->prefix_length
;
728 obj_body_buf
[index
++] =
729 (ipv4
->flag_local_protection
730 ? OBJECT_SUBOBJ_IP_FLAG_LOCAL_PROT
732 *length_ptr
= LENGTH_2WORDS
;
735 case RO_SUBOBJ_TYPE_IPV6
: {
736 struct pcep_ro_subobj_ipv6
*ipv6
=
737 (struct pcep_ro_subobj_ipv6
*)ro_subobj
;
738 encode_ipv6(&ipv6
->ip_addr
, uint32_ptr
);
739 index
+= LENGTH_4WORDS
;
740 obj_body_buf
[index
++] = ipv6
->prefix_length
;
741 obj_body_buf
[index
++] =
742 (ipv6
->flag_local_protection
743 ? OBJECT_SUBOBJ_IP_FLAG_LOCAL_PROT
745 *length_ptr
= LENGTH_5WORDS
;
748 case RO_SUBOBJ_TYPE_LABEL
: {
749 struct pcep_ro_subobj_32label
*label
=
750 (struct pcep_ro_subobj_32label
*)ro_subobj
;
751 obj_body_buf
[index
++] =
752 (label
->flag_global_label
753 ? OBJECT_SUBOBJ_LABEL_FLAG_GLOGAL
755 obj_body_buf
[index
++] = label
->class_type
;
756 uint32_ptr
= (uint32_t *)(obj_body_buf
+ index
);
757 *uint32_ptr
= htonl(label
->label
);
758 *length_ptr
= LENGTH_2WORDS
;
759 index
+= LENGTH_1WORD
;
762 case RO_SUBOBJ_TYPE_UNNUM
: {
763 struct pcep_ro_subobj_unnum
*unum
=
764 (struct pcep_ro_subobj_unnum
*)ro_subobj
;
765 index
+= 2; /* increment past 2 reserved bytes */
766 uint32_ptr
= (uint32_t *)(obj_body_buf
+ index
);
767 uint32_ptr
[0] = unum
->router_id
.s_addr
;
768 uint32_ptr
[1] = htonl(unum
->interface_id
);
769 *length_ptr
= LENGTH_3WORDS
;
770 index
+= LENGTH_2WORDS
;
773 case RO_SUBOBJ_TYPE_ASN
: {
774 struct pcep_ro_subobj_asn
*asn
=
775 (struct pcep_ro_subobj_asn
*)ro_subobj
;
776 uint16_t *uint16_ptr
=
777 (uint16_t *)(obj_body_buf
+ index
);
778 *uint16_ptr
= htons(asn
->asn
);
779 *length_ptr
= LENGTH_1WORD
;
783 case RO_SUBOBJ_TYPE_SR
: {
784 /* SR-ERO subobject format
787 * 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
788 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
789 * |L| Type=36 | Length | NT | Flags
791 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
793 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
794 * // NAI (variable, optional) //
795 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
798 struct pcep_ro_subobj_sr
*sr_subobj
=
799 (struct pcep_ro_subobj_sr
*)ro_subobj
;
800 obj_body_buf
[index
++] =
801 ((sr_subobj
->nai_type
<< 4) & 0xf0);
802 obj_body_buf
[index
++] =
803 ((sr_subobj
->flag_f
? OBJECT_SUBOBJ_SR_FLAG_F
805 | (sr_subobj
->flag_s
? OBJECT_SUBOBJ_SR_FLAG_S
807 | (sr_subobj
->flag_c
? OBJECT_SUBOBJ_SR_FLAG_C
809 | (sr_subobj
->flag_m
? OBJECT_SUBOBJ_SR_FLAG_M
811 uint32_ptr
= (uint32_t *)(obj_body_buf
+ index
);
812 /* Start with LENGTH_1WORD for the SubObj HDR + NT +
814 uint8_t sr_base_length
= LENGTH_1WORD
;
815 /* If the sid_absent flag is true, then dont convert the
817 if (sr_subobj
->flag_s
== false) {
818 uint32_ptr
[0] = htonl(sr_subobj
->sid
);
819 index
+= LENGTH_1WORD
;
820 uint32_ptr
= (uint32_t *)(obj_body_buf
+ index
);
821 sr_base_length
+= LENGTH_1WORD
;
824 /* The lengths below need to include:
825 * - sr_base_length: set above to include SR SubObj Hdr
826 * and the SID if present
827 * - Number of bytes written to the NAI
828 * The index will only be incremented below by the
829 * number of bytes written to the NAI, since the RO SR
830 * subobj header and the SID have already been written.
833 double_linked_list_node
*nai_node
=
834 (sr_subobj
->nai_list
== NULL
836 : sr_subobj
->nai_list
->head
);
837 if (nai_node
== NULL
) {
838 if (sr_subobj
->nai_type
839 == PCEP_SR_SUBOBJ_NAI_ABSENT
) {
840 *length_ptr
= sr_base_length
;
846 switch (sr_subobj
->nai_type
) {
847 case PCEP_SR_SUBOBJ_NAI_IPV4_NODE
:
849 ((struct in_addr
*)nai_node
->data
)
851 *length_ptr
= sr_base_length
+ LENGTH_1WORD
;
852 index
+= LENGTH_1WORD
;
855 case PCEP_SR_SUBOBJ_NAI_IPV6_NODE
:
856 encode_ipv6((struct in6_addr
*)nai_node
->data
,
858 *length_ptr
= sr_base_length
+ LENGTH_4WORDS
;
859 index
+= LENGTH_4WORDS
;
862 case PCEP_SR_SUBOBJ_NAI_UNNUMBERED_IPV4_ADJACENCY
:
864 ((struct in_addr
*)nai_node
->data
)
866 nai_node
= nai_node
->next_node
;
868 ((struct in_addr
*)nai_node
->data
)
870 nai_node
= nai_node
->next_node
;
872 ((struct in_addr
*)nai_node
->data
)
874 nai_node
= nai_node
->next_node
;
876 ((struct in_addr
*)nai_node
->data
)
878 *length_ptr
= sr_base_length
+ LENGTH_4WORDS
;
879 index
+= LENGTH_4WORDS
;
882 case PCEP_SR_SUBOBJ_NAI_IPV4_ADJACENCY
:
884 ((struct in_addr
*)nai_node
->data
)
886 nai_node
= nai_node
->next_node
;
888 ((struct in_addr
*)nai_node
->data
)
890 *length_ptr
= sr_base_length
+ LENGTH_2WORDS
;
891 index
+= LENGTH_2WORDS
;
894 case PCEP_SR_SUBOBJ_NAI_IPV6_ADJACENCY
:
895 encode_ipv6((struct in6_addr
*)nai_node
->data
,
897 nai_node
= nai_node
->next_node
;
898 encode_ipv6((struct in6_addr
*)nai_node
->data
,
900 *length_ptr
= sr_base_length
+ LENGTH_8WORDS
;
901 index
+= LENGTH_8WORDS
;
904 case PCEP_SR_SUBOBJ_NAI_LINK_LOCAL_IPV6_ADJACENCY
:
905 encode_ipv6((struct in6_addr
*)nai_node
->data
,
907 nai_node
= nai_node
->next_node
;
909 ((struct in_addr
*)nai_node
->data
)
911 nai_node
= nai_node
->next_node
;
912 encode_ipv6((struct in6_addr
*)nai_node
->data
,
914 nai_node
= nai_node
->next_node
;
916 ((struct in_addr
*)nai_node
->data
)
918 *length_ptr
= sr_base_length
+ LENGTH_10WORDS
;
919 index
+= LENGTH_10WORDS
;
935 void encode_ipv6(struct in6_addr
*src_ipv6
, uint32_t *dst
)
937 memcpy(dst
, src_ipv6
, sizeof(struct in6_addr
));
941 * Decoding functions.
944 void pcep_decode_object_hdr(const uint8_t *obj_buf
,
945 struct pcep_object_header
*obj_hdr
)
947 memset(obj_hdr
, 0, sizeof(struct pcep_object_header
));
949 obj_hdr
->object_class
= obj_buf
[0];
950 obj_hdr
->object_type
= (obj_buf
[1] >> 4) & 0x0f;
951 obj_hdr
->flag_p
= (obj_buf
[1] & OBJECT_HEADER_FLAG_P
);
952 obj_hdr
->flag_i
= (obj_buf
[1] & OBJECT_HEADER_FLAG_I
);
953 uint16_t net_order_length
;
954 memcpy(&net_order_length
, obj_buf
+ 2, sizeof(net_order_length
));
955 obj_hdr
->encoded_object_length
= ntohs(net_order_length
);
956 obj_hdr
->encoded_object
= obj_buf
;
959 uint16_t pcep_object_get_length(enum pcep_object_classes object_class
,
960 enum pcep_object_types object_type
)
962 uint8_t object_length
= pcep_object_class_lengths
[object_class
];
963 if (object_length
== 0) {
964 if (object_class
== PCEP_OBJ_CLASS_ENDPOINTS
) {
965 if (object_type
== PCEP_OBJ_TYPE_ENDPOINT_IPV4
) {
967 } else if (object_type
== PCEP_OBJ_TYPE_ENDPOINT_IPV6
) {
975 return object_length
;
978 uint16_t pcep_object_get_length_by_hdr(struct pcep_object_header
*object_hdr
)
980 return (pcep_object_get_length(object_hdr
->object_class
,
981 object_hdr
->object_type
));
984 bool pcep_object_has_tlvs(struct pcep_object_header
*object_hdr
)
986 uint8_t object_length
= pcep_object_get_length_by_hdr(object_hdr
);
987 if (object_length
== 0) {
991 return (object_hdr
->encoded_object_length
- object_length
) > 0;
994 struct pcep_object_header
*pcep_decode_object(const uint8_t *obj_buf
)
997 struct pcep_object_header object_hdr
;
998 /* Only initializes and decodes the Object Header: class, type, flags,
1000 pcep_decode_object_hdr(obj_buf
, &object_hdr
);
1002 if (object_hdr
.object_class
>= MAX_OBJECT_ENCODER_INDEX
) {
1004 "%s: Cannot decode unknown Object class [%d]",
1005 __func__
, object_hdr
.object_class
);
1009 object_decoder_funcptr obj_decoder
=
1010 object_decoders
[object_hdr
.object_class
];
1011 if (obj_decoder
== NULL
) {
1013 "%s: No object decoder found for Object class [%d]",
1014 __func__
, object_hdr
.object_class
);
1018 /* The object decoders will start decoding the object body, if
1019 * anything from the header is needed, they have the object_hdr */
1020 struct pcep_object_header
*object
=
1021 obj_decoder(&object_hdr
, obj_buf
+ OBJECT_HEADER_LENGTH
);
1022 if (object
== NULL
) {
1023 pcep_log(LOG_INFO
, "%s: Unable to decode Object class [%d].",
1024 __func__
, object_hdr
.object_class
);
1028 if (pcep_object_has_tlvs(&object_hdr
)) {
1029 object
->tlv_list
= dll_initialize();
1030 int num_iterations
= 0;
1031 uint16_t tlv_index
= pcep_object_get_length_by_hdr(&object_hdr
);
1032 while ((object
->encoded_object_length
- tlv_index
) > 0
1033 && num_iterations
++ < MAX_ITERATIONS
) {
1034 struct pcep_object_tlv_header
*tlv
=
1035 pcep_decode_tlv(obj_buf
+ tlv_index
);
1037 /* TODO should we do anything else here ? */
1041 /* The TLV length does not include the TLV header */
1042 tlv_index
+= normalize_pcep_tlv_length(
1043 tlv
->encoded_tlv_length
+ TLV_HEADER_LENGTH
);
1044 dll_append(object
->tlv_list
, tlv
);
1051 static struct pcep_object_header
*
1052 common_object_create(struct pcep_object_header
*hdr
, uint16_t new_obj_length
)
1054 struct pcep_object_header
*new_object
=
1055 pceplib_malloc(PCEPLIB_MESSAGES
, new_obj_length
);
1056 memset(new_object
, 0, new_obj_length
);
1057 memcpy(new_object
, hdr
, sizeof(struct pcep_object_header
));
1066 struct pcep_object_header
*pcep_decode_obj_open(struct pcep_object_header
*hdr
,
1067 const uint8_t *obj_buf
)
1069 struct pcep_object_open
*obj
=
1070 (struct pcep_object_open
*)common_object_create(
1071 hdr
, sizeof(struct pcep_object_open
));
1073 obj
->open_version
= (obj_buf
[0] >> 5) & 0x07;
1074 obj
->open_keepalive
= obj_buf
[1];
1075 obj
->open_deadtimer
= obj_buf
[2];
1076 obj
->open_sid
= obj_buf
[3];
1078 return (struct pcep_object_header
*)obj
;
1081 struct pcep_object_header
*pcep_decode_obj_rp(struct pcep_object_header
*hdr
,
1082 const uint8_t *obj_buf
)
1084 struct pcep_object_rp
*obj
=
1085 (struct pcep_object_rp
*)common_object_create(
1086 hdr
, sizeof(struct pcep_object_rp
));
1088 obj
->flag_reoptimization
= (obj_buf
[3] & OBJECT_RP_FLAG_R
);
1089 obj
->flag_bidirectional
= (obj_buf
[3] & OBJECT_RP_FLAG_B
);
1090 obj
->flag_strict
= (obj_buf
[3] & OBJECT_RP_FLAG_O
);
1091 obj
->flag_of
= (obj_buf
[3] & OBJECT_RP_FLAG_OF
);
1092 obj
->priority
= (obj_buf
[3] & 0x07);
1093 obj
->request_id
= ntohl(*((uint32_t *)(obj_buf
+ 4)));
1095 return (struct pcep_object_header
*)obj
;
1098 struct pcep_object_header
*
1099 pcep_decode_obj_notify(struct pcep_object_header
*hdr
, const uint8_t *obj_buf
)
1101 struct pcep_object_notify
*obj
=
1102 (struct pcep_object_notify
*)common_object_create(
1103 hdr
, sizeof(struct pcep_object_notify
));
1105 obj
->notification_type
= obj_buf
[2];
1106 obj
->notification_value
= obj_buf
[3];
1108 return (struct pcep_object_header
*)obj
;
1111 struct pcep_object_header
*
1112 pcep_decode_obj_nopath(struct pcep_object_header
*hdr
, const uint8_t *obj_buf
)
1114 struct pcep_object_nopath
*obj
=
1115 (struct pcep_object_nopath
*)common_object_create(
1116 hdr
, sizeof(struct pcep_object_nopath
));
1118 obj
->ni
= (obj_buf
[0] >> 1);
1119 obj
->flag_c
= (obj_buf
[0] & OBJECT_NOPATH_FLAG_C
);
1121 return (struct pcep_object_header
*)obj
;
1124 struct pcep_object_header
*
1125 pcep_decode_obj_association(struct pcep_object_header
*hdr
,
1126 const uint8_t *obj_buf
)
1128 uint16_t *uint16_ptr
= (uint16_t *)obj_buf
;
1129 uint32_t *uint32_ptr
= (uint32_t *)obj_buf
;
1131 if (hdr
->object_type
== PCEP_OBJ_TYPE_ASSOCIATION_IPV4
) {
1132 struct pcep_object_association_ipv4
*obj
=
1133 (struct pcep_object_association_ipv4
*)
1134 common_object_create(
1137 pcep_object_association_ipv4
));
1138 obj
->R_flag
= (obj_buf
[3] & OBJECT_ASSOCIATION_FLAG_R
);
1139 obj
->association_type
= ntohs(uint16_ptr
[2]);
1140 obj
->association_id
= ntohs(uint16_ptr
[3]);
1141 obj
->src
.s_addr
= uint32_ptr
[2];
1143 return (struct pcep_object_header
*)obj
;
1144 } else if (hdr
->object_type
== PCEP_OBJ_TYPE_ENDPOINT_IPV6
) {
1145 struct pcep_object_association_ipv6
*obj
=
1146 (struct pcep_object_association_ipv6
*)
1147 common_object_create(
1150 pcep_object_association_ipv6
));
1152 obj
->R_flag
= (obj_buf
[3] & OBJECT_ASSOCIATION_FLAG_R
);
1153 obj
->association_type
= ntohs(uint16_ptr
[2]);
1154 obj
->association_id
= ntohs(uint16_ptr
[3]);
1155 memcpy(&obj
->src
, &uint32_ptr
[2], sizeof(struct in6_addr
));
1157 return (struct pcep_object_header
*)obj
;
1162 struct pcep_object_header
*
1163 pcep_decode_obj_endpoints(struct pcep_object_header
*hdr
,
1164 const uint8_t *obj_buf
)
1166 uint32_t *uint32_ptr
= (uint32_t *)obj_buf
;
1168 if (hdr
->object_type
== PCEP_OBJ_TYPE_ENDPOINT_IPV4
) {
1169 struct pcep_object_endpoints_ipv4
*obj
=
1170 (struct pcep_object_endpoints_ipv4
*)
1171 common_object_create(
1174 pcep_object_endpoints_ipv4
));
1175 obj
->src_ipv4
.s_addr
= uint32_ptr
[0];
1176 obj
->dst_ipv4
.s_addr
= uint32_ptr
[1];
1178 return (struct pcep_object_header
*)obj
;
1179 } else if (hdr
->object_type
== PCEP_OBJ_TYPE_ENDPOINT_IPV6
) {
1180 struct pcep_object_endpoints_ipv6
*obj
=
1181 (struct pcep_object_endpoints_ipv6
*)
1182 common_object_create(
1185 pcep_object_endpoints_ipv6
));
1187 memcpy(&obj
->src_ipv6
, &uint32_ptr
[0], sizeof(struct in6_addr
));
1188 memcpy(&obj
->dst_ipv6
, &uint32_ptr
[4], sizeof(struct in6_addr
));
1190 return (struct pcep_object_header
*)obj
;
1196 struct pcep_object_header
*
1197 pcep_decode_obj_bandwidth(struct pcep_object_header
*hdr
,
1198 const uint8_t *obj_buf
)
1200 struct pcep_object_bandwidth
*obj
=
1201 (struct pcep_object_bandwidth
*)common_object_create(
1202 hdr
, sizeof(struct pcep_object_bandwidth
));
1204 uint32_t value
= ntohl(*((uint32_t *)obj_buf
));
1205 /* Seems like the compiler doesnt correctly copy to the float, so
1207 memcpy(&obj
->bandwidth
, &value
, sizeof(uint32_t));
1209 return (struct pcep_object_header
*)obj
;
1212 struct pcep_object_header
*
1213 pcep_decode_obj_metric(struct pcep_object_header
*hdr
, const uint8_t *obj_buf
)
1215 struct pcep_object_metric
*obj
=
1216 (struct pcep_object_metric
*)common_object_create(
1217 hdr
, sizeof(struct pcep_object_metric
));
1218 obj
->flag_b
= (obj_buf
[2] & OBJECT_METRIC_FLAC_B
);
1219 obj
->flag_c
= (obj_buf
[2] & OBJECT_METRIC_FLAC_C
);
1220 obj
->type
= obj_buf
[3];
1221 uint32_t value
= ntohl(*((uint32_t *)(obj_buf
+ 4)));
1222 /* Seems like the compiler doesnt correctly copy to the float, so
1224 memcpy(&obj
->value
, &value
, sizeof(uint32_t));
1226 return (struct pcep_object_header
*)obj
;
1229 struct pcep_object_header
*pcep_decode_obj_lspa(struct pcep_object_header
*hdr
,
1230 const uint8_t *obj_buf
)
1232 struct pcep_object_lspa
*obj
=
1233 (struct pcep_object_lspa
*)common_object_create(
1234 hdr
, sizeof(struct pcep_object_lspa
));
1235 uint32_t *uint32_ptr
= (uint32_t *)obj_buf
;
1237 obj
->lspa_exclude_any
= ntohl(uint32_ptr
[0]);
1238 obj
->lspa_include_any
= ntohl(uint32_ptr
[1]);
1239 obj
->lspa_include_all
= ntohl(uint32_ptr
[2]);
1240 obj
->setup_priority
= obj_buf
[12];
1241 obj
->holding_priority
= obj_buf
[13];
1242 obj
->flag_local_protection
= (obj_buf
[14] & OBJECT_LSPA_FLAG_L
);
1244 return (struct pcep_object_header
*)obj
;
1247 struct pcep_object_header
*pcep_decode_obj_svec(struct pcep_object_header
*hdr
,
1248 const uint8_t *obj_buf
)
1250 struct pcep_object_svec
*obj
=
1251 (struct pcep_object_svec
*)common_object_create(
1252 hdr
, sizeof(struct pcep_object_svec
));
1254 obj
->flag_link_diverse
= (obj_buf
[3] & OBJECT_SVEC_FLAG_L
);
1255 obj
->flag_node_diverse
= (obj_buf
[3] & OBJECT_SVEC_FLAG_N
);
1256 obj
->flag_srlg_diverse
= (obj_buf
[3] & OBJECT_SVEC_FLAG_S
);
1258 if (hdr
->encoded_object_length
> LENGTH_2WORDS
) {
1259 obj
->request_id_list
= dll_initialize();
1261 uint32_t *uint32_ptr
= (uint32_t *)obj_buf
;
1263 index
< ((hdr
->encoded_object_length
- LENGTH_2WORDS
) / 4);
1265 uint32_t *req_id_ptr
= pceplib_malloc(PCEPLIB_MESSAGES
,
1267 *req_id_ptr
= uint32_ptr
[index
];
1268 dll_append(obj
->request_id_list
, req_id_ptr
);
1272 return (struct pcep_object_header
*)obj
;
1275 struct pcep_object_header
*pcep_decode_obj_error(struct pcep_object_header
*hdr
,
1276 const uint8_t *obj_buf
)
1278 struct pcep_object_error
*obj
=
1279 (struct pcep_object_error
*)common_object_create(
1280 hdr
, sizeof(struct pcep_object_error
));
1282 obj
->error_type
= obj_buf
[2];
1283 obj
->error_value
= obj_buf
[3];
1285 return (struct pcep_object_header
*)obj
;
1288 struct pcep_object_header
*pcep_decode_obj_close(struct pcep_object_header
*hdr
,
1289 const uint8_t *obj_buf
)
1291 struct pcep_object_close
*obj
=
1292 (struct pcep_object_close
*)common_object_create(
1293 hdr
, sizeof(struct pcep_object_close
));
1295 obj
->reason
= obj_buf
[3];
1297 return (struct pcep_object_header
*)obj
;
1300 struct pcep_object_header
*pcep_decode_obj_srp(struct pcep_object_header
*hdr
,
1301 const uint8_t *obj_buf
)
1303 struct pcep_object_srp
*obj
=
1304 (struct pcep_object_srp
*)common_object_create(
1305 hdr
, sizeof(struct pcep_object_srp
));
1307 obj
->flag_lsp_remove
= (obj_buf
[3] & OBJECT_SRP_FLAG_R
);
1308 obj
->srp_id_number
= ntohl(*((uint32_t *)(obj_buf
+ 4)));
1310 return (struct pcep_object_header
*)obj
;
1313 struct pcep_object_header
*pcep_decode_obj_lsp(struct pcep_object_header
*hdr
,
1314 const uint8_t *obj_buf
)
1316 struct pcep_object_lsp
*obj
=
1317 (struct pcep_object_lsp
*)common_object_create(
1318 hdr
, sizeof(struct pcep_object_lsp
));
1320 obj
->flag_d
= (obj_buf
[3] & OBJECT_LSP_FLAG_D
);
1321 obj
->flag_s
= (obj_buf
[3] & OBJECT_LSP_FLAG_S
);
1322 obj
->flag_r
= (obj_buf
[3] & OBJECT_LSP_FLAG_R
);
1323 obj
->flag_a
= (obj_buf
[3] & OBJECT_LSP_FLAG_A
);
1324 obj
->flag_c
= (obj_buf
[3] & OBJECT_LSP_FLAG_C
);
1325 obj
->operational_status
= ((obj_buf
[3] >> 4) & 0x07);
1326 obj
->plsp_id
= ((ntohl(*((uint32_t *)obj_buf
)) >> 12) & 0x000fffff);
1328 return (struct pcep_object_header
*)obj
;
1331 struct pcep_object_header
*
1332 pcep_decode_obj_vendor_info(struct pcep_object_header
*hdr
,
1333 const uint8_t *obj_buf
)
1335 struct pcep_object_vendor_info
*obj
=
1336 (struct pcep_object_vendor_info
*)common_object_create(
1337 hdr
, sizeof(struct pcep_object_vendor_info
));
1338 obj
->enterprise_number
= ntohl(*((uint32_t *)(obj_buf
)));
1339 obj
->enterprise_specific_info
= ntohl(*((uint32_t *)(obj_buf
+ 4)));
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
:
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
;