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