6. System dependent parts
6.1 Introduction
We've tried to make BIRD as portable as possible, but unfortunately communication with the network stack differs from one OS to another, so we need at least some OS specific code. The good news is that this code is isolated in a small set of modules:
config.h
is a header file with configuration information, definition of the standard set of types and so on.
- Startup module
controls BIRD startup. Common for a family of OS's (e.g., for all Unices).
- Logging module
manages the system logs. [per OS family]
- IO module
gives an implementation of sockets, timers and the global event queue. [per OS family]
- KRT module
implements the Kernel and Device protocols. This is the most arcane part of the system dependent stuff and some functions differ even between various releases of a single OS.
6.2 Logging
The Logging module offers a simple set of functions for writing
messages to system logs and to the debug output. Message classes
used by this module are described in birdlib.h
and also in the
user's manual.
Function
void log_commit (log_buffer * buf) -- commit a log message
Arguments
- log_buffer * buf
message to write
Description
This function writes a message prepared in the log buffer to the log file (as specified in the configuration). The log buffer is reset after that. The log message is a full line, log_commit() terminates it.
The message class is an integer, not a first char of a string like in log(), so it should be written like *L_INFO.
Function
void log_msg (const char * msg, ... ...) -- log a message
Arguments
- const char * msg
printf-like formatting string with message class information prepended (L_DEBUG to L_BUG, see
lib/birdlib.h
)- ... ...
variable arguments
Description
This function formats a message according to the format string msg
and writes it to the corresponding log file (as specified in the
configuration). Please note that the message is automatically
formatted as a full line, no need to include n
inside.
It is essentially a sequence of log_reset(), logn() and log_commit().
Function
void bug (const char * msg, ... ...) -- report an internal error
Arguments
- const char * msg
a printf-like error message
- ... ...
variable arguments
Description
This function logs an internal error and aborts execution of the program.
Function
void die (const char * msg, ... ...) -- report a fatal error
Arguments
- const char * msg
a printf-like error message
- ... ...
variable arguments
Description
This function logs a fatal error and aborts execution of the program.
Function
void debug (const char * msg, ... ...) -- write to debug output
Arguments
- const char * msg
a printf-like message
- ... ...
variable arguments
Description
This function formats the message msg and prints it out to the debugging output. No newline character is appended.
Function
void debug_safe (const char * msg) -- async-safe write to debug output
Arguments
- const char * msg
a string message
Description
This function prints the message msg to the debugging output in a way that is async safe and can be used in signal handlers. No newline character is appended.
6.3 Kernel synchronization
This system dependent module implements the Kernel and Device protocol, that is synchronization of interface lists and routing tables with the OS kernel.
The whole kernel synchronization is a bit messy and touches some internals of the routing table engine, because routing table maintenance is a typical example of the proverbial compatibility between different Unices and we want to keep the overhead of our KRT business as low as possible and avoid maintaining a local routing table copy.
The kernel syncer can work in three different modes (according to system config header): Either with a single routing table and single KRT protocol [traditional UNIX] or with many routing tables and separate KRT protocols for all of them or with many routing tables, but every scan including all tables, so we start separate KRT protocols which cooperate with each other [Linux]. In this case, we keep only a single scan timer.
We use FIB node flags in the routing table to keep track of route synchronization status. We also attach temporary rte's to the routing table, but it cannot do any harm to the rest of BIRD since table synchronization is an atomic process.
When starting up, we cheat by looking if there is another KRT instance to be initialized later and performing table scan only once for all the instances.
The code uses OS-dependent parts for kernel updates and scans. These parts are in more specific sysdep directories (e.g. sysdep/linux) in functions krt_sys_* and kif_sys_* (and some others like krt_replace_rte()) and krt-sys.h header file. This is also used for platform specific protocol options and route attributes.
There was also an old code that used traditional UNIX ioctls for these tasks. It was unmaintained and later removed. For reference, see sysdep/krt-* files in commit 396dfa9042305f62da1f56589c4b98fac57fc2f6
Function
int krt_assume_onlink (struct iface * iface, int ipv6) -- check if routes on interface are considered onlink
Arguments
- struct iface * iface
The interface of the next hop
- int ipv6
Switch to only consider IPv6 or IPv4 addresses.
Description
The BSD kernel does not support an onlink flag. If the interface has only host addresses configured, all routes should be considered as onlink and the function returns 1. This is used when CONFIG_ASSUME_ONLINK is set.
Next Previous Contents