network.subr revision 161386
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 161386 2006-08-17 03:03:38Z brooks $ 26# 27 28# 29# Subroutines commonly used from network startup scripts. 30# Requires that rc.conf be loaded first. 31# 32 33# ifconfig_up if 34# Evaluate ifconfig(8) arguments for interface $if and 35# run ifconfig(8) with those arguments. It returns 0 if 36# arguments were found and executed or 1 if the interface 37# had no arguments. Pseudo arguments DHCP and WPA are handled 38# here. 39# 40ifconfig_up() 41{ 42 _cfg=1 43 44 ifconfig_args=`ifconfig_getargs $1` 45 if [ -n "${ifconfig_args}" ]; then 46 ifconfig $1 up 47 ifconfig $1 ${ifconfig_args} 48 _cfg=0 49 fi 50 51 if wpaif $1; then 52 if [ $_cfg -ne 0 ] ; then 53 ifconfig $1 up 54 fi 55 /etc/rc.d/wpa_supplicant start $1 56 _cfg=0 # XXX: not sure this should count 57 fi 58 59 if dhcpif $1; then 60 if [ $_cfg -ne 0 ] ; then 61 ifconfig $1 up 62 fi 63 if syncdhcpif $1; then 64 /etc/rc.d/dhclient start $1 65 fi 66 _cfg=0 67 fi 68 69 return $_cfg 70} 71 72# ifconfig_down if 73# returns 1 if wpa_supplicant or dhclient was stopped or 74# the interface exists. 75# 76ifconfig_down() 77{ 78 [ -z "$1" ] && return 1 79 _cfg=1 80 81 if wpaif $1; then 82 /etc/rc.d/wpa_supplicant stop $1 83 _cfg=0 84 fi 85 86 if dhcpif $1; then 87 /etc/rc.d/dhclient stop $1 88 _cfg=0 89 fi 90 91 if ifexists $1; then 92 ifconfig $1 down 93 _cfg=0 94 fi 95 96 return $_cfg 97} 98 99# get_if_var if var [default] 100# Return the value of the pseudo-hash corresponding to $if where 101# $var is a string containg the sub-string "IF" which will be 102# replaced with $if after the characters defined in _punct are 103# replaced with '_'. If the variable is unset, replace it with 104# $default if given. 105get_if_var() 106{ 107 if [ $# -ne 2 -a $# -ne 3 ]; then 108 err 3 'USAGE: get_if_var name var [default]' 109 fi 110 111 _if=$1 112 _punct=". - / +" 113 for _punct_c in $_punct; do 114 _if=`ltr ${_if} ${_punct_c} '_'` 115 done 116 _var=$2 117 _default=$3 118 119 prefix=${_var%%IF*} 120 suffix=${_var##*IF} 121 eval echo \${${prefix}${_if}${suffix}-${_default}} 122} 123 124# _ifconfig_getargs if 125# Echos the arguments for the supplied interface to stdout. 126# returns 1 if empty. In general, ifconfig_getargs should be used 127# outside this file. 128_ifconfig_getargs() 129{ 130 _ifn=$1 131 if [ -z "$_ifn" ]; then 132 return 1 133 fi 134 135 get_if_var $_ifn ifconfig_IF "$ifconfig_DEFAULT" 136} 137 138# ifconfig_getargs if 139# Takes the result from _ifconfig_getargs and removes pseudo 140# args such as DHCP and WPA. 141ifconfig_getargs() 142{ 143 _tmpargs=`_ifconfig_getargs $1` 144 if [ $? -eq 1 ]; then 145 return 1 146 fi 147 _args= 148 149 for _arg in $_tmpargs; do 150 case $_arg in 151 [Dd][Hh][Cc][Pp]) ;; 152 [Nn][Oo][Aa][Uu][Tt][Oo]) ;; 153 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) ;; 154 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) ;; 155 [Ww][Pp][Aa]) ;; 156 *) 157 _args="$_args $_arg" 158 ;; 159 esac 160 done 161 162 echo $_args 163} 164 165# autoif 166# Returns 0 if the interface should be automaticly configured at 167# boot time and 1 otherwise. 168autoif() 169{ 170 _tmpargs=`_ifconfig_getargs $1` 171 for _arg in $_tmpargs; do 172 case $_arg in 173 [Nn][Oo][Aa][Uu][Tt][Oo]) 174 return 1 175 ;; 176 esac 177 done 178 return 0 179} 180 181# dhcpif if 182# Returns 0 if the interface is a DHCP interface and 1 otherwise. 183dhcpif() 184{ 185 _tmpargs=`_ifconfig_getargs $1` 186 for _arg in $_tmpargs; do 187 case $_arg in 188 [Dd][Hh][Cc][Pp]) 189 return 0 190 ;; 191 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 192 return 0 193 ;; 194 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 195 return 0 196 ;; 197 esac 198 done 199 return 1 200} 201 202# syncdhcpif 203# Returns 0 if the interface should be configured synchronously and 204# 1 otherwise. 205syncdhcpif() 206{ 207 _tmpargs=`_ifconfig_getargs $1` 208 for _arg in $_tmpargs; do 209 case $_arg in 210 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 211 return 1 212 ;; 213 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 214 return 0 215 ;; 216 esac 217 done 218 if checkyesno synchronous_dhclient; then 219 return 0 220 else 221 return 1 222 fi 223} 224 225# wpaif if 226# Returns 0 if the interface is a WPA interface and 1 otherwise. 227wpaif() 228{ 229 _tmpargs=`_ifconfig_getargs $1` 230 for _arg in $_tmpargs; do 231 case $_arg in 232 [Ww][Pp][Aa]) 233 return 0 234 ;; 235 esac 236 done 237 return 1 238} 239 240# ifexists if 241# Returns 0 if the interface exists and 1 otherwise. 242ifexists() 243{ 244 ifconfig $1 > /dev/null 2>&1 245} 246 247# ipv4_up if 248# add IPv4 addresses to the interface $if 249ipv4_up() 250{ 251 _if=$1 252 ifalias_up ${_if} 253 ipv4_addrs_common ${_if} alias 254} 255 256# ipv4_down if 257# remove IPv4 addresses from the interface $if 258ipv4_down() 259{ 260 _if=$1 261 _ifs="^" 262 _ret=1 263 264 ifexists ${_if} || return 1 265 266 inetList="`ifconfig ${_if} | grep 'inet ' | tr "\n" "$_ifs"`" 267 268 oldifs="$IFS" 269 IFS="$_ifs" 270 for _inet in $inetList ; do 271 # get rid of extraneous line 272 [ -z "$_inet" ] && break 273 274 _inet=`expr "$_inet" : '.*\(inet \([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*'` 275 276 IFS="$oldifs" 277 ifconfig ${_if} ${_inet} delete 278 IFS="$_ifs" 279 _ret=0 280 done 281 IFS="$oldifs" 282 283 ifalias_down ${_if} && _ret=0 284 ipv4_addrs_common ${_if} -alias && _ret=0 285 286 return $_ret 287} 288 289# ipv4_addrs_common if action 290# Evaluate the ifconfig_if_ipv4 arguments for interface $if 291# and use $action to add or remove IPv4 addresses from $if. 292ipv4_addrs_common() 293{ 294 _ret=1 295 _if=$1 296 _action=$2 297 298 # get ipv4-addresses 299 cidr_addr=`get_if_var $_if ipv4_addrs_IF` 300 301 for _cidr in ${cidr_addr}; do 302 _ipaddr=${_cidr%%/*} 303 _netmask="/"${_cidr##*/} 304 _range=${_ipaddr##*.} 305 _ipnet=${_ipaddr%.*} 306 _iplow=${_range%-*} 307 _iphigh=${_range#*-} 308 309 # clear netmask when removing aliases 310 if [ "${_action}" = "-alias" ]; then 311 _netmask="" 312 fi 313 314 _ipcount=${_iplow} 315 while [ "${_ipcount}" -le "${_iphigh}" ]; do 316 eval "ifconfig ${_if} ${_action} ${_ipnet}.${_ipcount}${_netmask}" 317 _ipcount=$((${_ipcount}+1)) 318 _ret=0 319 320 # only the first ipaddr in a subnet need the real netmask 321 if [ "${_action}" != "-alias" ]; then 322 _netmask="/32" 323 fi 324 done 325 done 326 return $_ret 327} 328 329# ifalias_up if 330# Configure aliases for network interface $if. 331# It returns 0 if at least one alias was configured or 332# 1 if there were none. 333# 334ifalias_up() 335{ 336 _ret=1 337 alias=0 338 while : ; do 339 ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}` 340 if [ -n "${ifconfig_args}" ]; then 341 ifconfig $1 ${ifconfig_args} alias 342 alias=$((${alias} + 1)) 343 _ret=0 344 else 345 break 346 fi 347 done 348 return $_ret 349} 350 351#ifalias_down if 352# Remove aliases for network interface $if. 353# It returns 0 if at least one alias was removed or 354# 1 if there were none. 355# 356ifalias_down() 357{ 358 _ret=1 359 alias=0 360 while : ; do 361 ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}` 362 if [ -n "${ifconfig_args}" ]; then 363 ifconfig $1 ${ifconfig_args} -alias 364 alias=$((${alias} + 1)) 365 _ret=0 366 else 367 break 368 fi 369 done 370 return $_ret 371} 372 373# ifscript_up if 374# Evaluate a startup script for the $if interface. 375# It returns 0 if a script was found and processed or 376# 1 if no script was found. 377# 378ifscript_up() 379{ 380 if [ -r /etc/start_if.$1 ]; then 381 . /etc/start_if.$1 382 return 0 383 fi 384 return 1 385} 386 387# ifscript_down if 388# Evaluate a shutdown script for the $if interface. 389# It returns 0 if a script was found and processed or 390# 1 if no script was found. 391# 392ifscript_down() 393{ 394 if [ -r /etc/stop_if.$1 ]; then 395 . /etc/stop_if.$1 396 return 0 397 fi 398 return 1 399} 400 401# Create cloneable interfaces. 402# 403clone_up() 404{ 405 _prefix= 406 _list= 407 for ifn in ${cloned_interfaces}; do 408 ifconfig ${ifn} create 409 if [ $? -eq 0 ]; then 410 _list="${_list}${_prefix}${ifn}" 411 [ -z "$_prefix" ] && _prefix=' ' 412 fi 413 done 414 debug "Cloned: ${_list}" 415} 416 417# Destroy cloned interfaces. Destroyed interfaces are echoed 418# to standard output. 419# 420clone_down() 421{ 422 _prefix= 423 _list= 424 for ifn in ${cloned_interfaces}; do 425 ifconfig ${ifn} destroy 426 if [ $? -eq 0 ]; then 427 _list="${_list}${_prefix}${ifn}" 428 [ -z "$_prefix" ] && _prefix=' ' 429 fi 430 done 431 debug "Destroyed clones: ${_list}" 432} 433 434gif_up() { 435 case ${gif_interfaces} in 436 [Nn][Oo] | '') 437 ;; 438 *) 439 for i in ${gif_interfaces}; do 440 peers=`get_if_var $i gifconfig_IF` 441 case ${peers} in 442 '') 443 continue 444 ;; 445 *) 446 ifconfig $i create >/dev/null 2>&1 447 ifconfig $i tunnel ${peers} 448 ifconfig $i up 449 ;; 450 esac 451 done 452 ;; 453 esac 454} 455 456# 457# ipx_up ifn 458# Configure any IPX addresses for interface $ifn. Returns 0 if IPX 459# arguments were found and configured; returns 1 otherwise. 460# 461ipx_up() 462{ 463 ifn="$1" 464 ifconfig_args=`get_if_var $ifn ifconfig_IF_ipx` 465 if [ -n "${ifconfig_args}" ]; then 466 ifconfig ${ifn} ${ifconfig_args} 467 return 0 468 fi 469 return 1 470} 471 472# ipx_down ifn 473# Remove IPX addresses for interface $ifn. Returns 0 if IPX 474# addresses were found and unconfigured. It returns 1, otherwise. 475# 476ipx_down() 477{ 478 [ -z "$1" ] && return 1 479 _ifs="^" 480 _ret=1 481 482 ifexists $1 || return 1 483 484 ipxList="`ifconfig $1 | grep 'ipx ' | tr "\n" "$_ifs"`" 485 486 oldifs="$IFS" 487 IFS="$_ifs" 488 for _ipx in $ipxList ; do 489 # get rid of extraneous line 490 [ -z "$_ipx" ] && break 491 492 _ipx=`expr "$_ipx" : '.*\(ipx [0-9a-h]\{1,8\}H*\.[0-9a-h]\{1,12\}\).*'` 493 494 IFS="$oldifs" 495 ifconfig $1 ${_ipx} delete 496 IFS="$_ifs" 497 _ret=0 498 done 499 IFS="$oldifs" 500 501 return $_ret 502} 503 504# ifnet_rename 505# Rename all requested interfaces. 506# 507ifnet_rename() 508{ 509 510 _ifn_list="`ifconfig -l`" 511 [ -z "$_ifn_list" ] && return 0 512 for _if in ${_ifn_list} ; do 513 _ifname=`get_if_var $_if ifconfig_IF_name` 514 if [ ! -z "$_ifname" ]; then 515 ifconfig $_if name $_ifname 516 fi 517 done 518 return 0 519} 520 521# 522# list_net_interfaces type 523# List all network interfaces. The type of interface returned 524# can be controlled by the type argument. The type 525# argument can be any of the following: 526# nodhcp - all interfaces, excluding DHCP configured interfaces 527# dhcp - list only DHCP configured interfaces 528# If no argument is specified all network interfaces are output. 529# Note that the list will include cloned interfaces if applicable. 530# Cloned interfaces must already exist to have a chance to appear 531# in the list if ${network_interfaces} is set to `auto'. 532# 533list_net_interfaces() 534{ 535 type=$1 536 537 # Get a list of ALL the interfaces and make lo0 first if it's there. 538 # 539 case ${network_interfaces} in 540 [Aa][Uu][Tt][Oo]) 541 _prefix='' 542 _autolist="`ifconfig -l`" 543 _lo= 544 for _if in ${_autolist} ; do 545 if autoif $_if; then 546 if [ "$_if" = "lo0" ]; then 547 _lo="lo0 " 548 else 549 _tmplist="${_tmplist}${_prefix}${_if}" 550 [ -z "$_prefix" ] && _prefix=' ' 551 fi 552 fi 553 done 554 _tmplist="${_lo}${_tmplist}" 555 ;; 556 *) 557 _tmplist="${network_interfaces} ${cloned_interfaces}" 558 ;; 559 esac 560 561 if [ -z "$type" ]; then 562 echo $_tmplist 563 return 0 564 fi 565 566 # Separate out dhcp and non-dhcp interfaces 567 # 568 _aprefix= 569 _bprefix= 570 for _if in ${_tmplist} ; do 571 if dhcpif $_if; then 572 _dhcplist="${_dhcplist}${_aprefix}${_if}" 573 [ -z "$_aprefix" ] && _aprefix=' ' 574 elif [ -n "`_ifconfig_getargs $_if`" ]; then 575 _nodhcplist="${_nodhcplist}${_bprefix}${_if}" 576 [ -z "$_bprefix" ] && _bprefix=' ' 577 fi 578 done 579 580 case "$type" in 581 nodhcp) 582 echo $_nodhcplist 583 ;; 584 dhcp) 585 echo $_dhcplist 586 ;; 587 esac 588 return 0 589} 590 591hexdigit() 592{ 593 if [ $1 -lt 10 ]; then 594 echo $1 595 else 596 case $1 in 597 10) echo a ;; 598 11) echo b ;; 599 12) echo c ;; 600 13) echo d ;; 601 14) echo e ;; 602 15) echo f ;; 603 esac 604 fi 605} 606 607hexprint() 608{ 609 val=$1 610 str='' 611 612 dig=`hexdigit $((${val} & 15))` 613 str=${dig}${str} 614 val=$((${val} >> 4)) 615 while [ ${val} -gt 0 ]; do 616 dig=`hexdigit $((${val} & 15))` 617 str=${dig}${str} 618 val=$((${val} >> 4)) 619 done 620 621 echo ${str} 622} 623 624# Setup the interfaces for IPv6 625network6_interface_setup() 626{ 627 interfaces=$* 628 rtsol_interfaces='' 629 case ${ipv6_gateway_enable} in 630 [Yy][Ee][Ss]) 631 rtsol_available=no 632 ;; 633 *) 634 rtsol_available=yes 635 ;; 636 esac 637 for i in $interfaces; do 638 rtsol_interface=yes 639 prefix=`get_if_var $i ipv6_prefix_IF` 640 if [ -n "${prefix}" ]; then 641 rtsol_available=no 642 rtsol_interface=no 643 laddr=`network6_getladdr $i` 644 hostid=`expr "${laddr}" : 'fe80::\(.*\)%\(.*\)'` 645 for j in ${prefix}; do 646 address=$j\:${hostid} 647 ifconfig $i inet6 ${address} prefixlen 64 alias 648 649 case ${ipv6_gateway_enable} in 650 [Yy][Ee][Ss]) 651 # subnet-router anycast address 652 # (rfc2373) 653 ifconfig $i inet6 $j:: prefixlen 64 \ 654 alias anycast 655 ;; 656 esac 657 done 658 fi 659 ipv6_ifconfig=`get_if_var $i ipv6_ifconfig_IF` 660 if [ -n "${ipv6_ifconfig}" ]; then 661 rtsol_available=no 662 rtsol_interface=no 663 ifconfig $i inet6 ${ipv6_ifconfig} alias 664 fi 665 666 if [ ${rtsol_available} = yes -a ${rtsol_interface} = yes ] 667 then 668 case ${i} in 669 lo0|gif[0-9]*|stf[0-9]*|faith[0-9]*|lp[0-9]*|sl[0-9]*|tun[0-9]*) 670 ;; 671 *) 672 rtsol_interfaces="${rtsol_interfaces} ${i}" 673 ;; 674 esac 675 else 676 ifconfig $i inet6 677 fi 678 done 679 680 if [ ${rtsol_available} = yes -a -n "${rtsol_interfaces}" ]; then 681 # Act as endhost - automatically configured. 682 # You can configure only single interface, as 683 # specification assumes that autoconfigured host has 684 # single interface only. 685 sysctl net.inet6.ip6.accept_rtadv=1 686 set ${rtsol_interfaces} 687 ifconfig $1 up 688 rtsol ${rtsol_flags} $1 689 fi 690 691 for i in $interfaces; do 692 alias=0 693 while : ; do 694 ipv6_ifconfig=`get_if_var $i ipv6_ifconfig_IF_alias${alias}` 695 if [ -z "${ipv6_ifconfig}" ]; then 696 break; 697 fi 698 ifconfig $i inet6 ${ipv6_ifconfig} alias 699 alias=$((${alias} + 1)) 700 done 701 done 702} 703 704# Setup IPv6 to IPv4 mapping 705network6_stf_setup() 706{ 707 case ${stf_interface_ipv4addr} in 708 [Nn][Oo] | '') 709 ;; 710 *) 711 # assign IPv6 addr and interface route for 6to4 interface 712 stf_prefixlen=$((16+${stf_interface_ipv4plen:-0})) 713 OIFS="$IFS" 714 IFS=".$IFS" 715 set ${stf_interface_ipv4addr} 716 IFS="$OIFS" 717 hexfrag1=`hexprint $(($1*256 + $2))` 718 hexfrag2=`hexprint $(($3*256 + $4))` 719 ipv4_in_hexformat="${hexfrag1}:${hexfrag2}" 720 case ${stf_interface_ipv6_ifid} in 721 [Aa][Uu][Tt][Oo] | '') 722 for i in ${ipv6_network_interfaces}; do 723 laddr=`network6_getladdr ${i}` 724 case ${laddr} in 725 '') 726 ;; 727 *) 728 break 729 ;; 730 esac 731 done 732 stf_interface_ipv6_ifid=`expr "${laddr}" : \ 733 'fe80::\(.*\)%\(.*\)'` 734 case ${stf_interface_ipv6_ifid} in 735 '') 736 stf_interface_ipv6_ifid=0:0:0:1 737 ;; 738 esac 739 ;; 740 esac 741 ifconfig stf0 create >/dev/null 2>&1 742 ifconfig stf0 inet6 2002:${ipv4_in_hexformat}:${stf_interface_ipv6_slaid:-0}:${stf_interface_ipv6_ifid} \ 743 prefixlen ${stf_prefixlen} 744 # disallow packets to malicious 6to4 prefix 745 route add -inet6 2002:e000:: -prefixlen 20 ::1 -reject 746 route add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject 747 route add -inet6 2002:0000:: -prefixlen 24 ::1 -reject 748 route add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject 749 ;; 750 esac 751} 752 753# Setup static routes 754network6_static_routes_setup() 755{ 756 # Set up any static routes. 757 case ${ipv6_defaultrouter} in 758 [Nn][Oo] | '') 759 ;; 760 *) 761 ipv6_static_routes="default ${ipv6_static_routes}" 762 ipv6_route_default="default ${ipv6_defaultrouter}" 763 ;; 764 esac 765 case ${ipv6_static_routes} in 766 [Nn][Oo] | '') 767 ;; 768 *) 769 for i in ${ipv6_static_routes}; do 770 ipv6_route_args=`get_if_var $i ipv6_route_IF` 771 route add -inet6 ${ipv6_route_args} 772 done 773 ;; 774 esac 775} 776 777# Setup faith 778network6_faith_setup() 779{ 780 case ${ipv6_faith_prefix} in 781 [Nn][Oo] | '') 782 ;; 783 *) 784 sysctl net.inet6.ip6.keepfaith=1 785 ifconfig faith0 create >/dev/null 2>&1 786 ifconfig faith0 up 787 for prefix in ${ipv6_faith_prefix}; do 788 prefixlen=`expr "${prefix}" : ".*/\(.*\)"` 789 case ${prefixlen} in 790 '') 791 prefixlen=96 792 ;; 793 *) 794 prefix=`expr "${prefix}" : \ 795 "\(.*\)/${prefixlen}"` 796 ;; 797 esac 798 route add -inet6 ${prefix} -prefixlen ${prefixlen} ::1 799 route change -inet6 ${prefix} -prefixlen ${prefixlen} \ 800 -ifp faith0 801 done 802 ;; 803 esac 804} 805 806# Install the "default interface" to kernel, which will be used 807# as the default route when there's no router. 808network6_default_interface_setup() 809{ 810 # Choose IPv6 default interface if it is not clearly specified. 811 case ${ipv6_default_interface} in 812 '') 813 for i in ${ipv6_network_interfaces}; do 814 case $i in 815 lo0|faith[0-9]*) 816 continue 817 ;; 818 esac 819 laddr=`network6_getladdr $i exclude_tentative` 820 case ${laddr} in 821 '') 822 ;; 823 *) 824 ipv6_default_interface=$i 825 break 826 ;; 827 esac 828 done 829 ;; 830 esac 831 832 # Disallow unicast packets without outgoing scope identifiers, 833 # or route such packets to a "default" interface, if it is specified. 834 route add -inet6 fe80:: -prefixlen 10 ::1 -reject 835 case ${ipv6_default_interface} in 836 [Nn][Oo] | '') 837 route add -inet6 ff02:: -prefixlen 16 ::1 -reject 838 ;; 839 *) 840 laddr=`network6_getladdr ${ipv6_default_interface}` 841 route add -inet6 ff02:: ${laddr} -prefixlen 16 -interface \ 842 -cloning 843 844 # Disable installing the default interface with the 845 # case net.inet6.ip6.forwarding=0 and 846 # net.inet6.ip6.accept_rtadv=0, due to avoid conflict 847 # between the default router list and the manual 848 # configured default route. 849 case ${ipv6_gateway_enable} in 850 [Yy][Ee][Ss]) 851 ;; 852 *) 853 if [ `sysctl -n net.inet6.ip6.accept_rtadv` -eq 1 ] 854 then 855 ndp -I ${ipv6_default_interface} 856 fi 857 ;; 858 esac 859 ;; 860 esac 861} 862 863network6_getladdr() 864{ 865 ifconfig $1 2>/dev/null | while read proto addr rest; do 866 case ${proto} in 867 inet6) 868 case ${addr} in 869 fe80::*) 870 if [ -z "$2" ]; then 871 echo ${addr} 872 return 873 fi 874 case ${rest} in 875 *tentative*) 876 continue 877 ;; 878 *) 879 echo ${addr} 880 return 881 esac 882 esac 883 esac 884 done 885} 886