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 * This is the implementation of a High Level PCEP message object API.
21 #include <arpa/inet.h>
25 #include "pcep_msg_objects.h"
26 #include "pcep_msg_tlvs.h"
27 #include "pcep_utils_double_linked_list.h"
28 #include "pcep_utils_logging.h"
29 #include "pcep_utils_memory.h"
31 /* Internal common function used to create a pcep_object and populate the header
33 static struct pcep_object_header
*pcep_obj_create_common_with_tlvs(
34 uint8_t obj_length
, enum pcep_object_classes object_class
,
35 enum pcep_object_types object_type
, double_linked_list
*tlv_list
)
37 uint8_t *buffer
= pceplib_malloc(PCEPLIB_MESSAGES
, obj_length
);
38 memset(buffer
, 0, obj_length
);
40 /* The flag_p and flag_i flags will be set externally */
41 struct pcep_object_header
*hdr
= (struct pcep_object_header
*)buffer
;
42 hdr
->object_class
= object_class
;
43 hdr
->object_type
= object_type
;
44 hdr
->tlv_list
= tlv_list
;
49 static struct pcep_object_header
*
50 pcep_obj_create_common(uint8_t obj_length
,
51 enum pcep_object_classes object_class
,
52 enum pcep_object_types object_type
)
54 return pcep_obj_create_common_with_tlvs(obj_length
, object_class
,
58 struct pcep_object_open
*pcep_obj_create_open(uint8_t keepalive
,
59 uint8_t deadtimer
, uint8_t sid
,
60 double_linked_list
*tlv_list
)
62 struct pcep_object_open
*open
=
63 (struct pcep_object_open
*)pcep_obj_create_common_with_tlvs(
64 sizeof(struct pcep_object_open
), PCEP_OBJ_CLASS_OPEN
,
65 PCEP_OBJ_TYPE_OPEN
, tlv_list
);
68 PCEP_OBJECT_OPEN_VERSION
; /* PCEP version. Current version is 1
69 /No flags are currently defined. */
70 open
->open_keepalive
=
71 keepalive
; /* Maximum period of time between two consecutive
72 PCEP messages sent by the sender. */
73 open
->open_deadtimer
= deadtimer
; /* Specifies the amount of time before
74 closing the session down. */
75 open
->open_sid
= sid
; /* PCEP session number that identifies the current
81 struct pcep_object_rp
*pcep_obj_create_rp(uint8_t priority
, bool flag_r
,
82 bool flag_b
, bool flag_s
,
83 bool flag_of
, uint32_t reqid
,
84 double_linked_list
*tlv_list
)
86 if (priority
> OBJECT_RP_MAX_PRIORITY
) {
89 "%s: Error creating RP object, invalid priority [%d], max priority [%d].",
90 __func__
, priority
, OBJECT_RP_MAX_PRIORITY
);
94 struct pcep_object_rp
*obj
=
95 (struct pcep_object_rp
*)pcep_obj_create_common_with_tlvs(
96 sizeof(struct pcep_object_rp
), PCEP_OBJ_CLASS_RP
,
97 PCEP_OBJ_TYPE_RP
, tlv_list
);
99 obj
->priority
= priority
;
100 obj
->flag_reoptimization
= flag_r
;
101 obj
->flag_bidirectional
= flag_b
;
102 obj
->flag_strict
= flag_s
;
103 obj
->flag_of
= flag_of
;
104 obj
->request_id
= reqid
;
109 struct pcep_object_notify
*
110 pcep_obj_create_notify(enum pcep_notification_types notification_type
,
111 enum pcep_notification_values notification_value
)
113 struct pcep_object_notify
*obj
=
114 (struct pcep_object_notify
*)pcep_obj_create_common(
115 sizeof(struct pcep_object_notify
), PCEP_OBJ_CLASS_NOTF
,
118 obj
->notification_type
= notification_type
;
119 obj
->notification_value
= notification_value
;
124 struct pcep_object_nopath
*
125 pcep_obj_create_nopath(uint8_t ni
, bool flag_c
,
126 enum pcep_nopath_tlv_err_codes error_code
)
128 struct pcep_object_tlv_nopath_vector
*tlv
=
129 pcep_tlv_create_nopath_vector(error_code
);
130 double_linked_list
*tlv_list
= dll_initialize();
131 dll_append(tlv_list
, tlv
);
133 struct pcep_object_nopath
*obj
=
134 (struct pcep_object_nopath
*)pcep_obj_create_common_with_tlvs(
135 sizeof(struct pcep_object_nopath
),
136 PCEP_OBJ_CLASS_NOPATH
, PCEP_OBJ_TYPE_NOPATH
, tlv_list
);
139 obj
->flag_c
= flag_c
;
140 obj
->err_code
= error_code
;
145 struct pcep_object_association_ipv4
*
146 pcep_obj_create_association_ipv4(bool r_flag
, uint16_t association_type
,
147 uint16_t association_id
, struct in_addr src
)
149 struct pcep_object_association_ipv4
*obj
=
150 (struct pcep_object_association_ipv4
*)pcep_obj_create_common(
151 sizeof(struct pcep_object_association_ipv4
),
152 PCEP_OBJ_CLASS_ASSOCIATION
,
153 PCEP_OBJ_TYPE_ASSOCIATION_IPV4
);
155 obj
->R_flag
= r_flag
;
156 obj
->association_type
= association_type
;
157 obj
->association_id
= association_id
;
162 struct pcep_object_association_ipv6
*
163 pcep_obj_create_association_ipv6(bool r_flag
, uint16_t association_type
,
164 uint16_t association_id
, struct in6_addr src
)
166 struct pcep_object_association_ipv6
*obj
=
167 (struct pcep_object_association_ipv6
*)pcep_obj_create_common(
168 sizeof(struct pcep_object_association_ipv6
),
169 PCEP_OBJ_CLASS_ASSOCIATION
,
170 PCEP_OBJ_TYPE_ASSOCIATION_IPV6
);
172 obj
->R_flag
= r_flag
;
173 obj
->association_type
= association_type
;
174 obj
->association_id
= association_id
;
179 struct pcep_object_endpoints_ipv4
*
180 pcep_obj_create_endpoint_ipv4(const struct in_addr
*src_ipv4
,
181 const struct in_addr
*dst_ipv4
)
183 if (src_ipv4
== NULL
|| dst_ipv4
== NULL
) {
187 struct pcep_object_endpoints_ipv4
*obj
=
188 (struct pcep_object_endpoints_ipv4
*)pcep_obj_create_common(
189 sizeof(struct pcep_object_endpoints_ipv4
),
190 PCEP_OBJ_CLASS_ENDPOINTS
, PCEP_OBJ_TYPE_ENDPOINT_IPV4
);
192 obj
->src_ipv4
.s_addr
= src_ipv4
->s_addr
;
193 obj
->dst_ipv4
.s_addr
= dst_ipv4
->s_addr
;
198 struct pcep_object_endpoints_ipv6
*
199 pcep_obj_create_endpoint_ipv6(const struct in6_addr
*src_ipv6
,
200 const struct in6_addr
*dst_ipv6
)
202 if (src_ipv6
== NULL
|| dst_ipv6
== NULL
) {
206 struct pcep_object_endpoints_ipv6
*obj
=
207 (struct pcep_object_endpoints_ipv6
*)pcep_obj_create_common(
208 sizeof(struct pcep_object_endpoints_ipv6
),
209 PCEP_OBJ_CLASS_ENDPOINTS
, PCEP_OBJ_TYPE_ENDPOINT_IPV6
);
211 memcpy(&obj
->src_ipv6
, src_ipv6
, sizeof(struct in6_addr
));
212 memcpy(&obj
->dst_ipv6
, dst_ipv6
, sizeof(struct in6_addr
));
217 struct pcep_object_bandwidth
*pcep_obj_create_bandwidth(float bandwidth
)
219 struct pcep_object_bandwidth
*obj
=
220 (struct pcep_object_bandwidth
*)pcep_obj_create_common(
221 sizeof(struct pcep_object_bandwidth
),
222 PCEP_OBJ_CLASS_BANDWIDTH
, PCEP_OBJ_TYPE_BANDWIDTH_REQ
);
224 obj
->bandwidth
= bandwidth
;
229 struct pcep_object_metric
*pcep_obj_create_metric(enum pcep_metric_types type
,
230 bool flag_b
, bool flag_c
,
233 struct pcep_object_metric
*obj
=
234 (struct pcep_object_metric
*)pcep_obj_create_common(
235 sizeof(struct pcep_object_metric
),
236 PCEP_OBJ_CLASS_METRIC
, PCEP_OBJ_TYPE_METRIC
);
238 obj
->flag_b
= flag_b
;
239 obj
->flag_c
= flag_c
;
246 struct pcep_object_lspa
*
247 pcep_obj_create_lspa(uint32_t exclude_any
, uint32_t include_any
,
248 uint32_t include_all
, uint8_t setup_priority
,
249 uint8_t holding_priority
, bool flag_local_protection
)
251 struct pcep_object_lspa
*obj
=
252 (struct pcep_object_lspa
*)pcep_obj_create_common(
253 sizeof(struct pcep_object_lspa
), PCEP_OBJ_CLASS_LSPA
,
256 obj
->lspa_exclude_any
= exclude_any
;
257 obj
->lspa_include_any
= include_any
;
258 obj
->lspa_include_all
= include_all
;
259 obj
->setup_priority
= setup_priority
;
260 obj
->holding_priority
= holding_priority
;
261 obj
->flag_local_protection
= flag_local_protection
;
266 struct pcep_object_svec
*
267 pcep_obj_create_svec(bool srlg
, bool node
, bool link
,
268 double_linked_list
*request_id_list
)
270 if (request_id_list
== NULL
) {
274 struct pcep_object_svec
*obj
=
275 (struct pcep_object_svec
*)pcep_obj_create_common(
276 sizeof(struct pcep_object_svec
), PCEP_OBJ_CLASS_SVEC
,
279 obj
->flag_srlg_diverse
= srlg
;
280 obj
->flag_node_diverse
= node
;
281 obj
->flag_link_diverse
= link
;
282 obj
->request_id_list
= request_id_list
;
287 struct pcep_object_error
*
288 pcep_obj_create_error(enum pcep_error_type error_type
,
289 enum pcep_error_value error_value
)
291 struct pcep_object_error
*obj
=
292 (struct pcep_object_error
*)pcep_obj_create_common(
293 sizeof(struct pcep_object_error
), PCEP_OBJ_CLASS_ERROR
,
294 PCEP_OBJ_TYPE_ERROR
);
296 obj
->error_type
= error_type
;
297 obj
->error_value
= error_value
;
302 struct pcep_object_close
*pcep_obj_create_close(enum pcep_close_reason reason
)
304 struct pcep_object_close
*obj
=
305 (struct pcep_object_close
*)pcep_obj_create_common(
306 sizeof(struct pcep_object_close
), PCEP_OBJ_CLASS_CLOSE
,
307 PCEP_OBJ_TYPE_CLOSE
);
309 obj
->reason
= reason
;
314 struct pcep_object_srp
*pcep_obj_create_srp(bool lsp_remove
,
315 uint32_t srp_id_number
,
316 double_linked_list
*tlv_list
)
318 struct pcep_object_srp
*obj
=
319 (struct pcep_object_srp
*)pcep_obj_create_common_with_tlvs(
320 sizeof(struct pcep_object_srp
), PCEP_OBJ_CLASS_SRP
,
321 PCEP_OBJ_TYPE_SRP
, tlv_list
);
323 obj
->flag_lsp_remove
= lsp_remove
;
324 obj
->srp_id_number
= srp_id_number
;
329 struct pcep_object_lsp
*
330 pcep_obj_create_lsp(uint32_t plsp_id
, enum pcep_lsp_operational_status status
,
331 bool c_flag
, bool a_flag
, bool r_flag
, bool s_flag
,
332 bool d_flag
, double_linked_list
*tlv_list
)
334 /* The plsp_id is only 20 bits */
335 if (plsp_id
> MAX_PLSP_ID
) {
338 "%s: pcep_obj_create_lsp invalid plsp_id [%d] max value [%d]",
339 __func__
, plsp_id
, MAX_PLSP_ID
);
343 /* The status is only 3 bits */
344 if (status
> MAX_LSP_STATUS
) {
347 "%s: pcep_obj_create_lsp invalid status [%d] max value [%d]",
348 __func__
, plsp_id
, MAX_PLSP_ID
);
352 struct pcep_object_lsp
*obj
=
353 (struct pcep_object_lsp
*)pcep_obj_create_common_with_tlvs(
354 sizeof(struct pcep_object_lsp
), PCEP_OBJ_CLASS_LSP
,
355 PCEP_OBJ_TYPE_LSP
, tlv_list
);
357 obj
->plsp_id
= plsp_id
;
358 obj
->operational_status
= status
;
359 obj
->flag_c
= c_flag
;
360 obj
->flag_a
= a_flag
;
361 obj
->flag_r
= r_flag
;
362 obj
->flag_s
= s_flag
;
363 obj
->flag_d
= d_flag
;
368 struct pcep_object_vendor_info
*
369 pcep_obj_create_vendor_info(uint32_t enterprise_number
,
370 uint32_t enterprise_spec_info
)
372 struct pcep_object_vendor_info
*obj
=
373 (struct pcep_object_vendor_info
*)pcep_obj_create_common(
374 sizeof(struct pcep_object_vendor_info
),
375 PCEP_OBJ_CLASS_VENDOR_INFO
, PCEP_OBJ_TYPE_VENDOR_INFO
);
377 obj
->enterprise_number
= enterprise_number
;
378 obj
->enterprise_specific_info
= enterprise_spec_info
;
383 struct pcep_object_inter_layer
*
384 pcep_obj_create_inter_layer(bool flag_i
, bool flag_m
, bool flag_t
)
386 struct pcep_object_inter_layer
*obj
=
387 (struct pcep_object_inter_layer
*)pcep_obj_create_common(
388 sizeof(struct pcep_object_inter_layer
),
389 PCEP_OBJ_CLASS_INTER_LAYER
, PCEP_OBJ_TYPE_INTER_LAYER
);
391 obj
->flag_i
= flag_i
;
392 obj
->flag_m
= flag_m
;
393 obj
->flag_t
= flag_t
;
398 struct pcep_object_switch_layer
*
399 pcep_obj_create_switch_layer(double_linked_list
*switch_layer_rows
)
401 struct pcep_object_switch_layer
*obj
=
402 (struct pcep_object_switch_layer
*)pcep_obj_create_common(
403 sizeof(struct pcep_object_switch_layer
),
404 PCEP_OBJ_CLASS_SWITCH_LAYER
,
405 PCEP_OBJ_TYPE_SWITCH_LAYER
);
407 obj
->switch_layer_rows
= switch_layer_rows
;
412 struct pcep_object_req_adap_cap
*
413 pcep_obj_create_req_adap_cap(enum pcep_switching_capability sw_cap
,
414 enum pcep_lsp_encoding_type encoding
)
416 struct pcep_object_req_adap_cap
*obj
=
417 (struct pcep_object_req_adap_cap
*)pcep_obj_create_common(
418 sizeof(struct pcep_object_req_adap_cap
),
419 PCEP_OBJ_CLASS_REQ_ADAP_CAP
,
420 PCEP_OBJ_TYPE_REQ_ADAP_CAP
);
422 obj
->switching_capability
= sw_cap
;
423 obj
->encoding
= encoding
;
428 struct pcep_object_server_indication
*
429 pcep_obj_create_server_indication(enum pcep_switching_capability sw_cap
,
430 enum pcep_lsp_encoding_type encoding
,
431 double_linked_list
*tlv_list
)
433 struct pcep_object_server_indication
*obj
=
434 (struct pcep_object_server_indication
*)
435 pcep_obj_create_common_with_tlvs(
436 sizeof(struct pcep_object_server_indication
),
437 PCEP_OBJ_CLASS_SERVER_IND
,
438 PCEP_OBJ_TYPE_SERVER_IND
, tlv_list
);
440 obj
->switching_capability
= sw_cap
;
441 obj
->encoding
= encoding
;
446 struct pcep_object_objective_function
*
447 pcep_obj_create_objective_function(uint16_t of_code
,
448 double_linked_list
*tlv_list
)
450 struct pcep_object_objective_function
*obj
=
451 (struct pcep_object_objective_function
*)
452 pcep_obj_create_common_with_tlvs(
453 sizeof(struct pcep_object_objective_function
),
454 PCEP_OBJ_CLASS_OF
, PCEP_OBJ_TYPE_OF
, tlv_list
);
456 obj
->of_code
= of_code
;
461 /* Wrap a list of ro subobjects in a structure with an object header */
462 struct pcep_object_ro
*pcep_obj_create_ero(double_linked_list
*ero_list
)
464 struct pcep_object_ro
*ero
=
465 (struct pcep_object_ro
*)pcep_obj_create_common(
466 sizeof(struct pcep_object_ro
), PCEP_OBJ_CLASS_ERO
,
468 ero
->sub_objects
= ero_list
;
473 /* Wrap a list of ro subobjects in a structure with an object header */
474 struct pcep_object_ro
*pcep_obj_create_iro(double_linked_list
*iro_list
)
476 struct pcep_object_ro
*iro
=
477 (struct pcep_object_ro
*)pcep_obj_create_common(
478 sizeof(struct pcep_object_ro
), PCEP_OBJ_CLASS_IRO
,
480 iro
->sub_objects
= iro_list
;
485 /* Wrap a list of ro subobjects in a structure with an object header */
486 struct pcep_object_ro
*pcep_obj_create_rro(double_linked_list
*rro_list
)
488 struct pcep_object_ro
*rro
=
489 (struct pcep_object_ro
*)pcep_obj_create_common(
490 sizeof(struct pcep_object_ro
), PCEP_OBJ_CLASS_RRO
,
492 rro
->sub_objects
= rro_list
;
498 * Route Object Sub-object creation functions
501 static struct pcep_object_ro_subobj
*
502 pcep_obj_create_ro_subobj_common(uint8_t subobj_size
,
503 enum pcep_ro_subobj_types ro_subobj_type
,
504 bool flag_subobj_loose_hop
)
506 struct pcep_object_ro_subobj
*ro_subobj
=
507 pceplib_malloc(PCEPLIB_MESSAGES
, subobj_size
);
508 memset(ro_subobj
, 0, subobj_size
);
509 ro_subobj
->flag_subobj_loose_hop
= flag_subobj_loose_hop
;
510 ro_subobj
->ro_subobj_type
= ro_subobj_type
;
515 struct pcep_ro_subobj_ipv4
*
516 pcep_obj_create_ro_subobj_ipv4(bool loose_hop
, const struct in_addr
*rro_ipv4
,
517 uint8_t prefix_length
, bool flag_local_prot
)
519 if (rro_ipv4
== NULL
) {
523 struct pcep_ro_subobj_ipv4
*obj
=
524 (struct pcep_ro_subobj_ipv4
*)pcep_obj_create_ro_subobj_common(
525 sizeof(struct pcep_ro_subobj_ipv4
), RO_SUBOBJ_TYPE_IPV4
,
527 obj
->ip_addr
.s_addr
= rro_ipv4
->s_addr
;
528 obj
->prefix_length
= prefix_length
;
529 obj
->flag_local_protection
= flag_local_prot
;
534 struct pcep_ro_subobj_ipv6
*
535 pcep_obj_create_ro_subobj_ipv6(bool loose_hop
, const struct in6_addr
*rro_ipv6
,
536 uint8_t prefix_length
, bool flag_local_prot
)
538 if (rro_ipv6
== NULL
) {
542 struct pcep_ro_subobj_ipv6
*obj
=
543 (struct pcep_ro_subobj_ipv6
*)pcep_obj_create_ro_subobj_common(
544 sizeof(struct pcep_ro_subobj_ipv6
), RO_SUBOBJ_TYPE_IPV6
,
546 obj
->prefix_length
= prefix_length
;
547 obj
->flag_local_protection
= flag_local_prot
;
548 memcpy(&obj
->ip_addr
, rro_ipv6
, sizeof(struct in6_addr
));
553 struct pcep_ro_subobj_unnum
*
554 pcep_obj_create_ro_subobj_unnum(struct in_addr
*router_id
, uint32_t if_id
)
556 if (router_id
== NULL
) {
560 struct pcep_ro_subobj_unnum
*obj
=
561 (struct pcep_ro_subobj_unnum
*)pcep_obj_create_ro_subobj_common(
562 sizeof(struct pcep_ro_subobj_unnum
),
563 RO_SUBOBJ_TYPE_UNNUM
, false);
564 obj
->interface_id
= if_id
;
565 obj
->router_id
.s_addr
= router_id
->s_addr
;
570 struct pcep_ro_subobj_32label
*
571 pcep_obj_create_ro_subobj_32label(bool flag_global_label
, uint8_t class_type
,
574 struct pcep_ro_subobj_32label
*obj
= (struct pcep_ro_subobj_32label
*)
575 pcep_obj_create_ro_subobj_common(
576 sizeof(struct pcep_ro_subobj_32label
),
577 RO_SUBOBJ_TYPE_LABEL
, false);
578 obj
->class_type
= class_type
;
579 obj
->flag_global_label
= flag_global_label
;
585 struct pcep_ro_subobj_asn
*pcep_obj_create_ro_subobj_asn(uint16_t asn
)
587 struct pcep_ro_subobj_asn
*obj
=
588 (struct pcep_ro_subobj_asn
*)pcep_obj_create_ro_subobj_common(
589 sizeof(struct pcep_ro_subobj_asn
), RO_SUBOBJ_TYPE_ASN
,
596 /* Internal util function to create pcep_ro_subobj_sr sub-objects */
597 static struct pcep_ro_subobj_sr
*
598 pcep_obj_create_ro_subobj_sr_common(enum pcep_sr_subobj_nai nai_type
,
599 bool loose_hop
, bool f_flag
, bool s_flag
,
600 bool c_flag_in
, bool m_flag_in
)
602 struct pcep_ro_subobj_sr
*obj
=
603 (struct pcep_ro_subobj_sr
*)pcep_obj_create_ro_subobj_common(
604 sizeof(struct pcep_ro_subobj_sr
), RO_SUBOBJ_TYPE_SR
,
607 /* Flag logic according to draft-ietf-pce-segment-routing-16 */
608 bool c_flag
= c_flag_in
;
609 bool m_flag
= m_flag_in
;
615 if (m_flag
== false) {
619 obj
->nai_type
= nai_type
;
620 obj
->flag_f
= f_flag
;
621 obj
->flag_s
= s_flag
;
622 obj
->flag_c
= c_flag
;
623 obj
->flag_m
= m_flag
;
628 struct pcep_ro_subobj_sr
*pcep_obj_create_ro_subobj_sr_nonai(bool loose_hop
,
633 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
634 * If NT=0, the F bit MUST be 1, the S bit MUST be zero and the
635 * Length MUST be 8. */
636 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
637 PCEP_SR_SUBOBJ_NAI_ABSENT
, loose_hop
, true, false, c_flag
,
644 struct pcep_ro_subobj_sr
*
645 pcep_obj_create_ro_subobj_sr_ipv4_node(bool loose_hop
, bool sid_absent
,
646 bool c_flag
, bool m_flag
, uint32_t sid
,
647 struct in_addr
*ipv4_node_id
)
649 if (ipv4_node_id
== NULL
) {
653 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
654 * If NT=1, the F bit MUST be zero. If the S bit is 1, the Length
655 * MUST be 8, otherwise the Length MUST be 12 */
656 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
657 PCEP_SR_SUBOBJ_NAI_IPV4_NODE
, loose_hop
, false, sid_absent
,
663 obj
->nai_list
= dll_initialize();
664 /* Since the IP has to be stored in the list, copy it so the caller
665 * doesn't have any restrictions about the type of memory used
666 * externally for the IP. This memory will be freed with the object is
668 struct in_addr
*ipv4_node_id_copy
=
669 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in_addr
));
670 ipv4_node_id_copy
->s_addr
= ipv4_node_id
->s_addr
;
671 dll_append(obj
->nai_list
, ipv4_node_id_copy
);
676 struct pcep_ro_subobj_sr
*
677 pcep_obj_create_ro_subobj_sr_ipv6_node(bool loose_hop
, bool sid_absent
,
678 bool c_flag
, bool m_flag
, uint32_t sid
,
679 struct in6_addr
*ipv6_node_id
)
681 if (ipv6_node_id
== NULL
) {
685 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
686 * If NT=2, the F bit MUST be zero. If the S bit is 1, the Length
687 * MUST be 20, otherwise the Length MUST be 24. */
688 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
689 PCEP_SR_SUBOBJ_NAI_IPV6_NODE
, loose_hop
, false, sid_absent
,
695 obj
->nai_list
= dll_initialize();
696 struct in6_addr
*ipv6_node_id_copy
=
697 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in6_addr
));
698 memcpy(ipv6_node_id_copy
, ipv6_node_id
, sizeof(struct in6_addr
));
699 dll_append(obj
->nai_list
, ipv6_node_id_copy
);
704 struct pcep_ro_subobj_sr
*pcep_obj_create_ro_subobj_sr_ipv4_adj(
705 bool loose_hop
, bool sid_absent
, bool c_flag
, bool m_flag
, uint32_t sid
,
706 struct in_addr
*local_ipv4
, struct in_addr
*remote_ipv4
)
708 if (local_ipv4
== NULL
|| remote_ipv4
== NULL
) {
712 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
713 * If NT=3, the F bit MUST be zero. If the S bit is 1, the Length
714 * MUST be 12, otherwise the Length MUST be 16 */
715 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
716 PCEP_SR_SUBOBJ_NAI_IPV4_ADJACENCY
, loose_hop
, false, sid_absent
,
722 obj
->nai_list
= dll_initialize();
723 struct in_addr
*local_ipv4_copy
=
724 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in_addr
));
725 struct in_addr
*remote_ipv4_copy
=
726 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in_addr
));
727 local_ipv4_copy
->s_addr
= local_ipv4
->s_addr
;
728 remote_ipv4_copy
->s_addr
= remote_ipv4
->s_addr
;
729 dll_append(obj
->nai_list
, local_ipv4_copy
);
730 dll_append(obj
->nai_list
, remote_ipv4_copy
);
735 struct pcep_ro_subobj_sr
*pcep_obj_create_ro_subobj_sr_ipv6_adj(
736 bool loose_hop
, bool sid_absent
, bool c_flag
, bool m_flag
, uint32_t sid
,
737 struct in6_addr
*local_ipv6
, struct in6_addr
*remote_ipv6
)
739 if (local_ipv6
== NULL
|| remote_ipv6
== NULL
) {
743 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
744 * If NT=4, the F bit MUST be zero. If the S bit is 1, the Length
745 * MUST be 36, otherwise the Length MUST be 40 */
746 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
747 PCEP_SR_SUBOBJ_NAI_IPV6_ADJACENCY
, loose_hop
, false, sid_absent
,
753 obj
->nai_list
= dll_initialize();
754 struct in6_addr
*local_ipv6_copy
=
755 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in6_addr
));
756 struct in6_addr
*remote_ipv6_copy
=
757 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in6_addr
));
758 memcpy(local_ipv6_copy
, local_ipv6
, sizeof(struct in6_addr
));
759 memcpy(remote_ipv6_copy
, remote_ipv6
, sizeof(struct in6_addr
));
760 dll_append(obj
->nai_list
, local_ipv6_copy
);
761 dll_append(obj
->nai_list
, remote_ipv6_copy
);
766 struct pcep_ro_subobj_sr
*pcep_obj_create_ro_subobj_sr_unnumbered_ipv4_adj(
767 bool loose_hop
, bool sid_absent
, bool c_flag
, bool m_flag
, uint32_t sid
,
768 uint32_t local_node_id
, uint32_t local_if_id
, uint32_t remote_node_id
,
769 uint32_t remote_if_id
)
771 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
772 * If NT=5, the F bit MUST be zero. If the S bit is 1, the Length
773 * MUST be 20, otherwise the Length MUST be 24. */
774 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
775 PCEP_SR_SUBOBJ_NAI_UNNUMBERED_IPV4_ADJACENCY
, loose_hop
, false,
776 sid_absent
, c_flag
, m_flag
);
782 obj
->nai_list
= dll_initialize();
783 uint32_t *local_node_id_copy
=
784 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint32_t));
785 *local_node_id_copy
= local_node_id
;
786 dll_append(obj
->nai_list
, local_node_id_copy
);
788 uint32_t *local_if_id_copy
=
789 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint32_t));
790 *local_if_id_copy
= local_if_id
;
791 dll_append(obj
->nai_list
, local_if_id_copy
);
793 uint32_t *remote_node_id_copy
=
794 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint32_t));
795 *remote_node_id_copy
= remote_node_id
;
796 dll_append(obj
->nai_list
, remote_node_id_copy
);
798 uint32_t *remote_if_id_copy
=
799 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint32_t));
800 *remote_if_id_copy
= remote_if_id
;
801 dll_append(obj
->nai_list
, remote_if_id_copy
);
806 struct pcep_ro_subobj_sr
*pcep_obj_create_ro_subobj_sr_linklocal_ipv6_adj(
807 bool loose_hop
, bool sid_absent
, bool c_flag
, bool m_flag
, uint32_t sid
,
808 struct in6_addr
*local_ipv6
, uint32_t local_if_id
,
809 struct in6_addr
*remote_ipv6
, uint32_t remote_if_id
)
811 if (local_ipv6
== NULL
|| remote_ipv6
== NULL
) {
815 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
816 * If NT=6, the F bit MUST be zero. If the S bit is 1, the Length
817 * MUST be 44, otherwise the Length MUST be 48 */
818 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
819 PCEP_SR_SUBOBJ_NAI_LINK_LOCAL_IPV6_ADJACENCY
, loose_hop
, false,
820 sid_absent
, c_flag
, m_flag
);
825 obj
->nai_list
= dll_initialize();
826 struct in6_addr
*local_ipv6_copy
=
827 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in6_addr
));
828 memcpy(local_ipv6_copy
, local_ipv6
, sizeof(struct in6_addr
));
829 dll_append(obj
->nai_list
, local_ipv6_copy
);
831 uint32_t *local_if_id_copy
=
832 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint32_t));
833 *local_if_id_copy
= local_if_id
;
834 dll_append(obj
->nai_list
, local_if_id_copy
);
836 struct in6_addr
*remote_ipv6_copy
=
837 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in6_addr
));
838 memcpy(remote_ipv6_copy
, remote_ipv6
, sizeof(struct in6_addr
));
839 dll_append(obj
->nai_list
, remote_ipv6_copy
);
841 uint32_t *remote_if_id_copy
=
842 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint32_t));
843 *remote_if_id_copy
= remote_if_id
;
844 dll_append(obj
->nai_list
, remote_if_id_copy
);