* [PATCH net 1/6] selftests: ovpn: add nftables config dependencies for test-mark
2026-04-17 9:02 [PATCH net 0/6] pull request: fixes for ovpn 2026-04-17 Antonio Quartulli
@ 2026-04-17 9:03 ` Antonio Quartulli
2026-04-18 19:00 ` patchwork-bot+netdevbpf
2026-04-17 9:03 ` [PATCH net 2/6] selftests: ovpn: fail notification check on mismatch Antonio Quartulli
` (5 subsequent siblings)
6 siblings, 1 reply; 9+ messages in thread
From: Antonio Quartulli @ 2026-04-17 9:03 UTC (permalink / raw)
To: netdev
Cc: ralf, shuah, horms, Sabrina Dubroca, Jakub Kicinski, Paolo Abeni,
Andrew Lunn, David S. Miller, Eric Dumazet, Antonio Quartulli
From: Ralf Lici <ralf@mandelbit.com>
test-mark.sh installs nftables rules in an inet/filter output chain and
verifies packet drops via nft counters. In vmksft this can fail when the
nftables core is not enabled by the ovpn selftest config.
Add the missing kernel options required by this test:
- CONFIG_NETFILTER
- CONFIG_NF_TABLES
- CONFIG_NF_TABLES_INET
Fixes: 7b80d8a33500 ("selftests: ovpn: add test for the FW mark feature")
Reported-by: Jakub Kicinski <kuba@kernel.org>
Closes: https://lore.kernel.org/all/20260319124114.42f91f72@kernel.org/
Signed-off-by: Ralf Lici <ralf@mandelbit.com>
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
---
tools/testing/selftests/net/ovpn/config | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tools/testing/selftests/net/ovpn/config b/tools/testing/selftests/net/ovpn/config
index 42699740936d..d6cf033d555e 100644
--- a/tools/testing/selftests/net/ovpn/config
+++ b/tools/testing/selftests/net/ovpn/config
@@ -5,6 +5,9 @@ CONFIG_CRYPTO_GCM=y
CONFIG_DST_CACHE=y
CONFIG_INET=y
CONFIG_NET=y
+CONFIG_NETFILTER=y
CONFIG_NET_UDP_TUNNEL=y
+CONFIG_NF_TABLES=m
+CONFIG_NF_TABLES_INET=y
CONFIG_OVPN=m
CONFIG_STREAM_PARSER=y
--
2.52.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH net 1/6] selftests: ovpn: add nftables config dependencies for test-mark
2026-04-17 9:03 ` [PATCH net 1/6] selftests: ovpn: add nftables config dependencies for test-mark Antonio Quartulli
@ 2026-04-18 19:00 ` patchwork-bot+netdevbpf
0 siblings, 0 replies; 9+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-04-18 19:00 UTC (permalink / raw)
To: Antonio Quartulli
Cc: netdev, ralf, shuah, horms, sd, kuba, pabeni, andrew+netdev,
davem, edumazet
Hello:
This series was applied to netdev/net.git (main)
by Antonio Quartulli <antonio@openvpn.net>:
On Fri, 17 Apr 2026 11:03:00 +0200 you wrote:
> From: Ralf Lici <ralf@mandelbit.com>
>
> test-mark.sh installs nftables rules in an inet/filter output chain and
> verifies packet drops via nft counters. In vmksft this can fail when the
> nftables core is not enabled by the ovpn selftest config.
>
> Add the missing kernel options required by this test:
> - CONFIG_NETFILTER
> - CONFIG_NF_TABLES
> - CONFIG_NF_TABLES_INET
>
> [...]
Here is the summary with links:
- [net,1/6] selftests: ovpn: add nftables config dependencies for test-mark
https://git.kernel.org/netdev/net/c/e5fd34ab8dff
- [net,2/6] selftests: ovpn: fail notification check on mismatch
https://git.kernel.org/netdev/net/c/c409da0fe15e
- [net,3/6] selftests: ovpn: flatten slurped notification JSON before filtering
https://git.kernel.org/netdev/net/c/222e7f8d1ca3
- [net,4/6] selftests: ovpn: add prefix to helpers and shared variables
https://git.kernel.org/netdev/net/c/7c29665a3a3c
- [net,5/6] selftests: ovpn: align command flow with TAP
https://git.kernel.org/netdev/net/c/1be93bb979ab
- [net,6/6] selftests: ovpn: serialize YNL listener startup
https://git.kernel.org/netdev/net/c/6c9b1dc218fe
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH net 2/6] selftests: ovpn: fail notification check on mismatch
2026-04-17 9:02 [PATCH net 0/6] pull request: fixes for ovpn 2026-04-17 Antonio Quartulli
2026-04-17 9:03 ` [PATCH net 1/6] selftests: ovpn: add nftables config dependencies for test-mark Antonio Quartulli
@ 2026-04-17 9:03 ` Antonio Quartulli
2026-04-17 9:03 ` [PATCH net 3/6] selftests: ovpn: flatten slurped notification JSON before filtering Antonio Quartulli
` (4 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Antonio Quartulli @ 2026-04-17 9:03 UTC (permalink / raw)
To: netdev
Cc: ralf, shuah, horms, Sabrina Dubroca, Jakub Kicinski, Paolo Abeni,
Andrew Lunn, David S. Miller, Eric Dumazet, Antonio Quartulli
From: Ralf Lici <ralf@mandelbit.com>
compare_ntfs doesn't fail when expected and received notification
streams diverge.
Fix this bug by tracking the diff exit status explicitly and return it
to the caller so notification mismatches propagate as test failures.
Fixes: 77de28cd7cf1 ("selftests: ovpn: add notification parsing and matching")
Signed-off-by: Ralf Lici <ralf@mandelbit.com>
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
---
tools/testing/selftests/net/ovpn/common.sh | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/net/ovpn/common.sh b/tools/testing/selftests/net/ovpn/common.sh
index 4c08f756e63a..c92415aaddfc 100644
--- a/tools/testing/selftests/net/ovpn/common.sh
+++ b/tools/testing/selftests/net/ovpn/common.sh
@@ -140,23 +140,35 @@ add_peer() {
}
compare_ntfs() {
+ local diff_rc=0
+ local diff_file
+
if [ ${#tmp_jsons[@]} -gt 0 ]; then
suffix=""
[ "${SYMMETRIC_ID}" -eq 1 ] && suffix="${suffix}-symm"
[ "$FLOAT" == 1 ] && suffix="${suffix}-float"
expected="json/peer${1}${suffix}.json"
received="${tmp_jsons[$1]}"
+ diff_file=$(mktemp)
kill -TERM ${listener_pids[$1]} || true
wait ${listener_pids[$1]} || true
printf "Checking notifications for peer ${1}... "
if diff <(jq -s "${JQ_FILTER}" ${expected}) \
- <(jq -s "${JQ_FILTER}" ${received}); then
+ <(jq -s "${JQ_FILTER}" ${received}) \
+ >"${diff_file}" 2>&1; then
echo "OK"
+ else
+ diff_rc=$?
+ echo "failed"
+ cat "${diff_file}"
fi
+ rm -f "${diff_file}" || true
rm -f ${received} || true
fi
+
+ return "${diff_rc}"
}
cleanup() {
--
2.52.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH net 3/6] selftests: ovpn: flatten slurped notification JSON before filtering
2026-04-17 9:02 [PATCH net 0/6] pull request: fixes for ovpn 2026-04-17 Antonio Quartulli
2026-04-17 9:03 ` [PATCH net 1/6] selftests: ovpn: add nftables config dependencies for test-mark Antonio Quartulli
2026-04-17 9:03 ` [PATCH net 2/6] selftests: ovpn: fail notification check on mismatch Antonio Quartulli
@ 2026-04-17 9:03 ` Antonio Quartulli
2026-04-17 9:03 ` [PATCH net 4/6] selftests: ovpn: add prefix to helpers and shared variables Antonio Quartulli
` (3 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Antonio Quartulli @ 2026-04-17 9:03 UTC (permalink / raw)
To: netdev
Cc: ralf, shuah, horms, Sabrina Dubroca, Jakub Kicinski, Paolo Abeni,
Andrew Lunn, David S. Miller, Eric Dumazet, Antonio Quartulli
From: Ralf Lici <ralf@mandelbit.com>
Notification comparison uses jq -s, which slurps all inputs into an
array. Some inputs can be arrays themselves, and applying the .msg.peer
filter directly on those entries triggers jq type errors.
Expand any array-valued JSON items returned by jq -s before selecting
.msg.peer, so the filter handles both normal notification objects and []
entries without type errors.
Fixes: 77de28cd7cf1 ("selftests: ovpn: add notification parsing and matching")
Signed-off-by: Ralf Lici <ralf@mandelbit.com>
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
---
tools/testing/selftests/net/ovpn/common.sh | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/net/ovpn/common.sh b/tools/testing/selftests/net/ovpn/common.sh
index c92415aaddfc..d3b322e84fab 100644
--- a/tools/testing/selftests/net/ovpn/common.sh
+++ b/tools/testing/selftests/net/ovpn/common.sh
@@ -15,7 +15,8 @@ SYMMETRIC_ID=${SYMMETRIC_ID:-0}
export ID_OFFSET=$(( 9 * (SYMMETRIC_ID == 0) ))
-JQ_FILTER='map(select(.msg.peer | has("remote-ipv6") | not)) |
+JQ_FILTER='map(if type == "array" then .[] else . end) |
+ map(select(.msg.peer | has("remote-ipv6") | not)) |
map(del(.msg.ifindex)) | sort_by(.msg.peer.id)[]'
LAN_IP="11.11.11.11"
--
2.52.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH net 4/6] selftests: ovpn: add prefix to helpers and shared variables
2026-04-17 9:02 [PATCH net 0/6] pull request: fixes for ovpn 2026-04-17 Antonio Quartulli
` (2 preceding siblings ...)
2026-04-17 9:03 ` [PATCH net 3/6] selftests: ovpn: flatten slurped notification JSON before filtering Antonio Quartulli
@ 2026-04-17 9:03 ` Antonio Quartulli
2026-04-17 9:03 ` [PATCH net 5/6] selftests: ovpn: align command flow with TAP Antonio Quartulli
` (2 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Antonio Quartulli @ 2026-04-17 9:03 UTC (permalink / raw)
To: netdev
Cc: ralf, shuah, horms, Sabrina Dubroca, Jakub Kicinski, Paolo Abeni,
Andrew Lunn, David S. Miller, Eric Dumazet, Antonio Quartulli
From: Ralf Lici <ralf@mandelbit.com>
Current naming for shared variables, helpers and netnamespaces is
a bit unfortunate as it doesn't come with a clean prefix.
This showed to be problematic in case of name clashes with external
scripts or in case of abrupt test termination (hanging netns' weren't
easily reconducible to ovpn).
Rename common helper entry points and all shared globals in the ovpn
selftests to ovpn_ or OVPN_ names so test scripts and wrappers use a
single explicit prefix. Also rename the temporary network namespaces
created by the tests from peerN to ovpn_peerN. This makes leaked
namespaces easier to identify.
This is a mechanical refactor only, behavior is unchanged.
Fixes: 959bc330a439 ("testing/selftests: add test tool and scripts for ovpn module")
Signed-off-by: Ralf Lici <ralf@mandelbit.com>
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
---
tools/testing/selftests/net/ovpn/common.sh | 186 ++++++++++--------
.../selftests/net/ovpn/test-chachapoly.sh | 2 +-
.../net/ovpn/test-close-socket-tcp.sh | 2 +-
.../selftests/net/ovpn/test-close-socket.sh | 32 +--
.../testing/selftests/net/ovpn/test-float.sh | 2 +-
tools/testing/selftests/net/ovpn/test-mark.sh | 45 ++---
.../net/ovpn/test-symmetric-id-float.sh | 4 +-
.../net/ovpn/test-symmetric-id-tcp.sh | 4 +-
.../selftests/net/ovpn/test-symmetric-id.sh | 2 +-
tools/testing/selftests/net/ovpn/test-tcp.sh | 2 +-
tools/testing/selftests/net/ovpn/test.sh | 139 ++++++-------
11 files changed, 226 insertions(+), 194 deletions(-)
diff --git a/tools/testing/selftests/net/ovpn/common.sh b/tools/testing/selftests/net/ovpn/common.sh
index d3b322e84fab..38f187b9de23 100644
--- a/tools/testing/selftests/net/ovpn/common.sh
+++ b/tools/testing/selftests/net/ovpn/common.sh
@@ -4,63 +4,72 @@
#
# Author: Antonio Quartulli <antonio@openvpn.net>
-UDP_PEERS_FILE=${UDP_PEERS_FILE:-udp_peers.txt}
-TCP_PEERS_FILE=${TCP_PEERS_FILE:-tcp_peers.txt}
+OVPN_UDP_PEERS_FILE=${OVPN_UDP_PEERS_FILE:-udp_peers.txt}
+OVPN_TCP_PEERS_FILE=${OVPN_TCP_PEERS_FILE:-tcp_peers.txt}
OVPN_CLI=${OVPN_CLI:-./ovpn-cli}
-YNL_CLI=${YNL_CLI:-../../../../net/ynl/pyynl/cli.py}
-ALG=${ALG:-aes}
-PROTO=${PROTO:-UDP}
-FLOAT=${FLOAT:-0}
-SYMMETRIC_ID=${SYMMETRIC_ID:-0}
+OVPN_YNL=${OVPN_YNL:-../../../../net/ynl/pyynl/cli.py}
+OVPN_ALG=${OVPN_ALG:-aes}
+OVPN_PROTO=${OVPN_PROTO:-UDP}
+OVPN_FLOAT=${OVPN_FLOAT:-0}
+OVPN_SYMMETRIC_ID=${OVPN_SYMMETRIC_ID:-0}
-export ID_OFFSET=$(( 9 * (SYMMETRIC_ID == 0) ))
+export OVPN_ID_OFFSET=$(( 9 * (OVPN_SYMMETRIC_ID == 0) ))
-JQ_FILTER='map(if type == "array" then .[] else . end) |
+OVPN_JQ_FILTER='map(if type == "array" then .[] else . end) |
map(select(.msg.peer | has("remote-ipv6") | not)) |
map(del(.msg.ifindex)) | sort_by(.msg.peer.id)[]'
-LAN_IP="11.11.11.11"
+OVPN_LAN_IP="11.11.11.11"
-declare -A tmp_jsons=()
-declare -A listener_pids=()
+declare -A OVPN_TMP_JSONS=()
+declare -A OVPN_LISTENER_PIDS=()
-create_ns() {
- ip netns add peer${1}
+ovpn_create_ns() {
+ ip netns add "ovpn_peer${1}"
}
-setup_ns() {
+ovpn_setup_ns() {
+ local peer="ovpn_peer${1}"
+ local server_ns="ovpn_peer0"
+ local peer_ns
MODE="P2P"
if [ ${1} -eq 0 ]; then
MODE="MP"
- for p in $(seq 1 ${NUM_PEERS}); do
- ip link add veth${p} netns peer0 type veth peer name veth${p} netns peer${p}
-
- ip -n peer0 addr add 10.10.${p}.1/24 dev veth${p}
- ip -n peer0 addr add fd00:0:0:${p}::1/64 dev veth${p}
- ip -n peer0 link set veth${p} up
-
- ip -n peer${p} addr add 10.10.${p}.2/24 dev veth${p}
- ip -n peer${p} addr add fd00:0:0:${p}::2/64 dev veth${p}
- ip -n peer${p} link set veth${p} up
+ for p in $(seq 1 ${OVPN_NUM_PEERS}); do
+ peer_ns="ovpn_peer${p}"
+ ip link add veth${p} netns "${server_ns}" type veth \
+ peer name veth${p} netns "${peer_ns}"
+
+ ip -n "${server_ns}" addr add 10.10.${p}.1/24 dev \
+ veth${p}
+ ip -n "${server_ns}" addr add fd00:0:0:${p}::1/64 dev \
+ veth${p}
+ ip -n "${server_ns}" link set veth${p} up
+
+ ip -n "${peer_ns}" addr add 10.10.${p}.2/24 dev veth${p}
+ ip -n "${peer_ns}" addr add fd00:0:0:${p}::2/64 dev \
+ veth${p}
+ ip -n "${peer_ns}" link set veth${p} up
done
fi
- ip netns exec peer${1} ${OVPN_CLI} new_iface tun${1} $MODE
- ip -n peer${1} addr add ${2} dev tun${1}
+ ip netns exec "${peer}" ${OVPN_CLI} new_iface tun${1} $MODE
+ ip -n "${peer}" addr add ${2} dev tun${1}
# add a secondary IP to peer 1, to test a LAN behind a client
- if [ ${1} -eq 1 -a -n "${LAN_IP}" ]; then
- ip -n peer${1} addr add ${LAN_IP} dev tun${1}
- ip -n peer0 route add ${LAN_IP} via $(echo ${2} |sed -e s'!/.*!!') dev tun0
+ if [ ${1} -eq 1 -a -n "${OVPN_LAN_IP}" ]; then
+ ip -n "${peer}" addr add ${OVPN_LAN_IP} dev tun${1}
+ ip -n "${server_ns}" route add ${OVPN_LAN_IP} via \
+ $(echo ${2} |sed -e s'!/.*!!') dev tun0
fi
if [ -n "${3}" ]; then
- ip -n peer${1} link set mtu ${3} dev tun${1}
+ ip -n "${peer}" link set mtu ${3} dev tun${1}
fi
- ip -n peer${1} link set tun${1} up
+ ip -n "${peer}" link set tun${1} up
}
-build_capture_filter() {
+ovpn_build_capture_filter() {
# match the first four bytes of the openvpn data payload
- if [ "${PROTO}" == "UDP" ]; then
+ if [ "${OVPN_PROTO}" == "UDP" ]; then
# For UDP, libpcap transport indexing only works for IPv4, so
# use an explicit IPv4 or IPv6 expression based on the peer
# address. The IPv6 branch assumes there are no extension
@@ -77,86 +86,98 @@ build_capture_filter() {
fi
}
-setup_listener() {
+ovpn_setup_listener() {
+ local peer_ns="ovpn_peer${p}"
file=$(mktemp)
- PYTHONUNBUFFERED=1 ip netns exec peer${p} ${YNL_CLI} --family ovpn \
- --subscribe peers --output-json --duration 40 > ${file} &
- listener_pids[$1]=$!
- tmp_jsons[$1]="${file}"
+ PYTHONUNBUFFERED=1 ip netns exec "${peer_ns}" "${OVPN_YNL}" --family \
+ ovpn --subscribe peers --output-json --duration 40 > ${file} &
+ OVPN_LISTENER_PIDS[$1]=$!
+ OVPN_TMP_JSONS[$1]="${file}"
}
-add_peer() {
+ovpn_add_peer() {
labels=("ASYMM" "SYMM")
- M_ID=${labels[SYMMETRIC_ID]}
+ local peer_ns
+ local server_ns="ovpn_peer0"
+ M_ID=${labels[OVPN_SYMMETRIC_ID]}
- if [ "${PROTO}" == "UDP" ]; then
+ if [ "${OVPN_PROTO}" == "UDP" ]; then
if [ ${1} -eq 0 ]; then
- ip netns exec peer0 ${OVPN_CLI} new_multi_peer tun0 1 \
- ${M_ID} ${UDP_PEERS_FILE}
+ ip netns exec "${server_ns}" ${OVPN_CLI} \
+ new_multi_peer tun0 1 ${M_ID} \
+ ${OVPN_UDP_PEERS_FILE}
- for p in $(seq 1 ${NUM_PEERS}); do
- ip netns exec peer0 ${OVPN_CLI} new_key tun0 ${p} 1 0 ${ALG} 0 \
+ for p in $(seq 1 ${OVPN_NUM_PEERS}); do
+ ip netns exec "${server_ns}" ${OVPN_CLI} \
+ new_key tun0 ${p} 1 0 ${OVPN_ALG} 0 \
data64.key
done
else
- if [ "${SYMMETRIC_ID}" -eq 1 ]; then
+ peer_ns="ovpn_peer${1}"
+ if [ "${OVPN_SYMMETRIC_ID}" -eq 1 ]; then
PEER_ID=${1}
TX_ID="none"
else
PEER_ID=$(awk "NR == ${1} {print \$2}" \
- ${UDP_PEERS_FILE})
+ ${OVPN_UDP_PEERS_FILE})
TX_ID=${1}
fi
- RADDR=$(awk "NR == ${1} {print \$3}" ${UDP_PEERS_FILE})
- RPORT=$(awk "NR == ${1} {print \$4}" ${UDP_PEERS_FILE})
- LPORT=$(awk "NR == ${1} {print \$6}" ${UDP_PEERS_FILE})
- ip netns exec peer${1} ${OVPN_CLI} new_peer tun${1} \
- ${PEER_ID} ${TX_ID} ${LPORT} ${RADDR} ${RPORT}
- ip netns exec peer${1} ${OVPN_CLI} new_key tun${1} \
- ${PEER_ID} 1 0 ${ALG} 1 data64.key
+ RADDR=$(awk "NR == ${1} {print \$3}" \
+ ${OVPN_UDP_PEERS_FILE})
+ RPORT=$(awk "NR == ${1} {print \$4}" \
+ ${OVPN_UDP_PEERS_FILE})
+ LPORT=$(awk "NR == ${1} {print \$6}" \
+ ${OVPN_UDP_PEERS_FILE})
+ ip netns exec "${peer_ns}" ${OVPN_CLI} new_peer \
+ tun${1} ${PEER_ID} ${TX_ID} ${LPORT} ${RADDR} \
+ ${RPORT}
+ ip netns exec "${peer_ns}" ${OVPN_CLI} new_key tun${1} \
+ ${PEER_ID} 1 0 ${OVPN_ALG} 1 data64.key
fi
else
if [ ${1} -eq 0 ]; then
- (ip netns exec peer0 ${OVPN_CLI} listen tun0 1 ${M_ID} \
- ${TCP_PEERS_FILE} && {
- for p in $(seq 1 ${NUM_PEERS}); do
- ip netns exec peer0 ${OVPN_CLI} new_key tun0 ${p} 1 0 \
- ${ALG} 0 data64.key
+ (ip netns exec "${server_ns}" ${OVPN_CLI} listen tun0 \
+ 1 ${M_ID} ${OVPN_TCP_PEERS_FILE} && {
+ for p in $(seq 1 ${OVPN_NUM_PEERS}); do
+ ip netns exec "${server_ns}" \
+ ${OVPN_CLI} new_key tun0 ${p} \
+ 1 0 ${OVPN_ALG} 0 data64.key
done
}) &
sleep 5
else
- if [ "${SYMMETRIC_ID}" -eq 1 ]; then
+ peer_ns="ovpn_peer${1}"
+ if [ "${OVPN_SYMMETRIC_ID}" -eq 1 ]; then
PEER_ID=${1}
TX_ID="none"
else
PEER_ID=$(awk "NR == ${1} {print \$2}" \
- ${TCP_PEERS_FILE})
+ ${OVPN_TCP_PEERS_FILE})
TX_ID=${1}
fi
- ip netns exec peer${1} ${OVPN_CLI} connect tun${1} \
+ ip netns exec "${peer_ns}" ${OVPN_CLI} connect tun${1} \
${PEER_ID} ${TX_ID} 10.10.${1}.1 1 data64.key
fi
fi
}
-compare_ntfs() {
+ovpn_compare_ntfs() {
local diff_rc=0
local diff_file
- if [ ${#tmp_jsons[@]} -gt 0 ]; then
+ if [ ${#OVPN_TMP_JSONS[@]} -gt 0 ]; then
suffix=""
- [ "${SYMMETRIC_ID}" -eq 1 ] && suffix="${suffix}-symm"
- [ "$FLOAT" == 1 ] && suffix="${suffix}-float"
+ [ "${OVPN_SYMMETRIC_ID}" -eq 1 ] && suffix="${suffix}-symm"
+ [ "$OVPN_FLOAT" == 1 ] && suffix="${suffix}-float"
expected="json/peer${1}${suffix}.json"
- received="${tmp_jsons[$1]}"
+ received="${OVPN_TMP_JSONS[$1]}"
diff_file=$(mktemp)
- kill -TERM ${listener_pids[$1]} || true
- wait ${listener_pids[$1]} || true
+ kill -TERM ${OVPN_LISTENER_PIDS[$1]} || true
+ wait ${OVPN_LISTENER_PIDS[$1]} || true
printf "Checking notifications for peer ${1}... "
- if diff <(jq -s "${JQ_FILTER}" ${expected}) \
- <(jq -s "${JQ_FILTER}" ${received}) \
+ if diff <(jq -s "${OVPN_JQ_FILTER}" ${expected}) \
+ <(jq -s "${OVPN_JQ_FILTER}" ${received}) \
>"${diff_file}" 2>&1; then
echo "OK"
else
@@ -172,25 +193,30 @@ compare_ntfs() {
return "${diff_rc}"
}
-cleanup() {
+ovpn_cleanup() {
+ local peer_ns
# some ovpn-cli processes sleep in background so they need manual poking
killall $(basename ${OVPN_CLI}) 2>/dev/null || true
# netns peer0 is deleted without erasing ifaces first
for p in $(seq 1 10); do
- ip -n peer${p} link set tun${p} down 2>/dev/null || true
- ip netns exec peer${p} ${OVPN_CLI} del_iface tun${p} 2>/dev/null || true
+ peer_ns="ovpn_peer${p}"
+ ip -n "${peer_ns}" link set tun${p} down 2>/dev/null || true
+ ip netns exec "${peer_ns}" ${OVPN_CLI} del_iface tun${p} \
+ 2>/dev/null || true
done
for p in $(seq 1 10); do
- ip -n peer0 link del veth${p} 2>/dev/null || true
+ ip -n ovpn_peer0 link del veth${p} 2>/dev/null || true
done
for p in $(seq 0 10); do
- ip netns del peer${p} 2>/dev/null || true
+ ip netns del "ovpn_peer${p}" 2>/dev/null || true
done
}
-if [ "${PROTO}" == "UDP" ]; then
- NUM_PEERS=${NUM_PEERS:-$(wc -l ${UDP_PEERS_FILE} | awk '{print $1}')}
+if [ "${OVPN_PROTO}" == "UDP" ]; then
+ OVPN_NUM_PEERS=${OVPN_NUM_PEERS:-$(wc -l ${OVPN_UDP_PEERS_FILE} | \
+ awk '{print $1}')}
else
- NUM_PEERS=${NUM_PEERS:-$(wc -l ${TCP_PEERS_FILE} | awk '{print $1}')}
+ OVPN_NUM_PEERS=${OVPN_NUM_PEERS:-$(wc -l ${OVPN_TCP_PEERS_FILE} | \
+ awk '{print $1}')}
fi
diff --git a/tools/testing/selftests/net/ovpn/test-chachapoly.sh b/tools/testing/selftests/net/ovpn/test-chachapoly.sh
index 32504079a2b8..cd3d94355d58 100755
--- a/tools/testing/selftests/net/ovpn/test-chachapoly.sh
+++ b/tools/testing/selftests/net/ovpn/test-chachapoly.sh
@@ -4,6 +4,6 @@
#
# Author: Antonio Quartulli <antonio@openvpn.net>
-ALG="chachapoly"
+OVPN_ALG="chachapoly"
source test.sh
diff --git a/tools/testing/selftests/net/ovpn/test-close-socket-tcp.sh b/tools/testing/selftests/net/ovpn/test-close-socket-tcp.sh
index 093d44772ffd..392d269bada5 100755
--- a/tools/testing/selftests/net/ovpn/test-close-socket-tcp.sh
+++ b/tools/testing/selftests/net/ovpn/test-close-socket-tcp.sh
@@ -4,6 +4,6 @@
#
# Author: Antonio Quartulli <antonio@openvpn.net>
-PROTO="TCP"
+OVPN_PROTO="TCP"
source test-close-socket.sh
diff --git a/tools/testing/selftests/net/ovpn/test-close-socket.sh b/tools/testing/selftests/net/ovpn/test-close-socket.sh
index 0d09df14fe8e..6bc1b6eab8ac 100755
--- a/tools/testing/selftests/net/ovpn/test-close-socket.sh
+++ b/tools/testing/selftests/net/ovpn/test-close-socket.sh
@@ -8,38 +8,40 @@
set -e
source ./common.sh
+server_ns="ovpn_peer0"
-cleanup
+ovpn_cleanup
modprobe -q ovpn || true
-for p in $(seq 0 ${NUM_PEERS}); do
- create_ns ${p}
+for p in $(seq 0 ${OVPN_NUM_PEERS}); do
+ ovpn_create_ns ${p}
done
-for p in $(seq 0 ${NUM_PEERS}); do
- setup_ns ${p} 5.5.5.$((${p} + 1))/24
+for p in $(seq 0 ${OVPN_NUM_PEERS}); do
+ ovpn_setup_ns ${p} 5.5.5.$((${p} + 1))/24
done
-for p in $(seq 0 ${NUM_PEERS}); do
- add_peer ${p}
+for p in $(seq 0 ${OVPN_NUM_PEERS}); do
+ ovpn_add_peer ${p}
done
-for p in $(seq 1 ${NUM_PEERS}); 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
+for p in $(seq 1 ${OVPN_NUM_PEERS}); do
+ ip netns exec "${server_ns}" ${OVPN_CLI} set_peer tun0 ${p} 60 120
+ ip netns exec "ovpn_peer${p}" ${OVPN_CLI} set_peer tun${p} $((${p}+9)) \
+ 60 120
done
sleep 1
-for p in $(seq 1 ${NUM_PEERS}); do
- ip netns exec peer0 ping -qfc 500 -w 3 5.5.5.$((${p} + 1))
+for p in $(seq 1 ${OVPN_NUM_PEERS}); do
+ ip netns exec "${server_ns}" ping -qfc 500 -w 3 5.5.5.$((${p} + 1))
done
-ip netns exec peer0 iperf3 -1 -s &
+ip netns exec "${server_ns}" iperf3 -1 -s &
sleep 1
-ip netns exec peer1 iperf3 -Z -t 3 -c 5.5.5.1
+ip netns exec ovpn_peer1 iperf3 -Z -t 3 -c 5.5.5.1
-cleanup
+ovpn_cleanup
modprobe -r ovpn || true
diff --git a/tools/testing/selftests/net/ovpn/test-float.sh b/tools/testing/selftests/net/ovpn/test-float.sh
index ba5d725e18b0..91f8e113718e 100755
--- a/tools/testing/selftests/net/ovpn/test-float.sh
+++ b/tools/testing/selftests/net/ovpn/test-float.sh
@@ -4,6 +4,6 @@
#
# Author: Antonio Quartulli <antonio@openvpn.net>
-FLOAT="1"
+OVPN_FLOAT="1"
source test.sh
diff --git a/tools/testing/selftests/net/ovpn/test-mark.sh b/tools/testing/selftests/net/ovpn/test-mark.sh
index 8534428ed3eb..2ee5dc5fc538 100755
--- a/tools/testing/selftests/net/ovpn/test-mark.sh
+++ b/tools/testing/selftests/net/ovpn/test-mark.sh
@@ -11,62 +11,63 @@ set -e
MARK=1056
source ./common.sh
+server_ns="ovpn_peer0"
-cleanup
+ovpn_cleanup
modprobe -q ovpn || true
-for p in $(seq 0 "${NUM_PEERS}"); do
- create_ns "${p}"
+for p in $(seq 0 "${OVPN_NUM_PEERS}"); do
+ ovpn_create_ns "${p}"
done
for p in $(seq 0 3); do
- setup_ns "${p}" 5.5.5.$((p + 1))/24
+ ovpn_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 ASYMM \
- "${UDP_PEERS_FILE}" \
+ip netns exec "${server_ns}" "${OVPN_CLI}" new_multi_peer tun0 1 ASYMM \
+ "${OVPN_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
+ ip netns exec "${server_ns}" "${OVPN_CLI}" new_key tun0 "${p}" 1 0 \
+ "${OVPN_ALG}" 0 data64.key
done
for p in $(seq 1 3); do
- add_peer "${p}"
+ ovpn_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}" \
+ ip netns exec "${server_ns}" "${OVPN_CLI}" set_peer tun0 "${p}" 60 120
+ ip netns exec "ovpn_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 -w 3 5.5.5.$((p + 1))
+ ip netns exec "${server_ns}" ping -qfc 500 -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 {
+ip netns exec "${server_ns}" nft flush ruleset
+ip netns exec "${server_ns}" nft 'add table inet filter'
+ip netns exec "${server_ns}" nft 'add chain inet filter output {
type filter hook output priority 0;
policy accept;
}'
-ip netns exec peer0 nft add rule inet filter output \
+ip netns exec "${server_ns}" nft add rule inet filter output \
meta mark == ${MARK} \
counter drop
-DROP_COUNTER=$(ip netns exec peer0 nft list chain inet filter output \
+DROP_COUNTER=$(ip netns exec "${server_ns}" 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 \
+ PING_OUTPUT=$(ip netns exec "${server_ns}" ping \
-qfc 500 -w 1 5.5.5.$((p + 1)) 2>&1) && exit 1
echo "${PING_OUTPUT}"
LOST_PACKETS=$(echo "$PING_OUTPUT" \
@@ -76,7 +77,7 @@ for p in $(seq 1 3); do
done
# check if the final nft counter matches our counter
-TOTAL_COUNT=$(ip netns exec peer0 nft list chain inet filter output \
+TOTAL_COUNT=$(ip netns exec "${server_ns}" nft list chain inet filter output \
| sed -n 's/.*packets \([0-9]*\).*/\1/p')
if [ "${DROP_COUNTER}" -ne "${TOTAL_COUNT}" ]; then
echo "Expected ${TOTAL_COUNT} drops, got ${DROP_COUNTER}"
@@ -84,13 +85,13 @@ if [ "${DROP_COUNTER}" -ne "${TOTAL_COUNT}" ]; then
fi
echo "Removing the drop rule"
-ip netns exec peer0 nft flush ruleset
+ip netns exec "${server_ns}" nft flush ruleset
sleep 1
for p in $(seq 1 3); do
- ip netns exec peer0 ping -qfc 500 -w 3 5.5.5.$((p + 1))
+ ip netns exec "${server_ns}" ping -qfc 500 -w 3 5.5.5.$((p + 1))
done
-cleanup
+ovpn_cleanup
modprobe -r ovpn || true
diff --git a/tools/testing/selftests/net/ovpn/test-symmetric-id-float.sh b/tools/testing/selftests/net/ovpn/test-symmetric-id-float.sh
index b3711a81b463..75296fe72c39 100755
--- a/tools/testing/selftests/net/ovpn/test-symmetric-id-float.sh
+++ b/tools/testing/selftests/net/ovpn/test-symmetric-id-float.sh
@@ -5,7 +5,7 @@
# Author: Ralf Lici <ralf@mandelbit.com>
# Antonio Quartulli <antonio@openvpn.net>
-SYMMETRIC_ID="1"
-FLOAT="1"
+OVPN_SYMMETRIC_ID="1"
+OVPN_FLOAT="1"
source test.sh
diff --git a/tools/testing/selftests/net/ovpn/test-symmetric-id-tcp.sh b/tools/testing/selftests/net/ovpn/test-symmetric-id-tcp.sh
index 188cafb67b2f..680a465c49d2 100755
--- a/tools/testing/selftests/net/ovpn/test-symmetric-id-tcp.sh
+++ b/tools/testing/selftests/net/ovpn/test-symmetric-id-tcp.sh
@@ -5,7 +5,7 @@
# Author: Ralf Lici <ralf@mandelbit.com>
# Antonio Quartulli <antonio@openvpn.net>
-PROTO="TCP"
-SYMMETRIC_ID=1
+OVPN_PROTO="TCP"
+OVPN_SYMMETRIC_ID=1
source test.sh
diff --git a/tools/testing/selftests/net/ovpn/test-symmetric-id.sh b/tools/testing/selftests/net/ovpn/test-symmetric-id.sh
index 35b119c72e4f..a2e2808959d9 100755
--- a/tools/testing/selftests/net/ovpn/test-symmetric-id.sh
+++ b/tools/testing/selftests/net/ovpn/test-symmetric-id.sh
@@ -5,6 +5,6 @@
# Author: Ralf Lici <ralf@mandelbit.com>
# Antonio Quartulli <antonio@openvpn.net>
-SYMMETRIC_ID="1"
+OVPN_SYMMETRIC_ID="1"
source test.sh
diff --git a/tools/testing/selftests/net/ovpn/test-tcp.sh b/tools/testing/selftests/net/ovpn/test-tcp.sh
index ba3f1f315a34..27cc6e7b98bc 100755
--- a/tools/testing/selftests/net/ovpn/test-tcp.sh
+++ b/tools/testing/selftests/net/ovpn/test-tcp.sh
@@ -4,6 +4,6 @@
#
# Author: Antonio Quartulli <antonio@openvpn.net>
-PROTO="TCP"
+OVPN_PROTO="TCP"
source test.sh
diff --git a/tools/testing/selftests/net/ovpn/test.sh b/tools/testing/selftests/net/ovpn/test.sh
index b60e94a4094e..b766f4842940 100755
--- a/tools/testing/selftests/net/ovpn/test.sh
+++ b/tools/testing/selftests/net/ovpn/test.sh
@@ -8,37 +8,38 @@
set -e
source ./common.sh
+server_ns="ovpn_peer0"
-cleanup
+ovpn_cleanup
modprobe -q ovpn || true
-for p in $(seq 0 ${NUM_PEERS}); do
- create_ns ${p}
+for p in $(seq 0 ${OVPN_NUM_PEERS}); do
+ ovpn_create_ns ${p}
done
-for p in $(seq 0 ${NUM_PEERS}); do
- setup_listener ${p}
+for p in $(seq 0 ${OVPN_NUM_PEERS}); do
+ ovpn_setup_listener ${p}
done
-for p in $(seq 0 ${NUM_PEERS}); do
- setup_ns ${p} 5.5.5.$((${p} + 1))/24 ${MTU}
+for p in $(seq 0 ${OVPN_NUM_PEERS}); do
+ ovpn_setup_ns ${p} 5.5.5.$((${p} + 1))/24 ${MTU}
done
-for p in $(seq 0 ${NUM_PEERS}); do
- add_peer ${p}
+for p in $(seq 0 ${OVPN_NUM_PEERS}); do
+ ovpn_add_peer ${p}
done
-for p in $(seq 1 ${NUM_PEERS}); 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}+ID_OFFSET)) 60 120
+for p in $(seq 1 ${OVPN_NUM_PEERS}); do
+ ip netns exec "${server_ns}" ${OVPN_CLI} set_peer tun0 ${p} 60 120
+ ip netns exec "ovpn_peer${p}" ${OVPN_CLI} set_peer tun${p} \
+ $((${p}+OVPN_ID_OFFSET)) 60 120
done
sleep 1
TCPDUMP_TIMEOUT="1.5s"
-for p in $(seq 1 ${NUM_PEERS}); do
+for p in $(seq 1 ${OVPN_NUM_PEERS}); do
# The first part of the data packet header consists of:
# - TCP only: 2 bytes for the packet length
# - 5 bits for opcode ("9" for DATA_V2)
@@ -47,119 +48,121 @@ for p in $(seq 1 ${NUM_PEERS}); do
# - with asymmetric ID: "${p}" one way and "${p} + 9" the other way
# - with symmetric ID: "${p}" both ways
HEADER1=$(printf "0x4800000%x" ${p})
- HEADER2=$(printf "0x4800000%x" $((${p} + ID_OFFSET)))
+ HEADER2=$(printf "0x4800000%x" $((${p} + OVPN_ID_OFFSET)))
RADDR=""
- if [ "${PROTO}" == "UDP" ]; then
- RADDR=$(awk "NR == ${p} {print \$3}" ${UDP_PEERS_FILE})
+ if [ "${OVPN_PROTO}" == "UDP" ]; then
+ RADDR=$(awk "NR == ${p} {print \$3}" ${OVPN_UDP_PEERS_FILE})
fi
- timeout ${TCPDUMP_TIMEOUT} ip netns exec peer${p} \
+ timeout ${TCPDUMP_TIMEOUT} ip netns exec "ovpn_peer${p}" \
tcpdump --immediate-mode -p -ni veth${p} -c 1 \
- "$(build_capture_filter "${HEADER1}" "${RADDR}")" \
+ "$(ovpn_build_capture_filter "${HEADER1}" "${RADDR}")" \
>/dev/null 2>&1 &
TCPDUMP_PID1=$!
- timeout ${TCPDUMP_TIMEOUT} ip netns exec peer${p} \
+ timeout ${TCPDUMP_TIMEOUT} ip netns exec "ovpn_peer${p}" \
tcpdump --immediate-mode -p -ni veth${p} -c 1 \
- "$(build_capture_filter "${HEADER2}" "${RADDR}")" \
+ "$(ovpn_build_capture_filter "${HEADER2}" "${RADDR}")" \
>/dev/null 2>&1 &
TCPDUMP_PID2=$!
sleep 0.3
- ip netns exec peer0 ping -qfc 500 -w 3 5.5.5.$((${p} + 1))
- ip netns exec peer0 ping -qfc 500 -s 3000 -w 3 5.5.5.$((${p} + 1))
+ ip netns exec "${server_ns}" ping -qfc 500 -w 3 5.5.5.$((${p} + 1))
+ ip netns exec "${server_ns}" ping -qfc 500 -s 3000 -w 3 \
+ 5.5.5.$((${p} + 1))
wait ${TCPDUMP_PID1}
wait ${TCPDUMP_PID2}
done
# ping LAN behind client 1
-ip netns exec peer0 ping -qfc 500 -w 3 ${LAN_IP}
+ip netns exec "${server_ns}" ping -qfc 500 -w 3 ${OVPN_LAN_IP}
-if [ "$FLOAT" == "1" ]; then
+if [ "$OVPN_FLOAT" == "1" ]; then
# make clients float..
- for p in $(seq 1 ${NUM_PEERS}); do
- ip -n peer${p} addr del 10.10.${p}.2/24 dev veth${p}
- ip -n peer${p} addr add 10.10.${p}.3/24 dev veth${p}
+ for p in $(seq 1 ${OVPN_NUM_PEERS}); do
+ ip -n "ovpn_peer${p}" addr del 10.10.${p}.2/24 dev veth${p}
+ ip -n "ovpn_peer${p}" addr add 10.10.${p}.3/24 dev veth${p}
done
- for p in $(seq 1 ${NUM_PEERS}); do
- ip netns exec peer${p} ping -qfc 500 -w 3 5.5.5.1
+ for p in $(seq 1 ${OVPN_NUM_PEERS}); do
+ ip netns exec "ovpn_peer${p}" ping -qfc 500 -w 3 5.5.5.1
done
fi
-ip netns exec peer0 iperf3 -1 -s &
+ip netns exec "${server_ns}" iperf3 -1 -s &
sleep 1
-ip netns exec peer1 iperf3 -Z -t 3 -c 5.5.5.1
+ip netns exec ovpn_peer1 iperf3 -Z -t 3 -c 5.5.5.1
echo "Adding secondary key and then swap:"
-for p in $(seq 1 ${NUM_PEERS}); do
- ip netns exec peer0 ${OVPN_CLI} new_key tun0 ${p} 2 1 ${ALG} 0 \
- data64.key
- ip netns exec peer${p} ${OVPN_CLI} new_key tun${p} \
- $((${p} + ID_OFFSET)) 2 1 ${ALG} 1 data64.key
- ip netns exec peer${p} ${OVPN_CLI} swap_keys tun${p} \
- $((${p} + ID_OFFSET))
+for p in $(seq 1 ${OVPN_NUM_PEERS}); do
+ ip netns exec "${server_ns}" ${OVPN_CLI} new_key tun0 ${p} 2 1 \
+ ${OVPN_ALG} 0 data64.key
+ ip netns exec "ovpn_peer${p}" ${OVPN_CLI} new_key tun${p} \
+ $((${p} + OVPN_ID_OFFSET)) 2 1 ${OVPN_ALG} 1 data64.key
+ ip netns exec "ovpn_peer${p}" ${OVPN_CLI} swap_keys tun${p} \
+ $((${p} + OVPN_ID_OFFSET))
done
sleep 1
echo "Querying all peers:"
-ip netns exec peer0 ${OVPN_CLI} get_peer tun0
-ip netns exec peer1 ${OVPN_CLI} get_peer tun1
+ip netns exec "${server_ns}" ${OVPN_CLI} get_peer tun0
+ip netns exec ovpn_peer1 ${OVPN_CLI} get_peer tun1
echo "Querying peer 1:"
-ip netns exec peer0 ${OVPN_CLI} get_peer tun0 1
+ip netns exec "${server_ns}" ${OVPN_CLI} get_peer tun0 1
echo "Querying non-existent peer 20:"
-ip netns exec peer0 ${OVPN_CLI} get_peer tun0 20 || true
+ip netns exec "${server_ns}" ${OVPN_CLI} get_peer tun0 20 || true
echo "Deleting peer 1:"
-ip netns exec peer0 ${OVPN_CLI} del_peer tun0 1
-ip netns exec peer1 ${OVPN_CLI} del_peer tun1 $((1 + ID_OFFSET))
+ip netns exec "${server_ns}" ${OVPN_CLI} del_peer tun0 1
+ip netns exec ovpn_peer1 ${OVPN_CLI} del_peer tun1 $((1 + OVPN_ID_OFFSET))
echo "Querying keys:"
-for p in $(seq 2 ${NUM_PEERS}); do
- ip netns exec peer${p} ${OVPN_CLI} get_key tun${p} \
- $((${p} + ID_OFFSET)) 1
- ip netns exec peer${p} ${OVPN_CLI} get_key tun${p} \
- $((${p} + ID_OFFSET)) 2
+for p in $(seq 2 ${OVPN_NUM_PEERS}); do
+ ip netns exec "ovpn_peer${p}" ${OVPN_CLI} get_key tun${p} \
+ $((${p} + OVPN_ID_OFFSET)) 1
+ ip netns exec "ovpn_peer${p}" ${OVPN_CLI} get_key tun${p} \
+ $((${p} + OVPN_ID_OFFSET)) 2
done
echo "Deleting peer while sending traffic:"
-(ip netns exec peer2 ping -qf -w 4 5.5.5.1)&
+(ip netns exec ovpn_peer2 ping -qf -w 4 5.5.5.1)&
sleep 2
-ip netns exec peer0 ${OVPN_CLI} del_peer tun0 2
+ip netns exec "${server_ns}" ${OVPN_CLI} del_peer tun0 2
# following command fails in TCP mode
# (both ends get conn reset when one peer disconnects)
-ip netns exec peer2 ${OVPN_CLI} del_peer tun2 $((2 + ID_OFFSET)) || true
+ip netns exec ovpn_peer2 ${OVPN_CLI} del_peer tun2 $((2 + OVPN_ID_OFFSET)) || \
+ true
echo "Deleting keys:"
-for p in $(seq 3 ${NUM_PEERS}); do
- ip netns exec peer${p} ${OVPN_CLI} del_key tun${p} \
- $((${p} + ID_OFFSET)) 1
- ip netns exec peer${p} ${OVPN_CLI} del_key tun${p} \
- $((${p} + ID_OFFSET)) 2
+for p in $(seq 3 ${OVPN_NUM_PEERS}); do
+ ip netns exec "ovpn_peer${p}" ${OVPN_CLI} del_key tun${p} \
+ $((${p} + OVPN_ID_OFFSET)) 1
+ ip netns exec "ovpn_peer${p}" ${OVPN_CLI} del_key tun${p} \
+ $((${p} + OVPN_ID_OFFSET)) 2
done
echo "Setting timeout to 3s MP:"
-for p in $(seq 3 ${NUM_PEERS}); do
- ip netns exec peer0 ${OVPN_CLI} set_peer tun0 ${p} 3 3 || true
- ip netns exec peer${p} ${OVPN_CLI} set_peer tun${p} \
- $((${p} + ID_OFFSET)) 0 0
+for p in $(seq 3 ${OVPN_NUM_PEERS}); do
+ ip netns exec "${server_ns}" ${OVPN_CLI} set_peer tun0 ${p} 3 3 || true
+ ip netns exec "ovpn_peer${p}" ${OVPN_CLI} set_peer tun${p} \
+ $((${p} + OVPN_ID_OFFSET)) 0 0
done
# wait for peers to timeout
sleep 5
echo "Setting timeout to 3s P2P:"
-for p in $(seq 3 ${NUM_PEERS}); do
- ip netns exec peer${p} ${OVPN_CLI} set_peer tun${p} \
- $((${p} + ID_OFFSET)) 3 3
+for p in $(seq 3 ${OVPN_NUM_PEERS}); do
+ ip netns exec "ovpn_peer${p}" ${OVPN_CLI} set_peer tun${p} \
+ $((${p} + OVPN_ID_OFFSET)) 3 3
done
sleep 5
-for p in $(seq 0 ${NUM_PEERS}); do
- compare_ntfs ${p}
+for p in $(seq 0 ${OVPN_NUM_PEERS}); do
+ ovpn_compare_ntfs ${p}
done
-cleanup
+ovpn_cleanup
modprobe -r ovpn || true
--
2.52.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH net 5/6] selftests: ovpn: align command flow with TAP
2026-04-17 9:02 [PATCH net 0/6] pull request: fixes for ovpn 2026-04-17 Antonio Quartulli
` (3 preceding siblings ...)
2026-04-17 9:03 ` [PATCH net 4/6] selftests: ovpn: add prefix to helpers and shared variables Antonio Quartulli
@ 2026-04-17 9:03 ` Antonio Quartulli
2026-04-17 9:03 ` [PATCH net 6/6] selftests: ovpn: serialize YNL listener startup Antonio Quartulli
2026-04-18 18:54 ` [PATCH net 0/6] pull request: fixes for ovpn 2026-04-17 Jakub Kicinski
6 siblings, 0 replies; 9+ messages in thread
From: Antonio Quartulli @ 2026-04-17 9:03 UTC (permalink / raw)
To: netdev
Cc: ralf, shuah, horms, Sabrina Dubroca, Jakub Kicinski, Paolo Abeni,
Andrew Lunn, David S. Miller, Eric Dumazet, Antonio Quartulli
From: Ralf Lici <ralf@mandelbit.com>
Current tests do not properly adhere to the TAP infrastructure
therefore they do not properly report failures leading to hangs of
the CI machinery.
Restructure ovpn selftests into using the TAP infrastructure: split each
test in stages, execute stage bodies with fail-fast semantics, and emit
KTAP pass/fail for each stage.
Centralize behavior control in common.sh and makes the scripts use
dedicated wrappers for required-success, expected-failure, and non-fatal
commands. Also add the OVPN_VERBOSE mode that exposes captured command
output for debugging.
This way tests won't hang anymore in case of failure when executed
within the CI machinery.
This change also makes default OVPN_CLI and YNL resolution
independent from the caller CWD by anchoring both to COMMON_DIR, so
behavior is stable across direct execution and run_tests-style
execution.
Fixes: 959bc330a439 ("testing/selftests: add test tool and scripts for ovpn module")
Signed-off-by: Ralf Lici <ralf@mandelbit.com>
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
---
tools/testing/selftests/net/ovpn/common.sh | 182 +++++++-
.../selftests/net/ovpn/test-close-socket.sh | 90 ++--
tools/testing/selftests/net/ovpn/test-mark.sh | 236 ++++++----
tools/testing/selftests/net/ovpn/test.sh | 441 ++++++++++++------
4 files changed, 676 insertions(+), 273 deletions(-)
diff --git a/tools/testing/selftests/net/ovpn/common.sh b/tools/testing/selftests/net/ovpn/common.sh
index 38f187b9de23..2d844eb3aa6e 100644
--- a/tools/testing/selftests/net/ovpn/common.sh
+++ b/tools/testing/selftests/net/ovpn/common.sh
@@ -4,14 +4,18 @@
#
# Author: Antonio Quartulli <antonio@openvpn.net>
+OVPN_COMMON_DIR=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")
+source "$OVPN_COMMON_DIR/../../kselftest/ktap_helpers.sh"
+
OVPN_UDP_PEERS_FILE=${OVPN_UDP_PEERS_FILE:-udp_peers.txt}
OVPN_TCP_PEERS_FILE=${OVPN_TCP_PEERS_FILE:-tcp_peers.txt}
-OVPN_CLI=${OVPN_CLI:-./ovpn-cli}
-OVPN_YNL=${OVPN_YNL:-../../../../net/ynl/pyynl/cli.py}
+OVPN_CLI=${OVPN_CLI:-${OVPN_COMMON_DIR}/ovpn-cli}
+OVPN_YNL=${OVPN_YNL:-${OVPN_COMMON_DIR}/../../../../net/ynl/pyynl/cli.py}
OVPN_ALG=${OVPN_ALG:-aes}
OVPN_PROTO=${OVPN_PROTO:-UDP}
OVPN_FLOAT=${OVPN_FLOAT:-0}
OVPN_SYMMETRIC_ID=${OVPN_SYMMETRIC_ID:-0}
+OVPN_VERBOSE=${OVPN_VERBOSE:-0}
export OVPN_ID_OFFSET=$(( 9 * (OVPN_SYMMETRIC_ID == 0) ))
@@ -22,6 +26,111 @@ OVPN_LAN_IP="11.11.11.11"
declare -A OVPN_TMP_JSONS=()
declare -A OVPN_LISTENER_PIDS=()
+OVPN_CURRENT_STAGE=""
+
+ovpn_is_verbose() {
+ [[ "${OVPN_VERBOSE}" == "1" ]]
+}
+
+ovpn_log() {
+ ovpn_is_verbose || return 0
+ printf '%s\n' "$*"
+}
+
+ovpn_print_cmd_output() {
+ local output_file="$1"
+ local line
+
+ [[ -s "${output_file}" ]] || return 0
+
+ while IFS= read -r line; do
+ ovpn_log "${line}"
+ done < "${output_file}"
+}
+
+ovpn_cmd_run() {
+ local mode="$1"
+ local label="$2"
+ local output_file
+ local rc
+ local ret=0
+
+ shift 2
+
+ output_file=$(mktemp)
+ if "$@" >"${output_file}" 2>&1; then
+ rc=0
+ else
+ rc=$?
+ fi
+
+ case "${mode}" in
+ ok)
+ if [[ "${rc}" -ne 0 ]]; then
+ cat "${output_file}"
+ printf '%s\n' \
+ "${label}: command failed with rc=${rc}: $*"
+ ret="${rc}"
+ fi
+ ;;
+ mayfail)
+ ;;
+ fail)
+ [[ "${rc}" -eq 0 ]] && ret=1
+ ;;
+ esac
+
+ if ovpn_is_verbose && [[ "${rc}" -eq 0 || "${mode}" != "ok" ]]; then
+ ovpn_print_cmd_output "${output_file}"
+ fi
+
+ rm -f "${output_file}"
+ return "${ret}"
+}
+
+ovpn_cmd_ok() {
+ ovpn_cmd_run ok "$@"
+}
+
+ovpn_cmd_mayfail() {
+ ovpn_cmd_run mayfail "$@"
+}
+
+ovpn_cmd_fail() {
+ ovpn_cmd_run fail "$@"
+}
+
+ovpn_run_bg() {
+ local pid_var="$1"
+
+ shift
+ if ovpn_is_verbose; then
+ "$@" &
+ else
+ "$@" >/dev/null 2>&1 &
+ fi
+
+ printf -v "${pid_var}" '%s' "$!"
+}
+
+ovpn_run_stage() {
+ local label="$1"
+
+ shift
+ OVPN_CURRENT_STAGE="${label}"
+ "$@"
+ OVPN_CURRENT_STAGE=""
+ ktap_test_pass "${label}"
+}
+
+ovpn_stage_err() {
+ # ERR trap is global under set -eE: only report failures that happen
+ # while ovpn_run_stage() is actively executing a stage body.
+ if [[ -n "${OVPN_CURRENT_STAGE}" ]]; then
+ ktap_test_fail "${OVPN_CURRENT_STAGE}"
+ OVPN_CURRENT_STAGE=""
+ fi
+}
ovpn_create_ns() {
ip netns add "ovpn_peer${1}"
@@ -87,12 +196,16 @@ ovpn_build_capture_filter() {
}
ovpn_setup_listener() {
- local peer_ns="ovpn_peer${p}"
+ local peer="$1"
+ local file
+ local peer_ns="ovpn_peer${peer}"
+
file=$(mktemp)
PYTHONUNBUFFERED=1 ip netns exec "${peer_ns}" "${OVPN_YNL}" --family \
- ovpn --subscribe peers --output-json --duration 40 > ${file} &
- OVPN_LISTENER_PIDS[$1]=$!
- OVPN_TMP_JSONS[$1]="${file}"
+ ovpn --subscribe peers --output-json > "${file}" \
+ 2>/dev/null &
+ OVPN_LISTENER_PIDS["${peer}"]=$!
+ OVPN_TMP_JSONS["${peer}"]="${file}"
}
ovpn_add_peer() {
@@ -173,8 +286,7 @@ ovpn_compare_ntfs() {
received="${OVPN_TMP_JSONS[$1]}"
diff_file=$(mktemp)
- kill -TERM ${OVPN_LISTENER_PIDS[$1]} || true
- wait ${OVPN_LISTENER_PIDS[$1]} || true
+ ovpn_stop_listener "${1}" 1
printf "Checking notifications for peer ${1}... "
if diff <(jq -s "${OVPN_JQ_FILTER}" ${expected}) \
<(jq -s "${OVPN_JQ_FILTER}" ${received}) \
@@ -187,30 +299,60 @@ ovpn_compare_ntfs() {
fi
rm -f "${diff_file}" || true
- rm -f ${received} || true
+ rm -f "${received}" || true
+ unset "OVPN_TMP_JSONS[$1]"
fi
return "${diff_rc}"
}
+ovpn_stop_listener() {
+ local peer="$1"
+ local keep_json="${2:-0}"
+ local pid="${OVPN_LISTENER_PIDS[$peer]:-}"
+ local json="${OVPN_TMP_JSONS[$peer]:-}"
+
+ if [[ -n "${pid}" ]]; then
+ kill -TERM "${pid}" 2>/dev/null || true
+ wait "${pid}" 2>/dev/null || true
+ unset "OVPN_LISTENER_PIDS[$peer]"
+ fi
+
+ if [[ -n "${json}" && "${keep_json}" -eq 0 ]]; then
+ rm -f "${json}" || true
+ unset "OVPN_TMP_JSONS[$peer]"
+ fi
+}
+
+ovpn_cleanup_peer_ns() {
+ local peer="$1"
+ local peer_id="${peer#ovpn_peer}"
+
+ ip -n "${peer}" link set tun${peer_id} down 2>/dev/null || true
+ ip netns exec "${peer}" ${OVPN_CLI} del_iface tun${peer_id} \
+ 1>/dev/null 2>&1 || true
+ ip netns del "${peer}" 2>/dev/null || true
+}
+
ovpn_cleanup() {
- local peer_ns
+ local peer
+
# some ovpn-cli processes sleep in background so they need manual poking
- killall $(basename ${OVPN_CLI}) 2>/dev/null || true
+ killall "$(basename "${OVPN_CLI}")" 2>/dev/null || true
- # netns peer0 is deleted without erasing ifaces first
- for p in $(seq 1 10); do
- peer_ns="ovpn_peer${p}"
- ip -n "${peer_ns}" link set tun${p} down 2>/dev/null || true
- ip netns exec "${peer_ns}" ${OVPN_CLI} del_iface tun${p} \
- 2>/dev/null || true
+ for peer in "${!OVPN_LISTENER_PIDS[@]}"; do
+ ovpn_stop_listener "${peer}" 2>/dev/null
done
+
for p in $(seq 1 10); do
ip -n ovpn_peer0 link del veth${p} 2>/dev/null || true
done
- for p in $(seq 0 10); do
- ip netns del "ovpn_peer${p}" 2>/dev/null || true
- done
+
+ # remove from ovpn's netns pool
+ while IFS= read -r peer; do
+ [[ -n "${peer}" ]] || continue
+ ovpn_cleanup_peer_ns "${peer}" 2>/dev/null
+ done < <(ip netns list 2>/dev/null | awk '/^ovpn_/ {print $1}')
}
if [ "${OVPN_PROTO}" == "UDP" ]; then
diff --git a/tools/testing/selftests/net/ovpn/test-close-socket.sh b/tools/testing/selftests/net/ovpn/test-close-socket.sh
index 6bc1b6eab8ac..af1532b4d2da 100755
--- a/tools/testing/selftests/net/ovpn/test-close-socket.sh
+++ b/tools/testing/selftests/net/ovpn/test-close-socket.sh
@@ -5,43 +5,81 @@
# Author: Antonio Quartulli <antonio@openvpn.net>
#set -x
-set -e
+set -eE
source ./common.sh
-server_ns="ovpn_peer0"
-ovpn_cleanup
+ovpn_test_finished=0
-modprobe -q ovpn || true
+ovpn_test_exit() {
+ ovpn_cleanup
+ modprobe -r ovpn || true
+
+ if [ "${ovpn_test_finished}" -eq 0 ]; then
+ ktap_print_totals
+ fi
+}
+
+ovpn_prepare_network() {
+ local p
+ local peer_ns
+
+ for p in $(seq 0 ${OVPN_NUM_PEERS}); do
+ ovpn_cmd_ok "create namespace peer${p}" ovpn_create_ns "${p}"
+ done
-for p in $(seq 0 ${OVPN_NUM_PEERS}); do
- ovpn_create_ns ${p}
-done
+ for p in $(seq 0 ${OVPN_NUM_PEERS}); do
+ ovpn_cmd_ok "configure peer${p} namespace" ovpn_setup_ns \
+ "${p}" 5.5.5.$((p + 1))/24
+ done
-for p in $(seq 0 ${OVPN_NUM_PEERS}); do
- ovpn_setup_ns ${p} 5.5.5.$((${p} + 1))/24
-done
+ for p in $(seq 0 ${OVPN_NUM_PEERS}); do
+ ovpn_cmd_ok "register peer${p} in overlay" ovpn_add_peer "${p}"
+ done
-for p in $(seq 0 ${OVPN_NUM_PEERS}); do
- ovpn_add_peer ${p}
-done
+ for p in $(seq 1 ${OVPN_NUM_PEERS}); do
+ peer_ns="ovpn_peer${p}"
+ ovpn_cmd_ok "set peer0 timeout for peer ${p}" \
+ ip netns exec ovpn_peer0 ${OVPN_CLI} set_peer tun0 \
+ ${p} 60 120
+ ovpn_cmd_ok "set peer${p} timeout for peer ${p}" \
+ ip netns exec "${peer_ns}" ${OVPN_CLI} set_peer \
+ tun${p} $((p + OVPN_ID_OFFSET)) 60 120
+ done
+}
-for p in $(seq 1 ${OVPN_NUM_PEERS}); do
- ip netns exec "${server_ns}" ${OVPN_CLI} set_peer tun0 ${p} 60 120
- ip netns exec "ovpn_peer${p}" ${OVPN_CLI} set_peer tun${p} $((${p}+9)) \
- 60 120
-done
+ovpn_run_ping_traffic() {
+ local p
-sleep 1
+ for p in $(seq 1 ${OVPN_NUM_PEERS}); do
+ ovpn_cmd_ok "send ping traffic to peer ${p}" \
+ ip netns exec ovpn_peer0 ping -qfc 500 -w 3 \
+ 5.5.5.$((p + 1))
+ done
+}
-for p in $(seq 1 ${OVPN_NUM_PEERS}); do
- ip netns exec "${server_ns}" ping -qfc 500 -w 3 5.5.5.$((${p} + 1))
-done
+ovpn_run_iperf() {
+ local iperf_pid
-ip netns exec "${server_ns}" iperf3 -1 -s &
-sleep 1
-ip netns exec ovpn_peer1 iperf3 -Z -t 3 -c 5.5.5.1
+ ovpn_run_bg iperf_pid ip netns exec ovpn_peer0 iperf3 -1 -s
+ sleep 1
+ ovpn_cmd_ok "run iperf throughput flow" \
+ ip netns exec ovpn_peer1 iperf3 -Z -t 3 -c 5.5.5.1
+ wait "${iperf_pid}" || return 1
+}
+
+trap ovpn_test_exit EXIT
+trap ovpn_stage_err ERR
+
+ktap_print_header
+ktap_set_plan 3
ovpn_cleanup
+modprobe -q ovpn || true
+
+ovpn_run_stage "setup network topology" ovpn_prepare_network
+ovpn_run_stage "run ping traffic" ovpn_run_ping_traffic
+ovpn_run_stage "run iperf throughput" ovpn_run_iperf
-modprobe -r ovpn || true
+ovpn_test_finished=1
+ktap_finished
diff --git a/tools/testing/selftests/net/ovpn/test-mark.sh b/tools/testing/selftests/net/ovpn/test-mark.sh
index 2ee5dc5fc538..5a8f47554286 100755
--- a/tools/testing/selftests/net/ovpn/test-mark.sh
+++ b/tools/testing/selftests/net/ovpn/test-mark.sh
@@ -6,92 +6,166 @@
# Antonio Quartulli <antonio@openvpn.net>
#set -x
-set -e
+set -eE
MARK=1056
+MARK_DROP_COUNTER=0
source ./common.sh
-server_ns="ovpn_peer0"
-ovpn_cleanup
-
-modprobe -q ovpn || true
-
-for p in $(seq 0 "${OVPN_NUM_PEERS}"); do
- ovpn_create_ns "${p}"
-done
-
-for p in $(seq 0 3); do
- ovpn_setup_ns "${p}" 5.5.5.$((p + 1))/24
-done
-
-# add peer0 with mark
-ip netns exec "${server_ns}" "${OVPN_CLI}" new_multi_peer tun0 1 ASYMM \
- "${OVPN_UDP_PEERS_FILE}" \
- ${MARK}
-for p in $(seq 1 3); do
- ip netns exec "${server_ns}" "${OVPN_CLI}" new_key tun0 "${p}" 1 0 \
- "${OVPN_ALG}" 0 data64.key
-done
-
-for p in $(seq 1 3); do
- ovpn_add_peer "${p}"
-done
-
-for p in $(seq 1 3); do
- ip netns exec "${server_ns}" "${OVPN_CLI}" set_peer tun0 "${p}" 60 120
- ip netns exec "ovpn_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 "${server_ns}" ping -qfc 500 -w 3 5.5.5.$((p + 1))
-done
-
-echo "Adding an nftables drop rule based on mark value ${MARK}"
-ip netns exec "${server_ns}" nft flush ruleset
-ip netns exec "${server_ns}" nft 'add table inet filter'
-ip netns exec "${server_ns}" nft 'add chain inet filter output {
- type filter hook output priority 0;
- policy accept;
-}'
-ip netns exec "${server_ns}" nft add rule inet filter output \
- meta mark == ${MARK} \
- counter drop
-
-DROP_COUNTER=$(ip netns exec "${server_ns}" 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 "${server_ns}" ping \
- -qfc 500 -w 1 5.5.5.$((p + 1)) 2>&1) && exit 1
- echo "${PING_OUTPUT}"
- LOST_PACKETS=$(echo "$PING_OUTPUT" \
- | awk '/packets transmitted/ { 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 "${server_ns}" nft list chain inet filter output \
- | sed -n 's/.*packets \([0-9]*\).*/\1/p')
-if [ "${DROP_COUNTER}" -ne "${TOTAL_COUNT}" ]; then
- echo "Expected ${TOTAL_COUNT} drops, got ${DROP_COUNTER}"
- exit 1
-fi
-
-echo "Removing the drop rule"
-ip netns exec "${server_ns}" nft flush ruleset
-sleep 1
-
-for p in $(seq 1 3); do
- ip netns exec "${server_ns}" ping -qfc 500 -w 3 5.5.5.$((p + 1))
-done
+ovpn_test_finished=0
+
+ovpn_test_exit() {
+ ovpn_cleanup
+ modprobe -r ovpn || true
+
+ if [ "${ovpn_test_finished}" -eq 0 ]; then
+ ktap_print_totals
+ fi
+}
+
+ovpn_mark_prepare_network() {
+ local p
+ local peer_ns
+
+ for p in $(seq 0 "${OVPN_NUM_PEERS}"); do
+ ovpn_cmd_ok "create namespace peer${p}" ovpn_create_ns "${p}"
+ done
+
+ for p in $(seq 0 3); do
+ ovpn_cmd_ok "configure peer${p} namespace" ovpn_setup_ns \
+ "${p}" 5.5.5.$((p + 1))/24
+ done
+
+ ovpn_cmd_ok "create server-side multi-peer with fwmark" \
+ ip netns exec ovpn_peer0 "${OVPN_CLI}" new_multi_peer tun0 1 \
+ ASYMM "${OVPN_UDP_PEERS_FILE}" "${MARK}"
+ for p in $(seq 1 3); do
+ ovpn_cmd_ok "install server key for peer ${p}" \
+ ip netns exec ovpn_peer0 "${OVPN_CLI}" new_key tun0 \
+ "${p}" 1 0 "${OVPN_ALG}" 0 data64.key
+ done
+
+ for p in $(seq 1 3); do
+ ovpn_cmd_ok "register peer${p} in overlay" ovpn_add_peer "${p}"
+ done
+
+ for p in $(seq 1 3); do
+ peer_ns="ovpn_peer${p}"
+ ovpn_cmd_ok "set peer0 timeout for peer ${p}" \
+ ip netns exec ovpn_peer0 "${OVPN_CLI}" set_peer tun0 \
+ "${p}" 60 120
+ ovpn_cmd_ok "set peer${p} timeout for peer ${p}" \
+ ip netns exec "${peer_ns}" "${OVPN_CLI}" set_peer \
+ tun"${p}" $((p + OVPN_ID_OFFSET)) 60 120
+ done
+}
+
+ovpn_mark_run_baseline_traffic() {
+ local p
+
+ for p in $(seq 1 3); do
+ ovpn_cmd_ok "send baseline traffic to peer ${p}" \
+ ip netns exec ovpn_peer0 ping -qfc 500 -w 3 \
+ 5.5.5.$((p + 1))
+ done
+}
+
+ovpn_mark_add_drop_rule() {
+ ovpn_log "Adding an nftables drop rule based on mark value ${MARK}"
+
+ ovpn_cmd_ok "flush nft ruleset" ip netns exec ovpn_peer0 nft flush \
+ ruleset
+ ovpn_cmd_ok "create nft filter table" ip netns exec ovpn_peer0 nft \
+ "add table inet filter"
+ ovpn_cmd_ok "create nft filter output chain" \
+ ip netns exec ovpn_peer0 nft "add chain inet filter output { \
+ type filter hook output priority 0; policy accept; }"
+ ovpn_cmd_ok "add nft drop rule for mark ${MARK}" \
+ ip netns exec ovpn_peer0 nft add rule inet filter output \
+ meta mark == "${MARK}" \
+ counter drop
+
+ MARK_DROP_COUNTER=$(ip netns exec ovpn_peer0 nft list chain inet \
+ filter output | sed -n 's/.*packets \([0-9]*\).*/\1/p')
+ if [ -z "${MARK_DROP_COUNTER}" ]; then
+ printf '%s\n' "unable to read nft drop counter"
+ return 1
+ fi
+}
+
+ovpn_mark_verify_drop_traffic() {
+ local p
+ local ping_output
+ local lost_packets
+ local total_count
+
+ for p in $(seq 1 3); do
+ if ping_output=$(ip netns exec ovpn_peer0 ping -qfc 500 -w 1 \
+ 5.5.5.$((p + 1)) 2>&1); then
+ printf '%s\n' "expected ping to peer ${p} to fail \
+ after nft drop rule"
+ return 1
+ fi
+ ovpn_log "${ping_output}"
+ lost_packets=$(echo "${ping_output}" | \
+ awk '/packets transmitted/ { print $1 }')
+ if [ -z "${lost_packets}" ]; then
+ printf '%s\n' "unable to parse lost packets for peer \
+ ${p}"
+ return 1
+ fi
+ MARK_DROP_COUNTER=$((MARK_DROP_COUNTER + lost_packets))
+ done
+
+ total_count=$(ip netns exec ovpn_peer0 nft list chain inet filter \
+ output | sed -n 's/.*packets \([0-9]*\).*/\1/p')
+ if [ -z "${total_count}" ]; then
+ printf '%s\n' "unable to read final nft drop counter"
+ return 1
+ fi
+ if [ "${MARK_DROP_COUNTER}" -ne "${total_count}" ]; then
+ printf '%s\n' "expected ${MARK_DROP_COUNTER} drops, got \
+ ${total_count}"
+ return 1
+ fi
+}
+
+ovpn_mark_remove_drop_rule() {
+ ovpn_log "Removing the drop rule"
+
+ ovpn_cmd_ok "flush nft ruleset" ip netns exec ovpn_peer0 nft flush \
+ ruleset
+}
+
+ovpn_mark_verify_traffic_recovery() {
+ local p
+
+ sleep 1
+ for p in $(seq 1 3); do
+ ovpn_cmd_ok "send recovery traffic to peer ${p}" \
+ ip netns exec ovpn_peer0 ping -qfc 500 -w 3 \
+ 5.5.5.$((p + 1))
+ done
+}
+
+trap ovpn_test_exit EXIT
+trap ovpn_stage_err ERR
+
+ktap_print_header
+ktap_set_plan 6
ovpn_cleanup
+modprobe -q ovpn || true
-modprobe -r ovpn || true
+ovpn_run_stage "setup marked network topology" ovpn_mark_prepare_network
+ovpn_run_stage "run baseline traffic" ovpn_mark_run_baseline_traffic
+ovpn_run_stage "install nft mark drop rule" ovpn_mark_add_drop_rule
+ovpn_run_stage "drop marked traffic and count packets" \
+ ovpn_mark_verify_drop_traffic
+ovpn_run_stage "remove nft drop rule" ovpn_mark_remove_drop_rule
+ovpn_run_stage "traffic recovers after drop removal" \
+ ovpn_mark_verify_traffic_recovery
+
+ovpn_test_finished=1
+ktap_finished
diff --git a/tools/testing/selftests/net/ovpn/test.sh b/tools/testing/selftests/net/ovpn/test.sh
index b766f4842940..eca653112aeb 100755
--- a/tools/testing/selftests/net/ovpn/test.sh
+++ b/tools/testing/selftests/net/ovpn/test.sh
@@ -5,164 +5,313 @@
# Author: Antonio Quartulli <antonio@openvpn.net>
#set -x
-set -e
+set -eE
source ./common.sh
-server_ns="ovpn_peer0"
-ovpn_cleanup
+ovpn_test_finished=0
-modprobe -q ovpn || true
+ovpn_test_exit() {
+ ovpn_cleanup
+ modprobe -r ovpn || true
-for p in $(seq 0 ${OVPN_NUM_PEERS}); do
- ovpn_create_ns ${p}
-done
-
-for p in $(seq 0 ${OVPN_NUM_PEERS}); do
- ovpn_setup_listener ${p}
-done
-
-for p in $(seq 0 ${OVPN_NUM_PEERS}); do
- ovpn_setup_ns ${p} 5.5.5.$((${p} + 1))/24 ${MTU}
-done
-
-for p in $(seq 0 ${OVPN_NUM_PEERS}); do
- ovpn_add_peer ${p}
-done
-
-for p in $(seq 1 ${OVPN_NUM_PEERS}); do
- ip netns exec "${server_ns}" ${OVPN_CLI} set_peer tun0 ${p} 60 120
- ip netns exec "ovpn_peer${p}" ${OVPN_CLI} set_peer tun${p} \
- $((${p}+OVPN_ID_OFFSET)) 60 120
-done
-
-sleep 1
-
-TCPDUMP_TIMEOUT="1.5s"
-for p in $(seq 1 ${OVPN_NUM_PEERS}); do
- # The first part of the data packet header consists of:
- # - TCP only: 2 bytes for the packet length
- # - 5 bits for opcode ("9" for DATA_V2)
- # - 3 bits for key-id ("0" at this point)
- # - 12 bytes for peer-id:
- # - with asymmetric ID: "${p}" one way and "${p} + 9" the other way
- # - with symmetric ID: "${p}" both ways
- HEADER1=$(printf "0x4800000%x" ${p})
- HEADER2=$(printf "0x4800000%x" $((${p} + OVPN_ID_OFFSET)))
- RADDR=""
- if [ "${OVPN_PROTO}" == "UDP" ]; then
- RADDR=$(awk "NR == ${p} {print \$3}" ${OVPN_UDP_PEERS_FILE})
+ if [ "${ovpn_test_finished}" -eq 0 ]; then
+ ktap_print_totals
fi
+}
+
+ovpn_prepare_network() {
+ local p
+ local peer_ns
+
+ for p in $(seq 0 ${OVPN_NUM_PEERS}); do
+ ovpn_cmd_ok "create namespace peer${p}" ovpn_create_ns "${p}"
+ done
+
+ for p in $(seq 0 ${OVPN_NUM_PEERS}); do
+ ovpn_cmd_ok "start notification listener peer${p}" \
+ ovpn_setup_listener "${p}"
+ done
+
+ for p in $(seq 0 ${OVPN_NUM_PEERS}); do
+ ovpn_cmd_ok "configure peer${p} namespace" ovpn_setup_ns \
+ "${p}" 5.5.5.$((p + 1))/24 "${MTU}"
+ done
+
+ for p in $(seq 0 ${OVPN_NUM_PEERS}); do
+ ovpn_cmd_ok "register peer${p} in overlay" ovpn_add_peer "${p}"
+ done
- timeout ${TCPDUMP_TIMEOUT} ip netns exec "ovpn_peer${p}" \
- tcpdump --immediate-mode -p -ni veth${p} -c 1 \
- "$(ovpn_build_capture_filter "${HEADER1}" "${RADDR}")" \
- >/dev/null 2>&1 &
- TCPDUMP_PID1=$!
- timeout ${TCPDUMP_TIMEOUT} ip netns exec "ovpn_peer${p}" \
- tcpdump --immediate-mode -p -ni veth${p} -c 1 \
- "$(ovpn_build_capture_filter "${HEADER2}" "${RADDR}")" \
- >/dev/null 2>&1 &
- TCPDUMP_PID2=$!
-
- sleep 0.3
- ip netns exec "${server_ns}" ping -qfc 500 -w 3 5.5.5.$((${p} + 1))
- ip netns exec "${server_ns}" ping -qfc 500 -s 3000 -w 3 \
- 5.5.5.$((${p} + 1))
-
- wait ${TCPDUMP_PID1}
- wait ${TCPDUMP_PID2}
-done
-
-# ping LAN behind client 1
-ip netns exec "${server_ns}" ping -qfc 500 -w 3 ${OVPN_LAN_IP}
-
-if [ "$OVPN_FLOAT" == "1" ]; then
- # make clients float..
for p in $(seq 1 ${OVPN_NUM_PEERS}); do
- ip -n "ovpn_peer${p}" addr del 10.10.${p}.2/24 dev veth${p}
- ip -n "ovpn_peer${p}" addr add 10.10.${p}.3/24 dev veth${p}
+ peer_ns="ovpn_peer${p}"
+ ovpn_cmd_ok "set peer0 timeout for peer ${p}" \
+ ip netns exec ovpn_peer0 ${OVPN_CLI} set_peer tun0 \
+ ${p} 60 120
+ ovpn_cmd_ok "set peer${p} timeout for peer ${p}" \
+ ip netns exec "${peer_ns}" ${OVPN_CLI} set_peer \
+ tun${p} $((p + OVPN_ID_OFFSET)) 60 120
done
+}
+
+ovpn_run_basic_traffic() {
+ local p
+ local header1
+ local header2
+ local peer_ns
+ local raddr
+ local tcpdump_pid1
+ local tcpdump_pid2
+ local tcpdump_timeout="1.5s"
+
for p in $(seq 1 ${OVPN_NUM_PEERS}); do
- ip netns exec "ovpn_peer${p}" ping -qfc 500 -w 3 5.5.5.1
+ # The first part of the data packet header consists of:
+ # - TCP only: 2 bytes for the packet length
+ # - 5 bits for opcode ("9" for DATA_V2)
+ # - 3 bits for key-id ("0" at this point)
+ # - 12 bytes for peer-id:
+ # - with asymmetric ID: "${p}" one way and "${p} + 9" the
+ # other way
+ # - with symmetric ID: "${p}" both ways
+ header1=$(printf "0x4800000%x" ${p})
+ header2=$(printf "0x4800000%x" $((p + OVPN_ID_OFFSET)))
+ raddr=""
+ if [ "${OVPN_PROTO}" == "UDP" ]; then
+ raddr=$(awk "NR == ${p} {print \$3}" \
+ "${OVPN_UDP_PEERS_FILE}")
+ fi
+ peer_ns="ovpn_peer${p}"
+
+ timeout ${tcpdump_timeout} ip netns exec "${peer_ns}" \
+ tcpdump --immediate-mode -p -ni veth${p} -c 1 \
+ "$(ovpn_build_capture_filter "${header1}" "${raddr}")" \
+ >/dev/null 2>&1 &
+ tcpdump_pid1=$!
+ timeout ${tcpdump_timeout} ip netns exec "${peer_ns}" \
+ tcpdump --immediate-mode -p -ni veth${p} -c 1 \
+ "$(ovpn_build_capture_filter "${header2}" "${raddr}")" \
+ >/dev/null 2>&1 &
+ tcpdump_pid2=$!
+
+ sleep 0.3
+ ovpn_cmd_ok "send baseline traffic to peer ${p}" \
+ ip netns exec ovpn_peer0 \
+ ping -qfc 500 -w 3 5.5.5.$((p + 1))
+ ovpn_cmd_ok "send large-payload traffic to peer ${p}" \
+ ip netns exec ovpn_peer0 \
+ ping -qfc 500 -s 3000 -w 3 5.5.5.$((p + 1))
+
+ wait "${tcpdump_pid1}" || return 1
+ wait "${tcpdump_pid2}" || return 1
done
-fi
+}
+
+ovpn_run_lan_traffic() {
+ ovpn_cmd_ok "ping LAN behind peer1" \
+ ip netns exec ovpn_peer0 ping -qfc 500 -w 3 "${OVPN_LAN_IP}"
+}
+
+ovpn_run_float_mode() {
+ local p
+ local peer_ns
+
+ for p in $(seq 1 ${OVPN_NUM_PEERS}); do
+ peer_ns="ovpn_peer${p}"
+ ovpn_cmd_ok "float: remove old transport address on peer${p}" \
+ ip -n "${peer_ns}" addr del 10.10.${p}.2/24 dev veth${p}
+ ovpn_cmd_ok "float: add new transport address on peer${p}" \
+ ip -n "${peer_ns}" addr add 10.10.${p}.3/24 dev veth${p}
+ done
+ for p in $(seq 1 ${OVPN_NUM_PEERS}); do
+ peer_ns="ovpn_peer${p}"
+ ovpn_cmd_ok "ping tunnel after float peer ${p}" \
+ ip netns exec "${peer_ns}" ping -qfc 500 -w 3 5.5.5.1
+ done
+}
+
+ovpn_run_iperf() {
+ local iperf_pid
+
+ ovpn_run_bg iperf_pid ip netns exec ovpn_peer0 iperf3 -1 -s
+ sleep 1
+
+ ovpn_cmd_ok "run iperf throughput flow" \
+ ip netns exec ovpn_peer1 iperf3 -Z -t 3 -c 5.5.5.1
+ wait "${iperf_pid}" || return 1
+}
+
+ovpn_run_key_rollover() {
+ local p
+ local peer_ns
+
+ ovpn_log "Adding secondary key and then swap:"
+
+ for p in $(seq 1 ${OVPN_NUM_PEERS}); do
+ peer_ns="ovpn_peer${p}"
+ ovpn_cmd_ok "add secondary key on peer0 for peer ${p}" \
+ ip netns exec ovpn_peer0 ${OVPN_CLI} new_key tun0 \
+ ${p} 2 1 ${OVPN_ALG} 0 data64.key
+ ovpn_cmd_ok "add secondary key on peer${p} for peer ${p}" \
+ ip netns exec "${peer_ns}" ${OVPN_CLI} new_key tun${p} \
+ $((p + OVPN_ID_OFFSET)) 2 1 ${OVPN_ALG} 1 \
+ data64.key
+ ovpn_cmd_ok "swap keys on peer${p}" \
+ ip netns exec "${peer_ns}" ${OVPN_CLI} swap_keys \
+ tun${p} $((p + OVPN_ID_OFFSET))
+ done
+}
+
+ovpn_run_queries() {
+ ovpn_log "Querying all peers:"
+
+ ovpn_cmd_ok "query all peers from peer0" \
+ ip netns exec ovpn_peer0 ${OVPN_CLI} get_peer tun0
+ ovpn_cmd_ok "query all peers from peer1" \
+ ip netns exec ovpn_peer1 ${OVPN_CLI} get_peer tun1
-ip netns exec "${server_ns}" iperf3 -1 -s &
-sleep 1
-ip netns exec ovpn_peer1 iperf3 -Z -t 3 -c 5.5.5.1
-
-echo "Adding secondary key and then swap:"
-for p in $(seq 1 ${OVPN_NUM_PEERS}); do
- ip netns exec "${server_ns}" ${OVPN_CLI} new_key tun0 ${p} 2 1 \
- ${OVPN_ALG} 0 data64.key
- ip netns exec "ovpn_peer${p}" ${OVPN_CLI} new_key tun${p} \
- $((${p} + OVPN_ID_OFFSET)) 2 1 ${OVPN_ALG} 1 data64.key
- ip netns exec "ovpn_peer${p}" ${OVPN_CLI} swap_keys tun${p} \
- $((${p} + OVPN_ID_OFFSET))
-done
-
-sleep 1
-
-echo "Querying all peers:"
-ip netns exec "${server_ns}" ${OVPN_CLI} get_peer tun0
-ip netns exec ovpn_peer1 ${OVPN_CLI} get_peer tun1
-
-echo "Querying peer 1:"
-ip netns exec "${server_ns}" ${OVPN_CLI} get_peer tun0 1
-
-echo "Querying non-existent peer 20:"
-ip netns exec "${server_ns}" ${OVPN_CLI} get_peer tun0 20 || true
-
-echo "Deleting peer 1:"
-ip netns exec "${server_ns}" ${OVPN_CLI} del_peer tun0 1
-ip netns exec ovpn_peer1 ${OVPN_CLI} del_peer tun1 $((1 + OVPN_ID_OFFSET))
-
-echo "Querying keys:"
-for p in $(seq 2 ${OVPN_NUM_PEERS}); do
- ip netns exec "ovpn_peer${p}" ${OVPN_CLI} get_key tun${p} \
- $((${p} + OVPN_ID_OFFSET)) 1
- ip netns exec "ovpn_peer${p}" ${OVPN_CLI} get_key tun${p} \
- $((${p} + OVPN_ID_OFFSET)) 2
-done
-
-echo "Deleting peer while sending traffic:"
-(ip netns exec ovpn_peer2 ping -qf -w 4 5.5.5.1)&
-sleep 2
-ip netns exec "${server_ns}" ${OVPN_CLI} del_peer tun0 2
-# following command fails in TCP mode
-# (both ends get conn reset when one peer disconnects)
-ip netns exec ovpn_peer2 ${OVPN_CLI} del_peer tun2 $((2 + OVPN_ID_OFFSET)) || \
- true
-
-echo "Deleting keys:"
-for p in $(seq 3 ${OVPN_NUM_PEERS}); do
- ip netns exec "ovpn_peer${p}" ${OVPN_CLI} del_key tun${p} \
- $((${p} + OVPN_ID_OFFSET)) 1
- ip netns exec "ovpn_peer${p}" ${OVPN_CLI} del_key tun${p} \
- $((${p} + OVPN_ID_OFFSET)) 2
-done
-
-echo "Setting timeout to 3s MP:"
-for p in $(seq 3 ${OVPN_NUM_PEERS}); do
- ip netns exec "${server_ns}" ${OVPN_CLI} set_peer tun0 ${p} 3 3 || true
- ip netns exec "ovpn_peer${p}" ${OVPN_CLI} set_peer tun${p} \
- $((${p} + OVPN_ID_OFFSET)) 0 0
-done
-# wait for peers to timeout
-sleep 5
-
-echo "Setting timeout to 3s P2P:"
-for p in $(seq 3 ${OVPN_NUM_PEERS}); do
- ip netns exec "ovpn_peer${p}" ${OVPN_CLI} set_peer tun${p} \
- $((${p} + OVPN_ID_OFFSET)) 3 3
-done
-sleep 5
-
-for p in $(seq 0 ${OVPN_NUM_PEERS}); do
- ovpn_compare_ntfs ${p}
-done
+ ovpn_log "Querying peer 1:"
+
+ ovpn_cmd_ok "query peer 1 from peer0" \
+ ip netns exec ovpn_peer0 ${OVPN_CLI} get_peer tun0 1
+}
+
+ovpn_query_peer_missing() {
+ ovpn_log "Querying non-existent peer 20:"
+
+ ovpn_cmd_fail "query missing peer 20 on peer0" \
+ ip netns exec ovpn_peer0 ${OVPN_CLI} get_peer tun0 20
+}
+
+ovpn_run_peer_cleanup() {
+ local p
+ local peer_ns
+
+ ovpn_log "Deleting peer 1:"
+
+ ovpn_cmd_ok "delete peer1 on peer0" \
+ ip netns exec ovpn_peer0 ${OVPN_CLI} del_peer tun0 1
+ ovpn_cmd_ok "delete peer1 on peer1" \
+ ip netns exec ovpn_peer1 ${OVPN_CLI} del_peer tun1 \
+ $((1 + OVPN_ID_OFFSET))
+
+ ovpn_log "Querying keys:"
+
+ for p in $(seq 2 ${OVPN_NUM_PEERS}); do
+ peer_ns="ovpn_peer${p}"
+ ovpn_cmd_ok "query peer${p} key 1" \
+ ip netns exec "${peer_ns}" ${OVPN_CLI} get_key tun${p} \
+ $((p + OVPN_ID_OFFSET)) 1
+ ovpn_cmd_ok "query peer${p} key 2" \
+ ip netns exec "${peer_ns}" ${OVPN_CLI} get_key tun${p} \
+ $((p + OVPN_ID_OFFSET)) 2
+ done
+}
+
+ovpn_run_traffic_delete_peer() {
+ local ping_pid
+
+ ovpn_log "Deleting peer while sending traffic:"
+
+ ovpn_run_bg ping_pid ip netns exec ovpn_peer2 ping -qf -w 4 5.5.5.1
+ sleep 2
+ ovpn_cmd_ok "delete peer0 peer 2" \
+ ip netns exec ovpn_peer0 ${OVPN_CLI} del_peer tun0 2
+
+ if [ "${OVPN_PROTO}" == "TCP" ]; then
+ # In TCP mode this command is expected to fail for both peers.
+ ovpn_cmd_mayfail "delete peer2 peer 2 (TCP non-fatal)" \
+ ip netns exec ovpn_peer2 ${OVPN_CLI} del_peer tun2 \
+ $((2 + OVPN_ID_OFFSET))
+ else
+ ovpn_cmd_ok "delete peer2 peer 2" ip netns exec ovpn_peer2 \
+ ${OVPN_CLI} del_peer tun2 $((2 + OVPN_ID_OFFSET))
+ fi
+
+ wait "${ping_pid}" || true
+}
+
+ovpn_run_key_cleanup() {
+ local p
+ local peer_ns
+
+ ovpn_log "Deleting keys:"
+
+ for p in $(seq 3 ${OVPN_NUM_PEERS}); do
+ peer_ns="ovpn_peer${p}"
+ ovpn_cmd_ok "delete key 1 for peer${p}" \
+ ip netns exec "${peer_ns}" ${OVPN_CLI} del_key tun${p} \
+ $((p + OVPN_ID_OFFSET)) 1
+ ovpn_cmd_ok "delete key 2 for peer${p}" \
+ ip netns exec "${peer_ns}" ${OVPN_CLI} del_key tun${p} \
+ $((p + OVPN_ID_OFFSET)) 2
+ done
+}
+
+ovpn_run_timeouts() {
+ local p
+ local peer_ns
+
+ ovpn_log "Setting timeout to 3s MP:"
+
+ for p in $(seq 3 ${OVPN_NUM_PEERS}); do
+ # Non-fatal: this may fail in some protocol modes.
+ ovpn_cmd_mayfail "set peer0 timeout for peer ${p} (non-fatal)" \
+ ip netns exec ovpn_peer0 ${OVPN_CLI} set_peer tun0 \
+ ${p} 3 3
+ peer_ns="ovpn_peer${p}"
+ ovpn_cmd_ok "disable timeout on peer${p} while peer0 adjusts \
+ state" ip netns exec "${peer_ns}" ${OVPN_CLI} set_peer \
+ tun${p} $((p + OVPN_ID_OFFSET)) 0 0
+ done
+ # wait for peers to timeout
+ sleep 5
+
+ ovpn_log "Setting timeout to 3s P2P:"
+
+ for p in $(seq 3 ${OVPN_NUM_PEERS}); do
+ peer_ns="ovpn_peer${p}"
+ ovpn_cmd_ok "set peer${p} P2P timeout" \
+ ip netns exec "${peer_ns}" ${OVPN_CLI} set_peer \
+ tun${p} $((p + OVPN_ID_OFFSET)) 3 3
+ done
+ sleep 5
+}
+
+ovpn_run_notifications() {
+ local p
+
+ for p in $(seq 0 ${OVPN_NUM_PEERS}); do
+ ovpn_cmd_ok "validate listener output for peer ${p}" \
+ ovpn_compare_ntfs "${p}"
+ done
+}
+
+trap ovpn_test_exit EXIT
+trap ovpn_stage_err ERR
+
+ktap_print_header
+if [ "${OVPN_FLOAT}" == "1" ]; then
+ ktap_set_plan 13
+else
+ ktap_set_plan 12
+fi
ovpn_cleanup
+modprobe -q ovpn || true
+
+ovpn_run_stage "setup network topology" ovpn_prepare_network
+ovpn_run_stage "run baseline data traffic" ovpn_run_basic_traffic
+ovpn_run_stage "run LAN traffic behind peer1" ovpn_run_lan_traffic
+[ "${OVPN_FLOAT}" == "1" ] && ovpn_run_stage "run floating peer checks" \
+ ovpn_run_float_mode
+ovpn_run_stage "run iperf throughput" ovpn_run_iperf
+ovpn_run_stage "run key rollout" ovpn_run_key_rollover
+ovpn_run_stage "query peers" ovpn_run_queries
+ovpn_run_stage "query missing peer fails" ovpn_query_peer_missing
+ovpn_run_stage "peer lifecycle and key queries" ovpn_run_peer_cleanup
+ovpn_run_stage "delete peer while traffic" ovpn_run_traffic_delete_peer
+ovpn_run_stage "delete stale keys" ovpn_run_key_cleanup
+ovpn_run_stage "check timeout behavior" ovpn_run_timeouts
+ovpn_run_stage "validate notification output" ovpn_run_notifications
-modprobe -r ovpn || true
+ovpn_test_finished=1
+ktap_finished
--
2.52.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH net 6/6] selftests: ovpn: serialize YNL listener startup
2026-04-17 9:02 [PATCH net 0/6] pull request: fixes for ovpn 2026-04-17 Antonio Quartulli
` (4 preceding siblings ...)
2026-04-17 9:03 ` [PATCH net 5/6] selftests: ovpn: align command flow with TAP Antonio Quartulli
@ 2026-04-17 9:03 ` Antonio Quartulli
2026-04-18 18:54 ` [PATCH net 0/6] pull request: fixes for ovpn 2026-04-17 Jakub Kicinski
6 siblings, 0 replies; 9+ messages in thread
From: Antonio Quartulli @ 2026-04-17 9:03 UTC (permalink / raw)
To: netdev
Cc: ralf, shuah, horms, Sabrina Dubroca, Jakub Kicinski, Paolo Abeni,
Andrew Lunn, David S. Miller, Eric Dumazet, Antonio Quartulli
From: Ralf Lici <ralf@mandelbit.com>
Starting one background YNL notification listener per peer back-to-back
can intermittently stall the test setup before the listeners even reach
the Python main function.
This was reproducible in a reduced test.sh setup-only loop: a single
listener stayed stable across repeated runs, while starting listeners
for all peers could hang early in the listener launch phase. Adding a
short delay between listener launches makes the listeners start cleanly
and eliminates the reproduced hangs in repeated normal and slow-runner
tests.
Serialize listener startup with a small sleep between setup_listener
calls.
Fixes: 77de28cd7cf1 ("selftests: ovpn: add notification parsing and matching")
Signed-off-by: Ralf Lici <ralf@mandelbit.com>
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
---
tools/testing/selftests/net/ovpn/test.sh | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tools/testing/selftests/net/ovpn/test.sh b/tools/testing/selftests/net/ovpn/test.sh
index eca653112aeb..b50dbe45a4d0 100755
--- a/tools/testing/selftests/net/ovpn/test.sh
+++ b/tools/testing/selftests/net/ovpn/test.sh
@@ -31,6 +31,9 @@ ovpn_prepare_network() {
for p in $(seq 0 ${OVPN_NUM_PEERS}); do
ovpn_cmd_ok "start notification listener peer${p}" \
ovpn_setup_listener "${p}"
+ # starting all YNL listeners back-to-back can intermittently
+ # stall their startup so serialize launches a bit
+ sleep 0.5
done
for p in $(seq 0 ${OVPN_NUM_PEERS}); do
--
2.52.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH net 0/6] pull request: fixes for ovpn 2026-04-17
2026-04-17 9:02 [PATCH net 0/6] pull request: fixes for ovpn 2026-04-17 Antonio Quartulli
` (5 preceding siblings ...)
2026-04-17 9:03 ` [PATCH net 6/6] selftests: ovpn: serialize YNL listener startup Antonio Quartulli
@ 2026-04-18 18:54 ` Jakub Kicinski
6 siblings, 0 replies; 9+ messages in thread
From: Jakub Kicinski @ 2026-04-18 18:54 UTC (permalink / raw)
To: Antonio Quartulli
Cc: netdev, ralf, shuah, horms, Sabrina Dubroca, Paolo Abeni,
Andrew Lunn, David S. Miller, Eric Dumazet
On Fri, 17 Apr 2026 11:02:59 +0200 Antonio Quartulli wrote:
> This is a respin of the PR I originally sent against net-next + an extra
> fix (patch 6).
>
> Please note that this patch:
> https://lore.kernel.org/all/20260225010833.11301-1-liuhangbin@gmail.com/
> broke the selftests entirely due to the switch from sh to bash.
>
> There are new commits in the kselftest tree which take care of this:
> https://lore.kernel.org/all/20260416-selftest-fix-readlink-e-v1-0-94e4cabbdec4@kernel.org/
> but they are not in net yet, therefore you won't be able to test/run
> our kselftests for now.
It does work for us, FWIW, maybe because we run tests with make
run_tests. There were some entirely unnecessary changes to ktap
output which broke our systems but we patched around them :/
> TCP tests are still failing every now and then.
> It seems that sometimes a single ping over a TCP tunnel is lost,
> thus making the selftest fail.
They seem to fail for us around 50% of the time on debug kernel
builds. What's your repro rate?
> We believe this is a bug in ovpn which we are currently hunting down.
> So it's nothing wrong about the tests (they are actually doing their
> job!).
FWIW one of today's runs hit this:
https://netdev-ctrl.bots.linux.dev/logs/vmksft/net-extra-dbg/results/608740/3-test-symmetric-id-tcp-sh/stderr
decoded:
https://netdev-ctrl.bots.linux.dev/logs/vmksft/net-extra-dbg/results/608740/vm-crash-thr0-0
In any case - test_mark.sh looks good now, so I'll take it out of
the ignored list. Thanks! 2 more to go? :)
^ permalink raw reply [flat|nested] 9+ messages in thread