]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Implemented new configuration/reconfiguration interface and defined protocol
authorMartin Mares <mj@ucw.cz>
Fri, 5 Feb 1999 21:37:34 +0000 (21:37 +0000)
committerMartin Mares <mj@ucw.cz>
Fri, 5 Feb 1999 21:37:34 +0000 (21:37 +0000)
state machines. Full explanation will follow soon.

16 files changed:
TODO
conf/Makefile
conf/cf-lex.l
conf/conf.c [new file with mode: 0644]
conf/conf.h
nest/bird.h
nest/config.Y
nest/iface.c
nest/iface.h
nest/proto.c
nest/protocol.h
nest/rt-attr.c
nest/rt-dev.c
nest/rt-dev.h
nest/rt-table.c
sysdep/unix/main.c

diff --git a/TODO b/TODO
index 9fbf2d5223ac369da8abf4b4bb6710de7936a5f9..f681997ccc31ed7b6bc239daec8f29cbb5bad0e2 100644 (file)
--- 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?
index 270d556737f1ecbab47aa8720facb6c3e636a7a7..fdcd4c381971e7646933459f55738a2fde8fa9f1 100644 (file)
@@ -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
index 81e3b6a26265e33170073d8e64fa33246060d689..791d4adcc9eebfff95ce31f5daee53e23e019045 100644 (file)
@@ -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 (file)
index 0000000..06cd3d1
--- /dev/null
@@ -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;
+}
index 19ed34e9504fa294240fb30bd2e4ea3ad4f0e57d..54f5d5ebd3726f09e773a4a91a5717f6d22f5a3b 100644 (file)
@@ -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.
  */
 
 #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 */
index b9c9192beb8da338f3a4fb200392a562ddbd8e28..597e2050a2454009e93c384cdfbe042757e98490 100644 (file)
@@ -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
index 984365416a5ac4b08f7a58b8b0cc18fa612f9e01..a19cce63944ef24ea5735e17dbd52e2f6150c595 100644 (file)
@@ -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);
index ce638d2200d606935383d08664658a785211fcff..2b2af915a91507145582d7458cf0c731a39264a9 100644 (file)
@@ -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
index a7f90a6eb74332e481ffeb3d5885ea589a867298..fd72bf41b1058a323ebc8d97ace918d2c4d9f205 100644 (file)
@@ -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
index cb3113fd1bd471933541cd09873c78c905f96ead..976a967bd152614eddf720d45754e0e4fa6986f6 100644 (file)
@@ -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);
-}
index f516f0f212dc233a9c9b3e2f6e84d92a26190c69..c97206084093204ff493095232f08d2c8ac1b2c3 100644 (file)
@@ -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
index aa4a59ad5f497f7c2374d68e2d12da060eab447b..129ec0cef9d2c674b0e09faa4d61196ea5893cd5 100644 (file)
@@ -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");
index e7d43fb13c80e935dc0d1a47688643e03c7f2916..b6e8d7082df7349560146a1e2b9a35ebd643695f 100644 (file)
@@ -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.
  */
 #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,
 };
index 05a7f4c6d4d0ece361a4dd7b7194516122439751..64f2cd95e010d2b10338a36f74a0eec0d1e3dac5 100644 (file)
@@ -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;
 };
 
index 0ccb8da6d0117ce9275fd5d4f9955eff396618e4..916f887d38684422bd82ca4014d902e1c226f0d2 100644 (file)
@@ -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)
index bea479c1ae077faaf7c7fc287db1248b59d7016e..96e6cf91db6f7f4d83a63928dd040bdfa1948bd4 100644 (file)
@@ -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();