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