]> git.proxmox.com Git - mirror_frr.git/blame - pceplib/pcep_msg_objects.c
Merge pull request #8536 from idryzhov/bfd-enabled
[mirror_frr.git] / pceplib / pcep_msg_objects.c
CommitLineData
74971473
JG
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#include <string.h>
29#include <arpa/inet.h>
30#include <stdarg.h>
31#include <unistd.h>
32
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"
38
39/* Internal common function used to create a pcep_object and populate the header
40 */
41static 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)
44{
45 uint8_t *buffer = pceplib_malloc(PCEPLIB_MESSAGES, obj_length);
46 memset(buffer, 0, obj_length);
47
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;
53
54 return hdr;
55}
56
57static struct pcep_object_header *
58pcep_obj_create_common(uint8_t obj_length,
59 enum pcep_object_classes object_class,
60 enum pcep_object_types object_type)
61{
62 return pcep_obj_create_common_with_tlvs(obj_length, object_class,
63 object_type, NULL);
64}
65
66struct pcep_object_open *pcep_obj_create_open(uint8_t keepalive,
67 uint8_t deadtimer, uint8_t sid,
68 double_linked_list *tlv_list)
69{
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);
74
75 open->open_version =
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
84 session. */
85
86 return open;
87}
88
89struct 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)
93{
94 if (priority > OBJECT_RP_MAX_PRIORITY) {
95 pcep_log(
96 LOG_INFO,
97 "%s: Error creating RP object, invalid priority [%d], max priority [%d].",
98 __func__, priority, OBJECT_RP_MAX_PRIORITY);
99 return NULL;
100 }
101
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);
106
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;
113
114 return obj;
115}
116
117struct pcep_object_notify *
118pcep_obj_create_notify(enum pcep_notification_types notification_type,
119 enum pcep_notification_values notification_value)
120{
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,
124 PCEP_OBJ_TYPE_NOTF);
125
126 obj->notification_type = notification_type;
127 obj->notification_value = notification_value;
128
129 return obj;
130}
131
132struct pcep_object_nopath *
133pcep_obj_create_nopath(uint8_t ni, bool flag_c,
134 enum pcep_nopath_tlv_err_codes error_code)
135{
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);
140
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);
145
146 obj->ni = ni;
147 obj->flag_c = flag_c;
148 obj->err_code = error_code;
149
150 return obj;
151}
152
153struct pcep_object_association_ipv4 *
154pcep_obj_create_association_ipv4(bool r_flag, uint16_t association_type,
155 uint16_t association_id, struct in_addr src)
156{
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);
162
163 obj->R_flag = r_flag;
164 obj->association_type = association_type;
165 obj->association_id = association_id;
166 obj->src = src;
167
168 return obj;
169}
170struct pcep_object_association_ipv6 *
171pcep_obj_create_association_ipv6(bool r_flag, uint16_t association_type,
172 uint16_t association_id, struct in6_addr src)
173{
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);
179
180 obj->R_flag = r_flag;
181 obj->association_type = association_type;
182 obj->association_id = association_id;
183 obj->src = src;
184
185 return obj;
186}
187struct pcep_object_endpoints_ipv4 *
188pcep_obj_create_endpoint_ipv4(const struct in_addr *src_ipv4,
189 const struct in_addr *dst_ipv4)
190{
191 if (src_ipv4 == NULL || dst_ipv4 == NULL) {
192 return NULL;
193 }
194
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);
199
200 obj->src_ipv4.s_addr = src_ipv4->s_addr;
201 obj->dst_ipv4.s_addr = dst_ipv4->s_addr;
202
203 return obj;
204}
205
206struct pcep_object_endpoints_ipv6 *
207pcep_obj_create_endpoint_ipv6(const struct in6_addr *src_ipv6,
208 const struct in6_addr *dst_ipv6)
209{
210 if (src_ipv6 == NULL || dst_ipv6 == NULL) {
211 return NULL;
212 }
213
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);
218
219 memcpy(&obj->src_ipv6, src_ipv6, sizeof(struct in6_addr));
220 memcpy(&obj->dst_ipv6, dst_ipv6, sizeof(struct in6_addr));
221
222 return obj;
223}
224
225struct pcep_object_bandwidth *pcep_obj_create_bandwidth(float bandwidth)
226{
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);
231
232 obj->bandwidth = bandwidth;
233
234 return obj;
235}
236
237struct pcep_object_metric *pcep_obj_create_metric(enum pcep_metric_types type,
238 bool flag_b, bool flag_c,
239 float value)
240{
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);
245
246 obj->flag_b = flag_b;
247 obj->flag_c = flag_c;
248 obj->type = type;
249 obj->value = value;
250
251 return obj;
252}
253
254struct pcep_object_lspa *
255pcep_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)
258{
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,
262 PCEP_OBJ_TYPE_LSPA);
263
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;
270
271 return obj;
272}
273
274struct pcep_object_svec *
275pcep_obj_create_svec(bool srlg, bool node, bool link,
276 double_linked_list *request_id_list)
277{
278 if (request_id_list == NULL) {
279 return NULL;
280 }
281
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,
285 PCEP_OBJ_TYPE_SVEC);
286
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;
291
292 return obj;
293}
294
295struct pcep_object_error *
296pcep_obj_create_error(enum pcep_error_type error_type,
297 enum pcep_error_value error_value)
298{
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);
303
304 obj->error_type = error_type;
305 obj->error_value = error_value;
306
307 return obj;
308}
309
310struct pcep_object_close *pcep_obj_create_close(enum pcep_close_reason reason)
311{
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);
316
317 obj->reason = reason;
318
319 return obj;
320}
321
322struct pcep_object_srp *pcep_obj_create_srp(bool lsp_remove,
323 uint32_t srp_id_number,
324 double_linked_list *tlv_list)
325{
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);
330
331 obj->flag_lsp_remove = lsp_remove;
332 obj->srp_id_number = srp_id_number;
333
334 return obj;
335}
336
337struct pcep_object_lsp *
338pcep_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)
341{
342 /* The plsp_id is only 20 bits */
343 if (plsp_id > MAX_PLSP_ID) {
344 pcep_log(
345 LOG_INFO,
346 "%s: pcep_obj_create_lsp invalid plsp_id [%d] max value [%d]",
347 __func__, plsp_id, MAX_PLSP_ID);
348 return NULL;
349 }
350
351 /* The status is only 3 bits */
352 if (status > MAX_LSP_STATUS) {
353 pcep_log(
354 LOG_INFO,
355 "%s: pcep_obj_create_lsp invalid status [%d] max value [%d]",
356 __func__, plsp_id, MAX_PLSP_ID);
357 return NULL;
358 }
359
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);
364
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;
372
373 return obj;
374}
375
376struct pcep_object_vendor_info *
377pcep_obj_create_vendor_info(uint32_t enterprise_number,
378 uint32_t enterprise_spec_info)
379{
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);
384
385 obj->enterprise_number = enterprise_number;
386 obj->enterprise_specific_info = enterprise_spec_info;
387
388 return obj;
389}
390
391struct pcep_object_inter_layer *
392pcep_obj_create_inter_layer(bool flag_i, bool flag_m, bool flag_t)
393{
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);
398
399 obj->flag_i = flag_i;
400 obj->flag_m = flag_m;
401 obj->flag_t = flag_t;
402
403 return obj;
404}
405
406struct pcep_object_switch_layer *
407pcep_obj_create_switch_layer(double_linked_list *switch_layer_rows)
408{
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);
414
415 obj->switch_layer_rows = switch_layer_rows;
416
417 return obj;
418}
419
420struct pcep_object_req_adap_cap *
421pcep_obj_create_req_adap_cap(enum pcep_switching_capability sw_cap,
422 enum pcep_lsp_encoding_type encoding)
423{
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);
429
430 obj->switching_capability = sw_cap;
431 obj->encoding = encoding;
432
433 return obj;
434}
435
436struct pcep_object_server_indication *
437pcep_obj_create_server_indication(enum pcep_switching_capability sw_cap,
438 enum pcep_lsp_encoding_type encoding,
439 double_linked_list *tlv_list)
440{
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);
447
448 obj->switching_capability = sw_cap;
449 obj->encoding = encoding;
450
451 return obj;
452}
453
454struct pcep_object_objective_function *
455pcep_obj_create_objective_function(uint16_t of_code,
456 double_linked_list *tlv_list)
457{
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);
463
464 obj->of_code = of_code;
465
466 return obj;
467}
468
469/* Wrap a list of ro subobjects in a structure with an object header */
470struct pcep_object_ro *pcep_obj_create_ero(double_linked_list *ero_list)
471{
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,
475 PCEP_OBJ_TYPE_ERO);
476 ero->sub_objects = ero_list;
477
478 return ero;
479}
480
481/* Wrap a list of ro subobjects in a structure with an object header */
482struct pcep_object_ro *pcep_obj_create_iro(double_linked_list *iro_list)
483{
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,
487 PCEP_OBJ_TYPE_IRO);
488 iro->sub_objects = iro_list;
489
490 return iro;
491}
492
493/* Wrap a list of ro subobjects in a structure with an object header */
494struct pcep_object_ro *pcep_obj_create_rro(double_linked_list *rro_list)
495{
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,
499 PCEP_OBJ_TYPE_RRO);
500 rro->sub_objects = rro_list;
501
502 return rro;
503}
504
505/*
506 * Route Object Sub-object creation functions
507 */
508
509static struct pcep_object_ro_subobj *
510pcep_obj_create_ro_subobj_common(uint8_t subobj_size,
511 enum pcep_ro_subobj_types ro_subobj_type,
512 bool flag_subobj_loose_hop)
513{
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;
519
520 return ro_subobj;
521}
522
523struct pcep_ro_subobj_ipv4 *
524pcep_obj_create_ro_subobj_ipv4(bool loose_hop, const struct in_addr *rro_ipv4,
525 uint8_t prefix_length, bool flag_local_prot)
526{
527 if (rro_ipv4 == NULL) {
528 return NULL;
529 }
530
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,
534 loose_hop);
535 obj->ip_addr.s_addr = rro_ipv4->s_addr;
536 obj->prefix_length = prefix_length;
537 obj->flag_local_protection = flag_local_prot;
538
539 return obj;
540}
541
542struct pcep_ro_subobj_ipv6 *
543pcep_obj_create_ro_subobj_ipv6(bool loose_hop, const struct in6_addr *rro_ipv6,
544 uint8_t prefix_length, bool flag_local_prot)
545{
546 if (rro_ipv6 == NULL) {
547 return NULL;
548 }
549
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,
553 loose_hop);
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));
557
558 return obj;
559}
560
561struct pcep_ro_subobj_unnum *
562pcep_obj_create_ro_subobj_unnum(struct in_addr *router_id, uint32_t if_id)
563{
564 if (router_id == NULL) {
565 return NULL;
566 }
567
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;
574
575 return obj;
576}
577
578struct pcep_ro_subobj_32label *
579pcep_obj_create_ro_subobj_32label(bool flag_global_label, uint8_t class_type,
580 uint32_t label)
581{
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;
588 obj->label = label;
589
590 return obj;
591}
592
593struct pcep_ro_subobj_asn *pcep_obj_create_ro_subobj_asn(uint16_t asn)
594{
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,
598 false);
599 obj->asn = asn;
600
601 return obj;
602}
603
604/* Internal util function to create pcep_ro_subobj_sr sub-objects */
605static struct pcep_ro_subobj_sr *
606pcep_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)
609{
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,
613 loose_hop);
614
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;
618 if (s_flag) {
619 c_flag = false;
620 m_flag = false;
621 }
622
623 if (m_flag == false) {
624 c_flag = false;
625 }
626
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;
632
633 return obj;
634}
635
636struct pcep_ro_subobj_sr *pcep_obj_create_ro_subobj_sr_nonai(bool loose_hop,
637 uint32_t sid,
638 bool c_flag,
639 bool m_flag)
640{
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,
646 m_flag);
647 obj->sid = sid;
648
649 return obj;
650}
651
652struct pcep_ro_subobj_sr *
653pcep_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)
656{
657 if (ipv4_node_id == NULL) {
658 return NULL;
659 }
660
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,
666 c_flag, m_flag);
667
668 if (!sid_absent) {
669 obj->sid = sid;
670 }
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);
679
680 return obj;
681}
682
683struct pcep_ro_subobj_sr *
684pcep_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)
687{
688 if (ipv6_node_id == NULL) {
689 return NULL;
690 }
691
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,
697 c_flag, m_flag);
698
699 if (!sid_absent) {
700 obj->sid = sid;
701 }
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);
707
708 return obj;
709}
710
711struct 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)
714{
715 if (local_ipv4 == NULL || remote_ipv4 == NULL) {
716 return NULL;
717 }
718
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,
724 c_flag, m_flag);
725
726 if (!sid_absent) {
727 obj->sid = sid;
728 }
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);
738
739 return obj;
740}
741
742struct 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)
745{
746 if (local_ipv6 == NULL || remote_ipv6 == NULL) {
747 return NULL;
748 }
749
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,
755 c_flag, m_flag);
756
757 if (!sid_absent) {
758 obj->sid = sid;
759 }
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);
769
770 return obj;
771}
772
773struct 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)
777{
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);
784
785 if (!sid_absent) {
786 obj->sid = sid;
787 }
788
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);
794
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);
799
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);
804
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);
809
810 return obj;
811}
812
813struct 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)
817{
818 if (local_ipv6 == NULL || remote_ipv6 == NULL) {
819 return NULL;
820 }
821
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);
828
829 if (!sid_absent) {
830 obj->sid = sid;
831 }
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);
837
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);
842
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);
847
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);
852
853 return obj;
854}