fanotify: disallow mount/sb marks on kernel internal pseudo fs
[sfrench/cifs-2.6.git] / tools / testing / selftests / net / mptcp / mptcp_sockopt.sh
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3
4 . "$(dirname "${0}")/mptcp_lib.sh"
5
6 ret=0
7 sin=""
8 sout=""
9 cin=""
10 cout=""
11 ksft_skip=4
12 timeout_poll=30
13 timeout_test=$((timeout_poll * 2 + 1))
14 mptcp_connect=""
15
16 sec=$(date +%s)
17 rndh=$(printf %x $sec)-$(mktemp -u XXXXXX)
18 ns1="ns1-$rndh"
19 ns2="ns2-$rndh"
20 ns_sbox="ns_sbox-$rndh"
21
22 add_mark_rules()
23 {
24         local ns=$1
25         local m=$2
26
27         local t
28         for t in iptables ip6tables; do
29                 # just to debug: check we have multiple subflows connection requests
30                 ip netns exec $ns $t -A OUTPUT -p tcp --syn -m mark --mark $m -j ACCEPT
31
32                 # RST packets might be handled by a internal dummy socket
33                 ip netns exec $ns $t -A OUTPUT -p tcp --tcp-flags RST RST -m mark --mark 0 -j ACCEPT
34
35                 ip netns exec $ns $t -A OUTPUT -p tcp -m mark --mark $m -j ACCEPT
36                 ip netns exec $ns $t -A OUTPUT -p tcp -m mark --mark 0 -j DROP
37         done
38 }
39
40 init()
41 {
42         local netns
43         for netns in "$ns1" "$ns2" "$ns_sbox";do
44                 ip netns add $netns || exit $ksft_skip
45                 ip -net $netns link set lo up
46                 ip netns exec $netns sysctl -q net.mptcp.enabled=1
47                 ip netns exec $netns sysctl -q net.ipv4.conf.all.rp_filter=0
48                 ip netns exec $netns sysctl -q net.ipv4.conf.default.rp_filter=0
49         done
50
51         local i
52         for i in `seq 1 4`; do
53                 ip link add ns1eth$i netns "$ns1" type veth peer name ns2eth$i netns "$ns2"
54                 ip -net "$ns1" addr add 10.0.$i.1/24 dev ns1eth$i
55                 ip -net "$ns1" addr add dead:beef:$i::1/64 dev ns1eth$i nodad
56                 ip -net "$ns1" link set ns1eth$i up
57
58                 ip -net "$ns2" addr add 10.0.$i.2/24 dev ns2eth$i
59                 ip -net "$ns2" addr add dead:beef:$i::2/64 dev ns2eth$i nodad
60                 ip -net "$ns2" link set ns2eth$i up
61
62                 # let $ns2 reach any $ns1 address from any interface
63                 ip -net "$ns2" route add default via 10.0.$i.1 dev ns2eth$i metric 10$i
64
65                 ip netns exec $ns1 ./pm_nl_ctl add 10.0.$i.1 flags signal
66                 ip netns exec $ns1 ./pm_nl_ctl add dead:beef:$i::1 flags signal
67
68                 ip netns exec $ns2 ./pm_nl_ctl add 10.0.$i.2 flags signal
69                 ip netns exec $ns2 ./pm_nl_ctl add dead:beef:$i::2 flags signal
70         done
71
72         ip netns exec $ns1 ./pm_nl_ctl limits 8 8
73         ip netns exec $ns2 ./pm_nl_ctl limits 8 8
74
75         add_mark_rules $ns1 1
76         add_mark_rules $ns2 2
77 }
78
79 cleanup()
80 {
81         local netns
82         for netns in "$ns1" "$ns2" "$ns_sbox"; do
83                 ip netns del $netns
84         done
85         rm -f "$cin" "$cout"
86         rm -f "$sin" "$sout"
87 }
88
89 mptcp_lib_check_mptcp
90 mptcp_lib_check_kallsyms
91
92 ip -Version > /dev/null 2>&1
93 if [ $? -ne 0 ];then
94         echo "SKIP: Could not run test without ip tool"
95         exit $ksft_skip
96 fi
97
98 iptables -V > /dev/null 2>&1
99 if [ $? -ne 0 ];then
100         echo "SKIP: Could not run all tests without iptables tool"
101         exit $ksft_skip
102 fi
103
104 ip6tables -V > /dev/null 2>&1
105 if [ $? -ne 0 ];then
106         echo "SKIP: Could not run all tests without ip6tables tool"
107         exit $ksft_skip
108 fi
109
110 check_mark()
111 {
112         local ns=$1
113         local af=$2
114
115         local tables=iptables
116
117         if [ $af -eq 6 ];then
118                 tables=ip6tables
119         fi
120
121         local counters values
122         counters=$(ip netns exec $ns $tables -v -L OUTPUT | grep DROP)
123         values=${counters%DROP*}
124
125         local v
126         for v in $values; do
127                 if [ $v -ne 0 ]; then
128                         echo "FAIL: got $tables $values in ns $ns , not 0 - not all expected packets marked" 1>&2
129                         return 1
130                 fi
131         done
132
133         return 0
134 }
135
136 print_file_err()
137 {
138         ls -l "$1" 1>&2
139         echo "Trailing bytes are: "
140         tail -c 27 "$1"
141 }
142
143 check_transfer()
144 {
145         local in=$1
146         local out=$2
147         local what=$3
148
149         cmp "$in" "$out" > /dev/null 2>&1
150         if [ $? -ne 0 ] ;then
151                 echo "[ FAIL ] $what does not match (in, out):"
152                 print_file_err "$in"
153                 print_file_err "$out"
154                 ret=1
155
156                 return 1
157         fi
158
159         return 0
160 }
161
162 # $1: IP address
163 is_v6()
164 {
165         [ -z "${1##*:*}" ]
166 }
167
168 do_transfer()
169 {
170         local listener_ns="$1"
171         local connector_ns="$2"
172         local cl_proto="$3"
173         local srv_proto="$4"
174         local connect_addr="$5"
175
176         local port=12001
177
178         :> "$cout"
179         :> "$sout"
180
181         local mptcp_connect="./mptcp_connect -r 20"
182
183         local local_addr
184         if is_v6 "${connect_addr}"; then
185                 local_addr="::"
186         else
187                 local_addr="0.0.0.0"
188         fi
189
190         cmsg="TIMESTAMPNS"
191         if mptcp_lib_kallsyms_has "mptcp_ioctl$"; then
192                 cmsg+=",TCPINQ"
193         fi
194
195         timeout ${timeout_test} \
196                 ip netns exec ${listener_ns} \
197                         $mptcp_connect -t ${timeout_poll} -l -M 1 -p $port -s ${srv_proto} -c "${cmsg}" \
198                                 ${local_addr} < "$sin" > "$sout" &
199         local spid=$!
200
201         sleep 1
202
203         timeout ${timeout_test} \
204                 ip netns exec ${connector_ns} \
205                         $mptcp_connect -t ${timeout_poll} -M 2 -p $port -s ${cl_proto} -c "${cmsg}" \
206                                 $connect_addr < "$cin" > "$cout" &
207
208         local cpid=$!
209
210         wait $cpid
211         local retc=$?
212         wait $spid
213         local rets=$?
214
215         if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then
216                 echo " client exit code $retc, server $rets" 1>&2
217                 echo -e "\nnetns ${listener_ns} socket stat for ${port}:" 1>&2
218                 ip netns exec ${listener_ns} ss -Menita 1>&2 -o "sport = :$port"
219
220                 echo -e "\nnetns ${connector_ns} socket stat for ${port}:" 1>&2
221                 ip netns exec ${connector_ns} ss -Menita 1>&2 -o "dport = :$port"
222
223                 ret=1
224                 return 1
225         fi
226
227         if [ $local_addr = "::" ];then
228                 check_mark $listener_ns 6
229                 check_mark $connector_ns 6
230         else
231                 check_mark $listener_ns 4
232                 check_mark $connector_ns 4
233         fi
234
235         check_transfer $cin $sout "file received by server"
236
237         rets=$?
238
239         if [ $retc -eq 0 ] && [ $rets -eq 0 ];then
240                 return 0
241         fi
242
243         return 1
244 }
245
246 make_file()
247 {
248         local name=$1
249         local who=$2
250         local size=$3
251
252         dd if=/dev/urandom of="$name" bs=1024 count=$size 2> /dev/null
253         echo -e "\nMPTCP_TEST_FILE_END_MARKER" >> "$name"
254
255         echo "Created $name (size $size KB) containing data sent by $who"
256 }
257
258 do_mptcp_sockopt_tests()
259 {
260         local lret=0
261
262         if ! mptcp_lib_kallsyms_has "mptcp_diag_fill_info$"; then
263                 echo "INFO: MPTCP sockopt not supported: SKIP"
264                 return
265         fi
266
267         ip netns exec "$ns_sbox" ./mptcp_sockopt
268         lret=$?
269
270         if [ $lret -ne 0 ]; then
271                 echo "FAIL: SOL_MPTCP getsockopt" 1>&2
272                 ret=$lret
273                 return
274         fi
275
276         ip netns exec "$ns_sbox" ./mptcp_sockopt -6
277         lret=$?
278
279         if [ $lret -ne 0 ]; then
280                 echo "FAIL: SOL_MPTCP getsockopt (ipv6)" 1>&2
281                 ret=$lret
282                 return
283         fi
284 }
285
286 run_tests()
287 {
288         local listener_ns="$1"
289         local connector_ns="$2"
290         local connect_addr="$3"
291         local lret=0
292
293         do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP ${connect_addr}
294
295         lret=$?
296
297         if [ $lret -ne 0 ]; then
298                 ret=$lret
299                 return
300         fi
301 }
302
303 do_tcpinq_test()
304 {
305         ip netns exec "$ns_sbox" ./mptcp_inq "$@"
306         local lret=$?
307         if [ $lret -ne 0 ];then
308                 ret=$lret
309                 echo "FAIL: mptcp_inq $@" 1>&2
310                 return $lret
311         fi
312
313         echo "PASS: TCP_INQ cmsg/ioctl $@"
314         return $lret
315 }
316
317 do_tcpinq_tests()
318 {
319         local lret=0
320
321         if ! mptcp_lib_kallsyms_has "mptcp_ioctl$"; then
322                 echo "INFO: TCP_INQ not supported: SKIP"
323                 return
324         fi
325
326         local args
327         for args in "-t tcp" "-r tcp"; do
328                 do_tcpinq_test $args
329                 lret=$?
330                 if [ $lret -ne 0 ] ; then
331                         return $lret
332                 fi
333                 do_tcpinq_test -6 $args
334                 lret=$?
335                 if [ $lret -ne 0 ] ; then
336                         return $lret
337                 fi
338         done
339
340         do_tcpinq_test -r tcp -t tcp
341
342         return $?
343 }
344
345 sin=$(mktemp)
346 sout=$(mktemp)
347 cin=$(mktemp)
348 cout=$(mktemp)
349 init
350 make_file "$cin" "client" 1
351 make_file "$sin" "server" 1
352 trap cleanup EXIT
353
354 run_tests $ns1 $ns2 10.0.1.1
355 run_tests $ns1 $ns2 dead:beef:1::1
356
357 if [ $ret -eq 0 ];then
358         echo "PASS: all packets had packet mark set"
359 fi
360
361 do_mptcp_sockopt_tests
362 if [ $ret -eq 0 ];then
363         echo "PASS: SOL_MPTCP getsockopt has expected information"
364 fi
365
366 do_tcpinq_tests
367 exit $ret