Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'ovpn-net-20260417' of https://github.com/OpenVPN/ovpn-net-next

Antonio Quartulli says:

====================
This batch includes only fixes to the selftest harness:
* switch to TAP test orchestration
* parse slurped notifications as returned by jq -s
* add ovpn_ prefix to helpers and global variables to avoid clashes
* fail test in case of netlink notification mismatch
* add missing kernel config dependencies
* add delay when launching multiple ynl/cli.py listeners

* tag 'ovpn-net-20260417' of https://github.com/OpenVPN/ovpn-net-next:
selftests: ovpn: serialize YNL listener startup
selftests: ovpn: align command flow with TAP
selftests: ovpn: add prefix to helpers and shared variables
selftests: ovpn: flatten slurped notification JSON before filtering
selftests: ovpn: fail notification check on mismatch
selftests: ovpn: add nftables config dependencies for test-mark
====================

Link: https://patch.msgid.link/20260417090305.2775723-1-antonio@openvpn.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+800 -346
+272 -91
tools/testing/selftests/net/ovpn/common.sh
··· 4 4 # 5 5 # Author: Antonio Quartulli <antonio@openvpn.net> 6 6 7 - UDP_PEERS_FILE=${UDP_PEERS_FILE:-udp_peers.txt} 8 - TCP_PEERS_FILE=${TCP_PEERS_FILE:-tcp_peers.txt} 9 - OVPN_CLI=${OVPN_CLI:-./ovpn-cli} 10 - YNL_CLI=${YNL_CLI:-../../../../net/ynl/pyynl/cli.py} 11 - ALG=${ALG:-aes} 12 - PROTO=${PROTO:-UDP} 13 - FLOAT=${FLOAT:-0} 14 - SYMMETRIC_ID=${SYMMETRIC_ID:-0} 7 + OVPN_COMMON_DIR=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")") 8 + source "$OVPN_COMMON_DIR/../../kselftest/ktap_helpers.sh" 15 9 16 - export ID_OFFSET=$(( 9 * (SYMMETRIC_ID == 0) )) 10 + OVPN_UDP_PEERS_FILE=${OVPN_UDP_PEERS_FILE:-udp_peers.txt} 11 + OVPN_TCP_PEERS_FILE=${OVPN_TCP_PEERS_FILE:-tcp_peers.txt} 12 + OVPN_CLI=${OVPN_CLI:-${OVPN_COMMON_DIR}/ovpn-cli} 13 + OVPN_YNL=${OVPN_YNL:-${OVPN_COMMON_DIR}/../../../../net/ynl/pyynl/cli.py} 14 + OVPN_ALG=${OVPN_ALG:-aes} 15 + OVPN_PROTO=${OVPN_PROTO:-UDP} 16 + OVPN_FLOAT=${OVPN_FLOAT:-0} 17 + OVPN_SYMMETRIC_ID=${OVPN_SYMMETRIC_ID:-0} 18 + OVPN_VERBOSE=${OVPN_VERBOSE:-0} 17 19 18 - JQ_FILTER='map(select(.msg.peer | has("remote-ipv6") | not)) | 20 + export OVPN_ID_OFFSET=$(( 9 * (OVPN_SYMMETRIC_ID == 0) )) 21 + 22 + OVPN_JQ_FILTER='map(if type == "array" then .[] else . end) | 23 + map(select(.msg.peer | has("remote-ipv6") | not)) | 19 24 map(del(.msg.ifindex)) | sort_by(.msg.peer.id)[]' 20 - LAN_IP="11.11.11.11" 25 + OVPN_LAN_IP="11.11.11.11" 21 26 22 - declare -A tmp_jsons=() 23 - declare -A listener_pids=() 27 + declare -A OVPN_TMP_JSONS=() 28 + declare -A OVPN_LISTENER_PIDS=() 29 + OVPN_CURRENT_STAGE="" 24 30 25 - create_ns() { 26 - ip netns add peer${1} 31 + ovpn_is_verbose() { 32 + [[ "${OVPN_VERBOSE}" == "1" ]] 27 33 } 28 34 29 - setup_ns() { 35 + ovpn_log() { 36 + ovpn_is_verbose || return 0 37 + printf '%s\n' "$*" 38 + } 39 + 40 + ovpn_print_cmd_output() { 41 + local output_file="$1" 42 + local line 43 + 44 + [[ -s "${output_file}" ]] || return 0 45 + 46 + while IFS= read -r line; do 47 + ovpn_log "${line}" 48 + done < "${output_file}" 49 + } 50 + 51 + ovpn_cmd_run() { 52 + local mode="$1" 53 + local label="$2" 54 + local output_file 55 + local rc 56 + local ret=0 57 + 58 + shift 2 59 + 60 + output_file=$(mktemp) 61 + if "$@" >"${output_file}" 2>&1; then 62 + rc=0 63 + else 64 + rc=$? 65 + fi 66 + 67 + case "${mode}" in 68 + ok) 69 + if [[ "${rc}" -ne 0 ]]; then 70 + cat "${output_file}" 71 + printf '%s\n' \ 72 + "${label}: command failed with rc=${rc}: $*" 73 + ret="${rc}" 74 + fi 75 + ;; 76 + mayfail) 77 + ;; 78 + fail) 79 + [[ "${rc}" -eq 0 ]] && ret=1 80 + ;; 81 + esac 82 + 83 + if ovpn_is_verbose && [[ "${rc}" -eq 0 || "${mode}" != "ok" ]]; then 84 + ovpn_print_cmd_output "${output_file}" 85 + fi 86 + 87 + rm -f "${output_file}" 88 + return "${ret}" 89 + } 90 + 91 + ovpn_cmd_ok() { 92 + ovpn_cmd_run ok "$@" 93 + } 94 + 95 + ovpn_cmd_mayfail() { 96 + ovpn_cmd_run mayfail "$@" 97 + } 98 + 99 + ovpn_cmd_fail() { 100 + ovpn_cmd_run fail "$@" 101 + } 102 + 103 + ovpn_run_bg() { 104 + local pid_var="$1" 105 + 106 + shift 107 + if ovpn_is_verbose; then 108 + "$@" & 109 + else 110 + "$@" >/dev/null 2>&1 & 111 + fi 112 + 113 + printf -v "${pid_var}" '%s' "$!" 114 + } 115 + 116 + ovpn_run_stage() { 117 + local label="$1" 118 + 119 + shift 120 + OVPN_CURRENT_STAGE="${label}" 121 + "$@" 122 + OVPN_CURRENT_STAGE="" 123 + ktap_test_pass "${label}" 124 + } 125 + 126 + ovpn_stage_err() { 127 + # ERR trap is global under set -eE: only report failures that happen 128 + # while ovpn_run_stage() is actively executing a stage body. 129 + if [[ -n "${OVPN_CURRENT_STAGE}" ]]; then 130 + ktap_test_fail "${OVPN_CURRENT_STAGE}" 131 + OVPN_CURRENT_STAGE="" 132 + fi 133 + } 134 + 135 + ovpn_create_ns() { 136 + ip netns add "ovpn_peer${1}" 137 + } 138 + 139 + ovpn_setup_ns() { 140 + local peer="ovpn_peer${1}" 141 + local server_ns="ovpn_peer0" 142 + local peer_ns 30 143 MODE="P2P" 31 144 32 145 if [ ${1} -eq 0 ]; then 33 146 MODE="MP" 34 - for p in $(seq 1 ${NUM_PEERS}); do 35 - ip link add veth${p} netns peer0 type veth peer name veth${p} netns peer${p} 147 + for p in $(seq 1 ${OVPN_NUM_PEERS}); do 148 + peer_ns="ovpn_peer${p}" 149 + ip link add veth${p} netns "${server_ns}" type veth \ 150 + peer name veth${p} netns "${peer_ns}" 36 151 37 - ip -n peer0 addr add 10.10.${p}.1/24 dev veth${p} 38 - ip -n peer0 addr add fd00:0:0:${p}::1/64 dev veth${p} 39 - ip -n peer0 link set veth${p} up 152 + ip -n "${server_ns}" addr add 10.10.${p}.1/24 dev \ 153 + veth${p} 154 + ip -n "${server_ns}" addr add fd00:0:0:${p}::1/64 dev \ 155 + veth${p} 156 + ip -n "${server_ns}" link set veth${p} up 40 157 41 - ip -n peer${p} addr add 10.10.${p}.2/24 dev veth${p} 42 - ip -n peer${p} addr add fd00:0:0:${p}::2/64 dev veth${p} 43 - ip -n peer${p} link set veth${p} up 158 + ip -n "${peer_ns}" addr add 10.10.${p}.2/24 dev veth${p} 159 + ip -n "${peer_ns}" addr add fd00:0:0:${p}::2/64 dev \ 160 + veth${p} 161 + ip -n "${peer_ns}" link set veth${p} up 44 162 done 45 163 fi 46 164 47 - ip netns exec peer${1} ${OVPN_CLI} new_iface tun${1} $MODE 48 - ip -n peer${1} addr add ${2} dev tun${1} 165 + ip netns exec "${peer}" ${OVPN_CLI} new_iface tun${1} $MODE 166 + ip -n "${peer}" addr add ${2} dev tun${1} 49 167 # add a secondary IP to peer 1, to test a LAN behind a client 50 - if [ ${1} -eq 1 -a -n "${LAN_IP}" ]; then 51 - ip -n peer${1} addr add ${LAN_IP} dev tun${1} 52 - ip -n peer0 route add ${LAN_IP} via $(echo ${2} |sed -e s'!/.*!!') dev tun0 168 + if [ ${1} -eq 1 -a -n "${OVPN_LAN_IP}" ]; then 169 + ip -n "${peer}" addr add ${OVPN_LAN_IP} dev tun${1} 170 + ip -n "${server_ns}" route add ${OVPN_LAN_IP} via \ 171 + $(echo ${2} |sed -e s'!/.*!!') dev tun0 53 172 fi 54 173 if [ -n "${3}" ]; then 55 - ip -n peer${1} link set mtu ${3} dev tun${1} 174 + ip -n "${peer}" link set mtu ${3} dev tun${1} 56 175 fi 57 - ip -n peer${1} link set tun${1} up 176 + ip -n "${peer}" link set tun${1} up 58 177 } 59 178 60 - build_capture_filter() { 179 + ovpn_build_capture_filter() { 61 180 # match the first four bytes of the openvpn data payload 62 - if [ "${PROTO}" == "UDP" ]; then 181 + if [ "${OVPN_PROTO}" == "UDP" ]; then 63 182 # For UDP, libpcap transport indexing only works for IPv4, so 64 183 # use an explicit IPv4 or IPv6 expression based on the peer 65 184 # address. The IPv6 branch assumes there are no extension ··· 195 76 fi 196 77 } 197 78 198 - setup_listener() { 79 + ovpn_setup_listener() { 80 + local peer="$1" 81 + local file 82 + local peer_ns="ovpn_peer${peer}" 83 + 199 84 file=$(mktemp) 200 - PYTHONUNBUFFERED=1 ip netns exec peer${p} ${YNL_CLI} --family ovpn \ 201 - --subscribe peers --output-json --duration 40 > ${file} & 202 - listener_pids[$1]=$! 203 - tmp_jsons[$1]="${file}" 85 + PYTHONUNBUFFERED=1 ip netns exec "${peer_ns}" "${OVPN_YNL}" --family \ 86 + ovpn --subscribe peers --output-json > "${file}" \ 87 + 2>/dev/null & 88 + OVPN_LISTENER_PIDS["${peer}"]=$! 89 + OVPN_TMP_JSONS["${peer}"]="${file}" 204 90 } 205 91 206 - add_peer() { 92 + ovpn_add_peer() { 207 93 labels=("ASYMM" "SYMM") 208 - M_ID=${labels[SYMMETRIC_ID]} 94 + local peer_ns 95 + local server_ns="ovpn_peer0" 96 + M_ID=${labels[OVPN_SYMMETRIC_ID]} 209 97 210 - if [ "${PROTO}" == "UDP" ]; then 98 + if [ "${OVPN_PROTO}" == "UDP" ]; then 211 99 if [ ${1} -eq 0 ]; then 212 - ip netns exec peer0 ${OVPN_CLI} new_multi_peer tun0 1 \ 213 - ${M_ID} ${UDP_PEERS_FILE} 100 + ip netns exec "${server_ns}" ${OVPN_CLI} \ 101 + new_multi_peer tun0 1 ${M_ID} \ 102 + ${OVPN_UDP_PEERS_FILE} 214 103 215 - for p in $(seq 1 ${NUM_PEERS}); do 216 - ip netns exec peer0 ${OVPN_CLI} new_key tun0 ${p} 1 0 ${ALG} 0 \ 104 + for p in $(seq 1 ${OVPN_NUM_PEERS}); do 105 + ip netns exec "${server_ns}" ${OVPN_CLI} \ 106 + new_key tun0 ${p} 1 0 ${OVPN_ALG} 0 \ 217 107 data64.key 218 108 done 219 109 else 220 - if [ "${SYMMETRIC_ID}" -eq 1 ]; then 110 + peer_ns="ovpn_peer${1}" 111 + if [ "${OVPN_SYMMETRIC_ID}" -eq 1 ]; then 221 112 PEER_ID=${1} 222 113 TX_ID="none" 223 114 else 224 115 PEER_ID=$(awk "NR == ${1} {print \$2}" \ 225 - ${UDP_PEERS_FILE}) 116 + ${OVPN_UDP_PEERS_FILE}) 226 117 TX_ID=${1} 227 118 fi 228 - RADDR=$(awk "NR == ${1} {print \$3}" ${UDP_PEERS_FILE}) 229 - RPORT=$(awk "NR == ${1} {print \$4}" ${UDP_PEERS_FILE}) 230 - LPORT=$(awk "NR == ${1} {print \$6}" ${UDP_PEERS_FILE}) 231 - ip netns exec peer${1} ${OVPN_CLI} new_peer tun${1} \ 232 - ${PEER_ID} ${TX_ID} ${LPORT} ${RADDR} ${RPORT} 233 - ip netns exec peer${1} ${OVPN_CLI} new_key tun${1} \ 234 - ${PEER_ID} 1 0 ${ALG} 1 data64.key 119 + RADDR=$(awk "NR == ${1} {print \$3}" \ 120 + ${OVPN_UDP_PEERS_FILE}) 121 + RPORT=$(awk "NR == ${1} {print \$4}" \ 122 + ${OVPN_UDP_PEERS_FILE}) 123 + LPORT=$(awk "NR == ${1} {print \$6}" \ 124 + ${OVPN_UDP_PEERS_FILE}) 125 + ip netns exec "${peer_ns}" ${OVPN_CLI} new_peer \ 126 + tun${1} ${PEER_ID} ${TX_ID} ${LPORT} ${RADDR} \ 127 + ${RPORT} 128 + ip netns exec "${peer_ns}" ${OVPN_CLI} new_key tun${1} \ 129 + ${PEER_ID} 1 0 ${OVPN_ALG} 1 data64.key 235 130 fi 236 131 else 237 132 if [ ${1} -eq 0 ]; then 238 - (ip netns exec peer0 ${OVPN_CLI} listen tun0 1 ${M_ID} \ 239 - ${TCP_PEERS_FILE} && { 240 - for p in $(seq 1 ${NUM_PEERS}); do 241 - ip netns exec peer0 ${OVPN_CLI} new_key tun0 ${p} 1 0 \ 242 - ${ALG} 0 data64.key 133 + (ip netns exec "${server_ns}" ${OVPN_CLI} listen tun0 \ 134 + 1 ${M_ID} ${OVPN_TCP_PEERS_FILE} && { 135 + for p in $(seq 1 ${OVPN_NUM_PEERS}); do 136 + ip netns exec "${server_ns}" \ 137 + ${OVPN_CLI} new_key tun0 ${p} \ 138 + 1 0 ${OVPN_ALG} 0 data64.key 243 139 done 244 140 }) & 245 141 sleep 5 246 142 else 247 - if [ "${SYMMETRIC_ID}" -eq 1 ]; then 143 + peer_ns="ovpn_peer${1}" 144 + if [ "${OVPN_SYMMETRIC_ID}" -eq 1 ]; then 248 145 PEER_ID=${1} 249 146 TX_ID="none" 250 147 else 251 148 PEER_ID=$(awk "NR == ${1} {print \$2}" \ 252 - ${TCP_PEERS_FILE}) 149 + ${OVPN_TCP_PEERS_FILE}) 253 150 TX_ID=${1} 254 151 fi 255 - ip netns exec peer${1} ${OVPN_CLI} connect tun${1} \ 152 + ip netns exec "${peer_ns}" ${OVPN_CLI} connect tun${1} \ 256 153 ${PEER_ID} ${TX_ID} 10.10.${1}.1 1 data64.key 257 154 fi 258 155 fi 259 156 } 260 157 261 - compare_ntfs() { 262 - if [ ${#tmp_jsons[@]} -gt 0 ]; then 263 - suffix="" 264 - [ "${SYMMETRIC_ID}" -eq 1 ] && suffix="${suffix}-symm" 265 - [ "$FLOAT" == 1 ] && suffix="${suffix}-float" 266 - expected="json/peer${1}${suffix}.json" 267 - received="${tmp_jsons[$1]}" 158 + ovpn_compare_ntfs() { 159 + local diff_rc=0 160 + local diff_file 268 161 269 - kill -TERM ${listener_pids[$1]} || true 270 - wait ${listener_pids[$1]} || true 162 + if [ ${#OVPN_TMP_JSONS[@]} -gt 0 ]; then 163 + suffix="" 164 + [ "${OVPN_SYMMETRIC_ID}" -eq 1 ] && suffix="${suffix}-symm" 165 + [ "$OVPN_FLOAT" == 1 ] && suffix="${suffix}-float" 166 + expected="json/peer${1}${suffix}.json" 167 + received="${OVPN_TMP_JSONS[$1]}" 168 + diff_file=$(mktemp) 169 + 170 + ovpn_stop_listener "${1}" 1 271 171 printf "Checking notifications for peer ${1}... " 272 - if diff <(jq -s "${JQ_FILTER}" ${expected}) \ 273 - <(jq -s "${JQ_FILTER}" ${received}); then 172 + if diff <(jq -s "${OVPN_JQ_FILTER}" ${expected}) \ 173 + <(jq -s "${OVPN_JQ_FILTER}" ${received}) \ 174 + >"${diff_file}" 2>&1; then 274 175 echo "OK" 176 + else 177 + diff_rc=$? 178 + echo "failed" 179 + cat "${diff_file}" 275 180 fi 276 181 277 - rm -f ${received} || true 182 + rm -f "${diff_file}" || true 183 + rm -f "${received}" || true 184 + unset "OVPN_TMP_JSONS[$1]" 185 + fi 186 + 187 + return "${diff_rc}" 188 + } 189 + 190 + ovpn_stop_listener() { 191 + local peer="$1" 192 + local keep_json="${2:-0}" 193 + local pid="${OVPN_LISTENER_PIDS[$peer]:-}" 194 + local json="${OVPN_TMP_JSONS[$peer]:-}" 195 + 196 + if [[ -n "${pid}" ]]; then 197 + kill -TERM "${pid}" 2>/dev/null || true 198 + wait "${pid}" 2>/dev/null || true 199 + unset "OVPN_LISTENER_PIDS[$peer]" 200 + fi 201 + 202 + if [[ -n "${json}" && "${keep_json}" -eq 0 ]]; then 203 + rm -f "${json}" || true 204 + unset "OVPN_TMP_JSONS[$peer]" 278 205 fi 279 206 } 280 207 281 - cleanup() { 282 - # some ovpn-cli processes sleep in background so they need manual poking 283 - killall $(basename ${OVPN_CLI}) 2>/dev/null || true 208 + ovpn_cleanup_peer_ns() { 209 + local peer="$1" 210 + local peer_id="${peer#ovpn_peer}" 284 211 285 - # netns peer0 is deleted without erasing ifaces first 286 - for p in $(seq 1 10); do 287 - ip -n peer${p} link set tun${p} down 2>/dev/null || true 288 - ip netns exec peer${p} ${OVPN_CLI} del_iface tun${p} 2>/dev/null || true 289 - done 290 - for p in $(seq 1 10); do 291 - ip -n peer0 link del veth${p} 2>/dev/null || true 292 - done 293 - for p in $(seq 0 10); do 294 - ip netns del peer${p} 2>/dev/null || true 295 - done 212 + ip -n "${peer}" link set tun${peer_id} down 2>/dev/null || true 213 + ip netns exec "${peer}" ${OVPN_CLI} del_iface tun${peer_id} \ 214 + 1>/dev/null 2>&1 || true 215 + ip netns del "${peer}" 2>/dev/null || true 296 216 } 297 217 298 - if [ "${PROTO}" == "UDP" ]; then 299 - NUM_PEERS=${NUM_PEERS:-$(wc -l ${UDP_PEERS_FILE} | awk '{print $1}')} 218 + ovpn_cleanup() { 219 + local peer 220 + 221 + # some ovpn-cli processes sleep in background so they need manual poking 222 + killall "$(basename "${OVPN_CLI}")" 2>/dev/null || true 223 + 224 + for peer in "${!OVPN_LISTENER_PIDS[@]}"; do 225 + ovpn_stop_listener "${peer}" 2>/dev/null 226 + done 227 + 228 + for p in $(seq 1 10); do 229 + ip -n ovpn_peer0 link del veth${p} 2>/dev/null || true 230 + done 231 + 232 + # remove from ovpn's netns pool 233 + while IFS= read -r peer; do 234 + [[ -n "${peer}" ]] || continue 235 + ovpn_cleanup_peer_ns "${peer}" 2>/dev/null 236 + done < <(ip netns list 2>/dev/null | awk '/^ovpn_/ {print $1}') 237 + } 238 + 239 + if [ "${OVPN_PROTO}" == "UDP" ]; then 240 + OVPN_NUM_PEERS=${OVPN_NUM_PEERS:-$(wc -l ${OVPN_UDP_PEERS_FILE} | \ 241 + awk '{print $1}')} 300 242 else 301 - NUM_PEERS=${NUM_PEERS:-$(wc -l ${TCP_PEERS_FILE} | awk '{print $1}')} 243 + OVPN_NUM_PEERS=${OVPN_NUM_PEERS:-$(wc -l ${OVPN_TCP_PEERS_FILE} | \ 244 + awk '{print $1}')} 302 245 fi
+3
tools/testing/selftests/net/ovpn/config
··· 5 5 CONFIG_DST_CACHE=y 6 6 CONFIG_INET=y 7 7 CONFIG_NET=y 8 + CONFIG_NETFILTER=y 8 9 CONFIG_NET_UDP_TUNNEL=y 10 + CONFIG_NF_TABLES=m 11 + CONFIG_NF_TABLES_INET=y 9 12 CONFIG_OVPN=m 10 13 CONFIG_STREAM_PARSER=y
+1 -1
tools/testing/selftests/net/ovpn/test-chachapoly.sh
··· 4 4 # 5 5 # Author: Antonio Quartulli <antonio@openvpn.net> 6 6 7 - ALG="chachapoly" 7 + OVPN_ALG="chachapoly" 8 8 9 9 source test.sh
+1 -1
tools/testing/selftests/net/ovpn/test-close-socket-tcp.sh
··· 4 4 # 5 5 # Author: Antonio Quartulli <antonio@openvpn.net> 6 6 7 - PROTO="TCP" 7 + OVPN_PROTO="TCP" 8 8 9 9 source test-close-socket.sh
+71 -31
tools/testing/selftests/net/ovpn/test-close-socket.sh
··· 5 5 # Author: Antonio Quartulli <antonio@openvpn.net> 6 6 7 7 #set -x 8 - set -e 8 + set -eE 9 9 10 10 source ./common.sh 11 11 12 - cleanup 12 + ovpn_test_finished=0 13 13 14 + ovpn_test_exit() { 15 + ovpn_cleanup 16 + modprobe -r ovpn || true 17 + 18 + if [ "${ovpn_test_finished}" -eq 0 ]; then 19 + ktap_print_totals 20 + fi 21 + } 22 + 23 + ovpn_prepare_network() { 24 + local p 25 + local peer_ns 26 + 27 + for p in $(seq 0 ${OVPN_NUM_PEERS}); do 28 + ovpn_cmd_ok "create namespace peer${p}" ovpn_create_ns "${p}" 29 + done 30 + 31 + for p in $(seq 0 ${OVPN_NUM_PEERS}); do 32 + ovpn_cmd_ok "configure peer${p} namespace" ovpn_setup_ns \ 33 + "${p}" 5.5.5.$((p + 1))/24 34 + done 35 + 36 + for p in $(seq 0 ${OVPN_NUM_PEERS}); do 37 + ovpn_cmd_ok "register peer${p} in overlay" ovpn_add_peer "${p}" 38 + done 39 + 40 + for p in $(seq 1 ${OVPN_NUM_PEERS}); do 41 + peer_ns="ovpn_peer${p}" 42 + ovpn_cmd_ok "set peer0 timeout for peer ${p}" \ 43 + ip netns exec ovpn_peer0 ${OVPN_CLI} set_peer tun0 \ 44 + ${p} 60 120 45 + ovpn_cmd_ok "set peer${p} timeout for peer ${p}" \ 46 + ip netns exec "${peer_ns}" ${OVPN_CLI} set_peer \ 47 + tun${p} $((p + OVPN_ID_OFFSET)) 60 120 48 + done 49 + } 50 + 51 + ovpn_run_ping_traffic() { 52 + local p 53 + 54 + for p in $(seq 1 ${OVPN_NUM_PEERS}); do 55 + ovpn_cmd_ok "send ping traffic to peer ${p}" \ 56 + ip netns exec ovpn_peer0 ping -qfc 500 -w 3 \ 57 + 5.5.5.$((p + 1)) 58 + done 59 + } 60 + 61 + ovpn_run_iperf() { 62 + local iperf_pid 63 + 64 + ovpn_run_bg iperf_pid ip netns exec ovpn_peer0 iperf3 -1 -s 65 + sleep 1 66 + ovpn_cmd_ok "run iperf throughput flow" \ 67 + ip netns exec ovpn_peer1 iperf3 -Z -t 3 -c 5.5.5.1 68 + wait "${iperf_pid}" || return 1 69 + } 70 + 71 + trap ovpn_test_exit EXIT 72 + trap ovpn_stage_err ERR 73 + 74 + ktap_print_header 75 + ktap_set_plan 3 76 + 77 + ovpn_cleanup 14 78 modprobe -q ovpn || true 15 79 16 - for p in $(seq 0 ${NUM_PEERS}); do 17 - create_ns ${p} 18 - done 80 + ovpn_run_stage "setup network topology" ovpn_prepare_network 81 + ovpn_run_stage "run ping traffic" ovpn_run_ping_traffic 82 + ovpn_run_stage "run iperf throughput" ovpn_run_iperf 19 83 20 - for p in $(seq 0 ${NUM_PEERS}); do 21 - setup_ns ${p} 5.5.5.$((${p} + 1))/24 22 - done 23 - 24 - for p in $(seq 0 ${NUM_PEERS}); do 25 - add_peer ${p} 26 - done 27 - 28 - for p in $(seq 1 ${NUM_PEERS}); do 29 - ip netns exec peer0 ${OVPN_CLI} set_peer tun0 ${p} 60 120 30 - ip netns exec peer${p} ${OVPN_CLI} set_peer tun${p} $((${p}+9)) 60 120 31 - done 32 - 33 - sleep 1 34 - 35 - for p in $(seq 1 ${NUM_PEERS}); do 36 - ip netns exec peer0 ping -qfc 500 -w 3 5.5.5.$((${p} + 1)) 37 - done 38 - 39 - ip netns exec peer0 iperf3 -1 -s & 40 - sleep 1 41 - ip netns exec peer1 iperf3 -Z -t 3 -c 5.5.5.1 42 - 43 - cleanup 44 - 45 - modprobe -r ovpn || true 84 + ovpn_test_finished=1 85 + ktap_finished
+1 -1
tools/testing/selftests/net/ovpn/test-float.sh
··· 4 4 # 5 5 # Author: Antonio Quartulli <antonio@openvpn.net> 6 6 7 - FLOAT="1" 7 + OVPN_FLOAT="1" 8 8 9 9 source test.sh
+154 -79
tools/testing/selftests/net/ovpn/test-mark.sh
··· 6 6 # Antonio Quartulli <antonio@openvpn.net> 7 7 8 8 #set -x 9 - set -e 9 + set -eE 10 10 11 11 MARK=1056 12 + MARK_DROP_COUNTER=0 12 13 13 14 source ./common.sh 14 15 15 - cleanup 16 + ovpn_test_finished=0 16 17 18 + ovpn_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 + 27 + ovpn_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 + 64 + ovpn_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 + 74 + ovpn_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 + 97 + ovpn_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 + 134 + ovpn_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 + 141 + ovpn_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 + 152 + trap ovpn_test_exit EXIT 153 + trap ovpn_stage_err ERR 154 + 155 + ktap_print_header 156 + ktap_set_plan 6 157 + 158 + ovpn_cleanup 17 159 modprobe -q ovpn || true 18 160 19 - for p in $(seq 0 "${NUM_PEERS}"); do 20 - create_ns "${p}" 21 - done 161 + ovpn_run_stage "setup marked network topology" ovpn_mark_prepare_network 162 + ovpn_run_stage "run baseline traffic" ovpn_mark_run_baseline_traffic 163 + ovpn_run_stage "install nft mark drop rule" ovpn_mark_add_drop_rule 164 + ovpn_run_stage "drop marked traffic and count packets" \ 165 + ovpn_mark_verify_drop_traffic 166 + ovpn_run_stage "remove nft drop rule" ovpn_mark_remove_drop_rule 167 + ovpn_run_stage "traffic recovers after drop removal" \ 168 + ovpn_mark_verify_traffic_recovery 22 169 23 - for p in $(seq 0 3); do 24 - setup_ns "${p}" 5.5.5.$((p + 1))/24 25 - done 26 - 27 - # add peer0 with mark 28 - ip netns exec peer0 "${OVPN_CLI}" new_multi_peer tun0 1 ASYMM \ 29 - "${UDP_PEERS_FILE}" \ 30 - ${MARK} 31 - for p in $(seq 1 3); do 32 - ip netns exec peer0 "${OVPN_CLI}" new_key tun0 "${p}" 1 0 "${ALG}" 0 \ 33 - data64.key 34 - done 35 - 36 - for p in $(seq 1 3); do 37 - add_peer "${p}" 38 - done 39 - 40 - for p in $(seq 1 3); do 41 - ip netns exec peer0 "${OVPN_CLI}" set_peer tun0 "${p}" 60 120 42 - ip netns exec peer"${p}" "${OVPN_CLI}" set_peer tun"${p}" \ 43 - $((p + 9)) 60 120 44 - done 45 - 46 - sleep 1 47 - 48 - for p in $(seq 1 3); do 49 - ip netns exec peer0 ping -qfc 500 -w 3 5.5.5.$((p + 1)) 50 - done 51 - 52 - echo "Adding an nftables drop rule based on mark value ${MARK}" 53 - ip netns exec peer0 nft flush ruleset 54 - ip netns exec peer0 nft 'add table inet filter' 55 - ip netns exec peer0 nft 'add chain inet filter output { 56 - type filter hook output priority 0; 57 - policy accept; 58 - }' 59 - ip netns exec peer0 nft add rule inet filter output \ 60 - meta mark == ${MARK} \ 61 - counter drop 62 - 63 - DROP_COUNTER=$(ip netns exec peer0 nft list chain inet filter output \ 64 - | sed -n 's/.*packets \([0-9]*\).*/\1/p') 65 - sleep 1 66 - 67 - # ping should fail 68 - for p in $(seq 1 3); do 69 - PING_OUTPUT=$(ip netns exec peer0 ping \ 70 - -qfc 500 -w 1 5.5.5.$((p + 1)) 2>&1) && exit 1 71 - echo "${PING_OUTPUT}" 72 - LOST_PACKETS=$(echo "$PING_OUTPUT" \ 73 - | awk '/packets transmitted/ { print $1 }') 74 - # increment the drop counter by the amount of lost packets 75 - DROP_COUNTER=$((DROP_COUNTER + LOST_PACKETS)) 76 - done 77 - 78 - # check if the final nft counter matches our counter 79 - TOTAL_COUNT=$(ip netns exec peer0 nft list chain inet filter output \ 80 - | sed -n 's/.*packets \([0-9]*\).*/\1/p') 81 - if [ "${DROP_COUNTER}" -ne "${TOTAL_COUNT}" ]; then 82 - echo "Expected ${TOTAL_COUNT} drops, got ${DROP_COUNTER}" 83 - exit 1 84 - fi 85 - 86 - echo "Removing the drop rule" 87 - ip netns exec peer0 nft flush ruleset 88 - sleep 1 89 - 90 - for p in $(seq 1 3); do 91 - ip netns exec peer0 ping -qfc 500 -w 3 5.5.5.$((p + 1)) 92 - done 93 - 94 - cleanup 95 - 96 - modprobe -r ovpn || true 170 + ovpn_test_finished=1 171 + ktap_finished
+2 -2
tools/testing/selftests/net/ovpn/test-symmetric-id-float.sh
··· 5 5 # Author: Ralf Lici <ralf@mandelbit.com> 6 6 # Antonio Quartulli <antonio@openvpn.net> 7 7 8 - SYMMETRIC_ID="1" 9 - FLOAT="1" 8 + OVPN_SYMMETRIC_ID="1" 9 + OVPN_FLOAT="1" 10 10 11 11 source test.sh
+2 -2
tools/testing/selftests/net/ovpn/test-symmetric-id-tcp.sh
··· 5 5 # Author: Ralf Lici <ralf@mandelbit.com> 6 6 # Antonio Quartulli <antonio@openvpn.net> 7 7 8 - PROTO="TCP" 9 - SYMMETRIC_ID=1 8 + OVPN_PROTO="TCP" 9 + OVPN_SYMMETRIC_ID=1 10 10 11 11 source test.sh
+1 -1
tools/testing/selftests/net/ovpn/test-symmetric-id.sh
··· 5 5 # Author: Ralf Lici <ralf@mandelbit.com> 6 6 # Antonio Quartulli <antonio@openvpn.net> 7 7 8 - SYMMETRIC_ID="1" 8 + OVPN_SYMMETRIC_ID="1" 9 9 10 10 source test.sh
+1 -1
tools/testing/selftests/net/ovpn/test-tcp.sh
··· 4 4 # 5 5 # Author: Antonio Quartulli <antonio@openvpn.net> 6 6 7 - PROTO="TCP" 7 + OVPN_PROTO="TCP" 8 8 9 9 source test.sh
+291 -136
tools/testing/selftests/net/ovpn/test.sh
··· 5 5 # Author: Antonio Quartulli <antonio@openvpn.net> 6 6 7 7 #set -x 8 - set -e 8 + set -eE 9 9 10 10 source ./common.sh 11 11 12 - cleanup 12 + ovpn_test_finished=0 13 13 14 - modprobe -q ovpn || true 14 + ovpn_test_exit() { 15 + ovpn_cleanup 16 + modprobe -r ovpn || true 15 17 16 - for p in $(seq 0 ${NUM_PEERS}); do 17 - create_ns ${p} 18 - done 18 + if [ "${ovpn_test_finished}" -eq 0 ]; then 19 + ktap_print_totals 20 + fi 21 + } 19 22 20 - for p in $(seq 0 ${NUM_PEERS}); do 21 - setup_listener ${p} 22 - done 23 + ovpn_prepare_network() { 24 + local p 25 + local peer_ns 23 26 24 - for p in $(seq 0 ${NUM_PEERS}); do 25 - setup_ns ${p} 5.5.5.$((${p} + 1))/24 ${MTU} 26 - done 27 + for p in $(seq 0 ${OVPN_NUM_PEERS}); do 28 + ovpn_cmd_ok "create namespace peer${p}" ovpn_create_ns "${p}" 29 + done 27 30 28 - for p in $(seq 0 ${NUM_PEERS}); do 29 - add_peer ${p} 30 - done 31 + for p in $(seq 0 ${OVPN_NUM_PEERS}); do 32 + ovpn_cmd_ok "start notification listener peer${p}" \ 33 + ovpn_setup_listener "${p}" 34 + # starting all YNL listeners back-to-back can intermittently 35 + # stall their startup so serialize launches a bit 36 + sleep 0.5 37 + done 31 38 32 - for p in $(seq 1 ${NUM_PEERS}); do 33 - ip netns exec peer0 ${OVPN_CLI} set_peer tun0 ${p} 60 120 34 - ip netns exec peer${p} ${OVPN_CLI} set_peer tun${p} \ 35 - $((${p}+ID_OFFSET)) 60 120 36 - done 39 + for p in $(seq 0 ${OVPN_NUM_PEERS}); do 40 + ovpn_cmd_ok "configure peer${p} namespace" ovpn_setup_ns \ 41 + "${p}" 5.5.5.$((p + 1))/24 "${MTU}" 42 + done 37 43 38 - sleep 1 44 + for p in $(seq 0 ${OVPN_NUM_PEERS}); do 45 + ovpn_cmd_ok "register peer${p} in overlay" ovpn_add_peer "${p}" 46 + done 39 47 40 - TCPDUMP_TIMEOUT="1.5s" 41 - for p in $(seq 1 ${NUM_PEERS}); do 42 - # The first part of the data packet header consists of: 43 - # - TCP only: 2 bytes for the packet length 44 - # - 5 bits for opcode ("9" for DATA_V2) 45 - # - 3 bits for key-id ("0" at this point) 46 - # - 12 bytes for peer-id: 47 - # - with asymmetric ID: "${p}" one way and "${p} + 9" the other way 48 - # - with symmetric ID: "${p}" both ways 49 - HEADER1=$(printf "0x4800000%x" ${p}) 50 - HEADER2=$(printf "0x4800000%x" $((${p} + ID_OFFSET))) 51 - RADDR="" 52 - if [ "${PROTO}" == "UDP" ]; then 53 - RADDR=$(awk "NR == ${p} {print \$3}" ${UDP_PEERS_FILE}) 48 + for p in $(seq 1 ${OVPN_NUM_PEERS}); do 49 + peer_ns="ovpn_peer${p}" 50 + ovpn_cmd_ok "set peer0 timeout for peer ${p}" \ 51 + ip netns exec ovpn_peer0 ${OVPN_CLI} set_peer tun0 \ 52 + ${p} 60 120 53 + ovpn_cmd_ok "set peer${p} timeout for peer ${p}" \ 54 + ip netns exec "${peer_ns}" ${OVPN_CLI} set_peer \ 55 + tun${p} $((p + OVPN_ID_OFFSET)) 60 120 56 + done 57 + } 58 + 59 + ovpn_run_basic_traffic() { 60 + local p 61 + local header1 62 + local header2 63 + local peer_ns 64 + local raddr 65 + local tcpdump_pid1 66 + local tcpdump_pid2 67 + local tcpdump_timeout="1.5s" 68 + 69 + for p in $(seq 1 ${OVPN_NUM_PEERS}); do 70 + # The first part of the data packet header consists of: 71 + # - TCP only: 2 bytes for the packet length 72 + # - 5 bits for opcode ("9" for DATA_V2) 73 + # - 3 bits for key-id ("0" at this point) 74 + # - 12 bytes for peer-id: 75 + # - with asymmetric ID: "${p}" one way and "${p} + 9" the 76 + # other way 77 + # - with symmetric ID: "${p}" both ways 78 + header1=$(printf "0x4800000%x" ${p}) 79 + header2=$(printf "0x4800000%x" $((p + OVPN_ID_OFFSET))) 80 + raddr="" 81 + if [ "${OVPN_PROTO}" == "UDP" ]; then 82 + raddr=$(awk "NR == ${p} {print \$3}" \ 83 + "${OVPN_UDP_PEERS_FILE}") 84 + fi 85 + peer_ns="ovpn_peer${p}" 86 + 87 + timeout ${tcpdump_timeout} ip netns exec "${peer_ns}" \ 88 + tcpdump --immediate-mode -p -ni veth${p} -c 1 \ 89 + "$(ovpn_build_capture_filter "${header1}" "${raddr}")" \ 90 + >/dev/null 2>&1 & 91 + tcpdump_pid1=$! 92 + timeout ${tcpdump_timeout} ip netns exec "${peer_ns}" \ 93 + tcpdump --immediate-mode -p -ni veth${p} -c 1 \ 94 + "$(ovpn_build_capture_filter "${header2}" "${raddr}")" \ 95 + >/dev/null 2>&1 & 96 + tcpdump_pid2=$! 97 + 98 + sleep 0.3 99 + ovpn_cmd_ok "send baseline traffic to peer ${p}" \ 100 + ip netns exec ovpn_peer0 \ 101 + ping -qfc 500 -w 3 5.5.5.$((p + 1)) 102 + ovpn_cmd_ok "send large-payload traffic to peer ${p}" \ 103 + ip netns exec ovpn_peer0 \ 104 + ping -qfc 500 -s 3000 -w 3 5.5.5.$((p + 1)) 105 + 106 + wait "${tcpdump_pid1}" || return 1 107 + wait "${tcpdump_pid2}" || return 1 108 + done 109 + } 110 + 111 + ovpn_run_lan_traffic() { 112 + ovpn_cmd_ok "ping LAN behind peer1" \ 113 + ip netns exec ovpn_peer0 ping -qfc 500 -w 3 "${OVPN_LAN_IP}" 114 + } 115 + 116 + ovpn_run_float_mode() { 117 + local p 118 + local peer_ns 119 + 120 + for p in $(seq 1 ${OVPN_NUM_PEERS}); do 121 + peer_ns="ovpn_peer${p}" 122 + ovpn_cmd_ok "float: remove old transport address on peer${p}" \ 123 + ip -n "${peer_ns}" addr del 10.10.${p}.2/24 dev veth${p} 124 + ovpn_cmd_ok "float: add new transport address on peer${p}" \ 125 + ip -n "${peer_ns}" addr add 10.10.${p}.3/24 dev veth${p} 126 + done 127 + for p in $(seq 1 ${OVPN_NUM_PEERS}); do 128 + peer_ns="ovpn_peer${p}" 129 + ovpn_cmd_ok "ping tunnel after float peer ${p}" \ 130 + ip netns exec "${peer_ns}" ping -qfc 500 -w 3 5.5.5.1 131 + done 132 + } 133 + 134 + ovpn_run_iperf() { 135 + local iperf_pid 136 + 137 + ovpn_run_bg iperf_pid ip netns exec ovpn_peer0 iperf3 -1 -s 138 + sleep 1 139 + 140 + ovpn_cmd_ok "run iperf throughput flow" \ 141 + ip netns exec ovpn_peer1 iperf3 -Z -t 3 -c 5.5.5.1 142 + wait "${iperf_pid}" || return 1 143 + } 144 + 145 + ovpn_run_key_rollover() { 146 + local p 147 + local peer_ns 148 + 149 + ovpn_log "Adding secondary key and then swap:" 150 + 151 + for p in $(seq 1 ${OVPN_NUM_PEERS}); do 152 + peer_ns="ovpn_peer${p}" 153 + ovpn_cmd_ok "add secondary key on peer0 for peer ${p}" \ 154 + ip netns exec ovpn_peer0 ${OVPN_CLI} new_key tun0 \ 155 + ${p} 2 1 ${OVPN_ALG} 0 data64.key 156 + ovpn_cmd_ok "add secondary key on peer${p} for peer ${p}" \ 157 + ip netns exec "${peer_ns}" ${OVPN_CLI} new_key tun${p} \ 158 + $((p + OVPN_ID_OFFSET)) 2 1 ${OVPN_ALG} 1 \ 159 + data64.key 160 + ovpn_cmd_ok "swap keys on peer${p}" \ 161 + ip netns exec "${peer_ns}" ${OVPN_CLI} swap_keys \ 162 + tun${p} $((p + OVPN_ID_OFFSET)) 163 + done 164 + } 165 + 166 + ovpn_run_queries() { 167 + ovpn_log "Querying all peers:" 168 + 169 + ovpn_cmd_ok "query all peers from peer0" \ 170 + ip netns exec ovpn_peer0 ${OVPN_CLI} get_peer tun0 171 + ovpn_cmd_ok "query all peers from peer1" \ 172 + ip netns exec ovpn_peer1 ${OVPN_CLI} get_peer tun1 173 + 174 + ovpn_log "Querying peer 1:" 175 + 176 + ovpn_cmd_ok "query peer 1 from peer0" \ 177 + ip netns exec ovpn_peer0 ${OVPN_CLI} get_peer tun0 1 178 + } 179 + 180 + ovpn_query_peer_missing() { 181 + ovpn_log "Querying non-existent peer 20:" 182 + 183 + ovpn_cmd_fail "query missing peer 20 on peer0" \ 184 + ip netns exec ovpn_peer0 ${OVPN_CLI} get_peer tun0 20 185 + } 186 + 187 + ovpn_run_peer_cleanup() { 188 + local p 189 + local peer_ns 190 + 191 + ovpn_log "Deleting peer 1:" 192 + 193 + ovpn_cmd_ok "delete peer1 on peer0" \ 194 + ip netns exec ovpn_peer0 ${OVPN_CLI} del_peer tun0 1 195 + ovpn_cmd_ok "delete peer1 on peer1" \ 196 + ip netns exec ovpn_peer1 ${OVPN_CLI} del_peer tun1 \ 197 + $((1 + OVPN_ID_OFFSET)) 198 + 199 + ovpn_log "Querying keys:" 200 + 201 + for p in $(seq 2 ${OVPN_NUM_PEERS}); do 202 + peer_ns="ovpn_peer${p}" 203 + ovpn_cmd_ok "query peer${p} key 1" \ 204 + ip netns exec "${peer_ns}" ${OVPN_CLI} get_key tun${p} \ 205 + $((p + OVPN_ID_OFFSET)) 1 206 + ovpn_cmd_ok "query peer${p} key 2" \ 207 + ip netns exec "${peer_ns}" ${OVPN_CLI} get_key tun${p} \ 208 + $((p + OVPN_ID_OFFSET)) 2 209 + done 210 + } 211 + 212 + ovpn_run_traffic_delete_peer() { 213 + local ping_pid 214 + 215 + ovpn_log "Deleting peer while sending traffic:" 216 + 217 + ovpn_run_bg ping_pid ip netns exec ovpn_peer2 ping -qf -w 4 5.5.5.1 218 + sleep 2 219 + ovpn_cmd_ok "delete peer0 peer 2" \ 220 + ip netns exec ovpn_peer0 ${OVPN_CLI} del_peer tun0 2 221 + 222 + if [ "${OVPN_PROTO}" == "TCP" ]; then 223 + # In TCP mode this command is expected to fail for both peers. 224 + ovpn_cmd_mayfail "delete peer2 peer 2 (TCP non-fatal)" \ 225 + ip netns exec ovpn_peer2 ${OVPN_CLI} del_peer tun2 \ 226 + $((2 + OVPN_ID_OFFSET)) 227 + else 228 + ovpn_cmd_ok "delete peer2 peer 2" ip netns exec ovpn_peer2 \ 229 + ${OVPN_CLI} del_peer tun2 $((2 + OVPN_ID_OFFSET)) 54 230 fi 55 231 56 - timeout ${TCPDUMP_TIMEOUT} ip netns exec peer${p} \ 57 - tcpdump --immediate-mode -p -ni veth${p} -c 1 \ 58 - "$(build_capture_filter "${HEADER1}" "${RADDR}")" \ 59 - >/dev/null 2>&1 & 60 - TCPDUMP_PID1=$! 61 - timeout ${TCPDUMP_TIMEOUT} ip netns exec peer${p} \ 62 - tcpdump --immediate-mode -p -ni veth${p} -c 1 \ 63 - "$(build_capture_filter "${HEADER2}" "${RADDR}")" \ 64 - >/dev/null 2>&1 & 65 - TCPDUMP_PID2=$! 232 + wait "${ping_pid}" || true 233 + } 66 234 67 - sleep 0.3 68 - ip netns exec peer0 ping -qfc 500 -w 3 5.5.5.$((${p} + 1)) 69 - ip netns exec peer0 ping -qfc 500 -s 3000 -w 3 5.5.5.$((${p} + 1)) 235 + ovpn_run_key_cleanup() { 236 + local p 237 + local peer_ns 70 238 71 - wait ${TCPDUMP_PID1} 72 - wait ${TCPDUMP_PID2} 73 - done 239 + ovpn_log "Deleting keys:" 74 240 75 - # ping LAN behind client 1 76 - ip netns exec peer0 ping -qfc 500 -w 3 ${LAN_IP} 77 - 78 - if [ "$FLOAT" == "1" ]; then 79 - # make clients float.. 80 - for p in $(seq 1 ${NUM_PEERS}); do 81 - ip -n peer${p} addr del 10.10.${p}.2/24 dev veth${p} 82 - ip -n peer${p} addr add 10.10.${p}.3/24 dev veth${p} 241 + for p in $(seq 3 ${OVPN_NUM_PEERS}); do 242 + peer_ns="ovpn_peer${p}" 243 + ovpn_cmd_ok "delete key 1 for peer${p}" \ 244 + ip netns exec "${peer_ns}" ${OVPN_CLI} del_key tun${p} \ 245 + $((p + OVPN_ID_OFFSET)) 1 246 + ovpn_cmd_ok "delete key 2 for peer${p}" \ 247 + ip netns exec "${peer_ns}" ${OVPN_CLI} del_key tun${p} \ 248 + $((p + OVPN_ID_OFFSET)) 2 83 249 done 84 - for p in $(seq 1 ${NUM_PEERS}); do 85 - ip netns exec peer${p} ping -qfc 500 -w 3 5.5.5.1 250 + } 251 + 252 + ovpn_run_timeouts() { 253 + local p 254 + local peer_ns 255 + 256 + ovpn_log "Setting timeout to 3s MP:" 257 + 258 + for p in $(seq 3 ${OVPN_NUM_PEERS}); do 259 + # Non-fatal: this may fail in some protocol modes. 260 + ovpn_cmd_mayfail "set peer0 timeout for peer ${p} (non-fatal)" \ 261 + ip netns exec ovpn_peer0 ${OVPN_CLI} set_peer tun0 \ 262 + ${p} 3 3 263 + peer_ns="ovpn_peer${p}" 264 + ovpn_cmd_ok "disable timeout on peer${p} while peer0 adjusts \ 265 + state" ip netns exec "${peer_ns}" ${OVPN_CLI} set_peer \ 266 + tun${p} $((p + OVPN_ID_OFFSET)) 0 0 86 267 done 268 + # wait for peers to timeout 269 + sleep 5 270 + 271 + ovpn_log "Setting timeout to 3s P2P:" 272 + 273 + for p in $(seq 3 ${OVPN_NUM_PEERS}); do 274 + peer_ns="ovpn_peer${p}" 275 + ovpn_cmd_ok "set peer${p} P2P timeout" \ 276 + ip netns exec "${peer_ns}" ${OVPN_CLI} set_peer \ 277 + tun${p} $((p + OVPN_ID_OFFSET)) 3 3 278 + done 279 + sleep 5 280 + } 281 + 282 + ovpn_run_notifications() { 283 + local p 284 + 285 + for p in $(seq 0 ${OVPN_NUM_PEERS}); do 286 + ovpn_cmd_ok "validate listener output for peer ${p}" \ 287 + ovpn_compare_ntfs "${p}" 288 + done 289 + } 290 + 291 + trap ovpn_test_exit EXIT 292 + trap ovpn_stage_err ERR 293 + 294 + ktap_print_header 295 + if [ "${OVPN_FLOAT}" == "1" ]; then 296 + ktap_set_plan 13 297 + else 298 + ktap_set_plan 12 87 299 fi 88 300 89 - ip netns exec peer0 iperf3 -1 -s & 90 - sleep 1 91 - ip netns exec peer1 iperf3 -Z -t 3 -c 5.5.5.1 301 + ovpn_cleanup 302 + modprobe -q ovpn || true 92 303 93 - echo "Adding secondary key and then swap:" 94 - for p in $(seq 1 ${NUM_PEERS}); do 95 - ip netns exec peer0 ${OVPN_CLI} new_key tun0 ${p} 2 1 ${ALG} 0 \ 96 - data64.key 97 - ip netns exec peer${p} ${OVPN_CLI} new_key tun${p} \ 98 - $((${p} + ID_OFFSET)) 2 1 ${ALG} 1 data64.key 99 - ip netns exec peer${p} ${OVPN_CLI} swap_keys tun${p} \ 100 - $((${p} + ID_OFFSET)) 101 - done 304 + ovpn_run_stage "setup network topology" ovpn_prepare_network 305 + ovpn_run_stage "run baseline data traffic" ovpn_run_basic_traffic 306 + ovpn_run_stage "run LAN traffic behind peer1" ovpn_run_lan_traffic 307 + [ "${OVPN_FLOAT}" == "1" ] && ovpn_run_stage "run floating peer checks" \ 308 + ovpn_run_float_mode 309 + ovpn_run_stage "run iperf throughput" ovpn_run_iperf 310 + ovpn_run_stage "run key rollout" ovpn_run_key_rollover 311 + ovpn_run_stage "query peers" ovpn_run_queries 312 + ovpn_run_stage "query missing peer fails" ovpn_query_peer_missing 313 + ovpn_run_stage "peer lifecycle and key queries" ovpn_run_peer_cleanup 314 + ovpn_run_stage "delete peer while traffic" ovpn_run_traffic_delete_peer 315 + ovpn_run_stage "delete stale keys" ovpn_run_key_cleanup 316 + ovpn_run_stage "check timeout behavior" ovpn_run_timeouts 317 + ovpn_run_stage "validate notification output" ovpn_run_notifications 102 318 103 - sleep 1 104 - 105 - echo "Querying all peers:" 106 - ip netns exec peer0 ${OVPN_CLI} get_peer tun0 107 - ip netns exec peer1 ${OVPN_CLI} get_peer tun1 108 - 109 - echo "Querying peer 1:" 110 - ip netns exec peer0 ${OVPN_CLI} get_peer tun0 1 111 - 112 - echo "Querying non-existent peer 20:" 113 - ip netns exec peer0 ${OVPN_CLI} get_peer tun0 20 || true 114 - 115 - echo "Deleting peer 1:" 116 - ip netns exec peer0 ${OVPN_CLI} del_peer tun0 1 117 - ip netns exec peer1 ${OVPN_CLI} del_peer tun1 $((1 + ID_OFFSET)) 118 - 119 - echo "Querying keys:" 120 - for p in $(seq 2 ${NUM_PEERS}); do 121 - ip netns exec peer${p} ${OVPN_CLI} get_key tun${p} \ 122 - $((${p} + ID_OFFSET)) 1 123 - ip netns exec peer${p} ${OVPN_CLI} get_key tun${p} \ 124 - $((${p} + ID_OFFSET)) 2 125 - done 126 - 127 - echo "Deleting peer while sending traffic:" 128 - (ip netns exec peer2 ping -qf -w 4 5.5.5.1)& 129 - sleep 2 130 - ip netns exec peer0 ${OVPN_CLI} del_peer tun0 2 131 - # following command fails in TCP mode 132 - # (both ends get conn reset when one peer disconnects) 133 - ip netns exec peer2 ${OVPN_CLI} del_peer tun2 $((2 + ID_OFFSET)) || true 134 - 135 - echo "Deleting keys:" 136 - for p in $(seq 3 ${NUM_PEERS}); do 137 - ip netns exec peer${p} ${OVPN_CLI} del_key tun${p} \ 138 - $((${p} + ID_OFFSET)) 1 139 - ip netns exec peer${p} ${OVPN_CLI} del_key tun${p} \ 140 - $((${p} + ID_OFFSET)) 2 141 - done 142 - 143 - echo "Setting timeout to 3s MP:" 144 - for p in $(seq 3 ${NUM_PEERS}); do 145 - ip netns exec peer0 ${OVPN_CLI} set_peer tun0 ${p} 3 3 || true 146 - ip netns exec peer${p} ${OVPN_CLI} set_peer tun${p} \ 147 - $((${p} + ID_OFFSET)) 0 0 148 - done 149 - # wait for peers to timeout 150 - sleep 5 151 - 152 - echo "Setting timeout to 3s P2P:" 153 - for p in $(seq 3 ${NUM_PEERS}); do 154 - ip netns exec peer${p} ${OVPN_CLI} set_peer tun${p} \ 155 - $((${p} + ID_OFFSET)) 3 3 156 - done 157 - sleep 5 158 - 159 - for p in $(seq 0 ${NUM_PEERS}); do 160 - compare_ntfs ${p} 161 - done 162 - 163 - cleanup 164 - 165 - modprobe -r ovpn || true 319 + ovpn_test_finished=1 320 + ktap_finished