linux/tools/testing/selftests/net/unicast_extensions.sh
<<
>>
Prefs
   1#!/bin/sh
   2# SPDX-License-Identifier: GPL-2.0
   3#
   4# By Seth Schoen (c) 2021, for the IPv4 Unicast Extensions Project
   5# Thanks to David Ahern for help and advice on nettest modifications.
   6#
   7# Self-tests for IPv4 address extensions: the kernel's ability to accept
   8# certain traditionally unused or unallocated IPv4 addresses. For each kind
   9# of address, we test for interface assignment, ping, TCP, and forwarding.
  10# Must be run as root (to manipulate network namespaces and virtual
  11# interfaces).
  12#
  13# Things we test for here:
  14#
  15# * Currently the kernel accepts addresses in 0/8 and 240/4 as valid.
  16#
  17# * Notwithstanding that, 0.0.0.0 and 255.255.255.255 cannot be assigned.
  18#
  19# * Currently the kernel DOES NOT accept unicast use of the lowest
  20#   address in an IPv4 subnet (e.g. 192.168.100.0/32 in 192.168.100.0/24).
  21#   This is treated as a second broadcast address, for compatibility
  22#   with 4.2BSD (!).
  23#
  24# * Currently the kernel DOES NOT accept unicast use of any of 127/8.
  25#
  26# * Currently the kernel DOES NOT accept unicast use of any of 224/4.
  27#
  28# These tests provide an easy way to flip the expected result of any
  29# of these behaviors for testing kernel patches that change them.
  30
  31# Kselftest framework requirement - SKIP code is 4.
  32ksft_skip=4
  33
  34# nettest can be run from PATH or from same directory as this selftest
  35if ! which nettest >/dev/null; then
  36        PATH=$PWD:$PATH
  37        if ! which nettest >/dev/null; then
  38                echo "'nettest' command not found; skipping tests"
  39                exit $ksft_skip
  40        fi
  41fi
  42
  43result=0
  44
  45hide_output(){ exec 3>&1 4>&2 >/dev/null 2>/dev/null; }
  46show_output(){ exec >&3 2>&4; }
  47
  48show_result(){
  49        if [ $1 -eq 0 ]; then
  50                printf "TEST: %-60s  [ OK ]\n" "${2}"
  51        else
  52                printf "TEST: %-60s  [FAIL]\n" "${2}"
  53                result=1
  54        fi
  55}
  56
  57_do_segmenttest(){
  58        # Perform a simple set of link tests between a pair of
  59        # IP addresses on a shared (virtual) segment, using
  60        # ping and nettest.
  61        # foo --- bar
  62        # Arguments: ip_a ip_b prefix_length test_description
  63        #
  64        # Caller must set up foo-ns and bar-ns namespaces
  65        # containing linked veth devices foo and bar,
  66        # respectively.
  67
  68        ip -n foo-ns address add $1/$3 dev foo || return 1
  69        ip -n foo-ns link set foo up || return 1
  70        ip -n bar-ns address add $2/$3 dev bar || return 1
  71        ip -n bar-ns link set bar up || return 1
  72
  73        ip netns exec foo-ns timeout 2 ping -c 1 $2 || return 1
  74        ip netns exec bar-ns timeout 2 ping -c 1 $1 || return 1
  75
  76        nettest -B -N bar-ns -O foo-ns -r $1 || return 1
  77        nettest -B -N foo-ns -O bar-ns -r $2 || return 1
  78
  79        return 0
  80}
  81
  82_do_route_test(){
  83        # Perform a simple set of gateway tests.
  84        #
  85        # [foo] <---> [foo1]-[bar1] <---> [bar]   /prefix
  86        #  host          gateway          host
  87        #
  88        # Arguments: foo_ip foo1_ip bar1_ip bar_ip prefix_len test_description
  89        # Displays test result and returns success or failure.
  90
  91        # Caller must set up foo-ns, bar-ns, and router-ns
  92        # containing linked veth devices foo-foo1, bar1-bar
  93        # (foo in foo-ns, foo1 and bar1 in router-ns, and
  94        # bar in bar-ns).
  95
  96        ip -n foo-ns address add $1/$5 dev foo || return 1
  97        ip -n foo-ns link set foo up || return 1
  98        ip -n foo-ns route add default via $2 || return 1
  99        ip -n bar-ns address add $4/$5 dev bar || return 1
 100        ip -n bar-ns link set bar up || return 1
 101        ip -n bar-ns route add default via $3 || return 1
 102        ip -n router-ns address add $2/$5 dev foo1 || return 1
 103        ip -n router-ns link set foo1 up || return 1
 104        ip -n router-ns address add $3/$5 dev bar1 || return 1
 105        ip -n router-ns link set bar1 up || return 1
 106
 107        echo 1 | ip netns exec router-ns tee /proc/sys/net/ipv4/ip_forward
 108
 109        ip netns exec foo-ns timeout 2 ping -c 1 $2 || return 1
 110        ip netns exec foo-ns timeout 2 ping -c 1 $4 || return 1
 111        ip netns exec bar-ns timeout 2 ping -c 1 $3 || return 1
 112        ip netns exec bar-ns timeout 2 ping -c 1 $1 || return 1
 113
 114        nettest -B -N bar-ns -O foo-ns -r $1 || return 1
 115        nettest -B -N foo-ns -O bar-ns -r $4 || return 1
 116
 117        return 0
 118}
 119
 120segmenttest(){
 121        # Sets up veth link and tries to connect over it.
 122        # Arguments: ip_a ip_b prefix_len test_description
 123        hide_output
 124        ip netns add foo-ns
 125        ip netns add bar-ns
 126        ip link add foo netns foo-ns type veth peer name bar netns bar-ns
 127
 128        test_result=0
 129        _do_segmenttest "$@" || test_result=1
 130
 131        ip netns pids foo-ns | xargs -r kill -9
 132        ip netns pids bar-ns | xargs -r kill -9
 133        ip netns del foo-ns
 134        ip netns del bar-ns
 135        show_output
 136
 137        # inverted tests will expect failure instead of success
 138        [ -n "$expect_failure" ] && test_result=`expr 1 - $test_result`
 139
 140        show_result $test_result "$4"
 141}
 142
 143route_test(){
 144        # Sets up a simple gateway and tries to connect through it.
 145        # [foo] <---> [foo1]-[bar1] <---> [bar]   /prefix
 146        # Arguments: foo_ip foo1_ip bar1_ip bar_ip prefix_len test_description
 147        # Returns success or failure.
 148
 149        hide_output
 150        ip netns add foo-ns
 151        ip netns add bar-ns
 152        ip netns add router-ns
 153        ip link add foo netns foo-ns type veth peer name foo1 netns router-ns
 154        ip link add bar netns bar-ns type veth peer name bar1 netns router-ns
 155
 156        test_result=0
 157        _do_route_test "$@" || test_result=1
 158
 159        ip netns pids foo-ns | xargs -r kill -9
 160        ip netns pids bar-ns | xargs -r kill -9
 161        ip netns pids router-ns | xargs -r kill -9
 162        ip netns del foo-ns
 163        ip netns del bar-ns
 164        ip netns del router-ns
 165
 166        show_output
 167
 168        # inverted tests will expect failure instead of success
 169        [ -n "$expect_failure" ] && test_result=`expr 1 - $test_result`
 170        show_result $test_result "$6"
 171}
 172
 173echo "###########################################################################"
 174echo "Unicast address extensions tests (behavior of reserved IPv4 addresses)"
 175echo "###########################################################################"
 176#
 177# Test support for 240/4
 178segmenttest 240.1.2.1   240.1.2.4    24 "assign and ping within 240/4 (1 of 2) (is allowed)"
 179segmenttest 250.100.2.1 250.100.30.4 16 "assign and ping within 240/4 (2 of 2) (is allowed)"
 180#
 181# Test support for 0/8
 182segmenttest 0.1.2.17    0.1.2.23  24 "assign and ping within 0/8 (1 of 2) (is allowed)"
 183segmenttest 0.77.240.17 0.77.2.23 16 "assign and ping within 0/8 (2 of 2) (is allowed)"
 184#
 185# Even 255.255/16 is OK!
 186segmenttest 255.255.3.1 255.255.50.77 16 "assign and ping inside 255.255/16 (is allowed)"
 187#
 188# Or 255.255.255/24
 189segmenttest 255.255.255.1 255.255.255.254 24 "assign and ping inside 255.255.255/24 (is allowed)"
 190#
 191# Routing between different networks
 192route_test 240.5.6.7 240.5.6.1  255.1.2.1    255.1.2.3      24 "route between 240.5.6/24 and 255.1.2/24 (is allowed)"
 193route_test 0.200.6.7 0.200.38.1 245.99.101.1 245.99.200.111 16 "route between 0.200/16 and 245.99/16 (is allowed)"
 194#
 195# Test support for lowest address ending in .0
 196segmenttest 5.10.15.20 5.10.15.0 24 "assign and ping lowest address (/24)"
 197#
 198# Test support for lowest address not ending in .0
 199segmenttest 192.168.101.192 192.168.101.193 26 "assign and ping lowest address (/26)"
 200#
 201# Routing using lowest address as a gateway/endpoint
 202route_test 192.168.42.1 192.168.42.0 9.8.7.6 9.8.7.0 24 "routing using lowest address"
 203#
 204# ==============================================
 205# ==== TESTS THAT CURRENTLY EXPECT FAILURE =====
 206# ==============================================
 207expect_failure=true
 208# It should still not be possible to use 0.0.0.0 or 255.255.255.255
 209# as a unicast address.  Thus, these tests expect failure.
 210segmenttest 0.0.1.5       0.0.0.0         16 "assigning 0.0.0.0 (is forbidden)"
 211segmenttest 255.255.255.1 255.255.255.255 16 "assigning 255.255.255.255 (is forbidden)"
 212#
 213# Test support for not having all of 127 be loopback
 214# Currently Linux does not allow this, so this should fail too
 215segmenttest 127.99.4.5 127.99.4.6 16 "assign and ping inside 127/8 (is forbidden)"
 216#
 217# Test support for unicast use of class D
 218# Currently Linux does not allow this, so this should fail too
 219segmenttest 225.1.2.3 225.1.2.200 24 "assign and ping class D address (is forbidden)"
 220#
 221# Routing using class D as a gateway
 222route_test 225.1.42.1 225.1.42.2 9.8.7.6 9.8.7.1 24 "routing using class D (is forbidden)"
 223#
 224# Routing using 127/8
 225# Currently Linux does not allow this, so this should fail too
 226route_test 127.99.2.3 127.99.2.4 200.1.2.3 200.1.2.4 24 "routing using 127/8 (is forbidden)"
 227#
 228unset expect_failure
 229# =====================================================
 230# ==== END OF TESTS THAT CURRENTLY EXPECT FAILURE =====
 231# =====================================================
 232exit ${result}
 233