Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F143927247
D42525.id129891.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D42525.id129891.diff
View Options
diff --git a/tests/sys/netlink/Makefile b/tests/sys/netlink/Makefile
--- a/tests/sys/netlink/Makefile
+++ b/tests/sys/netlink/Makefile
@@ -4,7 +4,8 @@
TESTSDIR= ${TESTSBASE}/sys/netlink
-ATF_TESTS_C += test_snl test_snl_generic
+ATF_TESTS_C+= netlink_socket
+ATF_TESTS_C+= test_snl test_snl_generic
ATF_TESTS_PYTEST += test_nl_core.py
ATF_TESTS_PYTEST += test_rtnl_iface.py
ATF_TESTS_PYTEST += test_rtnl_ifaddr.py
diff --git a/tests/sys/netlink/netlink_socket.c b/tests/sys/netlink/netlink_socket.c
new file mode 100644
--- /dev/null
+++ b/tests/sys/netlink/netlink_socket.c
@@ -0,0 +1,161 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Gleb Smirnoff <glebius@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/module.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <netlink/netlink.h>
+#include <netlink/netlink_route.h>
+
+#include <atf-c.h>
+
+static struct itimerval itv = {
+ .it_interval = { 0, 0 },
+ .it_value = { 1, 0 }, /* one second */
+};
+static sig_atomic_t timer_done = 0;
+static void
+sigalarm(int sig __unused)
+{
+
+ timer_done = 1;
+}
+
+static struct sigaction sigact = {
+ .sa_handler = sigalarm,
+};
+
+ATF_TC_WITHOUT_HEAD(overflow);
+ATF_TC_BODY(overflow, tc)
+{
+#define BUFLEN 1000
+ struct nlmsghdr hdr;
+ int fd, sendspace, recvspace, sendavail, recvavail, rsize;
+ u_int cnt = 0;
+ socklen_t slen = sizeof(int);
+ char buf[BUFLEN];
+
+ ATF_REQUIRE((fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) != -1);
+ ATF_REQUIRE(getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sendspace,
+ &slen) == 0);
+ ATF_REQUIRE(getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &recvspace,
+ &slen) == 0);
+
+ hdr = (struct nlmsghdr) {
+ .nlmsg_type = RTM_GETLINK,
+ .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,
+ .nlmsg_len = sizeof(struct nlmsghdr),
+ };
+
+ /* Check the expected size of reply on a single RTM_GETLINK. */
+ ATF_REQUIRE(send(fd, &hdr, sizeof(hdr), 0) == sizeof(hdr));
+ ATF_REQUIRE(recv(fd, buf, sizeof(hdr), MSG_WAITALL | MSG_PEEK) ==
+ sizeof(hdr));
+ ATF_REQUIRE(ioctl(fd, FIONREAD, &rsize) != -1);
+
+ /*
+ * Flood the socket with requests, without reading out the replies.
+ * While we are flooding, the kernel tries to process the requests.
+ * Kernel takes off requests from the send buffer and puts replies
+ * on receive buffer. Once the receive buffer is full it stops working
+ * on queue in the send buffer. At this point we must get a solid
+ * failure. However, if we flood faster than kernel taskqueue runs,
+ * we may get intermittent failures.
+ */
+ do {
+ ssize_t rv;
+
+ rv = send(fd, &hdr, sizeof(hdr), MSG_DONTWAIT);
+ if (__predict_true(rv == sizeof(hdr)))
+ cnt++;
+ else {
+ ATF_REQUIRE(errno == EAGAIN);
+ ATF_REQUIRE(sizeof(hdr) * cnt > sendspace);
+ }
+ ATF_REQUIRE(ioctl(fd, FIONREAD, &recvavail) != -1);
+ ATF_REQUIRE(ioctl(fd, FIONWRITE, &sendavail) != -1);
+ } while (recvavail <= recvspace - rsize ||
+ sendavail <= sendspace - sizeof(hdr));
+ /* Both buffers full: block. */
+ timer_done = 0;
+ ATF_REQUIRE(sigaction(SIGALRM, &sigact, NULL) == 0);
+ ATF_REQUIRE(setitimer(ITIMER_REAL, &itv, NULL) == 0);
+ ATF_REQUIRE(send(fd, &hdr, sizeof(hdr), 0) == -1);
+ ATF_REQUIRE(errno == EINTR);
+ ATF_REQUIRE(timer_done == 1);
+
+ /*
+ * Now, reading something from the receive buffer should wake up the
+ * taskqueue and send buffer should start getting drained.
+ */
+ ATF_REQUIRE(recv(fd, buf, BUFLEN, 0) > sizeof(hdr));
+ timer_done = 0;
+ ATF_REQUIRE(setitimer(ITIMER_REAL, &itv, NULL) == 0);
+ ATF_REQUIRE(send(fd, &hdr, sizeof(hdr), 0) == sizeof(hdr));
+ ATF_REQUIRE(timer_done == 0);
+}
+
+ATF_TC_WITHOUT_HEAD(peek);
+ATF_TC_BODY(peek, tc)
+{
+#define BUFLEN 1000
+ struct nlmsghdr hdr;
+ char buf[BUFLEN];
+ ssize_t ss;
+ int fd;
+
+ ATF_REQUIRE((fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) != -1);
+
+ hdr = (struct nlmsghdr) {
+ .nlmsg_type = RTM_GETLINK,
+ .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,
+ .nlmsg_len = sizeof(struct nlmsghdr),
+ };
+
+ ATF_REQUIRE(send(fd, &hdr, sizeof(hdr), 0) == sizeof(hdr));
+ ss = -recv(fd, buf, 0, MSG_WAITALL | MSG_PEEK | MSG_TRUNC);
+ ATF_REQUIRE(recv(fd, buf, ss, MSG_WAITALL) == ss);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ if (modfind("netlink") == -1)
+ atf_tc_skip("netlink module not loaded");
+
+ ATF_TP_ADD_TC(tp, overflow);
+ ATF_TP_ADD_TC(tp, peek);
+
+ return (atf_no_error());
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Feb 3, 2:36 AM (17 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28420373
Default Alt Text
D42525.id129891.diff (5 KB)
Attached To
Mode
D42525: tests/netlink: add netlink socket buffer test
Attached
Detach File
Event Timeline
Log In to Comment