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.

selftests: ovpn: check asymmetric peer-id

Extend the base test to verify that the correct peer-id is set in data
packet headers. This is done by capturing ping packets with tcpdump during
the initial exchange and matching the first portion of the header
against the expected sequence for every connection.

Cc: Shuah Khan <shuah@kernel.org>
Cc: linux-kselftest@vger.kernel.org
Cc: horms@kernel.org
Signed-off-by: Ralf Lici <ralf@mandelbit.com>
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>

authored by

Ralf Lici and committed by
Antonio Quartulli
367f4b16 2e570a51

+263 -81
+3
tools/testing/selftests/net/ovpn/Makefile
··· 38 38 test-close-socket.sh \ 39 39 test-float.sh \ 40 40 test-large-mtu.sh \ 41 + test-symmetric-id-float.sh \ 42 + test-symmetric-id-tcp.sh \ 43 + test-symmetric-id.sh \ 41 44 test-tcp.sh \ 42 45 test.sh \ 43 46 # end of TEST_PROGS
+57 -12
tools/testing/selftests/net/ovpn/common.sh
··· 11 11 ALG=${ALG:-aes} 12 12 PROTO=${PROTO:-UDP} 13 13 FLOAT=${FLOAT:-0} 14 + SYMMETRIC_ID=${SYMMETRIC_ID:-0} 15 + 16 + export ID_OFFSET=$(( 9 * (SYMMETRIC_ID == 0) )) 14 17 15 18 JQ_FILTER='map(select(.msg.peer | has("remote-ipv6") | not)) | 16 19 map(del(.msg.ifindex)) | sort_by(.msg.peer.id)[]' ··· 57 54 ip -n peer${1} link set tun${1} up 58 55 } 59 56 57 + build_capture_filter() { 58 + # match the first four bytes of the openvpn data payload 59 + if [ "${PROTO}" == "UDP" ]; then 60 + # For UDP, libpcap transport indexing only works for IPv4, so 61 + # use an explicit IPv4 or IPv6 expression based on the peer 62 + # address. The IPv6 branch assumes there are no extension 63 + # headers in the outer packet. 64 + if [[ "${2}" == *:* ]]; then 65 + printf "ip6 and ip6[6] = 17 and ip6[48:4] = %s" "${1}" 66 + else 67 + printf "ip and udp[8:4] = %s" "${1}" 68 + fi 69 + else 70 + # openvpn over TCP prepends a 2-byte packet length ahead of the 71 + # DATA_V2 opcode, so skip it before matching the payload header 72 + printf "ip and tcp[(((tcp[12] & 0xf0) >> 2) + 2):4] = %s" "${1}" 73 + fi 74 + } 75 + 60 76 setup_listener() { 61 77 file=$(mktemp) 62 78 PYTHONUNBUFFERED=1 ip netns exec peer${p} ${YNL_CLI} --family ovpn \ ··· 85 63 } 86 64 87 65 add_peer() { 66 + labels=("ASYMM" "SYMM") 67 + M_ID=${labels[SYMMETRIC_ID]} 68 + 88 69 if [ "${PROTO}" == "UDP" ]; then 89 70 if [ ${1} -eq 0 ]; then 90 - ip netns exec peer0 ${OVPN_CLI} new_multi_peer tun0 1 ${UDP_PEERS_FILE} 71 + ip netns exec peer0 ${OVPN_CLI} new_multi_peer tun0 1 \ 72 + ${M_ID} ${UDP_PEERS_FILE} 91 73 92 74 for p in $(seq 1 ${NUM_PEERS}); do 93 75 ip netns exec peer0 ${OVPN_CLI} new_key tun0 ${p} 1 0 ${ALG} 0 \ 94 76 data64.key 95 77 done 96 78 else 97 - RADDR=$(awk "NR == ${1} {print \$2}" ${UDP_PEERS_FILE}) 98 - RPORT=$(awk "NR == ${1} {print \$3}" ${UDP_PEERS_FILE}) 99 - LPORT=$(awk "NR == ${1} {print \$5}" ${UDP_PEERS_FILE}) 100 - ip netns exec peer${1} ${OVPN_CLI} new_peer tun${1} ${1} ${LPORT} \ 101 - ${RADDR} ${RPORT} 102 - ip netns exec peer${1} ${OVPN_CLI} new_key tun${1} ${1} 1 0 ${ALG} 1 \ 103 - data64.key 79 + if [ "${SYMMETRIC_ID}" -eq 1 ]; then 80 + PEER_ID=${1} 81 + TX_ID="none" 82 + else 83 + PEER_ID=$(awk "NR == ${1} {print \$2}" \ 84 + ${UDP_PEERS_FILE}) 85 + TX_ID=${1} 86 + fi 87 + RADDR=$(awk "NR == ${1} {print \$3}" ${UDP_PEERS_FILE}) 88 + RPORT=$(awk "NR == ${1} {print \$4}" ${UDP_PEERS_FILE}) 89 + LPORT=$(awk "NR == ${1} {print \$6}" ${UDP_PEERS_FILE}) 90 + ip netns exec peer${1} ${OVPN_CLI} new_peer tun${1} \ 91 + ${PEER_ID} ${TX_ID} ${LPORT} ${RADDR} ${RPORT} 92 + ip netns exec peer${1} ${OVPN_CLI} new_key tun${1} \ 93 + ${PEER_ID} 1 0 ${ALG} 1 data64.key 104 94 fi 105 95 else 106 96 if [ ${1} -eq 0 ]; then 107 - (ip netns exec peer0 ${OVPN_CLI} listen tun0 1 ${TCP_PEERS_FILE} && { 97 + (ip netns exec peer0 ${OVPN_CLI} listen tun0 1 ${M_ID} \ 98 + ${TCP_PEERS_FILE} && { 108 99 for p in $(seq 1 ${NUM_PEERS}); do 109 100 ip netns exec peer0 ${OVPN_CLI} new_key tun0 ${p} 1 0 \ 110 101 ${ALG} 0 data64.key ··· 125 90 }) & 126 91 sleep 5 127 92 else 128 - ip netns exec peer${1} ${OVPN_CLI} connect tun${1} ${1} 10.10.${1}.1 1 \ 129 - data64.key 93 + if [ "${SYMMETRIC_ID}" -eq 1 ]; then 94 + PEER_ID=${1} 95 + TX_ID="none" 96 + else 97 + PEER_ID=$(awk "NR == ${1} {print \$2}" \ 98 + ${TCP_PEERS_FILE}) 99 + TX_ID=${1} 100 + fi 101 + ip netns exec peer${1} ${OVPN_CLI} connect tun${1} \ 102 + ${PEER_ID} ${TX_ID} 10.10.${1}.1 1 data64.key 130 103 fi 131 104 fi 132 105 } 133 106 134 107 compare_ntfs() { 135 108 if [ ${#tmp_jsons[@]} -gt 0 ]; then 136 - [ "$FLOAT" == 1 ] && suffix="-float" 109 + suffix="" 110 + [ "${SYMMETRIC_ID}" -eq 1 ] && suffix="${suffix}-symm" 111 + [ "$FLOAT" == 1 ] && suffix="${suffix}-float" 137 112 expected="json/peer${1}${suffix}.json" 138 113 received="${tmp_jsons[$1]}" 139 114
+1
tools/testing/selftests/net/ovpn/json/peer1-symm.json
··· 1 + {"name": "peer-del-ntf", "msg": {"ifindex": 0, "peer": {"del-reason": "userspace", "id": 1}}}
+1 -1
tools/testing/selftests/net/ovpn/json/peer1.json
··· 1 - {"name": "peer-del-ntf", "msg": {"ifindex": 0, "peer": {"del-reason": "userspace", "id": 1}}} 1 + {"name": "peer-del-ntf", "msg": {"ifindex": 0, "peer": {"del-reason": "userspace", "id": 10}}}
+1
tools/testing/selftests/net/ovpn/json/peer2-symm.json
··· 1 + {"name": "peer-del-ntf", "msg": {"ifindex": 0, "peer": {"del-reason": "userspace", "id": 2}}}
+1 -1
tools/testing/selftests/net/ovpn/json/peer2.json
··· 1 - {"name": "peer-del-ntf", "msg": {"ifindex": 0, "peer": {"del-reason": "userspace", "id": 2}}} 1 + {"name": "peer-del-ntf", "msg": {"ifindex": 0, "peer": {"del-reason": "userspace", "id": 11}}}
+1
tools/testing/selftests/net/ovpn/json/peer3-symm.json
··· 1 + {"name": "peer-del-ntf", "msg": {"ifindex": 0, "peer": {"del-reason": "expired", "id": 3}}}
+1 -1
tools/testing/selftests/net/ovpn/json/peer3.json
··· 1 - {"name": "peer-del-ntf", "msg": {"ifindex": 0, "peer": {"del-reason": "expired", "id": 3}}} 1 + {"name": "peer-del-ntf", "msg": {"ifindex": 0, "peer": {"del-reason": "expired", "id": 12}}}
+1
tools/testing/selftests/net/ovpn/json/peer4-symm.json
··· 1 + {"name": "peer-del-ntf", "msg": {"ifindex": 0, "peer": {"del-reason": "expired", "id": 4}}}
+1 -1
tools/testing/selftests/net/ovpn/json/peer4.json
··· 1 - {"name": "peer-del-ntf", "msg": {"ifindex": 0, "peer": {"del-reason": "expired", "id": 4}}} 1 + {"name": "peer-del-ntf", "msg": {"ifindex": 0, "peer": {"del-reason": "expired", "id": 13}}}
+1
tools/testing/selftests/net/ovpn/json/peer5-symm.json
··· 1 + {"name": "peer-del-ntf", "msg": {"ifindex": 0, "peer": {"del-reason": "expired", "id": 5}}}
+1 -1
tools/testing/selftests/net/ovpn/json/peer5.json
··· 1 - {"name": "peer-del-ntf", "msg": {"ifindex": 0, "peer": {"del-reason": "expired", "id": 5}}} 1 + {"name": "peer-del-ntf", "msg": {"ifindex": 0, "peer": {"del-reason": "expired", "id": 14}}}
+1
tools/testing/selftests/net/ovpn/json/peer6-symm.json
··· 1 + {"name": "peer-del-ntf", "msg": {"ifindex": 0, "peer": {"del-reason": "expired", "id": 6}}}
+1 -1
tools/testing/selftests/net/ovpn/json/peer6.json
··· 1 - {"name": "peer-del-ntf", "msg": {"ifindex": 0, "peer": {"del-reason": "expired", "id": 6}}} 1 + {"name": "peer-del-ntf", "msg": {"ifindex": 0, "peer": {"del-reason": "expired", "id": 15}}}
+92 -36
tools/testing/selftests/net/ovpn/ovpn-cli.c
··· 103 103 104 104 sa_family_t sa_family; 105 105 106 - unsigned long peer_id; 106 + unsigned long peer_id, tx_id; 107 107 unsigned long lport; 108 108 109 109 union { ··· 132 132 enum ovpn_key_direction key_dir; 133 133 enum ovpn_key_slot key_slot; 134 134 int key_id; 135 + 136 + bool asymm_id; 135 137 136 138 const char *peers_file; 137 139 }; ··· 651 649 652 650 attr = nla_nest_start(ctx->nl_msg, OVPN_A_PEER); 653 651 NLA_PUT_U32(ctx->nl_msg, OVPN_A_PEER_ID, ovpn->peer_id); 652 + if (ovpn->asymm_id) 653 + NLA_PUT_U32(ctx->nl_msg, OVPN_A_PEER_TX_ID, ovpn->tx_id); 654 654 NLA_PUT_U32(ctx->nl_msg, OVPN_A_PEER_SOCKET, ovpn->socket); 655 655 656 656 if (!is_tcp) { ··· 770 766 if (pattrs[OVPN_A_PEER_ID]) 771 767 fprintf(stderr, "* Peer %u\n", 772 768 nla_get_u32(pattrs[OVPN_A_PEER_ID])); 769 + 770 + if (pattrs[OVPN_A_PEER_TX_ID]) 771 + fprintf(stderr, "\tTX peer ID %u\n", 772 + nla_get_u32(pattrs[OVPN_A_PEER_TX_ID])); 773 773 774 774 if (pattrs[OVPN_A_PEER_SOCKET_NETNSID]) 775 775 fprintf(stderr, "\tsocket NetNS ID: %d\n", ··· 1665 1657 fprintf(stderr, "\tiface: ovpn interface name\n"); 1666 1658 1667 1659 fprintf(stderr, 1668 - "* listen <iface> <lport> <peers_file> [ipv6]: listen for incoming peer TCP connections\n"); 1660 + "* listen <iface> <lport> <id_type> <peers_file> [ipv6]: listen for incoming peer TCP connections\n"); 1669 1661 fprintf(stderr, "\tiface: ovpn interface name\n"); 1670 1662 fprintf(stderr, "\tlport: TCP port to listen to\n"); 1663 + fprintf(stderr, "\tid_type:\n"); 1664 + fprintf(stderr, 1665 + "\t\t- SYMM for ignoring the TX peer ID from the peers_file\n"); 1666 + fprintf(stderr, 1667 + "\t\t- ASYMM for using the TX peer ID from the peers_file\n"); 1671 1668 fprintf(stderr, 1672 1669 "\tpeers_file: file containing one peer per line: Line format:\n"); 1673 - fprintf(stderr, "\t\t<peer_id> <vpnaddr>\n"); 1670 + fprintf(stderr, "\t\t<peer_id> <tx_id> <vpnaddr>\n"); 1674 1671 fprintf(stderr, 1675 1672 "\tipv6: whether the socket should listen to the IPv6 wildcard address\n"); 1676 1673 1677 1674 fprintf(stderr, 1678 - "* connect <iface> <peer_id> <raddr> <rport> [key_file]: start connecting peer of TCP-based VPN session\n"); 1675 + "* connect <iface> <peer_id> <tx_id> <raddr> <rport> [key_file]: start connecting peer of TCP-based VPN session\n"); 1679 1676 fprintf(stderr, "\tiface: ovpn interface name\n"); 1680 - fprintf(stderr, "\tpeer_id: peer ID of the connecting peer\n"); 1677 + fprintf(stderr, 1678 + "\tpeer_id: peer ID found in data packets received from this peer\n"); 1679 + fprintf(stderr, 1680 + "\ttx_id: peer ID to be used when sending to this peer, 'none' for symmetric peer ID\n"); 1681 1681 fprintf(stderr, "\traddr: peer IP address to connect to\n"); 1682 1682 fprintf(stderr, "\trport: peer TCP port to connect to\n"); 1683 1683 fprintf(stderr, 1684 1684 "\tkey_file: file containing the symmetric key for encryption\n"); 1685 1685 1686 1686 fprintf(stderr, 1687 - "* new_peer <iface> <peer_id> <lport> <raddr> <rport> [vpnaddr]: add new peer\n"); 1687 + "* new_peer <iface> <peer_id> <tx_id> <lport> <raddr> <rport> [vpnaddr]: add new peer\n"); 1688 1688 fprintf(stderr, "\tiface: ovpn interface name\n"); 1689 - fprintf(stderr, "\tlport: local UDP port to bind to\n"); 1690 1689 fprintf(stderr, 1691 - "\tpeer_id: peer ID to be used in data packets to/from this peer\n"); 1690 + "\tpeer_id: peer ID found in data packets received from this peer\n"); 1691 + fprintf(stderr, 1692 + "\ttx_id: peer ID to be used when sending to this peer, 'none' for symmetric peer ID\n"); 1693 + fprintf(stderr, "\tlport: local UDP port to bind to\n"); 1692 1694 fprintf(stderr, "\traddr: peer IP address\n"); 1693 1695 fprintf(stderr, "\trport: peer UDP port\n"); 1694 1696 fprintf(stderr, "\tvpnaddr: peer VPN IP\n"); 1695 1697 1696 1698 fprintf(stderr, 1697 - "* new_multi_peer <iface> <lport> <peers_file>: add multiple peers as listed in the file\n"); 1699 + "* new_multi_peer <iface> <lport> <id_type> <peers_file>: add multiple peers as listed in the file\n"); 1698 1700 fprintf(stderr, "\tiface: ovpn interface name\n"); 1699 1701 fprintf(stderr, "\tlport: local UDP port to bind to\n"); 1702 + fprintf(stderr, "\tid_type:\n"); 1703 + fprintf(stderr, 1704 + "\t\t- SYMM for ignoring the TX peer ID from the peers_file\n"); 1705 + fprintf(stderr, 1706 + "\t\t- ASYMM for using the TX peer ID from the peers_file\n"); 1700 1707 fprintf(stderr, 1701 1708 "\tpeers_file: text file containing one peer per line. Line format:\n"); 1702 - fprintf(stderr, "\t\t<peer_id> <raddr> <rport> <vpnaddr>\n"); 1709 + fprintf(stderr, 1710 + "\t\t<peer_id> <tx_id> <raddr> <rport> <laddr> <lport> <vpnaddr>\n"); 1703 1711 1704 1712 fprintf(stderr, 1705 1713 "* set_peer <iface> <peer_id> <keepalive_interval> <keepalive_timeout>: set peer attributes\n"); ··· 1828 1804 } 1829 1805 1830 1806 static int ovpn_parse_new_peer(struct ovpn_ctx *ovpn, const char *peer_id, 1831 - const char *raddr, const char *rport, 1832 - const char *vpnip) 1807 + const char *tx_id, const char *raddr, 1808 + const char *rport, const char *vpnip) 1833 1809 { 1834 1810 ovpn->peer_id = strtoul(peer_id, NULL, 10); 1835 1811 if (errno == ERANGE || ovpn->peer_id > PEER_ID_UNDEF) { 1836 - fprintf(stderr, "peer ID value out of range\n"); 1812 + fprintf(stderr, "rx peer ID value out of range\n"); 1837 1813 return -1; 1814 + } 1815 + 1816 + if (ovpn->asymm_id) { 1817 + ovpn->tx_id = strtoul(tx_id, NULL, 10); 1818 + if (errno == ERANGE || ovpn->tx_id > PEER_ID_UNDEF) { 1819 + fprintf(stderr, "tx peer ID value out of range\n"); 1820 + return -1; 1821 + } 1838 1822 } 1839 1823 1840 1824 return ovpn_parse_remote(ovpn, raddr, rport, vpnip); ··· 1971 1939 1972 1940 static int ovpn_run_cmd(struct ovpn_ctx *ovpn) 1973 1941 { 1974 - char peer_id[10], vpnip[INET6_ADDRSTRLEN], laddr[128], lport[10]; 1975 - char raddr[128], rport[10]; 1942 + char peer_id[10], tx_id[10], vpnip[INET6_ADDRSTRLEN], laddr[128]; 1943 + char lport[10], raddr[128], rport[10]; 1976 1944 int n, ret; 1977 1945 FILE *fp; 1978 1946 ··· 1999 1967 2000 1968 int num_peers = 0; 2001 1969 2002 - while ((n = fscanf(fp, "%s %s\n", peer_id, vpnip)) == 2) { 1970 + while ((n = fscanf(fp, "%s %s %s\n", peer_id, tx_id, 1971 + vpnip)) == 3) { 2003 1972 struct ovpn_ctx peer_ctx = { 0 }; 2004 1973 2005 1974 if (num_peers == MAX_PEERS) { ··· 2010 1977 2011 1978 peer_ctx.ifindex = ovpn->ifindex; 2012 1979 peer_ctx.sa_family = ovpn->sa_family; 1980 + peer_ctx.asymm_id = ovpn->asymm_id; 2013 1981 2014 1982 peer_ctx.socket = ovpn_accept(ovpn); 2015 1983 if (peer_ctx.socket < 0) { ··· 2021 1987 /* store peer sockets to test TCP I/O */ 2022 1988 ovpn->cli_sockets[num_peers] = peer_ctx.socket; 2023 1989 2024 - ret = ovpn_parse_new_peer(&peer_ctx, peer_id, NULL, 2025 - NULL, vpnip); 1990 + ret = ovpn_parse_new_peer(&peer_ctx, peer_id, tx_id, 1991 + NULL, NULL, vpnip); 2026 1992 if (ret < 0) { 2027 1993 fprintf(stderr, "error while parsing line\n"); 2028 1994 return -1; ··· 2090 2056 return -1; 2091 2057 } 2092 2058 2093 - while ((n = fscanf(fp, "%s %s %s %s %s %s\n", peer_id, laddr, 2094 - lport, raddr, rport, vpnip)) == 6) { 2059 + while ((n = fscanf(fp, "%s %s %s %s %s %s %s\n", peer_id, tx_id, 2060 + laddr, lport, raddr, rport, vpnip)) == 7) { 2095 2061 struct ovpn_ctx peer_ctx = { 0 }; 2096 2062 2097 2063 peer_ctx.ifindex = ovpn->ifindex; 2098 2064 peer_ctx.socket = ovpn->socket; 2099 2065 peer_ctx.sa_family = AF_UNSPEC; 2066 + peer_ctx.asymm_id = ovpn->asymm_id; 2100 2067 2101 - ret = ovpn_parse_new_peer(&peer_ctx, peer_id, raddr, 2102 - rport, vpnip); 2068 + ret = ovpn_parse_new_peer(&peer_ctx, peer_id, tx_id, 2069 + raddr, rport, vpnip); 2103 2070 if (ret < 0) { 2104 2071 fprintf(stderr, "error while parsing line\n"); 2105 2072 return -1; ··· 2196 2161 case CMD_DEL_IFACE: 2197 2162 break; 2198 2163 case CMD_LISTEN: 2199 - if (argc < 5) 2164 + if (argc < 6) 2200 2165 return -EINVAL; 2201 2166 2202 2167 ovpn->lport = strtoul(argv[3], NULL, 10); ··· 2205 2170 return -1; 2206 2171 } 2207 2172 2208 - ovpn->peers_file = argv[4]; 2173 + if (strcmp(argv[4], "SYMM") == 0) { 2174 + ovpn->asymm_id = false; 2175 + } else if (strcmp(argv[4], "ASYMM") == 0) { 2176 + ovpn->asymm_id = true; 2177 + } else { 2178 + fprintf(stderr, "Cannot parse id type: %s\n", argv[4]); 2179 + return -1; 2180 + } 2181 + 2182 + ovpn->peers_file = argv[5]; 2209 2183 2210 2184 ovpn->sa_family = AF_INET; 2211 - if (argc > 5 && !strcmp(argv[5], "ipv6")) 2185 + if (argc > 6 && !strcmp(argv[6], "ipv6")) 2212 2186 ovpn->sa_family = AF_INET6; 2213 2187 break; 2214 2188 case CMD_CONNECT: 2215 - if (argc < 6) 2189 + if (argc < 7) 2216 2190 return -EINVAL; 2217 2191 2218 2192 ovpn->sa_family = AF_INET; 2193 + ovpn->asymm_id = strcmp(argv[4], "none"); 2219 2194 2220 2195 ret = ovpn_parse_new_peer(ovpn, argv[3], argv[4], argv[5], 2221 - NULL); 2196 + argv[6], NULL); 2222 2197 if (ret < 0) { 2223 2198 fprintf(stderr, "Cannot parse remote peer data\n"); 2224 2199 return -1; 2225 2200 } 2226 2201 2227 - if (argc > 6) { 2202 + if (argc > 7) { 2228 2203 ovpn->key_slot = OVPN_KEY_SLOT_PRIMARY; 2229 2204 ovpn->key_id = 0; 2230 2205 ovpn->cipher = OVPN_CIPHER_ALG_AES_GCM; 2231 2206 ovpn->key_dir = KEY_DIR_OUT; 2232 2207 2233 - ret = ovpn_parse_key(argv[6], ovpn); 2208 + ret = ovpn_parse_key(argv[7], ovpn); 2234 2209 if (ret) 2235 2210 return -1; 2236 2211 } 2237 2212 break; 2238 2213 case CMD_NEW_PEER: 2239 - if (argc < 7) 2214 + if (argc < 8) 2240 2215 return -EINVAL; 2241 2216 2242 - ovpn->lport = strtoul(argv[4], NULL, 10); 2217 + ovpn->asymm_id = strcmp(argv[4], "none"); 2218 + 2219 + ovpn->lport = strtoul(argv[5], NULL, 10); 2243 2220 if (errno == ERANGE || ovpn->lport > 65535) { 2244 2221 fprintf(stderr, "lport value out of range\n"); 2245 2222 return -1; 2246 2223 } 2247 2224 2248 - const char *vpnip = (argc > 7) ? argv[7] : NULL; 2225 + const char *vpnip = (argc > 8) ? argv[8] : NULL; 2249 2226 2250 - ret = ovpn_parse_new_peer(ovpn, argv[3], argv[5], argv[6], 2251 - vpnip); 2227 + ret = ovpn_parse_new_peer(ovpn, argv[3], argv[4], argv[6], 2228 + argv[7], vpnip); 2252 2229 if (ret < 0) 2253 2230 return -1; 2254 2231 break; 2255 2232 case CMD_NEW_MULTI_PEER: 2256 - if (argc < 5) 2233 + if (argc < 6) 2257 2234 return -EINVAL; 2258 2235 2259 2236 ovpn->lport = strtoul(argv[3], NULL, 10); ··· 2274 2227 return -1; 2275 2228 } 2276 2229 2277 - ovpn->peers_file = argv[4]; 2230 + if (!strcmp(argv[4], "SYMM")) { 2231 + ovpn->asymm_id = false; 2232 + } else if (!strcmp(argv[4], "ASYMM")) { 2233 + ovpn->asymm_id = true; 2234 + } else { 2235 + fprintf(stderr, "Cannot parse id type: %s\n", argv[4]); 2236 + return -1; 2237 + } 2238 + 2239 + ovpn->peers_file = argv[5]; 2278 2240 break; 2279 2241 case CMD_SET_PEER: 2280 2242 if (argc < 6)
+6 -6
tools/testing/selftests/net/ovpn/tcp_peers.txt
··· 1 - 1 5.5.5.2 2 - 2 5.5.5.3 3 - 3 5.5.5.4 4 - 4 5.5.5.5 5 - 5 5.5.5.6 6 - 6 5.5.5.7 1 + 1 10 5.5.5.2 2 + 2 11 5.5.5.3 3 + 3 12 5.5.5.4 4 + 4 13 5.5.5.5 5 + 5 14 5.5.5.6 6 + 6 15 5.5.5.7
+1 -1
tools/testing/selftests/net/ovpn/test-close-socket.sh
··· 27 27 28 28 for p in $(seq 1 ${NUM_PEERS}); do 29 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} 60 120 30 + ip netns exec peer${p} ${OVPN_CLI} set_peer tun${p} $((${p}+9)) 60 120 31 31 done 32 32 33 33 sleep 1
+11
tools/testing/selftests/net/ovpn/test-symmetric-id-float.sh
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + # Copyright (C) 2025 OpenVPN, Inc. 4 + # 5 + # Author: Ralf Lici <ralf@mandelbit.com> 6 + # Antonio Quartulli <antonio@openvpn.net> 7 + 8 + SYMMETRIC_ID="1" 9 + FLOAT="1" 10 + 11 + source test.sh
+11
tools/testing/selftests/net/ovpn/test-symmetric-id-tcp.sh
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + # Copyright (C) 2025 OpenVPN, Inc. 4 + # 5 + # Author: Ralf Lici <ralf@mandelbit.com> 6 + # Antonio Quartulli <antonio@openvpn.net> 7 + 8 + PROTO="TCP" 9 + SYMMETRIC_ID=1 10 + 11 + source test.sh
+10
tools/testing/selftests/net/ovpn/test-symmetric-id.sh
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + # Copyright (C) 2025 OpenVPN, Inc. 4 + # 5 + # Author: Ralf Lici <ralf@mandelbit.com> 6 + # Antonio Quartulli <antonio@openvpn.net> 7 + 8 + SYMMETRIC_ID="1" 9 + 10 + source test.sh
+54 -14
tools/testing/selftests/net/ovpn/test.sh
··· 31 31 32 32 for p in $(seq 1 ${NUM_PEERS}); do 33 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} ${p} 60 120 34 + ip netns exec peer${p} ${OVPN_CLI} set_peer tun${p} \ 35 + $((${p}+ID_OFFSET)) 60 120 35 36 done 36 37 37 38 sleep 1 38 39 40 + TCPDUMP_TIMEOUT="1.5s" 39 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}) 54 + fi 55 + 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=$! 66 + 67 + sleep 0.3 40 68 ip netns exec peer0 ping -qfc 500 -w 3 5.5.5.$((${p} + 1)) 41 69 ip netns exec peer0 ping -qfc 500 -s 3000 -w 3 5.5.5.$((${p} + 1)) 70 + 71 + wait ${TCPDUMP_PID1} 72 + wait ${TCPDUMP_PID2} 42 73 done 43 74 44 75 # ping LAN behind client 1 ··· 92 61 93 62 echo "Adding secondary key and then swap:" 94 63 for p in $(seq 1 ${NUM_PEERS}); do 95 - ip netns exec peer0 ${OVPN_CLI} new_key tun0 ${p} 2 1 ${ALG} 0 data64.key 96 - ip netns exec peer${p} ${OVPN_CLI} new_key tun${p} ${p} 2 1 ${ALG} 1 data64.key 97 - ip netns exec peer${p} ${OVPN_CLI} swap_keys tun${p} ${p} 64 + ip netns exec peer0 ${OVPN_CLI} new_key tun0 ${p} 2 1 ${ALG} 0 \ 65 + data64.key 66 + ip netns exec peer${p} ${OVPN_CLI} new_key tun${p} \ 67 + $((${p} + ID_OFFSET)) 2 1 ${ALG} 1 data64.key 68 + ip netns exec peer${p} ${OVPN_CLI} swap_keys tun${p} \ 69 + $((${p} + ID_OFFSET)) 98 70 done 99 71 100 72 sleep 1 ··· 109 75 echo "Querying peer 1:" 110 76 ip netns exec peer0 ${OVPN_CLI} get_peer tun0 1 111 77 112 - echo "Querying non-existent peer 10:" 113 - ip netns exec peer0 ${OVPN_CLI} get_peer tun0 10 || true 78 + echo "Querying non-existent peer 20:" 79 + ip netns exec peer0 ${OVPN_CLI} get_peer tun0 20 || true 114 80 115 81 echo "Deleting peer 1:" 116 82 ip netns exec peer0 ${OVPN_CLI} del_peer tun0 1 117 - ip netns exec peer1 ${OVPN_CLI} del_peer tun1 1 83 + ip netns exec peer1 ${OVPN_CLI} del_peer tun1 $((1 + ID_OFFSET)) 118 84 119 85 echo "Querying keys:" 120 86 for p in $(seq 2 ${NUM_PEERS}); do 121 - ip netns exec peer${p} ${OVPN_CLI} get_key tun${p} ${p} 1 122 - ip netns exec peer${p} ${OVPN_CLI} get_key tun${p} ${p} 2 87 + ip netns exec peer${p} ${OVPN_CLI} get_key tun${p} \ 88 + $((${p} + ID_OFFSET)) 1 89 + ip netns exec peer${p} ${OVPN_CLI} get_key tun${p} \ 90 + $((${p} + ID_OFFSET)) 2 123 91 done 124 92 125 93 echo "Deleting peer while sending traffic:" ··· 130 94 ip netns exec peer0 ${OVPN_CLI} del_peer tun0 2 131 95 # following command fails in TCP mode 132 96 # (both ends get conn reset when one peer disconnects) 133 - ip netns exec peer2 ${OVPN_CLI} del_peer tun2 2 || true 97 + ip netns exec peer2 ${OVPN_CLI} del_peer tun2 $((2 + ID_OFFSET)) || true 134 98 135 99 echo "Deleting keys:" 136 100 for p in $(seq 3 ${NUM_PEERS}); do 137 - ip netns exec peer${p} ${OVPN_CLI} del_key tun${p} ${p} 1 138 - ip netns exec peer${p} ${OVPN_CLI} del_key tun${p} ${p} 2 101 + ip netns exec peer${p} ${OVPN_CLI} del_key tun${p} \ 102 + $((${p} + ID_OFFSET)) 1 103 + ip netns exec peer${p} ${OVPN_CLI} del_key tun${p} \ 104 + $((${p} + ID_OFFSET)) 2 139 105 done 140 106 141 107 echo "Setting timeout to 3s MP:" 142 108 for p in $(seq 3 ${NUM_PEERS}); do 143 109 ip netns exec peer0 ${OVPN_CLI} set_peer tun0 ${p} 3 3 || true 144 - ip netns exec peer${p} ${OVPN_CLI} set_peer tun${p} ${p} 0 0 110 + ip netns exec peer${p} ${OVPN_CLI} set_peer tun${p} \ 111 + $((${p} + ID_OFFSET)) 0 0 145 112 done 146 113 # wait for peers to timeout 147 114 sleep 5 148 115 149 116 echo "Setting timeout to 3s P2P:" 150 117 for p in $(seq 3 ${NUM_PEERS}); do 151 - ip netns exec peer${p} ${OVPN_CLI} set_peer tun${p} ${p} 3 3 118 + ip netns exec peer${p} ${OVPN_CLI} set_peer tun${p} \ 119 + $((${p} + ID_OFFSET)) 3 3 152 120 done 153 121 sleep 5 154 122
+6 -6
tools/testing/selftests/net/ovpn/udp_peers.txt
··· 1 - 1 10.10.1.1 1 10.10.1.2 1 5.5.5.2 2 - 2 10.10.2.1 1 10.10.2.2 1 5.5.5.3 3 - 3 10.10.3.1 1 10.10.3.2 1 5.5.5.4 4 - 4 fd00:0:0:4::1 1 fd00:0:0:4::2 1 5.5.5.5 5 - 5 fd00:0:0:5::1 1 fd00:0:0:5::2 1 5.5.5.6 6 - 6 fd00:0:0:6::1 1 fd00:0:0:6::2 1 5.5.5.7 1 + 1 10 10.10.1.1 1 10.10.1.2 1 5.5.5.2 2 + 2 11 10.10.2.1 1 10.10.2.2 1 5.5.5.3 3 + 3 12 10.10.3.1 1 10.10.3.2 1 5.5.5.4 4 + 4 13 fd00:0:0:4::1 1 fd00:0:0:4::2 1 5.5.5.5 5 + 5 14 fd00:0:0:5::1 1 fd00:0:0:5::2 1 5.5.5.6 6 + 6 15 fd00:0:0:6::1 1 fd00:0:0:6::2 1 5.5.5.7