summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/prog-proto.sgml91
-rw-r--r--nest/Doc4
-rw-r--r--nest/proto.c119
3 files changed, 213 insertions, 1 deletions
diff --git a/doc/prog-proto.sgml b/doc/prog-proto.sgml
new file mode 100644
index 0000000..ab90b7a
--- /dev/null
+++ b/doc/prog-proto.sgml
@@ -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:
diff --git a/nest/Doc b/nest/Doc
index c0819e4..70d996b 100644
--- a/nest/Doc
+++ b/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
diff --git a/nest/proto.c b/nest/proto.c
index 5ec793e..8275638 100644
--- a/nest/proto.c
+++ b/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)
{