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