summaryrefslogtreecommitdiff
path: root/nest
diff options
context:
space:
mode:
Diffstat (limited to 'nest')
-rw-r--r--nest/proto.c61
-rw-r--r--nest/protocol.h4
2 files changed, 65 insertions, 0 deletions
diff --git a/nest/proto.c b/nest/proto.c
index 77bf082a..9d0990de 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -874,6 +874,28 @@ proto_copy_config(struct proto_config *dest, struct proto_config *src)
dest->protocol->copy_config(dest, src);
}
+void
+proto_clone_config(struct symbol *sym, struct proto_config *parent)
+{
+ struct proto_config *cf = proto_config_new(parent->protocol, SYM_PROTO);
+ proto_copy_config(cf, parent);
+ cf->name = sym->name;
+ cf->proto = NULL;
+ cf->parent = parent;
+
+ sym->class = cf->class;
+ sym->proto = cf;
+}
+
+static void
+proto_undef_clone(struct symbol *sym, struct proto_config *cf)
+{
+ rem_node(&cf->n);
+
+ sym->class = SYM_VOID;
+ sym->proto = NULL;
+}
+
/**
* protos_preconfig - pre-configuration processing
* @c: new configuration
@@ -973,6 +995,24 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty
{
p = oc->proto;
sym = cf_find_symbol(new, oc->name);
+
+ /* Handle dynamic protocols */
+ if (!sym && oc->parent && !new->shutdown)
+ {
+ struct symbol *parsym = cf_find_symbol(new, oc->parent->name);
+ if (parsym && parsym->class == SYM_PROTO)
+ {
+ /* This is hack, we would like to share config, but we need to copy it now */
+ new_config = new;
+ cfg_mem = new->mem;
+ conf_this_scope = new->root_scope;
+ sym = cf_get_symbol(oc->name);
+ proto_clone_config(sym, parsym->proto);
+ new_config = NULL;
+ cfg_mem = NULL;
+ }
+ }
+
if (sym && sym->class == SYM_PROTO && !new->shutdown)
{
/* Found match, let's check if we can smoothly switch to new configuration */
@@ -984,6 +1024,12 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty
if (! force_reconfig && proto_reconfigure(p, oc, nc, type))
continue;
+ if (nc->parent)
+ {
+ proto_undef_clone(sym, nc);
+ goto remove;
+ }
+
/* Unsuccessful, we will restart it */
if (!p->disabled && !nc->disabled)
log(L_INFO "Restarting protocol %s", p->name);
@@ -997,10 +1043,16 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty
}
else if (!new->shutdown)
{
+ remove:
log(L_INFO "Removing protocol %s", p->name);
p->down_code = PDC_CF_REMOVE;
p->cf_new = NULL;
}
+ else if (new->gr_down)
+ {
+ p->down_code = PDC_CMD_GR_DOWN;
+ p->cf_new = NULL;
+ }
else /* global shutdown */
{
p->down_code = PDC_CMD_SHUTDOWN;
@@ -1105,6 +1157,15 @@ proto_rethink_goal(struct proto *p)
}
}
+struct proto *
+proto_spawn(struct proto_config *cf, uint disabled)
+{
+ struct proto *p = proto_init(cf, TAIL(proto_list));
+ p->disabled = disabled;
+ proto_rethink_goal(p);
+ return p;
+}
+
/**
* DOC: Graceful restart recovery
diff --git a/nest/protocol.h b/nest/protocol.h
index 1e7bfb59..b6f414f6 100644
--- a/nest/protocol.h
+++ b/nest/protocol.h
@@ -89,6 +89,7 @@ void protos_build(void);
void proto_build(struct protocol *);
void protos_preconfig(struct config *);
void protos_commit(struct config *new, struct config *old, int force_restart, int type);
+struct proto * proto_spawn(struct proto_config *cf, uint disabled);
void protos_dump_all(void);
#define GA_UNKNOWN 0 /* Attribute not recognized */
@@ -113,6 +114,7 @@ struct proto_config {
struct config *global; /* Global configuration data */
struct protocol *protocol; /* Protocol */
struct proto *proto; /* Instance we've created */
+ struct proto_config *parent; /* Parent proto_config for dynamic protocols */
char *name;
char *dsc;
int class; /* SYM_PROTO or SYM_TEMPLATE */
@@ -255,6 +257,7 @@ struct proto_spec {
#define PDC_CMD_DISABLE 0x11 /* Result of disable command */
#define PDC_CMD_RESTART 0x12 /* Result of restart command */
#define PDC_CMD_SHUTDOWN 0x13 /* Result of global shutdown */
+#define PDC_CMD_GR_DOWN 0x14 /* Result of global graceful restart */
#define PDC_RX_LIMIT_HIT 0x21 /* Route receive limit reached */
#define PDC_IN_LIMIT_HIT 0x22 /* Route import limit reached */
#define PDC_OUT_LIMIT_HIT 0x23 /* Route export limit reached */
@@ -263,6 +266,7 @@ struct proto_spec {
void *proto_new(struct proto_config *);
void *proto_config_new(struct protocol *, int class);
void proto_copy_config(struct proto_config *dest, struct proto_config *src);
+void proto_clone_config(struct symbol *sym, struct proto_config *parent);
void proto_set_message(struct proto *p, char *msg, int len);
void graceful_restart_recovery(void);