1OSPF API Documentation 2====================== 3 4Disclaimer 5---------- 6 7The OSPF daemon contains an API for application access to the LSA database. 8This API and documentation was created by Ralph Keller, originally as patch for 9Zebra. Unfortunately, the page containing documentation for the API is no 10longer online. This page is an attempt to recreate documentation for the API 11(with lots of help from the WayBackMachine). 12 13Ralph has kindly licensed this documentation under GPLv2+. Please preserve the 14acknowledgements at the bottom of this document. 15 16Introduction 17------------ 18 19This page describes an API that allows external applications to access the 20link-state database (LSDB) of the OSPF daemon. The implementation is based on 21the OSPF code from FRRouting (forked from Quagga and formerly Zebra) routing 22protocol suite and is subject to the GNU General Public License. The OSPF API 23provides 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 34Opaque LSAs, which are described in :rfc:`2370`, allow you to distribute 35application-specific information within a network using the OSPF protocol. The 36information contained in opaque LSAs is transparent for the routing process but 37it can be processed by other modules such as traffic engineering (e.g., 38MPLS-TE). 39 40Architecture 41------------ 42 43The following picture depicts the architecture of the Quagga/Zebra protocol 44suite. The OSPF daemon is extended with opaque LSA capabilities and an API for 45external applications. The OSPF core module executes the OSPF protocol by 46discovering neighbors and exchanging neighbor state. The opaque module, 47implemented by Masahiko Endo, provides functions to exchange opaque LSAs 48between routers. Opaque LSAs can be generated by several modules such as the 49MPLS-TE module or the API server module. These modules then invoke the opaque 50module to flood their data to neighbors within the flooding scope. 51 52The client, which is an application potentially running on a different node 53than the OSPF daemon, links against the OSPF API client library. This client 54library establishes a socket connection with the API server module of the OSPF 55daemon and uses this connection to retrieve LSAs and originate opaque LSAs. 56 57.. figure:: ../figures/ospf_api_architecture.png 58 :alt: image 59 60 image 61 62The OSPF API server module works like any other internal opaque module (such as 63the MPLS-TE module), but listens to connections from external applications that 64want to communicate with the OSPF daemon. The API server module can handle 65multiple clients concurrently. 66 67One of the main objectives of the implementation is to make as little changes 68to the existing Zebra code as possible. 69 70Installation & Configuration 71---------------------------- 72 73Download FRRouting and unpack it. 74 75Configure and build FRR (note that ``--enable-opaque-lsa`` also enables the 76ospfapi server and ospfclient). 77 78:: 79 80 % sh ./configure --enable-opaque-lsa 81 % make 82 83This should also compile the client library and sample application in 84ospfclient. 85 86Make sure that you have enabled opaque LSAs in your configuration. Add the 87``ospf opaque-lsa`` statement to your :file:`ospfd.conf`: 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 107Usage 108----- 109 110In the following we describe how you can use the sample application to 111originate opaque LSAs. The sample application first registers with the OSPF 112daemon the opaque type it wants to inject and then waits until the OSPF daemon 113is ready to accept opaque LSAs of that type. Then the client application 114originates an opaque LSA, waits 10 seconds and then updates the opaque LSA with 115new opaque data. After another 20 seconds, the client application deletes the 116opaque LSA from the LSDB. If the clients terminates unexpectedly, the OSPF API 117module will remove all the opaque LSAs that the application registered. Since 118the opaque LSAs are flooded to other routers, we will see the opaque LSAs in 119all routers according to the flooding scope of the opaque LSA. 120 121We have a very simple demo setup, just two routers connected with an ATM 122point-to-point link. Start the modified OSPF daemons on two adjacent routers. 123First run on msr2: 124 125.. code-block:: console 126 127 # ./ospfd --apiserver -f /usr/local/etc/ospfd.conf 128 129And on the neighboring router msr3: 130 131.. code-block:: console 132 133 # ./ospfd --apiserver -f /usr/local/etc/ospfd.conf 134 135Now the two routers form adjacency and start exchanging their databases. 136Looking at the OSPF daemon of msr2 (or msr3), you see this: 137 138.. code-block:: console 139 140 ospfd> show ip ospf database 141 142 OSPF Router with ID (10.0.0.1) 143 144 Router Link States (Area 0.0.0.1) 145 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 149 150 Net Link States (Area 0.0.0.1) 151 152 Link ID ADV Router Age Seq# CkSum 153 10.0.0.2 10.0.0.2 60 0x80000001 0x5fcb 154 155Now we start the sample main application that originates an opaque LSA. 156 157.. code-block:: console 158 159 # cd ospfapi/apiclient 160 # ./main msr2 10 250 20 0.0.0.0 0.0.0.1 161 162This 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 165 166Again looking at the OSPF database you see: 167 168.. code-block:: console 169 170 ospfd> show ip ospf database 171 172 OSPF Router with ID (10.0.0.1) 173 174 Router Link States (Area 0.0.0.1) 175 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 179 180 Net Link States (Area 0.0.0.1) 181 182 Link ID ADV Router Age Seq# CkSum 183 10.0.0.2 10.0.0.2 442 0x80000001 0x5fcb 184 185 Area-Local Opaque-LSA (Area 0.0.0.1) 186 187 Opaque-Type/Id ADV Router Age Seq# CkSum 188 250.0.0.20 10.0.0.1 0 0x80000001 0x58a6 <=== opaque LSA 189 190You can take a closer look at this opaque LSA: 191 192.. code-block:: console 193 194 ospfd> show ip ospf database opaque-area 195 196 OSPF Router with ID (10.0.0.1) 197 198 199 Area-Local Opaque-LSA (Area 0.0.0.1) 200 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 214 215Note that the main application updates the opaque LSA after 10 seconds, then it 216looks as follows: 217 218.. code-block:: console 219 220 ospfd> show ip ospf database opaque-area 221 222 OSPF Router with ID (10.0.0.1) 223 224 225 Area-Local Opaque-LSA (Area 0.0.0.1) 226 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 240 241Note that the payload of the opaque LSA has changed as you can see above. 242 243Then, again after another 20 seconds, the opaque LSA is flushed from the LSDB. 244 245Important note: 246^^^^^^^^^^^^^^^ 247 248In order to originate an opaque LSA, there must be at least one active 249opaque-capable neighbor. Thus, you cannot originate opaque LSAs if no neighbors 250are present. If you try to originate when no neighbors are ready, you will 251receive a not ready error message. The reason for this restriction is that it 252might be possible that some routers have an identical opaque LSA from a 253previous origination in their LSDB that unfortunately could not be flushed due 254to a crash, and now if the router comes up again and starts originating a new 255opaque LSA, the new opaque LSA is considered older since it has a lower 256sequence number and is ignored by other routers (that consider the stalled 257opaque LSA as more recent). However, if the originating router first 258synchronizes the database before originating opaque LSAs, it will detect the 259older opaque LSA and can flush it first. 260 261Protocol and Message Formats 262---------------------------- 263 264If you are developing your own client application and you don't want to make 265use of the client library (due to the GNU license restriction or whatever 266reason), you can implement your own client-side message handling. The OSPF API 267uses two connections between the client and the OSPF API server: One connection 268is used for a synchronous request /reply protocol and another connection is 269used for asynchronous notifications (e.g., LSA update, neighbor status change). 270 271Each message begins with the following header: 272 273.. figure:: ../figures/ospf_api_msghdr.png 274 :alt: image 275 276 image 277 278The message type field can take one of the following values: 279 280+-------------------------------+---------+ 281| Messages to OSPF daemon | Value | 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+-----------------------------+---------+ 297| Messages from OSPF daemon | Value | 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 316The synchronous requests and replies have the following message formats: 317 318.. figure:: ../figures/ospf_api_msgs1.png 319 :alt: image 320 321 image 322 323The origin field allows origin-based filtering using the following origin 324types: 325 326+-------------------------+---------+ 327| Origin | Value | 328+=========================+=========+ 329| NON\_SELF\_ORIGINATED | 0 | 330+-------------------------+---------+ 331| SELF\_ORIGINATED | 1 | 332+-------------------------+---------+ 333| ANY\_ORIGIN | 2 | 334+-------------------------+---------+ 335 336The reply message has one of the following error codes: 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 362The asynchronous notifications have the following message formats: 363 364.. figure:: ../figures/ospf_api_msgs2.png 365 :alt: image 366 367 image 368 369 370.. Do not delete these acknowledgements! 371 372Original Acknowledgments from Ralph Keller 373------------------------------------------ 374 375I would like to thank Masahiko Endo, the author of the opaque LSA extension 376module, for his great support. His wonderful ASCII graphs explaining the 377internal workings of this code, and his invaluable input proved to be crucial 378in designing a useful API for accessing the link state database of the OSPF 379daemon. Once, he even decided to take the plane from Tokyo to Zurich so that we 380could actually meet and have face-to-face discussions, which was a lot of fun. 381Clearly, without Masahiko no API would ever be completed. I also would like to 382thank Daniel Bauer who wrote an opaque LSA implementation too and was willing 383to test the OSPF API code in one of his projects. 384