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