dest->protocol->copy_config(dest, src);
}
- sym->def = cf;
+ 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 = NULL;
++ 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
{
p = oc->proto;
sym = cf_find_symbol(new, oc->name);
- proto_clone_config(sym, parsym->def);
+
+ /* 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 */
bgp_down(p);
}
- ((struct bgp_config *) sym->def)->remote_ip = remote_ip;
+ static struct bgp_proto *
+ bgp_spawn(struct bgp_proto *pp, ip_addr remote_ip)
+ {
+ struct symbol *sym;
+ char fmt[SYM_MAX_LEN];
+
+ bsprintf(fmt, "%s%%0%dd", pp->cf->dynamic_name, pp->cf->dynamic_name_digits);
+
+ /* This is hack, we would like to share config, but we need to copy it now */
+ new_config = config;
+ cfg_mem = config->mem;
+ conf_this_scope = config->root_scope;
+ sym = cf_default_name(fmt, &(pp->dynamic_name_counter));
+ proto_clone_config(sym, pp->p.cf);
+ new_config = NULL;
+ cfg_mem = NULL;
+
+ /* Just pass remote_ip to bgp_init() */
- return (void *) proto_spawn(sym->def, 0);
++ ((struct bgp_config *) sym->proto)->remote_ip = remote_ip;
+
++ return (void *) proto_spawn(sym->proto, 0);
+ }
+
void
- bgp_stop(struct bgp_proto *p, uint subcode, byte *data, uint len)
+ bgp_stop(struct bgp_proto *p, int subcode, byte *data, uint len)
{
proto_notify_state(&p->p, PS_STOP);
bgp_graceful_close_conn(&p->outgoing_conn, subcode, data, len);