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.

at master 364 lines 8.8 kB view raw
1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3# Copyright (C) 2020-2025 OpenVPN, Inc. 4# 5# Author: Antonio Quartulli <antonio@openvpn.net> 6 7OVPN_COMMON_DIR=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")") 8source "$OVPN_COMMON_DIR/../../kselftest/ktap_helpers.sh" 9 10OVPN_UDP_PEERS_FILE=${OVPN_UDP_PEERS_FILE:-udp_peers.txt} 11OVPN_TCP_PEERS_FILE=${OVPN_TCP_PEERS_FILE:-tcp_peers.txt} 12OVPN_CLI=${OVPN_CLI:-${OVPN_COMMON_DIR}/ovpn-cli} 13OVPN_YNL=${OVPN_YNL:-${OVPN_COMMON_DIR}/../../../../net/ynl/pyynl/cli.py} 14OVPN_ALG=${OVPN_ALG:-aes} 15OVPN_PROTO=${OVPN_PROTO:-UDP} 16OVPN_FLOAT=${OVPN_FLOAT:-0} 17OVPN_SYMMETRIC_ID=${OVPN_SYMMETRIC_ID:-0} 18OVPN_VERBOSE=${OVPN_VERBOSE:-0} 19 20export OVPN_ID_OFFSET=$(( 9 * (OVPN_SYMMETRIC_ID == 0) )) 21 22OVPN_JQ_FILTER='map(if type == "array" then .[] else . end) | 23 map(select(.msg.peer | has("remote-ipv6") | not)) | 24 map(del(.msg.ifindex)) | sort_by(.msg.peer.id)[]' 25OVPN_LAN_IP="11.11.11.11" 26 27declare -A OVPN_TMP_JSONS=() 28declare -A OVPN_LISTENER_PIDS=() 29OVPN_CURRENT_STAGE="" 30 31ovpn_is_verbose() { 32 [[ "${OVPN_VERBOSE}" == "1" ]] 33} 34 35ovpn_log() { 36 ovpn_is_verbose || return 0 37 printf '%s\n' "$*" 38} 39 40ovpn_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 51ovpn_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 91ovpn_cmd_ok() { 92 ovpn_cmd_run ok "$@" 93} 94 95ovpn_cmd_mayfail() { 96 ovpn_cmd_run mayfail "$@" 97} 98 99ovpn_cmd_fail() { 100 ovpn_cmd_run fail "$@" 101} 102 103ovpn_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 116ovpn_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 126ovpn_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 135ovpn_create_ns() { 136 ip netns add "ovpn_peer${1}" 137} 138 139ovpn_setup_ns() { 140 local peer="ovpn_peer${1}" 141 local server_ns="ovpn_peer0" 142 local peer_ns 143 MODE="P2P" 144 145 if [ ${1} -eq 0 ]; then 146 MODE="MP" 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}" 151 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 157 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 162 done 163 fi 164 165 ip netns exec "${peer}" ${OVPN_CLI} new_iface tun${1} $MODE 166 ip -n "${peer}" addr add ${2} dev tun${1} 167 # add a secondary IP to peer 1, to test a LAN behind a client 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 172 fi 173 if [ -n "${3}" ]; then 174 ip -n "${peer}" link set mtu ${3} dev tun${1} 175 fi 176 ip -n "${peer}" link set tun${1} up 177} 178 179ovpn_build_capture_filter() { 180 # match the first four bytes of the openvpn data payload 181 if [ "${OVPN_PROTO}" == "UDP" ]; then 182 # For UDP, libpcap transport indexing only works for IPv4, so 183 # use an explicit IPv4 or IPv6 expression based on the peer 184 # address. The IPv6 branch assumes there are no extension 185 # headers in the outer packet. 186 if [[ "${2}" == *:* ]]; then 187 printf "ip6 and ip6[6] = 17 and ip6[48:4] = %s" "${1}" 188 else 189 printf "ip and udp[8:4] = %s" "${1}" 190 fi 191 else 192 # openvpn over TCP prepends a 2-byte packet length ahead of the 193 # DATA_V2 opcode, so skip it before matching the payload header 194 printf "ip and tcp[(((tcp[12] & 0xf0) >> 2) + 2):4] = %s" "${1}" 195 fi 196} 197 198ovpn_setup_listener() { 199 local peer="$1" 200 local file 201 local peer_ns="ovpn_peer${peer}" 202 203 file=$(mktemp) 204 PYTHONUNBUFFERED=1 ip netns exec "${peer_ns}" "${OVPN_YNL}" --family \ 205 ovpn --subscribe peers --output-json > "${file}" \ 206 2>/dev/null & 207 OVPN_LISTENER_PIDS["${peer}"]=$! 208 OVPN_TMP_JSONS["${peer}"]="${file}" 209} 210 211ovpn_add_peer() { 212 labels=("ASYMM" "SYMM") 213 local peer_ns 214 local server_ns="ovpn_peer0" 215 M_ID=${labels[OVPN_SYMMETRIC_ID]} 216 217 if [ "${OVPN_PROTO}" == "UDP" ]; then 218 if [ ${1} -eq 0 ]; then 219 ip netns exec "${server_ns}" ${OVPN_CLI} \ 220 new_multi_peer tun0 1 ${M_ID} \ 221 ${OVPN_UDP_PEERS_FILE} 222 223 for p in $(seq 1 ${OVPN_NUM_PEERS}); do 224 ip netns exec "${server_ns}" ${OVPN_CLI} \ 225 new_key tun0 ${p} 1 0 ${OVPN_ALG} 0 \ 226 data64.key 227 done 228 else 229 peer_ns="ovpn_peer${1}" 230 if [ "${OVPN_SYMMETRIC_ID}" -eq 1 ]; then 231 PEER_ID=${1} 232 TX_ID="none" 233 else 234 PEER_ID=$(awk "NR == ${1} {print \$2}" \ 235 ${OVPN_UDP_PEERS_FILE}) 236 TX_ID=${1} 237 fi 238 RADDR=$(awk "NR == ${1} {print \$3}" \ 239 ${OVPN_UDP_PEERS_FILE}) 240 RPORT=$(awk "NR == ${1} {print \$4}" \ 241 ${OVPN_UDP_PEERS_FILE}) 242 LPORT=$(awk "NR == ${1} {print \$6}" \ 243 ${OVPN_UDP_PEERS_FILE}) 244 ip netns exec "${peer_ns}" ${OVPN_CLI} new_peer \ 245 tun${1} ${PEER_ID} ${TX_ID} ${LPORT} ${RADDR} \ 246 ${RPORT} 247 ip netns exec "${peer_ns}" ${OVPN_CLI} new_key tun${1} \ 248 ${PEER_ID} 1 0 ${OVPN_ALG} 1 data64.key 249 fi 250 else 251 if [ ${1} -eq 0 ]; then 252 (ip netns exec "${server_ns}" ${OVPN_CLI} listen tun0 \ 253 1 ${M_ID} ${OVPN_TCP_PEERS_FILE} && { 254 for p in $(seq 1 ${OVPN_NUM_PEERS}); do 255 ip netns exec "${server_ns}" \ 256 ${OVPN_CLI} new_key tun0 ${p} \ 257 1 0 ${OVPN_ALG} 0 data64.key 258 done 259 }) & 260 sleep 5 261 else 262 peer_ns="ovpn_peer${1}" 263 if [ "${OVPN_SYMMETRIC_ID}" -eq 1 ]; then 264 PEER_ID=${1} 265 TX_ID="none" 266 else 267 PEER_ID=$(awk "NR == ${1} {print \$2}" \ 268 ${OVPN_TCP_PEERS_FILE}) 269 TX_ID=${1} 270 fi 271 ip netns exec "${peer_ns}" ${OVPN_CLI} connect tun${1} \ 272 ${PEER_ID} ${TX_ID} 10.10.${1}.1 1 data64.key 273 fi 274 fi 275} 276 277ovpn_compare_ntfs() { 278 local diff_rc=0 279 local diff_file 280 281 if [ ${#OVPN_TMP_JSONS[@]} -gt 0 ]; then 282 suffix="" 283 [ "${OVPN_SYMMETRIC_ID}" -eq 1 ] && suffix="${suffix}-symm" 284 [ "$OVPN_FLOAT" == 1 ] && suffix="${suffix}-float" 285 expected="json/peer${1}${suffix}.json" 286 received="${OVPN_TMP_JSONS[$1]}" 287 diff_file=$(mktemp) 288 289 ovpn_stop_listener "${1}" 1 290 printf "Checking notifications for peer ${1}... " 291 if diff <(jq -s "${OVPN_JQ_FILTER}" ${expected}) \ 292 <(jq -s "${OVPN_JQ_FILTER}" ${received}) \ 293 >"${diff_file}" 2>&1; then 294 echo "OK" 295 else 296 diff_rc=$? 297 echo "failed" 298 cat "${diff_file}" 299 fi 300 301 rm -f "${diff_file}" || true 302 rm -f "${received}" || true 303 unset "OVPN_TMP_JSONS[$1]" 304 fi 305 306 return "${diff_rc}" 307} 308 309ovpn_stop_listener() { 310 local peer="$1" 311 local keep_json="${2:-0}" 312 local pid="${OVPN_LISTENER_PIDS[$peer]:-}" 313 local json="${OVPN_TMP_JSONS[$peer]:-}" 314 315 if [[ -n "${pid}" ]]; then 316 kill -TERM "${pid}" 2>/dev/null || true 317 wait "${pid}" 2>/dev/null || true 318 unset "OVPN_LISTENER_PIDS[$peer]" 319 fi 320 321 if [[ -n "${json}" && "${keep_json}" -eq 0 ]]; then 322 rm -f "${json}" || true 323 unset "OVPN_TMP_JSONS[$peer]" 324 fi 325} 326 327ovpn_cleanup_peer_ns() { 328 local peer="$1" 329 local peer_id="${peer#ovpn_peer}" 330 331 ip -n "${peer}" link set tun${peer_id} down 2>/dev/null || true 332 ip netns exec "${peer}" ${OVPN_CLI} del_iface tun${peer_id} \ 333 1>/dev/null 2>&1 || true 334 ip netns del "${peer}" 2>/dev/null || true 335} 336 337ovpn_cleanup() { 338 local peer 339 340 # some ovpn-cli processes sleep in background so they need manual poking 341 killall "$(basename "${OVPN_CLI}")" 2>/dev/null || true 342 343 for peer in "${!OVPN_LISTENER_PIDS[@]}"; do 344 ovpn_stop_listener "${peer}" 2>/dev/null 345 done 346 347 for p in $(seq 1 10); do 348 ip -n ovpn_peer0 link del veth${p} 2>/dev/null || true 349 done 350 351 # remove from ovpn's netns pool 352 while IFS= read -r peer; do 353 [[ -n "${peer}" ]] || continue 354 ovpn_cleanup_peer_ns "${peer}" 2>/dev/null 355 done < <(ip netns list 2>/dev/null | awk '/^ovpn_/ {print $1}') 356} 357 358if [ "${OVPN_PROTO}" == "UDP" ]; then 359 OVPN_NUM_PEERS=${OVPN_NUM_PEERS:-$(wc -l ${OVPN_UDP_PEERS_FILE} | \ 360 awk '{print $1}')} 361else 362 OVPN_NUM_PEERS=${OVPN_NUM_PEERS:-$(wc -l ${OVPN_TCP_PEERS_FILE} | \ 363 awk '{print $1}')} 364fi