[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251121002044.16071-9-antonio@openvpn.net>
Date: Fri, 21 Nov 2025 01:20:39 +0100
From: Antonio Quartulli <antonio@...nvpn.net>
To: netdev@...r.kernel.org
Cc: Ralf Lici <ralf@...delbit.com>,
Sabrina Dubroca <sd@...asysnail.net>,
Jakub Kicinski <kuba@...nel.org>,
linux-kselftest@...r.kernel.org,
Shuah Khan <shuah@...nel.org>,
Antonio Quartulli <antonio@...nvpn.net>
Subject: [RFC net-next 08/13] selftests: ovpn: add test for the FW mark feature
From: Ralf Lici <ralf@...delbit.com>
Add a selftest to verify that the FW mark socket option is correctly
supported and its value propagated by ovpn.
The test adds and removes nftables DROP rules based on the mark value,
and checks that the rule counter aligns with the number of lost ping
packets.
Cc: Shuah Khan <shuah@...nel.org>
Signed-off-by: Ralf Lici <ralf@...delbit.com>
Signed-off-by: Antonio Quartulli <antonio@...nvpn.net>
---
tools/testing/selftests/net/ovpn/Makefile | 1 +
tools/testing/selftests/net/ovpn/ovpn-cli.c | 26 +++++-
tools/testing/selftests/net/ovpn/test-mark.sh | 81 +++++++++++++++++++
3 files changed, 106 insertions(+), 2 deletions(-)
create mode 100755 tools/testing/selftests/net/ovpn/test-mark.sh
diff --git a/tools/testing/selftests/net/ovpn/Makefile b/tools/testing/selftests/net/ovpn/Makefile
index d3a070db0bb5..7c87c95d957e 100644
--- a/tools/testing/selftests/net/ovpn/Makefile
+++ b/tools/testing/selftests/net/ovpn/Makefile
@@ -31,6 +31,7 @@ TEST_PROGS := \
test-close-socket.sh \
test-float.sh \
test-large-mtu.sh \
+ test-mark.sh \
test-tcp.sh \
test.sh \
# end of TEST_PROGS
diff --git a/tools/testing/selftests/net/ovpn/ovpn-cli.c b/tools/testing/selftests/net/ovpn/ovpn-cli.c
index baabb4c9120e..4df596d29b8c 100644
--- a/tools/testing/selftests/net/ovpn/ovpn-cli.c
+++ b/tools/testing/selftests/net/ovpn/ovpn-cli.c
@@ -6,6 +6,7 @@
* Author: Antonio Quartulli <antonio@...nvpn.net>
*/
+#include <stdint.h>
#include <stdio.h>
#include <inttypes.h>
#include <stdbool.h>
@@ -133,6 +134,8 @@ struct ovpn_ctx {
enum ovpn_key_slot key_slot;
int key_id;
+ uint32_t mark;
+
const char *peers_file;
};
@@ -521,6 +524,15 @@ static int ovpn_socket(struct ovpn_ctx *ctx, sa_family_t family, int proto)
return ret;
}
+ if (ctx->mark != 0) {
+ ret = setsockopt(s, SOL_SOCKET, SO_MARK, (void *)&ctx->mark,
+ sizeof(ctx->mark));
+ if (ret < 0) {
+ perror("setsockopt for SO_MARK");
+ return ret;
+ }
+ }
+
if (family == AF_INET6) {
opt = 0;
if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &opt,
@@ -1693,12 +1705,13 @@ static void usage(const char *cmd)
fprintf(stderr, "\tvpnaddr: peer VPN IP\n");
fprintf(stderr,
- "* new_multi_peer <iface> <lport> <peers_file>: add multiple peers as listed in the file\n");
+ "* new_multi_peer <iface> <lport> <peers_file> [mark]: add multiple peers as listed in the file\n");
fprintf(stderr, "\tiface: ovpn interface name\n");
fprintf(stderr, "\tlport: local UDP port to bind to\n");
fprintf(stderr,
"\tpeers_file: text file containing one peer per line. Line format:\n");
- fprintf(stderr, "\t\t<peer_id> <tx_id> <raddr> <rport> <laddr> <lport> <vpnaddr>\n");
+ fprintf(stderr, "\t\t<peer_id> <tx_id> <raddr> <rport> <laddr> <lport> <vpnaddr> [mark]\n");
+ fprintf(stderr, "\tmark: socket FW mark value\n");
fprintf(stderr,
"* set_peer <iface> <peer_id> <keepalive_interval> <keepalive_timeout>: set peer attributes\n");
@@ -2241,6 +2254,15 @@ static int ovpn_parse_cmd_args(struct ovpn_ctx *ovpn, int argc, char *argv[])
}
ovpn->peers_file = argv[4];
+
+ ovpn->mark = 0;
+ if (argc > 5) {
+ ovpn->mark = strtoul(argv[5], NULL, 10);
+ if (errno == ERANGE || ovpn->mark > UINT32_MAX) {
+ fprintf(stderr, "mark value out of range\n");
+ return -1;
+ }
+ }
break;
case CMD_SET_PEER:
if (argc < 6)
diff --git a/tools/testing/selftests/net/ovpn/test-mark.sh b/tools/testing/selftests/net/ovpn/test-mark.sh
new file mode 100755
index 000000000000..a4bfe938118d
--- /dev/null
+++ b/tools/testing/selftests/net/ovpn/test-mark.sh
@@ -0,0 +1,81 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (C) 2020-2025 OpenVPN, Inc.
+#
+# Author: Ralf Lici <ralf@...delbit.com>
+# Antonio Quartulli <antonio@...nvpn.net>
+
+#set -x
+set -e
+
+PROTO=UDP
+MARK=1056
+
+source ./common.sh
+
+cleanup
+
+modprobe -q ovpn || true
+
+for p in $(seq 0 ${NUM_PEERS}); do
+ create_ns ${p}
+done
+
+for p in $(seq 0 3); do
+ setup_ns ${p} 5.5.5.$((${p} + 1))/24
+done
+
+# add peer0 with mark
+ip netns exec peer0 ${OVPN_CLI} new_multi_peer tun0 1 ${UDP_PEERS_FILE} ${MARK}
+for p in $(seq 1 3); do
+ ip netns exec peer0 ${OVPN_CLI} new_key tun0 ${p} 1 0 ${ALG} 0 data64.key
+done
+
+for p in $(seq 1 3); do
+ add_peer ${p}
+done
+
+for p in $(seq 1 3); do
+ ip netns exec peer0 ${OVPN_CLI} set_peer tun0 ${p} 60 120
+ ip netns exec peer${p} ${OVPN_CLI} set_peer tun${p} $((${p} + 9)) 60 120
+done
+
+sleep 1
+
+for p in $(seq 1 3); do
+ ip netns exec peer0 ping -qfc 500 -s 3000 -w 3 5.5.5.$((${p} + 1))
+done
+
+echo "Adding an nftables drop rule based on mark value ${MARK}"
+ip netns exec peer0 nft flush ruleset
+ip netns exec peer0 nft 'add table inet filter'
+ip netns exec peer0 nft 'add chain inet filter output { type filter hook output priority 0; policy accept; }'
+ip netns exec peer0 nft add rule inet filter output meta mark == ${MARK} counter drop
+
+DROP_COUNTER=$(ip netns exec peer0 nft list chain inet filter output | sed -n 's/.*packets \([0-9]*\).*/\1/p')
+sleep 1
+
+# ping should fail
+for p in $(seq 1 3); do
+ PING_OUTPUT=$(ip netns exec peer0 ping -qfc 500 -w 1 5.5.5.$((p+1)) 2>&1) && exit 1
+ echo "${PING_OUTPUT}"
+ LOST_PACKETS=$(echo "$PING_OUTPUT" | grep 'packets transmitted' | awk '{ print $1 }')
+ # increment the drop counter by the amount of lost packets
+ DROP_COUNTER=$(($DROP_COUNTER+$LOST_PACKETS))
+done
+
+# check if the final nft counter matches our counter
+TOTAL_COUNT=$(ip netns exec peer0 nft list chain inet filter output | sed -n 's/.*packets \([0-9]*\).*/\1/p')
+[ ${DROP_COUNTER} -eq ${TOTAL_COUNT} ] || exit 1
+
+echo "Removing the drop rule"
+ip netns exec peer0 nft flush ruleset
+sleep 1
+
+for p in $(seq 1 3); do
+ ip netns exec peer0 ping -qfc 500 -s 3000 -w 3 5.5.5.$((${p} + 1))
+done
+
+cleanup
+
+modprobe -r ovpn || true
--
2.51.2
Powered by blists - more mailing lists