]> git.proxmox.com Git - mirror_frr.git/blob - pceplib/pcep_msg_objects.h
Merge pull request #8258 from volta-networks/feat_ldp_snmp_with_stats
[mirror_frr.git] / pceplib / pcep_msg_objects.h
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 * This is a High Level PCEP message object API.
25 */
26
27 #ifndef PCEP_OBJECTS_H
28 #define PCEP_OBJECTS_H
29
30 #include <stdbool.h>
31 #include <stdint.h>
32
33 #include "pcep.h"
34 #include "pcep_utils_double_linked_list.h"
35 #include "pcep_msg_object_error_types.h"
36 #include "pcep_msg_tlvs.h"
37
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41
42 /*
43 * Regarding memory usage:
44 * When creating objects, any objects passed into these APIs will be free'd when
45 * the enclosing pcep_message is free'd. That includes the double_linked_list's.
46 * So, just create the objects and TLVs, put them in their double_linked_list's,
47 * and everything will be managed internally. The enclosing message will be
48 * deleted by pcep_msg_free_message() or pcep_msg_free_message_list() which,
49 * in turn will call one of: pcep_obj_free_object() and pcep_obj_free_tlv().
50 * For received messages with objects, call pcep_msg_free_message() to free
51 * them.
52 */
53
54 enum pcep_object_classes {
55 PCEP_OBJ_CLASS_OPEN = 1,
56 PCEP_OBJ_CLASS_RP = 2,
57 PCEP_OBJ_CLASS_NOPATH = 3,
58 PCEP_OBJ_CLASS_ENDPOINTS = 4,
59 PCEP_OBJ_CLASS_BANDWIDTH = 5,
60 PCEP_OBJ_CLASS_METRIC = 6,
61 PCEP_OBJ_CLASS_ERO = 7,
62 PCEP_OBJ_CLASS_RRO = 8,
63 PCEP_OBJ_CLASS_LSPA = 9,
64 PCEP_OBJ_CLASS_IRO = 10,
65 PCEP_OBJ_CLASS_SVEC = 11,
66 PCEP_OBJ_CLASS_NOTF = 12,
67 PCEP_OBJ_CLASS_ERROR = 13,
68 PCEP_OBJ_CLASS_CLOSE = 15,
69 PCEP_OBJ_CLASS_OF = 21,
70 PCEP_OBJ_CLASS_LSP = 32,
71 PCEP_OBJ_CLASS_SRP = 33,
72 PCEP_OBJ_CLASS_VENDOR_INFO = 34,
73 PCEP_OBJ_CLASS_INTER_LAYER = 36, /* RFC 8282 */
74 PCEP_OBJ_CLASS_SWITCH_LAYER = 37, /* RFC 8282 */
75 PCEP_OBJ_CLASS_REQ_ADAP_CAP = 38, /* RFC 8282 */
76 PCEP_OBJ_CLASS_SERVER_IND = 39, /* RFC 8282 */
77 PCEP_OBJ_CLASS_ASSOCIATION = 40, /*draft-ietf-pce-association-group-10*/
78 PCEP_OBJ_CLASS_MAX,
79 };
80
81 enum pcep_object_types {
82 PCEP_OBJ_TYPE_OPEN = 1,
83 PCEP_OBJ_TYPE_RP = 1,
84 PCEP_OBJ_TYPE_NOPATH = 1,
85 PCEP_OBJ_TYPE_ENDPOINT_IPV4 = 1,
86 PCEP_OBJ_TYPE_ENDPOINT_IPV6 = 2,
87 PCEP_OBJ_TYPE_BANDWIDTH_REQ = 1,
88 PCEP_OBJ_TYPE_BANDWIDTH_TELSP = 2,
89 PCEP_OBJ_TYPE_BANDWIDTH_CISCO =
90 5, /* IANA unassigned, but rcvd from Cisco PCE */
91 PCEP_OBJ_TYPE_SRP = 1,
92 PCEP_OBJ_TYPE_VENDOR_INFO = 1,
93 PCEP_OBJ_TYPE_LSP = 1,
94 PCEP_OBJ_TYPE_METRIC = 1,
95 PCEP_OBJ_TYPE_ERO = 1,
96 PCEP_OBJ_TYPE_RRO = 1,
97 PCEP_OBJ_TYPE_LSPA = 1,
98 PCEP_OBJ_TYPE_IRO = 1,
99 PCEP_OBJ_TYPE_SVEC = 1,
100 PCEP_OBJ_TYPE_NOTF = 1,
101 PCEP_OBJ_TYPE_ERROR = 1,
102 PCEP_OBJ_TYPE_CLOSE = 1,
103 PCEP_OBJ_TYPE_INTER_LAYER = 1,
104 PCEP_OBJ_TYPE_SWITCH_LAYER = 1,
105 PCEP_OBJ_TYPE_REQ_ADAP_CAP = 1,
106 PCEP_OBJ_TYPE_SERVER_IND = 1,
107 PCEP_OBJ_TYPE_ASSOCIATION_IPV4 =
108 1, /*draft-ietf-pce-association-group-10*/
109 PCEP_OBJ_TYPE_ASSOCIATION_IPV6 =
110 2, /*draft-ietf-pce-association-group-10*/
111 PCEP_OBJ_TYPE_OF = 1,
112 PCEP_OBJ_TYPE_MAX = 2,
113 };
114
115 #define OBJECT_HEADER_FLAG_I 0x01
116 #define OBJECT_HEADER_FLAG_P 0x02
117
118 /* The flag_p and flag_i arent set via the APIs, if they need to be set, just
119 * set them on the returned object once it has been created. */
120 struct pcep_object_header {
121 enum pcep_object_classes object_class;
122 enum pcep_object_types object_type;
123 bool flag_p; /* PCC Processing rule bit: When set, the object MUST be
124 taken into account, when cleared the object is optional.
125 */
126 bool flag_i; /* PCE Ignore bit: indicates to a PCC whether or not an
127 optional object was processed */
128 double_linked_list *tlv_list;
129 /* Pointer into encoded_message field from the pcep_message */
130 const uint8_t *encoded_object;
131 uint16_t encoded_object_length;
132 };
133
134 #define PCEP_OBJECT_OPEN_VERSION 1
135
136 struct pcep_object_open {
137 struct pcep_object_header header;
138 uint8_t open_version; /* PCEP version. Current version is 1 */
139 uint8_t open_keepalive; /* Maximum period of time between two
140 consecutive PCEP messages sent by the sender.
141 */
142 uint8_t open_deadtimer; /* Specifies the amount of time before closing
143 the session down. */
144 uint8_t open_sid; /* PCEP session number that identifies the current
145 session. */
146 };
147
148 #define OBJECT_RP_FLAG_R 0x08
149 #define OBJECT_RP_FLAG_B 0x10
150 #define OBJECT_RP_FLAG_O 0x20
151 #define OBJECT_RP_FLAG_OF 0x80
152 #define OBJECT_RP_MAX_PRIORITY 0x07
153
154 struct pcep_object_rp {
155 struct pcep_object_header header;
156 uint8_t priority; /* 3 bit priority, max priority is 7 */
157 bool flag_reoptimization;
158 bool flag_bidirectional;
159 bool flag_strict; /* when set, a loose path is acceptable */
160 bool flag_of; /* Supply Objective Function on Response */
161 uint32_t request_id; /* The Request-id-number value combined with the
162 source for PCC & PCE creates a uniquely number.
163 */
164 };
165
166 enum pcep_notification_types {
167 PCEP_NOTIFY_TYPE_PENDING_REQUEST_CANCELLED = 1,
168 PCEP_NOTIFY_TYPE_PCE_OVERLOADED = 2
169 };
170
171 enum pcep_notification_values {
172 PCEP_NOTIFY_VALUE_PCC_CANCELLED_REQUEST = 1,
173 PCEP_NOTIFY_VALUE_PCE_CANCELLED_REQUEST = 2,
174 PCEP_NOTIFY_VALUE_PCE_CURRENTLY_OVERLOADED = 1,
175 PCEP_NOTIFY_VALUE_PCE_NO_LONGER_OVERLOADED = 2
176 };
177
178 struct pcep_object_notify {
179 struct pcep_object_header header;
180 enum pcep_notification_types notification_type;
181 enum pcep_notification_values notification_value;
182 };
183
184 enum pcep_association_type {
185 PCEP_ASSOCIATION_TYPE_PATH_PROTECTION_ASSOCIATION =
186 1, // iana unique value define as 2020-01-08!
187 PCEP_ASSOCIATION_TYPE_SR_POLICY_ASSOCIATION_TYPE =
188 65535 // TBD1 draft-barth-pce-segment-routing-policy-cp-04
189 };
190 #define OBJECT_ASSOCIATION_FLAG_R 0x01
191 struct pcep_object_association_ipv4 { // draft-ietf-pce-association-group-10
192 struct pcep_object_header header;
193 bool R_flag;
194 uint16_t association_type;
195 uint16_t association_id;
196 struct in_addr src;
197 };
198
199 struct pcep_object_association_ipv6 { // draft-ietf-pce-association-group-10
200 struct pcep_object_header header;
201 bool R_flag;
202 uint16_t association_type;
203 uint16_t association_id;
204 struct in6_addr src;
205 };
206
207
208 enum pcep_nopath_nature_of_issue {
209 PCEP_NOPATH_NI_NO_PATH_FOUND = 0,
210 PCEP_NOPATH_NI_PCE_CHAIN_BROKEN = 1,
211 };
212
213 enum pcep_nopath_tlv_err_codes {
214 PCEP_NOPATH_TLV_ERR_NO_TLV = 0,
215 PCEP_NOPATH_TLV_ERR_PCE_UNAVAILABLE = 1,
216 PCEP_NOPATH_TLV_ERR_UNKNOWN_DST = 2,
217 PCEP_NOPATH_TLV_ERR_UNKNOWN_SRC = 3
218 };
219
220 #define OBJECT_NOPATH_FLAG_C 0x80
221
222 struct pcep_object_nopath {
223 struct pcep_object_header header;
224 uint8_t ni; /* Nature of Issue, reports the nature of the issue that led
225 to a negative reply */
226 bool flag_c; /* when set, indicates the unsatisfied constraints by
227 including relevant PCEP objects. */
228 enum pcep_nopath_tlv_err_codes
229 err_code; /* When set other than 0, an appropriate TLV will be
230 included */
231 };
232
233 struct pcep_object_endpoints_ipv4 {
234 struct pcep_object_header header;
235 struct in_addr src_ipv4;
236 struct in_addr dst_ipv4;
237 };
238
239 struct pcep_object_endpoints_ipv6 {
240 struct pcep_object_header header;
241 struct in6_addr src_ipv6;
242 struct in6_addr dst_ipv6;
243 };
244
245 /* PCEP floats are encoded according to:
246 * https://en.wikipedia.org/wiki/IEEE_754-1985
247 * Luckily, this is the same encoding used by C */
248 struct pcep_object_bandwidth {
249 struct pcep_object_header header;
250 float bandwidth;
251 };
252
253 enum pcep_metric_types {
254 /* RFC 5440 */
255 PCEP_METRIC_IGP = 1,
256 PCEP_METRIC_TE = 2,
257 PCEP_METRIC_HOP_COUNT = 3,
258 /* RFC 5541 */
259 PCEP_METRIC_AGGREGATE_BW = 4,
260 PCEP_METRIC_MOST_LOADED_LINK = 5,
261 PCEP_METRIC_CUMULATIVE_IGP = 6,
262 PCEP_METRIC_CUMULATIVE_TE = 7,
263 /* RFC 8306 */
264 PCEP_METRIC_P2MP_IGP = 8,
265 PCEP_METRIC_P2MP_TE = 9,
266 PCEP_METRIC_P2MP_HOP_COUNT = 10,
267 /* RFC 8864 */
268 PCEP_METRIC_SEGMENT_ID_DEPTH = 11,
269 /* RFC 8233 */
270 PCEP_METRIC_PATH_DELAY = 12,
271 PCEP_METRIC_PATH_DELAY_VARIATION = 13,
272 PCEP_METRIC_PATH_LOSS = 14,
273 PCEP_METRIC_P2MP_PATH_DELAY = 15,
274 PCEP_METRIC_P2MP_PATH_DELAY_VARIATION = 16,
275 PCEP_METRIC_P2MP_PATH_LOSS = 17,
276 /* RFC 8282 */
277 PCEP_METRIC_NUM_PATH_ADAPTATIONS = 18,
278 PCEP_METRIC_NUM_PATH_LAYERS = 19,
279 /* RFC 8685 */
280 PCEP_METRIC_DOMAIN_COUNT = 20,
281 PCEP_METRIC_BORDER_NODE_COUNT = 21,
282 };
283
284 #define OBJECT_METRIC_FLAC_B 0x01
285 #define OBJECT_METRIC_FLAC_C 0x02
286
287 /* PCEP floats are encoded according to:
288 * https://en.wikipedia.org/wiki/IEEE_754-1985
289 * Luckily, this is the same encoding used by C */
290 struct pcep_object_metric {
291 struct pcep_object_header header;
292 enum pcep_metric_types type;
293 bool flag_b; /* Bound flag */
294 bool flag_c; /* Computed metric */
295 float value; /* Metric value in 32 bits */
296 };
297
298 #define OBJECT_LSPA_FLAG_L 0x01
299
300 struct pcep_object_lspa {
301 struct pcep_object_header header;
302 uint32_t lspa_exclude_any;
303 uint32_t lspa_include_any;
304 uint32_t lspa_include_all;
305 uint8_t setup_priority;
306 uint8_t holding_priority;
307 bool flag_local_protection; /* Local protection desired bit */
308 };
309
310 /* The SVEC object with some custom extensions. */
311 #define OBJECT_SVEC_FLAG_L 0x01
312 #define OBJECT_SVEC_FLAG_N 0x02
313 #define OBJECT_SVEC_FLAG_S 0x04
314
315 struct pcep_object_svec {
316 struct pcep_object_header header;
317 bool flag_link_diverse;
318 bool flag_node_diverse;
319 bool flag_srlg_diverse;
320 double_linked_list
321 *request_id_list; /* list of 32-bit request ID pointers */
322 };
323
324 struct pcep_object_error {
325 struct pcep_object_header header;
326 enum pcep_error_type error_type;
327 enum pcep_error_value error_value;
328 };
329
330 struct pcep_object_load_balancing {
331 struct pcep_object_header header;
332 uint8_t load_maxlsp; /* Maximum number of TE LSPs in the set */
333 uint32_t load_minband; /* Specifies the minimum bandwidth of each
334 element */
335 };
336
337 enum pcep_close_reason {
338 PCEP_CLOSE_REASON_NO = 1,
339 PCEP_CLOSE_REASON_DEADTIMER = 2,
340 PCEP_CLOSE_REASON_FORMAT = 3,
341 PCEP_CLOSE_REASON_UNKNOWN_REQ = 4,
342 PCEP_CLOSE_REASON_UNREC_MSG = 5
343 };
344
345 struct pcep_object_close {
346 struct pcep_object_header header;
347 enum pcep_close_reason reason;
348 };
349
350 /* Stateful PCE Request Parameters RFC 8231, 8281 */
351
352 #define OBJECT_SRP_FLAG_R 0x01
353
354 struct pcep_object_srp {
355 struct pcep_object_header header;
356 bool flag_lsp_remove; /* RFC 8281 */
357 uint32_t srp_id_number;
358 };
359
360 /* Label Switched Path Object RFC 8231 */
361 enum pcep_lsp_operational_status {
362 PCEP_LSP_OPERATIONAL_DOWN = 0,
363 PCEP_LSP_OPERATIONAL_UP = 1,
364 PCEP_LSP_OPERATIONAL_ACTIVE = 2,
365 PCEP_LSP_OPERATIONAL_GOING_DOWN = 3,
366 PCEP_LSP_OPERATIONAL_GOING_UP = 4,
367 };
368
369 #define MAX_PLSP_ID 0x000fffff /* The plsp_id is only 20 bits */
370 #define MAX_LSP_STATUS 0x0007 /* The status is only 3 bits */
371 #define OBJECT_LSP_FLAG_D 0x01
372 #define OBJECT_LSP_FLAG_S 0x02
373 #define OBJECT_LSP_FLAG_R 0x04
374 #define OBJECT_LSP_FLAG_A 0x08
375 #define OBJECT_LSP_FLAG_C 0x80
376
377 struct pcep_object_lsp {
378 struct pcep_object_header header;
379 uint32_t plsp_id; /* plsp_id is 20 bits, must be <= MAX_PLSP_ID*/
380 enum pcep_lsp_operational_status operational_status; /* max 3 bits */
381 bool flag_d;
382 bool flag_s;
383 bool flag_r;
384 bool flag_a;
385 bool flag_c;
386 };
387
388 /* RFC 7470 */
389 struct pcep_object_vendor_info {
390 struct pcep_object_header header;
391 uint32_t enterprise_number;
392 uint32_t enterprise_specific_info;
393 };
394
395 /* RFC 8282 */
396 #define OBJECT_INTER_LAYER_FLAG_I 0x01
397 #define OBJECT_INTER_LAYER_FLAG_M 0x02
398 #define OBJECT_INTER_LAYER_FLAG_T 0x04
399
400 struct pcep_object_inter_layer {
401 struct pcep_object_header header;
402 bool flag_i;
403 bool flag_m;
404 bool flag_t;
405 };
406
407 /* RFC 8282 */
408 #define OBJECT_SWITCH_LAYER_FLAG_I 0x01
409 enum pcep_lsp_encoding_type {
410 /* Values taken from RFC 3471 as suggested by RFC 8282 */
411 PCEP_LSP_ENC_PACKET = 1,
412 PCEP_LSP_ENC_ETHERNET = 2,
413 PCEP_LSP_ENC_PDH = 3,
414 PCEP_LSP_ENC_RESERVED4 = 4,
415 PCEP_LSP_ENC_SDH_SONET = 5,
416 PCEP_LSP_ENC_RESERVED6 = 6,
417 PCEP_LSP_ENC_DIG_WRAPPER = 7,
418 PCEP_LSP_ENC_LAMBDA = 8,
419 PCEP_LSP_ENC_FIBER = 9,
420 PCEP_LSP_ENC_RESERVED10 = 10,
421 PCEP_LSP_ENC_FIBER_CHAN = 11
422 };
423
424 enum pcep_switching_capability {
425 /* Switching capability values taken from RFC 4203/3471 as suggested by
426 RFC 8282 */
427 PCEP_SW_CAP_PSC1 = 1, /* Packet-Switch Capable-1 (PSC-1) */
428 PCEP_SW_CAP_PSC2 = 2,
429 PCEP_SW_CAP_PSC3 = 3,
430 PCEP_SW_CAP_PSC4 = 4,
431 PCEP_SW_CAP_L2SC = 51, /* Layer-2 Switch Capable */
432 PCEP_SW_CAP_TDM = 100, /* Time-Division-Multiplex Capable */
433 PCEP_SW_CAP_LSC = 150, /* Lambda-Switch Capable */
434 PCEP_SW_CAP_FSC = 200 /* Fiber-Switch Capable */
435 };
436
437 struct pcep_object_switch_layer_row {
438 enum pcep_lsp_encoding_type lsp_encoding_type;
439 enum pcep_switching_capability switching_type;
440 bool flag_i;
441 };
442
443 struct pcep_object_switch_layer {
444 struct pcep_object_header header;
445 double_linked_list
446 *switch_layer_rows; /* list of struct
447 pcep_object_switch_layer_row */
448 };
449
450 /* RFC 8282
451 * Requested Adaptation capability */
452
453 struct pcep_object_req_adap_cap {
454 struct pcep_object_header header;
455 enum pcep_switching_capability switching_capability;
456 enum pcep_lsp_encoding_type encoding;
457 };
458
459 /* RFC 8282 */
460
461 struct pcep_object_server_indication {
462 struct pcep_object_header header;
463 enum pcep_switching_capability switching_capability;
464 enum pcep_lsp_encoding_type encoding;
465 /* This object is identical to req_adap_cap, except it allows TLVs */
466 };
467
468 /* Objective Function Object: RFC 5541 */
469
470 struct pcep_object_objective_function {
471 struct pcep_object_header header;
472 uint16_t of_code;
473 };
474
475 /*
476 * Common Route Object sub-object definitions
477 * used by ERO, IRO, and RRO
478 */
479
480 /* Common Route Object sub-object types
481 * used by ERO, IRO, and RRO */
482 enum pcep_ro_subobj_types {
483 RO_SUBOBJ_TYPE_IPV4 = 1, /* RFC 3209 */
484 RO_SUBOBJ_TYPE_IPV6 = 2, /* RFC 3209 */
485 RO_SUBOBJ_TYPE_LABEL = 3, /* RFC 3209 */
486 RO_SUBOBJ_TYPE_UNNUM = 4, /* RFC 3477 */
487 RO_SUBOBJ_TYPE_ASN = 32, /* RFC 3209, Section 4.3.3.4 */
488 RO_SUBOBJ_TYPE_SR = 36, /* RFC 8408, draft-ietf-pce-segment-routing-16.
489 Type 5 for draft07 has been assigned to
490 something else. */
491 RO_SUBOBJ_UNKNOWN
492 };
493
494 struct pcep_object_ro {
495 struct pcep_object_header header;
496 double_linked_list
497 *sub_objects; /* list of struct pcep_object_ro_subobj */
498 };
499
500 struct pcep_object_ro_subobj {
501 bool flag_subobj_loose_hop; /* L subobj flag */
502 enum pcep_ro_subobj_types ro_subobj_type;
503 };
504
505 #define OBJECT_SUBOBJ_IP_FLAG_LOCAL_PROT 0x01
506
507 struct pcep_ro_subobj_ipv4 {
508 struct pcep_object_ro_subobj ro_subobj;
509 struct in_addr ip_addr;
510 uint8_t prefix_length;
511 bool flag_local_protection;
512 };
513
514 struct pcep_ro_subobj_ipv6 {
515 struct pcep_object_ro_subobj ro_subobj;
516 struct in6_addr ip_addr;
517 uint8_t prefix_length;
518 bool flag_local_protection;
519 };
520
521 struct pcep_ro_subobj_unnum {
522 struct pcep_object_ro_subobj ro_subobj;
523 struct in_addr router_id;
524 uint32_t interface_id;
525 };
526
527 #define OBJECT_SUBOBJ_LABEL_FLAG_GLOGAL 0x01
528 struct pcep_ro_subobj_32label {
529 struct pcep_object_ro_subobj ro_subobj;
530 bool flag_global_label;
531 uint8_t class_type; /* label class-type (generalized label = 2) */
532 uint32_t label; /* label supported */
533 };
534
535 struct pcep_ro_subobj_asn {
536 struct pcep_object_ro_subobj ro_subobj;
537 uint16_t asn; /* Autonomous system number */
538 };
539
540 /* The SR ERO and SR RRO subojbects are the same, except
541 * the SR-RRO does not have the L flag in the Type field.
542 * Defined in draft-ietf-pce-segment-routing-16 */
543 enum pcep_sr_subobj_nai {
544 PCEP_SR_SUBOBJ_NAI_ABSENT = 0,
545 PCEP_SR_SUBOBJ_NAI_IPV4_NODE = 1,
546 PCEP_SR_SUBOBJ_NAI_IPV6_NODE = 2,
547 PCEP_SR_SUBOBJ_NAI_IPV4_ADJACENCY = 3,
548 PCEP_SR_SUBOBJ_NAI_IPV6_ADJACENCY = 4,
549 PCEP_SR_SUBOBJ_NAI_UNNUMBERED_IPV4_ADJACENCY = 5,
550 PCEP_SR_SUBOBJ_NAI_LINK_LOCAL_IPV6_ADJACENCY = 6,
551 PCEP_SR_SUBOBJ_NAI_UNKNOWN
552 };
553
554 #define OBJECT_SUBOBJ_SR_FLAG_M 0x01
555 #define OBJECT_SUBOBJ_SR_FLAG_C 0x02
556 #define OBJECT_SUBOBJ_SR_FLAG_S 0x04
557 #define OBJECT_SUBOBJ_SR_FLAG_F 0x08
558
559 struct pcep_ro_subobj_sr {
560 struct pcep_object_ro_subobj ro_subobj;
561 enum pcep_sr_subobj_nai nai_type;
562 bool flag_f;
563 bool flag_s;
564 bool flag_c;
565 bool flag_m;
566
567 /* The SID and NAI are optional depending on the flags,
568 * and the NAI can be variable length */
569 uint32_t sid;
570 double_linked_list
571 *nai_list; /* double linked list of in_addr or in6_addr */
572 };
573
574 /* Macros to make a SID Label
575 *
576 * 0 1 2 3
577 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
578 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Label
579 | Label | TC |S| TTL | Stack
580 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Entry
581 */
582 #define ENCODE_SR_ERO_SID(label_20bits, tc_3bits, stack_bottom_bit, ttl_8bits) \
583 ((((label_20bits) << 12) & 0xfffff000) \
584 | (((tc_3bits) << 9) & 0x00000e00) \
585 | (((stack_bottom_bit) << 8) & 0x00000100) | ((ttl_8bits)&0xff))
586 #define GET_SR_ERO_SID_LABEL(SID) ((SID & 0xfffff000) >> 12)
587 #define GET_SR_ERO_SID_TC(SID) ((SID & 0x00000e00) >> 9)
588 #define GET_SR_ERO_SID_S(SID) ((SID & 0x00000100) >> 8)
589 #define GET_SR_ERO_SID_TTL(SID) ((SID & 0x000000ff))
590
591 /*
592 * All created objects will be in Host byte order, except for IPs.
593 * All IP addresses are expected to be passed-in in Network byte order,
594 * and any objects received will have their IPs in Network byte order.
595 * The message containing the objects should be converted to Network byte order
596 * with pcep_encode_msg_header() before sending, which will also convert the
597 * Objects, TLVs, and sub-objects.
598 */
599
600 struct pcep_object_open *pcep_obj_create_open(uint8_t keepalive,
601 uint8_t deadtimer, uint8_t sid,
602 double_linked_list *tlv_list);
603 struct pcep_object_rp *pcep_obj_create_rp(uint8_t priority, bool flag_r,
604 bool flag_b, bool flag_s,
605 bool flag_of, uint32_t reqid,
606 double_linked_list *tlv_list);
607 struct pcep_object_notify *
608 pcep_obj_create_notify(enum pcep_notification_types notification_type,
609 enum pcep_notification_values notification_value);
610 struct pcep_object_nopath *
611 pcep_obj_create_nopath(uint8_t ni, bool flag_c,
612 enum pcep_nopath_tlv_err_codes error_code);
613 struct pcep_object_association_ipv4 *
614 pcep_obj_create_association_ipv4(bool r_flag, uint16_t association_type,
615 uint16_t association_id, struct in_addr src);
616 struct pcep_object_association_ipv6 *
617 pcep_obj_create_association_ipv6(bool r_flag, uint16_t association_type,
618 uint16_t association_id, struct in6_addr src);
619 struct pcep_object_endpoints_ipv4 *
620 pcep_obj_create_endpoint_ipv4(const struct in_addr *src_ipv4,
621 const struct in_addr *dst_ipv4);
622 struct pcep_object_endpoints_ipv6 *
623 pcep_obj_create_endpoint_ipv6(const struct in6_addr *src_ipv6,
624 const struct in6_addr *dst_ipv6);
625 struct pcep_object_bandwidth *pcep_obj_create_bandwidth(float bandwidth);
626 struct pcep_object_metric *pcep_obj_create_metric(enum pcep_metric_types type,
627 bool flag_b, bool flag_c,
628 float value);
629 struct pcep_object_lspa *
630 pcep_obj_create_lspa(uint32_t exclude_any, uint32_t include_any,
631 uint32_t include_all, uint8_t setup_priority,
632 uint8_t holding_priority, bool flag_local_protection);
633 struct pcep_object_svec *
634 pcep_obj_create_svec(bool srlg, bool node, bool link,
635 double_linked_list *request_id_list);
636 struct pcep_object_error *
637 pcep_obj_create_error(enum pcep_error_type error_type,
638 enum pcep_error_value error_value);
639 struct pcep_object_close *pcep_obj_create_close(enum pcep_close_reason reason);
640 struct pcep_object_srp *pcep_obj_create_srp(bool lsp_remove,
641 uint32_t srp_id_number,
642 double_linked_list *tlv_list);
643 struct pcep_object_lsp *
644 pcep_obj_create_lsp(uint32_t plsp_id, enum pcep_lsp_operational_status status,
645 bool c_flag, bool a_flag, bool r_flag, bool s_flag,
646 bool d_flag, double_linked_list *tlv_list);
647 struct pcep_object_vendor_info *
648 pcep_obj_create_vendor_info(uint32_t enterprise_number,
649 uint32_t enterprise_spec_info);
650 struct pcep_object_inter_layer *
651 pcep_obj_create_inter_layer(bool flag_i, bool flag_m, bool flag_t);
652 struct pcep_object_switch_layer *
653 pcep_obj_create_switch_layer(double_linked_list *switch_layer_rows);
654 struct pcep_object_req_adap_cap *
655 pcep_obj_create_req_adap_cap(enum pcep_switching_capability sw_cap,
656 enum pcep_lsp_encoding_type encoding);
657 struct pcep_object_server_indication *
658 pcep_obj_create_server_indication(enum pcep_switching_capability sw_cap,
659 enum pcep_lsp_encoding_type encoding,
660 double_linked_list *tlv_list);
661 struct pcep_object_objective_function *
662 pcep_obj_create_objective_function(uint16_t of_code,
663 double_linked_list *tlv_list);
664
665 /* Route Object (Explicit ero, Reported rro, and Include iro) functions
666 * First, the sub-objects should be created and appended to a
667 * double_linked_list, then call one of these Route Object creation functions
668 * with the subobj list */
669 struct pcep_object_ro *pcep_obj_create_ero(double_linked_list *ero_list);
670 struct pcep_object_ro *pcep_obj_create_rro(double_linked_list *rro_list);
671 struct pcep_object_ro *pcep_obj_create_iro(double_linked_list *iro_list);
672 /* Route Object sub-object creation functions */
673 struct pcep_ro_subobj_ipv4 *
674 pcep_obj_create_ro_subobj_ipv4(bool loose_hop, const struct in_addr *ro_ipv4,
675 uint8_t prefix_len, bool flag_local_prot);
676 struct pcep_ro_subobj_ipv6 *
677 pcep_obj_create_ro_subobj_ipv6(bool loose_hop, const struct in6_addr *ro_ipv6,
678 uint8_t prefix_len, bool flag_local_prot);
679 struct pcep_ro_subobj_unnum *
680 pcep_obj_create_ro_subobj_unnum(struct in_addr *router_id, uint32_t if_id);
681 struct pcep_ro_subobj_32label *
682 pcep_obj_create_ro_subobj_32label(bool flag_global_label, uint8_t class_type,
683 uint32_t label);
684 struct pcep_ro_subobj_asn *pcep_obj_create_ro_subobj_asn(uint16_t asn);
685
686 /* SR ERO and SR RRO creation functions for different NAI (Node/Adj ID) types.
687 * - The loose_hop is only used for sr ero and must always be false for sr rro.
688 * - The NAI value will be set internally, depending on which function is used.
689 * m_flag:
690 * - If this flag is true, the SID value represents an MPLS label stack
691 * entry as specified in [RFC3032]. Otherwise, the SID value is an
692 * administratively configured value which represents an index into
693 * an MPLS label space (either SRGB or SRLB) per [RFC8402].
694 * c_flag:
695 * - If the M flag and the C flag are both true, then the TC, S, and TTL
696 * fields in the MPLS label stack entry are specified by the PCE. However,
697 * a PCC MAY choose to override these values according to its local policy
698 * and MPLS forwarding rules.
699 * - If the M flag is true but the C flag is false, then the TC, S, and TTL
700 * fields MUST be ignored by the PCC.
701 * - The PCC MUST set these fields according to its local policy and MPLS
702 * forwarding rules.
703 * - If the M flag is false then the C bit MUST be false. */
704 struct pcep_ro_subobj_sr *pcep_obj_create_ro_subobj_sr_nonai(bool loose_hop,
705 uint32_t sid,
706 bool c_flag,
707 bool m_flag);
708
709 /* The ipv4_node_id will be copied internally */
710 struct pcep_ro_subobj_sr *
711 pcep_obj_create_ro_subobj_sr_ipv4_node(bool loose_hop, bool sid_absent,
712 bool c_flag, bool m_flag, uint32_t sid,
713 struct in_addr *ipv4_node_id);
714 /* The ipv6_node_id will be copied internally */
715 struct pcep_ro_subobj_sr *
716 pcep_obj_create_ro_subobj_sr_ipv6_node(bool loose_hop, bool sid_absent,
717 bool c_flag, bool m_flag, uint32_t sid,
718 struct in6_addr *ipv6_node_id);
719 /* The local_ipv4 and remote_ipv4 will be copied internally */
720 struct pcep_ro_subobj_sr *pcep_obj_create_ro_subobj_sr_ipv4_adj(
721 bool loose_hop, bool sid_absent, bool c_flag, bool m_flag, uint32_t sid,
722 struct in_addr *local_ipv4, struct in_addr *remote_ipv4);
723 /* The local_ipv6 and remote_ipv6 will be copied internally */
724 struct pcep_ro_subobj_sr *pcep_obj_create_ro_subobj_sr_ipv6_adj(
725 bool loose_hop, bool sid_absent, bool c_flag, bool m_flag, uint32_t sid,
726 struct in6_addr *local_ipv6, struct in6_addr *remote_ipv6);
727 struct pcep_ro_subobj_sr *pcep_obj_create_ro_subobj_sr_unnumbered_ipv4_adj(
728 bool loose_hop, bool sid_absent, bool c_flag, bool m_flag, uint32_t sid,
729 uint32_t local_node_id, uint32_t local_if_id, uint32_t remote_node_id,
730 uint32_t remote_if_id);
731 /* The local_ipv6 and remote_ipv6 will be copied internally */
732 struct pcep_ro_subobj_sr *pcep_obj_create_ro_subobj_sr_linklocal_ipv6_adj(
733 bool loose_hop, bool sid_absent, bool c_flag, bool m_flag, uint32_t sid,
734 struct in6_addr *local_ipv6, uint32_t local_if_id,
735 struct in6_addr *remote_ipv6, uint32_t remote_if_id);
736
737 #ifdef __cplusplus
738 }
739 #endif
740
741 #endif