summaryrefslogtreecommitdiffstats
path: root/vtysh
diff options
context:
space:
mode:
authorQuentin Young <qlyoung@cumulusnetworks.com>2016-11-12 06:17:37 +0100
committerQuentin Young <qlyoung@cumulusnetworks.com>2016-11-12 06:17:37 +0100
commit07321a065d1126c00766ca3d6698e57936699f82 (patch)
treea7dac2bb2248d87f40b1c3c2af7440d9bea35421 /vtysh
parentlib, vtysh: Fix memory leaks, change cmd_element to const (diff)
parentMerge remote-tracking branch 'opensourcerouting/cmaster-next-vty2' into cmast... (diff)
downloadfrr-07321a065d1126c00766ca3d6698e57936699f82.tar.xz
frr-07321a065d1126c00766ca3d6698e57936699f82.zip
Merge branch 'cmaster-next' into vtysh-grammar
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com> Conflicts: lib/command.c lib/vty.c
Diffstat (limited to 'vtysh')
-rw-r--r--vtysh/Makefile.am1
-rw-r--r--vtysh/vtysh.c164
-rw-r--r--vtysh/vtysh.h9
-rw-r--r--vtysh/vtysh_config.c1
-rw-r--r--vtysh/vtysh_main.c65
5 files changed, 134 insertions, 106 deletions
diff --git a/vtysh/Makefile.am b/vtysh/Makefile.am
index 58ffdfca2..0ff2d738f 100644
--- a/vtysh/Makefile.am
+++ b/vtysh/Makefile.am
@@ -86,6 +86,7 @@ vtysh_cmd_FILES = $(vtysh_scan) \
$(top_srcdir)/zebra/zebra_fpm.c \
$(top_srcdir)/zebra/zebra_ptm.c \
$(top_srcdir)/zebra/zebra_mpls_vty.c \
+ $(top_srcdir)/watchquagga/watchquagga_vty.c \
$(BGP_VNC_RFAPI_SRC) $(BGP_VNC_RFP_SRC)
vtysh_cmd.c: $(vtysh_cmd_FILES) extract.pl
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index e8cf5aa23..85973bdb5 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -73,12 +73,11 @@ struct vtysh_client vtysh_client[] =
{ .fd = -1, .name = "bgpd", .flag = VTYSH_BGPD, .path = BGP_VTYSH_PATH, .next = NULL},
{ .fd = -1, .name = "isisd", .flag = VTYSH_ISISD, .path = ISIS_VTYSH_PATH, .next = NULL},
{ .fd = -1, .name = "pimd", .flag = VTYSH_PIMD, .path = PIM_VTYSH_PATH, .next = NULL},
+ { .fd = -1, .name = "watchquagga", .flag = VTYSH_WATCHQUAGGA, .path = WATCHQUAGGA_VTYSH_PATH, .next = NULL},
};
enum vtysh_write_integrated vtysh_write_integrated = WRITE_INTEGRATED_UNSPECIFIED;
-extern char config_default[];
-
static void
vclient_close (struct vtysh_client *vclient)
{
@@ -1068,7 +1067,7 @@ vtysh_end (void)
return CMD_SUCCESS;
}
-DEFUNSH (VTYSH_ALL,
+DEFUNSH (VTYSH_REALLYALL,
vtysh_end_all,
vtysh_end_all_cmd,
"end",
@@ -1410,8 +1409,8 @@ DEFUNSH (VTYSH_ALL,
return CMD_SUCCESS;
}
-DEFUNSH (VTYSH_ALL,
- vtysh_enable,
+DEFUNSH (VTYSH_REALLYALL,
+ vtysh_enable,
vtysh_enable_cmd,
"enable",
"Turn on privileged mode command\n")
@@ -1420,8 +1419,8 @@ DEFUNSH (VTYSH_ALL,
return CMD_SUCCESS;
}
-DEFUNSH (VTYSH_ALL,
- vtysh_disable,
+DEFUNSH (VTYSH_REALLYALL,
+ vtysh_disable,
vtysh_disable_cmd,
"disable",
"Turn off privileged mode command\n")
@@ -1431,7 +1430,7 @@ DEFUNSH (VTYSH_ALL,
return CMD_SUCCESS;
}
-DEFUNSH (VTYSH_ALL,
+DEFUNSH (VTYSH_REALLYALL,
vtysh_config_terminal,
vtysh_config_terminal_cmd,
"configure terminal",
@@ -1512,7 +1511,7 @@ vtysh_exit (struct vty *vty)
return CMD_SUCCESS;
}
-DEFUNSH (VTYSH_ALL,
+DEFUNSH (VTYSH_REALLYALL,
vtysh_exit_all,
vtysh_exit_all_cmd,
"exit",
@@ -2399,74 +2398,101 @@ backup_config_file (const char *fbackup)
free (integrate_sav);
}
-static int
-write_config_integrated(void)
+int
+vtysh_write_config_integrated(void)
{
u_int i;
char line[] = "write terminal\n";
- FILE *fp, *fp1;
+ FILE *fp;
+ int fd;
+ struct passwd *pwentry;
+ struct group *grentry;
+ uid_t uid = -1;
+ gid_t gid = -1;
+ struct stat st;
+ int err = 0;
fprintf (stdout,"Building Configuration...\n");
- backup_config_file(integrate_default);
- backup_config_file(host.config);
-
- fp = fopen (integrate_default, "w");
+ backup_config_file(quagga_config);
+ fp = fopen (quagga_config, "w");
if (fp == NULL)
{
- fprintf (stdout,"%% Can't open configuration file %s due to '%s'\n",
- integrate_default, safe_strerror(errno));
- return CMD_SUCCESS;
- }
-
- fp1 = fopen (host.config, "w");
- if (fp1 == NULL)
- {
- fprintf (stdout,"%% Can't open configuration file %s due to '%s'\n",
- host.config, safe_strerror(errno));
- return CMD_SUCCESS;
+ fprintf (stdout,"%% Error: failed to open configuration file %s: %s\n",
+ quagga_config, safe_strerror(errno));
+ return CMD_WARNING;
}
+ fd = fileno (fp);
- vtysh_config_write ();
- vtysh_config_dump (fp1);
-
- fclose (fp1);
for (i = 0; i < array_size(vtysh_client); i++)
vtysh_client_config (&vtysh_client[i], line);
vtysh_config_write ();
vtysh_config_dump (fp);
- fclose (fp);
+ if (fchmod (fd, CONFIGFILE_MASK) != 0)
+ {
+ printf ("%% Warning: can't chmod configuration file %s: %s\n",
+ quagga_config, safe_strerror(errno));
+ err++;
+ }
- if (chmod (integrate_default, CONFIGFILE_MASK) != 0)
+ pwentry = getpwnam (QUAGGA_USER);
+ if (pwentry)
+ uid = pwentry->pw_uid;
+ else
{
- fprintf (stdout,"%% Can't chmod configuration file %s: %s\n",
- integrate_default, safe_strerror(errno));
- return CMD_WARNING;
+ printf ("%% Warning: could not look up user \"%s\"\n", QUAGGA_USER);
+ err++;
}
- if (chmod (host.config, CONFIGFILE_MASK) != 0)
+ grentry = getgrnam (QUAGGA_GROUP);
+ if (grentry)
+ gid = grentry->gr_gid;
+ else
{
- fprintf (stdout,"%% Can't chmod configuration file %s: %s (%d)\n",
- integrate_default, safe_strerror(errno), errno);
- return CMD_WARNING;
+ printf ("%% Warning: could not look up group \"%s\"\n", QUAGGA_GROUP);
+ err++;
}
- fprintf(stdout,"Integrated configuration saved to %s\n",integrate_default);
- fprintf (stdout,"[OK]\n");
+ if (!fstat (fd, &st))
+ {
+ if (st.st_uid == uid)
+ uid = -1;
+ if (st.st_gid == gid)
+ gid = -1;
+ if ((uid != (uid_t)-1 || gid != (gid_t)-1) && fchown (fd, uid, gid))
+ {
+ printf ("%% Warning: can't chown configuration file %s: %s\n",
+ quagga_config, safe_strerror(errno));
+ err++;
+ }
+ }
+ else
+ {
+ printf ("%% Warning: stat() failed on %s: %s\n",
+ quagga_config, safe_strerror(errno));
+ err++;
+ }
+
+ fclose (fp);
+ printf ("Integrated configuration saved to %s\n", quagga_config);
+ if (err)
+ return CMD_WARNING;
+
+ printf ("[OK]\n");
return CMD_SUCCESS;
}
-static bool vtysh_writeconfig_integrated(void)
+static bool want_config_integrated(void)
{
struct stat s;
switch (vtysh_write_integrated)
{
case WRITE_INTEGRATED_UNSPECIFIED:
- if (stat(integrate_default, &s) && errno == ENOENT)
+ if (stat(quagga_config, &s) && errno == ENOENT)
return false;
return true;
case WRITE_INTEGRATED_NO:
@@ -2487,41 +2513,33 @@ DEFUN (vtysh_write_memory,
int ret = CMD_SUCCESS;
char line[] = "write memory\n";
u_int i;
- FILE *fp;
-
- /* If integrated Quagga.conf explicitely set. */
- if (vtysh_writeconfig_integrated())
- return write_config_integrated();
- else
- backup_config_file(integrate_default);
-
- fprintf (stdout,"Building Configuration...\n");
-
- for (i = 0; i < array_size(vtysh_client); i++)
- ret = vtysh_client_execute (&vtysh_client[i], line, stdout);
+ fprintf (stdout, "Note: this version of vtysh never writes vtysh.conf\n");
- fp = fopen(host.config, "w");
- if (fp == NULL)
+ /* If integrated Quagga.conf explicitely set. */
+ if (want_config_integrated())
{
- fprintf (stdout,"%% Can't open configuration file %s due to '%s'\n",
- host.config, safe_strerror(errno));
- return CMD_SUCCESS;
+ ret = CMD_WARNING;
+ for (i = 0; i < array_size(vtysh_client); i++)
+ if (vtysh_client[i].flag == VTYSH_WATCHQUAGGA)
+ break;
+ if (i < array_size(vtysh_client) && vtysh_client[i].fd != -1)
+ ret = vtysh_client_execute (&vtysh_client[i], "write integrated", stdout);
+
+ if (ret != CMD_SUCCESS)
+ {
+ printf("\nWarning: attempting direct configuration write without "
+ "watchquagga.\nFile permissions and ownership may be "
+ "incorrect, or write may fail.\n\n");
+ ret = vtysh_write_config_integrated();
+ }
+ return ret;
}
- vtysh_config_write ();
- vtysh_config_dump (fp);
-
- fclose (fp);
-
- if (chmod (host.config, CONFIGFILE_MASK) != 0)
- {
- fprintf (stdout,"%% Can't chmod configuration file %s: %s\n",
- integrate_default, safe_strerror(errno));
- return CMD_WARNING;
- }
+ fprintf (stdout,"Building Configuration...\n");
- fprintf (stdout,"[OK]\n");
+ for (i = 0; i < array_size(vtysh_client); i++)
+ ret = vtysh_client_execute (&vtysh_client[i], line, stdout);
return ret;
}
diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h
index 7241b4c12..dade049ad 100644
--- a/vtysh/vtysh.h
+++ b/vtysh/vtysh.h
@@ -34,7 +34,13 @@ DECLARE_MGROUP(MVTYSH)
#define VTYSH_ISISD 0x40
#define VTYSH_PIMD 0x100
#define VTYSH_LDPD 0x200
+#define VTYSH_WATCHQUAGGA 0x400
+/* commands in REALLYALL are crucial to correct vtysh operation */
+#define VTYSH_REALLYALL ~0U
+/* watchquagga is not in ALL since library CLI functions should not be
+ * run on it (logging & co. should stay in a fixed/frozen config, and
+ * things like prefix lists are not even initialised) */
#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD
#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_PIMD
#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_ISISD|VTYSH_PIMD
@@ -53,6 +59,8 @@ enum vtysh_write_integrated {
extern enum vtysh_write_integrated vtysh_write_integrated;
+extern char *quagga_config;
+
void vtysh_init_vty (void);
void vtysh_init_cmd (void);
extern int vtysh_connect_all (const char *optional_daemon_name);
@@ -73,6 +81,7 @@ void config_add_line (struct list *, const char *);
int vtysh_mark_file(const char *filename);
int vtysh_read_config (const char *);
+int vtysh_write_config_integrated (void);
void vtysh_config_parse_line (const char *);
diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
index 7ad457ee7..4ec0e0028 100644
--- a/vtysh/vtysh_config.c
+++ b/vtysh/vtysh_config.c
@@ -376,7 +376,6 @@ vtysh_read_config (const char *config_default_dir)
FILE *confp = NULL;
int ret;
- host_config_set (config_default_dir);
confp = fopen (config_default_dir, "r");
if (confp == NULL)
{
diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c
index 751152e91..999d90ab2 100644
--- a/vtysh/vtysh_main.c
+++ b/vtysh/vtysh_main.c
@@ -35,7 +35,6 @@
#include "getopt.h"
#include "command.h"
#include "memory.h"
-#include "privs.h"
#include "linklist.h"
#include "memory_vty.h"
@@ -45,30 +44,10 @@
/* VTY shell program name. */
char *progname;
-static zebra_capabilities_t _caps_p [] =
-{
- ZCAP_BIND,
- ZCAP_NET_RAW,
- ZCAP_NET_ADMIN,
-};
-
-struct zebra_privs_t vtysh_privs =
-{
-#if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
- .user = QUAGGA_USER,
- .group = QUAGGA_GROUP,
-#endif
-#ifdef VTY_GROUP
- .vty_group = VTY_GROUP,
-#endif
- .caps_p = _caps_p,
- .cap_num_p = array_size(_caps_p),
- .cap_num_i = 0,
-};
-
/* Configuration file name and directory. */
-char config_default[] = SYSCONFDIR VTYSH_DEFAULT_CONFIG;
-char quagga_config_default[] = SYSCONFDIR QUAGGA_DEFAULT_CONFIG;
+static char vtysh_config_always[] = SYSCONFDIR VTYSH_DEFAULT_CONFIG;
+static char quagga_config_default[] = SYSCONFDIR QUAGGA_DEFAULT_CONFIG;
+char *quagga_config = quagga_config_default;
char history_file[MAXPATHLEN];
/* Flag for indicate executing child command. */
@@ -166,6 +145,7 @@ usage (int status)
"-E, --echo Echo prompt and command in -c mode\n" \
"-C, --dryrun Check configuration for validity and exit\n" \
"-m, --markfile Mark input file with context end\n"
+ "-w, --writeconfig Write integrated config (Quagga.conf) and exit\n"
"-h, --help Display this help and exit\n\n" \
"Note that multiple commands may be executed from the command\n" \
"line by passing multiple -c args, or by embedding linefeed\n" \
@@ -189,6 +169,7 @@ struct option longopts[] =
{ "help", no_argument, NULL, 'h'},
{ "noerror", no_argument, NULL, 'n'},
{ "mark", no_argument, NULL, 'm'},
+ { "writeconfig", no_argument, NULL, 'w'},
{ 0 }
};
@@ -289,6 +270,7 @@ main (int argc, char **argv, char **env)
int echo_command = 0;
int no_error = 0;
int markfile = 0;
+ int writeconfig = 0;
int ret = 0;
char *homedir = NULL;
@@ -302,7 +284,7 @@ main (int argc, char **argv, char **env)
/* Option handling. */
while (1)
{
- opt = getopt_long (argc, argv, "be:c:d:nf:mEhC", longopts, 0);
+ opt = getopt_long (argc, argv, "be:c:d:nf:mEhCw", longopts, 0);
if (opt == EOF)
break;
@@ -346,6 +328,9 @@ main (int argc, char **argv, char **env)
case 'C':
dryrun = 1;
break;
+ case 'w':
+ writeconfig = 1;
+ break;
case 'h':
usage (0);
break;
@@ -355,12 +340,22 @@ main (int argc, char **argv, char **env)
}
}
+ if (markfile + writeconfig + dryrun + boot_flag > 1)
+ {
+ fprintf (stderr, "Invalid combination of arguments. Please specify at "
+ "most one of:\n\t-b, -C, -m, -w\n");
+ return 1;
+ }
+ if (inputfile && (writeconfig || boot_flag))
+ {
+ fprintf (stderr, "WARNING: Combinining the -f option with -b or -w is "
+ "NOT SUPPORTED since its\nresults are inconsistent!\n");
+ }
+
/* Initialize user input buffer. */
line_read = NULL;
setlinebuf(stdout);
- zprivs_init (&vtysh_privs);
-
/* Signal and others. */
vtysh_signal_init ();
@@ -373,7 +368,7 @@ main (int argc, char **argv, char **env)
vty_init_vtysh ();
/* Read vtysh configuration file before connecting to daemons. */
- vtysh_read_config(config_default);
+ vtysh_read_config(vtysh_config_always);
if (markfile)
{
@@ -422,6 +417,12 @@ main (int argc, char **argv, char **env)
exit(1);
}
+ if (writeconfig)
+ {
+ vtysh_execute ("enable");
+ return vtysh_write_config_integrated ();
+ }
+
if (inputfile)
{
vtysh_flock_config (inputfile);
@@ -512,17 +513,17 @@ main (int argc, char **argv, char **env)
history_truncate_file(history_file,1000);
exit (0);
}
-
+
/* Boot startup configuration file. */
if (boot_flag)
{
- vtysh_flock_config (integrate_default);
- int ret = vtysh_read_config (integrate_default);
+ vtysh_flock_config (quagga_config);
+ int ret = vtysh_read_config (quagga_config);
vtysh_unflock_config ();
if (ret)
{
fprintf (stderr, "Configuration file[%s] processing failure: %d\n",
- integrate_default, ret);
+ quagga_config, ret);
if (no_error)
exit (0);
else