[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <a4468403cc51ea6c0e8495d7d095befb37aa5aaf.1745323279.git.fmaurer@redhat.com>
Date: Tue, 22 Apr 2025 14:02:34 +0200
From: Felix Maurer <fmaurer@...hat.com>
To: socketcan@...tkopp.net,
mkl@...gutronix.de
Cc: shuah@...nel.org,
davem@...emloft.net,
edumazet@...gle.com,
kuba@...nel.org,
pabeni@...hat.com,
horms@...nel.org,
linux-can@...r.kernel.org,
netdev@...r.kernel.org,
linux-kselftest@...r.kernel.org,
dcaratti@...hat.com,
fstornio@...hat.com
Subject: [PATCH 1/4] selftests: can: Import tst-filter from can-tests
Tests for the can subsytem have been in the can-tests repository[1] so far.
Start moving the tests to kernel selftests by importing the current
tst-filter test. Subsequent patches will update the test to be more aligned
with the kernel selftests and follow the coding style.
The imported test verifies that the single filters on raw CAN sockets work
as expected.
[1]: https://github.com/linux-can/can-tests
Signed-off-by: Felix Maurer <fmaurer@...hat.com>
---
Notes:
I have removed the long form of the licenses in the beginning of the
file during the import, as that is covered by the SPDX line anyways. The
copyright is left as it was originally.
MAINTAINERS | 2 +
tools/testing/selftests/Makefile | 1 +
tools/testing/selftests/net/can/.gitignore | 2 +
tools/testing/selftests/net/can/Makefile | 9 +
.../selftests/net/can/test_raw_filter.c | 204 ++++++++++++++++++
.../selftests/net/can/test_raw_filter.sh | 37 ++++
6 files changed, 255 insertions(+)
create mode 100644 tools/testing/selftests/net/can/.gitignore
create mode 100644 tools/testing/selftests/net/can/Makefile
create mode 100644 tools/testing/selftests/net/can/test_raw_filter.c
create mode 100755 tools/testing/selftests/net/can/test_raw_filter.sh
diff --git a/MAINTAINERS b/MAINTAINERS
index 241ca9e260a2..55749b492ebb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5155,6 +5155,7 @@ F: include/uapi/linux/can/isotp.h
F: include/uapi/linux/can/raw.h
F: net/can/
F: net/sched/em_canid.c
+F: tools/testing/selftests/net/can/
CAN-J1939 NETWORK LAYER
M: Robin van der Gracht <robin@...tonic.nl>
@@ -16577,6 +16578,7 @@ X: net/ceph/
X: net/mac80211/
X: net/rfkill/
X: net/wireless/
+X: tools/testing/selftests/net/can/
NETWORKING [IPSEC]
M: Steffen Klassert <steffen.klassert@...unet.com>
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 8daac70c2f9d..e5c9ecd52b73 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -64,6 +64,7 @@ TARGETS += mqueue
TARGETS += nci
TARGETS += net
TARGETS += net/af_unix
+TARGETS += net/can
TARGETS += net/forwarding
TARGETS += net/hsr
TARGETS += net/mptcp
diff --git a/tools/testing/selftests/net/can/.gitignore b/tools/testing/selftests/net/can/.gitignore
new file mode 100644
index 000000000000..764a53fc837f
--- /dev/null
+++ b/tools/testing/selftests/net/can/.gitignore
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+test_raw_filter
diff --git a/tools/testing/selftests/net/can/Makefile b/tools/testing/selftests/net/can/Makefile
new file mode 100644
index 000000000000..44ef37f064ad
--- /dev/null
+++ b/tools/testing/selftests/net/can/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0
+
+top_srcdir = ../../../../..
+
+TEST_PROGS := test_raw_filter.sh
+
+TEST_GEN_FILES := test_raw_filter
+
+include ../../lib.mk
diff --git a/tools/testing/selftests/net/can/test_raw_filter.c b/tools/testing/selftests/net/can/test_raw_filter.c
new file mode 100644
index 000000000000..c84260f36565
--- /dev/null
+++ b/tools/testing/selftests/net/can/test_raw_filter.c
@@ -0,0 +1,204 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/*
+ * Copyright (c) 2011 Volkswagen Group Electronic Research
+ * All rights reserved.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <net/if.h>
+
+#include <linux/can.h>
+#include <linux/can/raw.h>
+
+#define ID 0x123
+#define TC 18 /* # of testcases */
+
+const int rx_res[TC] = {4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1};
+const int rxbits_res[TC] = {4369, 4369, 4369, 4369, 17, 4352, 17, 4352, 257, 257, 4112, 4112, 1, 256, 16, 4096, 1, 256};
+
+#define VCANIF "vcan0"
+
+canid_t calc_id(int testcase)
+{
+ canid_t id = ID;
+
+ if (testcase & 1)
+ id |= CAN_EFF_FLAG;
+ if (testcase & 2)
+ id |= CAN_RTR_FLAG;
+
+ return id;
+}
+
+canid_t calc_mask(int testcase)
+{
+ canid_t mask = CAN_SFF_MASK;
+
+ if (testcase > 15)
+ return (CAN_EFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG);
+
+ if (testcase & 4)
+ mask |= CAN_EFF_FLAG;
+ if (testcase & 8)
+ mask |= CAN_RTR_FLAG;
+
+ return mask;
+}
+
+int main(int argc, char **argv)
+{
+ fd_set rdfs;
+ struct timeval tv;
+ int s;
+ struct sockaddr_can addr;
+ struct can_filter rfilter;
+ struct can_frame frame;
+ int testcase;
+ int have_rx;
+ int rx;
+ int rxbits, rxbitval;
+ int ret;
+ int recv_own_msgs = 1;
+ int err = 0;
+ struct ifreq ifr;
+
+ if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
+ perror("socket");
+ err = 1;
+ goto out;
+ }
+
+ strcpy(ifr.ifr_name, VCANIF);
+ if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
+ perror("SIOCGIFINDEX");
+ err = 1;
+ goto out_socket;
+ }
+ addr.can_family = AF_CAN;
+ addr.can_ifindex = ifr.ifr_ifindex;
+
+ setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+ &recv_own_msgs, sizeof(recv_own_msgs));
+
+ if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ perror("bind");
+ err = 1;
+ goto out_socket;
+ }
+
+ printf("---\n");
+
+ for (testcase = 0; testcase < TC; testcase++) {
+
+ rfilter.can_id = calc_id(testcase);
+ rfilter.can_mask = calc_mask(testcase);
+ setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER,
+ &rfilter, sizeof(rfilter));
+
+ printf("testcase %2d filters : can_id = 0x%08X can_mask = 0x%08X\n",
+ testcase, rfilter.can_id, rfilter.can_mask);
+
+ printf("testcase %2d sending patterns ... ", testcase);
+
+ frame.can_dlc = 1;
+ frame.data[0] = testcase;
+
+ frame.can_id = ID;
+ if (write(s, &frame, sizeof(frame)) < 0) {
+ perror("write");
+ exit(1);
+ }
+ frame.can_id = (ID | CAN_RTR_FLAG);
+ if (write(s, &frame, sizeof(frame)) < 0) {
+ perror("write");
+ exit(1);
+ }
+ frame.can_id = (ID | CAN_EFF_FLAG);
+ if (write(s, &frame, sizeof(frame)) < 0) {
+ perror("write");
+ exit(1);
+ }
+ frame.can_id = (ID | CAN_EFF_FLAG | CAN_RTR_FLAG);
+ if (write(s, &frame, sizeof(frame)) < 0) {
+ perror("write");
+ exit(1);
+ }
+
+ printf("ok\n");
+
+ have_rx = 1;
+ rx = 0;
+ rxbits = 0;
+
+ while (have_rx) {
+
+ have_rx = 0;
+ FD_ZERO(&rdfs);
+ FD_SET(s, &rdfs);
+ tv.tv_sec = 0;
+ tv.tv_usec = 50000; /* 50ms timeout */
+
+ ret = select(s+1, &rdfs, NULL, NULL, &tv);
+ if (ret < 0) {
+ perror("select");
+ exit(1);
+ }
+
+ if (FD_ISSET(s, &rdfs)) {
+ have_rx = 1;
+ ret = read(s, &frame, sizeof(struct can_frame));
+ if (ret < 0) {
+ perror("read");
+ exit(1);
+ }
+ if ((frame.can_id & CAN_SFF_MASK) != ID) {
+ fprintf(stderr, "received wrong can_id!\n");
+ exit(1);
+ }
+ if (frame.data[0] != testcase) {
+ fprintf(stderr, "received wrong testcase!\n");
+ exit(1);
+ }
+
+ /* test & calc rxbits */
+ rxbitval = 1 << ((frame.can_id & (CAN_EFF_FLAG|CAN_RTR_FLAG|CAN_ERR_FLAG)) >> 28);
+
+ /* only receive a rxbitval once */
+ if ((rxbits & rxbitval) == rxbitval) {
+ fprintf(stderr, "received rxbitval %d twice!\n", rxbitval);
+ exit(1);
+ }
+ rxbits |= rxbitval;
+ rx++;
+
+ printf("testcase %2d rx : can_id = 0x%08X rx = %d rxbits = %d\n",
+ testcase, frame.can_id, rx, rxbits);
+ }
+ }
+ /* rx timed out -> check the received results */
+ if (rx_res[testcase] != rx) {
+ fprintf(stderr, "wrong rx value in testcase %d : %d (expected %d)\n",
+ testcase, rx, rx_res[testcase]);
+ exit(1);
+ }
+ if (rxbits_res[testcase] != rxbits) {
+ fprintf(stderr, "wrong rxbits value in testcase %d : %d (expected %d)\n",
+ testcase, rxbits, rxbits_res[testcase]);
+ exit(1);
+ }
+ printf("testcase %2d ok\n---\n", testcase);
+ }
+
+out_socket:
+ close(s);
+out:
+ return err;
+}
diff --git a/tools/testing/selftests/net/can/test_raw_filter.sh b/tools/testing/selftests/net/can/test_raw_filter.sh
new file mode 100755
index 000000000000..e5f175c8b27b
--- /dev/null
+++ b/tools/testing/selftests/net/can/test_raw_filter.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+#set -x
+
+ALL_TESTS="
+ test_raw_filter
+"
+
+net_dir=$(dirname $0)/..
+source $net_dir/lib.sh
+
+VCANIF="vcan0"
+
+setup()
+{
+ ip link add name $VCANIF type vcan || exit $ksft_skip
+ ip link set dev $VCANIF up
+ pwd
+}
+
+cleanup()
+{
+ ip link delete $VCANIF
+}
+
+test_raw_filter()
+{
+ ./test_raw_filter
+}
+
+trap cleanup EXIT
+setup
+
+tests_run
+
+exit $EXIT_STATUS
--
2.49.0
Powered by blists - more mailing lists