Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3# Copyright (C) 2020-2025 OpenVPN, Inc.
4#
5# Author: Ralf Lici <ralf@mandelbit.com>
6# Antonio Quartulli <antonio@openvpn.net>
7
8#set -x
9set -eE
10
11MARK=1056
12MARK_DROP_COUNTER=0
13
14source ./common.sh
15
16ovpn_test_finished=0
17
18ovpn_test_exit() {
19 ovpn_cleanup
20 modprobe -r ovpn || true
21
22 if [ "${ovpn_test_finished}" -eq 0 ]; then
23 ktap_print_totals
24 fi
25}
26
27ovpn_mark_prepare_network() {
28 local p
29 local peer_ns
30
31 for p in $(seq 0 "${OVPN_NUM_PEERS}"); do
32 ovpn_cmd_ok "create namespace peer${p}" ovpn_create_ns "${p}"
33 done
34
35 for p in $(seq 0 3); do
36 ovpn_cmd_ok "configure peer${p} namespace" ovpn_setup_ns \
37 "${p}" 5.5.5.$((p + 1))/24
38 done
39
40 ovpn_cmd_ok "create server-side multi-peer with fwmark" \
41 ip netns exec ovpn_peer0 "${OVPN_CLI}" new_multi_peer tun0 1 \
42 ASYMM "${OVPN_UDP_PEERS_FILE}" "${MARK}"
43 for p in $(seq 1 3); do
44 ovpn_cmd_ok "install server key for peer ${p}" \
45 ip netns exec ovpn_peer0 "${OVPN_CLI}" new_key tun0 \
46 "${p}" 1 0 "${OVPN_ALG}" 0 data64.key
47 done
48
49 for p in $(seq 1 3); do
50 ovpn_cmd_ok "register peer${p} in overlay" ovpn_add_peer "${p}"
51 done
52
53 for p in $(seq 1 3); do
54 peer_ns="ovpn_peer${p}"
55 ovpn_cmd_ok "set peer0 timeout for peer ${p}" \
56 ip netns exec ovpn_peer0 "${OVPN_CLI}" set_peer tun0 \
57 "${p}" 60 120
58 ovpn_cmd_ok "set peer${p} timeout for peer ${p}" \
59 ip netns exec "${peer_ns}" "${OVPN_CLI}" set_peer \
60 tun"${p}" $((p + OVPN_ID_OFFSET)) 60 120
61 done
62}
63
64ovpn_mark_run_baseline_traffic() {
65 local p
66
67 for p in $(seq 1 3); do
68 ovpn_cmd_ok "send baseline traffic to peer ${p}" \
69 ip netns exec ovpn_peer0 ping -qfc 500 -w 3 \
70 5.5.5.$((p + 1))
71 done
72}
73
74ovpn_mark_add_drop_rule() {
75 ovpn_log "Adding an nftables drop rule based on mark value ${MARK}"
76
77 ovpn_cmd_ok "flush nft ruleset" ip netns exec ovpn_peer0 nft flush \
78 ruleset
79 ovpn_cmd_ok "create nft filter table" ip netns exec ovpn_peer0 nft \
80 "add table inet filter"
81 ovpn_cmd_ok "create nft filter output chain" \
82 ip netns exec ovpn_peer0 nft "add chain inet filter output { \
83 type filter hook output priority 0; policy accept; }"
84 ovpn_cmd_ok "add nft drop rule for mark ${MARK}" \
85 ip netns exec ovpn_peer0 nft add rule inet filter output \
86 meta mark == "${MARK}" \
87 counter drop
88
89 MARK_DROP_COUNTER=$(ip netns exec ovpn_peer0 nft list chain inet \
90 filter output | sed -n 's/.*packets \([0-9]*\).*/\1/p')
91 if [ -z "${MARK_DROP_COUNTER}" ]; then
92 printf '%s\n' "unable to read nft drop counter"
93 return 1
94 fi
95}
96
97ovpn_mark_verify_drop_traffic() {
98 local p
99 local ping_output
100 local lost_packets
101 local total_count
102
103 for p in $(seq 1 3); do
104 if ping_output=$(ip netns exec ovpn_peer0 ping -qfc 500 -w 1 \
105 5.5.5.$((p + 1)) 2>&1); then
106 printf '%s\n' "expected ping to peer ${p} to fail \
107 after nft drop rule"
108 return 1
109 fi
110 ovpn_log "${ping_output}"
111 lost_packets=$(echo "${ping_output}" | \
112 awk '/packets transmitted/ { print $1 }')
113 if [ -z "${lost_packets}" ]; then
114 printf '%s\n' "unable to parse lost packets for peer \
115 ${p}"
116 return 1
117 fi
118 MARK_DROP_COUNTER=$((MARK_DROP_COUNTER + lost_packets))
119 done
120
121 total_count=$(ip netns exec ovpn_peer0 nft list chain inet filter \
122 output | sed -n 's/.*packets \([0-9]*\).*/\1/p')
123 if [ -z "${total_count}" ]; then
124 printf '%s\n' "unable to read final nft drop counter"
125 return 1
126 fi
127 if [ "${MARK_DROP_COUNTER}" -ne "${total_count}" ]; then
128 printf '%s\n' "expected ${MARK_DROP_COUNTER} drops, got \
129 ${total_count}"
130 return 1
131 fi
132}
133
134ovpn_mark_remove_drop_rule() {
135 ovpn_log "Removing the drop rule"
136
137 ovpn_cmd_ok "flush nft ruleset" ip netns exec ovpn_peer0 nft flush \
138 ruleset
139}
140
141ovpn_mark_verify_traffic_recovery() {
142 local p
143
144 sleep 1
145 for p in $(seq 1 3); do
146 ovpn_cmd_ok "send recovery traffic to peer ${p}" \
147 ip netns exec ovpn_peer0 ping -qfc 500 -w 3 \
148 5.5.5.$((p + 1))
149 done
150}
151
152trap ovpn_test_exit EXIT
153trap ovpn_stage_err ERR
154
155ktap_print_header
156ktap_set_plan 6
157
158ovpn_cleanup
159modprobe -q ovpn || true
160
161ovpn_run_stage "setup marked network topology" ovpn_mark_prepare_network
162ovpn_run_stage "run baseline traffic" ovpn_mark_run_baseline_traffic
163ovpn_run_stage "install nft mark drop rule" ovpn_mark_add_drop_rule
164ovpn_run_stage "drop marked traffic and count packets" \
165 ovpn_mark_verify_drop_traffic
166ovpn_run_stage "remove nft drop rule" ovpn_mark_remove_drop_rule
167ovpn_run_stage "traffic recovers after drop removal" \
168 ovpn_mark_verify_traffic_recovery
169
170ovpn_test_finished=1
171ktap_finished