summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Mares <mj@ucw.cz>1999-02-05 21:37:34 +0000
committerMartin Mares <mj@ucw.cz>1999-02-05 21:37:34 +0000
commit31b3e1bbf5bc823ec5cf6d88931132f00e6c52b9 (patch)
treeb3c3da837ca2079a222dfc99ab479bd040ba21ad
parentc4c63eecc37a744c53c23da89b1ba09b9640cb6e (diff)
Implemented new configuration/reconfiguration interface and defined protocol
state machines. Full explanation will follow soon.
-rw-r--r--TODO3
-rw-r--r--conf/Makefile2
-rw-r--r--conf/cf-lex.l47
-rw-r--r--conf/conf.c96
-rw-r--r--conf/conf.h28
-rw-r--r--nest/bird.h5
-rw-r--r--nest/config.Y10
-rw-r--r--nest/iface.c21
-rw-r--r--nest/iface.h4
-rw-r--r--nest/proto.c104
-rw-r--r--nest/protocol.h128
-rw-r--r--nest/rt-attr.c2
-rw-r--r--nest/rt-dev.c46
-rw-r--r--nest/rt-dev.h6
-rw-r--r--nest/rt-table.c2
-rw-r--r--sysdep/unix/main.c18
16 files changed, 353 insertions, 169 deletions
diff --git a/TODO b/TODO
index 9fbf2d52..f681997c 100644
--- a/TODO
+++ b/TODO
@@ -6,6 +6,9 @@ Core
* logging and tracing; use appropriate log levels
* check log calls for trailing newlines
+* Fix router ID calculation
+* debug dump: dump router ID as well
+
- TOS not supported by kernel -> automatically drop routes with TOS<>0
- fake multipath?
diff --git a/conf/Makefile b/conf/Makefile
index 270d5567..fdcd4c38 100644
--- a/conf/Makefile
+++ b/conf/Makefile
@@ -1,4 +1,4 @@
-source=cf-parse.tab.c cf-lex.c
+source=cf-parse.tab.c cf-lex.c conf.c
root-rel=../
include ../Rules
diff --git a/conf/cf-lex.l b/conf/cf-lex.l
index 81e3b6a2..791d4adc 100644
--- a/conf/cf-lex.l
+++ b/conf/cf-lex.l
@@ -1,7 +1,7 @@
/*
* BIRD -- Configuration Lexer
*
- * (c) 1998 Martin Mares <mj@ucw.cz>
+ * (c) 1998--1999 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
@@ -15,7 +15,6 @@
#include <stdarg.h>
#include "nest/bird.h"
-#include "lib/string.h"
#include "conf/conf.h"
#include "conf/cf-parse.tab.h"
@@ -34,9 +33,10 @@ static struct keyword {
static struct keyword *kw_hash[KW_HASH_SIZE];
static struct symbol **sym_hash;
static int allow_new_symbols;
-static int cf_lino;
static int default_counter;
+int conf_lino;
+
static int cf_hash(byte *c);
static struct symbol *cf_find_sym(byte *c, unsigned int h0);
@@ -121,11 +121,11 @@ WHITE [ \t]
{WHITE}+
\\\n {
- cf_lino++;
+ conf_lino++;
}
\n {
- cf_lino++;
+ conf_lino++;
return ';';
}
@@ -136,14 +136,14 @@ WHITE [ \t]
. cf_error("Unknown character");
<COMMENT>\n {
- cf_lino++;
+ conf_lino++;
BEGIN(INITIAL);
}
<COMMENT>.
<CCOMM>\*\/ BEGIN(INITIAL);
-<CCOMM>\n cf_lino++;
+<CCOMM>\n conf_lino++;
<CCOMM>\/\* cf_error("Comment nesting not supported");
<CCOMM><<EOF>> cf_error("Unterminated comment");
<CCOMM>.
@@ -206,7 +206,7 @@ cf_lex_init(int flag)
{
if (allow_new_symbols = flag)
sym_hash = cfg_allocz(SYM_HASH_SIZE * sizeof(struct keyword *));
- cf_lino = 1;
+ conf_lino = 1;
default_counter = 1;
}
@@ -222,34 +222,3 @@ cf_lex_init_tables(void)
kw_hash[h] = k;
}
}
-
-void
-cf_error(char *msg, ...)
-{
- /* FIXME */
-
- char buf[1024];
- va_list args;
-
- va_start(args, msg);
- bvsprintf(buf, msg, args);
- die(PATH_CONFIG ", line %d: %s", cf_lino, buf);
-}
-
-void
-cf_allocate(void)
-{
- if (cfg_pool)
- rfree(cfg_pool);
- cfg_pool = rp_new(&root_pool, "Config");
- cfg_mem = lp_new(cfg_pool, 1024);
-}
-
-char *
-cfg_strdup(char *c)
-{
- int l = strlen(c) + 1;
- char *z = cfg_allocu(l);
- memcpy(z, c, l);
- return z;
-}
diff --git a/conf/conf.c b/conf/conf.c
new file mode 100644
index 00000000..06cd3d19
--- /dev/null
+++ b/conf/conf.c
@@ -0,0 +1,96 @@
+/*
+ * BIRD Internet Routing Daemon -- Configuration File Handling
+ *
+ * (c) 1999 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <setjmp.h>
+#include <stdarg.h>
+
+#include "nest/bird.h"
+#include "nest/protocol.h"
+#include "nest/iface.h"
+#include "lib/resource.h"
+#include "lib/string.h"
+#include "conf/conf.h"
+#include "filter/filter.h"
+
+static jmp_buf conf_jmpbuf;
+
+struct config *config, *new_config;
+
+struct config *
+config_alloc(byte *name)
+{
+ pool *p = rp_new(&root_pool, "Config");
+ linpool *l = lp_new(p, 1024);
+ struct config *c = lp_allocz(l, sizeof(struct config));
+
+ c->pool = p;
+ cfg_mem = c->mem = l;
+ init_list(&c->protos);
+ c->file_name = cfg_strdup(name);
+ return c;
+}
+
+int
+config_parse(struct config *c)
+{
+ struct proto_config *p;
+
+ debug("Parsing configuration file <%s>\n", c->file_name);
+ new_config = c;
+ cfg_pool = c->pool;
+ cfg_mem = c->mem;
+ if (setjmp(conf_jmpbuf))
+ return 0;
+ cf_lex_init(1);
+ cf_lex_init_tables();
+ protos_preconfig(c);
+ cf_parse();
+#if 0 /* FIXME: We don't have interface list yet :( */
+ if (!c->router_id && !(c->router_id = auto_router_id()))
+ cf_error("Cannot determine router ID (no suitable network interface found), please configure it manually");
+#endif
+ filters_postconfig(); /* FIXME: Do we really need this? */
+ protos_postconfig(c);
+ return 1;
+}
+
+void
+config_free(struct config *c)
+{
+ rfree(c->pool);
+}
+
+void
+config_commit(struct config *c)
+{
+ config = c;
+ protos_commit(c);
+}
+
+void
+cf_error(char *msg, ...)
+{
+ char buf[1024];
+ va_list args;
+
+ va_start(args, msg);
+ if (bvsnprintf(buf, sizeof(buf), msg, args) < 0)
+ strcpy(buf, "<bug: error message too long>");
+ new_config->err_msg = cfg_strdup(buf);
+ new_config->err_lino = conf_lino;
+ longjmp(conf_jmpbuf, 1);
+}
+
+char *
+cfg_strdup(char *c)
+{
+ int l = strlen(c) + 1;
+ char *z = cfg_allocu(l);
+ memcpy(z, c, l);
+ return z;
+}
diff --git a/conf/conf.h b/conf/conf.h
index 19ed34e9..54f5d5eb 100644
--- a/conf/conf.h
+++ b/conf/conf.h
@@ -1,7 +1,7 @@
/*
* BIRD Internet Routing Daemon -- Configuration File Handling
*
- * (c) 1998 Martin Mares <mj@ucw.cz>
+ * (c) 1998--1999 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
@@ -11,6 +11,28 @@
#include "lib/resource.h"
+/* Configuration structure */
+
+struct config {
+ pool *pool; /* Pool the configuration is stored in */
+ linpool *mem; /* Linear pool containing configuration data */
+ list protos; /* Configured protocol instances (struct proto_config) */
+ u32 router_id; /* Our Router ID */
+ u16 this_as; /* Our Autonomous System Number */
+ char *err_msg; /* Parser error message */
+ int err_lino; /* Line containing error */
+ char *file_name; /* Name of configuration file */
+};
+
+extern struct config *config, *new_config;
+/* Please don't use these variables in protocols. Use proto_config->global instead. */
+
+struct config *config_alloc(byte *name);
+int config_parse(struct config *);
+void config_free(struct config *);
+void config_commit(struct config *);
+void cf_error(char *msg, ...) NORET;
+
/* Pools */
extern pool *cfg_pool;
@@ -41,11 +63,11 @@ struct symbol {
#define SYM_FUNCTION 5
#define SYM_FILTER 6
+extern int conf_lino;
+
void cf_lex_init_tables(void);
int cf_lex(void);
void cf_lex_init(int flag);
-void cf_error(char *msg, ...) NORET;
-void cf_allocate(void);
struct symbol *cf_default_name(char *prefix);
/* Parser */
diff --git a/nest/bird.h b/nest/bird.h
index b9c9192b..597e2050 100644
--- a/nest/bird.h
+++ b/nest/bird.h
@@ -1,7 +1,7 @@
/*
* BIRD Internet Routing Daemon -- Basic Declarations
*
- * (c) 1998 Martin Mares <mj@ucw.cz>
+ * (c) 1998--1999 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
@@ -13,7 +13,4 @@
#include "lib/birdlib.h"
#include "lib/ip.h"
-extern u32 router_id; /* Our Router ID */
-extern u16 this_as; /* Our Autonomous System Number */
-
#endif
diff --git a/nest/config.Y b/nest/config.Y
index 98436541..a19cce63 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -1,14 +1,14 @@
/*
* BIRD -- Core Configuration
*
- * (c) 1998 Martin Mares <mj@ucw.cz>
+ * (c) 1998--1999 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
CF_HDR
-static struct proto *this_proto;
+static struct proto_config *this_proto;
#include "nest/rt-dev.h"
@@ -27,7 +27,7 @@ CF_GRAMMAR
CF_ADDTO(conf, rtrid)
rtrid: ROUTER ID idval {
- router_id = $3;
+ new_config->router_id = $3;
}
;
@@ -87,7 +87,7 @@ dev_proto:
dev_iface_list:
INTERFACE TEXT {
- init_list(&((struct rt_dev_proto *) this_proto)->iface_list);
+ init_list(&((struct rt_dev_config *) this_proto)->iface_list);
rt_dev_add_iface($2);
}
| dev_iface_list ',' TEXT { rt_dev_add_iface($3); }
@@ -98,7 +98,7 @@ CF_CODE
void
rt_dev_add_iface(char *n)
{
- struct rt_dev_proto *p = (void *) this_proto;
+ struct rt_dev_config *p = (void *) this_proto;
struct iface_patt *k = cfg_alloc(sizeof(struct iface_patt));
k->pattern = cfg_strdup(n);
diff --git a/nest/iface.c b/nest/iface.c
index ce638d22..2b2af915 100644
--- a/nest/iface.c
+++ b/nest/iface.c
@@ -1,7 +1,7 @@
/*
* BIRD -- Management of Interfaces and Neighbor Cache
*
- * (c) 1998 Martin Mares <mj@ucw.cz>
+ * (c) 1998--1999 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
@@ -16,8 +16,6 @@
static pool *if_pool;
-u32 router_id;
-
/*
* Neighbor Cache
*
@@ -103,7 +101,7 @@ neigh_dump(neighbor *n)
debug("%s ", n->iface->name);
else
debug("[] ");
- debug("%s %p", n->proto->name, n->data);
+ debug("%s %p", n->proto->cf->name, n->data);
if (n->flags & NEF_STICKY)
debug(" STICKY");
debug("\n");
@@ -199,7 +197,6 @@ if_dump_all(void)
debug("Known network interfaces:\n");
WALK_LIST(i, iface_list)
if_dump(i);
- debug("\nRouter ID: %08x\n\n", router_id);
}
static inline int
@@ -322,28 +319,26 @@ if_feed_baby(struct proto *p)
if (!p->if_notify)
return;
- debug("Announcing interfaces to new protocol %s\n", p->name);
+ debug("Announcing interfaces to new protocol %s\n", p->cf->name);
WALK_LIST(i, iface_list)
p->if_notify(p, IF_CHANGE_CREATE | ((i->flags & IF_UP) ? IF_CHANGE_UP : 0), NULL, i);
}
-void
+u32
auto_router_id(void) /* FIXME: What if we run IPv6??? */
{
struct iface *i, *j;
- if (router_id)
- return;
j = NULL;
WALK_LIST(i, iface_list)
if ((i->flags & IF_UP) &&
!(i->flags & (IF_UNNUMBERED | IF_LOOPBACK | IF_IGNORE)) &&
(!j || ipa_to_u32(i->ip) < ipa_to_u32(j->ip)))
j = i;
- if (!j) /* FIXME: allow configuration or running without RID */
- bug("Cannot determine router ID, please configure manually");
- router_id = ipa_to_u32(j->ip);
- debug("Router ID set to %08x (%s)\n", router_id, j->name);
+ if (!j)
+ return 0;
+ debug("Guessed router ID %I (%s)\n", j->ip, j->name);
+ return ipa_to_u32(j->ip);
}
void
diff --git a/nest/iface.h b/nest/iface.h
index a7f90a6e..fd72bf41 100644
--- a/nest/iface.h
+++ b/nest/iface.h
@@ -1,7 +1,7 @@
/*
* BIRD Internet Routing Daemon -- Network Interfaces
*
- * (c) 1998 Martin Mares <mj@ucw.cz>
+ * (c) 1998--1999 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
@@ -54,7 +54,7 @@ void if_dump_all(void);
void if_update(struct iface *);
void if_end_update(void);
void if_feed_baby(struct proto *);
-void auto_router_id(void);
+u32 auto_router_id(void);
/*
* Neighbor Cache. We hold (direct neighbor, protocol) pairs we've seen
diff --git a/nest/proto.c b/nest/proto.c
index cb3113fd..976a967b 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -1,7 +1,7 @@
/*
* BIRD -- Protocols
*
- * (c) 1998 Martin Mares <mj@ucw.cz>
+ * (c) 1998--1999 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
@@ -23,47 +23,83 @@ list proto_list;
list inactive_proto_list;
void *
-proto_new(struct protocol *pr, unsigned size)
+proto_new(struct proto_config *c, unsigned size)
{
- struct proto *p = cfg_allocz(size);
+ struct protocol *pr = c->proto;
+ struct proto *p = cfg_allocz(size); /* FIXME: Allocate from global pool */
- debug("proto_new(%s)\n", pr->name);
+ p->cf = c;
+ p->debug = c->debug;
+ p->preference = c->preference;
+ p->disabled = c->disabled;
p->proto = pr;
- p->name = pr->name;
- p->debug = pr->debug;
- p->pool = rp_new(&root_pool, pr->name);
- add_tail(&inactive_proto_list, &p->n);
+ p->pool = rp_new(&root_pool, c->name);
return p;
}
+void *
+proto_config_new(struct protocol *pr, unsigned size)
+{
+ struct proto_config *c = cfg_allocz(size);
+
+ add_tail(&new_config->protos, &c->n);
+ c->global = new_config;
+ c->proto = pr;
+ c->debug = pr->debug;
+ c->name = pr->name;
+ return c;
+}
+
void
-protos_preconfig(void)
+protos_preconfig(struct config *c)
{
struct protocol *p;
init_list(&proto_list);
init_list(&inactive_proto_list);
- debug("Protocol preconfig\n");
+ debug("Protocol preconfig:");
WALK_LIST(p, protocol_list)
{
- debug("...%s\n", p->name);
+ debug(" %s", p->name);
if (p->preconfig)
- p->preconfig(p);
+ p->preconfig(p, c);
}
+ debug("\n");
}
void
-protos_postconfig(void)
+protos_postconfig(struct config *c)
{
+ struct proto_config *x;
struct protocol *p;
- debug("Protocol postconfig\n");
- WALK_LIST(p, protocol_list)
+ debug("Protocol postconfig:");
+ WALK_LIST(x, c->protos)
{
- debug("...%s\n", p->name);
+ debug(" %s", x->name);
+ p = x->proto;
if (p->postconfig)
- p->postconfig(p);
+ p->postconfig(x);
+ }
+ debug("\n");
+}
+
+void
+protos_commit(struct config *c)
+{
+ struct proto_config *x;
+ struct protocol *p;
+ struct proto *q;
+
+ debug("Protocol commit:");
+ WALK_LIST(x, c->protos)
+ {
+ debug(" %s", x->name);
+ p = x->proto;
+ q = p->init(x);
+ add_tail(&inactive_proto_list, &q->n);
}
+ debug("\n");
}
static void
@@ -72,12 +108,15 @@ proto_start(struct proto *p)
rem_node(&p->n);
if (p->disabled)
return;
- p->state = PRS_STARTING;
- if (p->start)
- p->start(p);
+ p->proto_state = PS_DOWN;
+ p->core_state = FS_HUNGRY;
+ if (p->proto->start && p->proto->start(p) != PS_UP)
+ bug("Delayed protocol start not supported yet");
+ p->proto_state = PS_UP;
+ p->core_state = FS_FEEDING;
if_feed_baby(p);
rt_feed_baby(p);
- p->state = PRS_UP;
+ p->core_state = FS_HAPPY;
add_tail(&proto_list, &p->n);
}
@@ -89,7 +128,7 @@ protos_start(void)
debug("Protocol start\n");
WALK_LIST_DELSAFE(p, n, inactive_proto_list)
{
- debug("...%s\n", p->name);
+ debug("Starting %s\n", p->cf->name);
proto_start(p);
}
}
@@ -98,19 +137,21 @@ void
protos_dump_all(void)
{
struct proto *p;
+ static char *p_states[] = { "DOWN", "START", "UP", "STOP" };
+ static char *c_states[] = { "HUNGRY", "FEEDING", "HAPPY", "FLUSHING" };
debug("Protocols:\n");
WALK_LIST(p, proto_list)
{
- debug(" protocol %s:\n", p->name);
+ debug(" protocol %s: state %s/%s\n", p->cf->name, p_states[p->proto_state], c_states[p->core_state]);
if (p->disabled)
debug("\tDISABLED\n");
- else if (p->dump)
- p->dump(p);
+ else if (p->proto->dump)
+ p->proto->dump(p);
}
WALK_LIST(p, inactive_proto_list)
- debug(" inactive %s\n", p->name);
+ debug(" inactive %s\n", p->cf->name);
}
void
@@ -125,14 +166,3 @@ protos_build(void)
add_tail(&protocol_list, &proto_static.n);
#endif
}
-
-void
-protos_init(void)
-{
- struct protocol *p;
-
- debug("Initializing protocols\n");
- WALK_LIST(p, protocol_list)
- if (p->init)
- p->init(p);
-}
diff --git a/nest/protocol.h b/nest/protocol.h
index f516f0f2..c9720608 100644
--- a/nest/protocol.h
+++ b/nest/protocol.h
@@ -1,7 +1,7 @@
/*
* BIRD Internet Routing Daemon -- Protocols
*
- * (c) 1998 Martin Mares <mj@ucw.cz>
+ * (c) 1998--1999 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
@@ -17,6 +17,9 @@ struct rte;
struct neighbor;
struct rtattr;
struct network;
+struct proto_config;
+struct config;
+struct proto;
/*
* Routing Protocol
@@ -27,15 +30,19 @@ struct protocol {
char *name;
unsigned debug; /* Default debugging flags */
- void (*init)(struct protocol *); /* Boot time */
- void (*preconfig)(struct protocol *); /* Just before configuring */
- void (*postconfig)(struct protocol *); /* After configuring */
+ void (*preconfig)(struct protocol *, struct config *); /* Just before configuring */
+ void (*postconfig)(struct proto_config *); /* After configuring each instance */
+ struct proto * (*init)(struct proto_config *); /* Create new instance */
+ int (*reconfigure)(struct proto *, struct proto_config *); /* Try to reconfigure instance */
+ void (*dump)(struct proto *); /* Debugging dump */
+ int (*start)(struct proto *); /* Start the instance */
+ int (*shutdown)(struct proto *); /* Stop the instance */
};
void protos_build(void);
-void protos_init(void);
-void protos_preconfig(void);
-void protos_postconfig(void);
+void protos_preconfig(struct config *);
+void protos_postconfig(struct config *);
+void protos_commit(struct config *);
void protos_start(void);
void protos_dump_all(void);
@@ -53,47 +60,128 @@ extern struct protocol proto_static;
* Routing Protocol Instance
*/
+struct proto_config {
+ node n;
+ struct config *global; /* Global configuration data */
+ struct protocol *proto; /* Protocol */
+ char *name;
+ unsigned debug, preference, disabled; /* Generic parameters */
+
+ /* Protocol-specific data follow... */
+};
+
struct proto {
node n;
struct protocol *proto; /* Protocol */
- char *name; /* Name of this instance */
+ struct proto_config *cf; /* Configuration data */
+ pool *pool; /* Pool containing local objects */
+
unsigned debug; /* Debugging flags */
- pool *pool; /* Local objects */
unsigned preference; /* Default route preference */
- unsigned state; /* PRS_... */
unsigned disabled; /* Manually disabled */
+ unsigned proto_state; /* Protocol state machine (see below) */
+ unsigned core_state; /* Core state machine (see below) */
void (*if_notify)(struct proto *, unsigned flags, struct iface *new, struct iface *old);
void (*rt_notify)(struct proto *, struct network *net, struct rte *new, struct rte *old);
void (*neigh_notify)(struct neighbor *neigh);
- void (*dump)(struct proto *); /* Debugging dump */
- void (*start)(struct proto *); /* Start the instance */
- void (*shutdown)(struct proto *, int time); /* Stop the instance */
int (*rta_same)(struct rtattr *, struct rtattr *);
int (*rte_better)(struct rte *, struct rte *);
void (*rte_insert)(struct network *, struct rte *);
void (*rte_remove)(struct network *, struct rte *);
- /* Reconfigure function? */
/* Input/output filters */
/* Connection to routing tables? */
/* Hic sunt protocol-specific data */
};
-#define PRS_DOWN 0 /* Inactive */
-#define PRS_STARTING 1
-#define PRS_UP 2
-
-void *proto_new(struct protocol *, unsigned size);
+void proto_build(struct proto_config *);
+void *proto_new(struct proto_config *, unsigned size);
+void *proto_config_new(struct protocol *, unsigned size);
extern list proto_list, inactive_proto_list;
/*
+ * Each protocol instance runs two different state machines:
+ *
+ * [P] The protocol machine: (implemented inside protocol)
+ *
+ * DOWN ----> START
+ * ^ |
+ * | V
+ * STOP <---- UP
+ *
+ * States: DOWN Protocol is down and it's waiting for the core
+ * requesting protocol start.
+ * START Protocol is waiting for connection with the rest
+ * of the network and it's not willing to accept
+ * packets. When it connects, it goes to UP state.
+ * UP Protocol is up and running. When the network
+ * connection breaks down or the core requests
+ * protocol to be terminated, it goes to STOP state.
+ * STOP Protocol is disconnecting from the network.
+ * After it disconnects, it returns to DOWN state.
+ *
+ * In: start() Called in DOWN state to request protocol startup.
+ * Returns new state: either UP or START (in this
+ * case, the protocol will notify the core when it
+ * finally comes UP).
+ * stop() Called in START, UP or STOP state to request
+ * protocol shutdown. Returns new state: either
+ * DOWN or STOP (in this case, the protocol will
+ * notify the core when it finally comes DOWN).
+ *
+ * Out: proto_notify_state() -- called by protocol instance when
+ * it does any state transition not covered by
+ * return values of start() and stop(). This includes
+ * START->UP (delayed protocol startup), UP->STOP
+ * (spontaneous shutdown) and STOP->DOWN (delayed
+ * shutdown).
+ */
+
+#define PS_DOWN 0
+#define PS_START 1
+#define PS_UP 2
+#define PS_STOP 3
+
+void proto_notify_state(struct proto *p, unsigned state);
+
+/*
+ * [F] The feeder machine: (implemented in core routines)
+ *
+ * HUNGRY ----> FEEDING
+ * ^ |
+ * | V
+ * FLUSHING <---- HAPPY
+ *
+ * States: HUNGRY Protocol either administratively down (i.e.,
+ * disabled by the user) or temporarily down
+ * (i.e., [P] is not UP)
+ * FEEDING The protocol came up and we're feeding it
+ * initial routes. [P] is UP.
+ * HAPPY The protocol is up and it's receiving normal
+ * routing updates. [P] is UP.
+ * FLUSHING The protocol is down and we're removing its
+ * routes from the table. [P] is STOP or DOWN.
+ *
+ * Normal lifecycle of a protocol looks like:
+ *
+ * HUNGRY/DOWN --> HUNGRY/START --> HUNGRY/UP -->
+ * FEEDING/UP --> HAPPY/UP --> FLUSHING/STOP|DOWN -->
+ * HUNGRY/STOP|DOWN --> HUNGRY/DOWN
+ */
+
+#define FS_HUNGRY 0
+#define FS_FEEDING 1
+#define FS_HAPPY 2
+#define FS_FLUSHING 3
+
+/*
* Known unique protocol instances as referenced by config routines
*/
-extern struct proto *cf_dev_proto;
+extern struct proto_config *cf_dev_proto;
#endif
diff --git a/nest/rt-attr.c b/nest/rt-attr.c
index aa4a59ad..129ec0ce 100644
--- a/nest/rt-attr.c
+++ b/nest/rt-attr.c
@@ -139,7 +139,7 @@ rta_dump(rta *a)
static char *rtd[] = { "", " DEV", " HOLE", " UNREACH", " PROHIBIT" };
debug("p=%s uc=%d %s %s%s%s TOS=%d",
- a->proto->name, a->uc, rts[a->source], sco[a->scope], rtc[a->cast],
+ a->proto->cf->name, a->uc, rts[a->source], sco[a->scope], rtc[a->cast],
rtd[a->dest], a->tos);
if (a->flags & RTF_EXTERIOR)
debug(" EXT");
diff --git a/nest/rt-dev.c b/nest/rt-dev.c
index e7d43fb1..b6e8d708 100644
--- a/nest/rt-dev.c
+++ b/nest/rt-dev.c
@@ -1,7 +1,7 @@
/*
* BIRD -- Direct Device Routes
*
- * (c) 1998 Martin Mares <mj@ucw.cz>
+ * (c) 1998--1999 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
@@ -18,12 +18,12 @@
#include "conf/conf.h"
#include "lib/resource.h"
-struct proto *cf_dev_proto;
+struct proto_config *cf_dev_proto;
static void
dev_if_notify(struct proto *p, unsigned c, struct iface *old, struct iface *new)
{
- struct rt_dev_proto *P = (void *) p;
+ struct rt_dev_config *P = (void *) p->cf;
if (old && !iface_patt_match(&P->iface_list, old) ||
new && !iface_patt_match(&P->iface_list, new))
@@ -68,42 +68,30 @@ dev_if_notify(struct proto *p, unsigned c, struct iface *old, struct iface *new)
}
}
-static void
-dev_start(struct proto *p)
+static struct proto *
+dev_init(struct proto_config *c)
{
-}
+ struct proto *p = proto_new(c, sizeof(struct proto));
-static void
-dev_init(struct protocol *p)
-{
+ p->if_notify = dev_if_notify;
+ return p;
}
static void
-dev_preconfig(struct protocol *x)
+dev_preconfig(struct protocol *x, struct config *c)
{
- struct rt_dev_proto *P = proto_new(&proto_device, sizeof(struct rt_dev_proto));
- struct proto *p = &P->p;
+ struct rt_dev_config *p = proto_config_new(&proto_device, sizeof(struct rt_dev_config));
struct iface_patt *k = cfg_alloc(sizeof(struct iface_patt));
- cf_dev_proto = p;
- p->preference = DEF_PREF_DIRECT;
- p->start = dev_start;
- p->if_notify = dev_if_notify;
- init_list(&P->iface_list);
+ cf_dev_proto = &p->c;
+ p->c.preference = DEF_PREF_DIRECT;
+ init_list(&p->iface_list);
k->pattern = "*";
- add_tail(&P->iface_list, &k->n);
-}
-
-static void
-dev_postconfig(struct protocol *p)
-{
+ add_tail(&p->iface_list, &k->n);
}
struct protocol proto_device = {
- { NULL, NULL },
- "Device",
- 0,
- dev_init,
- dev_preconfig,
- dev_postconfig
+ name: "Device",
+ preconfig: dev_preconfig,
+ init: dev_init,
};
diff --git a/nest/rt-dev.h b/nest/rt-dev.h
index 05a7f4c6..64f2cd95 100644
--- a/nest/rt-dev.h
+++ b/nest/rt-dev.h
@@ -1,7 +1,7 @@
/*
* BIRD -- Direct Device Routes
*
- * (c) 1998 Martin Mares <mj@ucw.cz>
+ * (c) 1998--1999 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
@@ -9,8 +9,8 @@
#ifndef _BIRD_RT_DEV_H_
#define _BIRD_RT_DEV_H_
-struct rt_dev_proto {
- struct proto p;
+struct rt_dev_config {
+ struct proto_config c;
list iface_list;
};
diff --git a/nest/rt-table.c b/nest/rt-table.c
index 0ccb8da6..916f887d 100644
--- a/nest/rt-table.c
+++ b/nest/rt-table.c
@@ -121,7 +121,7 @@ rt_feed_baby(struct proto *p)
if (!p->rt_notify)
return;
- debug("Announcing routes to new protocol %s\n", p->name);
+ debug("Announcing routes to new protocol %s\n", p->cf->name);
while (t)
{
FIB_WALK(&t->fib, fn)
diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c
index bea479c1..96e6cf91 100644
--- a/sysdep/unix/main.c
+++ b/sysdep/unix/main.c
@@ -1,7 +1,7 @@
/*
* BIRD Internet Routing Daemon -- Unix Entry Point
*
- * (c) 1998 Martin Mares <mj@ucw.cz>
+ * (c) 1998--1999 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
@@ -74,18 +74,17 @@ cf_read(byte *dest, unsigned int len)
static void
read_config(void)
{
- cf_lex_init_tables();
- cf_allocate();
+ struct config *conf = config_alloc(PATH_CONFIG);
+
conf_fd = open(PATH_CONFIG, O_RDONLY);
if (conf_fd < 0)
die("Unable to open configuration file " PATH_CONFIG ": %m");
- protos_preconfig();
cf_read_hook = cf_read;
- cf_lex_init(1);
- cf_parse();
- filters_postconfig();
- protos_postconfig();
+ if (!config_parse(conf))
+ die(PATH_CONFIG ", line %d: %s", conf->err_lino, conf->err_msg);
+ config_commit(conf);
}
+
/*
* Hic Est main()
*/
@@ -105,15 +104,12 @@ main(void)
protos_build();
add_tail(&protocol_list, &proto_unix_kernel.n);
- protos_init();
- debug("Reading configuration file.\n");
read_config();
signal_init();
scan_if_init();
- auto_router_id();
protos_start();