Fixes for the programmer's manual.
This commit is contained in:
parent
8d56febe64
commit
725270cb1d
14 changed files with 114 additions and 102 deletions
|
@ -456,7 +456,7 @@ cf_symbol_class_name(struct symbol *sym)
|
|||
* Grammar snippets are files (usually with extension |.Y|) contributed
|
||||
* by various BIRD modules in order to provide information about syntax of their
|
||||
* configuration and their CLI commands. Each snipped consists of several
|
||||
* section, each of them starting with a special keyword: |CF_HDR| for
|
||||
* sections, each of them starting with a special keyword: |CF_HDR| for
|
||||
* a list of |#include| directives needed by the C code, |CF_DEFINES|
|
||||
* for a list of C declarations, |CF_DECLS| for |bison| declarations
|
||||
* including keyword definitions specified as |CF_KEYWORDS|, |CF_GRAMMAR|
|
||||
|
@ -473,5 +473,5 @@ cf_symbol_class_name(struct symbol *sym)
|
|||
*
|
||||
* Values of |enum| filter types can be defined using |CF_ENUM| with
|
||||
* the following parameters: name of filter type, prefix common for all
|
||||
* literals of this type, names of all the possible values.
|
||||
* literals of this type and names of all the possible values.
|
||||
*/
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
/**
|
||||
* DOC: Configuration manager
|
||||
*
|
||||
* Configuration of BIRD is complex, yet straightforward. There exist three
|
||||
* Configuration of BIRD is complex, yet straightforward. There are three
|
||||
* modules taking care of the configuration: config manager (which takes care
|
||||
* of storage of the config information and controls switching between configs),
|
||||
* lexical analyzer and parser.
|
||||
|
@ -18,7 +18,7 @@
|
|||
* accompanied by a linear pool from which all information associated
|
||||
* with the config and pointed to by the &config structure is allocated.
|
||||
*
|
||||
* There can exist up four different configurations at one time: an active
|
||||
* There can exist up to four different configurations at one time: an active
|
||||
* one (pointed to by @config), configuration we are just switching from
|
||||
* (@old_config), one queued for the next reconfiguration (@future_config;
|
||||
* if it's non-%NULL and the user wants to reconfigure once again, we just
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
design decisions and rationale behind them. It also contains documentation on
|
||||
all the essential components of the system and their interfaces.
|
||||
|
||||
<p>Routing daemons are very complicated things which need to act in real time
|
||||
<p>Routing daemons are complicated things which need to act in real time
|
||||
to complex sequences of external events, respond correctly even to the most erroneous behavior
|
||||
of their environment and still handle enormous amount of data with reasonable
|
||||
speed. Due to all of this, their design is very tricky as one needs to carefully
|
||||
|
@ -47,7 +47,7 @@ Easily solvable by abstracting out routing tables and the corresponding operatio
|
|||
<item><it>Offer powerful route filtering.</it>
|
||||
There already were several attempts to incorporate route filters to a dynamic router,
|
||||
but most of them have used simple sequences of filtering rules which were very inflexible
|
||||
and hard to use for any non-trivial filters. We've decided to employ a simple loop-free
|
||||
and hard to use for non-trivial filters. We've decided to employ a simple loop-free
|
||||
programming language having access to all the route attributes and being able to
|
||||
modify the most of them.
|
||||
|
||||
|
@ -65,8 +65,7 @@ the routing process which are not affected by the change.
|
|||
In addition to the online reconfiguration, a routing daemon should be able to communicate
|
||||
with the user and with many other programs (primarily scripts used for network maintenance)
|
||||
in order to make it possible to inspect contents of routing tables, status of all
|
||||
routing protocols and also to control their behavior (i.e., it should be possible
|
||||
to disable, enable or reset a protocol without restarting all the others). To achieve
|
||||
routing protocols and also to control their behavior (disable, enable or reset a protocol without restarting all the others). To achieve
|
||||
this, we implement a simple command-line protocol based on those used by FTP and SMTP
|
||||
(that is textual commands and textual replies accompanied by a numeric code which makes
|
||||
them both readable to a human and easy to recognize in software).
|
||||
|
@ -77,7 +76,9 @@ of all the routing protocols and also of the user interface parts and to hope th
|
|||
the scheduler will assign time to them in a fair enough manner. This is surely a good
|
||||
solution, but we have resisted the temptation and preferred to avoid the overhead of threading
|
||||
and the large number of locks involved and preferred a event driven architecture with
|
||||
our own scheduling of events.
|
||||
our own scheduling of events. An unpleasant consequence of such an approach
|
||||
is that long lasting tasks must be split to more parts linked by special
|
||||
events or timers to make the CPU available for other tasks as well.
|
||||
|
||||
</itemize>
|
||||
|
||||
|
@ -106,7 +107,7 @@ grammar rules and the corresponding snippets of C code. For each group
|
|||
of code modules (core, each protocol, filters) there exist a configuration
|
||||
module taking care of all the related configuration stuff.
|
||||
|
||||
<tagp>Filters</tagp> implement the route filtering language.
|
||||
<tagp>The filter</tagp> implements the route filtering language.
|
||||
|
||||
<tagp>Protocol modules</tagp> implement the individual routing protocols.
|
||||
|
||||
|
@ -125,25 +126,33 @@ preferred the simplicity and straightforward nature of C which gives us fine
|
|||
control over all implementation details and on the other hand enough
|
||||
instruments to build the abstractions we need.
|
||||
|
||||
<p>The modules are statically linked to produce a single executable file
|
||||
(except for the client which stands on its own).
|
||||
|
||||
<p>The building process is controlled by a set of Makefiles for GNU Make,
|
||||
intermixed with several Perl and shell scripts.
|
||||
|
||||
<p>The initial configuration of the daemon, detection of system features
|
||||
and selection of the right modules to include for the particular OS
|
||||
and the set of protocols the user has chosen is performed by a configure
|
||||
script created using GNU Autoconf.
|
||||
script generated by GNU Autoconf.
|
||||
|
||||
<p>The parser of the configuration is generated by the GNU Bison.
|
||||
|
||||
<p>The documentation is generated using <file/SGMLtools/ with our own DTD
|
||||
and mapping rules. The printed form of the documentation is first converted
|
||||
and mapping rules which produce both an online version in HTML and
|
||||
a neatly formatted one for printing (first converted
|
||||
from SGML to &latex; and then processed by &tex; and <file/dvips/ to
|
||||
produce a PostScript file.
|
||||
get a PostScript file).
|
||||
|
||||
<p>The comments from C sources which form a part of the programmer's
|
||||
documentation are extracted using a modified version of the <file/kernel-doc/
|
||||
tool.
|
||||
|
||||
<p>If you want to work on BIRD, it's highly recommended to configure it
|
||||
with a <tt/--enable-debug/ switch which enables some internal consistency
|
||||
checks and it also links BIRD with a memory allocation checking library
|
||||
if you have one (either <tt/efence/ or <tt/dmalloc/).
|
||||
|
||||
<!--
|
||||
LocalWords: IPv IP CLI snippets Perl Autoconf SGMLtools DTD SGML dvips
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
\advance\textheight -2 ex
|
||||
%\renewcommand{\baselinestretch}{1.14}
|
||||
\setcounter{tocdepth}{1}
|
||||
\oddsidemargin 0.5 in
|
||||
\evensidemargin 0 in
|
||||
\oddsidemargin 0.15 in
|
||||
\evensidemargin -0.35 in
|
||||
\textwidth 6.5in
|
||||
|
||||
\def\ps@headings{\let\@mkboth\markboth
|
||||
|
|
|
@ -10,25 +10,23 @@
|
|||
/**
|
||||
* DOC: Filters
|
||||
*
|
||||
* You can find sources of filters language in |filter/|
|
||||
* directory. |filter/config.Y| filter grammar, and basically translates
|
||||
* source from user into tree of &f_inst structures. These trees are
|
||||
* later interpreted using code in |filter/filter.c|. Filters internally
|
||||
* work with values/variables in struct f_val, which contains type of
|
||||
* value and value.
|
||||
* You can find sources of the filter language in |filter/|
|
||||
* directory. File |filter/config.Y| contains filter grammar and basically translates
|
||||
* the source from user into a tree of &f_inst structures. These trees are
|
||||
* later interpreted using code in |filter/filter.c|.
|
||||
*
|
||||
* Filter consists of tree of &f_inst structures, one structure per
|
||||
* "instruction". Each &f_inst contains code, aux value which is
|
||||
* usually type of data this instruction operates on, and two generic
|
||||
* arguments (a1, a2). Some instructions contain pointer(s) to other
|
||||
* instructions in their (a1, a2) fields.
|
||||
* A filter is represented by a tree of &f_inst structures, one structure per
|
||||
* "instruction". Each &f_inst contains @code, @aux value which is
|
||||
* usually the data type this instruction operates on and two generic
|
||||
* arguments (@a1, @a2). Some instructions contain pointer(s) to other
|
||||
* instructions in their (@a1, @a2) fields.
|
||||
*
|
||||
* Filters use structure &f_val for its variables. Each &f_val
|
||||
* contains type and value. Types are constants prefixed with %T_. Few
|
||||
* of types are special; %T_RETURN can be or-ed with type to indicate
|
||||
* that return from function/from whole filter should be
|
||||
* forced. Important thing about &f_val s is that they may be copied
|
||||
* with simple =. That's fine for all currently defined types: strings
|
||||
* Filters use a &f_val structure for their data. Each &f_val
|
||||
* contains type and value (types are constants prefixed with %T_). Few
|
||||
* of the types are special; %T_RETURN can be or-ed with a type to indicate
|
||||
* that return from a function or from the whole filter should be
|
||||
* forced. Important thing about &f_val's is that they may be copied
|
||||
* with a simple |=|. That's fine for all currently defined types: strings
|
||||
* are read-only (and therefore okay), paths are copied for each
|
||||
* operation (okay too).
|
||||
*/
|
||||
|
|
2
lib/ip.c
2
lib/ip.c
|
@ -15,7 +15,7 @@
|
|||
* BIRD uses its own abstraction of IP address in order to share the same
|
||||
* code for both IPv4 and IPv6. IP addresses are represented as entities
|
||||
* of type &ip_addr which are never to be treated as numbers and instead
|
||||
* they should be manipulated using the following functions and macros.
|
||||
* they must be manipulated using the following functions and macros.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,7 +18,7 @@ references to.
|
|||
<p>We've tried to solve this problem by employing a resource tracking
|
||||
system which keeps track of all the resources allocated by all the
|
||||
modules of BIRD, deallocates everything automatically when a module
|
||||
shuts down and it's is able to print out the list of resources and
|
||||
shuts down and it is able to print out the list of resources and
|
||||
the corresponding modules they are allocated by.
|
||||
|
||||
<p>Each allocated resource (from now we'll speak about allocated
|
||||
|
|
|
@ -35,12 +35,12 @@
|
|||
* on the current state of command processing.
|
||||
*
|
||||
* The CLI commands are declared as a part of the configuration grammar
|
||||
* by using the |CF_CLI| macro. When a command is received, it's processed
|
||||
* by using the |CF_CLI| macro. When a command is received, it is processed
|
||||
* by the same lexical analyzer and parser as used for the configuration, but
|
||||
* it's switched to a special mode by prepending a fake token to the text,
|
||||
* so that it uses only the CLI command rules. Then the parser invokes
|
||||
* an execution routine corresponding to the command, which either constructs
|
||||
* the whole reply and returns back or (in case it expects the reply will be long)
|
||||
* the whole reply and returns it back or (in case it expects the reply will be long)
|
||||
* it prints a partial reply and asks the CLI module (using the @cont hook)
|
||||
* to call it again when the output is transferred to the user.
|
||||
*
|
||||
|
|
|
@ -8,14 +8,14 @@
|
|||
|
||||
<sect1>Introduction
|
||||
|
||||
<p>The routing protocols are the BIRD's heart and a fine amount of code
|
||||
<p>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 <tt/nest/ :-).
|
||||
|
||||
<p>When talking about protocols, one need to distinguish between <em/protocols/
|
||||
and protocol <em/instances/. A protocol exists exactly once, not depending on whether
|
||||
it's configured on not and it can have an arbitrary number of instances corresponding
|
||||
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.
|
||||
|
@ -49,7 +49,7 @@ we have decided to supervise them by a pair of simple state machines -- the prot
|
|||
state machine and a core state machine.
|
||||
|
||||
<p>The <em/protocol state machine/ corresponds to internal state of the protocol
|
||||
and the protocol can alter its state whenever it wants to. There exist
|
||||
and the protocol can alter its state whenever it wants to. There are
|
||||
the following states:
|
||||
|
||||
<descrip>
|
||||
|
@ -73,7 +73,7 @@ its state by calling the <func/proto_notify_state/ function.
|
|||
The states are traversed according to changes of the protocol state machine, but
|
||||
sometimes the transitions are delayed if the core needs to finish some actions
|
||||
(for example sending of new routes to the protocol) before proceeding to the
|
||||
new state. There exist the following core states:
|
||||
new state. There are the following core states:
|
||||
|
||||
<descrip>
|
||||
<tag/FS_HUNGRY/ The protocol is down, it doesn't have any routes and
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
* hold all the information about known networks, the associated routes and
|
||||
* their attributes.
|
||||
*
|
||||
* There exist multiple routing tables (a primary one together with any
|
||||
* 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 network entries (&rte), the first entry
|
||||
* on the list being the best possible one (i.e., the one we currently use
|
||||
* 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
|
||||
|
|
|
@ -9,60 +9,63 @@
|
|||
/**
|
||||
* DOC: Open Shortest Path First (OSPF)
|
||||
*
|
||||
* As OSPF protocol is quite complicated and complex implemenation is
|
||||
* split into many files. In |ospf.c| you can find mostly interfaces
|
||||
* for communication with nest. (E.g. reconfiguration hooks, shutdown
|
||||
* and inicialisation and so on.) In |packet.c| you can find various
|
||||
* functions for sending and receiving generic OSPF packet. There are
|
||||
* also routins for autentications, checksumming. |Iface.c| contains
|
||||
* interface state machine, allocation and deallocation of OSPF's
|
||||
* interface data structures. |Neighbor.c| includes neighbor state
|
||||
* machine and function for election of Designed Router and Backup
|
||||
* Designed router. In |hello.c| there are routines for sending
|
||||
* and receiving hello packets as well as functions for maintaining
|
||||
* wait times and inactivity timer. |Lsreq.c|, |lsack.c|, |dbdes.c|
|
||||
* contains functions for sending and receiving link-state request,
|
||||
* link-state acknoledge and database description respectively.
|
||||
* In |lsupd.c| there are function for sending and receiving
|
||||
* link-state updates and also flooding algoritmus. |Topology.c| is
|
||||
* a place where routins for searching LSAs in link-state database,
|
||||
* adding and deleting them, there are also functions for originating
|
||||
* various types of LSA. (router lsa, net lsa, external lsa) |Rt.c|
|
||||
* contains routins for calculating of routing table. |Lsalib.c| is a set
|
||||
* of various functions for work with LSAs. (Endianity transformations,
|
||||
* checksum calculation etc.)
|
||||
* The OSPF protocol is quite complicated and its complex implemenation is
|
||||
* split to many files. In |ospf.c|, you can find mostly interface
|
||||
* for communication with the core (e.g., reconfiguration hooks, shutdown
|
||||
* and initialisation and so on). In |packet.c|, you can find various
|
||||
* functions for sending and receiving of generic OSPF packets. There are
|
||||
* also routines for autentication and checksumming. File |iface.c| contains
|
||||
* the interface state machine, allocation and deallocation of OSPF's
|
||||
* interface data structures. Source |neighbor.c| includes the neighbor state
|
||||
* machine and functions for election of Designed Router and Backup
|
||||
* Designed router. In |hello.c|, there are routines for sending
|
||||
* and receiving of hello packets as well as functions for maintaining
|
||||
* wait times and the inactivity timer. Files |lsreq.c|, |lsack.c|, |dbdes.c|
|
||||
* contain functions for sending and receiving of link-state requests,
|
||||
* link-state acknoledges and database descriptions respectively.
|
||||
* In |lsupd.c|, there are functions for sending and receiving
|
||||
* of link-state updates and also the flooding algorithm. Source |topology.c| is
|
||||
* a place where routines for searching LSA's in the link-state database,
|
||||
* adding and deleting them reside, there also are functions for originating
|
||||
* of various types of LSA's (router LSA, net LSA, external LSA). File |rt.c|
|
||||
* contains routines for calculating the routing table. |lsalib.c| is a set
|
||||
* of various functions for working with the LSA's (endianity conversions,
|
||||
* calculation of checksum etc.).
|
||||
*
|
||||
* Just one instance of protocol is able to hold LSA databases for
|
||||
* multiple OSPF areas and exhange routing information between
|
||||
* multiple neighbors and calculate routing tables. The core
|
||||
* structure is &proto_ospf, to which multiple &ospf_area and
|
||||
* &ospf_iface are connected. To &ospf_area is connected
|
||||
* &top_hash_graph, which is a dynamic hashing structure that
|
||||
* describes link-state database. It allows fast search, adding
|
||||
* and deleting. LSA is kept in two pieces: header and body. Both of them are
|
||||
* kept in endianity of CPU.
|
||||
* One instance of the protocol is able to hold LSA databases for
|
||||
* multiple OSPF areas, to exchange routing information between
|
||||
* multiple neighbors and to calculate the routing tables. The core
|
||||
* structure is &proto_ospf to which multiple &ospf_area and
|
||||
* &ospf_iface structures are connected. To &ospf_area is also connected
|
||||
* &top_hash_graph which is a dynamic hashing structure that
|
||||
* describes the link-state database. It allows fast search, addition
|
||||
* and deletion. Each LSA is kept in two pieces: header and body. Both of them are
|
||||
* kept in endianity of the CPU.
|
||||
*
|
||||
* Every area has it's own area_disp() that is
|
||||
* responsible for late originating of router LSA, calcutating
|
||||
* of routing table and it also ages and flushes LSA database. This
|
||||
* Every area has its own area_disp() which is
|
||||
* responsible for late originating of router LSA, calculating
|
||||
* of the routing table and it also ages and flushes the LSA's. This
|
||||
* function is called in regular intervals.
|
||||
* To every &ospf_iface is connected one or more
|
||||
* &ospf_neighbors. This structure contains many timers and queues
|
||||
* for building adjacency and exchange routing messages.
|
||||
* To every &ospf_iface, we connect one or more
|
||||
* &ospf_neighbor's -- a structure containing many timers and queues
|
||||
* for building adjacency and for exchange of routing messages.
|
||||
*
|
||||
* BIRD's OSPF implementation respects RFC2328 in every detail but
|
||||
* some of inner function differs. RFC recommends to make a snapshot
|
||||
* of link-state database when new adjacency is building and send
|
||||
* database description packets based on information of this
|
||||
* snapshot. The database can be quite large in some networks so
|
||||
* I rather walk through &slist structure which allows me to
|
||||
* continue even if actual LSA I worked on is deleted. New
|
||||
* LSA are added to the tail of this slist.
|
||||
* BIRD's OSPF implementation respects RFC2328 in every detail, but
|
||||
* some of internal algorithms do differ. The RFC recommends to make a snapshot
|
||||
* of the link-state database when a new adjacency is forming and send
|
||||
* the database description packets based on information of this
|
||||
* snapshot. The database can be quite large in some networks, so
|
||||
* we rather walk through a &slist structure which allows us to
|
||||
* continue even if the actual LSA we were worked with is deleted. New
|
||||
* LSA's are added at the tail of this &slist.
|
||||
*
|
||||
* I also don't build another, new routing table besides the old
|
||||
* one because nest helps me. I simply flush all calculated and
|
||||
* deleted routes into nest's routing table. It's simplyfies
|
||||
* this process and spares memory.
|
||||
* We also don't keep a separate OSPF routing table, because the core
|
||||
* helps us by being able to recognize when a route is updated
|
||||
* to an identical one and it suppresses the update automatically.
|
||||
* Due to this, we can flush all the routes we've recalculated and
|
||||
* also those we're deleted to the core's routing table and the
|
||||
* core will take care of the rest. This simplifies the process
|
||||
* and conserves memory.
|
||||
*/
|
||||
|
||||
#include "ospf.h"
|
||||
|
|
|
@ -9,19 +9,18 @@
|
|||
/**
|
||||
* DOC: Static
|
||||
*
|
||||
* The Static protocol is implemented in a very straightforward way. It keeps
|
||||
* a two lists of static routes: one containing interface routes and one
|
||||
* The Static protocol is implemented in a straightforward way. It keeps
|
||||
* two lists of static routes: one containing interface routes and one
|
||||
* holding the remaining ones. Interface routes are inserted and removed according
|
||||
* to interface events received from the core via the if_notify() hook, routes
|
||||
* to interface events received from the core via the if_notify() hook. Routes
|
||||
* pointing to a neighboring router use a sticky node in the neighbor cache
|
||||
* to be notified about gaining or losing the neighbor and finally special
|
||||
* to be notified about gaining or losing the neighbor. Special
|
||||
* routes like black holes or rejects are inserted all the time.
|
||||
*
|
||||
* The only other thing worth mentioning is that when asked for reconfiguration,
|
||||
* Static not only compares the two configurations, but it also calculates
|
||||
* difference between the lists of static routes mentioned in the old config
|
||||
* and the lists in the new one and it just inserts the newly added routes
|
||||
* and removes the obsolete ones.
|
||||
* difference between the lists of static routes and it just inserts the
|
||||
* newly added routes and removes the obsolete ones.
|
||||
*/
|
||||
|
||||
#undef LOCAL_DEBUG
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
* 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]
|
||||
* 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 2.2].
|
||||
|
@ -33,7 +33,8 @@
|
|||
*
|
||||
* 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. */
|
||||
* only once for all the instances.
|
||||
*/
|
||||
|
||||
/*
|
||||
* If you are brave enough, continue now. You cannot say you haven't been warned.
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
* DOC: Logging
|
||||
*
|
||||
* The Logging module offers a simple set of functions for writing
|
||||
* messages to system logs and to the debug output.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
Loading…
Reference in a new issue