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