summaryrefslogtreecommitdiff
path: root/tests/t_net.sh
blob: 246ee07bd67249d0670940493824fe6c5297d975 (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
#!/usr/bin/env bash

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

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 ip link del $IFACE
    $RUN_SUDO ip link add $IFACE address 00:11:22:33:44:55 type dummy
    $RUN_SUDO ip link set dev $IFACE state up

    if [ $? -ne 0 ]; then
        echo "can't create interface $IFACE"
        exit 1
    fi
}

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

# t_client.rc required only for RUN_SUDO definition
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 [ ! -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 the networking unit-test
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: no RUN_SUDO=... in t_client.rc or environment, defaulting to 'sudo'." >&2
        echo "      if that does not work, set RUN_SUDO= correctly for your system." >&2
        RUN_SUDO="sudo"
    fi

    # check that we can run the unit-test binary with sudo
    if $RUN_SUDO $UNIT_TEST test
    then
        echo "$0: $RUN_SUDO $UNIT_TEST succeeded, good."
    else
        echo "$0: $RUN_SUDO $UNIT_TEST failed, cannot go on. SKIP." >&2
        exit 77
    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
    echo "Test $i: OK"
done

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

exit 0