Attention is currently required from: plaisthos.
Hello plaisthos,
I'd like you to do a code review.
Please visit
http://gerrit.openvpn.net/c/openvpn/+/1949?usp=email
to review the following change.
Change subject: tests: add an end-to-end test for --route gateway keywords
......................................................................
tests: add an end-to-end test for --route gateway keywords
Nothing self-contained checks that a route openvpn says it installed
actually reached the kernel with the gateway it reported. t_client.sh does
compare routes, but it needs a t_client.rc and reachable servers, so it
skips for contributors and in CI.
Run a TLS loopback pair inside a throwaway network namespace, ask the
client for a route via net_gateway, and check where it lands. route.c
tracks two gateways, the system default route and the route towards the
peer, and net_gateway is the former. The peer here is on loopback, so the
two differ and the assertion can tell them apart: resolving from the wrong
one leaves the route with no gateway and the install fails outright.
The namespace also means the fixed loopback ports cannot collide, so this
needs none of the retry-on-address-in-use handling t_cltsrv.sh has.
Skips rather than fails when it cannot run: not Linux, no iproute2, or no
way to get the privileges a namespace needs. Containers commonly disallow
namespace creation, so this will skip there and run on VMs and bare metal.
RUN_SUDO is picked up from t_client.rc the same way t_net.sh does.
Change-Id: I2e8f1449fe54e7f628e2bdb042ee2a567f25e02d
Signed-off-by: Charlie Vigue <[email protected]>
---
M tests/Makefile.am
A tests/t_route.sh
2 files changed, 142 insertions(+), 1 deletion(-)
git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/49/1949/1
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3907965..559533e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -18,7 +18,7 @@
SH_LOG_DRIVER = $(SHELL) $(top_srcdir)/forked-test-driver
if !WIN32
-test_scripts = t_client.sh t_lpback.sh t_cltsrv.sh t_server_null.sh
+test_scripts = t_client.sh t_lpback.sh t_cltsrv.sh t_server_null.sh t_route.sh
check_PROGRAMS = ntlm_support
if HAVE_SITNL
@@ -35,6 +35,7 @@
t_cltsrv-down.sh \
t_lpback.sh \
t_net.sh \
+ t_route.sh \
t_server_null.sh \
t_server_null_client.sh \
t_server_null_server.sh \
diff --git a/tests/t_route.sh b/tests/t_route.sh
new file mode 100755
index 0000000..f3bac06
--- /dev/null
+++ b/tests/t_route.sh
@@ -0,0 +1,140 @@
+#!/usr/bin/env bash
+#
+# t_route.sh - check that --route installs a route where it says it will
+#
+# The special gateway keywords (net_gateway, vpn_gateway, remote_host) are
+# resolved in route.c from data gathered off the system routing table. The
+# unit tests cover the resolution itself; this checks that the answer
+# reaches the kernel.
+#
+# route.c keeps two gateways: the system default route, and the route
+# towards the peer. net_gateway is the former. Here the peer is on
+# loopback, so the two are necessarily different and an assertion on the
+# installed gateway tells them apart.
+#
+# Everything runs in a throwaway network namespace, so the host routing
+# table is not touched and the fixed loopback ports cannot collide with
+# anything.
+
+srcdir="${srcdir:-.}"
+top_builddir="${top_builddir:-..}"
+top_srcdir="${top_srcdir:-${srcdir}/..}"
+openvpn="${openvpn:-${top_builddir}/src/openvpn/openvpn}"
+
+# Namespace topology: one interface carrying a default route, which is
+# what net_gateway has to resolve to.
+NS="ovpnroute$$"
+TUN="ovpnt$$"
+LAN_GW="10.71.1.1"
+TARGET="10.71.250.1" # what we ask to be routed via net_gateway
+VPN_LOCAL="10.71.8.2"
+VPN_REMOTE="10.71.8.1"
+
+# netlink, dummy interfaces and namespaces are all Linux-only. The rest of
+# this script would not even parse the same elsewhere.
+if [ "$(uname -s)" != "Linux" ]; then
+ echo "$0: this test runs only on Linux. SKIPPING TEST."
+ exit 77
+fi
+
+if [ ! -x "${openvpn}" ]; then
+ echo "$0: no (executable) openvpn binary in current build tree. FAIL." >&2
+ exit 1
+fi
+
+if ! command -v ip >/dev/null 2>&1; then
+ echo "$0: no iproute2 'ip' command in \$PATH. SKIPPING TEST." >&2
+ exit 77
+fi
+
+# t_client.rc is read only for a RUN_SUDO definition, as t_net.sh does
+if [ -r "${top_builddir}"/t_client.rc ]; then
+ . "${top_builddir}"/t_client.rc
+elif [ -r "${srcdir}"/t_client.rc ]; then
+ . "${srcdir}"/t_client.rc
+fi
+
+if [ "$(id -u)" -ne 0 ]; then
+ if [ -z "$RUN_SUDO" ]; then
+ RUN_SUDO="sudo"
+ fi
+else
+ RUN_SUDO=""
+fi
+
+# A namespace needs the same privileges the rest of the test does, so use
+# it as the probe.
+if ! $RUN_SUDO ip netns add "$NS" >/dev/null 2>&1; then
+ echo "$0: cannot create a network namespace with '$RUN_SUDO'." >&2
+ echo "$0: containers commonly disallow this. SKIPPING TEST." >&2
+ exit 77
+fi
+
+srv_pid=""
+clt_pid=""
+logdir=$(mktemp -d) || exit 1
+
+cleanup()
+{
+ [ -n "$clt_pid" ] && kill "$clt_pid" 2>/dev/null
+ [ -n "$srv_pid" ] && kill "$srv_pid" 2>/dev/null
+ wait 2>/dev/null
+ # deleting the namespace takes every interface and route in it with it
+ $RUN_SUDO ip netns del "$NS" 2>/dev/null
+ [ -n "$logdir" ] && rm -rf "$logdir"
+}
+trap cleanup EXIT
+
+nsexec() { $RUN_SUDO ip netns exec "$NS" "$@"; }
+
+set -e
+nsexec ip link set lo up
+nsexec ip link add lan0 type dummy
+nsexec ip link set lan0 up
+nsexec ip addr add 10.71.1.2/24 dev lan0
+nsexec ip route add default via "$LAN_GW" dev lan0
+set +e
+
+# A TLS loopback pair, as t_cltsrv.sh uses. Options after --config override
+# the config file, which is how the client gets a tun and a route.
+nsexec "${openvpn}" --cd "${top_srcdir}/sample" \
+ --config sample-config-files/loopback-server \
+ --verb 3 --ping-exit 60 >"$logdir"/srv.log 2>&1 &
+srv_pid=$!
+
+nsexec "${openvpn}" --cd "${top_srcdir}/sample" \
+ --config sample-config-files/loopback-client \
+ --dev "$TUN" --dev-type tun \
+ --ifconfig "$VPN_LOCAL" "$VPN_REMOTE" \
+ --route "$TARGET" 255.255.255.255 net_gateway \
+ --verb 4 --ping-exit 60 >"$logdir"/clt.log 2>&1 &
+clt_pid=$!
+
+# Wait for the route to show up rather than guessing at a sleep
+route_out=""
+for _ in $(seq 1 30); do
+ route_out=$(nsexec ip route show "$TARGET" 2>/dev/null)
+ [ -n "$route_out" ] && break
+ sleep 1
+done
+
+if [ -z "$route_out" ]; then
+ echo "$0: route to $TARGET was never installed. FAIL." >&2
+ echo "--- client log ---" >&2
+ cat "$logdir"/clt.log >&2
+ exit 1
+fi
+
+# net_gateway is the system default gateway, not the route to the peer
+case "$route_out" in
+ *"via $LAN_GW"*)
+ echo "$0: net_gateway resolved to $LAN_GW as expected"
+ ;;
+ *)
+ echo "$0: expected the route via the default gateway $LAN_GW," >&2
+ echo " got: $route_out. FAIL." >&2
+ exit 1
+ ;;
+esac
+
+exit 0
--
To view, visit http://gerrit.openvpn.net/c/openvpn/+/1949?usp=email
To unsubscribe, or for help writing mail filters, visit
http://gerrit.openvpn.net/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: openvpn
Gerrit-Branch: master
Gerrit-Change-Id: I2e8f1449fe54e7f628e2bdb042ee2a567f25e02d
Gerrit-Change-Number: 1949
Gerrit-PatchSet: 1
Gerrit-Owner: chugly <[email protected]>
Gerrit-Reviewer: plaisthos <[email protected]>
Gerrit-CC: openvpn-devel <[email protected]>
Gerrit-Attention: plaisthos <[email protected]>
_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel