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