All of lore.kernel.org
 help / color / mirror / Atom feed
* [net-next, v3 0/2] Adding SO_PEEK_OFF for TCPv6
@ 2024-08-28 18:37 jmaloy
  2024-08-28 18:37 ` [net-next, v3 1/2] tcp: add SO_PEEK_OFF socket option tor TCPv6 jmaloy
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: jmaloy @ 2024-08-28 18:37 UTC (permalink / raw)
  To: netdev, linux-kselftest, davem
  Cc: kuba, passt-dev, jmaloy, sbrivio, lvivier, dgibson, eric.dumazet,
	edumazet

From: Jon Maloy <jmaloy@redhat.com>

Adding SO_PEEK_OFF for TCPv6 and selftest for both TCPv4 and TCPv6

Jon Maloy (2):
  tcp: add SO_PEEK_OFF socket option tor TCPv6
  selftests: add selftest for tcp SO_PEEK_OFF support

 net/ipv6/af_inet6.c                           |   1 +
 tools/testing/selftests/net/Makefile          |   1 +
 tools/testing/selftests/net/tcp_so_peek_off.c | 183 ++++++++++++++++++
 3 files changed, 185 insertions(+)
 create mode 100644 tools/testing/selftests/net/tcp_so_peek_off.c

-- 
2.45.2


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [net-next, v3 1/2] tcp: add SO_PEEK_OFF socket option tor TCPv6
  2024-08-28 18:37 [net-next, v3 0/2] Adding SO_PEEK_OFF for TCPv6 jmaloy
@ 2024-08-28 18:37 ` jmaloy
  2024-08-28 23:54   ` Jason Xing
  2024-08-28 18:37 ` [net-next, v3 2/2] selftests: add selftest for tcp SO_PEEK_OFF support jmaloy
  2024-08-30  3:45 ` [net-next, v3 0/2] Adding SO_PEEK_OFF for TCPv6 Jakub Kicinski
  2 siblings, 1 reply; 5+ messages in thread
From: jmaloy @ 2024-08-28 18:37 UTC (permalink / raw)
  To: netdev, linux-kselftest, davem
  Cc: kuba, passt-dev, jmaloy, sbrivio, lvivier, dgibson, eric.dumazet,
	edumazet

From: Jon Maloy <jmaloy@redhat.com>

When doing further testing of the recently added SO_PEEK_OFF feature
for TCP I realized I had omitted to add it for TCP/IPv6.

I do that here.

Fixes: 05ea491641d3 ("tcp: add support for SO_PEEK_OFF socket option")
Reviewed-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
Tested-by: Stefano Brivio <sbrivio@redhat.com>
Signed-off-by: Jon Maloy <jmaloy@redhat.com>

---
v2: Removed redundant whitespace between "Fixes" and
    "Signed-off-by" lines. Based on feedback from J. Kicinski.
v3: Rephrased commit log to make it clear how the TCP/IPv6 omission
    was discovered. Based on feedback from J. Kicinski.
---
 net/ipv6/af_inet6.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 90d2c7e3f5e9..ba69b86f1c7d 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -708,6 +708,7 @@ const struct proto_ops inet6_stream_ops = {
 	.splice_eof	   = inet_splice_eof,
 	.sendmsg_locked    = tcp_sendmsg_locked,
 	.splice_read	   = tcp_splice_read,
+	.set_peek_off      = sk_set_peek_off,
 	.read_sock	   = tcp_read_sock,
 	.read_skb	   = tcp_read_skb,
 	.peek_len	   = tcp_peek_len,
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [net-next, v3 2/2] selftests: add selftest for tcp SO_PEEK_OFF support
  2024-08-28 18:37 [net-next, v3 0/2] Adding SO_PEEK_OFF for TCPv6 jmaloy
  2024-08-28 18:37 ` [net-next, v3 1/2] tcp: add SO_PEEK_OFF socket option tor TCPv6 jmaloy
@ 2024-08-28 18:37 ` jmaloy
  2024-08-30  3:45 ` [net-next, v3 0/2] Adding SO_PEEK_OFF for TCPv6 Jakub Kicinski
  2 siblings, 0 replies; 5+ messages in thread
From: jmaloy @ 2024-08-28 18:37 UTC (permalink / raw)
  To: netdev, linux-kselftest, davem
  Cc: kuba, passt-dev, jmaloy, sbrivio, lvivier, dgibson, eric.dumazet,
	edumazet

From: Jon Maloy <jmaloy@redhat.com>

We add a selftest to check that the new feature added in
commit 05ea491641d3 ("tcp: add support for SO_PEEK_OFF socket option")
works correctly.

Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
Tested-by: Stefano Brivio <sbrivio@redhat.com>
Signed-off-by: Jon Maloy <jmaloy@redhat.com>

---
v2: Made correction based on Jason Xing's comment.
v3: Removed redundant whitespace at end of file.
    Based on comment from Jakub Kicinski.
---
 tools/testing/selftests/net/Makefile          |   1 +
 tools/testing/selftests/net/tcp_so_peek_off.c | 183 ++++++++++++++++++
 2 files changed, 184 insertions(+)
 create mode 100644 tools/testing/selftests/net/tcp_so_peek_off.c

diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
index 8eaffd7a641c..1179e3261bef 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -80,6 +80,7 @@ TEST_PROGS += io_uring_zerocopy_tx.sh
 TEST_GEN_FILES += bind_bhash
 TEST_GEN_PROGS += sk_bind_sendto_listen
 TEST_GEN_PROGS += sk_connect_zero_addr
+TEST_GEN_PROGS += tcp_so_peek_off
 TEST_PROGS += test_ingress_egress_chaining.sh
 TEST_GEN_PROGS += so_incoming_cpu
 TEST_PROGS += sctp_vrf.sh
diff --git a/tools/testing/selftests/net/tcp_so_peek_off.c b/tools/testing/selftests/net/tcp_so_peek_off.c
new file mode 100644
index 000000000000..df8a39d9d3c3
--- /dev/null
+++ b/tools/testing/selftests/net/tcp_so_peek_off.c
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include "../kselftest.h"
+
+static char *afstr(int af)
+{
+	return af == AF_INET ? "TCP/IPv4" : "TCP/IPv6";
+}
+
+int tcp_peek_offset_probe(sa_family_t af)
+{
+	int optv = 0;
+	int ret = 0;
+	int s;
+
+	s = socket(af, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
+	if (s < 0) {
+		ksft_perror("Temporary TCP socket creation failed");
+	} else {
+		if (!setsockopt(s, SOL_SOCKET, SO_PEEK_OFF, &optv, sizeof(int)))
+			ret = 1;
+		else
+			printf("%s does not support SO_PEEK_OFF\n", afstr(af));
+		close(s);
+	}
+	return ret;
+}
+
+static void tcp_peek_offset_set(int s, int offset)
+{
+	if (setsockopt(s, SOL_SOCKET, SO_PEEK_OFF, &offset, sizeof(offset)))
+		ksft_perror("Failed to set SO_PEEK_OFF value\n");
+}
+
+static int tcp_peek_offset_get(int s)
+{
+	int offset;
+	socklen_t len = sizeof(offset);
+
+	if (getsockopt(s, SOL_SOCKET, SO_PEEK_OFF, &offset, &len))
+		ksft_perror("Failed to get SO_PEEK_OFF value\n");
+	return offset;
+}
+
+static int tcp_peek_offset_test(sa_family_t af)
+{
+	union {
+		struct sockaddr sa;
+		struct sockaddr_in a4;
+		struct sockaddr_in6 a6;
+	} a;
+	int res = 0;
+	int s[2] = {0, 0};
+	int recv_sock = 0;
+	int offset = 0;
+	ssize_t len;
+	char buf;
+
+	memset(&a, 0, sizeof(a));
+	a.sa.sa_family = af;
+
+	s[0] = socket(af, SOCK_STREAM, IPPROTO_TCP);
+	s[1] = socket(af, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);
+
+	if (s[0] < 0 || s[1] < 0) {
+		ksft_perror("Temporary socket creation failed\n");
+		goto out;
+	}
+	if (bind(s[0], &a.sa, sizeof(a)) < 0) {
+		ksft_perror("Temporary socket bind() failed\n");
+		goto out;
+	}
+	if (getsockname(s[0], &a.sa, &((socklen_t) { sizeof(a) })) < 0) {
+		ksft_perror("Temporary socket getsockname() failed\n");
+		goto out;
+	}
+	if (listen(s[0], 0) < 0) {
+		ksft_perror("Temporary socket listen() failed\n");
+		goto out;
+	}
+	if (connect(s[1], &a.sa, sizeof(a)) >= 0 || errno != EINPROGRESS) {
+		ksft_perror("Temporary socket connect() failed\n");
+		goto out;
+	}
+	recv_sock = accept(s[0], NULL, NULL);
+	if (recv_sock <= 0) {
+		ksft_perror("Temporary socket accept() failed\n");
+		goto out;
+	}
+
+	/* Some basic tests of getting/setting offset */
+	offset = tcp_peek_offset_get(recv_sock);
+	if (offset != -1) {
+		ksft_perror("Initial value of socket offset not -1\n");
+		goto out;
+	}
+	tcp_peek_offset_set(recv_sock, 0);
+	offset = tcp_peek_offset_get(recv_sock);
+	if (offset != 0) {
+		ksft_perror("Failed to set socket offset to 0\n");
+		goto out;
+	}
+
+	/* Transfer a message */
+	if (send(s[1], (char *)("ab"), 2, 0) <= 0 || errno != EINPROGRESS) {
+		ksft_perror("Temporary probe socket send() failed\n");
+		goto out;
+	}
+	/* Read first byte */
+	len = recv(recv_sock, &buf, 1, MSG_PEEK);
+	if (len != 1 || buf != 'a') {
+		ksft_perror("Failed to read first byte of message\n");
+		goto out;
+	}
+	offset = tcp_peek_offset_get(recv_sock);
+	if (offset != 1) {
+		ksft_perror("Offset not forwarded correctly at first byte\n");
+		goto out;
+	}
+	/* Try to read beyond last byte */
+	len = recv(recv_sock, &buf, 2, MSG_PEEK);
+	if (len != 1 || buf != 'b') {
+		ksft_perror("Failed to read last byte of message\n");
+		goto out;
+	}
+	offset = tcp_peek_offset_get(recv_sock);
+	if (offset != 2) {
+		ksft_perror("Offset not forwarded correctly at last byte\n");
+		goto out;
+	}
+	/* Flush message */
+	len = recv(recv_sock, NULL, 2, MSG_TRUNC);
+	if (len != 2) {
+		ksft_perror("Failed to flush message\n");
+		goto out;
+	}
+	offset = tcp_peek_offset_get(recv_sock);
+	if (offset != 0) {
+		ksft_perror("Offset not reverted correctly after flush\n");
+		goto out;
+	}
+
+	printf("%s with MSG_PEEK_OFF works correctly\n", afstr(af));
+	res = 1;
+out:
+	if (recv_sock >= 0)
+		close(recv_sock);
+	if (s[1] >= 0)
+		close(s[1]);
+	if (s[0] >= 0)
+		close(s[0]);
+	return res;
+}
+
+int main(void)
+{
+	int res4, res6;
+
+	res4 = tcp_peek_offset_probe(AF_INET);
+	res6 = tcp_peek_offset_probe(AF_INET6);
+
+	if (!res4 && !res6)
+		return KSFT_SKIP;
+
+	if (res4)
+		res4 = tcp_peek_offset_test(AF_INET);
+
+	if (res6)
+		res6 = tcp_peek_offset_test(AF_INET6);
+
+	if (!res4 || !res6)
+		return KSFT_FAIL;
+
+	return KSFT_PASS;
+}
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [net-next, v3 1/2] tcp: add SO_PEEK_OFF socket option tor TCPv6
  2024-08-28 18:37 ` [net-next, v3 1/2] tcp: add SO_PEEK_OFF socket option tor TCPv6 jmaloy
@ 2024-08-28 23:54   ` Jason Xing
  0 siblings, 0 replies; 5+ messages in thread
From: Jason Xing @ 2024-08-28 23:54 UTC (permalink / raw)
  To: jmaloy
  Cc: netdev, linux-kselftest, davem, kuba, passt-dev, sbrivio, lvivier,
	dgibson, eric.dumazet, edumazet

On Thu, Aug 29, 2024 at 2:38 AM <jmaloy@redhat.com> wrote:
>
> From: Jon Maloy <jmaloy@redhat.com>
>
> When doing further testing of the recently added SO_PEEK_OFF feature
> for TCP I realized I had omitted to add it for TCP/IPv6.
>
> I do that here.
>
> Fixes: 05ea491641d3 ("tcp: add support for SO_PEEK_OFF socket option")
> Reviewed-by: Eric Dumazet <edumazet@google.com>
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
> Tested-by: Stefano Brivio <sbrivio@redhat.com>
> Signed-off-by: Jon Maloy <jmaloy@redhat.com>

Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [net-next, v3 0/2] Adding SO_PEEK_OFF for TCPv6
  2024-08-28 18:37 [net-next, v3 0/2] Adding SO_PEEK_OFF for TCPv6 jmaloy
  2024-08-28 18:37 ` [net-next, v3 1/2] tcp: add SO_PEEK_OFF socket option tor TCPv6 jmaloy
  2024-08-28 18:37 ` [net-next, v3 2/2] selftests: add selftest for tcp SO_PEEK_OFF support jmaloy
@ 2024-08-30  3:45 ` Jakub Kicinski
  2 siblings, 0 replies; 5+ messages in thread
From: Jakub Kicinski @ 2024-08-30  3:45 UTC (permalink / raw)
  To: jmaloy
  Cc: netdev, linux-kselftest, davem, passt-dev, sbrivio, lvivier,
	dgibson, eric.dumazet, edumazet

On Wed, 28 Aug 2024 14:37:50 -0400 jmaloy@redhat.com wrote:
> Adding SO_PEEK_OFF for TCPv6 and selftest for both TCPv4 and TCPv6

Applied, thanks.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-08-30  3:45 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-28 18:37 [net-next, v3 0/2] Adding SO_PEEK_OFF for TCPv6 jmaloy
2024-08-28 18:37 ` [net-next, v3 1/2] tcp: add SO_PEEK_OFF socket option tor TCPv6 jmaloy
2024-08-28 23:54   ` Jason Xing
2024-08-28 18:37 ` [net-next, v3 2/2] selftests: add selftest for tcp SO_PEEK_OFF support jmaloy
2024-08-30  3:45 ` [net-next, v3 0/2] Adding SO_PEEK_OFF for TCPv6 Jakub Kicinski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.