? lib/aaa-notes.txt Index: zebra/main.c =================================================================== RCS file: /var/cvsroot/quagga/zebra/main.c,v retrieving revision 1.23 diff -u -p -r1.23 main.c --- zebra/main.c 29 Sep 2005 14:39:32 -0000 1.23 +++ zebra/main.c 26 Oct 2005 13:01:46 -0000 @@ -76,6 +76,7 @@ struct option longopts[] = { "vty_addr", required_argument, NULL, 'A'}, { "vty_port", required_argument, NULL, 'P'}, { "retain", no_argument, NULL, 'r'}, + { "ignore_errs", no_argument, NULL, 'I'}, #ifdef HAVE_NETLINK { "nl-bufsize", required_argument, NULL, 's'}, #endif /* HAVE_NETLINK */ @@ -129,12 +130,13 @@ usage (char *progname, int status) "-f, --config_file Set configuration file name\n"\ "-i, --pid_file Set process identifier file name\n"\ "-k, --keep_kernel Don't delete old routes which installed by "\ - "zebra.\n"\ + " zebra.\n"\ + "-I, --ignore_errs Ignore configuration file errors\n" \ "-l, --log_mode Set verbose log mode flag\n"\ "-A, --vty_addr Set vty's bind address\n"\ "-P, --vty_port Set vty's port number\n"\ "-r, --retain When program terminates, retain added route "\ - "by zebra.\n"\ + " by zebra.\n"\ "-u, --user User to run as\n"\ "-g, --group Group to run as\n", progname); #ifdef HAVE_NETLINK @@ -163,9 +165,6 @@ sighup (void) static void sigint (void) { - /* Decrared in rib.c */ - void rib_close (); - zlog_notice ("Terminating on signal"); if (!retain_mode) @@ -216,6 +215,7 @@ main (int argc, char **argv) char *config_file = NULL; char *progname; struct thread thread; + enum vty_config_err_behaviour behaviour = VTY_CONFIG_ERR_ABORT; /* Set umask before anything for security */ umask (0027); @@ -231,9 +231,9 @@ main (int argc, char **argv) int opt; #ifdef HAVE_NETLINK - opt = getopt_long (argc, argv, "bdklf:i:hA:P:ru:g:vs:", longopts, 0); + opt = getopt_long (argc, argv, "bdklf:i:hA:P:rIu:g:vs:", longopts, 0); #else - opt = getopt_long (argc, argv, "bdklf:i:hA:P:ru:g:v", longopts, 0); + opt = getopt_long (argc, argv, "bdklf:i:hA:P:rIu:g:v", longopts, 0); #endif /* HAVE_NETLINK */ if (opt == EOF) @@ -263,6 +263,9 @@ main (int argc, char **argv) case 'i': pid_file = optarg; break; + case 'I': + behaviour = VTY_CONFIG_ERR_IGNORE; + break; case 'P': /* Deal with atoi() returning 0 on failure, and zebra not listening on zebra port... */ @@ -346,7 +349,7 @@ main (int argc, char **argv) rib_sweep_route (); /* Configuration file read*/ - vty_read_config (config_file, config_default); + vty_read_config (config_file, config_default, behaviour); /* Clean up rib. */ rib_weed_tables (); Index: ripd/rip_main.c =================================================================== RCS file: /var/cvsroot/quagga/ripd/rip_main.c,v retrieving revision 1.17 diff -u -p -r1.17 rip_main.c --- ripd/rip_main.c 25 Oct 2005 23:31:05 -0000 1.17 +++ ripd/rip_main.c 26 Oct 2005 13:01:46 -0000 @@ -41,6 +41,7 @@ static struct option longopts[] = { "daemon", no_argument, NULL, 'd'}, { "config_file", required_argument, NULL, 'f'}, { "pid_file", required_argument, NULL, 'i'}, + { "ignore_errs", no_argument, NULL, 'I'}, { "help", no_argument, NULL, 'h'}, { "vty_addr", required_argument, NULL, 'A'}, { "vty_port", required_argument, NULL, 'P'}, @@ -108,6 +109,7 @@ Daemon which manages RIP version 1 and 2 -d, --daemon Runs in daemon mode\n\ -f, --config_file Set configuration file name\n\ -i, --pid_file Set process identifier file name\n\ +-I, --ignore_errs Ignore configuration file errors\n\ -A, --vty_addr Set vty's bind address\n\ -P, --vty_port Set vty's port number\n\ -r, --retain When program terminates, retain added route by ripd.\n\ @@ -132,7 +134,7 @@ sighup (void) zlog_info ("ripd restarting!"); /* Reload config file. */ - vty_read_config (config_file, config_default); + vty_read_config (config_file, config_default, VTY_CONFIG_ERR_IGNORE); /* Create VTY's socket */ vty_serv_sock (vty_addr, vty_port, RIP_VTYSH_PATH); @@ -187,6 +189,7 @@ main (int argc, char **argv) int daemon_mode = 0; char *progname; struct thread thread; + enum vty_config_err_behaviour behaviour = VTY_CONFIG_ERR_ABORT; /* Set umask before anything for security */ umask (0027); @@ -203,7 +206,7 @@ main (int argc, char **argv) { int opt; - opt = getopt_long (argc, argv, "df:i:hA:P:u:g:rv", longopts, 0); + opt = getopt_long (argc, argv, "df:Ii:hA:P:u:g:rv", longopts, 0); if (opt == EOF) break; @@ -224,6 +227,9 @@ main (int argc, char **argv) case 'i': pid_file = optarg; break; + case 'I': + behaviour = VTY_CONFIG_ERR_IGNORE; + break; case 'P': /* Deal with atoi() returning 0 on failure, and ripd not listening on rip port... */ @@ -278,7 +284,7 @@ main (int argc, char **argv) sort_node (); /* Get configuration file. */ - vty_read_config (config_file, config_default); + vty_read_config (config_file, config_default, behaviour); /* Change to the daemon program. */ if (daemon_mode) Index: ripngd/ripng_main.c =================================================================== RCS file: /var/cvsroot/quagga/ripngd/ripng_main.c,v retrieving revision 1.16 diff -u -p -r1.16 ripng_main.c --- ripngd/ripng_main.c 29 Sep 2005 14:39:32 -0000 1.16 +++ ripngd/ripng_main.c 26 Oct 2005 13:01:46 -0000 @@ -47,6 +47,7 @@ struct option longopts[] = { "daemon", no_argument, NULL, 'd'}, { "config_file", required_argument, NULL, 'f'}, { "pid_file", required_argument, NULL, 'i'}, + { "ignore_errs", no_argument, NULL, 'I'}, { "log_mode", no_argument, NULL, 'l'}, { "help", no_argument, NULL, 'h'}, { "vty_addr", required_argument, NULL, 'A'}, @@ -112,6 +113,7 @@ Daemon which manages RIPng.\n\n\ -d, --daemon Runs in daemon mode\n\ -f, --config_file Set configuration file name\n\ -i, --pid_file Set process identifier file name\n\ +-I, --ignore_errs Ignore configuration file errors\n\ -l. --log_mode Set verbose log mode flag\n\ -A, --vty_addr Set vty's bind address\n\ -P, --vty_port Set vty's port number\n\ @@ -135,7 +137,7 @@ sighup (void) ripng_reset (); /* Reload config file. */ - vty_read_config (config_file, config_default); + vty_read_config (config_file, config_default, VTY_CONFIG_ERR_ABORT); /* Create VTY's socket */ vty_serv_sock (vty_addr, vty_port, RIPNG_VTYSH_PATH); @@ -190,6 +192,7 @@ main (int argc, char **argv) int daemon_mode = 0; char *progname; struct thread thread; + enum vty_config_err_behaviour behaviour = VTY_CONFIG_ERR_ABORT; /* Set umask before anything for security */ umask (0027); @@ -204,7 +207,7 @@ main (int argc, char **argv) { int opt; - opt = getopt_long (argc, argv, "dlf:i:hA:P:u:g:v", longopts, 0); + opt = getopt_long (argc, argv, "dlf:Ii:hA:P:u:g:v", longopts, 0); if (opt == EOF) break; @@ -227,6 +230,9 @@ main (int argc, char **argv) break; case 'i': pid_file = optarg; + break; + case 'I': + behaviour = VTY_CONFIG_ERR_IGNORE; break; case 'P': /* Deal with atoi() returning 0 on failure, and ripngd not @@ -279,7 +285,7 @@ main (int argc, char **argv) sort_node (); /* Get configuration file. */ - vty_read_config (config_file, config_default); + vty_read_config (config_file, config_default, behaviour); /* Change to the daemon program. */ if (daemon_mode) Index: ospfd/ospf_main.c =================================================================== RCS file: /var/cvsroot/quagga/ospfd/ospf_main.c,v retrieving revision 1.24 diff -u -p -r1.24 ospf_main.c --- ospfd/ospf_main.c 29 Sep 2005 14:39:32 -0000 1.24 +++ ospfd/ospf_main.c 26 Oct 2005 13:01:46 -0000 @@ -88,6 +88,7 @@ struct option longopts[] = { "group", required_argument, NULL, 'g'}, { "apiserver", no_argument, NULL, 'a'}, { "version", no_argument, NULL, 'v'}, + { "ignore_errs", no_argument, NULL, 'I'}, { 0 } }; @@ -120,7 +121,8 @@ Daemon which manages OSPF.\n\n\ -P, --vty_port Set vty's port number\n\ -u, --user User to run as\n\ -g, --group Group to run as\n\ --a. --apiserver Enable OSPF apiserver\n\ +-a, --apiserver Enable OSPF apiserver\n\ +-I, --ignore_errs Ignore configuration file errors\n \ -v, --version Print program version\n\ -h, --help Display this help and exit\n\ \n\ @@ -184,6 +186,7 @@ main (int argc, char **argv) int daemon_mode = 0; char *config_file = NULL; char *progname; + enum vty_config_err_behaviour behaviour = VTY_CONFIG_ERR_ABORT; struct thread thread; /* Set umask before anything for security */ @@ -215,7 +218,7 @@ main (int argc, char **argv) { int opt; - opt = getopt_long (argc, argv, "dlf:i:hA:P:u:g:av", longopts, 0); + opt = getopt_long (argc, argv, "dlIf:i:hA:P:u:g:av", longopts, 0); if (opt == EOF) break; @@ -236,6 +239,9 @@ main (int argc, char **argv) case 'i': pid_file = optarg; break; + case 'I': + behaviour = VTY_CONFIG_ERR_IGNORE; + break; case 'P': /* Deal with atoi() returning 0 on failure, and ospfd not listening on ospfd port... */ @@ -304,7 +310,7 @@ main (int argc, char **argv) sort_node (); /* Get configuration file. */ - vty_read_config (config_file, config_default); + vty_read_config (config_file, config_default, behaviour); /* Change to the daemon program. */ if (daemon_mode) Index: bgpd/bgp_main.c =================================================================== RCS file: /var/cvsroot/quagga/bgpd/bgp_main.c,v retrieving revision 1.17 diff -u -p -r1.17 bgp_main.c --- bgpd/bgp_main.c 29 Sep 2005 14:39:32 -0000 1.17 +++ bgpd/bgp_main.c 26 Oct 2005 13:01:46 -0000 @@ -42,6 +42,7 @@ struct option longopts[] = { "daemon", no_argument, NULL, 'd'}, { "config_file", required_argument, NULL, 'f'}, { "pid_file", required_argument, NULL, 'i'}, + { "ignore_errs", no_argument, NULL, 'I'}, { "bgp_port", required_argument, NULL, 'p'}, { "vty_addr", required_argument, NULL, 'A'}, { "vty_port", required_argument, NULL, 'P'}, @@ -133,6 +134,7 @@ redistribution between different routing -d, --daemon Runs in daemon mode\n\ -f, --config_file Set configuration file name\n\ -i, --pid_file Set process identifier file name\n\ +-I, --ignore_errs Ignore configuration file errors\n\ -p, --bgp_port Set bgp protocol's port number\n\ -A, --vty_addr Set vty's bind address\n\ -P, --vty_port Set vty's port number\n\ @@ -198,6 +200,7 @@ main (int argc, char **argv) int daemon_mode = 0; char *progname; struct thread thread; + enum vty_config_err_behaviour behaviour = VTY_CONFIG_ERR_ABORT; /* Set umask before anything for security */ umask (0027); @@ -214,7 +217,7 @@ main (int argc, char **argv) /* Command line argument treatment. */ while (1) { - opt = getopt_long (argc, argv, "df:i:hp:A:P:rnu:g:v", longopts, 0); + opt = getopt_long (argc, argv, "df:Ii:hp:A:P:rnu:g:v", longopts, 0); if (opt == EOF) break; @@ -232,6 +235,9 @@ main (int argc, char **argv) case 'i': pid_file = optarg; break; + case 'I': + behaviour = VTY_CONFIG_ERR_IGNORE; + break; case 'p': bm->port = atoi (optarg); break; @@ -292,7 +298,7 @@ main (int argc, char **argv) sort_node (); /* Parse config file. */ - vty_read_config (config_file, config_default); + vty_read_config (config_file, config_default, behaviour); /* Turn into daemon if daemon_mode is set. */ if (daemon_mode) Index: ospf6d/ospf6_main.c =================================================================== RCS file: /var/cvsroot/quagga/ospf6d/ospf6_main.c,v retrieving revision 1.20 diff -u -p -r1.20 ospf6_main.c --- ospf6d/ospf6_main.c 29 Sep 2005 14:39:32 -0000 1.20 +++ ospf6d/ospf6_main.c 26 Oct 2005 13:01:46 -0000 @@ -72,6 +72,7 @@ struct option longopts[] = { "daemon", no_argument, NULL, 'd'}, { "config_file", required_argument, NULL, 'f'}, { "pid_file", required_argument, NULL, 'i'}, + { "ignore_errs", no_argument, NULL, 'I'}, { "vty_addr", required_argument, NULL, 'A'}, { "vty_port", required_argument, NULL, 'P'}, { "user", required_argument, NULL, 'u'}, @@ -109,6 +110,7 @@ Daemon which manages OSPF version 3.\n\n -d, --daemon Runs in daemon mode\n\ -f, --config_file Set configuration file name\n\ -i, --pid_file Set process identifier file name\n\ +-I, --ignore_errs Ignore configuration file errors\n\ -A, --vty_addr Set vty's bind address\n\ -P, --vty_port Set vty's port number\n\ -u, --user User to run as\n\ @@ -183,6 +185,7 @@ main (int argc, char *argv[], char *envp char *vty_addr = NULL; int vty_port = 0; char *config_file = NULL; + enum vty_config_err_behaviour behaviour = VTY_CONFIG_ERR_ABORT; struct thread thread; /* Set umask before anything for security */ @@ -194,7 +197,7 @@ main (int argc, char *argv[], char *envp /* Command line argument treatment. */ while (1) { - opt = getopt_long (argc, argv, "df:i:hp:A:P:u:g:v", longopts, 0); + opt = getopt_long (argc, argv, "df:i:Ihp:A:P:u:g:v", longopts, 0); if (opt == EOF) break; @@ -215,6 +218,9 @@ main (int argc, char *argv[], char *envp case 'i': pid_file = optarg; break; + case 'I': + behaviour = VTY_CONFIG_ERR_IGNORE; + break; case 'P': /* Deal with atoi() returning 0 on failure, and ospf6d not listening on ospf6d port... */ @@ -269,7 +275,7 @@ main (int argc, char *argv[], char *envp sort_node (); /* parse config file */ - vty_read_config (config_file, config_default); + vty_read_config (config_file, config_default, behaviour); if (daemon_mode) daemon (0, 0); Index: isisd/isis_main.c =================================================================== RCS file: /var/cvsroot/quagga/isisd/isis_main.c,v retrieving revision 1.20 diff -u -p -r1.20 isis_main.c --- isisd/isis_main.c 29 Sep 2005 14:39:32 -0000 1.20 +++ isisd/isis_main.c 26 Oct 2005 13:01:46 -0000 @@ -76,6 +76,7 @@ struct option longopts[] = { {"daemon", no_argument, NULL, 'd'}, {"config_file", required_argument, NULL, 'f'}, {"pid_file", required_argument, NULL, 'i'}, + {"ignore_errs", no_argument, NULL, 'I'}, {"vty_addr", required_argument, NULL, 'A'}, {"vty_port", required_argument, NULL, 'P'}, {"user", required_argument, NULL, 'u'}, @@ -120,6 +121,7 @@ Daemon which manages IS-IS routing\n\n\ -d, --daemon Runs in daemon mode\n\ -f, --config_file Set configuration file name\n\ -i, --pid_file Set process identifier file name\n\ +-I, --ignore_errs Ignore configuration file errors\n\ -A, --vty_addr Set vty's bind address\n\ -P, --vty_port Set vty's port number\n\ -u, --user User to run as\n\ @@ -214,6 +216,7 @@ main (int argc, char **argv, char **envp struct thread thread; char *config_file = NULL; char *vty_addr = NULL; + enum vty_config_err_behaviour behaviour = VTY_CONFIG_ERR_ABORT; /* Get the programname without the preceding path. */ progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]); @@ -234,7 +237,7 @@ main (int argc, char **argv, char **envp /* Command line argument treatment. */ while (1) { - opt = getopt_long (argc, argv, "df:i:hA:p:P:u:g:v", longopts, 0); + opt = getopt_long (argc, argv, "df:Ii:hA:p:P:u:g:v", longopts, 0); if (opt == EOF) break; @@ -252,6 +255,9 @@ main (int argc, char **argv, char **envp case 'i': pid_file = optarg; break; + case 'I' + behaviour = VTY_CONFIG_ERR_IGNORE; + break; case 'A': vty_addr = optarg; break; @@ -309,9 +315,9 @@ main (int argc, char **argv, char **envp /* parse config file */ /* this is needed three times! because we have interfaces before the areas */ - vty_read_config (config_file, config_default); - vty_read_config (config_file, config_default); - vty_read_config (config_file, config_default); + vty_read_config (config_file, config_default, behaviour); + vty_read_config (config_file, config_default, behaviour); + vty_read_config (config_file, config_default, behaviour); /* demonize */ if (daemon_mode) Index: lib/command.c =================================================================== RCS file: /var/cvsroot/quagga/lib/command.c,v retrieving revision 1.51 diff -u -p -r1.51 command.c --- lib/command.c 26 Oct 2005 05:49:54 -0000 1.51 +++ lib/command.c 26 Oct 2005 13:01:47 -0000 @@ -2283,36 +2283,30 @@ cmd_execute_command_strict (vector vline /* Configration make from file. */ int -config_from_file (struct vty *vty, FILE *fp) +cmd_execute_config (struct vty *vty, vector vline) { int ret; - vector vline; - while (fgets (vty->buf, VTY_BUFSIZ, fp)) - { - vline = cmd_make_strvec (vty->buf); + /* Execute configuration command : this is strict match */ + ret = cmd_execute_command_strict (vline, vty, NULL); - /* In case of comment line */ - if (vline == NULL) - continue; - /* Execute configuration command : this is strict match */ + /* Try again with setting node to CONFIG_NODE */ + while (ret != CMD_SUCCESS && ret != CMD_WARNING + && ret != CMD_ERR_NOTHING_TODO && vty->node != CONFIG_NODE) + { + vty->node = node_parent(vty->node); ret = cmd_execute_command_strict (vline, vty, NULL); - - /* Try again with setting node to CONFIG_NODE */ - while (ret != CMD_SUCCESS && ret != CMD_WARNING - && ret != CMD_ERR_NOTHING_TODO && vty->node != CONFIG_NODE) - { - vty->node = node_parent(vty->node); - ret = cmd_execute_command_strict (vline, vty, NULL); - } - - cmd_free_strvec (vline); - - if (ret != CMD_SUCCESS && ret != CMD_WARNING - && ret != CMD_ERR_NOTHING_TODO) - return ret; } - return CMD_SUCCESS; + + switch (ret) + { + case CMD_SUCCESS: + case CMD_WARNING: + case CMD_ERR_NOTHING_TODO: + return CMD_SUCCESS; + default: + return ret; + } } /* Configration from terminal */ Index: lib/command.h =================================================================== RCS file: /var/cvsroot/quagga/lib/command.h,v retrieving revision 1.20 diff -u -p -r1.20 command.h --- lib/command.h 22 Aug 2005 22:39:56 -0000 1.20 +++ lib/command.h 26 Oct 2005 13:01:48 -0000 @@ -334,7 +334,7 @@ extern void cmd_free_strvec (vector); extern vector cmd_describe_command (vector, struct vty *, int *status); extern char **cmd_complete_command (vector, struct vty *, int *status); extern const char *cmd_prompt (enum node_type); -extern int config_from_file (struct vty *, FILE *); +extern int cmd_execute_config (struct vty *, vector); extern enum node_type node_parent (enum node_type); extern int cmd_execute_command (vector, struct vty *, struct cmd_element **, int); extern int cmd_execute_command_strict (vector, struct vty *, struct cmd_element **); Index: lib/vty.c =================================================================== RCS file: /var/cvsroot/quagga/lib/vty.c,v retrieving revision 1.47 diff -u -p -r1.47 vty.c --- lib/vty.c 26 Oct 2005 05:49:54 -0000 1.47 +++ lib/vty.c 26 Oct 2005 13:01:48 -0000 @@ -2201,36 +2201,48 @@ vty_timeout (struct thread *thread) /* Read up configuration file from file_name. */ static void -vty_read_file (FILE *confp) +vty_read_file (FILE *confp, enum vty_config_err_behaviour behave) { int ret; struct vty *vty; + vector vline; vty = vty_new (); - vty->fd = 0; /* stdout */ + vty->fd = STDOUT_FILENO; vty->type = VTY_TERM; vty->node = CONFIG_NODE; - /* Execute configuration file */ - ret = config_from_file (vty, confp); - - if ( !((ret == CMD_SUCCESS) || (ret == CMD_ERR_NOTHING_TODO)) ) + while (fgets (vty->buf, VTY_BUFSIZ, confp)) { + if ( (vline = cmd_make_strvec (vty->buf)) == NULL) + continue; /* comment line probably */ + + ret = cmd_execute_config (vty, vline); + + cmd_free_strvec (vline); + switch (ret) - { - case CMD_ERR_AMBIGUOUS: - fprintf (stderr, "Ambiguous command.\n"); - break; - case CMD_ERR_NO_MATCH: - fprintf (stderr, "There is no such command.\n"); - break; - } - fprintf (stderr, "Error occured during reading below line.\n%s\n", - vty->buf); + { + case CMD_SUCCESS: + case CMD_ERR_NOTHING_TODO: + continue; /* next line of config */ + case CMD_ERR_AMBIGUOUS: + fprintf (stderr, "Ambiguous command.\n"); + break; + case CMD_ERR_NO_MATCH: + fprintf (stderr, "There is no such command.\n"); + break; + } + fprintf (stderr, "Error occured during reading below line.\n%s\n", + vty->buf); + + if (behave == VTY_CONFIG_ERR_IGNORE) + continue; + + /* default error behaviour is to quit */ vty_close (vty); - exit (1); + exit (1); } - vty_close (vty); } @@ -2301,7 +2313,8 @@ vty_use_backup_config (char *fullpath) /* Read up configuration file from file_name. */ void vty_read_config (char *config_file, - char *config_default_dir) + char *config_default_dir, + enum vty_config_err_behaviour behave) { char cwd[MAXPATHLEN]; FILE *confp = NULL; @@ -2391,7 +2404,7 @@ vty_read_config (char *config_file, fullpath = config_default_dir; } - vty_read_file (confp); + vty_read_file (confp, behave); fclose (confp); Index: lib/vty.h =================================================================== RCS file: /var/cvsroot/quagga/lib/vty.h,v retrieving revision 1.12 diff -u -p -r1.12 vty.h --- lib/vty.h 23 May 2005 12:43:34 -0000 1.12 +++ lib/vty.h 26 Oct 2005 13:01:48 -0000 @@ -119,6 +119,12 @@ struct vty struct thread *t_timeout; }; +enum vty_config_err_behaviour +{ + VTY_CONFIG_ERR_ABORT, /* default: abort on configuration file error */ + VTY_CONFIG_ERR_IGNORE, /* Ignore configuration file errors */ +}; + /* Integrated configuration file. */ #define INTEGRATE_DEFAULT_CONFIG "Quagga.conf" @@ -205,7 +211,7 @@ extern void vty_init_vtysh (void); extern void vty_reset (void); extern struct vty *vty_new (void); extern int vty_out (struct vty *, const char *, ...) PRINTF_ATTRIBUTE(2, 3); -extern void vty_read_config (char *, char *); +extern void vty_read_config (char *, char *, enum vty_config_err_behaviour); extern void vty_time_print (struct vty *, int); extern void vty_serv_sock (const char *, unsigned short, const char *); extern void vty_close (struct vty *);