diff options
author | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2019-04-08 17:05:07 +0200 |
---|---|---|
committer | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2019-04-30 13:32:39 +0200 |
commit | e0835db4f137c1686c26165053ec9c0578b94009 (patch) | |
tree | c2a1df271b3bdbb1c48231849eb4d5ed7a607a2a /nest/proto.c | |
parent | df092aa1def0419da74f15bd20582fab4ec09207 (diff) |
BGP: Dynamic BGP
Support for dynamically spawning BGP protocols for incoming connections.
Use 'neighbor range' to specify range of valid neighbor addresses, then
incoming connections from these addresses spawn new BGP instances.
Diffstat (limited to 'nest/proto.c')
-rw-r--r-- | nest/proto.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/nest/proto.c b/nest/proto.c index d4a333d0..415471c4 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->def = cf; +} + +static void +proto_undef_clone(struct symbol *sym, struct proto_config *cf) +{ + rem_node(&cf->n); + + sym->class = SYM_VOID; + sym->def = 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->def); + 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,6 +1043,7 @@ 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; @@ -1105,6 +1152,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 |