diff --git a/conf/conf.c b/conf/conf.c
index 439aa41..b43835c 100644
--- a/conf/conf.c
+++ b/conf/conf.c
@@ -239,7 +239,7 @@ global_commit(struct config *new, struct config *old)
 static int
 config_do_commit(struct config *c, int type)
 {
-  if (type == RECONFIG_UNDO)
+  if ((type & RECONFIG_TYPE_MASK) == RECONFIG_UNDO)
     {
       c = old_config;
       type = old_cftype;
@@ -285,7 +285,7 @@ config_done(void *unused UNUSED)
   if (old_config)
     log(L_INFO "Reconfigured");
 
-  if (future_cftype)
+  if ((future_cftype & RECONFIG_TYPE_MASK) != RECONFIG_NONE)
     {
       int type = future_cftype;
       struct config *conf = future_config;
@@ -302,6 +302,7 @@ config_done(void *unused UNUSED)
  * config_commit - commit a configuration
  * @c: new configuration
  * @type: type of reconfiguration (RECONFIG_SOFT or RECONFIG_HARD)
+ *        flags are possible (RECONFIG_KEEP_STATE)
  * @timeout: timeout for undo (in seconds; or 0 for no timeout)
  *
  * When a configuration is parsed and prepared for use, the
@@ -342,7 +343,7 @@ config_commit(struct config *c, int type, uint timeout)
 
   if (configuring)
     {
-      if (future_cftype)
+      if ((future_cftype & RECONFIG_TYPE_MASK) != RECONFIG_NONE)
 	{
 	  log(L_INFO "Queueing new configuration, ignoring the one already queued");
 	  config_free(future_config);
diff --git a/conf/conf.h b/conf/conf.h
index 5689fb6..e4eb0f9 100644
--- a/conf/conf.h
+++ b/conf/conf.h
@@ -75,10 +75,14 @@ void config_add_obstacle(struct config *);
 void config_del_obstacle(struct config *);
 void order_shutdown(void);
 
-#define RECONFIG_NONE	0
-#define RECONFIG_HARD	1
-#define RECONFIG_SOFT	2
-#define RECONFIG_UNDO	3
+/* reconfig types */
+#define RECONFIG_NONE		0
+#define RECONFIG_HARD		1
+#define RECONFIG_SOFT		2
+#define RECONFIG_UNDO		3
+#define RECONFIG_TYPE_MASK	3
+/* reconfig flags */
+#define RECONFIG_KEEP_STATE	4
 
 #define CONF_DONE	0
 #define CONF_PROGRESS	1
diff --git a/nest/proto.c b/nest/proto.c
index 3dcb342..2496e30 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -567,7 +567,7 @@ channel_reconfigure(struct channel *c, struct channel_config *cf)
   if (c->channel_state != CS_UP)
     return 1;
 
-  if (reconfigure_type == RECONFIG_SOFT)
+  if ((reconfigure_type & RECONFIG_TYPE_MASK) == RECONFIG_SOFT)
   {
     if (import_changed)
       log(L_INFO "Channel %s.%s changed import", c->proto->name, c->name);
@@ -869,6 +869,7 @@ proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_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)
+ *        flags are possible (RECONFIG_KEEP_STATE)
  *
  * Scan differences between @old and @new configuration and adjust all
  * protocol instances to conform to the new configuration.
@@ -913,6 +914,13 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty
 	nc = sym->def;
 	nc->proto = p;
 
+	/* Keep protocol state during soft config */
+	if (type & RECONFIG_KEEP_STATE && p->disabled != nc->disabled)
+	{
+	  log(L_INFO "Keeping state of protocol %s", p->name);
+	  nc->disabled = p->disabled;
+	}
+
 	/* We will try to reconfigure protocol p */
 	if (! force_reconfig && proto_reconfigure(p, oc, nc, type))
 	  continue;
