Next Previous Contents

2. Core

2.1 Forwarding Information Base

FIB is a data structure designed for storage of routes indexed by their network prefixes. It supports insertion, deletion, searching by prefix, `routing' (in CIDR sense, that is searching for a longest prefix matching a given IP address) and (which makes the structure very tricky to implement) asynchronous reading, that is enumerating the contents of a FIB while other modules add, modify or remove entries.

Internally, each FIB is represented as a collection of nodes of type fib_node indexed using a sophisticated hashing mechanism. We use two-stage hashing where we calculate a 16-bit primary hash key independent on hash table size and then we just divide the primary keys modulo table size to get a real hash key used for determining the bucket containing the node. The lists of nodes in each bucket are sorted according to the primary hash key, hence if we keep the total number of buckets to be a power of two, re-hashing of the structure keeps the relative order of the nodes.

To get the asynchronous reading consistent over node deletions, we need to keep a list of readers for each node. When a node gets deleted, its readers are automatically moved to the next node in the table.

Basic FIB operations are performed by functions defined by this module, enumerating of FIB contents is accomplished by using the FIB_WALK() macro or FIB_ITERATE_START() if you want to do it asynchronously.


Function

void fib_init (struct fib * f, pool * p, unsigned node_size, unsigned hash_order, fib_init_func init) -- initialize a new FIB

Arguments

struct fib * f

the FIB to be initialized (the structure itself being allocated by the caller)

pool * p

pool to allocate the nodes in

unsigned node_size

node size to be used (each node consists of a standard header fib_node followed by user data)

unsigned hash_order

initial hash order (a binary logarithm of hash table size), 0 to use default order (recommended)

fib_init_func init

pointer a function to be called to initialize a newly created node

Description

This function initializes a newly allocated FIB and prepares it for use.


Function

void * fib_find (struct fib * f, ip_addr * a, int len) -- search for FIB node by prefix

Arguments

struct fib * f

FIB to search in

ip_addr * a

pointer to IP address of the prefix

int len

prefix length

Description

Search for a FIB node corresponding to the given prefix, return a pointer to it or NULL if no such node exists.


Function

void * fib_get (struct fib * f, ip_addr * a, int len) -- find or create a FIB node

Arguments

struct fib * f

FIB to work with

ip_addr * a

pointer to IP address of the prefix

int len

prefix length

Description

Search for a FIB node corresponding to the given prefix and return a pointer to it. If no such node exists, create it.


Function

void * fib_route (struct fib * f, ip_addr a, int len) -- CIDR routing lookup

Arguments

struct fib * f

FIB to search in

ip_addr a

pointer to IP address of the prefix

int len

prefix length

Description

Search for a FIB node with longest prefix matching the given network, that is a node which a CIDR router would use for routing that network.


Function

void fib_delete (struct fib * f, void * E) -- delete a FIB node

Arguments

struct fib * f

FIB to delete from

void * E

entry to delete

Description

This function removes the given entry from the FIB, taking care of all the asynchronous readers by shifting them to the next node in the canonical reading order.


Function

void fib_free (struct fib * f) -- delete a FIB

Arguments

struct fib * f

FIB to be deleted

Description

This function deletes a FIB -- it frees all memory associated with it and all its entries.


Function

void fib_check (struct fib * f) -- audit a FIB

Arguments

struct fib * f

FIB to be checked

Description

This debugging function audits a FIB by checking its internal consistency. Use when you suspect somebody of corrupting innocent data structures.

2.2 Routing tables

Routing tables are probably the most important structures BIRD uses. They hold all the information about known networks, the associated routes and their attributes.

There are multiple routing tables (a primary one together with any number of secondary ones if requested by the configuration). Each table is basically a FIB containing entries describing the individual destination networks. For each network (represented by structure net), there is a one-way linked list of route entries (rte), the first entry on the list being the best one (i.e., the one we currently use for routing), the order of the other ones is undetermined.

The rte contains information specific to the route (preference, protocol metrics, time of last modification etc.) and a pointer to a rta structure (see the route attribute module for a precise explanation) holding the remaining route attributes which are expected to be shared by multiple routes in order to conserve memory.


Function

rte * rte_find (net * net, struct proto * p) -- find a route

Arguments

net * net

network node

struct proto * p

protocol

Description

The rte_find() function returns a route for destination net which belongs has been defined by protocol p.


Function

rte * rte_get_temp (rta * a) -- get a temporary rte

Arguments

rta * a

attributes to assign to the new route (a rta; in case it's un-cached, rte_update() will create a cached copy automatically)

Description

Create a temporary rte and bind it with the attributes a. Also set route preference to the default preference set for the protocol.


Function

void rte_announce (rtable * tab, net * net, rte * new, rte * old, ea_list * tmpa) -- announce a routing table change

Arguments

rtable * tab

table the route has been added to

net * net

network in question

rte * new

the new route to be announced

rte * old

previous optimal route for the same network

ea_list * tmpa

a list of temporary attributes belonging to the new route

Description

This function gets a routing table update and announces it to all protocols connected to the same table by their announcement hooks.

For each such protocol, we first call its import_control() hook which performs basic checks on the route (each protocol has a right to veto or force accept of the route before any filter is asked) and adds default values of attributes specific to the new protocol (metrics, tags etc.). Then it consults the protocol's export filter and if it accepts the route, the rt_notify() hook of the protocol gets called.


Function

void rte_free (rte * e) -- delete a rte

Arguments

rte * e

rte to be deleted

Description

rte_free() deletes the given rte from the routing table it's linked to.


Function

void rte_update (rtable * table, net * net, struct proto * p, rte * new) -- enter a new update to a routing table

Arguments

rtable * table

table to be updated

net * net

network node

struct proto * p

protocol submitting the update

rte * new

a rte representing the new route or NULL for route removal.

Description

This function is called by the routing protocols whenever they discover a new route or wish to update/remove an existing route. The right announcement sequence is to build route attributes first (either un-cached with aflags set to zero or a cached one using rta_lookup(); in this case please note that you need to increase the use count of the attributes yourself by calling rta_clone()), call rte_get_temp() to obtain a temporary rte, fill in all the appropriate data and finally submit the new rte by calling rte_update().

When rte_update() gets any route, it automatically validates it (checks, whether the network and next hop address are valid IP addresses and also whether a normal routing protocol doesn't try to smuggle a host or link scope route to the table), converts all protocol dependent attributes stored in the rte to temporary extended attributes, consults import filters of the protocol to see if the route should be accepted and/or its attributes modified, stores the temporary attributes back to the rte.

Now, having a "public" version of the route, we automatically find any old route defined by the protocol p for network n, replace it by the new one (or removing it if new is NULL), recalculate the optimal route for this destination and finally broadcast the change (if any) to all routing protocols by calling rte_announce().

All memory used for attribute lists and other temporary allocations is taken from a special linear pool rte_update_pool and freed when rte_update() finishes.


Function

void rte_dump (rte * e) -- dump a route

Arguments

rte * e

rte to be dumped

Description

This functions dumps contents of a rte to debug output.


Function

void rt_dump (rtable * t) -- dump a routing table

Arguments

rtable * t

routing table to be dumped

Description

This function dumps contents of a given routing table to debug output.


Function

void rt_dump_all (void) -- dump all routing tables

Description

This function dumps contents of all routing tables to debug output.


Function

void rt_init (void) -- initialize routing tables

Description

This function is called during BIRD startup. It initializes the routing table module.


Function

void rt_prune (rtable * tab) -- prune a routing table

Arguments

rtable * tab

routing table to be pruned

Description

This function is called whenever a protocol shuts down. It scans the routing table and removes all routes belonging to inactive protocols and also stale network entries.


Function

void rt_prune_all (void) -- prune all routing tables

Description

This function calls rt_prune() for all known routing tables.


Function

void rt_lock_table (rtable * r) -- lock a routing table

Arguments

rtable * r

routing table to be locked

Description

Lock a routing table, because it's in use by a protocol, preventing it from being freed when it gets undefined in a new configuration.


Function

void rt_unlock_table (rtable * r) -- unlock a routing table

Arguments

rtable * r

routing table to be unlocked

Description

Unlock a routing table formerly locked by rt_lock_table(), that is decrease its use count and delete it if it's scheduled for deletion by configuration changes.


Function

void rt_commit (struct config * new, struct config * old) -- commit new routing table configuration

Arguments

struct config * new

new configuration

struct config * old

original configuration or NULL if it's boot time config

Description

Scan differences between old and new configuration and modify the routing tables according to these changes. If new defines a previously unknown table, create it, if it omits a table existing in old, schedule it for deletion (it gets deleted when all protocols disconnect from it by calling rt_unlock_table()), if it exists in both configurations, leave it unchanged.


Function

int rt_feed_baby (struct proto * p) -- advertise routes to a new protocol

Arguments

struct proto * p

protocol to be fed

Description

This function performs one pass of advertisement of routes to a newly initialized protocol. It's called by the protocol code as long as it has something to do. (We avoid transferring all the routes in single pass in order not to monopolize CPU time.)


Function

void rt_feed_baby_abort (struct proto * p) -- abort protocol feeding

Arguments

struct proto * p

protocol

Description

This function is called by the protocol code when the protocol stops or ceases to exist before the last iteration of rt_feed_baby() has finished.


Function

net * net_find (rtable * tab, ip_addr addr, unsigned len) -- find a network entry

Arguments

rtable * tab

a routing table

ip_addr addr

address of the network

unsigned len

length of the network prefix

Description

net_find() looks up the given network in routing table tab and returns a pointer to its net entry or NULL if no such network exists.


Function

net * net_get (rtable * tab, ip_addr addr, unsigned len) -- obtain a network entry

Arguments

rtable * tab

a routing table

ip_addr addr

address of the network

unsigned len

length of the network prefix

Description

net_get() looks up the given network in routing table tab and returns a pointer to its net entry. If no such entry exists, it's created.


Function

rte * rte_cow (rte * r) -- copy a route for writing

Arguments

rte * r

a route entry to be copied

Description

rte_cow() takes a rte and prepares it for modification. The exact action taken depends on the flags of the rte -- if it's a temporary entry, it's just returned unchanged, else a new temporary entry with the same contents is created.

The primary use of this function is inside the filter machinery -- when a filter wants to modify rte contents (to change the preference or to attach another set of attributes), it must ensure that the rte is not shared with anyone else (and especially that it isn't stored in any routing table).

Result

a pointer to the new writable rte.

2.3 Route attribute cache

Each route entry carries a set of route attributes. Several of them vary from route to route, but most attributes are usually common for a large number of routes. To conserve memory, we've decided to store only the varying ones directly in the rte and hold the rest in a special structure called rta which is shared among all the rte's with these attributes.

Each rta contains all the static attributes of the route (i.e., those which are always present) as structure members and a list of dynamic attributes represented by a linked list of ea_list structures, each of them consisting of an array of eattr's containing the individual attributes. An attribute can be specified more than once in the ea_list chain and in such case the first occurrence overrides the others. This semantics is used especially when someone (for example a filter) wishes to alter values of several dynamic attributes, but it wants to preserve the original attribute lists maintained by another module.

Each eattr contains an attribute identifier (split to protocol ID and per-protocol attribute ID), protocol dependent flags, a type code (consisting of several bit fields describing attribute characteristics) and either an embedded 32-bit value or a pointer to a adata structure holding attribute contents.

There exist two variants of rta's -- cached and un-cached ones. Un-cached rta's can have arbitrarily complex structure of ea_list's and they can be modified by any module in the route processing chain. Cached rta's have their attribute lists normalized (that means at most one ea_list is present and its values are sorted in order to speed up searching), they are stored in a hash table to make fast lookup possible and they are provided with a use count to allow sharing.

Routing tables always contain only cached rta's.


Function

eattr * ea_find (ea_list * e, unsigned id) -- find an extended attribute

Arguments

ea_list * e

attribute list to search in

unsigned id

attribute ID to search for

Description

Given an extended attribute list, ea_find() searches for a first occurrence of an attribute with specified ID, returning either a pointer to its eattr structure or NULL if no such attribute exists.


Function

int ea_get_int (ea_list * e, unsigned id, int def) -- fetch an integer attribute

Arguments

ea_list * e

attribute list

unsigned id

attribute ID

int def

default value

Description

This function is a shortcut for retrieving a value of an integer attribute by calling ea_find() to find the attribute, extracting its value or returning a provided default if no such attribute is present.


Function

void ea_sort (ea_list * e) -- sort an attribute list

Arguments

ea_list * e

list to be sorted

Description

This function takes a ea_list chain and sorts the attributes within each of its entries.

If an attribute occurs multiple times in a single ea_list, ea_sort() leaves only the first (the only significant) occurrence.


Function

unsigned ea_scan (ea_list * e) -- estimate attribute list size

Arguments

ea_list * e

attribute list

Description

This function calculates an upper bound of the size of a given ea_list after merging with ea_merge().


Function

void ea_merge (ea_list * e, ea_list * t) -- merge segments of an attribute list

Arguments

ea_list * e

attribute list

ea_list * t

buffer to store the result to

Description

This function takes a possibly multi-segment attribute list and merges all of its segments to one.

The primary use of this function is for ea_list normalization: first call ea_scan() to determine how much memory will the result take, then allocate a buffer (usually using alloca()), merge the segments with ea_merge() and finally sort and prune the result by calling ea_sort().


Function

int ea_same (ea_list * x, ea_list * y) -- compare two ea_list's

Arguments

ea_list * x

attribute list

ea_list * y

attribute list

Description

ea_same() compares two normalized attribute lists x and y and returns 1 if they contain the same attributes, 0 otherwise.


Function

void ea_format (eattr * e, byte * buf) -- format an eattr for printing

Arguments

eattr * e

attribute to be formatted

byte * buf

destination buffer of size EA_FORMAT_BUF_SIZE

Description

This function takes an extended attribute represented by its eattr structure and formats it nicely for printing according to the type information.

If the protocol defining the attribute provides its own get_attr() hook, it's consulted first.


Function

void ea_dump (ea_list * e) -- dump an extended attribute

Arguments

ea_list * e

attribute to be dumped

Description

ea_dump() dumps contents of the extended attribute given to the debug output.


Function

unsigned int ea_hash (ea_list * e) -- calculate an ea_list hash key

Arguments

ea_list * e

attribute list

Description

ea_hash() takes an extended attribute list and calculated a hopefully uniformly distributed hash value from its contents.


Function

ea_list * ea_append (ea_list * to, ea_list * what) -- concatenate ea_list's

Arguments

ea_list * to

destination list (can be NULL)

ea_list * what

list to be appended (can be NULL)

Description

This function appends the ea_list what at the end of ea_list to and returns a pointer to the resulting list.


Function

rta * rta_lookup (rta * o) -- look up a rta in attribute cache

Arguments

rta * o

a un-cached rta

Description

rta_lookup() gets an un-cached rta structure and returns its cached counterpart. It starts with examining the attribute cache to see whether there exists a matching entry. If such an entry exists, it's returned and its use count is incremented, else a new entry is created with use count set to 1.

The extended attribute lists attached to the rta are automatically converted to the normalized form.


Function

void rta_dump (rta * a) -- dump route attributes

Arguments

rta * a

attribute structure to dump

Description

This function takes a rta and dumps its contents to the debug output.


Function

void rta_dump_all (void) -- dump attribute cache

Description

This function dumps the whole contents of route attribute cache to the debug output.


Function

void rta_init (void) -- initialize route attribute cache

Description

This function is called during initialization of the routing table module to set up the internals of the attribute cache.


Function

rta * rta_clone (rta * r) -- clone route attributes

Arguments

rta * r

a rta to be cloned

Description

rta_clone() takes a cached rta and returns its identical cached copy. Currently it works by just returning the original rta with its use count incremented.


Function

void rta_free (rta * r) -- free route attributes

Arguments

rta * r

a rta to be freed

Description

If you stop using a rta (for example when deleting a route which uses it), you need to call rta_free() to notify the attribute cache the attribute is no longer in use and can be freed if you were the last user (which rta_free() tests by inspecting the use count).

2.4 Routing protocols

Introduction

The routing protocols are the bird's heart and a fine amount of code is dedicated to their management and for providing support functions to them. (-: Actually, this is the reason why the directory with sources of the core code is called nest :-).

When talking about protocols, one need to distinguish between protocols and protocol instances. A protocol exists exactly once, not depending on whether it's configured or not and it can have an arbitrary number of instances corresponding to its "incarnations" requested by the configuration file. Each instance is completely autonomous, has its own configuration, its own status, its own set of routes and its own set of interfaces it works on.

A protocol is represented by a protocol structure containing all the basic information (protocol name, default settings and pointers to most of the protocol hooks). All these structures are linked in the protocol_list list.

Each instance has its own proto structure describing all its properties: protocol type, configuration, a resource pool where all resources belonging to the instance live, various protocol attributes (take a look at the declaration of proto in protocol.h), protocol states (see below for what do they mean), connections to routing tables, filters attached to the protocol and finally a set of pointers to the rest of protocol hooks (they are the same for all instances of the protocol, but in order to avoid extra indirections when calling the hooks from the fast path, they are stored directly in proto). The instance is always linked in both the global instance list (proto_list) and a per-status list (either active_proto_list for running protocols, initial_proto_list for protocols being initialized or flush_proto_list when the protocol is being shut down).

The protocol hooks are described in the next chapter, for more information about configuration of protocols, please refer to the configuration chapter and also to the description of the proto_commit function.

Protocol states

As startup and shutdown of each protocol are complex processes which can be affected by lots of external events (user's actions, reco>rte_cow()

Function

unsigned ea_scan (ea_list * e) -- estimate attribute list size

Arguments

ea_list * e

attribute list

Description

This function calculates an upper bound of the size of a given ea_list after merging with ea_merge().


Function

void ea_merge (ea_list * e, ea_list * t) -- merge segments of an attribute list

Arguments

ea_list * e

attribute list

ea_list * t

buffer to store the result to

Description

This function takes a possibly multi-segment attribute list and merges all of its segments to one.

The primary use of this function is for ea_list normalization: first call ea_scan() to determine how much memory will the result take, then allocate a buffer (usually using alloca()), merge the segments with ea_merge() and finally sort and prune the result by calling ea_sort().


Function

int ea_same (ea_list * x, ea_list * y) -- compare two ea_list's

Arguments

ea_list * x

attribute list

ea_list * y

attribute list

Description

ea_same() compares two normalized attribute lists x and y and returns 1 if they contain the same attributes, 0 otherwise.


Function

void ea_format (eattr * e, byte * buf) -- format an eattr for printing

Arguments

eattr * e

attribute to be formatted

byte * buf

destination buffer of size EA_FORMAT_BUF_SIZE

Description

This function takes an extended attribute represented by its eattr structure and formats it nicely for printing according to the type information.

If the protocol defining the attribute provides its own get_attr() hook, it's consulted first.


Function

void ea_dump (ea_list * e) -- dump an extended attribute

Arguments

ea_list * e

attribute to be dumped

Description

ea_dump() dumps contents of the extended attribute given to the debug output.


Function

unsigned int ea_hash (ea_list * e) -- calculate an ea_list hash key

Arguments

ea_list * e

attribute list

Description

ea_hash() takes an extended attribute list and calculated a hopefully uniformly distributed hash value from its contents.


Function

ea_list * ea_append (ea_list * to, ea_list * what) -- concatenate ea_list's

Arguments

ea_list * to

destination list (can be NULL)

ea_list * what

list to be appended (can be NULL)

Description

This function appends the ea_list what at the end of ea_list to and returns a pointer to the resulting list.


Function

rta * rta_lookup (rta * o) -- look up a rta in attribute cache

Arguments

rta * o

a un-cached rta

Description

rta_lookup() gets an un-cached rta structure and returns its cached counterpart. It starts with examining the attribute cache to see whether there exists a matching entry. If such an entry exists, it's returned and its use count is incremented, else a new entry is created with use count set to 1.

The extended attribute lists attached to the rta are automatically converted to the normalized form.


Function

void rta_dump (rta * a) -- dump route attributes

Arguments

rta * a

attribute structure to dump

Description

This function takes a rta and dumps its contents to the debug output.


Function

void rta_dump_all (void) -- dump attribute cache

Description

This function dumps the whole contents of route attribute cache to the debug output.


Function

void rta_init (void) -- initialize route attribute cache

Description

This function is called during initialization of the routing table module to set up the internals of the attribute cache.


Function

rta * rta_clone (rta * r) -- clone route attributes

Arguments

rta * r

a rta to be cloned

Description

rta_clone() takes a cached rta and returns its identical cached copy. Currently it works by just returning the original rta with its use count incremented.


Function

void rta_free (rta * r) -- free route attributes

Arguments

rta * r

a rta to be freed

Description

If you stop using a rta (for example when deleting a route which uses it), you need to call rta_free() to notify the attribute cache the attribute is no longer in use and can be freed if you were the last user (which rta_free() tests by inspecting the use count).

2.4 Routing protocols

Introduction

The routing protocols are the bird's heart and a fine amount of code is dedicated to their management and for providing support functions to them. (-: Actually, this is the reason why the directory with sources of the core code is called nest :-).

When talking about protocols, one need to distinguish between protocols and protocol instances. A protocol exists exactly once, not depending on whether it's configured or not and it can have an arbitrary number of instances corresponding to its "incarnations" requested by the configuration file. Each instance is completely autonomous, has its own configuration, its own status, its own set of routes and its own set of interfaces it works on.

A protocol is represented by a protocol structure containing all the basic information (protocol name, default settings and pointers to most of the protocol hooks). All these structures are linked in the protocol_list list.

Each instance has its own proto structure describing all its properties: protocol type, configuration, a resource pool where all resources belonging to the instance live, various protocol attributes (take a look at the declaration of proto in protocol.h), protocol states (see below for what do they mean), connections to routing tables, filters attached to the protocol and finally a set of pointers to the rest of protocol hooks (they are the same for all instances of the protocol, but in order to avoid extra indirections when calling the hooks from the fast path, they are stored directly in proto). The instance is always linked in both the global instance list (proto_list) and a per-status list (either active_proto_list for running protocols, initial_proto_list for protocols being initialized or flush_proto_list when the protocol is being shut down).

The protocol hooks are described in the next chapter, for more information about configuration of protocols, please refer to the configuration chapter and also to the description of the proto_commit function.

Protocol states

As startup and shutdown of each protocol are complex processes which can be affected by lots of external events (user's actions, reco>rte_cow()

Function

unsigned ea_scan (ea_list * e) -- estimate attribute list size

Arguments

ea_list * e

attribute list

Description

This function calculates an upper bound of the size of a given ea_list after merging with ea_merge().


Function

void ea_merge (ea_list * e, ea_list * t) -- merge segments of an attribute list

Arguments

ea_list * e

attribute list

ea_list * t

buffer to store the result to

Description

This function takes a possibly multi-segment attribute list and merges all of its segments to one.

The primary use of this function is for ea_list normalization: first call ea_scan() to determine how much memory will the result take, then allocate a buffer (usually using alloca()), merge the segments with ea_merge() and finally sort and prune the result by calling ea_sort().


Function

int ea_same (ea_list * x, ea_list * y) -- compare two ea_list's

Arguments

ea_list * x

attribute list

ea_list * y

attribute list

Description

ea_same() compares two normalized attribute lists x and y and returns 1 if they contain the same attributes, 0 otherwise.


Function

void ea_format (eattr * e, byte * buf) -- format an eattr for printing

Arguments

eattr * e

attribute to be formatted

byte * buf

destination buffer of size EA_FORMAT_BUF_SIZE

Description

This function takes an extended attribute represented by its eattr structure and formats it nicely for printing according to the type information.

If the protocol defining the attribute provides its own get_attr() hook, it's consulted first.


Function

void ea_dump (ea_list * e) -- dump an extended attribute

Arguments

ea_list * e

attribute to be dumped

Description

ea_dump() dumps contents of the extended attribute given to the debug output.


Function

unsigned int ea_hash (ea_list * e) -- calculate an ea_list hash key

Arguments

ea_list * e

attribute list

Description

ea_hash() takes an extended attribute list and calculated a hopefully uniformly distributed hash value from its contents.


Function

ea_list * ea_append (ea_list * to, ea_list * what) -- concatenate ea_list's

Arguments

ea_list * to

destination list (can be NULL)

ea_list * what

list to be appended (can be NULL)

Description

This function appends the ea_list what at the end of ea_list to and returns a pointer to the resulting list.


Function

rta * rta_lookup (rta * o) -- look up a rta in attribute cache

Arguments

rta * o

a un-cached rta

Description

rta_lookup() gets an un-cached rta structure and returns its cached counterpart. It starts with examining the attribute cache to see whether there exists a matching entry. If such an entry exists, it's returned and its use count is incremented, else a new entry is created with use count set to 1.

The extended attribute lists attached to the rta are automatically converted to the normalized form.


Function

void rta_dump (rta * a) -- dump route attributes

Arguments

rta * a

attribute structure to dump

Description

This function takes a rta and dumps its contents to the debug output.


Function

void rta_dump_all (void) -- dump attribute cache

Description

This function dumps the whole contents of route attribute cache to the debug output.


Function

void rta_init (void) -- initialize route attribute cache

Description

This function is called during initialization of the routing table module to set up the internals of the attribute cache.


Function

rta * rta_clone (rta * r) -- clone route attributes

Arguments

rta * r

a rta to be cloned

Description

rta_clone() takes a cached rta and returns its identical cached copy. Currently it works by just returning the original rta with its use count incremented.


Function

void rta_free (rta * r) -- free route attributes

Arguments

rta * r

a rta to be freed

Description

If you stop using a rta (for example when deleting a route which uses it), you need to call rta_free() to notify the attribute cache the attribute is no longer in use and can be freed if you were the last user (which rta_free() tests by inspecting the use count).

2.4 Routing protocols

Introduction

The routing protocols are the bird's heart and a fine amount of code is dedicated to their management and for providing support functions to them. (-: Actually, this is the reason why the directory with sources of the core code is called nest :-).

When talking about protocols, one need to distinguish between protocols and protocol instances. A protocol exists exactly once, not depending on whether it's configured or not and it can have an arbitrary number of instances corresponding to its "incarnations" requested by the configuration file. Each instance is completely autonomous, has its own configuration, its own status, its own set of routes and its own set of interfaces it works on.

A protocol is represented by a protocol structure containing all the basic information (protocol name, default settings and pointers to most of the protocol hooks). All these structures are linked in the protocol_list list.

Each instance has its own proto structure describing all its properties: protocol type, configuration, a resource pool where all resources belonging to the instance live, various protocol attributes (take a look at the declaration of proto in protocol.h), protocol states (see below for what do they mean), connections to routing tables, filters attached to the protocol and finally a set of pointers to the rest of protocol hooks (they are the same for all instances of the protocol, but in order to avoid extra indirections when calling the hooks from the fast path, they are stored directly in proto). The instance is always linked in both the global instance list (proto_list) and a per-status list (either active_proto_list for running protocols, initial_proto_list for protocols being initialized or flush_proto_list when the protocol is being shut down).

The protocol hooks are described in the next chapter, for more information about configuration of protocols, please refer to the configuration chapter and also to the description of the proto_commit function.

Protocol states

As startup and shutdown of each protocol are complex processes which can be affected by lots of external events (user's actions, reco>rte_cow()

Function

unsigned ea_scan (ea_list * e) -- estimate attribute list size

Arguments

ea_list * e

attribute list

Description

This function calculates an upper bound of the size of a given ea_list after merging with ea_merge().


Function

void ea_merge (ea_list * e, ea_list * t) -- merge segments of an attribute list

Arguments

ea_list * e

attribute list

ea_list * t

buffer to store the result to

Description

This function takes a possibly multi-segment attribute list and merges all of its segments to one.

The primary use of this function is for ea_list normalization: first call ea_scan() to determine how much memory will the result take, then allocate a buffer (usually using alloca()), merge the segments with ea_merge() and finally sort and prune the result by calling ea_sort().


Function

int ea_same (ea_list * x, ea_list * y) -- compare two ea_list's

Arguments

ea_list * x

attribute list

ea_list * y

attribute list

Description

ea_same() compares two normalized attribute lists x and y and returns 1 if they contain the same attributes, 0 otherwise.


Function

void ea_format (eattr * e, byte * buf) -- format an eattr for printing

Arguments

eattr * e

attribute to be formatted

byte * buf

destination buffer of size EA_FORMAT_BUF_SIZE

Description

This function takes an extended attribute represented by its eattr structure and formats it nicely for printing according to the type information.

If the protocol defining the attribute provides its own get_attr() hook, it's consulted first.


Function

void ea_dump (ea_list * e) -- dump an extended attribute

Arguments

ea_list * e

attribute to be dumped

Description

ea_dump() dumps contents of the extended attribute given to the debug output.


Function

unsigned int ea_hash (ea_list * e) -- calculate an ea_list hash key

Arguments

ea_list * e

attribute list

Description

ea_hash() takes an extended attribute list and calculated a hopefully uniformly distributed hash value from its contents.


Function

ea_list * ea_append (ea_list * to, ea_list * what) -- concatenate ea_list's

Arguments

ea_list * to

destination list (can be NULL)

ea_list * what

list to be appended (can be NULL)

Description

This function appends the ea_list what at the end of ea_list to and returns a pointer to the resulting list.


Function

rta * rta_lookup (rta * o) -- look up a rta in attribute cache

Arguments

rta * o

a un-cached rta

Description

rta_lookup() gets an un-cached rta structure and returns its cached counterpart. It starts with examining the attribute cache to see whether there exists a matching entry. If such an entry exists, it's returned and its use count is incremented, else a new entry is created with use count set to 1.

The extended attribute lists attached to the rta are automatically converted to the normalized form.


Function

void rta_dump (rta * a) -- dump route attributes

Arguments

rta * a

attribute structure to dump

Description

This function takes a rta and dumps its contents to the debug output.


Function

void rta_dump_all (void) -- dump attribute cache

Description

This function dumps the whole contents of route attribute cache to the debug output.


Function

void rta_init (void) -- initialize route attribute cache

Description

This function is called during initialization of the routing table module to set up the internals of the attribute cache.


Function

rta * rta_clone (rta * r) -- clone route attributes

Arguments

rta * r

a rta to be cloned

Description

rta_clone() takes a cached rta and returns its identical cached copy. Currently it works by just returning the original rta with its use count incremented.


Function

void rta_free (rta * r) -- free route attributes

Arguments

rta * r

a rta to be freed

Description

If you stop using a rta (for example when deleting a route which uses it), you need to call rta_free() to notify the attribute cache the attribute is no longer in use and can be freed if you were the last user (which rta_free() tests by inspecting the use count).

2.4 Routing protocols

Introduction

The routing protocols are the bird's heart and a fine amount of code is dedicated to their management and for providing support functions to them. (-: Actually, this is the reason why the directory with sources of the core code is called nest :-).

When talking about protocols, one need to distinguish between protocols and protocol instances. A protocol exists exactly once, not depending on whether it's configured or not and it can have an arbitrary number of instances corresponding to its "incarnations" requested by the configuration file. Each instance is completely autonomous, has its own configuration, its own status, its own set of routes and its own set of interfaces it works on.

A protocol is represented by a protocol structure containing all the basic information (protocol name, default settings and pointers to most of the protocol hooks). All these structures are linked in the protocol_list list.

Each instance has its own proto structure describing all its properties: protocol type, configuration, a resource pool where all resources belonging to the instance live, various protocol attributes (take a look at the declaration of proto in protocol.h), protocol states (see below for what do they mean), connections to routing tables, filters attached to the protocol and finally a set of pointers to the rest of protocol hooks (they are the same for all instances of the protocol, but in order to avoid extra indirections when calling the hooks from the fast path, they are stored directly in proto). The instance is always linked in both the global instance list (proto_list) and a per-status list (either active_proto_list for running protocols, initial_proto_list for protocols being initialized or flush_proto_list when the protocol is being shut down).

The protocol hooks are described in the next chapter, for more information about configuration of protocols, please refer to the configuration chapter and also to the description of the proto_commit function.

Protocol states

As startup and shutdown of each protocol are complex processes which can be affected by lots of external events (user's actions, reco>rte_cow()

Function

unsigned ea_scan (ea_list * e) -- estimate attribute list size

Arguments

ea_list * e

attribute list

Description

This function calculates an upper bound of the size of a given ea_list after merging with ea_merge().


Function

void ea_merge (ea_list * e, ea_list * t) -- merge segments of an attribute list

Arguments

ea_list * e

attribute list

ea_list * t

buffer to store the result to

Description

This function takes a possibly multi-segment attribute list and merges all of its segments to one.

The primary use of this function is for ea_list normalization: first call ea_scan() to determine how much memory will the result take, then allocate a buffer (usually using alloca()), merge the segments with ea_merge() and finally sort and prune the result by calling ea_sort().


Function

int ea_same (ea_list * x, ea_list * y) -- compare two ea_list's

Arguments

ea_list * x

attribute list

ea_list * y

attribute list

Description

ea_same() compares two normalized attribute lists x and y and returns 1 if they contain the same attributes, 0 otherwise.


Function

void ea_format (eattr * e, byte * buf) -- format an eattr for printing

Arguments

eattr * e

attribute to be formatted

byte * buf

destination buffer of size EA_FORMAT_BUF_SIZE

Description

This function takes an extended attribute represented by its eattr structure and formats it nicely for printing according to the type information.

If the protocol defining the attribute provides its own get_attr() hook, it's consulted first.


Function

void ea_dump (ea_list * e) -- dump an extended attribute

Arguments

ea_list * e

attribute to be dumped

Description

ea_dump() dumps contents of the extended attribute given to the debug output.


Function

unsigned int ea_hash (ea_list * e) -- calculate an ea_list hash key

Arguments

ea_list * e

attribute list

Description

ea_hash() takes an extended attribute list and calculated a hopefully uniformly distributed hash value from its contents.


Function

ea_list * ea_append (ea_list * to, ea_list * what) -- concatenate ea_list's

Arguments

ea_list * to

destination list (can be NULL)

ea_list * what

list to be appended (can be NULL)

Description

This function appends the ea_list what at the end of ea_list to and returns a pointer to the resulting list.


Function

rta * rta_lookup (rta * o) -- look up a rta in attribute cache

Arguments

rta * o

a un-cached rta

Description

rta_lookup() gets an un-cached rta structure and returns its cached counterpart. It starts with examining the attribute cache to see whether there exists a matching entry. If such an entry exists, it's returned and its use count is incremented, else a new entry is created with use count set to 1.

The extended attribute lists attached to the rta are automatically converted to the normalized form.


Function

void rta_dump (rta * a) -- dump route attributes

Arguments

rta * a

attribute structure to dump

Description

This function takes a rta and dumps its contents to the debug output.


Function

void rta_dump_all (void) -- dump attribute cache

Description

This function dumps the whole contents of route attribute cache to the debug output.


Function

void rta_init (void) -- initialize route attribute cache

Description

This function is called during initialization of the routing table module to set up the internals of the attribute cache.


Function

rta * rta_clone (rta * r) -- clone route attributes

Arguments

rta * r

a rta to be cloned

Description

rta_clone() takes a cached rta and returns its identical cached copy. Currently it works by just returning the original rta with its use count incremented.


Function

void rta_free (rta * r) -- free route attributes

Arguments

rta * r

a rta to be freed

Description

If you stop using a rta (for example when deleting a route which uses it), you need to call rta_free() to notify the attribute cache the attribute is no longer in use and can be freed if you were the last user (which rta_free() tests by inspecting the use count).

2.4 Routing protocols

Introduction

The routing protocols are the bird's heart and a fine amount of code is dedicated to their management and for providing support functions to them. (-: Actually, this is the reason why the directory with sources of the core code is called nest :-).

When talking about protocols, one need to distinguish between protocols and protocol instances. A protocol exists exactly once, not depending on whether it's configured or not and it can have an arbitrary number of instances corresponding to its "incarnations" requested by the configuration file. Each instance is completely autonomous, has its own configuration, its own status, its own set of routes and its own set of interfaces it works on.

A protocol is represented by a protocol structure containing all the basic information (protocol name, default settings and pointers to most of the protocol hooks). All these structures are linked in the protocol_list list.

Each instance has its own proto structure describing all its properties: protocol type, configuration, a resource pool where all resources belonging to the instance live, various protocol attributes (take a look at the declaration of proto in protocol.h), protocol states (see below for what do they mean), connections to routing tables, filters attached to the protocol and finally a set of pointers to the rest of protocol hooks (they are the same for all instances of the protocol, but in order to avoid extra indirections when calling the hooks from the fast path, they are stored directly in proto). The instance is always linked in both the global instance list (proto_list) and a per-status list (either active_proto_list for running protocols, initial_proto_list for protocols being initialized or flush_proto_list when the protocol is being shut down).

The protocol hooks are described in the next chapter, for more information about configuration of protocols, please refer to the configuration chapter and also to the description of the proto_commit function.

Protocol states

As startup and shutdown of each protocol are complex processes which can be affected by lots of external events (user's actions, reco>rte_cow()

Function

unsigned ea_scan (ea_list * e) -- estimate attribute list size

Arguments

ea_list * e

attribute list

Description

This function calculates an upper bound of the size of a given ea_list after merging with ea_merge().


Function

void ea_merge (ea_list *