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