aboutsummaryrefslogtreecommitdiff
path: root/tests/t_net.sh
blob: 0be5bb42f42d54bd0bd78507c8f9c3559f0cff2b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#!/bin/sh

IFACE="dummy0"
UNIT_TEST="./unit_tests/openvpn/networking_testdriver"
MAX_TEST=${1:-7}

KILL_EXEC=`which kill`
CC=${CC:-gcc}

srcdir="${srcdir:-.}"
top_builddir="${top_builddir:-..}"
openvpn="${top_builddir}/src/openvpn/openvpn"


# bail out right away on non-linux. NetLink (the object of this test) is only
# used on Linux, therefore testing other platform is not needed.
#
# Note: statements in the rest of the script may not even pass syntax check on
# solaris/bsd. It uses /bin/bash
if [ "$(uname -s)" != "Linux" ]; then
    echo "$0: this test runs only on Linux. SKIPPING TEST."
    exit 77
fi

# Commands used to retrieve the network state.
# State is retrieved after running sitnl and after running
# iproute commands. The two are then compared and expected to be equal.
typeset -a GET_STATE
GET_STATE[0]="ip link show dev $IFACE | sed 's/^[0-9]\+: //'"
GET_STATE[1]="ip addr show dev $IFACE | sed 's/^[0-9]\+: //'"
GET_STATE[2]="ip route show dev $IFACE"
GET_STATE[3]="ip -6 route show dev $IFACE"

LAST_STATE=$((${#GET_STATE[@]} - 1))

reload_dummy()
{
    $RUN_SUDO $openvpn --dev $IFACE --dev-type tun --rmtun >/dev/null
    $RUN_SUDO $openvpn --dev $IFACE --dev-type tun --mktun >/dev/null
    if [ $? -ne 0 ]; then
        echo "can't create interface $IFACE"
        exit 1
    fi

    #ip link set dev $IFACE address 00:11:22:33:44:55
}

run_test()
{
    # run all test cases from 0 to $1 in sequence
    CMD=
    for k in $(seq 0 $1); do
        # the unit-test prints to stdout the iproute command corresponding
        # to the sitnl operation being executed.
        # Format is "CMD: <commandhere>"
        OUT=$($RUN_SUDO $UNIT_TEST $k $IFACE)
        # ensure unit test worked properly
        if [ $? -ne 0 ]; then
            echo "unit-test $k errored out:"
            echo "$OUT"
            exit 1
        fi

        NEW=$(echo "$OUT" | sed -n 's/CMD: //p')
        CMD="$CMD $RUN_SUDO $NEW ;"
    done

    # collect state for later comparison
    for k in $(seq 0 $LAST_STATE); do
        STATE_TEST[$k]="$(eval ${GET_STATE[$k]})"
    done
}


## execution starts here

if [ -r "${top_builddir}"/t_client.rc ]; then
    . "${top_builddir}"/t_client.rc
elif [ -r "${srcdir}"/t_client.rc ]; then
    . "${srcdir}"/t_client.rc
else
    echo "$0: cannot find 't_client.rc' in build dir ('${top_builddir}')" >&2
    echo "$0: or source directory ('${srcdir}'). SKIPPING TEST." >&2
    exit 77
fi

if [ ! -x "$openvpn" ]; then
    echo "no (executable) openvpn binary in current build tree. FAIL." >&2
    exit 1
fi

if [ ! -x "$UNIT_TEST" ]; then
    echo "no test_networking driver available. SKIPPING TEST." >&2
    exit 77
fi


# Ensure PREFER_KSU is in a known state
PREFER_KSU="${PREFER_KSU:-0}"

# make sure we have permissions to run ifconfig/route from OpenVPN
# can't use "id -u" here - doesn't work on Solaris
ID=`id`
if expr "$ID" : "uid=0" >/dev/null
then :
else
    if [ "${PREFER_KSU}" -eq 1 ];
    then
        # Check if we have a valid kerberos ticket
        klist -l 1>/dev/null 2>/dev/null
        if [ $? -ne 0 ];
        then
            # No kerberos ticket found, skip ksu and fallback to RUN_SUDO
            PREFER_KSU=0
            echo "$0: No Kerberos ticket available.  Will not use ksu."
        else
            RUN_SUDO="ksu -q -e"
        fi
    fi

    if [ -z "$RUN_SUDO" ]
    then
        echo "$0: this test must run be as root, or RUN_SUDO=... " >&2
        echo "      must be set correctly in 't_client.rc'. SKIP." >&2
        exit 77
    else
        # We have to use sudo. Make sure that we (hopefully) do not have
        # to ask the users password during the test. This is done to
        # prevent timing issues, e.g. when the waits for openvpn to start
	    if $RUN_SUDO $KILL_EXEC -0 $$
        then
	        echo "$0: $RUN_SUDO $KILL_EXEC -0 succeeded, good."
        else
	        echo "$0: $RUN_SUDO $KILL_EXEC -0 failed, cannot go on. SKIP." >&2
	        exit 77
        fi
    fi
fi

for i in $(seq 0 $MAX_TEST); do
    # reload dummy module to cleanup state
    reload_dummy
    typeset -a STATE_TEST
    run_test $i

    # reload dummy module to cleanup state before running iproute commands
    reload_dummy

    # CMD has been set by the unit test
    eval $CMD
    if [ $? -ne 0 ]; then
        echo "error while executing:"
        echo "$CMD"
        exit 1
    fi

    # collect state after running manual ip command
    for k in $(seq 0 $LAST_STATE); do
        STATE_IP[$k]="$(eval ${GET_STATE[$k]})"
    done

    # ensure states after running unit test matches the one after running
    # manual iproute commands
    for j in $(seq 0 $LAST_STATE); do
        if [ "${STATE_TEST[$j]}" != "${STATE_IP[$j]}" ]; then
            echo "state $j mismatching after '$CMD'"
            echo "after unit-test:"
            echo "${STATE_TEST[$j]}"
            echo "after iproute command:"
            echo "${STATE_IP[$j]}"
            exit 1
        fi
    done

done

# remove interface for good
$RUN_SUDO $openvpn --dev $IFACE --dev-type tun --rmtun >/dev/null

exit 0