Zebra supports a ’FIB push’ interface that allows an external component to learn the forwarding information computed by the Quagga routing suite.
In Quagga, the Routing Information Base (RIB) resides inside
zebra. Routing protocols communicate their best routes to zebra, and
zebra computes the best route across protocols for each prefix. This
latter information makes up the Forwarding Information Base
(FIB). Zebra feeds the FIB to the kernel, which allows the IP stack in
the kernel to forward packets according to the routes computed by
Quagga. The kernel FIB is updated in an OS-specific way. For example,
netlink interface is used on Linux, and route sockets are
used on FreeBSD.
The FIB push interface aims to provide a cross-platform mechanism to support scenarios where the router has a forwarding path that is distinct from the kernel, commonly a hardware-based fast path. In these cases, the FIB needs to be maintained reliably in the fast path as well. We refer to the component that programs the forwarding plane (directly or indirectly) as the Forwarding Plane Manager or FPM.
The FIB push interface comprises of a TCP connection between zebra and the FPM. The connection is initiated by zebra – that is, the FPM acts as the TCP server.
The relevant zebra code kicks in when zebra is configured with the
--enable-fpm flag. Zebra periodically attempts to connect to
the well-known FPM port. Once the connection is up, zebra starts
sending messages containing routes over the socket to the FPM. Zebra
sends a complete copy of the forwarding table to the FPM, including
routes that it may have picked up from the kernel. The existing
interaction of zebra with the kernel remains unchanged – that is, the
kernel continues to receive FIB updates as before.
The encapsulation header for the messages exchanged with the FPM is defined by the file fpm/fpm.h in the quagga tree. The routes themselves are encoded in netlink or protobuf format, with netlink being the default.
Protobuf is one of a number of new serialization formats wherein the message schema is expressed in a purpose-built language. Code for encoding/decoding to/from the wire format is generated from the schema. Protobuf messages can be extended easily while maintaining backward-compatibility with older code. Protobuf has the following advantages over netlink:
As mentioned before, zebra encodes routes sent to the FPM in netlink
format by default. The format can be controlled via the
--fpm_format command-line option to zebra, which currently
takes the values
The zebra FPM interface uses replace semantics. That is, if a ’route add’ message for a prefix is followed by another ’route add’ message, the information in the second message is complete by itself, and replaces the information sent in the first message.
If the connection to the FPM goes down for some reason, zebra sends the FPM a complete copy of the forwarding table(s) when it reconnects.