0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 09:41:54 +00:00

Implemented new configuration/reconfiguration interface and defined protocol

state machines. Full explanation will follow soon.
This commit is contained in:
Martin Mares 1999-02-05 21:37:34 +00:00
parent c4c63eecc3
commit 31b3e1bbf5
16 changed files with 354 additions and 170 deletions

3
TODO
View File

@ -6,6 +6,9 @@ Core
* logging and tracing; use appropriate log levels * logging and tracing; use appropriate log levels
* check log calls for trailing newlines * 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 - TOS not supported by kernel -> automatically drop routes with TOS<>0
- fake multipath? - fake multipath?

View 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=../ root-rel=../
include ../Rules include ../Rules

View File

@ -1,7 +1,7 @@
/* /*
* BIRD -- Configuration Lexer * 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. * Can be freely distributed and used under the terms of the GNU GPL.
*/ */
@ -15,7 +15,6 @@
#include <stdarg.h> #include <stdarg.h>
#include "nest/bird.h" #include "nest/bird.h"
#include "lib/string.h"
#include "conf/conf.h" #include "conf/conf.h"
#include "conf/cf-parse.tab.h" #include "conf/cf-parse.tab.h"
@ -34,9 +33,10 @@ static struct keyword {
static struct keyword *kw_hash[KW_HASH_SIZE]; static struct keyword *kw_hash[KW_HASH_SIZE];
static struct symbol **sym_hash; static struct symbol **sym_hash;
static int allow_new_symbols; static int allow_new_symbols;
static int cf_lino;
static int default_counter; static int default_counter;
int conf_lino;
static int cf_hash(byte *c); static int cf_hash(byte *c);
static struct symbol *cf_find_sym(byte *c, unsigned int h0); static struct symbol *cf_find_sym(byte *c, unsigned int h0);
@ -121,11 +121,11 @@ WHITE [ \t]
{WHITE}+ {WHITE}+
\\\n { \\\n {
cf_lino++; conf_lino++;
} }
\n { \n {
cf_lino++; conf_lino++;
return ';'; return ';';
} }
@ -136,14 +136,14 @@ WHITE [ \t]
. cf_error("Unknown character"); . cf_error("Unknown character");
<COMMENT>\n { <COMMENT>\n {
cf_lino++; conf_lino++;
BEGIN(INITIAL); BEGIN(INITIAL);
} }
<COMMENT>. <COMMENT>.
<CCOMM>\*\/ BEGIN(INITIAL); <CCOMM>\*\/ BEGIN(INITIAL);
<CCOMM>\n cf_lino++; <CCOMM>\n conf_lino++;
<CCOMM>\/\* cf_error("Comment nesting not supported"); <CCOMM>\/\* cf_error("Comment nesting not supported");
<CCOMM><<EOF>> cf_error("Unterminated comment"); <CCOMM><<EOF>> cf_error("Unterminated comment");
<CCOMM>. <CCOMM>.
@ -206,7 +206,7 @@ cf_lex_init(int flag)
{ {
if (allow_new_symbols = flag) if (allow_new_symbols = flag)
sym_hash = cfg_allocz(SYM_HASH_SIZE * sizeof(struct keyword *)); sym_hash = cfg_allocz(SYM_HASH_SIZE * sizeof(struct keyword *));
cf_lino = 1; conf_lino = 1;
default_counter = 1; default_counter = 1;
} }
@ -222,34 +222,3 @@ cf_lex_init_tables(void)
kw_hash[h] = k; 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;
}

96
conf/conf.c Normal file
View File

@ -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;
}

View File

@ -1,7 +1,7 @@
/* /*
* BIRD Internet Routing Daemon -- Configuration File Handling * 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. * Can be freely distributed and used under the terms of the GNU GPL.
*/ */
@ -11,6 +11,28 @@
#include "lib/resource.h" #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 */ /* Pools */
extern pool *cfg_pool; extern pool *cfg_pool;
@ -41,11 +63,11 @@ struct symbol {
#define SYM_FUNCTION 5 #define SYM_FUNCTION 5
#define SYM_FILTER 6 #define SYM_FILTER 6
extern int conf_lino;
void cf_lex_init_tables(void); void cf_lex_init_tables(void);
int cf_lex(void); int cf_lex(void);
void cf_lex_init(int flag); void cf_lex_init(int flag);
void cf_error(char *msg, ...) NORET;
void cf_allocate(void);
struct symbol *cf_default_name(char *prefix); struct symbol *cf_default_name(char *prefix);
/* Parser */ /* Parser */

View File

@ -1,7 +1,7 @@
/* /*
* BIRD Internet Routing Daemon -- Basic Declarations * 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. * Can be freely distributed and used under the terms of the GNU GPL.
*/ */
@ -13,7 +13,4 @@
#include "lib/birdlib.h" #include "lib/birdlib.h"
#include "lib/ip.h" #include "lib/ip.h"
extern u32 router_id; /* Our Router ID */
extern u16 this_as; /* Our Autonomous System Number */
#endif #endif

View File

@ -1,14 +1,14 @@
/* /*
* BIRD -- Core Configuration * 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. * Can be freely distributed and used under the terms of the GNU GPL.
*/ */
CF_HDR CF_HDR
static struct proto *this_proto; static struct proto_config *this_proto;
#include "nest/rt-dev.h" #include "nest/rt-dev.h"
@ -27,7 +27,7 @@ CF_GRAMMAR
CF_ADDTO(conf, rtrid) CF_ADDTO(conf, rtrid)
rtrid: ROUTER ID idval { rtrid: ROUTER ID idval {
router_id = $3; new_config->router_id = $3;
} }
; ;
@ -87,7 +87,7 @@ dev_proto:
dev_iface_list: dev_iface_list:
INTERFACE TEXT { 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); rt_dev_add_iface($2);
} }
| dev_iface_list ',' TEXT { rt_dev_add_iface($3); } | dev_iface_list ',' TEXT { rt_dev_add_iface($3); }
@ -98,7 +98,7 @@ CF_CODE
void void
rt_dev_add_iface(char *n) 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)); struct iface_patt *k = cfg_alloc(sizeof(struct iface_patt));
k->pattern = cfg_strdup(n); k->pattern = cfg_strdup(n);

View File

@ -1,7 +1,7 @@
/* /*
* BIRD -- Management of Interfaces and Neighbor Cache * 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. * Can be freely distributed and used under the terms of the GNU GPL.
*/ */
@ -16,8 +16,6 @@
static pool *if_pool; static pool *if_pool;
u32 router_id;
/* /*
* Neighbor Cache * Neighbor Cache
* *
@ -103,7 +101,7 @@ neigh_dump(neighbor *n)
debug("%s ", n->iface->name); debug("%s ", n->iface->name);
else else
debug("[] "); debug("[] ");
debug("%s %p", n->proto->name, n->data); debug("%s %p", n->proto->cf->name, n->data);
if (n->flags & NEF_STICKY) if (n->flags & NEF_STICKY)
debug(" STICKY"); debug(" STICKY");
debug("\n"); debug("\n");
@ -199,7 +197,6 @@ if_dump_all(void)
debug("Known network interfaces:\n"); debug("Known network interfaces:\n");
WALK_LIST(i, iface_list) WALK_LIST(i, iface_list)
if_dump(i); if_dump(i);
debug("\nRouter ID: %08x\n\n", router_id);
} }
static inline int static inline int
@ -322,28 +319,26 @@ if_feed_baby(struct proto *p)
if (!p->if_notify) if (!p->if_notify)
return; 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) WALK_LIST(i, iface_list)
p->if_notify(p, IF_CHANGE_CREATE | ((i->flags & IF_UP) ? IF_CHANGE_UP : 0), NULL, i); 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??? */ auto_router_id(void) /* FIXME: What if we run IPv6??? */
{ {
struct iface *i, *j; struct iface *i, *j;
if (router_id)
return;
j = NULL; j = NULL;
WALK_LIST(i, iface_list) WALK_LIST(i, iface_list)
if ((i->flags & IF_UP) && if ((i->flags & IF_UP) &&
!(i->flags & (IF_UNNUMBERED | IF_LOOPBACK | IF_IGNORE)) && !(i->flags & (IF_UNNUMBERED | IF_LOOPBACK | IF_IGNORE)) &&
(!j || ipa_to_u32(i->ip) < ipa_to_u32(j->ip))) (!j || ipa_to_u32(i->ip) < ipa_to_u32(j->ip)))
j = i; j = i;
if (!j) /* FIXME: allow configuration or running without RID */ if (!j)
bug("Cannot determine router ID, please configure manually"); return 0;
router_id = ipa_to_u32(j->ip); debug("Guessed router ID %I (%s)\n", j->ip, j->name);
debug("Router ID set to %08x (%s)\n", router_id, j->name); return ipa_to_u32(j->ip);
} }
void void

View File

@ -1,7 +1,7 @@
/* /*
* BIRD Internet Routing Daemon -- Network Interfaces * 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. * 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_update(struct iface *);
void if_end_update(void); void if_end_update(void);
void if_feed_baby(struct proto *); 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 * Neighbor Cache. We hold (direct neighbor, protocol) pairs we've seen

View File

@ -1,7 +1,7 @@
/* /*
* BIRD -- Protocols * 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. * Can be freely distributed and used under the terms of the GNU GPL.
*/ */
@ -23,47 +23,83 @@ list proto_list;
list inactive_proto_list; list inactive_proto_list;
void * 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->proto = pr;
p->name = pr->name; p->pool = rp_new(&root_pool, c->name);
p->debug = pr->debug;
p->pool = rp_new(&root_pool, pr->name);
add_tail(&inactive_proto_list, &p->n);
return p; 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 void
protos_preconfig(void) protos_preconfig(struct config *c)
{ {
struct protocol *p; struct protocol *p;
init_list(&proto_list); init_list(&proto_list);
init_list(&inactive_proto_list); init_list(&inactive_proto_list);
debug("Protocol preconfig\n"); debug("Protocol preconfig:");
WALK_LIST(p, protocol_list) WALK_LIST(p, protocol_list)
{ {
debug("...%s\n", p->name); debug(" %s", p->name);
if (p->preconfig) if (p->preconfig)
p->preconfig(p); p->preconfig(p, c);
} }
debug("\n");
} }
void void
protos_postconfig(void) protos_postconfig(struct config *c)
{ {
struct proto_config *x;
struct protocol *p; struct protocol *p;
debug("Protocol postconfig\n"); debug("Protocol postconfig:");
WALK_LIST(p, protocol_list) WALK_LIST(x, c->protos)
{ {
debug("...%s\n", p->name); debug(" %s", x->name);
p = x->proto;
if (p->postconfig) 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 static void
@ -72,12 +108,15 @@ proto_start(struct proto *p)
rem_node(&p->n); rem_node(&p->n);
if (p->disabled) if (p->disabled)
return; return;
p->state = PRS_STARTING; p->proto_state = PS_DOWN;
if (p->start) p->core_state = FS_HUNGRY;
p->start(p); 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); if_feed_baby(p);
rt_feed_baby(p); rt_feed_baby(p);
p->state = PRS_UP; p->core_state = FS_HAPPY;
add_tail(&proto_list, &p->n); add_tail(&proto_list, &p->n);
} }
@ -89,7 +128,7 @@ protos_start(void)
debug("Protocol start\n"); debug("Protocol start\n");
WALK_LIST_DELSAFE(p, n, inactive_proto_list) WALK_LIST_DELSAFE(p, n, inactive_proto_list)
{ {
debug("...%s\n", p->name); debug("Starting %s\n", p->cf->name);
proto_start(p); proto_start(p);
} }
} }
@ -98,19 +137,21 @@ void
protos_dump_all(void) protos_dump_all(void)
{ {
struct proto *p; struct proto *p;
static char *p_states[] = { "DOWN", "START", "UP", "STOP" };
static char *c_states[] = { "HUNGRY", "FEEDING", "HAPPY", "FLUSHING" };
debug("Protocols:\n"); debug("Protocols:\n");
WALK_LIST(p, proto_list) 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) if (p->disabled)
debug("\tDISABLED\n"); debug("\tDISABLED\n");
else if (p->dump) else if (p->proto->dump)
p->dump(p); p->proto->dump(p);
} }
WALK_LIST(p, inactive_proto_list) WALK_LIST(p, inactive_proto_list)
debug(" inactive %s\n", p->name); debug(" inactive %s\n", p->cf->name);
} }
void void
@ -125,14 +166,3 @@ protos_build(void)
add_tail(&protocol_list, &proto_static.n); add_tail(&protocol_list, &proto_static.n);
#endif #endif
} }
void
protos_init(void)
{
struct protocol *p;
debug("Initializing protocols\n");
WALK_LIST(p, protocol_list)
if (p->init)
p->init(p);
}

View File

@ -1,7 +1,7 @@
/* /*
* BIRD Internet Routing Daemon -- Protocols * 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. * Can be freely distributed and used under the terms of the GNU GPL.
*/ */
@ -17,6 +17,9 @@ struct rte;
struct neighbor; struct neighbor;
struct rtattr; struct rtattr;
struct network; struct network;
struct proto_config;
struct config;
struct proto;
/* /*
* Routing Protocol * Routing Protocol
@ -27,15 +30,19 @@ struct protocol {
char *name; char *name;
unsigned debug; /* Default debugging flags */ unsigned debug; /* Default debugging flags */
void (*init)(struct protocol *); /* Boot time */ void (*preconfig)(struct protocol *, struct config *); /* Just before configuring */
void (*preconfig)(struct protocol *); /* Just before configuring */ void (*postconfig)(struct proto_config *); /* After configuring each instance */
void (*postconfig)(struct protocol *); /* After configuring */ 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_build(void);
void protos_init(void); void protos_preconfig(struct config *);
void protos_preconfig(void); void protos_postconfig(struct config *);
void protos_postconfig(void); void protos_commit(struct config *);
void protos_start(void); void protos_start(void);
void protos_dump_all(void); void protos_dump_all(void);
@ -53,47 +60,128 @@ extern struct protocol proto_static;
* Routing Protocol Instance * 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 { struct proto {
node n; node n;
struct protocol *proto; /* Protocol */ 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 */ unsigned debug; /* Debugging flags */
pool *pool; /* Local objects */
unsigned preference; /* Default route preference */ unsigned preference; /* Default route preference */
unsigned state; /* PRS_... */
unsigned disabled; /* Manually disabled */ 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 (*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 (*rt_notify)(struct proto *, struct network *net, struct rte *new, struct rte *old);
void (*neigh_notify)(struct neighbor *neigh); 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 (*rta_same)(struct rtattr *, struct rtattr *);
int (*rte_better)(struct rte *, struct rte *); int (*rte_better)(struct rte *, struct rte *);
void (*rte_insert)(struct network *, struct rte *); void (*rte_insert)(struct network *, struct rte *);
void (*rte_remove)(struct network *, struct rte *); void (*rte_remove)(struct network *, struct rte *);
/* Reconfigure function? */
/* Input/output filters */ /* Input/output filters */
/* Connection to routing tables? */ /* Connection to routing tables? */
/* Hic sunt protocol-specific data */ /* Hic sunt protocol-specific data */
}; };
#define PRS_DOWN 0 /* Inactive */ void proto_build(struct proto_config *);
#define PRS_STARTING 1 void *proto_new(struct proto_config *, unsigned size);
#define PRS_UP 2 void *proto_config_new(struct protocol *, unsigned size);
void *proto_new(struct protocol *, unsigned size);
extern list proto_list, inactive_proto_list; 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 * Known unique protocol instances as referenced by config routines
*/ */
extern struct proto *cf_dev_proto; extern struct proto_config *cf_dev_proto;
#endif #endif

View File

@ -139,7 +139,7 @@ rta_dump(rta *a)
static char *rtd[] = { "", " DEV", " HOLE", " UNREACH", " PROHIBIT" }; static char *rtd[] = { "", " DEV", " HOLE", " UNREACH", " PROHIBIT" };
debug("p=%s uc=%d %s %s%s%s TOS=%d", 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); rtd[a->dest], a->tos);
if (a->flags & RTF_EXTERIOR) if (a->flags & RTF_EXTERIOR)
debug(" EXT"); debug(" EXT");

View File

@ -1,7 +1,7 @@
/* /*
* BIRD -- Direct Device Routes * 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. * Can be freely distributed and used under the terms of the GNU GPL.
*/ */
@ -18,12 +18,12 @@
#include "conf/conf.h" #include "conf/conf.h"
#include "lib/resource.h" #include "lib/resource.h"
struct proto *cf_dev_proto; struct proto_config *cf_dev_proto;
static void static void
dev_if_notify(struct proto *p, unsigned c, struct iface *old, struct iface *new) 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) || if (old && !iface_patt_match(&P->iface_list, old) ||
new && !iface_patt_match(&P->iface_list, new)) 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 static struct proto *
dev_start(struct proto *p) 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 static void
dev_init(struct protocol *p) dev_preconfig(struct protocol *x, struct config *c)
{ {
} struct rt_dev_config *p = proto_config_new(&proto_device, sizeof(struct rt_dev_config));
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 iface_patt *k = cfg_alloc(sizeof(struct iface_patt)); struct iface_patt *k = cfg_alloc(sizeof(struct iface_patt));
cf_dev_proto = p; cf_dev_proto = &p->c;
p->preference = DEF_PREF_DIRECT; p->c.preference = DEF_PREF_DIRECT;
p->start = dev_start; init_list(&p->iface_list);
p->if_notify = dev_if_notify;
init_list(&P->iface_list);
k->pattern = "*"; k->pattern = "*";
add_tail(&P->iface_list, &k->n); add_tail(&p->iface_list, &k->n);
}
static void
dev_postconfig(struct protocol *p)
{
} }
struct protocol proto_device = { struct protocol proto_device = {
{ NULL, NULL }, name: "Device",
"Device", preconfig: dev_preconfig,
0, init: dev_init,
dev_init,
dev_preconfig,
dev_postconfig
}; };

View File

@ -1,7 +1,7 @@
/* /*
* BIRD -- Direct Device Routes * 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. * Can be freely distributed and used under the terms of the GNU GPL.
*/ */
@ -9,8 +9,8 @@
#ifndef _BIRD_RT_DEV_H_ #ifndef _BIRD_RT_DEV_H_
#define _BIRD_RT_DEV_H_ #define _BIRD_RT_DEV_H_
struct rt_dev_proto { struct rt_dev_config {
struct proto p; struct proto_config c;
list iface_list; list iface_list;
}; };

View File

@ -121,7 +121,7 @@ rt_feed_baby(struct proto *p)
if (!p->rt_notify) if (!p->rt_notify)
return; return;
debug("Announcing routes to new protocol %s\n", p->name); debug("Announcing routes to new protocol %s\n", p->cf->name);
while (t) while (t)
{ {
FIB_WALK(&t->fib, fn) FIB_WALK(&t->fib, fn)

View File

@ -1,7 +1,7 @@
/* /*
* BIRD Internet Routing Daemon -- Unix Entry Point * 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. * 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 static void
read_config(void) read_config(void)
{ {
cf_lex_init_tables(); struct config *conf = config_alloc(PATH_CONFIG);
cf_allocate();
conf_fd = open(PATH_CONFIG, O_RDONLY); conf_fd = open(PATH_CONFIG, O_RDONLY);
if (conf_fd < 0) if (conf_fd < 0)
die("Unable to open configuration file " PATH_CONFIG ": %m"); die("Unable to open configuration file " PATH_CONFIG ": %m");
protos_preconfig();
cf_read_hook = cf_read; cf_read_hook = cf_read;
cf_lex_init(1); if (!config_parse(conf))
cf_parse(); die(PATH_CONFIG ", line %d: %s", conf->err_lino, conf->err_msg);
filters_postconfig(); config_commit(conf);
protos_postconfig();
} }
/* /*
* Hic Est main() * Hic Est main()
*/ */
@ -105,15 +104,12 @@ main(void)
protos_build(); protos_build();
add_tail(&protocol_list, &proto_unix_kernel.n); add_tail(&protocol_list, &proto_unix_kernel.n);
protos_init();
debug("Reading configuration file.\n");
read_config(); read_config();
signal_init(); signal_init();
scan_if_init(); scan_if_init();
auto_router_id();
protos_start(); protos_start();