From 31b3e1bbf5bc823ec5cf6d88931132f00e6c52b9 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Fri, 5 Feb 1999 21:37:34 +0000 Subject: [PATCH] Implemented new configuration/reconfiguration interface and defined protocol state machines. Full explanation will follow soon. --- TODO | 3 ++ conf/Makefile | 2 +- conf/cf-lex.l | 47 +++-------------- conf/conf.c | 96 ++++++++++++++++++++++++++++++++++ conf/conf.h | 28 ++++++++-- nest/bird.h | 5 +- nest/config.Y | 10 ++-- nest/iface.c | 21 +++----- nest/iface.h | 4 +- nest/proto.c | 104 +++++++++++++++++++++++------------- nest/protocol.h | 128 ++++++++++++++++++++++++++++++++++++++------- nest/rt-attr.c | 2 +- nest/rt-dev.c | 48 +++++++---------- nest/rt-dev.h | 6 +-- nest/rt-table.c | 2 +- sysdep/unix/main.c | 18 +++---- 16 files changed, 354 insertions(+), 170 deletions(-) create mode 100644 conf/conf.c 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 + * (c) 1998--1999 Martin Mares * * Can be freely distributed and used under the terms of the GNU GPL. */ @@ -15,7 +15,6 @@ #include #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"); \n { - cf_lino++; + conf_lino++; BEGIN(INITIAL); } . \*\/ BEGIN(INITIAL); -\n cf_lino++; +\n conf_lino++; \/\* cf_error("Comment nesting not supported"); <> cf_error("Unterminated comment"); . @@ -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 + * + * Can be freely distributed and used under the terms of the GNU GPL. + */ + +#include +#include + +#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, ""); + 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 + * (c) 1998--1999 Martin Mares * * 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 + * (c) 1998--1999 Martin Mares * * 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 + * (c) 1998--1999 Martin Mares * * 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 + * (c) 1998--1999 Martin Mares * * 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 + * (c) 1998--1999 Martin Mares * * 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 + * (c) 1998--1999 Martin Mares * * 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 + * (c) 1998--1999 Martin Mares * * 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 + * (c) 1998--1999 Martin Mares * * 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)); + + p->if_notify = dev_if_notify; + return p; } static void -dev_init(struct protocol *p) +dev_preconfig(struct protocol *x, struct config *c) { -} - -static void -dev_preconfig(struct protocol *x) -{ - 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 + * (c) 1998--1999 Martin Mares * * 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 + * (c) 1998--1999 Martin Mares * * 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();