Next Previous Contents

## 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_reset (void) -- reset the log buffer

### Logging

This function resets a log buffer and discards buffered messages. Should be used before a log message is prepared using logn().

### Function

void log_commit (int class) -- commit a log message

### Arguments

int class

  message class information (L_DEBUG to L_BUG, see `lib/birdlib.h`)

### 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 (char * msg, ... ...) -- log a message

### Arguments

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 logn (char * msg, ... ...) -- prepare a partial message in the log buffer

### Arguments

char * msg

  printf-like formatting string (without message class information)

... ...

  variable arguments

### Description

This function formats a message according to the format string msg and adds it to the log buffer. Messages in the log buffer are logged when the buffer is flushed using log_commit() function. The message should not contain `\n`, log_commit() also terminates a line.

### Function

void bug (char * msg, ... ...) -- report an internal error

### Arguments

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 (char * msg, ... ...) -- report a fatal error

### Arguments

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 (char * msg, ... ...) -- write to debug output

### Arguments

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.

## 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

Next Previous Contents