summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2009-06-19 23:49:34 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2009-06-19 23:49:34 +0200
commitbf1aec970e9ac0600266fe7a045847a62f18ac3b (patch)
tree4b6a27829ddded655066f135a8e23da598e1d59a
parent789772ed4586213d6a7fbb867b9296a01ce1b9c0 (diff)
downloadbird-bf1aec970e9ac0600266fe7a045847a62f18ac3b.tar
bird-bf1aec970e9ac0600266fe7a045847a62f18ac3b.zip
Adds support for soft reconfiguration.
-rw-r--r--conf/conf.c15
-rw-r--r--conf/conf.h4
-rw-r--r--nest/proto.c21
-rw-r--r--nest/protocol.h2
-rw-r--r--sysdep/unix/config.Y9
-rw-r--r--sysdep/unix/main.c8
-rw-r--r--sysdep/unix/unix.h2
7 files changed, 36 insertions, 25 deletions
diff --git a/conf/conf.c b/conf/conf.c
index 71e81b5..710d5c2 100644
--- a/conf/conf.c
+++ b/conf/conf.c
@@ -189,7 +189,7 @@ global_commit(struct config *new, struct config *old)
}
static int
-config_do_commit(struct config *c)
+config_do_commit(struct config *c, int type)
{
int force_restart, nobs;
@@ -205,7 +205,7 @@ config_do_commit(struct config *c)
DBG("rt_commit\n");
rt_commit(c, old_config);
DBG("protos_commit\n");
- protos_commit(c, old_config, force_restart);
+ protos_commit(c, old_config, force_restart, type);
new_config = NULL; /* Just to be sure nobody uses that now */
if (old_config)
nobs = --old_config->obstacle_count;
@@ -236,7 +236,7 @@ config_done(void *unused UNUSED)
c = future_config;
future_config = NULL;
log(L_INFO "Switching to queued configuration...");
- if (!config_do_commit(c))
+ if (!config_do_commit(c, RECONFIG_HARD))
break;
}
}
@@ -244,6 +244,7 @@ config_done(void *unused UNUSED)
/**
* config_commit - commit a configuration
* @c: new configuration
+ * @type: type of reconfiguration (RECONFIG_SOFT or RECONFIG_HARD)
*
* When a configuration is parsed and prepared for use, the
* config_commit() function starts the process of reconfiguration.
@@ -263,11 +264,11 @@ config_done(void *unused UNUSED)
* are accepted.
*/
int
-config_commit(struct config *c)
+config_commit(struct config *c, int type)
{
if (!config) /* First-time configuration */
{
- config_do_commit(c);
+ config_do_commit(c, RECONFIG_HARD);
return CONF_DONE;
}
if (old_config) /* Reconfiguration already in progress */
@@ -288,7 +289,7 @@ config_commit(struct config *c)
future_config = c;
return CONF_QUEUED;
}
- if (config_do_commit(c))
+ if (config_do_commit(c, type))
{
config_done(NULL);
return CONF_DONE;
@@ -321,7 +322,7 @@ order_shutdown(void)
init_list(&c->tables);
c->shutdown = 1;
shutting_down = 1;
- config_commit(c);
+ config_commit(c, RECONFIG_HARD);
shutting_down = 2;
}
diff --git a/conf/conf.h b/conf/conf.h
index ef27f3f..8c2d549 100644
--- a/conf/conf.h
+++ b/conf/conf.h
@@ -50,7 +50,9 @@ struct config *config_alloc(byte *name);
int config_parse(struct config *);
int cli_parse(struct config *);
void config_free(struct config *);
-int config_commit(struct config *);
+int config_commit(struct config *, int type);
+#define RECONFIG_HARD 0
+#define RECONFIG_SOFT 1
void cf_error(char *msg, ...) NORET;
void config_add_obstacle(struct config *);
void config_del_obstacle(struct config *);
diff --git a/nest/proto.c b/nest/proto.c
index ef0587b..2af077b 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -269,6 +269,7 @@ proto_init(struct proto_config *c)
* @old: old configuration or %NULL if it's boot time config
* @force_reconfig: force restart of all protocols (used for example
* when the router ID changes)
+ * @type: type of reconfiguration (RECONFIG_SOFT or RECONFIG_HARD)
*
* Scan differences between @old and @new configuration and adjust all
* protocol instances to conform to the new configuration.
@@ -281,15 +282,17 @@ proto_init(struct proto_config *c)
* When a protocol exists in the old configuration, but it doesn't in the
* new one, it's shut down and deleted after the shutdown completes.
*
- * When a protocol exists in both configurations, the core decides whether
- * it's possible to reconfigure it dynamically (it checks all the core properties
- * of the protocol and if they match, it asks the reconfigure() hook of the
- * protocol to see if the protocol is able to switch to the new configuration).
- * If it isn't possible, the protocol is shut down and a new instance is started
- * with the new configuration after the shutdown is completed.
+ * When a protocol exists in both configurations, the core decides
+ * whether it's possible to reconfigure it dynamically - it checks all
+ * the core properties of the protocol (changes in filters are ignored
+ * if type is RECONFIG_SOFT) and if they match, it asks the
+ * reconfigure() hook of the protocol to see if the protocol is able
+ * to switch to the new configuration. If it isn't possible, the
+ * protocol is shut down and a new instance is started with the new
+ * configuration after the shutdown is completed.
*/
void
-protos_commit(struct config *new, struct config *old, int force_reconfig)
+protos_commit(struct config *new, struct config *old, int force_reconfig, int type)
{
struct proto_config *oc, *nc;
struct proto *p, *n;
@@ -310,8 +313,8 @@ protos_commit(struct config *new, struct config *old, int force_reconfig)
&& nc->preference == oc->preference
&& nc->disabled == oc->disabled
&& nc->table->table == oc->table->table
- && filter_same(nc->in_filter, oc->in_filter)
- && filter_same(nc->out_filter, oc->out_filter)
+ && ((type == RECONFIG_SOFT) || filter_same(nc->in_filter, oc->in_filter))
+ && ((type == RECONFIG_SOFT) || filter_same(nc->out_filter, oc->out_filter))
&& p->proto_state != PS_DOWN)
{
/* Generic attributes match, try converting them and then ask the protocol */
diff --git a/nest/protocol.h b/nest/protocol.h
index eee3a74..0f9d59d 100644
--- a/nest/protocol.h
+++ b/nest/protocol.h
@@ -55,7 +55,7 @@ void protos_build(void);
void proto_build(struct protocol *);
void protos_preconfig(struct config *);
void protos_postconfig(struct config *);
-void protos_commit(struct config *new, struct config *old, int force_restart);
+void protos_commit(struct config *new, struct config *old, int force_restart, int type);
void protos_dump_all(void);
#define GA_UNKNOWN 0 /* Attribute not recognized */
diff --git a/sysdep/unix/config.Y b/sysdep/unix/config.Y
index 5176be6..1917fe6 100644
--- a/sysdep/unix/config.Y
+++ b/sysdep/unix/config.Y
@@ -13,7 +13,7 @@ CF_HDR
CF_DECLS
-CF_KEYWORDS(LOG, SYSLOG, ALL, DEBUG, TRACE, INFO, REMOTE, WARNING, ERROR, AUTH, FATAL, BUG, STDERR)
+CF_KEYWORDS(LOG, SYSLOG, ALL, DEBUG, TRACE, INFO, REMOTE, WARNING, ERROR, AUTH, FATAL, BUG, STDERR, SOFT)
%type <i> log_mask log_mask_list log_cat
%type <g> log_file
@@ -65,8 +65,13 @@ log_cat:
/* Unix specific commands */
+CF_CLI_HELP(CONFIGURE, [soft] [\"<file>\"], [[Reload configuration]])
+
CF_CLI(CONFIGURE, cfg_name, [\"<file>\"], [[Reload configuration]])
-{ cmd_reconfig($2); } ;
+{ cmd_reconfig($2, RECONFIG_HARD); } ;
+
+CF_CLI(CONFIGURE SOFT, cfg_name, [\"<file>\"], [[Reload configuration and ignore changes in filters]])
+{ cmd_reconfig($3, RECONFIG_SOFT); } ;
CF_CLI(DOWN,,, [[Shut the daemon down]])
{ cli_msg(7, "Shutdown requested"); order_shutdown(); } ;
diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c
index 4df4e9f..5f5b165 100644
--- a/sysdep/unix/main.c
+++ b/sysdep/unix/main.c
@@ -115,7 +115,7 @@ read_config(void)
else
die("Unable to open configuration file %s: %m", config_name);
}
- config_commit(conf);
+ config_commit(conf, RECONFIG_HARD);
}
void
@@ -133,11 +133,11 @@ async_config(void)
config_free(conf);
}
else
- config_commit(conf);
+ config_commit(conf, RECONFIG_HARD);
}
void
-cmd_reconfig(char *name)
+cmd_reconfig(char *name, int type)
{
struct config *conf;
@@ -154,7 +154,7 @@ cmd_reconfig(char *name)
}
else
{
- switch (config_commit(conf))
+ switch (config_commit(conf, type))
{
case CONF_DONE:
cli_msg(3, "Reconfigured.");
diff --git a/sysdep/unix/unix.h b/sysdep/unix/unix.h
index 997a408..83f61af 100644
--- a/sysdep/unix/unix.h
+++ b/sysdep/unix/unix.h
@@ -16,7 +16,7 @@ struct pool;
void async_config(void);
void async_dump(void);
void async_shutdown(void);
-void cmd_reconfig(char *name);
+void cmd_reconfig(char *name, int type);
/* io.c */