]>
Commit | Line | Data |
---|---|---|
50cc7127 QY |
1 | OSPF API Documentation |
2 | ====================== | |
3 | ||
4 | Disclaimer | |
5 | ---------- | |
6 | ||
37f92f22 | 7 | The OSPF daemon contains an API for application access to the LSA database. |
06fa7bb9 QY |
8 | This API and documentation was created by Ralph Keller, originally as patch for |
9 | Zebra. Unfortunately, the page containing documentation for the API is no | |
10 | longer online. This page is an attempt to recreate documentation for the API | |
11 | (with lots of help from the WayBackMachine). | |
12 | ||
13 | Ralph has kindly licensed this documentation under GPLv2+. Please preserve the | |
14 | acknowledgements at the bottom of this document. | |
50cc7127 QY |
15 | |
16 | Introduction | |
17 | ------------ | |
18 | ||
37f92f22 QY |
19 | This page describes an API that allows external applications to access the |
20 | link-state database (LSDB) of the OSPF daemon. The implementation is based on | |
21 | the OSPF code from FRRouting (forked from Quagga and formerly Zebra) routing | |
22 | protocol suite and is subject to the GNU General Public License. The OSPF API | |
23 | provides you with the following functionality: | |
24 | ||
25 | - Retrieval of the full or partial link-state database of the OSPF daemon. | |
26 | This allows applications to obtain an exact copy of the LSDB including router | |
27 | LSAs, network LSAs and so on. Whenever a new LSA arrives at the OSPF daemon, | |
28 | the API module immediately informs the application by sending a message. This | |
29 | way, the application is always synchronized with the LSDB of the OSPF daemon. | |
30 | - Origination of own opaque LSAs (of type 9, 10, or 11) which are then | |
31 | distributed transparently to other routers within the flooding scope and | |
32 | received by other applications through the OSPF API. | |
33 | ||
34 | Opaque LSAs, which are described in :rfc:`2370`, allow you to distribute | |
35 | application-specific information within a network using the OSPF protocol. The | |
36 | information contained in opaque LSAs is transparent for the routing process but | |
37 | it can be processed by other modules such as traffic engineering (e.g., | |
38 | MPLS-TE). | |
50cc7127 QY |
39 | |
40 | Architecture | |
41 | ------------ | |
42 | ||
37f92f22 QY |
43 | The following picture depicts the architecture of the Quagga/Zebra protocol |
44 | suite. The OSPF daemon is extended with opaque LSA capabilities and an API for | |
45 | external applications. The OSPF core module executes the OSPF protocol by | |
46 | discovering neighbors and exchanging neighbor state. The opaque module, | |
47 | implemented by Masahiko Endo, provides functions to exchange opaque LSAs | |
48 | between routers. Opaque LSAs can be generated by several modules such as the | |
49 | MPLS-TE module or the API server module. These modules then invoke the opaque | |
50 | module to flood their data to neighbors within the flooding scope. | |
51 | ||
52 | The client, which is an application potentially running on a different node | |
53 | than the OSPF daemon, links against the OSPF API client library. This client | |
54 | library establishes a socket connection with the API server module of the OSPF | |
55 | daemon and uses this connection to retrieve LSAs and originate opaque LSAs. | |
50cc7127 QY |
56 | |
57 | .. figure:: ../figures/ospf_api_architecture.png | |
58 | :alt: image | |
59 | ||
60 | image | |
61 | ||
37f92f22 QY |
62 | The OSPF API server module works like any other internal opaque module (such as |
63 | the MPLS-TE module), but listens to connections from external applications that | |
64 | want to communicate with the OSPF daemon. The API server module can handle | |
65 | multiple clients concurrently. | |
50cc7127 | 66 | |
37f92f22 QY |
67 | One of the main objectives of the implementation is to make as little changes |
68 | to the existing Zebra code as possible. | |
50cc7127 QY |
69 | |
70 | Installation & Configuration | |
71 | ---------------------------- | |
72 | ||
37f92f22 | 73 | Download FRRouting and unpack it. |
50cc7127 | 74 | |
37f92f22 QY |
75 | Configure and build FRR (note that ``--enable-opaque-lsa`` also enables the |
76 | ospfapi server and ospfclient). | |
50cc7127 QY |
77 | |
78 | :: | |
79 | ||
50cc7127 QY |
80 | % sh ./configure --enable-opaque-lsa |
81 | % make | |
82 | ||
83 | This should also compile the client library and sample application in | |
84 | ospfclient. | |
85 | ||
37f92f22 QY |
86 | Make sure that you have enabled opaque LSAs in your configuration. Add the |
87 | ``ospf opaque-lsa`` statement to your :file:`ospfd.conf`: | |
50cc7127 QY |
88 | |
89 | :: | |
90 | ||
91 | ! -*- ospf -*- | |
92 | ! | |
93 | ! OSPFd sample configuration file | |
94 | ! | |
95 | ! | |
96 | hostname xxxxx | |
97 | password xxxxx | |
98 | ||
99 | router ospf | |
100 | router-id 10.0.0.1 | |
101 | network 10.0.0.1/24 area 1 | |
102 | neighbor 10.0.0.2 | |
103 | network 10.0.1.2/24 area 1 | |
104 | neighbor 10.0.1.1 | |
105 | ospf opaque-lsa <============ add this statement! | |
106 | ||
107 | Usage | |
108 | ----- | |
109 | ||
110 | In the following we describe how you can use the sample application to | |
37f92f22 QY |
111 | originate opaque LSAs. The sample application first registers with the OSPF |
112 | daemon the opaque type it wants to inject and then waits until the OSPF daemon | |
113 | is ready to accept opaque LSAs of that type. Then the client application | |
114 | originates an opaque LSA, waits 10 seconds and then updates the opaque LSA with | |
115 | new opaque data. After another 20 seconds, the client application deletes the | |
116 | opaque LSA from the LSDB. If the clients terminates unexpectedly, the OSPF API | |
117 | module will remove all the opaque LSAs that the application registered. Since | |
118 | the opaque LSAs are flooded to other routers, we will see the opaque LSAs in | |
119 | all routers according to the flooding scope of the opaque LSA. | |
50cc7127 QY |
120 | |
121 | We have a very simple demo setup, just two routers connected with an ATM | |
37f92f22 QY |
122 | point-to-point link. Start the modified OSPF daemons on two adjacent routers. |
123 | First run on msr2: | |
50cc7127 | 124 | |
37f92f22 | 125 | .. code-block:: console |
50cc7127 | 126 | |
37f92f22 | 127 | # ./ospfd --apiserver -f /usr/local/etc/ospfd.conf |
50cc7127 QY |
128 | |
129 | And on the neighboring router msr3: | |
130 | ||
37f92f22 | 131 | .. code-block:: console |
50cc7127 | 132 | |
37f92f22 | 133 | # ./ospfd --apiserver -f /usr/local/etc/ospfd.conf |
50cc7127 QY |
134 | |
135 | Now the two routers form adjacency and start exchanging their databases. | |
136 | Looking at the OSPF daemon of msr2 (or msr3), you see this: | |
137 | ||
37f92f22 | 138 | .. code-block:: console |
50cc7127 | 139 | |
37f92f22 | 140 | ospfd> show ip ospf database |
50cc7127 | 141 | |
37f92f22 | 142 | OSPF Router with ID (10.0.0.1) |
50cc7127 | 143 | |
37f92f22 | 144 | Router Link States (Area 0.0.0.1) |
50cc7127 | 145 | |
37f92f22 QY |
146 | Link ID ADV Router Age Seq# CkSum Link count |
147 | 10.0.0.1 10.0.0.1 55 0x80000003 0xc62f 2 | |
148 | 10.0.0.2 10.0.0.2 55 0x80000003 0xe3e4 3 | |
50cc7127 | 149 | |
37f92f22 | 150 | Net Link States (Area 0.0.0.1) |
50cc7127 | 151 | |
37f92f22 QY |
152 | Link ID ADV Router Age Seq# CkSum |
153 | 10.0.0.2 10.0.0.2 60 0x80000001 0x5fcb | |
50cc7127 QY |
154 | |
155 | Now we start the sample main application that originates an opaque LSA. | |
156 | ||
37f92f22 | 157 | .. code-block:: console |
50cc7127 | 158 | |
37f92f22 QY |
159 | # cd ospfapi/apiclient |
160 | # ./main msr2 10 250 20 0.0.0.0 0.0.0.1 | |
50cc7127 | 161 | |
37f92f22 QY |
162 | This originates an opaque LSA of type 10 (area local), with opaque type 250 |
163 | (experimental), opaque id of 20 (chosen arbitrarily), interface address 0.0.0.0 | |
164 | (which is used only for opaque LSAs type 9), and area 0.0.0.1 | |
50cc7127 QY |
165 | |
166 | Again looking at the OSPF database you see: | |
167 | ||
37f92f22 | 168 | .. code-block:: console |
50cc7127 | 169 | |
37f92f22 | 170 | ospfd> show ip ospf database |
50cc7127 | 171 | |
37f92f22 | 172 | OSPF Router with ID (10.0.0.1) |
50cc7127 | 173 | |
37f92f22 | 174 | Router Link States (Area 0.0.0.1) |
50cc7127 | 175 | |
37f92f22 QY |
176 | Link ID ADV Router Age Seq# CkSum Link count |
177 | 10.0.0.1 10.0.0.1 437 0x80000003 0xc62f 2 | |
178 | 10.0.0.2 10.0.0.2 437 0x80000003 0xe3e4 3 | |
50cc7127 | 179 | |
37f92f22 | 180 | Net Link States (Area 0.0.0.1) |
50cc7127 | 181 | |
37f92f22 QY |
182 | Link ID ADV Router Age Seq# CkSum |
183 | 10.0.0.2 10.0.0.2 442 0x80000001 0x5fcb | |
50cc7127 | 184 | |
37f92f22 | 185 | Area-Local Opaque-LSA (Area 0.0.0.1) |
50cc7127 | 186 | |
37f92f22 QY |
187 | Opaque-Type/Id ADV Router Age Seq# CkSum |
188 | 250.0.0.20 10.0.0.1 0 0x80000001 0x58a6 <=== opaque LSA | |
50cc7127 QY |
189 | |
190 | You can take a closer look at this opaque LSA: | |
191 | ||
37f92f22 | 192 | .. code-block:: console |
50cc7127 | 193 | |
37f92f22 | 194 | ospfd> show ip ospf database opaque-area |
50cc7127 | 195 | |
37f92f22 | 196 | OSPF Router with ID (10.0.0.1) |
50cc7127 QY |
197 | |
198 | ||
37f92f22 | 199 | Area-Local Opaque-LSA (Area 0.0.0.1) |
50cc7127 | 200 | |
37f92f22 QY |
201 | LS age: 4 |
202 | Options: 66 | |
203 | LS Type: Area-Local Opaque-LSA | |
204 | Link State ID: 250.0.0.20 (Area-Local Opaque-Type/ID) | |
205 | Advertising Router: 10.0.0.1 | |
206 | LS Seq Number: 80000001 | |
207 | Checksum: 0x58a6 | |
208 | Length: 24 | |
209 | Opaque-Type 250 (Private/Experimental) | |
210 | Opaque-ID 0x14 | |
211 | Opaque-Info: 4 octets of data | |
212 | Added using OSPF API: 4 octets of opaque data | |
213 | Opaque data: 1 0 0 0 <==== counter is 1 | |
50cc7127 | 214 | |
37f92f22 QY |
215 | Note that the main application updates the opaque LSA after 10 seconds, then it |
216 | looks as follows: | |
50cc7127 | 217 | |
37f92f22 | 218 | .. code-block:: console |
50cc7127 | 219 | |
37f92f22 | 220 | ospfd> show ip ospf database opaque-area |
50cc7127 | 221 | |
37f92f22 | 222 | OSPF Router with ID (10.0.0.1) |
50cc7127 QY |
223 | |
224 | ||
37f92f22 | 225 | Area-Local Opaque-LSA (Area 0.0.0.1) |
50cc7127 | 226 | |
37f92f22 QY |
227 | LS age: 1 |
228 | Options: 66 | |
229 | LS Type: Area-Local Opaque-LSA | |
230 | Link State ID: 250.0.0.20 (Area-Local Opaque-Type/ID) | |
231 | Advertising Router: 10.0.0.1 | |
232 | LS Seq Number: 80000002 | |
233 | Checksum: 0x59a3 | |
234 | Length: 24 | |
235 | Opaque-Type 250 (Private/Experimental) | |
236 | Opaque-ID 0x14 | |
237 | Opaque-Info: 4 octets of data | |
238 | Added using OSPF API: 4 octets of opaque data | |
239 | Opaque data: 2 0 0 0 <==== counter is now 2 | |
50cc7127 | 240 | |
37f92f22 | 241 | Note that the payload of the opaque LSA has changed as you can see above. |
50cc7127 | 242 | |
37f92f22 | 243 | Then, again after another 20 seconds, the opaque LSA is flushed from the LSDB. |
50cc7127 QY |
244 | |
245 | Important note: | |
246 | ^^^^^^^^^^^^^^^ | |
247 | ||
248 | In order to originate an opaque LSA, there must be at least one active | |
7c8c9c88 QY |
249 | opaque-capable neighbor. Thus, you cannot originate opaque LSAs if no neighbors |
250 | are present. If you try to originate when no neighbors are ready, you will | |
37f92f22 QY |
251 | receive a not ready error message. The reason for this restriction is that it |
252 | might be possible that some routers have an identical opaque LSA from a | |
253 | previous origination in their LSDB that unfortunately could not be flushed due | |
254 | to a crash, and now if the router comes up again and starts originating a new | |
255 | opaque LSA, the new opaque LSA is considered older since it has a lower | |
256 | sequence number and is ignored by other routers (that consider the stalled | |
257 | opaque LSA as more recent). However, if the originating router first | |
258 | synchronizes the database before originating opaque LSAs, it will detect the | |
259 | older opaque LSA and can flush it first. | |
50cc7127 QY |
260 | |
261 | Protocol and Message Formats | |
262 | ---------------------------- | |
263 | ||
37f92f22 QY |
264 | If you are developing your own client application and you don't want to make |
265 | use of the client library (due to the GNU license restriction or whatever | |
266 | reason), you can implement your own client-side message handling. The OSPF API | |
267 | uses two connections between the client and the OSPF API server: One connection | |
268 | is used for a synchronous request /reply protocol and another connection is | |
269 | used for asynchronous notifications (e.g., LSA update, neighbor status change). | |
50cc7127 QY |
270 | |
271 | Each message begins with the following header: | |
272 | ||
273 | .. figure:: ../figures/ospf_api_msghdr.png | |
274 | :alt: image | |
275 | ||
276 | image | |
277 | ||
278 | The message type field can take one of the following values: | |
279 | ||
280 | +-------------------------------+---------+ | |
56f0bea7 | 281 | | Messages to OSPF daemon | Value | |
50cc7127 QY |
282 | +===============================+=========+ |
283 | | MSG\_REGISTER\_OPAQUETYPE | 1 | | |
284 | +-------------------------------+---------+ | |
285 | | MSG\_UNREGISTER\_OPAQUETYPE | 2 | | |
286 | +-------------------------------+---------+ | |
287 | | MSG\_REGISTER\_EVENT | 3 | | |
288 | +-------------------------------+---------+ | |
289 | | MSG\_SYNC\_LSDB | 4 | | |
290 | +-------------------------------+---------+ | |
291 | | MSG\_ORIGINATE\_REQUEST | 5 | | |
292 | +-------------------------------+---------+ | |
293 | | MSG\_DELETE\_REQUEST | 6 | | |
294 | +-------------------------------+---------+ | |
295 | ||
296 | +-----------------------------+---------+ | |
56f0bea7 | 297 | | Messages from OSPF daemon | Value | |
50cc7127 QY |
298 | +=============================+=========+ |
299 | | MSG\_REPLY | 10 | | |
300 | +-----------------------------+---------+ | |
301 | | MSG\_READY\_NOTIFY | 11 | | |
302 | +-----------------------------+---------+ | |
303 | | MSG\_LSA\_UPDATE\_NOTIFY | 12 | | |
304 | +-----------------------------+---------+ | |
305 | | MSG\_LSA\_DELETE\_NOTIFY | 13 | | |
306 | +-----------------------------+---------+ | |
307 | | MSG\_NEW\_IF | 14 | | |
308 | +-----------------------------+---------+ | |
309 | | MSG\_DEL\_IF | 15 | | |
310 | +-----------------------------+---------+ | |
311 | | MSG\_ISM\_CHANGE | 16 | | |
312 | +-----------------------------+---------+ | |
313 | | MSG\_NSM\_CHANGE | 17 | | |
314 | +-----------------------------+---------+ | |
315 | ||
316 | The synchronous requests and replies have the following message formats: | |
317 | ||
318 | .. figure:: ../figures/ospf_api_msgs1.png | |
319 | :alt: image | |
320 | ||
321 | image | |
322 | ||
7c8c9c88 QY |
323 | The origin field allows origin-based filtering using the following origin |
324 | types: | |
50cc7127 QY |
325 | |
326 | +-------------------------+---------+ | |
327 | | Origin | Value | | |
328 | +=========================+=========+ | |
329 | | NON\_SELF\_ORIGINATED | 0 | | |
330 | +-------------------------+---------+ | |
331 | | SELF\_ORIGINATED | 1 | | |
332 | +-------------------------+---------+ | |
333 | | ANY\_ORIGIN | 2 | | |
334 | +-------------------------+---------+ | |
335 | ||
7c8c9c88 | 336 | The reply message has one of the following error codes: |
50cc7127 QY |
337 | |
338 | +--------------------------+---------+ | |
339 | | Error code | Value | | |
340 | +==========================+=========+ | |
341 | | API\_OK | 0 | | |
342 | +--------------------------+---------+ | |
343 | | API\_NOSUCHINTERFACE | -1 | | |
344 | +--------------------------+---------+ | |
345 | | API\_NOSUCHAREA | -2 | | |
346 | +--------------------------+---------+ | |
347 | | API\_NOSUCHLSA | -3 | | |
348 | +--------------------------+---------+ | |
349 | | API\_ILLEGALSATYPE | -4 | | |
350 | +--------------------------+---------+ | |
351 | | API\_ILLEGALOPAQUETYPE | -5 | | |
352 | +--------------------------+---------+ | |
353 | | API\_OPAQUETYPEINUSE | -6 | | |
354 | +--------------------------+---------+ | |
355 | | API\_NOMEMORY | -7 | | |
356 | +--------------------------+---------+ | |
357 | | API\_ERROR | -99 | | |
358 | +--------------------------+---------+ | |
359 | | API\_UNDEF | -100 | | |
360 | +--------------------------+---------+ | |
361 | ||
362 | The asynchronous notifications have the following message formats: | |
363 | ||
364 | .. figure:: ../figures/ospf_api_msgs2.png | |
365 | :alt: image | |
366 | ||
367 | image | |
368 | ||
7c8c9c88 QY |
369 | |
370 | .. Do not delete these acknowledgements! | |
371 | ||
50cc7127 QY |
372 | Original Acknowledgments from Ralph Keller |
373 | ------------------------------------------ | |
374 | ||
37f92f22 QY |
375 | I would like to thank Masahiko Endo, the author of the opaque LSA extension |
376 | module, for his great support. His wonderful ASCII graphs explaining the | |
377 | internal workings of this code, and his invaluable input proved to be crucial | |
378 | in designing a useful API for accessing the link state database of the OSPF | |
379 | daemon. Once, he even decided to take the plane from Tokyo to Zurich so that we | |
380 | could actually meet and have face-to-face discussions, which was a lot of fun. | |
381 | Clearly, without Masahiko no API would ever be completed. I also would like to | |
382 | thank Daniel Bauer who wrote an opaque LSA implementation too and was willing | |
50cc7127 | 383 | to test the OSPF API code in one of his projects. |