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 7UDP_PEERS_FILE=${UDP_PEERS_FILE:-udp_peers.txt} 8TCP_PEERS_FILE=${TCP_PEERS_FILE:-tcp_peers.txt} 9OVPN_CLI=${OVPN_CLI:-./ovpn-cli} 10YNL_CLI=${YNL_CLI:-../../../../net/ynl/pyynl/cli.py} 11ALG=${ALG:-aes} 12PROTO=${PROTO:-UDP} 13FLOAT=${FLOAT:-0} 14 15JQ_FILTER='map(select(.msg.peer | has("remote-ipv6") | not)) | 16 map(del(.msg.ifindex)) | sort_by(.msg.peer.id)[]' 17LAN_IP="11.11.11.11" 18 19declare -A tmp_jsons=() 20declare -A listener_pids=() 21 22create_ns() { 23 ip netns add peer${1} 24} 25 26setup_ns() { 27 MODE="P2P" 28 29 if [ ${1} -eq 0 ]; then 30 MODE="MP" 31 for p in $(seq 1 ${NUM_PEERS}); do 32 ip link add veth${p} netns peer0 type veth peer name veth${p} netns peer${p} 33 34 ip -n peer0 addr add 10.10.${p}.1/24 dev veth${p} 35 ip -n peer0 addr add fd00:0:0:${p}::1/64 dev veth${p} 36 ip -n peer0 link set veth${p} up 37 38 ip -n peer${p} addr add 10.10.${p}.2/24 dev veth${p} 39 ip -n peer${p} addr add fd00:0:0:${p}::2/64 dev veth${p} 40 ip -n peer${p} link set veth${p} up 41 done 42 fi 43 44 ip netns exec peer${1} ${OVPN_CLI} new_iface tun${1} $MODE 45 ip -n peer${1} addr add ${2} dev tun${1} 46 # add a secondary IP to peer 1, to test a LAN behind a client 47 if [ ${1} -eq 1 -a -n "${LAN_IP}" ]; then 48 ip -n peer${1} addr add ${LAN_IP} dev tun${1} 49 ip -n peer0 route add ${LAN_IP} via $(echo ${2} |sed -e s'!/.*!!') dev tun0 50 fi 51 if [ -n "${3}" ]; then 52 ip -n peer${1} link set mtu ${3} dev tun${1} 53 fi 54 ip -n peer${1} link set tun${1} up 55} 56 57setup_listener() { 58 file=$(mktemp) 59 PYTHONUNBUFFERED=1 ip netns exec peer${p} ${YNL_CLI} --family ovpn \ 60 --subscribe peers --output-json --duration 40 > ${file} & 61 listener_pids[$1]=$! 62 tmp_jsons[$1]="${file}" 63} 64 65add_peer() { 66 if [ "${PROTO}" == "UDP" ]; then 67 if [ ${1} -eq 0 ]; then 68 ip netns exec peer0 ${OVPN_CLI} new_multi_peer tun0 1 ${UDP_PEERS_FILE} 69 70 for p in $(seq 1 ${NUM_PEERS}); do 71 ip netns exec peer0 ${OVPN_CLI} new_key tun0 ${p} 1 0 ${ALG} 0 \ 72 data64.key 73 done 74 else 75 RADDR=$(awk "NR == ${1} {print \$2}" ${UDP_PEERS_FILE}) 76 RPORT=$(awk "NR == ${1} {print \$3}" ${UDP_PEERS_FILE}) 77 LPORT=$(awk "NR == ${1} {print \$5}" ${UDP_PEERS_FILE}) 78 ip netns exec peer${1} ${OVPN_CLI} new_peer tun${1} ${1} ${LPORT} \ 79 ${RADDR} ${RPORT} 80 ip netns exec peer${1} ${OVPN_CLI} new_key tun${1} ${1} 1 0 ${ALG} 1 \ 81 data64.key 82 fi 83 else 84 if [ ${1} -eq 0 ]; then 85 (ip netns exec peer0 ${OVPN_CLI} listen tun0 1 ${TCP_PEERS_FILE} && { 86 for p in $(seq 1 ${NUM_PEERS}); do 87 ip netns exec peer0 ${OVPN_CLI} new_key tun0 ${p} 1 0 \ 88 ${ALG} 0 data64.key 89 done 90 }) & 91 sleep 5 92 else 93 ip netns exec peer${1} ${OVPN_CLI} connect tun${1} ${1} 10.10.${1}.1 1 \ 94 data64.key 95 fi 96 fi 97} 98 99compare_ntfs() { 100 if [ ${#tmp_jsons[@]} -gt 0 ]; then 101 [ "$FLOAT" == 1 ] && suffix="-float" 102 expected="json/peer${1}${suffix}.json" 103 received="${tmp_jsons[$1]}" 104 105 kill -TERM ${listener_pids[$1]} || true 106 wait ${listener_pids[$1]} || true 107 printf "Checking notifications for peer ${1}... " 108 if diff <(jq -s "${JQ_FILTER}" ${expected}) \ 109 <(jq -s "${JQ_FILTER}" ${received}); then 110 echo "OK" 111 fi 112 113 rm -f ${received} || true 114 fi 115} 116 117cleanup() { 118 # some ovpn-cli processes sleep in background so they need manual poking 119 killall $(basename ${OVPN_CLI}) 2>/dev/null || true 120 121 # netns peer0 is deleted without erasing ifaces first 122 for p in $(seq 1 10); do 123 ip -n peer${p} link set tun${p} down 2>/dev/null || true 124 ip netns exec peer${p} ${OVPN_CLI} del_iface tun${p} 2>/dev/null || true 125 done 126 for p in $(seq 1 10); do 127 ip -n peer0 link del veth${p} 2>/dev/null || true 128 done 129 for p in $(seq 0 10); do 130 ip netns del peer${p} 2>/dev/null || true 131 done 132} 133 134if [ "${PROTO}" == "UDP" ]; then 135 NUM_PEERS=${NUM_PEERS:-$(wc -l ${UDP_PEERS_FILE} | awk '{print $1}')} 136else 137 NUM_PEERS=${NUM_PEERS:-$(wc -l ${TCP_PEERS_FILE} | awk '{print $1}')} 138fi 139