]> git.proxmox.com Git - mirror_frr.git/blob - pceplib/pcep_msg_objects.c
doc: Add `show ipv6 rpf X:X::X:X` command to docs
[mirror_frr.git] / pceplib / pcep_msg_objects.c
1 /*
2 * This file is part of the PCEPlib, a PCEP protocol library.
3 *
4 * Copyright (C) 2020 Volta Networks https://voltanet.io/
5 *
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.
10 *
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.
15 *
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/>.
18 *
19 * Author : Brady Johnson <brady@voltanet.io>
20 *
21 */
22
23
24 /*
25 * This is the implementation of a High Level PCEP message object API.
26 */
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include <string.h>
33 #include <arpa/inet.h>
34 #include <stdarg.h>
35 #include <unistd.h>
36
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"
42
43 /* Internal common function used to create a pcep_object and populate the header
44 */
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)
48 {
49 uint8_t *buffer = pceplib_malloc(PCEPLIB_MESSAGES, obj_length);
50 memset(buffer, 0, obj_length);
51
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;
57
58 return hdr;
59 }
60
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)
65 {
66 return pcep_obj_create_common_with_tlvs(obj_length, object_class,
67 object_type, NULL);
68 }
69
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)
73 {
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);
78
79 open->open_version =
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
88 session. */
89
90 return open;
91 }
92
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)
97 {
98 if (priority > OBJECT_RP_MAX_PRIORITY) {
99 pcep_log(
100 LOG_INFO,
101 "%s: Error creating RP object, invalid priority [%d], max priority [%d].",
102 __func__, priority, OBJECT_RP_MAX_PRIORITY);
103 return NULL;
104 }
105
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);
110
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;
117
118 return obj;
119 }
120
121 struct pcep_object_notify *
122 pcep_obj_create_notify(enum pcep_notification_types notification_type,
123 enum pcep_notification_values notification_value)
124 {
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,
128 PCEP_OBJ_TYPE_NOTF);
129
130 obj->notification_type = notification_type;
131 obj->notification_value = notification_value;
132
133 return obj;
134 }
135
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)
139 {
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);
144
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);
149
150 obj->ni = ni;
151 obj->flag_c = flag_c;
152 obj->err_code = error_code;
153
154 return obj;
155 }
156
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)
160 {
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);
166
167 obj->R_flag = r_flag;
168 obj->association_type = association_type;
169 obj->association_id = association_id;
170 obj->src = src;
171
172 return obj;
173 }
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)
177 {
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);
183
184 obj->R_flag = r_flag;
185 obj->association_type = association_type;
186 obj->association_id = association_id;
187 obj->src = src;
188
189 return obj;
190 }
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)
194 {
195 if (src_ipv4 == NULL || dst_ipv4 == NULL) {
196 return NULL;
197 }
198
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);
203
204 obj->src_ipv4.s_addr = src_ipv4->s_addr;
205 obj->dst_ipv4.s_addr = dst_ipv4->s_addr;
206
207 return obj;
208 }
209
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)
213 {
214 if (src_ipv6 == NULL || dst_ipv6 == NULL) {
215 return NULL;
216 }
217
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);
222
223 memcpy(&obj->src_ipv6, src_ipv6, sizeof(struct in6_addr));
224 memcpy(&obj->dst_ipv6, dst_ipv6, sizeof(struct in6_addr));
225
226 return obj;
227 }
228
229 struct pcep_object_bandwidth *pcep_obj_create_bandwidth(float bandwidth)
230 {
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);
235
236 obj->bandwidth = bandwidth;
237
238 return obj;
239 }
240
241 struct pcep_object_metric *pcep_obj_create_metric(enum pcep_metric_types type,
242 bool flag_b, bool flag_c,
243 float value)
244 {
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);
249
250 obj->flag_b = flag_b;
251 obj->flag_c = flag_c;
252 obj->type = type;
253 obj->value = value;
254
255 return obj;
256 }
257
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)
262 {
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,
266 PCEP_OBJ_TYPE_LSPA);
267
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;
274
275 return obj;
276 }
277
278 struct pcep_object_svec *
279 pcep_obj_create_svec(bool srlg, bool node, bool link,
280 double_linked_list *request_id_list)
281 {
282 if (request_id_list == NULL) {
283 return NULL;
284 }
285
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,
289 PCEP_OBJ_TYPE_SVEC);
290
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;
295
296 return obj;
297 }
298
299 struct pcep_object_error *
300 pcep_obj_create_error(enum pcep_error_type error_type,
301 enum pcep_error_value error_value)
302 {
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);
307
308 obj->error_type = error_type;
309 obj->error_value = error_value;
310
311 return obj;
312 }
313
314 struct pcep_object_close *pcep_obj_create_close(enum pcep_close_reason reason)
315 {
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);
320
321 obj->reason = reason;
322
323 return obj;
324 }
325
326 struct pcep_object_srp *pcep_obj_create_srp(bool lsp_remove,
327 uint32_t srp_id_number,
328 double_linked_list *tlv_list)
329 {
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);
334
335 obj->flag_lsp_remove = lsp_remove;
336 obj->srp_id_number = srp_id_number;
337
338 return obj;
339 }
340
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)
345 {
346 /* The plsp_id is only 20 bits */
347 if (plsp_id > MAX_PLSP_ID) {
348 pcep_log(
349 LOG_INFO,
350 "%s: pcep_obj_create_lsp invalid plsp_id [%d] max value [%d]",
351 __func__, plsp_id, MAX_PLSP_ID);
352 return NULL;
353 }
354
355 /* The status is only 3 bits */
356 if (status > MAX_LSP_STATUS) {
357 pcep_log(
358 LOG_INFO,
359 "%s: pcep_obj_create_lsp invalid status [%d] max value [%d]",
360 __func__, plsp_id, MAX_PLSP_ID);
361 return NULL;
362 }
363
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);
368
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;
376
377 return obj;
378 }
379
380 struct pcep_object_vendor_info *
381 pcep_obj_create_vendor_info(uint32_t enterprise_number,
382 uint32_t enterprise_spec_info)
383 {
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);
388
389 obj->enterprise_number = enterprise_number;
390 obj->enterprise_specific_info = enterprise_spec_info;
391
392 return obj;
393 }
394
395 struct pcep_object_inter_layer *
396 pcep_obj_create_inter_layer(bool flag_i, bool flag_m, bool flag_t)
397 {
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);
402
403 obj->flag_i = flag_i;
404 obj->flag_m = flag_m;
405 obj->flag_t = flag_t;
406
407 return obj;
408 }
409
410 struct pcep_object_switch_layer *
411 pcep_obj_create_switch_layer(double_linked_list *switch_layer_rows)
412 {
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);
418
419 obj->switch_layer_rows = switch_layer_rows;
420
421 return obj;
422 }
423
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)
427 {
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);
433
434 obj->switching_capability = sw_cap;
435 obj->encoding = encoding;
436
437 return obj;
438 }
439
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)
444 {
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);
451
452 obj->switching_capability = sw_cap;
453 obj->encoding = encoding;
454
455 return obj;
456 }
457
458 struct pcep_object_objective_function *
459 pcep_obj_create_objective_function(uint16_t of_code,
460 double_linked_list *tlv_list)
461 {
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);
467
468 obj->of_code = of_code;
469
470 return obj;
471 }
472
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)
475 {
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,
479 PCEP_OBJ_TYPE_ERO);
480 ero->sub_objects = ero_list;
481
482 return ero;
483 }
484
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)
487 {
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,
491 PCEP_OBJ_TYPE_IRO);
492 iro->sub_objects = iro_list;
493
494 return iro;
495 }
496
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)
499 {
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,
503 PCEP_OBJ_TYPE_RRO);
504 rro->sub_objects = rro_list;
505
506 return rro;
507 }
508
509 /*
510 * Route Object Sub-object creation functions
511 */
512
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)
517 {
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;
523
524 return ro_subobj;
525 }
526
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)
530 {
531 if (rro_ipv4 == NULL) {
532 return NULL;
533 }
534
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,
538 loose_hop);
539 obj->ip_addr.s_addr = rro_ipv4->s_addr;
540 obj->prefix_length = prefix_length;
541 obj->flag_local_protection = flag_local_prot;
542
543 return obj;
544 }
545
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)
549 {
550 if (rro_ipv6 == NULL) {
551 return NULL;
552 }
553
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,
557 loose_hop);
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));
561
562 return obj;
563 }
564
565 struct pcep_ro_subobj_unnum *
566 pcep_obj_create_ro_subobj_unnum(struct in_addr *router_id, uint32_t if_id)
567 {
568 if (router_id == NULL) {
569 return NULL;
570 }
571
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;
578
579 return obj;
580 }
581
582 struct pcep_ro_subobj_32label *
583 pcep_obj_create_ro_subobj_32label(bool flag_global_label, uint8_t class_type,
584 uint32_t label)
585 {
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;
592 obj->label = label;
593
594 return obj;
595 }
596
597 struct pcep_ro_subobj_asn *pcep_obj_create_ro_subobj_asn(uint16_t asn)
598 {
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,
602 false);
603 obj->asn = asn;
604
605 return obj;
606 }
607
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)
613 {
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,
617 loose_hop);
618
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;
622 if (s_flag) {
623 c_flag = false;
624 m_flag = false;
625 }
626
627 if (m_flag == false) {
628 c_flag = false;
629 }
630
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;
636
637 return obj;
638 }
639
640 struct pcep_ro_subobj_sr *pcep_obj_create_ro_subobj_sr_nonai(bool loose_hop,
641 uint32_t sid,
642 bool c_flag,
643 bool m_flag)
644 {
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,
650 m_flag);
651 obj->sid = sid;
652
653 return obj;
654 }
655
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)
660 {
661 if (ipv4_node_id == NULL) {
662 return NULL;
663 }
664
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,
670 c_flag, m_flag);
671
672 if (!sid_absent) {
673 obj->sid = sid;
674 }
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
679 * freed. */
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);
684
685 return obj;
686 }
687
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)
692 {
693 if (ipv6_node_id == NULL) {
694 return NULL;
695 }
696
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,
702 c_flag, m_flag);
703
704 if (!sid_absent) {
705 obj->sid = sid;
706 }
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);
712
713 return obj;
714 }
715
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)
719 {
720 if (local_ipv4 == NULL || remote_ipv4 == NULL) {
721 return NULL;
722 }
723
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,
729 c_flag, m_flag);
730
731 if (!sid_absent) {
732 obj->sid = sid;
733 }
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);
743
744 return obj;
745 }
746
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)
750 {
751 if (local_ipv6 == NULL || remote_ipv6 == NULL) {
752 return NULL;
753 }
754
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,
760 c_flag, m_flag);
761
762 if (!sid_absent) {
763 obj->sid = sid;
764 }
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);
774
775 return obj;
776 }
777
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)
782 {
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);
789
790 if (!sid_absent) {
791 obj->sid = sid;
792 }
793
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);
799
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);
804
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);
809
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);
814
815 return obj;
816 }
817
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)
822 {
823 if (local_ipv6 == NULL || remote_ipv6 == NULL) {
824 return NULL;
825 }
826
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);
833
834 if (!sid_absent) {
835 obj->sid = sid;
836 }
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);
842
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);
847
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);
852
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);
857
858 return obj;
859 }