From e0835db4f137c1686c26165053ec9c0578b94009 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Mon, 8 Apr 2019 17:05:07 +0200 Subject: 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. --- nest/proto.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ nest/protocol.h | 3 +++ 2 files changed, 59 insertions(+) (limited to 'nest') 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 diff --git a/nest/protocol.h b/nest/protocol.h index 56d66ed5..b26d9cc1 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 */ @@ -263,6 +265,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); -- cgit v1.2.3