1e2b447c9SSimon Horman#!/bin/bash
225f16c87SAaron Conole# SPDX-License-Identifier: GPL-2.0
325f16c87SAaron Conole#
425f16c87SAaron Conole# OVS kernel module self tests
525f16c87SAaron Conole
6af846afaSAaron Conoletrap ovs_exit_sig EXIT TERM INT ERR
7af846afaSAaron Conole
825f16c87SAaron Conole# Kselftest framework requirement - SKIP code is 4.
925f16c87SAaron Conoleksft_skip=4
1025f16c87SAaron Conole
1125f16c87SAaron ConolePAUSE_ON_FAIL=no
1225f16c87SAaron ConoleVERBOSE=0
1325f16c87SAaron ConoleTRACING=0
145e724cb6SAdrian MorenoWAIT_TIMEOUT=5
155e724cb6SAdrian Moreno
165e724cb6SAdrian Morenoif test "X$KSFT_MACHINE_SLOW" == "Xyes"; then
175e724cb6SAdrian Moreno	WAIT_TIMEOUT=10
185e724cb6SAdrian Morenofi
1925f16c87SAaron Conole
2025f16c87SAaron Conoletests="
21918423fdSAaron Conole	arp_ping				eth-arp: Basic arp ping between two NS
222893ba9cSAaron Conole	ct_connect_v4				ip4-ct-xon: Basic ipv4 tcp connection using ct
2305398aa4SAaron Conole	connect_v4				ip4-xon: Basic ipv4 ping between two NS
2460f10077SAaron Conole	nat_connect_v4				ip4-nat-xon: Basic ipv4 tcp connection via NAT
25094bdd48SBrad Cowie	nat_related_v4				ip4-nat-related: ICMP related matches work with SNAT
269feac87bSAaron Conole	netlink_checks				ovsnl: validate netlink attrs and settings
27aab1272fSAdrian Moreno	upcall_interfaces			ovs: test the upcall interfaces
2830d772a0SAdrian Moreno	drop_reason				drop: test drop reasons are emitted
2930d772a0SAdrian Moreno	psample					psample: Sampling packets with psample"
3025f16c87SAaron Conole
3125f16c87SAaron Conoleinfo() {
327abfd8ecSAaron Conole	[ "${ovs_dir}" != "" ] &&
337abfd8ecSAaron Conole		echo "`date +"[%m-%d %H:%M:%S]"` $*" >> ${ovs_dir}/debug.log
3425f16c87SAaron Conole	[ $VERBOSE = 0 ] || echo $*
3525f16c87SAaron Conole}
3625f16c87SAaron Conole
375e724cb6SAdrian Morenoovs_wait() {
385e724cb6SAdrian Moreno	info "waiting $WAIT_TIMEOUT s for: $@"
395e724cb6SAdrian Moreno
405e724cb6SAdrian Moreno	if "$@" ; then
415e724cb6SAdrian Moreno		info "wait succeeded immediately"
425e724cb6SAdrian Moreno		return 0
435e724cb6SAdrian Moreno	fi
445e724cb6SAdrian Moreno
455e724cb6SAdrian Moreno	# A quick re-check helps speed up small races in fast systems.
465e724cb6SAdrian Moreno	# However, fractional sleeps might not necessarily work.
475e724cb6SAdrian Moreno	local start=0
485e724cb6SAdrian Moreno	sleep 0.1 || { sleep 1; start=1; }
495e724cb6SAdrian Moreno
505e724cb6SAdrian Moreno	for (( i=start; i<WAIT_TIMEOUT; i++ )); do
515e724cb6SAdrian Moreno		if "$@" ; then
525e724cb6SAdrian Moreno			info "wait succeeded after $i seconds"
535e724cb6SAdrian Moreno			return 0
545e724cb6SAdrian Moreno		fi
555e724cb6SAdrian Moreno		sleep 1
565e724cb6SAdrian Moreno	done
575e724cb6SAdrian Moreno	info "wait failed after $i seconds"
585e724cb6SAdrian Moreno	return 1
595e724cb6SAdrian Moreno}
605e724cb6SAdrian Moreno
6125f16c87SAaron Conoleovs_base=`pwd`
6225f16c87SAaron Conolesbxs=
6325f16c87SAaron Conolesbx_add () {
6425f16c87SAaron Conole	info "adding sandbox '$1'"
6525f16c87SAaron Conole
6625f16c87SAaron Conole	sbxs="$sbxs $1"
6725f16c87SAaron Conole
6825f16c87SAaron Conole	NO_BIN=0
6925f16c87SAaron Conole
7025f16c87SAaron Conole	# Create sandbox.
7125f16c87SAaron Conole	local d="$ovs_base"/$1
7225f16c87SAaron Conole	if [ -e $d ]; then
7325f16c87SAaron Conole		info "removing $d"
7425f16c87SAaron Conole		rm -rf "$d"
7525f16c87SAaron Conole	fi
7625f16c87SAaron Conole	mkdir "$d" || return 1
7725f16c87SAaron Conole	ovs_setenv $1
7825f16c87SAaron Conole}
7925f16c87SAaron Conole
8025f16c87SAaron Conoleovs_exit_sig() {
8125f16c87SAaron Conole	[ -e ${ovs_dir}/cleanup ] && . "$ovs_dir/cleanup"
8225f16c87SAaron Conole}
8325f16c87SAaron Conole
8425f16c87SAaron Conoleon_exit() {
8525f16c87SAaron Conole	echo "$1" > ${ovs_dir}/cleanup.tmp
8625f16c87SAaron Conole	cat ${ovs_dir}/cleanup >> ${ovs_dir}/cleanup.tmp
8725f16c87SAaron Conole	mv ${ovs_dir}/cleanup.tmp ${ovs_dir}/cleanup
8825f16c87SAaron Conole}
8925f16c87SAaron Conole
9025f16c87SAaron Conoleovs_setenv() {
9125f16c87SAaron Conole	sandbox=$1
9225f16c87SAaron Conole
9325f16c87SAaron Conole	ovs_dir=$ovs_base${1:+/$1}; export ovs_dir
9425f16c87SAaron Conole
9525f16c87SAaron Conole	test -e ${ovs_dir}/cleanup || : > ${ovs_dir}/cleanup
9625f16c87SAaron Conole}
9725f16c87SAaron Conole
9825f16c87SAaron Conoleovs_sbx() {
9925f16c87SAaron Conole	if test "X$2" != X; then
1007abfd8ecSAaron Conole		(ovs_setenv $1; shift;
1017abfd8ecSAaron Conole		 info "run cmd: $@"; "$@" >> ${ovs_dir}/debug.log)
10225f16c87SAaron Conole	else
10325f16c87SAaron Conole		ovs_setenv $1
10425f16c87SAaron Conole	fi
10525f16c87SAaron Conole}
10625f16c87SAaron Conole
10725f16c87SAaron Conoleovs_add_dp () {
10825f16c87SAaron Conole	info "Adding DP/Bridge IF: sbx:$1 dp:$2 {$3, $4, $5}"
10925f16c87SAaron Conole	sbxname="$1"
11025f16c87SAaron Conole	shift
11125f16c87SAaron Conole	ovs_sbx "$sbxname" python3 $ovs_base/ovs-dpctl.py add-dp $*
11225f16c87SAaron Conole	on_exit "ovs_sbx $sbxname python3 $ovs_base/ovs-dpctl.py del-dp $1;"
11325f16c87SAaron Conole}
11425f16c87SAaron Conole
11574cc26f4SAaron Conoleovs_add_if () {
11674cc26f4SAaron Conole	info "Adding IF to DP: br:$2 if:$3"
1179feac87bSAaron Conole	if [ "$4" != "-u" ]; then
1189feac87bSAaron Conole		ovs_sbx "$1" python3 $ovs_base/ovs-dpctl.py add-if "$2" "$3" \
1199feac87bSAaron Conole		    || return 1
1209feac87bSAaron Conole	else
1219feac87bSAaron Conole		python3 $ovs_base/ovs-dpctl.py add-if \
1229feac87bSAaron Conole		    -u "$2" "$3" >$ovs_dir/$3.out 2>$ovs_dir/$3.err &
1239feac87bSAaron Conole		pid=$!
1249feac87bSAaron Conole		on_exit "ovs_sbx $1 kill -TERM $pid 2>/dev/null"
1259feac87bSAaron Conole	fi
12674cc26f4SAaron Conole}
12774cc26f4SAaron Conole
12874cc26f4SAaron Conoleovs_del_if () {
12974cc26f4SAaron Conole	info "Deleting IF from DP: br:$2 if:$3"
13074cc26f4SAaron Conole	ovs_sbx "$1" python3 $ovs_base/ovs-dpctl.py del-if "$2" "$3" || return 1
13174cc26f4SAaron Conole}
13274cc26f4SAaron Conole
13374cc26f4SAaron Conoleovs_netns_spawn_daemon() {
13474cc26f4SAaron Conole	sbx=$1
13574cc26f4SAaron Conole	shift
13674cc26f4SAaron Conole	netns=$1
13774cc26f4SAaron Conole	shift
13830d772a0SAdrian Moreno	if [ "$netns" == "_default" ]; then
13930d772a0SAdrian Moreno		$*  >> $ovs_dir/stdout  2>> $ovs_dir/stderr &
14030d772a0SAdrian Moreno	else
14174cc26f4SAaron Conole		ip netns exec $netns $*  >> $ovs_dir/stdout  2>> $ovs_dir/stderr &
14230d772a0SAdrian Moreno	fi
14374cc26f4SAaron Conole	pid=$!
14474cc26f4SAaron Conole	ovs_sbx "$sbx" on_exit "kill -TERM $pid 2>/dev/null"
14574cc26f4SAaron Conole}
14674cc26f4SAaron Conole
14730d772a0SAdrian Morenoovs_spawn_daemon() {
14830d772a0SAdrian Moreno	sbx=$1
14930d772a0SAdrian Moreno	shift
15030d772a0SAdrian Moreno	ovs_netns_spawn_daemon $sbx "_default" $*
15130d772a0SAdrian Moreno}
15230d772a0SAdrian Moreno
15374cc26f4SAaron Conoleovs_add_netns_and_veths () {
15474cc26f4SAaron Conole	info "Adding netns attached: sbx:$1 dp:$2 {$3, $4, $5}"
15574cc26f4SAaron Conole	ovs_sbx "$1" ip netns add "$3" || return 1
15674cc26f4SAaron Conole	on_exit "ovs_sbx $1 ip netns del $3"
15774cc26f4SAaron Conole	ovs_sbx "$1" ip link add "$4" type veth peer name "$5" || return 1
15874cc26f4SAaron Conole	on_exit "ovs_sbx $1 ip link del $4 >/dev/null 2>&1"
15974cc26f4SAaron Conole	ovs_sbx "$1" ip link set "$4" up || return 1
16074cc26f4SAaron Conole	ovs_sbx "$1" ip link set "$5" netns "$3" || return 1
16174cc26f4SAaron Conole	ovs_sbx "$1" ip netns exec "$3" ip link set "$5" up || return 1
16274cc26f4SAaron Conole
16374cc26f4SAaron Conole	if [ "$6" != "" ]; then
16474cc26f4SAaron Conole		ovs_sbx "$1" ip netns exec "$3" ip addr add "$6" dev "$5" \
16574cc26f4SAaron Conole		    || return 1
16674cc26f4SAaron Conole	fi
16774cc26f4SAaron Conole
1689feac87bSAaron Conole	if [ "$7" != "-u" ]; then
16974cc26f4SAaron Conole		ovs_add_if "$1" "$2" "$4" || return 1
1709feac87bSAaron Conole	else
1719feac87bSAaron Conole		ovs_add_if "$1" "$2" "$4" -u || return 1
1729feac87bSAaron Conole	fi
1739feac87bSAaron Conole
174a1797599SAdrian Moreno	if [ $TRACING -eq 1 ]; then
175a1797599SAdrian Moreno		ovs_netns_spawn_daemon "$1" "$3" tcpdump -l -i any -s 6553
176a1797599SAdrian Moreno		ovs_wait grep -q "listening on any" ${ovs_dir}/stderr
177a1797599SAdrian Moreno	fi
17874cc26f4SAaron Conole
17974cc26f4SAaron Conole	return 0
18074cc26f4SAaron Conole}
18174cc26f4SAaron Conole
182918423fdSAaron Conoleovs_add_flow () {
183918423fdSAaron Conole	info "Adding flow to DP: sbx:$1 br:$2 flow:$3 act:$4"
184918423fdSAaron Conole	ovs_sbx "$1" python3 $ovs_base/ovs-dpctl.py add-flow "$2" "$3" "$4"
185918423fdSAaron Conole	if [ $? -ne 0 ]; then
1867abfd8ecSAaron Conole		info "Flow [ $3 : $4 ] failed"
187918423fdSAaron Conole		return 1
188918423fdSAaron Conole	fi
189918423fdSAaron Conole	return 0
190918423fdSAaron Conole}
191918423fdSAaron Conole
19276035fd1SAaron Conoleovs_del_flows () {
19376035fd1SAaron Conole	info "Deleting all flows from DP: sbx:$1 br:$2"
19476035fd1SAaron Conole	ovs_sbx "$1" python3 $ovs_base/ovs-dpctl.py del-flows "$2"
19576035fd1SAaron Conole	return 0
19676035fd1SAaron Conole}
19776035fd1SAaron Conole
198aab1272fSAdrian Morenoovs_drop_record_and_run () {
199aab1272fSAdrian Moreno	local sbx=$1
200aab1272fSAdrian Moreno	shift
201aab1272fSAdrian Moreno
202aab1272fSAdrian Moreno	perf record -a -q -e skb:kfree_skb -o ${ovs_dir}/perf.data $* \
203aab1272fSAdrian Moreno		>> ${ovs_dir}/stdout 2>> ${ovs_dir}/stderr
204aab1272fSAdrian Moreno	return $?
205aab1272fSAdrian Moreno}
206aab1272fSAdrian Moreno
207aab1272fSAdrian Morenoovs_drop_reason_count()
208aab1272fSAdrian Moreno{
209aab1272fSAdrian Moreno	local reason=$1
210aab1272fSAdrian Moreno
211aab1272fSAdrian Moreno	local perf_output=`perf script -i ${ovs_dir}/perf.data -F trace:event,trace`
212aab1272fSAdrian Moreno	local pattern="skb:kfree_skb:.*reason: $reason"
213aab1272fSAdrian Moreno
214aab1272fSAdrian Moreno	return `echo "$perf_output" | grep "$pattern" | wc -l`
215aab1272fSAdrian Moreno}
216aab1272fSAdrian Moreno
21730d772a0SAdrian Morenoovs_test_flow_fails () {
21830d772a0SAdrian Moreno	ERR_MSG="Flow actions may not be safe on all matching packets"
21930d772a0SAdrian Moreno
22030d772a0SAdrian Moreno	PRE_TEST=$(dmesg | grep -c "${ERR_MSG}")
22130d772a0SAdrian Moreno	ovs_add_flow $@ &> /dev/null $@ && return 1
22230d772a0SAdrian Moreno	POST_TEST=$(dmesg | grep -c "${ERR_MSG}")
22330d772a0SAdrian Moreno
22430d772a0SAdrian Moreno	if [ "$PRE_TEST" == "$POST_TEST" ]; then
22530d772a0SAdrian Moreno		return 1
22630d772a0SAdrian Moreno	fi
22730d772a0SAdrian Moreno	return 0
22830d772a0SAdrian Moreno}
22930d772a0SAdrian Moreno
23025f16c87SAaron Conoleusage() {
23125f16c87SAaron Conole	echo
23225f16c87SAaron Conole	echo "$0 [OPTIONS] [TEST]..."
23325f16c87SAaron Conole	echo "If no TEST argument is given, all tests will be run."
23425f16c87SAaron Conole	echo
23525f16c87SAaron Conole	echo "Options"
23625f16c87SAaron Conole	echo "  -t: capture traffic via tcpdump"
23725f16c87SAaron Conole	echo "  -v: verbose"
23825f16c87SAaron Conole	echo "  -p: pause on failure"
23925f16c87SAaron Conole	echo
24025f16c87SAaron Conole	echo "Available tests${tests}"
24125f16c87SAaron Conole	exit 1
24225f16c87SAaron Conole}
24325f16c87SAaron Conole
24430d772a0SAdrian Moreno
24530d772a0SAdrian Moreno# psample test
24630d772a0SAdrian Moreno# - use psample to observe packets
24730d772a0SAdrian Morenotest_psample() {
24830d772a0SAdrian Moreno	sbx_add "test_psample" || return $?
24930d772a0SAdrian Moreno
25030d772a0SAdrian Moreno	# Add a datapath with per-vport dispatching.
25130d772a0SAdrian Moreno	ovs_add_dp "test_psample" psample -V 2:1 || return 1
25230d772a0SAdrian Moreno
25330d772a0SAdrian Moreno	info "create namespaces"
25430d772a0SAdrian Moreno	ovs_add_netns_and_veths "test_psample" "psample" \
25530d772a0SAdrian Moreno		client c0 c1 172.31.110.10/24 -u || return 1
25630d772a0SAdrian Moreno	ovs_add_netns_and_veths "test_psample" "psample" \
25730d772a0SAdrian Moreno		server s0 s1 172.31.110.20/24 -u || return 1
25830d772a0SAdrian Moreno
25930d772a0SAdrian Moreno	# Check if psample actions can be configured.
26030d772a0SAdrian Moreno	ovs_add_flow "test_psample" psample \
26130d772a0SAdrian Moreno	'in_port(1),eth(),eth_type(0x0806),arp()' 'psample(group=1)' &> /dev/null
26230d772a0SAdrian Moreno	if [ $? == 1 ]; then
26330d772a0SAdrian Moreno		info "no support for psample - skipping"
26430d772a0SAdrian Moreno		ovs_exit_sig
26530d772a0SAdrian Moreno		return $ksft_skip
26630d772a0SAdrian Moreno	fi
26730d772a0SAdrian Moreno
26830d772a0SAdrian Moreno	ovs_del_flows "test_psample" psample
26930d772a0SAdrian Moreno
27030d772a0SAdrian Moreno	# Test action verification.
27130d772a0SAdrian Moreno	OLDIFS=$IFS
27230d772a0SAdrian Moreno	IFS='*'
27330d772a0SAdrian Moreno	min_key='in_port(1),eth(),eth_type(0x0800),ipv4()'
27430d772a0SAdrian Moreno	for testcase in \
27530d772a0SAdrian Moreno		"cookie to large"*"psample(group=1,cookie=1615141312111009080706050403020100)" \
27630d772a0SAdrian Moreno		"no group with cookie"*"psample(cookie=abcd)" \
27730d772a0SAdrian Moreno		"no group"*"psample()";
27830d772a0SAdrian Moreno	do
27930d772a0SAdrian Moreno		set -- $testcase;
28030d772a0SAdrian Moreno		ovs_test_flow_fails "test_psample" psample $min_key $2
28130d772a0SAdrian Moreno		if [ $? == 1 ]; then
28230d772a0SAdrian Moreno			info "failed - $1"
28330d772a0SAdrian Moreno			return 1
28430d772a0SAdrian Moreno		fi
28530d772a0SAdrian Moreno	done
28630d772a0SAdrian Moreno	IFS=$OLDIFS
28730d772a0SAdrian Moreno
28830d772a0SAdrian Moreno	ovs_del_flows "test_psample" psample
28930d772a0SAdrian Moreno	# Allow ARP
29030d772a0SAdrian Moreno	ovs_add_flow "test_psample" psample \
29130d772a0SAdrian Moreno		'in_port(1),eth(),eth_type(0x0806),arp()' '2' || return 1
29230d772a0SAdrian Moreno	ovs_add_flow "test_psample" psample \
29330d772a0SAdrian Moreno		'in_port(2),eth(),eth_type(0x0806),arp()' '1' || return 1
29430d772a0SAdrian Moreno
29530d772a0SAdrian Moreno	# Sample first 14 bytes of all traffic.
29630d772a0SAdrian Moreno	ovs_add_flow "test_psample" psample \
29730d772a0SAdrian Moreno	    "in_port(1),eth(),eth_type(0x0800),ipv4()" \
29830d772a0SAdrian Moreno            "trunc(14),psample(group=1,cookie=c0ffee),2"
29930d772a0SAdrian Moreno
30030d772a0SAdrian Moreno	# Sample all traffic. In this case, use a sample() action with both
30130d772a0SAdrian Moreno	# psample and an upcall emulating simultaneous local sampling and
30230d772a0SAdrian Moreno	# sFlow / IPFIX.
30330d772a0SAdrian Moreno	nlpid=$(grep -E "listening on upcall packet handler" \
30430d772a0SAdrian Moreno            $ovs_dir/s0.out | cut -d ":" -f 2 | tr -d ' ')
30530d772a0SAdrian Moreno
30630d772a0SAdrian Moreno	ovs_add_flow "test_psample" psample \
30730d772a0SAdrian Moreno            "in_port(2),eth(),eth_type(0x0800),ipv4()" \
30830d772a0SAdrian Moreno            "sample(sample=100%,actions(psample(group=2,cookie=eeff0c),userspace(pid=${nlpid},userdata=eeff0c))),1"
30930d772a0SAdrian Moreno
31030d772a0SAdrian Moreno	# Record psample data.
31130d772a0SAdrian Moreno	ovs_spawn_daemon "test_psample" python3 $ovs_base/ovs-dpctl.py psample-events
3125e724cb6SAdrian Moreno	ovs_wait grep -q "listening for psample events" ${ovs_dir}/stdout
31330d772a0SAdrian Moreno
31430d772a0SAdrian Moreno	# Send a single ping.
31530d772a0SAdrian Moreno	ovs_sbx "test_psample" ip netns exec client ping -I c1 172.31.110.20 -c 1 || return 1
31630d772a0SAdrian Moreno
31730d772a0SAdrian Moreno	# We should have received one userspace action upcall and 2 psample packets.
3185e724cb6SAdrian Moreno	ovs_wait grep -q "userspace action command" $ovs_dir/s0.out || return 1
31930d772a0SAdrian Moreno
32030d772a0SAdrian Moreno	# client -> server samples should only contain the first 14 bytes of the packet.
3215e724cb6SAdrian Moreno	ovs_wait grep -qE "rate:4294967295,group:1,cookie:c0ffee data:[0-9a-f]{28}$" \
3225e724cb6SAdrian Moreno		$ovs_dir/stdout || return 1
3235e724cb6SAdrian Moreno
3245e724cb6SAdrian Moreno	ovs_wait grep -q "rate:4294967295,group:2,cookie:eeff0c" $ovs_dir/stdout || return 1
32530d772a0SAdrian Moreno
32630d772a0SAdrian Moreno	return 0
32730d772a0SAdrian Moreno}
32830d772a0SAdrian Moreno
329aab1272fSAdrian Moreno# drop_reason test
330aab1272fSAdrian Moreno# - drop packets and verify the right drop reason is reported
331aab1272fSAdrian Morenotest_drop_reason() {
332aab1272fSAdrian Moreno	which perf >/dev/null 2>&1 || return $ksft_skip
333*1cc34621SJakub Kicinski	which pahole >/dev/null 2>&1 || return $ksft_skip
334*1cc34621SJakub Kicinski
335*1cc34621SJakub Kicinski	ovs_drop_subsys=$(pahole -C skb_drop_reason_subsys |
336*1cc34621SJakub Kicinski			      awk '/OPENVSWITCH/ { print $3; }' |
337*1cc34621SJakub Kicinski			      tr -d ,)
338aab1272fSAdrian Moreno
339aab1272fSAdrian Moreno	sbx_add "test_drop_reason" || return $?
340aab1272fSAdrian Moreno
341aab1272fSAdrian Moreno	ovs_add_dp "test_drop_reason" dropreason || return 1
342aab1272fSAdrian Moreno
343aab1272fSAdrian Moreno	info "create namespaces"
344aab1272fSAdrian Moreno	for ns in client server; do
345aab1272fSAdrian Moreno		ovs_add_netns_and_veths "test_drop_reason" "dropreason" "$ns" \
346aab1272fSAdrian Moreno			"${ns:0:1}0" "${ns:0:1}1" || return 1
347aab1272fSAdrian Moreno	done
348aab1272fSAdrian Moreno
349aab1272fSAdrian Moreno	# Setup client namespace
350aab1272fSAdrian Moreno	ip netns exec client ip addr add 172.31.110.10/24 dev c1
351aab1272fSAdrian Moreno	ip netns exec client ip link set c1 up
352aab1272fSAdrian Moreno
353aab1272fSAdrian Moreno	# Setup server namespace
354aab1272fSAdrian Moreno	ip netns exec server ip addr add 172.31.110.20/24 dev s1
355aab1272fSAdrian Moreno	ip netns exec server ip link set s1 up
356aab1272fSAdrian Moreno
35776035fd1SAaron Conole	# Check if drop reasons can be sent
35876035fd1SAaron Conole	ovs_add_flow "test_drop_reason" dropreason \
35976035fd1SAaron Conole		'in_port(1),eth(),eth_type(0x0806),arp()' 'drop(10)' 2>/dev/null
36076035fd1SAaron Conole	if [ $? == 1 ]; then
36176035fd1SAaron Conole		info "no support for drop reasons - skipping"
36276035fd1SAaron Conole		ovs_exit_sig
36376035fd1SAaron Conole		return $ksft_skip
36476035fd1SAaron Conole	fi
36576035fd1SAaron Conole
36676035fd1SAaron Conole	ovs_del_flows "test_drop_reason" dropreason
36776035fd1SAaron Conole
368aab1272fSAdrian Moreno	# Allow ARP
369aab1272fSAdrian Moreno	ovs_add_flow "test_drop_reason" dropreason \
370aab1272fSAdrian Moreno		'in_port(1),eth(),eth_type(0x0806),arp()' '2' || return 1
371aab1272fSAdrian Moreno	ovs_add_flow "test_drop_reason" dropreason \
372aab1272fSAdrian Moreno		'in_port(2),eth(),eth_type(0x0806),arp()' '1' || return 1
373aab1272fSAdrian Moreno
374aab1272fSAdrian Moreno	# Allow client ICMP traffic but drop return path
375aab1272fSAdrian Moreno	ovs_add_flow "test_drop_reason" dropreason \
376aab1272fSAdrian Moreno		"in_port(1),eth(),eth_type(0x0800),ipv4(src=172.31.110.10,proto=1),icmp()" '2'
377aab1272fSAdrian Moreno	ovs_add_flow "test_drop_reason" dropreason \
378aab1272fSAdrian Moreno		"in_port(2),eth(),eth_type(0x0800),ipv4(src=172.31.110.20,proto=1),icmp()" 'drop'
379aab1272fSAdrian Moreno
380aab1272fSAdrian Moreno	ovs_drop_record_and_run "test_drop_reason" ip netns exec client ping -c 2 172.31.110.20
381*1cc34621SJakub Kicinski	ovs_drop_reason_count 0x${ovs_drop_subsys}0001 # OVS_DROP_FLOW_ACTION
382aab1272fSAdrian Moreno	if [[ "$?" -ne "2" ]]; then
383aab1272fSAdrian Moreno		info "Did not detect expected drops: $?"
384aab1272fSAdrian Moreno		return 1
385aab1272fSAdrian Moreno	fi
386aab1272fSAdrian Moreno
38742420291SAdrian Moreno	# Drop UDP 6000 traffic with an explicit action and an error code.
38842420291SAdrian Moreno	ovs_add_flow "test_drop_reason" dropreason \
38942420291SAdrian Moreno		"in_port(1),eth(),eth_type(0x0800),ipv4(src=172.31.110.10,proto=17),udp(dst=6000)" \
39042420291SAdrian Moreno                'drop(42)'
39142420291SAdrian Moreno	# Drop UDP 7000 traffic with an explicit action with no error code.
39242420291SAdrian Moreno	ovs_add_flow "test_drop_reason" dropreason \
39342420291SAdrian Moreno		"in_port(1),eth(),eth_type(0x0800),ipv4(src=172.31.110.10,proto=17),udp(dst=7000)" \
39442420291SAdrian Moreno                'drop(0)'
39542420291SAdrian Moreno
39642420291SAdrian Moreno	ovs_drop_record_and_run \
39742420291SAdrian Moreno            "test_drop_reason" ip netns exec client nc -i 1 -zuv 172.31.110.20 6000
398*1cc34621SJakub Kicinski	ovs_drop_reason_count 0x${ovs_drop_subsys}0004 # OVS_DROP_EXPLICIT_ACTION_ERROR
39942420291SAdrian Moreno	if [[ "$?" -ne "1" ]]; then
40042420291SAdrian Moreno		info "Did not detect expected explicit error drops: $?"
40142420291SAdrian Moreno		return 1
40242420291SAdrian Moreno	fi
40342420291SAdrian Moreno
40442420291SAdrian Moreno	ovs_drop_record_and_run \
40542420291SAdrian Moreno            "test_drop_reason" ip netns exec client nc -i 1 -zuv 172.31.110.20 7000
406*1cc34621SJakub Kicinski	ovs_drop_reason_count 0x${ovs_drop_subsys}0003 # OVS_DROP_EXPLICIT_ACTION
40742420291SAdrian Moreno	if [[ "$?" -ne "1" ]]; then
40842420291SAdrian Moreno		info "Did not detect expected explicit drops: $?"
40942420291SAdrian Moreno		return 1
41042420291SAdrian Moreno	fi
41142420291SAdrian Moreno
412aab1272fSAdrian Moreno	return 0
413aab1272fSAdrian Moreno}
414aab1272fSAdrian Moreno
415918423fdSAaron Conole# arp_ping test
416918423fdSAaron Conole# - client has 1500 byte MTU
417918423fdSAaron Conole# - server has 1500 byte MTU
418918423fdSAaron Conole# - send ARP ping between two ns
419918423fdSAaron Conoletest_arp_ping () {
420918423fdSAaron Conole
421918423fdSAaron Conole	which arping >/dev/null 2>&1 || return $ksft_skip
422918423fdSAaron Conole
423918423fdSAaron Conole	sbx_add "test_arp_ping" || return $?
424918423fdSAaron Conole
425918423fdSAaron Conole	ovs_add_dp "test_arp_ping" arpping || return 1
426918423fdSAaron Conole
427918423fdSAaron Conole	info "create namespaces"
428918423fdSAaron Conole	for ns in client server; do
429918423fdSAaron Conole		ovs_add_netns_and_veths "test_arp_ping" "arpping" "$ns" \
430918423fdSAaron Conole		    "${ns:0:1}0" "${ns:0:1}1" || return 1
431918423fdSAaron Conole	done
432918423fdSAaron Conole
433918423fdSAaron Conole	# Setup client namespace
434918423fdSAaron Conole	ip netns exec client ip addr add 172.31.110.10/24 dev c1
435918423fdSAaron Conole	ip netns exec client ip link set c1 up
436918423fdSAaron Conole	HW_CLIENT=`ip netns exec client ip link show dev c1 | grep -E 'link/ether [0-9a-f:]+' | awk '{print $2;}'`
437918423fdSAaron Conole	info "Client hwaddr: $HW_CLIENT"
438918423fdSAaron Conole
439918423fdSAaron Conole	# Setup server namespace
440918423fdSAaron Conole	ip netns exec server ip addr add 172.31.110.20/24 dev s1
441918423fdSAaron Conole	ip netns exec server ip link set s1 up
442918423fdSAaron Conole	HW_SERVER=`ip netns exec server ip link show dev s1 | grep -E 'link/ether [0-9a-f:]+' | awk '{print $2;}'`
443918423fdSAaron Conole	info "Server hwaddr: $HW_SERVER"
444918423fdSAaron Conole
445918423fdSAaron Conole	ovs_add_flow "test_arp_ping" arpping \
446918423fdSAaron Conole		"in_port(1),eth(),eth_type(0x0806),arp(sip=172.31.110.10,tip=172.31.110.20,sha=$HW_CLIENT,tha=ff:ff:ff:ff:ff:ff)" '2' || return 1
447918423fdSAaron Conole	ovs_add_flow "test_arp_ping" arpping \
448918423fdSAaron Conole		"in_port(2),eth(),eth_type(0x0806),arp()" '1' || return 1
449918423fdSAaron Conole
450918423fdSAaron Conole	ovs_sbx "test_arp_ping" ip netns exec client arping -I c1 172.31.110.20 -c 1 || return 1
451918423fdSAaron Conole
452918423fdSAaron Conole	return 0
453918423fdSAaron Conole}
454918423fdSAaron Conole
4552893ba9cSAaron Conole# ct_connect_v4 test
4562893ba9cSAaron Conole#  - client has 1500 byte MTU
4572893ba9cSAaron Conole#  - server has 1500 byte MTU
4582893ba9cSAaron Conole#  - use ICMP to ping in each direction
4592893ba9cSAaron Conole#  - only allow CT state stuff to pass through new in c -> s
4602893ba9cSAaron Conoletest_ct_connect_v4 () {
4612893ba9cSAaron Conole
4622893ba9cSAaron Conole	which nc >/dev/null 2>/dev/null || return $ksft_skip
4632893ba9cSAaron Conole
4642893ba9cSAaron Conole	sbx_add "test_ct_connect_v4" || return $?
4652893ba9cSAaron Conole
4662893ba9cSAaron Conole	ovs_add_dp "test_ct_connect_v4" ct4 || return 1
4672893ba9cSAaron Conole	info "create namespaces"
4682893ba9cSAaron Conole	for ns in client server; do
4692893ba9cSAaron Conole		ovs_add_netns_and_veths "test_ct_connect_v4" "ct4" "$ns" \
4702893ba9cSAaron Conole		    "${ns:0:1}0" "${ns:0:1}1" || return 1
4712893ba9cSAaron Conole	done
4722893ba9cSAaron Conole
4732893ba9cSAaron Conole	ip netns exec client ip addr add 172.31.110.10/24 dev c1
4742893ba9cSAaron Conole	ip netns exec client ip link set c1 up
4752893ba9cSAaron Conole	ip netns exec server ip addr add 172.31.110.20/24 dev s1
4762893ba9cSAaron Conole	ip netns exec server ip link set s1 up
4772893ba9cSAaron Conole
4782893ba9cSAaron Conole	# Add forwarding for ARP and ip packets - completely wildcarded
4792893ba9cSAaron Conole	ovs_add_flow "test_ct_connect_v4" ct4 \
4802893ba9cSAaron Conole		'in_port(1),eth(),eth_type(0x0806),arp()' '2' || return 1
4812893ba9cSAaron Conole	ovs_add_flow "test_ct_connect_v4" ct4 \
4822893ba9cSAaron Conole		'in_port(2),eth(),eth_type(0x0806),arp()' '1' || return 1
4832893ba9cSAaron Conole	ovs_add_flow "test_ct_connect_v4" ct4 \
4842893ba9cSAaron Conole		     'ct_state(-trk),eth(),eth_type(0x0800),ipv4()' \
4852893ba9cSAaron Conole		     'ct(commit),recirc(0x1)' || return 1
4862893ba9cSAaron Conole	ovs_add_flow "test_ct_connect_v4" ct4 \
4872893ba9cSAaron Conole		     'recirc_id(0x1),ct_state(+trk+new),in_port(1),eth(),eth_type(0x0800),ipv4(src=172.31.110.10)' \
4882893ba9cSAaron Conole		     '2' || return 1
4892893ba9cSAaron Conole	ovs_add_flow "test_ct_connect_v4" ct4 \
4902893ba9cSAaron Conole		     'recirc_id(0x1),ct_state(+trk+est),in_port(1),eth(),eth_type(0x0800),ipv4(src=172.31.110.10)' \
4912893ba9cSAaron Conole		     '2' || return 1
4922893ba9cSAaron Conole	ovs_add_flow "test_ct_connect_v4" ct4 \
4932893ba9cSAaron Conole		     'recirc_id(0x1),ct_state(+trk+est),in_port(2),eth(),eth_type(0x0800),ipv4(dst=172.31.110.10)' \
4942893ba9cSAaron Conole		     '1' || return 1
4952893ba9cSAaron Conole	ovs_add_flow "test_ct_connect_v4" ct4 \
4962893ba9cSAaron Conole		     'recirc_id(0x1),ct_state(+trk+inv),eth(),eth_type(0x0800),ipv4()' 'drop' || \
4972893ba9cSAaron Conole		     return 1
4982893ba9cSAaron Conole
4992893ba9cSAaron Conole	# do a ping
5002893ba9cSAaron Conole	ovs_sbx "test_ct_connect_v4" ip netns exec client ping 172.31.110.20 -c 3 || return 1
5012893ba9cSAaron Conole
5022893ba9cSAaron Conole	# create an echo server in 'server'
5032893ba9cSAaron Conole	echo "server" | \
5042893ba9cSAaron Conole		ovs_netns_spawn_daemon "test_ct_connect_v4" "server" \
5052893ba9cSAaron Conole				nc -lvnp 4443
5062893ba9cSAaron Conole	ovs_sbx "test_ct_connect_v4" ip netns exec client nc -i 1 -zv 172.31.110.20 4443 || return 1
5072893ba9cSAaron Conole
5082893ba9cSAaron Conole	# Now test in the other direction (should fail)
5092893ba9cSAaron Conole	echo "client" | \
5102893ba9cSAaron Conole		ovs_netns_spawn_daemon "test_ct_connect_v4" "client" \
5112893ba9cSAaron Conole				nc -lvnp 4443
5122893ba9cSAaron Conole	ovs_sbx "test_ct_connect_v4" ip netns exec client nc -i 1 -zv 172.31.110.10 4443
5132893ba9cSAaron Conole	if [ $? == 0 ]; then
5142893ba9cSAaron Conole	   info "ct connect to client was successful"
5152893ba9cSAaron Conole	   return 1
5162893ba9cSAaron Conole	fi
5172893ba9cSAaron Conole
5182893ba9cSAaron Conole	info "done..."
5192893ba9cSAaron Conole	return 0
5202893ba9cSAaron Conole}
5212893ba9cSAaron Conole
52205398aa4SAaron Conole# connect_v4 test
52305398aa4SAaron Conole#  - client has 1500 byte MTU
52405398aa4SAaron Conole#  - server has 1500 byte MTU
52505398aa4SAaron Conole#  - use ICMP to ping in each direction
52605398aa4SAaron Conoletest_connect_v4 () {
52705398aa4SAaron Conole
52805398aa4SAaron Conole	sbx_add "test_connect_v4" || return $?
52905398aa4SAaron Conole
53005398aa4SAaron Conole	ovs_add_dp "test_connect_v4" cv4 || return 1
53105398aa4SAaron Conole
53205398aa4SAaron Conole	info "create namespaces"
53305398aa4SAaron Conole	for ns in client server; do
53405398aa4SAaron Conole		ovs_add_netns_and_veths "test_connect_v4" "cv4" "$ns" \
53505398aa4SAaron Conole		    "${ns:0:1}0" "${ns:0:1}1" || return 1
53605398aa4SAaron Conole	done
53705398aa4SAaron Conole
53805398aa4SAaron Conole
53905398aa4SAaron Conole	ip netns exec client ip addr add 172.31.110.10/24 dev c1
54005398aa4SAaron Conole	ip netns exec client ip link set c1 up
54105398aa4SAaron Conole	ip netns exec server ip addr add 172.31.110.20/24 dev s1
54205398aa4SAaron Conole	ip netns exec server ip link set s1 up
54305398aa4SAaron Conole
54405398aa4SAaron Conole	# Add forwarding for ARP and ip packets - completely wildcarded
54505398aa4SAaron Conole	ovs_add_flow "test_connect_v4" cv4 \
54605398aa4SAaron Conole		'in_port(1),eth(),eth_type(0x0806),arp()' '2' || return 1
54705398aa4SAaron Conole	ovs_add_flow "test_connect_v4" cv4 \
54805398aa4SAaron Conole		'in_port(2),eth(),eth_type(0x0806),arp()' '1' || return 1
54905398aa4SAaron Conole	ovs_add_flow "test_connect_v4" cv4 \
55005398aa4SAaron Conole		'in_port(1),eth(),eth_type(0x0800),ipv4(src=172.31.110.10)' '2' || return 1
55105398aa4SAaron Conole	ovs_add_flow "test_connect_v4" cv4 \
55205398aa4SAaron Conole		'in_port(2),eth(),eth_type(0x0800),ipv4(src=172.31.110.20)' '1' || return 1
55305398aa4SAaron Conole
55405398aa4SAaron Conole	# do a ping
55505398aa4SAaron Conole	ovs_sbx "test_connect_v4" ip netns exec client ping 172.31.110.20 -c 3 || return 1
55605398aa4SAaron Conole
55705398aa4SAaron Conole	info "done..."
55805398aa4SAaron Conole	return 0
55905398aa4SAaron Conole}
56005398aa4SAaron Conole
56160f10077SAaron Conole# nat_connect_v4 test
56260f10077SAaron Conole#  - client has 1500 byte MTU
56360f10077SAaron Conole#  - server has 1500 byte MTU
56460f10077SAaron Conole#  - use ICMP to ping in each direction
56560f10077SAaron Conole#  - only allow CT state stuff to pass through new in c -> s
56660f10077SAaron Conoletest_nat_connect_v4 () {
56760f10077SAaron Conole	which nc >/dev/null 2>/dev/null || return $ksft_skip
56860f10077SAaron Conole
56960f10077SAaron Conole	sbx_add "test_nat_connect_v4" || return $?
57060f10077SAaron Conole
57160f10077SAaron Conole	ovs_add_dp "test_nat_connect_v4" nat4 || return 1
57260f10077SAaron Conole	info "create namespaces"
57360f10077SAaron Conole	for ns in client server; do
57460f10077SAaron Conole		ovs_add_netns_and_veths "test_nat_connect_v4" "nat4" "$ns" \
57560f10077SAaron Conole		    "${ns:0:1}0" "${ns:0:1}1" || return 1
57660f10077SAaron Conole	done
57760f10077SAaron Conole
57860f10077SAaron Conole	ip netns exec client ip addr add 172.31.110.10/24 dev c1
57960f10077SAaron Conole	ip netns exec client ip link set c1 up
58060f10077SAaron Conole	ip netns exec server ip addr add 172.31.110.20/24 dev s1
58160f10077SAaron Conole	ip netns exec server ip link set s1 up
58260f10077SAaron Conole
58360f10077SAaron Conole	ip netns exec client ip route add default via 172.31.110.20
58460f10077SAaron Conole
58560f10077SAaron Conole	ovs_add_flow "test_nat_connect_v4" nat4 \
58660f10077SAaron Conole		'in_port(1),eth(),eth_type(0x0806),arp()' '2' || return 1
58760f10077SAaron Conole	ovs_add_flow "test_nat_connect_v4" nat4 \
58860f10077SAaron Conole		'in_port(2),eth(),eth_type(0x0806),arp()' '1' || return 1
58960f10077SAaron Conole	ovs_add_flow "test_nat_connect_v4" nat4 \
59060f10077SAaron Conole		"ct_state(-trk),in_port(1),eth(),eth_type(0x0800),ipv4(dst=192.168.0.20)" \
59160f10077SAaron Conole		"ct(commit,nat(dst=172.31.110.20)),recirc(0x1)"
59260f10077SAaron Conole	ovs_add_flow "test_nat_connect_v4" nat4 \
59360f10077SAaron Conole		"ct_state(-trk),in_port(2),eth(),eth_type(0x0800),ipv4()" \
59460f10077SAaron Conole		"ct(commit,nat),recirc(0x2)"
59560f10077SAaron Conole
59660f10077SAaron Conole	ovs_add_flow "test_nat_connect_v4" nat4 \
59760f10077SAaron Conole		"recirc_id(0x1),ct_state(+trk-inv),in_port(1),eth(),eth_type(0x0800),ipv4()" "2"
59860f10077SAaron Conole	ovs_add_flow "test_nat_connect_v4" nat4 \
59960f10077SAaron Conole		"recirc_id(0x2),ct_state(+trk-inv),in_port(2),eth(),eth_type(0x0800),ipv4()" "1"
60060f10077SAaron Conole
60160f10077SAaron Conole	# do a ping
60260f10077SAaron Conole	ovs_sbx "test_nat_connect_v4" ip netns exec client ping 192.168.0.20 -c 3 || return 1
60360f10077SAaron Conole
60460f10077SAaron Conole	# create an echo server in 'server'
60560f10077SAaron Conole	echo "server" | \
60660f10077SAaron Conole		ovs_netns_spawn_daemon "test_nat_connect_v4" "server" \
60760f10077SAaron Conole				nc -lvnp 4443
60860f10077SAaron Conole	ovs_sbx "test_nat_connect_v4" ip netns exec client nc -i 1 -zv 192.168.0.20 4443 || return 1
60960f10077SAaron Conole
61060f10077SAaron Conole	# Now test in the other direction (should fail)
61160f10077SAaron Conole	echo "client" | \
61260f10077SAaron Conole		ovs_netns_spawn_daemon "test_nat_connect_v4" "client" \
61360f10077SAaron Conole				nc -lvnp 4443
61460f10077SAaron Conole	ovs_sbx "test_nat_connect_v4" ip netns exec client nc -i 1 -zv 172.31.110.10 4443
61560f10077SAaron Conole	if [ $? == 0 ]; then
61660f10077SAaron Conole	   info "connect to client was successful"
61760f10077SAaron Conole	   return 1
61860f10077SAaron Conole	fi
61960f10077SAaron Conole
62060f10077SAaron Conole	info "done..."
62160f10077SAaron Conole	return 0
62260f10077SAaron Conole}
62360f10077SAaron Conole
624094bdd48SBrad Cowie# nat_related_v4 test
625094bdd48SBrad Cowie#  - client->server ip packets go via SNAT
626094bdd48SBrad Cowie#  - client solicits ICMP destination unreachable packet from server
627094bdd48SBrad Cowie#  - undo NAT for ICMP reply and test dst ip has been updated
628094bdd48SBrad Cowietest_nat_related_v4 () {
629094bdd48SBrad Cowie	which nc >/dev/null 2>/dev/null || return $ksft_skip
630094bdd48SBrad Cowie
631094bdd48SBrad Cowie	sbx_add "test_nat_related_v4" || return $?
632094bdd48SBrad Cowie
633094bdd48SBrad Cowie	ovs_add_dp "test_nat_related_v4" natrelated4 || return 1
634094bdd48SBrad Cowie	info "create namespaces"
635094bdd48SBrad Cowie	for ns in client server; do
636094bdd48SBrad Cowie		ovs_add_netns_and_veths "test_nat_related_v4" "natrelated4" "$ns" \
637094bdd48SBrad Cowie			"${ns:0:1}0" "${ns:0:1}1" || return 1
638094bdd48SBrad Cowie	done
639094bdd48SBrad Cowie
640094bdd48SBrad Cowie	ip netns exec client ip addr add 172.31.110.10/24 dev c1
641094bdd48SBrad Cowie	ip netns exec client ip link set c1 up
642094bdd48SBrad Cowie	ip netns exec server ip addr add 172.31.110.20/24 dev s1
643094bdd48SBrad Cowie	ip netns exec server ip link set s1 up
644094bdd48SBrad Cowie
645094bdd48SBrad Cowie	ip netns exec server ip route add 192.168.0.20/32 via 172.31.110.10
646094bdd48SBrad Cowie
647094bdd48SBrad Cowie	# Allow ARP
648094bdd48SBrad Cowie	ovs_add_flow "test_nat_related_v4" natrelated4 \
649094bdd48SBrad Cowie		"in_port(1),eth(),eth_type(0x0806),arp()" "2" || return 1
650094bdd48SBrad Cowie	ovs_add_flow "test_nat_related_v4" natrelated4 \
651094bdd48SBrad Cowie		"in_port(2),eth(),eth_type(0x0806),arp()" "1" || return 1
652094bdd48SBrad Cowie
653094bdd48SBrad Cowie	# Allow IP traffic from client->server, rewrite source IP with SNAT to 192.168.0.20
654094bdd48SBrad Cowie	ovs_add_flow "test_nat_related_v4" natrelated4 \
655094bdd48SBrad Cowie		"ct_state(-trk),in_port(1),eth(),eth_type(0x0800),ipv4(dst=172.31.110.20)" \
656094bdd48SBrad Cowie		"ct(commit,nat(src=192.168.0.20)),recirc(0x1)" || return 1
657094bdd48SBrad Cowie	ovs_add_flow "test_nat_related_v4" natrelated4 \
658094bdd48SBrad Cowie		"recirc_id(0x1),ct_state(+trk-inv),in_port(1),eth(),eth_type(0x0800),ipv4()" \
659094bdd48SBrad Cowie		"2" || return 1
660094bdd48SBrad Cowie
661094bdd48SBrad Cowie	# Allow related ICMP responses back from server and undo NAT to restore original IP
662094bdd48SBrad Cowie	# Drop any ICMP related packets where dst ip hasn't been restored back to original IP
663094bdd48SBrad Cowie	ovs_add_flow "test_nat_related_v4" natrelated4 \
664094bdd48SBrad Cowie		"ct_state(-trk),in_port(2),eth(),eth_type(0x0800),ipv4()" \
665094bdd48SBrad Cowie		"ct(commit,nat),recirc(0x2)" || return 1
666094bdd48SBrad Cowie	ovs_add_flow "test_nat_related_v4" natrelated4 \
667094bdd48SBrad Cowie		"recirc_id(0x2),ct_state(+rel+trk),in_port(2),eth(),eth_type(0x0800),ipv4(src=172.31.110.20,dst=172.31.110.10,proto=1),icmp()" \
668094bdd48SBrad Cowie		"1" || return 1
669094bdd48SBrad Cowie	ovs_add_flow "test_nat_related_v4" natrelated4 \
670094bdd48SBrad Cowie		"recirc_id(0x2),ct_state(+rel+trk),in_port(2),eth(),eth_type(0x0800),ipv4(dst=192.168.0.20,proto=1),icmp()" \
671094bdd48SBrad Cowie		"drop" || return 1
672094bdd48SBrad Cowie
673094bdd48SBrad Cowie	# Solicit destination unreachable response from server
674094bdd48SBrad Cowie	ovs_sbx "test_nat_related_v4" ip netns exec client \
675094bdd48SBrad Cowie		bash -c "echo a | nc -u -w 1 172.31.110.20 10000"
676094bdd48SBrad Cowie
677094bdd48SBrad Cowie	# Check to make sure no packets matched the drop rule with incorrect dst ip
678094bdd48SBrad Cowie	python3 "$ovs_base/ovs-dpctl.py" dump-flows natrelated4 \
679094bdd48SBrad Cowie		| grep "drop" | grep "packets:0" >/dev/null || return 1
680094bdd48SBrad Cowie
681094bdd48SBrad Cowie	info "done..."
682094bdd48SBrad Cowie	return 0
683094bdd48SBrad Cowie}
684094bdd48SBrad Cowie
68525f16c87SAaron Conole# netlink_validation
68625f16c87SAaron Conole# - Create a dp
68725f16c87SAaron Conole# - check no warning with "old version" simulation
68825f16c87SAaron Conoletest_netlink_checks () {
68925f16c87SAaron Conole	sbx_add "test_netlink_checks" || return 1
69025f16c87SAaron Conole
69125f16c87SAaron Conole	info "setting up new DP"
69225f16c87SAaron Conole	ovs_add_dp "test_netlink_checks" nv0 || return 1
69325f16c87SAaron Conole	# now try again
69425f16c87SAaron Conole	PRE_TEST=$(dmesg | grep -E "RIP: [0-9a-fA-Fx]+:ovs_dp_cmd_new\+")
69525f16c87SAaron Conole	ovs_add_dp "test_netlink_checks" nv0 -V 0 || return 1
69625f16c87SAaron Conole	POST_TEST=$(dmesg | grep -E "RIP: [0-9a-fA-Fx]+:ovs_dp_cmd_new\+")
69725f16c87SAaron Conole	if [ "$PRE_TEST" != "$POST_TEST" ]; then
69825f16c87SAaron Conole		info "failed - gen warning"
69925f16c87SAaron Conole		return 1
70025f16c87SAaron Conole	fi
70125f16c87SAaron Conole
70274cc26f4SAaron Conole	ovs_add_netns_and_veths "test_netlink_checks" nv0 left left0 l0 || \
70374cc26f4SAaron Conole	    return 1
70474cc26f4SAaron Conole	ovs_add_netns_and_veths "test_netlink_checks" nv0 right right0 r0 || \
70574cc26f4SAaron Conole	    return 1
70674cc26f4SAaron Conole	[ $(python3 $ovs_base/ovs-dpctl.py show nv0 | grep port | \
70774cc26f4SAaron Conole	    wc -l) == 3 ] || \
70874cc26f4SAaron Conole	      return 1
70974cc26f4SAaron Conole	ovs_del_if "test_netlink_checks" nv0 right0 || return 1
71074cc26f4SAaron Conole	[ $(python3 $ovs_base/ovs-dpctl.py show nv0 | grep port | \
71174cc26f4SAaron Conole	    wc -l) == 2 ] || \
71274cc26f4SAaron Conole	      return 1
71374cc26f4SAaron Conole
714bd128f62SAaron Conole	info "Checking clone depth"
71542420291SAdrian Moreno	ERR_MSG="Flow actions may not be safe on all matching packets"
71642420291SAdrian Moreno	PRE_TEST=$(dmesg | grep -c "${ERR_MSG}")
71742420291SAdrian Moreno	ovs_add_flow "test_netlink_checks" nv0 \
718bd128f62SAaron Conole		'in_port(1),eth(),eth_type(0x800),ipv4()' \
719bd128f62SAaron Conole		'clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(drop)))))))))))))))))' \
720bd128f62SAaron Conole		>/dev/null 2>&1 && return 1
721bd128f62SAaron Conole	POST_TEST=$(dmesg | grep -c "${ERR_MSG}")
722bd128f62SAaron Conole
723bd128f62SAaron Conole	if [ "$PRE_TEST" == "$POST_TEST" ]; then
724bd128f62SAaron Conole		info "failed - clone depth too large"
725bd128f62SAaron Conole		return 1
726bd128f62SAaron Conole	fi
727bd128f62SAaron Conole
728bd128f62SAaron Conole	PRE_TEST=$(dmesg | grep -c "${ERR_MSG}")
729bd128f62SAaron Conole	ovs_add_flow "test_netlink_checks" nv0 \
73042420291SAdrian Moreno		'in_port(1),eth(),eth_type(0x0806),arp()' 'drop(0),2' \
73142420291SAdrian Moreno		&> /dev/null && return 1
73242420291SAdrian Moreno	POST_TEST=$(dmesg | grep -c "${ERR_MSG}")
73342420291SAdrian Moreno	if [ "$PRE_TEST" == "$POST_TEST" ]; then
73442420291SAdrian Moreno		info "failed - error not generated"
73542420291SAdrian Moreno		return 1
73642420291SAdrian Moreno	fi
73725f16c87SAaron Conole	return 0
73825f16c87SAaron Conole}
73925f16c87SAaron Conole
7409feac87bSAaron Conoletest_upcall_interfaces() {
7419feac87bSAaron Conole	sbx_add "test_upcall_interfaces" || return 1
7429feac87bSAaron Conole
7439feac87bSAaron Conole	info "setting up new DP"
7449feac87bSAaron Conole	ovs_add_dp "test_upcall_interfaces" ui0 -V 2:1 || return 1
7459feac87bSAaron Conole
7469feac87bSAaron Conole	ovs_add_netns_and_veths "test_upcall_interfaces" ui0 upc left0 l0 \
7479feac87bSAaron Conole	    172.31.110.1/24 -u || return 1
7489feac87bSAaron Conole
7495e724cb6SAdrian Moreno	ovs_wait grep -q "listening on upcall packet handler" ${ovs_dir}/left0.out
7505e724cb6SAdrian Moreno
7519feac87bSAaron Conole	info "sending arping"
7529feac87bSAaron Conole	ip netns exec upc arping -I l0 172.31.110.20 -c 1 \
7539feac87bSAaron Conole	    >$ovs_dir/arping.stdout 2>$ovs_dir/arping.stderr
7549feac87bSAaron Conole
7559feac87bSAaron Conole	grep -E "MISS upcall\[0/yes\]: .*arp\(sip=172.31.110.1,tip=172.31.110.20,op=1,sha=" $ovs_dir/left0.out >/dev/null 2>&1 || return 1
7569feac87bSAaron Conole	return 0
7579feac87bSAaron Conole}
7589feac87bSAaron Conole
75925f16c87SAaron Conolerun_test() {
76025f16c87SAaron Conole	(
76125f16c87SAaron Conole	tname="$1"
76225f16c87SAaron Conole	tdesc="$2"
76325f16c87SAaron Conole
76425f16c87SAaron Conole	if python3 ovs-dpctl.py -h 2>&1 | \
76592e37f20SAaron Conole	     grep -E "Need to (install|upgrade) the python" >/dev/null 2>&1; then
76625f16c87SAaron Conole		stdbuf -o0 printf "TEST: %-60s  [PYLIB]\n" "${tdesc}"
76725f16c87SAaron Conole		return $ksft_skip
76825f16c87SAaron Conole	fi
769818481dbSAaron Conole
770818481dbSAaron Conole	python3 ovs-dpctl.py show >/dev/null 2>&1 || \
771818481dbSAaron Conole		echo "[DPCTL] show exception."
772818481dbSAaron Conole
773818481dbSAaron Conole	if ! lsmod | grep openvswitch >/dev/null 2>&1; then
774818481dbSAaron Conole		stdbuf -o0 printf "TEST: %-60s  [NOMOD]\n" "${tdesc}"
775818481dbSAaron Conole		return $ksft_skip
776818481dbSAaron Conole	fi
777818481dbSAaron Conole
77825f16c87SAaron Conole	printf "TEST: %-60s  [START]\n" "${tname}"
77925f16c87SAaron Conole
78025f16c87SAaron Conole	unset IFS
78125f16c87SAaron Conole
78225f16c87SAaron Conole	eval test_${tname}
78325f16c87SAaron Conole	ret=$?
78425f16c87SAaron Conole
78525f16c87SAaron Conole	if [ $ret -eq 0 ]; then
78625f16c87SAaron Conole		printf "TEST: %-60s  [ OK ]\n" "${tdesc}"
78725f16c87SAaron Conole		ovs_exit_sig
78825f16c87SAaron Conole		rm -rf "$ovs_dir"
78925f16c87SAaron Conole	elif [ $ret -eq 1 ]; then
79025f16c87SAaron Conole		printf "TEST: %-60s  [FAIL]\n" "${tdesc}"
79125f16c87SAaron Conole		if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
79225f16c87SAaron Conole			echo
79325f16c87SAaron Conole			echo "Pausing. Logs in $ovs_dir/. Hit enter to continue"
79425f16c87SAaron Conole			read a
79525f16c87SAaron Conole		fi
79625f16c87SAaron Conole		ovs_exit_sig
79725f16c87SAaron Conole		[ "${PAUSE_ON_FAIL}" = "yes" ] || rm -rf "$ovs_dir"
79825f16c87SAaron Conole		exit 1
79925f16c87SAaron Conole	elif [ $ret -eq $ksft_skip ]; then
80025f16c87SAaron Conole		printf "TEST: %-60s  [SKIP]\n" "${tdesc}"
80125f16c87SAaron Conole	elif [ $ret -eq 2 ]; then
80225f16c87SAaron Conole		rm -rf test_${tname}
80325f16c87SAaron Conole		run_test "$1" "$2"
80425f16c87SAaron Conole	fi
80525f16c87SAaron Conole
80625f16c87SAaron Conole	return $ret
80725f16c87SAaron Conole	)
80825f16c87SAaron Conole	ret=$?
80925f16c87SAaron Conole	case $ret in
81025f16c87SAaron Conole		0)
81125f16c87SAaron Conole			[ $all_skipped = true ] && [ $exitcode=$ksft_skip ] && exitcode=0
81225f16c87SAaron Conole			all_skipped=false
81325f16c87SAaron Conole		;;
81425f16c87SAaron Conole		$ksft_skip)
81525f16c87SAaron Conole			[ $all_skipped = true ] && exitcode=$ksft_skip
81625f16c87SAaron Conole		;;
81725f16c87SAaron Conole		*)
81825f16c87SAaron Conole			all_skipped=false
81925f16c87SAaron Conole			exitcode=1
82025f16c87SAaron Conole		;;
82125f16c87SAaron Conole	esac
82225f16c87SAaron Conole
82325f16c87SAaron Conole	return $ret
82425f16c87SAaron Conole}
82525f16c87SAaron Conole
82625f16c87SAaron Conole
82725f16c87SAaron Conoleexitcode=0
82825f16c87SAaron Conoledesc=0
82925f16c87SAaron Conoleall_skipped=true
83025f16c87SAaron Conole
83125f16c87SAaron Conolewhile getopts :pvt o
83225f16c87SAaron Conoledo
83325f16c87SAaron Conole	case $o in
83425f16c87SAaron Conole	p) PAUSE_ON_FAIL=yes;;
83525f16c87SAaron Conole	v) VERBOSE=1;;
83625f16c87SAaron Conole	t) if which tcpdump > /dev/null 2>&1; then
83725f16c87SAaron Conole		TRACING=1
83825f16c87SAaron Conole	   else
83925f16c87SAaron Conole		echo "=== tcpdump not available, tracing disabled"
84025f16c87SAaron Conole	   fi
84125f16c87SAaron Conole	   ;;
84225f16c87SAaron Conole	*) usage;;
84325f16c87SAaron Conole	esac
84425f16c87SAaron Conoledone
84525f16c87SAaron Conoleshift $(($OPTIND-1))
84625f16c87SAaron Conole
84725f16c87SAaron ConoleIFS="
84825f16c87SAaron Conole"
84925f16c87SAaron Conole
85025f16c87SAaron Conolefor arg do
85125f16c87SAaron Conole	# Check first that all requested tests are available before running any
85225f16c87SAaron Conole	command -v > /dev/null "test_${arg}" || { echo "=== Test ${arg} not found"; usage; }
85325f16c87SAaron Conoledone
85425f16c87SAaron Conole
85525f16c87SAaron Conolename=""
85625f16c87SAaron Conoledesc=""
85725f16c87SAaron Conolefor t in ${tests}; do
85825f16c87SAaron Conole	[ "${name}" = "" ]	&& name="${t}"	&& continue
85925f16c87SAaron Conole	[ "${desc}" = "" ]	&& desc="${t}"
86025f16c87SAaron Conole
86125f16c87SAaron Conole	run_this=1
86225f16c87SAaron Conole	for arg do
86325f16c87SAaron Conole		[ "${arg}" != "${arg#--*}" ] && continue
86425f16c87SAaron Conole		[ "${arg}" = "${name}" ] && run_this=1 && break
86525f16c87SAaron Conole		run_this=0
86625f16c87SAaron Conole	done
86725f16c87SAaron Conole	if [ $run_this -eq 1 ]; then
86825f16c87SAaron Conole		run_test "${name}" "${desc}"
86925f16c87SAaron Conole	fi
87025f16c87SAaron Conole	name=""
87125f16c87SAaron Conole	desc=""
87225f16c87SAaron Conoledone
87325f16c87SAaron Conole
87425f16c87SAaron Conoleexit ${exitcode}
875