Commit 7b53682c authored by Stefano Brivio's avatar Stefano Brivio Committed by David S. Miller
Browse files

selftests: pmtu.sh: Add tests for UDP tunnels handled by Open vSwitch



The new tests check that IP and IPv6 packets exceeding the local PMTU
estimate, forwarded by an Open vSwitch instance from another node,
result in the correct route exceptions being created, and that
communication with end-to-end fragmentation, over GENEVE and VXLAN
Open vSwitch ports, is now possible as a result of PMTU discovery.

Signed-off-by: default avatarStefano Brivio <sbrivio@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent df40e39c
Loading
Loading
Loading
Loading
+180 −0
Original line number Diff line number Diff line
@@ -78,6 +78,26 @@
#	Same as pmtu_ipv{4,6}_br_vxlan{4,6}_exception, with a GENEVE tunnel
#	instead.
#
# - pmtu_ipv{4,6}_ovs_vxlan{4,6}_exception
#	Set up two namespaces, B, and C, with routing between the init namespace
#	and B over R1. A and R2 are unused in these tests. The init namespace
#	has a veth connection to C, and is connected to B via a VXLAN endpoint,
#	which is handled by Open vSwitch and bridged to C. MTU on the B-R1 link
#	is lower than other MTUs.
#
#	Check that C is able to communicate with B over the VXLAN tunnel, and
#	that PMTU exceptions with the correct values are created.
#
#	                  segment a_r1    segment b_r1            b_r1: 4000
#	                .--------------R1--------------.    everything
#	   C---veth    init                             B         else: 5000
#	        '- ovs                                  |
#	            '---- - - - - - VXLAN - - - - - - - '
#
# - pmtu_ipv{4,6}_ovs_geneve{4,6}_exception
#	Same as pmtu_ipv{4,6}_ovs_vxlan{4,6}_exception, with a GENEVE tunnel
#	instead.
#
# - pmtu_ipv{4,6}_fou{4,6}_exception
#	Same as pmtu_ipv4_vxlan4, but using a direct IPv4/IPv6 encapsulation
#	(FoU) over IPv4/IPv6, instead of VXLAN
@@ -174,6 +194,14 @@ tests="
	pmtu_ipv6_br_geneve4_exception	IPv6, bridged geneve4: PMTU exceptions	1
	pmtu_ipv4_br_geneve6_exception	IPv4, bridged geneve6: PMTU exceptions	1
	pmtu_ipv6_br_geneve6_exception	IPv6, bridged geneve6: PMTU exceptions	1
	pmtu_ipv4_ovs_vxlan4_exception	IPv4, OVS vxlan4: PMTU exceptions	1
	pmtu_ipv6_ovs_vxlan4_exception	IPv6, OVS vxlan4: PMTU exceptions	1
	pmtu_ipv4_ovs_vxlan6_exception	IPv4, OVS vxlan6: PMTU exceptions	1
	pmtu_ipv6_ovs_vxlan6_exception	IPv6, OVS vxlan6: PMTU exceptions	1
	pmtu_ipv4_ovs_geneve4_exception	IPv4, OVS geneve4: PMTU exceptions	1
	pmtu_ipv6_ovs_geneve4_exception	IPv6, OVS geneve4: PMTU exceptions	1
	pmtu_ipv4_ovs_geneve6_exception	IPv4, OVS geneve6: PMTU exceptions	1
	pmtu_ipv6_ovs_geneve6_exception	IPv6, OVS geneve6: PMTU exceptions	1
	pmtu_ipv4_fou4_exception	IPv4 over fou4: PMTU exceptions		1
	pmtu_ipv6_fou4_exception	IPv6 over fou4: PMTU exceptions		1
	pmtu_ipv4_fou6_exception	IPv4 over fou6: PMTU exceptions		1
@@ -698,6 +726,66 @@ setup_bridge() {
	run_cmd ${ns_a} ip link set veth_A-C master br0
}

setup_ovs_vxlan_or_geneve() {
	type="${1}"
	a_addr="${2}"
	b_addr="${3}"

	if [ "${type}" = "vxlan" ]; then
		opts="${opts} ttl 64 dstport 4789"
		opts_b="local ${b_addr}"
	fi

	run_cmd ovs-vsctl add-port ovs_br0 ${type}_a -- \
		set interface ${type}_a type=${type} \
		options:remote_ip=${b_addr} options:key=1 options:csum=true || return 1

	run_cmd ${ns_b} ip link add ${type}_b type ${type} id 1 ${opts_b} remote ${a_addr} ${opts} || return 1

	run_cmd ${ns_b} ip addr add ${tunnel4_b_addr}/${tunnel4_mask} dev ${type}_b
	run_cmd ${ns_b} ip addr add ${tunnel6_b_addr}/${tunnel6_mask} dev ${type}_b

	run_cmd ${ns_b} ip link set ${type}_b up
}

setup_ovs_geneve4() {
	setup_ovs_vxlan_or_geneve geneve ${prefix4}.${a_r1}.1  ${prefix4}.${b_r1}.1
}

setup_ovs_vxlan4() {
	setup_ovs_vxlan_or_geneve vxlan  ${prefix4}.${a_r1}.1  ${prefix4}.${b_r1}.1
}

setup_ovs_geneve6() {
	setup_ovs_vxlan_or_geneve geneve ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1
}

setup_ovs_vxlan6() {
	setup_ovs_vxlan_or_geneve vxlan  ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1
}

setup_ovs_bridge() {
	run_cmd ovs-vsctl add-br ovs_br0 || return 2
	run_cmd ip link set ovs_br0 up

	run_cmd ${ns_c} ip link add veth_C-A type veth peer name veth_A-C
	run_cmd ${ns_c} ip link set veth_A-C netns 1

	run_cmd         ip link set veth_A-C up
	run_cmd ${ns_c} ip link set veth_C-A up
	run_cmd ${ns_c} ip addr add ${veth4_c_addr}/${veth4_mask} dev veth_C-A
	run_cmd ${ns_c} ip addr add ${veth6_c_addr}/${veth6_mask} dev veth_C-A
	run_cmd ovs-vsctl add-port ovs_br0 veth_A-C

	# Move veth_A-R1 to init
	run_cmd ${ns_a} ip link set veth_A-R1 netns 1
	run_cmd ip addr add ${prefix4}.${a_r1}.1/${veth4_mask} dev veth_A-R1
	run_cmd ip addr add ${prefix6}:${a_r1}::1/${veth6_mask} dev veth_A-R1
	run_cmd ip link set veth_A-R1 up
	run_cmd ip route add ${prefix4}.${b_r1}.1 via ${prefix4}.${a_r1}.2
	run_cmd ip route add ${prefix6}:${b_r1}::1 via ${prefix6}:${a_r1}::2
}

setup() {
	[ "$(id -u)" -ne 0 ] && echo "  need to run as root" && return $ksft_skip

@@ -728,6 +816,11 @@ cleanup() {
	for n in ${NS_A} ${NS_B} ${NS_C} ${NS_R1} ${NS_R2}; do
		ip netns del ${n} 2> /dev/null
	done

	ip link del veth_A-C			2>/dev/null
	ip link del veth_A-R1			2>/dev/null
	ovs-vsctl --if-exists del-port vxlan_a	2>/dev/null
	ovs-vsctl --if-exists del-br ovs_br0	2>/dev/null
}

mtu() {
@@ -1044,6 +1137,93 @@ test_pmtu_ipv6_br_geneve6_exception() {
	test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception geneve 6 6
}

test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception() {
	type=${1}
	family=${2}
	outer_family=${3}
	ll_mtu=4000

	if [ ${outer_family} -eq 4 ]; then
		setup namespaces routing ovs_bridge ovs_${type}4 || return 2
		#                      IPv4 header   UDP header   VXLAN/GENEVE header   Ethernet header
		exp_mtu=$((${ll_mtu} - 20          - 8          - 8                   - 14))
	else
		setup namespaces routing ovs_bridge ovs_${type}6 || return 2
		#                      IPv6 header   UDP header   VXLAN/GENEVE header   Ethernet header
		exp_mtu=$((${ll_mtu} - 40          - 8          - 8                   - 14))
	fi

	if [ "${type}" = "vxlan" ]; then
		tun_a="vxlan_sys_4789"
	elif [ "${type}" = "geneve" ]; then
		tun_a="genev_sys_6081"
	fi

	trace ""        "${tun_a}"  "${ns_b}"  ${type}_b \
	      ""        veth_A-R1   "${ns_r1}" veth_R1-A \
	      "${ns_b}" veth_B-R1   "${ns_r1}" veth_R1-B \
	      ""        ovs_br0     ""         veth-A-C  \
	      "${ns_c}" veth_C-A

	if [ ${family} -eq 4 ]; then
		ping=ping
		dst=${tunnel4_b_addr}
	else
		ping=${ping6}
		dst=${tunnel6_b_addr}
	fi

	# Create route exception by exceeding link layer MTU
	mtu ""         veth_A-R1 $((${ll_mtu} + 1000))
	mtu ""         ovs_br0   $((${ll_mtu} + 1000))
	mtu ""         veth_A-C  $((${ll_mtu} + 1000))
	mtu "${ns_c}"  veth_C-A  $((${ll_mtu} + 1000))
	mtu "${ns_r1}" veth_R1-A $((${ll_mtu} + 1000))
	mtu "${ns_b}"  veth_B-R1 ${ll_mtu}
	mtu "${ns_r1}" veth_R1-B ${ll_mtu}

	mtu ""        ${tun_a}  $((${ll_mtu} + 1000))
	mtu "${ns_b}" ${type}_b $((${ll_mtu} + 1000))

	run_cmd ${ns_c} ${ping} -q -M want -i 0.1 -c 20 -s $((${ll_mtu} + 500)) ${dst} || return 1

	# Check that exceptions were created
	pmtu="$(route_get_dst_pmtu_from_exception "${ns_c}" ${dst})"
	check_pmtu_value ${exp_mtu} "${pmtu}" "exceeding link layer MTU on Open vSwitch ${type} interface"
}

test_pmtu_ipv4_ovs_vxlan4_exception() {
	test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception vxlan  4 4
}

test_pmtu_ipv6_ovs_vxlan4_exception() {
	test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception vxlan  6 4
}

test_pmtu_ipv4_ovs_geneve4_exception() {
	test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception geneve 4 4
}

test_pmtu_ipv6_ovs_geneve4_exception() {
	test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception geneve 6 4
}

test_pmtu_ipv4_ovs_vxlan6_exception() {
	test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception vxlan  4 6
}

test_pmtu_ipv6_ovs_vxlan6_exception() {
	test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception vxlan  6 6
}

test_pmtu_ipv4_ovs_geneve6_exception() {
	test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception geneve 4 6
}

test_pmtu_ipv6_ovs_geneve6_exception() {
	test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception geneve 6 6
}

test_pmtu_ipvX_over_fouY_or_gueY() {
	inner_family=${1}
	outer_family=${2}