xref: /linux/tools/testing/selftests/net/lib/ksft_setup_loopback.sh (revision 84318277d6334c6981ab326d4acc87c6a6ddc9b8)
1*bd28e5bdSJakub Kicinski#!/bin/bash
2*bd28e5bdSJakub Kicinski# SPDX-License-Identifier: GPL-2.0
3*bd28e5bdSJakub Kicinski
4*bd28e5bdSJakub Kicinski# Setup script for running ksft tests over a real interface in loopback mode.
5*bd28e5bdSJakub Kicinski# This scripts replaces the historical setup_loopback.sh. It puts
6*bd28e5bdSJakub Kicinski# a (presumably) real hardware interface into loopback mode, creates macvlan
7*bd28e5bdSJakub Kicinski# interfaces on top and places them in a network namespace for isolation.
8*bd28e5bdSJakub Kicinski#
9*bd28e5bdSJakub Kicinski# NETIF env variable must be exported to indicate the real target device.
10*bd28e5bdSJakub Kicinski# Note that the test will override NETIF with one of the macvlans, the
11*bd28e5bdSJakub Kicinski# actual ksft test will only see the macvlans.
12*bd28e5bdSJakub Kicinski#
13*bd28e5bdSJakub Kicinski# Example use:
14*bd28e5bdSJakub Kicinski#   export NETIF=eth0
15*bd28e5bdSJakub Kicinski#   ./net/lib/ksft_setup_loopback.sh ./drivers/net/gro.py
16*bd28e5bdSJakub Kicinski
17*bd28e5bdSJakub Kicinskiif [ -z "$NETIF" ]; then
18*bd28e5bdSJakub Kicinski    echo "Error: NETIF variable not set"
19*bd28e5bdSJakub Kicinski    exit 1
20*bd28e5bdSJakub Kicinskifi
21*bd28e5bdSJakub Kicinskiif ! [ -d "/sys/class/net/$NETIF" ]; then
22*bd28e5bdSJakub Kicinski    echo "Error: Can't find $NETIF, invalid netdevice"
23*bd28e5bdSJakub Kicinski    exit 1
24*bd28e5bdSJakub Kicinskifi
25*bd28e5bdSJakub Kicinski
26*bd28e5bdSJakub Kicinski# Save original settings for cleanup
27*bd28e5bdSJakub Kicinskireadonly FLUSH_PATH="/sys/class/net/${NETIF}/gro_flush_timeout"
28*bd28e5bdSJakub Kicinskireadonly IRQ_PATH="/sys/class/net/${NETIF}/napi_defer_hard_irqs"
29*bd28e5bdSJakub KicinskiFLUSH_TIMEOUT="$(< "${FLUSH_PATH}")"
30*bd28e5bdSJakub Kicinskireadonly FLUSH_TIMEOUT
31*bd28e5bdSJakub KicinskiHARD_IRQS="$(< "${IRQ_PATH}")"
32*bd28e5bdSJakub Kicinskireadonly HARD_IRQS
33*bd28e5bdSJakub Kicinski
34*bd28e5bdSJakub KicinskiSERVER_NS=$(mktemp -u server-XXXXXXXX)
35*bd28e5bdSJakub Kicinskireadonly SERVER_NS
36*bd28e5bdSJakub KicinskiCLIENT_NS=$(mktemp -u client-XXXXXXXX)
37*bd28e5bdSJakub Kicinskireadonly CLIENT_NS
38*bd28e5bdSJakub Kicinskireadonly SERVER_MAC="aa:00:00:00:00:02"
39*bd28e5bdSJakub Kicinskireadonly CLIENT_MAC="aa:00:00:00:00:01"
40*bd28e5bdSJakub Kicinski
41*bd28e5bdSJakub Kicinski# ksft expects addresses to communicate with remote
42*bd28e5bdSJakub Kicinskiexport  LOCAL_V6=2001:db8:1::1
43*bd28e5bdSJakub Kicinskiexport REMOTE_V6=2001:db8:1::2
44*bd28e5bdSJakub Kicinski
45*bd28e5bdSJakub Kicinskicleanup() {
46*bd28e5bdSJakub Kicinski    local exit_code=$?
47*bd28e5bdSJakub Kicinski
48*bd28e5bdSJakub Kicinski    echo "Cleaning up..."
49*bd28e5bdSJakub Kicinski
50*bd28e5bdSJakub Kicinski    # Remove macvlan interfaces and namespaces
51*bd28e5bdSJakub Kicinski    ip -netns "${SERVER_NS}" link del dev server 2>/dev/null || true
52*bd28e5bdSJakub Kicinski    ip netns del "${SERVER_NS}" 2>/dev/null || true
53*bd28e5bdSJakub Kicinski    ip -netns "${CLIENT_NS}" link del dev client 2>/dev/null || true
54*bd28e5bdSJakub Kicinski    ip netns del "${CLIENT_NS}" 2>/dev/null || true
55*bd28e5bdSJakub Kicinski
56*bd28e5bdSJakub Kicinski    # Disable loopback
57*bd28e5bdSJakub Kicinski    ethtool -K "${NETIF}" loopback off 2>/dev/null || true
58*bd28e5bdSJakub Kicinski    sleep 1
59*bd28e5bdSJakub Kicinski
60*bd28e5bdSJakub Kicinski    echo "${FLUSH_TIMEOUT}" >"${FLUSH_PATH}"
61*bd28e5bdSJakub Kicinski    echo "${HARD_IRQS}" >"${IRQ_PATH}"
62*bd28e5bdSJakub Kicinski
63*bd28e5bdSJakub Kicinski    exit $exit_code
64*bd28e5bdSJakub Kicinski}
65*bd28e5bdSJakub Kicinski
66*bd28e5bdSJakub Kicinskitrap cleanup EXIT INT TERM
67*bd28e5bdSJakub Kicinski
68*bd28e5bdSJakub Kicinski# Enable loopback mode
69*bd28e5bdSJakub Kicinskiecho "Enabling loopback on ${NETIF}..."
70*bd28e5bdSJakub Kicinskiethtool -K "${NETIF}" loopback on || {
71*bd28e5bdSJakub Kicinski    echo "Failed to enable loopback mode"
72*bd28e5bdSJakub Kicinski    exit 1
73*bd28e5bdSJakub Kicinski}
74*bd28e5bdSJakub Kicinski# The interface may need time to get carrier back, but selftests
75*bd28e5bdSJakub Kicinski# will wait for carrier, so no need to wait / sleep here.
76*bd28e5bdSJakub Kicinski
77*bd28e5bdSJakub Kicinski# Use timer on  host to trigger the network stack
78*bd28e5bdSJakub Kicinski# Also disable device interrupt to not depend on NIC interrupt
79*bd28e5bdSJakub Kicinski# Reduce test flakiness caused by unexpected interrupts
80*bd28e5bdSJakub Kicinskiecho 100000 >"${FLUSH_PATH}"
81*bd28e5bdSJakub Kicinskiecho 50 >"${IRQ_PATH}"
82*bd28e5bdSJakub Kicinski
83*bd28e5bdSJakub Kicinski# Create server namespace with macvlan
84*bd28e5bdSJakub Kicinskiip netns add "${SERVER_NS}"
85*bd28e5bdSJakub Kicinskiip link add link "${NETIF}" dev server address "${SERVER_MAC}" type macvlan
86*bd28e5bdSJakub Kicinskiip link set dev server netns "${SERVER_NS}"
87*bd28e5bdSJakub Kicinskiip -netns "${SERVER_NS}" link set dev server up
88*bd28e5bdSJakub Kicinskiip -netns "${SERVER_NS}" addr add $LOCAL_V6/64 dev server
89*bd28e5bdSJakub Kicinskiip -netns "${SERVER_NS}" link set dev lo up
90*bd28e5bdSJakub Kicinski
91*bd28e5bdSJakub Kicinski# Create client namespace with macvlan
92*bd28e5bdSJakub Kicinskiip netns add "${CLIENT_NS}"
93*bd28e5bdSJakub Kicinskiip link add link "${NETIF}" dev client address "${CLIENT_MAC}" type macvlan
94*bd28e5bdSJakub Kicinskiip link set dev client netns "${CLIENT_NS}"
95*bd28e5bdSJakub Kicinskiip -netns "${CLIENT_NS}" link set dev client up
96*bd28e5bdSJakub Kicinskiip -netns "${CLIENT_NS}" addr add $REMOTE_V6/64 dev client
97*bd28e5bdSJakub Kicinskiip -netns "${CLIENT_NS}" link set dev lo up
98*bd28e5bdSJakub Kicinski
99*bd28e5bdSJakub Kicinskiecho "Setup complete!"
100*bd28e5bdSJakub Kicinskiecho "  Device: ${NETIF}"
101*bd28e5bdSJakub Kicinskiecho "  Server NS: ${SERVER_NS}"
102*bd28e5bdSJakub Kicinskiecho "  Client NS: ${CLIENT_NS}"
103*bd28e5bdSJakub Kicinskiecho ""
104*bd28e5bdSJakub Kicinski
105*bd28e5bdSJakub Kicinski# Setup environment variables for tests
106*bd28e5bdSJakub Kicinskiexport NETIF=server
107*bd28e5bdSJakub Kicinskiexport REMOTE_TYPE=netns
108*bd28e5bdSJakub Kicinskiexport REMOTE_ARGS="${CLIENT_NS}"
109*bd28e5bdSJakub Kicinski
110*bd28e5bdSJakub Kicinski# Run the command
111*bd28e5bdSJakub Kicinskiip netns exec "${SERVER_NS}" "$@"
112