]>
Commit | Line | Data |
---|---|---|
efba0985 SM |
1 | PCEP Module Internals |
2 | ===================== | |
3 | ||
4 | Introduction | |
5 | ------------ | |
6 | ||
7 | The PCEP module for the pathd daemon implements the PCEP protocol described in | |
8 | :rfc:`5440` to update the policies and candidate paths. | |
9 | ||
10 | The protocol encoding/decoding and the basic session management is handled by | |
11 | the `pceplib external library 1.2 <https://github.com/volta-networks/pceplib/tree/devel-1.2>`_. | |
12 | ||
13 | Together with pceplib, this module supports at least partially: | |
14 | ||
15 | - :rfc:`5440` | |
16 | ||
17 | Most of the protocol defined in the RFC is implemented. | |
18 | All the messages can be parsed, but this was only tested in the context | |
19 | of segment routing. Only a very small subset of metric types can be | |
20 | configured, and there is a known issue with some Cisco routers not | |
21 | following the IANA numbers for metrics. | |
22 | ||
23 | - :rfc:`8231` | |
24 | ||
25 | Support delegation of candidate path after performing the initial | |
26 | computation request. If the PCE does not respond or cannot compute | |
27 | a path, an empty candidate path is delegated to the PCE. | |
28 | Only tested in the context of segment routing. | |
29 | ||
30 | - :rfc:`8408` | |
31 | ||
32 | Only used to comunicate the support for segment routing to the PCE. | |
33 | ||
34 | - :rfc:`8664` | |
35 | ||
36 | All the NAI types are implemented, but only the MPLS NAI are supported. | |
37 | If the PCE provide segments that are not MPLS labels, the PCC will | |
38 | return an error. | |
39 | ||
40 | Note that pceplib supports more RFCs and drafts, see pceplib | |
41 | `README <https://github.com/volta-networks/pceplib/blob/master/README.md>`_ | |
42 | for more details. | |
43 | ||
44 | ||
45 | Architecture | |
46 | ------------ | |
47 | ||
48 | Overview | |
49 | ........ | |
50 | ||
51 | The module is separated into multiple layers: | |
52 | ||
53 | - pathd interface | |
54 | - command-line console | |
55 | - controller | |
56 | - PCC | |
57 | - pceplib interface | |
58 | ||
59 | The pathd interface handles all the interactions with the daemon API. | |
60 | ||
61 | The command-line console handles all the VTYSH configuration commands. | |
62 | ||
63 | The controller manages the multiple PCC connections and the interaction between | |
64 | them and the daemon interface. | |
65 | ||
66 | The PCC handles a single connection to a PCE through a pceplib session. | |
67 | ||
68 | The pceplib interface abstracts the API of the pceplib. | |
69 | ||
70 | .. figure:: ../figures/pcep_module_threading_overview.svg | |
71 | ||
72 | ||
73 | Threading Model | |
74 | --------------- | |
75 | ||
76 | The module requires multiple threads to cooperate: | |
77 | ||
78 | - The main thread used by the pathd daemon. | |
79 | - The controller pthread used to isolate the PCC from the main thread. | |
80 | - The possible threads started in the pceplib library. | |
81 | ||
82 | To ensure thread safety, all the controller and PCC state data structures can | |
83 | only be read and modified in the controller thread, and all the global data | |
84 | structures can only be read and modified in the main thread. Most of the | |
85 | interactions between these threads are done through FRR timers and events. | |
86 | ||
87 | The controller is the bridge between the two threads, all the functions that | |
88 | **MUST** be called from the main thread start with the prefix `pcep_ctrl_` and | |
89 | all the functions that **MUST** be called from the controller thread start | |
90 | with the prefix `pcep_thread_`. When an asynchronous action must be taken in | |
91 | a different thread, an FRR event is sent to the thread. If some synchronous | |
92 | operation is needed, the calling thread will block and run a callback in the | |
93 | other thread, there the result is **COPIED** and returned to the calling thread. | |
94 | ||
95 | No function other than the controller functions defined for it should be called | |
96 | from the main thread. The only exception being some utility functions from | |
97 | `path_pcep_lib.[hc]`. | |
98 | ||
99 | All the calls to pathd API functions **MUST** be performed in the main thread, | |
100 | for that, the controller sends FRR events handled in function | |
101 | `path_pcep.c:pcep_main_event_handler`. | |
102 | ||
103 | For the same reason, the console client only runs in the main thread. It can | |
104 | freely use the global variable, but **MUST** use controller's `pcep_ctrl_` | |
105 | functions to interact with the PCCs. | |
106 | ||
107 | ||
108 | Source Code | |
109 | ----------- | |
110 | ||
111 | Generic Data Structures | |
112 | ....................... | |
113 | ||
114 | The data structures are defined in multiple places, and where they are defined | |
115 | dictates where they can be used. | |
116 | ||
117 | The data structures defined in `path_pcep.h` can be used anywhere in the module. | |
118 | ||
119 | Internally, throughout the module, the `struct path` data structure is used | |
120 | to describe PCEP messages. It is a simplified flattened structure that can | |
121 | represent multiple complex PCEP message types. The conversion from this | |
122 | structure to the PCEP data structures used by pceplib is done in the pceplib | |
123 | interface layer. | |
124 | ||
125 | The data structures defined in `path_pcep_controller.h` should only be used | |
126 | in `path_pcep_controller.c`. Even if a structure pointer is passed as a parameter | |
127 | to functions defined in `path_pcep_pcc.h`, these should consider it as an opaque | |
128 | data structure only used to call back controller functions. | |
129 | ||
130 | The same applies to the structures defined in `path_pcep_pcc.h`, even if the | |
131 | controller owns a reference to this data structure, it should never read or | |
132 | modify it directly, it should be considered an opaque structure. | |
133 | ||
134 | The global data structure can be accessed from the pathd interface layer | |
135 | `path_pcep.c` and the command line client code `path_pcep_cli.c`. | |
136 | ||
137 | ||
138 | Interface With Pathd | |
139 | .................... | |
140 | ||
141 | All the functions calling or called by the pathd daemon are implemented in | |
142 | `path_pcep.c`. These functions **MUST** run in the main FRR thread, and | |
143 | all the interactions with the controller and the PCCs **MUST** pass through | |
144 | the controller's `pcep_ctrl_` prefixed functions. | |
145 | ||
146 | To handle asynchronous events from the PCCs, a callback is passed to | |
147 | `pcep_ctrl_initialize` that is called in the FRR main thread context. | |
148 | ||
149 | ||
150 | Command Line Client | |
151 | ................... | |
152 | ||
153 | All the command line configuration commands (VTYSH) are implemented in | |
154 | `path_pcep_cli.c`. All the functions there run in the main FRR thread and | |
155 | can freely access the global variables. All the interaction with the | |
156 | controller's and the PCCs **MUST** pass through the controller `pcep_ctrl_` | |
157 | prefixed functions. | |
158 | ||
159 | ||
160 | Debugging Helpers | |
161 | ................. | |
162 | ||
163 | All the functions formating data structures for debugging and logging purposes | |
164 | are implemented in `path_pcep_debug.[hc]`. | |
165 | ||
166 | ||
167 | Interface with pceplib | |
168 | ...................... | |
169 | ||
170 | All the functions calling the pceplib external library are defined in | |
171 | `path_pcep_lib.[hc]`. Some functions are called from the main FRR thread, like | |
172 | `pcep_lib_initialize`, `pcep_lib_finalize`; some can be called from either | |
173 | thread, like `pcep_lib_free_counters`; some function must be called from the | |
174 | controller thread, like `pcep_lib_connect`. This will probably be formalized | |
175 | later on with function prefix like done in the controller. | |
176 | ||
177 | ||
178 | Controller | |
179 | .......... | |
180 | ||
181 | The controller is defined and implemented in `path_pcep_controller.[hc]`. | |
182 | Part of the controller code runs in FRR main thread and part runs in its own | |
183 | FRR pthread started to isolate the main thread from the PCCs' event loop. | |
184 | To communicate between the threads it uses FRR events, timers and | |
8c1186d3 | 185 | `event_execute` calls. |
efba0985 SM |
186 | |
187 | ||
188 | PCC | |
189 | ... | |
190 | ||
191 | Each PCC instance owns its state and runs in the controller thread. They are | |
192 | defined and implemented in `path_pcep_pcc.[hc]`. All the interactions with | |
193 | the daemon must pass through some controller's `pcep_thread_` prefixed function. |