1#!/bin/sh 2# SPDX-License-Identifier: GPL-2.0-or-later 3# Copyright (c) 2014-2017 Oracle and/or its affiliates. All Rights Reserved. 4# Copyright (c) 2016-2019 Petr Vorel <pvorel@suse.cz> 5# Author: Alexey Kodanev <alexey.kodanev@oracle.com> 6 7[ -n "$TST_LIB_NET_LOADED" ] && return 0 8TST_LIB_NET_LOADED=1 9 10TST_OPTS="6$TST_OPTS" 11TST_PARSE_ARGS_CALLER="$TST_PARSE_ARGS" 12TST_PARSE_ARGS="tst_net_parse_args" 13TST_USAGE_CALLER="$TST_USAGE" 14TST_USAGE="tst_net_usage" 15TST_SETUP_CALLER="$TST_SETUP" 16TST_SETUP="tst_net_setup" 17 18# Blank for an IPV4 test; 6 for an IPV6 test. 19TST_IPV6=${TST_IPV6:-} 20TST_IPVER=${TST_IPV6:-4} 21 22tst_net_parse_args() 23{ 24 case $1 in 25 6) TST_IPV6=6 TST_IPVER=6;; 26 *) $TST_PARSE_ARGS_CALLER "$1" "$2";; 27 esac 28} 29 30tst_net_read_opts() 31{ 32 local OPTIND 33 while getopts ":$TST_OPTS" opt; do 34 $TST_PARSE_ARGS "$opt" "$OPTARG" 35 done 36} 37 38tst_net_usage() 39{ 40 if [ -n "$TST_USAGE_CALLER" ]; then 41 $TST_USAGE_CALLER 42 else 43 echo "Usage: $0 [-6]" 44 echo "OPTIONS" 45 fi 46 echo "-6 IPv6 tests" 47} 48 49tst_net_remote_tmpdir() 50{ 51 [ "$TST_NEEDS_TMPDIR" = 1 ] || return 0 52 [ -n "$TST_USE_LEGACY_API" ] && tst_tmpdir 53 tst_rhost_run -c "mkdir -p $TST_TMPDIR" 54 tst_rhost_run -c "chmod 777 $TST_TMPDIR" 55 export TST_TMPDIR_RHOST=1 56} 57 58tst_net_setup() 59{ 60 tst_net_remote_tmpdir 61 [ -n "$TST_SETUP_CALLER" ] && $TST_SETUP_CALLER 62 63 if [ -z "$NS_ICMP_SENDER_DATA_MAXSIZE" ]; then 64 if [ "$TST_IPV6" ]; then 65 NS_ICMP_SENDER_DATA_MAXSIZE="$NS_ICMPV6_SENDER_DATA_MAXSIZE" 66 else 67 NS_ICMP_SENDER_DATA_MAXSIZE="$NS_ICMPV4_SENDER_DATA_MAXSIZE" 68 fi 69 fi 70} 71 72[ -n "$TST_USE_LEGACY_API" ] && . test.sh || . tst_test.sh 73 74if [ "$TST_PARSE_ARGS_CALLER" = "$TST_PARSE_ARGS" ]; then 75 tst_res TWARN "TST_PARSE_ARGS_CALLER same as TST_PARSE_ARGS, unset it ($TST_PARSE_ARGS)" 76 unset TST_PARSE_ARGS_CALLER 77fi 78if [ "$TST_SETUP_CALLER" = "$TST_SETUP" ]; then 79 tst_res TWARN "TST_SETUP_CALLER same as TST_SETUP, unset it ($TST_SETUP)" 80 unset TST_SETUP_CALLER 81fi 82if [ "$TST_USAGE_CALLER" = "$TST_USAGE" ]; then 83 tst_res TWARN "TST_USAGE_CALLER same as TST_USAGE, unset it ($TST_USAGE)" 84 unset TST_USAGE_CALLER 85fi 86 87if [ -n "$TST_USE_LEGACY_API" ]; then 88 tst_net_read_opts "$@" 89fi 90 91# old vs. new API compatibility layer 92tst_res_() 93{ 94 [ -z "$TST_USE_LEGACY_API" ] && tst_res $@ || tst_resm $@ 95} 96tst_brk_() 97{ 98 [ -z "$TST_USE_LEGACY_API" ] && tst_brk $@ || tst_brkm $@ 99} 100tst_require_root_() 101{ 102 if [ -z "$TST_USE_LEGACY_API" ]; then 103 _tst_require_root 104 else 105 tst_require_root 106 fi 107} 108 109init_ltp_netspace() 110{ 111 local pid 112 113 if [ ! -f /var/run/netns/ltp_ns -a -z "$LTP_NETNS" ]; then 114 tst_require_cmds ip 115 tst_require_root_ 116 117 ROD ip li add name ltp_ns_veth1 type veth peer name ltp_ns_veth2 118 pid="$(ROD ns_create net,mnt)" 119 mkdir -p /var/run/netns 120 ROD ln -s /proc/$pid/ns/net /var/run/netns/ltp_ns 121 ROD ns_exec $pid net,mnt mount --make-rprivate /sys 122 ROD ns_exec $pid net,mnt mount -t sysfs none /sys 123 ROD ns_ifmove ltp_ns_veth1 $pid 124 ROD ns_exec $pid net,mnt ip li set lo up 125 elif [ -n "$LTP_NETNS" ]; then 126 tst_res_ TINFO "using not default LTP netns: '$LTP_NETNS'" 127 fi 128 129 LHOST_IFACES="${LHOST_IFACES:-ltp_ns_veth2}" 130 RHOST_IFACES="${RHOST_IFACES:-ltp_ns_veth1}" 131 132 export TST_INIT_NETNS="no" 133 134 pid="$(echo $(readlink /var/run/netns/ltp_ns) | cut -f3 -d'/')" 135 export LTP_NETNS="${LTP_NETNS:-ns_exec $pid net,mnt}" 136 137 tst_restore_ipaddr 138 tst_restore_ipaddr rhost 139} 140 141# Run command on remote host. 142# Options: 143# -b run in background 144# -s safe option, if something goes wrong, will exit with TBROK 145# -c specify command to run (this must be binary, not shell builtin/function) 146# RETURN: 0 on success, 1 on failure 147tst_rhost_run() 148{ 149 local pre_cmd= 150 local post_cmd=' || echo RTERR' 151 local out= 152 local user="root" 153 local cmd= 154 local safe=0 155 156 OPTIND=0 157 158 while getopts :bsc:u: opt; do 159 case "$opt" in 160 b) [ "$TST_USE_NETNS" ] && pre_cmd= || pre_cmd="nohup" 161 post_cmd=" > /dev/null 2>&1 &" 162 out="1> /dev/null" 163 ;; 164 s) safe=1 ;; 165 c) cmd="$OPTARG" ;; 166 u) user="$OPTARG" ;; 167 *) tst_brk_ TBROK "tst_rhost_run: unknown option: $OPTARG" ;; 168 esac 169 done 170 171 OPTIND=0 172 173 if [ -z "$cmd" ]; then 174 [ "$safe" -eq 1 ] && \ 175 tst_brk_ TBROK "tst_rhost_run: command not defined" 176 tst_res_ TWARN "tst_rhost_run: command not defined" 177 return 1 178 fi 179 180 local output= 181 local ret=0 182 if [ -n "${TST_USE_SSH:-}" ]; then 183 output=`ssh -n -q $user@$RHOST "sh -c \ 184 '$pre_cmd $cmd $post_cmd'" $out 2>&1 || echo 'RTERR'` 185 elif [ -n "$TST_USE_NETNS" ]; then 186 output=`$LTP_NETNS sh -c \ 187 "$pre_cmd $cmd $post_cmd" $out 2>&1 || echo 'RTERR'` 188 else 189 output=`rsh -n -l $user $RHOST "sh -c \ 190 '$pre_cmd $cmd $post_cmd'" $out 2>&1 || echo 'RTERR'` 191 fi 192 echo "$output" | grep -q 'RTERR$' && ret=1 193 if [ $ret -eq 1 ]; then 194 output=$(echo "$output" | sed 's/RTERR//') 195 [ "$safe" -eq 1 ] && \ 196 tst_brk_ TBROK "'$cmd' failed on '$RHOST': '$output'" 197 fi 198 199 [ -z "$out" -a -n "$output" ] && echo "$output" 200 201 return $ret 202} 203 204# Run command on both lhost and rhost. 205# tst_net_run [-s] [-l LPARAM] [-r RPARAM] [ -q ] CMD [ARG [ARG2]] 206# Options: 207# -l LPARAM: parameter passed to CMD in lhost 208# -r RPARAM: parameter passed to CMD in rhost 209# -q: quiet mode (suppress failure warnings) 210# CMD: command to run (this must be binary, not shell builtin/function due 211# tst_rhost_run() limitation) 212# RETURN: 0 on success, 1 on missing CMD or exit code on lhost or rhost 213tst_net_run() 214{ 215 local cmd 216 local lparams 217 local rparams 218 local lsafe 219 local rsafe 220 local lret 221 local rret 222 local quiet 223 224 local OPTIND 225 while getopts l:qr:s opt; do 226 case "$opt" in 227 l) lparams="$OPTARG" ;; 228 q) quiet=1 ;; 229 r) rparams="$OPTARG" ;; 230 s) lsafe="ROD"; rsafe="-s" ;; 231 *) tst_brk_ TBROK "tst_net_run: unknown option: $OPTARG" ;; 232 esac 233 done 234 shift $((OPTIND - 1)) 235 cmd="$1" 236 shift 237 238 if [ -z "$cmd" ]; then 239 [ -n "$lsafe" ] && \ 240 tst_brk_ TBROK "tst_net_run: command not defined" 241 tst_res_ TWARN "tst_net_run: command not defined" 242 return 1 243 fi 244 245 $lsafe $cmd $lparams $@ 246 lret=$? 247 tst_rhost_run $rsafe -c "$cmd $rparams $@" 248 rret=$? 249 250 if [ -z "$quiet" ]; then 251 [ $lret -ne 0 ] && tst_res_ TWARN "tst_net_run: lhost command failed: $lret" 252 [ $rret -ne 0 ] && tst_res_ TWARN "tst_net_run: rhost command failed: $rret" 253 fi 254 255 [ $lret -ne 0 ] && return $lret 256 return $rret 257} 258 259EXPECT_RHOST_PASS() 260{ 261 tst_rhost_run -c "$*" > /dev/null 262 if [ $? -eq 0 ]; then 263 tst_res_ TPASS "$* passed as expected" 264 else 265 tst_res_ TFAIL "$* failed unexpectedly" 266 fi 267} 268 269EXPECT_RHOST_FAIL() 270{ 271 tst_rhost_run -c "$* 2> /dev/null" 272 if [ $? -ne 0 ]; then 273 tst_res_ TPASS "$* failed as expected" 274 else 275 tst_res_ TFAIL "$* passed unexpectedly" 276 fi 277} 278 279# Get test interface names for local/remote host. 280# tst_get_ifaces [TYPE] 281# TYPE: { lhost | rhost }; Default value is 'lhost'. 282tst_get_ifaces() 283{ 284 local type="${1:-lhost}" 285 if [ "$type" = "lhost" ]; then 286 echo "$LHOST_IFACES" 287 else 288 echo "$RHOST_IFACES" 289 fi 290} 291 292# Get count of test interfaces for local/remote host. 293tst_get_ifaces_cnt() 294{ 295 tst_require_cmds awk 296 local type="${1:-lhost}" 297 echo "$(tst_get_ifaces $type)" | awk '{print NF}' 298} 299 300# Get HW addresses from defined test interface names. 301# tst_get_hwaddrs [TYPE] 302# TYPE: { lhost | rhost }; Default value is 'lhost'. 303tst_get_hwaddrs() 304{ 305 local type="${1:-lhost}" 306 local addr= 307 local list= 308 309 for eth in $(tst_get_ifaces $type); do 310 311 local addr_path="/sys/class/net/${eth}/address" 312 313 case $type in 314 lhost) addr=$(cat $addr_path) ;; 315 rhost) addr=$(tst_rhost_run -s -c "cat $addr_path") 316 esac 317 318 [ -z "$list" ] && list="$addr" || list="$list $addr" 319 done 320 echo "$list" 321} 322 323# Get test HW address. 324# tst_hwaddr [TYPE] [LINK] 325# TYPE: { lhost | rhost }; Default value is 'lhost'. 326# LINK: link number starting from 0. Default value is '0'. 327tst_hwaddr() 328{ 329 tst_require_cmds awk 330 331 local type="${1:-lhost}" 332 local link_num="${2:-0}" 333 local hwaddrs= 334 link_num=$(( $link_num + 1 )) 335 [ "$type" = "lhost" ] && hwaddrs=$LHOST_HWADDRS || hwaddrs=$RHOST_HWADDRS 336 echo "$hwaddrs" | awk '{ print $'"$link_num"' }' 337} 338 339# Get test interface name. 340# tst_iface [TYPE] [LINK] 341# TYPE: { lhost | rhost }; Default value is 'lhost'. 342# LINK: link number starting from 0. Default value is '0'. 343tst_iface() 344{ 345 tst_require_cmds awk 346 347 local type="${1:-lhost}" 348 local link_num="${2:-0}" 349 link_num="$(( $link_num + 1 ))" 350 echo "$(tst_get_ifaces $type)" | awk '{ print $'"$link_num"' }' 351} 352 353# Get IP address 354# tst_ipaddr [TYPE] 355# TYPE: { lhost | rhost }; Default value is 'lhost'. 356tst_ipaddr() 357{ 358 local type="${1:-lhost}" 359 if [ "$TST_IPV6" ]; then 360 [ "$type" = "lhost" ] && echo "$IPV6_LHOST" || echo "$IPV6_RHOST" 361 else 362 [ "$type" = "lhost" ] && echo "$IPV4_LHOST" || echo "$IPV4_RHOST" 363 fi 364} 365 366# Get IP address of unused network, specified either counter and type 367# or by net and host. 368# counter mode: 369# tst_ipaddr_un [-h MIN,MAX] [-n MIN,MAX] [-p] [-c COUNTER] [TYPE] 370# net & host mode: 371# tst_ipaddr_un [-h MIN,MAX] [-n MIN,MAX] [-p] NET_ID [HOST_ID] 372# 373# TYPE: { lhost | rhost } (default: 'lhost') 374# NET_ID: integer or hex value of net (IPv4: 3rd octet <0,255>, IPv6: 3rd 375# hextet <0,65535>) 376# HOST_ID: integer or hex value of host (IPv4: 4th octet <0,255>, IPv6: the 377# last hextet <0, 65535>, default: 0) 378# 379# OPTIONS 380# -c COUNTER: integer value for counting HOST_ID and NET_ID (default: 1) 381# 382# -h: specify *host* address range (HOST_ID) 383# -h MIN,MAX or -h MIN or -h ,MAX 384# 385# -n: specify *network* address range (NET_ID) 386# -n MIN,MAX or -n MIN or -n ,MAX 387# 388# -p: print also prefix 389tst_ipaddr_un() 390{ 391 local default_max=255 392 [ "$TST_IPV6" ] && default_max=65535 393 local max_net_id=$default_max 394 local min_net_id=0 395 396 local counter host_id host_range is_counter max_host_id min_host_id net_id prefix tmp type 397 398 local OPTIND 399 while getopts "c:h:n:p" opt; do 400 case $opt in 401 c) counter="$OPTARG";; 402 h) 403 if echo $OPTARG | grep -q ','; then # 'min,max' or 'min,' or ',max' 404 min_host_id="$(echo $OPTARG | cut -d, -f1)" 405 max_host_id="$(echo $OPTARG | cut -d, -f2)" 406 else # min 407 min_host_id="$OPTARG" 408 fi 409 ;; 410 n) 411 if echo $OPTARG | grep -q ','; then # 'min,max' or 'min,' or ',max' 412 min_net_id="$(echo $OPTARG | cut -d, -f1)" 413 max_net_id="$(echo $OPTARG | cut -d, -f2)" 414 else # min 415 min_net_id="$OPTARG" 416 fi 417 ;; 418 m) 419 ! tst_is_int "$OPTARG" || [ "$OPTARG" -lt 0 ]|| [ "$OPTARG" -gt $max_net_id ] && \ 420 tst_brk TBROK "tst_ipaddr_un: -m must be integer <0,$max_net_id> ($OPTARG)" 421 [ "$OPTARG" -gt $max_net_id ] && \ 422 tst_brk_ TBROK "tst_ipaddr_un: -m cannot be higher than $max_net_id ($OPTARG)" 423 max_host_id="$OPTARG" 424 ;; 425 p) [ "$TST_IPV6" ] && prefix="/64" || prefix="/24";; 426 esac 427 done 428 shift $(($OPTIND - 1)) 429 [ $# -eq 0 -o "$1" = "lhost" -o "$1" = "rhost" ] && is_counter=1 430 431 if [ -z "$min_host_id" ]; then 432 [ "$is_counter" ] && min_host_id=1 || min_host_id=0 433 fi 434 if [ -z "$max_host_id" ]; then 435 [ "$is_counter" ] && max_host_id=$((default_max - 1)) || max_host_id=$default_max 436 fi 437 438 ! tst_is_int "$min_host_id" || ! tst_is_int "$max_host_id" || \ 439 [ $min_host_id -lt 0 -o $min_host_id -gt $default_max ] || \ 440 [ $max_host_id -lt 0 -o $max_host_id -gt $default_max ] && \ 441 tst_brk TBROK "tst_ipaddr_un: HOST_ID must be int in range <0,$default_max> ($min_host_id,$max_host_id)" 442 ! tst_is_int "$min_net_id" || ! tst_is_int "$max_net_id" || \ 443 [ $min_net_id -lt 0 -o $min_net_id -gt $default_max ] || \ 444 [ $max_net_id -lt 0 -o $max_net_id -gt $default_max ] && \ 445 tst_brk TBROK "tst_ipaddr_un: NET_ID must be int in range <0,$default_max> ($min_net_id,$max_net_id)" 446 447 [ $min_host_id -gt $max_host_id ] && \ 448 tst_brk TBROK "tst_ipaddr_un: max HOST_ID ($max_host_id) must be >= min HOST_ID ($min_host_id)" 449 [ $min_net_id -gt $max_net_id ] && \ 450 tst_brk TBROK "tst_ipaddr_un: max NET_ID ($max_net_id) must be >= min NET_ID ($min_net_id)" 451 452 # counter 453 host_range=$((max_host_id - min_host_id + 1)) 454 if [ "$is_counter" ]; then 455 [ -z "$counter" ] && counter=1 456 [ $counter -lt 1 ] && counter=1 457 type="${1:-lhost}" 458 tmp=$((counter * 2)) 459 [ "$type" = "rhost" ] && tmp=$((tmp - 1)) 460 net_id=$(((tmp - 1) / host_range)) 461 host_id=$((tmp - net_id * host_range + min_host_id - 1)) 462 else # net_id & host_id 463 net_id="$1" 464 host_id="${2:-0}" 465 if [ "$TST_IPV6" ]; then 466 net_id=$(printf %d $net_id) 467 host_id=$(printf %d $host_id) 468 fi 469 host_id=$((host_id % host_range + min_host_id)) 470 fi 471 472 net_id=$((net_id % (max_net_id - min_net_id + 1) + min_net_id)) 473 474 if [ -z "$TST_IPV6" ]; then 475 echo "${IPV4_NET16_UNUSED}.${net_id}.${host_id}${prefix}" 476 return 477 fi 478 479 [ $host_id -gt 0 ] && host_id="$(printf %x $host_id)" || host_id= 480 [ $net_id -gt 0 ] && net_id="$(printf %x $net_id)" || net_id= 481 [ "$net_id" ] && net_id=":$net_id" 482 echo "${IPV6_NET32_UNUSED}${net_id}::${host_id}${prefix}" 483} 484 485# tst_init_iface [TYPE] [LINK] 486# TYPE: { lhost | rhost }; Default value is 'lhost'. 487# LINK: link number starting from 0. Default value is '0'. 488tst_init_iface() 489{ 490 local type="${1:-lhost}" 491 local link_num="${2:-0}" 492 local iface="$(tst_iface $type $link_num)" 493 tst_res_ TINFO "initialize '$type' '$iface' interface" 494 495 if [ "$type" = "lhost" ]; then 496 if ip xfrm state 1>/dev/null 2>&1; then 497 ip xfrm policy flush || return $? 498 ip xfrm state flush || return $? 499 fi 500 ip link set $iface down || return $? 501 ip route flush dev $iface || return $? 502 ip addr flush dev $iface || return $? 503 ip link set $iface up 504 return $? 505 fi 506 507 if tst_rhost_run -c "ip xfrm state 1>/dev/null 2>&1"; then 508 tst_rhost_run -c "ip xfrm policy flush" || return $? 509 tst_rhost_run -c "ip xfrm state flush" || return $? 510 fi 511 tst_rhost_run -c "ip link set $iface down" || return $? 512 tst_rhost_run -c "ip route flush dev $iface" || return $? 513 tst_rhost_run -c "ip addr flush dev $iface" || return $? 514 tst_rhost_run -c "ip link set $iface up" 515} 516 517# tst_add_ipaddr [TYPE] [LINK] [-a IP] [-d] [-q] [-s] 518# Options: 519# TYPE: { lhost | rhost }, default value is 'lhost' 520# LINK: link number starting from 0, default value is '0' 521# -a IP: IP address to be added, default value is 522# $(tst_ipaddr)/$IPV{4,6}_{L,R}PREFIX 523# -d: delete address instead of adding 524# -q: quiet mode (don't print info) 525# -s: safe option, if something goes wrong, will exit with TBROK 526tst_add_ipaddr() 527{ 528 local action="add" 529 local addr dad lsafe mask quiet rsafe 530 531 local OPTIND 532 while getopts a:dqs opt; do 533 case "$opt" in 534 a) addr="$OPTARG" ;; 535 d) action="del" ;; 536 q) quiet=1 ;; 537 s) lsafe="ROD"; rsafe="-s" ;; 538 *) tst_brk TBROK "tst_add_ipaddr: unknown option: $OPTARG" ;; 539 esac 540 done 541 shift $((OPTIND - 1)) 542 543 local type="${1:-lhost}" 544 local link_num="${2:-0}" 545 local iface=$(tst_iface $type $link_num) 546 547 if [ "$TST_IPV6" ]; then 548 dad="nodad" 549 [ "$type" = "lhost" ] && mask=$IPV6_LPREFIX || mask=$IPV6_RPREFIX 550 else 551 [ "$type" = "lhost" ] && mask=$IPV4_LPREFIX || mask=$IPV4_RPREFIX 552 fi 553 [ -n "$addr" ] || addr="$(tst_ipaddr $type)" 554 echo $addr | grep -q / || addr="$addr/$mask" 555 556 if [ $type = "lhost" ]; then 557 [ "$quiet" ] || tst_res_ TINFO "$action local addr $addr" 558 $lsafe ip addr $action $addr dev $iface $dad 559 return $? 560 fi 561 562 [ "$quiet" ] || tst_res_ TINFO "$action remote addr $addr" 563 tst_rhost_run $rsafe -c "ip addr $action $addr dev $iface $dad" 564} 565 566# tst_del_ipaddr [ tst_add_ipaddr options ] 567# Delete IP address 568tst_del_ipaddr() 569{ 570 tst_add_ipaddr -d $@ 571} 572 573# tst_restore_ipaddr [TYPE] [LINK] 574# Restore default ip addresses defined in network.sh 575# TYPE: { lhost | rhost }; Default value is 'lhost'. 576# LINK: link number starting from 0. Default value is '0'. 577tst_restore_ipaddr() 578{ 579 tst_require_cmds ip 580 tst_require_root_ 581 582 local type="${1:-lhost}" 583 local link_num="${2:-0}" 584 585 tst_init_iface $type $link_num || return $? 586 587 local ret=0 588 local backup_tst_ipv6=$TST_IPV6 589 TST_IPV6= tst_add_ipaddr $type $link_num || ret=$? 590 TST_IPV6=6 tst_add_ipaddr $type $link_num || ret=$? 591 TST_IPV6=$backup_tst_ipv6 592 593 return $ret 594} 595 596# tst_wait_ipv6_dad [LHOST_IFACE] [RHOST_IFACE] 597# wait for IPv6 DAD completion 598tst_wait_ipv6_dad() 599{ 600 local ret= 601 local i= 602 local iface_loc=${1:-$(tst_iface)} 603 local iface_rmt=${2:-$(tst_iface rhost)} 604 605 for i in $(seq 1 50); do 606 ip a sh $iface_loc | grep -q tentative 607 ret=$? 608 609 tst_rhost_run -c "ip a sh $iface_rmt | grep -q tentative" 610 611 [ $ret -ne 0 -a $? -ne 0 ] && return 612 613 [ $(($i % 10)) -eq 0 ] && \ 614 tst_res_ TINFO "wait for IPv6 DAD completion $((i / 10))/5 sec" 615 616 tst_sleep 100ms 617 done 618} 619 620tst_dump_rhost_cmd() 621{ 622 tst_rhost_run -c "cat $TST_TMPDIR/netstress.log" 623} 624 625# Run network load test, see 'netstress -h' for option description 626tst_netload() 627{ 628 local rfile="tst_netload.res" 629 local expect_res="pass" 630 local ret=0 631 local type="tcp" 632 local hostopt= 633 local setup_srchost=0 634 # common options for client and server 635 local cs_opts= 636 637 local c_num="$TST_NETLOAD_CLN_NUMBER" 638 local c_requests="$TST_NETLOAD_CLN_REQUESTS" 639 local c_opts= 640 641 # number of server replies after which TCP connection is closed 642 local s_replies="${TST_NETLOAD_MAX_SRV_REPLIES:-500000}" 643 local s_opts= 644 local bind_to_device=1 645 646 if [ ! "$TST_NEEDS_TMPDIR" = 1 ]; then 647 tst_brk_ TBROK "Using tst_netload requires setting TST_NEEDS_TMPDIR=1" 648 fi 649 650 OPTIND=0 651 while getopts :a:H:d:n:N:r:R:S:b:t:T:fFe:m:A:D: opt; do 652 case "$opt" in 653 a) c_num="$OPTARG" ;; 654 H) c_opts="${c_opts}-H $OPTARG " 655 hostopt="$OPTARG" ;; 656 d) rfile="$OPTARG" ;; 657 n) c_opts="${c_opts}-n $OPTARG " ;; 658 N) c_opts="${c_opts}-N $OPTARG " ;; 659 r) c_requests="$OPTARG" ;; 660 A) c_opts="${c_opts}-A $OPTARG " ;; 661 R) s_replies="$OPTARG" ;; 662 S) c_opts="${c_opts}-S $OPTARG " 663 setup_srchost=1 ;; 664 b) cs_opts="${cs_opts}-b $OPTARG " ;; 665 t) cs_opts="${cs_opts}-t $OPTARG " ;; 666 T) cs_opts="${cs_opts}-T $OPTARG " 667 type="$OPTARG" ;; 668 m) cs_opts="${cs_opts}-m $OPTARG " ;; 669 f) cs_opts="${cs_opts}-f " ;; 670 F) cs_opts="${cs_opts}-F " ;; 671 e) expect_res="$OPTARG" ;; 672 D) [ "$TST_NETLOAD_BINDTODEVICE" = 1 ] && cs_opts="${cs_opts}-D $OPTARG " 673 bind_to_device=0 ;; 674 *) tst_brk_ TBROK "tst_netload: unknown option: $OPTARG" ;; 675 esac 676 done 677 OPTIND=0 678 679 [ "$setup_srchost" = 1 ] && s_opts="${s_opts}-S $hostopt " 680 681 if [ "$bind_to_device" = 1 -a "$TST_NETLOAD_BINDTODEVICE" = 1 ]; then 682 c_opts="${c_opts}-D $(tst_iface) " 683 s_opts="${s_opts}-D $(tst_iface rhost) " 684 fi 685 686 local expect_ret=0 687 [ "$expect_res" != "pass" ] && expect_ret=3 688 689 tst_rhost_run -c "pkill -9 netstress\$" 690 s_opts="${cs_opts}${s_opts}-R $s_replies -B $TST_TMPDIR" 691 tst_res_ TINFO "run server 'netstress $s_opts'" 692 tst_rhost_run -c "netstress $s_opts" > tst_netload.log 2>&1 693 if [ $? -ne 0 ]; then 694 cat tst_netload.log 695 local ttype="TFAIL" 696 grep -e 'CONF:' tst_netload.log && ttype="TCONF" 697 tst_brk_ $ttype "server failed" 698 fi 699 700 local port=$(tst_rhost_run -s -c "cat $TST_TMPDIR/netstress_port") 701 c_opts="${cs_opts}${c_opts}-a $c_num -r $c_requests -d $rfile -g $port" 702 703 tst_res_ TINFO "run client 'netstress -l $c_opts'" 704 netstress -l $c_opts > tst_netload.log 2>&1 || ret=$? 705 tst_rhost_run -c "pkill -9 netstress\$" 706 707 if [ "$expect_ret" -ne 0 ]; then 708 if [ $((ret & expect_ret)) -ne 0 ]; then 709 tst_res_ TPASS "netstress failed as expected" 710 else 711 tst_res_ TFAIL "expected '$expect_res' but ret: '$ret'" 712 fi 713 return $ret 714 fi 715 716 if [ "$ret" -ne 0 ]; then 717 tst_dump_rhost_cmd 718 cat tst_netload.log 719 [ $((ret & 3)) -ne 0 ] && \ 720 tst_brk_ TFAIL "expected '$expect_res' but ret: '$ret'" 721 [ $((ret & 32)) -ne 0 ] && \ 722 tst_brk_ TCONF "not supported configuration" 723 [ $((ret & 4)) -ne 0 ] && \ 724 tst_res_ TWARN "netstress has warnings" 725 fi 726 727 if [ ! -f $rfile ]; then 728 tst_dump_rhost_cmd 729 cat tst_netload.log 730 tst_brk_ TFAIL "can't read $rfile" 731 fi 732 733 tst_res_ TPASS "netstress passed, time spent '$(cat $rfile)' ms" 734 735 return $ret 736} 737 738# tst_ping [IFACE] [DST ADDR] [MESSAGE SIZE ARRAY] 739# Check icmp connectivity 740# IFACE: source interface name or IP address 741# DST ADDR: destination IPv4 or IPv6 address 742# MESSAGE SIZE ARRAY: message size array 743tst_ping() 744{ 745 # The max number of ICMP echo request 746 PING_MAX="${PING_MAX:-500}" 747 748 local src_iface="${1:-$(tst_iface)}" 749 local dst_addr="${2:-$(tst_ipaddr rhost)}"; shift $(( $# >= 2 ? 2 : 0 )) 750 local msg_sizes="$*" 751 local msg="tst_ping $dst_addr iface/saddr $src_iface, msg_size" 752 local cmd="ping" 753 local ret=0 754 755 echo "$dst_addr" | grep -q ':' && cmd="ping6" 756 tst_require_cmds $cmd 757 758 # ping cmd use 56 as default message size 759 for size in ${msg_sizes:-"56"}; do 760 $cmd -I $src_iface -c $PING_MAX $dst_addr \ 761 -s $size -i 0 > /dev/null 2>&1 762 ret=$? 763 if [ $ret -eq 0 ]; then 764 tst_res_ TPASS "$msg $size: pass" 765 else 766 tst_res_ TFAIL "$msg $size: fail" 767 break 768 fi 769 done 770 return $ret 771} 772 773# tst_icmp -t TIMEOUT -s MESSAGE_SIZE_ARRAY OPTS 774# TIMEOUT: total time for the test in seconds 775# OPTS: additional options for ns-icmpv4|6-sender tool 776tst_icmp() 777{ 778 local timeout=1 779 local msg_sizes=56 780 local opts= 781 local num= 782 local ret=0 783 784 OPTIND=0 785 while getopts :t:s: opt; do 786 case "$opt" in 787 t) timeout="$OPTARG" ;; 788 s) msg_sizes="$OPTARG" ;; 789 *) opts="-$OPTARG $opts" ;; 790 esac 791 done 792 OPTIND=0 793 794 local num=$(echo "$msg_sizes" | wc -w) 795 timeout="$(($timeout / $num))" 796 [ "$timeout" -eq 0 ] && timeout=1 797 798 opts="${opts}-I $(tst_iface) -S $(tst_ipaddr) -D $(tst_ipaddr rhost) " 799 opts="${opts}-M $(tst_hwaddr rhost) -t $timeout" 800 801 for size in $msg_sizes; do 802 ns-icmpv${TST_IPVER}_sender -s $size $opts 803 ret=$? 804 if [ $ret -eq 0 ]; then 805 tst_res_ TPASS "'ns-icmpv${TST_IPVER}_sender -s $size $opts' pass" 806 else 807 tst_res_ TFAIL "'ns-icmpv${TST_IPVER}_sender -s $size $opts' fail" 808 break 809 fi 810 done 811 return $ret 812} 813 814# tst_set_sysctl NAME VALUE [safe] 815# It can handle netns case when sysctl not namespaceified. 816tst_set_sysctl() 817{ 818 local name="$1" 819 local value="$2" 820 local safe= 821 [ "$3" = "safe" ] && safe="-s" 822 823 local rparam= 824 [ "$TST_USE_NETNS" = "yes" ] && rparam="-r '-e'" 825 826 tst_net_run $safe $rparam "sysctl -q -w $name=$value" 827} 828 829tst_cleanup_rhost() 830{ 831 tst_rhost_run -c "rm -rf $TST_TMPDIR" 832} 833 834tst_default_max_pkt() 835{ 836 local mtu="$(cat /sys/class/net/$(tst_iface)/mtu)" 837 838 echo "$((mtu + mtu / 10))" 839} 840 841# Management Link 842[ -z "$RHOST" ] && TST_USE_NETNS="yes" 843export RHOST="$RHOST" 844export PASSWD="${PASSWD:-}" 845# Don't use it in new tests, use tst_rhost_run() from tst_net.sh instead. 846export LTP_RSH="${LTP_RSH:-rsh -n}" 847 848# Test Links 849# IPV{4,6}_{L,R}HOST can be set with or without prefix (e.g. IP or IP/prefix), 850# but if you use IP/prefix form, /prefix will be removed by tst_net_vars. 851IPV4_LHOST="${IPV4_LHOST:-10.0.0.2/24}" 852IPV4_RHOST="${IPV4_RHOST:-10.0.0.1/24}" 853IPV6_LHOST="${IPV6_LHOST:-fd00:1:1:1::2/64}" 854IPV6_RHOST="${IPV6_RHOST:-fd00:1:1:1::1/64}" 855 856# tst_net_ip_prefix 857# Strip prefix from IP address and save both If no prefix found sets 858# default prefix. 859# 860# tst_net_iface_prefix reads prefix and interface from rtnetlink. 861# If nothing found sets default prefix value. 862# 863# tst_net_vars exports environment variables related to test links and 864# networks that aren't reachable through the test links. 865# 866# For full list of exported environment variables see: 867# tst_net_ip_prefix -h 868# tst_net_iface_prefix -h 869# tst_net_vars -h 870if [ -z "$_tst_net_parse_variables" ]; then 871 eval $(tst_net_ip_prefix $IPV4_LHOST || echo "exit $?") 872 eval $(tst_net_ip_prefix -r $IPV4_RHOST || echo "exit $?") 873 eval $(tst_net_ip_prefix $IPV6_LHOST || echo "exit $?") 874 eval $(tst_net_ip_prefix -r $IPV6_RHOST || echo "exit $?") 875fi 876 877[ -n "$TST_USE_NETNS" -a "$TST_INIT_NETNS" != "no" ] && init_ltp_netspace 878 879if [ -z "$_tst_net_parse_variables" ]; then 880 eval $(tst_net_iface_prefix $IPV4_LHOST || echo "exit $?") 881 eval $(tst_rhost_run -c 'tst_net_iface_prefix -r '$IPV4_RHOST \ 882 || echo "exit $?") 883 eval $(tst_net_iface_prefix $IPV6_LHOST || echo "exit $?") 884 eval $(tst_rhost_run -c 'tst_net_iface_prefix -r '$IPV6_RHOST \ 885 || echo "exit $?") 886 887 eval $(tst_net_vars $IPV4_LHOST/$IPV4_LPREFIX \ 888 $IPV4_RHOST/$IPV4_RPREFIX || echo "exit $?") 889 eval $(tst_net_vars $IPV6_LHOST/$IPV6_LPREFIX \ 890 $IPV6_RHOST/$IPV6_RPREFIX || echo "exit $?") 891 892 tst_res_ TINFO "Network config (local -- remote):" 893 tst_res_ TINFO "$LHOST_IFACES -- $RHOST_IFACES" 894 tst_res_ TINFO "$IPV4_LHOST/$IPV4_LPREFIX -- $IPV4_RHOST/$IPV4_RPREFIX" 895 tst_res_ TINFO "$IPV6_LHOST/$IPV6_LPREFIX -- $IPV6_RHOST/$IPV6_RPREFIX" 896 export _tst_net_parse_variables="yes" 897fi 898 899export TST_NETLOAD_CLN_REQUESTS="${TST_NETLOAD_CLN_REQUESTS:-10000}" 900export TST_NETLOAD_CLN_NUMBER="${TST_NETLOAD_CLN_NUMBER:-2}" 901export TST_NETLOAD_BINDTODEVICE="${TST_NETLOAD_BINDTODEVICE-1}" 902export HTTP_DOWNLOAD_DIR="${HTTP_DOWNLOAD_DIR:-/var/www/html}" 903export FTP_DOWNLOAD_DIR="${FTP_DOWNLOAD_DIR:-/var/ftp}" 904export FTP_UPLOAD_DIR="${FTP_UPLOAD_DIR:-/var/ftp/pub}" 905export FTP_UPLOAD_URLDIR="${FTP_UPLOAD_URLDIR:-pub}" 906 907# network/stress tests require additional parameters 908export NS_DURATION="${NS_DURATION:-10}" 909export NS_TIMES="${NS_TIMES:-10}" 910export CONNECTION_TOTAL="${CONNECTION_TOTAL:-10}" 911export IP_TOTAL="${IP_TOTAL:-100}" 912export IP_TOTAL_FOR_TCPIP="${IP_TOTAL_FOR_TCPIP:-100}" 913export ROUTE_TOTAL="${ROUTE_TOTAL:-100}" 914export MTU_CHANGE_TIMES="${MTU_CHANGE_TIMES:-100}" 915export IF_UPDOWN_TIMES="${IF_UPDOWN_TIMES:-100}" 916export DOWNLOAD_BIGFILESIZE="${DOWNLOAD_BIGFILESIZE:-2147483647}" 917export DOWNLOAD_REGFILESIZE="${DOWNLOAD_REGFILESIZE:-1048576}" 918export UPLOAD_BIGFILESIZE="${UPLOAD_BIGFILESIZE:-2147483647}" 919export UPLOAD_REGFILESIZE="${UPLOAD_REGFILESIZE:-1024}" 920export MCASTNUM_NORMAL="${MCASTNUM_NORMAL:-20}" 921export MCASTNUM_HEAVY="${MCASTNUM_HEAVY:-4000}" 922 923# Warning: make sure to set valid interface names and IP addresses below. 924# Set names for test interfaces, e.g. "eth0 eth1" 925# This is fallback for LHOST_IFACES in case tst_net_vars finds nothing or we 926# want to use more ifaces. 927export LHOST_IFACES="${LHOST_IFACES:-eth0}" 928export RHOST_IFACES="${RHOST_IFACES:-eth0}" 929# Maximum payload size for 'virt' performance tests, by default eqauls to 1.1 * MTU 930export TST_NET_MAX_PKT="${TST_NET_MAX_PKT:-$(tst_default_max_pkt)}" 931# Set corresponding HW addresses, e.g. "00:00:00:00:00:01 00:00:00:00:00:02" 932export LHOST_HWADDRS="${LHOST_HWADDRS:-$(tst_get_hwaddrs lhost)}" 933export RHOST_HWADDRS="${RHOST_HWADDRS:-$(tst_get_hwaddrs rhost)}" 934 935export NS_ICMPV4_SENDER_DATA_MAXSIZE=1472 936export NS_ICMPV6_SENDER_DATA_MAXSIZE=1452 937 938# More information about network parameters can be found 939# in the following document: testcases/network/stress/README 940 941if [ -n "$TST_USE_LEGACY_API" ]; then 942 tst_net_remote_tmpdir 943fi 944 945if [ -z "$TST_USE_LEGACY_API" ] && ! tst_cmd_available ping6; then 946 ping6() 947 { 948 ping -6 $@ 949 } 950 if [ -z "$_tst_net_ping6_warn_printed" ]; then 951 tst_res_ TINFO "ping6 binary/symlink is missing, using workaround. Please, report missing ping6 to your distribution." 952 export _tst_net_ping6_warn_printed=1 953 fi 954fi 955