121 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
| #!/bin/bash
 | |
| # SPDX-License-Identifier: GPL-2.0
 | |
| 
 | |
| readonly FLUSH_PATH="/sys/class/net/${dev}/gro_flush_timeout"
 | |
| readonly IRQ_PATH="/sys/class/net/${dev}/napi_defer_hard_irqs"
 | |
| readonly FLUSH_TIMEOUT="$(< ${FLUSH_PATH})"
 | |
| readonly HARD_IRQS="$(< ${IRQ_PATH})"
 | |
| readonly server_ns=$(mktemp -u server-XXXXXXXX)
 | |
| readonly client_ns=$(mktemp -u client-XXXXXXXX)
 | |
| 
 | |
| netdev_check_for_carrier() {
 | |
| 	local -r dev="$1"
 | |
| 
 | |
| 	for i in {1..5}; do
 | |
| 		carrier="$(cat /sys/class/net/${dev}/carrier)"
 | |
| 		if [[ "${carrier}" -ne 1 ]] ; then
 | |
| 			echo "carrier not ready yet..." >&2
 | |
| 			sleep 1
 | |
| 		else
 | |
| 			echo "carrier ready" >&2
 | |
| 			break
 | |
| 		fi
 | |
| 	done
 | |
| 	echo "${carrier}"
 | |
| }
 | |
| 
 | |
| # Assumes that there is no existing ipvlan device on the physical device
 | |
| setup_loopback_environment() {
 | |
| 	local dev="$1"
 | |
| 
 | |
| 	# Fail hard if cannot turn on loopback mode for current NIC
 | |
| 	ethtool -K "${dev}" loopback on || exit 1
 | |
| 	sleep 1
 | |
| 
 | |
| 	# Check for the carrier
 | |
| 	carrier=$(netdev_check_for_carrier ${dev})
 | |
| 	if [[ "${carrier}" -ne 1 ]] ; then
 | |
| 		echo "setup_loopback_environment failed"
 | |
| 		exit 1
 | |
| 	fi
 | |
| }
 | |
| 
 | |
| setup_macvlan_ns(){
 | |
| 	local -r link_dev="$1"
 | |
| 	local -r ns_name="$2"
 | |
| 	local -r ns_dev="$3"
 | |
| 	local -r ns_mac="$4"
 | |
| 	local -r addr="$5"
 | |
| 
 | |
| 	ip link add link "${link_dev}" dev "${ns_dev}" \
 | |
| 		address "${ns_mac}" type macvlan
 | |
| 	exit_code=$?
 | |
| 	if [[ "${exit_code}" -ne 0 ]]; then
 | |
| 		echo "setup_macvlan_ns failed"
 | |
| 		exit $exit_code
 | |
| 	fi
 | |
| 
 | |
| 	[[ -e /var/run/netns/"${ns_name}" ]] || ip netns add "${ns_name}"
 | |
| 	ip link set dev "${ns_dev}" netns "${ns_name}"
 | |
| 	ip -netns "${ns_name}" link set dev "${ns_dev}" up
 | |
| 	if [[ -n "${addr}" ]]; then
 | |
| 		ip -netns "${ns_name}" addr add dev "${ns_dev}" "${addr}"
 | |
| 	fi
 | |
| 
 | |
| 	sleep 1
 | |
| }
 | |
| 
 | |
| cleanup_macvlan_ns(){
 | |
| 	while (( $# >= 2 )); do
 | |
| 		ns_name="$1"
 | |
| 		ns_dev="$2"
 | |
| 		ip -netns "${ns_name}" link del dev "${ns_dev}"
 | |
| 		ip netns del "${ns_name}"
 | |
| 		shift 2
 | |
| 	done
 | |
| }
 | |
| 
 | |
| cleanup_loopback(){
 | |
| 	local -r dev="$1"
 | |
| 
 | |
| 	ethtool -K "${dev}" loopback off
 | |
| 	sleep 1
 | |
| 
 | |
| 	# Check for the carrier
 | |
| 	carrier=$(netdev_check_for_carrier ${dev})
 | |
| 	if [[ "${carrier}" -ne 1 ]] ; then
 | |
| 		echo "setup_loopback_environment failed"
 | |
| 		exit 1
 | |
| 	fi
 | |
| }
 | |
| 
 | |
| setup_interrupt() {
 | |
| 	# Use timer on  host to trigger the network stack
 | |
| 	# Also disable device interrupt to not depend on NIC interrupt
 | |
| 	# Reduce test flakiness caused by unexpected interrupts
 | |
| 	echo 100000 >"${FLUSH_PATH}"
 | |
| 	echo 50 >"${IRQ_PATH}"
 | |
| }
 | |
| 
 | |
| setup_ns() {
 | |
| 	# Set up server_ns namespace and client_ns namespace
 | |
| 	setup_macvlan_ns "${dev}" ${server_ns} server "${SERVER_MAC}"
 | |
| 	setup_macvlan_ns "${dev}" ${client_ns} client "${CLIENT_MAC}"
 | |
| }
 | |
| 
 | |
| cleanup_ns() {
 | |
| 	cleanup_macvlan_ns ${server_ns} server ${client_ns} client
 | |
| }
 | |
| 
 | |
| setup() {
 | |
| 	setup_loopback_environment "${dev}"
 | |
| 	setup_interrupt
 | |
| }
 | |
| 
 | |
| cleanup() {
 | |
| 	cleanup_loopback "${dev}"
 | |
| 
 | |
| 	echo "${FLUSH_TIMEOUT}" >"${FLUSH_PATH}"
 | |
| 	echo "${HARD_IRQS}" >"${IRQ_PATH}"
 | |
| }
 |