BIRD Programmer's Documentation: System dependent parts

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