p->proto_state = PS_DOWN;
p->last_state_change = current_time();
p->vrf = c->vrf;
+ p->vrf_set = c->vrf_set;
insert_node(&p->n, n);
p->event = ev_new_init(proto_pool, proto_event, p);
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
if ((nc->protocol != oc->protocol) ||
(nc->net_type != oc->net_type) ||
(nc->disabled != p->disabled) ||
- (nc->vrf != oc->vrf))
+ (nc->vrf != oc->vrf) ||
+ (nc->vrf_set != oc->vrf_set))
return 0;
p->name = nc->name;
{
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 */
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);
}
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;
}
}
+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
struct proto_stats *s = &c->stats;
if (c->in_keep_filtered)
- cli_msg(-1006, " Routes: %u imported, %u filtered, %u exported",
- s->imp_routes, s->filt_routes, s->exp_routes);
+ cli_msg(-1006, " Routes: %u imported, %u filtered, %u exported, %u preferred",
+ s->imp_routes, s->filt_routes, s->exp_routes, s->pref_routes);
else
- cli_msg(-1006, " Routes: %u imported, %u exported",
- s->imp_routes, s->exp_routes);
+ cli_msg(-1006, " Routes: %u imported, %u exported, %u preferred",
+ s->imp_routes, s->exp_routes, s->pref_routes);
cli_msg(-1006, " Route change stats: received rejected filtered ignored accepted");
cli_msg(-1006, " Import updates: %10u %10u %10u %10u %10u",
cli_msg(-1006, " Message: %s", p->message);
if (p->cf->router_id)
cli_msg(-1006, " Router ID: %R", p->cf->router_id);
- if (p->vrf)
- cli_msg(-1006, " VRF: %s", p->vrf->name);
+ if (p->vrf_set)
+ cli_msg(-1006, " VRF: %s", p->vrf ? p->vrf->name : "default");
if (p->proto->show_proto_info)
p->proto->show_proto_info(p);