| #!/bin/sh |
| # SPDX-License-Identifier: GPL-2.0 |
| # |
| # This test is for checking network interface |
| # For the moment it tests only ethernet interface (but wifi could be easily added) |
| # |
| # We assume that all network driver are loaded |
| # if not they probably have failed earlier in the boot process and their logged error will be catched by another test |
| # |
| |
| # Kselftest framework requirement - SKIP code is 4. |
| ksft_skip=4 |
| |
| # this function will try to up the interface |
| # if already up, nothing done |
| # arg1: network interface name |
| kci_net_start() |
| { |
| netdev=$1 |
| |
| ip link show "$netdev" |grep -q UP |
| if [ $? -eq 0 ];then |
| echo "SKIP: $netdev: interface already up" |
| return $ksft_skip |
| fi |
| |
| ip link set "$netdev" up |
| if [ $? -ne 0 ];then |
| echo "FAIL: $netdev: Fail to up interface" |
| return 1 |
| else |
| echo "PASS: $netdev: set interface up" |
| NETDEV_STARTED=1 |
| fi |
| return 0 |
| } |
| |
| # this function will try to setup an IP and MAC address on a network interface |
| # Doing nothing if the interface was already up |
| # arg1: network interface name |
| kci_net_setup() |
| { |
| netdev=$1 |
| |
| # do nothing if the interface was already up |
| if [ $NETDEV_STARTED -eq 0 ];then |
| return 0 |
| fi |
| |
| MACADDR='02:03:04:05:06:07' |
| ip link set dev $netdev address "$MACADDR" |
| if [ $? -ne 0 ];then |
| echo "FAIL: $netdev: Cannot set MAC address" |
| else |
| ip link show $netdev |grep -q "$MACADDR" |
| if [ $? -eq 0 ];then |
| echo "PASS: $netdev: set MAC address" |
| else |
| echo "FAIL: $netdev: Cannot set MAC address" |
| fi |
| fi |
| |
| #check that the interface did not already have an IP |
| ip address show "$netdev" |grep '^[[:space:]]*inet' |
| if [ $? -eq 0 ];then |
| echo "SKIP: $netdev: already have an IP" |
| return $ksft_skip |
| fi |
| |
| if [ "$veth_created" ]; then |
| echo "XFAIL: $netdev: set IP address unsupported for veth*" |
| else |
| # TODO what ipaddr to set ? DHCP ? |
| echo "SKIP: $netdev: set IP address" |
| fi |
| return $ksft_skip |
| } |
| |
| # test an ethtool command |
| # arg1: return code for not supported (see ethtool code source) |
| # arg2: summary of the command |
| # arg3: command to execute |
| kci_netdev_ethtool_test() |
| { |
| if [ $# -le 2 ];then |
| echo "SKIP: $netdev: ethtool: invalid number of arguments" |
| return 1 |
| fi |
| $3 >/dev/null |
| ret=$? |
| if [ $ret -ne 0 ];then |
| if [ $ret -eq "$1" ];then |
| echo "XFAIL: $netdev: ethtool $2 not supported" |
| return $ksft_skip |
| else |
| echo "FAIL: $netdev: ethtool $2" |
| return 1 |
| fi |
| else |
| echo "PASS: $netdev: ethtool $2" |
| fi |
| return 0 |
| } |
| |
| # test ethtool commands |
| # arg1: network interface name |
| kci_netdev_ethtool() |
| { |
| netdev=$1 |
| |
| #check presence of ethtool |
| ethtool --version 2>/dev/null >/dev/null |
| if [ $? -ne 0 ];then |
| echo "SKIP: ethtool not present" |
| return $ksft_skip |
| fi |
| |
| TMP_ETHTOOL_FEATURES="$(mktemp)" |
| if [ ! -e "$TMP_ETHTOOL_FEATURES" ];then |
| echo "SKIP: Cannot create a tmp file" |
| return 1 |
| fi |
| |
| ethtool -k "$netdev" > "$TMP_ETHTOOL_FEATURES" |
| if [ $? -ne 0 ];then |
| echo "FAIL: $netdev: ethtool list features" |
| rm "$TMP_ETHTOOL_FEATURES" |
| return 1 |
| fi |
| echo "PASS: $netdev: ethtool list features" |
| |
| while read -r FEATURE VALUE FIXED; do |
| [ "$FEATURE" != "Features" ] || continue # Skip "Features" |
| [ "$FIXED" != "[fixed]" ] || continue # Skip fixed features |
| feature="${FEATURE%:*}" |
| |
| ethtool --offload "$netdev" "$feature" off |
| if [ $? -eq 0 ]; then |
| echo "PASS: $netdev: Turned off feature: $feature" |
| else |
| echo "FAIL: $netdev: Failed to turn off feature:" \ |
| "$feature" |
| fi |
| |
| ethtool --offload "$netdev" "$feature" on |
| if [ $? -eq 0 ]; then |
| echo "PASS: $netdev: Turned on feature: $feature" |
| else |
| echo "FAIL: $netdev: Failed to turn on feature:" \ |
| "$feature" |
| fi |
| |
| #restore the feature to its initial state |
| ethtool --offload "$netdev" "$feature" "$VALUE" |
| if [ $? -eq 0 ]; then |
| echo "PASS: $netdev: Restore feature $feature" \ |
| "to initial state $VALUE" |
| else |
| echo "FAIL: $netdev: Failed to restore feature" \ |
| "$feature to initial state $VALUE" |
| fi |
| |
| done < "$TMP_ETHTOOL_FEATURES" |
| |
| rm "$TMP_ETHTOOL_FEATURES" |
| |
| kci_netdev_ethtool_test 74 'dump' "ethtool -d $netdev" |
| kci_netdev_ethtool_test 94 'stats' "ethtool -S $netdev" |
| |
| return 0 |
| } |
| |
| # stop a netdev |
| # arg1: network interface name |
| kci_netdev_stop() |
| { |
| netdev=$1 |
| |
| if [ $NETDEV_STARTED -eq 0 ];then |
| echo "SKIP: $netdev: interface kept up" |
| return 0 |
| fi |
| |
| ip link set "$netdev" down |
| if [ $? -ne 0 ];then |
| echo "FAIL: $netdev: stop interface" |
| return 1 |
| fi |
| echo "PASS: $netdev: stop interface" |
| return 0 |
| } |
| |
| # run all test on a netdev |
| # arg1: network interface name |
| kci_test_netdev() |
| { |
| NETDEV_STARTED=0 |
| IFACE_TO_UPDOWN="$1" |
| IFACE_TO_TEST="$1" |
| #check for VLAN interface |
| MASTER_IFACE="$(echo $1 | cut -d@ -f2)" |
| if [ ! -z "$MASTER_IFACE" ];then |
| IFACE_TO_UPDOWN="$MASTER_IFACE" |
| IFACE_TO_TEST="$(echo $1 | cut -d@ -f1)" |
| fi |
| |
| NETDEV_STARTED=0 |
| kci_net_start "$IFACE_TO_UPDOWN" |
| |
| kci_net_setup "$IFACE_TO_TEST" |
| |
| kci_netdev_ethtool "$IFACE_TO_TEST" |
| |
| kci_netdev_stop "$IFACE_TO_UPDOWN" |
| return 0 |
| } |
| |
| #check for needed privileges |
| if [ "$(id -u)" -ne 0 ];then |
| echo "SKIP: Need root privileges" |
| exit $ksft_skip |
| fi |
| |
| ip link show 2>/dev/null >/dev/null |
| if [ $? -ne 0 ];then |
| echo "SKIP: Could not run test without the ip tool" |
| exit $ksft_skip |
| fi |
| |
| TMP_LIST_NETDEV="$(mktemp)" |
| if [ ! -e "$TMP_LIST_NETDEV" ];then |
| echo "FAIL: Cannot create a tmp file" |
| exit 1 |
| fi |
| |
| ip link show |grep '^[0-9]' | grep -oE '[[:space:]].*eth[0-9]*:|[[:space:]].*enp[0-9]s[0-9]:' | cut -d\ -f2 | cut -d: -f1> "$TMP_LIST_NETDEV" |
| |
| if [ ! -s "$TMP_LIST_NETDEV" ]; then |
| echo "No valid network device found, creating veth pair" |
| ip link add veth0 type veth peer name veth1 |
| echo "veth0" > "$TMP_LIST_NETDEV" |
| veth_created=1 |
| fi |
| |
| while read netdev |
| do |
| kci_test_netdev "$netdev" |
| done < "$TMP_LIST_NETDEV" |
| |
| #clean up veth interface pair if it was created |
| if [ "$veth_created" ]; then |
| ip link delete veth0 |
| echo "Removed veth pair" |
| fi |
| |
| rm "$TMP_LIST_NETDEV" |
| exit 0 |