26
26
# - pmtu_ipv6
27
27
# Same as pmtu_ipv4, except for locked PMTU tests, using IPv6
28
28
#
29
+ # - pmtu_ipv4_dscp_icmp_exception
30
+ # Set up the same network topology as pmtu_ipv4, but use non-default
31
+ # routing table in A. A fib-rule is used to jump to this routing table
32
+ # based on DSCP. Send ICMPv4 packets with the expected DSCP value and
33
+ # verify that ECN doesn't interfere with the creation of PMTU exceptions.
34
+ #
35
+ # - pmtu_ipv4_dscp_udp_exception
36
+ # Same as pmtu_ipv4_dscp_icmp_exception, but use UDP instead of ICMP.
37
+ #
29
38
# - pmtu_ipv4_vxlan4_exception
30
39
# Set up the same network topology as pmtu_ipv4, create a VXLAN tunnel
31
40
# over IPv4 between A and B, routed via R1. On the link between R1 and B,
@@ -203,6 +212,8 @@ which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping)
203
212
tests="
204
213
pmtu_ipv4_exception ipv4: PMTU exceptions 1
205
214
pmtu_ipv6_exception ipv6: PMTU exceptions 1
215
+ pmtu_ipv4_dscp_icmp_exception ICMPv4 with DSCP and ECN: PMTU exceptions 1
216
+ pmtu_ipv4_dscp_udp_exception UDPv4 with DSCP and ECN: PMTU exceptions 1
206
217
pmtu_ipv4_vxlan4_exception IPv4 over vxlan4: PMTU exceptions 1
207
218
pmtu_ipv6_vxlan4_exception IPv6 over vxlan4: PMTU exceptions 1
208
219
pmtu_ipv4_vxlan6_exception IPv4 over vxlan6: PMTU exceptions 1
@@ -323,6 +334,9 @@ routes_nh="
323
334
B 6 default 61
324
335
"
325
336
337
+ policy_mark=0x04
338
+ rt_table=main
339
+
326
340
veth4_a_addr=" 192.168.1.1"
327
341
veth4_b_addr=" 192.168.1.2"
328
342
veth4_c_addr=" 192.168.2.10"
@@ -346,6 +360,7 @@ dummy6_mask="64"
346
360
err_buf=
347
361
tcpdump_pids=
348
362
nettest_pids=
363
+ socat_pids=
349
364
350
365
err () {
351
366
err_buf=" ${err_buf}${1}
@@ -723,7 +738,7 @@ setup_routing_old() {
723
738
724
739
ns_name=" $( nsname ${ns} ) "
725
740
726
- ip -n ${ns_name} route add ${addr} via ${gw}
741
+ ip -n " ${ns_name} " route add " ${addr} " table " ${rt_table} " via " ${gw} "
727
742
728
743
ns=" " ; addr=" " ; gw=" "
729
744
done
@@ -753,7 +768,7 @@ setup_routing_new() {
753
768
754
769
ns_name=" $( nsname ${ns} ) "
755
770
756
- ip -n ${ns_name} - ${fam} route add ${addr} nhid ${nhid}
771
+ ip -n " ${ns_name} " - " ${fam} " route add " ${addr} " table " ${rt_table} " nhid " ${nhid} "
757
772
758
773
ns=" " ; fam=" " ; addr=" " ; nhid=" "
759
774
done
@@ -798,6 +813,24 @@ setup_routing() {
798
813
return 0
799
814
}
800
815
816
+ setup_policy_routing () {
817
+ setup_routing
818
+
819
+ ip -netns " ${NS_A} " -4 rule add dsfield " ${policy_mark} " \
820
+ table " ${rt_table} "
821
+
822
+ # Set the IPv4 Don't Fragment bit with tc, since socat doesn't seem to
823
+ # have an option do to it.
824
+ tc -netns " ${NS_A} " qdisc replace dev veth_A-R1 root prio
825
+ tc -netns " ${NS_A} " qdisc replace dev veth_A-R2 root prio
826
+ tc -netns " ${NS_A} " filter add dev veth_A-R1 \
827
+ protocol ipv4 flower ip_proto udp \
828
+ action pedit ex munge ip df set 0x40 pipe csum ip and udp
829
+ tc -netns " ${NS_A} " filter add dev veth_A-R2 \
830
+ protocol ipv4 flower ip_proto udp \
831
+ action pedit ex munge ip df set 0x40 pipe csum ip and udp
832
+ }
833
+
801
834
setup_bridge () {
802
835
run_cmd ${ns_a} ip link add br0 type bridge || return $ksft_skip
803
836
run_cmd ${ns_a} ip link set br0 up
@@ -903,6 +936,11 @@ cleanup() {
903
936
done
904
937
nettest_pids=
905
938
939
+ for pid in ${socat_pids} ; do
940
+ kill " ${pid} "
941
+ done
942
+ socat_pids=
943
+
906
944
for n in ${NS_A} ${NS_B} ${NS_C} ${NS_R1} ${NS_R2} ; do
907
945
ip netns del ${n} 2> /dev/null
908
946
done
@@ -950,15 +988,21 @@ link_get_mtu() {
950
988
route_get_dst_exception () {
951
989
ns_cmd=" ${1} "
952
990
dst=" ${2} "
991
+ dsfield=" ${3} "
953
992
954
- ${ns_cmd} ip route get " ${dst} "
993
+ if [ -z " ${dsfield} " ]; then
994
+ dsfield=0
995
+ fi
996
+
997
+ ${ns_cmd} ip route get " ${dst} " dsfield " ${dsfield} "
955
998
}
956
999
957
1000
route_get_dst_pmtu_from_exception () {
958
1001
ns_cmd=" ${1} "
959
1002
dst=" ${2} "
1003
+ dsfield=" ${3} "
960
1004
961
- mtu_parse " $( route_get_dst_exception " ${ns_cmd} " ${dst} ) "
1005
+ mtu_parse " $( route_get_dst_exception " ${ns_cmd} " " ${dst} " " ${dsfield} " ) "
962
1006
}
963
1007
964
1008
check_pmtu_value () {
@@ -1068,6 +1112,95 @@ test_pmtu_ipv6_exception() {
1068
1112
test_pmtu_ipvX 6
1069
1113
}
1070
1114
1115
+ test_pmtu_ipv4_dscp_icmp_exception () {
1116
+ rt_table=100
1117
+
1118
+ setup namespaces policy_routing || return $ksft_skip
1119
+ trace " ${ns_a} " veth_A-R1 " ${ns_r1} " veth_R1-A \
1120
+ " ${ns_r1} " veth_R1-B " ${ns_b} " veth_B-R1 \
1121
+ " ${ns_a} " veth_A-R2 " ${ns_r2} " veth_R2-A \
1122
+ " ${ns_r2} " veth_R2-B " ${ns_b} " veth_B-R2
1123
+
1124
+ # Set up initial MTU values
1125
+ mtu " ${ns_a} " veth_A-R1 2000
1126
+ mtu " ${ns_r1} " veth_R1-A 2000
1127
+ mtu " ${ns_r1} " veth_R1-B 1400
1128
+ mtu " ${ns_b} " veth_B-R1 1400
1129
+
1130
+ mtu " ${ns_a} " veth_A-R2 2000
1131
+ mtu " ${ns_r2} " veth_R2-A 2000
1132
+ mtu " ${ns_r2} " veth_R2-B 1500
1133
+ mtu " ${ns_b} " veth_B-R2 1500
1134
+
1135
+ len=$(( 2000 - 20 - 8 )) # Fills MTU of veth_A-R1
1136
+
1137
+ dst1=" ${prefix4} .${b_r1} .1"
1138
+ dst2=" ${prefix4} .${b_r2} .1"
1139
+
1140
+ # Create route exceptions
1141
+ dsfield=${policy_mark} # No ECN bit set (Not-ECT)
1142
+ run_cmd " ${ns_a} " ping -q -M want -Q " ${dsfield} " -c 1 -w 1 -s " ${len} " " ${dst1} "
1143
+
1144
+ dsfield=$( printf " %#x" $(( policy_mark + 0x02 )) ) # ECN=2 (ECT(0))
1145
+ run_cmd " ${ns_a} " ping -q -M want -Q " ${dsfield} " -c 1 -w 1 -s " ${len} " " ${dst2} "
1146
+
1147
+ # Check that exceptions have been created with the correct PMTU
1148
+ pmtu_1=" $( route_get_dst_pmtu_from_exception " ${ns_a} " " ${dst1} " " ${policy_mark} " ) "
1149
+ check_pmtu_value " 1400" " ${pmtu_1} " " exceeding MTU" || return 1
1150
+
1151
+ pmtu_2=" $( route_get_dst_pmtu_from_exception " ${ns_a} " " ${dst2} " " ${policy_mark} " ) "
1152
+ check_pmtu_value " 1500" " ${pmtu_2} " " exceeding MTU" || return 1
1153
+ }
1154
+
1155
+ test_pmtu_ipv4_dscp_udp_exception () {
1156
+ rt_table=100
1157
+
1158
+ if ! which socat > /dev/null 2>&1 ; then
1159
+ echo " 'socat' command not found; skipping tests"
1160
+ return $ksft_skip
1161
+ fi
1162
+
1163
+ setup namespaces policy_routing || return $ksft_skip
1164
+ trace " ${ns_a} " veth_A-R1 " ${ns_r1} " veth_R1-A \
1165
+ " ${ns_r1} " veth_R1-B " ${ns_b} " veth_B-R1 \
1166
+ " ${ns_a} " veth_A-R2 " ${ns_r2} " veth_R2-A \
1167
+ " ${ns_r2} " veth_R2-B " ${ns_b} " veth_B-R2
1168
+
1169
+ # Set up initial MTU values
1170
+ mtu " ${ns_a} " veth_A-R1 2000
1171
+ mtu " ${ns_r1} " veth_R1-A 2000
1172
+ mtu " ${ns_r1} " veth_R1-B 1400
1173
+ mtu " ${ns_b} " veth_B-R1 1400
1174
+
1175
+ mtu " ${ns_a} " veth_A-R2 2000
1176
+ mtu " ${ns_r2} " veth_R2-A 2000
1177
+ mtu " ${ns_r2} " veth_R2-B 1500
1178
+ mtu " ${ns_b} " veth_B-R2 1500
1179
+
1180
+ len=$(( 2000 - 20 - 8 )) # Fills MTU of veth_A-R1
1181
+
1182
+ dst1=" ${prefix4} .${b_r1} .1"
1183
+ dst2=" ${prefix4} .${b_r2} .1"
1184
+
1185
+ # Create route exceptions
1186
+ run_cmd_bg " ${ns_b} " socat UDP-LISTEN:50000 OPEN:/dev/null,wronly=1
1187
+ socat_pids=" ${socat_pids} $! "
1188
+
1189
+ dsfield=${policy_mark} # No ECN bit set (Not-ECT)
1190
+ run_cmd " ${ns_a} " socat OPEN:/dev/zero,rdonly=1,readbytes=" ${len} " \
1191
+ UDP:" ${dst1} " :50000,tos=" ${dsfield} "
1192
+
1193
+ dsfield=$( printf " %#x" $(( policy_mark + 0x02 )) ) # ECN=2 (ECT(0))
1194
+ run_cmd " ${ns_a} " socat OPEN:/dev/zero,rdonly=1,readbytes=" ${len} " \
1195
+ UDP:" ${dst2} " :50000,tos=" ${dsfield} "
1196
+
1197
+ # Check that exceptions have been created with the correct PMTU
1198
+ pmtu_1=" $( route_get_dst_pmtu_from_exception " ${ns_a} " " ${dst1} " " ${policy_mark} " ) "
1199
+ check_pmtu_value " 1400" " ${pmtu_1} " " exceeding MTU" || return 1
1200
+ pmtu_2=" $( route_get_dst_pmtu_from_exception " ${ns_a} " " ${dst2} " " ${policy_mark} " ) "
1201
+ check_pmtu_value " 1500" " ${pmtu_2} " " exceeding MTU" || return 1
1202
+ }
1203
+
1071
1204
test_pmtu_ipvX_over_vxlanY_or_geneveY_exception () {
1072
1205
type=${1}
1073
1206
family=${2}
0 commit comments