summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorQuentin Young <qlyoung@cumulusnetworks.com>2016-11-12 05:17:37 +0000
committerQuentin Young <qlyoung@cumulusnetworks.com>2016-11-12 05:17:37 +0000
commit07321a065d1126c00766ca3d6698e57936699f82 (patch)
treea7dac2bb2248d87f40b1c3c2af7440d9bea35421 /lib
parent17aca20bfbb9d7e980a04c9b017f87f027901839 (diff)
parent11ec76edb225c0f0e6a57b1d667179b14aa2ac20 (diff)
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 'lib')
-rw-r--r--lib/command.c27
-rw-r--r--lib/command.h2
-rw-r--r--lib/log.c3
-rw-r--r--lib/log.h1
-rw-r--r--lib/network.c14
-rw-r--r--lib/network.h2
-rw-r--r--lib/pid_output.c3
-rw-r--r--lib/privs.c51
-rw-r--r--lib/vty.c17
9 files changed, 87 insertions, 33 deletions
diff --git a/lib/command.c b/lib/command.c
index 593822a66e..bf7e269acc 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -1350,6 +1350,9 @@ DEFUN (config_write,
return CMD_SUCCESS;
}
+ if (host.noconfig)
+ return CMD_SUCCESS;
+
/* Check and see if we are operating under vtysh configuration */
if (host.config == NULL)
{
@@ -1478,6 +1481,11 @@ DEFUN (show_startup_config,
char buf[BUFSIZ];
FILE *confp;
+ if (host.noconfig)
+ return CMD_SUCCESS;
+ if (host.config == NULL)
+ return CMD_WARNING;
+
confp = fopen (host.config, "r");
if (confp == NULL)
{
@@ -2281,7 +2289,11 @@ install_default (enum node_type node)
install_element (node, &show_running_config_cmd);
}
-/* Initialize command interface. Install basic nodes and commands. */
+/* Initialize command interface. Install basic nodes and commands.
+ *
+ * terminal = 0 -- vtysh / no logging, no config control
+ * terminal = 1 -- normal daemon
+ * terminal = -1 -- watchquagga / no logging, but minimal config control */
void
cmd_init (int terminal)
{
@@ -2296,6 +2308,7 @@ cmd_init (int terminal)
host.enable = NULL;
host.logfile = NULL;
host.config = NULL;
+ host.noconfig = (terminal < 0);
host.lines = -1;
host.motd = default_motd;
host.motdfile = NULL;
@@ -2338,12 +2351,17 @@ cmd_init (int terminal)
{
install_element (ENABLE_NODE, &config_logmsg_cmd);
install_default (CONFIG_NODE);
+
+ install_element (VIEW_NODE, &show_thread_cpu_cmd);
+ install_element (ENABLE_NODE, &clear_thread_cpu_cmd);
+
+ install_element (VIEW_NODE, &show_work_queues_cmd);
}
install_element (CONFIG_NODE, &hostname_cmd);
install_element (CONFIG_NODE, &no_hostname_cmd);
- if (terminal)
+ if (terminal > 0)
{
install_element (CONFIG_NODE, &password_cmd);
install_element (CONFIG_NODE, &enable_password_cmd);
@@ -2373,11 +2391,6 @@ cmd_init (int terminal)
install_element (CONFIG_NODE, &service_terminal_length_cmd);
install_element (CONFIG_NODE, &no_service_terminal_length_cmd);
- install_element (VIEW_NODE, &show_thread_cpu_cmd);
-
- install_element (ENABLE_NODE, &clear_thread_cpu_cmd);
- install_element (VIEW_NODE, &show_work_queues_cmd);
-
vrf_install_commands ();
}
srandom(time(NULL));
diff --git a/lib/command.h b/lib/command.h
index 3bcd66468d..50323d3753 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -57,6 +57,7 @@ struct host
/* config file name of this host */
char *config;
+ int noconfig;
/* Flags for services */
int advanced;
@@ -226,6 +227,7 @@ struct cmd_element
#define CMD_COMPLETE_LIST_MATCH 9
#define CMD_SUCCESS_DAEMON 10
#define CMD_ERR_NO_FILE 11
+#define CMD_SUSPEND 12
/* Argc max counts. */
#define CMD_ARGC_MAX 25
diff --git a/lib/log.c b/lib/log.c
index cd1f0bb771..f9877300b4 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -58,7 +58,8 @@ const char *zlog_proto_names[] =
"LDP",
"ISIS",
"PIM",
- "RFP",
+ "RFP",
+ "WATCHQUAGGA",
NULL,
};
diff --git a/lib/log.h b/lib/log.h
index cd4cd1495a..b36e5fbc80 100644
--- a/lib/log.h
+++ b/lib/log.h
@@ -59,6 +59,7 @@ typedef enum
ZLOG_ISIS,
ZLOG_PIM,
ZLOG_RFP,
+ ZLOG_WATCHQUAGGA,
} zlog_proto_t;
/* If maxlvl is set to ZLOG_DISABLED, then no messages will be sent
diff --git a/lib/network.c b/lib/network.c
index 5379ecb5a6..506e019136 100644
--- a/lib/network.c
+++ b/lib/network.c
@@ -94,6 +94,20 @@ set_nonblocking(int fd)
return 0;
}
+int
+set_cloexec(int fd)
+{
+ int flags;
+ flags = fcntl(fd, F_GETFD, 0);
+ if (flags == -1)
+ return -1;
+
+ flags |= FD_CLOEXEC;
+ if (fcntl(fd, F_SETFD, flags) == -1)
+ return -1;
+ return 0;
+}
+
float
htonf (float host)
{
diff --git a/lib/network.h b/lib/network.h
index 0fcb575d1c..a9126caf7f 100644
--- a/lib/network.h
+++ b/lib/network.h
@@ -33,6 +33,8 @@ extern int writen (int, const u_char *, int);
-1 on error. */
extern int set_nonblocking(int fd);
+extern int set_cloexec(int fd);
+
/* Does the I/O error indicate that the operation should be retried later? */
#define ERRNO_IO_RETRY(EN) \
(((EN) == EAGAIN) || ((EN) == EWOULDBLOCK) || ((EN) == EINTR))
diff --git a/lib/pid_output.c b/lib/pid_output.c
index 5261babc6d..de4c2fba99 100644
--- a/lib/pid_output.c
+++ b/lib/pid_output.c
@@ -24,6 +24,7 @@
#include <fcntl.h>
#include <log.h>
#include "version.h"
+#include "network.h"
#define PIDFILE_MASK 0644
#ifndef HAVE_FCNTL
@@ -84,6 +85,8 @@ pid_output (const char *path)
umask(oldumask);
memset (&lock, 0, sizeof(lock));
+ set_cloexec(fd);
+
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
diff --git a/lib/privs.c b/lib/privs.c
index 6cf87c18d4..ac2a8454c5 100644
--- a/lib/privs.c
+++ b/lib/privs.c
@@ -679,6 +679,15 @@ zprivs_init(struct zebra_privs_t *zprivs)
exit (1);
}
+ if (zprivs->vty_group)
+ {
+ /* in a "NULL" setup, this is allowed to fail too, but still try. */
+ if ((grentry = getgrnam (zprivs->vty_group)))
+ zprivs_state.vtygrp = grentry->gr_gid;
+ else
+ zprivs_state.vtygrp = (gid_t)-1;
+ }
+
/* NULL privs */
if (! (zprivs->user || zprivs->group
|| zprivs->cap_num_p || zprivs->cap_num_i) )
@@ -731,34 +740,30 @@ zprivs_init(struct zebra_privs_t *zprivs)
if (zprivs->vty_group)
/* Add the vty_group to the supplementary groups so it can be chowned to */
{
- if ( (grentry = getgrnam (zprivs->vty_group)) )
- {
- zprivs_state.vtygrp = grentry->gr_gid;
-
- for ( i = 0; i < ngroups; i++ )
- if ( groups[i] == zprivs_state.vtygrp )
- {
- found++;
- break;
- }
-
- if (!found)
- {
- fprintf (stderr, "privs_init: user(%s) is not part of vty group specified(%s)\n",
- zprivs->user, zprivs->vty_group);
- exit (1);
- }
- if ( i >= ngroups && ngroups < (int) ZEBRA_NUM_OF(groups) )
- {
- groups[i] = zprivs_state.vtygrp;
- }
- }
- else
+ if (zprivs_state.vtygrp == (gid_t)-1)
{
fprintf (stderr, "privs_init: could not lookup vty group %s\n",
zprivs->vty_group);
exit (1);
}
+
+ for ( i = 0; i < ngroups; i++ )
+ if ( groups[i] == zprivs_state.vtygrp )
+ {
+ found++;
+ break;
+ }
+
+ if (!found)
+ {
+ fprintf (stderr, "privs_init: user(%s) is not part of vty group specified(%s)\n",
+ zprivs->user, zprivs->vty_group);
+ exit (1);
+ }
+ if ( i >= ngroups && ngroups < (int) ZEBRA_NUM_OF(groups) )
+ {
+ groups[i] = zprivs_state.vtygrp;
+ }
}
if (ngroups)
diff --git a/lib/vty.c b/lib/vty.c
index 53a04851d5..c1cc332d89 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -1839,6 +1839,7 @@ vty_accept (struct thread *thread)
return -1;
}
set_nonblocking(vty_sock);
+ set_cloexec(vty_sock);
sockunion2hostprefix (&su, &p);
@@ -1937,6 +1938,7 @@ vty_serv_sock_addrinfo (const char *hostname, unsigned short port)
sockopt_v6only (ainfo->ai_family, sock);
sockopt_reuseaddr (sock);
sockopt_reuseport (sock);
+ set_cloexec (sock);
ret = bind (sock, ainfo->ai_addr, ainfo->ai_addrlen);
if (ret < 0)
@@ -2004,6 +2006,7 @@ vty_serv_sock_family (const char* addr, unsigned short port, int family)
/* This is server, so reuse address. */
sockopt_reuseaddr (accept_sock);
sockopt_reuseport (accept_sock);
+ set_cloexec (accept_sock);
/* Bind socket to universal address and given port. */
ret = sockunion_bind (accept_sock, &su, port, naddr);
@@ -2066,6 +2069,8 @@ vty_serv_un (const char *path)
len = sizeof (serv.sun_family) + strlen (serv.sun_path);
#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
+ set_cloexec (sock);
+
ret = bind (sock, (struct sockaddr *) &serv, len);
if (ret < 0)
{
@@ -2133,6 +2138,7 @@ vtysh_accept (struct thread *thread)
close (sock);
return -1;
}
+ set_cloexec(sock);
#ifdef VTYSH_DEBUG
printf ("VTY shell accept\n");
@@ -2227,8 +2233,15 @@ vtysh_read (struct thread *thread)
printf ("vtysh node: %d\n", vty->node);
#endif /* VTYSH_DEBUG */
- header[3] = ret;
- buffer_put(vty->obuf, header, 4);
+ /* hack for asynchronous "write integrated"
+ * - other commands in "buf" will be ditched
+ * - input during pending config-write is "unsupported" */
+ if (ret == CMD_SUSPEND)
+ break;
+
+ /* warning: watchquagga hardcodes this result write */
+ header[3] = ret;
+ buffer_put(vty->obuf, header, 4);
if (!vty->t_write && (vtysh_flush(vty) < 0))
/* Try to flush results; exit if a write error occurs. */