From: Antonio Quartulli <antonio@openvpn.net>
To: netdev@vger.kernel.org
Cc: Ralf Lici <ralf@mandelbit.com>,
Sabrina Dubroca <sd@queasysnail.net>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Andrew Lunn <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>, Shuah Khan <shuah@kernel.org>,
Antonio Quartulli <antonio@openvpn.net>
Subject: [PATCH net-next 8/9] selftests: ovpn: add test for the FW mark feature
Date: Sat, 28 Feb 2026 00:59:54 +0100 [thread overview]
Message-ID: <20260227235955.660-9-antonio@openvpn.net> (raw)
In-Reply-To: <20260227235955.660-1-antonio@openvpn.net>
From: Ralf Lici <ralf@mandelbit.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@kernel.org>
Signed-off-by: Ralf Lici <ralf@mandelbit.com>
Signed-off-by: Antonio Quartulli <antonio@openvpn.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 | 84 +++++++++++++++++++
3 files changed, 109 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 8c684f61220b..01bdcc0a8049 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@openvpn.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..9fb02f611794
--- /dev/null
+++ b/tools/testing/selftests/net/ovpn/test-mark.sh
@@ -0,0 +1,84 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (C) 2020-2025 OpenVPN, Inc.
+#
+# Author: Ralf Lici <ralf@mandelbit.com>
+# Antonio Quartulli <antonio@openvpn.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.52.0
next prev parent reply other threads:[~2026-02-28 0:00 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-27 23:59 [PATCH net-next 0/9] pull request: ovpn 2026-02-28 Antonio Quartulli
2026-02-27 23:59 ` [PATCH net-next 1/9] selftests: ovpn: allow compiling ovpn-cli.c with mbedtls3 Antonio Quartulli
2026-02-27 23:59 ` [PATCH net-next 2/9] ovpn: use correct array size to parse nested attributes in ovpn_nl_key_swap_doit Antonio Quartulli
2026-02-27 23:59 ` [PATCH net-next 3/9] ovpn: pktid: use bitops.h API Antonio Quartulli
2026-02-27 23:59 ` [PATCH net-next 4/9] ovpn: notify userspace on client float event Antonio Quartulli
2026-02-27 23:59 ` [PATCH net-next 5/9] selftests: ovpn: add notification parsing and matching Antonio Quartulli
2026-02-27 23:59 ` [PATCH net-next 6/9] ovpn: add support for asymmetric peer IDs Antonio Quartulli
2026-02-27 23:59 ` [PATCH net-next 7/9] selftests: ovpn: check asymmetric peer-id Antonio Quartulli
2026-02-27 23:59 ` Antonio Quartulli [this message]
2026-02-27 23:59 ` [PATCH net-next 9/9] ovpn: consolidate crypto allocations in one chunk Antonio Quartulli
2026-02-28 20:49 ` [PATCH net-next 0/9] pull request: ovpn 2026-02-28 Antonio Quartulli
2026-03-01 1:01 ` Jakub Kicinski
2026-03-03 21:02 ` Antonio Quartulli
2026-03-03 21:39 ` Jakub Kicinski
-- strict thread matches above, loose matches on Subject: below --
2026-03-04 23:06 [PATCH net-next 0/9] pull request: ovpn 2026-03-05 Antonio Quartulli
2026-03-04 23:06 ` [PATCH net-next 8/9] selftests: ovpn: add test for the FW mark feature Antonio Quartulli
2026-03-06 3:22 ` Jakub Kicinski
2026-03-10 14:49 [PATCH net-next 0/9] pull request: ovpn 2026-03-10 Antonio Quartulli
2026-03-10 14:50 ` [PATCH net-next 8/9] selftests: ovpn: add test for the FW mark feature Antonio Quartulli
2026-03-13 20:51 [PATCH net-next 0/9] pull request: ovpn 2026-03-13 Antonio Quartulli
2026-03-13 20:51 ` [PATCH net-next 8/9] selftests: ovpn: add test for the FW mark feature Antonio Quartulli
2026-03-17 10:40 [PATCH net-next 0/9] pull request: ovpn 2026-03-17 Antonio Quartulli
2026-03-17 10:40 ` [PATCH net-next 8/9] selftests: ovpn: add test for the FW mark feature Antonio Quartulli
2026-03-19 19:41 ` Jakub Kicinski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260227235955.660-9-antonio@openvpn.net \
--to=antonio@openvpn.net \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=ralf@mandelbit.com \
--cc=sd@queasysnail.net \
--cc=shuah@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox