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