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$ 26# 27IFCONFIG_CMD="/sbin/ifconfig" 28 29# Maximum number of addresses expanded from a address range specification. 30_IPEXPANDMAX=31 31 32# 33# Subroutines commonly used from network startup scripts. 34# Requires that rc.conf be loaded first. 35# 36 37# ifn_start ifn 38# Bring up and configure an interface. If some configuration is 39# applied, print the interface configuration. 40# 41ifn_start() 42{ 43 local ifn cfg 44 ifn="$1" 45 cfg=1 46 47 [ -z "$ifn" ] && err 1 "ifn_start called without an interface" 48 49 ifscript_up ${ifn} && cfg=0 50 ifconfig_up ${ifn} && cfg=0 51 if ! noafif $ifn; then 52 afexists inet && ipv4_up ${ifn} && cfg=0 53 afexists inet6 && ipv6_up ${ifn} && cfg=0 54 afexists ipx && ipx_up ${ifn} && cfg=0 55 fi 56 childif_create ${ifn} && cfg=0 57 58 return $cfg 59} 60 61# ifn_stop ifn 62# Shutdown and de-configure an interface. If action is taken, 63# print the interface name. 64# 65ifn_stop() 66{ 67 local ifn cfg 68 ifn="$1" 69 cfg=1 70 71 [ -z "$ifn" ] && err 1 "ifn_stop called without an interface" 72 73 if ! noafif $ifn; then 74 afexists ipx && ipx_down ${ifn} && cfg=0 75 afexists inet6 && ipv6_down ${ifn} && cfg=0 76 afexists inet && ipv4_down ${ifn} && cfg=0 77 fi 78 ifconfig_down ${ifn} && cfg=0 79 ifscript_down ${ifn} && cfg=0 80 childif_destroy ${ifn} && cfg=0 81 82 return $cfg 83} 84 85# ifn_vnetup ifn 86# Move ifn to the specified vnet jail. 87# 88ifn_vnetup() 89{ 90 91 ifn_vnet0 $1 vnet 92} 93 94# ifn_vnetdown ifn 95# Reclaim ifn from the specified vnet jail. 96# 97ifn_vnetdown() 98{ 99 100 ifn_vnet0 $1 -vnet 101} 102 103# ifn_vnet0 ifn action 104# Helper function for ifn_vnetup and ifn_vnetdown. 105# 106ifn_vnet0() 107{ 108 local _ifn _cfg _action _vnet 109 _ifn="$1" 110 _action="$2" 111 _cfg=1 112 113 if _vnet=$(vnetif $_ifn); then 114 ${IFCONFIG_CMD} $_ifn $_action $_vnet && _cfg=0 115 fi 116 117 return $_cfg 118} 119 120# ifconfig_up if 121# Evaluate ifconfig(8) arguments for interface $if and 122# run ifconfig(8) with those arguments. It returns 0 if 123# arguments were found and executed or 1 if the interface 124# had no arguments. Pseudo arguments DHCP and WPA are handled 125# here. 126# 127ifconfig_up() 128{ 129 local _cfg _ipv6_opts ifconfig_args 130 _cfg=1 131 132 # Make sure lo0 always comes up. 133 if [ "$1" = "lo0" ]; then 134 _cfg=0 135 fi 136 137 # ifconfig_IF 138 ifconfig_args=`ifconfig_getargs $1` 139 if [ -n "${ifconfig_args}" ]; then 140 eval ${IFCONFIG_CMD} $1 ${ifconfig_args} 141 _cfg=0 142 fi 143 144 # inet6 specific 145 if ! noafif $1 && afexists inet6; then 146 if checkyesno ipv6_activate_all_interfaces; then 147 _ipv6_opts="-ifdisabled" 148 elif [ "$1" != "lo0" ]; then 149 _ipv6_opts="ifdisabled" 150 fi 151 152 # backward compatibility: $ipv6_enable 153 case $ipv6_enable in 154 [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 155 case $1 in 156 bridge[0-9]*) 157 # No accept_rtadv by default on if_bridge(4) 158 # to avoid a conflict with the member 159 # interfaces. 160 ;; 161 *) 162 if ! checkyesno ipv6_gateway_enable; then 163 _ipv6_opts="${_ipv6_opts} accept_rtadv" 164 fi 165 ;; 166 esac 167 ;; 168 esac 169 170 case $ipv6_cpe_wanif in 171 $1) 172 _ipv6_opts="${_ipv6_opts} -no_radr accept_rtadv" 173 ;; 174 esac 175 176 if [ -n "${_ipv6_opts}" ]; then 177 ${IFCONFIG_CMD} $1 inet6 ${_ipv6_opts} 178 fi 179 180 # ifconfig_IF_ipv6 181 ifconfig_args=`ifconfig_getargs $1 ipv6` 182 if [ -n "${ifconfig_args}" ]; then 183 # backward compatibility: inet6 keyword 184 case "${ifconfig_args}" in 185 :*|[0-9a-fA-F]*:*) 186 warn "\$ifconfig_$1_ipv6 needs " \ 187 "\"inet6\" keyword for an IPv6 address." 188 ifconfig_args="inet6 ${ifconfig_args}" 189 ;; 190 esac 191 ${IFCONFIG_CMD} $1 inet6 -ifdisabled 192 eval ${IFCONFIG_CMD} $1 ${ifconfig_args} 193 _cfg=0 194 fi 195 196 # $ipv6_prefix_IF will be handled in 197 # ipv6_prefix_hostid_addr_common(). 198 ifconfig_args=`get_if_var $1 ipv6_prefix_IF` 199 if [ -n "${ifconfig_args}" ]; then 200 ${IFCONFIG_CMD} $1 inet6 -ifdisabled 201 _cfg=0 202 fi 203 204 # backward compatibility: $ipv6_ifconfig_IF 205 ifconfig_args=`get_if_var $1 ipv6_ifconfig_IF` 206 if [ -n "${ifconfig_args}" ]; then 207 warn "\$ipv6_ifconfig_$1 is obsolete." \ 208 " Use ifconfig_$1_ipv6 instead." 209 ${IFCONFIG_CMD} $1 inet6 -ifdisabled 210 eval ${IFCONFIG_CMD} $1 inet6 ${ifconfig_args} 211 _cfg=0 212 fi 213 fi 214 215 ifalias $1 link alias 216 ifalias $1 ether alias 217 218 if [ ${_cfg} -eq 0 ]; then 219 ${IFCONFIG_CMD} $1 up 220 fi 221 222 if wpaif $1; then 223 /etc/rc.d/wpa_supplicant start $1 224 _cfg=0 # XXX: not sure this should count 225 elif hostapif $1; then 226 /etc/rc.d/hostapd start $1 227 _cfg=0 228 fi 229 230 if dhcpif $1; then 231 if [ $_cfg -ne 0 ] ; then 232 ${IFCONFIG_CMD} $1 up 233 fi 234 if syncdhcpif $1; then 235 /etc/rc.d/dhclient start $1 236 fi 237 _cfg=0 238 fi 239 240 return $_cfg 241} 242 243# ifconfig_down if 244# returns 1 if wpa_supplicant or dhclient was stopped or 245# the interface exists. 246# 247ifconfig_down() 248{ 249 local _cfg 250 _cfg=1 251 252 if wpaif $1; then 253 /etc/rc.d/wpa_supplicant stop $1 254 _cfg=0 255 elif hostapif $1; then 256 /etc/rc.d/hostapd stop $1 257 _cfg=0 258 fi 259 260 if dhcpif $1; then 261 /etc/rc.d/dhclient stop $1 262 _cfg=0 263 fi 264 265 if ifexists $1; then 266 ${IFCONFIG_CMD} $1 down 267 _cfg=0 268 fi 269 270 return $_cfg 271} 272 273# get_if_var if var [default] 274# Return the value of the pseudo-hash corresponding to $if where 275# $var is a string containg the sub-string "IF" which will be 276# replaced with $if after the characters defined in _punct are 277# replaced with '_'. If the variable is unset, replace it with 278# $default if given. 279get_if_var() 280{ 281 local _if _punct _punct_c _var _default prefix suffix 282 283 if [ $# -ne 2 -a $# -ne 3 ]; then 284 err 3 'USAGE: get_if_var name var [default]' 285 fi 286 287 _if=$1 288 _punct=". - / +" 289 for _punct_c in $_punct; do 290 _if=`ltr ${_if} ${_punct_c} '_'` 291 done 292 _var=$2 293 _default=$3 294 295 prefix=${_var%%IF*} 296 suffix=${_var##*IF} 297 eval echo \${${prefix}${_if}${suffix}-${_default}} 298} 299 300# _ifconfig_getargs if [af] 301# Prints the arguments for the supplied interface to stdout. 302# Returns 1 if empty. In general, ifconfig_getargs should be used 303# outside this file. 304_ifconfig_getargs() 305{ 306 local _ifn _af 307 _ifn=$1 308 _af=${2+_$2} 309 310 if [ -z "$_ifn" ]; then 311 return 1 312 fi 313 314 get_if_var $_ifn ifconfig_IF$_af "$ifconfig_DEFAULT" 315} 316 317# ifconfig_getargs if [af] 318# Takes the result from _ifconfig_getargs and removes pseudo 319# args such as DHCP and WPA. 320ifconfig_getargs() 321{ 322 local _tmpargs _arg _args _vnet 323 _tmpargs=`_ifconfig_getargs $1 $2` 324 if [ $? -eq 1 ]; then 325 return 1 326 fi 327 _args= 328 _vnet=0 329 330 for _arg in $_tmpargs; do 331 case $_arg:$_vnet in 332 [Dd][Hh][Cc][Pp]:0) ;; 333 [Nn][Oo][Aa][Uu][Tt][Oo]:0) ;; 334 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]:0) ;; 335 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]:0) ;; 336 [Ww][Pp][Aa]:0) ;; 337 [Hh][Oo][Ss][Tt][Aa][Pp]:0) ;; 338 vnet:0) _vnet=1 ;; 339 *:1) _vnet=0 ;; 340 *:0) 341 _args="$_args $_arg" 342 ;; 343 esac 344 done 345 346 echo $_args 347} 348 349# autoif 350# Returns 0 if the interface should be automatically configured at 351# boot time and 1 otherwise. 352autoif() 353{ 354 local _tmpargs _arg 355 _tmpargs=`_ifconfig_getargs $1` 356 357 for _arg in $_tmpargs; do 358 case $_arg in 359 [Nn][Oo][Aa][Uu][Tt][Oo]) 360 return 1 361 ;; 362 esac 363 done 364 365 return 0 366} 367 368# dhcpif if 369# Returns 0 if the interface is a DHCP interface and 1 otherwise. 370dhcpif() 371{ 372 local _tmpargs _arg 373 _tmpargs=`_ifconfig_getargs $1` 374 375 case $1 in 376 lo[0-9]*|\ 377 stf[0-9]*|\ 378 faith[0-9]*|\ 379 lp[0-9]*|\ 380 sl[0-9]*) 381 return 1 382 ;; 383 esac 384 if noafif $1; then 385 return 1 386 fi 387 388 for _arg in $_tmpargs; do 389 case $_arg in 390 [Dd][Hh][Cc][Pp]) 391 return 0 392 ;; 393 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 394 return 0 395 ;; 396 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 397 return 0 398 ;; 399 esac 400 done 401 402 return 1 403} 404 405# syncdhcpif 406# Returns 0 if the interface should be configured synchronously and 407# 1 otherwise. 408syncdhcpif() 409{ 410 local _tmpargs _arg 411 _tmpargs=`_ifconfig_getargs $1` 412 413 if noafif $1; then 414 return 1 415 fi 416 417 for _arg in $_tmpargs; do 418 case $_arg in 419 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 420 return 1 421 ;; 422 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 423 return 0 424 ;; 425 esac 426 done 427 428 checkyesno synchronous_dhclient 429} 430 431# wpaif if 432# Returns 0 if the interface is a WPA interface and 1 otherwise. 433wpaif() 434{ 435 local _tmpargs _arg 436 _tmpargs=`_ifconfig_getargs $1` 437 438 for _arg in $_tmpargs; do 439 case $_arg in 440 [Ww][Pp][Aa]) 441 return 0 442 ;; 443 esac 444 done 445 446 return 1 447} 448 449# hostapif if 450# Returns 0 if the interface is a HOSTAP interface and 1 otherwise. 451hostapif() 452{ 453 local _tmpargs _arg 454 _tmpargs=`_ifconfig_getargs $1` 455 456 for _arg in $_tmpargs; do 457 case $_arg in 458 [Hh][Oo][Ss][Tt][Aa][Pp]) 459 return 0 460 ;; 461 esac 462 done 463 464 return 1 465} 466 467# vnetif if 468# Returns 0 and echo jail if "vnet" keyword is specified on the 469# interface, and 1 otherwise. 470vnetif() 471{ 472 local _tmpargs _arg _vnet 473 _tmpargs=`_ifconfig_getargs $1` 474 475 _vnet=0 476 for _arg in $_tmpargs; do 477 case $_arg:$_vnet in 478 vnet:0) _vnet=1 ;; 479 *:1) echo $_arg; return 0 ;; 480 esac 481 done 482 483 return 1 484} 485 486# afexists af 487# Returns 0 if the address family is enabled in the kernel 488# 1 otherwise. 489afexists() 490{ 491 local _af 492 _af=$1 493 494 case ${_af} in 495 inet|inet6) 496 check_kern_features ${_af} 497 ;; 498 ipx) 499 ${SYSCTL_N} net.ipx > /dev/null 2>&1 500 ;; 501 atm) 502 if [ -x /sbin/atmconfig ]; then 503 /sbin/atmconfig diag list > /dev/null 2>&1 504 else 505 return 1 506 fi 507 ;; 508 link|ether) 509 return 0 510 ;; 511 *) 512 err 1 "afexists(): Unsupported address family: $_af" 513 ;; 514 esac 515} 516 517# noafif if 518# Returns 0 if the interface has no af configuration and 1 otherwise. 519noafif() 520{ 521 local _if 522 _if=$1 523 524 case $_if in 525 pflog[0-9]*|\ 526 pfsync[0-9]*|\ 527 usbus[0-9]*|\ 528 an[0-9]*|\ 529 ath[0-9]*|\ 530 ipw[0-9]*|\ 531 ipfw[0-9]*|\ 532 iwi[0-9]*|\ 533 iwn[0-9]*|\ 534 ral[0-9]*|\ 535 wi[0-9]*|\ 536 wl[0-9]*|\ 537 wpi[0-9]*) 538 return 0 539 ;; 540 esac 541 542 return 1 543} 544 545# ipv6if if 546# Returns 0 if the interface should be configured for IPv6 and 547# 1 otherwise. 548ipv6if() 549{ 550 local _if _tmpargs i 551 _if=$1 552 553 if ! afexists inet6; then 554 return 1 555 fi 556 557 # lo0 is always IPv6-enabled 558 case $_if in 559 lo0) 560 return 0 561 ;; 562 esac 563 564 case "${ipv6_network_interfaces}" in 565 $_if|"$_if "*|*" $_if"|*" $_if "*|[Aa][Uu][Tt][Oo]) 566 # True if $ifconfig_IF_ipv6 is defined. 567 _tmpargs=`_ifconfig_getargs $_if ipv6` 568 if [ -n "${_tmpargs}" ]; then 569 return 0 570 fi 571 572 # True if $ipv6_prefix_IF is defined. 573 _tmpargs=`get_if_var $_if ipv6_prefix_IF` 574 if [ -n "${_tmpargs}" ]; then 575 return 0 576 fi 577 578 # backward compatibility: True if $ipv6_ifconfig_IF is defined. 579 _tmpargs=`get_if_var $_if ipv6_ifconfig_IF` 580 if [ -n "${_tmpargs}" ]; then 581 return 0 582 fi 583 ;; 584 esac 585 586 return 1 587} 588 589# ipv6_autoconfif if 590# Returns 0 if the interface should be configured for IPv6 with 591# Stateless Address Configuration; 1 otherwise. 592ipv6_autoconfif() 593{ 594 local _if _tmpargs _arg 595 _if=$1 596 597 case $_if in 598 lo[0-9]*|\ 599 stf[0-9]*|\ 600 faith[0-9]*|\ 601 lp[0-9]*|\ 602 sl[0-9]*) 603 return 1 604 ;; 605 esac 606 if noafif $_if; then 607 return 1 608 fi 609 if ! ipv6if $_if; then 610 return 1 611 fi 612 if checkyesno ipv6_gateway_enable; then 613 return 1 614 fi 615 _tmpargs=`get_if_var $_if ipv6_prefix_IF` 616 if [ -n "${_tmpargs}" ]; then 617 return 1 618 fi 619 # backward compatibility: $ipv6_enable 620 case $ipv6_enable in 621 [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 622 if checkyesno ipv6_gateway_enable; then 623 return 1 624 fi 625 case $1 in 626 bridge[0-9]*) 627 # No accept_rtadv by default on if_bridge(4) 628 # to avoid a conflict with the member 629 # interfaces. 630 return 1 631 ;; 632 *) 633 return 0 634 ;; 635 esac 636 ;; 637 esac 638 639 _tmpargs=`_ifconfig_getargs $_if ipv6` 640 for _arg in $_tmpargs; do 641 case $_arg in 642 accept_rtadv) 643 return 0 644 ;; 645 esac 646 done 647 648 # backward compatibility: $ipv6_ifconfig_IF 649 _tmpargs=`get_if_var $_if ipv6_ifconfig_IF` 650 for _arg in $_tmpargs; do 651 case $_arg in 652 accept_rtadv) 653 return 0 654 ;; 655 esac 656 done 657 658 return 1 659} 660 661# ifexists if 662# Returns 0 if the interface exists and 1 otherwise. 663ifexists() 664{ 665 [ -z "$1" ] && return 1 666 ${IFCONFIG_CMD} -n $1 > /dev/null 2>&1 667} 668 669# ipv4_up if 670# add IPv4 addresses to the interface $if 671ipv4_up() 672{ 673 local _if _ret 674 _if=$1 675 _ret=1 676 677 # Add 127.0.0.1/8 to lo0 unless otherwise specified. 678 if [ "${_if}" = "lo0" ]; then 679 ifconfig_args=`get_if_var ${_if} ifconfig_IF` 680 if [ -z "${ifconfig_args}" ]; then 681 ${IFCONFIG_CMD} ${_if} inet 127.0.0.1/8 alias 682 fi 683 fi 684 ifalias ${_if} inet alias && _ret=0 685 686 return $_ret 687} 688 689# ipv6_up if 690# add IPv6 addresses to the interface $if 691ipv6_up() 692{ 693 local _if _ret 694 _if=$1 695 _ret=1 696 697 if ! ipv6if $_if; then 698 return 0 699 fi 700 701 ifalias ${_if} inet6 alias && _ret=0 702 ipv6_prefix_hostid_addr_common ${_if} alias && _ret=0 703 ipv6_accept_rtadv_up ${_if} && _ret=0 704 705 return $_ret 706} 707 708# ipv4_down if 709# remove IPv4 addresses from the interface $if 710ipv4_down() 711{ 712 local _if _ifs _ret inetList oldifs _inet 713 _if=$1 714 _ifs="^" 715 _ret=1 716 717 ifalias ${_if} inet -alias && _ret=0 718 719 inetList="`${IFCONFIG_CMD} ${_if} | grep 'inet ' | tr "\n\t" "$_ifs"`" 720 721 oldifs="$IFS" 722 IFS="$_ifs" 723 for _inet in $inetList ; do 724 # get rid of extraneous line 725 case $_inet in 726 inet\ *) ;; 727 *) continue ;; 728 esac 729 730 _inet=`expr "$_inet" : '.*\(inet \([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*'` 731 732 IFS="$oldifs" 733 ${IFCONFIG_CMD} ${_if} ${_inet} delete 734 IFS="$_ifs" 735 _ret=0 736 done 737 IFS="$oldifs" 738 739 return $_ret 740} 741 742# ipv6_down if 743# remove IPv6 addresses from the interface $if 744ipv6_down() 745{ 746 local _if _ifs _ret inetList oldifs _inet6 747 _if=$1 748 _ifs="^" 749 _ret=1 750 751 if ! ipv6if $_if; then 752 return 0 753 fi 754 755 ipv6_accept_rtadv_down ${_if} && _ret=0 756 ipv6_prefix_hostid_addr_common ${_if} -alias && _ret=0 757 ifalias ${_if} inet6 -alias && _ret=0 758 759 inetList="`${IFCONFIG_CMD} ${_if} | grep 'inet6 ' | tr "\n\t" "$_ifs"`" 760 761 oldifs="$IFS" 762 IFS="$_ifs" 763 for _inet6 in $inetList ; do 764 # get rid of extraneous line 765 case $_inet in 766 inet6\ *) ;; 767 *) continue ;; 768 esac 769 770 _inet6=`expr "$_inet6" : '.*\(inet6 \([0-9a-f:]*\)\).*'` 771 772 IFS="$oldifs" 773 ${IFCONFIG_CMD} ${_if} ${_inet6} -alias 774 IFS="$_ifs" 775 _ret=0 776 done 777 IFS="$oldifs" 778 779 return $_ret 780} 781 782# ifalias if af action 783# Configure or remove aliases for network interface $if. 784# It returns 0 if at least one alias was configured or 785# removed, or 1 if there were none. 786# 787ifalias() 788{ 789 local _ret 790 _ret=1 791 792 afexists $2 || return $_ret 793 794 case "$2" in 795 inet|inet6|link|ether) 796 ifalias_af_common $1 $2 $3 && _ret=0 797 ;; 798 esac 799 800 return $_ret 801} 802 803# ifalias_expand_addr af action addr 804# Expand address range ("N-M") specification in addr. 805# "addr" must not include an address-family keyword. 806# The results will include an address-family keyword. 807# 808ifalias_expand_addr() 809{ 810 local _af _action 811 812 _af=$1 813 _action=$2 814 shift 2 815 816 afexists $_af || return 817 ifalias_expand_addr_$_af $_action $* 818} 819 820# ifalias_expand_addr_inet action addr 821# Helper function for ifalias_expand_addr(). Handles IPv4. 822# 823ifalias_expand_addr_inet() 824{ 825 local _action _arg _cidr _cidr_addr _exargs 826 local _ipaddr _plen _range _iphead _iptail _iplow _iphigh _ipcount 827 local _retstr _c 828 _action=$1 829 _arg=$2 830 shift 2 831 _exargs=$* 832 _retstr= 833 834 case $_action:$_arg:$_exargs in 835 *:*--*) return ;; # invalid 836 tmp:*[0-9]-[0-9]*:*) # to be expanded 837 _action="alias" 838 ;; 839 *:*[0-9]-[0-9]*:*) # to be expanded 840 ;; 841 tmp:*:*netmask*) # already expanded w/ netmask option 842 echo ${_arg%/[0-9]*} $_exargs && return 843 ;; 844 tmp:*:*) # already expanded w/o netmask option 845 echo $_arg $_exargs && return 846 ;; 847 *:*:*netmask*) # already expanded w/ netmask option 848 echo inet ${_arg%/[0-9]*} $_exargs && return 849 ;; 850 *:*:*) # already expanded w/o netmask option 851 echo inet $_arg $_exargs && return 852 ;; 853 esac 854 855 for _cidr in $_arg; do 856 _ipaddr=${_cidr%%/*} 857 _plen=${_cidr##*/} 858 # When subnet prefix length is not specified, use /32. 859 case $_plen in 860 $_ipaddr) _plen=32 ;; # "/" character not found 861 esac 862 863 OIFS=$IFS 864 IFS=. set -- $_ipaddr 865 _range= 866 _iphead= 867 _iptail= 868 for _c in $@; do 869 case $_range:$_c in 870 :[0-9]*-[0-9]*) 871 _range=$_c 872 ;; 873 :*) 874 _iphead="${_iphead}${_iphead:+.}${_c}" 875 ;; 876 *:*) 877 _iptail="${_iptail}${_iptail:+.}${_c}" 878 ;; 879 esac 880 done 881 IFS=$OIFS 882 _iplow=${_range%-*} 883 _iphigh=${_range#*-} 884 885 # clear netmask when removing aliases 886 if [ "$_action" = "-alias" ]; then 887 _plen="" 888 fi 889 890 _ipcount=$_iplow 891 while [ "$_ipcount" -le "$_iphigh" ]; do 892 _retstr="${_retstr} ${_iphead}${_iphead:+.}${_ipcount}${_iptail:+.}${_iptail}${_plen:+/}${_plen}" 893 if [ $_ipcount -gt $(($_iplow + $_IPEXPANDMAX)) ]; then 894 warn "Range specification is too large (${_iphead}${_iphead:+.}${_iplow}${_iptail:+.}${_iptail}-${_iphead}${_iphead:+.}${_iphigh}${_iptail:+.}${_iptail}). ${_iphead}${_iphead:+.}${_iplow}${_iptail:+.}${_iptail}-${_iphead}${_iphead:+.}${_ipcount}${_iptail:+.}${_iptail} was processed." 895 break 896 else 897 _ipcount=$(($_ipcount + 1)) 898 fi 899 # Forcibly set /32 for remaining aliases. 900 _plen=32 901 done 902 done 903 904 for _c in $_retstr; do 905 ifalias_expand_addr_inet $_action $_c $_exargs 906 done 907} 908 909# ifalias_expand_addr_inet6 action addr 910# Helper function for ifalias_expand_addr(). Handles IPv6. 911# 912ifalias_expand_addr_inet6() 913{ 914 local _action _arg _cidr _cidr_addr _exargs 915 local _ipaddr _plen _ipleft _ipright _iplow _iphigh _ipcount 916 local _ipv4part 917 local _retstr _c 918 _action=$1 919 _arg=$2 920 shift 2 921 _exargs=$* 922 _retstr= 923 924 case $_action:$_arg:$_exargs in 925 *:*--*:*) return ;; # invalid 926 tmp:*[0-9a-zA-Z]-[0-9a-zA-Z]*:*)# to be expanded 927 _action="alias" 928 ;; 929 *:*[0-9a-zA-Z]-[0-9a-zA-Z]*:*) # to be expanded 930 ;; 931 tmp:*:*prefixlen*) # already expanded w/ prefixlen option 932 echo ${_arg%/[0-9]*} $_exargs && return 933 ;; 934 tmp:*:*) # already expanded w/o prefixlen option 935 echo $_arg $_exargs && return 936 ;; 937 *:*:*prefixlen*) # already expanded w/ prefixlen option 938 echo inet6 ${_arg%/[0-9]*} $_exargs && return 939 ;; 940 *:*:*) # already expanded w/o prefixlen option 941 echo inet6 $_arg $_exargs && return 942 ;; 943 esac 944 945 for _cidr in $_arg; do 946 _ipaddr="${_cidr%%/*}" 947 _plen="${_cidr##*/}" 948 949 case $_action:$_ipaddr:$_cidr in 950 -alias:*:*) unset _plen ;; 951 *:$_cidr:$_ipaddr) unset _plen ;; 952 esac 953 954 if [ "${_ipaddr%:*.*.*.*}" = "$_ipaddr" ]; then 955 # Handle !v4mapped && !v4compat addresses. 956 957 # The default prefix length is 64. 958 case $_ipaddr:$_cidr in 959 $_cidr:$_ipaddr) _plen="64" ;; 960 esac 961 _ipleft=${_ipaddr%-*} 962 _ipright=${_ipaddr#*-} 963 _iplow=${_ipleft##*:} 964 _iphigh=${_ipright%%:*} 965 _ipleft=${_ipleft%:*} 966 _ipright=${_ipright#*:} 967 968 if [ "$_iphigh" = "$_ipright" ]; then 969 unset _ipright 970 else 971 _ipright=:$_ipright 972 fi 973 974 if [ -n "$_iplow" -a -n "$_iphigh" ]; then 975 _iplow=$((0x$_iplow)) 976 _iphigh=$((0x$_iphigh)) 977 _ipcount=$_iplow 978 while [ $_ipcount -le $_iphigh ]; do 979 _r=`printf "%s:%04x%s%s" \ 980 $_ipleft $_ipcount $_ipright \ 981 ${_plen:+/}$_plen` 982 _retstr="$_retstr $_r" 983 if [ $_ipcount -gt $(($_iplow + $_IPEXPANDMAX)) ] 984 then 985 warn "Range specification is too large $(printf '(%s:%04x%s-%s:%04x%s)' $_ipleft $_iplow $_ipright $_ipleft $_iphigh $_ipright). $(printf '%s:%04x%s-%s:%04x%s' $_ipleft $_iplow $_ipright $_ipleft $_ipcount $_ipright) was processed." 986 break 987 else 988 _ipcount=$(($_ipcount + 1)) 989 fi 990 done 991 else 992 _retstr="${_ipaddr}${_plen:+/}${_plen}" 993 fi 994 995 for _c in $_retstr; do 996 ifalias_expand_addr_inet6 $_action $_c $_exargs 997 done 998 else 999 # v4mapped/v4compat should handle as an IPv4 alias 1000 _ipv4part=${_ipaddr##*:} 1001 1002 # Adjust prefix length if any. If not, set the 1003 # default prefix length as 32. 1004 case $_ipaddr:$_cidr in 1005 $_cidr:$_ipaddr) _plen=32 ;; 1006 *) _plen=$(($_plen - 96)) ;; 1007 esac 1008 1009 _retstr=`ifalias_expand_addr_inet \ 1010 tmp ${_ipv4part}${_plen:+/}${_plen}` 1011 for _c in $_retstr; do 1012 ifalias_expand_addr_inet $_action $_c $_exargs 1013 done 1014 fi 1015 done 1016} 1017 1018# ifalias_af_common_handler if af action args 1019# Helper function for ifalias_af_common(). 1020# 1021ifalias_af_common_handler() 1022{ 1023 local _ret _if _af _action _args _c _tmpargs 1024 1025 _ret=1 1026 _if=$1 1027 _af=$2 1028 _action=$3 1029 shift 3 1030 _args=$* 1031 1032 case $_args in 1033 ${_af}\ *) ;; 1034 *) return ;; 1035 esac 1036 1037 # link(ether) does not support address removal. 1038 case $_af:$_action in 1039 link:-alias|ether:-alias) return ;; 1040 esac 1041 1042 _tmpargs= 1043 for _c in $_args; do 1044 case $_c in 1045 ${_af}) 1046 case $_tmpargs in 1047 ${_af}\ *-*) 1048 ifalias_af_common_handler $_if $_af $_action \ 1049 `ifalias_expand_addr $_af $_action ${_tmpargs#${_af}\ }` 1050 ;; 1051 ${_af}\ *) 1052 ${IFCONFIG_CMD} $_if $_tmpargs $_action && _ret=0 1053 ;; 1054 esac 1055 _tmpargs=$_af 1056 ;; 1057 *) 1058 _tmpargs="$_tmpargs $_c" 1059 ;; 1060 esac 1061 done 1062 # Process the last component if any. 1063 if [ -n "$_tmpargs}" ]; then 1064 case $_tmpargs in 1065 ${_af}\ *-*) 1066 ifalias_af_common_handler $_if $_af $_action \ 1067 `ifalias_expand_addr $_af $_action ${_tmpargs#${_af}\ }` 1068 ;; 1069 ${_af}\ *) 1070 ${IFCONFIG_CMD} $_if $_tmpargs $_action && _ret=0 1071 ;; 1072 esac 1073 fi 1074 1075 return $_ret 1076} 1077 1078# ifalias_af_common if af action 1079# Helper function for ifalias(). 1080# 1081ifalias_af_common() 1082{ 1083 local _ret _if _af _action alias ifconfig_args _aliasn _c _tmpargs _iaf 1084 1085 _ret=1 1086 _aliasn= 1087 _if=$1 1088 _af=$2 1089 _action=$3 1090 1091 # ifconfig_IF_aliasN which starts with $_af 1092 alias=0 1093 while : ; do 1094 ifconfig_args=`get_if_var $_if ifconfig_IF_alias${alias}` 1095 _iaf= 1096 case $ifconfig_args in 1097 inet\ *) _iaf=inet ;; 1098 inet6\ *) _iaf=inet6 ;; 1099 ipx\ *) _iaf=ipx ;; 1100 link\ *) _iaf=link ;; 1101 ether\ *) _iaf=ether ;; 1102 esac 1103 1104 case ${_af}:${_action}:${_iaf}:"${ifconfig_args}" in 1105 ${_af}:*:${_af}:*) 1106 _aliasn="$_aliasn $ifconfig_args" 1107 ;; 1108 ${_af}:*:"":"") 1109 break 1110 ;; 1111 inet:alias:"":*) 1112 _aliasn="$_aliasn inet $ifconfig_args" 1113 warn "\$ifconfig_${_if}_alias${alias} needs " \ 1114 "\"inet\" keyword for an IPv4 address." 1115 esac 1116 alias=$(($alias + 1)) 1117 done 1118 1119 # backward compatibility: ipv6_ifconfig_IF_aliasN. 1120 case $_af in 1121 inet6) 1122 alias=0 1123 while : ; do 1124 ifconfig_args=`get_if_var $_if ipv6_ifconfig_IF_alias${alias}` 1125 case ${_action}:"${ifconfig_args}" in 1126 *:"") 1127 break 1128 ;; 1129 alias:*) 1130 _aliasn="${_aliasn} inet6 ${ifconfig_args}" 1131 warn "\$ipv6_ifconfig_${_if}_alias${alias} " \ 1132 "is obsolete. Use ifconfig_$1_aliasN " \ 1133 "instead." 1134 ;; 1135 esac 1136 alias=$(($alias + 1)) 1137 done 1138 esac 1139 1140 # backward compatibility: ipv4_addrs_IF. 1141 for _tmpargs in `get_if_var $_if ipv4_addrs_IF`; do 1142 _aliasn="$_aliasn inet $_tmpargs" 1143 done 1144 1145 # Handle ifconfig_IF_aliases, ifconfig_IF_aliasN, and the others. 1146 _tmpargs= 1147 for _c in `get_if_var $_if ifconfig_IF_aliases` $_aliasn; do 1148 case $_c in 1149 inet|inet6|ipx|link|ether) 1150 case $_tmpargs in 1151 ${_af}\ *) 1152 eval ifalias_af_common_handler $_if $_af $_action $_tmpargs && _ret=0 1153 ;; 1154 esac 1155 _tmpargs=$_c 1156 ;; 1157 *) 1158 _tmpargs="$_tmpargs $_c" 1159 esac 1160 done 1161 # Process the last component 1162 case $_tmpargs in 1163 ${_af}\ *) 1164 ifalias_af_common_handler $_if $_af $_action $_tmpargs && _ret=0 1165 ;; 1166 esac 1167 1168 return $_ret 1169} 1170 1171# ipv6_prefix_hostid_addr_common if action 1172# Add or remove IPv6 prefix + hostid addr on the interface $if 1173# 1174ipv6_prefix_hostid_addr_common() 1175{ 1176 local _if _action prefix j 1177 _if=$1 1178 _action=$2 1179 prefix=`get_if_var ${_if} ipv6_prefix_IF` 1180 1181 if [ -n "${prefix}" ]; then 1182 for j in ${prefix}; do 1183 # The default prefixlen is 64. 1184 plen=${j#*/} 1185 case $j:$plen in 1186 $plen:$j) plen=64 ;; 1187 *) j=${j%/*} ;; 1188 esac 1189 1190 # Normalize the last part by removing ":" 1191 j=${j%::*} 1192 j=${j%:} 1193 ${IFCONFIG_CMD} ${_if} inet6 $j:: \ 1194 prefixlen $plen eui64 ${_action} 1195 1196 # if I am a router, add subnet router 1197 # anycast address (RFC 2373). 1198 if checkyesno ipv6_gateway_enable; then 1199 ${IFCONFIG_CMD} ${_if} inet6 $j:: \ 1200 prefixlen $plen ${_action} anycast 1201 fi 1202 done 1203 fi 1204} 1205 1206# ipv6_accept_rtadv_up if 1207# Enable accepting Router Advertisement and send Router 1208# Solicitation message 1209ipv6_accept_rtadv_up() 1210{ 1211 if ipv6_autoconfif $1; then 1212 ${IFCONFIG_CMD} $1 inet6 accept_rtadv up 1213 if ! checkyesno rtsold_enable; then 1214 rtsol ${rtsol_flags} $1 1215 fi 1216 fi 1217} 1218 1219# ipv6_accept_rtadv_down if 1220# Disable accepting Router Advertisement 1221ipv6_accept_rtadv_down() 1222{ 1223 if ipv6_autoconfif $1; then 1224 ${IFCONFIG_CMD} $1 inet6 -accept_rtadv 1225 fi 1226} 1227 1228# ifscript_up if 1229# Evaluate a startup script for the $if interface. 1230# It returns 0 if a script was found and processed or 1231# 1 if no script was found. 1232# 1233ifscript_up() 1234{ 1235 if [ -r /etc/start_if.$1 ]; then 1236 . /etc/start_if.$1 1237 return 0 1238 else 1239 return 1 1240 fi 1241} 1242 1243# ifscript_down if 1244# Evaluate a shutdown script for the $if interface. 1245# It returns 0 if a script was found and processed or 1246# 1 if no script was found. 1247# 1248ifscript_down() 1249{ 1250 if [ -r /etc/stop_if.$1 ]; then 1251 . /etc/stop_if.$1 1252 return 0 1253 else 1254 return 1 1255 fi 1256} 1257 1258# clone_up 1259# Create cloneable interfaces. 1260# 1261clone_up() 1262{ 1263 local _list ifn ifopt _iflist _n tmpargs 1264 _list= 1265 _iflist=$* 1266 1267 # create_args_IF 1268 for ifn in ${cloned_interfaces}; do 1269 # Parse ifn:ifopt. 1270 OIFS=$IFS; IFS=:; set -- $ifn; ifn=$1; ifopt=$2; IFS=$OIFS 1271 case $_iflist in 1272 ""|$ifn|$ifn\ *|*\ $ifn\ *|*\ $ifn) ;; 1273 *) continue ;; 1274 esac 1275 case $ifn in 1276 epair[0-9]*) 1277 # epair(4) uses epair[0-9] for creation and 1278 # epair[0-9][ab] for configuration. 1279 # 1280 # Skip if ${ifn}a or ${ifn}b already exist. 1281 if ${IFCONFIG_CMD} ${ifn}a > /dev/null 2>&1; then 1282 continue 1283 elif ${IFCONFIG_CMD} ${ifn}b > /dev/null 2>&1; then 1284 continue 1285 fi 1286 ${IFCONFIG_CMD} ${ifn} create \ 1287 `get_if_var ${ifn} create_args_IF` 1288 if [ $? -eq 0 ]; then 1289 _list="$_list ${ifn}a ${ifn}b" 1290 fi 1291 ;; 1292 *) 1293 # Skip if ${ifn} already exists. 1294 if ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then 1295 continue 1296 fi 1297 ${IFCONFIG_CMD} ${ifn} create \ 1298 `get_if_var ${ifn} create_args_IF` 1299 if [ $? -eq 0 ]; then 1300 _list="$_list $ifn" 1301 fi 1302 esac 1303 done 1304 if [ -n "$gif_interfaces" ]; then 1305 warn "\$gif_interfaces is obsolete. Use \$cloned_interfaces instead." 1306 fi 1307 for ifn in ${gif_interfaces}; do 1308 # Parse ifn:ifopt. 1309 OIFS=$IFS; IFS=:; set -- $ifn; ifn=$1; ifopt=$2; IFS=$OIFS 1310 case $_iflist in 1311 ""|$ifn|$ifn\ *|*\ $ifn\ *|*\ $ifn) ;; 1312 *) continue ;; 1313 esac 1314 # Skip if ifn already exists. 1315 if ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then 1316 continue 1317 fi 1318 case $ifn in 1319 gif[0-9]*) 1320 ${IFCONFIG_CMD} $ifn create 1321 ;; 1322 *) 1323 _n=$(${IFCONFIG_CMD} gif create) 1324 ${IFCONFIG_CMD} $_n name $ifn 1325 ;; 1326 esac 1327 if [ $? -eq 0 ]; then 1328 _list="$_list $ifn" 1329 fi 1330 tmpargs=$(get_if_var $ifn gifconfig_IF) 1331 eval ifconfig_${ifn}=\"tunnel \$tmpargs\" 1332 done 1333 if [ -n "${_list# }" ]; then 1334 echo "Created clone interfaces: ${_list# }." 1335 fi 1336 debug "Cloned: ${_list# }" 1337} 1338 1339# clone_down 1340# Destroy cloned interfaces. Destroyed interfaces are echoed to 1341# standard output. 1342# 1343clone_down() 1344{ 1345 local _list ifn _difn ifopt _iflist _sticky 1346 _list= 1347 _iflist=$* 1348 1349 : ${cloned_interfaces_sticky:=NO} 1350 if checkyesno cloned_interfaces_sticky; then 1351 _sticky=1 1352 else 1353 _sticky=0 1354 fi 1355 for ifn in ${cloned_interfaces} ${gif_interfaces}; do 1356 # Parse ifn:ifopt. 1357 OIFS=$IFS; IFS=:; set -- $ifn; ifn=$1; ifopt=$2; IFS=$OIFS 1358 case $ifopt:$_sticky in 1359 sticky:*) continue ;; # :sticky => not destroy 1360 nosticky:*) ;; # :nosticky => destroy 1361 *:1) continue ;; # global sticky knob == 1 1362 esac 1363 case $_iflist in 1364 ""|$ifn|$ifn\ *|*\ $ifn\ *|*\ $ifn) ;; 1365 *) continue ;; 1366 esac 1367 case $ifn in 1368 epair[0-9]*) 1369 # Note: epair(4) uses epair[0-9] for removal and 1370 # epair[0-9][ab] for configuration. 1371 # 1372 # Skip if both of ${ifn}a and ${ifn}b do not exist. 1373 if ${IFCONFIG_CMD} ${ifn}a > /dev/null 2>&1; then 1374 _difn=${ifn}a 1375 elif ${IFCONFIG_CMD} ${ifn}b > /dev/null 2>&1; then 1376 _difn=${ifn}b 1377 else 1378 continue 1379 fi 1380 ${IFCONFIG_CMD} -n $_difn destroy 1381 if [ $? -eq 0 ]; then 1382 _list="$_list ${ifn}a ${ifn}b" 1383 fi 1384 ;; 1385 *) 1386 # Skip if ifn does not exist. 1387 if ! ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then 1388 continue 1389 fi 1390 ${IFCONFIG_CMD} -n ${ifn} destroy 1391 if [ $? -eq 0 ]; then 1392 _list="$_list $ifn" 1393 fi 1394 ;; 1395 esac 1396 done 1397 if [ -n "${_list# }" ]; then 1398 echo "Destroyed clone interfaces: ${_list# }." 1399 fi 1400 debug "Destroyed clones: ${_list# }" 1401} 1402 1403# childif_create 1404# Create and configure child interfaces. Return 0 if child 1405# interfaces are created. 1406# 1407childif_create() 1408{ 1409 local cfg child child_vlans child_wlans create_args debug_flags ifn i 1410 cfg=1 1411 ifn=$1 1412 1413 # Create wireless interfaces 1414 child_wlans=`get_if_var $ifn wlans_IF` 1415 1416 for child in ${child_wlans}; do 1417 create_args="wlandev $ifn `get_if_var $child create_args_IF`" 1418 debug_flags="`get_if_var $child wlandebug_IF`" 1419 1420 if expr $child : 'wlan[0-9][0-9]*$' >/dev/null 2>&1; then 1421 ${IFCONFIG_CMD} $child create ${create_args} && cfg=0 1422 if [ -n "${debug_flags}" ]; then 1423 wlandebug -i $child ${debug_flags} 1424 fi 1425 else 1426 i=`${IFCONFIG_CMD} wlan create ${create_args}` 1427 if [ -n "${debug_flags}" ]; then 1428 wlandebug -i $i ${debug_flags} 1429 fi 1430 ${IFCONFIG_CMD} $i name $child && cfg=0 1431 fi 1432 if autoif $child; then 1433 ifn_start $child 1434 fi 1435 done 1436 1437 # Create vlan interfaces 1438 child_vlans=`get_if_var $ifn vlans_IF` 1439 1440 if [ -n "${child_vlans}" ]; then 1441 load_kld if_vlan 1442 fi 1443 1444 for child in ${child_vlans}; do 1445 if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then 1446 child="${ifn}.${child}" 1447 create_args=`get_if_var $child create_args_IF` 1448 ${IFCONFIG_CMD} $child create ${create_args} && cfg=0 1449 else 1450 create_args="vlandev $ifn `get_if_var $child create_args_IF`" 1451 if expr $child : 'vlan[0-9][0-9]*$' >/dev/null 2>&1; then 1452 ${IFCONFIG_CMD} $child create ${create_args} && cfg=0 1453 else 1454 i=`${IFCONFIG_CMD} vlan create ${create_args}` 1455 ${IFCONFIG_CMD} $i name $child && cfg=0 1456 fi 1457 fi 1458 if autoif $child; then 1459 ifn_start $child 1460 fi 1461 done 1462 1463 return ${cfg} 1464} 1465 1466# childif_destroy 1467# Destroy child interfaces. 1468# 1469childif_destroy() 1470{ 1471 local cfg child child_vlans child_wlans ifn 1472 cfg=1 1473 1474 child_wlans=`get_if_var $ifn wlans_IF` 1475 for child in ${child_wlans}; do 1476 if ! ifexists $child; then 1477 continue 1478 fi 1479 ${IFCONFIG_CMD} -n $child destroy && cfg=0 1480 done 1481 1482 child_vlans=`get_if_var $ifn vlans_IF` 1483 for child in ${child_vlans}; do 1484 if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then 1485 child="${ifn}.${child}" 1486 fi 1487 if ! ifexists $child; then 1488 continue 1489 fi 1490 ${IFCONFIG_CMD} -n $child destroy && cfg=0 1491 done 1492 1493 return ${cfg} 1494} 1495 1496# ng_mkpeer 1497# Create netgraph nodes. 1498# 1499ng_mkpeer() 1500{ 1501 ngctl -f - 2> /dev/null <<EOF 1502mkpeer $* 1503msg dummy nodeinfo 1504EOF 1505} 1506 1507# ng_create_one 1508# Create netgraph nodes. 1509# 1510ng_create_one() 1511{ 1512 local t 1513 1514 ng_mkpeer $* | while read line; do 1515 t=`expr "${line}" : '.* name="\([a-z]*[0-9]*\)" .*'` 1516 if [ -n "${t}" ]; then 1517 echo ${t} 1518 return 1519 fi 1520 done 1521} 1522 1523# ng_fec_create ifn 1524# Configure Fast EtherChannel for interface $ifn. Returns 0 if 1525# FEC arguments were found and configured; returns !0 otherwise. 1526ng_fec_create() 1527{ 1528 local req_iface iface bogus 1529 req_iface="$1" 1530 1531 ngctl shutdown ${req_iface}: > /dev/null 2>&1 1532 1533 bogus="" 1534 while true; do 1535 iface=`ng_create_one fec dummy fec` 1536 if [ -z "${iface}" ]; then 1537 exit 2 1538 fi 1539 if [ "${iface}" = "${req_iface}" ]; then 1540 break 1541 fi 1542 bogus="${bogus} ${iface}" 1543 done 1544 1545 for iface in ${bogus}; do 1546 ngctl shutdown ${iface}: 1547 done 1548} 1549 1550# fec_up 1551# Create Fast EtherChannel interfaces. 1552fec_up() 1553{ 1554 local i j 1555 1556 for i in ${fec_interfaces}; do 1557 ng_fec_create $i 1558 for j in `get_if_var $i fecconfig_IF`; do 1559 case ${j} in 1560 '') 1561 continue 1562 ;; 1563 *) 1564 ngctl msg ${i}: add_iface "\"${j}\"" 1565 ;; 1566 esac 1567 done 1568 done 1569} 1570 1571# ipx_up ifn 1572# Configure any IPX addresses for interface $ifn. Returns 0 if 1573# IPX arguments were found and configured; returns 1 otherwise. 1574# 1575ipx_up() 1576{ 1577 local ifn 1578 ifn="$1" 1579 1580 # ifconfig_IF_ipx 1581 ifconfig_args=`_ifconfig_getargs $ifn ipx` 1582 if [ -n "${ifconfig_args}" ]; then 1583 ${IFCONFIG_CMD} ${ifn} ${ifconfig_args} 1584 return 0 1585 fi 1586 1587 return 1 1588} 1589 1590# ipx_down ifn 1591# Remove IPX addresses for interface $ifn. Returns 0 if IPX 1592# addresses were found and unconfigured. It returns 1, otherwise. 1593# 1594ipx_down() 1595{ 1596 local _if _ifs _ret ipxList oldifs _ipx 1597 _if=$1 1598 _ifs="^" 1599 _ret=1 1600 ipxList="`${IFCONFIG_CMD} ${_if} | grep 'ipx ' | tr "\n" "$_ifs"`" 1601 oldifs="$IFS" 1602 1603 IFS="$_ifs" 1604 for _ipx in $ipxList ; do 1605 # get rid of extraneous line 1606 [ -z "$_ipx" ] && break 1607 1608 _ipx=`expr "$_ipx" : '.*\(ipx [0-9a-h]\{1,8\}H*\.[0-9a-h]\{1,12\}\).*'` 1609 1610 IFS="$oldifs" 1611 ${IFCONFIG_CMD} ${_if} ${_ipx} delete 1612 IFS="$_ifs" 1613 _ret=0 1614 done 1615 IFS="$oldifs" 1616 1617 return $_ret 1618} 1619 1620# ifnet_rename [ifname] 1621# Rename interfaces if ifconfig_IF_name is defined. 1622# 1623ifnet_rename() 1624{ 1625 local _if _ifname 1626 1627 # ifconfig_IF_name 1628 for _if in ${*:-$(${IFCONFIG_CMD} -l)}; do 1629 _ifname=`get_if_var $_if ifconfig_IF_name` 1630 if [ ! -z "$_ifname" ]; then 1631 ${IFCONFIG_CMD} $_if name $_ifname 1632 fi 1633 done 1634 1635 return 0 1636} 1637 1638# list_net_interfaces type 1639# List all network interfaces. The type of interface returned 1640# can be controlled by the type argument. The type 1641# argument can be any of the following: 1642# nodhcp - all interfaces, excluding DHCP configured interfaces 1643# dhcp - list only DHCP configured interfaces 1644# noautoconf - all interfaces, excluding IPv6 Stateless 1645# Address Autoconf configured interfaces 1646# autoconf - list only IPv6 Stateless Address Autoconf 1647# configured interfaces 1648# If no argument is specified all network interfaces are output. 1649# Note that the list will include cloned interfaces if applicable. 1650# Cloned interfaces must already exist to have a chance to appear 1651# in the list if ${network_interfaces} is set to `auto'. 1652# 1653list_net_interfaces() 1654{ 1655 local type _tmplist _list _autolist _lo _if 1656 type=$1 1657 1658 # Get a list of ALL the interfaces and make lo0 first if it's there. 1659 # 1660 _tmplist= 1661 case ${network_interfaces} in 1662 [Aa][Uu][Tt][Oo]) 1663 _autolist="`${IFCONFIG_CMD} -l`" 1664 _lo= 1665 for _if in ${_autolist} ; do 1666 if autoif $_if; then 1667 if [ "$_if" = "lo0" ]; then 1668 _lo="lo0 " 1669 else 1670 _tmplist="${_tmplist} ${_if}" 1671 fi 1672 fi 1673 done 1674 _tmplist="${_lo}${_tmplist# }" 1675 ;; 1676 *) 1677 for _if in ${network_interfaces} ${cloned_interfaces}; do 1678 # epair(4) uses epair[0-9] for creation and 1679 # epair[0-9][ab] for configuration. 1680 case $_if in 1681 epair[0-9]*) 1682 _tmplist="$_tmplist ${_if}a ${_if}b" 1683 ;; 1684 *) 1685 _tmplist="$_tmplist $_if" 1686 ;; 1687 esac 1688 done 1689 # 1690 # lo0 is effectively mandatory, so help prevent foot-shooting 1691 # 1692 case "$_tmplist" in 1693 lo0|'lo0 '*|*' lo0'|*' lo0 '*) 1694 # This is fine, do nothing 1695 _tmplist="${_tmplist# }" 1696 ;; 1697 *) 1698 _tmplist="lo0 ${_tmplist# }" 1699 ;; 1700 esac 1701 ;; 1702 esac 1703 1704 _list= 1705 case "$type" in 1706 nodhcp) 1707 for _if in ${_tmplist} ; do 1708 if ! dhcpif $_if && \ 1709 [ -n "`_ifconfig_getargs $_if`" ]; then 1710 _list="${_list# } ${_if}" 1711 fi 1712 done 1713 ;; 1714 dhcp) 1715 for _if in ${_tmplist} ; do 1716 if dhcpif $_if; then 1717 _list="${_list# } ${_if}" 1718 fi 1719 done 1720 ;; 1721 noautoconf) 1722 for _if in ${_tmplist} ; do 1723 if ! ipv6_autoconfif $_if && \ 1724 [ -n "`_ifconfig_getargs $_if ipv6`" ]; then 1725 _list="${_list# } ${_if}" 1726 fi 1727 done 1728 ;; 1729 autoconf) 1730 for _if in ${_tmplist} ; do 1731 if ipv6_autoconfif $_if; then 1732 _list="${_list# } ${_if}" 1733 fi 1734 done 1735 ;; 1736 *) 1737 _list=${_tmplist} 1738 ;; 1739 esac 1740 1741 echo $_list 1742 1743 return 0 1744} 1745 1746# get_default_if -address_family 1747# Get the interface of the default route for the given address family. 1748# The -address_family argument must be suitable passing to route(8). 1749# 1750get_default_if() 1751{ 1752 local routeget oldifs defif line 1753 defif= 1754 oldifs="$IFS" 1755 IFS=" 1756" 1757 for line in `route -n get $1 default 2>/dev/null`; do 1758 case $line in 1759 *interface:*) 1760 defif=${line##*: } 1761 ;; 1762 esac 1763 done 1764 IFS=${oldifs} 1765 1766 echo $defif 1767} 1768 1769# hexdigit arg 1770# Echo decimal number $arg (single digit) in hexadecimal format. 1771hexdigit() 1772{ 1773 printf '%x\n' "$1" 1774} 1775 1776# hexprint arg 1777# Echo decimal number $arg (multiple digits) in hexadecimal format. 1778hexprint() 1779{ 1780 printf '%x\n' "$1" 1781} 1782 1783is_wired_interface() 1784{ 1785 local media 1786 1787 case `${IFCONFIG_CMD} $1 2>/dev/null` in 1788 *media:?Ethernet*) media=Ethernet ;; 1789 esac 1790 1791 test "$media" = "Ethernet" 1792} 1793 1794# network6_getladdr if [flag] 1795# Echo link-local address from $if if any. 1796# If flag is defined, tentative ones will be excluded. 1797network6_getladdr() 1798{ 1799 local _if _flag proto addr rest 1800 _if=$1 1801 _flag=$2 1802 1803 ${IFCONFIG_CMD} $_if 2>/dev/null | while read proto addr rest; do 1804 case "${proto}/${addr}/${_flag}/${rest}" in 1805 inet6/fe80::*//*) 1806 echo ${addr} 1807 ;; 1808 inet6/fe80:://*tentative*) # w/o flag 1809 sleep `${SYSCTL_N} net.inet6.ip6.dad_count` 1810 network6_getladdr $_if $_flags 1811 ;; 1812 inet6/fe80::/*/*tentative*) # w/ flag 1813 echo ${addr} 1814 ;; 1815 *) 1816 continue 1817 ;; 1818 esac 1819 1820 return 1821 done 1822} 1823