xref: /linux/tools/testing/selftests/net/cmsg_ip.sh (revision 1cc3462159babb69c84c39cb1b4e262aef3ea325)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4source lib.sh
5
6IP4=172.16.0.1/24
7TGT4=172.16.0.2
8IP6=2001:db8:1::1/64
9TGT6=2001:db8:1::2
10TMPF=$(mktemp --suffix ".pcap")
11
12cleanup()
13{
14    rm -f $TMPF
15    cleanup_ns $NS
16}
17
18trap cleanup EXIT
19
20tcpdump -h | grep immediate-mode >> /dev/null
21if [ $? -ne 0 ]; then
22    echo "SKIP - tcpdump with --immediate-mode option required"
23    exit $ksft_skip
24fi
25
26# Namespaces
27setup_ns NS
28NSEXE="ip netns exec $NS"
29
30$NSEXE sysctl -w net.ipv4.ping_group_range='0 2147483647' > /dev/null
31
32# Connectivity
33ip -netns $NS link add type dummy
34ip -netns $NS link set dev dummy0 up
35ip -netns $NS addr add $IP4 dev dummy0
36ip -netns $NS addr add $IP6 dev dummy0
37
38# Test
39BAD=0
40TOTAL=0
41
42check_result() {
43    ((TOTAL++))
44    if [ $1 -ne $2 ]; then
45	echo "  Case $3 returned $1, expected $2"
46	((BAD++))
47    fi
48}
49
50# IPV6_DONTFRAG
51for ovr in setsock cmsg both diff; do
52    for df in 0 1; do
53	for p in u i r; do
54	    [ $p == "u" ] && prot=UDP
55	    [ $p == "i" ] && prot=ICMP
56	    [ $p == "r" ] && prot=RAW
57
58	    [ $ovr == "setsock" ] && m="-F $df"
59	    [ $ovr == "cmsg" ]    && m="-f $df"
60	    [ $ovr == "both" ]    && m="-F $df -f $df"
61	    [ $ovr == "diff" ]    && m="-F $((1 - df)) -f $df"
62
63	    $NSEXE ./cmsg_sender -s -S 2000 -6 -p $p $m $TGT6 1234
64	    check_result $? $df "DONTFRAG $prot $ovr"
65	done
66    done
67done
68
69# IP_TOS + IPV6_TCLASS
70
71test_dscp() {
72    local -r IPVER=$1
73    local -r TGT=$2
74    local -r MATCH=$3
75
76    local -r TOS=0x10
77    local -r TOS2=0x20
78    local -r ECN=0x3
79
80    ip $IPVER -netns $NS rule add tos $TOS lookup 300
81    ip $IPVER -netns $NS route add table 300 prohibit any
82
83    for ovr in setsock cmsg both diff; do
84	for p in u i r; do
85	    [ $p == "u" ] && prot=UDP
86	    [ $p == "i" ] && prot=ICMP
87	    [ $p == "r" ] && prot=RAW
88
89	    [ $ovr == "setsock" ] && m="-C"
90	    [ $ovr == "cmsg" ]    && m="-c"
91	    [ $ovr == "both" ]    && m="-C $((TOS2)) -c"
92	    [ $ovr == "diff" ]    && m="-C $((TOS )) -c"
93
94	    $NSEXE nohup tcpdump --immediate-mode -p -ni dummy0 -w $TMPF -c 4 2> /dev/null &
95	    BG=$!
96	    sleep 0.05
97
98	    $NSEXE ./cmsg_sender $IPVER -p $p $m $((TOS2)) $TGT 1234
99	    check_result $? 0 "$MATCH $prot $ovr - pass"
100
101	    while [ -d /proc/$BG ]; do
102	        $NSEXE ./cmsg_sender $IPVER -p $p $m $((TOS2)) $TGT 1234
103	    done
104
105	    tcpdump -r $TMPF -v 2>&1 | grep "$MATCH $TOS2" >> /dev/null
106	    check_result $? 0 "$MATCH $prot $ovr - packet data"
107	    rm $TMPF
108
109	    [ $ovr == "both" ]    && m="-C $((TOS )) -c"
110	    [ $ovr == "diff" ]    && m="-C $((TOS2)) -c"
111
112	    # Match prohibit rule: expect failure
113	    $NSEXE ./cmsg_sender $IPVER -p $p $m $((TOS)) -s $TGT 1234
114	    check_result $? 1 "$MATCH $prot $ovr - rejection"
115
116	    # Match prohibit rule: IPv4 masks ECN: expect failure
117	    if [[ "$IPVER" == "-4" ]]; then
118		$NSEXE ./cmsg_sender $IPVER -p $p $m "$((TOS | ECN))" -s $TGT 1234
119		check_result $? 1 "$MATCH $prot $ovr - rejection (ECN)"
120	    fi
121	done
122    done
123}
124
125test_dscp -4 $TGT4 tos
126test_dscp -6 $TGT6 class
127
128# IP_TTL + IPV6_HOPLIMIT
129test_ttl_hoplimit() {
130    local -r IPVER=$1
131    local -r TGT=$2
132    local -r MATCH=$3
133
134    local -r LIM=4
135
136    for ovr in setsock cmsg both diff; do
137	for p in u i r; do
138	    [ $p == "u" ] && prot=UDP
139	    [ $p == "i" ] && prot=ICMP
140	    [ $p == "r" ] && prot=RAW
141
142	    [ $ovr == "setsock" ] && m="-L"
143	    [ $ovr == "cmsg" ]    && m="-l"
144	    [ $ovr == "both" ]    && m="-L $LIM -l"
145	    [ $ovr == "diff" ]    && m="-L $((LIM + 1)) -l"
146
147	    $NSEXE nohup tcpdump --immediate-mode -p -ni dummy0 -w $TMPF -c 4 2> /dev/null &
148	    BG=$!
149	    sleep 0.05
150
151	    $NSEXE ./cmsg_sender $IPVER -p $p $m $LIM $TGT 1234
152	    check_result $? 0 "$MATCH $prot $ovr - pass"
153
154	    while [ -d /proc/$BG ]; do
155		$NSEXE ./cmsg_sender $IPVER -p $p $m $LIM $TGT 1234
156	    done
157
158	    tcpdump -r $TMPF -v 2>&1 | grep "$MATCH $LIM[^0-9]" >> /dev/null
159	    check_result $? 0 "$MATCH $prot $ovr - packet data"
160	    rm $TMPF
161	done
162    done
163}
164
165test_ttl_hoplimit -4 $TGT4 ttl
166test_ttl_hoplimit -6 $TGT6 hlim
167
168# IPV6 exthdr
169for p in u i r; do
170    # Very basic "does it crash" test
171    for h in h d r; do
172	$NSEXE ./cmsg_sender -p $p -6 -H $h $TGT6 1234
173	check_result $? 0 "ExtHdr $prot $ovr - pass"
174    done
175done
176
177# Summary
178if [ $BAD -ne 0 ]; then
179    echo "FAIL - $BAD/$TOTAL cases failed"
180    exit 1
181else
182    echo "OK"
183    exit 0
184fi
185