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.
33 #include <arpa/inet.h>
37 #include "pcep_msg_objects.h"
38 #include "pcep_msg_tlvs.h"
39 #include "pcep_utils_double_linked_list.h"
40 #include "pcep_utils_logging.h"
41 #include "pcep_utils_memory.h"
43 /* Internal common function used to create a pcep_object and populate the header
45 static struct pcep_object_header
*pcep_obj_create_common_with_tlvs(
46 uint8_t obj_length
, enum pcep_object_classes object_class
,
47 enum pcep_object_types object_type
, double_linked_list
*tlv_list
)
49 uint8_t *buffer
= pceplib_malloc(PCEPLIB_MESSAGES
, obj_length
);
50 memset(buffer
, 0, obj_length
);
52 /* The flag_p and flag_i flags will be set externally */
53 struct pcep_object_header
*hdr
= (struct pcep_object_header
*)buffer
;
54 hdr
->object_class
= object_class
;
55 hdr
->object_type
= object_type
;
56 hdr
->tlv_list
= tlv_list
;
61 static struct pcep_object_header
*
62 pcep_obj_create_common(uint8_t obj_length
,
63 enum pcep_object_classes object_class
,
64 enum pcep_object_types object_type
)
66 return pcep_obj_create_common_with_tlvs(obj_length
, object_class
,
70 struct pcep_object_open
*pcep_obj_create_open(uint8_t keepalive
,
71 uint8_t deadtimer
, uint8_t sid
,
72 double_linked_list
*tlv_list
)
74 struct pcep_object_open
*open
=
75 (struct pcep_object_open
*)pcep_obj_create_common_with_tlvs(
76 sizeof(struct pcep_object_open
), PCEP_OBJ_CLASS_OPEN
,
77 PCEP_OBJ_TYPE_OPEN
, tlv_list
);
80 PCEP_OBJECT_OPEN_VERSION
; /* PCEP version. Current version is 1
81 /No flags are currently defined. */
82 open
->open_keepalive
=
83 keepalive
; /* Maximum period of time between two consecutive
84 PCEP messages sent by the sender. */
85 open
->open_deadtimer
= deadtimer
; /* Specifies the amount of time before
86 closing the session down. */
87 open
->open_sid
= sid
; /* PCEP session number that identifies the current
93 struct pcep_object_rp
*pcep_obj_create_rp(uint8_t priority
, bool flag_r
,
94 bool flag_b
, bool flag_s
,
95 bool flag_of
, uint32_t reqid
,
96 double_linked_list
*tlv_list
)
98 if (priority
> OBJECT_RP_MAX_PRIORITY
) {
101 "%s: Error creating RP object, invalid priority [%d], max priority [%d].",
102 __func__
, priority
, OBJECT_RP_MAX_PRIORITY
);
106 struct pcep_object_rp
*obj
=
107 (struct pcep_object_rp
*)pcep_obj_create_common_with_tlvs(
108 sizeof(struct pcep_object_rp
), PCEP_OBJ_CLASS_RP
,
109 PCEP_OBJ_TYPE_RP
, tlv_list
);
111 obj
->priority
= priority
;
112 obj
->flag_reoptimization
= flag_r
;
113 obj
->flag_bidirectional
= flag_b
;
114 obj
->flag_strict
= flag_s
;
115 obj
->flag_of
= flag_of
;
116 obj
->request_id
= reqid
;
121 struct pcep_object_notify
*
122 pcep_obj_create_notify(enum pcep_notification_types notification_type
,
123 enum pcep_notification_values notification_value
)
125 struct pcep_object_notify
*obj
=
126 (struct pcep_object_notify
*)pcep_obj_create_common(
127 sizeof(struct pcep_object_notify
), PCEP_OBJ_CLASS_NOTF
,
130 obj
->notification_type
= notification_type
;
131 obj
->notification_value
= notification_value
;
136 struct pcep_object_nopath
*
137 pcep_obj_create_nopath(uint8_t ni
, bool flag_c
,
138 enum pcep_nopath_tlv_err_codes error_code
)
140 struct pcep_object_tlv_nopath_vector
*tlv
=
141 pcep_tlv_create_nopath_vector(error_code
);
142 double_linked_list
*tlv_list
= dll_initialize();
143 dll_append(tlv_list
, tlv
);
145 struct pcep_object_nopath
*obj
=
146 (struct pcep_object_nopath
*)pcep_obj_create_common_with_tlvs(
147 sizeof(struct pcep_object_nopath
),
148 PCEP_OBJ_CLASS_NOPATH
, PCEP_OBJ_TYPE_NOPATH
, tlv_list
);
151 obj
->flag_c
= flag_c
;
152 obj
->err_code
= error_code
;
157 struct pcep_object_association_ipv4
*
158 pcep_obj_create_association_ipv4(bool r_flag
, uint16_t association_type
,
159 uint16_t association_id
, struct in_addr src
)
161 struct pcep_object_association_ipv4
*obj
=
162 (struct pcep_object_association_ipv4
*)pcep_obj_create_common(
163 sizeof(struct pcep_object_association_ipv4
),
164 PCEP_OBJ_CLASS_ASSOCIATION
,
165 PCEP_OBJ_TYPE_ASSOCIATION_IPV4
);
167 obj
->R_flag
= r_flag
;
168 obj
->association_type
= association_type
;
169 obj
->association_id
= association_id
;
174 struct pcep_object_association_ipv6
*
175 pcep_obj_create_association_ipv6(bool r_flag
, uint16_t association_type
,
176 uint16_t association_id
, struct in6_addr src
)
178 struct pcep_object_association_ipv6
*obj
=
179 (struct pcep_object_association_ipv6
*)pcep_obj_create_common(
180 sizeof(struct pcep_object_association_ipv6
),
181 PCEP_OBJ_CLASS_ASSOCIATION
,
182 PCEP_OBJ_TYPE_ASSOCIATION_IPV6
);
184 obj
->R_flag
= r_flag
;
185 obj
->association_type
= association_type
;
186 obj
->association_id
= association_id
;
191 struct pcep_object_endpoints_ipv4
*
192 pcep_obj_create_endpoint_ipv4(const struct in_addr
*src_ipv4
,
193 const struct in_addr
*dst_ipv4
)
195 if (src_ipv4
== NULL
|| dst_ipv4
== NULL
) {
199 struct pcep_object_endpoints_ipv4
*obj
=
200 (struct pcep_object_endpoints_ipv4
*)pcep_obj_create_common(
201 sizeof(struct pcep_object_endpoints_ipv4
),
202 PCEP_OBJ_CLASS_ENDPOINTS
, PCEP_OBJ_TYPE_ENDPOINT_IPV4
);
204 obj
->src_ipv4
.s_addr
= src_ipv4
->s_addr
;
205 obj
->dst_ipv4
.s_addr
= dst_ipv4
->s_addr
;
210 struct pcep_object_endpoints_ipv6
*
211 pcep_obj_create_endpoint_ipv6(const struct in6_addr
*src_ipv6
,
212 const struct in6_addr
*dst_ipv6
)
214 if (src_ipv6
== NULL
|| dst_ipv6
== NULL
) {
218 struct pcep_object_endpoints_ipv6
*obj
=
219 (struct pcep_object_endpoints_ipv6
*)pcep_obj_create_common(
220 sizeof(struct pcep_object_endpoints_ipv6
),
221 PCEP_OBJ_CLASS_ENDPOINTS
, PCEP_OBJ_TYPE_ENDPOINT_IPV6
);
223 memcpy(&obj
->src_ipv6
, src_ipv6
, sizeof(struct in6_addr
));
224 memcpy(&obj
->dst_ipv6
, dst_ipv6
, sizeof(struct in6_addr
));
229 struct pcep_object_bandwidth
*pcep_obj_create_bandwidth(float bandwidth
)
231 struct pcep_object_bandwidth
*obj
=
232 (struct pcep_object_bandwidth
*)pcep_obj_create_common(
233 sizeof(struct pcep_object_bandwidth
),
234 PCEP_OBJ_CLASS_BANDWIDTH
, PCEP_OBJ_TYPE_BANDWIDTH_REQ
);
236 obj
->bandwidth
= bandwidth
;
241 struct pcep_object_metric
*pcep_obj_create_metric(enum pcep_metric_types type
,
242 bool flag_b
, bool flag_c
,
245 struct pcep_object_metric
*obj
=
246 (struct pcep_object_metric
*)pcep_obj_create_common(
247 sizeof(struct pcep_object_metric
),
248 PCEP_OBJ_CLASS_METRIC
, PCEP_OBJ_TYPE_METRIC
);
250 obj
->flag_b
= flag_b
;
251 obj
->flag_c
= flag_c
;
258 struct pcep_object_lspa
*
259 pcep_obj_create_lspa(uint32_t exclude_any
, uint32_t include_any
,
260 uint32_t include_all
, uint8_t setup_priority
,
261 uint8_t holding_priority
, bool flag_local_protection
)
263 struct pcep_object_lspa
*obj
=
264 (struct pcep_object_lspa
*)pcep_obj_create_common(
265 sizeof(struct pcep_object_lspa
), PCEP_OBJ_CLASS_LSPA
,
268 obj
->lspa_exclude_any
= exclude_any
;
269 obj
->lspa_include_any
= include_any
;
270 obj
->lspa_include_all
= include_all
;
271 obj
->setup_priority
= setup_priority
;
272 obj
->holding_priority
= holding_priority
;
273 obj
->flag_local_protection
= flag_local_protection
;
278 struct pcep_object_svec
*
279 pcep_obj_create_svec(bool srlg
, bool node
, bool link
,
280 double_linked_list
*request_id_list
)
282 if (request_id_list
== NULL
) {
286 struct pcep_object_svec
*obj
=
287 (struct pcep_object_svec
*)pcep_obj_create_common(
288 sizeof(struct pcep_object_svec
), PCEP_OBJ_CLASS_SVEC
,
291 obj
->flag_srlg_diverse
= srlg
;
292 obj
->flag_node_diverse
= node
;
293 obj
->flag_link_diverse
= link
;
294 obj
->request_id_list
= request_id_list
;
299 struct pcep_object_error
*
300 pcep_obj_create_error(enum pcep_error_type error_type
,
301 enum pcep_error_value error_value
)
303 struct pcep_object_error
*obj
=
304 (struct pcep_object_error
*)pcep_obj_create_common(
305 sizeof(struct pcep_object_error
), PCEP_OBJ_CLASS_ERROR
,
306 PCEP_OBJ_TYPE_ERROR
);
308 obj
->error_type
= error_type
;
309 obj
->error_value
= error_value
;
314 struct pcep_object_close
*pcep_obj_create_close(enum pcep_close_reason reason
)
316 struct pcep_object_close
*obj
=
317 (struct pcep_object_close
*)pcep_obj_create_common(
318 sizeof(struct pcep_object_close
), PCEP_OBJ_CLASS_CLOSE
,
319 PCEP_OBJ_TYPE_CLOSE
);
321 obj
->reason
= reason
;
326 struct pcep_object_srp
*pcep_obj_create_srp(bool lsp_remove
,
327 uint32_t srp_id_number
,
328 double_linked_list
*tlv_list
)
330 struct pcep_object_srp
*obj
=
331 (struct pcep_object_srp
*)pcep_obj_create_common_with_tlvs(
332 sizeof(struct pcep_object_srp
), PCEP_OBJ_CLASS_SRP
,
333 PCEP_OBJ_TYPE_SRP
, tlv_list
);
335 obj
->flag_lsp_remove
= lsp_remove
;
336 obj
->srp_id_number
= srp_id_number
;
341 struct pcep_object_lsp
*
342 pcep_obj_create_lsp(uint32_t plsp_id
, enum pcep_lsp_operational_status status
,
343 bool c_flag
, bool a_flag
, bool r_flag
, bool s_flag
,
344 bool d_flag
, double_linked_list
*tlv_list
)
346 /* The plsp_id is only 20 bits */
347 if (plsp_id
> MAX_PLSP_ID
) {
350 "%s: pcep_obj_create_lsp invalid plsp_id [%d] max value [%d]",
351 __func__
, plsp_id
, MAX_PLSP_ID
);
355 /* The status is only 3 bits */
356 if (status
> MAX_LSP_STATUS
) {
359 "%s: pcep_obj_create_lsp invalid status [%d] max value [%d]",
360 __func__
, plsp_id
, MAX_PLSP_ID
);
364 struct pcep_object_lsp
*obj
=
365 (struct pcep_object_lsp
*)pcep_obj_create_common_with_tlvs(
366 sizeof(struct pcep_object_lsp
), PCEP_OBJ_CLASS_LSP
,
367 PCEP_OBJ_TYPE_LSP
, tlv_list
);
369 obj
->plsp_id
= plsp_id
;
370 obj
->operational_status
= status
;
371 obj
->flag_c
= c_flag
;
372 obj
->flag_a
= a_flag
;
373 obj
->flag_r
= r_flag
;
374 obj
->flag_s
= s_flag
;
375 obj
->flag_d
= d_flag
;
380 struct pcep_object_vendor_info
*
381 pcep_obj_create_vendor_info(uint32_t enterprise_number
,
382 uint32_t enterprise_spec_info
)
384 struct pcep_object_vendor_info
*obj
=
385 (struct pcep_object_vendor_info
*)pcep_obj_create_common(
386 sizeof(struct pcep_object_vendor_info
),
387 PCEP_OBJ_CLASS_VENDOR_INFO
, PCEP_OBJ_TYPE_VENDOR_INFO
);
389 obj
->enterprise_number
= enterprise_number
;
390 obj
->enterprise_specific_info
= enterprise_spec_info
;
395 struct pcep_object_inter_layer
*
396 pcep_obj_create_inter_layer(bool flag_i
, bool flag_m
, bool flag_t
)
398 struct pcep_object_inter_layer
*obj
=
399 (struct pcep_object_inter_layer
*)pcep_obj_create_common(
400 sizeof(struct pcep_object_inter_layer
),
401 PCEP_OBJ_CLASS_INTER_LAYER
, PCEP_OBJ_TYPE_INTER_LAYER
);
403 obj
->flag_i
= flag_i
;
404 obj
->flag_m
= flag_m
;
405 obj
->flag_t
= flag_t
;
410 struct pcep_object_switch_layer
*
411 pcep_obj_create_switch_layer(double_linked_list
*switch_layer_rows
)
413 struct pcep_object_switch_layer
*obj
=
414 (struct pcep_object_switch_layer
*)pcep_obj_create_common(
415 sizeof(struct pcep_object_switch_layer
),
416 PCEP_OBJ_CLASS_SWITCH_LAYER
,
417 PCEP_OBJ_TYPE_SWITCH_LAYER
);
419 obj
->switch_layer_rows
= switch_layer_rows
;
424 struct pcep_object_req_adap_cap
*
425 pcep_obj_create_req_adap_cap(enum pcep_switching_capability sw_cap
,
426 enum pcep_lsp_encoding_type encoding
)
428 struct pcep_object_req_adap_cap
*obj
=
429 (struct pcep_object_req_adap_cap
*)pcep_obj_create_common(
430 sizeof(struct pcep_object_req_adap_cap
),
431 PCEP_OBJ_CLASS_REQ_ADAP_CAP
,
432 PCEP_OBJ_TYPE_REQ_ADAP_CAP
);
434 obj
->switching_capability
= sw_cap
;
435 obj
->encoding
= encoding
;
440 struct pcep_object_server_indication
*
441 pcep_obj_create_server_indication(enum pcep_switching_capability sw_cap
,
442 enum pcep_lsp_encoding_type encoding
,
443 double_linked_list
*tlv_list
)
445 struct pcep_object_server_indication
*obj
=
446 (struct pcep_object_server_indication
*)
447 pcep_obj_create_common_with_tlvs(
448 sizeof(struct pcep_object_server_indication
),
449 PCEP_OBJ_CLASS_SERVER_IND
,
450 PCEP_OBJ_TYPE_SERVER_IND
, tlv_list
);
452 obj
->switching_capability
= sw_cap
;
453 obj
->encoding
= encoding
;
458 struct pcep_object_objective_function
*
459 pcep_obj_create_objective_function(uint16_t of_code
,
460 double_linked_list
*tlv_list
)
462 struct pcep_object_objective_function
*obj
=
463 (struct pcep_object_objective_function
*)
464 pcep_obj_create_common_with_tlvs(
465 sizeof(struct pcep_object_objective_function
),
466 PCEP_OBJ_CLASS_OF
, PCEP_OBJ_TYPE_OF
, tlv_list
);
468 obj
->of_code
= of_code
;
473 /* Wrap a list of ro subobjects in a structure with an object header */
474 struct pcep_object_ro
*pcep_obj_create_ero(double_linked_list
*ero_list
)
476 struct pcep_object_ro
*ero
=
477 (struct pcep_object_ro
*)pcep_obj_create_common(
478 sizeof(struct pcep_object_ro
), PCEP_OBJ_CLASS_ERO
,
480 ero
->sub_objects
= ero_list
;
485 /* Wrap a list of ro subobjects in a structure with an object header */
486 struct pcep_object_ro
*pcep_obj_create_iro(double_linked_list
*iro_list
)
488 struct pcep_object_ro
*iro
=
489 (struct pcep_object_ro
*)pcep_obj_create_common(
490 sizeof(struct pcep_object_ro
), PCEP_OBJ_CLASS_IRO
,
492 iro
->sub_objects
= iro_list
;
497 /* Wrap a list of ro subobjects in a structure with an object header */
498 struct pcep_object_ro
*pcep_obj_create_rro(double_linked_list
*rro_list
)
500 struct pcep_object_ro
*rro
=
501 (struct pcep_object_ro
*)pcep_obj_create_common(
502 sizeof(struct pcep_object_ro
), PCEP_OBJ_CLASS_RRO
,
504 rro
->sub_objects
= rro_list
;
510 * Route Object Sub-object creation functions
513 static struct pcep_object_ro_subobj
*
514 pcep_obj_create_ro_subobj_common(uint8_t subobj_size
,
515 enum pcep_ro_subobj_types ro_subobj_type
,
516 bool flag_subobj_loose_hop
)
518 struct pcep_object_ro_subobj
*ro_subobj
=
519 pceplib_malloc(PCEPLIB_MESSAGES
, subobj_size
);
520 memset(ro_subobj
, 0, subobj_size
);
521 ro_subobj
->flag_subobj_loose_hop
= flag_subobj_loose_hop
;
522 ro_subobj
->ro_subobj_type
= ro_subobj_type
;
527 struct pcep_ro_subobj_ipv4
*
528 pcep_obj_create_ro_subobj_ipv4(bool loose_hop
, const struct in_addr
*rro_ipv4
,
529 uint8_t prefix_length
, bool flag_local_prot
)
531 if (rro_ipv4
== NULL
) {
535 struct pcep_ro_subobj_ipv4
*obj
=
536 (struct pcep_ro_subobj_ipv4
*)pcep_obj_create_ro_subobj_common(
537 sizeof(struct pcep_ro_subobj_ipv4
), RO_SUBOBJ_TYPE_IPV4
,
539 obj
->ip_addr
.s_addr
= rro_ipv4
->s_addr
;
540 obj
->prefix_length
= prefix_length
;
541 obj
->flag_local_protection
= flag_local_prot
;
546 struct pcep_ro_subobj_ipv6
*
547 pcep_obj_create_ro_subobj_ipv6(bool loose_hop
, const struct in6_addr
*rro_ipv6
,
548 uint8_t prefix_length
, bool flag_local_prot
)
550 if (rro_ipv6
== NULL
) {
554 struct pcep_ro_subobj_ipv6
*obj
=
555 (struct pcep_ro_subobj_ipv6
*)pcep_obj_create_ro_subobj_common(
556 sizeof(struct pcep_ro_subobj_ipv6
), RO_SUBOBJ_TYPE_IPV6
,
558 obj
->prefix_length
= prefix_length
;
559 obj
->flag_local_protection
= flag_local_prot
;
560 memcpy(&obj
->ip_addr
, rro_ipv6
, sizeof(struct in6_addr
));
565 struct pcep_ro_subobj_unnum
*
566 pcep_obj_create_ro_subobj_unnum(struct in_addr
*router_id
, uint32_t if_id
)
568 if (router_id
== NULL
) {
572 struct pcep_ro_subobj_unnum
*obj
=
573 (struct pcep_ro_subobj_unnum
*)pcep_obj_create_ro_subobj_common(
574 sizeof(struct pcep_ro_subobj_unnum
),
575 RO_SUBOBJ_TYPE_UNNUM
, false);
576 obj
->interface_id
= if_id
;
577 obj
->router_id
.s_addr
= router_id
->s_addr
;
582 struct pcep_ro_subobj_32label
*
583 pcep_obj_create_ro_subobj_32label(bool flag_global_label
, uint8_t class_type
,
586 struct pcep_ro_subobj_32label
*obj
= (struct pcep_ro_subobj_32label
*)
587 pcep_obj_create_ro_subobj_common(
588 sizeof(struct pcep_ro_subobj_32label
),
589 RO_SUBOBJ_TYPE_LABEL
, false);
590 obj
->class_type
= class_type
;
591 obj
->flag_global_label
= flag_global_label
;
597 struct pcep_ro_subobj_asn
*pcep_obj_create_ro_subobj_asn(uint16_t asn
)
599 struct pcep_ro_subobj_asn
*obj
=
600 (struct pcep_ro_subobj_asn
*)pcep_obj_create_ro_subobj_common(
601 sizeof(struct pcep_ro_subobj_asn
), RO_SUBOBJ_TYPE_ASN
,
608 /* Internal util function to create pcep_ro_subobj_sr sub-objects */
609 static struct pcep_ro_subobj_sr
*
610 pcep_obj_create_ro_subobj_sr_common(enum pcep_sr_subobj_nai nai_type
,
611 bool loose_hop
, bool f_flag
, bool s_flag
,
612 bool c_flag_in
, bool m_flag_in
)
614 struct pcep_ro_subobj_sr
*obj
=
615 (struct pcep_ro_subobj_sr
*)pcep_obj_create_ro_subobj_common(
616 sizeof(struct pcep_ro_subobj_sr
), RO_SUBOBJ_TYPE_SR
,
619 /* Flag logic according to draft-ietf-pce-segment-routing-16 */
620 bool c_flag
= c_flag_in
;
621 bool m_flag
= m_flag_in
;
627 if (m_flag
== false) {
631 obj
->nai_type
= nai_type
;
632 obj
->flag_f
= f_flag
;
633 obj
->flag_s
= s_flag
;
634 obj
->flag_c
= c_flag
;
635 obj
->flag_m
= m_flag
;
640 struct pcep_ro_subobj_sr
*pcep_obj_create_ro_subobj_sr_nonai(bool loose_hop
,
645 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
646 * If NT=0, the F bit MUST be 1, the S bit MUST be zero and the
647 * Length MUST be 8. */
648 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
649 PCEP_SR_SUBOBJ_NAI_ABSENT
, loose_hop
, true, false, c_flag
,
656 struct pcep_ro_subobj_sr
*
657 pcep_obj_create_ro_subobj_sr_ipv4_node(bool loose_hop
, bool sid_absent
,
658 bool c_flag
, bool m_flag
, uint32_t sid
,
659 struct in_addr
*ipv4_node_id
)
661 if (ipv4_node_id
== NULL
) {
665 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
666 * If NT=1, the F bit MUST be zero. If the S bit is 1, the Length
667 * MUST be 8, otherwise the Length MUST be 12 */
668 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
669 PCEP_SR_SUBOBJ_NAI_IPV4_NODE
, loose_hop
, false, sid_absent
,
675 obj
->nai_list
= dll_initialize();
676 /* Since the IP has to be stored in the list, copy it so the caller
677 * doesn't have any restrictions about the type of memory used
678 * externally for the IP. This memory will be freed with the object is
680 struct in_addr
*ipv4_node_id_copy
=
681 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in_addr
));
682 ipv4_node_id_copy
->s_addr
= ipv4_node_id
->s_addr
;
683 dll_append(obj
->nai_list
, ipv4_node_id_copy
);
688 struct pcep_ro_subobj_sr
*
689 pcep_obj_create_ro_subobj_sr_ipv6_node(bool loose_hop
, bool sid_absent
,
690 bool c_flag
, bool m_flag
, uint32_t sid
,
691 struct in6_addr
*ipv6_node_id
)
693 if (ipv6_node_id
== NULL
) {
697 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
698 * If NT=2, the F bit MUST be zero. If the S bit is 1, the Length
699 * MUST be 20, otherwise the Length MUST be 24. */
700 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
701 PCEP_SR_SUBOBJ_NAI_IPV6_NODE
, loose_hop
, false, sid_absent
,
707 obj
->nai_list
= dll_initialize();
708 struct in6_addr
*ipv6_node_id_copy
=
709 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in6_addr
));
710 memcpy(ipv6_node_id_copy
, ipv6_node_id
, sizeof(struct in6_addr
));
711 dll_append(obj
->nai_list
, ipv6_node_id_copy
);
716 struct pcep_ro_subobj_sr
*pcep_obj_create_ro_subobj_sr_ipv4_adj(
717 bool loose_hop
, bool sid_absent
, bool c_flag
, bool m_flag
, uint32_t sid
,
718 struct in_addr
*local_ipv4
, struct in_addr
*remote_ipv4
)
720 if (local_ipv4
== NULL
|| remote_ipv4
== NULL
) {
724 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
725 * If NT=3, the F bit MUST be zero. If the S bit is 1, the Length
726 * MUST be 12, otherwise the Length MUST be 16 */
727 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
728 PCEP_SR_SUBOBJ_NAI_IPV4_ADJACENCY
, loose_hop
, false, sid_absent
,
734 obj
->nai_list
= dll_initialize();
735 struct in_addr
*local_ipv4_copy
=
736 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in_addr
));
737 struct in_addr
*remote_ipv4_copy
=
738 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in_addr
));
739 local_ipv4_copy
->s_addr
= local_ipv4
->s_addr
;
740 remote_ipv4_copy
->s_addr
= remote_ipv4
->s_addr
;
741 dll_append(obj
->nai_list
, local_ipv4_copy
);
742 dll_append(obj
->nai_list
, remote_ipv4_copy
);
747 struct pcep_ro_subobj_sr
*pcep_obj_create_ro_subobj_sr_ipv6_adj(
748 bool loose_hop
, bool sid_absent
, bool c_flag
, bool m_flag
, uint32_t sid
,
749 struct in6_addr
*local_ipv6
, struct in6_addr
*remote_ipv6
)
751 if (local_ipv6
== NULL
|| remote_ipv6
== NULL
) {
755 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
756 * If NT=4, the F bit MUST be zero. If the S bit is 1, the Length
757 * MUST be 36, otherwise the Length MUST be 40 */
758 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
759 PCEP_SR_SUBOBJ_NAI_IPV6_ADJACENCY
, loose_hop
, false, sid_absent
,
765 obj
->nai_list
= dll_initialize();
766 struct in6_addr
*local_ipv6_copy
=
767 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in6_addr
));
768 struct in6_addr
*remote_ipv6_copy
=
769 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in6_addr
));
770 memcpy(local_ipv6_copy
, local_ipv6
, sizeof(struct in6_addr
));
771 memcpy(remote_ipv6_copy
, remote_ipv6
, sizeof(struct in6_addr
));
772 dll_append(obj
->nai_list
, local_ipv6_copy
);
773 dll_append(obj
->nai_list
, remote_ipv6_copy
);
778 struct pcep_ro_subobj_sr
*pcep_obj_create_ro_subobj_sr_unnumbered_ipv4_adj(
779 bool loose_hop
, bool sid_absent
, bool c_flag
, bool m_flag
, uint32_t sid
,
780 uint32_t local_node_id
, uint32_t local_if_id
, uint32_t remote_node_id
,
781 uint32_t remote_if_id
)
783 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
784 * If NT=5, the F bit MUST be zero. If the S bit is 1, the Length
785 * MUST be 20, otherwise the Length MUST be 24. */
786 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
787 PCEP_SR_SUBOBJ_NAI_UNNUMBERED_IPV4_ADJACENCY
, loose_hop
, false,
788 sid_absent
, c_flag
, m_flag
);
794 obj
->nai_list
= dll_initialize();
795 uint32_t *local_node_id_copy
=
796 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint32_t));
797 *local_node_id_copy
= local_node_id
;
798 dll_append(obj
->nai_list
, local_node_id_copy
);
800 uint32_t *local_if_id_copy
=
801 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint32_t));
802 *local_if_id_copy
= local_if_id
;
803 dll_append(obj
->nai_list
, local_if_id_copy
);
805 uint32_t *remote_node_id_copy
=
806 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint32_t));
807 *remote_node_id_copy
= remote_node_id
;
808 dll_append(obj
->nai_list
, remote_node_id_copy
);
810 uint32_t *remote_if_id_copy
=
811 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint32_t));
812 *remote_if_id_copy
= remote_if_id
;
813 dll_append(obj
->nai_list
, remote_if_id_copy
);
818 struct pcep_ro_subobj_sr
*pcep_obj_create_ro_subobj_sr_linklocal_ipv6_adj(
819 bool loose_hop
, bool sid_absent
, bool c_flag
, bool m_flag
, uint32_t sid
,
820 struct in6_addr
*local_ipv6
, uint32_t local_if_id
,
821 struct in6_addr
*remote_ipv6
, uint32_t remote_if_id
)
823 if (local_ipv6
== NULL
|| remote_ipv6
== NULL
) {
827 /* According to draft-ietf-pce-segment-routing-16#section-5.2.1
828 * If NT=6, the F bit MUST be zero. If the S bit is 1, the Length
829 * MUST be 44, otherwise the Length MUST be 48 */
830 struct pcep_ro_subobj_sr
*obj
= pcep_obj_create_ro_subobj_sr_common(
831 PCEP_SR_SUBOBJ_NAI_LINK_LOCAL_IPV6_ADJACENCY
, loose_hop
, false,
832 sid_absent
, c_flag
, m_flag
);
837 obj
->nai_list
= dll_initialize();
838 struct in6_addr
*local_ipv6_copy
=
839 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in6_addr
));
840 memcpy(local_ipv6_copy
, local_ipv6
, sizeof(struct in6_addr
));
841 dll_append(obj
->nai_list
, local_ipv6_copy
);
843 uint32_t *local_if_id_copy
=
844 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint32_t));
845 *local_if_id_copy
= local_if_id
;
846 dll_append(obj
->nai_list
, local_if_id_copy
);
848 struct in6_addr
*remote_ipv6_copy
=
849 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct in6_addr
));
850 memcpy(remote_ipv6_copy
, remote_ipv6
, sizeof(struct in6_addr
));
851 dll_append(obj
->nai_list
, remote_ipv6_copy
);
853 uint32_t *remote_if_id_copy
=
854 pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(uint32_t));
855 *remote_if_id_copy
= remote_if_id
;
856 dll_append(obj
->nai_list
, remote_if_id_copy
);