summaryrefslogtreecommitdiffstats
path: root/doc/developer/ospf-api.rst
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-09 13:16:35 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-09 13:16:35 +0000
commite2bbf175a2184bd76f6c54ccf8456babeb1a46fc (patch)
treef0b76550d6e6f500ada964a3a4ee933a45e5a6f1 /doc/developer/ospf-api.rst
parentInitial commit. (diff)
downloadfrr-e2bbf175a2184bd76f6c54ccf8456babeb1a46fc.tar.xz
frr-e2bbf175a2184bd76f6c54ccf8456babeb1a46fc.zip
Adding upstream version 9.1.upstream/9.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'doc/developer/ospf-api.rst')
-rw-r--r--doc/developer/ospf-api.rst383
1 files changed, 383 insertions, 0 deletions
diff --git a/doc/developer/ospf-api.rst b/doc/developer/ospf-api.rst
new file mode 100644
index 0000000..41c31b2
--- /dev/null
+++ b/doc/developer/ospf-api.rst
@@ -0,0 +1,383 @@
+OSPF API Documentation
+======================
+
+Disclaimer
+----------
+
+The OSPF daemon contains an API for application access to the LSA database.
+This API and documentation was created by Ralph Keller, originally as patch for
+Zebra. Unfortunately, the page containing documentation for the API is no
+longer online. This page is an attempt to recreate documentation for the API
+(with lots of help from the WayBackMachine).
+
+Ralph has kindly licensed this documentation under GPLv2+. Please preserve the
+acknowledgements at the bottom of this document.
+
+Introduction
+------------
+
+This page describes an API that allows external applications to access the
+link-state database (LSDB) of the OSPF daemon. The implementation is based on
+the OSPF code from FRRouting (forked from Quagga and formerly Zebra) routing
+protocol suite and is subject to the GNU General Public License. The OSPF API
+provides you with the following functionality:
+
+- Retrieval of the full or partial link-state database of the OSPF daemon.
+ This allows applications to obtain an exact copy of the LSDB including router
+ LSAs, network LSAs and so on. Whenever a new LSA arrives at the OSPF daemon,
+ the API module immediately informs the application by sending a message. This
+ way, the application is always synchronized with the LSDB of the OSPF daemon.
+- Origination of own opaque LSAs (of type 9, 10, or 11) which are then
+ distributed transparently to other routers within the flooding scope and
+ received by other applications through the OSPF API.
+
+Opaque LSAs, which are described in :rfc:`2370`, allow you to distribute
+application-specific information within a network using the OSPF protocol. The
+information contained in opaque LSAs is transparent for the routing process but
+it can be processed by other modules such as traffic engineering (e.g.,
+MPLS-TE).
+
+Architecture
+------------
+
+The following picture depicts the architecture of the Quagga/Zebra protocol
+suite. The OSPF daemon is extended with opaque LSA capabilities and an API for
+external applications. The OSPF core module executes the OSPF protocol by
+discovering neighbors and exchanging neighbor state. The opaque module,
+implemented by Masahiko Endo, provides functions to exchange opaque LSAs
+between routers. Opaque LSAs can be generated by several modules such as the
+MPLS-TE module or the API server module. These modules then invoke the opaque
+module to flood their data to neighbors within the flooding scope.
+
+The client, which is an application potentially running on a different node
+than the OSPF daemon, links against the OSPF API client library. This client
+library establishes a socket connection with the API server module of the OSPF
+daemon and uses this connection to retrieve LSAs and originate opaque LSAs.
+
+.. figure:: ../figures/ospf_api_architecture.png
+ :alt: image
+
+ image
+
+The OSPF API server module works like any other internal opaque module (such as
+the MPLS-TE module), but listens to connections from external applications that
+want to communicate with the OSPF daemon. The API server module can handle
+multiple clients concurrently.
+
+One of the main objectives of the implementation is to make as little changes
+to the existing Zebra code as possible.
+
+Installation & Configuration
+----------------------------
+
+Download FRRouting and unpack it.
+
+Configure and build FRR (note that ``--enable-opaque-lsa`` also enables the
+ospfapi server and ospfclient).
+
+::
+
+ % sh ./configure --enable-opaque-lsa
+ % make
+
+This should also compile the client library and sample application in
+ospfclient.
+
+Make sure that you have enabled opaque LSAs in your configuration. Add the
+``ospf opaque-lsa`` statement to your :file:`ospfd.conf`:
+
+::
+
+ ! -*- ospf -*-
+ !
+ ! OSPFd sample configuration file
+ !
+ !
+ hostname xxxxx
+ password xxxxx
+
+ router ospf
+ router-id 10.0.0.1
+ network 10.0.0.1/24 area 1
+ neighbor 10.0.0.2
+ network 10.0.1.2/24 area 1
+ neighbor 10.0.1.1
+ ospf opaque-lsa <============ add this statement!
+
+Usage
+-----
+
+In the following we describe how you can use the sample application to
+originate opaque LSAs. The sample application first registers with the OSPF
+daemon the opaque type it wants to inject and then waits until the OSPF daemon
+is ready to accept opaque LSAs of that type. Then the client application
+originates an opaque LSA, waits 10 seconds and then updates the opaque LSA with
+new opaque data. After another 20 seconds, the client application deletes the
+opaque LSA from the LSDB. If the clients terminates unexpectedly, the OSPF API
+module will remove all the opaque LSAs that the application registered. Since
+the opaque LSAs are flooded to other routers, we will see the opaque LSAs in
+all routers according to the flooding scope of the opaque LSA.
+
+We have a very simple demo setup, just two routers connected with an ATM
+point-to-point link. Start the modified OSPF daemons on two adjacent routers.
+First run on msr2:
+
+.. code-block:: console
+
+ # ./ospfd --apiserver -f /usr/local/etc/ospfd.conf
+
+And on the neighboring router msr3:
+
+.. code-block:: console
+
+ # ./ospfd --apiserver -f /usr/local/etc/ospfd.conf
+
+Now the two routers form adjacency and start exchanging their databases.
+Looking at the OSPF daemon of msr2 (or msr3), you see this:
+
+.. code-block:: console
+
+ ospfd> show ip ospf database
+
+ OSPF Router with ID (10.0.0.1)
+
+ Router Link States (Area 0.0.0.1)
+
+ Link ID ADV Router Age Seq# CkSum Link count
+ 10.0.0.1 10.0.0.1 55 0x80000003 0xc62f 2
+ 10.0.0.2 10.0.0.2 55 0x80000003 0xe3e4 3
+
+ Net Link States (Area 0.0.0.1)
+
+ Link ID ADV Router Age Seq# CkSum
+ 10.0.0.2 10.0.0.2 60 0x80000001 0x5fcb
+
+Now we start the sample main application that originates an opaque LSA.
+
+.. code-block:: console
+
+ # cd ospfapi/apiclient
+ # ./main msr2 10 250 20 0.0.0.0 0.0.0.1
+
+This originates an opaque LSA of type 10 (area local), with opaque type 250
+(experimental), opaque id of 20 (chosen arbitrarily), interface address 0.0.0.0
+(which is used only for opaque LSAs type 9), and area 0.0.0.1
+
+Again looking at the OSPF database you see:
+
+.. code-block:: console
+
+ ospfd> show ip ospf database
+
+ OSPF Router with ID (10.0.0.1)
+
+ Router Link States (Area 0.0.0.1)
+
+ Link ID ADV Router Age Seq# CkSum Link count
+ 10.0.0.1 10.0.0.1 437 0x80000003 0xc62f 2
+ 10.0.0.2 10.0.0.2 437 0x80000003 0xe3e4 3
+
+ Net Link States (Area 0.0.0.1)
+
+ Link ID ADV Router Age Seq# CkSum
+ 10.0.0.2 10.0.0.2 442 0x80000001 0x5fcb
+
+ Area-Local Opaque-LSA (Area 0.0.0.1)
+
+ Opaque-Type/Id ADV Router Age Seq# CkSum
+ 250.0.0.20 10.0.0.1 0 0x80000001 0x58a6 <=== opaque LSA
+
+You can take a closer look at this opaque LSA:
+
+.. code-block:: console
+
+ ospfd> show ip ospf database opaque-area
+
+ OSPF Router with ID (10.0.0.1)
+
+
+ Area-Local Opaque-LSA (Area 0.0.0.1)
+
+ LS age: 4
+ Options: 66
+ LS Type: Area-Local Opaque-LSA
+ Link State ID: 250.0.0.20 (Area-Local Opaque-Type/ID)
+ Advertising Router: 10.0.0.1
+ LS Seq Number: 80000001
+ Checksum: 0x58a6
+ Length: 24
+ Opaque-Type 250 (Private/Experimental)
+ Opaque-ID 0x14
+ Opaque-Info: 4 octets of data
+ Added using OSPF API: 4 octets of opaque data
+ Opaque data: 1 0 0 0 <==== counter is 1
+
+Note that the main application updates the opaque LSA after 10 seconds, then it
+looks as follows:
+
+.. code-block:: console
+
+ ospfd> show ip ospf database opaque-area
+
+ OSPF Router with ID (10.0.0.1)
+
+
+ Area-Local Opaque-LSA (Area 0.0.0.1)
+
+ LS age: 1
+ Options: 66
+ LS Type: Area-Local Opaque-LSA
+ Link State ID: 250.0.0.20 (Area-Local Opaque-Type/ID)
+ Advertising Router: 10.0.0.1
+ LS Seq Number: 80000002
+ Checksum: 0x59a3
+ Length: 24
+ Opaque-Type 250 (Private/Experimental)
+ Opaque-ID 0x14
+ Opaque-Info: 4 octets of data
+ Added using OSPF API: 4 octets of opaque data
+ Opaque data: 2 0 0 0 <==== counter is now 2
+
+Note that the payload of the opaque LSA has changed as you can see above.
+
+Then, again after another 20 seconds, the opaque LSA is flushed from the LSDB.
+
+Important note:
+^^^^^^^^^^^^^^^
+
+In order to originate an opaque LSA, there must be at least one active
+opaque-capable neighbor. Thus, you cannot originate opaque LSAs if no neighbors
+are present. If you try to originate when no neighbors are ready, you will
+receive a not ready error message. The reason for this restriction is that it
+might be possible that some routers have an identical opaque LSA from a
+previous origination in their LSDB that unfortunately could not be flushed due
+to a crash, and now if the router comes up again and starts originating a new
+opaque LSA, the new opaque LSA is considered older since it has a lower
+sequence number and is ignored by other routers (that consider the stalled
+opaque LSA as more recent). However, if the originating router first
+synchronizes the database before originating opaque LSAs, it will detect the
+older opaque LSA and can flush it first.
+
+Protocol and Message Formats
+----------------------------
+
+If you are developing your own client application and you don't want to make
+use of the client library (due to the GNU license restriction or whatever
+reason), you can implement your own client-side message handling. The OSPF API
+uses two connections between the client and the OSPF API server: One connection
+is used for a synchronous request /reply protocol and another connection is
+used for asynchronous notifications (e.g., LSA update, neighbor status change).
+
+Each message begins with the following header:
+
+.. figure:: ../figures/ospf_api_msghdr.png
+ :alt: image
+
+ image
+
+The message type field can take one of the following values:
+
++-------------------------------+---------+
+| Messages to OSPF daemon | Value |
++===============================+=========+
+| MSG\_REGISTER\_OPAQUETYPE | 1 |
++-------------------------------+---------+
+| MSG\_UNREGISTER\_OPAQUETYPE | 2 |
++-------------------------------+---------+
+| MSG\_REGISTER\_EVENT | 3 |
++-------------------------------+---------+
+| MSG\_SYNC\_LSDB | 4 |
++-------------------------------+---------+
+| MSG\_ORIGINATE\_REQUEST | 5 |
++-------------------------------+---------+
+| MSG\_DELETE\_REQUEST | 6 |
++-------------------------------+---------+
+
++-----------------------------+---------+
+| Messages from OSPF daemon | Value |
++=============================+=========+
+| MSG\_REPLY | 10 |
++-----------------------------+---------+
+| MSG\_READY\_NOTIFY | 11 |
++-----------------------------+---------+
+| MSG\_LSA\_UPDATE\_NOTIFY | 12 |
++-----------------------------+---------+
+| MSG\_LSA\_DELETE\_NOTIFY | 13 |
++-----------------------------+---------+
+| MSG\_NEW\_IF | 14 |
++-----------------------------+---------+
+| MSG\_DEL\_IF | 15 |
++-----------------------------+---------+
+| MSG\_ISM\_CHANGE | 16 |
++-----------------------------+---------+
+| MSG\_NSM\_CHANGE | 17 |
++-----------------------------+---------+
+
+The synchronous requests and replies have the following message formats:
+
+.. figure:: ../figures/ospf_api_msgs1.png
+ :alt: image
+
+ image
+
+The origin field allows origin-based filtering using the following origin
+types:
+
++-------------------------+---------+
+| Origin | Value |
++=========================+=========+
+| NON\_SELF\_ORIGINATED | 0 |
++-------------------------+---------+
+| SELF\_ORIGINATED | 1 |
++-------------------------+---------+
+| ANY\_ORIGIN | 2 |
++-------------------------+---------+
+
+The reply message has one of the following error codes:
+
++--------------------------+---------+
+| Error code | Value |
++==========================+=========+
+| API\_OK | 0 |
++--------------------------+---------+
+| API\_NOSUCHINTERFACE | -1 |
++--------------------------+---------+
+| API\_NOSUCHAREA | -2 |
++--------------------------+---------+
+| API\_NOSUCHLSA | -3 |
++--------------------------+---------+
+| API\_ILLEGALSATYPE | -4 |
++--------------------------+---------+
+| API\_ILLEGALOPAQUETYPE | -5 |
++--------------------------+---------+
+| API\_OPAQUETYPEINUSE | -6 |
++--------------------------+---------+
+| API\_NOMEMORY | -7 |
++--------------------------+---------+
+| API\_ERROR | -99 |
++--------------------------+---------+
+| API\_UNDEF | -100 |
++--------------------------+---------+
+
+The asynchronous notifications have the following message formats:
+
+.. figure:: ../figures/ospf_api_msgs2.png
+ :alt: image
+
+ image
+
+
+.. Do not delete these acknowledgements!
+
+Original Acknowledgments from Ralph Keller
+------------------------------------------
+
+I would like to thank Masahiko Endo, the author of the opaque LSA extension
+module, for his great support. His wonderful ASCII graphs explaining the
+internal workings of this code, and his invaluable input proved to be crucial
+in designing a useful API for accessing the link state database of the OSPF
+daemon. Once, he even decided to take the plane from Tokyo to Zurich so that we
+could actually meet and have face-to-face discussions, which was a lot of fun.
+Clearly, without Masahiko no API would ever be completed. I also would like to
+thank Daniel Bauer who wrote an opaque LSA implementation too and was willing
+to test the OSPF API code in one of his projects.