Added documentation on protocols.
Protocol hooks deserve an extra chapter (to come soon).
This commit is contained in:
parent
e4ba0ec197
commit
3c6269b8fe
3 changed files with 213 additions and 1 deletions
91
doc/prog-proto.sgml
Normal file
91
doc/prog-proto.sgml
Normal file
|
@ -0,0 +1,91 @@
|
|||
<!--
|
||||
BIRD Programmer's Guide: Protocols
|
||||
|
||||
(c) 2000 Martin Mares <mj@ucw.cz>
|
||||
-->
|
||||
|
||||
<sect1>Routing protocols
|
||||
|
||||
<sect2>Introduction
|
||||
|
||||
<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
|
||||
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.
|
||||
|
||||
<p>A protocol is represented by a <struct/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 <param/protocol_list/ list.
|
||||
|
||||
<p>Each instance has its own <struct/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 <struct/proto/ in
|
||||
<tt/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 <struct/proto/). The instance is always linked in both the global instance list
|
||||
(<param/proto_list/) and a per-status list (either <param/active_proto_list/ for
|
||||
running protocols, <param/initial_proto_list/ for protocols being initialized or
|
||||
<param/flush_proto_list/ when the protocol is being shut down).
|
||||
|
||||
<p>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 <func/proto_commit/ function.
|
||||
|
||||
<sect2>Protocol states
|
||||
|
||||
<p>As startup and shutdown of each protocol are complex processes which can be affected
|
||||
by lots of external events (user's actions, reconfigurations, behaviour of neighboring routers etc.),
|
||||
we have decided to supervise them by a pair of simple state machines -- the protocol
|
||||
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
|
||||
the following states:
|
||||
|
||||
<descrip>
|
||||
<tag/PS_DOWN/ The protocol is down and waits for being woken up by calling its
|
||||
start() hook.
|
||||
<tag/PS_START/ The protocol is waiting for connection with the rest of the
|
||||
network. It's active, it has resources allocated, but it still doesn't want
|
||||
any routes since it doesn't know what to do with them.
|
||||
<tag/PS_UP/ The protocol is up and running. It communicates with the core,
|
||||
delivers routes to tables and wants to hear announcement about route changes.
|
||||
<tag/PS_STOP/ The protocol has been shut down (either by being asked by the
|
||||
core code to do so or due to having encountered a protocol error).
|
||||
</descrip>
|
||||
|
||||
<p>Unless the protocol is in the <tt/PS_DOWN/ state, it can decide to change
|
||||
its state by calling the <func/proto_notify_state/ function.
|
||||
|
||||
<p>At any time, the core code can ask the protocol to shut down by calling its stop() hook.
|
||||
|
||||
<p>The <em/core state machine/ takes care of the core view of protocol state.
|
||||
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:
|
||||
|
||||
<descrip>
|
||||
<tag/FS_HUNGRY/ The protocol is down, it doesn't have any routes and
|
||||
doesn't want them.
|
||||
<tag/FS_FEEDING/ The protocol has reached the <tt/PS_UP/ state, but
|
||||
we are still busy sending the initial set of routes to it.
|
||||
<tag/FS_HAPPY/ The protocol is up and has complete routing information.
|
||||
<tag/FS_FLUSHING/ The protocol is shutting down (it's in either <tt/PS_STOP/
|
||||
or <tt/PS_DOWN/ state) and we're flushing all of its routes from the
|
||||
routing tables.
|
||||
</descrip>
|
||||
|
||||
<sect2>Functions of the protocol module
|
||||
|
||||
<p>The protocol module provides the following functions:
|
4
nest/Doc
4
nest/Doc
|
@ -2,8 +2,10 @@ H Core
|
|||
S rt-fib.c
|
||||
S rt-table.c
|
||||
S rt-attr.c
|
||||
D prog-proto.sgml
|
||||
S proto.c
|
||||
#S proto-hooks.c
|
||||
S neighbor.c
|
||||
#S cli.c
|
||||
#S iface.c
|
||||
S locks.c
|
||||
#S proto.c
|
||||
|
|
119
nest/proto.c
119
nest/proto.c
|
@ -85,6 +85,20 @@ proto_relink(struct proto *p)
|
|||
proto_enqueue(l, p);
|
||||
}
|
||||
|
||||
/**
|
||||
* proto_new - create a new protocol instance
|
||||
* @c: protocol configuration
|
||||
* @size: size of protocol data structure (each protocol instance is represented by
|
||||
* a structure starting with generic part [struct &proto] and continued
|
||||
* with data specific to the protocol)
|
||||
*
|
||||
* When a new configuration has been read in, the core code starts
|
||||
* initializing all the protocol instandces configured by calling their
|
||||
* init() hooks with the corresponding instance configuration. The initialization
|
||||
* code of the protocol is expected to create a new instance according to the
|
||||
* configuration by calling this function and then modifying the default settings
|
||||
* to values wanted by the protocol.
|
||||
*/
|
||||
void *
|
||||
proto_new(struct proto_config *c, unsigned size)
|
||||
{
|
||||
|
@ -116,6 +130,20 @@ proto_init_instance(struct proto *p)
|
|||
rt_lock_table(p->table);
|
||||
}
|
||||
|
||||
/**
|
||||
* proto_add_announce_hook - connect protocol to a routing table
|
||||
* @p: protocol instance
|
||||
* @t: routing table to connect to
|
||||
*
|
||||
* This function creates a connection between the protocol instance @p
|
||||
* and the routing table @t, making the protocol hear all changes in
|
||||
* the table.
|
||||
*
|
||||
* Unless you want to listen to multiple routing tables (as the Pipe
|
||||
* protocol does), you needn't to worry about this function since the
|
||||
* connection to the protocol's primary routing table is initialized
|
||||
* automatically by the core code.
|
||||
*/
|
||||
struct announce_hook *
|
||||
proto_add_announce_hook(struct proto *p, struct rtable *t)
|
||||
{
|
||||
|
@ -144,6 +172,19 @@ proto_flush_hooks(struct proto *p)
|
|||
p->ahooks = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* proto_config_new - create a new protocol configuration
|
||||
* @pr: protocol the configuration will belong to
|
||||
* @size: size of the structure including generic data
|
||||
*
|
||||
* Whenever the configuration file says that a new instance
|
||||
* of a routing protocol should be created, the parser calls
|
||||
* proto_config_new() to create a configuration entry for this
|
||||
* instance (a structure staring with the &proto_config header
|
||||
* containing all the generic items followed by protocol-specific
|
||||
* ones). Also, the configuration entry gets added to the list
|
||||
* of protocol instances kept in the configuration.
|
||||
*/
|
||||
void *
|
||||
proto_config_new(struct protocol *pr, unsigned size)
|
||||
{
|
||||
|
@ -159,6 +200,14 @@ proto_config_new(struct protocol *pr, unsigned size)
|
|||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* protos_preconfig - pre-configuration processing
|
||||
* @c: new configuration
|
||||
*
|
||||
* This function calls the preconfig() hooks of all routing
|
||||
* protocols available to prepare them for reading of the new
|
||||
* configuration.
|
||||
*/
|
||||
void
|
||||
protos_preconfig(struct config *c)
|
||||
{
|
||||
|
@ -176,6 +225,13 @@ protos_preconfig(struct config *c)
|
|||
DBG("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* protos_postconfig - post-configuration processing
|
||||
* @c: new configuration
|
||||
*
|
||||
* This function calls the postconfig() hooks of all protocol
|
||||
* instances specified in configuration @c.
|
||||
*/
|
||||
void
|
||||
protos_postconfig(struct config *c)
|
||||
{
|
||||
|
@ -207,6 +263,31 @@ proto_init(struct proto_config *c)
|
|||
return q;
|
||||
}
|
||||
|
||||
/**
|
||||
* protos_commit - commit new protocol configuration
|
||||
* @new: new configuration
|
||||
* @old: old configuration or %NULL if it's boot time config
|
||||
* @force_reconfig: force restart of all protocols (used for example
|
||||
* when the router ID changes)
|
||||
*
|
||||
* Scan differences between @old and @new configuration and adjust all
|
||||
* protocol instances to conform to the new configuration.
|
||||
*
|
||||
* When a protocol exists in the new configuration, but it doesn't in the
|
||||
* original one, it's immediately started. When a collision with the other
|
||||
* running protocol would arise, the new protocol will be temporarily stopped
|
||||
* by the locking mechanism.
|
||||
*
|
||||
* When a protocol exists in the old configuration, but it doesn't in the
|
||||
* new one, it's shut down and deleted after the shutdown completes.
|
||||
*
|
||||
* When a protocol exists in both configurations, the core decides whether
|
||||
* it's possible to reconfigure it dynamically (it checks all the core properties
|
||||
* of the protocol and if they match, it asks the reconfigure() hook of the
|
||||
* protocol to see if the protocol is able to switch to the new configuration).
|
||||
* If it isn't possible, the protocol is shut down and a new instance is started
|
||||
* with the new configuration after the shutdown is completed.
|
||||
*/
|
||||
void
|
||||
protos_commit(struct config *new, struct config *old, int force_reconfig)
|
||||
{
|
||||
|
@ -332,6 +413,15 @@ proto_rethink_goal(struct proto *p)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* protos_dump_all - dump status of all protocols
|
||||
*
|
||||
* This function dumps status of all existing protocol instances to the
|
||||
* debug output. It involves printing of general status information
|
||||
* such as protocol states, its position on the protocol lists
|
||||
* and also calling of a dump() hook of the protocol to print
|
||||
* the internals.
|
||||
*/
|
||||
void
|
||||
protos_dump_all(void)
|
||||
{
|
||||
|
@ -360,6 +450,14 @@ protos_dump_all(void)
|
|||
debug(" flushing %s\n", p->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* proto_build - make a single protocol available
|
||||
* @p: the protocol
|
||||
*
|
||||
* After the platform specific initialization code uses protos_build()
|
||||
* to add all the standard protocols, it should call proto_build() for
|
||||
* all platform specific protocols to infrom the core that they exist.
|
||||
*/
|
||||
void
|
||||
proto_build(struct protocol *p)
|
||||
{
|
||||
|
@ -371,6 +469,15 @@ proto_build(struct protocol *p)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* protos_build - build a protocol list
|
||||
*
|
||||
* This function is called during BIRD startup to insert
|
||||
* all standard protocols to the global protocol list. Insertion
|
||||
* of platform specific protocols (such as the kernel syncer)
|
||||
* is in the domain of competence of the platform dependent
|
||||
* startup code.
|
||||
*/
|
||||
void
|
||||
protos_build(void)
|
||||
{
|
||||
|
@ -441,6 +548,18 @@ proto_feed(void *P)
|
|||
proto_feed_more(P);
|
||||
}
|
||||
|
||||
/**
|
||||
* proto_notify_state - notify core about protocol state change
|
||||
* @p: protocol the state of which has changed
|
||||
* @ps: the new status
|
||||
*
|
||||
* Whenever a state of a protocol changes due to some event internal
|
||||
* to the protocol (i.e., not inside a start() or shutdown() hook),
|
||||
* it should immediately notify the core about the change by calling
|
||||
* proto_notify_state() which will write the new state to the &proto
|
||||
* structure and take all the actions necessary to adapt to the new
|
||||
* state.
|
||||
*/
|
||||
void
|
||||
proto_notify_state(struct proto *p, unsigned ps)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue