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