* Re: [PATCH v2 10/11] vsock_test: skip read() in test_stream*close tests on a VMCI host
From: Stefano Garzarella @ 2019-08-01 15:58 UTC (permalink / raw)
To: Sergei Shtylyov
Cc: netdev, kvm, Stefan Hajnoczi, Dexuan Cui, virtualization,
David S. Miller, Jorgen Hansen, linux-kernel
In-Reply-To: <79ffb2a6-8ed2-cce2-7704-ed872446c0fe@cogentembedded.com>
On Thu, Aug 01, 2019 at 06:53:32PM +0300, Sergei Shtylyov wrote:
> Hello!
>
Hi :)
> On 08/01/2019 06:25 PM, Stefano Garzarella wrote:
>
> > When VMCI transport is used, if the guest closes a connection,
> > all data is gone and EOF is returned, so we should skip the read
> > of data written by the peer before closing the connection.
> >
> > Reported-by: Jorgen Hansen <jhansen@vmware.com>
> > Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
> > ---
> > tools/testing/vsock/vsock_test.c | 26 ++++++++++++++++++++++++--
> > 1 file changed, 24 insertions(+), 2 deletions(-)
> >
> > diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
> > index cb606091489f..64adf45501ca 100644
> > --- a/tools/testing/vsock/vsock_test.c
> > +++ b/tools/testing/vsock/vsock_test.c
> [...]
> > @@ -79,16 +80,27 @@ static void test_stream_client_close_server(const struct test_opts *opts)
> > exit(EXIT_FAILURE);
> > }
> >
> > + local_cid = vsock_get_local_cid(fd);
> > +
> > control_expectln("CLOSED");
> >
> > send_byte(fd, -EPIPE);
> > - recv_byte(fd, 1);
> > +
> > + /* Skip the read of data wrote by the peer if we are on VMCI and
>
> s/wrote/written/?
>
Thanks, I'll fix it!
Stefano
> > + * we are on the host side, because when the guest closes a
> > + * connection, all data is gone and EOF is returned.
> > + */
> > + if (!(opts->transport == TEST_TRANSPORT_VMCI &&
> > + local_cid == VMADDR_CID_HOST))
> > + recv_byte(fd, 1);
> > +
> > recv_byte(fd, 0);
> > close(fd);
> > }
> [...]
>
> MBR, Sergei
--
^ permalink raw reply
* Re: [PATCH v2 10/11] vsock_test: skip read() in test_stream*close tests on a VMCI host
From: Sergei Shtylyov @ 2019-08-01 15:53 UTC (permalink / raw)
To: Stefano Garzarella, netdev
Cc: kvm, Stefan Hajnoczi, Dexuan Cui, virtualization, David S. Miller,
Jorgen Hansen, linux-kernel
In-Reply-To: <20190801152541.245833-11-sgarzare@redhat.com>
Hello!
On 08/01/2019 06:25 PM, Stefano Garzarella wrote:
> When VMCI transport is used, if the guest closes a connection,
> all data is gone and EOF is returned, so we should skip the read
> of data written by the peer before closing the connection.
>
> Reported-by: Jorgen Hansen <jhansen@vmware.com>
> Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
> ---
> tools/testing/vsock/vsock_test.c | 26 ++++++++++++++++++++++++--
> 1 file changed, 24 insertions(+), 2 deletions(-)
>
> diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
> index cb606091489f..64adf45501ca 100644
> --- a/tools/testing/vsock/vsock_test.c
> +++ b/tools/testing/vsock/vsock_test.c
[...]
> @@ -79,16 +80,27 @@ static void test_stream_client_close_server(const struct test_opts *opts)
> exit(EXIT_FAILURE);
> }
>
> + local_cid = vsock_get_local_cid(fd);
> +
> control_expectln("CLOSED");
>
> send_byte(fd, -EPIPE);
> - recv_byte(fd, 1);
> +
> + /* Skip the read of data wrote by the peer if we are on VMCI and
s/wrote/written/?
> + * we are on the host side, because when the guest closes a
> + * connection, all data is gone and EOF is returned.
> + */
> + if (!(opts->transport == TEST_TRANSPORT_VMCI &&
> + local_cid == VMADDR_CID_HOST))
> + recv_byte(fd, 1);
> +
> recv_byte(fd, 0);
> close(fd);
> }
[...]
MBR, Sergei
^ permalink raw reply
* Re: [PATCH bpf] libbpf: set BTF FD for prog only when there is supported .BTF.ext data
From: Alexei Starovoitov @ 2019-08-01 15:47 UTC (permalink / raw)
To: Andrii Nakryiko
Cc: bpf, Network Development, Alexei Starovoitov, Daniel Borkmann,
Andrey Ignatov, Andrii Nakryiko, Kernel Team
In-Reply-To: <20190801072405.2835116-1-andriin@fb.com>
On Thu, Aug 1, 2019 at 12:41 AM Andrii Nakryiko <andriin@fb.com> wrote:
>
> 5d01ab7bac46 ("libbpf: fix erroneous multi-closing of BTF FD")
> introduced backwards-compatibility issue, manifesting itself as -E2BIG
> error returned on program load due to unknown non-zero btf_fd attribute
> value for BPF_PROG_LOAD sys_bpf() sub-command.
>
> This patch fixes bug by ensuring that we only ever associate BTF FD with
> program if there is a BTF.ext data that was successfully loaded into
> kernel, which automatically means kernel supports func_info/line_info
> and associated BTF FD for progs (checked and ensured also by BTF
> sanitization code).
>
> Fixes: 5d01ab7bac46 ("libbpf: fix erroneous multi-closing of BTF FD")
> Reported-by: Andrey Ignatov <rdna@fb.com>
> Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Applied. Thanks
^ permalink raw reply
* Re: [PATCH rdma-next 0/3] ODP support for mlx5 DC QPs
From: Leon Romanovsky @ 2019-08-01 14:55 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Doug Ledford, RDMA mailing list, Michael Guralnik, Moni Shoua,
Saeed Mahameed, linux-netdev
In-Reply-To: <20190801142432.GD23885@mellanox.com>
On Thu, Aug 01, 2019 at 02:24:37PM +0000, Jason Gunthorpe wrote:
> On Thu, Aug 01, 2019 at 03:21:36PM +0300, Leon Romanovsky wrote:
> > From: Leon Romanovsky <leonro@mellanox.com>
> >
> > From Michael,
> >
> > The series adds support for on-demand paging for DC transport.
> > Adding handling of DC WQE parsing upon page faults and exposing
> > capabilities.
> >
> > As DC is mlx-only transport, the capabilities are exposed to the user
> > using the direct-verbs mechanism. Namely through the mlx5dv_query_device.
>
> The cover letter should like to the RDMA core PR that uses the new
> API...
PR will be send in near future by Yishai. I don't have PR links at the
submission stage yet.
Thanks
>
> Jason
^ permalink raw reply
* [PATCH v2 03/11] VSOCK: extract utility functions from vsock_diag_test.c
From: Stefano Garzarella @ 2019-08-01 15:25 UTC (permalink / raw)
To: netdev
Cc: kvm, Stefan Hajnoczi, Dexuan Cui, virtualization, David S. Miller,
Jorgen Hansen, linux-kernel
In-Reply-To: <20190801152541.245833-1-sgarzare@redhat.com>
From: Stefan Hajnoczi <stefanha@redhat.com>
Move useful functions into a separate file in preparation for more
vsock test programs.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
v2:
* aligned with the current SPDX [Stefano]
---
tools/testing/vsock/Makefile | 2 +-
tools/testing/vsock/util.c | 66 +++++++++++++++++++
tools/testing/vsock/util.h | 36 +++++++++++
tools/testing/vsock/vsock_diag_test.c | 92 +++++++--------------------
4 files changed, 125 insertions(+), 71 deletions(-)
create mode 100644 tools/testing/vsock/util.c
create mode 100644 tools/testing/vsock/util.h
diff --git a/tools/testing/vsock/Makefile b/tools/testing/vsock/Makefile
index d41a4e13960a..a916878a2d8c 100644
--- a/tools/testing/vsock/Makefile
+++ b/tools/testing/vsock/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
all: test
test: vsock_diag_test
-vsock_diag_test: vsock_diag_test.o timeout.o control.o
+vsock_diag_test: vsock_diag_test.o timeout.o control.o util.o
CFLAGS += -g -O2 -Werror -Wall -I. -I../../include -I../../../usr/include -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE -D_GNU_SOURCE
.PHONY: all test clean
diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
new file mode 100644
index 000000000000..f40f45b36d2f
--- /dev/null
+++ b/tools/testing/vsock/util.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vsock test utilities
+ *
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * Author: Stefan Hajnoczi <stefanha@redhat.com>
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+
+#include "timeout.h"
+#include "util.h"
+
+/* Install signal handlers */
+void init_signals(void)
+{
+ struct sigaction act = {
+ .sa_handler = sigalrm,
+ };
+
+ sigaction(SIGALRM, &act, NULL);
+ signal(SIGPIPE, SIG_IGN);
+}
+
+/* Parse a CID in string representation */
+unsigned int parse_cid(const char *str)
+{
+ char *endptr = NULL;
+ unsigned long n;
+
+ errno = 0;
+ n = strtoul(str, &endptr, 10);
+ if (errno || *endptr != '\0') {
+ fprintf(stderr, "malformed CID \"%s\"\n", str);
+ exit(EXIT_FAILURE);
+ }
+ return n;
+}
+
+/* Run test cases. The program terminates if a failure occurs. */
+void run_tests(const struct test_case *test_cases,
+ const struct test_opts *opts)
+{
+ int i;
+
+ for (i = 0; test_cases[i].name; i++) {
+ void (*run)(const struct test_opts *opts);
+
+ printf("%s...", test_cases[i].name);
+ fflush(stdout);
+
+ if (opts->mode == TEST_MODE_CLIENT)
+ run = test_cases[i].run_client;
+ else
+ run = test_cases[i].run_server;
+
+ if (run)
+ run(opts);
+
+ printf("ok\n");
+ }
+}
diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h
new file mode 100644
index 000000000000..033e7d59a42a
--- /dev/null
+++ b/tools/testing/vsock/util.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef UTIL_H
+#define UTIL_H
+
+/* Tests can either run as the client or the server */
+enum test_mode {
+ TEST_MODE_UNSET,
+ TEST_MODE_CLIENT,
+ TEST_MODE_SERVER
+};
+
+/* Test runner options */
+struct test_opts {
+ enum test_mode mode;
+ unsigned int peer_cid;
+};
+
+/* A test case definition. Test functions must print failures to stderr and
+ * terminate with exit(EXIT_FAILURE).
+ */
+struct test_case {
+ const char *name; /* human-readable name */
+
+ /* Called when test mode is TEST_MODE_CLIENT */
+ void (*run_client)(const struct test_opts *opts);
+
+ /* Called when test mode is TEST_MODE_SERVER */
+ void (*run_server)(const struct test_opts *opts);
+};
+
+void init_signals(void);
+unsigned int parse_cid(const char *str);
+void run_tests(const struct test_case *test_cases,
+ const struct test_opts *opts);
+
+#endif /* UTIL_H */
diff --git a/tools/testing/vsock/vsock_diag_test.c b/tools/testing/vsock/vsock_diag_test.c
index fc391e041954..944c8a72eed7 100644
--- a/tools/testing/vsock/vsock_diag_test.c
+++ b/tools/testing/vsock/vsock_diag_test.c
@@ -9,12 +9,10 @@
#include <getopt.h>
#include <stdio.h>
-#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
-#include <signal.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -28,12 +26,7 @@
#include "timeout.h"
#include "control.h"
-
-enum test_mode {
- TEST_MODE_UNSET,
- TEST_MODE_CLIENT,
- TEST_MODE_SERVER
-};
+#include "util.h"
/* Per-socket status */
struct vsock_stat {
@@ -334,7 +327,7 @@ static void free_sock_stat(struct list_head *sockets)
free(st);
}
-static void test_no_sockets(unsigned int peer_cid)
+static void test_no_sockets(const struct test_opts *opts)
{
LIST_HEAD(sockets);
@@ -345,7 +338,7 @@ static void test_no_sockets(unsigned int peer_cid)
free_sock_stat(&sockets);
}
-static void test_listen_socket_server(unsigned int peer_cid)
+static void test_listen_socket_server(const struct test_opts *opts)
{
union {
struct sockaddr sa;
@@ -383,7 +376,7 @@ static void test_listen_socket_server(unsigned int peer_cid)
free_sock_stat(&sockets);
}
-static void test_connect_client(unsigned int peer_cid)
+static void test_connect_client(const struct test_opts *opts)
{
union {
struct sockaddr sa;
@@ -392,7 +385,7 @@ static void test_connect_client(unsigned int peer_cid)
.svm = {
.svm_family = AF_VSOCK,
.svm_port = 1234,
- .svm_cid = peer_cid,
+ .svm_cid = opts->peer_cid,
},
};
int fd;
@@ -429,7 +422,7 @@ static void test_connect_client(unsigned int peer_cid)
free_sock_stat(&sockets);
}
-static void test_connect_server(unsigned int peer_cid)
+static void test_connect_server(const struct test_opts *opts)
{
union {
struct sockaddr sa;
@@ -481,9 +474,9 @@ static void test_connect_server(unsigned int peer_cid)
clientaddr.sa.sa_family);
exit(EXIT_FAILURE);
}
- if (clientaddr.svm.svm_cid != peer_cid) {
+ if (clientaddr.svm.svm_cid != opts->peer_cid) {
fprintf(stderr, "expected peer CID %u from accept(2), got %u\n",
- peer_cid, clientaddr.svm.svm_cid);
+ opts->peer_cid, clientaddr.svm.svm_cid);
exit(EXIT_FAILURE);
}
@@ -502,11 +495,7 @@ static void test_connect_server(unsigned int peer_cid)
free_sock_stat(&sockets);
}
-static struct {
- const char *name;
- void (*run_client)(unsigned int peer_cid);
- void (*run_server)(unsigned int peer_cid);
-} test_cases[] = {
+static struct test_case test_cases[] = {
{
.name = "No sockets",
.run_server = test_no_sockets,
@@ -523,30 +512,6 @@ static struct {
{},
};
-static void init_signals(void)
-{
- struct sigaction act = {
- .sa_handler = sigalrm,
- };
-
- sigaction(SIGALRM, &act, NULL);
- signal(SIGPIPE, SIG_IGN);
-}
-
-static unsigned int parse_cid(const char *str)
-{
- char *endptr = NULL;
- unsigned long int n;
-
- errno = 0;
- n = strtoul(str, &endptr, 10);
- if (errno || *endptr != '\0') {
- fprintf(stderr, "malformed CID \"%s\"\n", str);
- exit(EXIT_FAILURE);
- }
- return n;
-}
-
static const char optstring[] = "";
static const struct option longopts[] = {
{
@@ -601,9 +566,10 @@ int main(int argc, char **argv)
{
const char *control_host = NULL;
const char *control_port = NULL;
- int mode = TEST_MODE_UNSET;
- unsigned int peer_cid = VMADDR_CID_ANY;
- int i;
+ struct test_opts opts = {
+ .mode = TEST_MODE_UNSET,
+ .peer_cid = VMADDR_CID_ANY,
+ };
init_signals();
@@ -619,16 +585,16 @@ int main(int argc, char **argv)
break;
case 'm':
if (strcmp(optarg, "client") == 0)
- mode = TEST_MODE_CLIENT;
+ opts.mode = TEST_MODE_CLIENT;
else if (strcmp(optarg, "server") == 0)
- mode = TEST_MODE_SERVER;
+ opts.mode = TEST_MODE_SERVER;
else {
fprintf(stderr, "--mode must be \"client\" or \"server\"\n");
return EXIT_FAILURE;
}
break;
case 'p':
- peer_cid = parse_cid(optarg);
+ opts.peer_cid = parse_cid(optarg);
break;
case 'P':
control_port = optarg;
@@ -641,35 +607,21 @@ int main(int argc, char **argv)
if (!control_port)
usage();
- if (mode == TEST_MODE_UNSET)
+ if (opts.mode == TEST_MODE_UNSET)
usage();
- if (peer_cid == VMADDR_CID_ANY)
+ if (opts.peer_cid == VMADDR_CID_ANY)
usage();
if (!control_host) {
- if (mode != TEST_MODE_SERVER)
+ if (opts.mode != TEST_MODE_SERVER)
usage();
control_host = "0.0.0.0";
}
- control_init(control_host, control_port, mode == TEST_MODE_SERVER);
-
- for (i = 0; test_cases[i].name; i++) {
- void (*run)(unsigned int peer_cid);
+ control_init(control_host, control_port,
+ opts.mode == TEST_MODE_SERVER);
- printf("%s...", test_cases[i].name);
- fflush(stdout);
-
- if (mode == TEST_MODE_CLIENT)
- run = test_cases[i].run_client;
- else
- run = test_cases[i].run_server;
-
- if (run)
- run(peer_cid);
-
- printf("ok\n");
- }
+ run_tests(test_cases, &opts);
control_cleanup();
return EXIT_SUCCESS;
--
2.20.1
^ permalink raw reply related
* [PATCH v2 05/11] VSOCK: add full barrier between test cases
From: Stefano Garzarella @ 2019-08-01 15:25 UTC (permalink / raw)
To: netdev
Cc: kvm, Stefan Hajnoczi, Dexuan Cui, virtualization, David S. Miller,
Jorgen Hansen, linux-kernel
In-Reply-To: <20190801152541.245833-1-sgarzare@redhat.com>
From: Stefan Hajnoczi <stefanha@redhat.com>
See code comment for details.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
tools/testing/vsock/util.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
index f838bcee3589..4280a56ba677 100644
--- a/tools/testing/vsock/util.c
+++ b/tools/testing/vsock/util.c
@@ -161,10 +161,24 @@ void run_tests(const struct test_case *test_cases,
printf("%s...", test_cases[i].name);
fflush(stdout);
- if (opts->mode == TEST_MODE_CLIENT)
+ if (opts->mode == TEST_MODE_CLIENT) {
+ /* Full barrier before executing the next test. This
+ * ensures that client and server are executing the
+ * same test case. In particular, it means whoever is
+ * faster will not see the peer still executing the
+ * last test. This is important because port numbers
+ * can be used by multiple test cases.
+ */
+ control_expectln("NEXT");
+ control_writeln("NEXT");
+
run = test_cases[i].run_client;
- else
+ } else {
+ control_writeln("NEXT");
+ control_expectln("NEXT");
+
run = test_cases[i].run_server;
+ }
if (run)
run(opts);
--
2.20.1
^ permalink raw reply related
* [PATCH v2 06/11] VSOCK: add send_byte()/recv_byte() test utilities
From: Stefano Garzarella @ 2019-08-01 15:25 UTC (permalink / raw)
To: netdev
Cc: kvm, Stefan Hajnoczi, Dexuan Cui, virtualization, David S. Miller,
Jorgen Hansen, linux-kernel
In-Reply-To: <20190801152541.245833-1-sgarzare@redhat.com>
From: Stefan Hajnoczi <stefanha@redhat.com>
Test cases will want to transfer data. This patch adds utility
functions to do this.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
tools/testing/vsock/util.c | 99 ++++++++++++++++++++++++++++++++++++++
tools/testing/vsock/util.h | 2 +
2 files changed, 101 insertions(+)
diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
index 4280a56ba677..d46a6e079b96 100644
--- a/tools/testing/vsock/util.c
+++ b/tools/testing/vsock/util.c
@@ -9,6 +9,7 @@
#include <errno.h>
#include <stdio.h>
+#include <stdint.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
@@ -149,6 +150,104 @@ int vsock_stream_accept(unsigned int cid, unsigned int port,
return client_fd;
}
+/* Transmit one byte and check the return value.
+ *
+ * expected_ret:
+ * <0 Negative errno (for testing errors)
+ * 0 End-of-file
+ * 1 Success
+ */
+void send_byte(int fd, int expected_ret)
+{
+ const uint8_t byte = 'A';
+ ssize_t nwritten;
+
+ timeout_begin(TIMEOUT);
+ do {
+ nwritten = write(fd, &byte, sizeof(byte));
+ timeout_check("write");
+ } while (nwritten < 0 && errno == EINTR);
+ timeout_end();
+
+ if (expected_ret < 0) {
+ if (nwritten != -1) {
+ fprintf(stderr, "bogus write(2) return value %zd\n",
+ nwritten);
+ exit(EXIT_FAILURE);
+ }
+ if (errno != -expected_ret) {
+ perror("write");
+ exit(EXIT_FAILURE);
+ }
+ return;
+ }
+
+ if (nwritten < 0) {
+ perror("write");
+ exit(EXIT_FAILURE);
+ }
+ if (nwritten == 0) {
+ if (expected_ret == 0)
+ return;
+
+ fprintf(stderr, "unexpected EOF while sending byte\n");
+ exit(EXIT_FAILURE);
+ }
+ if (nwritten != sizeof(byte)) {
+ fprintf(stderr, "bogus write(2) return value %zd\n", nwritten);
+ exit(EXIT_FAILURE);
+ }
+}
+
+/* Receive one byte and check the return value.
+ *
+ * expected_ret:
+ * <0 Negative errno (for testing errors)
+ * 0 End-of-file
+ * 1 Success
+ */
+void recv_byte(int fd, int expected_ret)
+{
+ uint8_t byte;
+ ssize_t nread;
+
+ timeout_begin(TIMEOUT);
+ do {
+ nread = read(fd, &byte, sizeof(byte));
+ timeout_check("read");
+ } while (nread < 0 && errno == EINTR);
+ timeout_end();
+
+ if (expected_ret < 0) {
+ if (nread != -1) {
+ fprintf(stderr, "bogus read(2) return value %zd\n",
+ nread);
+ exit(EXIT_FAILURE);
+ }
+ if (errno != -expected_ret) {
+ perror("read");
+ exit(EXIT_FAILURE);
+ }
+ return;
+ }
+
+ if (nread < 0) {
+ perror("read");
+ exit(EXIT_FAILURE);
+ }
+ if (nread == 0) {
+ if (expected_ret == 0)
+ return;
+
+ fprintf(stderr, "unexpected EOF while receiving byte\n");
+ exit(EXIT_FAILURE);
+ }
+ if (nread != sizeof(byte)) {
+ fprintf(stderr, "bogus read(2) return value %zd\n", nread);
+ exit(EXIT_FAILURE);
+ }
+}
+
/* Run test cases. The program terminates if a failure occurs. */
void run_tests(const struct test_case *test_cases,
const struct test_opts *opts)
diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h
index 1786305cfddd..fe524d393d67 100644
--- a/tools/testing/vsock/util.h
+++ b/tools/testing/vsock/util.h
@@ -36,6 +36,8 @@ unsigned int parse_cid(const char *str);
int vsock_stream_connect(unsigned int cid, unsigned int port);
int vsock_stream_accept(unsigned int cid, unsigned int port,
struct sockaddr_vm *clientaddrp);
+void send_byte(int fd, int expected_ret);
+void recv_byte(int fd, int expected_ret);
void run_tests(const struct test_case *test_cases,
const struct test_opts *opts);
--
2.20.1
^ permalink raw reply related
* [PATCH v2 07/11] VSOCK: add AF_VSOCK test cases
From: Stefano Garzarella @ 2019-08-01 15:25 UTC (permalink / raw)
To: netdev
Cc: kvm, Stefan Hajnoczi, Dexuan Cui, virtualization, David S. Miller,
Jorgen Hansen, linux-kernel
In-Reply-To: <20190801152541.245833-1-sgarzare@redhat.com>
From: Stefan Hajnoczi <stefanha@redhat.com>
The vsock_test.c program runs a test suite of AF_VSOCK test cases.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
v2:
* Drop unnecessary includes [Stefan]
* Aligned with the current SPDX [Stefano]
* Set MULTICONN_NFDS to 100 [Stefano]
* Change (i % 1) in (i % 2) in the 'multiconn' test [Stefano]
---
tools/testing/vsock/.gitignore | 1 +
tools/testing/vsock/Makefile | 5 +-
tools/testing/vsock/README | 1 +
tools/testing/vsock/vsock_test.c | 312 +++++++++++++++++++++++++++++++
4 files changed, 317 insertions(+), 2 deletions(-)
create mode 100644 tools/testing/vsock/vsock_test.c
diff --git a/tools/testing/vsock/.gitignore b/tools/testing/vsock/.gitignore
index dc5f11faf530..7f7a2ccc30c4 100644
--- a/tools/testing/vsock/.gitignore
+++ b/tools/testing/vsock/.gitignore
@@ -1,2 +1,3 @@
*.d
+vsock_test
vsock_diag_test
diff --git a/tools/testing/vsock/Makefile b/tools/testing/vsock/Makefile
index a916878a2d8c..f8293c6910c9 100644
--- a/tools/testing/vsock/Makefile
+++ b/tools/testing/vsock/Makefile
@@ -1,10 +1,11 @@
# SPDX-License-Identifier: GPL-2.0-only
all: test
-test: vsock_diag_test
+test: vsock_test vsock_diag_test
+vsock_test: vsock_test.o timeout.o control.o util.o
vsock_diag_test: vsock_diag_test.o timeout.o control.o util.o
CFLAGS += -g -O2 -Werror -Wall -I. -I../../include -I../../../usr/include -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE -D_GNU_SOURCE
.PHONY: all test clean
clean:
- ${RM} *.o *.d vsock_diag_test
+ ${RM} *.o *.d vsock_test vsock_diag_test
-include *.d
diff --git a/tools/testing/vsock/README b/tools/testing/vsock/README
index cf7dc64273bf..4d5045e7d2c3 100644
--- a/tools/testing/vsock/README
+++ b/tools/testing/vsock/README
@@ -5,6 +5,7 @@ Hyper-V.
The following tests are available:
+ * vsock_test - core AF_VSOCK socket functionality
* vsock_diag_test - vsock_diag.ko module for listing open sockets
The following prerequisite steps are not automated and must be performed prior
diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
new file mode 100644
index 000000000000..06099d037405
--- /dev/null
+++ b/tools/testing/vsock/vsock_test.c
@@ -0,0 +1,312 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vsock_test - vsock.ko test suite
+ *
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * Author: Stefan Hajnoczi <stefanha@redhat.com>
+ */
+
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "timeout.h"
+#include "control.h"
+#include "util.h"
+
+static void test_stream_connection_reset(const struct test_opts *opts)
+{
+ union {
+ struct sockaddr sa;
+ struct sockaddr_vm svm;
+ } addr = {
+ .svm = {
+ .svm_family = AF_VSOCK,
+ .svm_port = 1234,
+ .svm_cid = opts->peer_cid,
+ },
+ };
+ int ret;
+ int fd;
+
+ fd = socket(AF_VSOCK, SOCK_STREAM, 0);
+
+ timeout_begin(TIMEOUT);
+ do {
+ ret = connect(fd, &addr.sa, sizeof(addr.svm));
+ timeout_check("connect");
+ } while (ret < 0 && errno == EINTR);
+ timeout_end();
+
+ if (ret != -1) {
+ fprintf(stderr, "expected connect(2) failure, got %d\n", ret);
+ exit(EXIT_FAILURE);
+ }
+ if (errno != ECONNRESET) {
+ fprintf(stderr, "unexpected connect(2) errno %d\n", errno);
+ exit(EXIT_FAILURE);
+ }
+
+ close(fd);
+}
+
+static void test_stream_client_close_client(const struct test_opts *opts)
+{
+ int fd;
+
+ fd = vsock_stream_connect(opts->peer_cid, 1234);
+ if (fd < 0) {
+ perror("connect");
+ exit(EXIT_FAILURE);
+ }
+
+ send_byte(fd, 1);
+ close(fd);
+ control_writeln("CLOSED");
+}
+
+static void test_stream_client_close_server(const struct test_opts *opts)
+{
+ int fd;
+
+ fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
+ if (fd < 0) {
+ perror("accept");
+ exit(EXIT_FAILURE);
+ }
+
+ control_expectln("CLOSED");
+
+ send_byte(fd, -EPIPE);
+ recv_byte(fd, 1);
+ recv_byte(fd, 0);
+ close(fd);
+}
+
+static void test_stream_server_close_client(const struct test_opts *opts)
+{
+ int fd;
+
+ fd = vsock_stream_connect(opts->peer_cid, 1234);
+ if (fd < 0) {
+ perror("connect");
+ exit(EXIT_FAILURE);
+ }
+
+ control_expectln("CLOSED");
+
+ send_byte(fd, -EPIPE);
+ recv_byte(fd, 1);
+ recv_byte(fd, 0);
+ close(fd);
+}
+
+static void test_stream_server_close_server(const struct test_opts *opts)
+{
+ int fd;
+
+ fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
+ if (fd < 0) {
+ perror("accept");
+ exit(EXIT_FAILURE);
+ }
+
+ send_byte(fd, 1);
+ close(fd);
+ control_writeln("CLOSED");
+}
+
+/* With the standard socket sizes, VMCI is able to support about 100
+ * concurrent stream connections.
+ */
+#define MULTICONN_NFDS 100
+
+static void test_stream_multiconn_client(const struct test_opts *opts)
+{
+ int fds[MULTICONN_NFDS];
+ int i;
+
+ for (i = 0; i < MULTICONN_NFDS; i++) {
+ fds[i] = vsock_stream_connect(opts->peer_cid, 1234);
+ if (fds[i] < 0) {
+ perror("connect");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ for (i = 0; i < MULTICONN_NFDS; i++) {
+ if (i % 2)
+ recv_byte(fds[i], 1);
+ else
+ send_byte(fds[i], 1);
+ }
+
+ for (i = 0; i < MULTICONN_NFDS; i++)
+ close(fds[i]);
+}
+
+static void test_stream_multiconn_server(const struct test_opts *opts)
+{
+ int fds[MULTICONN_NFDS];
+ int i;
+
+ for (i = 0; i < MULTICONN_NFDS; i++) {
+ fds[i] = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
+ if (fds[i] < 0) {
+ perror("accept");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ for (i = 0; i < MULTICONN_NFDS; i++) {
+ if (i % 2)
+ send_byte(fds[i], 1);
+ else
+ recv_byte(fds[i], 1);
+ }
+
+ for (i = 0; i < MULTICONN_NFDS; i++)
+ close(fds[i]);
+}
+
+static struct test_case test_cases[] = {
+ {
+ .name = "SOCK_STREAM connection reset",
+ .run_client = test_stream_connection_reset,
+ },
+ {
+ .name = "SOCK_STREAM client close",
+ .run_client = test_stream_client_close_client,
+ .run_server = test_stream_client_close_server,
+ },
+ {
+ .name = "SOCK_STREAM server close",
+ .run_client = test_stream_server_close_client,
+ .run_server = test_stream_server_close_server,
+ },
+ {
+ .name = "SOCK_STREAM multiple connections",
+ .run_client = test_stream_multiconn_client,
+ .run_server = test_stream_multiconn_server,
+ },
+ {},
+};
+
+static const char optstring[] = "";
+static const struct option longopts[] = {
+ {
+ .name = "control-host",
+ .has_arg = required_argument,
+ .val = 'H',
+ },
+ {
+ .name = "control-port",
+ .has_arg = required_argument,
+ .val = 'P',
+ },
+ {
+ .name = "mode",
+ .has_arg = required_argument,
+ .val = 'm',
+ },
+ {
+ .name = "peer-cid",
+ .has_arg = required_argument,
+ .val = 'p',
+ },
+ {
+ .name = "help",
+ .has_arg = no_argument,
+ .val = '?',
+ },
+ {},
+};
+
+static void usage(void)
+{
+ fprintf(stderr, "Usage: vsock_test [--help] [--control-host=<host>] --control-port=<port> --mode=client|server --peer-cid=<cid>\n"
+ "\n"
+ " Server: vsock_test --control-port=1234 --mode=server --peer-cid=3\n"
+ " Client: vsock_test --control-host=192.168.0.1 --control-port=1234 --mode=client --peer-cid=2\n"
+ "\n"
+ "Run vsock.ko tests. Must be launched in both guest\n"
+ "and host. One side must use --mode=client and\n"
+ "the other side must use --mode=server.\n"
+ "\n"
+ "A TCP control socket connection is used to coordinate tests\n"
+ "between the client and the server. The server requires a\n"
+ "listen address and the client requires an address to\n"
+ "connect to.\n"
+ "\n"
+ "The CID of the other side must be given with --peer-cid=<cid>.\n");
+ exit(EXIT_FAILURE);
+}
+
+int main(int argc, char **argv)
+{
+ const char *control_host = NULL;
+ const char *control_port = NULL;
+ struct test_opts opts = {
+ .mode = TEST_MODE_UNSET,
+ .peer_cid = VMADDR_CID_ANY,
+ };
+
+ init_signals();
+
+ for (;;) {
+ int opt = getopt_long(argc, argv, optstring, longopts, NULL);
+
+ if (opt == -1)
+ break;
+
+ switch (opt) {
+ case 'H':
+ control_host = optarg;
+ break;
+ case 'm':
+ if (strcmp(optarg, "client") == 0)
+ opts.mode = TEST_MODE_CLIENT;
+ else if (strcmp(optarg, "server") == 0)
+ opts.mode = TEST_MODE_SERVER;
+ else {
+ fprintf(stderr, "--mode must be \"client\" or \"server\"\n");
+ return EXIT_FAILURE;
+ }
+ break;
+ case 'p':
+ opts.peer_cid = parse_cid(optarg);
+ break;
+ case 'P':
+ control_port = optarg;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ }
+
+ if (!control_port)
+ usage();
+ if (opts.mode == TEST_MODE_UNSET)
+ usage();
+ if (opts.peer_cid == VMADDR_CID_ANY)
+ usage();
+
+ if (!control_host) {
+ if (opts.mode != TEST_MODE_SERVER)
+ usage();
+ control_host = "0.0.0.0";
+ }
+
+ control_init(control_host, control_port,
+ opts.mode == TEST_MODE_SERVER);
+
+ run_tests(test_cases, &opts);
+
+ control_cleanup();
+ return EXIT_SUCCESS;
+}
--
2.20.1
^ permalink raw reply related
* [PATCH v2 08/11] VSOCK: add vsock_get_local_cid() test utility
From: Stefano Garzarella @ 2019-08-01 15:25 UTC (permalink / raw)
To: netdev
Cc: kvm, Stefan Hajnoczi, Dexuan Cui, virtualization, David S. Miller,
Jorgen Hansen, linux-kernel
In-Reply-To: <20190801152541.245833-1-sgarzare@redhat.com>
This patch adds utility to get local CID, useful to
understand if we are in the host or guest.
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
tools/testing/vsock/util.c | 17 +++++++++++++++++
tools/testing/vsock/util.h | 1 +
2 files changed, 18 insertions(+)
diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
index d46a6e079b96..41b94495ecb1 100644
--- a/tools/testing/vsock/util.c
+++ b/tools/testing/vsock/util.c
@@ -13,6 +13,7 @@
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
+#include <assert.h>
#include "timeout.h"
#include "control.h"
@@ -44,6 +45,22 @@ unsigned int parse_cid(const char *str)
return n;
}
+/* Get the local CID */
+unsigned int vsock_get_local_cid(int fd)
+{
+ struct sockaddr_vm svm;
+ socklen_t svm_len = sizeof(svm);
+
+ if (getsockname(fd, (struct sockaddr *) &svm, &svm_len)) {
+ perror("getsockname");
+ exit(EXIT_FAILURE);
+ }
+
+ assert(svm.svm_family == AF_VSOCK);
+
+ return svm.svm_cid;
+}
+
/* Connect to <cid, port> and return the file descriptor. */
int vsock_stream_connect(unsigned int cid, unsigned int port)
{
diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h
index fe524d393d67..379e02ab59bb 100644
--- a/tools/testing/vsock/util.h
+++ b/tools/testing/vsock/util.h
@@ -36,6 +36,7 @@ unsigned int parse_cid(const char *str);
int vsock_stream_connect(unsigned int cid, unsigned int port);
int vsock_stream_accept(unsigned int cid, unsigned int port,
struct sockaddr_vm *clientaddrp);
+unsigned int vsock_get_local_cid(int fd);
void send_byte(int fd, int expected_ret);
void recv_byte(int fd, int expected_ret);
void run_tests(const struct test_case *test_cases,
--
2.20.1
^ permalink raw reply related
* [PATCH v2 09/11] vsock_test: add --transport parameter
From: Stefano Garzarella @ 2019-08-01 15:25 UTC (permalink / raw)
To: netdev
Cc: kvm, Stefan Hajnoczi, Dexuan Cui, virtualization, David S. Miller,
Jorgen Hansen, linux-kernel
In-Reply-To: <20190801152541.245833-1-sgarzare@redhat.com>
Add new --transport parameter to skip some tests or checks
not supported by a specific transport.
Suggested-by: Jorgen Hansen <jhansen@vmware.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
tools/testing/vsock/util.h | 8 ++++++++
tools/testing/vsock/vsock_test.c | 20 +++++++++++++++++++-
2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h
index 379e02ab59bb..7fdb8100f035 100644
--- a/tools/testing/vsock/util.h
+++ b/tools/testing/vsock/util.h
@@ -12,9 +12,17 @@ enum test_mode {
TEST_MODE_SERVER
};
+enum test_transport {
+ TEST_TRANSPORT_UNSET,
+ TEST_TRANSPORT_VMCI,
+ TEST_TRANSPORT_VIRTIO,
+ TEST_TRANSPORT_HYPERV
+};
+
/* Test runner options */
struct test_opts {
enum test_mode mode;
+ enum test_transport transport;
unsigned int peer_cid;
};
diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
index 06099d037405..cb606091489f 100644
--- a/tools/testing/vsock/vsock_test.c
+++ b/tools/testing/vsock/vsock_test.c
@@ -218,6 +218,11 @@ static const struct option longopts[] = {
.has_arg = required_argument,
.val = 'p',
},
+ {
+ .name = "transport",
+ .has_arg = required_argument,
+ .val = 't',
+ },
{
.name = "help",
.has_arg = no_argument,
@@ -228,7 +233,7 @@ static const struct option longopts[] = {
static void usage(void)
{
- fprintf(stderr, "Usage: vsock_test [--help] [--control-host=<host>] --control-port=<port> --mode=client|server --peer-cid=<cid>\n"
+ fprintf(stderr, "Usage: vsock_test [--help] [--control-host=<host>] --control-port=<port> --mode=client|server --peer-cid=<cid> [--transport=vmci|virtio|hyperv]\n"
"\n"
" Server: vsock_test --control-port=1234 --mode=server --peer-cid=3\n"
" Client: vsock_test --control-host=192.168.0.1 --control-port=1234 --mode=client --peer-cid=2\n"
@@ -252,6 +257,7 @@ int main(int argc, char **argv)
const char *control_port = NULL;
struct test_opts opts = {
.mode = TEST_MODE_UNSET,
+ .transport = TEST_TRANSPORT_UNSET,
.peer_cid = VMADDR_CID_ANY,
};
@@ -283,6 +289,18 @@ int main(int argc, char **argv)
case 'P':
control_port = optarg;
break;
+ case 't':
+ if (strcmp(optarg, "vmci") == 0)
+ opts.transport = TEST_TRANSPORT_VMCI;
+ else if (strcmp(optarg, "virtio") == 0)
+ opts.transport = TEST_TRANSPORT_VIRTIO;
+ else if (strcmp(optarg, "hyperv") == 0)
+ opts.transport = TEST_TRANSPORT_HYPERV;
+ else {
+ fprintf(stderr, "--transport must be \"vmci\" or \"virtio\" or \"hyperv\"\n");
+ return EXIT_FAILURE;
+ }
+ break;
case '?':
default:
usage();
--
2.20.1
^ permalink raw reply related
* [PATCH v2 11/11] vsock_test: wait for the remote to close the connection
From: Stefano Garzarella @ 2019-08-01 15:25 UTC (permalink / raw)
To: netdev
Cc: kvm, Stefan Hajnoczi, Dexuan Cui, virtualization, David S. Miller,
Jorgen Hansen, linux-kernel
In-Reply-To: <20190801152541.245833-1-sgarzare@redhat.com>
Before check if a send returns -EPIPE, we need to make sure the
connection is closed.
To do that, we use epoll API to wait EPOLLRDHUP or EPOLLHUP events
on the socket.
Reported-by: Jorgen Hansen <jhansen@vmware.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
tools/testing/vsock/util.c | 38 ++++++++++++++++++++++++++++++++
tools/testing/vsock/util.h | 1 +
tools/testing/vsock/vsock_test.c | 10 +++++++++
3 files changed, 49 insertions(+)
diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
index 41b94495ecb1..425181fe196c 100644
--- a/tools/testing/vsock/util.c
+++ b/tools/testing/vsock/util.c
@@ -14,6 +14,7 @@
#include <signal.h>
#include <unistd.h>
#include <assert.h>
+#include <sys/epoll.h>
#include "timeout.h"
#include "control.h"
@@ -61,6 +62,43 @@ unsigned int vsock_get_local_cid(int fd)
return svm.svm_cid;
}
+/* Wait for the remote to close the connection */
+void vsock_wait_remote_close(int fd)
+{
+ struct epoll_event ev;
+ int epollfd, nfds;
+
+ epollfd = epoll_create1(0);
+ if (epollfd == -1) {
+ perror("epoll_create1");
+ exit(EXIT_FAILURE);
+ }
+
+ ev.events = EPOLLRDHUP | EPOLLHUP;
+ ev.data.fd = fd;
+ if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) {
+ perror("epoll_ctl");
+ exit(EXIT_FAILURE);
+ }
+
+ nfds = epoll_wait(epollfd, &ev, 1, TIMEOUT * 1000);
+ if (nfds == -1) {
+ perror("epoll_wait");
+ exit(EXIT_FAILURE);
+ }
+
+ if (nfds == 0) {
+ fprintf(stderr, "epoll_wait timed out\n");
+ exit(EXIT_FAILURE);
+ }
+
+ assert(nfds == 1);
+ assert(ev.events & (EPOLLRDHUP | EPOLLHUP));
+ assert(ev.data.fd == fd);
+
+ close(epollfd);
+}
+
/* Connect to <cid, port> and return the file descriptor. */
int vsock_stream_connect(unsigned int cid, unsigned int port)
{
diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h
index 7fdb8100f035..89816966c05b 100644
--- a/tools/testing/vsock/util.h
+++ b/tools/testing/vsock/util.h
@@ -45,6 +45,7 @@ int vsock_stream_connect(unsigned int cid, unsigned int port);
int vsock_stream_accept(unsigned int cid, unsigned int port,
struct sockaddr_vm *clientaddrp);
unsigned int vsock_get_local_cid(int fd);
+void vsock_wait_remote_close(int fd);
void send_byte(int fd, int expected_ret);
void recv_byte(int fd, int expected_ret);
void run_tests(const struct test_case *test_cases,
diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
index 64adf45501ca..a664675bec5a 100644
--- a/tools/testing/vsock/vsock_test.c
+++ b/tools/testing/vsock/vsock_test.c
@@ -84,6 +84,11 @@ static void test_stream_client_close_server(const struct test_opts *opts)
control_expectln("CLOSED");
+ /* Wait for the remote to close the connection, before check
+ * -EPIPE error on send.
+ */
+ vsock_wait_remote_close(fd);
+
send_byte(fd, -EPIPE);
/* Skip the read of data wrote by the peer if we are on VMCI and
@@ -113,6 +118,11 @@ static void test_stream_server_close_client(const struct test_opts *opts)
control_expectln("CLOSED");
+ /* Wait for the remote to close the connection, before check
+ * -EPIPE error on send.
+ */
+ vsock_wait_remote_close(fd);
+
send_byte(fd, -EPIPE);
/* Skip the read of data wrote by the peer if we are on VMCI and
--
2.20.1
^ permalink raw reply related
* [PATCH v2 10/11] vsock_test: skip read() in test_stream*close tests on a VMCI host
From: Stefano Garzarella @ 2019-08-01 15:25 UTC (permalink / raw)
To: netdev
Cc: kvm, Stefan Hajnoczi, Dexuan Cui, virtualization, David S. Miller,
Jorgen Hansen, linux-kernel
In-Reply-To: <20190801152541.245833-1-sgarzare@redhat.com>
When VMCI transport is used, if the guest closes a connection,
all data is gone and EOF is returned, so we should skip the read
of data written by the peer before closing the connection.
Reported-by: Jorgen Hansen <jhansen@vmware.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
tools/testing/vsock/vsock_test.c | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
index cb606091489f..64adf45501ca 100644
--- a/tools/testing/vsock/vsock_test.c
+++ b/tools/testing/vsock/vsock_test.c
@@ -71,6 +71,7 @@ static void test_stream_client_close_client(const struct test_opts *opts)
static void test_stream_client_close_server(const struct test_opts *opts)
{
+ unsigned int local_cid;
int fd;
fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
@@ -79,16 +80,27 @@ static void test_stream_client_close_server(const struct test_opts *opts)
exit(EXIT_FAILURE);
}
+ local_cid = vsock_get_local_cid(fd);
+
control_expectln("CLOSED");
send_byte(fd, -EPIPE);
- recv_byte(fd, 1);
+
+ /* Skip the read of data wrote by the peer if we are on VMCI and
+ * we are on the host side, because when the guest closes a
+ * connection, all data is gone and EOF is returned.
+ */
+ if (!(opts->transport == TEST_TRANSPORT_VMCI &&
+ local_cid == VMADDR_CID_HOST))
+ recv_byte(fd, 1);
+
recv_byte(fd, 0);
close(fd);
}
static void test_stream_server_close_client(const struct test_opts *opts)
{
+ unsigned int local_cid;
int fd;
fd = vsock_stream_connect(opts->peer_cid, 1234);
@@ -97,10 +109,20 @@ static void test_stream_server_close_client(const struct test_opts *opts)
exit(EXIT_FAILURE);
}
+ local_cid = vsock_get_local_cid(fd);
+
control_expectln("CLOSED");
send_byte(fd, -EPIPE);
- recv_byte(fd, 1);
+
+ /* Skip the read of data wrote by the peer if we are on VMCI and
+ * we are on the host side, because when the guest closes a
+ * connection, all data is gone and EOF is returned.
+ */
+ if (!(opts->transport == TEST_TRANSPORT_VMCI &&
+ local_cid == VMADDR_CID_HOST))
+ recv_byte(fd, 1);
+
recv_byte(fd, 0);
close(fd);
}
--
2.20.1
^ permalink raw reply related
* [PATCH v2 04/11] VSOCK: extract connect/accept functions from vsock_diag_test.c
From: Stefano Garzarella @ 2019-08-01 15:25 UTC (permalink / raw)
To: netdev
Cc: kvm, Stefan Hajnoczi, Dexuan Cui, virtualization, David S. Miller,
Jorgen Hansen, linux-kernel
In-Reply-To: <20190801152541.245833-1-sgarzare@redhat.com>
From: Stefan Hajnoczi <stefanha@redhat.com>
Many test cases will need to connect to the server or accept incoming
connections. This patch extracts these operations into utility
functions that can be reused.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
tools/testing/vsock/util.c | 108 ++++++++++++++++++++++++++
tools/testing/vsock/util.h | 6 ++
tools/testing/vsock/vsock_diag_test.c | 81 ++-----------------
3 files changed, 119 insertions(+), 76 deletions(-)
diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
index f40f45b36d2f..f838bcee3589 100644
--- a/tools/testing/vsock/util.c
+++ b/tools/testing/vsock/util.c
@@ -11,8 +11,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
+#include <unistd.h>
#include "timeout.h"
+#include "control.h"
#include "util.h"
/* Install signal handlers */
@@ -41,6 +43,112 @@ unsigned int parse_cid(const char *str)
return n;
}
+/* Connect to <cid, port> and return the file descriptor. */
+int vsock_stream_connect(unsigned int cid, unsigned int port)
+{
+ union {
+ struct sockaddr sa;
+ struct sockaddr_vm svm;
+ } addr = {
+ .svm = {
+ .svm_family = AF_VSOCK,
+ .svm_port = port,
+ .svm_cid = cid,
+ },
+ };
+ int ret;
+ int fd;
+
+ control_expectln("LISTENING");
+
+ fd = socket(AF_VSOCK, SOCK_STREAM, 0);
+
+ timeout_begin(TIMEOUT);
+ do {
+ ret = connect(fd, &addr.sa, sizeof(addr.svm));
+ timeout_check("connect");
+ } while (ret < 0 && errno == EINTR);
+ timeout_end();
+
+ if (ret < 0) {
+ int old_errno = errno;
+
+ close(fd);
+ fd = -1;
+ errno = old_errno;
+ }
+ return fd;
+}
+
+/* Listen on <cid, port> and return the first incoming connection. The remote
+ * address is stored to clientaddrp. clientaddrp may be NULL.
+ */
+int vsock_stream_accept(unsigned int cid, unsigned int port,
+ struct sockaddr_vm *clientaddrp)
+{
+ union {
+ struct sockaddr sa;
+ struct sockaddr_vm svm;
+ } addr = {
+ .svm = {
+ .svm_family = AF_VSOCK,
+ .svm_port = port,
+ .svm_cid = cid,
+ },
+ };
+ union {
+ struct sockaddr sa;
+ struct sockaddr_vm svm;
+ } clientaddr;
+ socklen_t clientaddr_len = sizeof(clientaddr.svm);
+ int fd;
+ int client_fd;
+ int old_errno;
+
+ fd = socket(AF_VSOCK, SOCK_STREAM, 0);
+
+ if (bind(fd, &addr.sa, sizeof(addr.svm)) < 0) {
+ perror("bind");
+ exit(EXIT_FAILURE);
+ }
+
+ if (listen(fd, 1) < 0) {
+ perror("listen");
+ exit(EXIT_FAILURE);
+ }
+
+ control_writeln("LISTENING");
+
+ timeout_begin(TIMEOUT);
+ do {
+ client_fd = accept(fd, &clientaddr.sa, &clientaddr_len);
+ timeout_check("accept");
+ } while (client_fd < 0 && errno == EINTR);
+ timeout_end();
+
+ old_errno = errno;
+ close(fd);
+ errno = old_errno;
+
+ if (client_fd < 0)
+ return client_fd;
+
+ if (clientaddr_len != sizeof(clientaddr.svm)) {
+ fprintf(stderr, "unexpected addrlen from accept(2), %zu\n",
+ (size_t)clientaddr_len);
+ exit(EXIT_FAILURE);
+ }
+ if (clientaddr.sa.sa_family != AF_VSOCK) {
+ fprintf(stderr, "expected AF_VSOCK from accept(2), got %d\n",
+ clientaddr.sa.sa_family);
+ exit(EXIT_FAILURE);
+ }
+
+ if (clientaddrp)
+ *clientaddrp = clientaddr.svm;
+ return client_fd;
+}
+
/* Run test cases. The program terminates if a failure occurs. */
void run_tests(const struct test_case *test_cases,
const struct test_opts *opts)
diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h
index 033e7d59a42a..1786305cfddd 100644
--- a/tools/testing/vsock/util.h
+++ b/tools/testing/vsock/util.h
@@ -2,6 +2,9 @@
#ifndef UTIL_H
#define UTIL_H
+#include <sys/socket.h>
+#include <linux/vm_sockets.h>
+
/* Tests can either run as the client or the server */
enum test_mode {
TEST_MODE_UNSET,
@@ -30,6 +33,9 @@ struct test_case {
void init_signals(void);
unsigned int parse_cid(const char *str);
+int vsock_stream_connect(unsigned int cid, unsigned int port);
+int vsock_stream_accept(unsigned int cid, unsigned int port,
+ struct sockaddr_vm *clientaddrp);
void run_tests(const struct test_case *test_cases,
const struct test_opts *opts);
diff --git a/tools/testing/vsock/vsock_diag_test.c b/tools/testing/vsock/vsock_diag_test.c
index 944c8a72eed7..abd7dc2a9631 100644
--- a/tools/testing/vsock/vsock_diag_test.c
+++ b/tools/testing/vsock/vsock_diag_test.c
@@ -13,13 +13,11 @@
#include <string.h>
#include <errno.h>
#include <unistd.h>
-#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <linux/list.h>
#include <linux/net.h>
#include <linux/netlink.h>
-#include <linux/vm_sockets.h>
#include <linux/sock_diag.h>
#include <linux/vm_sockets_diag.h>
#include <netinet/tcp.h>
@@ -378,33 +376,12 @@ static void test_listen_socket_server(const struct test_opts *opts)
static void test_connect_client(const struct test_opts *opts)
{
- union {
- struct sockaddr sa;
- struct sockaddr_vm svm;
- } addr = {
- .svm = {
- .svm_family = AF_VSOCK,
- .svm_port = 1234,
- .svm_cid = opts->peer_cid,
- },
- };
int fd;
- int ret;
LIST_HEAD(sockets);
struct vsock_stat *st;
- control_expectln("LISTENING");
-
- fd = socket(AF_VSOCK, SOCK_STREAM, 0);
-
- timeout_begin(TIMEOUT);
- do {
- ret = connect(fd, &addr.sa, sizeof(addr.svm));
- timeout_check("connect");
- } while (ret < 0 && errno == EINTR);
- timeout_end();
-
- if (ret < 0) {
+ fd = vsock_stream_connect(opts->peer_cid, 1234);
+ if (fd < 0) {
perror("connect");
exit(EXIT_FAILURE);
}
@@ -424,66 +401,19 @@ static void test_connect_client(const struct test_opts *opts)
static void test_connect_server(const struct test_opts *opts)
{
- union {
- struct sockaddr sa;
- struct sockaddr_vm svm;
- } addr = {
- .svm = {
- .svm_family = AF_VSOCK,
- .svm_port = 1234,
- .svm_cid = VMADDR_CID_ANY,
- },
- };
- union {
- struct sockaddr sa;
- struct sockaddr_vm svm;
- } clientaddr;
- socklen_t clientaddr_len = sizeof(clientaddr.svm);
- LIST_HEAD(sockets);
struct vsock_stat *st;
- int fd;
+ LIST_HEAD(sockets);
int client_fd;
- fd = socket(AF_VSOCK, SOCK_STREAM, 0);
-
- if (bind(fd, &addr.sa, sizeof(addr.svm)) < 0) {
- perror("bind");
- exit(EXIT_FAILURE);
- }
-
- if (listen(fd, 1) < 0) {
- perror("listen");
- exit(EXIT_FAILURE);
- }
-
- control_writeln("LISTENING");
-
- timeout_begin(TIMEOUT);
- do {
- client_fd = accept(fd, &clientaddr.sa, &clientaddr_len);
- timeout_check("accept");
- } while (client_fd < 0 && errno == EINTR);
- timeout_end();
-
+ client_fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
if (client_fd < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
- if (clientaddr.sa.sa_family != AF_VSOCK) {
- fprintf(stderr, "expected AF_VSOCK from accept(2), got %d\n",
- clientaddr.sa.sa_family);
- exit(EXIT_FAILURE);
- }
- if (clientaddr.svm.svm_cid != opts->peer_cid) {
- fprintf(stderr, "expected peer CID %u from accept(2), got %u\n",
- opts->peer_cid, clientaddr.svm.svm_cid);
- exit(EXIT_FAILURE);
- }
read_vsock_stat(&sockets);
- check_num_sockets(&sockets, 2);
- find_vsock_stat(&sockets, fd);
+ check_num_sockets(&sockets, 1);
st = find_vsock_stat(&sockets, client_fd);
check_socket_state(st, TCP_ESTABLISHED);
@@ -491,7 +421,6 @@ static void test_connect_server(const struct test_opts *opts)
control_expectln("DONE");
close(client_fd);
- close(fd);
free_sock_stat(&sockets);
}
--
2.20.1
^ permalink raw reply related
* [PATCH v2 02/11] VSOCK: add SPDX identifiers to vsock tests
From: Stefano Garzarella @ 2019-08-01 15:25 UTC (permalink / raw)
To: netdev
Cc: kvm, Stefan Hajnoczi, Dexuan Cui, virtualization, David S. Miller,
Jorgen Hansen, linux-kernel
In-Reply-To: <20190801152541.245833-1-sgarzare@redhat.com>
From: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
v2:
* Aligned with the current SPDX [Stefano]
---
tools/testing/vsock/control.h | 1 +
tools/testing/vsock/timeout.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/tools/testing/vsock/control.h b/tools/testing/vsock/control.h
index 54a07efd267c..dac3964a891d 100644
--- a/tools/testing/vsock/control.h
+++ b/tools/testing/vsock/control.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef CONTROL_H
#define CONTROL_H
diff --git a/tools/testing/vsock/timeout.h b/tools/testing/vsock/timeout.h
index 77db9ce9860a..ecb7c840e65a 100644
--- a/tools/testing/vsock/timeout.h
+++ b/tools/testing/vsock/timeout.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef TIMEOUT_H
#define TIMEOUT_H
--
2.20.1
^ permalink raw reply related
* [PATCH v2 01/11] VSOCK: fix header include in vsock_diag_test
From: Stefano Garzarella @ 2019-08-01 15:25 UTC (permalink / raw)
To: netdev
Cc: kvm, Stefan Hajnoczi, Dexuan Cui, virtualization, David S. Miller,
Jorgen Hansen, linux-kernel
In-Reply-To: <20190801152541.245833-1-sgarzare@redhat.com>
From: Stefan Hajnoczi <stefanha@redhat.com>
The vsock_diag_test program directly included ../../../include/uapi/
headers from the source tree. Tests are supposed to use the
usr/include/linux/ headers that have been prepared with make
headers_install instead.
Suggested-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
tools/testing/vsock/Makefile | 2 +-
tools/testing/vsock/README | 2 +-
tools/testing/vsock/vsock_diag_test.c | 5 ++---
3 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/tools/testing/vsock/Makefile b/tools/testing/vsock/Makefile
index 5be687b1e16c..d41a4e13960a 100644
--- a/tools/testing/vsock/Makefile
+++ b/tools/testing/vsock/Makefile
@@ -3,7 +3,7 @@ all: test
test: vsock_diag_test
vsock_diag_test: vsock_diag_test.o timeout.o control.o
-CFLAGS += -g -O2 -Werror -Wall -I. -I../../include/uapi -I../../include -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE -D_GNU_SOURCE
+CFLAGS += -g -O2 -Werror -Wall -I. -I../../include -I../../../usr/include -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE -D_GNU_SOURCE
.PHONY: all test clean
clean:
${RM} *.o *.d vsock_diag_test
diff --git a/tools/testing/vsock/README b/tools/testing/vsock/README
index 2cc6d7302db6..cf7dc64273bf 100644
--- a/tools/testing/vsock/README
+++ b/tools/testing/vsock/README
@@ -10,7 +10,7 @@ The following tests are available:
The following prerequisite steps are not automated and must be performed prior
to running tests:
-1. Build the kernel and these tests.
+1. Build the kernel, make headers_install, and build these tests.
2. Install the kernel and tests on the host.
3. Install the kernel and tests inside the guest.
4. Boot the guest and ensure that the AF_VSOCK transport is enabled.
diff --git a/tools/testing/vsock/vsock_diag_test.c b/tools/testing/vsock/vsock_diag_test.c
index c481101364a4..fc391e041954 100644
--- a/tools/testing/vsock/vsock_diag_test.c
+++ b/tools/testing/vsock/vsock_diag_test.c
@@ -21,12 +21,11 @@
#include <linux/list.h>
#include <linux/net.h>
#include <linux/netlink.h>
+#include <linux/vm_sockets.h>
#include <linux/sock_diag.h>
+#include <linux/vm_sockets_diag.h>
#include <netinet/tcp.h>
-#include "../../../include/uapi/linux/vm_sockets.h"
-#include "../../../include/uapi/linux/vm_sockets_diag.h"
-
#include "timeout.h"
#include "control.h"
--
2.20.1
^ permalink raw reply related
* [PATCH v2 00/11] VSOCK: add vsock_test test suite
From: Stefano Garzarella @ 2019-08-01 15:25 UTC (permalink / raw)
To: netdev
Cc: kvm, Stefan Hajnoczi, Dexuan Cui, virtualization, David S. Miller,
Jorgen Hansen, linux-kernel
The vsock_diag.ko module already has a test suite but the core AF_VSOCK
functionality has no tests. This patch series adds several test cases that
exercise AF_VSOCK SOCK_STREAM socket semantics (send/recv, connect/accept,
half-closed connections, simultaneous connections).
Stefan: Do you think we should have a single application or is better to
split it in single tests (e.g. vsock_test_send_recv, vsock_test_half_close,
vsock_test_multiconnection, etc.)?
Jorgen: Please test the VMCI transport and let me know if the fixes work.
I added the '--transport' parameter to skip the read() on the half-closed
connection test.
Dexuan: Do you think can be useful to test HyperV?
The v1 of this series was originally sent by Stefan. I rebased on master
and tried to fix some issues reported by Jorgen.
v2:
- Patch 1 added by Stefan to fix header include in vsock_diag_test.
- Patch 2 added by Stefan to add SPDX identifiers. I modified it to be
aligned with SPDX currently used on master.
- Patch 3:
* fixed SPDX [Stefano].
- Patch 7:
* Drop unnecessary includes [Stefan]
* Fixed SPDX [Stefano]
* Set MULTICONN_NFDS to 100 [Stefano]
* Changed (i % 1) in (i % 2) in the 'multiconn' test [Stefano]
- Patches 8,9,10 added to skip read after close in test_stream*close tests
on a VMCI host.
- Patch 11 added to wait for the remote to close the connection, before
check if a send returns -EPIPE.
v1: https://patchwork.ozlabs.org/cover/847998/
Stefan Hajnoczi (7):
VSOCK: fix header include in vsock_diag_test
VSOCK: add SPDX identifiers to vsock tests
VSOCK: extract utility functions from vsock_diag_test.c
VSOCK: extract connect/accept functions from vsock_diag_test.c
VSOCK: add full barrier between test cases
VSOCK: add send_byte()/recv_byte() test utilities
VSOCK: add AF_VSOCK test cases
Stefano Garzarella (4):
VSOCK: add vsock_get_local_cid() test utility
vsock_test: add --transport parameter
vsock_test: skip read() in test_stream*close tests on a VMCI host
vsock_test: wait for the remote to close the connection
tools/testing/vsock/.gitignore | 1 +
tools/testing/vsock/Makefile | 9 +-
tools/testing/vsock/README | 3 +-
tools/testing/vsock/control.h | 1 +
tools/testing/vsock/timeout.h | 1 +
tools/testing/vsock/util.c | 342 ++++++++++++++++++++++++
tools/testing/vsock/util.h | 54 ++++
tools/testing/vsock/vsock_diag_test.c | 170 ++----------
tools/testing/vsock/vsock_test.c | 362 ++++++++++++++++++++++++++
9 files changed, 793 insertions(+), 150 deletions(-)
create mode 100644 tools/testing/vsock/util.c
create mode 100644 tools/testing/vsock/util.h
create mode 100644 tools/testing/vsock/vsock_test.c
--
2.20.1
^ permalink raw reply
* Re: [net-next,rfc] net: bridge: mdb: Extend with multicast LLADDR
From: Nikolay Aleksandrov @ 2019-08-01 15:25 UTC (permalink / raw)
To: Horatiu Vultur, idosch, andrew, allan.nielsen
Cc: davem, roopa, petrm, tglx, fw, netdev, linux-kernel, bridge
In-Reply-To: <696c9bcc-f7e3-3d22-69c4-cdf4f37280a9@cumulusnetworks.com>
On 01/08/2019 17:15, Nikolay Aleksandrov wrote:
> On 01/08/2019 17:11, Nikolay Aleksandrov wrote:
>> On 01/08/2019 17:07, Nikolay Aleksandrov wrote:
>>> Hi Horatiu,
>>> Overall I think MDB is the right way, we'd like to contain the multicast code.
>>> A few comments below.
>>>
>>> On 01/08/2019 15:50, Horatiu Vultur wrote:
>> [snip]
>>>>
>>>> Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
>>>> Co-developed-by: Allan W. Nielsen <allan.nielsen@microchip.com>
>>>> Signed-off-by: Allan W. Nielsen <allan.nielsen@microchip.com>
>>>> ---
>>>> include/linux/if_bridge.h | 1 +
>>>> include/uapi/linux/if_bridge.h | 1 +
>>>> net/bridge/br_device.c | 7 +++++--
>>>> net/bridge/br_forward.c | 3 ++-
>>>> net/bridge/br_input.c | 13 ++++++++++--
>>>> net/bridge/br_mdb.c | 47 +++++++++++++++++++++++++++++++++++-------
>>>> net/bridge/br_multicast.c | 4 +++-
>>>> net/bridge/br_private.h | 3 ++-
>>>> 8 files changed, 64 insertions(+), 15 deletions(-)
>>>>
>>>
>>> Overall I don't think we need this BR_PKT_MULTICAST_L2, we could do the below much
>>> easier and without the checks if you use a per-mdb flag that says it's to be treated
>>> as a MULTICAST_L2 entry. Then you remove all of the BR_PKT_MULTICAST_L2 code (see the
>>> attached patch based on this one for example). and continue processing it as it is processed today.
>>> We'll keep the fast-path with minimal number of new conditionals.
>>>
>>> Something like the patch I've attached to this reply, note that it is not complete
>>> just to show the intent, you'll have to re-work br_mdb_notify() to make it proper
>>> and there're most probably other details I've missed. If you find even better/less
>>> complex way to do it then please do.
>>>
>>> Cheers,
>>> Nik
>>
>> Oops, I sent back your original patch. Here's the actually changed version
>> I was talking about.
>>
>> Thanks,
>> Nik
>>
>>
>>
>
> The querier exists change is a hack just to get the point, I'd prefer
> to re-write that portion in a better way which makes more sense, i.e.
> get that check out of there since it doesn't mean that an actual querier
> exists. :)
>
TBH, I'm inclined to just use proto == 0 *internally* as this even though it's reserved,
we're not putting it on the wire or using it to construct packets, it's just internal
use which can change into a flag if some day that value needs to be used. Obviously
to user-space we need it to be a flag, we can't expose or configure it as a proto value
without making it permanent uapi. I haven't looked into detail how feasible this is,
just a thought that might make it simpler.
^ permalink raw reply
* Re: [PATCH iproute2-next] ip tunnel: add json output
From: Stephen Hemminger @ 2019-08-01 15:16 UTC (permalink / raw)
To: Andrea Claudi; +Cc: netdev, dsahern
In-Reply-To: <7090709d3ddace589952a128fb62f6603e2da9e8.1564653511.git.aclaudi@redhat.com>
On Thu, 1 Aug 2019 12:12:58 +0200
Andrea Claudi <aclaudi@redhat.com> wrote:
> Add json support on iptunnel and ip6tunnel.
> The plain text output format should remain the same.
>
> Signed-off-by: Andrea Claudi <aclaudi@redhat.com>
> ---
> ip/ip6tunnel.c | 82 +++++++++++++++++++++++++++++++--------------
> ip/iptunnel.c | 90 +++++++++++++++++++++++++++++++++-----------------
> ip/tunnel.c | 42 +++++++++++++++++------
> 3 files changed, 148 insertions(+), 66 deletions(-)
>
> diff --git a/ip/ip6tunnel.c b/ip/ip6tunnel.c
> index d7684a673fdc4..f2b9710c1320f 100644
> --- a/ip/ip6tunnel.c
> +++ b/ip/ip6tunnel.c
> @@ -71,57 +71,90 @@ static void usage(void)
> static void print_tunnel(const void *t)
> {
> const struct ip6_tnl_parm2 *p = t;
> - char s1[1024];
> - char s2[1024];
> + SPRINT_BUF(b1);
>
> /* Do not use format_host() for local addr,
> * symbolic name will not be useful.
> */
> - printf("%s: %s/ipv6 remote %s local %s",
> - p->name,
> - tnl_strproto(p->proto),
> - format_host_r(AF_INET6, 16, &p->raddr, s1, sizeof(s1)),
> - rt_addr_n2a_r(AF_INET6, 16, &p->laddr, s2, sizeof(s2)));
> + open_json_object(NULL);
> + print_string(PRINT_ANY, "ifname", "%s: ", p->name);
Print this using color for interface name?
> + snprintf(b1, sizeof(b1), "%s/ipv6", tnl_strproto(p->proto));
> + print_string(PRINT_ANY, "mode", "%s ", b1);
> + print_string(PRINT_ANY,
> + "remote",
> + "remote %s ",
> + format_host_r(AF_INET6, 16, &p->raddr, b1, sizeof(b1)));
> + print_string(PRINT_ANY,
> + "local",
> + "local %s",
> + rt_addr_n2a_r(AF_INET6, 16, &p->laddr, b1, sizeof(b1)));
> +
> if (p->link) {
> const char *n = ll_index_to_name(p->link);
>
> if (n)
> - printf(" dev %s", n);
> + print_string(PRINT_ANY, "link", " dev %s", n);
> }
>
> if (p->flags & IP6_TNL_F_IGN_ENCAP_LIMIT)
> - printf(" encaplimit none");
> + print_bool(PRINT_ANY,
> + "ip6_tnl_f_ign_encap_limit",
> + " encaplimit none",
> + true);
For flags like this, print_null is more typical JSON than a boolean
value. Null is better for presence flag. Bool is better if both true and
false are printed.
^ permalink raw reply
* Fw: [Bug 204399] New: error in handling vlan tag by raw ethernet socket
From: Stephen Hemminger @ 2019-08-01 14:51 UTC (permalink / raw)
To: netdev
Begin forwarded message:
Date: Thu, 01 Aug 2019 06:37:39 +0000
From: bugzilla-daemon@bugzilla.kernel.org
To: stephen@networkplumber.org
Subject: [Bug 204399] New: error in handling vlan tag by raw ethernet socket
https://bugzilla.kernel.org/show_bug.cgi?id=204399
Bug ID: 204399
Summary: error in handling vlan tag by raw ethernet socket
Product: Networking
Version: 2.5
Kernel Version: 5.0.0-21-generic #22-Ubuntu x86_64
Hardware: All
OS: Linux
Tree: Mainline
Status: NEW
Severity: high
Priority: P1
Component: IPV4
Assignee: stephen@networkplumber.org
Reporter: Lvenkatakumarchakka@gmail.com
Regression: No
Created attachment 284067
--> https://bugzilla.kernel.org/attachment.cgi?id=284067&action=edit
set/unset the variable "stripping_vlan_tag" to reproduce the issue
I am using raw ethernet socket and sending/receiving network traffic.
problem I am seeing is if read socket is opened before starting sending the
vlan traffic, read socket is able to capture packets along with vlan tag. but
if I open the read socket before starting sending the packets, vlan tag is
being stripped and only those four bytes are missing from the packet. Rest of
the packet is intact.
Please refer to the small code snippet which consistently produces the bug.
set/unset the variable "stripping_vlan_tag" to reproduce the issue.
is this a bug in the kernel or any problem with my coding ?
I am working on a project where I will be opening all the required sockets at
once and will be using as and when required. In that case, I am not able to
capture vlan tags which is blocking me. However, tcpdump is capture along with
vlan tag.
please be noted that, both the cards are in same system and are connected just
back to back using a cat5 cable. eth0 is built-in card and eth1 is usb based
external network card.
Is there a way to get rid of this issue ?
Best Regards,
Lokesh.
--
You are receiving this mail because:
You are the assignee for the bug.
^ permalink raw reply
* Re: [PATCH mlx5-next 1/3] IB/mlx5: Query ODP capabilities for DC
From: Leon Romanovsky @ 2019-08-01 14:51 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Doug Ledford, RDMA mailing list, Michael Guralnik, Moni Shoua,
Saeed Mahameed, linux-netdev
In-Reply-To: <20190801142511.GE23885@mellanox.com>
On Thu, Aug 01, 2019 at 02:25:16PM +0000, Jason Gunthorpe wrote:
> On Thu, Aug 01, 2019 at 03:21:37PM +0300, Leon Romanovsky wrote:
>
> > diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
> > index ec571fd7fcf8..5eae8d734435 100644
> > +++ b/include/linux/mlx5/mlx5_ifc.h
> > @@ -944,7 +944,9 @@ struct mlx5_ifc_odp_cap_bits {
> >
> > struct mlx5_ifc_odp_per_transport_service_cap_bits xrc_odp_caps;
> >
> > - u8 reserved_at_100[0x700];
> > + struct mlx5_ifc_odp_per_transport_service_cap_bits dc_odp_caps;
> > +
> > + u8 reserved_at_100[0x6E0];
> > };
>
> Not splitting this to mlx5-next?
This whole patch goes to mlx5-next, because it touches
drivers/net/ethernet/mellanox/mlx5/core/main.c too and splitting
to ifc specific patch won't change anything.
Thanks
>
> Jason
^ permalink raw reply
* Re: [PATCH mlx5-next 1/3] IB/mlx5: Query ODP capabilities for DC
From: Jason Gunthorpe @ 2019-08-01 14:25 UTC (permalink / raw)
To: Leon Romanovsky
Cc: Doug Ledford, Leon Romanovsky, RDMA mailing list,
Michael Guralnik, Moni Shoua, Saeed Mahameed, linux-netdev
In-Reply-To: <20190801122139.25224-2-leon@kernel.org>
On Thu, Aug 01, 2019 at 03:21:37PM +0300, Leon Romanovsky wrote:
> diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
> index ec571fd7fcf8..5eae8d734435 100644
> +++ b/include/linux/mlx5/mlx5_ifc.h
> @@ -944,7 +944,9 @@ struct mlx5_ifc_odp_cap_bits {
>
> struct mlx5_ifc_odp_per_transport_service_cap_bits xrc_odp_caps;
>
> - u8 reserved_at_100[0x700];
> + struct mlx5_ifc_odp_per_transport_service_cap_bits dc_odp_caps;
> +
> + u8 reserved_at_100[0x6E0];
> };
Not splitting this to mlx5-next?
Jason
^ permalink raw reply
* Re: [PATCH rdma-next 0/3] ODP support for mlx5 DC QPs
From: Jason Gunthorpe @ 2019-08-01 14:24 UTC (permalink / raw)
To: Leon Romanovsky
Cc: Doug Ledford, Leon Romanovsky, RDMA mailing list,
Michael Guralnik, Moni Shoua, Saeed Mahameed, linux-netdev
In-Reply-To: <20190801122139.25224-1-leon@kernel.org>
On Thu, Aug 01, 2019 at 03:21:36PM +0300, Leon Romanovsky wrote:
> From: Leon Romanovsky <leonro@mellanox.com>
>
> From Michael,
>
> The series adds support for on-demand paging for DC transport.
> Adding handling of DC WQE parsing upon page faults and exposing
> capabilities.
>
> As DC is mlx-only transport, the capabilities are exposed to the user
> using the direct-verbs mechanism. Namely through the mlx5dv_query_device.
The cover letter should like to the RDMA core PR that uses the new
API...
Jason
^ permalink raw reply
* Re: [PATCH] net: bridge: Allow bridge to joing multicast groups
From: Allan W. Nielsen @ 2019-08-01 14:22 UTC (permalink / raw)
To: Nikolay Aleksandrov
Cc: Horatiu Vultur, roopa, davem, bridge, netdev, linux-kernel
In-Reply-To: <b755f613-e6d8-a2e6-16cd-6f13ec0a6ddc@cumulusnetworks.com>
The 07/26/2019 15:31, Nikolay Aleksandrov wrote:
...
> You know that in order to not run in promisc mode you'll have to disable
> port flooding and port learning, right ? Otherwise they're always put in promisc.
Yes, we have spend some time looking at nbp_update_port_count and trying to
understand the reasoning behind it.
Our understanding is that this is to make it work with a pure SW bridge
implementation, and this is actually an optimization to allow disable promisc
mode if all forwarding is static (no flooding and no learning).
We also noticed that the Ocelot and the Rocker drivers avoids this "issue" by
not implementing promisc mode.
But promisc mode is a really nice feature for debugging, and we would actually
like to have it, and when HW that can do learning/flooding it does not seem to
be necessary.
I tried to understand how this is handled in the Mellanox drivers, but gave up.
Too big, and we lack the insight in their design.
Do you know if there are better ways to prevent switchdev-offloaded-slave
interfaces to go to promisc mode?
/Allan
^ permalink raw reply
* Re: [net-next,rfc] net: bridge: mdb: Extend with multicast LLADDR
From: Nikolay Aleksandrov @ 2019-08-01 14:15 UTC (permalink / raw)
To: Horatiu Vultur, idosch, andrew, allan.nielsen
Cc: davem, roopa, petrm, tglx, fw, netdev, linux-kernel, bridge
In-Reply-To: <1db865a6-9deb-fbd2-dee6-83609fcc2d95@cumulusnetworks.com>
On 01/08/2019 17:11, Nikolay Aleksandrov wrote:
> On 01/08/2019 17:07, Nikolay Aleksandrov wrote:
>> Hi Horatiu,
>> Overall I think MDB is the right way, we'd like to contain the multicast code.
>> A few comments below.
>>
>> On 01/08/2019 15:50, Horatiu Vultur wrote:
> [snip]
>>>
>>> Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
>>> Co-developed-by: Allan W. Nielsen <allan.nielsen@microchip.com>
>>> Signed-off-by: Allan W. Nielsen <allan.nielsen@microchip.com>
>>> ---
>>> include/linux/if_bridge.h | 1 +
>>> include/uapi/linux/if_bridge.h | 1 +
>>> net/bridge/br_device.c | 7 +++++--
>>> net/bridge/br_forward.c | 3 ++-
>>> net/bridge/br_input.c | 13 ++++++++++--
>>> net/bridge/br_mdb.c | 47 +++++++++++++++++++++++++++++++++++-------
>>> net/bridge/br_multicast.c | 4 +++-
>>> net/bridge/br_private.h | 3 ++-
>>> 8 files changed, 64 insertions(+), 15 deletions(-)
>>>
>>
>> Overall I don't think we need this BR_PKT_MULTICAST_L2, we could do the below much
>> easier and without the checks if you use a per-mdb flag that says it's to be treated
>> as a MULTICAST_L2 entry. Then you remove all of the BR_PKT_MULTICAST_L2 code (see the
>> attached patch based on this one for example). and continue processing it as it is processed today.
>> We'll keep the fast-path with minimal number of new conditionals.
>>
>> Something like the patch I've attached to this reply, note that it is not complete
>> just to show the intent, you'll have to re-work br_mdb_notify() to make it proper
>> and there're most probably other details I've missed. If you find even better/less
>> complex way to do it then please do.
>>
>> Cheers,
>> Nik
>
> Oops, I sent back your original patch. Here's the actually changed version
> I was talking about.
>
> Thanks,
> Nik
>
>
>
The querier exists change is a hack just to get the point, I'd prefer
to re-write that portion in a better way which makes more sense, i.e.
get that check out of there since it doesn't mean that an actual querier
exists. :)
^ permalink raw reply
* Re: [PATCH V2 7/9] vhost: do not use RCU to synchronize MMU notifier with worker
From: Jason Gunthorpe @ 2019-08-01 14:15 UTC (permalink / raw)
To: Jason Wang; +Cc: mst, kvm, virtualization, netdev, linux-kernel, linux-mm
In-Reply-To: <a3bde826-6329-68e4-2826-8a9de4c5bd1e@redhat.com>
On Thu, Aug 01, 2019 at 01:02:18PM +0800, Jason Wang wrote:
>
> On 2019/8/1 上午3:30, Jason Gunthorpe wrote:
> > On Wed, Jul 31, 2019 at 09:28:20PM +0800, Jason Wang wrote:
> > > On 2019/7/31 下午8:39, Jason Gunthorpe wrote:
> > > > On Wed, Jul 31, 2019 at 04:46:53AM -0400, Jason Wang wrote:
> > > > > We used to use RCU to synchronize MMU notifier with worker. This leads
> > > > > calling synchronize_rcu() in invalidate_range_start(). But on a busy
> > > > > system, there would be many factors that may slow down the
> > > > > synchronize_rcu() which makes it unsuitable to be called in MMU
> > > > > notifier.
> > > > >
> > > > > A solution is SRCU but its overhead is obvious with the expensive full
> > > > > memory barrier. Another choice is to use seqlock, but it doesn't
> > > > > provide a synchronization method between readers and writers. The last
> > > > > choice is to use vq mutex, but it need to deal with the worst case
> > > > > that MMU notifier must be blocked and wait for the finish of swap in.
> > > > >
> > > > > So this patch switches use a counter to track whether or not the map
> > > > > was used. The counter was increased when vq try to start or finish
> > > > > uses the map. This means, when it was even, we're sure there's no
> > > > > readers and MMU notifier is synchronized. When it was odd, it means
> > > > > there's a reader we need to wait it to be even again then we are
> > > > > synchronized.
> > > > You just described a seqlock.
> > >
> > > Kind of, see my explanation below.
> > >
> > >
> > > > We've been talking about providing this as some core service from mmu
> > > > notifiers because nearly every use of this API needs it.
> > >
> > > That would be very helpful.
> > >
> > >
> > > > IMHO this gets the whole thing backwards, the common pattern is to
> > > > protect the 'shadow pte' data with a seqlock (usually open coded),
> > > > such that the mmu notififer side has the write side of that lock and
> > > > the read side is consumed by the thread accessing or updating the SPTE.
> > >
> > > Yes, I've considered something like that. But the problem is, mmu notifier
> > > (writer) need to wait for the vhost worker to finish the read before it can
> > > do things like setting dirty pages and unmapping page. It looks to me
> > > seqlock doesn't provide things like this.
> > The seqlock is usually used to prevent a 2nd thread from accessing the
> > VA while it is being changed by the mm. ie you use something seqlocky
> > instead of the ugly mmu_notifier_unregister/register cycle.
>
>
> Yes, so we have two mappings:
>
> [1] vring address to VA
> [2] VA to PA
>
> And have several readers and writers
>
> 1) set_vring_num_addr(): writer of both [1] and [2]
> 2) MMU notifier: reader of [1] writer of [2]
> 3) GUP: reader of [1] writer of [2]
> 4) memory accessors: reader of [1] and [2]
>
> Fortunately, 1) 3) and 4) have already synchronized through vq->mutex. We
> only need to deal with synchronization between 2) and each of the reset:
> Sync between 1) and 2): For mapping [1], I do
> mmu_notifier_unregister/register. This help to avoid holding any lock to do
> overlap check.
I suspect you could have done this with a RCU technique instead of
register/unregister.
> Sync between 2) and 4): For mapping [1], both are readers, no need any
> synchronization. For mapping [2], synchronize through RCU (or something
> simliar to seqlock).
You can't really use a seqlock, seqlocks are collision-retry locks,
and the semantic here is that invalidate_range_start *MUST* not
continue until thread doing #4 above is guarenteed no longer touching
the memory.
This must be a proper barrier, like a spinlock, mutex, or
synchronize_rcu.
And, again, you can't re-invent a spinlock with open coding and get
something better.
Jason
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox