xref: /linux/tools/testing/selftests/net/ovpn/test-mark.sh (revision 68993ced0f618e36cf33388f1e50223e5e6e78cc)
17b80d8a3SRalf Lici#!/bin/bash
27b80d8a3SRalf Lici# SPDX-License-Identifier: GPL-2.0
37b80d8a3SRalf Lici# Copyright (C) 2020-2025 OpenVPN, Inc.
47b80d8a3SRalf Lici#
57b80d8a3SRalf Lici#	Author:	Ralf Lici <ralf@mandelbit.com>
67b80d8a3SRalf Lici#		Antonio Quartulli <antonio@openvpn.net>
77b80d8a3SRalf Lici
87b80d8a3SRalf Lici#set -x
91be93bb9SRalf Liciset -eE
107b80d8a3SRalf Lici
117b80d8a3SRalf LiciMARK=1056
121be93bb9SRalf LiciMARK_DROP_COUNTER=0
137b80d8a3SRalf Lici
147b80d8a3SRalf Licisource ./common.sh
157b80d8a3SRalf Lici
161be93bb9SRalf Liciovpn_test_finished=0
171be93bb9SRalf Lici
181be93bb9SRalf Liciovpn_test_exit() {
197c29665aSRalf Lici	ovpn_cleanup
201be93bb9SRalf Lici	modprobe -r ovpn || true
217b80d8a3SRalf Lici
221be93bb9SRalf Lici	if [ "${ovpn_test_finished}" -eq 0 ]; then
231be93bb9SRalf Lici		ktap_print_totals
241be93bb9SRalf Lici	fi
251be93bb9SRalf Lici}
261be93bb9SRalf Lici
271be93bb9SRalf Liciovpn_mark_prepare_network() {
281be93bb9SRalf Lici	local p
291be93bb9SRalf Lici	local peer_ns
307b80d8a3SRalf Lici
317c29665aSRalf Lici	for p in $(seq 0 "${OVPN_NUM_PEERS}"); do
321be93bb9SRalf Lici		ovpn_cmd_ok "create namespace peer${p}" ovpn_create_ns "${p}"
337b80d8a3SRalf Lici	done
347b80d8a3SRalf Lici
357b80d8a3SRalf Lici	for p in $(seq 0 3); do
361be93bb9SRalf Lici		ovpn_cmd_ok "configure peer${p} namespace" ovpn_setup_ns \
371be93bb9SRalf Lici			"${p}" 5.5.5.$((p + 1))/24
387b80d8a3SRalf Lici	done
397b80d8a3SRalf Lici
401be93bb9SRalf Lici	ovpn_cmd_ok "create server-side multi-peer with fwmark" \
411be93bb9SRalf Lici		ip netns exec ovpn_peer0 "${OVPN_CLI}" new_multi_peer tun0 1 \
421be93bb9SRalf Lici			ASYMM "${OVPN_UDP_PEERS_FILE}" "${MARK}"
437b80d8a3SRalf Lici	for p in $(seq 1 3); do
441be93bb9SRalf Lici		ovpn_cmd_ok "install server key for peer ${p}" \
451be93bb9SRalf Lici			ip netns exec ovpn_peer0 "${OVPN_CLI}" new_key tun0 \
461be93bb9SRalf Lici				"${p}" 1 0 "${OVPN_ALG}" 0 data64.key
477b80d8a3SRalf Lici	done
487b80d8a3SRalf Lici
497b80d8a3SRalf Lici	for p in $(seq 1 3); do
501be93bb9SRalf Lici		ovpn_cmd_ok "register peer${p} in overlay" ovpn_add_peer "${p}"
517b80d8a3SRalf Lici	done
527b80d8a3SRalf Lici
537b80d8a3SRalf Lici	for p in $(seq 1 3); do
541be93bb9SRalf Lici		peer_ns="ovpn_peer${p}"
551be93bb9SRalf Lici		ovpn_cmd_ok "set peer0 timeout for peer ${p}" \
561be93bb9SRalf Lici			ip netns exec ovpn_peer0 "${OVPN_CLI}" set_peer tun0 \
571be93bb9SRalf Lici				"${p}" 60 120
581be93bb9SRalf Lici		ovpn_cmd_ok "set peer${p} timeout for peer ${p}" \
591be93bb9SRalf Lici			ip netns exec "${peer_ns}" "${OVPN_CLI}" set_peer \
601be93bb9SRalf Lici				tun"${p}" $((p + OVPN_ID_OFFSET)) 60 120
617b80d8a3SRalf Lici	done
621be93bb9SRalf Lici}
637b80d8a3SRalf Lici
641be93bb9SRalf Liciovpn_mark_run_baseline_traffic() {
651be93bb9SRalf Lici	local p
667b80d8a3SRalf Lici
677b80d8a3SRalf Lici	for p in $(seq 1 3); do
681be93bb9SRalf Lici		ovpn_cmd_ok "send baseline traffic to peer ${p}" \
69*7f114497SRalf Lici			ip netns exec ovpn_peer0 ping -qfc 100 -w 3 \
701be93bb9SRalf Lici				5.5.5.$((p + 1))
717b80d8a3SRalf Lici	done
721be93bb9SRalf Lici}
737b80d8a3SRalf Lici
741be93bb9SRalf Liciovpn_mark_add_drop_rule() {
751be93bb9SRalf Lici	ovpn_log "Adding an nftables drop rule based on mark value ${MARK}"
761be93bb9SRalf Lici
771be93bb9SRalf Lici	ovpn_cmd_ok "flush nft ruleset" ip netns exec ovpn_peer0 nft flush \
781be93bb9SRalf Lici		ruleset
791be93bb9SRalf Lici	ovpn_cmd_ok "create nft filter table" ip netns exec ovpn_peer0 nft \
801be93bb9SRalf Lici		"add table inet filter"
811be93bb9SRalf Lici	ovpn_cmd_ok "create nft filter output chain" \
821be93bb9SRalf Lici		ip netns exec ovpn_peer0 nft "add chain inet filter output { \
831be93bb9SRalf Lici			type filter hook output priority 0; policy accept; }"
841be93bb9SRalf Lici	ovpn_cmd_ok "add nft drop rule for mark ${MARK}" \
851be93bb9SRalf Lici		ip netns exec ovpn_peer0 nft add rule inet filter output \
861be93bb9SRalf Lici			meta mark == "${MARK}" \
877b80d8a3SRalf Lici			counter drop
887b80d8a3SRalf Lici
891be93bb9SRalf Lici	MARK_DROP_COUNTER=$(ip netns exec ovpn_peer0 nft list chain inet \
901be93bb9SRalf Lici		filter output | sed -n 's/.*packets \([0-9]*\).*/\1/p')
911be93bb9SRalf Lici	if [ -z "${MARK_DROP_COUNTER}" ]; then
921be93bb9SRalf Lici		printf '%s\n' "unable to read nft drop counter"
931be93bb9SRalf Lici		return 1
947b80d8a3SRalf Lici	fi
951be93bb9SRalf Lici}
967b80d8a3SRalf Lici
971be93bb9SRalf Liciovpn_mark_verify_drop_traffic() {
981be93bb9SRalf Lici	local p
991be93bb9SRalf Lici	local ping_output
1001be93bb9SRalf Lici	local lost_packets
1011be93bb9SRalf Lici	local total_count
1027b80d8a3SRalf Lici
1037b80d8a3SRalf Lici	for p in $(seq 1 3); do
104*7f114497SRalf Lici		if ping_output=$(ip netns exec ovpn_peer0 ping -qfc 100 -w 1 \
1051be93bb9SRalf Lici			5.5.5.$((p + 1)) 2>&1); then
1061be93bb9SRalf Lici			printf '%s\n' "expected ping to peer ${p} to fail \
1071be93bb9SRalf Lici				after nft drop rule"
1081be93bb9SRalf Lici			return 1
1091be93bb9SRalf Lici		fi
1101be93bb9SRalf Lici		ovpn_log "${ping_output}"
1111be93bb9SRalf Lici		lost_packets=$(echo "${ping_output}" | \
1121be93bb9SRalf Lici				awk '/packets transmitted/ { print $1 }')
1131be93bb9SRalf Lici		if [ -z "${lost_packets}" ]; then
1141be93bb9SRalf Lici			printf '%s\n' "unable to parse lost packets for peer \
1151be93bb9SRalf Lici				${p}"
1161be93bb9SRalf Lici			return 1
1171be93bb9SRalf Lici		fi
1181be93bb9SRalf Lici		MARK_DROP_COUNTER=$((MARK_DROP_COUNTER + lost_packets))
1197b80d8a3SRalf Lici	done
1207b80d8a3SRalf Lici
1211be93bb9SRalf Lici	total_count=$(ip netns exec ovpn_peer0 nft list chain inet filter \
1221be93bb9SRalf Lici		output | sed -n 's/.*packets \([0-9]*\).*/\1/p')
1231be93bb9SRalf Lici	if [ -z "${total_count}" ]; then
1241be93bb9SRalf Lici		printf '%s\n' "unable to read final nft drop counter"
1251be93bb9SRalf Lici		return 1
1261be93bb9SRalf Lici	fi
1271be93bb9SRalf Lici	if [ "${MARK_DROP_COUNTER}" -ne "${total_count}" ]; then
1281be93bb9SRalf Lici		printf '%s\n' "expected ${MARK_DROP_COUNTER} drops, got \
1291be93bb9SRalf Lici			${total_count}"
1301be93bb9SRalf Lici		return 1
1311be93bb9SRalf Lici	fi
1321be93bb9SRalf Lici}
1331be93bb9SRalf Lici
1341be93bb9SRalf Liciovpn_mark_remove_drop_rule() {
1351be93bb9SRalf Lici	ovpn_log "Removing the drop rule"
1361be93bb9SRalf Lici
1371be93bb9SRalf Lici	ovpn_cmd_ok "flush nft ruleset" ip netns exec ovpn_peer0 nft flush \
1381be93bb9SRalf Lici		ruleset
1391be93bb9SRalf Lici}
1401be93bb9SRalf Lici
1411be93bb9SRalf Liciovpn_mark_verify_traffic_recovery() {
1421be93bb9SRalf Lici	local p
1431be93bb9SRalf Lici
1441be93bb9SRalf Lici	sleep 1
1451be93bb9SRalf Lici	for p in $(seq 1 3); do
1461be93bb9SRalf Lici		ovpn_cmd_ok "send recovery traffic to peer ${p}" \
147*7f114497SRalf Lici			ip netns exec ovpn_peer0 ping -qfc 100 -w 3 \
1481be93bb9SRalf Lici				5.5.5.$((p + 1))
1491be93bb9SRalf Lici	done
1501be93bb9SRalf Lici}
1511be93bb9SRalf Lici
1521be93bb9SRalf Licitrap ovpn_test_exit EXIT
1531be93bb9SRalf Licitrap ovpn_stage_err ERR
1541be93bb9SRalf Lici
1551be93bb9SRalf Liciktap_print_header
1561be93bb9SRalf Liciktap_set_plan 6
1571be93bb9SRalf Lici
1587c29665aSRalf Liciovpn_cleanup
1591be93bb9SRalf Licimodprobe -q ovpn || true
1607b80d8a3SRalf Lici
1611be93bb9SRalf Liciovpn_run_stage "setup marked network topology" ovpn_mark_prepare_network
1621be93bb9SRalf Liciovpn_run_stage "run baseline traffic" ovpn_mark_run_baseline_traffic
1631be93bb9SRalf Liciovpn_run_stage "install nft mark drop rule" ovpn_mark_add_drop_rule
1641be93bb9SRalf Liciovpn_run_stage "drop marked traffic and count packets" \
1651be93bb9SRalf Lici	ovpn_mark_verify_drop_traffic
1661be93bb9SRalf Liciovpn_run_stage "remove nft drop rule" ovpn_mark_remove_drop_rule
1671be93bb9SRalf Liciovpn_run_stage "traffic recovers after drop removal" \
1681be93bb9SRalf Lici	ovpn_mark_verify_traffic_recovery
1691be93bb9SRalf Lici
1701be93bb9SRalf Liciovpn_test_finished=1
1711be93bb9SRalf Liciktap_finished
172