xref: /linux/tools/testing/selftests/net/ovpn/common.sh (revision 77de28cd7cf172e782319a144bf64e693794d78b)
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