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 * This is the implementation of a High Level PCEP message object API.
29 #include <arpa/inet.h>
33 #include "pcep_msg_objects.h"
34 #include "pcep_msg_tlvs.h"
35 #include "pcep_utils_double_linked_list.h"
36 #include "pcep_utils_logging.h"
37 #include "pcep_utils_memory.h"
39 /* Internal common function used to create a pcep_object and populate the header
41 static struct pcep_object_header
*pcep_obj_create_common_with_tlvs(
42 uint8_t obj_length
, enum pcep_object_classes object_class
,
43 enum pcep_object_types object_type
, double_linked_list
*tlv_list
)
45 uint8_t *buffer
= pceplib_malloc(PCEPLIB_MESSAGES
, obj_length
);
46 memset(buffer
, 0, obj_length
);
48 /* The flag_p and flag_i flags will be set externally */
49 struct pcep_object_header
*hdr
= (struct pcep_object_header
*)buffer
;
50 hdr
->object_class
= object_class
;
51 hdr
->object_type
= object_type
;
52 hdr
->tlv_list
= tlv_list
;
57 static struct pcep_object_header
*
58 pcep_obj_create_common(uint8_t obj_length
,
59 enum pcep_object_classes object_class
,
60 enum pcep_object_types object_type
)
62 return pcep_obj_create_common_with_tlvs(obj_length
, object_class
,
66 struct pcep_object_open
*pcep_obj_create_open(uint8_t keepalive
,
67 uint8_t deadtimer
, uint8_t sid
,
68 double_linked_list
*tlv_list
)
70 struct pcep_object_open
*open
=
71 (struct pcep_object_open
*)pcep_obj_create_common_with_tlvs(
72 sizeof(struct pcep_object_open
), PCEP_OBJ_CLASS_OPEN
,
73 PCEP_OBJ_TYPE_OPEN
, tlv_list
);
76 PCEP_OBJECT_OPEN_VERSION
; /* PCEP version. Current version is 1
77 /No flags are currently defined. */
78 open
->open_keepalive
=
79 keepalive
; /* Maximum period of time between two consecutive
80 PCEP messages sent by the sender. */
81 open
->open_deadtimer
= deadtimer
; /* Specifies the amount of time before
82 closing the session down. */
83 open
->open_sid
= sid
; /* PCEP session number that identifies the current
89 struct pcep_object_rp
*pcep_obj_create_rp(uint8_t priority
, bool flag_r
,
90 bool flag_b
, bool flag_s
,
91 bool flag_of
, uint32_t reqid
,
92 double_linked_list
*tlv_list
)
94 if (priority
> OBJECT_RP_MAX_PRIORITY
) {
97 "%s: Error creating RP object, invalid priority [%d], max priority [%d].",
98 __func__
, priority
, OBJECT_RP_MAX_PRIORITY
);
102 struct pcep_object_rp
*obj
=
103 (struct pcep_object_rp
*)pcep_obj_create_common_with_tlvs(
104 sizeof(struct pcep_object_rp
), PCEP_OBJ_CLASS_RP
,
105 PCEP_OBJ_TYPE_RP
, tlv_list
);
107 obj
->priority
= priority
;
108 obj
->flag_reoptimization
= flag_r
;
109 obj
->flag_bidirectional
= flag_b
;
110 obj
->flag_strict
= flag_s
;
111 obj
->flag_of
= flag_of
;
112 obj
->request_id
= reqid
;
117 struct pcep_object_notify
*
118 pcep_obj_create_notify(enum pcep_notification_types notification_type
,
119 enum pcep_notification_values notification_value
)
121 struct pcep_object_notify
*obj
=
122 (struct pcep_object_notify
*)pcep_obj_create_common(
123 sizeof(struct pcep_object_notify
), PCEP_OBJ_CLASS_NOTF
,
126 obj
->notification_type
= notification_type
;
127 obj
->notification_value
= notification_value
;
132 struct pcep_object_nopath
*
133 pcep_obj_create_nopath(uint8_t ni
, bool flag_c
,
134 enum pcep_nopath_tlv_err_codes error_code
)
136 struct pcep_object_tlv_nopath_vector
*tlv
=
137 pcep_tlv_create_nopath_vector(error_code
);
138 double_linked_list
*tlv_list
= dll_initialize();
139 dll_append(tlv_list
, tlv
);
141 struct pcep_object_nopath
*obj
=
142 (struct pcep_object_nopath
*)pcep_obj_create_common_with_tlvs(
143 sizeof(struct pcep_object_nopath
),
144 PCEP_OBJ_CLASS_NOPATH
, PCEP_OBJ_TYPE_NOPATH
, tlv_list
);
147 obj
->flag_c
= flag_c
;
148 obj
->err_code
= error_code
;
153 struct pcep_object_association_ipv4
*
154 pcep_obj_create_association_ipv4(bool r_flag
, uint16_t association_type
,
155 uint16_t association_id
, struct in_addr src
)
157 struct pcep_object_association_ipv4
*obj
=
158 (struct pcep_object_association_ipv4
*)pcep_obj_create_common(
159 sizeof(struct pcep_object_association_ipv4
),
160 PCEP_OBJ_CLASS_ASSOCIATION
,
161 PCEP_OBJ_TYPE_ASSOCIATION_IPV4
);
163 obj
->R_flag
= r_flag
;
164 obj
->association_type
= association_type
;
165 obj
->association_id
= association_id
;
170 struct pcep_object_association_ipv6
*
171 pcep_obj_create_association_ipv6(bool r_flag
, uint16_t association_type
,
172 uint16_t association_id
, struct in6_addr src
)
174 struct pcep_object_association_ipv6
*obj
=
175 (struct pcep_object_association_ipv6
*)pcep_obj_create_common(
176 sizeof(struct pcep_object_association_ipv6
),
177 PCEP_OBJ_CLASS_ASSOCIATION
,
178 PCEP_OBJ_TYPE_ASSOCIATION_IPV6
);
180 obj
->R_flag
= r_flag
;
181 obj
->association_type
= association_type
;
182 obj
->association_id
= association_id
;
187 struct pcep_object_endpoints_ipv4
*
188 pcep_obj_create_endpoint_ipv4(const struct in_addr
*src_ipv4
,
189 const struct in_addr
*dst_ipv4
)
191 if (src_ipv4
== NULL
|| dst_ipv4
== NULL
) {
195 struct pcep_object_endpoints_ipv4
*obj
=
196 (struct pcep_object_endpoints_ipv4
*)pcep_obj_create_common(
197 sizeof(struct pcep_object_endpoints_ipv4
),
198 PCEP_OBJ_CLASS_ENDPOINTS
, PCEP_OBJ_TYPE_ENDPOINT_IPV4
);
200 obj
->src_ipv4
.s_addr
= src_ipv4
->s_addr
;
201 obj
->dst_ipv4
.s_addr
= dst_ipv4
->s_addr
;
206 struct pcep_object_endpoints_ipv6
*
207 pcep_obj_create_endpoint_ipv6(const struct in6_addr
*src_ipv6
,
208 const struct in6_addr
*dst_ipv6
)
210 if (src_ipv6
== NULL
|| dst_ipv6
== NULL
) {
214 struct pcep_object_endpoints_ipv6
*obj
=
215 (struct pcep_object_endpoints_ipv6
*)pcep_obj_create_common(
216 sizeof(struct pcep_object_endpoints_ipv6
),
217 PCEP_OBJ_CLASS_ENDPOINTS
, PCEP_OBJ_TYPE_ENDPOINT_IPV6
);
219 memcpy(&obj
->src_ipv6
, src_ipv6
, sizeof(struct in6_addr
));
220 memcpy(&obj
->dst_ipv6
, dst_ipv6
, sizeof(struct in6_addr
));
225 struct pcep_object_bandwidth
*pcep_obj_create_bandwidth(float bandwidth
)
227 struct pcep_object_bandwidth
*obj
=
228 (struct pcep_object_bandwidth
*)pcep_obj_create_common(
229 sizeof(struct pcep_object_bandwidth
),
230 PCEP_OBJ_CLASS_BANDWIDTH
, PCEP_OBJ_TYPE_BANDWIDTH_REQ
);
232 obj
->bandwidth
= bandwidth
;
237 struct pcep_object_metric
*pcep_obj_create_metric(enum pcep_metric_types type
,
238 bool flag_b
, bool flag_c
,
241 struct pcep_object_metric
*obj
=
242 (struct pcep_object_metric
*)pcep_obj_create_common(
243 sizeof(struct pcep_object_metric
),
244 PCEP_OBJ_CLASS_METRIC
, PCEP_OBJ_TYPE_METRIC
);
246 obj
->flag_b
= flag_b
;
247 obj
->flag_c
= flag_c
;
254 struct pcep_object_lspa
*
255 pcep_obj_create_lspa(uint32_t exclude_any
, uint32_t include_any
,
256 uint32_t include_all
, uint8_t setup_priority
,
257 uint8_t holding_priority
, bool flag_local_protection
)
259 struct pcep_object_lspa
*obj
=
260 (struct pcep_object_lspa
*)pcep_obj_create_common(
261 sizeof(struct pcep_object_lspa
), PCEP_OBJ_CLASS_LSPA
,
264 obj
->lspa_exclude_any
= exclude_any
;
265 obj
->lspa_include_any
= include_any
;
266 obj
->lspa_include_all
= include_all
;
267 obj
->setup_priority
= setup_priority
;
268 obj
->holding_priority
= holding_priority
;
269 obj
->flag_local_protection
= flag_local_protection
;
274 struct pcep_object_svec
*
275 pcep_obj_create_svec(bool srlg
, bool node
, bool link
,
276 double_linked_list
*request_id_list
)
278 if (request_id_list
== NULL
) {
282 struct pcep_object_svec
*obj
=
283 (struct pcep_object_svec
*)pcep_obj_create_common(
284 sizeof(struct pcep_object_svec
), PCEP_OBJ_CLASS_SVEC
,
287 obj
->flag_srlg_diverse
= srlg
;
288 obj
->flag_node_diverse
= node
;
289 obj
->flag_link_diverse
= link
;
290 obj
->request_id_list
= request_id_list
;
295 struct pcep_object_error
*
296 pcep_obj_create_error(enum pcep_error_type error_type
,
297 enum pcep_error_value error_value
)
299 struct pcep_object_error
*obj
=
300 (struct pcep_object_error
*)pcep_obj_create_common(
301 sizeof(struct pcep_object_error
), PCEP_OBJ_CLASS_ERROR
,
302 PCEP_OBJ_TYPE_ERROR
);
304 obj
->error_type
= error_type
;
305 obj
->error_value
= error_value
;
310 struct pcep_object_close
*pcep_obj_create_close(enum pcep_close_reason reason
)
312 struct pcep_object_close
*obj
=
313 (struct pcep_object_close
*)pcep_obj_create_common(
314 sizeof(struct pcep_object_close
), PCEP_OBJ_CLASS_CLOSE
,
315 PCEP_OBJ_TYPE_CLOSE
);
317 obj
->reason
= reason
;
322 struct pcep_object_srp
*pcep_obj_create_srp(bool lsp_remove
,
323 uint32_t srp_id_number
,
324 double_linked_list
*tlv_list
)
326 struct pcep_object_srp
*obj
=
327 (struct pcep_object_srp
*)pcep_obj_create_common_with_tlvs(
328 sizeof(struct pcep_object_srp
), PCEP_OBJ_CLASS_SRP
,
329 PCEP_OBJ_TYPE_SRP
, tlv_list
);
331 obj
->flag_lsp_remove
= lsp_remove
;
332 obj
->srp_id_number
= srp_id_number
;
337 struct pcep_object_lsp
*
338 pcep_obj_create_lsp(uint32_t plsp_id
, enum pcep_lsp_operational_status status
,
339 bool c_flag
, bool a_flag
, bool r_flag
, bool s_flag
,
340 bool d_flag
, double_linked_list
*tlv_list
)
342 /* The plsp_id is only 20 bits */
343 if (plsp_id
> MAX_PLSP_ID
) {
346 "%s: pcep_obj_create_lsp invalid plsp_id [%d] max value [%d]",
347 __func__
, plsp_id
, MAX_PLSP_ID
);
351 /* The status is only 3 bits */
352 if (status
> MAX_LSP_STATUS
) {
355 "%s: pcep_obj_create_lsp invalid status [%d] max value [%d]",
356 __func__
, plsp_id
, MAX_PLSP_ID
);
360 struct pcep_object_lsp
*obj
=
361 (struct pcep_object_lsp
*)pcep_obj_create_common_with_tlvs(
362 sizeof(struct pcep_object_lsp
), PCEP_OBJ_CLASS_LSP
,
363 PCEP_OBJ_TYPE_LSP
, tlv_list
);
365 obj
->plsp_id
= plsp_id
;
366 obj
->operational_status
= status
;
367 obj
->flag_c
= c_flag
;
368 obj
->flag_a
= a_flag
;
369 obj
->flag_r
= r_flag
;
370 obj
->flag_s
= s_flag
;
371 obj
->flag_d
= d_flag
;
376 struct pcep_object_vendor_info
*
377 pcep_obj_create_vendor_info(uint32_t enterprise_number
,
378 uint32_t enterprise_spec_info
)
380 struct pcep_object_vendor_info
*obj
=
381 (struct pcep_object_vendor_info
*)pcep_obj_create_common(
382 sizeof(struct pcep_object_vendor_info
),
383 PCEP_OBJ_CLASS_VENDOR_INFO
, PCEP_OBJ_TYPE_VENDOR_INFO
);
385 obj
->enterprise_number
= enterprise_number
;
386 obj
->enterprise_specific_info
= enterprise_spec_info
;
391 struct pcep_object_inter_layer
*
392 pcep_obj_create_inter_layer(bool flag_i
, bool flag_m
, bool flag_t
)
394 struct pcep_object_inter_layer
*obj
=
395 (struct pcep_object_inter_layer
*)pcep_obj_create_common(
396 sizeof(struct pcep_object_inter_layer
),
397 PCEP_OBJ_CLASS_INTER_LAYER
, PCEP_OBJ_TYPE_INTER_LAYER
);
399 obj
->flag_i
= flag_i
;
400 obj
->flag_m
= flag_m
;
401 obj
->flag_t
= flag_t
;
406 struct pcep_object_switch_layer
*
407 pcep_obj_create_switch_layer(double_linked_list
*switch_layer_rows
)
409 struct pcep_object_switch_layer
*obj
=
410 (struct pcep_object_switch_layer
*)pcep_obj_create_common(
411 sizeof(struct pcep_object_switch_layer
),
412 PCEP_OBJ_CLASS_SWITCH_LAYER
,
413 PCEP_OBJ_TYPE_SWITCH_LAYER
);
415 obj
->switch_layer_rows
= switch_layer_rows
;
420 struct pcep_object_req_adap_cap
*
421 pcep_obj_create_req_adap_cap(enum pcep_switching_capability sw_cap
,
422 enum pcep_lsp_encoding_type encoding
)
424 struct pcep_object_req_adap_cap
*obj
=
425 (struct pcep_object_req_adap_cap
*)pcep_obj_create_common(
426 sizeof(struct pcep_object_req_adap_cap
),
427 PCEP_OBJ_CLASS_REQ_ADAP_CAP
,
428 PCEP_OBJ_TYPE_REQ_ADAP_CAP
);
430 obj
->switching_capability
= sw_cap
;
431 obj
->encoding
= encoding
;
436 struct pcep_object_server_indication
*
437 pcep_obj_create_server_indication(enum pcep_switching_capability sw_cap
,
438 enum pcep_lsp_encoding_type encoding
,
439 double_linked_list
*tlv_list
)
441 struct pcep_object_server_indication
*obj
=
442 (struct pcep_object_server_indication
*)
443 pcep_obj_create_common_with_tlvs(
444 sizeof(struct pcep_object_server_indication
),
445 PCEP_OBJ_CLASS_SERVER_IND
,
446 PCEP_OBJ_TYPE_SERVER_IND
, tlv_list
);
448 obj
->switching_capability
= sw_cap
;
449 obj
->encoding
= encoding
;
454 struct pcep_object_objective_function
*
455 pcep_obj_create_objective_function(uint16_t of_code
,
456 double_linked_list
*tlv_list
)
458 struct pcep_object_objective_function
*obj
=
459 (struct pcep_object_objective_function
*)
460 pcep_obj_create_common_with_tlvs(
461 sizeof(struct pcep_object_objective_function
),
462 PCEP_OBJ_CLASS_OF
, PCEP_OBJ_TYPE_OF
, tlv_list
);
464 obj
->of_code
= of_code
;
469 /* Wrap a list of ro subobjects in a structure with an object header */
470 struct pcep_object_ro
*pcep_obj_create_ero(double_linked_list
*ero_list
)
472 struct pcep_object_ro
*ero
=
473 (struct pcep_object_ro
*)pcep_obj_create_common(
474 sizeof(struct pcep_object_ro
), PCEP_OBJ_CLASS_ERO
,
476 ero
->sub_objects
= ero_list
;
481 /* Wrap a list of ro subobjects in a structure with an object header */
482 struct pcep_object_ro
*pcep_obj_create_iro(double_linked_list
*iro_list
)
484 struct pcep_object_ro
*iro
=
485 (struct pcep_object_ro
*)pcep_obj_create_common(
486 sizeof(struct pcep_object_ro
), PCEP_OBJ_CLASS_IRO
,
488 iro
->sub_objects
= iro_list
;
493 /* Wrap a list of ro subobjects in a structure with an object header */
494 struct pcep_object_ro
*pcep_obj_create_rro(double_linked_list
*rro_list
)
496 struct pcep_object_ro
*rro
=
497 (struct pcep_object_ro
*)pcep_obj_create_common(
498 sizeof(struct pcep_object_ro
), PCEP_OBJ_CLASS_RRO
,
500 rro
->sub_objects
= rro_list
;
506 * Route Object Sub-object creation functions
509 static struct pcep_object_ro_subobj
*
510 pcep_obj_create_ro_subobj_common(uint8_t subobj_size
,
511 enum pcep_ro_subobj_types ro_subobj_type
,
512 bool flag_subobj_loose_hop
)
514 struct pcep_object_ro_subobj
*ro_subobj
=
515 pceplib_malloc(PCEPLIB_MESSAGES
, subobj_size
);
516 memset(ro_subobj
, 0, subobj_size
);
517 ro_subobj
->flag_subobj_loose_hop
= flag_subobj_loose_hop
;
518 ro_subobj
->ro_subobj_type
= ro_subobj_type
;
523 struct pcep_ro_subobj_ipv4
*
524 pcep_obj_create_ro_subobj_ipv4(bool loose_hop
, const struct in_addr
*rro_ipv4
,
525 uint8_t prefix_length
, bool flag_local_prot
)
527 if (rro_ipv4
== NULL
) {
531 struct pcep_ro_subobj_ipv4
*obj
=
532 (struct pcep_ro_subobj_ipv4
*)pcep_obj_create_ro_subobj_common(
533 sizeof(struct pcep_ro_subobj_ipv4
), RO_SUBOBJ_TYPE_IPV4
,
535 obj
->ip_addr
.s_addr
= rro_ipv4
->s_addr
;
536 obj
->prefix_length
= prefix_length
;
537 obj
->flag_local_protection
= flag_local_prot
;
542 struct pcep_ro_subobj_ipv6
*
543 pcep_obj_create_ro_subobj_ipv6(bool loose_hop
, const struct in6_addr
*rro_ipv6
,
544 uint8_t prefix_length
, bool flag_local_prot
)
546 if (rro_ipv6
== NULL
) {
550 struct pcep_ro_subobj_ipv6
*obj
=
551 (struct pcep_ro_subobj_ipv6
*)pcep_obj_create_ro_subobj_common(
552 sizeof(struct pcep_ro_subobj_ipv6
), RO_SUBOBJ_TYPE_IPV6
,
554 obj
->prefix_length
= prefix_length
;
555 obj
->flag_local_protection
= flag_local_prot
;
556 memcpy(&obj
->ip_addr
, rro_ipv6
, sizeof(struct in6_addr
));
561 struct pcep_ro_subobj_unnum
*
562 pcep_obj_create_ro_subobj_unnum(struct in_addr
*router_id
, uint32_t if_id
)
564 if (router_id
== NULL
) {
568 struct pcep_ro_subobj_unnum
*obj
=
569 (struct pcep_ro_subobj_unnum
*)pcep_obj_create_ro_subobj_common(
570 sizeof(struct pcep_ro_subobj_unnum
),
571 RO_SUBOBJ_TYPE_UNNUM
, false);
572 obj
->interface_id
= if_id
;
573 obj
->router_id
.s_addr
= router_id
->s_addr
;
578 struct pcep_ro_subobj_32label
*
579 pcep_obj_create_ro_subobj_32label(bool flag_global_label
, uint8_t class_type
,
582 struct pcep_ro_subobj_32label
*obj
= (struct pcep_ro_subobj_32label
*)
583 pcep_obj_create_ro_subobj_common(
584 sizeof(struct pcep_ro_subobj_32label
),
585 RO_SUBOBJ_TYPE_LABEL
, false);
586 obj
->class_type
= class_type
;
587 obj
->flag_global_label
= flag_global_label
;
593 struct pcep_ro_subobj_asn
*pcep_obj_create_ro_subobj_asn(uint16_t asn
)
595 struct pcep_ro_subobj_asn
*obj
=
596 (struct pcep_ro_subobj_asn
*)pcep_obj_create_ro_subobj_common(
597 sizeof(struct pcep_ro_subobj_asn
), RO_SUBOBJ_TYPE_ASN
,
604 /* Internal util function to create pcep_ro_subobj_sr sub-objects */
605 static struct pcep_ro_subobj_sr
*
606 pcep_obj_create_ro_subobj_sr_common(enum pcep_sr_subobj_nai nai_type
,
607 bool loose_hop
, bool f_flag
, bool s_flag
,
608 bool c_flag_in
, bool m_flag_in
)
610 struct pcep_ro_subobj_sr
*obj
=
611 (struct pcep_ro_subobj_sr
*)pcep_obj_create_ro_subobj_common(
612 sizeof(struct pcep_ro_subobj_sr
), RO_SUBOBJ_TYPE_SR
,
615 /* Flag logic according to draft-ietf-pce-segment-routing-16 */
616 bool c_flag
= c_flag_in
;
617 bool m_flag
= m_flag_in
;
623 if (m_flag
== false) {
627 obj
->nai_type
= nai_type
;
628 obj
->flag_f
= f_flag
;
629 obj
->flag_s
= s_flag
;
630 obj
->flag_c
= c_flag
;
631 obj
->flag_m
= m_flag
;
636 struct pcep_ro_subobj_sr
*pcep_obj_create_ro_subobj_sr_nonai(bool loose_hop
,
641 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
642 * If NT=0, the F bit MUST be 1, the S bit MUST be zero and the
643 * Length MUST be 8. */
644 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
645 PCEP_SR_SUBOBJ_NAI_ABSENT
, loose_hop
, true, false, c_flag
,
652 struct pcep_ro_subobj_sr
*
653 pcep_obj_create_ro_subobj_sr_ipv4_node(bool loose_hop
, bool sid_absent
,
654 bool c_flag
, bool m_flag
, uint32_t sid
,
655 struct in_addr
*ipv4_node_id
)
657 if (ipv4_node_id
== NULL
) {
661 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
662 * If NT=1, the F bit MUST be zero. If the S bit is 1, the Length
663 * MUST be 8, otherwise the Length MUST be 12 */
664 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
665 PCEP_SR_SUBOBJ_NAI_IPV4_NODE
, loose_hop
, false, sid_absent
,
671 obj
->nai_list
= dll_initialize();
672 /* Since the IP has to be stored in the list, copy it so the caller
673 * doesnt have any restrictions about the type of memory used externally
674 * for the IP. This memory will be freed with the object is freed. */
675 struct in_addr
*ipv4_node_id_copy
=
676 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in_addr
));
677 ipv4_node_id_copy
->s_addr
= ipv4_node_id
->s_addr
;
678 dll_append(obj
->nai_list
, ipv4_node_id_copy
);
683 struct pcep_ro_subobj_sr
*
684 pcep_obj_create_ro_subobj_sr_ipv6_node(bool loose_hop
, bool sid_absent
,
685 bool c_flag
, bool m_flag
, uint32_t sid
,
686 struct in6_addr
*ipv6_node_id
)
688 if (ipv6_node_id
== NULL
) {
692 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
693 * If NT=2, the F bit MUST be zero. If the S bit is 1, the Length
694 * MUST be 20, otherwise the Length MUST be 24. */
695 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
696 PCEP_SR_SUBOBJ_NAI_IPV6_NODE
, loose_hop
, false, sid_absent
,
702 obj
->nai_list
= dll_initialize();
703 struct in6_addr
*ipv6_node_id_copy
=
704 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in6_addr
));
705 memcpy(ipv6_node_id_copy
, ipv6_node_id
, sizeof(struct in6_addr
));
706 dll_append(obj
->nai_list
, ipv6_node_id_copy
);
711 struct pcep_ro_subobj_sr
*pcep_obj_create_ro_subobj_sr_ipv4_adj(
712 bool loose_hop
, bool sid_absent
, bool c_flag
, bool m_flag
, uint32_t sid
,
713 struct in_addr
*local_ipv4
, struct in_addr
*remote_ipv4
)
715 if (local_ipv4
== NULL
|| remote_ipv4
== NULL
) {
719 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
720 * If NT=3, the F bit MUST be zero. If the S bit is 1, the Length
721 * MUST be 12, otherwise the Length MUST be 16 */
722 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
723 PCEP_SR_SUBOBJ_NAI_IPV4_ADJACENCY
, loose_hop
, false, sid_absent
,
729 obj
->nai_list
= dll_initialize();
730 struct in_addr
*local_ipv4_copy
=
731 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in_addr
));
732 struct in_addr
*remote_ipv4_copy
=
733 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in_addr
));
734 local_ipv4_copy
->s_addr
= local_ipv4
->s_addr
;
735 remote_ipv4_copy
->s_addr
= remote_ipv4
->s_addr
;
736 dll_append(obj
->nai_list
, local_ipv4_copy
);
737 dll_append(obj
->nai_list
, remote_ipv4_copy
);
742 struct pcep_ro_subobj_sr
*pcep_obj_create_ro_subobj_sr_ipv6_adj(
743 bool loose_hop
, bool sid_absent
, bool c_flag
, bool m_flag
, uint32_t sid
,
744 struct in6_addr
*local_ipv6
, struct in6_addr
*remote_ipv6
)
746 if (local_ipv6
== NULL
|| remote_ipv6
== NULL
) {
750 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
751 * If NT=4, the F bit MUST be zero. If the S bit is 1, the Length
752 * MUST be 36, otherwise the Length MUST be 40 */
753 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
754 PCEP_SR_SUBOBJ_NAI_IPV6_ADJACENCY
, loose_hop
, false, sid_absent
,
760 obj
->nai_list
= dll_initialize();
761 struct in6_addr
*local_ipv6_copy
=
762 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in6_addr
));
763 struct in6_addr
*remote_ipv6_copy
=
764 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in6_addr
));
765 memcpy(local_ipv6_copy
, local_ipv6
, sizeof(struct in6_addr
));
766 memcpy(remote_ipv6_copy
, remote_ipv6
, sizeof(struct in6_addr
));
767 dll_append(obj
->nai_list
, local_ipv6_copy
);
768 dll_append(obj
->nai_list
, remote_ipv6_copy
);
773 struct pcep_ro_subobj_sr
*pcep_obj_create_ro_subobj_sr_unnumbered_ipv4_adj(
774 bool loose_hop
, bool sid_absent
, bool c_flag
, bool m_flag
, uint32_t sid
,
775 uint32_t local_node_id
, uint32_t local_if_id
, uint32_t remote_node_id
,
776 uint32_t remote_if_id
)
778 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
779 * If NT=5, the F bit MUST be zero. If the S bit is 1, the Length
780 * MUST be 20, otherwise the Length MUST be 24. */
781 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
782 PCEP_SR_SUBOBJ_NAI_UNNUMBERED_IPV4_ADJACENCY
, loose_hop
, false,
783 sid_absent
, c_flag
, m_flag
);
789 obj
->nai_list
= dll_initialize();
790 uint32_t *local_node_id_copy
=
791 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint32_t));
792 *local_node_id_copy
= local_node_id
;
793 dll_append(obj
->nai_list
, local_node_id_copy
);
795 uint32_t *local_if_id_copy
=
796 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint32_t));
797 *local_if_id_copy
= local_if_id
;
798 dll_append(obj
->nai_list
, local_if_id_copy
);
800 uint32_t *remote_node_id_copy
=
801 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint32_t));
802 *remote_node_id_copy
= remote_node_id
;
803 dll_append(obj
->nai_list
, remote_node_id_copy
);
805 uint32_t *remote_if_id_copy
=
806 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint32_t));
807 *remote_if_id_copy
= remote_if_id
;
808 dll_append(obj
->nai_list
, remote_if_id_copy
);
813 struct pcep_ro_subobj_sr
*pcep_obj_create_ro_subobj_sr_linklocal_ipv6_adj(
814 bool loose_hop
, bool sid_absent
, bool c_flag
, bool m_flag
, uint32_t sid
,
815 struct in6_addr
*local_ipv6
, uint32_t local_if_id
,
816 struct in6_addr
*remote_ipv6
, uint32_t remote_if_id
)
818 if (local_ipv6
== NULL
|| remote_ipv6
== NULL
) {
822 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
823 * If NT=6, the F bit MUST be zero. If the S bit is 1, the Length
824 * MUST be 44, otherwise the Length MUST be 48 */
825 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
826 PCEP_SR_SUBOBJ_NAI_LINK_LOCAL_IPV6_ADJACENCY
, loose_hop
, false,
827 sid_absent
, c_flag
, m_flag
);
832 obj
->nai_list
= dll_initialize();
833 struct in6_addr
*local_ipv6_copy
=
834 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in6_addr
));
835 memcpy(local_ipv6_copy
, local_ipv6
, sizeof(struct in6_addr
));
836 dll_append(obj
->nai_list
, local_ipv6_copy
);
838 uint32_t *local_if_id_copy
=
839 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint32_t));
840 *local_if_id_copy
= local_if_id
;
841 dll_append(obj
->nai_list
, local_if_id_copy
);
843 struct in6_addr
*remote_ipv6_copy
=
844 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in6_addr
));
845 memcpy(remote_ipv6_copy
, remote_ipv6
, sizeof(struct in6_addr
));
846 dll_append(obj
->nai_list
, remote_ipv6_copy
);
848 uint32_t *remote_if_id_copy
=
849 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint32_t));
850 *remote_if_id_copy
= remote_if_id
;
851 dll_append(obj
->nai_list
, remote_if_id_copy
);