network.subr revision 230453
1# 2# Copyright (c) 2003 The FreeBSD Project. All rights reserved. 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions 6# are met: 7# 1. Redistributions of source code must retain the above copyright 8# notice, this list of conditions and the following disclaimer. 9# 2. Redistributions in binary form must reproduce the above copyright 10# notice, this list of conditions and the following disclaimer in the 11# documentation and/or other materials provided with the distribution. 12# 13# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 14# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16# ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 17# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23# SUCH DAMAGE. 24# 25# $FreeBSD: head/etc/network.subr 230453 2012-01-22 10:57:32Z hrs $ 26# 27 28# 29# Subroutines commonly used from network startup scripts. 30# Requires that rc.conf be loaded first. 31# 32 33# ifn_start ifn 34# Bring up and configure an interface. If some configuration is 35# applied, print the interface configuration. 36# 37ifn_start() 38{ 39 local ifn cfg 40 ifn="$1" 41 cfg=1 42 43 [ -z "$ifn" ] && err 1 "ifn_start called without an interface" 44 45 ifscript_up ${ifn} && cfg=0 46 ifconfig_up ${ifn} && cfg=0 47 afexists inet && ipv4_up ${ifn} && cfg=0 48 afexists inet6 && ipv6_up ${ifn} && cfg=0 49 afexists ipx && ipx_up ${ifn} && cfg=0 50 childif_create ${ifn} && cfg=0 51 52 return $cfg 53} 54 55# ifn_stop ifn 56# Shutdown and de-configure an interface. If action is taken, 57# print the interface name. 58# 59ifn_stop() 60{ 61 local ifn cfg 62 ifn="$1" 63 cfg=1 64 65 [ -z "$ifn" ] && err 1 "ifn_stop called without an interface" 66 67 afexists ipx && ipx_down ${ifn} && cfg=0 68 afexists inet6 && ipv6_down ${ifn} && cfg=0 69 afexists inet && ipv4_down ${ifn} && cfg=0 70 ifconfig_down ${ifn} && cfg=0 71 ifscript_down ${ifn} && cfg=0 72 childif_destroy ${ifn} && cfg=0 73 74 return $cfg 75} 76 77# ifconfig_up if 78# Evaluate ifconfig(8) arguments for interface $if and 79# run ifconfig(8) with those arguments. It returns 0 if 80# arguments were found and executed or 1 if the interface 81# had no arguments. Pseudo arguments DHCP and WPA are handled 82# here. 83# 84ifconfig_up() 85{ 86 local _cfg _ipv6_opts ifconfig_args 87 _cfg=1 88 89 # Make sure lo0 always comes up. 90 if [ "$1" = "lo0" ]; then 91 _cfg=0 92 fi 93 94 # ifconfig_IF 95 ifconfig_args=`ifconfig_getargs $1` 96 if [ -n "${ifconfig_args}" ]; then 97 eval ifconfig $1 ${ifconfig_args} 98 _cfg=0 99 fi 100 101 # inet6 specific 102 if afexists inet6; then 103 if checkyesno ipv6_activate_all_interfaces; then 104 _ipv6_opts="-ifdisabled" 105 elif [ "$1" != "lo0" ]; then 106 _ipv6_opts="ifdisabled" 107 fi 108 109 # backward compatibility: $ipv6_enable 110 case $ipv6_enable in 111 [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 112 if ! checkyesno ipv6_gateway_enable; then 113 _ipv6_opts="${_ipv6_opts} accept_rtadv" 114 fi 115 ;; 116 esac 117 118 case $ipv6_cpe_wanif in 119 $1) 120 _ipv6_opts="${_ipv6_opts} -no_radr accept_rtadv" 121 ;; 122 esac 123 124 if [ -n "${_ipv6_opts}" ]; then 125 ifconfig $1 inet6 ${_ipv6_opts} 126 fi 127 128 # ifconfig_IF_ipv6 129 ifconfig_args=`ifconfig_getargs $1 ipv6` 130 if [ -n "${ifconfig_args}" ]; then 131 # backward compatibility: inet6 keyword 132 case "${ifconfig_args}" in 133 :*|[0-9a-fA-F]*:*) 134 warn "\$ifconfig_$1_ipv6 needs " \ 135 "\"inet6\" keyword for an IPv6 address." 136 ifconfig_args="inet6 ${ifconfig_args}" 137 ;; 138 esac 139 ifconfig $1 inet6 -ifdisabled 140 eval ifconfig $1 ${ifconfig_args} 141 _cfg=0 142 fi 143 144 # $ipv6_prefix_IF will be handled in 145 # ipv6_prefix_hostid_addr_common(). 146 ifconfig_args=`get_if_var $1 ipv6_prefix_IF` 147 if [ -n "${ifconfig_args}" ]; then 148 ifconfig $1 inet6 -ifdisabled 149 _cfg=0 150 fi 151 152 # backward compatibility: $ipv6_ifconfig_IF 153 ifconfig_args=`get_if_var $1 ipv6_ifconfig_IF` 154 if [ -n "${ifconfig_args}" ]; then 155 warn "\$ipv6_ifconfig_$1 is obsolete." \ 156 " Use ifconfig_$1_ipv6 instead." 157 ifconfig $1 inet6 -ifdisabled 158 eval ifconfig $1 inet6 ${ifconfig_args} 159 _cfg=0 160 fi 161 fi 162 163 if [ ${_cfg} -eq 0 ]; then 164 ifconfig $1 up 165 fi 166 167 if wpaif $1; then 168 /etc/rc.d/wpa_supplicant start $1 169 _cfg=0 # XXX: not sure this should count 170 fi 171 172 if dhcpif $1; then 173 if [ $_cfg -ne 0 ] ; then 174 ifconfig $1 up 175 fi 176 if syncdhcpif $1; then 177 /etc/rc.d/dhclient start $1 178 fi 179 _cfg=0 180 fi 181 182 return $_cfg 183} 184 185# ifconfig_down if 186# returns 1 if wpa_supplicant or dhclient was stopped or 187# the interface exists. 188# 189ifconfig_down() 190{ 191 local _cfg 192 _cfg=1 193 194 if wpaif $1; then 195 /etc/rc.d/wpa_supplicant stop $1 196 _cfg=0 197 fi 198 199 if dhcpif $1; then 200 /etc/rc.d/dhclient stop $1 201 _cfg=0 202 fi 203 204 if ifexists $1; then 205 ifconfig $1 down 206 _cfg=0 207 fi 208 209 return $_cfg 210} 211 212# get_if_var if var [default] 213# Return the value of the pseudo-hash corresponding to $if where 214# $var is a string containg the sub-string "IF" which will be 215# replaced with $if after the characters defined in _punct are 216# replaced with '_'. If the variable is unset, replace it with 217# $default if given. 218get_if_var() 219{ 220 local _if _punct _punct_c _var _default prefix suffix 221 222 if [ $# -ne 2 -a $# -ne 3 ]; then 223 err 3 'USAGE: get_if_var name var [default]' 224 fi 225 226 _if=$1 227 _punct=". - / +" 228 for _punct_c in $_punct; do 229 _if=`ltr ${_if} ${_punct_c} '_'` 230 done 231 _var=$2 232 _default=$3 233 234 prefix=${_var%%IF*} 235 suffix=${_var##*IF} 236 eval echo \${${prefix}${_if}${suffix}-${_default}} 237} 238 239# _ifconfig_getargs if [af] 240# Prints the arguments for the supplied interface to stdout. 241# Returns 1 if empty. In general, ifconfig_getargs should be used 242# outside this file. 243_ifconfig_getargs() 244{ 245 local _ifn _af 246 _ifn=$1 247 _af=${2+_$2} 248 249 if [ -z "$_ifn" ]; then 250 return 1 251 fi 252 253 get_if_var $_ifn ifconfig_IF$_af "$ifconfig_DEFAULT" 254} 255 256# ifconfig_getargs if [af] 257# Takes the result from _ifconfig_getargs and removes pseudo 258# args such as DHCP and WPA. 259ifconfig_getargs() 260{ 261 local _tmpargs _arg _args 262 _tmpargs=`_ifconfig_getargs $1 $2` 263 if [ $? -eq 1 ]; then 264 return 1 265 fi 266 _args= 267 268 for _arg in $_tmpargs; do 269 case $_arg in 270 [Dd][Hh][Cc][Pp]) ;; 271 [Nn][Oo][Aa][Uu][Tt][Oo]) ;; 272 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) ;; 273 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) ;; 274 [Ww][Pp][Aa]) ;; 275 *) 276 _args="$_args $_arg" 277 ;; 278 esac 279 done 280 281 echo $_args 282} 283 284# autoif 285# Returns 0 if the interface should be automatically configured at 286# boot time and 1 otherwise. 287autoif() 288{ 289 local _tmpargs _arg 290 _tmpargs=`_ifconfig_getargs $1` 291 292 for _arg in $_tmpargs; do 293 case $_arg in 294 [Nn][Oo][Aa][Uu][Tt][Oo]) 295 return 1 296 ;; 297 esac 298 done 299 300 return 0 301} 302 303# dhcpif if 304# Returns 0 if the interface is a DHCP interface and 1 otherwise. 305dhcpif() 306{ 307 local _tmpargs _arg 308 _tmpargs=`_ifconfig_getargs $1` 309 310 if noafif $1; then 311 return 1 312 fi 313 314 for _arg in $_tmpargs; do 315 case $_arg in 316 [Dd][Hh][Cc][Pp]) 317 return 0 318 ;; 319 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 320 return 0 321 ;; 322 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 323 return 0 324 ;; 325 esac 326 done 327 328 return 1 329} 330 331# syncdhcpif 332# Returns 0 if the interface should be configured synchronously and 333# 1 otherwise. 334syncdhcpif() 335{ 336 local _tmpargs _arg 337 _tmpargs=`_ifconfig_getargs $1` 338 339 if noafif $1; then 340 return 1 341 fi 342 343 for _arg in $_tmpargs; do 344 case $_arg in 345 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 346 return 1 347 ;; 348 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 349 return 0 350 ;; 351 esac 352 done 353 354 checkyesno synchronous_dhclient 355} 356 357# wpaif if 358# Returns 0 if the interface is a WPA interface and 1 otherwise. 359wpaif() 360{ 361 local _tmpargs _arg 362 _tmpargs=`_ifconfig_getargs $1` 363 364 for _arg in $_tmpargs; do 365 case $_arg in 366 [Ww][Pp][Aa]) 367 return 0 368 ;; 369 esac 370 done 371 372 return 1 373} 374 375# afexists af 376# Returns 0 if the address family is enabled in the kernel 377# 1 otherwise. 378afexists() 379{ 380 local _af 381 _af=$1 382 383 case ${_af} in 384 inet|inet6) 385 check_kern_features ${_af} 386 ;; 387 ipx) 388 ${SYSCTL_N} net.ipx > /dev/null 2>&1 389 ;; 390 atm) 391 if [ -x /sbin/atmconfig ]; then 392 /sbin/atmconfig diag list > /dev/null 2>&1 393 else 394 return 1 395 fi 396 ;; 397 *) 398 err 1 "afexists(): Unsupported address family: $_af" 399 ;; 400 esac 401} 402 403# noafif if 404# Returns 0 if the interface has no af configuration and 1 otherwise. 405noafif() 406{ 407 local _if 408 _if=$1 409 410 case $_if in 411 pflog[0-9]*|\ 412 pfsync[0-9]*|\ 413 an[0-9]*|\ 414 ath[0-9]*|\ 415 ipw[0-9]*|\ 416 ipfw[0-9]*|\ 417 iwi[0-9]*|\ 418 iwn[0-9]*|\ 419 ral[0-9]*|\ 420 wi[0-9]*|\ 421 wl[0-9]*|\ 422 wpi[0-9]*) 423 return 0 424 ;; 425 esac 426 427 return 1 428} 429 430# ipv6if if 431# Returns 0 if the interface should be configured for IPv6 and 432# 1 otherwise. 433ipv6if() 434{ 435 local _if _tmpargs i 436 _if=$1 437 438 if ! afexists inet6; then 439 return 1 440 fi 441 442 # lo0 is always IPv6-enabled 443 case $_if in 444 lo0) 445 return 0 446 ;; 447 esac 448 449 case "${ipv6_network_interfaces}" in 450 $_if|"$_if "*|*" $_if"|*" $_if "*|[Aa][Uu][Tt][Oo]) 451 # True if $ifconfig_IF_ipv6 is defined. 452 _tmpargs=`_ifconfig_getargs $_if ipv6` 453 if [ -n "${_tmpargs}" ]; then 454 return 0 455 fi 456 457 # True if $ipv6_prefix_IF is defined. 458 _tmpargs=`get_if_var $_if ipv6_prefix_IF` 459 if [ -n "${_tmpargs}" ]; then 460 return 0 461 fi 462 463 # backward compatibility: True if $ipv6_ifconfig_IF is defined. 464 _tmpargs=`get_if_var $_if ipv6_ifconfig_IF` 465 if [ -n "${_tmpargs}" ]; then 466 return 0 467 fi 468 ;; 469 esac 470 471 return 1 472} 473 474# ipv6_autoconfif if 475# Returns 0 if the interface should be configured for IPv6 with 476# Stateless Address Configuration; 1 otherwise. 477ipv6_autoconfif() 478{ 479 local _if _tmpargs _arg 480 _if=$1 481 482 case $_if in 483 lo0|\ 484 stf[0-9]*|\ 485 faith[0-9]*|\ 486 lp[0-9]*|\ 487 sl[0-9]*) 488 return 1 489 ;; 490 esac 491 if noafif $_if; then 492 return 1 493 fi 494 if ! ipv6if $_if; then 495 return 1 496 fi 497 if checkyesno ipv6_gateway_enable; then 498 return 1 499 fi 500 _tmpargs=`get_if_var $_if ipv6_prefix_IF` 501 if [ -n "${_tmpargs}" ]; then 502 return 1 503 fi 504 # backward compatibility: $ipv6_enable 505 case $ipv6_enable in 506 [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 507 return 0 508 ;; 509 esac 510 511 _tmpargs=`_ifconfig_getargs $_if ipv6` 512 for _arg in $_tmpargs; do 513 case $_arg in 514 accept_rtadv) 515 return 0 516 ;; 517 esac 518 done 519 520 # backward compatibility: $ipv6_ifconfig_IF 521 _tmpargs=`get_if_var $_if ipv6_ifconfig_IF` 522 for _arg in $_tmpargs; do 523 case $_arg in 524 accept_rtadv) 525 return 0 526 ;; 527 esac 528 done 529 530 return 1 531} 532 533# ifexists if 534# Returns 0 if the interface exists and 1 otherwise. 535ifexists() 536{ 537 [ -z "$1" ] && return 1 538 ifconfig -n $1 > /dev/null 2>&1 539} 540 541# ipv4_up if 542# add IPv4 addresses to the interface $if 543ipv4_up() 544{ 545 local _if _ret 546 _if=$1 547 _ret=1 548 549 # Add 127.0.0.1/8 to lo0 unless otherwise specified. 550 if [ "${_if}" = "lo0" ]; then 551 ifconfig_args=`get_if_var ${_if} ifconfig_IF` 552 if [ -z "${ifconfig_args}" ]; then 553 ifconfig ${_if} inet 127.0.0.1/8 alias 554 fi 555 fi 556 ifalias_up ${_if} inet && _ret=0 557 ipv4_addrs_common ${_if} alias && _ret=0 558 559 return $_ret 560} 561 562# ipv6_up if 563# add IPv6 addresses to the interface $if 564ipv6_up() 565{ 566 local _if _ret 567 _if=$1 568 _ret=1 569 570 if ! ipv6if $_if; then 571 return 0 572 fi 573 574 ifalias_up ${_if} inet6 && _ret=0 575 ipv6_prefix_hostid_addr_common ${_if} alias && _ret=0 576 ipv6_accept_rtadv_up ${_if} && _ret=0 577 578 return $_ret 579} 580 581# ipv4_down if 582# remove IPv4 addresses from the interface $if 583ipv4_down() 584{ 585 local _if _ifs _ret inetList oldifs _inet 586 _if=$1 587 _ifs="^" 588 _ret=1 589 590 inetList="`ifconfig ${_if} | grep 'inet ' | tr "\n" "$_ifs"`" 591 592 oldifs="$IFS" 593 IFS="$_ifs" 594 for _inet in $inetList ; do 595 # get rid of extraneous line 596 [ -z "$_inet" ] && break 597 598 _inet=`expr "$_inet" : '.*\(inet \([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*'` 599 600 IFS="$oldifs" 601 ifconfig ${_if} ${_inet} delete 602 IFS="$_ifs" 603 _ret=0 604 done 605 IFS="$oldifs" 606 607 ifalias_down ${_if} inet && _ret=0 608 ipv4_addrs_common ${_if} -alias && _ret=0 609 610 return $_ret 611} 612 613# ipv6_down if 614# remove IPv6 addresses from the interface $if 615ipv6_down() 616{ 617 local _if _ifs _ret inetList oldifs _inet6 618 _if=$1 619 _ifs="^" 620 _ret=1 621 622 if ! ipv6if $_if; then 623 return 0 624 fi 625 626 ipv6_accept_rtadv_down ${_if} && _ret=0 627 ipv6_prefix_hostid_addr_common ${_if} -alias && _ret=0 628 ifalias_down ${_if} inet6 && _ret=0 629 630 inetList="`ifconfig ${_if} | grep 'inet6 ' | tr "\n" "$_ifs"`" 631 632 oldifs="$IFS" 633 IFS="$_ifs" 634 for _inet6 in $inetList ; do 635 # get rid of extraneous line 636 [ -z "$_inet6" ] && break 637 638 _inet6=`expr "$_inet6" : '.*\(inet6 \([0-9a-f:]*\)\).*'` 639 640 IFS="$oldifs" 641 ifconfig ${_if} ${_inet6} -alias 642 IFS="$_ifs" 643 _ret=0 644 done 645 IFS="$oldifs" 646 647 return $_ret 648} 649 650# ipv4_addrs_common if action 651# Evaluate the ifconfig_if_ipv4 arguments for interface $if and 652# use $action to add or remove IPv4 addresses from $if. 653ipv4_addrs_common() 654{ 655 local _ret _if _action _cidr _cidr_addr 656 local _ipaddr _netmask _range _ipnet _iplow _iphigh _ipcount 657 _ret=1 658 _if=$1 659 _action=$2 660 661 # get ipv4-addresses 662 cidr_addr=`get_if_var $_if ipv4_addrs_IF` 663 664 for _cidr in ${cidr_addr}; do 665 _ipaddr=${_cidr%%/*} 666 _netmask="/"${_cidr##*/} 667 _range=${_ipaddr##*.} 668 _ipnet=${_ipaddr%.*} 669 _iplow=${_range%-*} 670 _iphigh=${_range#*-} 671 672 # clear netmask when removing aliases 673 if [ "${_action}" = "-alias" ]; then 674 _netmask="" 675 fi 676 677 _ipcount=${_iplow} 678 while [ "${_ipcount}" -le "${_iphigh}" ]; do 679 eval "ifconfig ${_if} ${_action} ${_ipnet}.${_ipcount}${_netmask}" 680 _ipcount=$((${_ipcount}+1)) 681 _ret=0 682 683 # only the first ipaddr in a subnet need the real netmask 684 if [ "${_action}" != "-alias" ]; then 685 _netmask="/32" 686 fi 687 done 688 done 689 690 return $_ret 691} 692 693# ifalias_up if af 694# Configure aliases for network interface $if. 695# It returns 0 if at least one alias was configured or 696# 1 if there were none. 697# 698ifalias_up() 699{ 700 local _ret 701 _ret=1 702 703 case "$2" in 704 inet) 705 _ret=`ifalias_ipv4_up "$1"` 706 ;; 707 inet6) 708 _ret=`ifalias_ipv6_up "$1"` 709 ;; 710 esac 711 712 return $_ret 713} 714 715# ifalias_ipv4_up if 716# Helper function for ifalias_up(). Handles IPv4. 717# 718ifalias_ipv4_up() 719{ 720 local _ret alias ifconfig_args 721 _ret=1 722 723 # ifconfig_IF_aliasN which starts with "inet" 724 alias=0 725 while : ; do 726 ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}` 727 case "${ifconfig_args}" in 728 inet\ *) 729 ifconfig $1 ${ifconfig_args} alias && _ret=0 730 ;; 731 inet6\ *) 732 ;; 733 "") 734 break 735 ;; 736 *) 737 warn "\$ifconfig_$1_alias${alias} needs " \ 738 "\"inet\" keyword for an IPv4 address." 739 ifconfig $1 ${ifconfig_args} alias && _ret=0 740 ;; 741 esac 742 alias=$((${alias} + 1)) 743 done 744 745 return $_ret 746} 747 748# ifalias_ipv6_up if 749# Helper function for ifalias_up(). Handles IPv6. 750# 751ifalias_ipv6_up() 752{ 753 local _ret alias ifconfig_args 754 _ret=1 755 756 # ifconfig_IF_aliasN which starts with "inet6" 757 alias=0 758 while : ; do 759 ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}` 760 case "${ifconfig_args}" in 761 inet6\ *) 762 ifconfig $1 ${ifconfig_args} alias && _ret=0 763 ;; 764 "") 765 break 766 ;; 767 esac 768 alias=$((${alias} + 1)) 769 done 770 771 # backward compatibility: ipv6_ifconfig_IF_aliasN. 772 alias=0 773 while : ; do 774 ifconfig_args=`get_if_var $1 ipv6_ifconfig_IF_alias${alias}` 775 case "${ifconfig_args}" in 776 "") 777 break 778 ;; 779 *) 780 ifconfig $1 inet6 ${ifconfig_args} alias && _ret=0 781 warn "\$ipv6_ifconfig_$1_alias${alias} is obsolete." \ 782 " Use ifconfig_$1_aliasN instead." 783 ;; 784 esac 785 alias=$((${alias} + 1)) 786 done 787 788 return $_ret 789} 790 791# ifalias_down if af 792# Remove aliases for network interface $if. 793# It returns 0 if at least one alias was removed or 794# 1 if there were none. 795# 796ifalias_down() 797{ 798 local _ret 799 _ret=1 800 801 case "$2" in 802 inet) 803 _ret=`ifalias_ipv4_down "$1"` 804 ;; 805 inet6) 806 _ret=`ifalias_ipv6_down "$1"` 807 ;; 808 esac 809 810 return $_ret 811} 812 813# ifalias_ipv4_down if 814# Helper function for ifalias_down(). Handles IPv4. 815# 816ifalias_ipv4_down() 817{ 818 local _ret alias ifconfig_args 819 _ret=1 820 821 # ifconfig_IF_aliasN which starts with "inet" 822 alias=0 823 while : ; do 824 ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}` 825 case "${ifconfig_args}" in 826 inet\ *) 827 ifconfig $1 ${ifconfig_args} -alias && _ret=0 828 ;; 829 "") 830 break 831 ;; 832 esac 833 alias=$((${alias} + 1)) 834 done 835 836 return $_ret 837} 838 839# ifalias_ipv6_down if 840# Helper function for ifalias_down(). Handles IPv6. 841# 842ifalias_ipv6_down() 843{ 844 local _ret alias ifconfig_args 845 _ret=1 846 847 # ifconfig_IF_aliasN which starts with "inet6" 848 alias=0 849 while : ; do 850 ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}` 851 case "${ifconfig_args}" in 852 inet6\ *) 853 ifconfig $1 ${ifconfig_args} -alias && _ret=0 854 ;; 855 "") 856 break 857 ;; 858 esac 859 alias=$((${alias} + 1)) 860 done 861 862 # backward compatibility: ipv6_ifconfig_IF_aliasN. 863 alias=0 864 while : ; do 865 ifconfig_args=`get_if_var $1 ipv6_ifconfig_IF_alias${alias}` 866 case "${ifconfig_args}" in 867 "") 868 break 869 ;; 870 *) 871 ifconfig $1 inet6 ${ifconfig_args} -alias && _ret=0 872 warn "\$ipv6_ifconfig_$1_alias${alias} is obsolete." \ 873 " Use ifconfig_$1_aliasN instead." 874 ;; 875 esac 876 alias=$((${alias} + 1)) 877 done 878 879 return $_ret 880} 881 882# ipv6_prefix_hostid_addr_common if action 883# Add or remove IPv6 prefix + hostid addr on the interface $if 884# 885ipv6_prefix_hostid_addr_common() 886{ 887 local _if _action prefix laddr hostid j address 888 _if=$1 889 _action=$2 890 prefix=`get_if_var ${_if} ipv6_prefix_IF` 891 892 if [ -n "${prefix}" ]; then 893 laddr=`network6_getladdr ${_if}` 894 hostid=${laddr#fe80::} 895 hostid=${hostid%\%*} 896 897 for j in ${prefix}; do 898 address=$j\:${hostid} 899 ifconfig ${_if} inet6 ${address} prefixlen 64 ${_action} 900 901 # if I am a router, add subnet router 902 # anycast address (RFC 2373). 903 if checkyesno ipv6_gateway_enable; then 904 ifconfig ${_if} inet6 $j:: prefixlen 64 \ 905 ${_action} anycast 906 fi 907 done 908 fi 909} 910 911# ipv6_accept_rtadv_up if 912# Enable accepting Router Advertisement and send Router 913# Solicitation message 914ipv6_accept_rtadv_up() 915{ 916 if ipv6_autoconfif $1; then 917 ifconfig $1 inet6 accept_rtadv up 918 if ! checkyesno rtsold_enable; then 919 rtsol ${rtsol_flags} $1 920 fi 921 fi 922} 923 924# ipv6_accept_rtadv_down if 925# Disable accepting Router Advertisement 926ipv6_accept_rtadv_down() 927{ 928 if ipv6_autoconfif $1; then 929 ifconfig $1 inet6 -accept_rtadv 930 fi 931} 932 933# ifscript_up if 934# Evaluate a startup script for the $if interface. 935# It returns 0 if a script was found and processed or 936# 1 if no script was found. 937# 938ifscript_up() 939{ 940 if [ -r /etc/start_if.$1 ]; then 941 . /etc/start_if.$1 942 return 0 943 else 944 return 1 945 fi 946} 947 948# ifscript_down if 949# Evaluate a shutdown script for the $if interface. 950# It returns 0 if a script was found and processed or 951# 1 if no script was found. 952# 953ifscript_down() 954{ 955 if [ -r /etc/stop_if.$1 ]; then 956 . /etc/stop_if.$1 957 return 0 958 else 959 return 1 960 fi 961} 962 963# clone_up 964# Create cloneable interfaces. 965# 966clone_up() 967{ 968 local _prefix _list ifn 969 _prefix= 970 _list= 971 972 # create_args_IF 973 for ifn in ${cloned_interfaces}; do 974 ifconfig ${ifn} create `get_if_var ${ifn} create_args_IF` 975 if [ $? -eq 0 ]; then 976 _list="${_list}${_prefix}${ifn}" 977 [ -z "$_prefix" ] && _prefix=' ' 978 fi 979 done 980 debug "Cloned: ${_list}" 981} 982 983# clone_down 984# Destroy cloned interfaces. Destroyed interfaces are echoed to 985# standard output. 986# 987clone_down() 988{ 989 local _prefix _list ifn 990 _prefix= 991 _list= 992 993 for ifn in ${cloned_interfaces}; do 994 ifconfig -n ${ifn} destroy 995 if [ $? -eq 0 ]; then 996 _list="${_list}${_prefix}${ifn}" 997 [ -z "$_prefix" ] && _prefix=' ' 998 fi 999 done 1000 debug "Destroyed clones: ${_list}" 1001} 1002 1003# childif_create 1004# Create and configure child interfaces. Return 0 if child 1005# interfaces are created. 1006# 1007childif_create() 1008{ 1009 local cfg child child_vlans child_wlans create_args debug_flags ifn i 1010 cfg=1 1011 ifn=$1 1012 1013 # Create wireless interfaces 1014 child_wlans=`get_if_var $ifn wlans_IF` 1015 1016 for child in ${child_wlans}; do 1017 create_args="wlandev $ifn `get_if_var $child create_args_IF`" 1018 debug_flags="`get_if_var $child wlandebug_IF`" 1019 1020 if expr $child : 'wlan[0-9][0-9]*$' >/dev/null 2>&1; then 1021 ifconfig $child create ${create_args} && cfg=0 1022 if [ -n "${debug_flags}" ]; then 1023 wlandebug -i $child ${debug_flags} 1024 fi 1025 else 1026 i=`ifconfig wlan create ${create_args}` 1027 if [ -n "${debug_flags}" ]; then 1028 wlandebug -i $i ${debug_flags} 1029 fi 1030 ifconfig $i name $child && cfg=0 1031 fi 1032 if autoif $child; then 1033 ifn_start $child 1034 fi 1035 done 1036 1037 # Create vlan interfaces 1038 child_vlans=`get_if_var $ifn vlans_IF` 1039 1040 if [ -n "${child_vlans}" ]; then 1041 load_kld if_vlan 1042 fi 1043 1044 for child in ${child_vlans}; do 1045 if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then 1046 child="${ifn}.${child}" 1047 create_args=`get_if_var $child create_args_IF` 1048 ifconfig $child create ${create_args} && cfg=0 1049 else 1050 create_args="vlandev $ifn `get_if_var $child create_args_IF`" 1051 if expr $child : 'vlan[0-9][0-9]*$' >/dev/null 2>&1; then 1052 ifconfig $child create ${create_args} && cfg=0 1053 else 1054 i=`ifconfig vlan create ${create_args}` 1055 ifconfig $i name $child && cfg=0 1056 fi 1057 fi 1058 if autoif $child; then 1059 ifn_start $child 1060 fi 1061 done 1062 1063 return ${cfg} 1064} 1065 1066# childif_destroy 1067# Destroy child interfaces. 1068# 1069childif_destroy() 1070{ 1071 local cfg child child_vlans child_wlans ifn 1072 cfg=1 1073 1074 child_wlans=`get_if_var $ifn wlans_IF` 1075 for child in ${child_wlans}; do 1076 if ! ifexists $child; then 1077 continue 1078 fi 1079 ifconfig -n $child destroy && cfg=0 1080 done 1081 1082 child_vlans=`get_if_var $ifn vlans_IF` 1083 for child in ${child_vlans}; do 1084 if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then 1085 child="${ifn}.${child}" 1086 fi 1087 if ! ifexists $child; then 1088 continue 1089 fi 1090 ifconfig -n $child destroy && cfg=0 1091 done 1092 1093 return ${cfg} 1094} 1095 1096# ng_mkpeer 1097# Create netgraph nodes. 1098# 1099ng_mkpeer() 1100{ 1101 ngctl -f - 2> /dev/null <<EOF 1102mkpeer $* 1103msg dummy nodeinfo 1104EOF 1105} 1106 1107# ng_create_one 1108# Create netgraph nodes. 1109# 1110ng_create_one() 1111{ 1112 local t 1113 1114 ng_mkpeer $* | while read line; do 1115 t=`expr "${line}" : '.* name="\([a-z]*[0-9]*\)" .*'` 1116 if [ -n "${t}" ]; then 1117 echo ${t} 1118 return 1119 fi 1120 done 1121} 1122 1123# gif_up 1124# Create gif(4) tunnel interfaces. 1125gif_up() 1126{ 1127 local i peers 1128 1129 for i in ${gif_interfaces}; do 1130 peers=`get_if_var $i gifconfig_IF` 1131 case ${peers} in 1132 '') 1133 continue 1134 ;; 1135 *) 1136 if expr $i : 'gif[0-9][0-9]*$' >/dev/null 2>&1; then 1137 ifconfig $i create >/dev/null 2>&1 1138 else 1139 gif=`ifconfig gif create` 1140 ifconfig $gif name $i 1141 fi 1142 ifconfig $i tunnel ${peers} 1143 ifconfig $i up 1144 ;; 1145 esac 1146 done 1147} 1148 1149# ng_fec_create ifn 1150# Configure Fast EtherChannel for interface $ifn. Returns 0 if 1151# FEC arguments were found and configured; returns !0 otherwise. 1152ng_fec_create() 1153{ 1154 local req_iface iface bogus 1155 req_iface="$1" 1156 1157 ngctl shutdown ${req_iface}: > /dev/null 2>&1 1158 1159 bogus="" 1160 while true; do 1161 iface=`ng_create_one fec dummy fec` 1162 if [ -z "${iface}" ]; then 1163 exit 2 1164 fi 1165 if [ "${iface}" = "${req_iface}" ]; then 1166 break 1167 fi 1168 bogus="${bogus} ${iface}" 1169 done 1170 1171 for iface in ${bogus}; do 1172 ngctl shutdown ${iface}: 1173 done 1174} 1175 1176# fec_up 1177# Create Fast EtherChannel interfaces. 1178fec_up() 1179{ 1180 local i j 1181 1182 for i in ${fec_interfaces}; do 1183 ng_fec_create $i 1184 for j in `get_if_var $i fecconfig_IF`; do 1185 case ${j} in 1186 '') 1187 continue 1188 ;; 1189 *) 1190 ngctl msg ${i}: add_iface "\"${j}\"" 1191 ;; 1192 esac 1193 done 1194 done 1195} 1196 1197# ipx_up ifn 1198# Configure any IPX addresses for interface $ifn. Returns 0 if 1199# IPX arguments were found and configured; returns 1 otherwise. 1200# 1201ipx_up() 1202{ 1203 local ifn 1204 ifn="$1" 1205 1206 # ifconfig_IF_ipx 1207 ifconfig_args=`_ifconfig_getargs $ifn ipx` 1208 if [ -n "${ifconfig_args}" ]; then 1209 ifconfig ${ifn} ${ifconfig_args} 1210 return 0 1211 fi 1212 1213 return 1 1214} 1215 1216# ipx_down ifn 1217# Remove IPX addresses for interface $ifn. Returns 0 if IPX 1218# addresses were found and unconfigured. It returns 1, otherwise. 1219# 1220ipx_down() 1221{ 1222 local _if _ifs _ret ipxList oldifs _ipx 1223 _if=$1 1224 _ifs="^" 1225 _ret=1 1226 ipxList="`ifconfig ${_if} | grep 'ipx ' | tr "\n" "$_ifs"`" 1227 oldifs="$IFS" 1228 1229 IFS="$_ifs" 1230 for _ipx in $ipxList ; do 1231 # get rid of extraneous line 1232 [ -z "$_ipx" ] && break 1233 1234 _ipx=`expr "$_ipx" : '.*\(ipx [0-9a-h]\{1,8\}H*\.[0-9a-h]\{1,12\}\).*'` 1235 1236 IFS="$oldifs" 1237 ifconfig ${_if} ${_ipx} delete 1238 IFS="$_ifs" 1239 _ret=0 1240 done 1241 IFS="$oldifs" 1242 1243 return $_ret 1244} 1245 1246# ifnet_rename 1247# Rename all requested interfaces. 1248# 1249ifnet_rename() 1250{ 1251 local _if _ifname 1252 1253 # ifconfig_IF_name 1254 for _if in `ifconfig -l`; do 1255 _ifname=`get_if_var $_if ifconfig_IF_name` 1256 if [ ! -z "$_ifname" ]; then 1257 ifconfig $_if name $_ifname 1258 fi 1259 done 1260 1261 return 0 1262} 1263 1264# list_net_interfaces type 1265# List all network interfaces. The type of interface returned 1266# can be controlled by the type argument. The type 1267# argument can be any of the following: 1268# nodhcp - all interfaces, excluding DHCP configured interfaces 1269# dhcp - list only DHCP configured interfaces 1270# noautoconf - all interfaces, excluding IPv6 Stateless 1271# Address Autoconf configured interfaces 1272# autoconf - list only IPv6 Stateless Address Autoconf 1273# configured interfaces 1274# If no argument is specified all network interfaces are output. 1275# Note that the list will include cloned interfaces if applicable. 1276# Cloned interfaces must already exist to have a chance to appear 1277# in the list if ${network_interfaces} is set to `auto'. 1278# 1279list_net_interfaces() 1280{ 1281 local type _tmplist _list _autolist _lo _if 1282 type=$1 1283 1284 # Get a list of ALL the interfaces and make lo0 first if it's there. 1285 # 1286 _tmplist= 1287 case ${network_interfaces} in 1288 [Aa][Uu][Tt][Oo]) 1289 _autolist="`ifconfig -l`" 1290 _lo= 1291 for _if in ${_autolist} ; do 1292 if autoif $_if; then 1293 if [ "$_if" = "lo0" ]; then 1294 _lo="lo0 " 1295 else 1296 _tmplist="${_tmplist} ${_if}" 1297 fi 1298 fi 1299 done 1300 _tmplist="${_lo}${_tmplist# }" 1301 ;; 1302 *) 1303 _tmplist="${network_interfaces} ${cloned_interfaces}" 1304 1305 # lo0 is effectively mandatory, so help prevent foot-shooting 1306 # 1307 case "$_tmplist" in 1308 lo0|'lo0 '*|*' lo0'|*' lo0 '*) ;; # This is fine, do nothing 1309 *) _tmplist="lo0 ${_tmplist}" ;; 1310 esac 1311 ;; 1312 esac 1313 1314 _list= 1315 case "$type" in 1316 nodhcp) 1317 for _if in ${_tmplist} ; do 1318 if ! dhcpif $_if && \ 1319 [ -n "`_ifconfig_getargs $_if`" ]; then 1320 _list="${_list# } ${_if}" 1321 fi 1322 done 1323 ;; 1324 dhcp) 1325 for _if in ${_tmplist} ; do 1326 if dhcpif $_if; then 1327 _list="${_list# } ${_if}" 1328 fi 1329 done 1330 ;; 1331 noautoconf) 1332 for _if in ${_tmplist} ; do 1333 if ! ipv6_autoconfif $_if && \ 1334 [ -n "`_ifconfig_getargs $_if ipv6`" ]; then 1335 _list="${_list# } ${_if}" 1336 fi 1337 done 1338 ;; 1339 autoconf) 1340 for _if in ${_tmplist} ; do 1341 if ipv6_autoconfif $_if; then 1342 _list="${_list# } ${_if}" 1343 fi 1344 done 1345 ;; 1346 *) 1347 _list=${_tmplist} 1348 ;; 1349 esac 1350 1351 echo $_list 1352 1353 return 0 1354} 1355 1356# get_default_if -address_family 1357# Get the interface of the default route for the given address family. 1358# The -address_family argument must be suitable passing to route(8). 1359# 1360get_default_if() 1361{ 1362 local routeget oldifs defif line 1363 defif= 1364 oldifs="$IFS" 1365 IFS=" 1366" 1367 for line in `route -n get $1 default 2>/dev/null`; do 1368 case $line in 1369 *interface:*) 1370 defif=${line##*: } 1371 ;; 1372 esac 1373 done 1374 IFS=${oldifs} 1375 1376 echo $defif 1377} 1378 1379# hexdigit arg 1380# Echo decimal number $arg (single digit) in hexadecimal format. 1381hexdigit() 1382{ 1383 printf '%x\n' "$1" 1384} 1385 1386# hexprint arg 1387# Echo decimal number $arg (multiple digits) in hexadecimal format. 1388hexprint() 1389{ 1390 printf '%x\n' "$1" 1391} 1392 1393is_wired_interface() 1394{ 1395 local media 1396 1397 case `ifconfig $1 2>/dev/null` in 1398 *media:?Ethernet*) media=Ethernet ;; 1399 esac 1400 1401 test "$media" = "Ethernet" 1402} 1403 1404# network6_getladdr if [flag] 1405# Echo link-local address from $if if any. 1406# If flag is defined, tentative ones will be excluded. 1407network6_getladdr() 1408{ 1409 local proto addr rest 1410 ifconfig $1 2>/dev/null | while read proto addr rest; do 1411 case ${proto} in 1412 inet6) 1413 case ${addr} in 1414 fe80::*) 1415 if [ -z "$2" ]; then 1416 echo ${addr} 1417 return 1418 fi 1419 case ${rest} in 1420 *tentative*) 1421 continue 1422 ;; 1423 *) 1424 echo ${addr} 1425 return 1426 esac 1427 esac 1428 esac 1429 done 1430} 1431