]>
Commit | Line | Data |
---|---|---|
74971473 JG |
1 | .. _pceplib: |
2 | ||
3 | ******* | |
4 | PCEPlib | |
5 | ******* | |
6 | ||
7 | Overview | |
8 | ======== | |
9 | ||
10 | The PCEPlib is a PCEP implementation library that can be used by either a PCE | |
11 | or PCC. | |
12 | ||
13 | Currently, only the FRR pathd has been implemented as a PCC with the PCEPlib. | |
14 | The PCEPlib is able to simultaneously connect to multiple PCEP peers and can | |
15 | maintain persistent PCEP connections. | |
16 | ||
17 | ||
18 | PCEPlib compliance | |
19 | ================== | |
20 | ||
21 | The PCEPlib implements version 1 of the PCEP protocol, according to `RFC 5440 <https://tools.ietf.org/html/rfc5440>`_. | |
22 | ||
23 | Additionally, the PCEPlib implements the following PCEP extensions: | |
24 | ||
25 | - `RFC 8281 <https://tools.ietf.org/html/rfc8281>`_ PCE initiated for PCE-Initiated LSP Setup | |
26 | - `RFC 8231 <https://tools.ietf.org/html/rfc8231>`_ Extensions for Stateful PCE | |
27 | - `RFC 8232 <https://tools.ietf.org/html/rfc8232>`_ Optimizations of Label Switched Path State Synchronization Procedures for a Stateful PCE | |
28 | - `RFC 8282 <https://tools.ietf.org/html/rfc8282>`_ Extensions to PCEP for Inter-Layer MPLS and GMPLS Traffic Engineering | |
29 | - `RFC 8408 <https://tools.ietf.org/html/rfc8408>`_ Conveying Path Setup Type in PCE Communication Protocol (PCEP) Messages | |
30 | - `draft-ietf-pce-segment-routing-07 <https://tools.ietf.org/html/draft-ietf-pce-segment-routing-07>`_, | |
31 | `draft-ietf-pce-segment-routing-16 <https://tools.ietf.org/html/draft-ietf-pce-segment-routing-16>`_, | |
32 | `RFC 8664 <https://tools.ietf.org/html/rfc8664>`_ Segment routing protocol extensions | |
33 | - `RFC 7470 <https://tools.ietf.org/html/rfc7470>`_ Conveying Vendor-Specific Constraints | |
34 | - `Draft-ietf-pce-association-group-10 <https://tools.ietf.org/html/draft-ietf-pce-association-group-10>`_ | |
35 | Establishing Relationships Between Sets of Label Switched Paths | |
36 | - `Draft-barth-pce-segment-routing-policy-cp-04 <https://tools.ietf.org/html/draft-barth-pce-segment-routing-policy-cp-04>`_ | |
37 | Segment Routing Policy Candidate Paths | |
38 | ||
39 | ||
40 | PCEPlib Architecture | |
41 | ==================== | |
42 | ||
43 | The PCEPlib is comprised of the following modules, each of which will be | |
44 | detailed in the following sections. | |
45 | ||
46 | - **pcep_messages** | |
47 | - PCEP messages, objects, and TLVs implementations | |
48 | ||
49 | - **pcep_pcc** | |
50 | - PCEPlib public PCC API with a sample PCC binary | |
51 | ||
52 | - **pcep_session_logic** | |
53 | - PCEP Session handling | |
54 | ||
55 | - **pcep_socket_comm** | |
56 | - Socket communications | |
57 | ||
58 | - **pcep_timers** | |
59 | - PCEP timers | |
60 | ||
61 | - **pcep_utils** | |
62 | - Internal utilities used by the PCEPlib modules. | |
63 | ||
64 | The interaction of these modules can be seen in the following diagram. | |
65 | ||
66 | PCEPlib Architecture: | |
67 | ||
68 | .. image:: images/PCEPlib_design.jpg | |
69 | ||
70 | ||
71 | PCEP Session Logic library | |
72 | -------------------------- | |
73 | ||
74 | The PCEP Session Logic library orchestrates calls to the rest of the PCC libraries. | |
75 | ||
76 | PCEP Session Logic library responsibilities: | |
77 | ||
78 | - Handle messages received from "PCEP Socket Comm" | |
79 | - Create and manage "PCEP Session" objects | |
80 | - Set timers and react to timer expirations | |
81 | - Manage counters | |
82 | ||
83 | The PCEP Session Logic library will have 2 main triggers controlled by a | |
84 | pthread condition variable: | |
85 | ||
86 | - Timer expirations - ``on_timer_expire()`` callback | |
87 | - Messages received from PCEP SocketComm - ``message_received()`` callback | |
88 | ||
89 | The counters are created and managed using the ``pcep_utils/pcep_utils_counters.h`` | |
90 | counters library. The following are the different counter groups managed: | |
91 | ||
92 | - **COUNTER_SUBGROUP_ID_RX_MSG** | |
93 | - **COUNTER_SUBGROUP_ID_TX_MSG** | |
94 | - **COUNTER_SUBGROUP_ID_RX_OBJ** | |
95 | - **COUNTER_SUBGROUP_ID_TX_OBJ** | |
96 | - **COUNTER_SUBGROUP_ID_RX_SUBOBJ** | |
97 | - **COUNTER_SUBGROUP_ID_TX_SUBOBJ** | |
98 | - **COUNTER_SUBGROUP_ID_RX_RO_SR_SUBOBJ** | |
99 | - **COUNTER_SUBGROUP_ID_TX_RO_SR_SUBOBJ** | |
100 | - **COUNTER_SUBGROUP_ID_RX_TLV** | |
101 | - **COUNTER_SUBGROUP_ID_TX_TLV** | |
102 | - **COUNTER_SUBGROUP_ID_EVENT** | |
103 | ||
104 | The counters can be obtained and reset as explained later in the PCEPlib PCC API. | |
105 | ||
106 | PCEP Socket Comm library | |
107 | ------------------------ | |
108 | ||
109 | PCEP communication can be configured to be handled internally in this simple | |
110 | library. When this library is instantiated by the PCEP Session Logic, callbacks | |
111 | are provided to handle received messages and error conditions. | |
112 | ||
113 | The following diagram illustrates how the library works. | |
114 | ||
115 | PCEPlib Socket Comm: | |
116 | ||
117 | .. image:: images/PCEPlib_socket_comm.jpg | |
118 | ||
119 | ||
120 | PCEP Timers library | |
121 | ------------------- | |
122 | ||
123 | Timers can be configured to be handled internally by this library. When this | |
124 | library is instantiated by the PCEP Session Logic, callbacks are provided to | |
125 | ha:0 | |
126 | ndle timer expirations. The following timers are implemented and handled, | |
127 | according to `RFC 5440 <https://tools.ietf.org/html/rfc5440>`_. | |
128 | ||
129 | - Open KeepWait (fixed at 60 seconds) | |
130 | - Set once the PCC sends an Open, and if it expires before receiving a KeepAlive or PCErr, then the PCC should send a PCErr and close the TCP connection | |
131 | ||
132 | - Keepalive timer | |
133 | - How often the PCC should send Keepalive messages to the PCE (and vice-versa) | |
134 | - The timer will be reset after any message is sent: any message serves as a Keepalive | |
135 | ||
136 | - DeadTimer | |
137 | - If no messages are received before expiration, the session is declared as down | |
138 | - Reset everytime any message is received | |
139 | ||
140 | - PCReq request timer | |
141 | - How long the PCC waits for the PCE to reply to PCReq messages. | |
142 | ||
143 | PCEPlib Timers: | |
144 | ||
145 | .. image:: images/PCEPlib_timers.jpg | |
146 | ||
147 | ||
148 | PCEP Messages library | |
149 | --------------------- | |
150 | ||
151 | The PCEP Messages library has all of the implemented PCEP messages, objects, | |
152 | TLVs, and related functionality. | |
153 | ||
154 | The following header files can be used for creating and handling received PCEP | |
155 | entities. | |
156 | ||
157 | - pcep-messages.h | |
158 | - pcep-objects.h | |
159 | - pcep-tlvs.h | |
160 | ||
161 | ||
162 | PCEP Messages | |
163 | +++++++++++++ | |
164 | ||
165 | The following PCEP messages can be created and received: | |
166 | ||
167 | - ``struct pcep_message* pcep_msg_create_open(...);`` | |
168 | - ``struct pcep_message* pcep_msg_create_open_with_tlvs(...);`` | |
169 | - ``struct pcep_message* pcep_msg_create_request(...);`` | |
170 | - ``struct pcep_message* pcep_msg_create_request_ipv6(...);`` | |
171 | - ``struct pcep_message* pcep_msg_create_reply(...);`` | |
172 | - ``struct pcep_message* pcep_msg_create_close(...);`` | |
173 | - ``struct pcep_message* pcep_msg_create_error(...);`` | |
174 | - ``struct pcep_message* pcep_msg_create_error_with_objects(...);`` | |
175 | - ``struct pcep_message* pcep_msg_create_keepalive(...);`` | |
176 | - ``struct pcep_message* pcep_msg_create_report(...);`` | |
177 | - ``struct pcep_message* pcep_msg_create_update(...);`` | |
178 | - ``struct pcep_message* pcep_msg_create_initiate(...);`` | |
179 | ||
180 | Refer to ``pcep_messages/include/pcep-messages.h`` and the API section | |
181 | below for more details. | |
182 | ||
183 | ||
184 | PCEP Objects | |
185 | ++++++++++++ | |
186 | ||
187 | The following PCEP objects can be created and received: | |
188 | ||
189 | - ``struct pcep_object_open* pcep_obj_create_open(...);`` | |
190 | - ``struct pcep_object_rp* pcep_obj_create_rp(...);`` | |
191 | - ``struct pcep_object_notify* pcep_obj_create_notify(...);`` | |
192 | - ``struct pcep_object_nopath* pcep_obj_create_nopath(...);`` | |
193 | - ``struct pcep_object_association_ipv4* pcep_obj_create_association_ipv4(...);`` | |
194 | - ``struct pcep_object_association_ipv6* pcep_obj_create_association_ipv6(...);`` | |
195 | - ``struct pcep_object_endpoints_ipv4* pcep_obj_create_endpoint_ipv4(...);`` | |
196 | - ``struct pcep_object_endpoints_ipv6* pcep_obj_create_endpoint_ipv6(...);`` | |
197 | - ``struct pcep_object_bandwidth* pcep_obj_create_bandwidth(...);`` | |
198 | - ``struct pcep_object_metric* pcep_obj_create_metric(...);`` | |
199 | - ``struct pcep_object_lspa* pcep_obj_create_lspa(...);`` | |
200 | - ``struct pcep_object_svec* pcep_obj_create_svec(...);`` | |
201 | - ``struct pcep_object_error* pcep_obj_create_error(...);`` | |
202 | - ``struct pcep_object_close* pcep_obj_create_close(...);`` | |
203 | - ``struct pcep_object_srp* pcep_obj_create_srp(...);`` | |
204 | - ``struct pcep_object_lsp* pcep_obj_create_lsp(...);`` | |
205 | - ``struct pcep_object_vendor_info* pcep_obj_create_vendor_info(...);`` | |
206 | - ``struct pcep_object_ro* pcep_obj_create_ero(...);`` | |
207 | - ``struct pcep_object_ro* pcep_obj_create_rro(...);`` | |
208 | - ``struct pcep_object_ro* pcep_obj_create_iro(...);`` | |
209 | - ``struct pcep_ro_subobj_ipv4* pcep_obj_create_ro_subobj_ipv4(...);`` | |
210 | - ``struct pcep_ro_subobj_ipv6* pcep_obj_create_ro_subobj_ipv6(...);`` | |
211 | - ``struct pcep_ro_subobj_unnum* pcep_obj_create_ro_subobj_unnum(...);`` | |
212 | - ``struct pcep_ro_subobj_32label* pcep_obj_create_ro_subobj_32label(...);`` | |
213 | - ``struct pcep_ro_subobj_asn* pcep_obj_create_ro_subobj_asn(...);`` | |
214 | - ``struct pcep_ro_subobj_sr* pcep_obj_create_ro_subobj_sr_nonai(...);`` | |
215 | - ``struct pcep_ro_subobj_sr* pcep_obj_create_ro_subobj_sr_ipv4_node(...);`` | |
216 | - ``struct pcep_ro_subobj_sr* pcep_obj_create_ro_subobj_sr_ipv6_node(...);`` | |
217 | - ``struct pcep_ro_subobj_sr* pcep_obj_create_ro_subobj_sr_ipv4_adj(...);`` | |
218 | - ``struct pcep_ro_subobj_sr* pcep_obj_create_ro_subobj_sr_ipv6_adj(...);`` | |
219 | - ``struct pcep_ro_subobj_sr* pcep_obj_create_ro_subobj_sr_unnumbered_ipv4_adj(...);`` | |
220 | - ``struct pcep_ro_subobj_sr* pcep_obj_create_ro_subobj_sr_linklocal_ipv6_adj(...);`` | |
221 | ||
222 | Refer to ``pcep_messages/include/pcep-objects.h`` and the API section | |
223 | below for more details. | |
224 | ||
225 | ||
226 | PCEP TLVs | |
227 | +++++++++ | |
228 | ||
229 | The following PCEP TLVs (Tag, Length, Value) can be created and received: | |
230 | ||
231 | - Open Object TLVs | |
232 | - ``struct pcep_object_tlv_stateful_pce_capability* pcep_tlv_create_stateful_pce_capability(...);`` | |
233 | - ``struct pcep_object_tlv_lsp_db_version* pcep_tlv_create_lsp_db_version(...);`` | |
234 | - ``struct pcep_object_tlv_speaker_entity_identifier* pcep_tlv_create_speaker_entity_id(...);`` | |
235 | - ``struct pcep_object_tlv_path_setup_type* pcep_tlv_create_path_setup_type(...);`` | |
236 | - ``struct pcep_object_tlv_path_setup_type_capability* pcep_tlv_create_path_setup_type_capability(...);`` | |
237 | - ``struct pcep_object_tlv_sr_pce_capability* pcep_tlv_create_sr_pce_capability(...);`` | |
238 | ||
239 | - LSP Object TLVs | |
240 | - ``struct pcep_object_tlv_ipv4_lsp_identifier* pcep_tlv_create_ipv4_lsp_identifiers(...);`` | |
241 | - ``struct pcep_object_tlv_ipv6_lsp_identifier* pcep_tlv_create_ipv6_lsp_identifiers(...);`` | |
242 | - ``struct pcep_object_tlv_symbolic_path_name* pcep_tlv_create_symbolic_path_name(...);`` | |
243 | - ``struct pcep_object_tlv_lsp_error_code* pcep_tlv_create_lsp_error_code(...);`` | |
244 | - ``struct pcep_object_tlv_rsvp_error_spec* pcep_tlv_create_rsvp_ipv4_error_spec(...);`` | |
245 | - ``struct pcep_object_tlv_rsvp_error_spec* pcep_tlv_create_rsvp_ipv6_error_spec(...);`` | |
246 | - ``struct pcep_object_tlv_nopath_vector* pcep_tlv_create_nopath_vector(...);`` | |
247 | - ``struct pcep_object_tlv_vendor_info* pcep_tlv_create_vendor_info(...);`` | |
248 | - ``struct pcep_object_tlv_arbitrary* pcep_tlv_create_tlv_arbitrary(...);`` | |
249 | ||
250 | - SRPAG (SR Association Group) TLVs | |
251 | - ``struct pcep_object_tlv_srpag_pol_id *pcep_tlv_create_srpag_pol_id_ipv4(...);`` | |
252 | - ``struct pcep_object_tlv_srpag_pol_id *pcep_tlv_create_srpag_pol_id_ipv6(...);`` | |
253 | - ``struct pcep_object_tlv_srpag_pol_name *pcep_tlv_create_srpag_pol_name(...);`` | |
254 | - ``struct pcep_object_tlv_srpag_cp_id *pcep_tlv_create_srpag_cp_id(...);`` | |
255 | - ``struct pcep_object_tlv_srpag_cp_pref *pcep_tlv_create_srpag_cp_pref(...);`` | |
256 | ||
257 | Refer to ``pcep_messages/include/pcep-tlvs.h`` and the API section | |
258 | below for more details. | |
259 | ||
260 | ||
261 | PCEP PCC | |
262 | -------- | |
263 | ||
264 | This module has a Public PCC API library (explained in detail later) and a | |
265 | sample PCC binary. The APIs in this library encapsulate other PCEPlib libraries | |
266 | for simplicity. With this API, the PCEPlib PCC can be started and stopped, and | |
267 | the PCEPlib event queue can be accessed. The PCEP Messages library is not | |
268 | encapsulated, and should be used directly. | |
269 | ||
270 | ||
271 | Internal Dependencies | |
272 | --------------------- | |
273 | ||
274 | The following diagram illustrates the internal PCEPlib library dependencies. | |
275 | ||
276 | PCEPlib internal dependencies: | |
277 | ||
278 | .. image:: images/PCEPlib_internal_deps.jpg | |
279 | ||
280 | ||
281 | External Dependencies | |
282 | --------------------- | |
283 | ||
284 | Originally the PCEPlib was based on the open source `libpcep project <https://www.acreo.se/open-software-libpcep>`_, | |
285 | but that dependency has been reduced to just one source file (pcep-tools.[ch]). | |
286 | ||
287 | ||
288 | PCEPlib Threading model | |
289 | ----------------------- | |
290 | ||
291 | The PCEPlib can be run in stand-alone mode whereby a thread is launched for | |
292 | timers and socket comm, as is illustrated in the following diagram. | |
293 | ||
294 | PCEPlib Threading model: | |
295 | ||
296 | .. image:: images/PCEPlib_threading_model.jpg | |
297 | ||
298 | The PCEPlib can also be configured to use an external timers and socket | |
299 | infrastructure like the FRR threads and tasks. In this case, no internal | |
300 | threads are launched for timers and socket comm, as is illustrated in the | |
301 | following diagram. | |
302 | ||
303 | PCEPlib Threading model with external infra: | |
304 | ||
305 | .. image:: images/PCEPlib_threading_model_frr_infra.jpg | |
306 | ||
307 | ||
308 | Building | |
309 | -------- | |
310 | ||
311 | The autotools build system is used and integrated with the frr build system. | |
312 | ||
313 | Testing | |
314 | ------- | |
315 | ||
316 | The Unit Tests for an individual library are executed with the ``make check`` | |
317 | command. The Unit Test binary will be written to the project ``build`` directory. | |
318 | All Unit Tests are executed with Valgrind, and any memory issues reported by | |
319 | Valgrind will cause the Unit Test to fail. | |
320 | ||
321 | ||
322 | PCEPlib PCC API | |
323 | =============== | |
324 | ||
325 | The following sections describe the PCEPlib PCC API. | |
326 | ||
327 | ||
328 | PCEPlib PCC Initialization and Destruction | |
329 | ------------------------------------------ | |
330 | ||
331 | The PCEPlib can be initialized to handle memory, timers, and socket comm | |
332 | internally in what is called stand-alone mode, or with an external | |
333 | infrastructure, like FRR. | |
334 | ||
335 | PCEPlib PCC Initialization and Destruction in stand-alone mode | |
336 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
337 | ||
338 | PCEPlib PCC initialization and destruction functions: | |
339 | ||
340 | - ``bool initialize_pcc();`` | |
341 | - ``bool initialize_pcc_wait_for_completion();`` | |
342 | - ``bool destroy_pcc();`` | |
343 | ||
344 | The PCC can be initialized with either ``initialize_pcc()`` or | |
345 | ``initialize_pcc_wait_for_completion()``. | |
346 | ||
347 | - ``initialize_pcc_wait_for_completion()`` blocks until ``destroy_pcc()`` | |
348 | is called from a separate pthread. | |
349 | - ``initialize_pcc()`` is non-blocking and will be stopped when | |
350 | ``destroy_pcc()`` is called. | |
351 | ||
352 | Both initialize functions will launch 3 pthreads: | |
353 | ||
354 | - 1 Timer pthread | |
355 | - 1 SocketComm pthread | |
356 | - 1 SessionLogic pthread | |
357 | ||
358 | When ``destroy_pcc()`` is called, all pthreads will be stopped and all | |
359 | resources will be released. | |
360 | ||
361 | All 3 functions return true upon success, and false otherwise. | |
362 | ||
363 | PCEPlib PCC Initialization and Destruction with FRR infrastructure | |
364 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
365 | ||
366 | PCEPlib PCC initialization and destruction functions: | |
367 | ||
368 | - ``bool initialize_pcc_infra(struct pceplib_infra_config *infra_config);`` | |
369 | - ``bool destroy_pcc();`` | |
370 | ||
371 | The ``pceplib_infra_config`` struct has the following fields: | |
372 | ||
373 | - **void *pceplib_infra_mt** | |
374 | - FRR Memory type pointer for infra related memory management | |
375 | ||
376 | - **void *pceplib_messages_mt** | |
377 | - FRR Memory type pointer for PCEP messages related memory management | |
378 | ||
379 | - **pceplib_malloc_func mfunc** | |
380 | - FRR malloc function pointer | |
381 | ||
382 | - **pceplib_calloc_func cfunc** | |
383 | - FRR calloc function pointer | |
384 | ||
385 | - **pceplib_realloc_func rfunc** | |
386 | - FRR realloc function pointer | |
387 | ||
388 | - **pceplib_strdup_func sfunc** | |
389 | - FRR strdup function pointer | |
390 | ||
391 | - **pceplib_free_func ffunc** | |
392 | - FRR free function pointer | |
393 | ||
394 | - **void *external_infra_data** | |
395 | - FRR data used by FRR timers and sockets infrastructure | |
396 | ||
397 | - **ext_timer_create timer_create_func** | |
398 | - FRR timer create function pointer | |
399 | ||
400 | - **ext_timer_cancel timer_cancel_func** | |
401 | - FRR timer cancel function pointer | |
402 | ||
403 | - **ext_socket_write socket_write_func** | |
404 | - FRR socket write function pointer, indicating fd is ready to be written to | |
405 | ||
406 | - **ext_socket_read socket_read_func** | |
407 | - FRR socket write function pointer, indicating fd is ready to be read from | |
408 | ||
409 | ||
410 | PCEPlib PCC configuration | |
411 | ------------------------- | |
412 | ||
413 | PCEPlib PCC configuratoin functions: | |
414 | ||
415 | - ``pcep_configuration *create_default_pcep_configuration();`` | |
416 | - ``void destroy_pcep_configuration(pcep_configuration *config);`` | |
417 | ||
418 | A ``pcep_configuration`` object with default values is created with | |
419 | ``create_default_pcep_configuration()``. These values can be tailored to | |
420 | specific use cases. | |
421 | ||
422 | Created ``pcep_configuration`` objects are destroyed with | |
423 | ``destroy_pcep_configuration()``. | |
424 | ||
425 | ||
426 | PCEPlib PCC configuration paramaters | |
427 | ++++++++++++++++++++++++++++++++++++ | |
428 | ||
429 | The ``pcep_configuration`` object is defined in ``pcep_session_logic/include/pcep_session_logic.h`` | |
430 | The attributes in the ``pcep_configuration`` object are detailed as follows. | |
431 | ||
432 | PCEP Connection parameters: | |
433 | ||
434 | - **dst_pcep_port** | |
435 | - Defaults to 0, in which case the default PCEP TCP destination port | |
436 | 4189 will be used. | |
437 | - Set to use a specific PCEP TCP destination port. | |
438 | ||
439 | - **src_pcep_port** | |
440 | - Defaults to 0, in which case the default PCEP TCP source port | |
441 | 4189 will be used. | |
442 | - Set to use a specific PCEP TCP source port. | |
443 | ||
444 | - **Source IP** | |
445 | - Defaults to IPv4 INADDR_ANY | |
446 | - Set **src_ip.src_ipv4** and **is_src_ipv6=false** to set the source IPv4. | |
447 | - Set **src_ip.src_ipv6** and **is_src_ipv6=true** to set the source IPv6. | |
448 | ||
449 | - **socket_connect_timeout_millis** | |
450 | - Maximum amount of time to wait to connect to the PCE TCP socket | |
451 | before failing, in milliseconds. | |
452 | ||
453 | PCEP Versioning: | |
454 | ||
455 | - **pcep_msg_versioning->draft_ietf_pce_segment_routing_07** | |
456 | - Defaults to false, in which case draft 16 versioning will be used. | |
457 | - Set to true to use draft 07 versioning. | |
458 | ||
459 | PCEP Open Message Parameters: | |
460 | ||
461 | - **keep_alive_seconds** | |
462 | - Sent to PCE in PCEP Open Msg | |
463 | - Recommended value = 30, Minimum value = 1 | |
464 | - Disabled by setting value = 0 | |
465 | ||
466 | - **dead_timer_seconds** | |
467 | - Sent to PCE in PCEP Open Msg | |
468 | - Recommended value = 4 * keepalive timer value | |
469 | ||
470 | - Supported value ranges for PCEP Open Message received from the PCE | |
471 | - **min_keep_alive_seconds**, **max_keep_alive_seconds** | |
472 | - **min_dead_timer_seconds**, **max_dead_timer_seconds** | |
473 | ||
474 | - **request_time_seconds** | |
475 | - When a PCC sends a PcReq to a PCE, the amount of time a PCC will | |
476 | wait for a PcRep reply from the PCE. | |
477 | ||
478 | - **max_unknown_requests** | |
479 | - If a PCC/PCE receives PCRep/PCReq messages with unknown requests | |
480 | at a rate equal or greater than MAX-UNKNOWN-REQUESTS per minute, | |
481 | the PCC/PCE MUST send a PCEP CLOSE message. | |
482 | - Recommended value = 5 | |
483 | ||
484 | - **max_unknown_messages** | |
485 | - If a PCC/PCE receives unrecognized messages at a rate equal or | |
486 | greater than MAX-UNKNOWN-MESSAGES per minute, the PCC/PCE MUST | |
487 | send a PCEP CLOSE message | |
488 | - Recommended value = 5 | |
489 | ||
490 | Stateful PCE Capability TLV configuration parameters (RFC 8231, 8232, 8281, and | |
491 | draft-ietf-pce-segment-routing-16): | |
492 | ||
493 | - **support_stateful_pce_lsp_update** | |
494 | - If this flag is true, then a Stateful PCE Capability TLV will | |
495 | be added to the PCEP Open object, with the LSP Update Capability | |
496 | U-flag set true. | |
497 | - The rest of these parameters are used to configure the Stateful | |
498 | PCE Capability TLV | |
499 | ||
500 | - **support_pce_lsp_instantiation** | |
501 | - Sets the I-flag true, indicating the PCC allows instantiation | |
502 | of an LSP by a PCE. | |
503 | ||
504 | - **support_include_db_version** | |
505 | - Sets the S-bit true, indicating the PCC will include the | |
506 | LSP-DB-VERSION TLV in each LSP object. See lsp_db_version below. | |
507 | ||
508 | - **support_lsp_triggered_resync** | |
509 | - Sets the T-bit true, indicating the PCE can trigger resynchronization | |
510 | of LSPs at any point in the life of the session. | |
511 | ||
512 | - **support_lsp_delta_sync** | |
513 | - Sets the D-bit true, indicating the PCEP speaker allows incremental | |
514 | (delta) State Synchronization. | |
515 | ||
516 | - **support_pce_triggered_initial_sync** | |
517 | - Sets the F-bit true, indicating the PCE SHOULD trigger initial (first) | |
518 | State Synchronization | |
519 | ||
520 | LSP DB Version TLV configuration parameters: | |
521 | ||
522 | - **lsp_db_version** | |
523 | - If this parameter has a value other than 0, and the above | |
524 | support_include_db_version flag is true, then an LSP DB | |
525 | Version TLV will be added to the PCEP Open object. | |
526 | - This parameter should only be set if LSP-DB survived a restart | |
527 | and is available. | |
528 | - This value will be copied over to the pcep_session upon initialization. | |
529 | ||
530 | SR PCE Capability sub-TLV configuration parameters (draft-ietf-pce-segment-routing-16): | |
531 | ||
532 | - **support_sr_te_pst** | |
533 | - If this flag is true, then an SR PCE Capability sub-TLV will be | |
534 | added to a Path Setup type Capability TLV, which will be added | |
535 | to the PCEP Open object. | |
536 | - The PST used in the Path Setup type Capability will be 1, | |
537 | indicating the Path is setup using Segment Routing Traffic Engineering. | |
538 | ||
539 | Only set the following fields if the **support_sr_te_pst** flag is true. | |
540 | ||
541 | - **pcc_can_resolve_nai_to_sid** | |
542 | - Sets the N-flag true, indicating that the PCC is capable of resolving | |
543 | a Node or Adjacency Identifier to a SID | |
544 | ||
545 | - **max_sid_depth** | |
546 | - If set other than 0, then the PCC imposes a limit on the Maximum | |
547 | SID depth. | |
548 | - If this parameter is other than 0, then the X bit will be true, | |
549 | and the parameter value will be set in the MSD field. | |
550 | ||
551 | ||
552 | PCEPlib PCC connections | |
553 | ----------------------- | |
554 | ||
555 | PCEPlib PCC connect and disconnect functions: | |
556 | ||
557 | - ``pcep_session *connect_pce(pcep_configuration *config, struct in_addr *pce_ip);`` | |
558 | - ``pcep_session *connect_pce_ipv6(pcep_configuration *config, struct in6_addr *pce_ip);`` | |
559 | - ``void disconnect_pce(pcep_session *session);`` | |
560 | ||
561 | When connecting to a PCE, a ``pcep_session`` will be returned on success, NULL | |
562 | otherwise. | |
563 | ||
564 | Refer to the above PCC configuration parameters section for setting the source | |
565 | and destination PCEP TCP ports, and the source IP address and version. | |
566 | ||
567 | ||
568 | PCEP Messages, Objects, and TLVs | |
569 | -------------------------------- | |
570 | ||
571 | The PCEP messages, objects, and TLVs created in the PCEPlib are high-level API | |
572 | structures, meaning they need to be encoded before being sent on-the-wire, and | |
573 | the raw data received needs to be decoded into these structures. This makes | |
574 | using these objects much easier for the library consumer, since they do not | |
575 | need to know the detailed raw format of the PCEP entities. | |
576 | ||
577 | ||
578 | PCEP Messages | |
579 | +++++++++++++ | |
580 | ||
581 | Received messages (in the ``pcep_event`` explained below) are of type | |
582 | ``pcep_message``, which have the following fields: | |
583 | ||
584 | - ``struct pcep_message_header *msg_header;`` | |
585 | - Defines the PCEP version and message type | |
586 | ||
587 | - ``double_linked_list *obj_list;`` | |
588 | - A double linked list of the message objects | |
589 | - Each entry is a pointer to a ``struct pcep_object_header``, and | |
590 | using the ``object_class`` and ``object_type`` fields, the pointer | |
591 | can be cast to the appropriate object structure to access the | |
592 | rest of the object fields | |
593 | ||
594 | - ``uint8_t *encoded_message;`` | |
595 | - This field is only populated for received messages or once the | |
596 | ``pcep_encode_message()`` function has been called on the message. | |
597 | - This field is a pointer to the raw PCEP data for the entire | |
598 | message, including all objects and TLVs. | |
599 | ||
600 | - ``uint16_t encoded_message_length;`` | |
601 | - This field is only populated for received messages or once the | |
602 | ``pcep_encode_message()`` function has been called on the message. | |
603 | - This field is the length of the entire raw message, including | |
604 | all objects and TLVs. | |
605 | - This field is in host byte order. | |
606 | ||
607 | ||
608 | PCEP Objects | |
609 | ++++++++++++ | |
610 | ||
611 | A PCEP message has a double linked list of pointers to ``struct pcep_object_header`` | |
612 | structures, which have the following fields: | |
613 | ||
614 | - ``enum pcep_object_classes object_class;`` | |
615 | - ``enum pcep_object_types object_type;`` | |
616 | - ``bool flag_p;`` | |
617 | - PCC Processing rule bit: When set, the object MUST be taken into | |
618 | account, when cleared the object is optional | |
619 | ||
620 | - ``bool flag_i;`` | |
621 | - PCE Ignore bit: indicates to a PCC whether or not an optional | |
622 | object was processed | |
623 | ||
624 | - ``double_linked_list *tlv_list;`` | |
625 | - A double linked list of the object TLVs | |
626 | - Each entry is a pointer to a ``struct pcep_object_tlv_header``, and | |
627 | using the TLV type field, the pointer can be cast to the | |
628 | appropriate TLV structure to access the rest of the TLV fields | |
629 | ||
630 | - ``uint8_t *encoded_object;`` | |
631 | - This field is only populated for received objects or once the | |
632 | ``pcep_encode_object()`` (called by ``pcep_encode_message()``) | |
633 | function has been called on the object. | |
634 | - Pointer into the encoded_message field (from the pcep_message) | |
635 | where the raw object PCEP data starts. | |
636 | ||
637 | - ``uint16_t encoded_object_length;`` | |
638 | - This field is only populated for received objects or once the | |
639 | ``pcep_encode_object()`` (called by ``pcep_encode_message()``) | |
640 | function has been called on the object. | |
641 | - This field is the length of the entire raw TLV | |
642 | - This field is in host byte order. | |
643 | ||
644 | The object class and type can be used to cast the ``struct pcep_object_header`` | |
645 | pointer to the appropriate object structure so the specific object fields can | |
646 | be accessed. | |
647 | ||
648 | ||
649 | PCEP TLVs | |
650 | +++++++++ | |
651 | ||
652 | A PCEP object has a double linked list of pointers to ``struct pcep_object_tlv_header`` | |
653 | structures, which have the following fields: | |
654 | ||
655 | - ``enum pcep_object_tlv_types type;`` | |
656 | - ``uint8_t *encoded_tlv;`` | |
657 | - This field is only populated for received TLVs or once the | |
658 | ``pcep_encode_tlv()`` (called by ``pcep_encode_message()``) | |
659 | function has been called on the TLV. | |
660 | - Pointer into the encoded_message field (from the pcep_message) | |
661 | where the raw TLV PCEP data starts. | |
662 | ||
663 | - ``uint16_t encoded_tlv_length;`` | |
664 | - This field is only populated for received TLVs or once the | |
665 | ``pcep_encode_tlv()`` (called by ``pcep_encode_message()``) | |
666 | function has been called on the TLV. | |
667 | - This field is the length of the entire raw TLV | |
668 | - This field is in host byte order. | |
669 | ||
670 | ||
671 | Memory management | |
672 | +++++++++++++++++ | |
673 | ||
674 | Any of the PCEPlib Message Library functions that receive a pointer to a | |
675 | ``double_linked_list``, ``pcep_object_header``, or ``pcep_object_tlv_header``, | |
676 | transfer the ownership of the entity to the PCEPlib. The memory will be freed | |
677 | internally when the encapsulating structure is freed. If the memory for any of | |
678 | these is freed by the caller, then there will be a double memory free error | |
679 | when the memory is freed internally in the PCEPlib. | |
680 | ||
681 | Any of the PCEPlib Message Library functions that receive either a pointer to a | |
682 | ``struct in_addr`` or ``struct in6_addr`` will allocate memory for the IP | |
683 | address internally and copy the IP address. It is the responsibility of the | |
684 | caller to manage the memory for the IP address passed into the PCEPlib Message | |
685 | Library functions. | |
686 | ||
687 | For messages received via the event queue (explained below), the message will | |
688 | be freed when the event is freed by calling ``destroy_pcep_event()``. | |
689 | ||
690 | When sending messages, the message will be freed internally in the PCEPlib when | |
691 | the ``send_message()`` ``pcep_pcc`` API function when the ``free_after_send`` flag | |
692 | is set true. | |
693 | ||
694 | To manually delete a message, call the ``pcep_msg_free_message()`` function. | |
695 | Internally, this will call ``pcep_obj_free_object()`` and ``pcep_obj_free_tlv()`` | |
696 | appropriately. | |
697 | ||
698 | ||
699 | Sending a PCEP Report message | |
700 | ----------------------------- | |
701 | ||
702 | This section shows how to send a PCEP Report messages from the PCC to the PCE, | |
703 | and serves as an example of how to send other messages. Refer to the sample | |
704 | PCC binary located in ``pcep_pcc/src/pcep_pcc.c`` for code examples os sending | |
705 | a PCEP Report message. | |
706 | ||
707 | The Report message must have at least an SRP, LSP, and ERO object. | |
708 | ||
709 | The PCEP Report message objects are created with the following APIs: | |
710 | ||
711 | - ``struct pcep_object_srp *pcep_obj_create_srp(...);`` | |
712 | - ``struct pcep_object_lsp *pcep_obj_create_lsp(...);`` | |
713 | - ``struct pcep_object_ro *pcep_obj_create_ero(...);`` | |
714 | - Create ero subobjects with the ``pcep_obj_create_ro_subobj_*(...);`` functions | |
715 | ||
716 | PCEP Report message is created with the following API: | |
717 | ||
718 | - ``struct pcep_header *pcep_msg_create_report(double_linked_list *report_object_list);`` | |
719 | ||
720 | A PCEP report messages is sent with the following API: | |
721 | ||
722 | - ``void send_message(pcep_session *session, pcep_message *message, bool free_after_send);`` | |
723 | ||
724 | ||
725 | PCEPlib Received event queue | |
726 | ---------------------------- | |
727 | ||
728 | PCEP events and messages of interest to the PCEPlib consumer will be stored | |
729 | internally in a message queue for retrieval. | |
730 | ||
731 | The following are the event types: | |
732 | ||
733 | - **MESSAGE_RECEIVED** | |
734 | - **PCE_CLOSED_SOCKET** | |
735 | - **PCE_SENT_PCEP_CLOSE** | |
736 | - **PCE_DEAD_TIMER_EXPIRED** | |
737 | - **PCE_OPEN_KEEP_WAIT_TIMER_EXPIRED** | |
738 | - **PCC_CONNECTED_TO_PCE** | |
739 | - **PCC_CONNECTION_FAILURE** | |
740 | - **PCC_PCEP_SESSION_CLOSED** | |
741 | - **PCC_RCVD_INVALID_OPEN** | |
742 | - **PCC_SENT_INVALID_OPEN** | |
743 | - **PCC_RCVD_MAX_INVALID_MSGS** | |
744 | - **PCC_RCVD_MAX_UNKOWN_MSGS** | |
745 | ||
746 | The following PCEP messages will not be posted on the message queue, as they | |
747 | are handled internally in the library: | |
748 | ||
749 | - **Open** | |
750 | - **Keep Alive** | |
751 | - **Close** | |
752 | ||
753 | Received event queue API: | |
754 | ||
755 | - ``bool event_queue_is_empty();`` | |
756 | - Returns true if the queue is empty, false otherwise | |
757 | ||
758 | - ``uint32_t event_queue_num_events_available();`` | |
759 | - Return the number of events on the queue, 0 if empty | |
760 | ||
761 | - ``struct pcep_event *event_queue_get_event();`` | |
762 | - Return the next event on the queue, NULL if empty | |
763 | - The ``message`` pointer will only be non-NULL if ``event_type`` | |
764 | is ``MESSAGE_RECEIVED`` | |
765 | ||
766 | - ``void destroy_pcep_event(struct pcep_event *event);`` | |
767 | - Free the PCEP Event resources, including the PCEP message if present | |
768 | ||
769 | ||
770 | PCEPlib Counters | |
771 | ---------------- | |
772 | ||
773 | The PCEPlib counters are managed in the ``pcep_session_logic`` library, and can | |
774 | be accessed in the ``pcep_session_counters`` field of the ``pcep_session`` structure. | |
775 | There are 2 API functions to manage the counters: | |
776 | ||
777 | - ``void dump_pcep_session_counters(pcep_session *session);`` | |
778 | - Dump all of the counters to the logs | |
779 | ||
780 | - ``void reset_pcep_session_counters(pcep_session *session);`` | |
781 |