]> git.ipfire.org Git - thirdparty/bird.git/blobdiff - conf/conf.c
Filter: Improve handling of stack frames in filter bytecode
[thirdparty/bird.git] / conf / conf.c
index 885e2e7e0ebf2b17ed85494d76239875cd729c0c..025c040e60eeeaf57ec57e1c2757b4e809c4cca4 100644 (file)
@@ -55,6 +55,7 @@
 #include "lib/timer.h"
 #include "conf/conf.h"
 #include "filter/filter.h"
+#include "sysdep/unix/unix.h"
 
 
 static jmp_buf conf_jmpbuf;
@@ -98,6 +99,7 @@ config_alloc(const char *name)
   memcpy(ndup, name, nlen);
 
   init_list(&c->tests);
+  init_list(&c->symbols);
   c->mrtdump_file = -1; /* Hack, this should be sysdep-specific */
   c->pool = p;
   c->mem = l;
@@ -138,6 +140,7 @@ config_parse(struct config *c)
   protos_preconfig(c);
   rt_preconfig(c);
   cf_parse();
+  rt_postconfig(c);
 
   if (EMPTY_LIST(c->protos))
     cf_error("No protocol is specified in the config file");
@@ -209,13 +212,21 @@ config_del_obstacle(struct config *c)
 {
   DBG("+++ deleting obstacle %d\n", c->obstacle_count);
   c->obstacle_count--;
-  if (!c->obstacle_count)
+  if (!c->obstacle_count && (c != config))
     ev_schedule(config_event);
 }
 
 static int
 global_commit(struct config *new, struct config *old)
 {
+  if (!new->hostname)
+    {
+      new->hostname = get_hostname(new->mem);
+
+      if (!new->hostname)
+        log(L_WARN "Cannot determine hostname");
+    }
+
   if (!old)
     return 0;
 
@@ -258,6 +269,8 @@ config_do_commit(struct config *c, int type)
   if (old_config)
     old_config->obstacle_count++;
 
+  DBG("filter_commit\n");
+  filter_commit(c, old_config);
   DBG("sysdep_commit\n");
   int force_restart = sysdep_commit(c, old_config);
   DBG("global_commit\n");
@@ -444,6 +457,24 @@ config_undo(void)
   return CONF_PROGRESS;
 }
 
+int
+config_status(void)
+{
+  if (shutting_down)
+    return CONF_SHUTDOWN;
+
+  if (configuring)
+    return future_cftype ? CONF_QUEUED : CONF_PROGRESS;
+
+  return CONF_DONE;
+}
+
+btime
+config_timer_status(void)
+{
+  return tm_active(config_timer) ? tm_remains(config_timer) : -1;
+}
+
 extern void cmd_reconfig_undo_notify(void);
 
 static void
@@ -474,19 +505,27 @@ config_init(void)
  * for switching to an empty configuration.
  */
 void
-order_shutdown(void)
+order_shutdown(int gr)
 {
   struct config *c;
 
   if (shutting_down)
     return;
 
-  log(L_INFO "Shutting down");
+  if (!gr)
+    log(L_INFO "Shutting down");
+  else
+    log(L_INFO "Shutting down for graceful restart");
+
   c = lp_alloc(config->mem, sizeof(struct config));
   memcpy(c, config, sizeof(struct config));
   init_list(&c->protos);
   init_list(&c->tables);
+  init_list(&c->symbols);
+  memset(c->def_tables, 0, sizeof(c->def_tables));
+  HASH_INIT(c->sym_hash, c->pool, 4);
   c->shutdown = 1;
+  c->gr_down = gr;
 
   config_commit(c, RECONFIG_HARD, 0);
   shutting_down = 1;
@@ -512,6 +551,7 @@ cf_error(const char *msg, ...)
   va_end(args);
   new_config->err_msg = cfg_strdup(buf);
   new_config->err_lino = ifs->lino;
+  new_config->err_chno = ifs->chno - ifs->toklen + 1;
   new_config->err_file_name = ifs->file_name;
   cf_lex_unwind();
   longjmp(conf_jmpbuf, 1);
@@ -546,6 +586,7 @@ cfg_copy_list(list *dest, list *src, unsigned node_size)
   {
     dn = cfg_alloc(node_size);
     memcpy(dn, sn, node_size);
+    memset(dn, 0, sizeof(node));
     add_tail(dest, dn);
   }
 }