Add support for common SOL_SOCKET cmsgs in ICMPv6 sockets. Extend the cmsg tests to cover more cmsgs and socket types.
SOL_IPV6 cmsgs to follow.
Jakub Kicinski (11): net: ping6: remove a pr_debug() statement net: ping6: support packet timestamping net: ping6: support setting socket options via cmsg selftests: net: rename cmsg_so_mark selftests: net: make cmsg_so_mark ready for more options selftests: net: cmsg_sender: support icmp and raw sockets selftests: net: cmsg_so_mark: test ICMP and RAW sockets selftests: net: cmsg_so_mark: test with SO_MARK set by setsockopt selftests: net: cmsg_sender: support setting SO_TXTIME selftests: net: cmsg_sender: support Tx timestamping selftests: net: test standard socket cmsgs across UDP and ICMP sockets
net/ipv6/ping.c | 14 +- tools/testing/selftests/net/.gitignore | 2 +- tools/testing/selftests/net/Makefile | 3 +- tools/testing/selftests/net/cmsg_sender.c | 380 ++++++++++++++++++++ tools/testing/selftests/net/cmsg_so_mark.c | 67 ---- tools/testing/selftests/net/cmsg_so_mark.sh | 32 +- tools/testing/selftests/net/cmsg_time.sh | 83 +++++ 7 files changed, 499 insertions(+), 82 deletions(-) create mode 100644 tools/testing/selftests/net/cmsg_sender.c delete mode 100644 tools/testing/selftests/net/cmsg_so_mark.c create mode 100755 tools/testing/selftests/net/cmsg_time.sh
We have ftrace and BPF today, there's no need for printing arguments at the start of a function.
Signed-off-by: Jakub Kicinski kuba@kernel.org --- net/ipv6/ping.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index 9256f6ba87ef..86a72f7a61cf 100644 --- a/net/ipv6/ping.c +++ b/net/ipv6/ping.c @@ -59,8 +59,6 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) struct pingfakehdr pfh; struct ipcm6_cookie ipc6;
- pr_debug("ping_v6_sendmsg(sk=%p,sk->num=%u)\n", inet, inet->inet_num); - err = ping_common_sendmsg(AF_INET6, msg, len, &user_icmph, sizeof(user_icmph)); if (err)
On 2/9/22 4:36 PM, Jakub Kicinski wrote:
We have ftrace and BPF today, there's no need for printing arguments at the start of a function.
Signed-off-by: Jakub Kicinski kuba@kernel.org
net/ipv6/ping.c | 2 -- 1 file changed, 2 deletions(-)
Reviewed-by: David Ahern dsahern@kernel.org
Nothing prevents the user from requesting timestamping on ping6 sockets, yet timestamps are not going to be reported. Plumb the flags through.
Signed-off-by: Jakub Kicinski kuba@kernel.org --- net/ipv6/ping.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index 86a72f7a61cf..3228ccd8abf1 100644 --- a/net/ipv6/ping.c +++ b/net/ipv6/ping.c @@ -113,6 +113,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
ipcm6_init_sk(&ipc6, np); ipc6.sockc.mark = sk->sk_mark; + ipc6.sockc.tsflags = sk->sk_tsflags; fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
dst = ip6_sk_dst_lookup_flow(sk, &fl6, daddr, false);
On Wed, Feb 9, 2022 at 4:36 PM Jakub Kicinski kuba@kernel.org wrote:
Nothing prevents the user from requesting timestamping on ping6 sockets, yet timestamps are not going to be reported. Plumb the flags through.
Signed-off-by: Jakub Kicinski kuba@kernel.org
net/ipv6/ping.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index 86a72f7a61cf..3228ccd8abf1 100644 --- a/net/ipv6/ping.c +++ b/net/ipv6/ping.c @@ -113,6 +113,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
ipcm6_init_sk(&ipc6, np); ipc6.sockc.mark = sk->sk_mark;
ipc6.sockc.tsflags = sk->sk_tsflags; fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel); dst = ip6_sk_dst_lookup_flow(sk, &fl6, daddr, false);
-- 2.34.1
probably deserves a fixes tag? otherwise looks fine to me
On Wed, 9 Feb 2022 16:44:18 -0800 Maciej Żenczykowski wrote:
probably deserves a fixes tag?
I went with a "never worked + unlikely a generic app (which depends on TS) will use ICMP6 sockets" classification. Let's see if we get another vote to make this a fix.
otherwise looks fine to me
Thanks!
On 2/9/22 4:36 PM, Jakub Kicinski wrote:
Nothing prevents the user from requesting timestamping on ping6 sockets, yet timestamps are not going to be reported. Plumb the flags through.
Signed-off-by: Jakub Kicinski kuba@kernel.org
net/ipv6/ping.c | 1 + 1 file changed, 1 insertion(+)
Reviewed-by: David Ahern dsahern@kernel.org
no opinion on the Fixes tag.
Minor reordering of the code and a call to sock_cmsg_send() gives us support for setting the common socket options via cmsg (the usual ones - SO_MARK, SO_TIMESTAMPING_OLD, SCM_TXTIME).
Signed-off-by: Jakub Kicinski kuba@kernel.org --- net/ipv6/ping.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index 3228ccd8abf1..d5544cf67ffe 100644 --- a/net/ipv6/ping.c +++ b/net/ipv6/ping.c @@ -97,6 +97,14 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) (oif && sk->sk_bound_dev_if && oif != sk->sk_bound_dev_if)) return -EINVAL;
+ ipcm6_init_sk(&ipc6, np); + ipc6.sockc.tsflags = sk->sk_tsflags; + ipc6.sockc.mark = sk->sk_mark; + + err = sock_cmsg_send(sk, msg, &ipc6.sockc); + if (err) + return err; + /* TODO: use ip6_datagram_send_ctl to get options from cmsg */
memset(&fl6, 0, sizeof(fl6)); @@ -105,15 +113,12 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) fl6.saddr = np->saddr; fl6.daddr = *daddr; fl6.flowi6_oif = oif; - fl6.flowi6_mark = sk->sk_mark; + fl6.flowi6_mark = ipc6.sockc.mark; fl6.flowi6_uid = sk->sk_uid; fl6.fl6_icmp_type = user_icmph.icmp6_type; fl6.fl6_icmp_code = user_icmph.icmp6_code; security_sk_classify_flow(sk, flowi6_to_flowi_common(&fl6));
- ipcm6_init_sk(&ipc6, np); - ipc6.sockc.mark = sk->sk_mark; - ipc6.sockc.tsflags = sk->sk_tsflags; fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
dst = ip6_sk_dst_lookup_flow(sk, &fl6, daddr, false);
On 2/9/22 4:36 PM, Jakub Kicinski wrote:
Minor reordering of the code and a call to sock_cmsg_send() gives us support for setting the common socket options via cmsg (the usual ones - SO_MARK, SO_TIMESTAMPING_OLD, SCM_TXTIME).
Signed-off-by: Jakub Kicinski kuba@kernel.org
net/ipv6/ping.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
Reviewed-by: David Ahern dsahern@kernel.org
Rename the file in prep for generalization.
Signed-off-by: Jakub Kicinski kuba@kernel.org --- tools/testing/selftests/net/.gitignore | 2 +- tools/testing/selftests/net/Makefile | 2 +- .../selftests/net/{cmsg_so_mark.c => cmsg_sender.c} | 0 tools/testing/selftests/net/cmsg_so_mark.sh | 8 ++++---- 4 files changed, 6 insertions(+), 6 deletions(-) rename tools/testing/selftests/net/{cmsg_so_mark.c => cmsg_sender.c} (100%)
diff --git a/tools/testing/selftests/net/.gitignore b/tools/testing/selftests/net/.gitignore index 7581a7348e1b..21a411b04890 100644 --- a/tools/testing/selftests/net/.gitignore +++ b/tools/testing/selftests/net/.gitignore @@ -35,4 +35,4 @@ test_unix_oob gro ioam6_parser toeplitz -cmsg_so_mark +cmsg_sender diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index 9897fa9ab953..8f4c1f16655f 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -52,7 +52,7 @@ TEST_GEN_FILES += gro TEST_GEN_PROGS = reuseport_bpf reuseport_bpf_cpu reuseport_bpf_numa TEST_GEN_PROGS += reuseport_dualstack reuseaddr_conflict tls TEST_GEN_FILES += toeplitz -TEST_GEN_FILES += cmsg_so_mark +TEST_GEN_FILES += cmsg_sender
TEST_FILES := settings
diff --git a/tools/testing/selftests/net/cmsg_so_mark.c b/tools/testing/selftests/net/cmsg_sender.c similarity index 100% rename from tools/testing/selftests/net/cmsg_so_mark.c rename to tools/testing/selftests/net/cmsg_sender.c diff --git a/tools/testing/selftests/net/cmsg_so_mark.sh b/tools/testing/selftests/net/cmsg_so_mark.sh index 19c6aab8d0e9..29a623aac74b 100755 --- a/tools/testing/selftests/net/cmsg_so_mark.sh +++ b/tools/testing/selftests/net/cmsg_so_mark.sh @@ -41,14 +41,14 @@ check_result() { fi }
-ip netns exec $NS ./cmsg_so_mark $TGT4 1234 $((MARK + 1)) +ip netns exec $NS ./cmsg_sender $TGT4 1234 $((MARK + 1)) check_result $? 0 "IPv4 pass" -ip netns exec $NS ./cmsg_so_mark $TGT6 1234 $((MARK + 1)) +ip netns exec $NS ./cmsg_sender $TGT6 1234 $((MARK + 1)) check_result $? 0 "IPv6 pass"
-ip netns exec $NS ./cmsg_so_mark $TGT4 1234 $MARK +ip netns exec $NS ./cmsg_sender $TGT4 1234 $MARK check_result $? 1 "IPv4 rejection" -ip netns exec $NS ./cmsg_so_mark $TGT6 1234 $MARK +ip netns exec $NS ./cmsg_sender $TGT6 1234 $MARK check_result $? 1 "IPv6 rejection"
# Summary
Parametrize the code so that it can support UDP and ICMP sockets in the future, and more cmsg types.
Signed-off-by: Jakub Kicinski kuba@kernel.org --- tools/testing/selftests/net/cmsg_sender.c | 135 ++++++++++++++++---- tools/testing/selftests/net/cmsg_so_mark.sh | 8 +- 2 files changed, 117 insertions(+), 26 deletions(-)
diff --git a/tools/testing/selftests/net/cmsg_sender.c b/tools/testing/selftests/net/cmsg_sender.c index 27f2804892a7..4528ae638aea 100644 --- a/tools/testing/selftests/net/cmsg_sender.c +++ b/tools/testing/selftests/net/cmsg_sender.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include <errno.h> +#include <error.h> #include <netdb.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -8,60 +10,149 @@ #include <linux/types.h> #include <sys/socket.h>
-int main(int argc, const char **argv) +enum { + ERN_SUCCESS = 0, + /* Well defined errors, callers may depend on these */ + ERN_SEND = 1, + /* Informational, can reorder */ + ERN_HELP, + ERN_SEND_SHORT, + ERN_SOCK_CREATE, + ERN_RESOLVE, + ERN_CMSG_WR, +}; + +struct options { + bool silent_send; + const char *host; + const char *service; + struct { + unsigned int type; + } sock; + struct { + bool ena; + unsigned int val; + } mark; +} opt = { + .sock = { + .type = SOCK_DGRAM, + }, +}; + +static void __attribute__((noreturn)) cs_usage(const char *bin) +{ + printf("Usage: %s [opts] <dst host> <dst port / service>\n", bin); + printf("Options:\n" + "\t\t-s Silent send() failures\n" + "\t\t-m val Set SO_MARK with given value\n" + ""); + exit(ERN_HELP); +} + +static void cs_parse_args(int argc, char *argv[]) +{ + char o; + + while ((o = getopt(argc, argv, "sm:")) != -1) { + switch (o) { + case 's': + opt.silent_send = true; + break; + case 'm': + opt.mark.ena = true; + opt.mark.val = atoi(optarg); + break; + } + } + + if (optind != argc - 2) + cs_usage(argv[0]); + + opt.host = argv[optind]; + opt.service = argv[optind + 1]; +} + +static void +cs_write_cmsg(struct msghdr *msg, char *cbuf, size_t cbuf_sz) { - char cbuf[CMSG_SPACE(sizeof(__u32))]; - struct addrinfo hints, *ai; struct cmsghdr *cmsg; + size_t cmsg_len; + + msg->msg_control = cbuf; + cmsg_len = 0; + + if (opt.mark.ena) { + cmsg = (struct cmsghdr *)(cbuf + cmsg_len); + cmsg_len += CMSG_SPACE(sizeof(__u32)); + if (cbuf_sz < cmsg_len) + error(ERN_CMSG_WR, EFAULT, "cmsg buffer too small"); + + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SO_MARK; + cmsg->cmsg_len = CMSG_LEN(sizeof(__u32)); + *(__u32 *)CMSG_DATA(cmsg) = opt.mark.val; + } + + if (cmsg_len) + msg->msg_controllen = cmsg_len; + else + msg->msg_control = NULL; +} + +int main(int argc, char *argv[]) +{ + struct addrinfo hints, *ai; struct iovec iov[1]; struct msghdr msg; - int mark; + char cbuf[1024]; int err; int fd;
- if (argc != 4) { - fprintf(stderr, "Usage: %s <dst_ip> <port> <mark>\n", argv[0]); - return 1; - } - mark = atoi(argv[3]); + cs_parse_args(argc, argv);
memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_DGRAM; + hints.ai_socktype = opt.sock.type;
ai = NULL; - err = getaddrinfo(argv[1], argv[2], &hints, &ai); + err = getaddrinfo(opt.host, opt.service, &hints, &ai); if (err) { - fprintf(stderr, "Can't resolve address: %s\n", strerror(errno)); - return 1; + fprintf(stderr, "Can't resolve address [%s]:%s: %s\n", + opt.host, opt.service, strerror(errno)); + return ERN_SOCK_CREATE; }
fd = socket(ai->ai_family, SOCK_DGRAM, IPPROTO_UDP); if (fd < 0) { fprintf(stderr, "Can't open socket: %s\n", strerror(errno)); freeaddrinfo(ai); - return 1; + return ERN_RESOLVE; }
iov[0].iov_base = "bla"; iov[0].iov_len = 4;
+ memset(&msg, 0, sizeof(msg)); msg.msg_name = ai->ai_addr; msg.msg_namelen = ai->ai_addrlen; msg.msg_iov = iov; msg.msg_iovlen = 1; - msg.msg_control = cbuf; - msg.msg_controllen = sizeof(cbuf);
- cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SO_MARK; - cmsg->cmsg_len = CMSG_LEN(sizeof(__u32)); - *(__u32 *)CMSG_DATA(cmsg) = mark; + cs_write_cmsg(&msg, cbuf, sizeof(cbuf));
err = sendmsg(fd, &msg, 0); + if (err < 0) { + if (!opt.silent_send) + fprintf(stderr, "send failed: %s\n", strerror(errno)); + err = ERN_SEND; + } else if (err != 4) { + fprintf(stderr, "short send\n"); + err = ERN_SEND_SHORT; + } else { + err = ERN_SUCCESS; + }
close(fd); freeaddrinfo(ai); - return err != 4; + return err; } diff --git a/tools/testing/selftests/net/cmsg_so_mark.sh b/tools/testing/selftests/net/cmsg_so_mark.sh index 29a623aac74b..841d706dc91b 100755 --- a/tools/testing/selftests/net/cmsg_so_mark.sh +++ b/tools/testing/selftests/net/cmsg_so_mark.sh @@ -41,14 +41,14 @@ check_result() { fi }
-ip netns exec $NS ./cmsg_sender $TGT4 1234 $((MARK + 1)) +ip netns exec $NS ./cmsg_sender -m $((MARK + 1)) $TGT4 1234 check_result $? 0 "IPv4 pass" -ip netns exec $NS ./cmsg_sender $TGT6 1234 $((MARK + 1)) +ip netns exec $NS ./cmsg_sender -m $((MARK + 1)) $TGT6 1234 check_result $? 0 "IPv6 pass"
-ip netns exec $NS ./cmsg_sender $TGT4 1234 $MARK +ip netns exec $NS ./cmsg_sender -s -m $MARK $TGT4 1234 check_result $? 1 "IPv4 rejection" -ip netns exec $NS ./cmsg_sender $TGT6 1234 $MARK +ip netns exec $NS ./cmsg_sender -s -m $MARK $TGT6 1234 check_result $? 1 "IPv6 rejection"
# Summary
Support sending fake ICMP(v6) messages and UDP via RAW sockets.
Signed-off-by: Jakub Kicinski kuba@kernel.org --- tools/testing/selftests/net/cmsg_sender.c | 64 +++++++++++++++++++---- 1 file changed, 55 insertions(+), 9 deletions(-)
diff --git a/tools/testing/selftests/net/cmsg_sender.c b/tools/testing/selftests/net/cmsg_sender.c index 4528ae638aea..edb8c427c7cb 100644 --- a/tools/testing/selftests/net/cmsg_sender.c +++ b/tools/testing/selftests/net/cmsg_sender.c @@ -7,7 +7,10 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <linux/icmp.h> +#include <linux/icmpv6.h> #include <linux/types.h> +#include <linux/udp.h> #include <sys/socket.h>
enum { @@ -27,7 +30,9 @@ struct options { const char *host; const char *service; struct { + unsigned int family; unsigned int type; + unsigned int proto; } sock; struct { bool ena; @@ -35,7 +40,9 @@ struct options { } mark; } opt = { .sock = { + .family = AF_UNSPEC, .type = SOCK_DGRAM, + .proto = IPPROTO_UDP, }, };
@@ -44,6 +51,10 @@ static void __attribute__((noreturn)) cs_usage(const char *bin) printf("Usage: %s [opts] <dst host> <dst port / service>\n", bin); printf("Options:\n" "\t\t-s Silent send() failures\n" + "\t\t-4/-6 Force IPv4 / IPv6 only\n" + "\t\t-p prot Socket protocol\n" + "\t\t (u = UDP (default); i = ICMP; r = RAW)\n" + "\n" "\t\t-m val Set SO_MARK with given value\n" ""); exit(ERN_HELP); @@ -53,11 +64,29 @@ static void cs_parse_args(int argc, char *argv[]) { char o;
- while ((o = getopt(argc, argv, "sm:")) != -1) { + while ((o = getopt(argc, argv, "46sp:m:")) != -1) { switch (o) { case 's': opt.silent_send = true; break; + case '4': + opt.sock.family = AF_INET; + break; + case '6': + opt.sock.family = AF_INET6; + break; + case 'p': + if (*optarg == 'u' || *optarg == 'U') { + opt.sock.proto = IPPROTO_UDP; + } else if (*optarg == 'i' || *optarg == 'I') { + opt.sock.proto = IPPROTO_ICMP; + } else if (*optarg == 'r') { + opt.sock.type = SOCK_RAW; + } else { + printf("Error: unknown protocol: %s\n", optarg); + cs_usage(argv[0]); + } + break; case 'm': opt.mark.ena = true; opt.mark.val = atoi(optarg); @@ -101,6 +130,7 @@ cs_write_cmsg(struct msghdr *msg, char *cbuf, size_t cbuf_sz)
int main(int argc, char *argv[]) { + char buf[] = "blablablabla"; struct addrinfo hints, *ai; struct iovec iov[1]; struct msghdr msg; @@ -111,26 +141,42 @@ int main(int argc, char *argv[]) cs_parse_args(argc, argv);
memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = opt.sock.type; + hints.ai_family = opt.sock.family;
ai = NULL; err = getaddrinfo(opt.host, opt.service, &hints, &ai); if (err) { - fprintf(stderr, "Can't resolve address [%s]:%s: %s\n", - opt.host, opt.service, strerror(errno)); + fprintf(stderr, "Can't resolve address [%s]:%s\n", + opt.host, opt.service); return ERN_SOCK_CREATE; }
- fd = socket(ai->ai_family, SOCK_DGRAM, IPPROTO_UDP); + if (ai->ai_family == AF_INET6 && opt.sock.proto == IPPROTO_ICMP) + opt.sock.proto = IPPROTO_ICMPV6; + + fd = socket(ai->ai_family, opt.sock.type, opt.sock.proto); if (fd < 0) { fprintf(stderr, "Can't open socket: %s\n", strerror(errno)); freeaddrinfo(ai); return ERN_RESOLVE; }
- iov[0].iov_base = "bla"; - iov[0].iov_len = 4; + if (opt.sock.proto == IPPROTO_ICMP) { + buf[0] = ICMP_ECHO; + buf[1] = 0; + } else if (opt.sock.proto == IPPROTO_ICMPV6) { + buf[0] = ICMPV6_ECHO_REQUEST; + buf[1] = 0; + } else if (opt.sock.type == SOCK_RAW) { + struct udphdr hdr = { 1, 2, htons(sizeof(buf)), 0 }; + struct sockaddr_in6 *sin6 = (void *)ai->ai_addr;; + + memcpy(buf, &hdr, sizeof(hdr)); + sin6->sin6_port = htons(opt.sock.proto); + } + + iov[0].iov_base = buf; + iov[0].iov_len = sizeof(buf);
memset(&msg, 0, sizeof(msg)); msg.msg_name = ai->ai_addr; @@ -145,7 +191,7 @@ int main(int argc, char *argv[]) if (!opt.silent_send) fprintf(stderr, "send failed: %s\n", strerror(errno)); err = ERN_SEND; - } else if (err != 4) { + } else if (err != sizeof(buf)) { fprintf(stderr, "short send\n"); err = ERN_SEND_SHORT; } else {
Use new capabilities of cmsg_sender to test ICMP and RAW sockets, previously only UDP was tested.
Before SO_MARK support was added to ICMPv6:
# ./cmsg_so_mark.sh Case ICMP rejection returned 0, expected 1 FAIL - 1/12 cases failed
After:
# ./cmsg_so_mark.sh OK
Signed-off-by: Jakub Kicinski kuba@kernel.org --- tools/testing/selftests/net/cmsg_so_mark.sh | 24 ++++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/tools/testing/selftests/net/cmsg_so_mark.sh b/tools/testing/selftests/net/cmsg_so_mark.sh index 841d706dc91b..925f6b9deee2 100755 --- a/tools/testing/selftests/net/cmsg_so_mark.sh +++ b/tools/testing/selftests/net/cmsg_so_mark.sh @@ -18,6 +18,8 @@ trap cleanup EXIT # Namespaces ip netns add $NS
+ip netns exec $NS sysctl -w net.ipv4.ping_group_range='0 2147483647' > /dev/null + # Connectivity ip -netns $NS link add type dummy ip -netns $NS link set dev dummy0 up @@ -41,15 +43,21 @@ check_result() { fi }
-ip netns exec $NS ./cmsg_sender -m $((MARK + 1)) $TGT4 1234 -check_result $? 0 "IPv4 pass" -ip netns exec $NS ./cmsg_sender -m $((MARK + 1)) $TGT6 1234 -check_result $? 0 "IPv6 pass" +for i in 4 6; do + [ $i == 4 ] && TGT=$TGT4 || TGT=$TGT6 + + for p in u i r; do + [ $p == "u" ] && prot=UDP + [ $p == "i" ] && prot=ICMP + [ $p == "r" ] && prot=RAW + + ip netns exec $NS ./cmsg_sender -$i -p $p -m $((MARK + 1)) $TGT 1234 + check_result $? 0 "$prot pass"
-ip netns exec $NS ./cmsg_sender -s -m $MARK $TGT4 1234 -check_result $? 1 "IPv4 rejection" -ip netns exec $NS ./cmsg_sender -s -m $MARK $TGT6 1234 -check_result $? 1 "IPv6 rejection" + ip netns exec $NS ./cmsg_sender -$i -p $p -m $MARK -s $TGT 1234 + check_result $? 1 "$prot rejection" + done +done
# Summary if [ $BAD -ne 0 ]; then
Test if setting SO_MARK with setsockopt works and if cmsg takes precedence over it.
Signed-off-by: Jakub Kicinski kuba@kernel.org --- tools/testing/selftests/net/cmsg_sender.c | 14 ++++++++++- tools/testing/selftests/net/cmsg_so_mark.sh | 28 +++++++++++++-------- 2 files changed, 31 insertions(+), 11 deletions(-)
diff --git a/tools/testing/selftests/net/cmsg_sender.c b/tools/testing/selftests/net/cmsg_sender.c index edb8c427c7cb..c7586a4b0361 100644 --- a/tools/testing/selftests/net/cmsg_sender.c +++ b/tools/testing/selftests/net/cmsg_sender.c @@ -29,6 +29,9 @@ struct options { bool silent_send; const char *host; const char *service; + struct { + unsigned int mark; + } sockopt; struct { unsigned int family; unsigned int type; @@ -56,6 +59,7 @@ static void __attribute__((noreturn)) cs_usage(const char *bin) "\t\t (u = UDP (default); i = ICMP; r = RAW)\n" "\n" "\t\t-m val Set SO_MARK with given value\n" + "\t\t-M val Set SO_MARK via setsockopt\n" ""); exit(ERN_HELP); } @@ -64,7 +68,7 @@ static void cs_parse_args(int argc, char *argv[]) { char o;
- while ((o = getopt(argc, argv, "46sp:m:")) != -1) { + while ((o = getopt(argc, argv, "46sp:m:M:")) != -1) { switch (o) { case 's': opt.silent_send = true; @@ -91,6 +95,9 @@ static void cs_parse_args(int argc, char *argv[]) opt.mark.ena = true; opt.mark.val = atoi(optarg); break; + case 'M': + opt.sockopt.mark = atoi(optarg); + break; } }
@@ -175,6 +182,11 @@ int main(int argc, char *argv[]) sin6->sin6_port = htons(opt.sock.proto); }
+ if (opt.sockopt.mark && + setsockopt(fd, SOL_SOCKET, SO_MARK, + &opt.sockopt.mark, sizeof(opt.sockopt.mark))) + error(ERN_SOCKOPT, errno, "setsockopt SO_MARK"); + iov[0].iov_base = buf; iov[0].iov_len = sizeof(buf);
diff --git a/tools/testing/selftests/net/cmsg_so_mark.sh b/tools/testing/selftests/net/cmsg_so_mark.sh index 925f6b9deee2..1650b8622f2f 100755 --- a/tools/testing/selftests/net/cmsg_so_mark.sh +++ b/tools/testing/selftests/net/cmsg_so_mark.sh @@ -43,19 +43,27 @@ check_result() { fi }
-for i in 4 6; do - [ $i == 4 ] && TGT=$TGT4 || TGT=$TGT6 +for ovr in setsock cmsg both; do + for i in 4 6; do + [ $i == 4 ] && TGT=$TGT4 || TGT=$TGT6
- for p in u i r; do - [ $p == "u" ] && prot=UDP - [ $p == "i" ] && prot=ICMP - [ $p == "r" ] && prot=RAW + for p in u i r; do + [ $p == "u" ] && prot=UDP + [ $p == "i" ] && prot=ICMP + [ $p == "r" ] && prot=RAW
- ip netns exec $NS ./cmsg_sender -$i -p $p -m $((MARK + 1)) $TGT 1234 - check_result $? 0 "$prot pass" + [ $ovr == "setsock" ] && m="-M" + [ $ovr == "cmsg" ] && m="-m" + [ $ovr == "both" ] && m="-M $MARK -m"
- ip netns exec $NS ./cmsg_sender -$i -p $p -m $MARK -s $TGT 1234 - check_result $? 1 "$prot rejection" + ip netns exec $NS ./cmsg_sender -$i -p $p $m $((MARK + 1)) $TGT 1234 + check_result $? 0 "$prot $ovr - pass" + + [ $ovr == "diff" ] && m="-M $((MARK + 1)) -m" + + ip netns exec $NS ./cmsg_sender -$i -p $p $m $MARK -s $TGT 1234 + check_result $? 1 "$prot $ovr - rejection" + done done done
Add ability to send delayed packets.
Signed-off-by: Jakub Kicinski kuba@kernel.org --- tools/testing/selftests/net/cmsg_sender.c | 49 +++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/net/cmsg_sender.c b/tools/testing/selftests/net/cmsg_sender.c index c7586a4b0361..5a722baa108b 100644 --- a/tools/testing/selftests/net/cmsg_sender.c +++ b/tools/testing/selftests/net/cmsg_sender.c @@ -6,9 +6,11 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <time.h> #include <unistd.h> #include <linux/icmp.h> #include <linux/icmpv6.h> +#include <linux/net_tstamp.h> #include <linux/types.h> #include <linux/udp.h> #include <sys/socket.h> @@ -23,6 +25,8 @@ enum { ERN_SOCK_CREATE, ERN_RESOLVE, ERN_CMSG_WR, + ERN_SOCKOPT, + ERN_GETTIME, };
struct options { @@ -41,6 +45,10 @@ struct options { bool ena; unsigned int val; } mark; + struct { + bool ena; + unsigned int delay; + } txtime; } opt = { .sock = { .family = AF_UNSPEC, @@ -49,6 +57,8 @@ struct options { }, };
+static struct timespec time_start_mono; + static void __attribute__((noreturn)) cs_usage(const char *bin) { printf("Usage: %s [opts] <dst host> <dst port / service>\n", bin); @@ -60,6 +70,7 @@ static void __attribute__((noreturn)) cs_usage(const char *bin) "\n" "\t\t-m val Set SO_MARK with given value\n" "\t\t-M val Set SO_MARK via setsockopt\n" + "\t\t-d val Set SO_TXTIME with given delay (usec)\n" ""); exit(ERN_HELP); } @@ -68,7 +79,7 @@ static void cs_parse_args(int argc, char *argv[]) { char o;
- while ((o = getopt(argc, argv, "46sp:m:M:")) != -1) { + while ((o = getopt(argc, argv, "46sp:m:M:d:")) != -1) { switch (o) { case 's': opt.silent_send = true; @@ -91,6 +102,7 @@ static void cs_parse_args(int argc, char *argv[]) cs_usage(argv[0]); } break; + case 'm': opt.mark.ena = true; opt.mark.val = atoi(optarg); @@ -98,6 +110,10 @@ static void cs_parse_args(int argc, char *argv[]) case 'M': opt.sockopt.mark = atoi(optarg); break; + case 'd': + opt.txtime.ena = true; + opt.txtime.delay = atoi(optarg); + break; } }
@@ -109,7 +125,7 @@ static void cs_parse_args(int argc, char *argv[]) }
static void -cs_write_cmsg(struct msghdr *msg, char *cbuf, size_t cbuf_sz) +cs_write_cmsg(int fd, struct msghdr *msg, char *cbuf, size_t cbuf_sz) { struct cmsghdr *cmsg; size_t cmsg_len; @@ -128,6 +144,30 @@ cs_write_cmsg(struct msghdr *msg, char *cbuf, size_t cbuf_sz) cmsg->cmsg_len = CMSG_LEN(sizeof(__u32)); *(__u32 *)CMSG_DATA(cmsg) = opt.mark.val; } + if (opt.txtime.ena) { + struct sock_txtime so_txtime = { + .clockid = CLOCK_MONOTONIC, + }; + __u64 txtime; + + if (setsockopt(fd, SOL_SOCKET, SO_TXTIME, + &so_txtime, sizeof(so_txtime))) + error(ERN_SOCKOPT, errno, "setsockopt TXTIME"); + + txtime = time_start_mono.tv_sec * (1000ULL * 1000 * 1000) + + time_start_mono.tv_nsec + + opt.txtime.delay * 1000; + + cmsg = (struct cmsghdr *)(cbuf + cmsg_len); + cmsg_len += CMSG_SPACE(sizeof(txtime)); + if (cbuf_sz < cmsg_len) + error(ERN_CMSG_WR, EFAULT, "cmsg buffer too small"); + + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_TXTIME; + cmsg->cmsg_len = CMSG_LEN(sizeof(txtime)); + memcpy(CMSG_DATA(cmsg), &txtime, sizeof(txtime)); + }
if (cmsg_len) msg->msg_controllen = cmsg_len; @@ -187,6 +227,9 @@ int main(int argc, char *argv[]) &opt.sockopt.mark, sizeof(opt.sockopt.mark))) error(ERN_SOCKOPT, errno, "setsockopt SO_MARK");
+ if (clock_gettime(CLOCK_MONOTONIC, &time_start_mono)) + error(ERN_GETTIME, errno, "gettime MONOTINIC"); + iov[0].iov_base = buf; iov[0].iov_len = sizeof(buf);
@@ -196,7 +239,7 @@ int main(int argc, char *argv[]) msg.msg_iov = iov; msg.msg_iovlen = 1;
- cs_write_cmsg(&msg, cbuf, sizeof(cbuf)); + cs_write_cmsg(fd, &msg, cbuf, sizeof(cbuf));
err = sendmsg(fd, &msg, 0); if (err < 0) {
Support requesting Tx timestamps:
$ ./cmsg_sender -p i -t -4 $tgt 123 -d 1000 SCHED ts0 61us SND ts0 1071us
Signed-off-by: Jakub Kicinski kuba@kernel.org --- tools/testing/selftests/net/cmsg_sender.c | 123 +++++++++++++++++++++- 1 file changed, 122 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/net/cmsg_sender.c b/tools/testing/selftests/net/cmsg_sender.c index 5a722baa108b..24444dc72543 100644 --- a/tools/testing/selftests/net/cmsg_sender.c +++ b/tools/testing/selftests/net/cmsg_sender.c @@ -8,6 +8,7 @@ #include <string.h> #include <time.h> #include <unistd.h> +#include <linux/errqueue.h> #include <linux/icmp.h> #include <linux/icmpv6.h> #include <linux/net_tstamp.h> @@ -27,6 +28,9 @@ enum { ERN_CMSG_WR, ERN_SOCKOPT, ERN_GETTIME, + ERN_RECVERR, + ERN_CMSG_RD, + ERN_CMSG_RCV, };
struct options { @@ -49,6 +53,9 @@ struct options { bool ena; unsigned int delay; } txtime; + struct { + bool ena; + } ts; } opt = { .sock = { .family = AF_UNSPEC, @@ -57,6 +64,7 @@ struct options { }, };
+static struct timespec time_start_real; static struct timespec time_start_mono;
static void __attribute__((noreturn)) cs_usage(const char *bin) @@ -71,6 +79,7 @@ static void __attribute__((noreturn)) cs_usage(const char *bin) "\t\t-m val Set SO_MARK with given value\n" "\t\t-M val Set SO_MARK via setsockopt\n" "\t\t-d val Set SO_TXTIME with given delay (usec)\n" + "\t\t-t Enable time stamp reporting\n" ""); exit(ERN_HELP); } @@ -79,7 +88,7 @@ static void cs_parse_args(int argc, char *argv[]) { char o;
- while ((o = getopt(argc, argv, "46sp:m:M:d:")) != -1) { + while ((o = getopt(argc, argv, "46sp:m:M:d:t")) != -1) { switch (o) { case 's': opt.silent_send = true; @@ -114,6 +123,9 @@ static void cs_parse_args(int argc, char *argv[]) opt.txtime.ena = true; opt.txtime.delay = atoi(optarg); break; + case 't': + opt.ts.ena = true; + break; } }
@@ -168,6 +180,25 @@ cs_write_cmsg(int fd, struct msghdr *msg, char *cbuf, size_t cbuf_sz) cmsg->cmsg_len = CMSG_LEN(sizeof(txtime)); memcpy(CMSG_DATA(cmsg), &txtime, sizeof(txtime)); } + if (opt.ts.ena) { + __u32 val = SOF_TIMESTAMPING_SOFTWARE | + SOF_TIMESTAMPING_OPT_TSONLY; + + if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, + &val, sizeof(val))) + error(ERN_SOCKOPT, errno, "setsockopt TIMESTAMPING"); + + cmsg = (struct cmsghdr *)(cbuf + cmsg_len); + cmsg_len += CMSG_SPACE(sizeof(__u32)); + if (cbuf_sz < cmsg_len) + error(ERN_CMSG_WR, EFAULT, "cmsg buffer too small"); + + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SO_TIMESTAMPING; + cmsg->cmsg_len = CMSG_LEN(sizeof(__u32)); + *(__u32 *)CMSG_DATA(cmsg) = SOF_TIMESTAMPING_TX_SCHED | + SOF_TIMESTAMPING_TX_SOFTWARE; + }
if (cmsg_len) msg->msg_controllen = cmsg_len; @@ -175,6 +206,86 @@ cs_write_cmsg(int fd, struct msghdr *msg, char *cbuf, size_t cbuf_sz) msg->msg_control = NULL; }
+static const char *cs_ts_info2str(unsigned int info) +{ + static const char *names[] = { + [SCM_TSTAMP_SND] = "SND", + [SCM_TSTAMP_SCHED] = "SCHED", + [SCM_TSTAMP_ACK] = "ACK", + }; + + if (info < sizeof(names) / sizeof(names[0])) + return names[info]; + return "unknown"; +} + +static void +cs_read_cmsg(int fd, struct msghdr *msg, char *cbuf, size_t cbuf_sz) +{ + struct sock_extended_err *see; + struct scm_timestamping *ts; + struct cmsghdr *cmsg; + int i, err; + + if (!opt.ts.ena) + return; + msg->msg_control = cbuf; + msg->msg_controllen = cbuf_sz; + + while (true) { + ts = NULL; + see = NULL; + memset(cbuf, 0, cbuf_sz); + + err = recvmsg(fd, msg, MSG_ERRQUEUE); + if (err < 0) { + if (errno == EAGAIN) + break; + error(ERN_RECVERR, errno, "recvmsg ERRQ"); + } + + for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; + cmsg = CMSG_NXTHDR(msg, cmsg)) { + if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SO_TIMESTAMPING_OLD) { + if (cmsg->cmsg_len < sizeof(*ts)) + error(ERN_CMSG_RD, EINVAL, "TS cmsg"); + + ts = (void *)CMSG_DATA(cmsg); + } + if ((cmsg->cmsg_level == SOL_IP && + cmsg->cmsg_type == IP_RECVERR) || + (cmsg->cmsg_level == SOL_IPV6 && + cmsg->cmsg_type == IPV6_RECVERR)) { + if (cmsg->cmsg_len < sizeof(*see)) + error(ERN_CMSG_RD, EINVAL, "sock_err cmsg"); + + see = (void *)CMSG_DATA(cmsg); + } + } + + if (!ts) + error(ERN_CMSG_RCV, ENOENT, "TS cmsg not found"); + if (!see) + error(ERN_CMSG_RCV, ENOENT, "sock_err cmsg not found"); + + for (i = 0; i < 3; i++) { + unsigned long long rel_time; + + if (!ts->ts[i].tv_sec && !ts->ts[i].tv_nsec) + continue; + + rel_time = (ts->ts[i].tv_sec - time_start_real.tv_sec) * + (1000ULL * 1000) + + (ts->ts[i].tv_nsec - time_start_real.tv_nsec) / + 1000; + printf(" %5s ts%d %lluus\n", + cs_ts_info2str(see->ee_info), + i, rel_time); + } + } +} + int main(int argc, char *argv[]) { char buf[] = "blablablabla"; @@ -227,6 +338,8 @@ int main(int argc, char *argv[]) &opt.sockopt.mark, sizeof(opt.sockopt.mark))) error(ERN_SOCKOPT, errno, "setsockopt SO_MARK");
+ if (clock_gettime(CLOCK_REALTIME, &time_start_real)) + error(ERN_GETTIME, errno, "gettime REALTIME"); if (clock_gettime(CLOCK_MONOTONIC, &time_start_mono)) error(ERN_GETTIME, errno, "gettime MONOTINIC");
@@ -246,13 +359,21 @@ int main(int argc, char *argv[]) if (!opt.silent_send) fprintf(stderr, "send failed: %s\n", strerror(errno)); err = ERN_SEND; + goto err_out; } else if (err != sizeof(buf)) { fprintf(stderr, "short send\n"); err = ERN_SEND_SHORT; + goto err_out; } else { err = ERN_SUCCESS; }
+ /* Make sure all timestamps have time to loop back */ + usleep(opt.txtime.delay); + + cs_read_cmsg(fd, &msg, cbuf, sizeof(cbuf)); + +err_out: close(fd); freeaddrinfo(ai); return err;
Test TIMESTAMPING and TXTIME across UDP / ICMP and IP versions.
Before ICMPv6 support: # ./tools/testing/selftests/net/cmsg_time.sh Case ICMPv6 - ts cnt returned '0', expected '2' Case ICMPv6 - ts0 SCHED returned '', expected 'OK' Case ICMPv6 - ts0 SND returned '', expected 'OK' Case ICMPv6 - TXTIME abs returned '', expected 'OK' Case ICMPv6 - TXTIME rel returned '', expected 'OK' FAIL - 5/36 cases failed
After: # ./tools/testing/selftests/net/cmsg_time.sh OK
Signed-off-by: Jakub Kicinski kuba@kernel.org --- tools/testing/selftests/net/Makefile | 1 + tools/testing/selftests/net/cmsg_time.sh | 83 ++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100755 tools/testing/selftests/net/cmsg_time.sh
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index 8f4c1f16655f..3bfeaf06b960 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -30,6 +30,7 @@ TEST_PROGS += ioam6.sh TEST_PROGS += gro.sh TEST_PROGS += gre_gso.sh TEST_PROGS += cmsg_so_mark.sh +TEST_PROGS += cmsg_time.sh TEST_PROGS += srv6_end_dt46_l3vpn_test.sh TEST_PROGS += srv6_end_dt4_l3vpn_test.sh TEST_PROGS += srv6_end_dt6_l3vpn_test.sh diff --git a/tools/testing/selftests/net/cmsg_time.sh b/tools/testing/selftests/net/cmsg_time.sh new file mode 100755 index 000000000000..91161e1da734 --- /dev/null +++ b/tools/testing/selftests/net/cmsg_time.sh @@ -0,0 +1,83 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +NS=ns +IP4=172.16.0.1/24 +TGT4=172.16.0.2 +IP6=2001:db8:1::1/64 +TGT6=2001:db8:1::2 + +cleanup() +{ + ip netns del $NS +} + +trap cleanup EXIT + +# Namespaces +ip netns add $NS + +ip netns exec $NS sysctl -w net.ipv4.ping_group_range='0 2147483647' > /dev/null + +# Connectivity +ip -netns $NS link add type dummy +ip -netns $NS link set dev dummy0 up +ip -netns $NS addr add $IP4 dev dummy0 +ip -netns $NS addr add $IP6 dev dummy0 + +# Need FQ for TXTIME +ip netns exec $NS tc qdisc replace dev dummy0 root fq + +# Test +BAD=0 +TOTAL=0 + +check_result() { + ((TOTAL++)) + if [ $1 -ne 0 ]; then + echo " Case $4 returned $1, expected 0" + ((BAD++)) + elif [ "$2" != "$3" ]; then + echo " Case $4 returned '$2', expected '$3'" + ((BAD++)) + fi +} + +for i in "-4 $TGT4" "-6 $TGT6"; do + for p in u i r; do + [ $p == "u" ] && prot=UDPv${i:1:2} + [ $p == "i" ] && prot=ICMPv${i:1:2} + [ $p == "r" ] && prot=RAWv${i:1:2} + + ts=$(ip netns exec $NS ./cmsg_sender -p $p $i 1234) + check_result $? "$ts" "" "$prot - no options" + + ts=$(ip netns exec $NS ./cmsg_sender -p $p $i 1234 -t | wc -l) + check_result $? "$ts" "2" "$prot - ts cnt" + ts=$(ip netns exec $NS ./cmsg_sender -p $p $i 1234 -t | + sed -n "s/.*SCHED ts0 [0-9].*/OK/p") + check_result $? "$ts" "OK" "$prot - ts0 SCHED" + ts=$(ip netns exec $NS ./cmsg_sender -p $p $i 1234 -t | + sed -n "s/.*SND ts0 [0-9].*/OK/p") + check_result $? "$ts" "OK" "$prot - ts0 SND" + + ts=$(ip netns exec $NS ./cmsg_sender -p $p $i 1234 -t -d 1000 | + awk '/SND/ { if ($3 > 1000) print "OK"; }') + check_result $? "$ts" "OK" "$prot - TXTIME abs" + + ts=$(ip netns exec $NS ./cmsg_sender -p $p $i 1234 -t -d 1000 | + awk '/SND/ {snd=$3} + /SCHED/ {sch=$3} + END { if (snd - sch > 500) print "OK"; }') + check_result $? "$ts" "OK" "$prot - TXTIME rel" + done +done + +# Summary +if [ $BAD -ne 0 ]; then + echo "FAIL - $BAD/$TOTAL cases failed" + exit 1 +else + echo "OK" + exit 0 +fi
Hello:
This series was applied to netdev/net-next.git (master) by David S. Miller davem@davemloft.net:
On Wed, 9 Feb 2022 16:36:38 -0800 you wrote:
Add support for common SOL_SOCKET cmsgs in ICMPv6 sockets. Extend the cmsg tests to cover more cmsgs and socket types.
SOL_IPV6 cmsgs to follow.
Jakub Kicinski (11): net: ping6: remove a pr_debug() statement net: ping6: support packet timestamping net: ping6: support setting socket options via cmsg selftests: net: rename cmsg_so_mark selftests: net: make cmsg_so_mark ready for more options selftests: net: cmsg_sender: support icmp and raw sockets selftests: net: cmsg_so_mark: test ICMP and RAW sockets selftests: net: cmsg_so_mark: test with SO_MARK set by setsockopt selftests: net: cmsg_sender: support setting SO_TXTIME selftests: net: cmsg_sender: support Tx timestamping selftests: net: test standard socket cmsgs across UDP and ICMP sockets
[...]
Here is the summary with links: - [net-next,01/11] net: ping6: remove a pr_debug() statement https://git.kernel.org/netdev/net-next/c/426522394649 - [net-next,02/11] net: ping6: support packet timestamping https://git.kernel.org/netdev/net-next/c/e7b060460f29 - [net-next,03/11] net: ping6: support setting socket options via cmsg https://git.kernel.org/netdev/net-next/c/3ebb0b1032e5 - [net-next,04/11] selftests: net: rename cmsg_so_mark https://git.kernel.org/netdev/net-next/c/a086ee24cce2 - [net-next,05/11] selftests: net: make cmsg_so_mark ready for more options https://git.kernel.org/netdev/net-next/c/49b786130296 - [net-next,06/11] selftests: net: cmsg_sender: support icmp and raw sockets https://git.kernel.org/netdev/net-next/c/de17e305a810 - [net-next,07/11] selftests: net: cmsg_so_mark: test ICMP and RAW sockets https://git.kernel.org/netdev/net-next/c/0344488e11ca - [net-next,08/11] selftests: net: cmsg_so_mark: test with SO_MARK set by setsockopt https://git.kernel.org/netdev/net-next/c/9bbfbc92c64a - [net-next,09/11] selftests: net: cmsg_sender: support setting SO_TXTIME https://git.kernel.org/netdev/net-next/c/4d397424a5e0 - [net-next,10/11] selftests: net: cmsg_sender: support Tx timestamping https://git.kernel.org/netdev/net-next/c/eb8f3116fb3f - [net-next,11/11] selftests: net: test standard socket cmsgs across UDP and ICMP sockets https://git.kernel.org/netdev/net-next/c/af6ca20591ef
You are awesome, thank you!
On Wed, Feb 9, 2022 at 7:36 PM Jakub Kicinski kuba@kernel.org wrote:
Add support for common SOL_SOCKET cmsgs in ICMPv6 sockets. Extend the cmsg tests to cover more cmsgs and socket types.
SOL_IPV6 cmsgs to follow.
Jakub Kicinski (11): net: ping6: remove a pr_debug() statement net: ping6: support packet timestamping net: ping6: support setting socket options via cmsg selftests: net: rename cmsg_so_mark selftests: net: make cmsg_so_mark ready for more options selftests: net: cmsg_sender: support icmp and raw sockets selftests: net: cmsg_so_mark: test ICMP and RAW sockets selftests: net: cmsg_so_mark: test with SO_MARK set by setsockopt selftests: net: cmsg_sender: support setting SO_TXTIME selftests: net: cmsg_sender: support Tx timestamping selftests: net: test standard socket cmsgs across UDP and ICMP sockets
net/ipv6/ping.c | 14 +- tools/testing/selftests/net/.gitignore | 2 +- tools/testing/selftests/net/Makefile | 3 +- tools/testing/selftests/net/cmsg_sender.c | 380 ++++++++++++++++++++ tools/testing/selftests/net/cmsg_so_mark.c | 67 ---- tools/testing/selftests/net/cmsg_so_mark.sh | 32 +- tools/testing/selftests/net/cmsg_time.sh | 83 +++++ 7 files changed, 499 insertions(+), 82 deletions(-) create mode 100644 tools/testing/selftests/net/cmsg_sender.c delete mode 100644 tools/testing/selftests/net/cmsg_so_mark.c create mode 100755 tools/testing/selftests/net/cmsg_time.sh
Already merged, but since I was on the cc line: overall looks great to me too. Thanks Jakub.
linux-kselftest-mirror@lists.linaro.org