My attempt was a bit more crude:
diff --git a/nest/config.Y b/nest/config.Y
index aef5ed46..829bf96c 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -64,7 +64,7 @@ proto_postconfig(void)
CF_DECLS
-CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
+CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, KEEP_STATE, DEBUG, ALL, OFF, DIRECT)
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, VRF, TABLE, STATES, ROUTES, FILTERS)
CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, SADR, MPLS)
CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED)
@@ -205,6 +205,7 @@ proto_name:
proto_item:
/* EMPTY */
| DISABLED bool { this_proto->disabled = $2; }
+ | KEEP_STATE bool { this_proto->keep_state = $2 }
| DEBUG debug_mask { this_proto->debug = $2; }
| MRTDUMP mrtdump_mask { this_proto->mrtdump = $2; }
| ROUTER ID idval { this_proto->router_id = $3; }
diff --git a/nest/proto.c b/nest/proto.c
index d4a333d0..397d6fb2 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -984,6 +984,8 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty
if (! force_reconfig && proto_reconfigure(p, oc, nc, type))
continue;
+ nc->disabled = nc->keep_state ? p->disabled : nc->disabled;
+
/* Unsuccessful, we will restart it */
if (!p->disabled && !nc->disabled)
log(L_INFO "Restarting protocol %s", p->name);
diff --git a/nest/protocol.h b/nest/protocol.h
index 6c04071b..d984b4c2 100644
--- a/nest/protocol.h
+++ b/nest/protocol.h
@@ -118,6 +118,7 @@ struct proto_config {
int class; /* SYM_PROTO or SYM_TEMPLATE */
u8 net_type; /* Protocol network type (NET_*), 0 for undefined */
u8 disabled; /* Protocol enabled/disabled by default */
+ u8 keep_state; /* Keep current enabled/disabled state during reconfiguration */
u32 debug, mrtdump; /* Debugging bitfields, both use D_* constants */
u32 router_id; /* Protocol specific router ID */