summaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
authorQuentin Young <qlyoung@cumulusnetworks.com>2019-04-22 22:22:00 +0200
committerQuentin Young <qlyoung@cumulusnetworks.com>2019-04-22 22:22:00 +0200
commit37f92f2215ff00eb7d5c9ed4a7f8b980018d46c2 (patch)
treef54f7021c25328da7798164db533fb20af336b8f /doc
parentMerge pull request #3786 from mjstapp/dplane_intf (diff)
downloadfrr-37f92f2215ff00eb7d5c9ed4a7f8b980018d46c2.tar.xz
frr-37f92f2215ff00eb7d5c9ed4a7f8b980018d46c2.zip
doc: cleanup OSPF API server documentation
* Reflow to 80 columns * Improve markup * Add --apiserver option to example ospfd invocations * Add note on requirement of this option to use api server Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Diffstat (limited to 'doc')
-rw-r--r--doc/developer/ospf-api.rst325
-rw-r--r--doc/user/ospfd.rst2
2 files changed, 158 insertions, 169 deletions
diff --git a/doc/developer/ospf-api.rst b/doc/developer/ospf-api.rst
index f4f38a63e..a219b58f5 100644
--- a/doc/developer/ospf-api.rst
+++ b/doc/developer/ospf-api.rst
@@ -4,76 +4,73 @@ OSPF API Documentation
Disclaimer
----------
-The OSPF daemon contains an API for application access to the LSA
-database. This API was created by Ralph Keller, originally as patch for
-Zebra. Unfortunately, the page containing documentation of the API is no
-longer online. This page is an attempt to recreate documentation for the
-API (with lots of help of the WayBackMachine)
+The OSPF daemon contains an API for application access to the LSA database.
+This API was created by Ralph Keller, originally as patch for Zebra.
+Unfortunately, the page containing documentation of the API is no longer
+online. This page is an attempt to recreate documentation for the API (with
+lots of help of the WayBackMachine)
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).
+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.
+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.
+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.
+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
+Download FRRouting and unpack it.
-Configure your frr version (note that --enable-opaque-lsa also enables
-the ospfapi server and ospfclient).
+Configure and build FRR (note that ``--enable-opaque-lsa`` also enables the
+ospfapi server and ospfclient).
::
@@ -83,8 +80,8 @@ the ospfapi server and ospfclient).
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 ospfd.conf:
+Make sure that you have enabled opaque LSAs in your configuration. Add the
+``ospf opaque-lsa`` statement to your :file:`ospfd.conf`:
::
@@ -108,171 +105,165 @@ 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.
+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:
+point-to-point link. Start the modified OSPF daemons on two adjacent routers.
+First run on msr2:
-::
+.. code-block:: console
- > msr2:/home/keller/ospfapi/zebra/ospfd# ./ospfd -f /usr/local/etc/ospfd.conf
+ # ./ospfd --apiserver -f /usr/local/etc/ospfd.conf
And on the neighboring router msr3:
-::
+.. code-block:: console
- > msr3:/home/keller/ospfapi/zebra/ospfd# ./ospfd -f /usr/local/etc/ospfd.conf
+ # ./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
+ ospfd> show ip ospf database
- OSPF Router with ID (10.0.0.1)
+ OSPF Router with ID (10.0.0.1)
- Router Link States (Area 0.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
+ 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)
+ 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
+ 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
+ # 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
+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
+ ospfd> show ip ospf database
- OSPF Router with ID (10.0.0.1)
+ OSPF Router with ID (10.0.0.1)
- Router Link States (Area 0.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
+ 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)
+ 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
+ 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)
+ 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
+ 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
+ ospfd> show ip ospf database opaque-area
- OSPF Router with ID (10.0.0.1)
+ OSPF Router with ID (10.0.0.1)
- Area-Local Opaque-LSA (Area 0.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
+ 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:
+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
+ ospfd> show ip ospf database opaque-area
- OSPF Router with ID (10.0.0.1)
+ OSPF Router with ID (10.0.0.1)
- Area-Local Opaque-LSA (Area 0.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
+ 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.
+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.
+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 of no
-neighbors are present. If you try to originate even so no neighbor is
-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.
+opaque-capable neighbor. Thus, you cannot originate opaque LSAs of no neighbors
+are present. If you try to originate even so no neighbor is 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).
+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:
@@ -326,8 +317,7 @@ The synchronous requests and replies have the following message formats:
image
-The origin field allows to select according to the following types of
-origins:
+The origin field allows to select according to the following types of origins:
+-------------------------+---------+
| Origin | Value |
@@ -375,13 +365,12 @@ The asynchronous notifications have the following message formats:
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
+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.
diff --git a/doc/user/ospfd.rst b/doc/user/ospfd.rst
index ad0a8639a..83e14d474 100644
--- a/doc/user/ospfd.rst
+++ b/doc/user/ospfd.rst
@@ -26,7 +26,7 @@ Configuring OSPF
.. option:: -a, --apiserver
- Enable the OSPF API server
+ Enable the OSPF API server. This is required to use ``ospfclient``.
*ospfd* must acquire interface information from *zebra* in order to function.
Therefore *zebra* must be running before invoking *ospfd*. Also, if *zebra* is