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