]> git.ipfire.org Git - thirdparty/bird.git/blobdiff - nest/proto.c
Nest: VRF of protocol can be explicitly specified as 'default'
[thirdparty/bird.git] / nest / proto.c
index fadce6c7c3e70d4fb59c05dd635a189403cc8837..696616509613933809cd9ddd1f04e4df51e6a6a2 100644 (file)
@@ -765,6 +765,7 @@ proto_init(struct proto_config *c, node *n)
   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);
@@ -874,6 +875,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
@@ -910,7 +933,8 @@ proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_config
   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;
@@ -973,6 +997,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 +1026,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 +1045,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 +1159,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
@@ -1693,11 +1756,11 @@ channel_show_stats(struct channel *c)
   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",
@@ -1777,8 +1840,8 @@ proto_cmd_show(struct proto *p, uintptr_t verbose, int cnt)
       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);