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_get_unused 418# walk through net.wlan and find unused device that can be created 419# 420wlan_get_unused() 421{ 422 local idx 423 424 idx=0 425 426 while : ; do 427 if ! ${SYSCTL_N} -q net.wlan.${idx}.%parent >/dev/null; then 428 echo "wlan${idx}" 429 break 430 fi 431 idx=$((${idx} + 1)) 432 done 433} 434 435# wlan_is_parent 436# check if given interface is parent for any existing wlan device 437# 438wlan_is_parent() 439{ 440 sysctl -q net.wlan | grep -q "%parent: ${1}" 441} 442 443# wlan_up 444# Create IEEE 802.11 interfaces. 445# 446wlan_up() 447{ 448 local _prefix _list parent child child_wlans create_args debug_flags 449 _prefix= 450 _list= 451 452 local _rcconf _auto 453 _rcconf="" 454 _auto="" 455 456 local wlan_devices 457 if [ -n "$1" ]; then 458 wlan_devices="$1" 459 else 460 wlan_devices="`${SYSCTL_N} -q net.wlan.devices`" 461 fi 462 463 # Order detected devices so that interfaces configured via rc.conf are 464 # created first, and then all other devices are automatically assigned 465 for parent in ${wlan_devices}; do 466 child_wlans=`get_if_var $parent wlans_IF` 467 if [ -n "${child_wlans}" ]; then 468 _rcconf="${_rcconf} ${parent}" 469 else 470 _auto="${_auto} ${parent}" 471 fi 472 done 473 474 for parent in ${_rcconf} ${_auto}; do 475 if wlan_is_parent $parent; then 476 continue 477 fi 478 # Parse wlans_$parent="$child ..." 479 child_wlans=`get_if_var $parent wlans_IF` 480 # Or find first unused wlan device to create 481 if [ -z "${child_wlans}" ]; then 482 child_wlans=`wlan_get_unused` 483 fi 484 for child in ${child_wlans}; do 485 if ifexists $child; then 486 continue 487 fi 488 489 create_args="wlandev $parent `get_if_var $child create_args_IF`" 490 debug_flags="`get_if_var $child wlandebug_IF`" 491 if expr $child : 'wlan[0-9][0-9]*$' >/dev/null 2>&1; then 492 ifconfig $child create ${create_args} 493 else 494 ifconfig wlan create ${create_args} name $child 495 fi 496 if [ $? -eq 0 ]; then 497 _list="${_list}${_prefix}${child}" 498 [ -z "$_prefix" ] && _prefix=' ' 499 fi 500 if [ -n "${debug_flags}" ]; then 501 wlandebug -i $child ${debug_flags} 502 fi 503 done 504 done 505 506 if [ -n "${_list}" ]; then 507 echo "Created wlan interfaces: ${_list}" 508 fi 509 debug "Created wlan interfaces: ${_list}" 510} 511 512# wlan_down 513# Destroy IEEE 802.11 interfaces. 514# 515wlan_down() 516{ 517 local _prefix _list parent child child_wlans 518 _prefix= 519 _list= 520 521 local wlan_devices 522 if [ -n "$1" ]; then 523 wlan_devices="$1" 524 else 525 wlan_devices="`${SYSCTL_N} -q net.wlan.devices`" 526 fi 527 528 for parent in ${wlan_devices}; do 529 child_wlans=`get_if_var $parent wlans_IF` 530 for child in ${child_wlans}; do 531 if ! ifexists $child; then 532 continue 533 fi 534 535 ifconfig -n $child destroy 536 if [ $? -eq 0 ]; then 537 _list="${_list}${_prefix}${child}" 538 [ -z "$_prefix" ] && _prefix=' ' 539 fi 540 done 541 done 542 543 if [ -n "${_list}" ]; then 544 echo "Destroyed wlan interfaces: ${_list}" 545 fi 546 debug "Destroyed wlan interfaces: ${_list}" 547} 548 549# clone_up 550# Create cloneable interfaces. 551# 552clone_up() 553{ 554 local _prefix _list ifn 555 _prefix= 556 _list= 557 558 for ifn in ${cloned_interfaces}; do 559 ifconfig ${ifn} create 560 if [ $? -eq 0 ]; then 561 _list="${_list}${_prefix}${ifn}" 562 [ -z "$_prefix" ] && _prefix=' ' 563 fi 564 done 565 if [ -n "${_list}" ]; then 566 echo "Created clone interfaces: ${_list}" 567 fi 568 debug "Created clone interfaces: ${_list}" 569} 570 571# clone_down 572# Destroy cloned interfaces. 573# 574clone_down() 575{ 576 local _prefix _list ifn 577 _prefix= 578 _list= 579 580 for ifn in ${cloned_interfaces}; do 581 ifconfig ${ifn} destroy 582 if [ $? -eq 0 ]; then 583 _list="${_list}${_prefix}${ifn}" 584 [ -z "$_prefix" ] && _prefix=' ' 585 fi 586 done 587 if [ -n "${_list}" ]; then 588 echo "Destroyed clone interfaces: ${_list}" 589 fi 590 debug "Destroyed clone interfaces: ${_list}" 591} 592 593# gif_up 594# Create IPv6<-->IPv4 tunnels 595# 596gif_up() { 597 local _if _peers 598 599 case ${gif_interfaces} in 600 [Nn][Oo] | '') 601 return 602 ;; 603 esac 604 605 for _if in ${gif_interfaces}; do 606 eval _peers=\$gifconfig_${_if} 607 case ${_peers} in 608 '') 609 continue 610 ;; 611 *) 612 ifconfig $_if create >/dev/null 2>&1 613 ifconfig $_if tunnel ${_peers} 614 ifconfig $_if up 615 ;; 616 esac 617 done 618} 619 620# ifnet_rename 621# Rename all requested interfaces. 622# 623ifnet_rename() 624{ 625 local _ifn_list _if _ifname 626 627 _ifn_list=$(ifconfig -l) 628 [ -z "$_ifn_list" ] && return 0 629 630 for _if in ${_ifn_list} ; do 631 _ifname=`get_if_var $_if ifconfig_IF_name` 632 if [ -n "$_ifname" ]; then 633 ifconfig $_if name $_ifname 634 fi 635 done 636 return 0 637} 638 639# list_net_interfaces 640# List all network interfaces. 641# Note that the list will include cloned interfaces if applicable. 642# Cloned interfaces must already exist to have a chance to appear 643# in the list if ${network_interfaces} is set to `auto'. 644# 645list_net_interfaces() 646{ 647 local _tmplist _autolist _lo _if 648 649 case ${network_interfaces} in 650 [Aa][Uu][Tt][Oo]) 651 _autolist=$(ifconfig -l) 652 _lo= 653 for _if in ${_autolist} ; do 654 if [ "$_if" = "lo0" ]; then 655 _lo="lo0" 656 else 657 _tmplist="${_tmplist} ${_if}" 658 fi 659 done 660 _tmplist="${_lo} ${_tmplist}" 661 ;; 662 *) 663 _tmplist="${network_interfaces} ${cloned_interfaces}" 664 ;; 665 esac 666 667 echo $_tmplist 668} 669 670hexdigit() 671{ 672 if [ $1 -lt 10 ]; then 673 echo $1 674 else 675 case $1 in 676 10) echo a ;; 677 11) echo b ;; 678 12) echo c ;; 679 13) echo d ;; 680 14) echo e ;; 681 15) echo f ;; 682 esac 683 fi 684} 685 686hexprint() 687{ 688 local val str dig 689 val=$1 690 str='' 691 692 dig=`hexdigit $((${val} & 15))` 693 str=${dig}${str} 694 val=$((${val} >> 4)) 695 while [ ${val} -gt 0 ]; do 696 dig=`hexdigit $((${val} & 15))` 697 str=${dig}${str} 698 val=$((${val} >> 4)) 699 done 700 701 echo ${str} 702} 703 704is_wired_interface() 705{ 706 local media 707 708 case `ifconfig $1 2>/dev/null` in 709 *media:?Ethernet*) media=Ethernet ;; 710 esac 711 712 test "$media" = "Ethernet" 713} 714 715# 716# IPv6-specific setup subroutines 717# 718 719# Setup the interfaces for IPv6 720network6_interface_setup() 721{ 722 local interfaces rtsol_interfaces ipv6_ifconfig 723 local rtsol_available rtsol_interface 724 local prefix laddr hostid address 725 local _if j 726 727 interfaces=$* 728 rtsol_interfaces='' 729 case ${ipv6_gateway_enable} in 730 [Yy][Ee][Ss]) 731 rtsol_available=no 732 ;; 733 *) 734 rtsol_available=yes 735 ;; 736 esac 737 for _if in $interfaces; do 738 rtsol_interface=yes 739 prefix=`get_if_var $_if ipv6_prefix_IF` 740 if [ -n "${prefix}" ]; then 741 rtsol_available=no 742 rtsol_interface=no 743 laddr=`network6_getladdr $_if` 744 hostid=`expr "${laddr}" : 'fe80::\(.*\)%\(.*\)'` 745 for j in ${prefix}; do 746 address=$j\:${hostid} 747 ifconfig $_if inet6 ${address} prefixlen 64 alias 748 749 case ${ipv6_gateway_enable} in 750 [Yy][Ee][Ss]) 751 # subnet-router anycast address 752 # (rfc2373) 753 ifconfig $_if inet6 $j:: prefixlen 64 \ 754 alias anycast 755 ;; 756 esac 757 done 758 fi 759 ipv6_ifconfig=`ifconfig_getargs $_if ipv6` 760 ipv6_ifconfig="${ipv6_ifconfig#inet6 }" 761 if [ -n "${ipv6_ifconfig}" ]; then 762 rtsol_available=no 763 rtsol_interface=no 764 ifconfig $_if inet6 ${ipv6_ifconfig} alias 765 fi 766 767 if [ "${rtsol_available}" = "yes" -a \ 768 "${rtsol_interface}" = "yes" ]; then 769 case ${i} in 770 lo0|gif[0-9]*|stf[0-9]*|lp[0-9]*|sl[0-9]*|tun[0-9]*) 771 ;; 772 *) 773 rtsol_interfaces="${rtsol_interfaces} ${_if}" 774 ;; 775 esac 776 else 777 ifconfig $_if inet6 778 fi 779 done 780 781 if [ "${rtsol_available}" = "yes" -a -n "${rtsol_interfaces}" ]; then 782 # Act as endhost - automatically configured. 783 # You can configure only single interface, as 784 # specification assumes that autoconfigured host has 785 # single interface only. 786 ${SYSCTL_W} net.inet6.ip6.accept_rtadv=1 787 set ${rtsol_interfaces} 788 ifconfig $1 up 789 echo "Auto configuring interface $1 ..." 790 rtsol $1 791 fi 792 793 for _if in $interfaces; do 794 ifalias_up $_if ipv6 795 done 796} 797 798# Setup IPv6 to IPv4 mapping 799network6_stf_setup() 800{ 801 local stf_prefixlen stf_interface_ipv6_ifid 802 local hexfrag1 hexfrag2 ipv4_in_hexformat laddr 803 local _if OIFS 804 805 case ${stf_interface_ipv4addr} in 806 [Nn][Oo] | '') 807 ;; 808 *) 809 # assign IPv6 addr and interface route for 6to4 interface 810 stf_prefixlen=$((16+${stf_interface_ipv4plen:-0})) 811 OIFS="$IFS" 812 IFS=".$IFS" 813 set ${stf_interface_ipv4addr} 814 IFS="$OIFS" 815 hexfrag1=`hexprint $(($1*256 + $2))` 816 hexfrag2=`hexprint $(($3*256 + $4))` 817 ipv4_in_hexformat="${hexfrag1}:${hexfrag2}" 818 case ${stf_interface_ipv6_ifid} in 819 [Aa][Uu][Tt][Oo] | '') 820 for _if in ${ipv6_network_interfaces}; do 821 laddr=`network6_getladdr $_if` 822 case ${laddr} in 823 '') 824 ;; 825 *) 826 break 827 ;; 828 esac 829 done 830 stf_interface_ipv6_ifid=`expr "${laddr}" : \ 831 'fe80::\(.*\)%\(.*\)'` 832 case ${stf_interface_ipv6_ifid} in 833 '') 834 stf_interface_ipv6_ifid=0:0:0:1 835 ;; 836 esac 837 ;; 838 esac 839 ifconfig stf0 create >/dev/null 2>&1 840 ifconfig stf0 inet6 2002:${ipv4_in_hexformat}:${stf_interface_ipv6_slaid:-0}:${stf_interface_ipv6_ifid} \ 841 prefixlen ${stf_prefixlen} 842 # disallow packets to malicious 6to4 prefix 843 route add -inet6 2002:e000:: -prefixlen 20 ::1 -reject 844 route add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject 845 route add -inet6 2002:0000:: -prefixlen 24 ::1 -reject 846 route add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject 847 ;; 848 esac 849} 850 851# Setup static routes 852network6_static_routes_setup() 853{ 854 local _rt 855 856 # Set up any static routes. 857 case ${ipv6_defaultrouter} in 858 [Nn][Oo] | '') 859 ;; 860 *) 861 ipv6_static_routes="default ${ipv6_static_routes}" 862 ipv6_route_default="default ${ipv6_defaultrouter}" 863 ;; 864 esac 865 case ${ipv6_static_routes} in 866 [Nn][Oo] | '') 867 ;; 868 *) 869 for _rt in ${ipv6_static_routes}; do 870 eval ipv6_route_args=\$ipv6_route_${_rt} 871 route add -inet6 ${ipv6_route_args} 872 done 873 ;; 874 esac 875} 876 877# Install the "default interface" to kernel, which will be used 878# as the default route when there's no router. 879network6_default_interface_setup() 880{ 881 local _if laddr 882 883 # Choose IPv6 default interface if it is not clearly specified. 884 case ${ipv6_default_interface} in 885 '') 886 for _if in ${ipv6_network_interfaces}; do 887 if [ "${_if}" = "lo0" ]; then 888 continue 889 fi 890 891 laddr=`network6_getladdr $_if exclude_tentative` 892 case ${laddr} in 893 '') 894 ;; 895 *) 896 ipv6_default_interface=$_if 897 break 898 ;; 899 esac 900 done 901 ;; 902 esac 903 904 # Disallow unicast packets without outgoing scope identifiers, 905 # or route such packets to a "default" interface, if it is specified. 906 route add -inet6 fe80:: -prefixlen 10 ::1 -reject 907 case ${ipv6_default_interface} in 908 [Nn][Oo] | '') 909 route add -inet6 ff02:: -prefixlen 16 ::1 -reject 910 ;; 911 *) 912 laddr=`network6_getladdr ${ipv6_default_interface}` 913 route add -inet6 ff02:: ${laddr} -prefixlen 16 -interface \ 914 -cloning 915 916 # Disable installing the default interface with the 917 # case net.inet6.ip6.forwarding=0 and 918 # net.inet6.ip6.accept_rtadv=0, due to avoid conflict 919 # between the default router list and the manual 920 # configured default route. 921 case ${ipv6_gateway_enable} in 922 [Yy][Ee][Ss]) 923 ;; 924 *) 925 if [ `${SYSCTL_N} net.inet6.ip6.accept_rtadv` -eq 1 ] 926 then 927 ndp -I ${ipv6_default_interface} 928 fi 929 ;; 930 esac 931 ;; 932 esac 933} 934 935network6_getladdr() 936{ 937 local proto addr rest 938 939 ifconfig $1 2>/dev/null | while read proto addr rest; do 940 case ${proto} in 941 inet6) 942 case ${addr} in 943 fe80::*) 944 if [ -z "$2" ]; then 945 echo ${addr} 946 return 947 fi 948 case ${rest} in 949 *tentative*) 950 continue 951 ;; 952 *) 953 echo ${addr} 954 return 955 esac 956 esac 957 esac 958 done 959} 960