ipvtap_test.sh 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #!/bin/bash
  2. # SPDX-License-Identifier: GPL-2.0
  3. #
  4. # Simple tests for ipvtap
  5. #
  6. # The testing environment looks this way:
  7. #
  8. # |------HNS-------| |------PHY-------|
  9. # | veth<----------------->veth |
  10. # |------|--|------| |----------------|
  11. # | |
  12. # | | |-----TST0-------|
  13. # | |------------|----ipvlan |
  14. # | |----------------|
  15. # |
  16. # | |-----TST1-------|
  17. # |---------------|----ipvlan |
  18. # |----------------|
  19. #
  20. ALL_TESTS="
  21. test_ip_set
  22. "
  23. source lib.sh
  24. DEBUG=0
  25. VETH_HOST=vethtst.h
  26. VETH_PHY=vethtst.p
  27. NS_COUNT=32
  28. IP_ITERATIONS=1024
  29. IPSET_TIMEOUT="60s"
  30. ns_run() {
  31. ns=$1
  32. shift
  33. if [[ "$ns" == "global" ]]; then
  34. "$@" >/dev/null
  35. else
  36. ip netns exec "$ns" "$@" >/dev/null
  37. fi
  38. }
  39. test_ip_setup_env() {
  40. setup_ns NS_PHY
  41. setup_ns HST_NS
  42. # setup simulated other-host (phy) and host itself
  43. ns_run "$HST_NS" ip link add $VETH_HOST type veth peer name $VETH_PHY \
  44. netns "$NS_PHY" >/dev/null
  45. ns_run "$HST_NS" ip link set $VETH_HOST up
  46. ns_run "$NS_PHY" ip link set $VETH_PHY up
  47. for ((i=0; i<NS_COUNT; i++)); do
  48. setup_ns ipvlan_ns_$i
  49. ns="ipvlan_ns_$i"
  50. if [ "$DEBUG" = "1" ]; then
  51. echo "created NS ${!ns}"
  52. fi
  53. if ! ns_run "$HST_NS" ip link add netns ${!ns} ipvlan0 \
  54. link $VETH_HOST \
  55. type ipvtap mode l2 bridge; then
  56. exit_error "FAIL: Failed to configure ipvlan link."
  57. fi
  58. done
  59. }
  60. test_ip_cleanup_env() {
  61. ns_run "$HST_NS" ip link del $VETH_HOST
  62. cleanup_all_ns
  63. }
  64. exit_error() {
  65. echo "$1"
  66. exit $ksft_fail
  67. }
  68. rnd() {
  69. echo $(( RANDOM % 32 + 16 ))
  70. }
  71. test_ip_set_thread() {
  72. # Here we are trying to create some IP conflicts between namespaces.
  73. # If just add/remove IP, nothing interesting will happen.
  74. # But if add random IP and then remove random IP,
  75. # eventually conflicts start to apear.
  76. ip link set ipvlan0 up
  77. for ((i=0; i<IP_ITERATIONS; i++)); do
  78. v=$(rnd)
  79. ip a a "172.25.0.$v/24" dev ipvlan0 2>/dev/null
  80. ip a a "fc00::$v/64" dev ipvlan0 2>/dev/null
  81. v=$(rnd)
  82. ip a d "172.25.0.$v/24" dev ipvlan0 2>/dev/null
  83. ip a d "fc00::$v/64" dev ipvlan0 2>/dev/null
  84. done
  85. }
  86. test_ip_set() {
  87. RET=0
  88. trap test_ip_cleanup_env EXIT
  89. test_ip_setup_env
  90. declare -A ns_pids
  91. for ((i=0; i<NS_COUNT; i++)); do
  92. ns="ipvlan_ns_$i"
  93. ns_run ${!ns} timeout "$IPSET_TIMEOUT" \
  94. bash -c "$0 test_ip_set_thread"&
  95. ns_pids[$i]=$!
  96. done
  97. for ((i=0; i<NS_COUNT; i++)); do
  98. wait "${ns_pids[$i]}"
  99. done
  100. declare -A all_ips
  101. for ((i=0; i<NS_COUNT; i++)); do
  102. ns="ipvlan_ns_$i"
  103. ip_output=$(ip netns exec ${!ns} ip a l dev ipvlan0 | grep inet)
  104. while IFS= read -r nsip_out; do
  105. if [[ -z $nsip_out ]]; then
  106. continue;
  107. fi
  108. nsip=$(awk '{print $2}' <<< "$nsip_out")
  109. if [[ -v all_ips[$nsip] ]]; then
  110. RET=$ksft_fail
  111. log_test "conflict for $nsip"
  112. return "$RET"
  113. else
  114. all_ips[$nsip]=$i
  115. fi
  116. done <<< "$ip_output"
  117. done
  118. if [ "$DEBUG" = "1" ]; then
  119. for key in "${!all_ips[@]}"; do
  120. echo "$key: ${all_ips[$key]}"
  121. done
  122. fi
  123. trap - EXIT
  124. test_ip_cleanup_env
  125. log_test "test multithreaded ip set"
  126. }
  127. if [[ "$1" == "-d" ]]; then
  128. DEBUG=1
  129. shift
  130. fi
  131. if [[ "$1" == "-t" ]]; then
  132. shift
  133. TESTS="$*"
  134. fi
  135. if [[ "$1" == "test_ip_set_thread" ]]; then
  136. test_ip_set_thread
  137. else
  138. require_command ip
  139. tests_run
  140. fi