summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/vty.c26
-rw-r--r--lib/vty.h7
-rw-r--r--vtysh/vtysh.c17
-rw-r--r--vtysh/vtysh.h2
4 files changed, 52 insertions, 0 deletions
diff --git a/lib/vty.c b/lib/vty.c
index 0a4a3d2b86..256a3bb3f5 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -345,8 +345,17 @@ int vty_out(struct vty *vty, const char *format, ...)
case VTY_SHELL_SERV:
case VTY_FILE:
default:
+ vty->vty_buf_size_accumulated += strlen(filtered);
/* print without crlf replacement */
buffer_put(vty->obuf, (uint8_t *)filtered, strlen(filtered));
+ /* For every chunk of memory, we invoke vtysh_flush where we
+ * put the data of collective vty->obuf Linked List items on the
+ * socket and free the vty->obuf data.
+ */
+ if (vty->vty_buf_size_accumulated >= VTY_MAX_INTERMEDIATE_FLUSH) {
+ vty->vty_buf_size_accumulated = 0;
+ vtysh_flush(vty);
+ }
break;
}
@@ -2118,6 +2127,8 @@ static void vtysh_accept(struct event *thread)
int client_len;
struct sockaddr_un client;
struct vty *vty;
+ int ret = 0;
+ uint32_t sndbufsize = VTY_SEND_BUF_MAX;
vty_event_serv(VTYSH_SERV, vtyserv);
@@ -2141,6 +2152,20 @@ static void vtysh_accept(struct event *thread)
close(sock);
return;
}
+
+ /*
+ * Increasing the SEND socket buffer size so that the socket can hold
+ * before sending it to VTY shell.
+ */
+ ret = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&sndbufsize,
+ sizeof(sndbufsize));
+ if (ret < 0) {
+ flog_err(EC_LIB_SOCKET,
+ "Cannot set socket %d send buffer size, %s", sock,
+ safe_strerror(errno));
+ close(sock);
+ return;
+ }
set_cloexec(sock);
#ifdef VTYSH_DEBUG
@@ -2227,6 +2252,7 @@ static int vtysh_flush(struct vty *vty)
vty_close(vty);
return -1;
case BUFFER_EMPTY:
+ vty->vty_buf_size_accumulated = 0;
break;
}
return 0;
diff --git a/lib/vty.h b/lib/vty.h
index c336a816cc..e511e8e79a 100644
--- a/lib/vty.h
+++ b/lib/vty.h
@@ -236,6 +236,7 @@ struct vty {
uintptr_t mgmt_req_pending_data;
bool mgmt_locked_candidate_ds;
bool mgmt_locked_running_ds;
+ uint64_t vty_buf_size_accumulated;
};
static inline void vty_push_context(struct vty *vty, int node, uint64_t id)
@@ -338,6 +339,12 @@ struct vty_arg {
/* Vty read buffer size. */
#define VTY_READ_BUFSIZ 512
+/* Vty max send buffer size */
+#define VTY_SEND_BUF_MAX 16777216
+
+/* Vty flush intermediate size */
+#define VTY_MAX_INTERMEDIATE_FLUSH 131072
+
/* Directory separator. */
#ifndef DIRECTORY_SEP
#define DIRECTORY_SEP '/'
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index c43e1909e3..2d80feef6c 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -4639,6 +4639,7 @@ static int vtysh_connect(struct vtysh_client *vclient)
struct sockaddr_un addr;
struct stat s_stat;
const char *path;
+ uint32_t rcvbufsize = VTYSH_RCV_BUF_MAX;
if (!vclient->path[0])
snprintf(vclient->path, sizeof(vclient->path), "%s/%s.vty",
@@ -4688,6 +4689,22 @@ static int vtysh_connect(struct vtysh_client *vclient)
close(sock);
return -1;
}
+
+ /*
+ * Increasing the RECEIVE socket buffer size so that the socket can hold
+ * after receving from other process.
+ */
+ ret = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&rcvbufsize,
+ sizeof(rcvbufsize));
+ if (ret < 0) {
+#ifdef DEBUG
+ fprintf(stderr, "Cannot set socket %d rcv buffer size, %s\n",
+ sock, safe_strerror(errno));
+#endif /* DEBUG */
+ close(sock);
+ return -1;
+ }
+
vclient->fd = sock;
return 0;
diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h
index b1d57aa3c2..3c532b99a8 100644
--- a/vtysh/vtysh.h
+++ b/vtysh/vtysh.h
@@ -36,6 +36,8 @@ extern struct event_loop *master;
#define VTYSH_PIM6D 0x100000
#define VTYSH_MGMTD 0x200000
+#define VTYSH_RCV_BUF_MAX 16777216
+
#define VTYSH_WAS_ACTIVE (-2)
/* commands in REALLYALL are crucial to correct vtysh operation */