From 7cd468a3d7dee7d6c92f69a0bb7061ae208ec727 Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Mon, 19 Dec 2016 23:05:39 +0100 Subject: Reorganize source tree to use single autotools instance Change-Id: I7b51f88292e057c6443b12224486f2d0c9f8ae23 Signed-off-by: Damjan Marion --- src/vpp/conf/startup.conf | 99 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 src/vpp/conf/startup.conf (limited to 'src/vpp/conf/startup.conf') diff --git a/src/vpp/conf/startup.conf b/src/vpp/conf/startup.conf new file mode 100644 index 00000000..bce00202 --- /dev/null +++ b/src/vpp/conf/startup.conf @@ -0,0 +1,99 @@ + +unix { + nodaemon + log /tmp/vpp.log + full-coredump +} + +api-trace { + on +} + +api-segment { + gid vpp +} + +cpu { + ## In the VPP there is one main thread and optionally the user can create worker(s) + ## The main thread and worker thread(s) can be pinned to CPU core(s) manually or automatically + + ## Manual pinning of thread(s) to CPU core(s) + + ## Set logical CPU core where main thread runs + # main-core 1 + + ## Set logical CPU core(s) where worker threads are running + # corelist-workers 2-3,18-19 + + ## Automatic pinning of thread(s) to CPU core(s) + + ## Sets number of CPU core(s) to be skipped (1 ... N-1) + ## Skipped CPU core(s) are not used for pinning main thread and working thread(s). + ## The main thread is automatically pinned to the first available CPU core and worker(s) + ## are pinned to next free CPU core(s) after core assigned to main thread + # skip-cores 4 + + ## Specify a number of workers to be created + ## Workers are pinned to N consecutive CPU cores while skipping "skip-cores" CPU core(s) + ## and main thread's CPU core + # workers 2 + + ## Set scheduling policy and priority of main and worker threads + + ## Scheduling policy options are: other (SCHED_OTHER), batch (SCHED_BATCH) + ## idle (SCHED_IDLE), fifo (SCHED_FIFO), rr (SCHED_RR) + # scheduler-policy fifo + + ## Scheduling priority is used only for "real-time policies (fifo and rr), + ## and has to be in the range of priorities supported for a particular policy + # scheduler-priority 50 +} + +dpdk { + ## Change default settings for all intefaces + # dev default { + ## Number of receive queues, enables RSS + ## Default is 1 + # num-rx-queues 3 + + ## Number of transmit queues, Default is equal + ## to number of worker threads or 1 if no workers treads + # num-tx-queues 3 + + ## Number of descriptors in transmit and receive rings + ## increasing or reducing number can impact performance + ## Default is 1024 for both rx and tx + # num-rx-desc 512 + # num-tx-desc 512 + + ## VLAN strip offload mode for interface + ## Default is off + # vlan-strip-offload on + # } + + ## Whitelist specific interface by specifying PCI address + # dev 0000:02:00.0 + + ## Whitelist specific interface by specifying PCI address and in + ## addition specify custom parameters for this interface + # dev 0000:02:00.1 { + # num-rx-queues 2 + # } + + ## Change UIO driver used by VPP, Options are: uio_pci_generic, vfio-pci + ## and igb_uio (default) + # uio-driver uio_pci_generic + + ## Disable mutli-segment buffers, improves performance but + ## disables Jumbo MTU support + # no-multi-seg + + ## Increase number of buffers allocated, needed only in scenarios with + ## large number of interfaces and worker threads. Value is per CPU socket. + ## Default is 32768 + # num-mbufs 128000 + + ## Change hugepages allocation per-socket, needed only if there is need for + ## larger number of mbufs. Default is 256M on each detected CPU socket + # socket-mem 2048,2048 +} -- cgit 1.2.3-korg From d0f673ee92121e13a88ad7002e0c860b2cfc5e4b Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Tue, 31 Jan 2017 17:29:33 +0100 Subject: dpdk: move to uio_pci_generic Change-Id: I3d8b7947ae6d721e9b514a59a7d2de49aed419b5 Signed-off-by: Damjan Marion --- build-root/deb/debian/vpp.service | 6 +++--- build-root/deb/debian/vpp.upstart | 2 +- build-root/rpm/vpp.spec | 2 +- src/vnet/devices/dpdk/init.c | 2 +- src/vpp/conf/startup.conf | 6 +++--- src/vpp/conf/startup.uiopcigeneric.conf | 18 ------------------ 6 files changed, 9 insertions(+), 27 deletions(-) delete mode 100644 src/vpp/conf/startup.uiopcigeneric.conf (limited to 'src/vpp/conf/startup.conf') diff --git a/build-root/deb/debian/vpp.service b/build-root/deb/debian/vpp.service index 40549856..aa1651c4 100644 --- a/build-root/deb/debian/vpp.service +++ b/build-root/deb/debian/vpp.service @@ -4,10 +4,10 @@ After=network.target [Service] Type=simple -ExecStartPre=-/bin/rm -f /dev/shm/db /dev/shm/global_vm /dev/shm/vpe-api -ExecStartPre=-/sbin/modprobe igb_uio +ExecStartPre=-/bin/rm -f /dev/shm/db /dev/shm/global_vm /dev/shm/vpe-api +ExecStartPre=-/sbin/modprobe uio_pci_generic ExecStart=/usr/bin/vpp -c /etc/vpp/startup.conf -ExecStopPost=/bin/rm -f /dev/shm/db /dev/shm/global_vm /dev/shm/vpe-api +ExecStopPost=/bin/rm -f /dev/shm/db /dev/shm/global_vm /dev/shm/vpe-api Restart=always [Install] diff --git a/build-root/deb/debian/vpp.upstart b/build-root/deb/debian/vpp.upstart index f5908783..62e1d278 100644 --- a/build-root/deb/debian/vpp.upstart +++ b/build-root/deb/debian/vpp.upstart @@ -8,7 +8,7 @@ respawn pre-start script rm -f /dev/shm/db /dev/shm/global_vm /dev/shm/vpe-api || true # should be there via dkms, but if not, start anyway - modprobe igb_uio || true + modprobe uio_pci_generic || true end script diff --git a/build-root/rpm/vpp.spec b/build-root/rpm/vpp.spec index 5575b5b1..95196e9b 100644 --- a/build-root/rpm/vpp.spec +++ b/build-root/rpm/vpp.spec @@ -118,7 +118,7 @@ mkdir -p -m755 %{buildroot}/usr/share/vpp/api mkdir -p -m755 %{buildroot}/etc/vpp mkdir -p -m755 %{buildroot}/etc/sysctl.d install -p -m 644 %{_mu_build_dir}/rpm/vpp.service %{buildroot}%{_unitdir} -install -p -m 644 %{_mu_build_dir}/../src/vpp/conf/startup.uiopcigeneric.conf %{buildroot}/etc/vpp/startup.conf +install -p -m 644 %{_mu_build_dir}/../src/vpp/conf/startup.conf %{buildroot}/etc/vpp/startup.conf install -p -m 644 %{_mu_build_dir}/../src/vpp/conf/80-vpp.conf %{buildroot}/etc/sysctl.d # # libraries diff --git a/src/vnet/devices/dpdk/init.c b/src/vnet/devices/dpdk/init.c index 01ef48cb..7249cc52 100755 --- a/src/vnet/devices/dpdk/init.c +++ b/src/vnet/devices/dpdk/init.c @@ -1165,7 +1165,7 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input) } if (!conf->uio_driver_name) - conf->uio_driver_name = format (0, "igb_uio%c", 0); + conf->uio_driver_name = format (0, "uio_pci_generic%c", 0); /* * Use 1G huge pages if available. diff --git a/src/vpp/conf/startup.conf b/src/vpp/conf/startup.conf index bce00202..a100e3e6 100644 --- a/src/vpp/conf/startup.conf +++ b/src/vpp/conf/startup.conf @@ -80,9 +80,9 @@ dpdk { # num-rx-queues 2 # } - ## Change UIO driver used by VPP, Options are: uio_pci_generic, vfio-pci - ## and igb_uio (default) - # uio-driver uio_pci_generic + ## Change UIO driver used by VPP, Options are: igb_uio, vfio-pci + ## and uio_pci_generic (default) + # uio-driver vfio-pci ## Disable mutli-segment buffers, improves performance but ## disables Jumbo MTU support diff --git a/src/vpp/conf/startup.uiopcigeneric.conf b/src/vpp/conf/startup.uiopcigeneric.conf deleted file mode 100644 index 03a89dff..00000000 --- a/src/vpp/conf/startup.uiopcigeneric.conf +++ /dev/null @@ -1,18 +0,0 @@ - -unix { - nodaemon - log /tmp/vpp.log - full-coredump -} - -dpdk { - uio-driver uio_pci_generic -} - -api-trace { - on -} - -api-segment { - gid vpp -} -- cgit 1.2.3-korg From 6e9cf3b9b53e69408514f9451235119a31045ed6 Mon Sep 17 00:00:00 2001 From: Dave Wallace Date: Thu, 16 Feb 2017 11:10:09 -0500 Subject: Fix comment for num-mbufs default in startup.conf Change-Id: I8bb175cc9673895d4a8856786ecabfd66dd906e9 Signed-off-by: Dave Wallace --- src/vpp/conf/startup.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vpp/conf/startup.conf') diff --git a/src/vpp/conf/startup.conf b/src/vpp/conf/startup.conf index a100e3e6..19e322a8 100644 --- a/src/vpp/conf/startup.conf +++ b/src/vpp/conf/startup.conf @@ -90,7 +90,7 @@ dpdk { ## Increase number of buffers allocated, needed only in scenarios with ## large number of interfaces and worker threads. Value is per CPU socket. - ## Default is 32768 + ## Default is 16384 # num-mbufs 128000 ## Change hugepages allocation per-socket, needed only if there is need for -- cgit 1.2.3-korg From 60750434fce12e320968a5bbc14cca080048ffd1 Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Thu, 23 Mar 2017 10:48:47 +0100 Subject: Comment out dpdk section in startup.conf It is empty anyway and it is causing problems if dpdk plugin is not loaded. Change-Id: I7b49afec39c78cbaf0c57b50621fb3e6848e3469 Signed-off-by: Damjan Marion --- src/vpp/conf/startup.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/vpp/conf/startup.conf') diff --git a/src/vpp/conf/startup.conf b/src/vpp/conf/startup.conf index 19e322a8..324facc0 100644 --- a/src/vpp/conf/startup.conf +++ b/src/vpp/conf/startup.conf @@ -49,7 +49,7 @@ cpu { # scheduler-priority 50 } -dpdk { +# dpdk { ## Change default settings for all intefaces # dev default { ## Number of receive queues, enables RSS @@ -96,4 +96,4 @@ dpdk { ## Change hugepages allocation per-socket, needed only if there is need for ## larger number of mbufs. Default is 256M on each detected CPU socket # socket-mem 2048,2048 -} +# } -- cgit 1.2.3-korg From 3474f9adca19dbd8ab41460f8e891924beaa0210 Mon Sep 17 00:00:00 2001 From: Burt Silverman Date: Sat, 27 May 2017 22:40:30 -0400 Subject: Show example syntax for setting plugin path Change-Id: I7972273d0e9bd36e3fd6e12ab0268341ba572313 Signed-off-by: Burt Silverman --- src/vpp/conf/startup.conf | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/vpp/conf/startup.conf') diff --git a/src/vpp/conf/startup.conf b/src/vpp/conf/startup.conf index 324facc0..f671439b 100644 --- a/src/vpp/conf/startup.conf +++ b/src/vpp/conf/startup.conf @@ -97,3 +97,12 @@ cpu { ## larger number of mbufs. Default is 256M on each detected CPU socket # socket-mem 2048,2048 # } + +# Adjusting the plugin path depending on where the VPP plugins are: +#plugins +#{ +# path /home/bms/vpp/build-root/install-vpp-native/vpp/lib64/vpp_plugins +#} + +# Alternate syntax to choose plugin path +#plugin_path /home/bms/vpp/build-root/install-vpp-native/vpp/lib64/vpp_plugins -- cgit 1.2.3-korg From aad20988b6a0a5058e520948d2a5835cfbc3b523 Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Tue, 20 Jun 2017 16:35:29 +0200 Subject: Rewrite vppctl in C - removes python dependency - removes vpp_api_test dependency - communicates over unix socket - properly detects terminal size and type - responds on terminal resize Change-Id: I46c0a49f9b5f9ef8a0a31faec4fc5d49aa3ee02e Signed-off-by: Damjan Marion --- Makefile | 2 +- src/vpp.am | 4 + src/vpp/app/vppctl.c | 322 ++++++++++++++++++++++++++++++++++++++++++++++ src/vpp/conf/startup.conf | 1 + 4 files changed, 328 insertions(+), 1 deletion(-) create mode 100644 src/vpp/app/vppctl.c (limited to 'src/vpp/conf/startup.conf') diff --git a/Makefile b/Makefile index 3ef236a6..af946959 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ GDB?=gdb PLATFORM?=vpp SAMPLE_PLUGIN?=no -MINIMAL_STARTUP_CONF="unix { interactive }" +MINIMAL_STARTUP_CONF="unix { interactive cli-listen /run/vpp/cli.sock gid $(shell id -g) }" GDB_ARGS= -ex "handle SIGUSR1 noprint nostop" diff --git a/src/vpp.am b/src/vpp.am index 1c95949a..614bd26a 100644 --- a/src/vpp.am +++ b/src/vpp.am @@ -85,6 +85,10 @@ bin_vpp_LDADD = \ bin_vpp_LDFLAGS = -Wl,--export-dynamic +bin_PROGRAMS += bin/vppctl +bin_vppctl_SOURCES = vpp/app/vppctl.c +bin_vppctl_LDADD = libvppinfra.la + if ENABLE_TESTS noinst_PROGRAMS += bin/test_client diff --git a/src/vpp/app/vppctl.c b/src/vpp/app/vppctl.c new file mode 100644 index 00000000..a8f3eab0 --- /dev/null +++ b/src/vpp/app/vppctl.c @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG 0 + +#if DEBUG +#define TELCMDS +#define TELOPTS +#endif + +#include + +#include +#include +#include + +#define SOCKET_FILE "/run/vpp/cli.sock" + +volatile int window_resized = 0; +struct termios orig_tio; + +static void +send_ttype (clib_socket_t * s, int is_dumb) +{ + clib_socket_tx_add_formatted (s, "%c%c%c" "%c%s" "%c%c", + IAC, SB, TELOPT_TTYPE, + 0, is_dumb ? "dumb" : getenv ("TERM"), + IAC, SE); + clib_socket_tx (s); +} + +static void +send_naws (clib_socket_t * s) +{ + struct winsize ws; + + if (ioctl (STDIN_FILENO, TIOCGWINSZ, &ws) < 0) + { + clib_unix_warning ("ioctl(TIOCGWINSZ)"); + return; + } + + clib_socket_tx_add_formatted (s, "%c%c%c" "%c%c%c%c" "%c%c", + IAC, SB, TELOPT_NAWS, + ws.ws_col >> 8, ws.ws_col & 0xff, + ws.ws_row >> 8, ws.ws_row & 0xff, IAC, SE); + clib_socket_tx (s); +} + +static void +signal_handler_winch (int signum) +{ + window_resized = 1; +} + +static void +signal_handler_term (int signum) +{ + tcsetattr (STDIN_FILENO, TCSAFLUSH, &orig_tio); +} + +static u8 * +process_input (u8 * str, clib_socket_t * s, int is_interactive) +{ + int i = 0; + + while (i < vec_len (s->rx_buffer)) + { + if (s->rx_buffer[i] == IAC) + { + if (s->rx_buffer[i + 1] == SB) + { + u8 *sb = 0; + char opt = s->rx_buffer[i + 2]; + i += 3; + while (s->rx_buffer[i] != IAC) + vec_add1 (sb, s->rx_buffer[i++]); + +#if DEBUG + clib_warning ("SB %s\n %U", TELOPT (opt), + format_hexdump, sb, vec_len (sb)); +#endif + vec_free (sb); + i += 2; + if (opt == TELOPT_TTYPE) + send_ttype (s, !is_interactive); + else if (is_interactive && opt == TELOPT_NAWS) + send_naws (s); + } + else + { +#if DEBUG + clib_warning ("IAC at %d, IAC %s %s", i, + TELCMD (s->rx_buffer[i + 1]), + TELOPT (s->rx_buffer[i + 2])); +#endif + i += 3; + } + } + else + vec_add1 (str, s->rx_buffer[i++]); + } + vec_reset_length (s->rx_buffer); + return str; +} + + +int +main (int argc, char *argv[]) +{ + clib_socket_t _s = { 0 }, *s = &_s; + clib_error_t *error = 0; + struct epoll_event event; + struct sigaction sa; + struct termios tio; + int efd = -1; + u8 *str = 0; + u8 *cmd = 0; + int do_quit = 0; + + + clib_mem_init (0, 64ULL << 10); + + /* process command line */ + argc--; + argv++; + + if (argc > 1 && strcmp (argv[0], "-s") == 0) + { + s->config = argv[1]; + argc -= 2; + argv += 2; + } + else + s->config = SOCKET_FILE; + + while (argc--) + cmd = format (cmd, "%s%c", (argv++)[0], argc ? ' ' : 0); + + s->flags = SOCKET_IS_CLIENT; + + error = clib_socket_init (s); + if (error) + goto done; + + /* Capture terminal resize events */ + memset (&sa, 0, sizeof (struct sigaction)); + sa.sa_handler = signal_handler_winch; + + if (sigaction (SIGWINCH, &sa, 0) < 0) + { + error = clib_error_return_unix (0, "sigaction"); + goto done; + } + + sa.sa_handler = signal_handler_term; + if (sigaction (SIGTERM, &sa, 0) < 0) + { + error = clib_error_return_unix (0, "sigaction"); + goto done; + } + + /* Save the original tty state so we can restore it later */ + tcgetattr (STDIN_FILENO, &orig_tio); + + /* Tweak the tty settings */ + tio = orig_tio; + /* echo off, canonical mode off, ext'd input processing off */ + tio.c_lflag &= ~(ECHO | ICANON | IEXTEN); + tio.c_cc[VMIN] = 1; /* 1 byte at a time */ + tio.c_cc[VTIME] = 0; /* no timer */ + tcsetattr (STDIN_FILENO, TCSAFLUSH, &tio); + + efd = epoll_create1 (0); + + /* register STDIN */ + event.events = EPOLLIN | EPOLLPRI | EPOLLERR; + event.data.fd = STDIN_FILENO; + if (epoll_ctl (efd, EPOLL_CTL_ADD, STDIN_FILENO, &event) != 0) + { + error = clib_error_return_unix (0, "epoll_ctl[%d]", STDIN_FILENO); + goto done; + } + + /* register socket */ + event.events = EPOLLIN | EPOLLPRI | EPOLLERR; + event.data.fd = s->fd; + if (epoll_ctl (efd, EPOLL_CTL_ADD, s->fd, &event) != 0) + { + error = clib_error_return_unix (0, "epoll_ctl[%d]", s->fd); + goto done; + } + + while (1) + { + int n; + + if (window_resized) + { + window_resized = 0; + send_naws (s); + } + + if ((n = epoll_wait (efd, &event, 1, -1)) < 0) + { + /* maybe we received signal */ + if (errno == EINTR) + continue; + + error = clib_error_return_unix (0, "epoll_wait"); + goto done; + } + + if (n == 0) + continue; + + if (event.data.fd == STDIN_FILENO) + { + int n; + char c[100]; + + n = read (STDIN_FILENO, c, sizeof (c)); + if (n > 0) + { + memcpy (clib_socket_tx_add (s, n), c, n); + error = clib_socket_tx (s); + if (error) + goto done; + } + else if (n < 0) + clib_warning ("read rv=%d", n); + } + else if (event.data.fd == s->fd) + { + error = clib_socket_rx (s, 100); + if (error) + break; + + if (clib_socket_rx_end_of_file (s)) + break; + + str = process_input (str, s, cmd == 0); + + if (vec_len (str) > 0) + { + n = write (STDOUT_FILENO, str, vec_len (str)); + if (n < 0) + { + error = clib_error_return_unix (0, "write"); + goto done; + } + vec_reset_length (str); + } + + if (do_quit) + { + clib_socket_tx_add_formatted (s, "q\n"); + clib_socket_tx (s); + do_quit = 0; + } + if (cmd) + { + clib_socket_tx_add_formatted (s, "%s\n", cmd); + clib_socket_tx (s); + vec_free (cmd); + do_quit = 1; + } + } + else + { + error = clib_error_return (0, "unknown fd"); + goto done; + } + } + + error = clib_socket_close (s); + +done: + vec_free (cmd); + vec_free (str); + if (efd > -1) + close (efd); + + if (error) + { + clib_error_report (error); + return 1; + } + tcsetattr (STDIN_FILENO, TCSAFLUSH, &orig_tio); + return 0; +} + +/* *INDENT-ON* */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/vpp/conf/startup.conf b/src/vpp/conf/startup.conf index f671439b..1d22358d 100644 --- a/src/vpp/conf/startup.conf +++ b/src/vpp/conf/startup.conf @@ -3,6 +3,7 @@ unix { nodaemon log /tmp/vpp.log full-coredump + cli-listen /run/vpp/cli.sock } api-trace { -- cgit 1.2.3-korg From 7d4a22cdea203c94fca13a0cfc4a0e5364719f8e Mon Sep 17 00:00:00 2001 From: John Lo Date: Mon, 24 Jul 2017 13:08:36 -0400 Subject: Add sample config of bonded interface in startup.conf template Change-Id: I3985befbdd2a1a1a0e9473095034d0da7e5c32ed Signed-off-by: John Lo --- src/vpp/conf/startup.conf | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/vpp/conf/startup.conf') diff --git a/src/vpp/conf/startup.conf b/src/vpp/conf/startup.conf index 1d22358d..e63026bc 100644 --- a/src/vpp/conf/startup.conf +++ b/src/vpp/conf/startup.conf @@ -81,6 +81,16 @@ cpu { # num-rx-queues 2 # } + ## Specify bonded interface and its slaves via PCI addresses + ## + ## Bonded interface in XOR load balance mode (mode 2) with L3 and L4 headers + # vdev eth_bond0,mode=2,slave=0000:02:00.0,slave=0000:03:00.0,xmit_policy=l34 + # vdev eth_bond1,mode=2,slave=0000:02:00.1,slave=0000:03:00.1,xmit_policy=l34 + ## + ## Bonded interface in Active-Back up mode (mode 1) + # vdev eth_bond0,mode=1,slave=0000:02:00.0,slave=0000:03:00.0 + # vdev eth_bond1,mode=1,slave=0000:02:00.1,slave=0000:03:00.1 + ## Change UIO driver used by VPP, Options are: igb_uio, vfio-pci ## and uio_pci_generic (default) # uio-driver vfio-pci -- cgit 1.2.3-korg From c900ccc34ca74f30cc3bee621c54954c02be36ff Mon Sep 17 00:00:00 2001 From: Ed Warnicke Date: Sun, 20 Aug 2017 18:42:19 -0700 Subject: Enabled gid vpp in startup.conf to allow non-root vppctl access Change-Id: I1ca9736dbefc9c284f5176de176fcc3dd1bfcd82 Signed-off-by: Ed Warnicke --- src/vpp/conf/startup.conf | 1 + 1 file changed, 1 insertion(+) (limited to 'src/vpp/conf/startup.conf') diff --git a/src/vpp/conf/startup.conf b/src/vpp/conf/startup.conf index e63026bc..6ebe1efe 100644 --- a/src/vpp/conf/startup.conf +++ b/src/vpp/conf/startup.conf @@ -4,6 +4,7 @@ unix { log /tmp/vpp.log full-coredump cli-listen /run/vpp/cli.sock + gid vpp } api-trace { -- cgit 1.2.3-korg From 49fe046e431c4d76b0c45c609e05e1b0a3063360 Mon Sep 17 00:00:00 2001 From: Dave Barach Date: Tue, 12 Sep 2017 17:06:56 -0400 Subject: API message table inspection utilities Add doxygen tags for show/clear commands Change-Id: Ic939c561b15b0b720a8db1ecacc17e3d74419e1d Signed-off-by: Dave Barach --- src/vlibapi/api_common.h | 3 + src/vlibmemory/memory_vlib.c | 493 +++++++++++++++++++++++++++++++++++++------ src/vpp/conf/startup.conf | 13 ++ 3 files changed, 449 insertions(+), 60 deletions(-) (limited to 'src/vpp/conf/startup.conf') diff --git a/src/vlibapi/api_common.h b/src/vlibapi/api_common.h index bbeccfc2..dc6761bc 100644 --- a/src/vlibapi/api_common.h +++ b/src/vlibapi/api_common.h @@ -255,6 +255,9 @@ typedef struct /* Replay in progress? */ int replay_in_progress; + /* Dump (msg-name, crc) snapshot here at startup */ + u8 *save_msg_table_filename; + /* List of API client reaper functions */ _vl_msg_api_function_list_elt_t *reaper_function_registrations; diff --git a/src/vlibmemory/memory_vlib.c b/src/vlibmemory/memory_vlib.c index 55a90d64..401f388a 100644 --- a/src/vlibmemory/memory_vlib.c +++ b/src/vlibmemory/memory_vlib.c @@ -38,6 +38,14 @@ #include #include +/** + * @file + * @brief Binary API messaging via shared memory + * Low-level, primary provisioning interface + */ +/*? %%clicmd:group_label Binary API CLI %% ?*/ +/*? %%syscfg:group_label Binary API configuration %% ?*/ + #define TRACE_VLIB_MEMORY_QUEUE 0 #include /* enumerate all vlib messages */ @@ -188,7 +196,6 @@ vl_api_memclnt_create_t_handler (vl_api_memclnt_create_t * mp) int rv = 0; void *oldheap; api_main_t *am = &api_main; - u8 *serialized_message_table = 0; /* * This is tortured. Maintain a vlib-address-space private @@ -220,9 +227,6 @@ vl_api_memclnt_create_t_handler (vl_api_memclnt_create_t * mp) svm = am->vlib_rp; - if (am->serialized_message_table_in_shmem == 0) - serialized_message_table = vl_api_serialize_message_table (am, 0); - pthread_mutex_lock (&svm->mutex); oldheap = svm_push_data_heap (svm); *regpp = clib_mem_alloc (sizeof (vl_api_registration_t)); @@ -237,14 +241,11 @@ vl_api_memclnt_create_t_handler (vl_api_memclnt_create_t * mp) regp->name = format (0, "%s", mp->name); vec_add1 (regp->name, 0); - if (serialized_message_table) - am->serialized_message_table_in_shmem = - vec_dup (serialized_message_table); pthread_mutex_unlock (&svm->mutex); svm_pop_heap (oldheap); - vec_free (serialized_message_table); + ASSERT (am->serialized_message_table_in_shmem); rp = vl_msg_api_alloc (sizeof (*rp)); rp->_vl_msg_id = ntohs (VL_API_MEMCLNT_CREATE_REPLY); @@ -487,6 +488,9 @@ memclnt_process (vlib_main_t * vm, f64 sleep_time, start_time; f64 vector_rate; int i; + u8 *serialized_message_table = 0; + svm_region_t *svm; + void *oldheap; vlib_set_queue_signal_callback (vm, memclnt_queue_callback); @@ -519,6 +523,60 @@ memclnt_process (vlib_main_t * vm, rp->last_msg_id); } + /* + * Snapshoot the api message table. + */ + serialized_message_table = vl_api_serialize_message_table (am, 0); + + svm = am->vlib_rp; + pthread_mutex_lock (&svm->mutex); + oldheap = svm_push_data_heap (svm); + + am->serialized_message_table_in_shmem = vec_dup (serialized_message_table); + + pthread_mutex_unlock (&svm->mutex); + svm_pop_heap (oldheap); + + /* + * Save the api message table snapshot, if configured + */ + if (am->save_msg_table_filename) + { + int fd, rv; + u8 *chroot_file; + if (strstr ((char *) am->save_msg_table_filename, "..") + || index ((char *) am->save_msg_table_filename, '/')) + { + clib_warning ("illegal save-message-table filename '%s'", + am->save_msg_table_filename); + goto skip_save; + } + + chroot_file = format (0, "/tmp/%s%c", am->save_msg_table_filename, 0); + + fd = creat ((char *) chroot_file, 0644); + + if (fd < 0) + { + clib_unix_warning ("creat"); + goto skip_save; + } + rv = write (fd, serialized_message_table, + vec_len (serialized_message_table)); + + if (rv != vec_len (serialized_message_table)) + clib_unix_warning ("write"); + + rv = close (fd); + if (rv < 0) + clib_unix_warning ("close"); + + vec_free (chroot_file); + } + +skip_save: + vec_free (serialized_message_table); + /* $$$ pay attention to frame size, control CPU usage */ while (1) { @@ -726,6 +784,15 @@ memclnt_process (vlib_main_t * vm, return 0; } +/* *INDENT-OFF* */ +VLIB_REGISTER_NODE (memclnt_node,static) = { + .function = memclnt_process, + .type = VLIB_NODE_TYPE_PROCESS, + .name = "api-rx-from-ring", + .state = VLIB_NODE_STATE_DISABLED, +}; +/* *INDENT-ON* */ + static clib_error_t * vl_api_show_histogram_command (vlib_main_t * vm, @@ -762,11 +829,15 @@ vl_api_show_histogram_command (vlib_main_t * vm, return 0; } +/*? + * Display the binary api sleep-time histogram +?*/ /* *INDENT-OFF* */ -VLIB_CLI_COMMAND (cli_show_api_histogram_command, static) = { - .path = "show api histogram", - .short_help = "show api histogram", - .function = vl_api_show_histogram_command, +VLIB_CLI_COMMAND (cli_show_api_histogram_command, static) = +{ + .path = "show api histogram", + .short_help = "show api histogram", + .function = vl_api_show_histogram_command, }; /* *INDENT-ON* */ @@ -782,21 +853,15 @@ vl_api_clear_histogram_command (vlib_main_t * vm, return 0; } +/*? + * Clear the binary api sleep-time histogram +?*/ /* *INDENT-OFF* */ -VLIB_CLI_COMMAND (cli_clear_api_histogram_command, static) = { - .path = "clear api histogram", - .short_help = "clear api histogram", - .function = vl_api_clear_histogram_command, -}; -/* *INDENT-ON* */ - - -/* *INDENT-OFF* */ -VLIB_REGISTER_NODE (memclnt_node,static) = { - .function = memclnt_process, - .type = VLIB_NODE_TYPE_PROCESS, - .name = "api-rx-from-ring", - .state = VLIB_NODE_STATE_DISABLED, +VLIB_CLI_COMMAND (cli_clear_api_histogram_command, static) = +{ + .path = "clear api histogram", + .short_help = "clear api histogram", + .function = vl_api_clear_histogram_command, }; /* *INDENT-ON* */ @@ -1064,33 +1129,46 @@ vl_api_status_command (vlib_main_t * vm, } /* *INDENT-OFF* */ -VLIB_CLI_COMMAND (cli_show_api_command, static) = { - .path = "show api", - .short_help = "Show API information", +VLIB_CLI_COMMAND (cli_show_api_command, static) = +{ + .path = "show api", + .short_help = "Show API information", }; /* *INDENT-ON* */ +/*? + * Display binary api message allocation ring statistics +?*/ /* *INDENT-OFF* */ -VLIB_CLI_COMMAND (cli_show_api_ring_command, static) = { - .path = "show api ring-stats", - .short_help = "Message ring statistics", - .function = vl_api_ring_command, +VLIB_CLI_COMMAND (cli_show_api_ring_command, static) = +{ + .path = "show api ring-stats", + .short_help = "Message ring statistics", + .function = vl_api_ring_command, }; /* *INDENT-ON* */ +/*? + * Display current api client connections +?*/ /* *INDENT-OFF* */ -VLIB_CLI_COMMAND (cli_show_api_clients_command, static) = { - .path = "show api clients", - .short_help = "Client information", - .function = vl_api_client_command, +VLIB_CLI_COMMAND (cli_show_api_clients_command, static) = +{ + .path = "show api clients", + .short_help = "Client information", + .function = vl_api_client_command, }; /* *INDENT-ON* */ +/*? + * Display the current api message tracing status +?*/ /* *INDENT-OFF* */ -VLIB_CLI_COMMAND (cli_show_api_status_command, static) = { - .path = "show api status", - .short_help = "Show API trace status", - .function = vl_api_status_command, +VLIB_CLI_COMMAND (cli_show_api_status_command, static) = +{ + .path = "show api trace-status", + .short_help = "Display API trace status", + .function = vl_api_status_command, }; /* *INDENT-ON* */ @@ -1133,11 +1211,15 @@ vl_api_message_table_command (vlib_main_t * vm, return 0; } +/*? + * Display the current api message decode tables +?*/ /* *INDENT-OFF* */ -VLIB_CLI_COMMAND (cli_show_api_message_table_command, static) = { - .path = "show api message-table", - .short_help = "Message Table", - .function = vl_api_message_table_command, +VLIB_CLI_COMMAND (cli_show_api_message_table_command, static) = +{ + .path = "show api message-table", + .short_help = "Message Table", + .function = vl_api_message_table_command, }; /* *INDENT-ON* */ @@ -1207,11 +1289,15 @@ configure: return 0; } +/*? + * Control the binary API trace mechanism +?*/ /* *INDENT-OFF* */ -VLIB_CLI_COMMAND (trace, static) = { - .path = "set api-trace", - .short_help = "API trace", - .function = vl_api_trace_command, +VLIB_CLI_COMMAND (trace, static) = +{ + .path = "set api-trace [on][on tx][on rx][off][free][debug on][debug off]", + .short_help = "API trace", + .function = vl_api_trace_command, }; /* *INDENT-ON* */ @@ -1265,9 +1351,9 @@ format_api_msg_range (u8 * s, va_list * args) vl_api_msg_range_t *rp = va_arg (*args, vl_api_msg_range_t *); if (rp == 0) - s = format (s, "%-20s%9s%9s", "Name", "First-ID", "Last-ID"); + s = format (s, "%-50s%9s%9s", "Name", "First-ID", "Last-ID"); else - s = format (s, "%-20s%9d%9d", rp->name, rp->first_msg_id, + s = format (s, "%-50s%9d%9d", rp->name, rp->first_msg_id, rp->last_msg_id); return s; @@ -1303,11 +1389,15 @@ vl_api_show_plugin_command (vlib_main_t * vm, return 0; } +/*? + * Display the plugin binary API message range table +?*/ /* *INDENT-OFF* */ -VLIB_CLI_COMMAND (cli_show_api_plugin_command, static) = { - .path = "show api plugin", - .short_help = "show api plugin", - .function = vl_api_show_plugin_command, +VLIB_CLI_COMMAND (cli_show_api_plugin_command, static) = +{ + .path = "show api plugin", + .short_help = "show api plugin", + .function = vl_api_show_plugin_command, }; /* *INDENT-ON* */ @@ -1925,12 +2015,17 @@ api_trace_command_fn (vlib_main_t * vm, return 0; } +/*? + * Display, replay, or save a binary API trace +?*/ + /* *INDENT-OFF* */ -VLIB_CLI_COMMAND (api_trace_command, static) = { - .path = "api trace", - .short_help = - "api trace [on|off][dump|save|replay ][status][free][post-mortem-on]", - .function = api_trace_command_fn, +VLIB_CLI_COMMAND (api_trace_command, static) = +{ + .path = "api trace", + .short_help = + "api trace [on|off][dump|save|replay ][status][free][post-mortem-on]", + .function = api_trace_command_fn, }; /* *INDENT-ON* */ @@ -1951,6 +2046,9 @@ api_config_fn (vlib_main_t * vm, unformat_input_t * input) vl_msg_api_trace_onoff (am, which, 1 /* on */ ); vl_msg_api_post_mortem_dump_enable_disable (1 /* enable */ ); } + else if (unformat (input, "save-api-table %s", + &am->save_msg_table_filename)) + ; else return clib_error_return (0, "unknown input `%U'", format_unformat_error, input); @@ -1958,6 +2056,12 @@ api_config_fn (vlib_main_t * vm, unformat_input_t * input) return 0; } +/*? + * This module has three configuration parameters: + * "on" or "enable" - enables binary api tracing + * "nitems " - sets the size of the circular buffer to + * "save-api-table " - dumps the API message table to /tmp/ +?*/ VLIB_CONFIG_FUNCTION (api_config_fn, "api-trace"); static clib_error_t * @@ -1986,6 +2090,275 @@ api_queue_config_fn (vlib_main_t * vm, unformat_input_t * input) VLIB_CONFIG_FUNCTION (api_queue_config_fn, "api-queue"); +static u8 * +extract_name (u8 * s) +{ + u8 *rv; + + rv = vec_dup (s); + + while (vec_len (rv) && rv[vec_len (rv)] != '_') + _vec_len (rv)--; + + rv[vec_len (rv)] = 0; + + return rv; +} + +static u8 * +extract_crc (u8 * s) +{ + int i; + u8 *rv; + + rv = vec_dup (s); + + for (i = vec_len (rv) - 1; i >= 0; i--) + { + if (rv[i] == '_') + { + vec_delete (rv, i + 1, 0); + break; + } + } + return rv; +} + +typedef struct +{ + u8 *name_and_crc; + u8 *name; + u8 *crc; + u32 msg_index; + int which; +} msg_table_unserialize_t; + +static int +table_id_cmp (void *a1, void *a2) +{ + msg_table_unserialize_t *n1 = a1; + msg_table_unserialize_t *n2 = a2; + + return (n1->msg_index - n2->msg_index); +} + +static int +table_name_and_crc_cmp (void *a1, void *a2) +{ + msg_table_unserialize_t *n1 = a1; + msg_table_unserialize_t *n2 = a2; + + return strcmp ((char *) n1->name_and_crc, (char *) n2->name_and_crc); +} + +static clib_error_t * +dump_api_table_file_command_fn (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + u8 *filename = 0; + api_main_t *am = &api_main; + serialize_main_t _sm, *sm = &_sm; + clib_error_t *error; + u32 nmsgs; + u32 msg_index; + u8 *name_and_crc; + int compare_current = 0; + int numeric_sort = 0; + msg_table_unserialize_t *table = 0, *item; + u32 i; + u32 ndifferences = 0; + + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (input, "file %s", &filename)) + ; + else if (unformat (input, "compare-current") + || unformat (input, "compare")) + compare_current = 1; + else if (unformat (input, "numeric")) + numeric_sort = 1; + else + return clib_error_return (0, "unknown input `%U'", + format_unformat_error, input); + } + + if (numeric_sort && compare_current) + return clib_error_return + (0, "Comparison and numeric sorting are incompatible"); + + if (filename == 0) + return clib_error_return (0, "File not specified"); + + /* Load the serialized message table from the table dump */ + + error = unserialize_open_unix_file (sm, (char *) filename); + + if (error) + return error; + + unserialize_integer (sm, &nmsgs, sizeof (u32)); + + for (i = 0; i < nmsgs; i++) + { + msg_index = unserialize_likely_small_unsigned_integer (sm); + unserialize_cstring (sm, (char **) &name_and_crc); + vec_add2 (table, item, 1); + item->msg_index = msg_index; + item->name_and_crc = name_and_crc; + item->name = extract_name (name_and_crc); + item->crc = extract_crc (name_and_crc); + item->which = 0; /* file */ + } + serialize_close (sm); + + /* Compare with the current image? */ + if (compare_current) + { + /* Append the current message table */ + u8 *tblv = vec_dup (am->serialized_message_table_in_shmem); + + serialize_open_vector (sm, tblv); + unserialize_integer (sm, &nmsgs, sizeof (u32)); + + for (i = 0; i < nmsgs; i++) + { + msg_index = unserialize_likely_small_unsigned_integer (sm); + unserialize_cstring (sm, (char **) &name_and_crc); + + vec_add2 (table, item, 1); + item->msg_index = msg_index; + item->name_and_crc = name_and_crc; + item->name = extract_name (name_and_crc); + item->crc = extract_crc (name_and_crc); + item->which = 1; /* current_image */ + } + } + + /* Sort the table. */ + if (numeric_sort) + vec_sort_with_function (table, table_id_cmp); + else + vec_sort_with_function (table, table_name_and_crc_cmp); + + if (compare_current) + { + ndifferences = 0; + + /* + * In this case, the recovered table will have two entries per + * API message. So, if entries i and i+1 match, the message definitions + * are identical. Otherwise, the crc is different, or a message is + * present in only one of the tables. + */ + vlib_cli_output (vm, "%=60s %s", "Message Name", "Result"); + + for (i = 0; i < vec_len (table);) + { + /* Last message lonely? */ + if (i == vec_len (table) - 1) + { + ndifferences++; + goto last_unique; + } + + /* Identical pair? */ + if (!strncmp + ((char *) table[i].name_and_crc, + (char *) table[i + 1].name_and_crc, + vec_len (table[i].name_and_crc))) + { + i += 2; + continue; + } + + ndifferences++; + + /* Only in one of two tables? */ + if (strncmp ((char *) table[i].name, (char *) table[i + 1].name, + vec_len (table[i].name))) + { + last_unique: + vlib_cli_output (vm, "%-60s only in %s", + table[i].name, table[i].which ? + "image" : "file"); + i++; + continue; + } + /* In both tables, but with different signatures */ + vlib_cli_output (vm, "%-60s definition changed", table[i].name); + i += 2; + } + if (ndifferences == 0) + vlib_cli_output (vm, "No api message signature differences found."); + else + vlib_cli_output (vm, "Found %u api message signature differences", + ndifferences); + goto cleanup; + } + + /* Dump the table, sorted as shown above */ + vlib_cli_output (vm, "%=60s %=8s %=10s", "Message name", "MsgID", "CRC"); + + for (i = 0; i < vec_len (table); i++) + { + item = table + i; + vlib_cli_output (vm, "%-60s %8u %10s", item->name, + item->msg_index, item->crc); + } + +cleanup: + for (i = 0; i < vec_len (table); i++) + { + vec_free (table[i].name_and_crc); + vec_free (table[i].name); + vec_free (table[i].crc); + } + + vec_free (table); + + return 0; +} + +/*? + * Displays a serialized API message decode table, sorted by message name + * + * @cliexpar + * @cliexstart{show api dump file } + * Message name MsgID CRC + * accept_session 407 8e2a127e + * accept_session_reply 408 67d8c22a + * add_node_next 549 e4202993 + * add_node_next_reply 550 e89d6eed + * etc. + * @cliexend +?*/ + +/*? + * Compares a serialized API message decode table with the current image + * + * @cliexpar + * @cliexstart{show api dump file compare} + * ip_add_del_route definition changed + * ip_table_add_del definition changed + * l2_macs_event only in image + * vnet_ip4_fib_counters only in file + * vnet_ip4_nbr_counters only in file + * @cliexend +?*/ + +/*? + * Display a serialized API message decode table +?*/ +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (dump_api_table_file, static) = +{ + .path = "show api dump", + .short_help = "show api dump file [numeric | compare-current]", + .function = dump_api_table_file_command_fn, +}; +/* *INDENT-ON* */ + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vpp/conf/startup.conf b/src/vpp/conf/startup.conf index 6ebe1efe..c3b9872e 100644 --- a/src/vpp/conf/startup.conf +++ b/src/vpp/conf/startup.conf @@ -8,7 +8,20 @@ unix { } api-trace { +## This stanza controls binary API tracing. Unless there is a very strong reason, +## please leave this feature enabled. on +## Additional parameters: +## +## To set the number of binary API trace records in the circular buffer, configure nitems +## +## nitems +## +## To save the api message table decode tables, configure a filename. Results in /tmp/ +## Very handy for understanding api message changes between versions, identifying missing +## plugins, and so forth. +## +## save-api-table } api-segment { -- cgit 1.2.3-korg