OSDN Git Service

2d33e533ad361108740cf70c89f860c92cf4a020
[tomoyo/tomoyo-test1.git] / tools / testing / selftests / net / pmtu.sh
1 #!/bin/sh
2 # SPDX-License-Identifier: GPL-2.0
3 #
4 # Check that route PMTU values match expectations
5 #
6 # Tests currently implemented:
7 #
8 # - test_pmtu_vti6_exception
9 #       Set up vti6 tunnel on top of veth, with xfrm states and policies, in two
10 #       namespaces with matching endpoints. Check that route exception is
11 #       created by exceeding link layer MTU with ping to other endpoint. Then
12 #       decrease and increase MTU of tunnel, checking that route exception PMTU
13 #       changes accordingly
14
15 NS_A="ns-$(mktemp -u XXXXXX)"
16 NS_B="ns-$(mktemp -u XXXXXX)"
17 ns_a="ip netns exec ${NS_A}"
18 ns_b="ip netns exec ${NS_B}"
19
20 veth6_a_addr="fd00:1::a"
21 veth6_b_addr="fd00:1::b"
22 veth6_mask="64"
23
24 vti6_a_addr="fd00:2::a"
25 vti6_b_addr="fd00:2::b"
26 vti6_mask="64"
27
28 setup_namespaces() {
29         ip netns add ${NS_A} || return 1
30         ip netns add ${NS_B}
31 }
32
33 setup_veth() {
34         ${ns_a} ip link add veth_a type veth peer name veth_b || return 1
35         ${ns_a} ip link set veth_b netns ${NS_B}
36
37         ${ns_a} ip addr add ${veth6_a_addr}/${veth6_mask} dev veth_a
38         ${ns_b} ip addr add ${veth6_b_addr}/${veth6_mask} dev veth_b
39
40         ${ns_a} ip link set veth_a up
41         ${ns_b} ip link set veth_b up
42 }
43
44 setup_vti6() {
45         ${ns_a} ip link add vti_a type vti6 local ${veth6_a_addr} remote ${veth6_b_addr} key 10 || return 1
46         ${ns_b} ip link add vti_b type vti6 local ${veth6_b_addr} remote ${veth6_a_addr} key 10
47
48         ${ns_a} ip addr add ${vti6_a_addr}/${vti6_mask} dev vti_a
49         ${ns_b} ip addr add ${vti6_b_addr}/${vti6_mask} dev vti_b
50
51         ${ns_a} ip link set vti_a up
52         ${ns_b} ip link set vti_b up
53
54         sleep 1
55 }
56
57 setup_xfrm() {
58         ${ns_a} ip -6 xfrm state add src ${veth6_a_addr} dst ${veth6_b_addr} spi 0x1000 proto esp aead "rfc4106(gcm(aes))" 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel || return 1
59         ${ns_a} ip -6 xfrm state add src ${veth6_b_addr} dst ${veth6_a_addr} spi 0x1001 proto esp aead "rfc4106(gcm(aes))" 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel
60         ${ns_a} ip -6 xfrm policy add dir out mark 10 tmpl src ${veth6_a_addr} dst ${veth6_b_addr} proto esp mode tunnel
61         ${ns_a} ip -6 xfrm policy add dir in mark 10 tmpl src ${veth6_b_addr} dst ${veth6_a_addr} proto esp mode tunnel
62
63         ${ns_b} ip -6 xfrm state add src ${veth6_a_addr} dst ${veth6_b_addr} spi 0x1000 proto esp aead "rfc4106(gcm(aes))" 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel
64         ${ns_b} ip -6 xfrm state add src ${veth6_b_addr} dst ${veth6_a_addr} spi 0x1001 proto esp aead "rfc4106(gcm(aes))" 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel
65         ${ns_b} ip -6 xfrm policy add dir out mark 10 tmpl src ${veth6_b_addr} dst ${veth6_a_addr} proto esp mode tunnel
66         ${ns_b} ip -6 xfrm policy add dir in mark 10 tmpl src ${veth6_a_addr} dst ${veth6_b_addr} proto esp mode tunnel
67 }
68
69 setup() {
70         tunnel_type="$1"
71
72         [ "$(id -u)" -ne 0 ] && echo "SKIP: need to run as root" && exit 0
73
74         setup_namespaces || { echo "SKIP: namespaces not supported"; exit 0; }
75         setup_veth || { echo "SKIP: veth not supported"; exit 0; }
76
77         case ${tunnel_type} in
78         "vti6")
79                 setup_vti6 || { echo "SKIP: vti6 not supported"; exit 0; }
80                 setup_xfrm || { echo "SKIP: xfrm not supported"; exit 0; }
81                 ;;
82         *)
83                 ;;
84         esac
85 }
86
87 cleanup() {
88         ip netns del ${NS_A} 2 > /dev/null
89         ip netns del ${NS_B} 2 > /dev/null
90 }
91
92 mtu() {
93         ns_cmd="${1}"
94         dev="${2}"
95         mtu="${3}"
96
97         ${ns_cmd} ip link set dev ${dev} mtu ${mtu}
98 }
99
100 mtu_parse() {
101         input="${1}"
102
103         next=0
104         for i in ${input}; do
105                 [ ${next} -eq 1 ] && echo "${i}" && return
106                 [ "${i}" = "mtu" ] && next=1
107         done
108 }
109
110 route_get_dst_exception() {
111         ns_cmd="${1}"
112         dst="${2}"
113
114         ${ns_cmd} ip route get "${dst}"
115 }
116
117 route_get_dst_pmtu_from_exception() {
118         ns_cmd="${1}"
119         dst="${2}"
120
121         mtu_parse "$(route_get_dst_exception "${ns_cmd}" ${dst})"
122 }
123
124 test_pmtu_vti6_exception() {
125         setup vti6
126
127         # Create route exception by exceeding link layer MTU
128         mtu "${ns_a}" veth_a 4000
129         mtu "${ns_b}" veth_b 4000
130         mtu "${ns_a}" vti_a 5000
131         mtu "${ns_b}" vti_b 5000
132         ${ns_a} ping6 -q -i 0.1 -w 2 -s 60000 ${vti6_b_addr} > /dev/null
133
134         # Check that exception was created
135         if [ "$(route_get_dst_pmtu_from_exception "${ns_a}" ${vti6_b_addr})" = "" ]; then
136                 echo "FAIL: Tunnel exceeding link layer MTU didn't create route exception"
137                 exit 1
138         fi
139
140         # Decrease tunnel MTU, check for PMTU decrease in route exception
141         mtu "${ns_a}" vti_a 3000
142
143         if [ "$(route_get_dst_pmtu_from_exception "${ns_a}" ${vti6_b_addr})" -ne 3000 ]; then
144                 echo "FAIL: Decreasing tunnel MTU didn't decrease route exception PMTU"
145                 exit 1
146         fi
147
148         # Increase tunnel MTU, check for PMTU increase in route exception
149         mtu "${ns_a}" vti_a 9000
150         if [ "$(route_get_dst_pmtu_from_exception "${ns_a}" ${vti6_b_addr})" -ne 9000 ]; then
151                 echo "FAIL: Increasing tunnel MTU didn't increase route exception PMTU"
152                 exit 1
153         fi
154
155         echo "PASS"
156 }
157
158 trap cleanup EXIT
159
160 test_pmtu_vti6_exception
161
162 exit 0