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