network.subr revision 242181
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 242181 2012-10-27 17:06:26Z 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 if checkyesno ipv6_gateway_enable; then 508 return 1 509 else 510 return 0 511 fi 512 ;; 513 esac 514 515 _tmpargs=`_ifconfig_getargs $_if ipv6` 516 for _arg in $_tmpargs; do 517 case $_arg in 518 accept_rtadv) 519 return 0 520 ;; 521 esac 522 done 523 524 # backward compatibility: $ipv6_ifconfig_IF 525 _tmpargs=`get_if_var $_if ipv6_ifconfig_IF` 526 for _arg in $_tmpargs; do 527 case $_arg in 528 accept_rtadv) 529 return 0 530 ;; 531 esac 532 done 533 534 return 1 535} 536 537# ifexists if 538# Returns 0 if the interface exists and 1 otherwise. 539ifexists() 540{ 541 [ -z "$1" ] && return 1 542 ifconfig -n $1 > /dev/null 2>&1 543} 544 545# ipv4_up if 546# add IPv4 addresses to the interface $if 547ipv4_up() 548{ 549 local _if _ret 550 _if=$1 551 _ret=1 552 553 # Add 127.0.0.1/8 to lo0 unless otherwise specified. 554 if [ "${_if}" = "lo0" ]; then 555 ifconfig_args=`get_if_var ${_if} ifconfig_IF` 556 if [ -z "${ifconfig_args}" ]; then 557 ifconfig ${_if} inet 127.0.0.1/8 alias 558 fi 559 fi 560 ifalias_up ${_if} inet && _ret=0 561 ipv4_addrs_common ${_if} alias && _ret=0 562 563 return $_ret 564} 565 566# ipv6_up if 567# add IPv6 addresses to the interface $if 568ipv6_up() 569{ 570 local _if _ret 571 _if=$1 572 _ret=1 573 574 if ! ipv6if $_if; then 575 return 0 576 fi 577 578 ifalias_up ${_if} inet6 && _ret=0 579 ipv6_prefix_hostid_addr_common ${_if} alias && _ret=0 580 ipv6_accept_rtadv_up ${_if} && _ret=0 581 582 return $_ret 583} 584 585# ipv4_down if 586# remove IPv4 addresses from the interface $if 587ipv4_down() 588{ 589 local _if _ifs _ret inetList oldifs _inet 590 _if=$1 591 _ifs="^" 592 _ret=1 593 594 inetList="`ifconfig ${_if} | grep 'inet ' | tr "\n" "$_ifs"`" 595 596 oldifs="$IFS" 597 IFS="$_ifs" 598 for _inet in $inetList ; do 599 # get rid of extraneous line 600 [ -z "$_inet" ] && break 601 602 _inet=`expr "$_inet" : '.*\(inet \([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*'` 603 604 IFS="$oldifs" 605 ifconfig ${_if} ${_inet} delete 606 IFS="$_ifs" 607 _ret=0 608 done 609 IFS="$oldifs" 610 611 ifalias_down ${_if} inet && _ret=0 612 ipv4_addrs_common ${_if} -alias && _ret=0 613 614 return $_ret 615} 616 617# ipv6_down if 618# remove IPv6 addresses from the interface $if 619ipv6_down() 620{ 621 local _if _ifs _ret inetList oldifs _inet6 622 _if=$1 623 _ifs="^" 624 _ret=1 625 626 if ! ipv6if $_if; then 627 return 0 628 fi 629 630 ipv6_accept_rtadv_down ${_if} && _ret=0 631 ipv6_prefix_hostid_addr_common ${_if} -alias && _ret=0 632 ifalias_down ${_if} inet6 && _ret=0 633 634 inetList="`ifconfig ${_if} | grep 'inet6 ' | tr "\n" "$_ifs"`" 635 636 oldifs="$IFS" 637 IFS="$_ifs" 638 for _inet6 in $inetList ; do 639 # get rid of extraneous line 640 [ -z "$_inet6" ] && break 641 642 _inet6=`expr "$_inet6" : '.*\(inet6 \([0-9a-f:]*\)\).*'` 643 644 IFS="$oldifs" 645 ifconfig ${_if} ${_inet6} -alias 646 IFS="$_ifs" 647 _ret=0 648 done 649 IFS="$oldifs" 650 651 return $_ret 652} 653 654# ipv4_addrs_common if action 655# Evaluate the ifconfig_if_ipv4 arguments for interface $if and 656# use $action to add or remove IPv4 addresses from $if. 657ipv4_addrs_common() 658{ 659 local _ret _if _action _cidr _cidr_addr 660 local _ipaddr _netmask _range _ipnet _iplow _iphigh _ipcount 661 _ret=1 662 _if=$1 663 _action=$2 664 665 # get ipv4-addresses 666 cidr_addr=`get_if_var $_if ipv4_addrs_IF` 667 668 for _cidr in ${cidr_addr}; do 669 _ipaddr=${_cidr%%/*} 670 _netmask="/"${_cidr##*/} 671 _range=${_ipaddr##*.} 672 _ipnet=${_ipaddr%.*} 673 _iplow=${_range%-*} 674 _iphigh=${_range#*-} 675 676 # clear netmask when removing aliases 677 if [ "${_action}" = "-alias" ]; then 678 _netmask="" 679 fi 680 681 _ipcount=${_iplow} 682 while [ "${_ipcount}" -le "${_iphigh}" ]; do 683 eval "ifconfig ${_if} ${_action} ${_ipnet}.${_ipcount}${_netmask}" 684 _ipcount=$((${_ipcount}+1)) 685 _ret=0 686 687 # only the first ipaddr in a subnet need the real netmask 688 if [ "${_action}" != "-alias" ]; then 689 _netmask="/32" 690 fi 691 done 692 done 693 694 return $_ret 695} 696 697# ifalias_up if af 698# Configure aliases for network interface $if. 699# It returns 0 if at least one alias was configured or 700# 1 if there were none. 701# 702ifalias_up() 703{ 704 local _ret 705 _ret=1 706 707 case "$2" in 708 inet) 709 _ret=`ifalias_ipv4_up "$1"` 710 ;; 711 inet6) 712 _ret=`ifalias_ipv6_up "$1"` 713 ;; 714 esac 715 716 return $_ret 717} 718 719# ifalias_ipv4_up if 720# Helper function for ifalias_up(). Handles IPv4. 721# 722ifalias_ipv4_up() 723{ 724 local _ret alias ifconfig_args 725 _ret=1 726 727 # ifconfig_IF_aliasN which starts with "inet" 728 alias=0 729 while : ; do 730 ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}` 731 case "${ifconfig_args}" in 732 inet\ *) 733 ifconfig $1 ${ifconfig_args} alias && _ret=0 734 ;; 735 inet6\ *) 736 ;; 737 "") 738 break 739 ;; 740 *) 741 warn "\$ifconfig_$1_alias${alias} needs " \ 742 "\"inet\" keyword for an IPv4 address." 743 ifconfig $1 ${ifconfig_args} alias && _ret=0 744 ;; 745 esac 746 alias=$((${alias} + 1)) 747 done 748 749 return $_ret 750} 751 752# ifalias_ipv6_up if 753# Helper function for ifalias_up(). Handles IPv6. 754# 755ifalias_ipv6_up() 756{ 757 local _ret alias ifconfig_args 758 _ret=1 759 760 # ifconfig_IF_aliasN which starts with "inet6" 761 alias=0 762 while : ; do 763 ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}` 764 case "${ifconfig_args}" in 765 inet6\ *) 766 ifconfig $1 ${ifconfig_args} alias && _ret=0 767 ;; 768 "") 769 break 770 ;; 771 esac 772 alias=$((${alias} + 1)) 773 done 774 775 # backward compatibility: ipv6_ifconfig_IF_aliasN. 776 alias=0 777 while : ; do 778 ifconfig_args=`get_if_var $1 ipv6_ifconfig_IF_alias${alias}` 779 case "${ifconfig_args}" in 780 "") 781 break 782 ;; 783 *) 784 ifconfig $1 inet6 ${ifconfig_args} alias && _ret=0 785 warn "\$ipv6_ifconfig_$1_alias${alias} is obsolete." \ 786 " Use ifconfig_$1_aliasN instead." 787 ;; 788 esac 789 alias=$((${alias} + 1)) 790 done 791 792 return $_ret 793} 794 795# ifalias_down if af 796# Remove aliases for network interface $if. 797# It returns 0 if at least one alias was removed or 798# 1 if there were none. 799# 800ifalias_down() 801{ 802 local _ret 803 _ret=1 804 805 case "$2" in 806 inet) 807 _ret=`ifalias_ipv4_down "$1"` 808 ;; 809 inet6) 810 _ret=`ifalias_ipv6_down "$1"` 811 ;; 812 esac 813 814 return $_ret 815} 816 817# ifalias_ipv4_down if 818# Helper function for ifalias_down(). Handles IPv4. 819# 820ifalias_ipv4_down() 821{ 822 local _ret alias ifconfig_args 823 _ret=1 824 825 # ifconfig_IF_aliasN which starts with "inet" 826 alias=0 827 while : ; do 828 ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}` 829 case "${ifconfig_args}" in 830 inet\ *) 831 ifconfig $1 ${ifconfig_args} -alias && _ret=0 832 ;; 833 "") 834 break 835 ;; 836 esac 837 alias=$((${alias} + 1)) 838 done 839 840 return $_ret 841} 842 843# ifalias_ipv6_down if 844# Helper function for ifalias_down(). Handles IPv6. 845# 846ifalias_ipv6_down() 847{ 848 local _ret alias ifconfig_args 849 _ret=1 850 851 # ifconfig_IF_aliasN which starts with "inet6" 852 alias=0 853 while : ; do 854 ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}` 855 case "${ifconfig_args}" in 856 inet6\ *) 857 ifconfig $1 ${ifconfig_args} -alias && _ret=0 858 ;; 859 "") 860 break 861 ;; 862 esac 863 alias=$((${alias} + 1)) 864 done 865 866 # backward compatibility: ipv6_ifconfig_IF_aliasN. 867 alias=0 868 while : ; do 869 ifconfig_args=`get_if_var $1 ipv6_ifconfig_IF_alias${alias}` 870 case "${ifconfig_args}" in 871 "") 872 break 873 ;; 874 *) 875 ifconfig $1 inet6 ${ifconfig_args} -alias && _ret=0 876 warn "\$ipv6_ifconfig_$1_alias${alias} is obsolete." \ 877 " Use ifconfig_$1_aliasN instead." 878 ;; 879 esac 880 alias=$((${alias} + 1)) 881 done 882 883 return $_ret 884} 885 886# ipv6_prefix_hostid_addr_common if action 887# Add or remove IPv6 prefix + hostid addr on the interface $if 888# 889ipv6_prefix_hostid_addr_common() 890{ 891 local _if _action prefix laddr hostid j address 892 _if=$1 893 _action=$2 894 prefix=`get_if_var ${_if} ipv6_prefix_IF` 895 896 if [ -n "${prefix}" ]; then 897 laddr=`network6_getladdr ${_if}` 898 hostid=${laddr#fe80::} 899 hostid=${hostid%\%*} 900 901 for j in ${prefix}; do 902 address=$j\:${hostid} 903 ifconfig ${_if} inet6 ${address} prefixlen 64 ${_action} 904 905 # if I am a router, add subnet router 906 # anycast address (RFC 2373). 907 if checkyesno ipv6_gateway_enable; then 908 ifconfig ${_if} inet6 $j:: prefixlen 64 \ 909 ${_action} anycast 910 fi 911 done 912 fi 913} 914 915# ipv6_accept_rtadv_up if 916# Enable accepting Router Advertisement and send Router 917# Solicitation message 918ipv6_accept_rtadv_up() 919{ 920 if ipv6_autoconfif $1; then 921 ifconfig $1 inet6 accept_rtadv up 922 if ! checkyesno rtsold_enable; then 923 rtsol ${rtsol_flags} $1 924 fi 925 fi 926} 927 928# ipv6_accept_rtadv_down if 929# Disable accepting Router Advertisement 930ipv6_accept_rtadv_down() 931{ 932 if ipv6_autoconfif $1; then 933 ifconfig $1 inet6 -accept_rtadv 934 fi 935} 936 937# ifscript_up if 938# Evaluate a startup script for the $if interface. 939# It returns 0 if a script was found and processed or 940# 1 if no script was found. 941# 942ifscript_up() 943{ 944 if [ -r /etc/start_if.$1 ]; then 945 . /etc/start_if.$1 946 return 0 947 else 948 return 1 949 fi 950} 951 952# ifscript_down if 953# Evaluate a shutdown script for the $if interface. 954# It returns 0 if a script was found and processed or 955# 1 if no script was found. 956# 957ifscript_down() 958{ 959 if [ -r /etc/stop_if.$1 ]; then 960 . /etc/stop_if.$1 961 return 0 962 else 963 return 1 964 fi 965} 966 967# clone_up 968# Create cloneable interfaces. 969# 970clone_up() 971{ 972 local _prefix _list ifn 973 _prefix= 974 _list= 975 976 # create_args_IF 977 for ifn in ${cloned_interfaces}; do 978 ifconfig ${ifn} create `get_if_var ${ifn} create_args_IF` 979 if [ $? -eq 0 ]; then 980 _list="${_list}${_prefix}${ifn}" 981 [ -z "$_prefix" ] && _prefix=' ' 982 fi 983 done 984 debug "Cloned: ${_list}" 985} 986 987# clone_down 988# Destroy cloned interfaces. Destroyed interfaces are echoed to 989# standard output. 990# 991clone_down() 992{ 993 local _prefix _list ifn 994 _prefix= 995 _list= 996 997 for ifn in ${cloned_interfaces}; do 998 ifconfig -n ${ifn} destroy 999 if [ $? -eq 0 ]; then 1000 _list="${_list}${_prefix}${ifn}" 1001 [ -z "$_prefix" ] && _prefix=' ' 1002 fi 1003 done 1004 debug "Destroyed clones: ${_list}" 1005} 1006 1007# childif_create 1008# Create and configure child interfaces. Return 0 if child 1009# interfaces are created. 1010# 1011childif_create() 1012{ 1013 local cfg child child_vlans child_wlans create_args debug_flags ifn i 1014 cfg=1 1015 ifn=$1 1016 1017 # Create wireless interfaces 1018 child_wlans=`get_if_var $ifn wlans_IF` 1019 1020 for child in ${child_wlans}; do 1021 create_args="wlandev $ifn `get_if_var $child create_args_IF`" 1022 debug_flags="`get_if_var $child wlandebug_IF`" 1023 1024 if expr $child : 'wlan[0-9][0-9]*$' >/dev/null 2>&1; then 1025 ifconfig $child create ${create_args} && cfg=0 1026 if [ -n "${debug_flags}" ]; then 1027 wlandebug -i $child ${debug_flags} 1028 fi 1029 else 1030 i=`ifconfig wlan create ${create_args}` 1031 if [ -n "${debug_flags}" ]; then 1032 wlandebug -i $i ${debug_flags} 1033 fi 1034 ifconfig $i name $child && cfg=0 1035 fi 1036 if autoif $child; then 1037 ifn_start $child 1038 fi 1039 done 1040 1041 # Create vlan interfaces 1042 child_vlans=`get_if_var $ifn vlans_IF` 1043 1044 if [ -n "${child_vlans}" ]; then 1045 load_kld if_vlan 1046 fi 1047 1048 for child in ${child_vlans}; do 1049 if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then 1050 child="${ifn}.${child}" 1051 create_args=`get_if_var $child create_args_IF` 1052 ifconfig $child create ${create_args} && cfg=0 1053 else 1054 create_args="vlandev $ifn `get_if_var $child create_args_IF`" 1055 if expr $child : 'vlan[0-9][0-9]*$' >/dev/null 2>&1; then 1056 ifconfig $child create ${create_args} && cfg=0 1057 else 1058 i=`ifconfig vlan create ${create_args}` 1059 ifconfig $i name $child && cfg=0 1060 fi 1061 fi 1062 if autoif $child; then 1063 ifn_start $child 1064 fi 1065 done 1066 1067 return ${cfg} 1068} 1069 1070# childif_destroy 1071# Destroy child interfaces. 1072# 1073childif_destroy() 1074{ 1075 local cfg child child_vlans child_wlans ifn 1076 cfg=1 1077 1078 child_wlans=`get_if_var $ifn wlans_IF` 1079 for child in ${child_wlans}; do 1080 if ! ifexists $child; then 1081 continue 1082 fi 1083 ifconfig -n $child destroy && cfg=0 1084 done 1085 1086 child_vlans=`get_if_var $ifn vlans_IF` 1087 for child in ${child_vlans}; do 1088 if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then 1089 child="${ifn}.${child}" 1090 fi 1091 if ! ifexists $child; then 1092 continue 1093 fi 1094 ifconfig -n $child destroy && cfg=0 1095 done 1096 1097 return ${cfg} 1098} 1099 1100# ng_mkpeer 1101# Create netgraph nodes. 1102# 1103ng_mkpeer() 1104{ 1105 ngctl -f - 2> /dev/null <<EOF 1106mkpeer $* 1107msg dummy nodeinfo 1108EOF 1109} 1110 1111# ng_create_one 1112# Create netgraph nodes. 1113# 1114ng_create_one() 1115{ 1116 local t 1117 1118 ng_mkpeer $* | while read line; do 1119 t=`expr "${line}" : '.* name="\([a-z]*[0-9]*\)" .*'` 1120 if [ -n "${t}" ]; then 1121 echo ${t} 1122 return 1123 fi 1124 done 1125} 1126 1127# gif_up 1128# Create gif(4) tunnel interfaces. 1129gif_up() 1130{ 1131 local i peers 1132 1133 for i in ${gif_interfaces}; do 1134 peers=`get_if_var $i gifconfig_IF` 1135 case ${peers} in 1136 '') 1137 continue 1138 ;; 1139 *) 1140 if expr $i : 'gif[0-9][0-9]*$' >/dev/null 2>&1; then 1141 ifconfig $i create >/dev/null 2>&1 1142 else 1143 gif=`ifconfig gif create` 1144 ifconfig $gif name $i 1145 fi 1146 ifconfig $i tunnel ${peers} 1147 ifconfig $i up 1148 ;; 1149 esac 1150 done 1151} 1152 1153# ng_fec_create ifn 1154# Configure Fast EtherChannel for interface $ifn. Returns 0 if 1155# FEC arguments were found and configured; returns !0 otherwise. 1156ng_fec_create() 1157{ 1158 local req_iface iface bogus 1159 req_iface="$1" 1160 1161 ngctl shutdown ${req_iface}: > /dev/null 2>&1 1162 1163 bogus="" 1164 while true; do 1165 iface=`ng_create_one fec dummy fec` 1166 if [ -z "${iface}" ]; then 1167 exit 2 1168 fi 1169 if [ "${iface}" = "${req_iface}" ]; then 1170 break 1171 fi 1172 bogus="${bogus} ${iface}" 1173 done 1174 1175 for iface in ${bogus}; do 1176 ngctl shutdown ${iface}: 1177 done 1178} 1179 1180# fec_up 1181# Create Fast EtherChannel interfaces. 1182fec_up() 1183{ 1184 local i j 1185 1186 for i in ${fec_interfaces}; do 1187 ng_fec_create $i 1188 for j in `get_if_var $i fecconfig_IF`; do 1189 case ${j} in 1190 '') 1191 continue 1192 ;; 1193 *) 1194 ngctl msg ${i}: add_iface "\"${j}\"" 1195 ;; 1196 esac 1197 done 1198 done 1199} 1200 1201# ipx_up ifn 1202# Configure any IPX addresses for interface $ifn. Returns 0 if 1203# IPX arguments were found and configured; returns 1 otherwise. 1204# 1205ipx_up() 1206{ 1207 local ifn 1208 ifn="$1" 1209 1210 # ifconfig_IF_ipx 1211 ifconfig_args=`_ifconfig_getargs $ifn ipx` 1212 if [ -n "${ifconfig_args}" ]; then 1213 ifconfig ${ifn} ${ifconfig_args} 1214 return 0 1215 fi 1216 1217 return 1 1218} 1219 1220# ipx_down ifn 1221# Remove IPX addresses for interface $ifn. Returns 0 if IPX 1222# addresses were found and unconfigured. It returns 1, otherwise. 1223# 1224ipx_down() 1225{ 1226 local _if _ifs _ret ipxList oldifs _ipx 1227 _if=$1 1228 _ifs="^" 1229 _ret=1 1230 ipxList="`ifconfig ${_if} | grep 'ipx ' | tr "\n" "$_ifs"`" 1231 oldifs="$IFS" 1232 1233 IFS="$_ifs" 1234 for _ipx in $ipxList ; do 1235 # get rid of extraneous line 1236 [ -z "$_ipx" ] && break 1237 1238 _ipx=`expr "$_ipx" : '.*\(ipx [0-9a-h]\{1,8\}H*\.[0-9a-h]\{1,12\}\).*'` 1239 1240 IFS="$oldifs" 1241 ifconfig ${_if} ${_ipx} delete 1242 IFS="$_ifs" 1243 _ret=0 1244 done 1245 IFS="$oldifs" 1246 1247 return $_ret 1248} 1249 1250# ifnet_rename 1251# Rename all requested interfaces. 1252# 1253ifnet_rename() 1254{ 1255 local _if _ifname 1256 1257 # ifconfig_IF_name 1258 for _if in `ifconfig -l`; do 1259 _ifname=`get_if_var $_if ifconfig_IF_name` 1260 if [ ! -z "$_ifname" ]; then 1261 ifconfig $_if name $_ifname 1262 fi 1263 done 1264 1265 return 0 1266} 1267 1268# list_net_interfaces type 1269# List all network interfaces. The type of interface returned 1270# can be controlled by the type argument. The type 1271# argument can be any of the following: 1272# nodhcp - all interfaces, excluding DHCP configured interfaces 1273# dhcp - list only DHCP configured interfaces 1274# noautoconf - all interfaces, excluding IPv6 Stateless 1275# Address Autoconf configured interfaces 1276# autoconf - list only IPv6 Stateless Address Autoconf 1277# configured interfaces 1278# If no argument is specified all network interfaces are output. 1279# Note that the list will include cloned interfaces if applicable. 1280# Cloned interfaces must already exist to have a chance to appear 1281# in the list if ${network_interfaces} is set to `auto'. 1282# 1283list_net_interfaces() 1284{ 1285 local type _tmplist _list _autolist _lo _if 1286 type=$1 1287 1288 # Get a list of ALL the interfaces and make lo0 first if it's there. 1289 # 1290 _tmplist= 1291 case ${network_interfaces} in 1292 [Aa][Uu][Tt][Oo]) 1293 _autolist="`ifconfig -l`" 1294 _lo= 1295 for _if in ${_autolist} ; do 1296 if autoif $_if; then 1297 if [ "$_if" = "lo0" ]; then 1298 _lo="lo0 " 1299 else 1300 _tmplist="${_tmplist} ${_if}" 1301 fi 1302 fi 1303 done 1304 _tmplist="${_lo}${_tmplist# }" 1305 ;; 1306 *) 1307 _tmplist="${network_interfaces} ${cloned_interfaces}" 1308 1309 # lo0 is effectively mandatory, so help prevent foot-shooting 1310 # 1311 case "$_tmplist" in 1312 lo0|'lo0 '*|*' lo0'|*' lo0 '*) ;; # This is fine, do nothing 1313 *) _tmplist="lo0 ${_tmplist}" ;; 1314 esac 1315 ;; 1316 esac 1317 1318 _list= 1319 case "$type" in 1320 nodhcp) 1321 for _if in ${_tmplist} ; do 1322 if ! dhcpif $_if && \ 1323 [ -n "`_ifconfig_getargs $_if`" ]; then 1324 _list="${_list# } ${_if}" 1325 fi 1326 done 1327 ;; 1328 dhcp) 1329 for _if in ${_tmplist} ; do 1330 if dhcpif $_if; then 1331 _list="${_list# } ${_if}" 1332 fi 1333 done 1334 ;; 1335 noautoconf) 1336 for _if in ${_tmplist} ; do 1337 if ! ipv6_autoconfif $_if && \ 1338 [ -n "`_ifconfig_getargs $_if ipv6`" ]; then 1339 _list="${_list# } ${_if}" 1340 fi 1341 done 1342 ;; 1343 autoconf) 1344 for _if in ${_tmplist} ; do 1345 if ipv6_autoconfif $_if; then 1346 _list="${_list# } ${_if}" 1347 fi 1348 done 1349 ;; 1350 *) 1351 _list=${_tmplist} 1352 ;; 1353 esac 1354 1355 echo $_list 1356 1357 return 0 1358} 1359 1360# get_default_if -address_family 1361# Get the interface of the default route for the given address family. 1362# The -address_family argument must be suitable passing to route(8). 1363# 1364get_default_if() 1365{ 1366 local routeget oldifs defif line 1367 defif= 1368 oldifs="$IFS" 1369 IFS=" 1370" 1371 for line in `route -n get $1 default 2>/dev/null`; do 1372 case $line in 1373 *interface:*) 1374 defif=${line##*: } 1375 ;; 1376 esac 1377 done 1378 IFS=${oldifs} 1379 1380 echo $defif 1381} 1382 1383# hexdigit arg 1384# Echo decimal number $arg (single digit) in hexadecimal format. 1385hexdigit() 1386{ 1387 printf '%x\n' "$1" 1388} 1389 1390# hexprint arg 1391# Echo decimal number $arg (multiple digits) in hexadecimal format. 1392hexprint() 1393{ 1394 printf '%x\n' "$1" 1395} 1396 1397is_wired_interface() 1398{ 1399 local media 1400 1401 case `ifconfig $1 2>/dev/null` in 1402 *media:?Ethernet*) media=Ethernet ;; 1403 esac 1404 1405 test "$media" = "Ethernet" 1406} 1407 1408# network6_getladdr if [flag] 1409# Echo link-local address from $if if any. 1410# If flag is defined, tentative ones will be excluded. 1411network6_getladdr() 1412{ 1413 local proto addr rest 1414 ifconfig $1 2>/dev/null | while read proto addr rest; do 1415 case ${proto} in 1416 inet6) 1417 case ${addr} in 1418 fe80::*) 1419 if [ -z "$2" ]; then 1420 echo ${addr} 1421 return 1422 fi 1423 case ${rest} in 1424 *tentative*) 1425 continue 1426 ;; 1427 *) 1428 echo ${addr} 1429 return 1430 esac 1431 esac 1432 esac 1433 done 1434} 1435