0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109 ERR=4
0110 PING6="ping"
0111 PAUSE_ON_FAIL="no"
0112
0113 readonly NS0=$(mktemp -u ns0-XXXXXXXX)
0114 readonly NS1=$(mktemp -u ns1-XXXXXXXX)
0115 readonly NS2=$(mktemp -u ns2-XXXXXXXX)
0116 readonly NS3=$(mktemp -u ns3-XXXXXXXX)
0117
0118
0119
0120
0121
0122
0123
0124 exit_cleanup()
0125 {
0126 for ns in "$@"; do
0127 ip netns delete "${ns}" 2>/dev/null || true
0128 done
0129
0130 if [ "${ERR}" -eq 4 ]; then
0131 echo "Error: Setting up the testing environment failed." >&2
0132 fi
0133
0134 exit "${ERR}"
0135 }
0136
0137
0138
0139
0140
0141 create_namespaces()
0142 {
0143 ip netns add "${NS0}" || exit_cleanup
0144 ip netns add "${NS1}" || exit_cleanup "${NS0}"
0145 ip netns add "${NS2}" || exit_cleanup "${NS0}" "${NS1}"
0146 ip netns add "${NS3}" || exit_cleanup "${NS0}" "${NS1}" "${NS2}"
0147 }
0148
0149
0150
0151 exit_cleanup_all()
0152 {
0153 exit_cleanup "${NS0}" "${NS1}" "${NS2}" "${NS3}"
0154 }
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167 iface_config()
0168 {
0169 local NS="${1}"; readonly NS
0170 local DEV="${2}"; readonly DEV
0171 local LOCAL_IP4="${3}"; readonly LOCAL_IP4
0172 local PEER_IP4="${4}"; readonly PEER_IP4
0173 local LOCAL_IP6="${5}"; readonly LOCAL_IP6
0174 local PEER_IP6="${6}"; readonly PEER_IP6
0175
0176 ip -netns "${NS}" link set dev "${DEV}" up
0177 ip -netns "${NS}" address add dev "${DEV}" "${LOCAL_IP4}" peer "${PEER_IP4}"
0178 ip -netns "${NS}" address add dev "${DEV}" "${LOCAL_IP6}" peer "${PEER_IP6}" nodad
0179 }
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189 setup_underlay()
0190 {
0191 for ns in "${NS0}" "${NS1}" "${NS2}" "${NS3}"; do
0192 ip -netns "${ns}" link set dev lo up
0193 done;
0194
0195 ip link add name veth01 netns "${NS0}" type veth peer name veth10 netns "${NS1}"
0196 ip link add name veth12 netns "${NS1}" type veth peer name veth21 netns "${NS2}"
0197 ip link add name veth23 netns "${NS2}" type veth peer name veth32 netns "${NS3}"
0198 iface_config "${NS0}" veth01 192.0.2.10 192.0.2.11/32 2001:db8::10 2001:db8::11/128
0199 iface_config "${NS1}" veth10 192.0.2.11 192.0.2.10/32 2001:db8::11 2001:db8::10/128
0200 iface_config "${NS1}" veth12 192.0.2.21 192.0.2.22/32 2001:db8::21 2001:db8::22/128
0201 iface_config "${NS2}" veth21 192.0.2.22 192.0.2.21/32 2001:db8::22 2001:db8::21/128
0202 iface_config "${NS2}" veth23 192.0.2.32 192.0.2.33/32 2001:db8::32 2001:db8::33/128
0203 iface_config "${NS3}" veth32 192.0.2.33 192.0.2.32/32 2001:db8::33 2001:db8::32/128
0204
0205 tc -netns "${NS1}" qdisc add dev veth10 ingress
0206 tc -netns "${NS2}" qdisc add dev veth23 ingress
0207 }
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223 setup_overlay_ipv4()
0224 {
0225
0226 ip -netns "${NS0}" address add 192.0.2.100/32 dev lo
0227 ip -netns "${NS3}" address add 192.0.2.103/32 dev lo
0228 ip -netns "${NS0}" route add 192.0.2.103/32 src 192.0.2.100 via 192.0.2.11
0229 ip -netns "${NS3}" route add 192.0.2.100/32 src 192.0.2.103 via 192.0.2.32
0230
0231
0232
0233 ip netns exec "${NS1}" sysctl -qw net.ipv4.ip_forward=1
0234 ip netns exec "${NS2}" sysctl -qw net.ipv4.ip_forward=1
0235 ip -netns "${NS1}" route add 192.0.2.100/32 via 192.0.2.10
0236 ip -netns "${NS2}" route add 192.0.2.103/32 via 192.0.2.33
0237
0238
0239
0240
0241 ip netns exec "${NS1}" sysctl -qw net.ipv4.conf.all.rp_filter=0
0242 ip netns exec "${NS2}" sysctl -qw net.ipv4.conf.all.rp_filter=0
0243 ip netns exec "${NS1}" sysctl -qw net.ipv4.conf.default.rp_filter=0
0244 ip netns exec "${NS2}" sysctl -qw net.ipv4.conf.default.rp_filter=0
0245 }
0246
0247 setup_overlay_ipv6()
0248 {
0249
0250 ip -netns "${NS0}" address add 2001:db8::100/128 dev lo
0251 ip -netns "${NS3}" address add 2001:db8::103/128 dev lo
0252 ip -netns "${NS0}" route add 2001:db8::103/128 src 2001:db8::100 via 2001:db8::11
0253 ip -netns "${NS3}" route add 2001:db8::100/128 src 2001:db8::103 via 2001:db8::32
0254
0255
0256
0257 ip netns exec "${NS1}" sysctl -qw net.ipv6.conf.all.forwarding=1
0258 ip netns exec "${NS2}" sysctl -qw net.ipv6.conf.all.forwarding=1
0259 ip -netns "${NS1}" route add 2001:db8::100/128 via 2001:db8::10
0260 ip -netns "${NS2}" route add 2001:db8::103/128 via 2001:db8::33
0261 }
0262
0263 setup_overlay_mpls()
0264 {
0265
0266 ip -netns "${NS0}" address add 2001:db8::200/128 dev lo
0267 ip -netns "${NS3}" address add 2001:db8::203/128 dev lo
0268 ip -netns "${NS0}" route add 2001:db8::203/128 src 2001:db8::200 encap mpls 203 via 2001:db8::11
0269 ip -netns "${NS3}" route add 2001:db8::200/128 src 2001:db8::203 encap mpls 200 via 2001:db8::32
0270
0271
0272
0273 ip netns exec "${NS1}" sysctl -qw net.mpls.platform_labels=256
0274 ip netns exec "${NS2}" sysctl -qw net.mpls.platform_labels=256
0275 ip -netns "${NS1}" -family mpls route add 200 via inet6 2001:db8::10
0276 ip -netns "${NS2}" -family mpls route add 203 via inet6 2001:db8::33
0277 }
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290 ping_test_one()
0291 {
0292 local PING="$1"; readonly PING
0293 local IP="$2"; readonly IP
0294 local MSG="$3"; readonly MSG
0295 local RET
0296
0297 printf "TEST: %-60s " "${MSG}"
0298
0299 set +e
0300 ip netns exec "${NS0}" "${PING}" -w 5 -c 1 "${IP}" > /dev/null 2>&1
0301 RET=$?
0302 set -e
0303
0304 if [ "${RET}" -eq 0 ]; then
0305 printf "[ OK ]\n"
0306 else
0307 ERR=1
0308 printf "[FAIL]\n"
0309 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
0310 printf "\nHit enter to continue, 'q' to quit\n"
0311 read a
0312 if [ "$a" = "q" ]; then
0313 exit 1
0314 fi
0315 fi
0316 fi
0317 }
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328 ping_test()
0329 {
0330 local UNDERLAY="$1"; readonly UNDERLAY
0331 local MODE
0332 local MSG
0333
0334 if [ "${MULTIPROTO}" = "multiproto" ]; then
0335 MODE=" (multiproto mode)"
0336 else
0337 MODE=""
0338 fi
0339
0340 if [ $IPV4 ]; then
0341 ping_test_one "ping" "192.0.2.103" "IPv4 packets over ${UNDERLAY}${MODE}"
0342 fi
0343 if [ $IPV6 ]; then
0344 ping_test_one "${PING6}" "2001:db8::103" "IPv6 packets over ${UNDERLAY}${MODE}"
0345 fi
0346 if [ $MPLS_UC ]; then
0347 ping_test_one "${PING6}" "2001:db8::203" "Unicast MPLS packets over ${UNDERLAY}${MODE}"
0348 fi
0349 }
0350
0351
0352
0353
0354
0355
0356
0357
0358 test_overlay()
0359 {
0360 local ETHERTYPE="$1"; readonly ETHERTYPE
0361 local MULTIPROTO="$2"; readonly MULTIPROTO
0362 local IPV4
0363 local IPV6
0364 local MPLS_UC
0365
0366 case "${ETHERTYPE}" in
0367 "ipv4")
0368 IPV4="ipv4"
0369 if [ "${MULTIPROTO}" = "multiproto" ]; then
0370 IPV6="ipv6"
0371 else
0372 IPV6=""
0373 fi
0374 MPLS_UC=""
0375 ;;
0376 "ipv6")
0377 IPV6="ipv6"
0378 IPV4=""
0379 MPLS_UC=""
0380 ;;
0381 "mpls_uc")
0382 MPLS_UC="mpls_uc"
0383 IPV4=""
0384 IPV6=""
0385 ;;
0386 *)
0387 exit 1
0388 ;;
0389 esac
0390 readonly IPV4
0391 readonly IPV6
0392 readonly MPLS_UC
0393
0394
0395 ip -netns "${NS1}" link add name bareudp_ns1 up type bareudp dstport 6635 ethertype "${ETHERTYPE}" "${MULTIPROTO}"
0396 ip -netns "${NS2}" link add name bareudp_ns2 up type bareudp dstport 6635 ethertype "${ETHERTYPE}" "${MULTIPROTO}"
0397
0398
0399 if [ $IPV4 ]; then
0400
0401 tc -netns "${NS1}" filter add dev veth10 ingress protocol ipv4 \
0402 flower dst_ip 192.0.2.103/32 \
0403 action tunnel_key set src_ip 192.0.2.21 dst_ip 192.0.2.22 id 0 \
0404 action mirred egress redirect dev bareudp_ns1
0405 tc -netns "${NS2}" filter add dev veth23 ingress protocol ipv4 \
0406 flower dst_ip 192.0.2.100/32 \
0407 action tunnel_key set src_ip 192.0.2.22 dst_ip 192.0.2.21 id 0 \
0408 action mirred egress redirect dev bareudp_ns2
0409 fi
0410
0411
0412 if [ $IPV6 ]; then
0413
0414 tc -netns "${NS1}" filter add dev veth10 ingress protocol ipv6 \
0415 flower dst_ip 2001:db8::103/128 \
0416 action tunnel_key set src_ip 192.0.2.21 dst_ip 192.0.2.22 id 0 \
0417 action mirred egress redirect dev bareudp_ns1
0418 tc -netns "${NS2}" filter add dev veth23 ingress protocol ipv6 \
0419 flower dst_ip 2001:db8::100/128 \
0420 action tunnel_key set src_ip 192.0.2.22 dst_ip 192.0.2.21 id 0 \
0421 action mirred egress redirect dev bareudp_ns2
0422 fi
0423
0424
0425 if [ $MPLS_UC ]; then
0426 ip netns exec "${NS1}" sysctl -qw net.mpls.conf.bareudp_ns1.input=1
0427 ip netns exec "${NS2}" sysctl -qw net.mpls.conf.bareudp_ns2.input=1
0428
0429
0430 tc -netns "${NS1}" filter add dev veth10 ingress protocol mpls_uc \
0431 flower mpls_label 203 \
0432 action tunnel_key set src_ip 192.0.2.21 dst_ip 192.0.2.22 id 0 \
0433 action mirred egress redirect dev bareudp_ns1
0434 tc -netns "${NS2}" filter add dev veth23 ingress protocol mpls_uc \
0435 flower mpls_label 200 \
0436 action tunnel_key set src_ip 192.0.2.22 dst_ip 192.0.2.21 id 0 \
0437 action mirred egress redirect dev bareudp_ns2
0438 fi
0439
0440
0441 ping_test "UDPv4"
0442
0443
0444
0445 tc -netns "${NS1}" filter delete dev veth10 ingress
0446 tc -netns "${NS2}" filter delete dev veth23 ingress
0447
0448
0449 if [ $IPV4 ]; then
0450
0451 tc -netns "${NS1}" filter add dev veth10 ingress protocol ipv4 \
0452 flower dst_ip 192.0.2.103/32 \
0453 action tunnel_key set src_ip 2001:db8::21 dst_ip 2001:db8::22 id 0 \
0454 action mirred egress redirect dev bareudp_ns1
0455 tc -netns "${NS2}" filter add dev veth23 ingress protocol ipv4 \
0456 flower dst_ip 192.0.2.100/32 \
0457 action tunnel_key set src_ip 2001:db8::22 dst_ip 2001:db8::21 id 0 \
0458 action mirred egress redirect dev bareudp_ns2
0459 fi
0460
0461
0462 if [ $IPV6 ]; then
0463
0464 tc -netns "${NS1}" filter add dev veth10 ingress protocol ipv6 \
0465 flower dst_ip 2001:db8::103/128 \
0466 action tunnel_key set src_ip 2001:db8::21 dst_ip 2001:db8::22 id 0 \
0467 action mirred egress redirect dev bareudp_ns1
0468 tc -netns "${NS2}" filter add dev veth23 ingress protocol ipv6 \
0469 flower dst_ip 2001:db8::100/128 \
0470 action tunnel_key set src_ip 2001:db8::22 dst_ip 2001:db8::21 id 0 \
0471 action mirred egress redirect dev bareudp_ns2
0472 fi
0473
0474
0475 if [ $MPLS_UC ]; then
0476
0477 tc -netns "${NS1}" filter add dev veth10 ingress protocol mpls_uc \
0478 flower mpls_label 203 \
0479 action tunnel_key set src_ip 2001:db8::21 dst_ip 2001:db8::22 id 0 \
0480 action mirred egress redirect dev bareudp_ns1
0481 tc -netns "${NS2}" filter add dev veth23 ingress protocol mpls_uc \
0482 flower mpls_label 200 \
0483 action tunnel_key set src_ip 2001:db8::22 dst_ip 2001:db8::21 id 0 \
0484 action mirred egress redirect dev bareudp_ns2
0485 fi
0486
0487
0488 ping_test "UDPv6"
0489
0490 tc -netns "${NS1}" filter delete dev veth10 ingress
0491 tc -netns "${NS2}" filter delete dev veth23 ingress
0492 ip -netns "${NS1}" link delete bareudp_ns1
0493 ip -netns "${NS2}" link delete bareudp_ns2
0494 }
0495
0496 check_features()
0497 {
0498 ip link help 2>&1 | grep -q bareudp
0499 if [ $? -ne 0 ]; then
0500 echo "Missing bareudp support in iproute2" >&2
0501 exit_cleanup
0502 fi
0503
0504
0505 ping -w 1 -c 1 ::1 > /dev/null 2>&1 || PING6="ping6"
0506 }
0507
0508 usage()
0509 {
0510 echo "Usage: $0 [-p]"
0511 exit 1
0512 }
0513
0514 while getopts :p o
0515 do
0516 case $o in
0517 p) PAUSE_ON_FAIL="yes";;
0518 *) usage;;
0519 esac
0520 done
0521
0522 check_features
0523
0524
0525
0526
0527 create_namespaces
0528
0529 set -e
0530 trap exit_cleanup_all EXIT
0531
0532 setup_underlay
0533 setup_overlay_ipv4
0534 setup_overlay_ipv6
0535 setup_overlay_mpls
0536
0537 test_overlay ipv4 nomultiproto
0538 test_overlay ipv6 nomultiproto
0539 test_overlay ipv4 multiproto
0540 test_overlay mpls_uc nomultiproto
0541
0542 if [ "${ERR}" -eq 1 ]; then
0543 echo "Some tests failed." >&2
0544 else
0545 ERR=0
0546 fi