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