]>
Commit | Line | Data |
---|---|---|
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 | * This is a High Level PCEP message object TLV API. | |
25 | */ | |
26 | ||
27 | #ifndef PCEP_TLVS_H_ | |
28 | #define PCEP_TLVS_H_ | |
29 | ||
30 | #include <arpa/inet.h> | |
31 | #include <stdint.h> | |
32 | ||
33 | #include "pcep.h" | |
34 | #include "pcep_utils_double_linked_list.h" | |
35 | ||
36 | #ifdef __cplusplus | |
37 | extern "C" { | |
38 | #endif | |
39 | ||
40 | /* | |
41 | * Regarding memory usage: | |
42 | * When creating TLVs, any TLVs passed into messages or objects with these APIs | |
43 | * will be free'd when the the enclosing pcep_message is free'd. That includes | |
44 | * the double_linked_list's. So, just create the objects and TLVs, put them in | |
45 | * their double_linked_list's, and everything will be managed internally. The | |
46 | * enclosing message will be deleted by pcep_msg_free_message() or | |
47 | * pcep_msg_free_message_list() which, * in turn will call one of: | |
48 | * pcep_obj_free_object() and pcep_obj_free_tlv(). | |
49 | * For received messages, call pcep_msg_free_message() to free them. | |
50 | */ | |
51 | ||
52 | /* These numbers can be found here: | |
53 | * https://www.iana.org/assignments/pcep/pcep.xhtml */ | |
54 | enum pcep_object_tlv_types { | |
55 | PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR = 1, | |
56 | PCEP_OBJ_TLV_TYPE_OBJECTIVE_FUNCTION_LIST = 4, /* RFC 5541 */ | |
57 | PCEP_OBJ_TLV_TYPE_VENDOR_INFO = 7, /* RFC 7470 */ | |
58 | PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY = 16, /* RFC 8231 */ | |
59 | PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME = 17, /* RFC 8232 */ | |
60 | PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS = 18, /* RFC 8231 */ | |
61 | PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS = 19, /* RFC 8231 */ | |
62 | PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE = 20, /* RFC 8232 */ | |
63 | PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC = 21, /* RFC 8232 */ | |
64 | PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION = 23, /* RFC 8232 */ | |
65 | PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID = 24, /* RFC 8232 */ | |
66 | PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY = | |
67 | 26, /* draft-ietf-pce-segment-routing-16 */ | |
68 | PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE = 28, /* RFC 8408 */ | |
69 | PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY = | |
70 | 34, /* RFC 8408, draft-ietf-pce-segment-routing-16 */ | |
71 | PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID = | |
72 | 60, /*TDB2 draft-barth-pce-segment-routing-policy-cp-04 */ | |
73 | PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME = | |
74 | 61, /*TDB3 draft-barth-pce-segment-routing-policy-cp-04 */ | |
75 | PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID = | |
76 | 62, /*TDB4 draft-barth-pce-segment-routing-policy-cp-04 */ | |
77 | PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE = | |
78 | 63, /*TDB5 draft-barth-pce-segment-routing-policy-cp-04 */ | |
79 | PCEP_OBJ_TLV_TYPE_UNKNOWN = 128, | |
80 | PCEP_OBJ_TLV_TYPE_ARBITRARY = | |
81 | 65533 /* Max IANA To write arbitrary data */ | |
82 | }; | |
83 | ||
84 | struct pcep_object_tlv_header { | |
85 | enum pcep_object_tlv_types type; | |
86 | /* Pointer into encoded_message field from the pcep_message */ | |
87 | const uint8_t *encoded_tlv; | |
88 | uint16_t encoded_tlv_length; | |
89 | }; | |
90 | ||
91 | /* STATEFUL-PCE-CAPABILITY TLV, Used in Open Object. RFCs: 8231, 8232, 8281 */ | |
92 | #define TLV_STATEFUL_PCE_CAP_FLAG_U 0x01 | |
93 | #define TLV_STATEFUL_PCE_CAP_FLAG_S 0x02 | |
94 | #define TLV_STATEFUL_PCE_CAP_FLAG_I 0x04 | |
95 | #define TLV_STATEFUL_PCE_CAP_FLAG_T 0x08 | |
96 | #define TLV_STATEFUL_PCE_CAP_FLAG_D 0x10 | |
97 | #define TLV_STATEFUL_PCE_CAP_FLAG_F 0x20 | |
98 | ||
99 | struct pcep_object_tlv_stateful_pce_capability { | |
100 | struct pcep_object_tlv_header header; | |
101 | bool flag_u_lsp_update_capability; /* RFC 8231 */ | |
102 | bool flag_s_include_db_version; /* RFC 8232 */ | |
103 | bool flag_i_lsp_instantiation_capability; /* RFC 8281 */ | |
104 | bool flag_t_triggered_resync; /* RFC 8232 */ | |
105 | bool flag_d_delta_lsp_sync; /* RFC 8232 */ | |
106 | bool flag_f_triggered_initial_sync; /* RFC 8232 */ | |
107 | }; | |
108 | ||
109 | /* NOPATH-VECTOR TLV, Used in the Reply NoPath Object. */ | |
110 | struct pcep_object_tlv_nopath_vector { | |
111 | struct pcep_object_tlv_header header; | |
112 | uint32_t error_code; | |
113 | }; | |
114 | ||
115 | /* STATEFUL-PCE-CAPABILITY TLV, Used in Open Object. RFCs: 8232 */ | |
116 | struct pcep_object_tlv_lsp_db_version { | |
117 | struct pcep_object_tlv_header header; | |
118 | uint64_t lsp_db_version; | |
119 | }; | |
120 | ||
121 | /* Speaker Entity Identifier TLV, Used in Open Object. RFCs: 8232 */ | |
122 | struct pcep_object_tlv_speaker_entity_identifier { | |
123 | struct pcep_object_tlv_header header; | |
124 | double_linked_list *speaker_entity_id_list; /* list of uint32_t speaker | |
125 | entity ids */ | |
126 | }; | |
127 | ||
128 | /* Ipv4 LSP Identifier TLV, Used in LSP Object. RFCs: 8231 */ | |
129 | struct pcep_object_tlv_ipv4_lsp_identifier { | |
130 | struct pcep_object_tlv_header header; | |
131 | struct in_addr ipv4_tunnel_sender; | |
132 | uint16_t lsp_id; | |
133 | uint16_t tunnel_id; | |
134 | struct in_addr extended_tunnel_id; | |
135 | struct in_addr ipv4_tunnel_endpoint; | |
136 | }; | |
137 | ||
138 | /* Ipv6 LSP Identifier TLV, Used in LSP Object. RFCs: 8231 */ | |
139 | struct pcep_object_tlv_ipv6_lsp_identifier { | |
140 | struct pcep_object_tlv_header header; | |
141 | struct in6_addr ipv6_tunnel_sender; | |
142 | uint16_t lsp_id; | |
143 | uint16_t tunnel_id; | |
144 | struct in6_addr extended_tunnel_id; | |
145 | struct in6_addr ipv6_tunnel_endpoint; | |
146 | }; | |
147 | ||
148 | /* Symbolic Path Name TLV, Used in LSP Object. RFCs: 8231 */ | |
149 | #define MAX_SYMBOLIC_PATH_NAME 256 | |
150 | ||
151 | struct pcep_object_tlv_symbolic_path_name { | |
152 | struct pcep_object_tlv_header header; | |
153 | uint16_t symbolic_path_name_length; | |
154 | char symbolic_path_name[MAX_SYMBOLIC_PATH_NAME]; | |
155 | }; | |
156 | ||
157 | /* LSP Error Code TLV, Used in LSP Object. RFCs: 8231 */ | |
158 | enum pcep_tlv_lsp_error_codes { | |
159 | PCEP_TLV_LSP_ERROR_CODE_UNKNOWN = 1, | |
160 | PCEP_TLV_LSP_ERROR_CODE_LSP_LIMIT_REACHED = 2, | |
161 | PCEP_TLV_LSP_ERROR_CODE_TOO_MANY_PENDING_LSP_UPDATES = 3, | |
162 | PCEP_TLV_LSP_ERROR_CODE_UNACCEPTABLE_PARAMS = 4, | |
163 | PCEP_TLV_LSP_ERROR_CODE_INTERNAL_ERROR = 5, | |
164 | PCEP_TLV_LSP_ERROR_CODE_LSP_BROUGHT_DOWN = 6, | |
165 | PCEP_TLV_LSP_ERROR_CODE_LSP_PREEMPTED = 7, | |
166 | PCEP_TLV_LSP_ERROR_CODE_RSVP_SIGNALING_ERROR = 8, | |
167 | }; | |
168 | ||
169 | struct pcep_object_tlv_lsp_error_code { | |
170 | struct pcep_object_tlv_header header; | |
171 | enum pcep_tlv_lsp_error_codes lsp_error_code; | |
172 | }; | |
173 | ||
174 | /* Path Setup Type TLV, Used in RP and SRP Object. RFCs: 8408, | |
175 | * draft-ietf-pce-segment-routing-16 */ | |
176 | #define SR_TE_PST 1 | |
177 | ||
178 | struct pcep_object_tlv_path_setup_type { | |
179 | struct pcep_object_tlv_header header; | |
180 | uint8_t path_setup_type; | |
181 | }; | |
182 | ||
183 | /* Path Setup Type Capability TLV, Used in Open Object. RFCs: 8408, | |
184 | * draft-ietf-pce-segment-routing-16 */ | |
185 | struct pcep_object_tlv_path_setup_type_capability { | |
186 | struct pcep_object_tlv_header header; | |
187 | double_linked_list *pst_list; /* list of uint8_t PSTs */ | |
188 | double_linked_list *sub_tlv_list; /* list of sub_tlvs */ | |
189 | }; | |
190 | ||
191 | /* SR PCE Capability sub-TLV, Used in Open Object. RFCs: | |
192 | * draft-ietf-pce-segment-routing-16 */ | |
193 | #define TLV_SR_PCE_CAP_FLAG_X 0x01 | |
194 | #define TLV_SR_PCE_CAP_FLAG_N 0x02 | |
195 | ||
196 | struct pcep_object_tlv_sr_pce_capability { | |
197 | struct pcep_object_tlv_header header; | |
198 | bool flag_n; | |
199 | bool flag_x; | |
200 | uint8_t max_sid_depth; | |
201 | }; | |
202 | ||
203 | ||
204 | /* RSVP Error Spec TLV, Used in LSP Object. RFCs: 8231, 2205 */ | |
205 | #define RSVP_ERROR_SPEC_IPV4_CTYPE 1 | |
206 | #define RSVP_ERROR_SPEC_IPV6_CTYPE 2 | |
207 | #define RSVP_ERROR_SPEC_CLASS_NUM 6 | |
208 | ||
209 | struct pcep_object_tlv_rsvp_error_spec { | |
210 | struct pcep_object_tlv_header header; | |
211 | uint8_t class_num; | |
212 | uint8_t c_type; | |
213 | uint8_t error_code; | |
214 | uint16_t error_value; | |
215 | /* Use the c_type to determine which union entry to use */ | |
216 | union error_spec_ip { | |
217 | struct in_addr ipv4_error_node_address; | |
218 | struct in6_addr ipv6_error_node_address; | |
219 | } error_spec_ip; | |
220 | }; | |
221 | ||
222 | /* SR Policy Identifier TLV Used in Association Object. | |
223 | * draft-barth-pce-segment-routing-policy-cp-04*/ | |
224 | struct pcep_object_tlv_srpag_pol_id { | |
225 | struct pcep_object_tlv_header header; | |
226 | uint32_t color; | |
227 | bool is_ipv4; | |
228 | union end_point_ { | |
229 | struct in_addr ipv4; | |
230 | struct in6_addr ipv6; | |
231 | } end_point; | |
232 | }; | |
233 | ||
234 | /*draft-ietf-spring-segment-routing-policy-06*/ | |
235 | #define MAX_POLICY_NAME 256 | |
236 | ||
237 | /* SR Policy Name TLV Used in Association Object. | |
238 | * draft-barth-pce-segment-routing-policy-cp-04*/ | |
239 | struct pcep_object_tlv_srpag_pol_name { | |
240 | struct pcep_object_tlv_header header; | |
241 | uint16_t name_length; | |
242 | char name[MAX_POLICY_NAME]; | |
243 | }; | |
244 | ||
245 | /* SR Candidate Path Id TLV Used in Association Object. | |
246 | * draft-barth-pce-segment-routing-policy-cp-04*/ | |
247 | struct pcep_object_tlv_srpag_cp_id { | |
248 | struct pcep_object_tlv_header header; | |
249 | uint8_t proto; | |
250 | uint32_t orig_asn; | |
251 | struct in6_addr orig_addres; /*With ipv4 embedded*/ | |
252 | uint32_t discriminator; | |
253 | }; | |
254 | ||
255 | /* SR Candidate Preference TLV Used in Association Object. | |
256 | * draft-barth-pce-segment-routing-policy-cp-04*/ | |
257 | struct pcep_object_tlv_srpag_cp_pref { | |
258 | struct pcep_object_tlv_header header; | |
259 | uint32_t preference; | |
260 | }; | |
261 | ||
262 | struct pcep_object_tlv_vendor_info { | |
263 | struct pcep_object_tlv_header header; | |
264 | uint32_t enterprise_number; | |
265 | uint32_t enterprise_specific_info; | |
266 | }; | |
267 | ||
268 | /* arbitrary TLV 65535 */ | |
269 | #define MAX_ARBITRARY_SIZE 256 | |
270 | struct pcep_object_tlv_arbitrary { | |
271 | struct pcep_object_tlv_header header; | |
272 | enum pcep_object_tlv_types arbitraty_type; | |
273 | uint16_t data_length; | |
274 | char data[MAX_ARBITRARY_SIZE]; | |
275 | }; | |
276 | ||
277 | /* Objective Functions List RFC 5541 | |
278 | * At least the following 6 OF codes must be supported */ | |
279 | enum objective_function_codes { | |
280 | PCEP_OF_CODE_MINIMUM_COST_PATH = 1, /* MCP */ | |
281 | PCEP_OF_CODE_MINIMUM_LOAD_PATH = 2, /* MLP */ | |
282 | PCEP_OF_CODE_MAXIMUM_BW_PATH = 3, /* MBP */ | |
283 | PCEP_OF_CODE_MINIMIZE_AGGR_BW_CONSUMPTION = 4, /* MBC */ | |
284 | PCEP_OF_CODE_MINIMIZE_MOST_LOADED_LINK = 5, /* MLL */ | |
285 | PCEP_OF_CODE_MINIMIZE_CUMULATIVE_COST_PATHS = 6, /* MCC */ | |
286 | }; | |
287 | ||
288 | struct pcep_object_tlv_of_list { | |
289 | struct pcep_object_tlv_header header; | |
290 | double_linked_list *of_list; /* list of uint16_t OF code points */ | |
291 | }; | |
292 | ||
293 | /* | |
294 | * TLV creation functions | |
295 | */ | |
296 | ||
297 | /* | |
298 | * Open Object TLVs | |
299 | */ | |
300 | ||
301 | struct pcep_object_tlv_stateful_pce_capability * | |
302 | pcep_tlv_create_stateful_pce_capability( | |
303 | bool flag_u_lsp_update_capability, bool flag_s_include_db_version, | |
304 | bool flag_i_lsp_instantiation_capability, bool flag_t_triggered_resync, | |
305 | bool flag_d_delta_lsp_sync, bool flag_f_triggered_initial_sync); | |
306 | struct pcep_object_tlv_lsp_db_version * | |
307 | pcep_tlv_create_lsp_db_version(uint64_t lsp_db_version); | |
308 | struct pcep_object_tlv_speaker_entity_identifier * | |
309 | pcep_tlv_create_speaker_entity_id(double_linked_list *speaker_entity_id_list); | |
310 | struct pcep_object_tlv_path_setup_type * | |
311 | pcep_tlv_create_path_setup_type(uint8_t pst); | |
312 | struct pcep_object_tlv_path_setup_type_capability * | |
313 | pcep_tlv_create_path_setup_type_capability(double_linked_list *pst_list, | |
314 | double_linked_list *sub_tlv_list); | |
315 | struct pcep_object_tlv_sr_pce_capability * | |
316 | pcep_tlv_create_sr_pce_capability(bool flag_n, bool flag_x, | |
317 | uint8_t max_sid_depth); | |
318 | struct pcep_object_tlv_of_list * | |
319 | pcep_tlv_create_of_list(double_linked_list *of_list); | |
320 | ||
321 | /* | |
322 | * LSP Object TLVs | |
323 | */ | |
324 | ||
325 | struct pcep_object_tlv_ipv4_lsp_identifier * | |
326 | pcep_tlv_create_ipv4_lsp_identifiers(struct in_addr *ipv4_tunnel_sender, | |
327 | struct in_addr *ipv4_tunnel_endpoint, | |
328 | uint16_t lsp_id, uint16_t tunnel_id, | |
329 | struct in_addr *extended_tunnel_id); | |
330 | struct pcep_object_tlv_ipv6_lsp_identifier * | |
331 | pcep_tlv_create_ipv6_lsp_identifiers(struct in6_addr *ipv6_tunnel_sender, | |
332 | struct in6_addr *extended_tunnel_id, | |
333 | uint16_t lsp_id, uint16_t tunnel_id, | |
334 | struct in6_addr *ipv6_tunnel_endpoint); | |
335 | /* symbolic_path_name_length should NOT include the null terminator and cannot | |
336 | * be zero */ | |
337 | struct pcep_object_tlv_symbolic_path_name * | |
338 | pcep_tlv_create_symbolic_path_name(const char *symbolic_path_name, | |
339 | uint16_t symbolic_path_name_length); | |
340 | struct pcep_object_tlv_lsp_error_code * | |
341 | pcep_tlv_create_lsp_error_code(enum pcep_tlv_lsp_error_codes lsp_error_code); | |
342 | struct pcep_object_tlv_rsvp_error_spec * | |
343 | pcep_tlv_create_rsvp_ipv4_error_spec(struct in_addr *error_node_ip, | |
344 | uint8_t error_code, uint16_t error_value); | |
345 | struct pcep_object_tlv_rsvp_error_spec * | |
346 | pcep_tlv_create_rsvp_ipv6_error_spec(struct in6_addr *error_node_ip, | |
347 | uint8_t error_code, uint16_t error_value); | |
348 | ||
349 | struct pcep_object_tlv_nopath_vector * | |
350 | pcep_tlv_create_nopath_vector(uint32_t error_code); | |
351 | struct pcep_object_tlv_vendor_info * | |
352 | pcep_tlv_create_vendor_info(uint32_t enterprise_number, | |
353 | uint32_t enterprise_specific_info); | |
354 | ||
355 | struct pcep_object_tlv_arbitrary * | |
356 | pcep_tlv_create_tlv_arbitrary(const char *data, uint16_t data_length, | |
357 | int tlv_id); | |
358 | /* | |
359 | * SRPAG (SR Association Group) TLVs | |
360 | */ | |
361 | ||
362 | struct pcep_object_tlv_srpag_pol_id * | |
363 | pcep_tlv_create_srpag_pol_id_ipv4(uint32_t color, struct in_addr *ipv4); | |
364 | struct pcep_object_tlv_srpag_pol_id * | |
365 | pcep_tlv_create_srpag_pol_id_ipv6(uint32_t color, struct in6_addr *ipv6); | |
366 | struct pcep_object_tlv_srpag_pol_name * | |
367 | pcep_tlv_create_srpag_pol_name(const char *pol_name, uint16_t pol_name_length); | |
368 | struct pcep_object_tlv_srpag_cp_id * | |
369 | pcep_tlv_create_srpag_cp_id(uint8_t proto_origin, uint32_t asn, | |
370 | struct in6_addr *in6_addr_with_mapped_ipv4, | |
371 | uint32_t discriminator); | |
372 | struct pcep_object_tlv_srpag_cp_pref * | |
373 | pcep_tlv_create_srpag_cp_pref(uint32_t pref); | |
374 | ||
375 | ||
376 | #ifdef __cplusplus | |
377 | } | |
378 | #endif | |
379 | ||
380 | #endif /* PCEP_TLVS_H_ */ |